From: Somin Kim Date: Thu, 7 Apr 2016 01:12:25 +0000 (+0900) Subject: Applying Tizen C++ coding style to statistics context provider(except prediction) X-Git-Tag: submit/tizen/20160503.015801^2~27 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f1be648e515b6be9fc9a717b5df4bc8eeb5b431f;p=platform%2Fcore%2Fcontext%2Fcontext-provider.git Applying Tizen C++ coding style to statistics context provider(except prediction) Change-Id: If4cb6ec05b0775691d5c82df3e6ce9dc8a2dba7d Signed-off-by: Somin Kim --- diff --git a/src/statistics/StatisticsContextProvider.cpp b/src/statistics/StatisticsContextProvider.cpp new file mode 100644 index 0000000..762cb60 --- /dev/null +++ b/src/statistics/StatisticsContextProvider.cpp @@ -0,0 +1,89 @@ +/* + * 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 +#include +#include +#include + +#include "app/AppStatisticsProvider.h" + +#ifndef _DISABLE_PREDICTION_ENGINE_ +// include prediction engine header files here +#endif + +#ifdef _MOBILE_ +#include "media/MediaStatisticsProvider.h" +#include "social/SocialStatisticsProvider.h" +#endif + +#ifdef _TV_ +#include "media/MediaStatisticsProvider.h" +#endif + +template +void registerProvider(const char *subject, const char *privilege) +{ + if (!Provider::isSupported(subject)) + return; + + ctx::ContextProviderInfo providerInfo(Provider::create, Provider::destroy, NULL, privilege); + ctx::context_manager::registerProvider(subject, providerInfo); +} + +EXTAPI bool ctx::initStatisticsContextProvider() +{ + AppStatisticsProvider::create(NULL); + registerProvider(APP_SUBJ_RECENTLY_USED, APP_HISTORY_PRIV); + registerProvider(APP_SUBJ_FREQUENTLY_USED, APP_HISTORY_PRIV); + registerProvider(APP_SUBJ_RARELY_USED, APP_HISTORY_PRIV); + registerProvider(APP_SUBJ_PEAK_TIME, APP_HISTORY_PRIV); + registerProvider(APP_SUBJ_COMMON_SETTING, APP_HISTORY_PRIV); + registerProvider(APP_SUBJ_FREQUENCY, APP_HISTORY_PRIV); + AppStatisticsProvider::submitTriggerItem(); + +#ifndef _DISABLE_PREDICTION_ENGINE_ +// initialize the prediction engine here +#endif + +#ifdef _MOBILE_ + MediaStatisticsProvider::create(NULL); + registerProvider(MEDIA_SUBJ_PEAK_TIME_FOR_MUSIC, MEDIA_HISTORY_PRIV); + registerProvider(MEDIA_SUBJ_PEAK_TIME_FOR_VIDEO, MEDIA_HISTORY_PRIV); + registerProvider(MEDIA_SUBJ_COMMON_SETTING_FOR_MUSIC, MEDIA_HISTORY_PRIV); + registerProvider(MEDIA_SUBJ_COMMON_SETTING_FOR_VIDEO, MEDIA_HISTORY_PRIV); + registerProvider(MEDIA_SUBJ_MUSIC_FREQUENCY, MEDIA_HISTORY_PRIV); + registerProvider(MEDIA_SUBJ_VIDEO_FREQUENCY, MEDIA_HISTORY_PRIV); + MediaStatisticsProvider::submitTriggerItem(); + + SocialStatisticsProvider::create(NULL); + registerProvider(SOCIAL_SUBJ_FREQ_ADDRESS, SOCIAL_HISTORY_PRIV); + registerProvider(SOCIAL_SUBJ_FREQUENCY, SOCIAL_HISTORY_PRIV); + SocialStatisticsProvider::submitTriggerItem(); +#endif + +#ifdef _TV_ + MediaStatisticsProvider::create(NULL); + registerProvider(MEDIA_SUBJ_PEAK_TIME_FOR_MUSIC, MEDIA_HISTORY_PRIV); + registerProvider(MEDIA_SUBJ_PEAK_TIME_FOR_VIDEO, MEDIA_HISTORY_PRIV); + registerProvider(MEDIA_SUBJ_COMMON_SETTING_FOR_MUSIC, MEDIA_HISTORY_PRIV); + registerProvider(MEDIA_SUBJ_COMMON_SETTING_FOR_VIDEO, MEDIA_HISTORY_PRIV); + registerProvider(MEDIA_SUBJ_MUSIC_FREQUENCY, MEDIA_HISTORY_PRIV); + registerProvider(MEDIA_SUBJ_VIDEO_FREQUENCY, MEDIA_HISTORY_PRIV); + MediaStatisticsProvider::submitTriggerItem(); +#endif + + return true; +} diff --git a/src/statistics/app/ActiveWindowMonitor.cpp b/src/statistics/app/ActiveWindowMonitor.cpp new file mode 100644 index 0000000..db8b753 --- /dev/null +++ b/src/statistics/app/ActiveWindowMonitor.cpp @@ -0,0 +1,148 @@ +/* + * 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 +#include +#include + +#include +#include +#include "../shared/SystemInfo.h" +#include "AppStatisticsTypes.h" +#include "ActiveWindowMonitor.h" + +/* Active window changes frequently. + * We thus consider the apps being foregrounded at least 3 secs */ +#define ONE_DAY_IN_SEC 86400 + +ctx::AppUseMonitor::AppUseMonitor() : + __signalId(-1), + __lastCleanupTime(0), + __dbusWatcher(DBusType::SYSTEM) +{ + __startLogging(); +} + +ctx::AppUseMonitor::~AppUseMonitor() +{ + __stopLogging(); +} + +bool ctx::AppUseMonitor::__startLogging() +{ + __signalId = __dbusWatcher.watch(NULL, "/Org/Tizen/Aul/AppStatus", "org.tizen.aul.AppStatus", "AppStatusChange", this); + _D("Active window monitoring started (%lld)", __signalId); + return (__signalId > 0); +} + +void ctx::AppUseMonitor::__stopLogging() +{ + if (__signalId > 0) { + __dbusWatcher.unwatch(__signalId); + _D("Active window monitoring stopped"); + } +} + +void ctx::AppUseMonitor::onSignal(const char* sender, const char* path, const char* iface, const char* name, GVariant* param) +{ + gint pid = 0; + const gchar *appId = NULL; + const gchar *pkgId = NULL; + const gchar *status = NULL; + const gchar *type = NULL; + + g_variant_get(param, "(i&s&s&s&s)", &pid, &appId, &pkgId, &status, &type); + _D("AppEvent: %s, %s, %s", appId, status, type); + + IF_FAIL_VOID(appId && status && type); + IF_FAIL_VOID(STR_EQ(type, "uiapp") && !__isSkippable(appId)); + + if (STR_EQ(status, "fg")) { + __createRecord(appId); + } else if (STR_EQ(status, "bg")) { + __finishRecord(appId); + __removeExpired(); + } +} + +void ctx::AppUseMonitor::__createRecord(std::string appId) +{ + int audioJack; + int systemVolume; + int mediaVolume; + std::string bssid; + Json data; + data.set(NULL, STATS_APP_ID, appId); + + if (ctx::system_info::getAudioJackState(&audioJack)) + data.set(NULL, STATS_AUDIO_JACK, audioJack); + + if (ctx::system_info::getVolume(&systemVolume, &mediaVolume)) { + data.set(NULL, STATS_SYSTEM_VOLUME, systemVolume); + data.set(NULL, STATS_MEDIA_VOLUME, mediaVolume); + } + + if (ctx::system_info::getWifiBssid(bssid)) + data.set(NULL, STATS_BSSID, bssid); + + __dbManager.insert(0, APP_TABLE_USAGE_LOG, data, NULL); +} + +void ctx::AppUseMonitor::__finishRecord(std::string appId) +{ + /* TODO: It might be necessary to update system status here */ + 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 " = '" << appId << "'" \ + " AND " STATS_DURATION " = 0)"; + __dbManager.execute(0, query.str().c_str(), NULL); +} + +bool ctx::AppUseMonitor::__isSkippable(std::string appId) +{ + /* TODO: circular cache */ + app_info_h appInfo = NULL; + int err = app_manager_get_app_info(appId.c_str(), &appInfo); + IF_FAIL_RETURN_TAG(err == APP_MANAGER_ERROR_NONE && appInfo, true, _E, "app_manager_get_app_info() failed"); + + bool nodisp = false; + err = app_info_is_nodisplay(appInfo, &nodisp); + if (err != APP_MANAGER_ERROR_NONE) { + app_info_destroy(appInfo); + _E("app_info_is_nodisplay() failed"); + return true; + } + + app_info_destroy(appInfo); + return nodisp; +} + +void ctx::AppUseMonitor::__removeExpired() +{ + int timestamp = static_cast(time(NULL)); + IF_FAIL_VOID(timestamp - __lastCleanupTime >= ONE_DAY_IN_SEC); + + __lastCleanupTime = timestamp; + + std::stringstream query; + query << "DELETE FROM " APP_TABLE_USAGE_LOG " WHERE " \ + STATS_UNIV_TIME " < strftime('%s', 'now') - " << LOG_RETENTION_PERIOD; + __dbManager.execute(0, query.str().c_str(), NULL); +} diff --git a/src/statistics/app/ActiveWindowMonitor.h b/src/statistics/app/ActiveWindowMonitor.h new file mode 100644 index 0000000..64f0d34 --- /dev/null +++ b/src/statistics/app/ActiveWindowMonitor.h @@ -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_STATS_APP_USE_MONITOR_H_ +#define _CONTEXT_STATS_APP_USE_MONITOR_H_ + +#include +#include +#include +#include + +namespace ctx { + + class AppUseMonitor : public IDBusSignalListener { + private: + int64_t __signalId; + int __lastCleanupTime; + DBusSignalWatcher __dbusWatcher; + DatabaseManager __dbManager; + + bool __startLogging(void); + void __stopLogging(void); + + bool __isSkippable(std::string appId); + void __createRecord(std::string appId); + void __finishRecord(std::string appId); + void __removeExpired(); + void onSignal(const char *sender, const char *path, const char *iface, const char *name, GVariant *param); + + public: + AppUseMonitor(); + ~AppUseMonitor(); + }; /* class AppUseMonitor */ + +} /* namespace ctx */ + +#endif /* End of _CONTEXT_STATS_APP_USE_MONITOR_H_ */ diff --git a/src/statistics/app/AppStatisticsProvider.cpp b/src/statistics/app/AppStatisticsProvider.cpp new file mode 100644 index 0000000..49fe480 --- /dev/null +++ b/src/statistics/app/AppStatisticsProvider.cpp @@ -0,0 +1,128 @@ +/* + * 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 +#include +#include +#include "AppStatisticsProvider.h" +#include "DbHandle.h" + +#include "DbInit.h" +#include "InstallMonitor.h" +#include "ActiveWindowMonitor.h" + +static ctx::AppInstallMonitor *__installMon = NULL; +static ctx::AppUseMonitor *__launchMon = NULL; + +ctx::AppStatisticsProvider *ctx::AppStatisticsProvider::__instance = NULL; + +ctx::AppStatisticsProvider::AppStatisticsProvider() +{ +} + +ctx::AppStatisticsProvider::~AppStatisticsProvider() +{ + delete __installMon; + delete __launchMon; + __installMon = NULL; + __launchMon = NULL; +} + +ctx::ContextProviderBase *ctx::AppStatisticsProvider::create(void *data) +{ + IF_FAIL_RETURN(!__instance, __instance); + + __instance = new(std::nothrow) AppStatisticsProvider(); + IF_FAIL_RETURN_TAG(__instance, NULL, _E, "Memory allocation failed"); + + if (!__instance->__init()) { + destroy(data); + return NULL; + } + + _I(BLUE("Created")); + return __instance; +} + +void ctx::AppStatisticsProvider::destroy(void *data) +{ + IF_FAIL_VOID(__instance); + delete __instance; + __instance = NULL; + _I(BLUE("Destroyed")); +} + +bool ctx::AppStatisticsProvider::isSupported(const char* subject) +{ + return true; +} + +void ctx::AppStatisticsProvider::submitTriggerItem() +{ + context_manager::registerTriggerItem(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::AppStatisticsProvider::__init() +{ + AppDbInitializer *initializer = new(std::nothrow) AppDbInitializer(); + IF_FAIL_RETURN_TAG(initializer, false, _E, "Memory allocation failed"); + + __installMon = new(std::nothrow) ctx::AppInstallMonitor(); + __launchMon = new(std::nothrow) ctx::AppUseMonitor(); + IF_FAIL_CATCH_TAG(__installMon && __launchMon, _E, "Memory allocation failed"); + return true; + +CATCH: + delete __installMon; + delete __launchMon; + __installMon = NULL; + __launchMon = NULL; + return false; +} + +int ctx::AppStatisticsProvider::subscribe(const char* subject, ctx::Json option, ctx::Json* requestResult) +{ + return ERR_NOT_SUPPORTED; +} + +int ctx::AppStatisticsProvider::unsubscribe(const char* subject, ctx::Json option) +{ + return ERR_NOT_SUPPORTED; +} + +int ctx::AppStatisticsProvider::read(const char* subject, ctx::Json option, ctx::Json* requestResult) +{ + ctx::AppDbHandle *handle = new(std::nothrow) ctx::AppDbHandle(); + 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::AppStatisticsProvider::write(const char* subject, ctx::Json data, ctx::Json* requestResult) +{ + return ERR_NOT_SUPPORTED; +} diff --git a/src/statistics/app/AppStatisticsProvider.h b/src/statistics/app/AppStatisticsProvider.h new file mode 100644 index 0000000..1d5bb2d --- /dev/null +++ b/src/statistics/app/AppStatisticsProvider.h @@ -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_STATS_APP_STATS_PROVIDER_H_ +#define _CONTEXT_STATS_APP_STATS_PROVIDER_H_ + +#include +#include "AppStatisticsTypes.h" + +namespace ctx { + + class AppStatisticsProvider : public ContextProviderBase { + public: + static ContextProviderBase *create(void *data); + static void destroy(void *data); + static bool isSupported(const char *subject); + static void submitTriggerItem(); + + int subscribe(const char *subject, ctx::Json option, ctx::Json *requestResult); + int unsubscribe(const char *subject, ctx::Json option); + int read(const char *subject, ctx::Json option, ctx::Json *requestResult); + int write(const char *subject, ctx::Json data, ctx::Json *requestResult); + + private: + static AppStatisticsProvider *__instance; + + AppStatisticsProvider(); + ~AppStatisticsProvider(); + bool __init(); + + }; /* class AppStatisticsProvider */ + +} /* namespace ctx */ + +#endif /* End of _CONTEXT_STATS_APP_STATS_PROVIDER_H_ */ diff --git a/src/statistics/app/AppStatisticsTypes.h b/src/statistics/app/AppStatisticsTypes.h new file mode 100644 index 0000000..aa8f2d2 --- /dev/null +++ b/src/statistics/app/AppStatisticsTypes.h @@ -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_STATS_APP_TYPES_H_ +#define _CONTEXT_STATS_APP_TYPES_H_ + +#include "../shared/CommonTypes.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 /* End of _CONTEXT_STATS_APP_TYPES_H_ */ diff --git a/src/statistics/app/DbHandle.cpp b/src/statistics/app/DbHandle.cpp new file mode 100644 index 0000000..bf58209 --- /dev/null +++ b/src/statistics/app/DbHandle.cpp @@ -0,0 +1,217 @@ +/* + * 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 +#include +#include +#include "AppStatisticsTypes.h" +#include "DbHandle.h" + +ctx::AppDbHandle::AppDbHandle() +{ +} + +ctx::AppDbHandle::~AppDbHandle() +{ +} + +int ctx::AppDbHandle::read(const char* subject, ctx::Json filter) +{ + std::string query; + + if (STR_EQ(subject, APP_SUBJ_RECENTLY_USED)) { + query = createSqlRecentlyUsed(filter); + + } else if (STR_EQ(subject, APP_SUBJ_FREQUENTLY_USED)) { + query = createSqlFrequentlyUsed(filter); + + } else if (STR_EQ(subject, APP_SUBJ_RARELY_USED)) { + query = createSqlRarelyUsed(filter); + + } else if (STR_EQ(subject, APP_SUBJ_PEAK_TIME)) { + query = createSqlPeakTime(filter); + + } else if (STR_EQ(subject, APP_SUBJ_COMMON_SETTING)) { + query = createSqlCommonSetting(filter); + + } else if (STR_EQ(subject, APP_SUBJ_FREQUENCY)) { + __isTriggerItem = true; + query = createSqlFrequency(filter); + } + + IF_FAIL_RETURN(!query.empty(), ERR_OPERATION_FAILED); + + bool ret = executeQuery(subject, filter, query.c_str()); + IF_FAIL_RETURN(ret, ERR_OPERATION_FAILED); + + return ERR_NONE; +} + +std::string ctx::AppDbHandle::createWhereClauseWithDeviceStatus(ctx::Json filter) +{ + std::stringstream whereClause; + std::string bssid; + int audioJack; + + whereClause << StatsDbHandleBase::createWhereClause(filter); + + if (filter.get(NULL, STATS_BSSID, &bssid)) + whereClause << " AND " STATS_BSSID " = '" << bssid << "'"; + + if (filter.get(NULL, STATS_AUDIO_JACK, &audioJack)) + whereClause << " AND " STATS_AUDIO_JACK " = " << audioJack; + + return whereClause.str(); +} + +std::string ctx::AppDbHandle::createSqlPeakTime(ctx::Json filter) +{ + return StatsDbHandleBase::createSqlPeakTime(filter, APP_TABLE_USAGE_LOG, createWhereClause(filter)); +} + +std::string ctx::AppDbHandle::createSqlCommonSetting(ctx::Json filter) +{ + return StatsDbHandleBase::createSqlCommonSetting(filter, APP_TABLE_USAGE_LOG, createWhereClause(filter)); +} + +std::string ctx::AppDbHandle::createSqlFrequency(ctx::Json filter) +{ + ctx::Json filterCleaned; + std::string weekStr; + std::string timeOfDay; + std::string appId; + + if (!filter.get(NULL, STATS_APP_ID, &appId)) { + _E("Invalid parameter"); + return ""; + } + + if (filter.get(NULL, STATS_DAY_OF_WEEK, &weekStr)) + filterCleaned.set(NULL, STATS_DAY_OF_WEEK, weekStr); + + if (filter.get(NULL, STATS_TIME_OF_DAY, &timeOfDay)) + filterCleaned.set(NULL, STATS_TIME_OF_DAY, timeOfDay); + + std::string whereClause = createWhereClause(filterCleaned); + + 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 " << whereClause << + " GROUP BY " STATS_APP_ID ";"; + + query << + "INSERT OR IGNORE INTO " APP_TEMP_USAGE_FREQ " (" STATS_APP_ID ")" \ + " VALUES ('" << appId << "');"; + + 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 " = '" << appId << "'"; + + return query.str(); +} + +std::string ctx::AppDbHandle::createSqlRecentlyUsed(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 " << createWhereClauseWithDeviceStatus(filter) << + " GROUP BY " STATS_APP_ID \ + " ORDER BY MAX(" STATS_UNIV_TIME ") DESC" \ + " LIMIT " << limit; + + return query.str(); +} + +std::string ctx::AppDbHandle::createSqlFrequentlyUsed(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 " << createWhereClauseWithDeviceStatus(filter) << + " GROUP BY " STATS_APP_ID \ + " ORDER BY COUNT(*) DESC" \ + " LIMIT " << limit; + + return query.str(); +} + +std::string ctx::AppDbHandle::createSqlRarelyUsed(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 " << createWhereClauseWithDeviceStatus(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::AppDbHandle::replyTriggerItem(int error, ctx::Json &jsonResult) +{ + IF_FAIL_VOID_TAG(STR_EQ(__reqSubject.c_str(), APP_SUBJ_FREQUENCY), _E, "Invalid subject"); + + ctx::Json results; + std::string valStr; + int val; + + jsonResult.get(NULL, STATS_APP_ID, &valStr); + results.set(NULL, STATS_APP_ID, valStr); + jsonResult.get(NULL, STATS_TOTAL_COUNT, &val); + results.set(NULL, STATS_TOTAL_COUNT, val); + jsonResult.get(NULL, STATS_RANK, &val); + results.set(NULL, STATS_RANK, val); + + context_manager::replyToRead(__reqSubject.c_str(), __reqFilter, error, results); +} diff --git a/src/statistics/app/DbHandle.h b/src/statistics/app/DbHandle.h new file mode 100644 index 0000000..ac2e7d5 --- /dev/null +++ b/src/statistics/app/DbHandle.h @@ -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_STATS_APP_DB_HANDLE_H_ +#define _CONTEXT_STATS_APP_DB_HANDLE_H_ + +#include +#include +#include "../shared/DbHandleBase.h" + +namespace ctx { + class AppDbHandle : public StatsDbHandleBase { + public: + AppDbHandle(); + ~AppDbHandle(); + + int read(const char* subject, ctx::Json filter); + + protected: + std::string createWhereClauseWithDeviceStatus(ctx::Json filter); + std::string createSqlRecentlyUsed(ctx::Json filter); + std::string createSqlFrequentlyUsed(ctx::Json filter); + std::string createSqlRarelyUsed(ctx::Json filter); + std::string createSqlPeakTime(ctx::Json filter); + std::string createSqlCommonSetting(ctx::Json filter); + std::string createSqlFrequency(ctx::Json filter); + void replyTriggerItem(int error, ctx::Json &jsonResult); + }; +} + +#endif /* End of _CONTEXT_STATS_APP_DB_HANDLE_H_ */ diff --git a/src/statistics/app/DbInit.cpp b/src/statistics/app/DbInit.cpp new file mode 100644 index 0000000..a2a5912 --- /dev/null +++ b/src/statistics/app/DbInit.cpp @@ -0,0 +1,107 @@ +/* + * 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 +#include +#include +#include "AppStatisticsTypes.h" +#include "DbInit.h" + +#define EMPTY_CHECKER_QID 999 + +ctx::AppDbInitializer::AppDbInitializer() +{ + __createTable(); + __checkAppList(); +} + +ctx::AppDbInitializer::~AppDbInitializer() +{ +} + +void ctx::AppDbInitializer::__createTable() +{ + static bool done = false; + IF_FAIL_VOID(!done); + + __dbManager.createTable(0, APP_TABLE_USAGE_LOG, APP_TABLE_USAGE_LOG_COLUMNS, NULL, NULL); + __dbManager.createTable(0, APP_TABLE_REMOVABLE_APP, APP_TABLE_REMOVABLE_APP_COLUMNS, NULL, NULL); + __dbManager.execute(0, APP_TEMP_USAGE_FREQ_SQL, NULL); + + done = true; +} + +void ctx::AppDbInitializer::__checkAppList() +{ + __dbManager.execute(EMPTY_CHECKER_QID, "SELECT * FROM " APP_TABLE_REMOVABLE_APP " LIMIT 1", this); +} + +void ctx::AppDbInitializer::__duplicateAppList() +{ + 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, __packageInfoCb, 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::AppDbInitializer::__packageInfoCb(package_info_h packageInfo, void *userData) +{ + int err = package_info_foreach_app_from_package(packageInfo, PACKAGE_INFO_UIAPP, __appInfoCb, userData); + IF_FAIL_RETURN_TAG(err == PACKAGE_MANAGER_ERROR_NONE, false, _E, "package_info_foreach_app_from_package() failed"); + return true; +} + +bool ctx::AppDbInitializer::__appInfoCb(package_info_app_component_type_e compType, const char *appId, void *userData) +{ + Json data; + DatabaseManager dbManager; + + data.set(NULL, STATS_APP_ID, appId); + return dbManager.insert(0, APP_TABLE_REMOVABLE_APP, data, NULL); +} + +void ctx::AppDbInitializer::onTableCreated(unsigned int queryId, int error) +{ +} + +void ctx::AppDbInitializer::onInserted(unsigned int queryId, int error, int64_t rowId) +{ +} + +void ctx::AppDbInitializer::onExecuted(unsigned int queryId, int error, std::vector& records) +{ + if (queryId != EMPTY_CHECKER_QID) { + _E("Unknown Query ID: %d", queryId); + delete this; + return; + } + + if (records.empty()) + __duplicateAppList(); + + delete this; +} diff --git a/src/statistics/app/DbInit.h b/src/statistics/app/DbInit.h new file mode 100644 index 0000000..c8d18c2 --- /dev/null +++ b/src/statistics/app/DbInit.h @@ -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_STATS_APP_DB_INITIALIZER_H_ +#define _CONTEXT_STATS_APP_DB_INITIALIZER_H_ + +#include +#include + +namespace ctx { + + class AppDbInitializer : public IDatabaseListener { + private: + void __createTable(); + void __checkAppList(); + void __duplicateAppList(); + + void onTableCreated(unsigned int queryId, int error); + void onInserted(unsigned int queryId, int error, int64_t rowId); + void onExecuted(unsigned int queryId, int error, std::vector& records); + + static bool __packageInfoCb(package_info_h packageInfo, void *userData); + static bool __appInfoCb(package_info_app_component_type_e compType, const char *appId, void *userData); + + DatabaseManager __dbManager; + + public: + AppDbInitializer(); + ~AppDbInitializer(); + }; + +} /* namespace ctx */ + +#endif /* End of _CONTEXT_STATS_APP_DB_INITIALIZER_H_ */ diff --git a/src/statistics/app/InstallMonitor.cpp b/src/statistics/app/InstallMonitor.cpp new file mode 100644 index 0000000..4dea409 --- /dev/null +++ b/src/statistics/app/InstallMonitor.cpp @@ -0,0 +1,103 @@ +/* + * 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 +#include +#include +#include +#include +#include "AppStatisticsTypes.h" +#include "InstallMonitor.h" + +static package_manager_event_type_e __lastEventType; + +ctx::AppInstallMonitor::AppInstallMonitor() : + __pkgmgrHandle(NULL) +{ + __startMonitoring(); +} + +ctx::AppInstallMonitor::~AppInstallMonitor() +{ + __stopMonitoring(); +} + +bool ctx::AppInstallMonitor::__startMonitoring() +{ + int err = package_manager_create(&__pkgmgrHandle); + IF_FAIL_RETURN_TAG(err == PACKAGE_MANAGER_ERROR_NONE, false, _E, "package_manager_create() failed"); + + err = package_manager_set_event_cb(__pkgmgrHandle, __packageEventCb, this); + IF_FAIL_RETURN_TAG(err == PACKAGE_MANAGER_ERROR_NONE, false, _E, "package_manager_set_event_cb() failed"); + + return true; +} + +void ctx::AppInstallMonitor::__stopMonitoring() +{ + if(__pkgmgrHandle) { + package_manager_unset_event_cb(__pkgmgrHandle); + package_manager_destroy(__pkgmgrHandle); + __pkgmgrHandle = NULL; + } +} + +void ctx::AppInstallMonitor::__packageEventCb(const char *type, const char *package, package_manager_event_type_e eventType, package_manager_event_state_e eventState, int progress, package_manager_error_e error, void *userData) +{ + IF_FAIL_VOID_TAG(error == PACKAGE_MANAGER_ERROR_NONE, _E, "package_manager error: %d", error); + + if (!(eventType == PACKAGE_MANAGER_EVENT_TYPE_INSTALL && eventState == PACKAGE_MANAGER_EVENT_STATE_COMPLETED) && + !(eventType == PACKAGE_MANAGER_EVENT_TYPE_UNINSTALL && eventState == PACKAGE_MANAGER_EVENT_STATE_STARTED)) { + _D("Skipping event type-%d / state-%d", eventType, eventState); + return; + } + + package_info_h pkgInfo; + int err = package_manager_get_package_info(package, &pkgInfo); + IF_FAIL_VOID_TAG(err == PACKAGE_MANAGER_ERROR_NONE, _E, "package_manager_get_package_info() failed"); + + __lastEventType = eventType; + + err = package_info_foreach_app_from_package(pkgInfo, PACKAGE_INFO_UIAPP, __appInfoCb, userData); + if (err != PACKAGE_MANAGER_ERROR_NONE) + _E("package_info_foreach_app_from_package() failed"); + + package_info_destroy(pkgInfo); +} + +bool ctx::AppInstallMonitor::__appInfoCb(package_info_app_component_type_e compType, const char *appId, void *userData) +{ + DatabaseManager dbManager; + + if (__lastEventType == PACKAGE_MANAGER_EVENT_TYPE_INSTALL) { + Json data; + data.set(NULL, STATS_APP_ID, appId); + dbManager.insert(0, APP_TABLE_REMOVABLE_APP, data, NULL); + } else if (__lastEventType == PACKAGE_MANAGER_EVENT_TYPE_UNINSTALL) { + dbManager.execute(0, __createDeletionQuery(APP_TABLE_REMOVABLE_APP, appId).c_str(), NULL); + dbManager.execute(0, __createDeletionQuery(APP_TABLE_USAGE_LOG, appId).c_str(), NULL); + } + + return true; +} + +std::string ctx::AppInstallMonitor::__createDeletionQuery(const char* tableName, const char* appId) +{ + std::stringstream query; + query << "DELETE FROM " << tableName; + query << " WHERE " STATS_APP_ID " = '" << appId << "'"; + return query.str(); +} diff --git a/src/statistics/app/InstallMonitor.h b/src/statistics/app/InstallMonitor.h new file mode 100644 index 0000000..a022946 --- /dev/null +++ b/src/statistics/app/InstallMonitor.h @@ -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_STATS_APP_INSTALL_MONITOR_H_ +#define _CONTEXT_STATS_APP_INSTALL_MONITOR_H_ + +#include +#include + +namespace ctx { + + class AppInstallMonitor : public IDatabaseListener { + private: + package_manager_h __pkgmgrHandle; + + bool __startMonitoring(); + void __stopMonitoring(); + + static std::string __createDeletionQuery(const char* tableName, const char* appId); + static void __packageEventCb(const char *type, const char *package, package_manager_event_type_e eventType, package_manager_event_state_e eventState, int progress, package_manager_error_e error, void *userData); + static bool __appInfoCb(package_info_app_component_type_e compType, const char *appId, void *userData); + + void onTableCreated(unsigned int queryId, int error) {} + void onInserted(unsigned int queryId, int error, int64_t rowId) {} + void onExecuted(unsigned int queryId, int error, std::vector& records) {} + + public: + AppInstallMonitor(); + ~AppInstallMonitor(); + }; + +} /* namespace ctx */ + +#endif /* End of _CONTEXT_STATS_APP_INSTALL_MONITOR_H_ */ diff --git a/src/statistics/app/active_window_monitor.cpp b/src/statistics/app/active_window_monitor.cpp deleted file mode 100644 index 2b7b1ee..0000000 --- a/src/statistics/app/active_window_monitor.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* - * 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 -#include -#include - -#include -#include -#include "../shared/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 ONE_DAY_IN_SEC 86400 - -ctx::app_use_monitor::app_use_monitor() - : signal_id(-1) - , last_cleanup_time(0) - , __dbusWatcher(DBusType::SYSTEM) -{ - start_logging(); -} - -ctx::app_use_monitor::~app_use_monitor() -{ - stop_logging(); -} - -bool ctx::app_use_monitor::start_logging() -{ - signal_id = __dbusWatcher.watch(NULL, "/Org/Tizen/Aul/AppStatus", "org.tizen.aul.AppStatus", "AppStatusChange", this); - _D("Active window monitoring started (%lld)", signal_id); - return (signal_id > 0); -} - -void ctx::app_use_monitor::stop_logging() -{ - if (signal_id > 0) { - __dbusWatcher.unwatch(signal_id); - _D("Active window monitoring stopped"); - } -} - -void ctx::app_use_monitor::onSignal(const char* sender, const char* path, const char* iface, const char* name, GVariant* param) -{ - gint pid = 0; - const gchar *appid = NULL; - const gchar *pkgid = NULL; - const gchar *status = NULL; - const gchar *type = NULL; - - g_variant_get(param, "(i&s&s&s&s)", &pid, &appid, &pkgid, &status, &type); - _D("AppEvent: %s, %s, %s", appid, status, type); - - IF_FAIL_VOID(appid && status && type); - IF_FAIL_VOID(STR_EQ(type, "uiapp") && !is_skippable(appid)); - - if (STR_EQ(status, "fg")) { - create_record(appid); - } else if (STR_EQ(status, "bg")) { - finish_record(appid); - remove_expired(); - } -} - -void ctx::app_use_monitor::create_record(std::string 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); - - __dbManager.insert(0, APP_TABLE_USAGE_LOG, data, NULL); -} - -void ctx::app_use_monitor::finish_record(std::string app_id) -{ - /* TODO: It might be necessary to update system status here */ - 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)"; - __dbManager.execute(0, query.str().c_str(), NULL); -} - -bool ctx::app_use_monitor::is_skippable(std::string app_id) -{ - /* TODO: circular cache */ - app_info_h app_info = NULL; - int err = app_manager_get_app_info(app_id.c_str(), &app_info); - IF_FAIL_RETURN_TAG(err == APP_MANAGER_ERROR_NONE && app_info, true, _E, "app_manager_get_app_info() failed"); - - bool nodisp = false; - err = app_info_is_nodisplay(app_info, &nodisp); - if (err != APP_MANAGER_ERROR_NONE) { - app_info_destroy(app_info); - _E("app_info_is_nodisplay() failed"); - return true; - } - - app_info_destroy(app_info); - return nodisp; -} - -void ctx::app_use_monitor::remove_expired() -{ - int timestamp = static_cast(time(NULL)); - IF_FAIL_VOID(timestamp - last_cleanup_time >= ONE_DAY_IN_SEC); - - last_cleanup_time = timestamp; - - std::stringstream query; - query << "DELETE FROM " APP_TABLE_USAGE_LOG " WHERE " \ - STATS_UNIV_TIME " < strftime('%s', 'now') - " << LOG_RETENTION_PERIOD; - __dbManager.execute(0, query.str().c_str(), NULL); -} diff --git a/src/statistics/app/active_window_monitor.h b/src/statistics/app/active_window_monitor.h deleted file mode 100644 index d86a141..0000000 --- a/src/statistics/app/active_window_monitor.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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 -#include -#include -#include - -namespace ctx { - - class app_use_monitor : public IDBusSignalListener { - private: - int64_t signal_id; - int last_cleanup_time; - DBusSignalWatcher __dbusWatcher; - DatabaseManager __dbManager; - - bool start_logging(void); - void stop_logging(void); - - bool is_skippable(std::string app_id); - void create_record(std::string app_id); - void finish_record(std::string app_id); - void remove_expired(); - void onSignal(const char *sender, const char *path, const char *iface, const char *name, GVariant *param); - - 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_inactive_detector/inactive_detector_storage.cpp b/src/statistics/app/app_inactive_detector/inactive_detector_storage.cpp index 0feb2b7..9e278102 100644 --- a/src/statistics/app/app_inactive_detector/inactive_detector_storage.cpp +++ b/src/statistics/app/app_inactive_detector/inactive_detector_storage.cpp @@ -27,7 +27,7 @@ /*int ctx::inactive_detector_storage::create_table() { - bool ret = __dbManager.create_table(0, WIFI_TABLE_NAME, WIFI_CREATE_TABLE_COLUMNS, NULL, NULL); + bool ret = __dbManager.createTable(0, WIFI_TABLE_NAME, WIFI_CREATE_TABLE_COLUMNS, NULL, NULL); _D("Table Creation Request: %s", ret ? "SUCCESS" : "FAIL"); return ret; }*/ @@ -168,7 +168,7 @@ void ctx::inactive_detector_storage::onExecuted(unsigned int query_id, std::vector& records) { if (error != ERR_NONE) { - _E("on_query_result_received query_id:%d, error:%d", query_id, error); + _E("query_id:%d, error:%d", query_id, error); return; } @@ -197,7 +197,7 @@ void ctx::inactive_detector_storage::onExecuted(unsigned int query_id, } else { - _E("on_query_result_received/classification query_id:%d, error:%d", + _E("classification query_id:%d, error:%d", query_id, _error); } } @@ -206,7 +206,7 @@ void ctx::inactive_detector_storage::onExecuted(unsigned int query_id, _D("UPDATE_CLUSTERS execute query id: %d", query_id); } else { - _E("on_query_result_received unknown query_id:%d", query_id); + _E("unknown query_id:%d", query_id); } } diff --git a/src/statistics/app/app_stats_provider.cpp b/src/statistics/app/app_stats_provider.cpp deleted file mode 100644 index d924034..0000000 --- a/src/statistics/app/app_stats_provider.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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 -#include -#include -#include "app_stats_provider.h" -#include "db_handle.h" - -#include "db_init.h" -#include "install_monitor.h" -#include "active_window_monitor.h" - -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::ContextProviderBase *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"); - - if (!__instance->init()) { - destroy(data); - return NULL; - } - - _I(BLUE("Created")); - 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::registerTriggerItem(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* requestResult) -{ - 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* requestResult) -{ - 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* requestResult) -{ - return ERR_NOT_SUPPORTED; -} diff --git a/src/statistics/app/app_stats_provider.h b/src/statistics/app/app_stats_provider.h deleted file mode 100644 index b224d77..0000000 --- a/src/statistics/app/app_stats_provider.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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 -#include "app_stats_types.h" - -namespace ctx { - - class app_statistics_provider : public ContextProviderBase { - public: - static ContextProviderBase *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 *requestResult); - int unsubscribe(const char *subject, ctx::Json option); - int read(const char *subject, ctx::Json option, ctx::Json *requestResult); - int write(const char *subject, ctx::Json data, ctx::Json *requestResult); - - 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 deleted file mode 100644 index 279a75c..0000000 --- a/src/statistics/app/app_stats_types.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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 "../shared/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/db_handle.cpp b/src/statistics/app/db_handle.cpp deleted file mode 100644 index bddb70f..0000000 --- a/src/statistics/app/db_handle.cpp +++ /dev/null @@ -1,217 +0,0 @@ -/* - * 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 -#include -#include -#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::replyToRead(req_subject.c_str(), req_filter, error, results); -} diff --git a/src/statistics/app/db_handle.h b/src/statistics/app/db_handle.h deleted file mode 100644 index c4cc79e..0000000 --- a/src/statistics/app/db_handle.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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 -#include -#include "../shared/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 deleted file mode 100644 index 1b2d0df..0000000 --- a/src/statistics/app/db_init.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - * 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 -#include -#include -#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); - - __dbManager.createTable(0, APP_TABLE_USAGE_LOG, APP_TABLE_USAGE_LOG_COLUMNS, NULL, NULL); - __dbManager.createTable(0, APP_TABLE_REMOVABLE_APP, APP_TABLE_REMOVABLE_APP_COLUMNS, NULL, NULL); - __dbManager.execute(0, APP_TEMP_USAGE_FREQ_SQL, NULL); - - done = true; -} - -void ctx::app_db_initializer::check_app_list() -{ - __dbManager.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; - DatabaseManager dbManager; - - data.set(NULL, STATS_APP_ID, app_id); - return dbManager.insert(0, APP_TABLE_REMOVABLE_APP, data, NULL); -} - -void ctx::app_db_initializer::onTableCreated(unsigned int query_id, int error) -{ -} - -void ctx::app_db_initializer::onInserted(unsigned int query_id, int error, int64_t row_id) -{ -} - -void ctx::app_db_initializer::onExecuted(unsigned int query_id, int error, std::vector& 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 deleted file mode 100644 index cd5b39e..0000000 --- a/src/statistics/app/db_init.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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 -#include - -namespace ctx { - - class app_db_initializer : public IDatabaseListener { - private: - void create_table(); - void check_app_list(); - void duplicate_app_list(); - - void onTableCreated(unsigned int query_id, int error); - void onInserted(unsigned int query_id, int error, int64_t row_id); - void onExecuted(unsigned int query_id, int error, std::vector& 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); - - DatabaseManager __dbManager; - - 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 deleted file mode 100644 index 4efbb09..0000000 --- a/src/statistics/app/install_monitor.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#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) -{ - DatabaseManager dbManager; - - if (last_event_type == PACKAGE_MANAGER_EVENT_TYPE_INSTALL) { - Json data; - data.set(NULL, STATS_APP_ID, app_id); - dbManager.insert(0, APP_TABLE_REMOVABLE_APP, data, NULL); - } else if (last_event_type == PACKAGE_MANAGER_EVENT_TYPE_UNINSTALL) { - dbManager.execute(0, create_deletion_query(APP_TABLE_REMOVABLE_APP, app_id).c_str(), NULL); - dbManager.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 deleted file mode 100644 index 73b374d..0000000 --- a/src/statistics/app/install_monitor.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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 - -namespace ctx { - - class app_install_monitor : public IDatabaseListener { - private: - package_manager_h pkgmgr_h; - - bool start_monitoring(); - void stop_monitoring(); - - void onTableCreated(unsigned int query_id, int error) {} - void onInserted(unsigned int query_id, int error, int64_t row_id) {} - void onExecuted(unsigned int query_id, int error, std::vector& 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/DbHandle.cpp b/src/statistics/media/DbHandle.cpp new file mode 100644 index 0000000..5eeb81e --- /dev/null +++ b/src/statistics/media/DbHandle.cpp @@ -0,0 +1,123 @@ +/* + * 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 +#include +#include +#include "../shared/SystemInfo.h" +#include "MediaStatisticsTypes.h" +#include "DbHandle.h" + +ctx::MediaDbHandle::MediaDbHandle() +{ +} + +ctx::MediaDbHandle::~MediaDbHandle() +{ +} + +int ctx::MediaDbHandle::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 = createSqlPeakTime(MEDIA_TYPE_MUSIC, filter); + + } else if (STR_EQ(subject, MEDIA_SUBJ_PEAK_TIME_FOR_VIDEO)) { + query = createSqlPeakTime(MEDIA_TYPE_VIDEO, filter); + + } else if (STR_EQ(subject, MEDIA_SUBJ_COMMON_SETTING_FOR_MUSIC)) { + query = createSqlCommonSetting(MEDIA_TYPE_MUSIC, filter); + + } else if (STR_EQ(subject, MEDIA_SUBJ_COMMON_SETTING_FOR_VIDEO)) { + query = createSqlCommonSetting(MEDIA_TYPE_VIDEO, filter); + + } else if (STR_EQ(subject, MEDIA_SUBJ_MUSIC_FREQUENCY)) { + __isTriggerItem = true; + query = createSqlFrequency(MEDIA_TYPE_MUSIC, filter); + + } else if (STR_EQ(subject, MEDIA_SUBJ_VIDEO_FREQUENCY)) { + __isTriggerItem = true; + query = createSqlFrequency(MEDIA_TYPE_VIDEO, filter); + } + + IF_FAIL_RETURN(!query.empty(), ERR_OPERATION_FAILED); + + bool ret = executeQuery(subject, filter, query.c_str()); + IF_FAIL_RETURN(ret, ERR_OPERATION_FAILED); + + return ERR_NONE; +} + +std::string ctx::MediaDbHandle::createWhereClause(int mediaType, ctx::Json filter) +{ + std::stringstream whereClause; + + whereClause << CX_MEDIA_TYPE " = " << mediaType << " AND "; + whereClause << StatsDbHandleBase::createWhereClause(filter); + + return whereClause.str(); +} + +std::string ctx::MediaDbHandle::createSqlPeakTime(int mediaType, ctx::Json filter) +{ + std::string where = createWhereClause(mediaType, filter); + return StatsDbHandleBase::createSqlPeakTime(filter, MEDIA_TABLE_NAME, where); +} + +std::string ctx::MediaDbHandle::createSqlCommonSetting(int mediaType, ctx::Json filter) +{ + std::string where = createWhereClause(mediaType, filter); + return StatsDbHandleBase::createSqlCommonSetting(filter, MEDIA_TABLE_NAME, where); +} + +std::string ctx::MediaDbHandle::createSqlFrequency(int mediaType, ctx::Json filter) +{ + ctx::Json filterCleaned; + std::string weekStr; + std::string timeOfDay; + + if (filter.get(NULL, STATS_DAY_OF_WEEK, &weekStr)) + filterCleaned.set(NULL, STATS_DAY_OF_WEEK, weekStr); + + if (filter.get(NULL, STATS_TIME_OF_DAY, &timeOfDay)) + filterCleaned.set(NULL, STATS_TIME_OF_DAY, timeOfDay); + + std::string whereClause = createWhereClause(mediaType, filterCleaned); + + std::stringstream query; + query << + "SELECT IFNULL(COUNT(*),0) AS " STATS_TOTAL_COUNT \ + " FROM " MEDIA_TABLE_NAME \ + " WHERE " << whereClause; + + return query.str(); +} + +void ctx::MediaDbHandle::replyTriggerItem(int error, ctx::Json &jsonResult) +{ + IF_FAIL_VOID_TAG(STR_EQ(__reqSubject.c_str(), MEDIA_SUBJ_MUSIC_FREQUENCY) || + STR_EQ(__reqSubject.c_str(), MEDIA_SUBJ_VIDEO_FREQUENCY), _E, "Invalid subject"); + + ctx::Json results; + int val; + + jsonResult.get(NULL, STATS_TOTAL_COUNT, &val); + results.set(NULL, STATS_TOTAL_COUNT, val); + + context_manager::replyToRead(__reqSubject.c_str(), __reqFilter, error, results); +} diff --git a/src/statistics/media/DbHandle.h b/src/statistics/media/DbHandle.h new file mode 100644 index 0000000..8a1f036 --- /dev/null +++ b/src/statistics/media/DbHandle.h @@ -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_STATS_MEDIA_DB_HANDLE_H_ +#define _CONTEXT_STATS_MEDIA_DB_HANDLE_H_ + +#include +#include +#include "../shared/DbHandleBase.h" + +namespace ctx { + class MediaDbHandle : public StatsDbHandleBase { + public: + MediaDbHandle(); + ~MediaDbHandle(); + + int read(const char* subject, ctx::Json filter); + + protected: + std::string createWhereClause(int mediaType, ctx::Json filter); + std::string createSqlPeakTime(int mediaType, ctx::Json filter); + std::string createSqlCommonSetting(int mediaType, ctx::Json filter); + std::string createSqlFrequency(int mediaType, ctx::Json filter); + void replyTriggerItem(int error, ctx::Json &jsonResult); + }; +} + +#endif /* End of _CONTEXT_STATS_MEDIA_DB_HANDLE_H_ */ diff --git a/src/statistics/media/MediaContentMonitor.cpp b/src/statistics/media/MediaContentMonitor.cpp new file mode 100644 index 0000000..74b59a8 --- /dev/null +++ b/src/statistics/media/MediaContentMonitor.cpp @@ -0,0 +1,149 @@ +/* + * 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 +#include +#include "../shared/SystemInfo.h" +#include "MediaStatisticsTypes.h" +#include "DbHandle.h" +#include "MediaContentMonitor.h" + +#define PLAYCOUNT_RETENTION_PERIOD 259200 /* 1 month in secs */ +#define ONE_DAY_IN_SEC 86400 + +ctx::MediaContentMonitor::MediaContentMonitor() : + __started(false), + __lastCleanupTime(0) +{ + __dbManager.createTable(0, MEDIA_TABLE_NAME, MEDIA_TABLE_COLUMNS, NULL, NULL); + __dbManager.execute(0, MEDIA_PLAYCOUNT_TABLE_SCHEMA, NULL); + + __started = __startMonitoring(); +} + +ctx::MediaContentMonitor::~MediaContentMonitor() +{ + if (__started) + __stopMonitoring(); +} + +bool ctx::MediaContentMonitor::__startMonitoring() +{ + int err; + err = media_content_connect(); + IF_FAIL_RETURN_TAG(err == MEDIA_CONTENT_ERROR_NONE, false, _E, "media_content_connect() failed"); + + err = media_content_set_db_updated_cb(__onMediaContentDbUpdated, this); + if (err != MEDIA_CONTENT_ERROR_NONE) { + media_content_disconnect(); + _E("media_content_set_db_updated_cb() failed"); + return false; + } + + return true; +} + +void ctx::MediaContentMonitor::__stopMonitoring() +{ + media_content_unset_db_updated_cb(); + media_content_disconnect(); +} + +void ctx::MediaContentMonitor::__onMediaContentDbUpdated( + media_content_error_e error, int pid, + media_content_db_update_item_type_e updateItem, + media_content_db_update_type_e updateType, + media_content_type_e mediaType, + char *uuid, char *path, char *mimeType, void *userData) +{ + IF_FAIL_VOID(error == MEDIA_CONTENT_ERROR_NONE && uuid != NULL); + IF_FAIL_VOID(updateItem == MEDIA_ITEM_FILE && updateType == MEDIA_CONTENT_UPDATE); + IF_FAIL_VOID(mediaType == MEDIA_CONTENT_TYPE_MUSIC || mediaType == MEDIA_CONTENT_TYPE_VIDEO); + + media_info_h media = NULL; + media_info_get_media_from_db(uuid, &media); + IF_FAIL_VOID_TAG(media, _E, "media_info_get_media_from_db() failed"); + + int cnt = -1; + media_info_get_played_count(media, &cnt); + media_info_destroy(media); + IF_FAIL_VOID_TAG(cnt >= 0, _E, "Invalid play count"); + + MediaContentMonitor *instance = static_cast(userData); + instance->__updatePlayCount(uuid, + (mediaType == MEDIA_CONTENT_TYPE_MUSIC) ? MEDIA_TYPE_MUSIC : MEDIA_TYPE_VIDEO, + cnt); +} + +void ctx::MediaContentMonitor::__appendCleanupQuery(std::stringstream &query) +{ + int timestamp = static_cast(time(NULL)); + IF_FAIL_VOID(timestamp - __lastCleanupTime >= ONE_DAY_IN_SEC); + + __lastCleanupTime = 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::MediaContentMonitor::__updatePlayCount(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 << "';"; + __appendCleanupQuery(query); + query << + /* Checking whether the play count changes */ + "SELECT MediaType FROM Log_MediaPlayCount" \ + " WHERE UUID = '" << uuid << "' AND Diff > 0;"; + + __dbManager.execute(0, query.str().c_str(), this); +} + +void ctx::MediaContentMonitor::onExecuted(unsigned int queryId, int error, std::vector& records) +{ + IF_FAIL_VOID(!records.empty()); + + int mediaType = 0; + records[0].get(NULL, CX_MEDIA_TYPE, &mediaType); + + __insertLog(mediaType); +} + +void ctx::MediaContentMonitor::__insertLog(int mediaType) +{ + int systemVolume = -1, mediaVolume = -1, audioJack = -1; + + Json data; + data.set(NULL, CX_MEDIA_TYPE, mediaType); + + if (ctx::system_info::getAudioJackState(&audioJack)) + data.set(NULL, STATS_AUDIO_JACK, audioJack); + + if (ctx::system_info::getVolume(&systemVolume, &mediaVolume)) { + data.set(NULL, STATS_SYSTEM_VOLUME, systemVolume); + data.set(NULL, STATS_MEDIA_VOLUME, mediaVolume); + } + + __dbManager.insert(0, MEDIA_TABLE_NAME, data, NULL); +} diff --git a/src/statistics/media/MediaContentMonitor.h b/src/statistics/media/MediaContentMonitor.h new file mode 100644 index 0000000..b8709aa --- /dev/null +++ b/src/statistics/media/MediaContentMonitor.h @@ -0,0 +1,56 @@ +/* + * 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_MEDIA_CONTENT_MONITOR_H_ +#define _CONTEXT_STATS_MEDIA_CONTENT_MONITOR_H_ + +#include +#include +#include + +namespace ctx { + + class MediaContentMonitor : public IDatabaseListener { + private: + bool __started; + int __lastCleanupTime; + DatabaseManager __dbManager; + + bool __startMonitoring(); + void __stopMonitoring(); + + void __appendCleanupQuery(std::stringstream &query); + void __updatePlayCount(const char *uuid, int type, int count); + void __insertLog(int mediaType); + + void onTableCreated(unsigned int queryId, int error) {} + void onInserted(unsigned int queryId, int error, int64_t rowId) {} + void onExecuted(unsigned int queryId, int error, std::vector& records); + + static void __onMediaContentDbUpdated(media_content_error_e error, int pid, + media_content_db_update_item_type_e updateItem, + media_content_db_update_type_e updateType, + media_content_type_e mediaType, + char *uuid, char *path, char *mimeType, void *userData); + + public: + MediaContentMonitor(); + ~MediaContentMonitor(); + }; + +} /* namespace ctx */ + +#endif /* End of _CONTEXT_STATS_MEDIA_CONTENT_MONITOR_H_ */ diff --git a/src/statistics/media/MediaStatisticsProvider.cpp b/src/statistics/media/MediaStatisticsProvider.cpp new file mode 100644 index 0000000..582d654 --- /dev/null +++ b/src/statistics/media/MediaStatisticsProvider.cpp @@ -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 +#include +#include +#include "MediaStatisticsProvider.h" +#include "DbHandle.h" +#include "MediaContentMonitor.h" + +static ctx::MediaContentMonitor *__contentMon = NULL; + +ctx::MediaStatisticsProvider *ctx::MediaStatisticsProvider::__instance = NULL; + +ctx::MediaStatisticsProvider::MediaStatisticsProvider() +{ +} + +ctx::MediaStatisticsProvider::~MediaStatisticsProvider() +{ + delete __contentMon; + __contentMon = NULL; +} + +ctx::ContextProviderBase *ctx::MediaStatisticsProvider::create(void *data) +{ + IF_FAIL_RETURN(!__instance, __instance); + + __instance = new(std::nothrow) MediaStatisticsProvider(); + IF_FAIL_RETURN_TAG(__instance, NULL, _E, "Memory allocation failed"); + + _I(BLUE("Created")); + + if (!__instance->__init()) { + destroy(data); + return NULL; + } + + return __instance; +} + +void ctx::MediaStatisticsProvider::destroy(void *data) +{ + IF_FAIL_VOID(__instance); + delete __instance; + __instance = NULL; + _I(BLUE("Destroyed")); +} + +bool ctx::MediaStatisticsProvider::isSupported(const char* subject) +{ + return true; +} + +void ctx::MediaStatisticsProvider::submitTriggerItem() +{ + context_manager::registerTriggerItem(MEDIA_SUBJ_MUSIC_FREQUENCY, OPS_READ, + "{" TRIG_DEF_TOTAL_COUNT "}", + "{" TRIG_DEF_TIME_OF_DAY "," TRIG_DEF_DAY_OF_WEEK "}"); + + context_manager::registerTriggerItem(MEDIA_SUBJ_VIDEO_FREQUENCY, OPS_READ, + "{" TRIG_DEF_TOTAL_COUNT "}", + "{" TRIG_DEF_TIME_OF_DAY "," TRIG_DEF_DAY_OF_WEEK "}"); +} + +bool ctx::MediaStatisticsProvider::__init() +{ + __contentMon = new(std::nothrow) ctx::MediaContentMonitor(); + IF_FAIL_RETURN_TAG(__contentMon, false, _E, "Memory allocation failed"); + return true; +} + +int ctx::MediaStatisticsProvider::subscribe(const char* subject, ctx::Json option, ctx::Json* requestResult) +{ + return ERR_NOT_SUPPORTED; +} + +int ctx::MediaStatisticsProvider::unsubscribe(const char* subject, ctx::Json option) +{ + return ERR_NOT_SUPPORTED; +} + +int ctx::MediaStatisticsProvider::read(const char* subject, ctx::Json option, ctx::Json* requestResult) +{ + MediaDbHandle *handle = new(std::nothrow) MediaDbHandle(); + 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::MediaStatisticsProvider::write(const char* subject, ctx::Json data, ctx::Json* requestResult) +{ + return ERR_NOT_SUPPORTED; +} diff --git a/src/statistics/media/MediaStatisticsProvider.h b/src/statistics/media/MediaStatisticsProvider.h new file mode 100644 index 0000000..edcbc5a --- /dev/null +++ b/src/statistics/media/MediaStatisticsProvider.h @@ -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_STATS_MEDIA_STATS_PROVIDER_H_ +#define _CONTEXT_STATS_MEDIA_STATS_PROVIDER_H_ + +#include +#include "MediaStatisticsTypes.h" + +namespace ctx { + + class MediaStatisticsProvider : public ContextProviderBase { + public: + static ContextProviderBase *create(void *data); + static void destroy(void *data); + static bool isSupported(const char *subject); + static void submitTriggerItem(); + + int subscribe(const char* subject, ctx::Json option, ctx::Json* requestResult); + int unsubscribe(const char* subject, ctx::Json option); + int read(const char* subject, ctx::Json option, ctx::Json* requestResult); + int write(const char* subject, ctx::Json data, ctx::Json* requestResult); + + private: + static MediaStatisticsProvider *__instance; + + MediaStatisticsProvider(); + ~MediaStatisticsProvider(); + bool __init(); + + }; /* class MediaStatisticsProvider */ + +} /* namespace ctx */ + +#endif /* End of _CONTEXT_STATS_MEDIA_STATS_PROVIDER_H_ */ diff --git a/src/statistics/media/MediaStatisticsTypes.h b/src/statistics/media/MediaStatisticsTypes.h new file mode 100644 index 0000000..71d1fa1 --- /dev/null +++ b/src/statistics/media/MediaStatisticsTypes.h @@ -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_STATS_MEDIA_TYPES_H_ +#define _CONTEXT_STATS_MEDIA_TYPES_H_ + +#include "../shared/CommonTypes.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 mediaType_e { + MEDIA_TYPE_MUSIC = 1, + MEDIA_TYPE_VIDEO, +}; + +#endif /* End of _CONTEXT_STATS_MEDIA_TYPES_H_ */ diff --git a/src/statistics/media/db_handle.cpp b/src/statistics/media/db_handle.cpp deleted file mode 100644 index 9561f69..0000000 --- a/src/statistics/media/db_handle.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/* - * 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 -#include -#include -#include "../shared/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::replyToRead(req_subject.c_str(), req_filter, error, results); -} diff --git a/src/statistics/media/db_handle.h b/src/statistics/media/db_handle.h deleted file mode 100644 index deb3ded..0000000 --- a/src/statistics/media/db_handle.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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 -#include -#include "../shared/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 deleted file mode 100644 index 6ae9f13..0000000 --- a/src/statistics/media/media_content_monitor.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/* - * 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 -#include -#include "../shared/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) -{ - __dbManager.createTable(0, MEDIA_TABLE_NAME, MEDIA_TABLE_COLUMNS, NULL, NULL); - __dbManager.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(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(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;"; - - __dbManager.execute(0, query.str().c_str(), this); -} - -void ctx::media_content_monitor::onExecuted(unsigned int query_id, int error, std::vector& 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); - } - - __dbManager.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 deleted file mode 100644 index 260f84f..0000000 --- a/src/statistics/media/media_content_monitor.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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 -#include -#include - -namespace ctx { - - class media_content_monitor : public IDatabaseListener { - private: - bool started; - int last_cleanup_time; - DatabaseManager __dbManager; - - 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 onTableCreated(unsigned int query_id, int error) {} - void onInserted(unsigned int query_id, int error, int64_t row_id) {} - void onExecuted(unsigned int query_id, int error, std::vector& 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 deleted file mode 100644 index feac914..0000000 --- a/src/statistics/media/media_stats_provider.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* - * 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 -#include -#include -#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::ContextProviderBase *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::registerTriggerItem(MEDIA_SUBJ_MUSIC_FREQUENCY, OPS_READ, - "{" TRIG_DEF_TOTAL_COUNT "}", - "{" TRIG_DEF_TIME_OF_DAY "," TRIG_DEF_DAY_OF_WEEK "}"); - - context_manager::registerTriggerItem(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* requestResult) -{ - 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* requestResult) -{ - 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* requestResult) -{ - return ERR_NOT_SUPPORTED; -} diff --git a/src/statistics/media/media_stats_provider.h b/src/statistics/media/media_stats_provider.h deleted file mode 100644 index ff695c6..0000000 --- a/src/statistics/media/media_stats_provider.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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 -#include "media_stats_types.h" - -namespace ctx { - - class media_statistics_provider : public ContextProviderBase { - public: - static ContextProviderBase *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* requestResult); - int unsubscribe(const char* subject, ctx::Json option); - int read(const char* subject, ctx::Json option, ctx::Json* requestResult); - int write(const char* subject, ctx::Json data, ctx::Json* requestResult); - - 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 deleted file mode 100644 index 8d08170..0000000 --- a/src/statistics/media/media_stats_types.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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 "../shared/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/shared/CommonTypes.h b/src/statistics/shared/CommonTypes.h new file mode 100644 index 0000000..d6673e1 --- /dev/null +++ b/src/statistics/shared/CommonTypes.h @@ -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 "rowId" + +#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 StatsDayOfWeek_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 /* End of _CONTEXT_STATS_COMMMON_TYPES_ */ diff --git a/src/statistics/shared/DbHandleBase.cpp b/src/statistics/shared/DbHandleBase.cpp new file mode 100644 index 0000000..b2917b5 --- /dev/null +++ b/src/statistics/shared/DbHandleBase.cpp @@ -0,0 +1,226 @@ +/* + * 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 +#include +#include +#include "CommonTypes.h" +#include "DbHandleBase.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::StatsDbHandleBase::StatsDbHandleBase() : + __isTriggerItem(false) +{ +} + +ctx::StatsDbHandleBase::~StatsDbHandleBase() +{ +} + +int ctx::StatsDbHandleBase::generateQid() +{ + static int qid = 0; + + if (qid++ < 0) qid = 1; + return qid; +} + +bool ctx::StatsDbHandleBase::executeQuery(const char* subject, ctx::Json filter, const char* query) +{ + bool ret = __dbManager.execute(generateQid(), query, this); + IF_FAIL_RETURN(ret, false); + + __reqSubject = subject; + __reqFilter = filter; + + return true; +} + +std::string ctx::StatsDbHandleBase::createWhereClause(ctx::Json filter) +{ + std::stringstream whereClause; + int week = 0; + int start = 0; + int end = 0; + int timespan = DEFAULT_TIMESPAN; + std::string appId; + std::string weekStr; + std::string timeOfDay; + + if (filter.get(NULL, STATS_DAY_OF_WEEK, &weekStr)) { + // In case of string (from Trigger) + if (weekStr == STATS_WEEKDAY) { + week = STATS_DAY_OF_WEEK_WEEKDAY; + + } else if (weekStr == STATS_WEEKEND) { + week = STATS_DAY_OF_WEEK_WEEKEND; + + } else if (weekStr == STATS_SUN) { + week = STATS_DAY_OF_WEEK_SUN; + + } else if (weekStr == STATS_MON) { + week = STATS_DAY_OF_WEEK_MON; + + } else if (weekStr == STATS_TUE) { + week = STATS_DAY_OF_WEEK_TUE; + + } else if (weekStr == STATS_WED) { + week = STATS_DAY_OF_WEEK_WED; + + } else if (weekStr == STATS_THU) { + week = STATS_DAY_OF_WEEK_THU; + + } else if (weekStr == STATS_FRI) { + week = STATS_DAY_OF_WEEK_FRI; + + } else if (weekStr == 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: + whereClause << "(" DAY_OF_WEEK(STATS_LOCAL_TIME) " > 0 AND " DAY_OF_WEEK(STATS_LOCAL_TIME) " < 6) AND "; + break; + case STATS_DAY_OF_WEEK_WEEKEND: + whereClause << "(" 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: + whereClause << DAY_OF_WEEK(STATS_LOCAL_TIME) " = " << week - STATS_DAY_OF_WEEK_SUN << " AND "; + break; + default: + break; + } + + if (filter.get(NULL, STATS_APP_ID, &appId)) + whereClause << STATS_APP_ID " = '" << appId << "' AND "; + + if (filter.get(NULL, STATS_START_TIME, &start)) + whereClause << STATS_UNIV_TIME " >= " << start << " AND "; + + if (filter.get(NULL, STATS_END_TIME, &end)) + whereClause << STATS_UNIV_TIME " <= " << end << " AND "; + + if (filter.get(NULL, STATS_TIME_OF_DAY, &timeOfDay)) { + size_t pivot = timeOfDay.find('-'); + if (pivot != std::string::npos) { + std::string from = timeOfDay.substr(0, pivot); + std::string to = timeOfDay.substr(pivot + 1); + whereClause << "(" HOUR_OF_DAY(STATS_LOCAL_TIME) " >= " << from \ + << " AND " HOUR_OF_DAY(STATS_LOCAL_TIME) " < " << to << ") AND "; + } + } + + filter.get(NULL, STATS_TIMESPAN, ×pan); + whereClause << STATS_UNIV_TIME " > strftime('%s', 'now', '-" << timespan <<" day')"; + + return whereClause.str(); +} + +std::string ctx::StatsDbHandleBase::createSqlPeakTime(ctx::Json filter, const char* tableName, std::string whereClause) +{ + 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 " << tableName << \ + " WHERE " << whereClause << \ + " GROUP BY " HOUR_OF_DAY(STATS_LOCAL_TIME) \ + " ORDER BY " STATS_TOTAL_COUNT " DESC" \ + " LIMIT " << limit; + + return query.str(); +} + +std::string ctx::StatsDbHandleBase::createSqlCommonSetting(ctx::Json filter, const char* tableName, std::string whereClause) +{ + std::stringstream query; + + query << + "SELECT ( SELECT " STATS_AUDIO_JACK \ + " FROM " << tableName << \ + " WHERE " << whereClause << \ + " GROUP BY " STATS_AUDIO_JACK \ + " ORDER BY count(" STATS_AUDIO_JACK ") DESC" \ + " LIMIT 1 ) AS " STATS_AUDIO_JACK \ + ", ( SELECT " STATS_SYSTEM_VOLUME \ + " FROM " << tableName << \ + " WHERE " << whereClause << \ + " GROUP BY " STATS_SYSTEM_VOLUME \ + " ORDER BY count(" STATS_SYSTEM_VOLUME ") DESC" \ + " LIMIT 1 ) AS " STATS_SYSTEM_VOLUME \ + ", ( SELECT " STATS_MEDIA_VOLUME \ + " FROM " << tableName << \ + " WHERE " << whereClause << \ + " GROUP BY " STATS_MEDIA_VOLUME \ + " ORDER BY count(" STATS_MEDIA_VOLUME ") DESC" \ + " LIMIT 1 ) AS " STATS_MEDIA_VOLUME; + + return query.str(); +} + +void ctx::StatsDbHandleBase::onTableCreated(unsigned int queryId, int error) +{ +} + +void ctx::StatsDbHandleBase::onInserted(unsigned int queryId, int error, int64_t rowId) +{ + delete this; +} + +void ctx::StatsDbHandleBase::jsonVectorToArray(std::vector &vecJson, ctx::Json &jsonResult) +{ + std::vector::iterator vecJsonEnd = vecJson.end(); + + for(auto vecJsonPos = vecJson.begin(); vecJsonPos != vecJsonEnd; ++vecJsonPos) { + Json originJson = *vecJsonPos; + jsonResult.append(NULL, STATS_QUERY_RESULT, originJson); + } +} + +void ctx::StatsDbHandleBase::onExecuted(unsigned int queryId, int error, std::vector& records) +{ + if (__isTriggerItem) { + if (records.size() == 1) { + replyTriggerItem(error, records[0]); + } else { + _E("Invalid query result"); + Json dummy; + context_manager::replyToRead(__reqSubject.c_str(), __reqFilter, ERR_OPERATION_FAILED, dummy); + } + } else { + Json results = "{\"" STATS_QUERY_RESULT "\":[]}"; + jsonVectorToArray(records, results); + context_manager::replyToRead(__reqSubject.c_str(), __reqFilter, error, results); + } + + delete this; +} diff --git a/src/statistics/shared/DbHandleBase.h b/src/statistics/shared/DbHandleBase.h new file mode 100644 index 0000000..0a06cb9 --- /dev/null +++ b/src/statistics/shared/DbHandleBase.h @@ -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 _CONTEXT_STATS_DB_HANDLE_BASE_H_ +#define _CONTEXT_STATS_DB_HANDLE_BASE_H_ + +#include +#include +#include + +namespace ctx { + class StatsDbHandleBase : public IDatabaseListener { + protected: + bool __isTriggerItem; + std::string __reqSubject; + ctx::Json __reqFilter; + DatabaseManager __dbManager; + + StatsDbHandleBase(); + ~StatsDbHandleBase(); + + std::string createWhereClause(ctx::Json filter); + std::string createSqlPeakTime(ctx::Json filter, const char* tableName, std::string whereClause); + std::string createSqlCommonSetting(ctx::Json filter, const char* tableName, std::string whereClause); + + bool executeQuery(const char* subject, ctx::Json filter, const char* query); + virtual void replyTriggerItem(int error, ctx::Json &jsonResult) = 0; + static int generateQid(); + + private: + void jsonVectorToArray(std::vector &vecJson, ctx::Json &jsonResult); + + void onTableCreated(unsigned int queryId, int error); + void onInserted(unsigned int queryId, int error, int64_t rowId); + void onExecuted(unsigned int queryId, int error, std::vector& records); + }; +} + +#endif /* End of _CONTEXT_STATS_DB_HANDLE_BASE_H_ */ diff --git a/src/statistics/shared/SystemInfo.cpp b/src/statistics/shared/SystemInfo.cpp new file mode 100644 index 0000000..ad6b1f2 --- /dev/null +++ b/src/statistics/shared/SystemInfo.cpp @@ -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 +#include +#include +#include +#include +#include "SystemInfo.h" + +#define CONNECTED 1 +#define NOT_CONNECTED 0 + +bool ctx::system_info::getAudioJackState(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::getVolume(int* systemVolume, int* mediaVolume) +{ + int err; + + err = sound_manager_get_volume(SOUND_TYPE_SYSTEM, systemVolume); + IF_FAIL_RETURN(err == RUNTIME_INFO_ERROR_NONE, false); + + err = sound_manager_get_volume(SOUND_TYPE_MEDIA, mediaVolume); + IF_FAIL_RETURN(err == RUNTIME_INFO_ERROR_NONE, false); + + return true; +} + +bool ctx::system_info::getWifiBssid(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 *strBuf = 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, &strBuf); + bssid = (strBuf != NULL ? strBuf : ""); + g_free(strBuf); + + wifi_ap_destroy(ap); + wifi_deinitialize(); + + return !bssid.empty(); +#endif + bssid = ctx::SharedVars().get(ctx::SharedVars::WIFI_BSSID); + return true; +} diff --git a/src/statistics/shared/SystemInfo.h b/src/statistics/shared/SystemInfo.h new file mode 100644 index 0000000..86f5b19 --- /dev/null +++ b/src/statistics/shared/SystemInfo.h @@ -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_STATS_SYSTEM_INFO_READER_H_ +#define _CONTEXT_STATS_SYSTEM_INFO_READER_H_ + +#include + +namespace ctx { + namespace system_info { + bool getAudioJackState(int* state); + bool getVolume(int* systemVolume, int* mediaVolume); + bool getWifiBssid(std::string& bssid); + } +} + +#endif /* End of _CONTEXT_STATS_SYSTEM_INFO_READER_H_ */ diff --git a/src/statistics/shared/common_types.h b/src/statistics/shared/common_types.h deleted file mode 100644 index f173df9..0000000 --- a/src/statistics/shared/common_types.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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 deleted file mode 100644 index e8d60d7..0000000 --- a/src/statistics/shared/db_handle_base.cpp +++ /dev/null @@ -1,226 +0,0 @@ -/* - * 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 -#include -#include -#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 = __dbManager.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, ×pan); - 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::onTableCreated(unsigned int query_id, int error) -{ -} - -void ctx::stats_db_handle_base::onInserted(unsigned int query_id, int error, int64_t row_id) -{ - delete this; -} - -void ctx::stats_db_handle_base::json_vector_to_array(std::vector &vec_json, ctx::Json &json_result) -{ - std::vector::iterator json_vec_end = vec_json.end(); - - for(std::vector::iterator json_vec_pos = vec_json.begin(); json_vec_pos != json_vec_end; ++json_vec_pos) { - Json origin_j = *json_vec_pos; - json_result.append(NULL, STATS_QUERY_RESULT, origin_j); - } -} - -void ctx::stats_db_handle_base::onExecuted(unsigned int query_id, int error, std::vector& records) -{ - if (is_trigger_item) { - if (records.size() == 1) { - reply_trigger_item(error, records[0]); - } else { - _E("Invalid query result"); - Json dummy; - context_manager::replyToRead(req_subject.c_str(), req_filter, ERR_OPERATION_FAILED, dummy); - } - } else { - Json results = "{\"" STATS_QUERY_RESULT "\":[]}"; - json_vector_to_array(records, results); - context_manager::replyToRead(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 deleted file mode 100644 index 8c9a201..0000000 --- a/src/statistics/shared/db_handle_base.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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 -#include -#include - -namespace ctx { - class stats_db_handle_base : public IDatabaseListener { - protected: - bool is_trigger_item; - std::string req_subject; - ctx::Json req_filter; - DatabaseManager __dbManager; - - 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 &vec_json, ctx::Json &json_result); - - void onTableCreated(unsigned int query_id, int error); - void onInserted(unsigned int query_id, int error, int64_t row_id); - void onExecuted(unsigned int query_id, int error, std::vector& records); - }; -} - -#endif /* __CONTEXT_STATS_DB_HANDLE_BASE_H__ */ diff --git a/src/statistics/shared/system_info.cpp b/src/statistics/shared/system_info.cpp deleted file mode 100644 index 3437d69..0000000 --- a/src/statistics/shared/system_info.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#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::SharedVars().get(ctx::SharedVars::WIFI_BSSID); - return true; -} diff --git a/src/statistics/shared/system_info.h b/src/statistics/shared/system_info.h deleted file mode 100644 index 025a056..0000000 --- a/src/statistics/shared/system_info.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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 - -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/DbHandle.cpp b/src/statistics/social/DbHandle.cpp new file mode 100644 index 0000000..9886e48 --- /dev/null +++ b/src/statistics/social/DbHandle.cpp @@ -0,0 +1,161 @@ +/* + * 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 +#include +#include +#include +#include "SocialStatisticsTypes.h" +#include "DbHandle.h" + +ctx::SocialDbHandle::SocialDbHandle() +{ +} + +ctx::SocialDbHandle::~SocialDbHandle() +{ +} + +int ctx::SocialDbHandle::read(const char* subject, ctx::Json filter) +{ + std::string query; + + if (STR_EQ(subject, SOCIAL_SUBJ_FREQ_ADDRESS)) { + query = createSqlFreqAddress(filter); + + } else if (STR_EQ(subject, SOCIAL_SUBJ_FREQUENCY)) { + __isTriggerItem = true; + query = createSqlFrequency(filter); + } + + IF_FAIL_RETURN(!query.empty(), ERR_OPERATION_FAILED); + + bool ret = executeQuery(subject, filter, query.c_str()); + IF_FAIL_RETURN(ret, ERR_OPERATION_FAILED); + + return ERR_NONE; +} + +std::string ctx::SocialDbHandle::createWhereClause(ctx::Json filter) +{ + std::stringstream whereClause; + int commType = -1; + + whereClause << StatsDbHandleBase::createWhereClause(filter); + + filter.get(NULL, SOCIAL_COMMUNICATION_TYPE, &commType); + + switch(commType) { + case SOCIAL_COMMUNICATION_TYPE_CALL: + whereClause << + " AND " SOCIAL_PHONE_LOG_TYPE " >= " << CONTACTS_PLOG_TYPE_VOICE_INCOMING << + " AND " SOCIAL_PHONE_LOG_TYPE " <= " << CONTACTS_PLOG_TYPE_VIDEO_BLOCKED; + break; + case SOCIAL_COMMUNICATION_TYPE_MESSAGE: + whereClause << + " AND " SOCIAL_PHONE_LOG_TYPE " >= " << CONTACTS_PLOG_TYPE_MMS_INCOMING << + " AND " SOCIAL_PHONE_LOG_TYPE " <= " << CONTACTS_PLOG_TYPE_MMS_BLOCKED; + break; + default: + break; + } + + return whereClause.str(); +} + +std::string ctx::SocialDbHandle::createSqlFreqAddress(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 " << createWhereClause(filter) << + " GROUP BY " SOCIAL_ADDRESS \ + " ORDER BY COUNT(*) DESC" \ + " LIMIT " << limit; + + return query.str(); +} + +std::string ctx::SocialDbHandle::createSqlFrequency(ctx::Json filter) +{ + ctx::Json filterCleaned; + std::string weekStr; + std::string timeOfDay; + std::string address; + + if (!filter.get(NULL, SOCIAL_ADDRESS, &address)) { + _E("Invalid parameter"); + return ""; + } + + if (filter.get(NULL, STATS_DAY_OF_WEEK, &weekStr)) + filterCleaned.set(NULL, STATS_DAY_OF_WEEK, weekStr); + + if (filter.get(NULL, STATS_TIME_OF_DAY, &timeOfDay)) + filterCleaned.set(NULL, STATS_TIME_OF_DAY, timeOfDay); + + 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 " << createWhereClause(filterCleaned) << + " 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::SocialDbHandle::replyTriggerItem(int error, ctx::Json &jsonResult) +{ + IF_FAIL_VOID_TAG(STR_EQ(__reqSubject.c_str(), SOCIAL_SUBJ_FREQUENCY), _E, "Invalid subject"); + + ctx::Json results; + std::string valStr; + int val; + + jsonResult.get(NULL, SOCIAL_ADDRESS, &valStr); + results.set(NULL, SOCIAL_ADDRESS, valStr); + jsonResult.get(NULL, STATS_TOTAL_COUNT, &val); + results.set(NULL, STATS_TOTAL_COUNT, val); + jsonResult.get(NULL, STATS_RANK, &val); + results.set(NULL, STATS_RANK, val); + + context_manager::replyToRead(__reqSubject.c_str(), __reqFilter, error, results); +} diff --git a/src/statistics/social/DbHandle.h b/src/statistics/social/DbHandle.h new file mode 100644 index 0000000..3ff4ecf --- /dev/null +++ b/src/statistics/social/DbHandle.h @@ -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_STATS_SOCIAL_DB_HANDLE_H_ +#define _CONTEXT_STATS_SOCIAL_DB_HANDLE_H_ + +#include +#include +#include "../shared/DbHandleBase.h" + +namespace ctx { + class SocialDbHandle : public StatsDbHandleBase { + public: + SocialDbHandle(); + ~SocialDbHandle(); + + int read(const char* subject, ctx::Json filter); + + protected: + std::string createWhereClause(ctx::Json filter); + std::string createSqlFreqAddress(ctx::Json filter); + std::string createSqlFrequency(ctx::Json filter); + void replyTriggerItem(int error, ctx::Json &jsonResult); + }; +} + +#endif /* End of _CONTEXT_STATS_SOCIAL_DB_HANDLE_H_ */ diff --git a/src/statistics/social/LogAggregator.cpp b/src/statistics/social/LogAggregator.cpp new file mode 100644 index 0000000..dd6db76 --- /dev/null +++ b/src/statistics/social/LogAggregator.cpp @@ -0,0 +1,167 @@ +/* + * 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 +#include +#include +#include "SocialStatisticsTypes.h" +#include "LogAggregator.h" + +ctx::ContactLogAggregator::ContactLogAggregator() : + __timerId(-1), + __timeDiff(0) +{ + __createTable(); + __timerId = __timerManager.setAt(3, 0, DayOfWeek::EVERYDAY, this); +} + +ctx::ContactLogAggregator::~ContactLogAggregator() +{ + __timerManager.remove(__timerId); +} + +void ctx::ContactLogAggregator::__createTable() +{ + static bool done = false; + IF_FAIL_VOID(!done); + + __dbManager.createTable(0, SOCIAL_TABLE_CONTACT_LOG, SOCIAL_TABLE_CONTACT_LOG_COLUMNS, NULL, NULL); + __dbManager.execute(0, SOCIAL_TEMP_CONTACT_FREQ_SQL, NULL); + + done = true; +} + +bool ctx::ContactLogAggregator::onTimerExpired(int timerId) +{ + aggregateContactLog(); + return true; +} + +void ctx::ContactLogAggregator::aggregateContactLog() +{ + __dbManager.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::ContactLogAggregator::onExecuted(unsigned int queryId, int error, std::vector& records) +{ + IF_FAIL_VOID_TAG(!records.empty(), _E, "Invalid query result"); + + int lastTime = 0; + records[0].get(NULL, STATS_LAST_TIME, &lastTime); + records[0].get(NULL, TIME_DIFFERENCE, &__timeDiff); + + _D("Last Time: %d / Local - UTC: %d", lastTime, __timeDiff); + + contacts_list_h list = NULL; + + __getUpdatedContactLogList(lastTime, &list); + IF_FAIL_VOID(list); + + __removeExpiredLog(); + __insertContactLogList(list); + __destroyContactLogList(list); +} + +void ctx::ContactLogAggregator::__getUpdatedContactLogList(int lastTime, 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_INCOMING); + 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, lastTime); + 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::ContactLogAggregator::__destroyContactLogList(contacts_list_h list) +{ + if (list) + contacts_list_destroy(list, true); + + contacts_disconnect(); +} + +void ctx::ContactLogAggregator::__insertContactLogList(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 logType; + 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, &logType); + 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, logType); + data.set(NULL, STATS_DURATION, duration); + data.set(NULL, STATS_UNIV_TIME, accessTime); + data.set(NULL, STATS_LOCAL_TIME, accessTime + __timeDiff); + + __dbManager.insert(0, SOCIAL_TABLE_CONTACT_LOG, data, NULL); + + } while(contacts_list_next(list) == CONTACTS_ERROR_NONE); +} + +void ctx::ContactLogAggregator::__removeExpiredLog() +{ + std::stringstream query; + query << "DELETE FROM " SOCIAL_TABLE_CONTACT_LOG " WHERE " \ + STATS_UNIV_TIME " < strftime('%s', 'now') - " << LOG_RETENTION_PERIOD; + __dbManager.execute(0, query.str().c_str(), NULL); +} diff --git a/src/statistics/social/LogAggregator.h b/src/statistics/social/LogAggregator.h new file mode 100644 index 0000000..cc3962d --- /dev/null +++ b/src/statistics/social/LogAggregator.h @@ -0,0 +1,54 @@ +/* + * 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_SOCIAL_CONTACT_LOG_AGGREGATOR_H_ +#define _CONTEXT_STATS_SOCIAL_CONTACT_LOG_AGGREGATOR_H_ + +#include +#include +#include + +namespace ctx { + + class ContactLogAggregator : public IDatabaseListener, public ITimerListener { + private: + int __timerId; + int __timeDiff; + TimerManager __timerManager; + DatabaseManager __dbManager; + + void __createTable(); + void __getUpdatedContactLogList(int last_time, contacts_list_h *list); + void __insertContactLogList(contacts_list_h list); + void __destroyContactLogList(contacts_list_h list); + void __removeExpiredLog(); + + public: + ContactLogAggregator(); + ~ContactLogAggregator(); + + void aggregateContactLog(); + + void onTableCreated(unsigned int queryId, int error) {} + void onInserted(unsigned int queryId, int error, int64_t rowId) {} + void onExecuted(unsigned int queryId, int error, std::vector& records); + bool onTimerExpired(int timerId); + + }; /* class ContactLogAggregator */ + +} /* namespace ctx */ + +#endif /* End of _CONTEXT_STATS_SOCIAL_CONTACT_LOG_AGGREGTOR_H_ */ diff --git a/src/statistics/social/SocialStatisticsProvider.cpp b/src/statistics/social/SocialStatisticsProvider.cpp new file mode 100644 index 0000000..0a33725 --- /dev/null +++ b/src/statistics/social/SocialStatisticsProvider.cpp @@ -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 +#include +#include +#include "SocialStatisticsProvider.h" +#include "DbHandle.h" +#include "LogAggregator.h" + +static ctx::ContactLogAggregator *__aggregator = NULL; + +ctx::SocialStatisticsProvider *ctx::SocialStatisticsProvider::__instance = NULL; + +ctx::SocialStatisticsProvider::SocialStatisticsProvider() +{ +} + +ctx::SocialStatisticsProvider::~SocialStatisticsProvider() +{ + delete __aggregator; +} + +ctx::ContextProviderBase *ctx::SocialStatisticsProvider::create(void *data) +{ + IF_FAIL_RETURN(!__instance, __instance); + + __instance = new(std::nothrow) SocialStatisticsProvider(); + IF_FAIL_RETURN_TAG(__instance, NULL, _E, "Memory allocation failed"); + + _I(BLUE("Created")); + + if (!__instance->__init()) { + destroy(data); + return NULL; + } + + return __instance; +} + +void ctx::SocialStatisticsProvider::destroy(void *data) +{ + IF_FAIL_VOID(__instance); + delete __instance; + __instance = NULL; + _I(BLUE("Destroyed")); +} + +bool ctx::SocialStatisticsProvider::isSupported(const char* subject) +{ + return true; +} + +void ctx::SocialStatisticsProvider::submitTriggerItem() +{ + context_manager::registerTriggerItem(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::SocialStatisticsProvider::__init() +{ + __aggregator = new(std::nothrow) ContactLogAggregator(); + IF_FAIL_RETURN_TAG(__aggregator, false, _E, "Memory allocation failed"); + return true; +} + +int ctx::SocialStatisticsProvider::subscribe(const char* subject, ctx::Json option, ctx::Json* requestResult) +{ + return ERR_NOT_SUPPORTED; +} + +int ctx::SocialStatisticsProvider::unsubscribe(const char* subject, ctx::Json option) +{ + return ERR_NOT_SUPPORTED; +} + +int ctx::SocialStatisticsProvider::read(const char* subject, ctx::Json option, ctx::Json* requestResult) +{ + ctx::SocialDbHandle *handle = new(std::nothrow) ctx::SocialDbHandle(); + 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::SocialStatisticsProvider::write(const char* subject, ctx::Json data, ctx::Json* requestResult) +{ + return ERR_NOT_SUPPORTED; +} diff --git a/src/statistics/social/SocialStatisticsProvider.h b/src/statistics/social/SocialStatisticsProvider.h new file mode 100644 index 0000000..3075915 --- /dev/null +++ b/src/statistics/social/SocialStatisticsProvider.h @@ -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_STATS_SOCIAL_STATS_PROVIDER_H_ +#define _CONTEXT_STATS_SOCIAL_STATS_PROVIDER_H_ + +#include +#include "SocialStatisticsTypes.h" + +namespace ctx { + + class SocialStatisticsProvider : public ContextProviderBase { + public: + static ContextProviderBase *create(void *data); + static void destroy(void *data); + static bool isSupported(const char *subject); + static void submitTriggerItem(); + + int subscribe(const char* subject, ctx::Json option, ctx::Json* requestResult); + int unsubscribe(const char* subject, ctx::Json option); + int read(const char* subject, ctx::Json option, ctx::Json* requestResult); + int write(const char* subject, ctx::Json data, ctx::Json* requestResult); + + private: + static SocialStatisticsProvider *__instance; + + SocialStatisticsProvider(); + ~SocialStatisticsProvider(); + bool __init(); + + }; /* class SocialStatisticsProvider */ + +} /* namespace ctx */ + +#endif /* End of _CONTEXT_SOCIAL_STATS_PROVIDER_H_ */ diff --git a/src/statistics/social/SocialStatisticsTypes.h b/src/statistics/social/SocialStatisticsTypes.h new file mode 100644 index 0000000..2675302 --- /dev/null +++ b/src/statistics/social/SocialStatisticsTypes.h @@ -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_STATS_SOCIAL_TYPES_H_ +#define _CONTEXT_STATS_SOCIAL_TYPES_H_ + +#include "../shared/CommonTypes.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 SocialCommType { + SOCIAL_COMMUNICATION_TYPE_CALL = 1, + SOCIAL_COMMUNICATION_TYPE_MESSAGE, + SOCIAL_COMMUNICATION_TYPE_ALL +}; + +#endif /* End of _CONTEXT_STATS_SOCIAL_TYPES_ */ diff --git a/src/statistics/social/db_handle.cpp b/src/statistics/social/db_handle.cpp deleted file mode 100644 index 6dfa677..0000000 --- a/src/statistics/social/db_handle.cpp +++ /dev/null @@ -1,161 +0,0 @@ -/* - * 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 -#include -#include -#include -#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_INCOMING << - " 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_INCOMING << - " 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::replyToRead(req_subject.c_str(), req_filter, error, results); -} diff --git a/src/statistics/social/db_handle.h b/src/statistics/social/db_handle.h deleted file mode 100644 index 1bf88fd..0000000 --- a/src/statistics/social/db_handle.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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 -#include -#include "../shared/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 deleted file mode 100644 index 9d58c1a..0000000 --- a/src/statistics/social/log_aggregator.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/* - * 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 -#include -#include -#include "social_stats_types.h" -#include "log_aggregator.h" - -ctx::contact_log_aggregator::contact_log_aggregator() - : timer_id(-1) - , time_diff(0) -{ - create_table(); - timer_id = __timerManager.setAt(3, 0, DayOfWeek::EVERYDAY, this); -} - -ctx::contact_log_aggregator::~contact_log_aggregator() -{ - __timerManager.remove(timer_id); -} - -void ctx::contact_log_aggregator::create_table() -{ - static bool done = false; - IF_FAIL_VOID(!done); - - __dbManager.createTable(0, SOCIAL_TABLE_CONTACT_LOG, SOCIAL_TABLE_CONTACT_LOG_COLUMNS, NULL, NULL); - __dbManager.execute(0, SOCIAL_TEMP_CONTACT_FREQ_SQL, NULL); - - done = true; -} - -bool ctx::contact_log_aggregator::onTimerExpired(int timer) -{ - aggregate_contact_log(); - return true; -} - -void ctx::contact_log_aggregator::aggregate_contact_log() -{ - __dbManager.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::onExecuted(unsigned int query_id, int error, std::vector& 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_INCOMING); - 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); - - __dbManager.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; - __dbManager.execute(0, query.str().c_str(), NULL); -} diff --git a/src/statistics/social/log_aggregator.h b/src/statistics/social/log_aggregator.h deleted file mode 100644 index a73c44b..0000000 --- a/src/statistics/social/log_aggregator.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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 -#include -#include - -namespace ctx { - - class contact_log_aggregator : public IDatabaseListener, public ITimerListener { - private: - int timer_id; - int time_diff; - TimerManager __timerManager; - DatabaseManager __dbManager; - - 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 onTableCreated(unsigned int queryId, int error) {} - void onInserted(unsigned int queryId, int error, int64_t rowId) {} - void onExecuted(unsigned int query_id, int error, std::vector& records); - bool onTimerExpired(int timer_id); - - }; /* 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 deleted file mode 100644 index 196b11e..0000000 --- a/src/statistics/social/social_stats_provider.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* - * 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 -#include -#include -#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::ContextProviderBase *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::registerTriggerItem(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* requestResult) -{ - 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* requestResult) -{ - 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* requestResult) -{ - return ERR_NOT_SUPPORTED; -} diff --git a/src/statistics/social/social_stats_provider.h b/src/statistics/social/social_stats_provider.h deleted file mode 100644 index 1666b78..0000000 --- a/src/statistics/social/social_stats_provider.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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 -#include "social_stats_types.h" - -namespace ctx { - - class social_statistics_provider : public ContextProviderBase { - public: - static ContextProviderBase *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* requestResult); - int unsubscribe(const char* subject, ctx::Json option); - int read(const char* subject, ctx::Json option, ctx::Json* requestResult); - int write(const char* subject, ctx::Json data, ctx::Json* requestResult); - - 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 deleted file mode 100644 index ae52986..0000000 --- a/src/statistics/social/social_stats_types.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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 "../shared/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 deleted file mode 100644 index 1fa29ee..0000000 --- a/src/statistics/statistics_context_provider.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - * 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 -#include -#include -#include - -#include "app/app_stats_provider.h" - -#ifndef _DISABLE_PREDICTION_ENGINE_ -// include prediction engine header files here -#endif - -#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 -void registerProvider(const char *subject, const char *privilege) -{ - if (!provider::is_supported(subject)) - return; - - ctx::ContextProviderInfo providerInfo(provider::create, provider::destroy, NULL, privilege); - ctx::context_manager::registerProvider(subject, providerInfo); -} - -EXTAPI bool ctx::initStatisticsContextProvider() -{ - app_statistics_provider::create(NULL); - registerProvider(APP_SUBJ_RECENTLY_USED, APP_HISTORY_PRIV); - registerProvider(APP_SUBJ_FREQUENTLY_USED, APP_HISTORY_PRIV); - registerProvider(APP_SUBJ_RARELY_USED, APP_HISTORY_PRIV); - registerProvider(APP_SUBJ_PEAK_TIME, APP_HISTORY_PRIV); - registerProvider(APP_SUBJ_COMMON_SETTING, APP_HISTORY_PRIV); - registerProvider(APP_SUBJ_FREQUENCY, APP_HISTORY_PRIV); - app_statistics_provider::submit_trigger_item(); - -#ifndef _DISABLE_PREDICTION_ENGINE_ -// initialize the prediction engine here -#endif - -#ifdef _MOBILE_ - media_statistics_provider::create(NULL); - registerProvider(MEDIA_SUBJ_PEAK_TIME_FOR_MUSIC, MEDIA_HISTORY_PRIV); - registerProvider(MEDIA_SUBJ_PEAK_TIME_FOR_VIDEO, MEDIA_HISTORY_PRIV); - registerProvider(MEDIA_SUBJ_COMMON_SETTING_FOR_MUSIC, MEDIA_HISTORY_PRIV); - registerProvider(MEDIA_SUBJ_COMMON_SETTING_FOR_VIDEO, MEDIA_HISTORY_PRIV); - registerProvider(MEDIA_SUBJ_MUSIC_FREQUENCY, MEDIA_HISTORY_PRIV); - registerProvider(MEDIA_SUBJ_VIDEO_FREQUENCY, MEDIA_HISTORY_PRIV); - media_statistics_provider::submit_trigger_item(); - - social_statistics_provider::create(NULL); - registerProvider(SOCIAL_SUBJ_FREQ_ADDRESS, SOCIAL_HISTORY_PRIV); - registerProvider(SOCIAL_SUBJ_FREQUENCY, SOCIAL_HISTORY_PRIV); - social_statistics_provider::submit_trigger_item(); -#endif - -#ifdef _TV_ - media_statistics_provider::create(NULL); - registerProvider(MEDIA_SUBJ_PEAK_TIME_FOR_MUSIC, MEDIA_HISTORY_PRIV); - registerProvider(MEDIA_SUBJ_PEAK_TIME_FOR_VIDEO, MEDIA_HISTORY_PRIV); - registerProvider(MEDIA_SUBJ_COMMON_SETTING_FOR_MUSIC, MEDIA_HISTORY_PRIV); - registerProvider(MEDIA_SUBJ_COMMON_SETTING_FOR_VIDEO, MEDIA_HISTORY_PRIV); - registerProvider(MEDIA_SUBJ_MUSIC_FREQUENCY, MEDIA_HISTORY_PRIV); - registerProvider(MEDIA_SUBJ_VIDEO_FREQUENCY, MEDIA_HISTORY_PRIV); - media_statistics_provider::submit_trigger_item(); -#endif - - return true; -}