Add exception handling for mothodcall of dbus listenser 38/230038/2
authormk5004.lee <mk5004.lee@samsung.com>
Tue, 7 Apr 2020 09:03:20 +0000 (18:03 +0900)
committermk5004.lee <mk5004.lee@samsung.com>
Wed, 8 Apr 2020 00:43:36 +0000 (09:43 +0900)
Change-Id: Id029e291add66af0809f4a596ce518e39a0731e6
Signed-off-by: mk5004.lee <mk5004.lee@samsung.com>
notification-ex/common.cc [new file with mode: 0644]
notification-ex/common.h
notification-ex/dbus_event_listener.cc
unittest/mock/gio_mock.h

diff --git a/notification-ex/common.cc b/notification-ex/common.cc
new file mode 100644 (file)
index 0000000..4d56ebb
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2020 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 "notification-ex/common.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "NOTIFICATION_EX"
+#define NOTIFICATION_EX_ERROR_QUARK "notification-ex-error-quark"
+
+namespace notification {
+
+static const GDBusErrorEntry dbus_error_entries[] = {
+  {ERROR_INVALID_PARAMETER, "org.freedesktop.Notification-ex.Error.INVALID_PARAMETER"},
+  {ERROR_OUT_OF_MEMORY,     "org.freedesktop.Notification-ex.Error.OUT_OF_MEMORY"},
+  {ERROR_IO_ERROR,          "org.freedesktop.Notification-ex.Error.IO_ERROR"},
+  {ERROR_PERMISSION_DENIED, "org.freedesktop.Notification-ex.Error.PERMISSION_DENIED"},
+  {ERROR_FROM_DB,           "org.freedesktop.Notification-ex.Error.FROM_DB"},
+  {ERROR_ALREADY_EXIST_ID,  "org.freedesktop.Notification-ex.Error.ALREADY_EXIST_ID"},
+  {ERROR_FROM_DBUS,         "org.freedesktop.Notification-ex.Error.FROM_DBUS"},
+  {ERROR_NOT_EXIST_ID,      "org.freedesktop.Notification-ex.Error.NOT_EXIST_ID"},
+  {ERROR_SERVICE_NOT_READY, "org.freedesktop.Notification-ex.Error.SERVICE_NOT_READY"},
+};
+
+GQuark noti_ex_error_quark(void) {
+  static volatile gsize quark_volatile = 0;
+  static const char *domain_name = NULL;
+
+  GQuark quark = g_quark_try_string(NOTIFICATION_EX_ERROR_QUARK);
+  if (quark == 0) {
+    if (domain_name == NULL)
+      domain_name = strdup(NOTIFICATION_EX_ERROR_QUARK);
+  } else {
+    domain_name = NOTIFICATION_EX_ERROR_QUARK;
+  }
+
+  g_dbus_error_register_error_domain(domain_name, &quark_volatile,
+        dbus_error_entries, G_N_ELEMENTS(dbus_error_entries));
+  return (GQuark)quark_volatile;
+}
+
+}  // namespace notification
index fd45e75..9c56d5c 100644 (file)
@@ -18,6 +18,7 @@
 #define NOTIFICATION_EX_COMMON_H_
 
 #include <tizen.h>
+#include <gio/gio.h>
 
 #define REGULAR_UID_MIN 5000
 
@@ -36,7 +37,8 @@ enum NotificationError {
   ERROR_SERVICE_NOT_READY = TIZEN_ERROR_NOTIFICATION | 0x05, /**< No response from notification service */
 };
 
+GQuark noti_ex_error_quark(void);
+
 }  // namespace notification
 
 #endif  // NOTIFICATION_EX_COMMON_H_
-
index fe83282..38a20e3 100644 (file)
@@ -162,29 +162,31 @@ void DBusEventListener::Impl::SignalCb(GDBusConnection* connection,
     || (cur_appid == sender_appid))
     return;
 
-  LOGE("%s : %s", cur_appid.c_str(), sender_appid.c_str());
-
-  char* raw = nullptr;
-  list<Bundle> ret_list;
-  while (g_variant_iter_loop(iter, "(s)", &raw) && raw != nullptr) {
-    Bundle ret(raw);
-    ret_list.emplace_back(ret);
-  }
-
-  Bundle b(event_info_raw);
-  EventInfo info(b);
+  LOGD("%s : %s", cur_appid.c_str(), sender_appid.c_str());
+
+  try {
+    char* raw = nullptr;
+    list<Bundle> ret_list;
+    while (g_variant_iter_loop(iter, "(s)", &raw) && raw != nullptr) {
+      Bundle ret(raw);
+      ret_list.emplace_back(ret);
+    }
 
-  if (info.GetEventType() == EventInfo::Post
+    Bundle b(event_info_raw);
+    EventInfo info(b);
+    if (info.GetEventType() == EventInfo::Post
            || info.GetEventType() == EventInfo::Update) {
-    uid_t uid = GetSenderUid(connection, sender_name);
-    if (uid >= NORMAL_UID_BASE) {
-      pid_t pid = GetSenderPid(connection, sender_name);
-      info.SetValidatedOwner(util::GetAppId(pid));
-      info.SetValidatedUid(uid);
+      uid_t uid = GetSenderUid(connection, sender_name);
+      if (uid >= NORMAL_UID_BASE) {
+        pid_t pid = GetSenderPid(connection, sender_name);
+        info.SetValidatedOwner(util::GetAppId(pid));
+        info.SetValidatedUid(uid);
+      }
     }
+    dl->parent_->NotifyObserver(info, ret_list);
+  } catch(Exception &ex) {
+    LOGE("%s %d", ex.what(), ex.GetErrorCode());
   }
-
-  dl->parent_->NotifyObserver(info, ret_list);
 }
 
 void DBusEventListener::Impl::OnMethodCall(
@@ -195,32 +197,36 @@ void DBusEventListener::Impl::OnMethodCall(
   LOGI("method_name[%s] sender[%s]", method_name, sender);
   DBusEventListener::Impl* dl = static_cast<DBusEventListener::Impl*>(user_data);
   GVariant *reply_body = NULL;
-  if (g_strcmp0(method_name, "Get") == 0) {
+  try {
     char* appid = NULL;
     char* serialized = NULL;
-    g_variant_get(parameters, "(&s&s)", &appid, &serialized);
-
-    Bundle b(serialized);
-    EventInfo info(b);
-    list<Bundle> result = dl->parent_->NotifyObserver(info);
-    GVariantBuilder* builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
-    for (auto& i : result) {
-      g_variant_builder_add(builder, "(s)",
+    if (g_strcmp0(method_name, "Get") == 0) {
+      g_variant_get(parameters, "(&s&s)", &appid, &serialized);
+
+      Bundle b(serialized);
+      EventInfo info(b);
+      list<Bundle> result = dl->parent_->NotifyObserver(info);
+      GVariantBuilder* builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
+      for (auto& i : result) {
+        g_variant_builder_add(builder, "(s)",
           reinterpret_cast<char*>(i.ToRaw().first.get()));
+      }
+      reply_body = g_variant_new("(a(s))", builder);
+      g_variant_builder_unref(builder);
+    } else if (g_strcmp0(method_name, "Count") == 0) {
+      g_variant_get(parameters, "(&s&s)", &appid, &serialized);
+
+      Bundle b(serialized);
+      EventInfo info(b);
+      int num = dl->parent_->NotifyNumberRequest(info);
+      reply_body = g_variant_new("(i)", num);
     }
-    reply_body = g_variant_new("(a(s))", builder);
-    g_variant_builder_unref(builder);
-  } else if (g_strcmp0(method_name, "Count") == 0) {
-    char* appid = NULL;
-    char* serialized = NULL;
-    g_variant_get(parameters, "(&s&s)", &appid, &serialized);
-
-    Bundle b(serialized);
-    EventInfo info(b);
-    int num = dl->parent_->NotifyNumberRequest(info);
-    reply_body = g_variant_new("(i)", num);
+    g_dbus_method_invocation_return_value(invocation, reply_body);
+  } catch (Exception &ex) {
+    LOGE("%s %d", ex.what(), ex.GetErrorCode());
+    g_dbus_method_invocation_return_error(invocation, noti_ex_error_quark(),
+            ERROR_IO_ERROR, "OnMethodCall fail");
   }
-  g_dbus_method_invocation_return_value(invocation, reply_body);
 }
 
 int DBusEventListener::Impl::RegisterGDBusInterface() {
index ea0a33d..16f787f 100644 (file)
 #define MOCK_GIO_H_
 
 #include "mock.h"
-#include <glib.h>
+#include <gio/gio.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-typedef struct _GFile GFile;
-typedef struct _GError GError;
-typedef void GDBusConnection;
-typedef void GCancellable;
-typedef void* gpointer;
-typedef int gboolean;
-
-typedef enum {
-  G_FILE_COPY_NONE                 = 0,
-  G_FILE_COPY_OVERWRITE            = (1 << 0),
-  G_FILE_COPY_BACKUP               = (1 << 1),
-  G_FILE_COPY_NOFOLLOW_SYMLINKS    = (1 << 2),
-  G_FILE_COPY_ALL_METADATA         = (1 << 3),
-  G_FILE_COPY_NO_FALLBACK_FOR_MOVE = (1 << 4),
-  G_FILE_COPY_TARGET_DEFAULT_PERMS = (1 << 5)
-} GFileCopyFlags;
-
-
-typedef void (*GFileProgressCallback) (goffset current_num_bytes,
-    goffset total_num_bytes, gpointer user_data);
-
 DECLARE_FAKE_VALUE_FUNC(GFile*, g_file_new_for_path, const char*);
 DECLARE_FAKE_VALUE_FUNC(gboolean, g_file_query_exists, GFile*, GCancellable*);
 DECLARE_FAKE_VALUE_FUNC(gboolean, g_file_make_directory, GFile*, GCancellable*,