Merge from tizen 2.4 latest. 56/51456/2 accepted/tizen/mobile/20151111.232111 accepted/tizen/tv/20151111.232118 accepted/tizen/wearable/20151111.232135 submit/tizen/20151111.080035
authorKyuho Jo <kyuho.jo@samsung.com>
Tue, 10 Nov 2015 01:59:35 +0000 (10:59 +0900)
committerKyuho Jo <kyuho.jo@samsung.com>
Tue, 10 Nov 2015 05:05:10 +0000 (14:05 +0900)
Change-Id: Ic260bc3ee54201b4572976dfec9c5f6cd808c4ff
Signed-off-by: Kyuho Jo <kyuho.jo@samsung.com>
12 files changed:
CMakeLists.txt
include/notification.h
include/notification_db.h
include/notification_setting_internal.h
include/notification_status.h
include/notification_type.h
packaging/notification.spec
src/notification.c
src/notification_ipc.c
src/notification_noti.c
src/notification_setting.c
test-app/main.c

index 8dad647..87da206 100644 (file)
@@ -5,11 +5,6 @@ SET(PREFIX ${CMAKE_INSTALL_PREFIX})
 SET(EXEC_PREFIX "\${prefix}")
 SET(LIBDIR ${LIB_INSTALL_DIR})
 SET(INCLUDEDIR "\${prefix}/include/${PROJECT_NAME}")
-SET(ICONDIR "${PREFIX}/share/${PROJECT_NAME}")
-SET(RESDIR "${PREFIX}/share/${PROJECT_NAME}")
-SET(DBDIR "/usr/dbspace")
-SET(IMGDIR "${RESDIR}/images")
-SET(DBFILE ".notification.db")
 SET(MAJOR_VER 0)
 SET(VERSION ${MAJOR_VER}.1.0)
 
@@ -68,6 +63,7 @@ pkg_check_modules(pkgs REQUIRED
        elementary
        ecore
        eina
+       libtzplatform-config
 )
 
 FOREACH(flag ${pkgs_CFLAGS})
@@ -79,12 +75,6 @@ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
 
 SET(CMAKE_SKIP_BUILD_RPATH TRUE)
 
-ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"")
-ADD_DEFINITIONS("-DICONDIR=\"${ICONDIR}\"")
-ADD_DEFINITIONS("-DDBDIR=\"${DBDIR}\"")
-ADD_DEFINITIONS("-DDBFILE=\"${DBFILE}\"")
-ADD_DEFINITIONS("-DIMGDIR=\"${IMGDIR}\"")
-
 IF (HAVE_X11)
 ADD_DEFINITIONS("-DHAVE_X11")
 ENDIF (HAVE_X11)
@@ -104,8 +94,6 @@ CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc @ONLY)
 INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
 INSTALL(FILES ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
 
-INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/images/ DESTINATION ${IMGDIR} FILES_MATCHING PATTERN "*.png")
-
 FOREACH(hfile ${HEADERS-DEVEL})
        INSTALL(FILES ${CMAKE_SOURCE_DIR}/${hfile} DESTINATION include/${PROJECT_NAME})
 ENDFOREACH(hfile)
index 35e9b23..b396b32 100644 (file)
@@ -120,13 +120,14 @@ int notification_get_image(notification_h noti,
  * @details If input_time is @c 0, time information is taken from the current time.
  * @since_tizen @if WEARABLE 2.3.1 @elseif MOBILE 2.3 @endif
  * @param[in] noti       The notification handle
- * @param[in] input_time The input time
+ * @param[in] input_time The input time. If you want the time stamp is not be shown, set this as NOTIFICATION_DO_NOT_SHOW_TIME_STAMP
  * @return #NOTIFICATION_ERROR_NONE on success,
  *         otherwise any other value on failure
  * @retval #NOTIFICATION_ERROR_NONE         Success
  * @retval #NOTIFICATION_ERROR_INVALID_PARAMETER Invalid parameter
  * @pre Notification handle should be created by notification_create().
  * @see notification_create()
+ * @see NOTIFICATION_DO_NOT_SHOW_TIME_STAMP
  * @par Sample code:
  * @code
 #include <notification.h>
@@ -1070,7 +1071,7 @@ int notification_delete(notification_h noti);
  * @brief Creates internal structure data and returns a notification handle.
  * @details Available type is #NOTIFICATION_TYPE_NOTI and #NOTIFICATION_TYPE_ONGOING.
  * #NOTIFICATION_TYPE_NOTI is remaining notification data even if device is restarted.
- * #NOTIFICATION_TYPE_ONGOING can display progressive feather, but notification data is removed after device is restarted.
+ * #NOTIFICATION_TYPE_ONGOING can display progress on a notification with #NOTIFICATION_LY_ONGOING_PROGRESS layout.
  * @since_tizen @if WEARABLE 2.3.1 @elseif MOBILE 2.3 @endif
  * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
  * @param[in] type The notification type
index 1e3482c..ac631c9 100644 (file)
 
 #include <bundle.h>
 #include <sqlite3.h>
+#include <tzplatform_config.h>
 
-#ifndef DBDIR
-#error "DBDIR not defined"
-#endif
-
-#ifndef DBFILE
-#error "DBFILE not defined"
-#endif
-
-#define DBPATH DBDIR"/"DBFILE
-
+#define DBPATH tzplatform_mkpath(TZ_SYS_DB, ".notification.db")
 #define NOTIFICATION_QUERY_MAX 4096
-
 #define NOTIFICATION_EMPTY_STR ""
 #define NOTIFICATION_CHECK_STR(p) ((p)?(p):NOTIFICATION_EMPTY_STR)
 
 sqlite3 *notification_db_open(const char *dbfile);
-
 int notification_db_close(sqlite3 ** db);
-
 int notification_db_exec(sqlite3 * db, const char *query, int *num_changes);
-
 char *notification_db_column_text(sqlite3_stmt * stmt, int col);
-
 bundle *notification_db_column_bundle(sqlite3_stmt * stmt, int col);
 
 #endif                         /* __NOTIFICATION_DB_H__ */
index 5a14225..83bcf75 100644 (file)
@@ -50,6 +50,9 @@ int notification_setting_set_allow_to_notify(notification_setting_h setting, boo
 int notification_setting_get_do_not_disturb_except(notification_setting_h setting, bool *value);
 int notification_setting_set_do_not_disturb_except(notification_setting_h setting, bool value);
 
+int notification_setting_insert_package(const char *package_id);
+int notification_setting_delete_package(const char *package_id);
+
 /* System setting */
 typedef struct notification_system_setting* notification_system_setting_h;
 
index 356577e..ccfd07c 100644 (file)
@@ -36,9 +36,8 @@ extern "C" {
  */
 
 /**
- * @brief Shows a toast popup window with given messaege
+ * @brief Shows a toast popup window with given message
  * @since_tizen @if WEARABLE 2.3.1 @elseif MOBILE 2.3 @endif
- * @privlevel public
  * @param[in] message The messages to be posted
  * @return  #NOTIFICATION_ERROR_NONE on success,
  *          otherwise any other value on failure
index cddd779..3b3d154 100644 (file)
@@ -44,6 +44,8 @@ extern "C" {
  * @{
  */
 
+#define NOTIFICATION_DO_NOT_SHOW_TIME_STAMP -1  /**< Do not show time stamp on the notificaion. Could be passed as a argument of notification_set_time() */
+
 /**
  * @brief Enumeration for notification layout type.
  * @since_tizen @if WEARABLE 2.3.1 @elseif MOBILE 2.3 @endif
@@ -58,7 +60,8 @@ typedef enum _notification_ly_type {
        NOTIFICATION_LY_NOTI_THUMBNAIL,
         /**< Layout for notification. Used to display images*/
        NOTIFICATION_LY_ONGOING_EVENT,
-        /**< Layout for ongoing notification. Used to display text message*/
+        /**< Layout for ongoing notification. Used to display text message.
+         * notifications with NOTIFICATION_LY_ONGOING_EVENT can not be protected from removing by user since tizen 2.4 */
        NOTIFICATION_LY_ONGOING_PROGRESS,
         /**< Layout for ongoing notification. Used to display progress*/
        NOTIFICATION_LY_MAX,
index 0863c1c..b1d9447 100644 (file)
@@ -1,7 +1,7 @@
 %bcond_with wayland
 Name:       notification
-Summary:    notification library
-Version:    0.2.34
+Summary:    Notification library
+Version:    0.2.41
 Release:    1
 Group:      TBD
 License:    Apache-2.0
@@ -26,11 +26,12 @@ BuildRequires: pkgconfig(edbus)
 BuildRequires: pkgconfig(elementary)
 BuildRequires: pkgconfig(ecore)
 BuildRequires: pkgconfig(eina)
+BuildRequires: pkgconfig(libtzplatform-config)
 
 BuildRequires: cmake
 Requires(post): /sbin/ldconfig
-Requires(post): /usr/bin/sqlite3
-requires(postun): /sbin/ldconfig
+Requires(post): %{TZ_SYS_BIN}/sqlite3
+Requires(postun): /sbin/ldconfig
 
 %description
 Client/Server library for sending notifications.
@@ -70,8 +71,8 @@ make %{?jobs:-j%jobs}
 rm -rf %{buildroot}
 %make_install
 
-mkdir -p %{buildroot}/usr/share/license
-cp -f LICENSE %{buildroot}/usr/share/license/%{name}
+mkdir -p %{buildroot}%{TZ_SYS_SHARE}/license
+cp -f LICENSE %{buildroot}%{TZ_SYS_SHARE}/license/%{name}
 
 %clean
 rm -rf %{buildroot}
@@ -79,14 +80,14 @@ rm -rf %{buildroot}
 %post
 /sbin/ldconfig
 
-if [ ! -d /usr/dbspace ]
+if [ ! -d %{TZ_SYS_DB} ]
 then
-       mkdir /usr/dbspace
+       mkdir %{TZ_SYS_DB}
 fi
 
-if [ ! -f /usr/dbspace/.notification.db ]
+if [ ! -f %{TZ_SYS_DB}/.notification.db ]
 then
-       sqlite3 /usr/dbspace/.notification.db 'PRAGMA journal_mode = PERSIST;
+       sqlite3 %{TZ_SYS_DB}/.notification.db 'PRAGMA journal_mode = PERSIST;
                create  table if not exists noti_list ( 
                        type INTEGER NOT NULL,
                        layout INTEGER NOT NULL default 0,
@@ -133,7 +134,9 @@ then
                        display_applist INTEGER,
                        progress_size DOUBLE default 0,
                        progress_percentage DOUBLE default 0,
-                       rowid INTEGER PRIMARY KEY AUTOINCREMENT,        
+                       rowid INTEGER PRIMARY KEY AUTOINCREMENT,
+                       ongoing_flag INTEGER default 0,
+                       auto_remove INTEGER default 1,
                        UNIQUE (caller_pkgname, priv_id)  
                ); 
                create table if not exists noti_group_data (
@@ -191,12 +194,14 @@ then
 
                CREATE UNIQUE INDEX package_name_idx1 ON notification_setting (package_name);
        '
+else
+       echo %{TZ_SYS_DB}/.notification.db ": DB file is already exists"
 fi
 
-chown :5000 /usr/dbspace/.notification.db
-chown :5000 /usr/dbspace/.notification.db-journal
-chmod 644 /usr/dbspace/.notification.db
-chmod 644 /usr/dbspace/.notification.db-journal
+chown :5000 %{TZ_SYS_DB}/.notification.db
+chown :5000 %{TZ_SYS_DB}/.notification.db-journal
+chmod 644 %{TZ_SYS_DB}/.notification.db
+chmod 644 %{TZ_SYS_DB}/.notification.db-journal
 
 %postun -p /sbin/ldconfig
 
@@ -204,7 +209,7 @@ chmod 644 /usr/dbspace/.notification.db-journal
 %manifest notification.manifest
 %defattr(-,root,root,-)
 %{_libdir}/libnotification.so*
-/usr/share/license/%{name}
+%{TZ_SYS_SHARE}/license/%{name}
 
 %files devel
 %defattr(-,root,root,-)
index 18b19f0..2d33a36 100644 (file)
@@ -1693,7 +1693,7 @@ static notification_h _notification_create(notification_type_e type)
        noti->vibration_type = NOTIFICATION_VIBRATION_TYPE_NONE;
        noti->led_operation = NOTIFICATION_LED_OP_OFF;
        noti->display_applist = NOTIFICATION_DISPLAY_APP_NOTIFICATION_TRAY | NOTIFICATION_DISPLAY_APP_TICKER | NOTIFICATION_DISPLAY_APP_INDICATOR;
-
+       noti->auto_remove = true;
 
        err_app_manager = app_manager_get_app_id(getpid(), &app_id);
        if (err_app_manager != APP_MANAGER_ERROR_NONE || app_id == NULL) {
@@ -1713,7 +1713,8 @@ static notification_h _notification_create(notification_type_e type)
        err_app_manager = package_info_create(noti->caller_pkgname, &package_info);
 
        if (err_app_manager != PACKAGE_MANAGER_ERROR_NONE || package_info == NULL) {
-               NOTIFICATION_WARN("package_info_create failed err[%d] package_info[%p]", err_app_manager, package_info);
+               NOTIFICATION_WARN("package_info_create failed err[%d] package_info[%p] caller_pkgname[%s]",
+                               err_app_manager, package_info, noti->caller_pkgname);
                goto out;
        }
 
@@ -1935,6 +1936,9 @@ EXPORT_API int notification_clone(notification_h noti, notification_h *clone)
        new_noti->progress_size = noti->progress_size;
        new_noti->progress_percentage = noti->progress_percentage;
 
+       new_noti->ongoing_flag = noti->ongoing_flag;
+       new_noti->auto_remove = noti->auto_remove;
+
        new_noti->app_icon_path = NULL;
        new_noti->app_name = NULL;
        new_noti->temp_title = NULL;
index 96149e3..bb6c891 100644 (file)
@@ -410,6 +410,8 @@ EXPORT_API int notification_ipc_make_noti_from_packet(notification_h noti, const
        char *temp_title = NULL;
        char *temp_content = NULL;
        char *tag = NULL;
+       bool *ongoing_flag;
+       bool *auto_remove;
 
        if (noti == NULL) {
                NOTIFICATION_ERR("invalid data");
@@ -417,7 +419,7 @@ EXPORT_API int notification_ipc_make_noti_from_packet(notification_h noti, const
        }
 
        ret = packet_get(packet,
-                       "iiiiisssssssssssssssssssssisisisiiiiiiiiddsssss",
+                       "iiiiisssssssssssssssssssssisisisiiiiiiiiddsssssii",
                        &type,
                        &layout,
                        &group_id,
@@ -464,9 +466,11 @@ EXPORT_API int notification_ipc_make_noti_from_packet(notification_h noti, const
                        &app_name,
                        &temp_title,
                        &temp_content,
-                       &tag);
+                       &tag,
+                       &ongoing_flag,
+                       &auto_remove);
 
-       if (ret != 47) {
+       if (ret != 49) {
                NOTIFICATION_ERR("failed to create a noti from packet");
                return NOTIFICATION_ERROR_INVALID_PARAMETER;
        }
@@ -520,6 +524,8 @@ EXPORT_API int notification_ipc_make_noti_from_packet(notification_h noti, const
        noti->progress_size = progress_size;
        noti->progress_percentage = progress_percentage;
        noti->tag = _dup_string(tag);
+       noti->ongoing_flag = ongoing_flag;
+       noti->auto_remove = auto_remove;
 
        return NOTIFICATION_ERROR_NONE;
 }
@@ -620,7 +626,7 @@ EXPORT_API struct packet *notification_ipc_make_packet_from_noti(notification_h
        }
 
        result = func_to_create_packet(command,
-                       "iiiiisssssssssssssssssssssisisisiiiiiiiiddsssss",
+                       "iiiiisssssssssssssssssssssisisisiiiiiiiiddsssssii",
                        noti->type,
                        noti->layout,
                        noti->group_id,
@@ -667,7 +673,9 @@ EXPORT_API struct packet *notification_ipc_make_packet_from_noti(notification_h
                        NOTIFICATION_CHECK_STR(noti->app_name),
                        NOTIFICATION_CHECK_STR(noti->temp_title),
                        NOTIFICATION_CHECK_STR(noti->temp_content),
-                       NOTIFICATION_CHECK_STR(noti->tag));
+                       NOTIFICATION_CHECK_STR(noti->tag),
+                       noti->ongoing_flag,
+                       noti->auto_remove);
 
 out:
        /* Free decoded data */
@@ -801,7 +809,7 @@ EXPORT_API struct packet *notification_ipc_make_reply_packet_from_noti(notificat
        }
 
        result = packet_create_reply(packet,
-                       "iiiiisssssssssssssssssssssisisisiiiiiiiiddsssss",
+                       "iiiiisssssssssssssssssssssisisisiiiiiiiiddsssssii",
                        noti->type,
                        noti->layout,
                        noti->group_id,
@@ -848,7 +856,9 @@ EXPORT_API struct packet *notification_ipc_make_reply_packet_from_noti(notificat
                        NOTIFICATION_CHECK_STR(noti->app_name),
                        NOTIFICATION_CHECK_STR(noti->temp_title),
                        NOTIFICATION_CHECK_STR(noti->temp_content),
-                       NOTIFICATION_CHECK_STR(noti->tag));
+                       NOTIFICATION_CHECK_STR(noti->tag),
+                       noti->ongoing_flag,
+                       noti->auto_remove);
 
        /* Free decoded data */
        if (args) {
index 90191f4..6c3e7c6 100644 (file)
@@ -27,6 +27,7 @@
 #include <Ecore.h>
 #include <Elementary.h>
 #include <Eina.h>
+#include <pkgmgr-info.h>
 #include <package_manager.h>
 
 #include <notification.h>
@@ -279,7 +280,7 @@ static int _insertion_query_create(notification_h noti, char **query)
                 "b_event_handler_click_on_icon, b_event_handler_click_on_thumbnail, "
                 "sound_type, sound_path, vibration_type, vibration_path, led_operation, led_argb, led_on_ms, led_off_ms, "
                 "flags_for_property, flag_simmode, display_applist, "
-                "progress_size, progress_percentage) values ("
+                "progress_size, progress_percentage, ongoing_flag, auto_remove) values ("
                 "%d, "
                 "%d, "
                 "'%s', '%s', "
@@ -297,7 +298,7 @@ static int _insertion_query_create(notification_h noti, char **query)
                 "'%s', '%s', "
                 "%d, '%s', %d, '%s', %d, %d, %d, %d,"
                 "%d, %d, %d, "
-                "$progress_size, $progress_percentage)",
+                "$progress_size, $progress_percentage, %d, %d)",
                 noti->type,
                 noti->layout,
                 NOTIFICATION_CHECK_STR(noti->caller_pkgname),
@@ -329,7 +330,9 @@ static int _insertion_query_create(notification_h noti, char **query)
                 noti->led_argb,
                 noti->led_on_ms,
                 noti->led_off_ms,
-                noti->flags_for_property, flag_simmode, noti->display_applist);
+                noti->flags_for_property, flag_simmode, noti->display_applist,
+                noti->ongoing_flag,
+                noti->auto_remove);
 
        /* Free decoded data */
        if (args) {
@@ -478,7 +481,8 @@ static int _update_query_create(notification_h noti, char **query)
                 "led_on_ms = %d, led_off_ms = %d, "
                 "flags_for_property = %d, flag_simmode = %d, "
                 "display_applist = %d, "
-                "progress_size = $progress_size, progress_percentage = $progress_percentage "
+                "progress_size = $progress_size, progress_percentage = $progress_percentage, "
+                "ongoing_flag = %d, auto_remove = %d "
                 "where priv_id = %d ",
                 noti->type,
                 noti->layout,
@@ -510,6 +514,7 @@ static int _update_query_create(notification_h noti, char **query)
                 noti->led_on_ms,
                 noti->led_off_ms,
                 noti->flags_for_property, flag_simmode, noti->display_applist,
+                noti->ongoing_flag, noti->auto_remove,
                 noti->priv_id);
 
        /* Free decoded data */
@@ -609,6 +614,9 @@ static void _notification_noti_populate_from_stmt(sqlite3_stmt * stmt, notificat
        noti->progress_size = sqlite3_column_double(stmt, col++);
        noti->progress_percentage = sqlite3_column_double(stmt, col++);
 
+       noti->ongoing_flag = sqlite3_column_int(stmt, col++);
+       noti->auto_remove = sqlite3_column_int(stmt, col++);
+
        noti->app_icon_path = NULL;
        noti->app_name = NULL;
        noti->temp_title = NULL;
@@ -714,6 +722,50 @@ err:
        return ret;
 }
 
+
+static int _get_package_id_by_app_id(const char *app_id, char **package_id)
+{
+       int err = NOTIFICATION_ERROR_NONE;
+       int retval;
+       char *pkg_id = NULL;
+       char *pkg_id_dup = NULL;
+       pkgmgrinfo_appinfo_h pkgmgrinfo_appinfo = NULL;
+
+       if (app_id == NULL || package_id == NULL) {
+               NOTIFICATION_ERR("NOTIFICATION_ERROR_INVALID_PARAMETER");
+               err = NOTIFICATION_ERROR_INVALID_PARAMETER;
+               goto out;
+       }
+
+       if ((retval = pkgmgrinfo_appinfo_get_appinfo(app_id, &pkgmgrinfo_appinfo)) != PMINFO_R_OK) {
+               NOTIFICATION_ERR("pkgmgrinfo_appinfo_get_appinfo failed [%d]", retval);
+               err = NOTIFICATION_ERROR_INVALID_OPERATION;
+               goto out;
+       }
+
+       if ((retval = pkgmgrinfo_appinfo_get_pkgname(pkgmgrinfo_appinfo, &pkg_id)) != PMINFO_R_OK || pkg_id == NULL) {
+               NOTIFICATION_ERR("pkgmgrinfo_appinfo_get_pkgname failed [%d]", retval);
+               err = NOTIFICATION_ERROR_INVALID_OPERATION;
+               goto out;
+       }
+
+       pkg_id_dup = strdup(pkg_id);
+
+       if (pkg_id_dup == NULL) {
+               NOTIFICATION_ERR("strdup failed");
+               err = NOTIFICATION_ERROR_OUT_OF_MEMORY;
+               goto out;
+       }
+
+       *package_id = pkg_id_dup;
+
+out:
+       if (pkgmgrinfo_appinfo)
+               pkgmgrinfo_appinfo_destroy_appinfo(pkgmgrinfo_appinfo);
+
+       return err;
+}
+
 static bool _is_allowed_to_notify(const char *caller_package_name)
 {
        notification_setting_h setting = NULL;
@@ -724,10 +776,10 @@ static bool _is_allowed_to_notify(const char *caller_package_name)
        err = notification_setting_get_setting_by_package_name(caller_package_name, &setting);
        if (err != NOTIFICATION_ERROR_NONE) {
                /* Retry with package id */
-               err = package_manager_get_package_id_by_app_id (caller_package_name, &package_id);
+               err = _get_package_id_by_app_id (caller_package_name, &package_id);
 
-               if (err != PACKAGE_MANAGER_ERROR_NONE || package_id == NULL) {
-                       NOTIFICATION_ERR("package_manager_get_package_id_by_app_id failed [%d]", err);
+               if (err != NOTIFICATION_ERROR_NONE || package_id == NULL) {
+                       NOTIFICATION_ERR("_get_package_id_by_app_id failed [%d]", err);
                        goto out;
                }
                else {
@@ -761,6 +813,92 @@ out:
        return ret;
 }
 
+static int _handle_do_not_disturb_option(notification_h noti)
+{
+       int err = NOTIFICATION_ERROR_NONE;
+       bool do_not_disturb = false;
+       bool do_not_disturb_exception = false;
+       char *package_id = NULL;
+       notification_system_setting_h system_setting = NULL;
+       notification_setting_h setting = NULL;
+
+       if (noti == NULL) {
+               NOTIFICATION_ERR("NOTIFICATION_ERROR_INVALID_PARAMETER");
+               err = NOTIFICATION_ERROR_INVALID_PARAMETER;
+               goto out;
+       }
+
+       /* Get system setting */
+       if ((err = notification_system_setting_load_system_setting(&system_setting)) != NOTIFICATION_ERROR_NONE) {
+               NOTIFICATION_ERR("notification_system_setting_load_system_setting failed [%d]", err);
+               goto out;
+       }
+
+       if ((err = notification_system_setting_get_do_not_disturb(system_setting, &do_not_disturb)) != NOTIFICATION_ERROR_NONE) {
+               NOTIFICATION_ERR("notification_system_setting_get_do_not_disturb failed [%d]", err);
+               goto out;
+       }
+
+       NOTIFICATION_DBG("do_not_disturb [%d]", do_not_disturb);
+
+       if (do_not_disturb) {
+               /* Check exception option of the caller package */
+               err = notification_setting_get_setting_by_package_name(noti->caller_pkgname, &setting);
+
+               if (err != NOTIFICATION_ERROR_NONE) {
+                       /* Retry with package id */
+                       err = _get_package_id_by_app_id (noti->caller_pkgname, &package_id);
+
+                       if (err != NOTIFICATION_ERROR_NONE || package_id == NULL) {
+                               NOTIFICATION_ERR("_get_package_id_by_app_id failed [%d]", err);
+                               goto out;
+                       }
+                       else {
+                               err = notification_setting_get_setting_by_package_name(package_id, &setting);
+                               if (err != NOTIFICATION_ERROR_NONE) {
+                                       NOTIFICATION_ERR("notification_setting_get_setting_by_package_name failed [%d]", err);
+                                       goto out;
+                               }
+                       }
+               }
+
+               err = notification_setting_get_do_not_disturb_except(setting, &do_not_disturb_exception);
+               if (err != NOTIFICATION_ERROR_NONE) {
+                       NOTIFICATION_ERR("notification_setting_get_allow_to_notify failed [%d]", err);
+                       goto out;
+               }
+
+               if (do_not_disturb_exception == false) {
+                       /* do_not_disturb is ON and do_not_disturb_exception is OFF */
+                       /* Then add this notification only on quick panel and indicator*/
+                       noti->display_applist = noti->display_applist & (NOTIFICATION_DISPLAY_APP_NOTIFICATION_TRAY | NOTIFICATION_DISPLAY_APP_INDICATOR);
+                       /* and reset all sound and vibration and led options*/
+                       noti->sound_type = NOTIFICATION_SOUND_TYPE_NONE;
+                       SAFE_FREE(noti->sound_path);
+                       noti->vibration_type = NOTIFICATION_VIBRATION_TYPE_NONE;
+                       SAFE_FREE(noti->vibration_path);
+                       noti->led_operation = NOTIFICATION_LED_OP_OFF;
+                       noti->led_argb = 0;
+                       noti->led_on_ms = 0;
+                       noti->led_off_ms = 0;
+               }
+
+       }
+
+out:
+       SAFE_FREE(package_id);
+
+       if (system_setting) {
+               notification_system_setting_free_system_setting(system_setting);
+       }
+
+       if (setting) {
+               notification_setting_free_notification(setting);
+       }
+
+       return err;
+}
+
 EXPORT_API int notification_noti_insert(notification_h noti)
 {
        int ret = 0;
@@ -776,10 +914,14 @@ EXPORT_API int notification_noti_insert(notification_h noti)
        }
 
        if (_is_allowed_to_notify((const char*)noti->caller_pkgname) == false) {
-               NOTIFICATION_DBG("Not allowed to notify");
+               NOTIFICATION_DBG("[%s] is not allowed to notify", noti->caller_pkgname);
                return NOTIFICATION_ERROR_PERMISSION_DENIED;
        }
 
+       if (_handle_do_not_disturb_option(noti) != NOTIFICATION_ERROR_NONE) {
+               NOTIFICATION_WARN("_handle_do_not_disturb_option failed");
+       }
+
        /* Open DB */
        db = notification_db_open(DBPATH);
        if (!db) {
@@ -908,7 +1050,7 @@ int notification_noti_get_by_priv_id(notification_h noti, char *pkgname, int pri
                         "b_event_handler_click_on_button_4, b_event_handler_click_on_button_5, b_event_handler_click_on_button_6, "
                         "b_event_handler_click_on_icon, b_event_handler_click_on_thumbnail, "
                         "sound_type, sound_path, vibration_type, vibration_path, led_operation, led_argb, led_on_ms, led_off_ms, "
-                        "flags_for_property, display_applist, progress_size, progress_percentage "
+                        "flags_for_property, display_applist, progress_size, progress_percentage, ongoing_flag, auto_remove "
                         "from noti_list ";
 
        if (pkgname != NULL) {
@@ -982,7 +1124,7 @@ EXPORT_API int notification_noti_get_by_tag(notification_h noti, char *pkgname,
                         "b_event_handler_click_on_button_4, b_event_handler_click_on_button_5, b_event_handler_click_on_button_6, "
                         "b_event_handler_click_on_icon, b_event_handler_click_on_thumbnail, "
                         "sound_type, sound_path, vibration_type, vibration_path, led_operation, led_argb, led_on_ms, led_off_ms, "
-                        "flags_for_property, display_applist, progress_size, progress_percentage "
+                        "flags_for_property, display_applist, progress_size, progress_percentage, ongoing_flag, auto_remove "
                         "from noti_list where caller_pkgname = ? and tag = ?", -1, &stmt, NULL);
                if (ret != SQLITE_OK) {
                        NOTIFICATION_ERR("Error: %s\n", sqlite3_errmsg(db));
@@ -1010,7 +1152,7 @@ EXPORT_API int notification_noti_get_by_tag(notification_h noti, char *pkgname,
                         "b_event_handler_click_on_button_4, b_event_handler_click_on_button_5, b_event_handler_click_on_button_6, "
                         "b_event_handler_click_on_icon, b_event_handler_click_on_thumbnail, "
                         "sound_type, sound_path, vibration_type, vibration_path, led_operation, led_argb, led_on_ms, led_off_ms, "
-                        "flags_for_property, display_applist, progress_size, progress_percentage "
+                        "flags_for_property, display_applist, progress_size, progress_percentage, ongoing_flag, auto_remove "
                         "from noti_list where  tag = ?", -1, &stmt, NULL);
                if (ret != SQLITE_OK) {
                        NOTIFICATION_ERR("Error: %s\n", sqlite3_errmsg(db));
@@ -1059,6 +1201,15 @@ EXPORT_API int notification_noti_update(notification_h noti)
                return get_last_result();
        }
 
+       if (_is_allowed_to_notify((const char*)noti->caller_pkgname) == false) {
+               NOTIFICATION_DBG("[%s] is not allowed to notify", noti->caller_pkgname);
+               return NOTIFICATION_ERROR_PERMISSION_DENIED;
+       }
+
+       if (_handle_do_not_disturb_option(noti) != NOTIFICATION_ERROR_NONE) {
+               NOTIFICATION_WARN("_handle_do_not_disturb_option failed");
+       }
+
        /* Check private ID is exist */
        ret = _notification_noti_check_priv_id(noti, db);
        if (ret != NOTIFICATION_ERROR_ALREADY_EXIST_ID) {
@@ -1648,7 +1799,7 @@ int notification_noti_get_grouping_list(notification_type_e type,
                 "b_event_handler_click_on_button_4, b_event_handler_click_on_button_5, b_event_handler_click_on_button_6, "
                 "b_event_handler_click_on_icon, b_event_handler_click_on_thumbnail, "
                 "sound_type, sound_path, vibration_type, vibration_path, led_operation, led_argb, led_on_ms, led_off_ms, "
-                "flags_for_property, display_applist, progress_size, progress_percentage "
+                "flags_for_property, display_applist, progress_size, progress_percentage, ongoing_flag, auto_remove "
                 "from noti_list ");
 
        if (status == VCONFKEY_TELEPHONY_SIM_INSERTED) {
@@ -1754,7 +1905,7 @@ int notification_noti_get_detail_list(const char *pkgname,
                 "b_event_handler_click_on_button_4, b_event_handler_click_on_button_5, b_event_handler_click_on_button_6, "
                 "b_event_handler_click_on_icon, b_event_handler_click_on_thumbnail, "
                 "sound_type, sound_path, vibration_type, vibration_path, led_operation, led_argb, led_on_ms, led_off_ms, "
-                "flags_for_property, display_applist, progress_size, progress_percentage "
+                "flags_for_property, display_applist, progress_size, progress_percentage, ongoing_flag, auto_remove "
                 "from noti_list ");
 
        if (priv_id == NOTIFICATION_PRIV_ID_NONE && group_id == NOTIFICATION_GROUP_ID_NONE) {
index f8c8a05..2ba4a9b 100644 (file)
@@ -533,7 +533,7 @@ static bool _is_package_in_setting_table(sqlite3 *db, const char *package_name)
                goto out;
        }
 
-       if (sqlite3_ret != SQLITE_OK) {
+       if (sqlite3_ret != SQLITE_OK && sqlite3_ret != SQLITE_ROW) {
                NOTIFICATION_ERR("sqlite3_step failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
                err = false;
                goto out;
@@ -662,6 +662,147 @@ out:
        return err;
 }
 
+typedef enum {
+       OPERATION_TYPE_INSERT_RECORD = 0,
+       OPERATION_TYPE_DELETE_RECORD = 1,
+} notification_setting_operation_type;
+
+static int _notification_setting_alter_package_list(notification_setting_operation_type operation_type, const char *package_name)
+{
+       sqlite3 *db = NULL;
+       sqlite3_stmt *db_statement = NULL;
+       int sqlite3_ret = SQLITE_OK;
+       int field_index = 1;
+       bool is_package_in_setting_table = false;
+       int err = NOTIFICATION_ERROR_NONE;
+
+       sqlite3_ret = db_util_open(DBPATH, &db, 0);
+
+       if (sqlite3_ret != SQLITE_OK || db == NULL) {
+               NOTIFICATION_ERR("db_util_open failed [%s][%d]", DBPATH, sqlite3_ret);
+               err = NOTIFICATION_ERROR_FROM_DB;
+               goto out;
+       }
+
+       sqlite3_exec(db, "BEGIN immediate;", NULL, NULL, NULL);
+
+       is_package_in_setting_table = _is_package_in_setting_table(db, package_name);
+
+       switch (operation_type) {
+       case OPERATION_TYPE_INSERT_RECORD :
+               if (is_package_in_setting_table == true) {
+                       NOTIFICATION_INFO("[%s] is already exist", package_name);
+                       goto out;
+               }
+               NOTIFICATION_INFO("[%s] will be inserted", package_name);
+               sqlite3_ret = sqlite3_prepare_v2(db, "INSERT INTO notification_setting (package_name) VALUES (?) ", -1, &db_statement, NULL);
+               break;
+
+       case OPERATION_TYPE_DELETE_RECORD :
+               if (is_package_in_setting_table == false) {
+                       NOTIFICATION_INFO("[%s] is not exist", package_name);
+                       goto out;
+               }
+               NOTIFICATION_INFO("[%s] will be removed", package_name);
+               sqlite3_ret = sqlite3_prepare_v2(db, "DELETE FROM notification_setting WHERE package_name = ? ", -1, &db_statement, NULL);
+               break;
+       default :
+               break;
+       }
+
+       if (sqlite3_ret != SQLITE_OK) {
+               NOTIFICATION_ERR("sqlite3_prepare_v2 failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
+               err = NOTIFICATION_ERROR_FROM_DB;
+               goto out;
+       }
+
+       sqlite3_bind_text(db_statement, field_index++, package_name, -1, SQLITE_TRANSIENT);
+
+       sqlite3_ret = sqlite3_step(db_statement);
+
+       if (sqlite3_ret != SQLITE_OK && sqlite3_ret != SQLITE_DONE) {
+               NOTIFICATION_ERR("sqlite3_step failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
+               err = NOTIFICATION_ERROR_FROM_DB;
+       }
+
+out:
+       if (db_statement) {
+               sqlite3_finalize(db_statement);
+       }
+
+       if (db) {
+               NOTIFICATION_INFO("err [%d]", err);
+               if (err == NOTIFICATION_ERROR_NONE) {
+                       sqlite3_exec(db, "END;", NULL, NULL, NULL);
+               }
+               else {
+                       sqlite3_exec(db, "ROLLBACK;", NULL, NULL, NULL);
+               }
+
+               if ((sqlite3_ret = db_util_close(db)) != SQLITE_OK) {
+                       NOTIFICATION_WARN("fail to db_util_close - [%d]", sqlite3_ret);
+               }
+       }
+
+       return err;
+}
+
+bool privilege_info_cb(const char *privilege_name, void *user_data)
+{
+       bool *found = user_data;
+
+       if (privilege_name && strcmp(NOTIFICATION_PRIVILEGE, privilege_name) == 0) {
+               *found = true;
+               return false;
+       }
+
+       return true;
+}
+
+static bool _has_privilege(const char *package_id)
+{
+       bool found = false;
+       int error_from_package_info = PACKAGE_MANAGER_ERROR_NONE;
+       package_info_h package_info = NULL;
+
+       error_from_package_info = package_info_create(package_id, &package_info);
+       if (error_from_package_info != PACKAGE_MANAGER_ERROR_NONE) {
+               NOTIFICATION_ERR("package_info_create failed [%d]", error_from_package_info);
+               goto out;
+       }
+
+       error_from_package_info = package_info_foreach_privilege_info(package_info, privilege_info_cb, &found);
+
+       if (error_from_package_info != PACKAGE_MANAGER_ERROR_NONE) {
+               NOTIFICATION_ERR("package_info_foreach_privilege_info failed [%d]", error_from_package_info);
+               goto out;
+       }
+
+out:
+
+       if (package_info) {
+               package_info_destroy(package_info);
+       }
+
+       return found;
+}
+
+EXPORT_API int notification_setting_insert_package(const char *package_id)
+{
+       int err = NOTIFICATION_ERROR_NONE;
+
+       if (_has_privilege(package_id) == true) {
+               err = _notification_setting_alter_package_list(OPERATION_TYPE_INSERT_RECORD, package_id);
+       }
+
+       return err;
+}
+
+EXPORT_API int notification_setting_delete_package(const char *package_id)
+{
+       return _notification_setting_alter_package_list(OPERATION_TYPE_DELETE_RECORD, package_id);
+}
+
 /* system setting --------------------------------*/
 
 EXPORT_API int notification_system_setting_load_system_setting(notification_system_setting_h *system_setting)
index bfdb4c0..82b1668 100644 (file)
 /* notification header */
 #include <notification.h>
 #include <notification_internal.h>
+#include <notification_ongoing_flag.h>
 #include <notification_status.h>
 #include <notification_setting.h>
 #include <notification_setting_internal.h>
+#include <notification_list.h>
 #include <notification_text_domain.h>
 
 /*-----------------------------------------------------------------------------------------*/
@@ -154,6 +156,7 @@ void testapp_show_menu (testapp_menu_type_e menu)
                testapp_print (" 6.  Post a heads notification with a button\n");
                testapp_print (" 7.  Post a notification with domain text\n");
                testapp_print (" 8.  Load by tag\n");
+               testapp_print (" 9.  Get list\n");
                testapp_print ("------------------------------------------\n");
                break;
        case TESTAPP_MENU_TYPE_SETTING_TEST_MENU:
@@ -194,6 +197,9 @@ static int testapp_add_a_notification()
        noti_err  = notification_set_text(noti_handle, NOTIFICATION_TEXT_TYPE_INFO_3, "I'm Info 3", "INFO_3", NOTIFICATION_VARIABLE_TYPE_NONE);
        noti_err  = notification_set_text(noti_handle, NOTIFICATION_TEXT_TYPE_INFO_SUB_3, "I'm Info Sub 3", "INFO_SUB_3", NOTIFICATION_VARIABLE_TYPE_NONE);
 
+       noti_err  = notification_set_ongoing_flag(noti_handle, true);
+       noti_err  = notification_set_auto_remove(noti_handle, false);
+
        noti_err = notification_set_display_applist(noti_handle, NOTIFICATION_DISPLAY_APP_INDICATOR | NOTIFICATION_DISPLAY_APP_NOTIFICATION_TRAY | NOTIFICATION_DISPLAY_APP_TICKER);
 
        noti_err  = notification_post(noti_handle);
@@ -262,15 +268,16 @@ static int testapp_test_post_notification_on_indicator()
        notification_h noti_handle = NULL;
        int noti_err = NOTIFICATION_ERROR_NONE;
 
-       noti_handle = notification_create(NOTIFICATION_TYPE_NOTI);
+       noti_handle = notification_create(NOTIFICATION_TYPE_ONGOING);
 
        if (noti_handle == NULL) {
                testapp_print("notification_create failed");
                goto FINISH_OFF;
        }
 
-       noti_err  = notification_set_text(noti_handle, NOTIFICATION_TEXT_TYPE_TITLE, "I'm Title", "TITLE", NOTIFICATION_VARIABLE_TYPE_NONE);
-       noti_err  = notification_set_text(noti_handle, NOTIFICATION_TEXT_TYPE_CONTENT, "I'm Content", "This is very loooooooooooooooooooooooooooooooooooooooooong message", NOTIFICATION_VARIABLE_TYPE_NONE);
+       noti_err  = notification_set_image(noti_handle, NOTIFICATION_IMAGE_TYPE_ICON_FOR_INDICATOR, "/usr/apps/org.tizen.indicator/res/icons/Shealth/B03_shealth.png");
+       // noti_err  = notification_set_text(noti_handle, NOTIFICATION_TEXT_TYPE_TITLE, "I'm Title", "TITLE", NOTIFICATION_VARIABLE_TYPE_NONE);
+       // noti_err  = notification_set_text(noti_handle, NOTIFICATION_TEXT_TYPE_CONTENT, "I'm Content", "This is very loooooooooooooooooooooooooooooooooooooooooong message", NOTIFICATION_VARIABLE_TYPE_NONE);
 
        noti_err  = notification_set_display_applist(noti_handle, NOTIFICATION_DISPLAY_APP_TICKER | NOTIFICATION_DISPLAY_APP_INDICATOR);
 
@@ -501,6 +508,46 @@ FINISH_OFF:
        return noti_err;
 }
 
+static int testapp_test_get_list()
+{
+       notification_h noti_handle = NULL;
+       notification_list_h noti_list_handle = NULL;
+       notification_list_h noti_list_cursor_handle = NULL;
+       int noti_err = NOTIFICATION_ERROR_NONE;
+       int priv_id;
+       int group_id;
+       int type;
+       bool ongoing_flag;
+       bool auto_remove;
+
+       noti_err = notification_get_detail_list("./notification-test-app", NOTIFICATION_PRIV_ID_NONE, NOTIFICATION_GROUP_ID_NONE, 10, &noti_list_handle);
+
+       if (noti_err != NOTIFICATION_ERROR_NONE) {
+               testapp_print("notification_get_detail_list failed[%d]\n", noti_err);
+               goto FINISH_OFF;
+       }
+
+       noti_list_cursor_handle = notification_list_get_head(noti_list_handle);
+
+       while (noti_list_cursor_handle) {
+               noti_handle = notification_list_get_data(noti_list_cursor_handle);
+               notification_get_id(noti_handle, &group_id, &priv_id);
+               notification_get_type(noti_handle, &type);
+               notification_get_ongoing_flag(noti_handle, &ongoing_flag);
+               notification_get_auto_remove(noti_handle, &auto_remove);
+
+               testapp_print("priv_id[%d] type[%d] ongoing_flag[%d] auto_remove[%d]\n", priv_id, type, ongoing_flag, auto_remove);
+               noti_list_cursor_handle = notification_list_get_next(noti_list_cursor_handle);
+       }
+
+
+FINISH_OFF:
+       if (noti_list_handle)
+               notification_free_list(noti_list_handle);
+
+       return noti_err;
+}
+
 static gboolean testapp_interpret_command_basic_test (int selected_number)
 {
        gboolean go_to_loop = TRUE;
@@ -538,6 +585,10 @@ static gboolean testapp_interpret_command_basic_test (int selected_number)
                testapp_test_load_by_tag();
                break;
 
+       case 9:
+               testapp_test_get_list();
+               break;
+
        case 0:
                go_to_loop = FALSE;
                break;
@@ -615,6 +666,10 @@ static int testapp_test_update_setting()
                notification_setting_update_setting(setting);
        }
 
+       if (setting) {
+               notification_setting_free_notification(setting);
+       }
+
        return err;
 }