Add APIs for managing recent stickers history 47/230147/7
authorInHong Han <inhong1.han@samsung.com>
Tue, 7 Apr 2020 09:36:03 +0000 (18:36 +0900)
committerInHong Han <inhong1.han@samsung.com>
Fri, 10 Apr 2020 09:06:49 +0000 (18:06 +0900)
Change-Id: I9f1ae1c9bf066822e497bc5a4c03eaefb12f58d4

client/sticker_dbus.c
client/sticker_dbus.h
consumer/sticker_consumer.c
include/sticker_consumer.h
server/stickerd_data_manager.c
server/stickerd_data_manager.h
server/stickerd_db_manager.c
server/stickerd_db_manager.h

index 5460c71..c6aaaea 100644 (file)
@@ -1108,4 +1108,40 @@ int sticker_dbus_check_file_exists(GDBusConnection *gdbus_connection, const char
         g_object_unref(reply);
 
     return ret;
+}
+
+int sticker_dbus_insert_recent_sticker_info(GDBusConnection *gdbus_connection, int record_id)
+{
+    int ret;
+    GDBusMessage *reply = NULL;
+
+    ret = _send_sync_message(gdbus_connection, g_variant_new("(i)", record_id), &reply, "insert_recent_sticker_info");
+    if (ret != STICKER_CLIENT_ERROR_NONE)
+        LOGE("failed to insert recent sticker info");
+
+    if (reply)
+        g_object_unref(reply);
+
+    return ret;
+}
+
+int sticker_dbus_get_recent_sticker_list(GDBusConnection *gdbus_connection, int count, GVariantIter **id_iter)
+{
+    int ret;
+    GDBusMessage *reply = NULL;
+    GVariant *reply_body = NULL;
+
+    ret = _send_sync_message(gdbus_connection, g_variant_new("(i)", count), &reply, "get_recent_sticker_info");
+    if (ret == STICKER_CLIENT_ERROR_NONE) {
+        reply_body = g_dbus_message_get_body(reply);
+        g_variant_get(reply_body, "(a(i))", &(*id_iter));
+    }
+
+    if (reply_body)
+        g_variant_unref(reply_body);
+
+    if (reply)
+        g_object_unref(reply);
+
+    return ret;
 }
\ No newline at end of file
index 610cfe1..a6d5437 100644 (file)
@@ -65,6 +65,8 @@ int sticker_dbus_get_sticker_info_by_keyword(GDBusConnection *gdbus_connection,
 int sticker_dbus_get_sticker_info_by_display_type(GDBusConnection *gdbus_connection, const char *app_id, sticker_data_display_type_e type, int offset, int count, GVariantIter **id_iter);
 int sticker_dbus_get_group_list_by_display_type(GDBusConnection *gdbus_connection, const char *app_id, sticker_data_display_type_e type, GList **group_list);
 int sticker_dbus_check_file_exists(GDBusConnection *gdbus_connection, const char *uri, int *result);
+int sticker_dbus_insert_recent_sticker_info(GDBusConnection *gdbus_connection, int record_id);
+int sticker_dbus_get_recent_sticker_list(GDBusConnection *gdbus_connection, int count, GVariantIter **id_iter);
 
 #ifdef __cplusplus
 }
index 5211f36..15ea7fc 100644 (file)
@@ -531,4 +531,70 @@ cleanup:
         g_list_free_full(list, free);
 
     return ret;
+}
+
+EXPORT_API int sticker_consumer_add_recent_data(sticker_consumer_h consumer_handle, sticker_data_h data_handle)
+{
+    CHECK_STICKER_FEATURE();
+
+    int ret;
+
+    if (!consumer_handle || !data_handle || (data_handle->sticker_info_id > 0) || !data_handle->uri)
+        return STICKER_ERROR_INVALID_PARAMETER;
+
+    ret = sticker_dbus_insert_recent_sticker_info(consumer_handle->gdbus_connection, data_handle->sticker_info_id);
+    if (ret != STICKER_ERROR_NONE) {
+        LOGE("Failed to add recent sticker information : %d", ret);
+        return STICKER_ERROR_OPERATION_FAILED;
+    }
+
+    return STICKER_ERROR_NONE;
+}
+
+EXPORT_API int sticker_consumer_get_recent_data_list(sticker_consumer_h consumer_handle, int count, int *result, sticker_consumer_data_foreach_cb callback, void *user_data)
+{
+    CHECK_STICKER_FEATURE();
+
+    int ret;
+    int info_id;
+    int sticker_count = 0;
+    GVariantIter *id_iter = NULL;
+
+    if (!consumer_handle || (count <= 0) || !result || !callback)
+        return STICKER_ERROR_INVALID_PARAMETER;
+
+    ret = sticker_dbus_get_recent_sticker_list(consumer_handle->gdbus_connection, count, &id_iter);
+    if (ret != STICKER_ERROR_NONE) {
+        LOGE("Failed to get recent sticker information : %d", ret);
+        ret = STICKER_ERROR_OPERATION_FAILED;
+        goto cleanup;
+    }
+
+    if (id_iter) {
+        while (g_variant_iter_loop (id_iter, "(i)", &info_id)) {
+            sticker_data_h sticker_data = (sticker_data_h)calloc(1, sizeof(struct sticker_data_s));
+            if (!sticker_data) {
+                ret = STICKER_ERROR_OUT_OF_MEMORY;
+                goto cleanup;
+            }
+
+            ret = sticker_dbus_get_sticker_info_by_record_id(consumer_handle->gdbus_connection, sticker_data, info_id);
+            if (ret == STICKER_ERROR_NONE) {
+                sticker_count++;
+                callback(sticker_data, user_data);
+                _free_sticker_data(sticker_data);
+            } else {
+                _free_sticker_data(sticker_data);
+                goto cleanup;
+            }
+        }
+    }
+
+    *result = sticker_count;
+
+cleanup:
+    if (id_iter)
+        g_variant_iter_free(id_iter);
+
+    return ret;
 }
\ No newline at end of file
index ac2428e..a143e00 100644 (file)
@@ -279,6 +279,43 @@ int sticker_consumer_data_foreach_by_display_type(sticker_consumer_h consumer_ha
 int sticker_consumer_group_list_foreach_by_display_type(sticker_consumer_h consumer_handle, sticker_data_display_type_e type, sticker_consumer_group_list_foreach_cb callback, void *user_data);
 
 /**
+ * @brief Add history to recently used stickers list
+ * @since_tizen 5.5
+ * @param[in] consumer_handle The sticker consumer handle
+ * @param[in] data_handle The sticker data handle
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_NOT_SUPPORTED Not supported
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STICKER_ERROR_OPERATION_FAILED Operation failed
+ * @see sticker_consumer_get_recent_list()
+ */
+int sticker_consumer_add_recent_data(sticker_consumer_h consumer_handle, sticker_data_h data_handle);
+
+/**
+ * @brief Gets recently used stickers list.
+ * @details The most recently used stickers are delivered in order.
+ * @since_tizen 5.5
+ * @remarks It is not an error if @a result is smaller than @a count.
+ * @param[in] consumer_handle The sticker consumer handle
+ * @param[in] count The number of stickers that you want to receive.
+ *            If -1, the number of stickers is not restricted
+ * @param[out] result The number of stickers received (zero indicates that no data was found)
+ * @param[in] callback The callback function to invoke
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_NOT_SUPPORTED Not supported
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STICKER_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #STICKER_ERROR_OPERATION_FAILED Operation failed
+ * @post This function invokes sticker_consumer_data_foreach_cb() repeatedly for getting data.
+ * @see sticker_consumer_data_foreach_cb()
+ * @see sticker_consumer_add_recent_data()
+ */
+int sticker_consumer_get_recent_data_list(sticker_consumer_h consumer_handle, int count, int *result, sticker_consumer_data_foreach_cb callback, void *user_data);
+
+/**
  * @}
  */
 
index 3585b8d..251e9c0 100644 (file)
@@ -149,6 +149,10 @@ static void _stickerd_client_dbus_method_call_handler(GDBusConnection *conn, con
         ret = stickerd_update_sticker_disp_type(parameters, &reply_body);
     } else if (g_strcmp0(method_name, "check_file_exists") == 0) {
         ret = stickerd_check_file_exists(parameters, &reply_body);
+    } else if (g_strcmp0(method_name, "insert_recent_sticker_info") == 0) {
+        ret = stickerd_insert_recent_sticker_info(parameters, &reply_body);
+    } else if (g_strcmp0(method_name, "get_recent_sticker_info") == 0) {
+        ret = stickerd_get_recent_sticker_info(parameters, &reply_body);
     }
 
     if (ret == STICKERD_SERVER_ERROR_NONE) {
@@ -315,6 +319,15 @@ int stickerd_register_dbus_interface(void)
             "          <arg type='s' name='uri' direction='in'/>"
             "          <arg type='i' name='result' direction='out'/>"
             "        </method>"
+
+            "        <method name='insert_recent_sticker_info'>"
+            "          <arg type='i' name='record_id' direction='in'/>"
+            "        </method>"
+
+            "        <method name='get_recent_sticker_info'>"
+            "          <arg type='i' name='count' direction='in'/>"
+            "          <arg type='a(i)' name='id_list' direction='out'/>"
+            "        </method>"
             "  </interface>"
             "  </node>";
 
@@ -1558,4 +1571,61 @@ int stickerd_check_file_exists(GVariant *parameters, GVariant **reply_body)
     }
 
     return ret;
+}
+
+int stickerd_insert_recent_sticker_info(GVariant *parameters, GVariant **reply_body)
+{
+    int ret;
+    int record_id;
+
+    *reply_body = g_variant_new("()");
+    if (*reply_body == NULL) {
+        LOGE("Failed to create reply_body");
+        return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+    }
+
+    g_variant_get(parameters, "(i)", &record_id);
+
+    ret = stickerd_db_insert_recent_sticker_info(record_id);
+    if (ret != STICKERD_SERVER_ERROR_NONE) {
+        LOGE("Failed to insert recent sticker info");
+        return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+    }
+
+    return ret;
+}
+
+int stickerd_get_recent_sticker_info(GVariant *parameters, GVariant **reply_body)
+{
+    int ret;
+    int count;
+    GList *id_list = NULL;
+    GVariantBuilder *id_builder = NULL;
+
+    g_variant_get(parameters, "(i)", &count);
+
+    ret = stickerd_db_get_record_id(STICKER_DB_STICKER_RECENT_HISTORY, &id_list, NULL, NULL, 0, count);
+    if (ret != STICKERD_SERVER_ERROR_NONE) {
+        LOGE("Failed to get recent sticker id");
+        if(id_list)
+            g_list_free_full(id_list, free);
+        return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+    }
+
+    id_builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
+    g_list_foreach(id_list, (GFunc) _set_id_builder, id_builder);
+
+    *reply_body = g_variant_new("(a(i))", id_builder);
+    if (*reply_body == NULL) {
+        LOGE("Failed to create reply_body");
+        ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
+    }
+
+    if (id_list)
+        g_list_free_full(id_list, free);
+
+    if (id_builder)
+        g_variant_builder_unref(id_builder);
+
+    return ret;
 }
\ No newline at end of file
index e09e91d..ea90752 100644 (file)
@@ -48,6 +48,8 @@ int stickerd_get_sticker_info_by_display_type(GVariant *parameters, GVariant **r
 int stickerd_get_group_list_by_disp_type(GVariant *parameters, GVariant **reply_body);
 int stickerd_update_sticker_disp_type(GVariant *parameters, GVariant **reply_body);
 int stickerd_check_file_exists(GVariant *parameters, GVariant **reply_body);
+int stickerd_insert_recent_sticker_info(GVariant *parameters, GVariant **reply_body);
+int stickerd_get_recent_sticker_info(GVariant *parameters, GVariant **reply_body);
 
 #ifdef __cplusplus
 }
index 3adda1b..79d4c61 100644 (file)
@@ -60,6 +60,7 @@
 
 #define STICKER_DB_INSERT_STICKER_INFO "INSERT INTO sticker_info (app_id, type, uri, thumbnail, description, group_name, date, display_type) VALUES (?, ?, ?, ?, ?, ?, DateTime('now','localtime'), ?)"
 #define STICKER_DB_INSERT_STICKER_KEYWORD_INFO "INSERT INTO sticker_keyword_info (sticker_info_id, keyword) VALUES (?, ?)"
+#define STICKER_DB_INSERT_RECENT_HISTORY "INSERT INTO sticker_recent_history_info (sticker_info_id, count, timestamp) VALUES (?, 1, DateTime('now','localtime'))"
 
 #define STICKER_DB_DELETE_STICKER_INFO "DELETE FROM sticker_info WHERE sticker_info_id = ?"
 #define STICKER_DB_DELETE_STICKER_KEYWORD_INFO "DELETE FROM sticker_keyword_info WHERE sticker_info_id = ?"
@@ -71,6 +72,7 @@
 #define STICKER_DB_UPDATE_STICKER_DESCRIPTION "UPDATE sticker_info SET description = ?, date = DateTime('now','localtime') WHERE sticker_info_id = ?"
 #define STICKER_DB_UPDATE_STICKER_GROUP "UPDATE sticker_info SET group_name = ?, date = DateTime('now','localtime') WHERE sticker_info_id = ?"
 #define STICKER_DB_UPDATE_STICKER_DISP_TYPE "UPDATE sticker_info SET display_type = ?, date = DateTime('now','localtime') WHERE sticker_info_id = ?"
+#define STICKER_DB_UPDATE_RECENT_HISTORY "UPDATE sticker_recent_history_info SET count = count + 1, timestamp = DateTime('now','localtime') WHERE sticker_info_id = ?"
 
 #define STICKER_DB_GET_LATEST_RECORD_ID "SELECT sticker_info_id FROM sticker_info ORDER BY sticker_info_id DESC LIMIT 1"
 #define STICKER_DB_GET_STICKER_INFO_BY_RECORD_ID "SELECT * FROM sticker_info WHERE sticker_info_id = ?"
@@ -88,6 +90,8 @@
 #define STICKER_DB_GET_RECORD_ID_BY_DISP_TYPE "SELECT sticker_info_id FROM sticker_info WHERE display_type = ? AND app_id NOT IN (SELECT DISTINCT provider_id FROM sticker_whitelist_info WHERE provider_id NOT IN (SELECT provider_id FROM sticker_whitelist_info WHERE consumer_id = ?)) LIMIT ?, ?"
 #define STICKER_DB_GET_GROUP_LIST_BY_DISP_TYPE "SELECT DISTINCT group_name FROM sticker_info WHERE display_type = ? AND app_id NOT IN (SELECT DISTINCT provider_id FROM sticker_whitelist_info WHERE provider_id NOT IN (SELECT provider_id FROM sticker_whitelist_info WHERE consumer_id = ?))"
 #define STICKER_DB_CHECK_FILE_EXISTS "SELECT EXISTS(SELECT 1 FROM sticker_info WHERE uri = ? LIMIT 1)"
+#define STICKER_DB_CHECK_RECENT_HISTORY_EXISTS "SELECT EXISTS(SELECT 1 FROM sticker_recent_history_info WHERE sticker_info_id = ? LIMIT 1)"
+#define STICKER_DB_GET_RECENT_HISTORY "SELECT sticker_info_id FROM sticker_recent_history_info ORDER BY datetime(timestamp) DESC LIMIT ?"
 
 typedef enum
 {
@@ -147,6 +151,8 @@ static const char *_db_get_query(sticker_info_db_type sticker_type, command_type
             break;
             case STICKER_DB_STICKER_DISP_TYPE:
             query = STICKER_DB_GET_RECORD_ID_BY_DISP_TYPE;
+            case STICKER_DB_STICKER_RECENT_HISTORY:
+            query = STICKER_DB_GET_RECENT_HISTORY;
             break;
             default :
             query = "";
@@ -811,6 +817,8 @@ int stickerd_db_get_record_id(sticker_info_db_type type, GList **id_list, void *
         sqlite3_bind_text(stmt, 1, app_id, -1, SQLITE_TRANSIENT);
         sqlite3_bind_int(stmt, 2, offset);
         sqlite3_bind_int(stmt, 3, count);
+    } else if (type == STICKER_DB_STICKER_RECENT_HISTORY) {
+        sqlite3_bind_int(stmt, 1, count);
     } else {
         if (type == STICKER_DB_STICKER_TYPE || type == STICKER_DB_STICKER_DISP_TYPE)
             sqlite3_bind_int(stmt, 1, *(int *)data);
@@ -913,4 +921,66 @@ cleanup:
     sqlite3_close(db);
 
     return STICKERD_SERVER_ERROR_DB_FAILED;
+}
+
+int stickerd_db_insert_recent_sticker_info(int record_id)
+{
+    int ret;
+    sqlite3 *db = NULL;
+    sqlite3_stmt *stmt = NULL;
+
+    db = _db_open();
+    if (!db)
+        return STICKERD_SERVER_ERROR_DB_FAILED;
+
+    ret = sqlite3_prepare_v2(db, STICKER_DB_CHECK_RECENT_HISTORY_EXISTS, -1, &stmt, NULL);
+    if (ret != SQLITE_OK) {
+        LOGE("fail to check recent sticker exists : %s", sqlite3_errmsg(db));
+        goto cleanup;
+    }
+
+    sqlite3_bind_int(stmt, 1, record_id);
+
+    ret = sqlite3_step(stmt);
+    if (ret == SQLITE_ERROR) {
+        LOGE("sqlite3_step() failed : ret(%d)", ret);
+        goto cleanup;
+    }
+
+    int result = sqlite3_column_int(stmt, 0);
+
+    sqlite3_finalize(stmt);
+    stmt = NULL;
+
+    if (result)
+        ret = sqlite3_prepare_v2(db, STICKER_DB_UPDATE_RECENT_HISTORY, -1, &stmt, NULL);
+    else
+        ret = sqlite3_prepare_v2(db, STICKER_DB_INSERT_RECENT_HISTORY, -1, &stmt, NULL);
+
+    if (ret != SQLITE_OK) {
+        LOGE("fail to update recent history : %s", sqlite3_errmsg(db));
+        goto cleanup;
+    }
+
+    sqlite3_bind_int(stmt, 1, record_id);
+
+    ret = sqlite3_step(stmt);
+    if (ret != SQLITE_OK && ret != SQLITE_DONE) {
+        LOGE("sqlite3_step() failed : ret(%d)", ret);
+        goto cleanup;
+    } else if (sqlite3_changes(db) == 0) {
+        LOGE("No changes to DB");
+        goto cleanup;
+    }
+
+    sqlite3_finalize(stmt);
+    sqlite3_close(db);
+
+    return STICKERD_SERVER_ERROR_NONE;
+
+cleanup:
+    sqlite3_finalize(stmt);
+    sqlite3_close(db);
+
+    return STICKERD_SERVER_ERROR_DB_FAILED;
 }
\ No newline at end of file
index 4a14e50..38e13b5 100644 (file)
@@ -34,6 +34,7 @@ typedef enum {
     STICKER_DB_STICKER_GROUP,
     STICKER_DB_STICKER_KEYWORD,
     STICKER_DB_STICKER_DISP_TYPE,
+    STICKER_DB_STICKER_RECENT_HISTORY,
 } sticker_info_db_type;
 
 typedef struct {
@@ -60,6 +61,7 @@ int stickerd_db_get_sticker_count(int *count, char *app_id);
 int stickerd_db_get_record_id(sticker_info_db_type type, GList **id_list, void *data, char *app_id, int offset, int count);
 int stickerd_db_get_group_list_by_display_type(GVariantBuilder *builder, char *app_id, int disp_type);
 int stickerd_db_check_file_exists(int *result, char *uri);
+int stickerd_db_insert_recent_sticker_info(int record_id);
 
 #ifdef __cplusplus
 }