From 9dd2989caf6f10420c26df483aa89ab57f379da6 Mon Sep 17 00:00:00 2001 From: Myungki Lee Date: Fri, 16 Dec 2016 19:06:53 +0900 Subject: [PATCH] Add the check routine for app_enable/disable - when app disabled, notification will not post. Change-Id: If6bffd5b4e73e5127655270b57c5ec6d1f9e3d78 Signed-off-by: Myungki Lee --- include/notification_setting_internal.h | 43 ++++++++++++++-- include/notification_setting_service.h | 1 + scripts/505.notification_upgrade.sh | 1 + src/notification_db.c | 1 + src/notification_ipc.c | 15 ++++-- src/notification_noti.c | 88 +++++++++++++++++++++++++++++---- src/notification_setting.c | 14 ++++++ src/notification_setting_service.c | 45 +++++++++++++++-- test-app/main.c | 2 +- 9 files changed, 187 insertions(+), 23 deletions(-) diff --git a/include/notification_setting_internal.h b/include/notification_setting_internal.h index fcc9df6..7fd9c98 100644 --- a/include/notification_setting_internal.h +++ b/include/notification_setting_internal.h @@ -83,11 +83,12 @@ typedef enum notification_dnd_allowed_calls { struct notification_setting { char *package_name; char *appid; - bool allow_to_notify; - bool do_not_disturb_except; - bool pop_up_notification; - int visibility_class; + bool allow_to_notify; + bool do_not_disturb_except; + bool pop_up_notification; + int visibility_class; lock_screen_content_level_e lock_screen_content_level; + bool app_disabled; }; /* System setting */ @@ -560,6 +561,40 @@ int notification_setting_set_lock_screen_content(notification_setting_h setting, /* * @internal + * @brief Gets The value that determines whether the app is disabled + * @since_tizen 3.0 + * @privlevel public + * @privilege %http://tizen.org/privilege/notification + * @param[in] setting The notification system setting handle + * @param[out] value The value that determines whether the app is disabled + * @return #NOTIFICATION_ERROR_NONE on success, + * otherwise any other value on failure + * @retval #NOTIFICATION_ERROR_NONE Success + * @retval #NOTIFICATION_ERROR_INVALID_PARAMETER Invalid parameter + * @par sample code: + * @code +#include +{ + int err = 0; + bool value = true; + notification_system_setting_h setting = NULL; + + err = notification_setting_get_setting(&setting); + if (err != NOTIFICATION_ERROR_NONE) + return; + + err = notification_setting_get_app_disabled(setting, &value); + if (err != NOTIFICATION_ERROR_NONE) + return; + + return 0; +} + * @endcode + */ +int notification_setting_get_app_disabled(notification_setting_h setting, bool *value); + +/* + * @internal * @brief Gets the notification system setting handle. * @since_tizen @if wearable 2.3.1 @elseif mobile 2.3 @endif * @privlevel public diff --git a/include/notification_setting_service.h b/include/notification_setting_service.h index b146141..fdf15bb 100644 --- a/include/notification_setting_service.h +++ b/include/notification_setting_service.h @@ -44,6 +44,7 @@ int notification_system_setting_get_dnd_schedule_enabled_uid(uid_t **uids, int * int notification_get_dnd_and_allow_to_notify(const char *appid, int *do_not_disturb, int *do_not_disturb_except, int *allow_to_notify, uid_t uid); int notification_system_setting_load_dnd_allow_exception(dnd_allow_exception_h *dnd_allow_exception, int *count, uid_t uid); int notification_system_setting_update_dnd_allow_exception(int type, int value, uid_t uid); +int notification_setting_db_update_app_disabled(const char *appid, bool value, uid_t uid); #ifdef __cplusplus } #endif diff --git a/scripts/505.notification_upgrade.sh b/scripts/505.notification_upgrade.sh index 17ea26c..f57d2ff 100644 --- a/scripts/505.notification_upgrade.sh +++ b/scripts/505.notification_upgrade.sh @@ -79,6 +79,7 @@ CREATE TABLE notification_setting ( visibility_class INTEGER DEFAULT 0, pop_up_notification INTEGER DEFAULT 1, lock_screen_content_level INTEGER DEFAULT 0, + app_disabled INTEGER DEFAULT 0, UNIQUE (uid, package_name, appid) ); diff --git a/src/notification_db.c b/src/notification_db.c index ea002ff..d9c0791 100755 --- a/src/notification_db.c +++ b/src/notification_db.c @@ -135,6 +135,7 @@ create table if not exists noti_list ( \ visibility_class INTEGER DEFAULT 0, \ pop_up_notification INTEGER DEFAULT 1, \ lock_screen_content_level INTEGER DEFAULT 0, \ + app_disabled INTEGER DEFAULT 0, \ UNIQUE (uid, package_name, appid) \ ); \ CREATE TABLE IF NOT EXISTS notification_system_setting ( \ diff --git a/src/notification_ipc.c b/src/notification_ipc.c index f17badf..c568ff1 100755 --- a/src/notification_ipc.c +++ b/src/notification_ipc.c @@ -1397,7 +1397,7 @@ int notification_ipc_update_setting(notification_setting_h setting, uid_t uid) return result; } - body = g_variant_new("(ssiiiiii)", + body = g_variant_new("(ssiiiiiii)", setting->package_name, setting->appid, (int)(setting->allow_to_notify), @@ -1405,6 +1405,7 @@ int notification_ipc_update_setting(notification_setting_h setting, uid_t uid) (int)(setting->visibility_class), (int)(setting->pop_up_notification), (int)(setting->lock_screen_content_level), + (int)(setting->app_disabled), uid); result = _send_sync_noti(body, &reply, "update_noti_setting"); @@ -2091,14 +2092,15 @@ EXPORT_API GVariant *notification_ipc_make_gvariant_from_setting(struct notifica { GVariant *body = NULL; - body = g_variant_new("(ssiiiii)", + body = g_variant_new("(ssiiiiii)", noti_setting->package_name, noti_setting->appid, noti_setting->allow_to_notify, noti_setting->do_not_disturb_except, noti_setting->visibility_class, noti_setting->pop_up_notification, - noti_setting->lock_screen_content_level); + noti_setting->lock_screen_content_level, + noti_setting->app_disabled); return body; } @@ -2114,20 +2116,22 @@ EXPORT_API int notification_ipc_make_setting_from_gvariant(struct notification_s int visibility_class; int pop_up_notification; int lock_screen_content_level; + int app_disabled; if (noti_setting == NULL || variant == NULL) { NOTIFICATION_ERR("invalid data"); return NOTIFICATION_ERROR_INVALID_PARAMETER; } g_variant_get(variant, - "(&s&siiiii)", + "(&s&siiiiii)", &pkgname, &appid, &allow_to_notify, &do_not_disturb_except, &visibility_class, &pop_up_notification, - &lock_screen_content_level); + &lock_screen_content_level, + &app_disabled); NOTIFICATION_DBG("setting from variant %s !!", pkgname); @@ -2138,6 +2142,7 @@ EXPORT_API int notification_ipc_make_setting_from_gvariant(struct notification_s noti_setting->visibility_class = visibility_class; noti_setting->pop_up_notification = pop_up_notification; noti_setting->lock_screen_content_level = lock_screen_content_level; + noti_setting->app_disabled = app_disabled; NOTIFICATION_DBG("setting from variant %s, %s", noti_setting->package_name, pkgname); diff --git a/src/notification_noti.c b/src/notification_noti.c index 635d60b..1bcc46e 100755 --- a/src/notification_noti.c +++ b/src/notification_noti.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -706,26 +707,88 @@ err: return ret; } -static bool _is_allowed_to_notify(const char *appid, uid_t uid) +static int __get_setting_from_app_control(notification_h noti, notification_setting_h *setting) +{ + notification_setting_h setting_new = NULL; + app_control_h app_control = NULL; + bundle *b = NULL; + char *app_id = NULL; + int ret; + + ret = notification_get_execute_option(noti, + NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH, + NULL, + &b); + if (ret != NOTIFICATION_ERROR_NONE || b == NULL) { + NOTIFICATION_ERR("notification_get_execute_option failed [%x]", ret); + return ret; + } + + ret = app_control_create(&app_control); + if (ret != APP_CONTROL_ERROR_NONE) { + NOTIFICATION_ERR("app_control_create failed [%x]", ret); + goto out; + } + + ret = app_control_import_from_bundle(app_control, b); + if (ret != APP_CONTROL_ERROR_NONE) { + NOTIFICATION_ERR("app_control_import_from_bundle failed [%x]", ret); + goto out; + } + + ret = app_control_get_app_id(app_control, &app_id); + if (ret != APP_CONTROL_ERROR_NONE || app_id == NULL) { + NOTIFICATION_ERR("app_control_get_app_id failed [%x]", ret); + goto out; + } + + ret = noti_setting_service_get_setting_by_appid(app_id, &setting_new, noti->uid); + if (ret != APP_CONTROL_ERROR_NONE || setting == NULL) { + NOTIFICATION_ERR("noti_setting_service_get_setting_by_appid failed [%x]", ret); + goto out; + } + + *setting = setting_new; + +out: + if (app_id) + free(app_id); + + if (app_control) + app_control_destroy(app_control); + + return ret; +} + +static bool _is_allowed_to_notify(notification_h noti) { notification_setting_h setting = NULL; - int err; + bool allow_to_notify = true; + bool app_disabled = false; bool ret = true; + int err; - err = noti_setting_service_get_setting_by_appid(appid, &setting, uid); + err = noti_setting_service_get_setting_by_appid(noti->caller_pkgname, &setting, noti->uid); if (err != NOTIFICATION_ERROR_NONE) { - NOTIFICATION_ERR("noti_setting_service_get_setting_by_appid failed [%d]", err); + err = __get_setting_from_app_control(noti, &setting); + if (err != NOTIFICATION_ERROR_NONE) + return ret; + } + + err = notification_setting_get_allow_to_notify(setting, &allow_to_notify); + if (err != NOTIFICATION_ERROR_NONE) { + NOTIFICATION_ERR("get_allow_to_notify failed [%x]", err); goto out; } - err = notification_setting_get_allow_to_notify(setting, &ret); + err = notification_setting_get_app_disabled(setting, &app_disabled); if (err != NOTIFICATION_ERROR_NONE) { - NOTIFICATION_ERR("notification_setting_get_allow_to_notify failed [%d]", err); + NOTIFICATION_ERR("get_app_disabled failed [%x]", err); goto out; } - if (ret != true) - NOTIFICATION_DBG("[%s] is not allowed to notify", appid); + if (!allow_to_notify || app_disabled) + ret = false; out: if (setting) @@ -862,7 +925,7 @@ EXPORT_API int notification_noti_insert(notification_h noti) return NOTIFICATION_ERROR_INVALID_PARAMETER; } - if (_is_allowed_to_notify((const char *)noti->caller_pkgname, noti->uid) == false) { + if (_is_allowed_to_notify(noti) == false) { NOTIFICATION_DBG("[%s] is not allowed to notify", noti->caller_pkgname); return NOTIFICATION_ERROR_PERMISSION_DENIED; } @@ -1144,11 +1207,16 @@ EXPORT_API int notification_noti_update(notification_h noti) sqlite3_stmt *stmt = NULL; char *query = NULL; + if (noti == NULL) { + NOTIFICATION_ERR("NOTIFICATION_ERROR_INVALID_PARAMETER"); + return NOTIFICATION_ERROR_INVALID_PARAMETER; + } + db = notification_db_open(DBPATH); if (!db) return get_last_result(); - if (_is_allowed_to_notify((const char *)noti->caller_pkgname, noti->uid) == false) { + if (_is_allowed_to_notify(noti) == false) { NOTIFICATION_DBG("[%s] is not allowed to notify", noti->caller_pkgname); return NOTIFICATION_ERROR_PERMISSION_DENIED; } diff --git a/src/notification_setting.c b/src/notification_setting.c index 488c649..aa2df98 100755 --- a/src/notification_setting.c +++ b/src/notification_setting.c @@ -236,6 +236,7 @@ EXPORT_API int notification_setting_get_lock_screen_content(notification_setting } *level = setting->lock_screen_content_level; + return NOTIFICATION_ERROR_NONE; } @@ -247,6 +248,19 @@ EXPORT_API int notification_setting_set_lock_screen_content(notification_setting } setting->lock_screen_content_level = level; + + return NOTIFICATION_ERROR_NONE; +} + +EXPORT_API int notification_setting_get_app_disabled(notification_setting_h setting, bool *value) +{ + if (setting == NULL || value == NULL) { + NOTIFICATION_ERR("Invalid parameter"); + return NOTIFICATION_ERROR_INVALID_PARAMETER; + } + + *value = setting->app_disabled; + return NOTIFICATION_ERROR_NONE; } diff --git a/src/notification_setting_service.c b/src/notification_setting_service.c index 9c596ee..4f41768 100644 --- a/src/notification_setting_service.c +++ b/src/notification_setting_service.c @@ -119,7 +119,7 @@ int noti_setting_service_get_setting_by_appid(const char *appid, notification_se } sql_query = sqlite3_mprintf("SELECT package_name, appid, allow_to_notify, do_not_disturb_except, visibility_class, " - "pop_up_notification, lock_screen_content_level FROM %s " + "pop_up_notification, lock_screen_content_level, app_disabled FROM %s " "WHERE appid = %Q AND uid = %d", NOTIFICATION_SETTING_DB_TABLE, appid, uid); if (!sql_query) { @@ -160,6 +160,7 @@ int noti_setting_service_get_setting_by_appid(const char *appid, notification_se _get_table_field_data_int(query_result, &(result_setting_array[i].visibility_class), col_index++); _get_table_field_data_int(query_result, (int *)&(result_setting_array[i].pop_up_notification), col_index++); _get_table_field_data_int(query_result, (int *)&(result_setting_array[i].lock_screen_content_level), col_index++); + _get_table_field_data_int(query_result, (int *)&(result_setting_array[i].app_disabled), col_index++); *setting = result_setting_array; @@ -208,8 +209,8 @@ int noti_setting_get_setting_array(notification_setting_h *setting_array, int *c } sql_query = sqlite3_mprintf("SELECT package_name, appid, allow_to_notify, do_not_disturb_except, visibility_class, " - "pop_up_notification, lock_screen_content_level FROM %s WHERE uid = %d " - "ORDER BY package_name, appid ", NOTIFICATION_SETTING_DB_TABLE, uid); + "pop_up_notification, lock_screen_content_level, app_disabled FROM %s WHERE uid = %d AND app_disabled = %d " + "ORDER BY package_name, appid ", NOTIFICATION_SETTING_DB_TABLE, uid, 0); if (!sql_query) { NOTIFICATION_ERR("fail to alloc query"); /* LCOV_EXCL_LINE */ @@ -248,6 +249,7 @@ int noti_setting_get_setting_array(notification_setting_h *setting_array, int *c _get_table_field_data_int(query_result, (int *)&(result_setting_array[i].visibility_class), col_index++); _get_table_field_data_int(query_result, (int *)&(result_setting_array[i].pop_up_notification), col_index++); _get_table_field_data_int(query_result, (int *)&(result_setting_array[i].lock_screen_content_level), col_index++); + _get_table_field_data_int(query_result, (int *)&(result_setting_array[i].app_disabled), col_index++); } *setting_array = result_setting_array; @@ -858,3 +860,40 @@ out: return ret; } +EXPORT_API int notification_setting_db_update_app_disabled(const char *appid, bool value, uid_t uid) +{ + int err = NOTIFICATION_ERROR_NONE; + int sqlret; + sqlite3 *db = NULL; + char *sqlbuf = NULL; + + if (appid == NULL) + return NOTIFICATION_ERROR_INVALID_PARAMETER; + + sqlret = db_util_open(DBPATH, &db, 0); + if (sqlret != SQLITE_OK || db == NULL) { + NOTIFICATION_ERR("db_util_open failed [%s][%d]", DBPATH, sqlret); + return NOTIFICATION_ERROR_FROM_DB; + } + + sqlbuf = sqlite3_mprintf("UPDATE notification_setting SET " \ + "app_disabled = %d WHERE appid = %Q AND uid = %d", + value, appid, uid); + if (!sqlbuf) { + NOTIFICATION_ERR("fail to alloc query"); + err = NOTIFICATION_ERROR_OUT_OF_MEMORY; + goto return_close_db; + } + + err = notification_db_exec(db, sqlbuf, NULL); + +return_close_db: + if (sqlbuf) + sqlite3_free(sqlbuf); + + sqlret = db_util_close(db); + if (sqlret != SQLITE_OK) + NOTIFICATION_WARN("fail to db_util_close - [%d]", sqlret); + + return err; +} diff --git a/test-app/main.c b/test-app/main.c index 4eb26ad..47b3505 100755 --- a/test-app/main.c +++ b/test-app/main.c @@ -709,7 +709,7 @@ static int testapp_test_update_setting() int err = NOTIFICATION_ERROR_NONE; notification_setting_h setting = NULL; - err = notification_setting_get_setting_by_package_name("org.tizen.internet", &setting); + err = notification_setting_get_setting_by_package_name("org.tizen.browser", &setting); if (err != NOTIFICATION_ERROR_NONE || setting == NULL) { testapp_print("notification_setting_get_setting_by_package_name failed [%d]", err); -- 2.7.4