Import statistics-context-provider into src/statistics 33/56633/1
authorMu-Woong Lee <muwoong.lee@samsung.com>
Mon, 11 Jan 2016 12:54:59 +0000 (21:54 +0900)
committerMu-Woong Lee <muwoong.lee@samsung.com>
Mon, 11 Jan 2016 12:54:59 +0000 (21:54 +0900)
Change-Id: I35a81227cc11518143aeae3b300ed71534cd97bf
Signed-off-by: Mu-Woong Lee <muwoong.lee@samsung.com>
73 files changed:
include/statistics_context_provider.h [new file with mode: 0644]
packaging/context-provider.spec
src/CMakeLists.txt
src/statistics/CMakeLists.txt [new file with mode: 0644]
src/statistics/app/app_stats_provider.cpp [new file with mode: 0644]
src/statistics/app/app_stats_provider.h [new file with mode: 0644]
src/statistics/app/app_stats_types.h [new file with mode: 0644]
src/statistics/app/app_use_monitor/active_window_monitor.cpp [new file with mode: 0644]
src/statistics/app/app_use_monitor/active_window_monitor.h [new file with mode: 0644]
src/statistics/app/app_use_monitor/launch_monitor.cpp [new file with mode: 0644]
src/statistics/app/app_use_monitor/launch_monitor.h [new file with mode: 0644]
src/statistics/app/db_handle.cpp [new file with mode: 0644]
src/statistics/app/db_handle.h [new file with mode: 0644]
src/statistics/app/db_init.cpp [new file with mode: 0644]
src/statistics/app/db_init.h [new file with mode: 0644]
src/statistics/app/install_monitor.cpp [new file with mode: 0644]
src/statistics/app/install_monitor.h [new file with mode: 0644]
src/statistics/media/db_handle.cpp [new file with mode: 0644]
src/statistics/media/db_handle.h [new file with mode: 0644]
src/statistics/media/media_content_monitor.cpp [new file with mode: 0644]
src/statistics/media/media_content_monitor.h [new file with mode: 0644]
src/statistics/media/media_stats_provider.cpp [new file with mode: 0644]
src/statistics/media/media_stats_provider.h [new file with mode: 0644]
src/statistics/media/media_stats_types.h [new file with mode: 0644]
src/statistics/prediction/assoc_rule.cpp [new file with mode: 0644]
src/statistics/prediction/assoc_rule.h [new file with mode: 0644]
src/statistics/prediction/assoc_rule_miner.cpp [new file with mode: 0644]
src/statistics/prediction/assoc_rule_miner.h [new file with mode: 0644]
src/statistics/prediction/assoc_rule_of_ids.h [new file with mode: 0644]
src/statistics/prediction/assoc_rule_producer.cpp [new file with mode: 0644]
src/statistics/prediction/assoc_rule_producer.h [new file with mode: 0644]
src/statistics/prediction/basket.cpp [new file with mode: 0644]
src/statistics/prediction/basket.h [new file with mode: 0644]
src/statistics/prediction/basket_compressor.cpp [new file with mode: 0644]
src/statistics/prediction/basket_compressor.h [new file with mode: 0644]
src/statistics/prediction/basket_filter.cpp [new file with mode: 0644]
src/statistics/prediction/basket_filter.h [new file with mode: 0644]
src/statistics/prediction/basket_producer.cpp [new file with mode: 0644]
src/statistics/prediction/basket_producer.h [new file with mode: 0644]
src/statistics/prediction/baskets_agregator.cpp [new file with mode: 0644]
src/statistics/prediction/baskets_agregator.h [new file with mode: 0644]
src/statistics/prediction/event.cpp [new file with mode: 0644]
src/statistics/prediction/event.h [new file with mode: 0644]
src/statistics/prediction/event_set.h [new file with mode: 0644]
src/statistics/prediction/i_item_id_filter.h [new file with mode: 0644]
src/statistics/prediction/interval.cpp [new file with mode: 0644]
src/statistics/prediction/interval.h [new file with mode: 0644]
src/statistics/prediction/item.cpp [new file with mode: 0644]
src/statistics/prediction/item.h [new file with mode: 0644]
src/statistics/prediction/item_catalogue.cpp [new file with mode: 0644]
src/statistics/prediction/item_catalogue.h [new file with mode: 0644]
src/statistics/prediction/item_id_set.h [new file with mode: 0644]
src/statistics/prediction/item_set.cpp [new file with mode: 0644]
src/statistics/prediction/item_set.h [new file with mode: 0644]
src/statistics/prediction/item_string_converter.cpp [new file with mode: 0644]
src/statistics/prediction/item_string_converter.h [new file with mode: 0644]
src/statistics/prediction/single_category_item_id_filter.cpp [new file with mode: 0644]
src/statistics/prediction/single_category_item_id_filter.h [new file with mode: 0644]
src/statistics/prediction/weight_apriori.cpp [new file with mode: 0644]
src/statistics/prediction/weight_apriori.h [new file with mode: 0644]
src/statistics/shared/common_types.h [new file with mode: 0644]
src/statistics/shared/db_handle_base.cpp [new file with mode: 0644]
src/statistics/shared/db_handle_base.h [new file with mode: 0644]
src/statistics/shared/system_info.cpp [new file with mode: 0644]
src/statistics/shared/system_info.h [new file with mode: 0644]
src/statistics/social/db_handle.cpp [new file with mode: 0644]
src/statistics/social/db_handle.h [new file with mode: 0644]
src/statistics/social/log_aggregator.cpp [new file with mode: 0644]
src/statistics/social/log_aggregator.h [new file with mode: 0644]
src/statistics/social/social_stats_provider.cpp [new file with mode: 0644]
src/statistics/social/social_stats_provider.h [new file with mode: 0644]
src/statistics/social/social_stats_types.h [new file with mode: 0644]
src/statistics/statistics_context_provider.cpp [new file with mode: 0644]

diff --git a/include/statistics_context_provider.h b/include/statistics_context_provider.h
new file mode 100644 (file)
index 0000000..b45c3fd
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * 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_STATISTICS_CONTEXT_PROVIDER_H__
+#define __CONTEXT_STATISTICS_CONTEXT_PROVIDER_H__
+
+namespace ctx {
+       bool init_statistics_context_provider();
+}
+
+#endif /* __CONTEXT_STATISTICS_CONTEXT_PROVIDER_H__ */
index 84efb12f4b68f624923bd40a68324db0302bdf7b..5746f9da50f5066c32ae3aac482ed6090daeff77 100644 (file)
@@ -8,12 +8,27 @@ Source0:    %{name}-%{version}.tar.gz
 
 %define BUILD_PROFILE %{?profile}%{!?profile:%{?tizen_profile_name}}
 
+# Using the active window hooking for app monitoring, via ecore-x
+%define ACTIVE_WINDOW_HOOK off
+
 BuildRequires: cmake
+
 BuildRequires: pkgconfig(context-common)
 BuildRequires: pkgconfig(vconf)
 BuildRequires: pkgconfig(capi-system-info)
 BuildRequires: pkgconfig(capi-system-device)
 BuildRequires: pkgconfig(capi-system-runtime-info)
+BuildRequires: pkgconfig(capi-appfw-package-manager)
+BuildRequires: pkgconfig(capi-appfw-application)
+BuildRequires: pkgconfig(capi-appfw-app-manager)
+BuildRequires: pkgconfig(pkgmgr)
+BuildRequires: pkgconfig(pkgmgr-info)
+BuildRequires: pkgconfig(capi-media-sound-manager)
+
+%if "%{ACTIVE_WINDOW_HOOK}" == "on"
+BuildRequires: pkgconfig(ecore)
+BuildRequires: pkgconfig(ecore-x)
+%endif
 
 %if "%{?BUILD_PROFILE}" == "mobile"
 BuildRequires: pkgconfig(capi-network-bluetooth)
@@ -23,6 +38,8 @@ BuildRequires: pkgconfig(tapi)
 BuildRequires: pkgconfig(msg-service)
 BuildRequires: pkgconfig(capi-messaging-email)
 BuildRequires: pkgconfig(motion)
+BuildRequires: pkgconfig(contacts-service2)
+BuildRequires: pkgconfig(capi-content-media-content)
 %endif
 
 %if "%{?BUILD_PROFILE}" == "wearable"
@@ -37,6 +54,7 @@ BuildRequires: pkgconfig(motion)
 %if "%{?BUILD_PROFILE}" == "tv"
 BuildRequires: pkgconfig(capi-network-bluetooth)
 BuildRequires: pkgconfig(capi-network-wifi)
+BuildRequires: pkgconfig(capi-content-media-content)
 %endif
 
 %description
@@ -62,7 +80,8 @@ export   CFLAGS+=" -DTIZEN_ENGINEER_MODE"
 export CXXFLAGS+=" -DTIZEN_ENGINEER_MODE"
 export   FFLAGS+=" -DTIZEN_ENGINEER_MODE"
 
-cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DMAJORVER=${MAJORVER} -DFULLVER=%{version} -DPROFILE=%{?BUILD_PROFILE}
+cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DMAJORVER=${MAJORVER} -DFULLVER=%{version} \
+               -DPROFILE=%{?BUILD_PROFILE} -DACTIVE_WINDOW_HOOK=%{ACTIVE_WINDOW_HOOK}
 make %{?jobs:-j%jobs}
 
 %install
index a5a98d742d3137f9586868f7be793a11ca8563e6..06f3799df4b305cd5e34f8749873ef93a468dc06 100644 (file)
@@ -1,10 +1,16 @@
 CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
 
 ADD_SUBDIRECTORY(device)
-GET_DIRECTORY_PROPERTY(target DIRECTORY device DEFINITION target)
-GET_DIRECTORY_PROPERTY(deps DIRECTORY device DEFINITION deps)
-SET(target_all "${target_all} -l${target}")
-SET(deps_list "${deps_list} ${deps}")
+GET_DIRECTORY_PROPERTY(target_sub DIRECTORY device DEFINITION target)
+GET_DIRECTORY_PROPERTY(deps_sub DIRECTORY device DEFINITION deps)
+SET(target_all "${target_all} -l${target_sub}")
+SET(deps_list "${deps_list} ${deps_sub}")
+
+ADD_SUBDIRECTORY(statistics)
+GET_DIRECTORY_PROPERTY(target_sub DIRECTORY statistics DEFINITION target)
+GET_DIRECTORY_PROPERTY(deps_sub DIRECTORY statistics DEFINITION deps)
+SET(target_all "${target_all} -l${target_sub}")
+SET(deps_list "${deps_list} ${deps_sub}")
 
 SEPARATE_ARGUMENTS(deps_list)
 LIST(REMOVE_DUPLICATES deps_list)
diff --git a/src/statistics/CMakeLists.txt b/src/statistics/CMakeLists.txt
new file mode 100644 (file)
index 0000000..d0ee7d6
--- /dev/null
@@ -0,0 +1,62 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+SET(target "ctx-statistics")
+
+# Common Options
+INCLUDE_DIRECTORIES(
+       ${CMAKE_CURRENT_SOURCE_DIR}/shared
+)
+
+# Common Profile
+FILE(GLOB srcs ./*.cpp)
+FILE(GLOB srcs ${srcs} shared/*.cpp)
+FILE(GLOB srcs ${srcs} app/*.cpp)
+FILE(GLOB srcs ${srcs} prediction/*.cpp)
+
+SET(deps "capi-system-runtime-info pkgmgr pkgmgr-info capi-appfw-package-manager")
+SET(deps "${deps} capi-appfw-application capi-appfw-app-manager")
+SET(deps "${deps} capi-media-sound-manager")
+
+IF("${ACTIVE_WINDOW_HOOK}" STREQUAL "on")
+       ADD_DEFINITIONS("-D_USE_ACTIVE_WINDOW_HOOKING_")
+       SET(deps "${deps} ecore ecore-x")
+       SET(srcs ${srcs} app/app_use_monitor/active_window_monitor.cpp)
+ELSE("${ACTIVE_WINDOW_HOOK}" STREQUAL "on")
+       SET(srcs ${srcs} app/app_use_monitor/launch_monitor.cpp)
+ENDIF("${ACTIVE_WINDOW_HOOK}" STREQUAL "on")
+
+# Mobile Profile
+IF("${PROFILE}" STREQUAL "mobile")
+       FILE(GLOB srcs ${srcs} media/*.cpp)
+       FILE(GLOB srcs ${srcs} social/*.cpp)
+       SET(deps "${deps} contacts-service2 capi-content-media-content")
+ENDIF("${PROFILE}" STREQUAL "mobile")
+
+# Wearable Profile
+#IF("${PROFILE}" STREQUAL "wearable")
+#ENDIF("${PROFILE}" STREQUAL "wearable")
+
+# TV Profile
+IF("${PROFILE}" STREQUAL "tv")
+       FILE(GLOB srcs ${srcs} media/*.cpp)
+       SET(deps "${deps} capi-content-media-content")
+ENDIF("${PROFILE}" STREQUAL "tv")
+
+MESSAGE("Statistics Provider Sources: ${srcs}")
+
+# Build
+INCLUDE(FindPkgConfig)
+PKG_CHECK_MODULES(stats_pkgs REQUIRED ${deps_common} ${deps})
+
+FOREACH(flag ${stats_pkgs_CFLAGS})
+       SET(extra_cflags "${extra_cflags} ${flag}")
+ENDFOREACH(flag)
+
+ADD_LIBRARY(${target} SHARED ${srcs})
+TARGET_LINK_LIBRARIES(${target} ${stats_pkgs_LDFLAGS})
+SET_TARGET_PROPERTIES(${target} PROPERTIES COMPILE_FLAGS ${extra_cflags})
+SET_TARGET_PROPERTIES(${target} PROPERTIES COMPILE_DEFINITIONS "LOG_TAG=\"CONTEXT-STATS\"")
+SET_TARGET_PROPERTIES(${target} PROPERTIES SOVERSION ${MAJORVER})
+SET_TARGET_PROPERTIES(${target} PROPERTIES VERSION ${FULLVER})
+
+# Install
+INSTALL(TARGETS ${target} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT RuntimeLibraries)
diff --git a/src/statistics/app/app_stats_provider.cpp b/src/statistics/app/app_stats_provider.cpp
new file mode 100644 (file)
index 0000000..59a224b
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * 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 <context_mgr.h>
+#include "app_stats_provider.h"
+#include "db_handle.h"
+
+#include "db_init.h"
+#include "install_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_use_monitor *launch_mon = NULL;
+
+ctx::app_statistics_provider *ctx::app_statistics_provider::__instance = NULL;
+
+ctx::app_statistics_provider::app_statistics_provider()
+{
+}
+
+ctx::app_statistics_provider::~app_statistics_provider()
+{
+       delete install_mon;
+       delete launch_mon;
+       install_mon = NULL;
+       launch_mon = NULL;
+}
+
+ctx::context_provider_iface *ctx::app_statistics_provider::create(void *data)
+{
+       IF_FAIL_RETURN(!__instance, __instance);
+
+       __instance = new(std::nothrow) app_statistics_provider();
+       IF_FAIL_RETURN_TAG(__instance, NULL, _E, "Memory allocation failed");
+
+       _I(BLUE("Created"));
+
+       if (!__instance->init()) {
+               destroy(data);
+               return NULL;
+       }
+
+       return __instance;
+}
+
+void ctx::app_statistics_provider::destroy(void *data)
+{
+       IF_FAIL_VOID(__instance);
+       delete __instance;
+       __instance = NULL;
+       _I(BLUE("Destroyed"));
+}
+
+bool ctx::app_statistics_provider::is_supported(const char* subject)
+{
+       return true;
+}
+
+void ctx::app_statistics_provider::submit_trigger_item()
+{
+       context_manager::register_trigger_item(APP_SUBJ_FREQUENCY, OPS_READ,
+                       "{" TRIG_DEF_RANK "," TRIG_DEF_TOTAL_COUNT "}",
+                       "{"
+                               "\"AppId\":{\"type\":\"string\"},"
+                               TRIG_DEF_TIME_OF_DAY "," TRIG_DEF_DAY_OF_WEEK
+                       "}");
+}
+
+bool ctx::app_statistics_provider::init()
+{
+       app_db_initializer *initializer = new(std::nothrow) app_db_initializer();
+       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_use_monitor();
+       IF_FAIL_CATCH_TAG(install_mon && launch_mon, _E, "Memory allocation failed");
+       return true;
+
+CATCH:
+       delete install_mon;
+       delete launch_mon;
+       install_mon = NULL;
+       launch_mon = NULL;
+       return false;
+}
+
+int ctx::app_statistics_provider::subscribe(const char* subject, ctx::json option, ctx::json* request_result)
+{
+       return ERR_NOT_SUPPORTED;
+}
+
+int ctx::app_statistics_provider::unsubscribe(const char* subject, ctx::json option)
+{
+       return ERR_NOT_SUPPORTED;
+}
+
+int ctx::app_statistics_provider::read(const char* subject, ctx::json option, ctx::json* request_result)
+{
+       ctx::app_db_handle *handle = new(std::nothrow) ctx::app_db_handle();
+       IF_FAIL_RETURN_TAG(handle, ERR_OPERATION_FAILED, _E, "Memory allocation failed");
+
+       int err = handle->read(subject, option);
+       if (err != ERR_NONE) {
+               delete handle;
+               return err;
+       }
+
+       return ERR_NONE;
+}
+
+int ctx::app_statistics_provider::write(const char* subject, ctx::json data, ctx::json* request_result)
+{
+       return ERR_NOT_SUPPORTED;
+}
diff --git a/src/statistics/app/app_stats_provider.h b/src/statistics/app/app_stats_provider.h
new file mode 100644 (file)
index 0000000..f5804bd
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * 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_STATS_PROVIDER_H__
+#define __CONTEXT_APP_STATS_PROVIDER_H__
+
+#include <provider_iface.h>
+#include "app_stats_types.h"
+
+namespace ctx {
+
+       class app_statistics_provider : public context_provider_iface {
+       public:
+               static context_provider_iface *create(void *data);
+               static void destroy(void *data);
+               static bool is_supported(const char *subject);
+               static void submit_trigger_item();
+
+               int subscribe(const char *subject, ctx::json option, ctx::json *request_result);
+               int unsubscribe(const char *subject, ctx::json option);
+               int read(const char *subject, ctx::json option, ctx::json *request_result);
+               int write(const char *subject, ctx::json data, ctx::json *request_result);
+
+       private:
+               static app_statistics_provider *__instance;
+
+               app_statistics_provider();
+               ~app_statistics_provider();
+               bool init();
+
+       };      /* class app_statistics_provider */
+
+}      /* namespace ctx */
+
+#endif /* __CONTEXT_APP_STATS_PROVIDER_H__ */
diff --git a/src/statistics/app/app_stats_types.h b/src/statistics/app/app_stats_types.h
new file mode 100644 (file)
index 0000000..96ed505
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * 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_STATS_TYPES_H__
+#define __CONTEXT_APP_STATS_TYPES_H__
+
+#include <common_types.h>
+
+#define APP_HISTORY_PRIV                       "apphistory.read"
+#define APP_SUBJ_RECENTLY_USED         "stats/app/recently"
+#define APP_SUBJ_FREQUENTLY_USED       "stats/app/often"
+#define APP_SUBJ_RARELY_USED           "stats/app/rarely"
+#define APP_SUBJ_PEAK_TIME                     "stats/app/peak_time"
+#define APP_SUBJ_COMMON_SETTING                "stats/app/setting"
+#define APP_SUBJ_FREQUENCY                     "stats/app/frequency"
+
+#define APP_TABLE_REMOVABLE_APP        "Log_RemovableApp"
+#define APP_TABLE_REMOVABLE_APP_COLUMNS \
+       "AppId TEXT NOT NULL UNIQUE"
+
+#define APP_TABLE_USAGE_LOG            "Log_AppLaunch"
+#define APP_TABLE_USAGE_LOG_COLUMNS \
+       "AppId TEXT NOT NULL, Duration INTEGER NOT NULL DEFAULT 0, " \
+       "SystemVolume INTEGER, MediaVolume INTEGER, AudioJack INTEGER, " \
+       "BSSID TEXT, " \
+       "UTC TIMESTAMP DEFAULT (strftime('%s', 'now')), " \
+       "LocalTime TIMESTAMP DEFAULT (strftime('%s', 'now', 'localtime'))"
+
+#define APP_TEMP_USAGE_FREQ            "Temp_AppLaunchFreq"
+#define APP_TEMP_USAGE_FREQ_SQL \
+       "CREATE TABLE IF NOT EXISTS " APP_TEMP_USAGE_FREQ \
+       " (AppId TEXT NOT NULL UNIQUE, TotalCount INTEGER DEFAULT 0);"
+
+#endif
diff --git a/src/statistics/app/app_use_monitor/active_window_monitor.cpp b/src/statistics/app/app_use_monitor/active_window_monitor.cpp
new file mode 100644 (file)
index 0000000..1aca2c7
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ * 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 <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
+
+#define ONE_DAY_IN_SEC 86400
+
+static Ecore_Event_Handler *window_property_event_handler = NULL;
+
+ctx::app_use_monitor::app_use_monitor()
+       : last_cleanup_time(0)
+       , 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;
+       append_cleanup_query(query);
+       query << "INSERT INTO " << APP_TABLE_USAGE_LOG << " ("
+               << cols.str() << ") VALUES (" << vals.str() << ")";
+
+       db_manager::execute(0, query.str().c_str(), NULL);
+}
+
+void ctx::app_use_monitor::append_cleanup_query(std::stringstream &query)
+{
+       IF_FAIL_VOID(last_timestamp - last_cleanup_time >= ONE_DAY_IN_SEC);
+
+       last_cleanup_time = last_timestamp;
+
+       query << "DELETE FROM " APP_TABLE_USAGE_LOG " WHERE " \
+               STATS_UNIV_TIME " < strftime('%s', 'now') - " << LOG_RETENTION_PERIOD << ";";
+}
diff --git a/src/statistics/app/app_use_monitor/active_window_monitor.h b/src/statistics/app/app_use_monitor/active_window_monitor.h
new file mode 100644 (file)
index 0000000..443d2bc
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 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 <sstream>
+#include <Ecore.h>
+
+namespace ctx {
+
+       class app_use_monitor {
+       private:
+               int last_cleanup_time;
+               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 append_cleanup_query(std::stringstream &query);
+
+               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__ */
diff --git a/src/statistics/app/app_use_monitor/launch_monitor.cpp b/src/statistics/app/app_use_monitor/launch_monitor.cpp
new file mode 100644 (file)
index 0000000..4421063
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * 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 <db_mgr.h>
+#include <json.h>
+#include <types_internal.h>
+
+#include <system_info.h>
+#include "../app_stats_types.h"
+#include "launch_monitor.h"
+
+ctx::app_use_monitor::app_use_monitor()
+{
+       start_logging();
+}
+
+ctx::app_use_monitor::~app_use_monitor()
+{
+       stop_logging();
+}
+
+bool ctx::app_use_monitor::start_logging()
+{
+       int err = app_manager_set_app_context_event_cb(app_context_event_cb, this);
+       IF_FAIL_RETURN_TAG(err == APP_MANAGER_ERROR_NONE, false, _E, "app_manager_set_app_context_event_cb() failed");
+       return true;
+}
+
+void ctx::app_use_monitor::stop_logging()
+{
+       app_manager_unset_app_context_event_cb();
+}
+
+void ctx::app_use_monitor::app_context_event_cb(app_context_h app_context, app_context_event_e event, void *user_data)
+{
+       char *app_id = NULL;
+       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_use_monitor *monitor = static_cast<app_use_monitor*>(user_data);
+
+       if (event == APP_CONTEXT_EVENT_LAUNCHED) {
+               monitor->log_launch_event(app_id);
+       } else if (event == APP_CONTEXT_EVENT_TERMINATED) {
+               monitor->log_terminate_event(app_id);
+       }
+       g_free(app_id);
+}
+
+void ctx::app_use_monitor::log_launch_event(const char* app_id)
+{
+       int audiojack;
+       int system_volume;
+       int media_volume;
+       std::string bssid;
+       json data;
+       data.set(NULL, STATS_APP_ID, app_id);
+
+       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);
+       }
+
+       if (ctx::system_info::get_wifi_bssid(bssid))
+               data.set(NULL, STATS_BSSID, bssid);
+
+       db_manager::insert(0, APP_TABLE_USAGE_LOG, data, NULL);
+}
+
+void ctx::app_use_monitor::log_terminate_event(const char* app_id)
+{
+       std::stringstream query;
+       query <<
+               "UPDATE " APP_TABLE_USAGE_LOG \
+               " SET " STATS_DURATION " = strftime('%s', 'now') - " STATS_UNIV_TIME \
+               " WHERE " STATS_COL_ROW_ID " = (" \
+                       "SELECT MAX(" STATS_COL_ROW_ID ") FROM " APP_TABLE_USAGE_LOG \
+                       " WHERE " STATS_APP_ID " = '" << app_id << "'" \
+                       " AND " STATS_DURATION " = 0)";
+       db_manager::execute(0, query.str().c_str(), NULL);
+}
diff --git a/src/statistics/app/app_use_monitor/launch_monitor.h b/src/statistics/app/app_use_monitor/launch_monitor.h
new file mode 100644 (file)
index 0000000..43b3f66
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * 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 <app_manager.h>
+#include <db_listener_iface.h>
+
+namespace ctx {
+
+       class app_use_monitor : public db_listener_iface {
+       private:
+               bool start_logging(void);
+               void stop_logging(void);
+
+               void log_launch_event(const char* app_id);
+               void log_terminate_event(const char* app_id);
+
+               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 app_context_event_cb(app_context_h app_context, app_context_event_e event, void *user_data);
+
+       public:
+               app_use_monitor();
+               ~app_use_monitor();
+       };      /* class app_use_monitor */
+
+}      /* namespace ctx */
+
+#endif /* __CONTEXT_APP_USE_MONITOR_H__ */
diff --git a/src/statistics/app/db_handle.cpp b/src/statistics/app/db_handle.cpp
new file mode 100644 (file)
index 0000000..5491d24
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * 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 <context_mgr.h>
+#include <db_mgr.h>
+#include "app_stats_types.h"
+#include "db_handle.h"
+
+ctx::app_db_handle::app_db_handle()
+{
+}
+
+ctx::app_db_handle::~app_db_handle()
+{
+}
+
+int ctx::app_db_handle::read(const char* subject, ctx::json filter)
+{
+       std::string query;
+
+       if (STR_EQ(subject, APP_SUBJ_RECENTLY_USED)) {
+               query = create_sql_recently_used(filter);
+
+       } else if (STR_EQ(subject, APP_SUBJ_FREQUENTLY_USED)) {
+               query = create_sql_frequently_used(filter);
+
+       } else if (STR_EQ(subject, APP_SUBJ_RARELY_USED)) {
+               query = create_sql_rarely_used(filter);
+
+       } else if (STR_EQ(subject, APP_SUBJ_PEAK_TIME)) {
+               query = create_sql_peak_time(filter);
+
+       } else if (STR_EQ(subject, APP_SUBJ_COMMON_SETTING)) {
+               query = create_sql_common_setting(filter);
+
+       } else if (STR_EQ(subject, APP_SUBJ_FREQUENCY)) {
+               is_trigger_item = true;
+               query = create_sql_frequency(filter);
+       }
+
+       IF_FAIL_RETURN(!query.empty(), ERR_OPERATION_FAILED);
+
+       bool ret = execute_query(subject, filter, query.c_str());
+       IF_FAIL_RETURN(ret, ERR_OPERATION_FAILED);
+
+       return ERR_NONE;
+}
+
+std::string ctx::app_db_handle::create_where_clause_with_device_status(ctx::json filter)
+{
+       std::stringstream where_clause;
+       std::string bssid;
+       int audio_jack;
+
+       where_clause << stats_db_handle_base::create_where_clause(filter);
+
+       if (filter.get(NULL, STATS_BSSID, &bssid))
+               where_clause << " AND " STATS_BSSID " = '" << bssid << "'";
+
+       if (filter.get(NULL, STATS_AUDIO_JACK, &audio_jack))
+               where_clause << " AND " STATS_AUDIO_JACK " = " << audio_jack;
+
+       return where_clause.str();
+}
+
+std::string ctx::app_db_handle::create_sql_peak_time(ctx::json filter)
+{
+       return stats_db_handle_base::create_sql_peak_time(filter, APP_TABLE_USAGE_LOG, create_where_clause(filter));
+}
+
+std::string ctx::app_db_handle::create_sql_common_setting(ctx::json filter)
+{
+       return stats_db_handle_base::create_sql_common_setting(filter, APP_TABLE_USAGE_LOG, create_where_clause(filter));
+}
+
+std::string ctx::app_db_handle::create_sql_frequency(ctx::json filter)
+{
+       ctx::json filter_cleaned;
+       std::string week_str;
+       std::string time_of_day;
+       std::string app_id;
+
+       if (!filter.get(NULL, STATS_APP_ID, &app_id)) {
+               _E("Invalid parameter");
+               return "";
+       }
+
+       if (filter.get(NULL, STATS_DAY_OF_WEEK, &week_str))
+               filter_cleaned.set(NULL, STATS_DAY_OF_WEEK, week_str);
+
+       if (filter.get(NULL, STATS_TIME_OF_DAY, &time_of_day))
+               filter_cleaned.set(NULL, STATS_TIME_OF_DAY, time_of_day);
+
+       std::string where_clause = create_where_clause(filter_cleaned);
+
+       std::stringstream query;
+
+       query <<
+               "DELETE FROM " APP_TEMP_USAGE_FREQ ";";
+
+       query <<
+               "INSERT INTO " APP_TEMP_USAGE_FREQ \
+               " SELECT " STATS_APP_ID ", COUNT(*) AS " STATS_TOTAL_COUNT \
+               " FROM " APP_TABLE_USAGE_LOG \
+               " WHERE " << where_clause <<
+               " GROUP BY " STATS_APP_ID ";";
+
+       query <<
+               "INSERT OR IGNORE INTO " APP_TEMP_USAGE_FREQ " (" STATS_APP_ID ")" \
+               " VALUES ('" << app_id << "');";
+
+       query <<
+               "SELECT S." STATS_APP_ID ", S." STATS_TOTAL_COUNT ", 1+COUNT(lesser." STATS_TOTAL_COUNT ") AS " STATS_RANK \
+               " FROM " APP_TEMP_USAGE_FREQ " AS S" \
+               " LEFT JOIN " APP_TEMP_USAGE_FREQ " AS lesser" \
+               " ON S." STATS_TOTAL_COUNT " < lesser." STATS_TOTAL_COUNT \
+               " WHERE S." STATS_APP_ID " = '" << app_id << "'";
+
+       return query.str();
+}
+
+std::string ctx::app_db_handle::create_sql_recently_used(ctx::json filter)
+{
+       std::stringstream query;
+       int limit = DEFAULT_LIMIT;
+
+       filter.get(NULL, STATS_RESULT_SIZE, &limit);
+
+       query <<
+               "SELECT " STATS_APP_ID ", " \
+                       "COUNT(*) AS " STATS_TOTAL_COUNT ", " \
+                       "SUM(" STATS_DURATION ") AS " STATS_TOTAL_DURATION ", " \
+                       "MAX(" STATS_UNIV_TIME ") AS " STATS_LAST_TIME \
+               " FROM " APP_TABLE_USAGE_LOG \
+               " WHERE " << create_where_clause_with_device_status(filter) <<
+               " GROUP BY " STATS_APP_ID \
+               " ORDER BY MAX(" STATS_UNIV_TIME ") DESC" \
+               " LIMIT " << limit;
+
+       return query.str();
+}
+
+std::string ctx::app_db_handle::create_sql_frequently_used(ctx::json filter)
+{
+       std::stringstream query;
+       int limit = DEFAULT_LIMIT;
+
+       filter.get(NULL, STATS_RESULT_SIZE, &limit);
+
+       query <<
+               "SELECT " STATS_APP_ID ", " \
+                       "COUNT(*) AS " STATS_TOTAL_COUNT ", " \
+                       "SUM(" STATS_DURATION ") AS " STATS_TOTAL_DURATION ", " \
+                       "MAX(" STATS_UNIV_TIME ") AS " STATS_LAST_TIME \
+               " FROM " APP_TABLE_USAGE_LOG \
+               " WHERE " << create_where_clause_with_device_status(filter) <<
+               " GROUP BY " STATS_APP_ID \
+               " ORDER BY COUNT(*) DESC" \
+               " LIMIT " << limit;
+
+       return query.str();
+}
+
+std::string ctx::app_db_handle::create_sql_rarely_used(ctx::json filter)
+{
+       std::stringstream query;
+       int limit = DEFAULT_LIMIT;
+
+       filter.get(NULL, STATS_RESULT_SIZE, &limit);
+
+       query <<
+               "SELECT i." STATS_APP_ID ", " \
+                       "COUNT(u." STATS_DURATION ") AS " STATS_TOTAL_COUNT ", " \
+                       "IFNULL(SUM(u." STATS_DURATION "),0) AS " STATS_TOTAL_DURATION ", " \
+                       "IFNULL(MAX(u." STATS_UNIV_TIME "),-1) AS " STATS_LAST_TIME \
+               " FROM " APP_TABLE_REMOVABLE_APP " i LEFT OUTER JOIN (" \
+                       " SELECT * FROM " APP_TABLE_USAGE_LOG \
+                       " WHERE " << create_where_clause_with_device_status(filter) << ") u" \
+                       " ON i." STATS_APP_ID " = u." STATS_APP_ID \
+               " GROUP BY i." STATS_APP_ID \
+               " ORDER BY " STATS_TOTAL_COUNT " ASC" \
+               " LIMIT " << limit;
+
+       return query.str();
+}
+
+void ctx::app_db_handle::reply_trigger_item(int error, ctx::json &json_result)
+{
+       IF_FAIL_VOID_TAG(STR_EQ(req_subject.c_str(), APP_SUBJ_FREQUENCY), _E, "Invalid subject");
+
+       ctx::json results;
+       std::string val_str;
+       int val;
+
+       json_result.get(NULL, STATS_APP_ID, &val_str);
+       results.set(NULL, STATS_APP_ID, val_str);
+       json_result.get(NULL, STATS_TOTAL_COUNT, &val);
+       results.set(NULL, STATS_TOTAL_COUNT, val);
+       json_result.get(NULL, STATS_RANK, &val);
+       results.set(NULL, STATS_RANK, val);
+
+       context_manager::reply_to_read(req_subject.c_str(), req_filter, error, results);
+}
diff --git a/src/statistics/app/db_handle.h b/src/statistics/app/db_handle.h
new file mode 100644 (file)
index 0000000..8cb2659
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * 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_DB_HANDLE_H__
+#define __CONTEXT_APP_DB_HANDLE_H__
+
+#include <string>
+#include <json.h>
+#include <db_handle_base.h>
+
+namespace ctx {
+       class app_db_handle : public stats_db_handle_base {
+               public:
+                       app_db_handle();
+                       ~app_db_handle();
+
+                       int read(const char* subject, ctx::json filter);
+
+               private:
+                       std::string create_where_clause_with_device_status(ctx::json filter);
+                       std::string create_sql_recently_used(ctx::json filter);
+                       std::string create_sql_frequently_used(ctx::json filter);
+                       std::string create_sql_rarely_used(ctx::json filter);
+                       std::string create_sql_peak_time(ctx::json filter);
+                       std::string create_sql_common_setting(ctx::json filter);
+                       std::string create_sql_frequency(ctx::json filter);
+                       void reply_trigger_item(int error, ctx::json &json_result);
+       };
+}
+
+#endif /* __CONTEXT_APP_DB_HANDLE_H__ */
diff --git a/src/statistics/app/db_init.cpp b/src/statistics/app/db_init.cpp
new file mode 100644 (file)
index 0000000..a5a7af9
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * 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 <json.h>
+#include <types_internal.h>
+#include <db_mgr.h>
+#include "app_stats_types.h"
+#include "db_init.h"
+
+#define EMPTY_CHECKER_QID 999
+
+ctx::app_db_initializer::app_db_initializer()
+{
+       create_table();
+       check_app_list();
+}
+
+ctx::app_db_initializer::~app_db_initializer()
+{
+}
+
+void ctx::app_db_initializer::create_table()
+{
+       static bool done = false;
+       IF_FAIL_VOID(!done);
+
+       db_manager::create_table(0, APP_TABLE_USAGE_LOG, APP_TABLE_USAGE_LOG_COLUMNS, NULL, NULL);
+       db_manager::create_table(0, APP_TABLE_REMOVABLE_APP, APP_TABLE_REMOVABLE_APP_COLUMNS, NULL, NULL);
+       db_manager::execute(0, APP_TEMP_USAGE_FREQ_SQL, NULL);
+
+       done = true;
+}
+
+void ctx::app_db_initializer::check_app_list()
+{
+       db_manager::execute(EMPTY_CHECKER_QID, "SELECT * FROM " APP_TABLE_REMOVABLE_APP " LIMIT 1", this);
+}
+
+void ctx::app_db_initializer::duplicate_app_list()
+{
+       int err;
+       package_manager_filter_h filter;
+
+       err = package_manager_filter_create(&filter);
+       IF_FAIL_VOID_TAG(err == PACKAGE_MANAGER_ERROR_NONE, _E, "package_manager_filter_create() failed");
+
+       err = package_manager_filter_add_bool(filter, PACKAGE_MANAGER_PKGINFO_PROP_REMOVABLE, true);
+       IF_FAIL_CATCH_TAG(err == PACKAGE_MANAGER_ERROR_NONE, _E, "package_manager_filter_add_bool() failed");
+
+       err = package_manager_filter_foreach_package_info(filter, package_info_cb, this);
+       IF_FAIL_CATCH_TAG(err == PACKAGE_MANAGER_ERROR_NONE, _E, "package_manager_filter_foreach_package_info() failed");
+
+CATCH:
+       if (filter)
+               package_manager_filter_destroy(filter);
+}
+
+bool ctx::app_db_initializer::package_info_cb(package_info_h package_info, void *user_data)
+{
+       int err = package_info_foreach_app_from_package(package_info, PACKAGE_INFO_UIAPP, app_info_cb, user_data);
+       IF_FAIL_RETURN_TAG(err == PACKAGE_MANAGER_ERROR_NONE, false, _E, "package_info_foreach_app_from_package() failed");
+       return true;
+}
+
+bool ctx::app_db_initializer::app_info_cb(package_info_app_component_type_e comp_type, const char *app_id, void *user_data)
+{
+       json data;
+       data.set(NULL, STATS_APP_ID, app_id);
+       return db_manager::insert(0, APP_TABLE_REMOVABLE_APP, data, NULL);
+}
+
+void ctx::app_db_initializer::on_creation_result_received(unsigned int query_id, int error)
+{
+}
+
+void ctx::app_db_initializer::on_insertion_result_received(unsigned int query_id, int error, int64_t row_id)
+{
+}
+
+void ctx::app_db_initializer::on_query_result_received(unsigned int query_id, int error, std::vector<json>& records)
+{
+       if (query_id != EMPTY_CHECKER_QID) {
+               _E("Unknown Query ID: %d", query_id);
+               delete this;
+               return;
+       }
+
+       if (records.empty())
+               duplicate_app_list();
+
+       delete this;
+}
diff --git a/src/statistics/app/db_init.h b/src/statistics/app/db_init.h
new file mode 100644 (file)
index 0000000..b042675
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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_DB_INITIALIZER_H__
+#define __CONTEXT_APP_DB_INITIALIZER_H__
+
+#include <package_manager.h>
+#include <db_listener_iface.h>
+
+namespace ctx {
+
+       class app_db_initializer : public db_listener_iface {
+               private:
+                       void create_table();
+                       void check_app_list();
+                       void duplicate_app_list();
+
+                       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 bool package_info_cb(package_info_h package_info, void *user_data);
+                       static bool app_info_cb(package_info_app_component_type_e comp_type, const char *app_id, void *user_data);
+
+               public:
+                       app_db_initializer();
+                       ~app_db_initializer();
+       };
+
+}      /* namespace ctx */
+
+#endif
diff --git a/src/statistics/app/install_monitor.cpp b/src/statistics/app/install_monitor.cpp
new file mode 100644 (file)
index 0000000..7cec212
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * 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 <glib.h>
+#include <json.h>
+#include <types_internal.h>
+#include <db_mgr.h>
+#include "app_stats_types.h"
+#include "install_monitor.h"
+
+static package_manager_event_type_e last_event_type;
+
+ctx::app_install_monitor::app_install_monitor()
+       : pkgmgr_h(NULL)
+{
+       start_monitoring();
+}
+
+ctx::app_install_monitor::~app_install_monitor()
+{
+       stop_monitoring();
+}
+
+bool ctx::app_install_monitor::start_monitoring()
+{
+       int err = package_manager_create(&pkgmgr_h);
+       IF_FAIL_RETURN_TAG(err == PACKAGE_MANAGER_ERROR_NONE, false, _E, "package_manager_create() failed");
+
+       err = package_manager_set_event_cb(pkgmgr_h, package_event_cb, this);
+       IF_FAIL_RETURN_TAG(err == PACKAGE_MANAGER_ERROR_NONE, false, _E, "package_manager_set_event_cb() failed");
+
+       return true;
+}
+
+void ctx::app_install_monitor::stop_monitoring()
+{
+       if(pkgmgr_h) {
+               package_manager_unset_event_cb(pkgmgr_h);
+               package_manager_destroy(pkgmgr_h);
+               pkgmgr_h = NULL;
+       }
+}
+
+void ctx::app_install_monitor::package_event_cb(const char *type, const char *package, package_manager_event_type_e event_type, package_manager_event_state_e event_state, int progress, package_manager_error_e error, void *user_data)
+{
+       IF_FAIL_VOID_TAG(error == PACKAGE_MANAGER_ERROR_NONE, _E, "package_manager error: %d", error);
+
+       if (!(event_type == PACKAGE_MANAGER_EVENT_TYPE_INSTALL && event_state == PACKAGE_MANAGER_EVENT_STATE_COMPLETED) &&
+               !(event_type == PACKAGE_MANAGER_EVENT_TYPE_UNINSTALL && event_state == PACKAGE_MANAGER_EVENT_STATE_STARTED)) {
+               _D("Skipping event type-%d / state-%d", event_type, event_state);
+               return;
+       }
+
+       package_info_h pkg_info;
+       int err = package_manager_get_package_info(package, &pkg_info);
+       IF_FAIL_VOID_TAG(err == PACKAGE_MANAGER_ERROR_NONE, _E, "package_manager_get_package_info() failed");
+
+       last_event_type = event_type;
+
+       err = package_info_foreach_app_from_package(pkg_info, PACKAGE_INFO_UIAPP, app_info_cb, user_data);
+       if (err != PACKAGE_MANAGER_ERROR_NONE)
+               _E("package_info_foreach_app_from_package() failed");
+
+       package_info_destroy(pkg_info);
+}
+
+bool ctx::app_install_monitor::app_info_cb(package_info_app_component_type_e comp_type, const char *app_id, void *user_data)
+{
+       if (last_event_type == PACKAGE_MANAGER_EVENT_TYPE_INSTALL) {
+               json data;
+               data.set(NULL, STATS_APP_ID, app_id);
+               db_manager::insert(0, APP_TABLE_REMOVABLE_APP, data, NULL);
+       } else if (last_event_type == PACKAGE_MANAGER_EVENT_TYPE_UNINSTALL) {
+               db_manager::execute(0, create_deletion_query(APP_TABLE_REMOVABLE_APP, app_id).c_str(), NULL);
+               db_manager::execute(0, create_deletion_query(APP_TABLE_USAGE_LOG, app_id).c_str(), NULL);
+       }
+
+       return true;
+}
+
+std::string ctx::app_install_monitor::create_deletion_query(const char* table_name, const char* app_id)
+{
+       std::stringstream query;
+       query << "DELETE FROM " << table_name;
+       query << " WHERE " STATS_APP_ID " = '" << app_id << "'";
+       return query.str();
+}
diff --git a/src/statistics/app/install_monitor.h b/src/statistics/app/install_monitor.h
new file mode 100644 (file)
index 0000000..0bfee65
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * 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_INSTALL_MONITOR_H__
+#define __CONTEXT_APP_INSTALL_MONITOR_H__
+
+#include <package_manager.h>
+#include <db_listener_iface.h>
+
+namespace ctx {
+
+       class app_install_monitor : public db_listener_iface {
+       private:
+               package_manager_h pkgmgr_h;
+
+               bool start_monitoring();
+               void stop_monitoring();
+
+               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 std::string create_deletion_query(const char* table_name, const char* app_id);
+               static void package_event_cb(const char *type, const char *package, package_manager_event_type_e event_type, package_manager_event_state_e event_state, int progress, package_manager_error_e error, void *user_data);
+               static bool app_info_cb(package_info_app_component_type_e comp_type, const char *app_id, void *user_data);
+
+       public:
+               app_install_monitor();
+               ~app_install_monitor();
+       };
+
+}      /* namespace ctx */
+
+#endif
diff --git a/src/statistics/media/db_handle.cpp b/src/statistics/media/db_handle.cpp
new file mode 100644 (file)
index 0000000..50d0dec
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * 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 <context_mgr.h>
+#include <db_mgr.h>
+#include <system_info.h>
+#include "media_stats_types.h"
+#include "db_handle.h"
+
+ctx::media_db_handle::media_db_handle()
+{
+}
+
+ctx::media_db_handle::~media_db_handle()
+{
+}
+
+int ctx::media_db_handle::read(const char* subject, ctx::json filter)
+{
+       //TODO: filter validation (in the API side?)
+       std::string query;
+
+       if (STR_EQ(subject, MEDIA_SUBJ_PEAK_TIME_FOR_MUSIC)) {
+               query = create_sql_peak_time(MEDIA_TYPE_MUSIC, filter);
+
+       } else if (STR_EQ(subject, MEDIA_SUBJ_PEAK_TIME_FOR_VIDEO)) {
+               query = create_sql_peak_time(MEDIA_TYPE_VIDEO, filter);
+
+       } else if (STR_EQ(subject, MEDIA_SUBJ_COMMON_SETTING_FOR_MUSIC)) {
+               query = create_sql_common_setting(MEDIA_TYPE_MUSIC, filter);
+
+       } else if (STR_EQ(subject, MEDIA_SUBJ_COMMON_SETTING_FOR_VIDEO)) {
+               query = create_sql_common_setting(MEDIA_TYPE_VIDEO, filter);
+
+       } else if (STR_EQ(subject, MEDIA_SUBJ_MUSIC_FREQUENCY)) {
+               is_trigger_item = true;
+               query = create_sql_frequency(MEDIA_TYPE_MUSIC, filter);
+
+       } else if (STR_EQ(subject, MEDIA_SUBJ_VIDEO_FREQUENCY)) {
+               is_trigger_item = true;
+               query = create_sql_frequency(MEDIA_TYPE_VIDEO, filter);
+       }
+
+       IF_FAIL_RETURN(!query.empty(), ERR_OPERATION_FAILED);
+
+       bool ret = execute_query(subject, filter, query.c_str());
+       IF_FAIL_RETURN(ret, 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 << CX_MEDIA_TYPE " = " << media_type << " AND ";
+       where_clause << stats_db_handle_base::create_where_clause(filter);
+
+       return where_clause.str();
+}
+
+std::string ctx::media_db_handle::create_sql_peak_time(int media_type, ctx::json filter)
+{
+       std::string where = create_where_clause(media_type, filter);
+       return stats_db_handle_base::create_sql_peak_time(filter, MEDIA_TABLE_NAME, where);
+}
+
+std::string ctx::media_db_handle::create_sql_common_setting(int media_type, ctx::json filter)
+{
+       std::string where = create_where_clause(media_type, filter);
+       return stats_db_handle_base::create_sql_common_setting(filter, MEDIA_TABLE_NAME, where);
+}
+
+std::string ctx::media_db_handle::create_sql_frequency(int media_type, ctx::json filter)
+{
+       ctx::json filter_cleaned;
+       std::string week_str;
+       std::string time_of_day;
+
+       if (filter.get(NULL, STATS_DAY_OF_WEEK, &week_str))
+               filter_cleaned.set(NULL, STATS_DAY_OF_WEEK, week_str);
+
+       if (filter.get(NULL, STATS_TIME_OF_DAY, &time_of_day))
+               filter_cleaned.set(NULL, STATS_TIME_OF_DAY, time_of_day);
+
+       std::string where_clause = create_where_clause(media_type, filter_cleaned);
+
+       std::stringstream query;
+       query <<
+               "SELECT IFNULL(COUNT(*),0) AS " STATS_TOTAL_COUNT \
+               " FROM " MEDIA_TABLE_NAME \
+               " WHERE " << where_clause;
+
+       return query.str();
+}
+
+void ctx::media_db_handle::reply_trigger_item(int error, ctx::json &json_result)
+{
+       IF_FAIL_VOID_TAG(STR_EQ(req_subject.c_str(), MEDIA_SUBJ_MUSIC_FREQUENCY) ||
+               STR_EQ(req_subject.c_str(), MEDIA_SUBJ_VIDEO_FREQUENCY), _E, "Invalid subject");
+
+       ctx::json results;
+       int val;
+
+       json_result.get(NULL, STATS_TOTAL_COUNT, &val);
+       results.set(NULL, STATS_TOTAL_COUNT, val);
+
+       context_manager::reply_to_read(req_subject.c_str(), req_filter, error, results);
+}
diff --git a/src/statistics/media/db_handle.h b/src/statistics/media/db_handle.h
new file mode 100644 (file)
index 0000000..a42c247
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * 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_DB_HANDLE_H__
+#define __CONTEXT_MEDIA_DB_HANDLE_H__
+
+#include <string>
+#include <json.h>
+#include <db_handle_base.h>
+
+namespace ctx {
+       class media_db_handle : public stats_db_handle_base {
+               public:
+                       media_db_handle();
+                       ~media_db_handle();
+
+                       int read(const char* subject, ctx::json filter);
+
+               private:
+                       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);
+                       std::string create_sql_frequency(int media_type, ctx::json filter);
+                       void reply_trigger_item(int error, ctx::json &json_result);
+       };
+}
+
+#endif /* __CONTEXT_MEDIA_DB_HANDLE_H__ */
diff --git a/src/statistics/media/media_content_monitor.cpp b/src/statistics/media/media_content_monitor.cpp
new file mode 100644 (file)
index 0000000..4fbeed7
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * 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 <time.h>
+#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"
+
+#define PLAYCOUNT_RETENTION_PERIOD 259200      /* 1 month in secs */
+#define ONE_DAY_IN_SEC 86400
+
+ctx::media_content_monitor::media_content_monitor()
+       : started(false)
+       , last_cleanup_time(0)
+{
+       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::append_cleanup_query(std::stringstream &query)
+{
+       int timestamp = static_cast<int>(time(NULL));
+       IF_FAIL_VOID(timestamp - last_cleanup_time >= ONE_DAY_IN_SEC);
+
+       last_cleanup_time = timestamp;
+
+       query <<
+               "DELETE FROM Log_MediaPlayCount WHERE UTC < strftime('%s', 'now') - " << PLAYCOUNT_RETENTION_PERIOD << ";" \
+               "DELETE FROM " MEDIA_TABLE_NAME " WHERE UTC < strftime('%s', 'now') - " << LOG_RETENTION_PERIOD << ";";
+}
+
+void ctx::media_content_monitor::update_play_count(const char *uuid, int type, int count)
+{
+       std::stringstream query;
+       query <<
+               /* Inserting the media record to the play count table, if not exist */
+               "INSERT OR IGNORE INTO Log_MediaPlayCount" \
+               " (UUID, MediaType) VALUES ('" << uuid << "'," << type <<");" \
+               /* Updating the play count and getting the diff from the previous count */
+               "UPDATE Log_MediaPlayCount SET Diff = " << count << " - Count," \
+               " Count = " << count << ", UTC = strftime('%s', 'now')" \
+               " WHERE UUID = '" << uuid << "';";
+       append_cleanup_query(query);
+       query <<
+               /* Checking whether the play count changes */
+               "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);
+}
diff --git a/src/statistics/media/media_content_monitor.h b/src/statistics/media/media_content_monitor.h
new file mode 100644 (file)
index 0000000..d51d54c
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * 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 <sstream>
+#include <media_content.h>
+#include <db_listener_iface.h>
+
+namespace ctx {
+
+       class media_content_monitor : public db_listener_iface {
+       private:
+               bool started;
+               int last_cleanup_time;
+
+               bool start_monitoring();
+               void stop_monitoring();
+
+               void append_cleanup_query(std::stringstream &query);
+               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
diff --git a/src/statistics/media/media_stats_provider.cpp b/src/statistics/media/media_stats_provider.cpp
new file mode 100644 (file)
index 0000000..d6ad2b7
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * 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 <glib.h>
+#include <string>
+#include <context_mgr.h>
+#include "media_stats_provider.h"
+#include "db_handle.h"
+#include "media_content_monitor.h"
+
+static ctx::media_content_monitor *content_mon = NULL;
+
+ctx::media_statistics_provider *ctx::media_statistics_provider::__instance = NULL;
+
+ctx::media_statistics_provider::media_statistics_provider()
+{
+}
+
+ctx::media_statistics_provider::~media_statistics_provider()
+{
+       delete content_mon;
+       content_mon = NULL;
+}
+
+ctx::context_provider_iface *ctx::media_statistics_provider::create(void *data)
+{
+       IF_FAIL_RETURN(!__instance, __instance);
+
+       __instance = new(std::nothrow) media_statistics_provider();
+       IF_FAIL_RETURN_TAG(__instance, NULL, _E, "Memory allocation failed");
+
+       _I(BLUE("Created"));
+
+       if (!__instance->init()) {
+               destroy(data);
+               return NULL;
+       }
+
+       return __instance;
+}
+
+void ctx::media_statistics_provider::destroy(void *data)
+{
+       IF_FAIL_VOID(__instance);
+       delete __instance;
+       __instance = NULL;
+       _I(BLUE("Destroyed"));
+}
+
+bool ctx::media_statistics_provider::is_supported(const char* subject)
+{
+       return true;
+}
+
+void ctx::media_statistics_provider::submit_trigger_item()
+{
+       context_manager::register_trigger_item(MEDIA_SUBJ_MUSIC_FREQUENCY, OPS_READ,
+                       "{" TRIG_DEF_TOTAL_COUNT "}",
+                       "{" TRIG_DEF_TIME_OF_DAY "," TRIG_DEF_DAY_OF_WEEK "}");
+
+       context_manager::register_trigger_item(MEDIA_SUBJ_VIDEO_FREQUENCY, OPS_READ,
+                       "{" TRIG_DEF_TOTAL_COUNT "}",
+                       "{" TRIG_DEF_TIME_OF_DAY "," TRIG_DEF_DAY_OF_WEEK "}");
+}
+
+bool ctx::media_statistics_provider::init()
+{
+       content_mon = new(std::nothrow) ctx::media_content_monitor();
+       IF_FAIL_RETURN_TAG(content_mon, false, _E, "Memory allocation failed");
+       return true;
+}
+
+int ctx::media_statistics_provider::subscribe(const char* subject, ctx::json option, ctx::json* request_result)
+{
+       return ERR_NOT_SUPPORTED;
+}
+
+int ctx::media_statistics_provider::unsubscribe(const char* subject, ctx::json option)
+{
+       return ERR_NOT_SUPPORTED;
+}
+
+int ctx::media_statistics_provider::read(const char* subject, ctx::json option, ctx::json* request_result)
+{
+       media_db_handle *handle = new(std::nothrow) media_db_handle();
+       IF_FAIL_RETURN_TAG(handle, ERR_OPERATION_FAILED, _E, "Memory allocation failed");
+
+       int err = handle->read(subject, option);
+       if (err != ERR_NONE) {
+               delete handle;
+               return err;
+       }
+
+       return ERR_NONE;
+}
+
+int ctx::media_statistics_provider::write(const char* subject, ctx::json data, ctx::json* request_result)
+{
+       return ERR_NOT_SUPPORTED;
+}
diff --git a/src/statistics/media/media_stats_provider.h b/src/statistics/media/media_stats_provider.h
new file mode 100644 (file)
index 0000000..49949c3
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * 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_STATS_PROVIDER_H__
+#define __CONTEXT_MEDIA_STATS_PROVIDER_H__
+
+#include <provider_iface.h>
+#include "media_stats_types.h"
+
+namespace ctx {
+
+       class media_statistics_provider : public context_provider_iface {
+       public:
+               static context_provider_iface *create(void *data);
+               static void destroy(void *data);
+               static bool is_supported(const char *subject);
+               static void submit_trigger_item();
+
+               int subscribe(const char* subject, ctx::json option, ctx::json* request_result);
+               int unsubscribe(const char* subject, ctx::json option);
+               int read(const char* subject, ctx::json option, ctx::json* request_result);
+               int write(const char* subject, ctx::json data, ctx::json* request_result);
+
+       private:
+               static media_statistics_provider *__instance;
+
+               media_statistics_provider();
+               ~media_statistics_provider();
+               bool init();
+
+       };      /* class media_statistics_provider */
+
+}      /* namespace ctx */
+
+#endif /* __CONTEXT_CONTEXT_MEDIA_STATS_PROVIDER_H__ */
diff --git a/src/statistics/media/media_stats_types.h b/src/statistics/media/media_stats_types.h
new file mode 100644 (file)
index 0000000..79cfe3f
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 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_STATS_TYPES_H__
+#define __CONTEXT_MEDIA_STATS_TYPES_H__
+
+#include <common_types.h>
+
+#define MEDIA_HISTORY_PRIV                                     "mediahistory.read"
+#define MEDIA_SUBJ_PEAK_TIME_FOR_MUSIC         "stats/music/peak_time"
+#define MEDIA_SUBJ_PEAK_TIME_FOR_VIDEO         "stats/video/peak_time"
+#define MEDIA_SUBJ_COMMON_SETTING_FOR_MUSIC    "stats/music/setting"
+#define MEDIA_SUBJ_COMMON_SETTING_FOR_VIDEO    "stats/video/setting"
+#define MEDIA_SUBJ_MUSIC_FREQUENCY                     "stats/music/frequency"
+#define MEDIA_SUBJ_VIDEO_FREQUENCY                     "stats/video/frequency"
+
+#define MEDIA_TABLE_NAME       "Log_MediaPlayback"
+#define MEDIA_TABLE_COLUMNS \
+       "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_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, " \
+       " UTC TIMESTAMP DEFAULT (strftime('%s', 'now')))"
+
+#define CX_MEDIA_TYPE          "MediaType"
+
+enum media_type_e {
+       MEDIA_TYPE_MUSIC = 1,
+       MEDIA_TYPE_VIDEO,
+};
+
+#endif
diff --git a/src/statistics/prediction/assoc_rule.cpp b/src/statistics/prediction/assoc_rule.cpp
new file mode 100644 (file)
index 0000000..05be246
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * 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 "assoc_rule.h"
+
+std::ostream& ctx::operator<<(std::ostream &out, const ctx::AssocRule &rule)
+{
+       return out << rule.antecedent << " => " << rule.consequent
+                       << "; support:" << rule.support << "; confidence:" << rule.confidence;
+}
+
+bool ctx::operator==(const ctx::AssocRule& left, const ctx::AssocRule& right)
+{
+       return  left.antecedent == right.antecedent &&
+                       left.consequent == right.consequent &&
+                       left.support == right.support &&
+                       left.confidence == right.confidence;
+}
diff --git a/src/statistics/prediction/assoc_rule.h b/src/statistics/prediction/assoc_rule.h
new file mode 100644 (file)
index 0000000..252684e
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * 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 INCLUDE_ASSOC_RULE_H_
+#define INCLUDE_ASSOC_RULE_H_
+
+#include "item_set.h"
+#include <iostream>
+
+namespace ctx {
+
+       struct AssocRule {
+               ItemSet antecedent;
+               ItemSet consequent;
+               double support;
+               double confidence;
+
+               AssocRule(const ItemSet& antecedent_,
+                               const ItemSet& consequent_,
+                               const double& support_,
+                               const double& confidence_)
+                               : antecedent(antecedent_)
+                               , consequent(consequent_)
+                               , support(support_)
+                               , confidence(confidence_) {}
+       };
+
+       bool operator==(const AssocRule& left, const AssocRule& right);
+
+       std::ostream& operator<<(std::ostream &out, const AssocRule &rule);
+
+}      /* namespace ctx */
+
+#endif /* INCLUDE_ASSOC_RULE_H_ */
diff --git a/src/statistics/prediction/assoc_rule_miner.cpp b/src/statistics/prediction/assoc_rule_miner.cpp
new file mode 100644 (file)
index 0000000..a639af8
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * 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 "assoc_rule_miner.h"
+#include "single_category_item_id_filter.h"
+#include "basket_filter.h"
+#include "basket_compressor.h"
+#include "baskets_agregator.h"
+#include "assoc_rule_producer.h"
+#include "weight_apriori.h"
+
+std::list<ctx::AssocRule> ctx::AssocRuleMiner::mine_from_baskets(
+               std::list<ctx::Basket>& initBaskets,
+               ctx::ItemCatalogue& itemCatalogue,
+               double minSupport,
+               double minConfidence,
+               std::string consequentCategory)
+{
+       SingleCategoryItemIdFilter itemIdFilter(consequentCategory, itemCatalogue);
+       BasketFilter::filter_in_place(initBaskets,itemIdFilter);
+
+       std::list<Basket> compressedBaskets = BasketCompressor::compress(initBaskets);
+
+       BasketsAgregator basketsAgregator(compressedBaskets);
+       basketsAgregator.generate_bitsets(itemCatalogue.maxId());
+       auto freqItemSets = WeightApriori::find_frequent_itemid_sets(basketsAgregator, minSupport);
+       auto rulesOfIds = AssocRuleProducer::generate_rules(freqItemSets, itemIdFilter, minConfidence);
+       return remove_assoc_rule_ids(rulesOfIds, itemCatalogue);
+}
+
+std::list<ctx::AssocRule> ctx::AssocRuleMiner::mine_from_events(
+               const ctx::EventSet& events,
+               double minSupport,
+               double minConfidence,
+               std::string consequentCategory)
+{
+       ItemCatalogue itemCatalogue;
+
+       BasketProducer basketProducer(itemCatalogue);
+       for (auto& event : events) {
+               basketProducer.put_event(event);
+       }
+
+       std::list<Basket> initBaskets = basketProducer.make_baskets();
+
+       return mine_from_baskets(initBaskets, itemCatalogue, minSupport, minConfidence, consequentCategory);
+}
+
+std::list<ctx::AssocRule> ctx::AssocRuleMiner::remove_assoc_rule_ids(
+               const std::list<ctx::AssocRuleOfIds>& rulesOfIds,
+               const ctx::ItemCatalogue& itemCatalogue)
+{
+       std::list<AssocRule> result;
+       for (const AssocRuleOfIds ruleOfIds : rulesOfIds) {
+               AssocRule rule(remove_assoc_rule_ids(ruleOfIds.antecedent, itemCatalogue),
+                                       remove_assoc_rule_ids(ruleOfIds.consequent, itemCatalogue),
+                                       ruleOfIds.support,
+                                       ruleOfIds.confidence);
+               result.push_back(rule);
+       }
+       return result;
+}
+
+ctx::ItemSet ctx::AssocRuleMiner::remove_assoc_rule_ids(const ctx::ItemIdSet& itemIdSet, const ctx::ItemCatalogue& itemCatalogue)
+{
+       ItemSet itemSet;
+       for (int id : itemIdSet) {
+               itemSet.push_back(itemCatalogue.item_of_id(id));
+       }
+       return itemSet;
+}
diff --git a/src/statistics/prediction/assoc_rule_miner.h b/src/statistics/prediction/assoc_rule_miner.h
new file mode 100644 (file)
index 0000000..6d57e3f
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * 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 ASSOC_RULE_MINER_H_
+#define ASSOC_RULE_MINER_H_
+
+#include <list>
+#include <string>
+#include "event_set.h"
+#include "assoc_rule.h"
+#include "assoc_rule_of_ids.h"
+#include "basket_producer.h"
+#include "i_item_id_filter.h"
+
+namespace ctx {
+
+       class AssocRuleMiner {
+
+       public:
+               static std::list<AssocRule> mine_from_events(
+                               const EventSet& events,
+                               double minSupport,
+                               double minConfidence,
+                               std::string consequentCategory);
+               static std::list<AssocRule> mine_from_baskets(
+                               std::list<Basket>& initBaskets,
+                               ItemCatalogue& itemCatalogue,
+                               double minSupport,
+                               double minConfidence,
+                               std::string consequentCategory);
+       private:
+               static std::list<AssocRule> remove_assoc_rule_ids(const std::list<AssocRuleOfIds>& rulesOfIds, const ItemCatalogue& itemCatalogue);
+               static ItemSet remove_assoc_rule_ids(const ItemIdSet& itemIdSet, const ItemCatalogue& itemCatalogue);
+
+       };
+
+}      /* namespace ctx */
+
+#endif /* ASSOC_RULE_MINER_H_ */
diff --git a/src/statistics/prediction/assoc_rule_of_ids.h b/src/statistics/prediction/assoc_rule_of_ids.h
new file mode 100644 (file)
index 0000000..b7dea9a
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * 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 ASSOC_RULE_OF_IDS_H_
+#define ASSOC_RULE_OF_IDS_H_
+
+#include "item_id_set.h"
+
+namespace ctx {
+
+       /* rule of the form antecedent => consequent */
+       class AssocRuleOfIds {
+
+       public:
+               ItemIdSet antecedent;
+               ItemIdSet consequent;
+               double support;
+               double confidence;
+       };
+
+       inline bool operator==(const AssocRuleOfIds& left, const AssocRuleOfIds& right)
+       {
+               return  left.support == right.support
+                        && left.confidence == right.confidence
+                        && left.antecedent == right.antecedent
+                        && left.consequent == right.consequent;
+       }
+
+}      /* namespace ctx */
+
+#endif /* ASSOC_RULE_OF_IDS_H_ */
diff --git a/src/statistics/prediction/assoc_rule_producer.cpp b/src/statistics/prediction/assoc_rule_producer.cpp
new file mode 100644 (file)
index 0000000..da9f5d2
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 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 "assoc_rule_producer.h"
+
+ctx::AssocRuleOfIds ctx::AssocRuleProducer::rule_template(const ctx::ItemIdSet& sourceItemIdSet,
+               const ctx::IItemIdFilter& itemIdFilter)
+{
+       AssocRuleOfIds ruleTempl;
+       for (int itemId : sourceItemIdSet) {
+               ItemIdSet &destination = itemIdFilter.pass(itemId)
+                               ? ruleTempl.consequent
+                               : ruleTempl.antecedent;
+               destination.push_back(itemId);
+       }
+       return ruleTempl;
+}
+
+std::list<ctx::AssocRuleOfIds> ctx::AssocRuleProducer::generate_rules(
+               const std::list<std::pair<ctx::ItemIdSet, double>>& freqItemIdSets,
+               const ctx::IItemIdFilter& itemIdFilter, double minConfidence)
+{
+       std::list<AssocRuleOfIds> rules;
+
+       for (auto & pair : freqItemIdSets) {
+               ItemIdSet freqItemIdSet = pair.first;
+               double support = pair.second;
+               AssocRuleOfIds rule = AssocRuleProducer::rule_template(freqItemIdSet, itemIdFilter);
+               if (rule.antecedent.size() > 0 && rule.consequent.size() > 0) {
+                       rule.support = support;
+                       double antecedentSupport = AssocRuleProducer::supportOf(freqItemIdSets, rule.antecedent);
+                       rule.confidence = support / antecedentSupport;
+                       if (rule.confidence >= minConfidence) {
+                               rules.push_back(rule);
+                       }
+               }
+       }
+       return rules;
+}
+
+double ctx::AssocRuleProducer::supportOf(
+               const std::list<std::pair<ctx::ItemIdSet, double>> &allFreqItemIdSets, const ctx::ItemIdSet &wanted)
+{
+       for (auto & pair : allFreqItemIdSets) {
+               if (pair.first == wanted) {
+                       return pair.second;
+               }
+       }
+       return 0.0;
+}
diff --git a/src/statistics/prediction/assoc_rule_producer.h b/src/statistics/prediction/assoc_rule_producer.h
new file mode 100644 (file)
index 0000000..03eaecf
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * 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 ASSOC_RULE_PRODUCER_H_
+#define ASSOC_RULE_PRODUCER_H_
+
+#include "assoc_rule_of_ids.h"
+#include "basket.h"
+#include "i_item_id_filter.h"
+#include <list>
+
+namespace ctx {
+
+       class AssocRuleProducer {
+
+       public:
+               static std::list<AssocRuleOfIds> generate_rules(
+                               const std::list<std::pair<ItemIdSet,double>> &freqItemIdSets,
+                               const IItemIdFilter &itemIdFilter,
+                               double minConfidence);
+
+               static AssocRuleOfIds rule_template(const ItemIdSet &sourceItemIdSet, const IItemIdFilter &antecedentItemIdFilter);
+
+       private:
+               static double supportOf(const std::list<std::pair<ItemIdSet,double>> &allFreqItemIdSets, const ItemIdSet &wanted);
+
+       };
+
+}      /* namespace ctx */
+
+#endif /* ASSOC_RULE_PRODUCER_H_ */
diff --git a/src/statistics/prediction/basket.cpp b/src/statistics/prediction/basket.cpp
new file mode 100644 (file)
index 0000000..35357ce
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * 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 "basket.h"
+
+void ctx::Basket::compute_bitset(int maxId)
+{
+       mBitSet.resize(maxId+1, false);
+       for (int itemId : itemIdSet) {
+               mBitSet[itemId] = true;
+       }
+}
+
+bool ctx::Basket::includes(const ctx::ItemIdSet& potentialSubset)
+{
+       for (int itemId : potentialSubset) {
+               if (!mBitSet[itemId]) {
+                       return false;
+               }
+       }
+       return true;
+}
diff --git a/src/statistics/prediction/basket.h b/src/statistics/prediction/basket.h
new file mode 100644 (file)
index 0000000..2b40eb6
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * 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 INCLUDE_BASKET_H_
+#define INCLUDE_BASKET_H_
+
+#include "item_id_set.h"
+#include <vector>
+
+namespace ctx {
+
+       class Basket {
+
+       public:
+               ItemIdSet itemIdSet;
+               int weight;
+
+               Basket(const ItemIdSet& itemIdSet_, const int& weight_) : itemIdSet(itemIdSet_), weight(weight_) {};
+               void compute_bitset(int maxId);
+               bool includes(const ItemIdSet& potentialSubset); // compute_bitset() should be invoked first
+
+       private:
+               std::vector<bool> mBitSet;
+
+       };
+
+       // TODO If there is no "inline" below the project does not compile.
+       inline bool operator==(const Basket& left, const Basket& right)
+       {
+               return left.weight == right.weight && left.itemIdSet == right.itemIdSet;
+       }
+
+}      /* namespace ctx */
+
+#endif /* INCLUDE_BASKET_H_ */
diff --git a/src/statistics/prediction/basket_compressor.cpp b/src/statistics/prediction/basket_compressor.cpp
new file mode 100644 (file)
index 0000000..f46c40d
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * 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 "basket_compressor.h"
+#include <sstream>
+#include <map>
+
+std::string ctx::BasketCompressor::itemset_string(const ctx::ItemIdSet& itemIdSet)
+{
+       std::stringstream ss;
+       for (int itemId : itemIdSet) {
+               ss << itemId << ',';
+       }
+       return ss.str();
+}
+
+std::list<ctx::Basket> ctx::BasketCompressor::compress(const std::list<ctx::Basket>& inputBaskets)
+{
+       std::map<std::string,Basket> basketsMap;
+       // TODO: maybe it is worth to resign from string keys and use std::map<ItemSet,weight> instead.
+
+       for (const Basket& basket : inputBaskets) {
+               std::string itemSetStr = itemset_string(basket.itemIdSet);
+
+               auto findResult = basketsMap.find(itemSetStr);
+               if (findResult == basketsMap.end()) {
+                       basketsMap.insert(std::pair<std::string,Basket>(itemSetStr, basket));
+               } else {
+                       Basket& compressedBasket = findResult->second;
+                       compressedBasket.weight += basket.weight;
+               }
+       }
+
+       std::list<Basket> compressedBaskets;
+       for (auto pair : basketsMap) {
+               compressedBaskets.push_back(pair.second);
+       }
+       return compressedBaskets;
+}
diff --git a/src/statistics/prediction/basket_compressor.h b/src/statistics/prediction/basket_compressor.h
new file mode 100644 (file)
index 0000000..a0f5a95
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * 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 BASKET_COMPRESSOR_H_
+#define BASKET_COMPRESSOR_H_
+
+#include <list>
+#include <string>
+#include "basket.h"
+
+namespace ctx {
+
+       class BasketCompressor {
+
+       public:
+               static std::list<Basket> compress(const std::list<Basket> &inputBaskets);
+
+       private:
+               static std::string itemset_string(const ItemIdSet &itemIdSet);
+
+       };
+
+}      /* namespace ctx */
+
+#endif /* BASKET_COMPRESSOR_H_ */
diff --git a/src/statistics/prediction/basket_filter.cpp b/src/statistics/prediction/basket_filter.cpp
new file mode 100644 (file)
index 0000000..da03b6c
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * 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 "basket_filter.h"
+
+void ctx::BasketFilter::filter_in_place(std::list<ctx::Basket>& baskets, const ctx::IItemIdFilter& itemIdFilter)
+{
+       baskets.remove_if([&itemIdFilter] (Basket &basket) -> bool { return !BasketPass(basket, itemIdFilter); });
+}
+
+bool ctx::BasketFilter::BasketPass(const ctx::Basket& basket, const ctx::IItemIdFilter& itemIdFilter)
+{
+       for (int itemId : basket.itemIdSet) {
+               if (itemIdFilter.pass(itemId)) {
+                       return true;
+               }
+       }
+       return false;
+}
diff --git a/src/statistics/prediction/basket_filter.h b/src/statistics/prediction/basket_filter.h
new file mode 100644 (file)
index 0000000..18a03fd
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * 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 BASKET_FILTER_H_
+#define BASKET_FILTER_H_
+
+#include "basket.h"
+#include "i_item_id_filter.h"
+#include <list>
+
+namespace ctx {
+
+       class BasketFilter {
+
+       public:
+               static void filter_in_place(std::list<Basket> &inputBaskets, const IItemIdFilter &itemIdFilter);
+
+       private:
+               static bool BasketPass(const Basket &basket, const IItemIdFilter &itemIdFilter);
+
+       };
+
+}      /* namespace ctx */
+
+#endif /* BASKET_FILTER_H_ */
diff --git a/src/statistics/prediction/basket_producer.cpp b/src/statistics/prediction/basket_producer.cpp
new file mode 100644 (file)
index 0000000..99a3af9
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * 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 "basket_producer.h"
+#include <set>
+
+void ctx::BasketProducer::put_event(const ctx::Event& event)
+{
+       int iid = mItemCatalogue.id_of(event.item);
+       put_change(event.interval.start, iid);  // positive value indicates start
+       put_change(event.interval.end,  -iid);  // negative value indicates end
+}
+
+std::list<ctx::Basket> ctx::BasketProducer::make_baskets()
+{
+       std::list<Basket> baskets;
+
+       time_t intervalStart;
+       std::set<int> currentItemIds;
+
+       bool first = true;
+       for (auto changePair : mChanges) {
+               if (first) {
+                       first = false;
+               } else {
+                       time_t intervalEnd = changePair.first;
+                       int weight = intervalEnd - intervalStart;
+                       ItemIdSet itemIdSet;
+                       for (int itemId : currentItemIds) {
+                               itemIdSet.push_back(itemId);
+                       }
+                       baskets.push_back(Basket(itemIdSet, weight));
+               }
+
+               for (int itemId : changePair.second) {
+                       if (itemId > 0) {  // item with itemId starts now
+                               currentItemIds.insert(itemId);
+                       } else {           // item with -itemId ends now
+                               currentItemIds.erase(-itemId);
+                       }
+               }
+
+               intervalStart = changePair.first;
+       }
+
+       return baskets;
+}
+
+void ctx::BasketProducer::put_change(time_t time, int value)
+{
+       if (mChanges.find(time) == mChanges.end()) {
+               mChanges[time] = std::list<int>();
+       }
+       mChanges[time].push_back(value);
+}
diff --git a/src/statistics/prediction/basket_producer.h b/src/statistics/prediction/basket_producer.h
new file mode 100644 (file)
index 0000000..c265d94
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 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 INCLUDE_BASKET_PRODUCER_H_
+#define INCLUDE_BASKET_PRODUCER_H_
+
+#include "event.h"
+#include "basket.h"
+#include "item_catalogue.h"
+#include <list>
+
+namespace ctx {
+
+       class BasketProducer {
+
+       public:
+               BasketProducer(ItemCatalogue& itemCatalogue) : mItemCatalogue(itemCatalogue) {};
+               void put_event(const Event& e);
+               std::list<Basket> make_baskets();
+
+       private:
+               void put_change(time_t time, int value);
+
+               ItemCatalogue& mItemCatalogue;
+
+               /*
+                * Changes in timestamps.
+                * If an item starts than its id is stored.
+                * If an item ends than its negated id is stored.
+                */
+               std::map<time_t, std::list<int>> mChanges;
+
+       };
+
+}      /* namespace ctx */
+
+#endif /* INCLUDE_BASKET_PRODUCER_H_ */
diff --git a/src/statistics/prediction/baskets_agregator.cpp b/src/statistics/prediction/baskets_agregator.cpp
new file mode 100644 (file)
index 0000000..7a57e9b
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * 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 "baskets_agregator.h"
+
+ctx::BasketsAgregator::BasketsAgregator(std::list<ctx::Basket>& baskets) : mBaskets(baskets)
+{
+}
+
+ctx::ItemIdSet ctx::BasketsAgregator::unique_item_ids()
+{
+       ItemIdSet allItemIds;
+       for (const Basket& basket : mBaskets) {
+               for (int itemId : basket.itemIdSet) {
+                       allItemIds.push_back(itemId);
+               }
+       }
+       allItemIds.sort();
+       allItemIds.unique();
+       return allItemIds;
+}
+
+void ctx::BasketsAgregator::generate_bitsets(int maxId)
+{
+       for (Basket& basket : mBaskets) {
+               basket.compute_bitset(maxId);
+       }
+}
+
+double ctx::BasketsAgregator::supportOf(const ctx::ItemIdSet& itemIdSet)
+{
+       int matchedCount = 0;
+       int unmatchedCount = 0;
+       for (Basket& basket : mBaskets) {
+               if (basket.includes(itemIdSet)) {
+                       matchedCount += basket.weight;
+               } else {
+                       unmatchedCount += basket.weight;
+               }
+       }
+       return (double) matchedCount / (double) (matchedCount + unmatchedCount);
+}
diff --git a/src/statistics/prediction/baskets_agregator.h b/src/statistics/prediction/baskets_agregator.h
new file mode 100644 (file)
index 0000000..e3093fe
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * 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 INCLUDE_BASKETS_AGREGATOR_H_
+#define INCLUDE_BASKETS_AGREGATOR_H_
+
+#include <list>
+#include <memory>
+#include "basket.h"
+
+namespace ctx {
+
+       class BasketsAgregator {
+
+       public:
+               BasketsAgregator(std::list<Basket>& baskets);
+               void generate_bitsets(int maxId);
+               ItemIdSet unique_item_ids();
+               double supportOf(const ItemIdSet &itemIdSet);
+
+       private:
+               std::list<Basket>& mBaskets;
+
+       };
+
+}      /* namespace ctx */
+
+#endif /* INCLUDE_BASKETS_AGREGATOR_H_ */
diff --git a/src/statistics/prediction/event.cpp b/src/statistics/prediction/event.cpp
new file mode 100644 (file)
index 0000000..817e108
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * 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 "event.h"
+
+bool ctx::operator==(const ctx::Event& left, const ctx::Event& right)
+{
+       return left.item == right.item && left.interval == right.interval;
+}
+
+bool ctx::operator!=(const ctx::Event& left, const ctx::Event& right)
+{
+       return !(left == right);
+}
diff --git a/src/statistics/prediction/event.h b/src/statistics/prediction/event.h
new file mode 100644 (file)
index 0000000..029296f
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * 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 INCLUDE_EVENT_H_
+#define INCLUDE_EVENT_H_
+
+#include "item.h"
+#include "interval.h"
+
+namespace ctx {
+
+       struct Event {
+               Item item;
+               Interval interval;
+
+               /* long time event */
+               Event(const Item& item_, const Interval& interval_) : item(item_), interval(interval_) {}
+
+               /* instant event */
+               Event(const Item& item_, const time_t& start_time_) : item(item_), interval(start_time_, start_time_ + 1) {}
+       };
+
+       bool operator==(const Event& left, const Event& right);
+       bool operator!=(const Event& left, const Event& right);
+
+}      /* namespace ctx */
+
+#endif /* INCLUDE_EVENT_H_ */
diff --git a/src/statistics/prediction/event_set.h b/src/statistics/prediction/event_set.h
new file mode 100644 (file)
index 0000000..dda0bc2
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * 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 INCLUDE_EVENT_SET_H_
+#define INCLUDE_EVENT_SET_H_
+
+#include "event.h"
+
+namespace ctx {
+
+       typedef std::list<Event> EventSet;
+
+}      /* namespace ctx */
+
+#endif /* INCLUDE_EVENT_SET_H_ */
diff --git a/src/statistics/prediction/i_item_id_filter.h b/src/statistics/prediction/i_item_id_filter.h
new file mode 100644 (file)
index 0000000..dd4c386
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * 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 I_ITEM_ID_FILTER_H_
+#define I_ITEM_ID_FILTER_H_
+
+namespace ctx {
+
+       class IItemIdFilter {
+
+       public:
+               virtual ~IItemIdFilter() {}
+               virtual bool pass(int itemId) const = 0;
+
+       };
+
+}      /* namespace ctx */
+
+#endif /* I_ITEM_ID_FILTER_H_ */
diff --git a/src/statistics/prediction/interval.cpp b/src/statistics/prediction/interval.cpp
new file mode 100644 (file)
index 0000000..b6dc8f9
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * 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 "interval.h"
+
+bool ctx::operator==(const Interval& left, const Interval& right)
+{
+       return left.start == right.start && left.end == right.end;
+}
+
+bool ctx::operator!=(const Interval& left, const Interval& right)
+{
+       return !(left == right);
+}
diff --git a/src/statistics/prediction/interval.h b/src/statistics/prediction/interval.h
new file mode 100644 (file)
index 0000000..2153aa0
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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 INCLUDE_INTERVAL_H_
+#define INCLUDE_INTERVAL_H_
+
+#include <ctime>
+
+namespace ctx {
+
+       struct Interval {
+               time_t start;
+               time_t end;
+
+               Interval(time_t start_, time_t end_) : start(start_), end(end_) {}
+       };
+
+       bool operator==(const Interval& left, const Interval& right);
+       bool operator!=(const Interval& left, const Interval& right);
+
+}      /* namespace ctx */
+
+#endif /* INCLUDE_INTERVAL_H_ */
diff --git a/src/statistics/prediction/item.cpp b/src/statistics/prediction/item.cpp
new file mode 100644 (file)
index 0000000..9a80ca9
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * 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 "item.h"
+
+ctx::Item::Item(const std::string &s)
+{
+       size_t leftBracket = s.find('[');
+       size_t rightBracket = s.find(']', leftBracket);
+       category = s.substr(leftBracket + 1, rightBracket - 1);
+       value = s.substr(rightBracket + 1);
+       return;
+}
+
+bool ctx::Item::operator==(const ctx::Item& other) const
+{
+       return other.category == category && other.value == value;
+}
+
+bool ctx::Item::operator!=(const ctx::Item& other) const
+{
+       return !operator==(other);
+}
+
+std::ostream& ctx::operator<<(std::ostream& out, const ctx::Item& item)
+{
+       return out << '[' << item.category << ']' << item.value;
+}
diff --git a/src/statistics/prediction/item.h b/src/statistics/prediction/item.h
new file mode 100644 (file)
index 0000000..edf7d28
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * 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 INCLUDE_ITEM_H_
+#define INCLUDE_ITEM_H_
+
+#include <string>
+#include <iostream>
+
+namespace ctx {
+
+       struct Item {
+               std::string category;
+               std::string value;
+
+               Item(const std::string &category_, const std::string &value_) : category(category_), value(value_) {}
+               Item(const std::string &s); // in the form of "[Category]Value"
+
+               bool operator==(const Item& other) const;
+               bool operator!=(const Item& other) const;
+       };
+
+       std::ostream& operator<<(std::ostream& out, const Item& item);
+
+}      /* namespace ctx */
+
+namespace std {
+
+       template <> struct hash<ctx::Item> {
+               size_t operator()(const ctx::Item &item) const {
+                       hash<std::string> hasher;
+                       return hasher(item.category + ":" + item.value);
+               }
+       };
+
+}
+
+#endif /* INCLUDE_ITEM_H_ */
diff --git a/src/statistics/prediction/item_catalogue.cpp b/src/statistics/prediction/item_catalogue.cpp
new file mode 100644 (file)
index 0000000..666b5a8
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * 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 "item_catalogue.h"
+#include "item_string_converter.h"
+
+int ctx::ItemCatalogue::id_of(const ctx::Item& item)
+{
+       std::string s = ItemStringConverter::item_to_string(item);
+       std::map<std::string,int>::iterator it = mItemIdsOfStrings.find(s);
+       if (it == mItemIdsOfStrings.end()) { // new item
+               mMaxId++;
+               mItemIdsOfStrings[s] = mMaxId;
+               mItemStrings.push_back(s);
+               extendCategoryItemIds(item.category, mMaxId);
+               return mMaxId;
+       } else { // existing item
+               return mItemIdsOfStrings[s];
+       }
+}
+
+bool ctx::ItemCatalogue::exists_item_of_id(int id) const
+{
+       return id > 0 && id <= mMaxId;
+}
+
+ctx::Item ctx::ItemCatalogue::item_of_id(int id) const
+{
+       return ItemStringConverter::string_to_item(mItemStrings[id]);
+}
+
+std::set<int> ctx::ItemCatalogue::category_item_ids(std::string category) const
+{
+       auto it = mCategoryItemIds.find(category);
+       if (it == mCategoryItemIds.end()) {
+               return std::set<int>();
+       } else {
+               return it->second;
+       }
+}
+
+void ctx::ItemCatalogue::extendCategoryItemIds(std::string category, int itemId)
+{
+       if (mCategoryItemIds.find(category) == mCategoryItemIds.end()) {
+               mCategoryItemIds[category] = std::set<int>();
+       }
+       mCategoryItemIds[category].insert(itemId);
+}
diff --git a/src/statistics/prediction/item_catalogue.h b/src/statistics/prediction/item_catalogue.h
new file mode 100644 (file)
index 0000000..96b5279
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * 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 INCLUDE_ITEMCATALOGUE_H_
+#define INCLUDE_ITEMCATALOGUE_H_
+
+#include "item.h"
+#include <map>
+#include <set>
+#include <vector>
+
+namespace ctx {
+
+       class ItemCatalogue {
+
+       public:
+               ItemCatalogue() : mMaxId(0) {
+                       mItemStrings.push_back(std::string(""));
+               }
+
+               int id_of(Item const &item);
+
+               bool exists_item_of_id(int id) const;
+               Item item_of_id(int id) const;
+               std::set<int> category_item_ids(std::string category) const;
+               int maxId() const {return mMaxId;};
+
+       private:
+               /* Translates item string to its id */
+               std::map<std::string,int> mItemIdsOfStrings;
+
+               /* Translating category string to int */
+               std::map<std::string,std::set<int>> mCategoryItemIds;
+
+               /* Stores item strings (index is item's id) */
+               std::vector<std::string> mItemStrings;
+
+               /* Preserves maximal item's id */
+               int mMaxId;
+
+               void extendCategoryItemIds(std::string category, int itemId);
+
+       };
+
+}      /* namespace ctx */
+
+#endif /* INCLUDE_ITEMCATALOGUE_H_ */
diff --git a/src/statistics/prediction/item_id_set.h b/src/statistics/prediction/item_id_set.h
new file mode 100644 (file)
index 0000000..0604fed
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * 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 INCLUDE_ITEM_ID_SET_H_
+#define INCLUDE_ITEM_ID_SET_H_
+
+#include <list>
+
+namespace ctx {
+
+       /* A set storing item ids */
+       typedef std::list<int> ItemIdSet;
+
+}      /* namespace ctx */
+
+#endif /* INCLUDE_ITEM_ID_SET_H_ */
diff --git a/src/statistics/prediction/item_set.cpp b/src/statistics/prediction/item_set.cpp
new file mode 100644 (file)
index 0000000..c8dc55b
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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 "item_set.h"
+#include <algorithm>
+
+std::ostream& ctx::operator<<(std::ostream& out, const ctx::ItemSet& itemSet)
+{
+       bool first = true;
+       for (auto& item : itemSet) {
+               if (first) {
+                       first = false;
+               } else {
+                       out << ", ";
+               }
+               out << item;
+       }
+       return out;
+}
+
+bool ctx::itemset_includes_in(const ctx::ItemSet& small, const ctx::ItemSet& big)
+{
+       for (const Item& s : small)
+               if (std::find(big.begin(), big.end(), s) == big.end())
+                       return false;
+       return true;
+}
diff --git a/src/statistics/prediction/item_set.h b/src/statistics/prediction/item_set.h
new file mode 100644 (file)
index 0000000..98a1b6d
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * 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 INCLUDE_ITEM_SET_H_
+#define INCLUDE_ITEM_SET_H_
+
+#include <list>
+#include "item.h"
+
+namespace ctx {
+
+       /* A set storing item ids */
+       typedef std::list<Item> ItemSet;
+
+       std::ostream& operator<<(std::ostream& out, const ItemSet& itemSet);
+
+       bool itemset_includes_in(const ItemSet& small, const ItemSet& big);
+
+}      /* namespace ctx */
+
+#endif /* INCLUDE_ITEM_SET_H_ */
diff --git a/src/statistics/prediction/item_string_converter.cpp b/src/statistics/prediction/item_string_converter.cpp
new file mode 100644 (file)
index 0000000..399847a
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * 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 "item_string_converter.h"
+#include <string>
+
+std::string ctx::ItemStringConverter::item_to_string(const ctx::Item &item)
+{
+       return item.category + SEPARATOR + item.value;
+}
+
+ctx::Item ctx::ItemStringConverter::string_to_item(const std::string& s)
+{
+       size_t pos = s.find(SEPARATOR);
+       //assert(pos != std::string::npos);
+       return Item(s.substr(0, pos), s.substr(pos + 1));
+}
diff --git a/src/statistics/prediction/item_string_converter.h b/src/statistics/prediction/item_string_converter.h
new file mode 100644 (file)
index 0000000..961c1f3
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * 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 INCLUDE_ITEMSTRINGCONVERTER_H_
+#define INCLUDE_ITEMSTRINGCONVERTER_H_
+
+#include "item.h"
+
+namespace ctx {
+
+       class ItemStringConverter {
+
+       public:
+               static const char SEPARATOR = ':';
+               static std::string item_to_string(const Item &item);
+               static Item string_to_item(const std::string& s);
+
+       };
+
+}      /* namespace ctx */
+
+#endif /* INCLUDE_ITEMSTRINGCONVERTER_H_ */
diff --git a/src/statistics/prediction/single_category_item_id_filter.cpp b/src/statistics/prediction/single_category_item_id_filter.cpp
new file mode 100644 (file)
index 0000000..6646e8d
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * 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 "single_category_item_id_filter.h"
+
+ctx::SingleCategoryItemIdFilter::SingleCategoryItemIdFilter(std::string category, const ctx::ItemCatalogue &itemCatalogue)
+{
+       mAcceptedItemIds = itemCatalogue.category_item_ids(category);
+}
+
+bool ctx::SingleCategoryItemIdFilter::pass(int itemId) const
+{
+       return mAcceptedItemIds.find(itemId) != mAcceptedItemIds.end();
+}
diff --git a/src/statistics/prediction/single_category_item_id_filter.h b/src/statistics/prediction/single_category_item_id_filter.h
new file mode 100644 (file)
index 0000000..4ef9cf4
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * 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 SINGLE_CATEGORY_ITEM_ID_FILTER_H_
+#define SINGLE_CATEGORY_ITEM_ID_FILTER_H_
+
+#include "i_item_id_filter.h"
+#include "item_catalogue.h"
+
+namespace ctx {
+
+       class SingleCategoryItemIdFilter : public IItemIdFilter {
+
+       public:
+               SingleCategoryItemIdFilter(std::string category, const ItemCatalogue& itemCatalogue);
+               bool pass(int itemId) const override;
+
+       private:
+               std::set<int> mAcceptedItemIds;
+
+       };
+
+}      /* namespace ctx */
+
+#endif /* SINGLE_CATEGORY_ITEM_ID_FILTER_H_ */
diff --git a/src/statistics/prediction/weight_apriori.cpp b/src/statistics/prediction/weight_apriori.cpp
new file mode 100644 (file)
index 0000000..92aaebc
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * 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 "weight_apriori.h"
+#include <algorithm>
+#include <iostream>
+
+std::list<ctx::ItemIdSet> ctx::WeightApriori::find_wider_candidates(const std::list<ctx::ItemIdSet> &narrowFreqSets, int widerSize)
+{
+       std::list<ItemIdSet> candidates;
+       for (auto iter1 = narrowFreqSets.begin(); iter1 != narrowFreqSets.end(); ++iter1) {
+               auto iter2 = iter1; ++iter2;
+               for (;iter2 != narrowFreqSets.end(); ++iter2) {
+                       ItemIdSet itemIdSet1 = *iter1;
+                       ItemIdSet itemIdSet2 = *iter2;
+                       itemIdSet1.merge(itemIdSet2);
+                       itemIdSet1.unique();
+                       if (int(itemIdSet1.size()) == widerSize) {
+                               candidates.push_back(itemIdSet1);
+                       }
+               }
+       }
+       candidates.sort();
+       candidates.unique();
+       return candidates;
+}
+
+void ctx::WeightApriori::prune_wider_candidates(std::list<ctx::ItemIdSet>& widerCandidates, const std::list<ctx::ItemIdSet>& narrowFreqSets)
+{
+       std::list<ItemIdSet> pruned;
+       for (auto iter = widerCandidates.begin(); iter != widerCandidates.end();) {
+               if (survives_prunning(*iter, narrowFreqSets)) {
+                       ++iter;
+               } else {
+                       iter = widerCandidates.erase(iter);
+               }
+       }
+}
+
+bool ctx::WeightApriori::survives_prunning(ctx::ItemIdSet& widerCandidate, const std::list<ctx::ItemIdSet>& narrowFreqSets)
+{
+       int removedItemId = widerCandidate.front();
+       widerCandidate.pop_front();
+       for (auto iter = widerCandidate.begin();; ++iter) {
+               if (std::find(narrowFreqSets.begin(), narrowFreqSets.end(), widerCandidate) == narrowFreqSets.end()) {
+                       return false; // Caution: In this case the original contents of widerCandidate is not preserved.
+               }
+               if (iter == widerCandidate.end()) {
+                       widerCandidate.push_back(removedItemId); // Restoring original contents of widerCandidate.
+                       return true;
+               }
+               int newRemovedItemId = *iter;
+               *iter = removedItemId;
+               removedItemId = newRemovedItemId;
+       }
+}
+
+std::list<std::pair<ctx::ItemIdSet, double>> ctx::WeightApriori::find_frequent_itemid_sets(ctx::BasketsAgregator &basketAgregator, double supportThreshold)
+{
+       std::list<std::pair<ItemIdSet, double>> allFreqItemsets;
+       std::list<ItemIdSet> freqItemsetsOfCurrSize;
+       std::list<ItemIdSet> candidates;
+
+       int candidateSize = 1;
+       candidates = single_size_candidates(basketAgregator);
+
+       while (!candidates.empty()) {
+               for (ItemIdSet candidate : candidates) {
+                       double support = basketAgregator.supportOf(candidate);
+                       if (support >= supportThreshold) {
+                               freqItemsetsOfCurrSize.push_back(candidate);
+                               allFreqItemsets.push_back(std::make_pair(candidate,support));
+                       }
+               }
+               candidates = find_wider_candidates(freqItemsetsOfCurrSize, ++candidateSize);
+               freqItemsetsOfCurrSize.clear();
+       }
+       return allFreqItemsets;
+}
+
+std::list<ctx::ItemIdSet> ctx::WeightApriori::single_size_candidates(ctx::BasketsAgregator& basketAgregator)
+{
+       std::list<ItemIdSet> candidates;
+       for (int itemId : basketAgregator.unique_item_ids()) {
+               candidates.push_back({itemId});
+       }
+       return candidates;
+}
diff --git a/src/statistics/prediction/weight_apriori.h b/src/statistics/prediction/weight_apriori.h
new file mode 100644 (file)
index 0000000..94aecf2
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * 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 INCLUDE_WEIGHT_APRIORI_H_
+#define INCLUDE_WEIGHT_APRIORI_H_
+
+#include "baskets_agregator.h"
+#include <list>
+#include <utility>
+
+namespace ctx {
+
+       class WeightApriori {
+
+       public:
+               static std::list<ItemIdSet> find_wider_candidates(const std::list<ItemIdSet> &narrowFreqSets, int widerSize);
+               static void prune_wider_candidates(std::list<ItemIdSet> &widerCandidates, const std::list<ItemIdSet> &narrowFreqSets);
+
+               static bool survives_prunning(ItemIdSet &widerCandidate, const std::list<ItemIdSet> &narrowFreqSets);
+
+               /* Find frequent itemsets along with its support value. */
+               static std::list<std::pair<ItemIdSet,double>> find_frequent_itemid_sets(BasketsAgregator &basketAgregator, double supportThreshold);
+
+       private:
+               static std::list<ItemIdSet> single_size_candidates(BasketsAgregator &basketAgregator);
+
+       };
+
+}      /* namespace ctx */
+
+#endif /* INCLUDE_WEIGHT_APRIORI_H_ */
diff --git a/src/statistics/shared/common_types.h b/src/statistics/shared/common_types.h
new file mode 100644 (file)
index 0000000..f173df9
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * 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_STATS_COMMON_TYPES_H__
+#define __CONTEXT_STATS_COMMON_TYPES_H__
+
+#define LOG_RETENTION_PERIOD   7776000         /* 90 days in secs */
+
+#define DEFAULT_TIMESPAN               30
+#define DEFAULT_LIMIT                  10
+
+#define STATS_QUERY_RESULT             "QueryResult"
+#define STATS_RESULT_SIZE              "ResultSize"
+#define STATS_COL_ROW_ID               "row_id"
+
+#define STATS_TIMESPAN                 "TimeSpan"
+#define STATS_START_TIME               "StartTime"
+#define STATS_END_TIME                 "EndTime"
+#define STATS_LAST_TIME                        "LastTime"
+#define STATS_TOTAL_COUNT              "TotalCount"
+#define STATS_AVERAGE_COUNT            "AvgCount"
+#define STATS_DURATION                 "Duration"
+#define STATS_TOTAL_DURATION   "TotalDuration"
+#define STATS_DAY_OF_WEEK              "DayOfWeek"
+#define STATS_HOUR_OF_DAY              "HourOfDay"
+#define STATS_TIME_OF_DAY              "TimeOfDay"
+#define STATS_TOTAL_COUNT              "TotalCount"
+#define STATS_APP_ID                   "AppId"
+#define STATS_PKG_ID                   "PkgId"
+#define STATS_AUDIO_JACK               "AudioJack"
+#define STATS_SYSTEM_VOLUME            "SystemVolume"
+#define STATS_MEDIA_VOLUME             "MediaVolume"
+#define STATS_BSSID                            "BSSID"
+#define STATS_UNIV_TIME                        "UTC"
+#define STATS_LOCAL_TIME               "LocalTime"
+#define STATS_RANK                             "Rank"
+
+#define STATS_SUN              "Sun"
+#define STATS_MON              "Mon"
+#define STATS_TUE              "Tue"
+#define STATS_WED              "Wed"
+#define STATS_THU              "Thu"
+#define STATS_FRI              "Fri"
+#define STATS_SAT              "Sat"
+#define STATS_WEEKDAY  "Weekday"
+#define STATS_WEEKEND  "Weekend"
+
+enum stats_day_of_week_e {
+       STATS_DAY_OF_WEEK_WEEKDAY = 1,
+       STATS_DAY_OF_WEEK_WEEKEND,
+       STATS_DAY_OF_WEEK_ALL,
+       STATS_DAY_OF_WEEK_SUN,
+       STATS_DAY_OF_WEEK_MON,
+       STATS_DAY_OF_WEEK_TUE,
+       STATS_DAY_OF_WEEK_WED,
+       STATS_DAY_OF_WEEK_THU,
+       STATS_DAY_OF_WEEK_FRI,
+       STATS_DAY_OF_WEEK_SAT,
+};
+
+#define TRIG_DEF_RANK                  "\"Rank\":{\"type\":\"integer\",\"min\":1}"
+#define TRIG_DEF_TOTAL_COUNT   "\"TotalCount\":{\"type\":\"integer\",\"min\":0}"
+#define TRIG_DEF_TIME_OF_DAY   "\"TimeOfDay\":{\"type\":\"string\"}"
+#define TRIG_DEF_DAY_OF_WEEK   "\"DayOfWeek\":{\"type\":\"string\",\"values\":[\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\",\"Sun\",\"Weekday\",\"Weekend\"]}"
+
+#endif
diff --git a/src/statistics/shared/db_handle_base.cpp b/src/statistics/shared/db_handle_base.cpp
new file mode 100644 (file)
index 0000000..e3d0602
--- /dev/null
@@ -0,0 +1,227 @@
+/*
+ * 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 <context_mgr.h>
+#include <db_mgr.h>
+#include "common_types.h"
+#include "db_handle_base.h"
+
+#define DAY_OF_WEEK(SECOND) "CAST(strftime('%w', " SECOND ", 'unixepoch') AS INTEGER)"
+#define HOUR_OF_DAY(SECOND) "CAST(strftime('%H', " SECOND ", 'unixepoch') AS INTEGER)"
+
+ctx::stats_db_handle_base::stats_db_handle_base()
+       : is_trigger_item(false)
+{
+}
+
+ctx::stats_db_handle_base::~stats_db_handle_base()
+{
+}
+
+int ctx::stats_db_handle_base::generate_qid()
+{
+       static int qid = 0;
+
+       if (qid++ < 0) qid = 1;
+       return qid;
+}
+
+bool ctx::stats_db_handle_base::execute_query(const char* subject, ctx::json filter, const char* query)
+{
+       bool ret = db_manager::execute(generate_qid(), query, this);
+       IF_FAIL_RETURN(ret, false);
+
+       req_subject = subject;
+       req_filter = filter;
+
+       return true;
+}
+
+std::string ctx::stats_db_handle_base::create_where_clause(ctx::json filter)
+{
+       std::stringstream where_clause;
+       int week = 0;
+       int start = 0;
+       int end = 0;
+       int timespan = DEFAULT_TIMESPAN;
+       std::string app_id;
+       std::string week_str;
+       std::string time_of_day;
+
+       if (filter.get(NULL, STATS_DAY_OF_WEEK, &week_str)) {
+               // In case of string (from Trigger)
+               if (week_str == STATS_WEEKDAY) {
+                       week = STATS_DAY_OF_WEEK_WEEKDAY;
+
+               } else if (week_str == STATS_WEEKEND) {
+                       week = STATS_DAY_OF_WEEK_WEEKEND;
+
+               } else if (week_str == STATS_SUN) {
+                       week = STATS_DAY_OF_WEEK_SUN;
+
+               } else if (week_str == STATS_MON) {
+                       week = STATS_DAY_OF_WEEK_MON;
+
+               } else if (week_str == STATS_TUE) {
+                       week = STATS_DAY_OF_WEEK_TUE;
+
+               } else if (week_str == STATS_WED) {
+                       week = STATS_DAY_OF_WEEK_WED;
+
+               } else if (week_str == STATS_THU) {
+                       week = STATS_DAY_OF_WEEK_THU;
+
+               } else if (week_str == STATS_FRI) {
+                       week = STATS_DAY_OF_WEEK_FRI;
+
+               } else if (week_str == STATS_SAT) {
+                       week = STATS_DAY_OF_WEEK_SAT;
+               }
+       } else {
+               // In case of integer (from History)
+               filter.get(NULL, STATS_DAY_OF_WEEK, &week);
+       }
+
+       switch(week) {
+       case STATS_DAY_OF_WEEK_WEEKDAY:
+               where_clause << "(" DAY_OF_WEEK(STATS_LOCAL_TIME) " > 0 AND " DAY_OF_WEEK(STATS_LOCAL_TIME) " < 6) AND ";
+               break;
+       case STATS_DAY_OF_WEEK_WEEKEND:
+               where_clause << "(" DAY_OF_WEEK(STATS_LOCAL_TIME) " = 0 OR " DAY_OF_WEEK(STATS_LOCAL_TIME) " = 6) AND ";
+               break;
+       case STATS_DAY_OF_WEEK_SUN:
+       case STATS_DAY_OF_WEEK_MON:
+       case STATS_DAY_OF_WEEK_TUE:
+       case STATS_DAY_OF_WEEK_WED:
+       case STATS_DAY_OF_WEEK_THU:
+       case STATS_DAY_OF_WEEK_FRI:
+       case STATS_DAY_OF_WEEK_SAT:
+               where_clause << DAY_OF_WEEK(STATS_LOCAL_TIME) " = " << week - STATS_DAY_OF_WEEK_SUN << " AND ";
+               break;
+       default:
+               break;
+       }
+
+       if (filter.get(NULL, STATS_APP_ID, &app_id))
+               where_clause << STATS_APP_ID " = '" << app_id << "' AND ";
+
+       if (filter.get(NULL, STATS_START_TIME, &start))
+               where_clause << STATS_UNIV_TIME " >= " << start << " AND ";
+
+       if (filter.get(NULL, STATS_END_TIME, &end))
+               where_clause << STATS_UNIV_TIME " <= " << end << " AND ";
+
+       if (filter.get(NULL, STATS_TIME_OF_DAY, &time_of_day)) {
+               size_t pivot = time_of_day.find('-');
+               if (pivot != std::string::npos) {
+                       std::string from = time_of_day.substr(0, pivot);
+                       std::string to = time_of_day.substr(pivot + 1);
+                       where_clause << "(" HOUR_OF_DAY(STATS_LOCAL_TIME) " >= " << from \
+                               << " AND " HOUR_OF_DAY(STATS_LOCAL_TIME) " < " << to << ") AND ";
+               }
+       }
+
+       filter.get(NULL, STATS_TIMESPAN, &timespan);
+       where_clause << STATS_UNIV_TIME " > strftime('%s', 'now', '-" << timespan <<" day')";
+
+       return where_clause.str();
+}
+
+std::string ctx::stats_db_handle_base::create_sql_peak_time(ctx::json filter, const char* table_name, std::string where_clause)
+{
+       std::stringstream query;
+       int limit = DEFAULT_LIMIT;
+
+       filter.get(NULL, STATS_RESULT_SIZE, &limit);
+
+       query <<
+               "SELECT " \
+                       HOUR_OF_DAY(STATS_LOCAL_TIME) " AS " STATS_HOUR_OF_DAY ", COUNT(*) AS " STATS_TOTAL_COUNT \
+               " FROM " << table_name << \
+               " WHERE " << where_clause << \
+               " GROUP BY " HOUR_OF_DAY(STATS_LOCAL_TIME) \
+               " ORDER BY " STATS_TOTAL_COUNT " DESC" \
+               " LIMIT " << limit;
+
+       return query.str();
+}
+
+std::string ctx::stats_db_handle_base::create_sql_common_setting(ctx::json filter, const char* table_name, std::string where_clause)
+{
+       std::stringstream query;
+
+       query <<
+               "SELECT ( SELECT " STATS_AUDIO_JACK \
+                               " FROM " << table_name << \
+                               " WHERE " << where_clause << \
+                               " GROUP BY " STATS_AUDIO_JACK \
+                               " ORDER BY count(" STATS_AUDIO_JACK ") DESC" \
+                               " LIMIT 1 ) AS " STATS_AUDIO_JACK \
+                       ", ( SELECT " STATS_SYSTEM_VOLUME \
+                               " FROM " << table_name << \
+                               " WHERE " << where_clause << \
+                               " GROUP BY " STATS_SYSTEM_VOLUME \
+                               " ORDER BY count(" STATS_SYSTEM_VOLUME ") DESC" \
+                               " LIMIT 1 ) AS " STATS_SYSTEM_VOLUME \
+                       ", ( SELECT " STATS_MEDIA_VOLUME \
+                               " FROM " << table_name << \
+                               " WHERE " << where_clause << \
+                               " GROUP BY " STATS_MEDIA_VOLUME \
+                               " ORDER BY count(" STATS_MEDIA_VOLUME ") DESC" \
+                               " LIMIT 1 ) AS " STATS_MEDIA_VOLUME;
+
+       return query.str();
+}
+
+void ctx::stats_db_handle_base::on_creation_result_received(unsigned int query_id, int error)
+{
+}
+
+void ctx::stats_db_handle_base::on_insertion_result_received(unsigned int query_id, int error, int64_t row_id)
+{
+       delete this;
+}
+
+void ctx::stats_db_handle_base::json_vector_to_array(std::vector<json> &vec_json, ctx::json &json_result)
+{
+       std::vector<json>::iterator json_vec_end = vec_json.end();
+
+       for(std::vector<json>::iterator json_vec_pos = vec_json.begin(); json_vec_pos != json_vec_end; ++json_vec_pos) {
+               json origin_j = *json_vec_pos;
+               json_result.array_append(NULL, STATS_QUERY_RESULT, origin_j);
+       }
+}
+
+void ctx::stats_db_handle_base::on_query_result_received(unsigned int query_id, int error, std::vector<json>& records)
+{
+       if (is_trigger_item) {
+               if (records.size() == 1) {
+                       reply_trigger_item(error, records[0]);
+               } else {
+                       _E("Invalid query result");
+                       json dummy;
+                       context_manager::reply_to_read(req_subject.c_str(), req_filter, ERR_OPERATION_FAILED, dummy);
+               }
+       } else {
+               json results = "{\"" STATS_QUERY_RESULT "\":[]}";
+               json_vector_to_array(records, results);
+               context_manager::reply_to_read(req_subject.c_str(), req_filter, error, results);
+       }
+
+       delete this;
+}
diff --git a/src/statistics/shared/db_handle_base.h b/src/statistics/shared/db_handle_base.h
new file mode 100644 (file)
index 0000000..6e05696
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * 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_STATS_DB_HANDLE_BASE_H__
+#define __CONTEXT_STATS_DB_HANDLE_BASE_H__
+
+#include <string>
+#include <json.h>
+#include <db_listener_iface.h>
+
+namespace ctx {
+       class stats_db_handle_base : public db_listener_iface {
+               protected:
+                       bool is_trigger_item;
+                       std::string req_subject;
+                       ctx::json req_filter;
+
+                       stats_db_handle_base();
+                       ~stats_db_handle_base();
+
+                       std::string create_where_clause(ctx::json filter);
+                       std::string create_sql_peak_time(ctx::json filter, const char* table_name, std::string where_clause);
+                       std::string create_sql_common_setting(ctx::json filter, const char* table_name, std::string where_clause);
+
+                       bool execute_query(const char* subject, ctx::json filter, const char* query);
+                       virtual void reply_trigger_item(int error, ctx::json &json_result) = 0;
+                       static int generate_qid();
+
+               private:
+                       void json_vector_to_array(std::vector<json> &vec_json, ctx::json &json_result);
+
+                       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);
+       };
+}
+
+#endif /* __CONTEXT_STATS_DB_HANDLE_BASE_H__ */
diff --git a/src/statistics/shared/system_info.cpp b/src/statistics/shared/system_info.cpp
new file mode 100644 (file)
index 0000000..548e328
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * 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 <glib.h>
+#include <runtime_info.h>
+#include <sound_manager.h>
+#include <types_internal.h>
+#include <shared_vars.h>
+#include "system_info.h"
+
+#define CONNECTED              1
+#define NOT_CONNECTED  0
+
+bool ctx::system_info::get_audio_jack_state(int* state)
+{
+       int value = NOT_CONNECTED;
+       int err = runtime_info_get_value_int(RUNTIME_INFO_KEY_AUDIO_JACK_STATUS, &value);
+       IF_FAIL_RETURN(err == RUNTIME_INFO_ERROR_NONE, false);
+
+       *state = (value == NOT_CONNECTED ? NOT_CONNECTED : CONNECTED);
+
+       return true;
+}
+
+bool ctx::system_info::get_volume(int* system_volume, int* media_volume)
+{
+       int err;
+
+       err = sound_manager_get_volume(SOUND_TYPE_SYSTEM, system_volume);
+       IF_FAIL_RETURN(err == RUNTIME_INFO_ERROR_NONE, false);
+
+       err = sound_manager_get_volume(SOUND_TYPE_MEDIA, media_volume);
+       IF_FAIL_RETURN(err == RUNTIME_INFO_ERROR_NONE, false);
+
+       return true;
+}
+
+bool ctx::system_info::get_wifi_bssid(std::string& bssid)
+{
+#if 0
+       /* NOTE: This routine does not work, because the wifi API does not support multi-sessions in one process */
+       int err;
+       char *str_buf = NULL;
+       wifi_ap_h ap = NULL;
+
+       err = wifi_initialize();
+       IF_FAIL_RETURN_TAG(err == WIFI_ERROR_NONE, false, _W, "wifi_initialize() failed (%d)", err);
+
+       err = wifi_get_connected_ap(&ap);
+       if (err != WIFI_ERROR_NONE) {
+               _D("wifi_get_connected_ap() failed (%d)", err);
+               wifi_deinitialize();
+               return false;
+       }
+
+       wifi_ap_get_bssid(ap, &str_buf);
+       bssid = (str_buf != NULL ? str_buf : "");
+       g_free(str_buf);
+
+       wifi_ap_destroy(ap);
+       wifi_deinitialize();
+
+       return !bssid.empty();
+#endif
+       bssid = ctx::shared::wifi_bssid;
+       return true;
+}
diff --git a/src/statistics/shared/system_info.h b/src/statistics/shared/system_info.h
new file mode 100644 (file)
index 0000000..025a056
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * 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_SYSTEM_INFO_READER_H__
+#define __CONTEXT_SYSTEM_INFO_READER_H__
+
+#include <string>
+
+namespace ctx {
+       namespace system_info {
+               bool get_audio_jack_state(int* state);
+               bool get_volume(int* system_volume, int* media_volume);
+               bool get_wifi_bssid(std::string& bssid);
+       }
+}
+
+#endif /* __CONTEXT_SYSTEM_INFO_READER_H__ */
diff --git a/src/statistics/social/db_handle.cpp b/src/statistics/social/db_handle.cpp
new file mode 100644 (file)
index 0000000..ccdb1c2
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * 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 <contacts.h>
+#include <types_internal.h>
+#include <context_mgr.h>
+#include <db_mgr.h>
+#include "social_stats_types.h"
+#include "db_handle.h"
+
+ctx::social_db_handle::social_db_handle()
+{
+}
+
+ctx::social_db_handle::~social_db_handle()
+{
+}
+
+int ctx::social_db_handle::read(const char* subject, ctx::json filter)
+{
+       std::string query;
+
+       if (STR_EQ(subject, SOCIAL_SUBJ_FREQ_ADDRESS)) {
+               query = create_sql_freq_address(filter);
+
+       } else if (STR_EQ(subject, SOCIAL_SUBJ_FREQUENCY)) {
+               is_trigger_item = true;
+               query = create_sql_frequency(filter);
+       }
+
+       IF_FAIL_RETURN(!query.empty(), ERR_OPERATION_FAILED);
+
+       bool ret = execute_query(subject, filter, query.c_str());
+       IF_FAIL_RETURN(ret, ERR_OPERATION_FAILED);
+
+       return ERR_NONE;
+}
+
+std::string ctx::social_db_handle::create_where_clause(ctx::json filter)
+{
+       std::stringstream where_clause;
+       int comm_type = -1;
+
+       where_clause << stats_db_handle_base::create_where_clause(filter);
+
+       filter.get(NULL, SOCIAL_COMMUNICATION_TYPE, &comm_type);
+
+       switch(comm_type) {
+       case SOCIAL_COMMUNICATION_TYPE_CALL:
+               where_clause <<
+                       " AND " SOCIAL_PHONE_LOG_TYPE " >= " << CONTACTS_PLOG_TYPE_VOICE_INCOMMING <<
+                       " AND " SOCIAL_PHONE_LOG_TYPE " <= " << CONTACTS_PLOG_TYPE_VIDEO_BLOCKED;
+               break;
+       case SOCIAL_COMMUNICATION_TYPE_MESSAGE:
+               where_clause <<
+                       " AND " SOCIAL_PHONE_LOG_TYPE " >= " << CONTACTS_PLOG_TYPE_MMS_INCOMMING <<
+                       " AND " SOCIAL_PHONE_LOG_TYPE " <= " << CONTACTS_PLOG_TYPE_MMS_BLOCKED;
+               break;
+       default:
+               break;
+       }
+
+       return where_clause.str();
+}
+
+std::string ctx::social_db_handle::create_sql_freq_address(ctx::json filter)
+{
+       std::stringstream query;
+       int limit = DEFAULT_LIMIT;
+
+       filter.get(NULL, STATS_RESULT_SIZE, &limit);
+
+       query <<
+               "SELECT " SOCIAL_ADDRESS ", " \
+                       "COUNT(*) AS " STATS_TOTAL_COUNT ", " \
+                       "SUM(" STATS_DURATION ") AS " STATS_TOTAL_DURATION ", " \
+                       "MAX(" STATS_UNIV_TIME ") AS " STATS_LAST_TIME \
+               " FROM " SOCIAL_TABLE_CONTACT_LOG \
+               " WHERE " << create_where_clause(filter) <<
+               " GROUP BY " SOCIAL_ADDRESS \
+               " ORDER BY COUNT(*) DESC" \
+               " LIMIT " << limit;
+
+       return query.str();
+}
+
+std::string ctx::social_db_handle::create_sql_frequency(ctx::json filter)
+{
+       ctx::json filter_cleaned;
+       std::string week_str;
+       std::string time_of_day;
+       std::string address;
+
+       if (!filter.get(NULL, SOCIAL_ADDRESS, &address)) {
+               _E("Invalid parameter");
+               return "";
+       }
+
+       if (filter.get(NULL, STATS_DAY_OF_WEEK, &week_str))
+               filter_cleaned.set(NULL, STATS_DAY_OF_WEEK, week_str);
+
+       if (filter.get(NULL, STATS_TIME_OF_DAY, &time_of_day))
+               filter_cleaned.set(NULL, STATS_TIME_OF_DAY, time_of_day);
+
+       std::stringstream query;
+
+       query <<
+               "DELETE FROM " SOCIAL_TEMP_CONTACT_FREQ ";";
+
+       query <<
+               "INSERT INTO " SOCIAL_TEMP_CONTACT_FREQ \
+               " SELECT " SOCIAL_ADDRESS ", COUNT(*) AS " STATS_TOTAL_COUNT \
+               " FROM " SOCIAL_TABLE_CONTACT_LOG \
+               " WHERE " << create_where_clause(filter_cleaned) <<
+               " GROUP BY " SOCIAL_ADDRESS ";";
+
+       query <<
+               "INSERT OR IGNORE INTO " SOCIAL_TEMP_CONTACT_FREQ " (" SOCIAL_ADDRESS ")" \
+               " VALUES ('" << address << "');";
+
+       query <<
+               "SELECT S." SOCIAL_ADDRESS ", S." STATS_TOTAL_COUNT ", 1+COUNT(lesser." STATS_TOTAL_COUNT ") AS " STATS_RANK \
+               " FROM " SOCIAL_TEMP_CONTACT_FREQ " AS S" \
+               " LEFT JOIN " SOCIAL_TEMP_CONTACT_FREQ " AS lesser" \
+               " ON S." STATS_TOTAL_COUNT " < lesser." STATS_TOTAL_COUNT \
+               " WHERE S." SOCIAL_ADDRESS " = '" << address << "'";
+
+
+       return query.str();
+}
+
+void ctx::social_db_handle::reply_trigger_item(int error, ctx::json &json_result)
+{
+       IF_FAIL_VOID_TAG(STR_EQ(req_subject.c_str(), SOCIAL_SUBJ_FREQUENCY), _E, "Invalid subject");
+
+       ctx::json results;
+       std::string val_str;
+       int val;
+
+       json_result.get(NULL, SOCIAL_ADDRESS, &val_str);
+       results.set(NULL, SOCIAL_ADDRESS, val_str);
+       json_result.get(NULL, STATS_TOTAL_COUNT, &val);
+       results.set(NULL, STATS_TOTAL_COUNT, val);
+       json_result.get(NULL, STATS_RANK, &val);
+       results.set(NULL, STATS_RANK, val);
+
+       context_manager::reply_to_read(req_subject.c_str(), req_filter, error, results);
+}
diff --git a/src/statistics/social/db_handle.h b/src/statistics/social/db_handle.h
new file mode 100644 (file)
index 0000000..8254f41
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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_SOCIAL_DB_HANDLE_H__
+#define __CONTEXT_SOCIAL_DB_HANDLE_H__
+
+#include <string>
+#include <json.h>
+#include <db_handle_base.h>
+
+namespace ctx {
+       class social_db_handle : public stats_db_handle_base {
+               public:
+                       social_db_handle();
+                       ~social_db_handle();
+
+                       int read(const char* subject, ctx::json filter);
+
+               private:
+                       std::string create_where_clause(ctx::json filter);
+                       std::string create_sql_freq_address(ctx::json filter);
+                       std::string create_sql_frequency(ctx::json filter);
+                       void reply_trigger_item(int error, ctx::json &json_result);
+       };
+}
+
+#endif /* __CONTEXT_SOCIAL_DB_HANDLE_H__ */
diff --git a/src/statistics/social/log_aggregator.cpp b/src/statistics/social/log_aggregator.cpp
new file mode 100644 (file)
index 0000000..4e80053
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * 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 <json.h>
+#include <db_mgr.h>
+#include <timer_mgr.h>
+#include <types_internal.h>
+#include "social_stats_types.h"
+#include "log_aggregator.h"
+
+ctx::contact_log_aggregator::contact_log_aggregator()
+       : timer_id(-1)
+{
+       create_table();
+       timer_id = timer_manager::set_at(3, 0, timer_types::EVERYDAY, this, NULL);
+}
+
+ctx::contact_log_aggregator::~contact_log_aggregator()
+{
+       timer_manager::remove(timer_id);
+}
+
+void ctx::contact_log_aggregator::create_table()
+{
+       static bool done = false;
+       IF_FAIL_VOID(!done);
+
+       db_manager::create_table(0, SOCIAL_TABLE_CONTACT_LOG, SOCIAL_TABLE_CONTACT_LOG_COLUMNS, NULL, NULL);
+       db_manager::execute(0, SOCIAL_TEMP_CONTACT_FREQ_SQL, NULL);
+
+       done = true;
+}
+
+bool ctx::contact_log_aggregator::on_timer_expired(int timer, void* user_data)
+{
+       aggregate_contact_log();
+       return true;
+}
+
+void ctx::contact_log_aggregator::aggregate_contact_log()
+{
+       db_manager::execute(0,
+                       "SELECT IFNULL(MAX(" STATS_UNIV_TIME "),0) AS " STATS_LAST_TIME \
+                       ", (strftime('%s', 'now', 'localtime')) - (strftime('%s', 'now')) AS " TIME_DIFFERENCE \
+                       " FROM " SOCIAL_TABLE_CONTACT_LOG, this);
+}
+
+void ctx::contact_log_aggregator::on_query_result_received(unsigned int query_id, int error, std::vector<json>& records)
+{
+       IF_FAIL_VOID_TAG(!records.empty(), _E, "Invalid query result");
+
+       int last_time = 0;
+       records[0].get(NULL, STATS_LAST_TIME, &last_time);
+       records[0].get(NULL, TIME_DIFFERENCE, &time_diff);
+
+       _D("Last Time: %d / Local - UTC: %d", last_time, time_diff);
+
+       contacts_list_h list = NULL;
+
+       get_updated_contact_log_list(last_time, &list);
+       IF_FAIL_VOID(list);
+
+       remove_expired_log();
+       insert_contact_log_list(list);
+       destroy_contact_log_list(list);
+}
+
+void ctx::contact_log_aggregator::get_updated_contact_log_list(int last_time, contacts_list_h *list)
+{
+       contacts_filter_h filter = NULL;
+       contacts_query_h query = NULL;
+
+       int err = contacts_connect();
+       IF_FAIL_VOID_TAG(err == CONTACTS_ERROR_NONE, _E, "contacts_connect() failed");
+
+       err = contacts_filter_create(_contacts_phone_log._uri, &filter);
+       IF_FAIL_CATCH_TAG(err == CONTACTS_ERROR_NONE, _E, "contacts_filter_create() failed");
+
+       contacts_filter_add_int(filter, _contacts_phone_log.log_type, CONTACTS_MATCH_GREATER_THAN_OR_EQUAL, CONTACTS_PLOG_TYPE_VOICE_INCOMMING);
+       contacts_filter_add_operator(filter, CONTACTS_FILTER_OPERATOR_AND);
+       contacts_filter_add_int(filter, _contacts_phone_log.log_type, CONTACTS_MATCH_LESS_THAN_OR_EQUAL, CONTACTS_PLOG_TYPE_MMS_BLOCKED);
+       contacts_filter_add_operator(filter, CONTACTS_FILTER_OPERATOR_AND);
+       contacts_filter_add_int(filter, _contacts_phone_log.log_time , CONTACTS_MATCH_GREATER_THAN, last_time);
+       contacts_filter_add_operator(filter, CONTACTS_FILTER_OPERATOR_AND);
+
+       err = contacts_query_create(_contacts_phone_log._uri, &query);
+       IF_FAIL_CATCH_TAG(err == CONTACTS_ERROR_NONE, _E, "contacts_query_create() failed");
+
+       contacts_query_set_filter(query, filter);
+       contacts_query_set_sort(query, _contacts_phone_log.log_time, true);
+
+       err = contacts_db_get_records_with_query(query, 0, 0, list);
+       IF_FAIL_CATCH_TAG(err == CONTACTS_ERROR_NONE, _E, "contacts_db_get_records_with_query() failed");
+
+CATCH:
+       if (filter)
+               contacts_filter_destroy(filter);
+       if (query)
+               contacts_query_destroy(query);
+}
+
+void ctx::contact_log_aggregator::destroy_contact_log_list(contacts_list_h list)
+{
+       if (list)
+               contacts_list_destroy(list, true);
+
+       contacts_disconnect();
+}
+
+void ctx::contact_log_aggregator::insert_contact_log_list(contacts_list_h list)
+{
+       IF_FAIL_VOID(contacts_list_first(list) == CONTACTS_ERROR_NONE);
+
+       do {
+               contacts_record_h record = NULL;
+               contacts_list_get_current_record_p(list, &record);
+               if (record == NULL) break;
+
+               ctx::json data;
+
+               char* address = NULL;
+               int log_type;
+               int duration = 0;
+               int accesstime = 0;
+
+               contacts_record_get_str_p(record, _contacts_phone_log.address, &address);
+
+               if (!address) {
+                       _W("Getting address failed");
+                       continue;
+               }
+
+               contacts_record_get_int(record, _contacts_phone_log.log_type, &log_type);
+               contacts_record_get_int(record, _contacts_phone_log.extra_data1, &duration);
+               contacts_record_get_int(record, _contacts_phone_log.log_time, &accesstime);
+
+               data.set(NULL, SOCIAL_ADDRESS, address);
+               data.set(NULL, SOCIAL_PHONE_LOG_TYPE, log_type);
+               data.set(NULL, STATS_DURATION, duration);
+               data.set(NULL, STATS_UNIV_TIME, accesstime);
+               data.set(NULL, STATS_LOCAL_TIME, accesstime + time_diff);
+
+               db_manager::insert(0, SOCIAL_TABLE_CONTACT_LOG, data, NULL);
+
+       } while(contacts_list_next(list) == CONTACTS_ERROR_NONE);
+}
+
+void ctx::contact_log_aggregator::remove_expired_log()
+{
+       std::stringstream query;
+       query << "DELETE FROM " SOCIAL_TABLE_CONTACT_LOG " WHERE " \
+               STATS_UNIV_TIME " < strftime('%s', 'now') - " << LOG_RETENTION_PERIOD;
+       db_manager::execute(0, query.str().c_str(), NULL);
+}
diff --git a/src/statistics/social/log_aggregator.h b/src/statistics/social/log_aggregator.h
new file mode 100644 (file)
index 0000000..57c154f
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * 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_SOCIAL_CONTACT_LOG_AGGREGATOR_H__
+#define __CONTEXT_SOCIAL_CONTACT_LOG_AGGREGATOR_H__
+
+#include <contacts.h>
+#include <db_listener_iface.h>
+#include <timer_listener_iface.h>
+
+namespace ctx {
+
+       class contact_log_aggregator : public db_listener_iface, public timer_listener_iface {
+               private:
+                       int timer_id;
+                       int time_diff;
+                       void create_table();
+                       void get_updated_contact_log_list(int last_time, contacts_list_h *list);
+                       void insert_contact_log_list(contacts_list_h list);
+                       void destroy_contact_log_list(contacts_list_h list);
+                       void remove_expired_log();
+
+               public:
+                       contact_log_aggregator();
+                       ~contact_log_aggregator();
+
+                       void aggregate_contact_log();
+
+                       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);
+                       bool on_timer_expired(int timer_id, void* user_data);
+
+       };      /* class phone_contact_log_aggregator */
+
+}      /* namespace ctx */
+
+#endif
diff --git a/src/statistics/social/social_stats_provider.cpp b/src/statistics/social/social_stats_provider.cpp
new file mode 100644 (file)
index 0000000..92bb856
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * 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 <context_mgr.h>
+#include "social_stats_provider.h"
+#include "db_handle.h"
+#include "log_aggregator.h"
+
+static ctx::contact_log_aggregator *aggregator = NULL;
+
+ctx::social_statistics_provider *ctx::social_statistics_provider::__instance = NULL;
+
+ctx::social_statistics_provider::social_statistics_provider()
+{
+}
+
+ctx::social_statistics_provider::~social_statistics_provider()
+{
+       delete aggregator;
+}
+
+ctx::context_provider_iface *ctx::social_statistics_provider::create(void *data)
+{
+       IF_FAIL_RETURN(!__instance, __instance);
+
+       __instance = new(std::nothrow) social_statistics_provider();
+       IF_FAIL_RETURN_TAG(__instance, NULL, _E, "Memory allocation failed");
+
+       _I(BLUE("Created"));
+
+       if (!__instance->init()) {
+               destroy(data);
+               return NULL;
+       }
+
+       return __instance;
+}
+
+void ctx::social_statistics_provider::destroy(void *data)
+{
+       IF_FAIL_VOID(__instance);
+       delete __instance;
+       __instance = NULL;
+       _I(BLUE("Destroyed"));
+}
+
+bool ctx::social_statistics_provider::is_supported(const char* subject)
+{
+       return true;
+}
+
+void ctx::social_statistics_provider::submit_trigger_item()
+{
+       context_manager::register_trigger_item(SOCIAL_SUBJ_FREQUENCY, OPS_READ,
+                       "{" TRIG_DEF_RANK "," TRIG_DEF_TOTAL_COUNT "}",
+                       "{"
+                               "\"Address\":{\"type\":\"string\"},"
+                               TRIG_DEF_TIME_OF_DAY "," TRIG_DEF_DAY_OF_WEEK
+                       "}");
+}
+
+bool ctx::social_statistics_provider::init()
+{
+       aggregator = new(std::nothrow) contact_log_aggregator();
+       IF_FAIL_RETURN_TAG(aggregator, false, _E, "Memory allocation failed");
+       return true;
+}
+
+int ctx::social_statistics_provider::subscribe(const char* subject, ctx::json option, ctx::json* request_result)
+{
+       return ERR_NOT_SUPPORTED;
+}
+
+int ctx::social_statistics_provider::unsubscribe(const char* subject, ctx::json option)
+{
+       return ERR_NOT_SUPPORTED;
+}
+
+int ctx::social_statistics_provider::read(const char* subject, ctx::json option, ctx::json* request_result)
+{
+       ctx::social_db_handle *handle = new(std::nothrow) ctx::social_db_handle();
+       IF_FAIL_RETURN_TAG(handle, ERR_OPERATION_FAILED, _E, "Memory allocation failed");
+
+       int err = handle->read(subject, option);
+       if (err != ERR_NONE) {
+               delete handle;
+               return err;
+       }
+
+       return ERR_NONE;
+}
+
+int ctx::social_statistics_provider::write(const char* subject, ctx::json data, ctx::json* request_result)
+{
+       return ERR_NOT_SUPPORTED;
+}
diff --git a/src/statistics/social/social_stats_provider.h b/src/statistics/social/social_stats_provider.h
new file mode 100644 (file)
index 0000000..64ab059
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * 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_SOCIAL_STATS_PROVIDER_H__
+#define __CONTEXT_SOCIAL_STATS_PROVIDER_H__
+
+#include <provider_iface.h>
+#include "social_stats_types.h"
+
+namespace ctx {
+
+       class social_statistics_provider : public context_provider_iface {
+       public:
+               static context_provider_iface *create(void *data);
+               static void destroy(void *data);
+               static bool is_supported(const char *subject);
+               static void submit_trigger_item();
+
+               int subscribe(const char* subject, ctx::json option, ctx::json* request_result);
+               int unsubscribe(const char* subject, ctx::json option);
+               int read(const char* subject, ctx::json option, ctx::json* request_result);
+               int write(const char* subject, ctx::json data, ctx::json* request_result);
+
+       private:
+               static social_statistics_provider *__instance;
+
+               social_statistics_provider();
+               ~social_statistics_provider();
+               bool init();
+
+       };      /* class social_statistics_provider */
+
+}      /* namespace ctx */
+
+#endif /* __CONTEXT_SOCIAL_STATS_PROVIDER_H__ */
diff --git a/src/statistics/social/social_stats_types.h b/src/statistics/social/social_stats_types.h
new file mode 100644 (file)
index 0000000..b627c67
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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_SOCIAL_STATS_TYPES_H__
+#define __CONTEXT_SOCIAL_STATS_TYPES_H__
+
+#include <common_types.h>
+
+#define SOCIAL_HISTORY_PRIV                    "callhistory.read"
+#define SOCIAL_SUBJ_FREQ_ADDRESS       "stats/contact/often"
+#define SOCIAL_SUBJ_FREQUENCY          "stats/contact/frequency"
+
+#define SOCIAL_TABLE_CONTACT_LOG       "Log_Contact"
+#define SOCIAL_TABLE_CONTACT_LOG_COLUMNS \
+       "Address TEXT NOT NULL, PLogType INTEGER NOT NULL, " \
+       "Duration INTEGER NOT NULL DEFAULT 0, " \
+       "UTC TIMESTAMP DEFAULT (strftime('%s', 'now')), " \
+       "LocalTime TIMESTAMP DEFAULT (strftime('%s', 'now', 'localtime'))"
+
+#define SOCIAL_TEMP_CONTACT_FREQ       "Temp_ContactFreq"
+#define SOCIAL_TEMP_CONTACT_FREQ_SQL \
+       "CREATE TABLE IF NOT EXISTS " SOCIAL_TEMP_CONTACT_FREQ \
+       " (Address TEXT NOT NULL UNIQUE, TotalCount INTEGER DEFAULT 0);"
+
+#define SOCIAL_COMMUNICATION_TYPE      "CommunicationType"
+#define SOCIAL_ADDRESS                         "Address"
+#define SOCIAL_PHONE_LOG_TYPE          "PLogType"
+#define TIME_DIFFERENCE                                "TimeDIff"
+
+enum _social_comm_type_e {
+       SOCIAL_COMMUNICATION_TYPE_CALL = 1,
+       SOCIAL_COMMUNICATION_TYPE_MESSAGE,
+       SOCIAL_COMMUNICATION_TYPE_ALL
+};
+
+#endif
diff --git a/src/statistics/statistics_context_provider.cpp b/src/statistics/statistics_context_provider.cpp
new file mode 100644 (file)
index 0000000..62fea4d
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * 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 <context_mgr.h>
+#include <provider_iface.h>
+#include <statistics_context_provider.h>
+
+#include "app/app_stats_provider.h"
+
+#ifdef _MOBILE_
+#include "media/media_stats_provider.h"
+#include "social/social_stats_provider.h"
+#endif
+
+#ifdef _TV_
+#include "media/media_stats_provider.h"
+#endif
+
+template<typename provider>
+void register_provider(const char *subject, const char *privilege)
+{
+       if (!provider::is_supported(subject))
+               return;
+
+       ctx::context_provider_info provider_info(provider::create, provider::destroy, NULL, privilege);
+       ctx::context_manager::register_provider(subject, provider_info);
+}
+
+EXTAPI bool ctx::init_statistics_context_provider()
+{
+       app_statistics_provider::create(NULL);
+       register_provider<app_statistics_provider>(APP_SUBJ_RECENTLY_USED, APP_HISTORY_PRIV);
+       register_provider<app_statistics_provider>(APP_SUBJ_FREQUENTLY_USED, APP_HISTORY_PRIV);
+       register_provider<app_statistics_provider>(APP_SUBJ_RARELY_USED, APP_HISTORY_PRIV);
+       register_provider<app_statistics_provider>(APP_SUBJ_PEAK_TIME, APP_HISTORY_PRIV);
+       register_provider<app_statistics_provider>(APP_SUBJ_COMMON_SETTING, APP_HISTORY_PRIV);
+       register_provider<app_statistics_provider>(APP_SUBJ_FREQUENCY, APP_HISTORY_PRIV);
+       app_statistics_provider::submit_trigger_item();
+
+#ifdef _MOBILE_
+       media_statistics_provider::create(NULL);
+       register_provider<media_statistics_provider>(MEDIA_SUBJ_PEAK_TIME_FOR_MUSIC, MEDIA_HISTORY_PRIV);
+       register_provider<media_statistics_provider>(MEDIA_SUBJ_PEAK_TIME_FOR_VIDEO, MEDIA_HISTORY_PRIV);
+       register_provider<media_statistics_provider>(MEDIA_SUBJ_COMMON_SETTING_FOR_MUSIC, MEDIA_HISTORY_PRIV);
+       register_provider<media_statistics_provider>(MEDIA_SUBJ_COMMON_SETTING_FOR_VIDEO, MEDIA_HISTORY_PRIV);
+       register_provider<media_statistics_provider>(MEDIA_SUBJ_MUSIC_FREQUENCY, MEDIA_HISTORY_PRIV);
+       register_provider<media_statistics_provider>(MEDIA_SUBJ_VIDEO_FREQUENCY, MEDIA_HISTORY_PRIV);
+       media_statistics_provider::submit_trigger_item();
+
+       social_statistics_provider::create(NULL);
+       register_provider<social_statistics_provider>(SOCIAL_SUBJ_FREQ_ADDRESS, SOCIAL_HISTORY_PRIV);
+       register_provider<social_statistics_provider>(SOCIAL_SUBJ_FREQUENCY, SOCIAL_HISTORY_PRIV);
+       social_statistics_provider::submit_trigger_item();
+#endif
+
+#ifdef _TV_
+       media_statistics_provider::create(NULL);
+       register_provider<media_statistics_provider>(MEDIA_SUBJ_PEAK_TIME_FOR_MUSIC, MEDIA_HISTORY_PRIV);
+       register_provider<media_statistics_provider>(MEDIA_SUBJ_PEAK_TIME_FOR_VIDEO, MEDIA_HISTORY_PRIV);
+       register_provider<media_statistics_provider>(MEDIA_SUBJ_COMMON_SETTING_FOR_MUSIC, MEDIA_HISTORY_PRIV);
+       register_provider<media_statistics_provider>(MEDIA_SUBJ_COMMON_SETTING_FOR_VIDEO, MEDIA_HISTORY_PRIV);
+       register_provider<media_statistics_provider>(MEDIA_SUBJ_MUSIC_FREQUENCY, MEDIA_HISTORY_PRIV);
+       register_provider<media_statistics_provider>(MEDIA_SUBJ_VIDEO_FREQUENCY, MEDIA_HISTORY_PRIV);
+       media_statistics_provider::submit_trigger_item();
+#endif
+
+       return true;
+}