statistics: modify foregroun app monitor to run in two-phases 53/58653/2
authorMu-Woong Lee <muwoong.lee@samsung.com>
Tue, 2 Feb 2016 11:58:27 +0000 (20:58 +0900)
committerMu-Woong Lee <muwoong.lee@samsung.com>
Wed, 3 Feb 2016 04:45:53 +0000 (13:45 +0900)
Creating a log record when an app goes to foreground,
and update the duration attribute of the record when another app goes to foreground.

Change-Id: I68f336d78b24e86056d4bfa68c753d831d0ba14d
Signed-off-by: Mu-Woong Lee <muwoong.lee@samsung.com>
src/statistics/app/active_window_monitor.cpp
src/statistics/app/active_window_monitor.h

index 629950828af70a5528d08a9153052cc44e1701cc..ee7ea660626125d123986fbb841623a6384db65b 100644 (file)
 
 /* Active window changes frequently.
  * We thus consider the apps being foregrounded at least 3 secs */
-#define MIN_VALID_USE_TIME 2
 #define ONE_DAY_IN_SEC 86400
 
 ctx::app_use_monitor::app_use_monitor()
        : signal_id(-1)
        , last_cleanup_time(0)
-       , last_timestamp(0)
-       , last_pid(-1)
 {
        start_logging();
 }
@@ -70,102 +67,84 @@ void ctx::app_use_monitor::on_signal_received(const char* sender, const char* pa
        const gchar *type = NULL;
 
        g_variant_get(param, "(i&s&s&s&s)", &pid, &appid, &pkgid, &status, &type);
-       IF_FAIL_VOID(appid && status && type);
-       IF_FAIL_VOID(STR_EQ(status, "fg") && STR_EQ(type, "uiapp"));
-
-       on_active_window_changed(appid);
-}
-
-void ctx::app_use_monitor::on_active_window_changed(std::string app_id)
-{
-       IF_FAIL_VOID(last_app_id != app_id);
-       _D("New fourground app '%s'", app_id.c_str());
-
-       int timestamp = static_cast<int>(time(NULL));
-       int duration = timestamp - last_timestamp;
-
-       if (!last_app_id.empty() && duration >= MIN_VALID_USE_TIME)
-               verify_used_app(last_app_id.c_str(), duration);
-
-       last_timestamp = timestamp;
-       last_app_id = app_id;
-}
+       _D("AppEvent: %s, %s, %s", appid, status, type);
 
-void ctx::app_use_monitor::verify_used_app(const char *app_id, int duration)
-{
-       app_info_h app_info = NULL;
-       int err = app_manager_get_app_info(app_id, &app_info);
-       IF_FAIL_VOID_TAG(err == APP_MANAGER_ERROR_NONE && app_info, _E, "app_manager_get_app_info() failed");
-
-       bool nodisp = false;
-       err = app_info_is_nodisplay(app_info, &nodisp);
-       IF_FAIL_CATCH_TAG(err == APP_MANAGER_ERROR_NONE, _E, "app_info_is_nodisplay() failed");
-       IF_FAIL_CATCH(!nodisp);
-
-       insert_log(app_id, duration);
+       IF_FAIL_VOID(appid && status && type);
+       IF_FAIL_VOID(STR_EQ(type, "uiapp") && !is_skippable(appid));
 
-CATCH:
-       if (app_info)
-               app_info_destroy(app_info);
+       if (STR_EQ(status, "fg")) {
+               create_record(appid);
+       } else if (STR_EQ(status, "bg")) {
+               finish_record(appid);
+               remove_expired();
+       }
 }
 
-void ctx::app_use_monitor::insert_log(const char *app_id, int duration)
+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);
 
-       std::stringstream cols;
-       std::stringstream vals;
-
-       /* App ID */
-       cols << STATS_APP_ID << ",";
-       vals << "'" << app_id << "',";
+       if (ctx::system_info::get_audio_jack_state(&audiojack))
+               data.set(NULL, STATS_AUDIO_JACK, audiojack);
 
-       /* Audio Jack */
-       if (ctx::system_info::get_audio_jack_state(&audiojack)) {
-               cols << STATS_AUDIO_JACK << ",";
-               vals << audiojack << ",";
-       }
-
-       /* Volume */
        if (ctx::system_info::get_volume(&system_volume, &media_volume)) {
-               cols << STATS_SYSTEM_VOLUME << "," << STATS_MEDIA_VOLUME << ",";
-               vals << system_volume << "," << media_volume << ",";
+               data.set(NULL, STATS_SYSTEM_VOLUME, system_volume);
+               data.set(NULL, STATS_MEDIA_VOLUME, media_volume);
        }
 
-       /* BSSID */
-       if (ctx::system_info::get_wifi_bssid(bssid)) {
-               cols << STATS_BSSID << ",";
-               vals << "'" << bssid << "',";
-       }
+       if (ctx::system_info::get_wifi_bssid(bssid))
+               data.set(NULL, STATS_BSSID, bssid);
 
-       /* Time */
-       cols << STATS_UNIV_TIME << ",";
-       vals << "(strftime('%s', 'now')) - " << duration << ",";
+       db_manager::insert(0, APP_TABLE_USAGE_LOG, data, NULL);
+}
 
-       cols << STATS_LOCAL_TIME << ",";
-       vals << "(strftime('%s', 'now', 'localtime')) - " << duration << ",";
+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)";
+       db_manager::execute(0, query.str().c_str(), NULL);
+}
 
-       /* Duration */
-       cols << STATS_DURATION;
-       vals << duration;
+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");
 
-       std::stringstream query;
-       append_cleanup_query(query);
-       query << "INSERT INTO " << APP_TABLE_USAGE_LOG << " ("
-               << cols.str() << ") VALUES (" << vals.str() << ")";
+       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;
+       }
 
-       db_manager::execute(0, query.str().c_str(), NULL);
+       app_info_destroy(app_info);
+       return nodisp;
 }
 
-void ctx::app_use_monitor::append_cleanup_query(std::stringstream &query)
+void ctx::app_use_monitor::remove_expired()
 {
-       IF_FAIL_VOID(last_timestamp - last_cleanup_time >= ONE_DAY_IN_SEC);
+       int timestamp = static_cast<int>(time(NULL));
+       IF_FAIL_VOID(timestamp - last_cleanup_time >= ONE_DAY_IN_SEC);
 
-       last_cleanup_time = last_timestamp;
+       last_cleanup_time = timestamp;
 
+       std::stringstream query;
        query << "DELETE FROM " APP_TABLE_USAGE_LOG " WHERE " \
-               STATS_UNIV_TIME " < strftime('%s', 'now') - " << LOG_RETENTION_PERIOD << ";";
+               STATS_UNIV_TIME " < strftime('%s', 'now') - " << LOG_RETENTION_PERIOD;
+       db_manager::execute(0, query.str().c_str(), NULL);
 }
index 685d41cbfec5ddc36c93e7b6871b36b3e85130da..c20f6aa89f41c4a2b96329c099b090086656c706 100644 (file)
@@ -27,18 +27,14 @@ namespace ctx {
        private:
                int64_t signal_id;
                int last_cleanup_time;
-               int last_timestamp;
-               int last_pid;
-               std::string last_app_id;
 
                bool start_logging(void);
                void stop_logging(void);
 
-               void verify_used_app(const char *app_id, int duration);
-               void insert_log(const char *app_id, int duration);
-               void append_cleanup_query(std::stringstream &query);
-
-               void on_active_window_changed(std::string app_id);
+               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 on_signal_received(const char* sender, const char* path, const char* iface, const char* name, GVariant* param);
 
        public: