Add exception handling based on try-catch 24/184924/3
authorjusung son <jusung07.son@samsung.com>
Tue, 24 Jul 2018 09:08:00 +0000 (18:08 +0900)
committerHyunho Kang <hhstark.kang@samsung.com>
Wed, 25 Jul 2018 01:34:01 +0000 (01:34 +0000)
Change-Id: Ib5d755b453d5b4211e8e149a826a298affa1664f
Signed-off-by: jusung son <jusung07.son@samsung.com>
16 files changed:
watchface-common/watchface_exception.h [new file with mode: 0644]
watchface-complication-provider/complication-provider.cc
watchface-complication-provider/watchface-complication-provider.cc
watchface-complication/CMakeLists.txt
watchface-complication/complication-bundle.cc
watchface-complication/complication-connector.cc
watchface-complication/complication-connector.h
watchface-complication/complication.cc
watchface-complication/complication.h
watchface-complication/design-element.cc
watchface-complication/editables-container.cc
watchface-complication/received-editable.cc
watchface-complication/watchface-complication.cc
watchface-complication/watchface-editable.cc
watchface-editor/editables-editor.cc
watchface-editor/watchface-editor.cc

diff --git a/watchface-common/watchface_exception.h b/watchface-common/watchface_exception.h
new file mode 100644 (file)
index 0000000..420dd9b
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+#ifndef WATCHFACE_COMPLICATION_EXCEPTION_H_
+#define WATCHFACE_COMPLICATION_EXCEPTION_H_
+
+#include <string>
+#include <exception>
+#include "watchface-common.h"
+
+#define THROW(error_code) throw Exception(error_code, __FILE__, __LINE__)
+
+namespace watchface_complication {
+  class Exception : public std::exception {
+    public:
+      Exception(int error_code, std::string file = __FILE__, int line = __LINE__ ) {
+        _error_code = error_code;
+        _whatMessage = file.substr(file.find_last_of("/") + 1) + ":"
+           + std::to_string(line) + GetErrorString(error_code);
+      }
+      virtual ~Exception() {};
+      virtual const char *what(void) const noexcept {
+        return _whatMessage.c_str();
+      }
+      int GetErrorCode() {
+        return _error_code;
+      }
+
+      private:
+      int _error_code;
+      std::string _whatMessage;
+      std::string GetErrorString(int error_code) {
+        switch (error_code) {
+        case WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY:
+          return ": OUT_OF_MEMORY";
+        case WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER:
+          return ": INVALID_PARAMETER";
+        case WATCHFACE_COMPLICATION_ERROR_IO_ERROR:
+          return ": IO_ERROR";
+        case WATCHFACE_COMPLICATION_ERROR_NO_DATA:
+          return ": NO_DATA";
+        case WATCHFACE_COMPLICATION_ERROR_PERMISSION_DENIED:
+          return ": PERMISSION_DENIED";
+        case WATCHFACE_COMPLICATION_ERROR_NOT_SUPPORTED:
+          return ": NOT_SUPPORTED";
+        case WATCHFACE_COMPLICATION_ERROR_DB:
+          return ": DB_ERROR";
+        case WATCHFACE_COMPLICATION_ERROR_DBUS:
+          return ": DBUS_ERROR";
+        case WATCHFACE_COMPLICATION_ERROR_EDIT_NOT_READY:
+          return ": EDIT_NOT_READY";
+        case WATCHFACE_COMPLICATION_ERROR_EXIST_ID:
+          return ": EXIST_ID";
+        case WATCHFACE_COMPLICATION_ERROR_NOT_EXIST:
+          return ": NOT_EXIST";
+        default :
+          return "";
+      }
+    }
+  };
+}
+
+#endif  /* WATCHFACE_COMPLICATION_DB_MANAGER_H_ */
index 414ba9f..68eced3 100644 (file)
@@ -39,13 +39,20 @@ ComplicationProvider::~ComplicationProvider() = default;
 ComplicationProvider::Impl::Impl(ComplicationProvider* parent,
                                  const std::string& provider_id)
   : parent_(parent), provider_id_(provider_id) {
-  subscribe_id_ = ComplicationConnector::GetInst().SubscribeSignal(
-    ComplicationConnector::Complication, provider_id_, -1, this);
+  int ret;
+  try {
+    subscribe_id_ = ComplicationConnector::GetInst().SubscribeSignal(
+      ComplicationConnector::Complication, provider_id_, -1, this);
+  } catch (...) {
+    throw;
+  }
 
   std::list<std::string> privlege_list;
   required_privileges_.push_back(std::string(PRIVILEGE_DATASHARING));
 
-  DBManager::GetSupportTypes(provider_id_, &support_types_);
+  ret = DBManager::GetSupportTypes(provider_id_, &support_types_);
+  if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
+    THROW(ret);
 
   privlege_list = DBManager::GetRequiredPrivlegeList(provider_id_);
   for (auto& i : privlege_list) {
@@ -139,13 +146,16 @@ void ComplicationProvider::Impl::OnSignal(GDBusConnection* connection,
   int complication_id;
   char *context_raw = NULL;
   int type;
+  Bundle* context_data;
+  Bundle* shared_data;
+  bool ret;
 
   auto sender_info = sender_info_.find(sender_name);
   auto si = sender_info->second;
 
   if (sender_info == sender_info_.end()) {
     char* sender_app_id = NULL;
-    int watcher_id;
+    int watcher_id = 0;
     g_variant_get_child(parameters, 0, "&s", &sender_app_id);
 
     if (sender_app_id == NULL  ||
@@ -153,11 +163,17 @@ void ComplicationProvider::Impl::OnSignal(GDBusConnection* connection,
       LOGE("sender_app_id %s", sender_app_id);
       return;
     }
-
-    watcher_id = ComplicationConnector::GetInst().Watch(
+    try {
+      watcher_id = ComplicationConnector::GetInst().Watch(
                                       std::string(sender_app_id), this);
-
-    si = new SenderInfo(sender_name, sender_app_id, watcher_id);
+    } catch (...) {
+    }
+    try {
+      si = new SenderInfo(sender_name, sender_app_id, watcher_id);
+    } catch (const std::bad_alloc &ba) {
+      LOGE("SenderInfo::Exception bad_alloc");
+      return;
+    }
     sender_info_[sender_name] = si;
     LOGI("create new sender_info_ ");
   }
@@ -195,6 +211,11 @@ void ComplicationProvider::Impl::OnSignal(GDBusConnection* connection,
       return;
     }
 
+    if (!util::CheckComplicationType(static_cast<int>(type))) {
+      LOGE("invaild type [%d]", type);
+      return;
+    }
+
     if ((support_types_ & type) == 0) {
       LOGE("Not supported type [%d][%d]", support_types_, type);
       return;
@@ -202,25 +223,40 @@ void ComplicationProvider::Impl::OnSignal(GDBusConnection* connection,
 
     LOGI("get : %s, %d, %d", sender_app_id, complication_id, type);
 
-    Bundle* context_data = new Bundle(std::string(context_raw));
-    Bundle* shared_data = new Bundle();
+    try {
+      context_data = new Bundle(std::string(context_raw));
+      shared_data = new Bundle();
+    } catch (const std::bad_alloc &ba) {
+      LOGE("Bundle::Exception bad_alloc");
+      return;
+    } catch (Exception &ex) {
+      LOGE("%s %d", ex.what(), ex.GetErrorCode());
+      return;
+    }
 
     /* Call update request callback and fill shared data */
     parent_->OnDataUpdateRequest(sender_app_id, (ComplicationType)type,
                                 context_data, shared_data);
     delete context_data;
-    ComplicationConnector::GetInst().EmitSignal(
-      ComplicationConnector::Complication,
-      std::string(sender_app_id),
-      provider_id_, -1,
-      ComplicationConnector::GetInst().GetCmdStr(
-          ComplicationConnector::CompUpdated),
-      g_variant_new("(siis)",
-                    (provider_id_).c_str(),
-                    type,
-                    complication_id,
-                    shared_data->ToString()));
+    try {
+      ret = ComplicationConnector::GetInst().EmitSignal(
+            ComplicationConnector::Complication,
+            std::string(sender_app_id),
+            provider_id_, -1,
+            ComplicationConnector::GetInst().GetCmdStr(
+                ComplicationConnector::CompUpdated),
+            g_variant_new("(siis)",
+                          (provider_id_).c_str(),
+                          type,
+                          complication_id,
+                          shared_data->ToString()));
+    } catch (Exception &ex) {
+      LOGE("%s %d", ex.what(), ex.GetErrorCode());
+      ret = false;
+  }
     delete shared_data;
+    if (ret == false)
+      LOGE("EmitSignal failed %s %s %d", sender_app_id, (provider_id_).c_str(), complication_id);
   }
 }
 
@@ -256,7 +292,8 @@ int ComplicationProvider::NotifyDataUpdate() {
     }
   }
 
-  emit_ret = ComplicationConnector::GetInst().EmitSignal(
+  try {
+    emit_ret = ComplicationConnector::GetInst().EmitSignal(
                             ComplicationConnector::Complication,
                             "",
                             impl_->provider_id_, -1,
@@ -264,6 +301,10 @@ int ComplicationProvider::NotifyDataUpdate() {
                                  ComplicationConnector::CompNotifyDataUpdate),
                             g_variant_new("(s)",
                                 impl_->provider_id_.c_str()));
+  } catch (Exception &ex) {
+    LOGE("%s %d", ex.what(), ex.GetErrorCode());
+    return ex.GetErrorCode();
+  }
 
   if (emit_ret == false)
     ret = WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
index 79edc20..18c7a54 100644 (file)
@@ -126,7 +126,15 @@ extern "C" EXPORT_API int watchface_complication_provider_add_update_requested_c
   auto ws = cp->second;
 
   if (cp == __providers.end()) {
-    ws = new WatchComplicationProviderStub(provider_id);
+    try {
+      ws = new WatchComplicationProviderStub(provider_id);
+    } catch (const std::bad_alloc &ba) {
+      LOGE("WatchComplicationProviderStub::Exception bad_alloc");
+      return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
+    } catch (Exception &ex) {
+      LOGE("%s %d", ex.what(), ex.GetErrorCode());
+      return ex.GetErrorCode();
+    }
     __providers[provider_id] = ws;
     LOGI("create new provider : %s", provider_id);
   }
@@ -180,7 +188,7 @@ extern "C" EXPORT_API int watchface_complication_provider_setup_reply_to_editor(
   int ret;
   int str_len = 0;
   bundle_raw* raw_data = NULL;
-  bool emit_signal_ret;
+  bool emit_signal_ret = false;
 
   ret = app_control_get_extra_data(handle, SETUP_EDITOR_APPID_KEY, &editor_appid);
   if (ret != 0) {
@@ -210,7 +218,8 @@ extern "C" EXPORT_API int watchface_complication_provider_setup_reply_to_editor(
     }
   }
 
-  emit_signal_ret = ComplicationConnector::GetInst().EmitSignal(
+  try {
+    emit_signal_ret = ComplicationConnector::GetInst().EmitSignal(
       ComplicationConnector::Editable,
       std::string(editor_appid),
       std::string(editor_appid), -1,
@@ -218,7 +227,10 @@ extern "C" EXPORT_API int watchface_complication_provider_setup_reply_to_editor(
           ComplicationConnector::SetupReply),
       g_variant_new("(is)", atoi(editable_id),
                     raw_data == NULL ? "" : reinterpret_cast<char*>(raw_data)));
-
+  } catch (Exception &ex) {
+    LOGE("%s %d", ex.what(), ex.GetErrorCode());
+    emit_signal_ret = false;
+  }
   free(editor_appid);
   free(editable_id);
   free(raw_data);
index 2ab7f37..3d99838 100644 (file)
@@ -33,6 +33,7 @@ SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
 SET(CMAKE_CXX_FLAGS_RELEASE "-O2")
 
 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../watchface-common)
 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../watchface-common/include)
 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include)
 
index 82a951d..4455a73 100644 (file)
@@ -17,6 +17,7 @@
 #include <dlog.h>
 
 #include "watchface-complication/complication-bundle.h"
+#include "watchface-common/watchface_exception.h"
 
 #ifdef LOG_TAG
 #undef LOG_TAG
@@ -29,19 +30,32 @@ namespace watchface_complication {
 Bundle::Bundle() {
   LOGE("create bundle !!");
   raw_ = bundle_create();
+  if (raw_ == NULL)
+    THROW(WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY);
 }
 
 Bundle::Bundle(std::string raw) {
   if (!raw.empty()) {
     raw_ = bundle_decode(reinterpret_cast<const bundle_raw*>(raw.c_str()),
                          raw.length());
+    if (raw_ == NULL) {
+      int ret = get_last_result();
+      if (ret == BUNDLE_ERROR_OUT_OF_MEMORY)
+        THROW(WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY);
+      else
+        THROW(WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER);
+    }
   } else {
     raw_ = bundle_create();
+    if (raw_ == NULL)
+      THROW(WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY);
   }
 }
 
 Bundle::Bundle(bundle* raw) {
   raw_ = bundle_dup(raw);
+  if (raw_ == NULL)
+    THROW(WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY);
 }
 
 Bundle::Bundle(Bundle&& b) : raw_(b.raw_) {
@@ -57,6 +71,8 @@ Bundle& Bundle::operator = (Bundle&& b) {
 Bundle::Bundle(const Bundle& b) : raw_(bundle_dup(b.raw_)) {}
 Bundle& Bundle::operator = (const Bundle& b) {
   raw_ = bundle_dup(b.raw_);
+  if (raw_ == NULL)
+    THROW(WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY);
   return *this;
 }
 
@@ -70,12 +86,16 @@ bundle* Bundle::GetRaw() {
 
 const char* Bundle::ToString() {
   int str_len = 0;
+  int ret;
   bundle_raw* temp;
 
   if (str_raw_ != NULL)
     return str_raw_;
 
-  bundle_encode(raw_, &temp, &str_len);
+  ret = bundle_encode(raw_, &temp, &str_len);
+  if (ret != BUNDLE_ERROR_NONE)
+    THROW(WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY);
+
   str_raw_ = reinterpret_cast<char*>(temp);
   return str_raw_;
 }
index 1180820..0d0ebbf 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "watchface-complication/complication-connector.h"
 #include "watchface-complication/complication-connector-implementation.h"
+#include "watchface-common/watchface_exception.h"
 
 #ifdef LOG_TAG
 #undef LOG_TAG
@@ -58,9 +59,14 @@ std::string ComplicationConnector::GetAppId() {
 
 int ComplicationConnector::Watch(std::string appid, IEventListener* listener) {
   int watcher_id;
+  std::string name;
 
   LOGI("watch on : %s", appid.c_str());
-  std::string name = ComplicationConnector::GetInst().EncodeStr(Name, appid);
+  try {
+    name = ComplicationConnector::GetInst().EncodeStr(Name, appid);
+  } catch (...) {
+    throw;
+  }
 
   watcher_id = g_bus_watch_name_on_connection(
       impl_->conn_,
@@ -72,6 +78,11 @@ int ComplicationConnector::Watch(std::string appid, IEventListener* listener) {
       NULL);
   LOGI("watch %s, %d", name.c_str(), watcher_id);
 
+  if (watcher_id == 0) {
+    LOGI("watch on name failed %s, %d", name.c_str(), watcher_id);
+    THROW(WATCHFACE_COMPLICATION_ERROR_IO_ERROR);
+  }
+
   return watcher_id;
 }
 
@@ -85,9 +96,14 @@ bool ComplicationConnector::EmitSignal(SigType type, std::string target_id,
                                        std::string cmd, GVariant* data) {
   GError *err = NULL;
   gboolean result = TRUE;
-  std::string path = ComplicationConnector::GetInst().EncodeStr(
-                       type == Complication ? CompPath : EditablePath,
-                       id, sub_id);
+  std::string path;
+  try {
+    path = ComplicationConnector::GetInst().EncodeStr(
+                         type == Complication ? CompPath : EditablePath,
+                         id, sub_id);
+  } catch (...) {
+    throw;
+  }
   std::string name = ComplicationConnector::GetInst()
                      .EncodeStr(Name, target_id);
 
@@ -118,9 +134,14 @@ int ComplicationConnector::SubscribeSignal(SigType type, std::string id,
   int subscribe_id;
 
   LOGI("subscribe : %s, %d", id.c_str(), sub_id);
-  std::string path = ComplicationConnector::GetInst().EncodeStr(
-                       type == Complication ? CompPath : EditablePath,
-                       id, sub_id);
+  std::string path;
+  try {
+    path = ComplicationConnector::GetInst().EncodeStr(
+                   type == Complication ? CompPath : EditablePath,
+                   id, sub_id);
+  } catch (int e) {
+    throw;
+  }
 
   subscribe_id = g_dbus_connection_signal_subscribe(
                    impl_->conn_,
@@ -133,13 +154,20 @@ int ComplicationConnector::SubscribeSignal(SigType type, std::string id,
                    impl_->SignalCb,
                    listener,
                    NULL);
+
+  if (subscribe_id == 0) {
+    LOGE("subscribe %s, %d", path.c_str(), subscribe_id);
+    THROW(WATCHFACE_COMPLICATION_ERROR_IO_ERROR);
+  }
+
   LOGI("subscribe %s, %d", path.c_str(), subscribe_id);
 
   return subscribe_id;
 }
 
 void ComplicationConnector::UnSubscribeSignal(int subscribe_id) {
-  g_dbus_connection_signal_unsubscribe(impl_->conn_, subscribe_id);
+  if (subscribe_id > 0)
+    g_dbus_connection_signal_unsubscribe(impl_->conn_, subscribe_id);
 }
 
 std::string ComplicationConnector::EncodeStr(EncodeType type,
index 587d74d..9af27b9 100644 (file)
@@ -22,6 +22,7 @@
 #include <memory>
 
 #include "watchface-complication/include/watchface-complication-internal.h"
+#include "watchface-common/watchface_exception.h"
 
 namespace watchface_complication {
 
index e36b5ad..dfd2e21 100644 (file)
@@ -60,15 +60,22 @@ Complication::Impl::Impl(Complication* parent, int id,
   RestoreStateOrSetDefault();
   LoadPeriod();
   LoadLabel();
-  subscribe_id_ = ComplicationConnector::GetInst().SubscribeSignal(
-                    ComplicationConnector::Complication, cur_provider_id_,
-                    -1, this);
-  LOGI("subscribe signal %d", subscribe_id_);
+  if (cur_type_ != NoData) {
+    try {
+      subscribe_id_ = ComplicationConnector::GetInst().SubscribeSignal(
+                      ComplicationConnector::Complication, cur_provider_id_,
+                      -1, this);
+    } catch (...) {
+      throw;
+    }
+  }
+  LOGI("subscribe signal %d %d ", subscribe_id_, cur_type_);
 }
 
 Complication::Impl::~Impl() {
   LOGI("complication destroy %d", complication_id_);
-  ComplicationConnector::GetInst().UnSubscribeSignal(subscribe_id_);
+  if (subscribe_id_ > 0)
+    ComplicationConnector::GetInst().UnSubscribeSignal(subscribe_id_);
 
   if (periodic_timer_)
     g_source_remove(periodic_timer_);
@@ -119,9 +126,14 @@ void Complication::Impl::OnSignal(GDBusConnection* connection,
       return;
     }
 
-    int watcher_id = ComplicationConnector::GetInst().Watch(
+    try {
+      /* Ignore the generated exception.
+         There are codes for performance, and if signal is received, it is tried again.  */
+      int watcher_id = ComplicationConnector::GetInst().Watch(
                                         sender_appid, this);
-    sender_info_[sender_name] = watcher_id;
+      sender_info_[sender_name] = watcher_id;
+    } catch (...) {
+    }
   }
 
   if (signal_name.compare(ComplicationConnector::GetInst().GetCmdStr(
@@ -135,8 +147,18 @@ void Complication::Impl::OnSignal(GDBusConnection* connection,
           type, cur_type_);
       return;
     }
-    if (raw != NULL)
-      last_data_.reset(new Bundle(std::string(reinterpret_cast<char*>(raw))));
+
+    try {
+      if (raw != NULL)
+        last_data_.reset(new Bundle(std::string(reinterpret_cast<char*>(raw))));
+    } catch (const std::bad_alloc &ba) {
+      LOGE("Bundle::Exception bad_alloc");
+      return;
+    } catch (Exception &ex) {
+      LOGE("%s %d", ex.what(), ex.GetErrorCode());
+      return;
+    }
+
     LOGI("data: %s, %d, cur_type :%d", provider_id, complication_id, cur_type_);
     if (last_data_ != nullptr) {
       parent_->OnDataUpdated(
@@ -178,8 +200,13 @@ int Complication::Impl::FindCandidateDataIdx(std::string provider_id, int type)
 void Complication::Impl::RestoreStateOrSetDefault() {
   char* prev_provider_id = NULL;
   char* prev_provider_type = NULL;
-  std::unique_ptr<Bundle> setting_data =
-      EditablesManager::GetInst().LoadSetting(complication_id_);
+  std::unique_ptr<Bundle> setting_data;
+
+  try {
+    setting_data = EditablesManager::GetInst().LoadSetting(complication_id_);
+  } catch (...) {
+    throw;
+  }
 
   if (setting_data == nullptr) {
     cur_provider_id_ = default_provider_id_;
@@ -205,8 +232,12 @@ void Complication::Impl::RestoreStateOrSetDefault() {
   cur_data_idx_ = FindCandidateDataIdx(cur_provider_id_, cur_type_);
   context_data_ = EditablesManager::GetInst().LoadContext(complication_id_,
       cur_provider_id_.c_str());
-  if (context_data_ != nullptr)
-    last_context_data_.reset(new Bundle(context_data_.get()->GetRaw()));
+  try {
+    if (context_data_ != nullptr)
+      last_context_data_.reset(new Bundle(context_data_.get()->GetRaw()));
+  } catch (...) {
+    throw;
+  }
 }
 
 int Complication::Impl::StoreSetting(int comp_id, std::string& provider_id,
@@ -232,10 +263,16 @@ int Complication::Impl::StoreSetting(int comp_id, std::string& provider_id,
   bundle_encode(setting_data, &raw_data, &raw_len);
   bundle_free(setting_data);
 
-  ret = EditablesManager::GetInst().StoreSetting(comp_id, raw_data);
-  if (ret != WATCHFACE_COMPLICATION_ERROR_NONE) {
+  try {
+    ret = EditablesManager::GetInst().StoreSetting(comp_id, raw_data);
+    if (ret != WATCHFACE_COMPLICATION_ERROR_NONE) {
+      free(raw_data);
+      return ret;
+    }
+  } catch (Exception &ex) {
+    LOGE("%s %d", ex.what(), ex.GetErrorCode());
     free(raw_data);
-    return ret;
+    return ex.GetErrorCode();
   }
 
   free(raw_data);
@@ -402,10 +439,15 @@ int Complication::SetCurDataIdx(int cur_data_idx) {
     impl_->cur_provider_id_.c_str(), impl_->cur_type_);
 
   ComplicationConnector::GetInst().UnSubscribeSignal(impl_->subscribe_id_);
-  impl_->subscribe_id_ = ComplicationConnector::GetInst().SubscribeSignal(
-                    ComplicationConnector::Complication, impl_->cur_provider_id_,
-                    -1, impl_.get());
-  LOGI("subscribe signal %d", impl_->subscribe_id_);
+  if (impl_->cur_type_ == NoData) {
+    impl_->subscribe_id_ = -1;
+  } else {
+
+    impl_->subscribe_id_ = ComplicationConnector::GetInst().SubscribeSignal(
+                      ComplicationConnector::Complication, impl_->cur_provider_id_,
+                      -1, impl_.get());
+    LOGI("subscribe signal %d", impl_->subscribe_id_);
+  }
 
   return WATCHFACE_COMPLICATION_ERROR_NONE;
 }
@@ -497,6 +539,7 @@ int Complication::SendDataUpdateRequest() {
 
   const char* context_data_raw = "";
   int ret;
+  bool emit_ret = false;
 
   ret = aul_complication_update_request(ComplicationConnector::GetInst().GetAppId().c_str(),
                 provider_appid.c_str(), getuid());
@@ -513,21 +556,29 @@ int Complication::SendDataUpdateRequest() {
 
   if (impl_->context_data_ != nullptr)
     context_data_raw = impl_->context_data_->ToString();
+  try {
+    emit_ret = ComplicationConnector::GetInst().EmitSignal(
+      ComplicationConnector::Complication,
+      provider_appid,
+      impl_->cur_provider_id_,
+      -1,
+      ComplicationConnector::GetInst().GetCmdStr(
+          ComplicationConnector::CompUpdateRequest),
+      g_variant_new("(siis)",
+                    ComplicationConnector::GetInst().GetAppId().c_str(),
+                    impl_->complication_id_,
+                    impl_->cur_type_,
+                    context_data_raw));
+  } catch (Exception &ex) {
+    LOGE("%s %d", ex.what(), ex.GetErrorCode());
+    return ex.GetErrorCode();
+  }
+
+  if (emit_ret == false)
+    ret = WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
 
-  ComplicationConnector::GetInst().EmitSignal(
-    ComplicationConnector::Complication,
-    provider_appid,
-    impl_->cur_provider_id_,
-    -1,
-    ComplicationConnector::GetInst().GetCmdStr(
-        ComplicationConnector::CompUpdateRequest),
-    g_variant_new("(siis)",
-                  ComplicationConnector::GetInst().GetAppId().c_str(),
-                  impl_->complication_id_,
-                  impl_->cur_type_,
-                  context_data_raw));
   LOGI("emit signal done");
-  return WATCHFACE_COMPLICATION_ERROR_NONE;
+  return ret;
 }
 
 const char* Complication::GetProviderIdKey() {
@@ -566,12 +617,26 @@ int Complication::UpdateLastContext() {
     return WATCHFACE_COMPLICATION_ERROR_NONE;
   }
 
-  int ret = EditablesManager::GetInst().StoreContext(impl_->complication_id_,
-      impl_->cur_provider_id_.c_str(), *impl_->context_data_.get());
+  try {
+    int ret = EditablesManager::GetInst().StoreContext(impl_->complication_id_,
+        impl_->cur_provider_id_.c_str(), *impl_->context_data_.get());
   if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
     return ret;
+  } catch (Exception &ex) {
+    LOGE("%s %d", ex.what(), ex.GetErrorCode());
+    return ex.GetErrorCode();
+  }
+
+  try {
+    impl_->last_context_data_.reset(new Bundle((impl_->context_data_.get())->GetRaw()));
+  } catch (const std::bad_alloc &ba) {
+    LOGE("Bundle::Exception bad_alloc");
+    return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
+  } catch (Exception &ex) {
+    LOGE("%s %d", ex.what(), ex.GetErrorCode());
+    return ex.GetErrorCode();
+  }
 
-  impl_->last_context_data_.reset(new Bundle((impl_->context_data_.get())->GetRaw()));
   return WATCHFACE_COMPLICATION_ERROR_NONE;
 }
 
@@ -640,7 +705,17 @@ int Complication::Impl::AddCandidate(std::string provider_id, int type) {
   bundle_add_str(data, provider_id_key_.c_str(), provider_id.c_str());
   bundle_add_str(data, provider_type_key_.c_str(),
       std::to_string(type).c_str());
-  candidates_list_.emplace_back(new Bundle(data));
+  try {
+    candidates_list_.emplace_back(new Bundle(data));
+  } catch (const std::bad_alloc &ba) {
+    LOGE("Bundle::Exception bad_alloc");
+    bundle_free(data);
+    return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
+  } catch (Exception &ex) {
+    LOGE("%s %d", ex.what(), ex.GetErrorCode());
+    bundle_free(data);
+    return ex.GetErrorCode();
+  }
   bundle_free(data);
 
   return WATCHFACE_COMPLICATION_ERROR_NONE;
index 57ce3fd..20d2d18 100644 (file)
@@ -28,6 +28,7 @@
 #include "watchface-complication/complication-connector.h"
 #include "watchface-complication/editables-manager.h"
 #include "watchface-complication/db-manager.h"
+#include "watchface-common/watchface_exception.h"
 
 namespace watchface_complication {
 
index d64d7d3..b92d72d 100644 (file)
@@ -119,11 +119,17 @@ int DesignElement::UpdateLastData() {
   bundle_raw* raw_data = NULL;
   int raw_len;
   bundle_encode(const_cast<Bundle*>(cur_data)->GetRaw(), &raw_data, &raw_len);
-  int ret = EditablesManager::GetInst().StoreSetting(impl_->id_, raw_data);
-  free(raw_data);
-
-  if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
-    return ret;
+  try {
+    int ret = EditablesManager::GetInst().StoreSetting(impl_->id_, raw_data);
+    free(raw_data);
+
+    if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
+      return ret;
+  } catch (Exception &ex) {
+    LOGE("%s %d", ex.what(), ex.GetErrorCode());
+    free(raw_data);
+    return ex.GetErrorCode();
+  }
 
   impl_->last_data_idx_ = impl_->cur_data_idx_;
   return WATCHFACE_COMPLICATION_ERROR_NONE;
index 4970605..89b7f7e 100644 (file)
@@ -163,6 +163,7 @@ int EditablesContainer::RequestEdit() {
   int str_len = 0;
   bundle_raw* str_raw = NULL;
   char** list_arr;
+  bool emit_ret = false;
 
   if (impl_->editor_id_.empty())
     return -1;
@@ -223,23 +224,36 @@ int EditablesContainer::RequestEdit() {
   impl_->FreeList(list_arr, impl_->ed_list_.size());
   bundle_encode(container, &str_raw, &str_len);
 
-  ComplicationConnector::GetInst().EmitSignal(
-    ComplicationConnector::Editable,
-    impl_->editor_id_,
-    impl_->editor_id_,
-    -1,
-    ComplicationConnector::GetInst().GetCmdStr(
-        ComplicationConnector::EditableEditRequest),
-    g_variant_new("(ss)",
-                  ComplicationConnector::GetInst().GetAppId().c_str(),
-                  str_raw)
-  );
+  try {
+    emit_ret = ComplicationConnector::GetInst().EmitSignal(
+      ComplicationConnector::Editable,
+      impl_->editor_id_,
+      impl_->editor_id_,
+      -1,
+      ComplicationConnector::GetInst().GetCmdStr(
+          ComplicationConnector::EditableEditRequest),
+      g_variant_new("(ss)",
+                    ComplicationConnector::GetInst().GetAppId().c_str(),
+                    str_raw)
+    );
+  } catch (Exception &ex) {
+    LOGE("%s %d", ex.what(), ex.GetErrorCode());
+    emit_ret = false;
+  }
 
   bundle_free_encoded_rawdata(&str_raw);
   bundle_free(container);
 
+  if (emit_ret == false)
+    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+
+  try {
   impl_->watcher_id_ = ComplicationConnector::GetInst().Watch(impl_->editor_id_,
       this->impl_.get());
+  } catch (Exception &ex) {
+    LOGE("%s %d", ex.what(), ex.GetErrorCode());
+    return ex.GetErrorCode();
+  }
 
   return WATCHFACE_COMPLICATION_ERROR_NONE;
 }
index 985532c..9dfbee0 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "watchface-complication/received-editable.h"
 #include "watchface-complication/received-editable-implementation.h"
+#include "watchface-common/watchface_exception.h"
 
 #ifdef LOG_TAG
 #undef LOG_TAG
@@ -38,7 +39,7 @@ ReceivedEditable::~ReceivedEditable() = default;
 ReceivedEditable::Impl::Impl(ReceivedEditable* parent, std::string raw)
   : parent_(parent) {
   if (raw.empty())
-    return;
+    THROW(WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER);
 
   bundle* data = bundle_decode(
                    reinterpret_cast<const bundle_raw*>(
@@ -203,7 +204,16 @@ int ReceivedEditable::UpdateLastContext() {
     LOGI("Empty context");
     return WATCHFACE_COMPLICATION_ERROR_NONE;
   }
-  impl_->last_context_data_.reset(new Bundle((impl_->context_data_.get())->GetRaw()));
+
+  try {
+    impl_->last_context_data_.reset(new Bundle((impl_->context_data_.get())->GetRaw()));
+  } catch (const std::bad_alloc &ba) {
+    LOGE("Bundle::Exception bad_alloc");
+    return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
+  } catch (Exception &ex) {
+    LOGE("%s %d", ex.what(), ex.GetErrorCode());
+    return ex.GetErrorCode();
+  }
   return WATCHFACE_COMPLICATION_ERROR_NONE;
 }
 
index 3877eef..5caeb07 100644 (file)
@@ -112,12 +112,17 @@ extern "C" EXPORT_API int watchface_complication_add_updated_cb(
     void *user_data) {
   if (handle == NULL || cb == NULL)
     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
-
+  int ret;
   auto sh = static_cast<SharedHandle<WatchComplicationStub>*>(handle);
   auto ptr = SharedHandle<WatchComplicationStub>::Share(sh);
-  ptr.get()->AddCallbackInfo(new CallbackInfo(cb, user_data));
 
-  return WATCHFACE_COMPLICATION_ERROR_NONE;
+  try {
+    ret = ptr.get()->AddCallbackInfo(new CallbackInfo(cb, user_data));
+  } catch (const std::bad_alloc &ba) {
+    LOGE("WatchComplicationProviderStub::Exception bad_alloc");
+    return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
+  }
+  return ret;
 }
 
 extern "C" EXPORT_API int watchface_complication_remove_updated_cb(
@@ -168,9 +173,12 @@ extern "C" EXPORT_API int watchface_complication_create(int complication_id,
     LOGI("comp created");
     auto sh = SharedHandle<WatchComplicationStub>::Make(ws);
     *created_handle = static_cast<void*>(sh);
-  } catch(...) {
-    LOGE("Create complication fail");
-    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+  } catch (const std::bad_alloc &ba) {
+    LOGE("WatchComplicationStub::Exception bad_alloc");
+    return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
+  } catch (Exception &ex) {
+    LOGE("%s %d", ex.what(), ex.GetErrorCode());
+    return ex.GetErrorCode();
   }
 
   return WATCHFACE_COMPLICATION_ERROR_NONE;
@@ -190,14 +198,18 @@ extern "C" EXPORT_API int watchface_complication_get_current_provider_id(
     complication_h handle, char** cur_provider_id) {
   if (handle == NULL || cur_provider_id == NULL)
     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
-
+  char* tmp;
   auto sh = static_cast<SharedHandle<WatchComplicationStub>*>(handle);
   auto ptr = SharedHandle<WatchComplicationStub>::Share(sh);
   if (ptr.get()->GetCurProviderId() == NULL)
     return WATCHFACE_COMPLICATION_ERROR_NO_DATA;
 
   LOGI("provider id : %s", ptr.get()->GetCurProviderId());
-  *cur_provider_id = strdup(ptr.get()->GetCurProviderId());
+  tmp = strdup(ptr.get()->GetCurProviderId());
+  if (tmp == NULL)
+    return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
+
+  *cur_provider_id = tmp;
 
   return WATCHFACE_COMPLICATION_ERROR_NONE;
 }
@@ -611,17 +623,18 @@ extern "C" EXPORT_API int watchface_complication_allowed_list_apply(
         (provider_info*)g_list_nth_data(list_handle->allowed_list, i);
     if (info == NULL || info->provider_id == NULL)
       continue;
-    allowed_list.emplace_back(std::unique_ptr<Complication::ProviderInfo>(
-      new Complication::ProviderInfo(
-        std::string(info->provider_id), info->types))
-    );
+    try {
+      allowed_list.emplace_back(std::unique_ptr<Complication::ProviderInfo>(
+        new Complication::ProviderInfo(
+          std::string(info->provider_id), info->types))
+      );
+    } catch(const std::bad_alloc &ba) {
+      LOGE("ProviderInfo::Exception bad_alloc");
+      return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
+    }
   }
 
-  int ret = ptr.get()->ApplyAllowedList(std::move(allowed_list));
-  if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
-    return ret;
-
-  return WATCHFACE_COMPLICATION_ERROR_NONE;
+  return  ptr.get()->ApplyAllowedList(std::move(allowed_list));
 }
 
 extern "C" EXPORT_API int watchface_complication_allowed_list_clear(
@@ -633,9 +646,6 @@ extern "C" EXPORT_API int watchface_complication_allowed_list_clear(
   }
   auto sh = static_cast<SharedHandle<WatchComplicationStub>*>(handle);
   auto ptr = SharedHandle<WatchComplicationStub>::Share(sh);
-  int ret = ptr.get()->ClearAllowedList();
-  if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
-    return ret;
 
-  return WATCHFACE_COMPLICATION_ERROR_NONE;
+  return ptr.get()->ClearAllowedList();
 }
index 65ec470..7032406 100644 (file)
@@ -26,6 +26,7 @@
 #include "watchface-complication/shared-handle.h"
 #include "watchface-complication/editables-manager.h"
 #include "watchface-common/watchface-util.h"
+#include "watchface-common/watchface_exception.h"
 
 #ifdef LOG_TAG
 #undef LOG_TAG
@@ -182,12 +183,21 @@ extern "C" EXPORT_API int watchface_editable_add_design_element(
     LOGE("ID already exist");
     return WATCHFACE_COMPLICATION_ERROR_EXIST_ID;
   }
-  auto de = std::shared_ptr<IEditable>(new DesignElement(edit_id, cur_data_idx,
+
+  try {
+    auto de = std::shared_ptr<IEditable>(new DesignElement(edit_id, cur_data_idx,
                      std::shared_ptr<IEditable::Geometry>(
                        new IEditable::Geometry(geo->x, geo->y, geo->w, geo->h))));
-  de.get()->SetLabel(std::string(editable_name));
-  de.get()->SetCandidates(std::move(new_list));
-  ec->Add(de, edit_id);
+    de.get()->SetLabel(std::string(editable_name));
+    ret = de.get()->SetCandidates(std::move(new_list));
+    if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
+      return ret;
+
+    ec->Add(de, edit_id);
+  } catch (const std::bad_alloc &ba) {
+    LOGE("DesignElement::Exception bad_alloc");
+    return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
+  }
 
   return WATCHFACE_COMPLICATION_ERROR_NONE;
 }
@@ -200,13 +210,18 @@ extern "C" EXPORT_API int watchface_editable_add_complication(
 
   EditablesContainerStub* ec = static_cast<EditablesContainerStub*>(handle);
   SharedHandle<IEditable>* sh = static_cast<SharedHandle<IEditable>*>(comp);
+  int ret;
 
   /* Update candidates */
-  SharedHandle<IEditable>::Share(sh).get()->SetCandidates(
+  ret = SharedHandle<IEditable>::Share(sh).get()->SetCandidates(
       std::list<std::unique_ptr<Bundle>>());
 
+  if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
+    return ret;
+
   IEditable::Geometry editable_geo(geo->x, geo->y, geo->w, geo->h);
   SharedHandle<IEditable>::Share(sh).get()->SetGeo(editable_geo);
+
   if (ec->IsExist(edit_id)) {
     LOGE("ID already exist");
     return WATCHFACE_COMPLICATION_ERROR_EXIST_ID;
@@ -243,12 +258,19 @@ extern "C" EXPORT_API int watchface_editable_request_edit(
   }
 
   EditablesContainerStub* ec = static_cast<EditablesContainerStub*>(handle);
-  auto ci = new UpdateCallbackInfo(cb, user_data);
-  ec->ClearUpdateCallbackInfo();
-  ec->AddUpdateCallbackInfo(ci);
-  ec->RequestEdit();
 
-  return WATCHFACE_COMPLICATION_ERROR_NONE;
+  try {
+    auto ci = new UpdateCallbackInfo(cb, user_data);
+    ec->ClearUpdateCallbackInfo();
+    ec->AddUpdateCallbackInfo(ci);
+  } catch  (const std::bad_alloc &ba) {
+    LOGE("UpdateCallbackInfo::Exception bad_alloc");
+    return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
+  }
+
+  ret = ec->RequestEdit();
+
+  return ret;
 }
 
 extern "C" EXPORT_API int watchface_editable_add_edit_ready_cb(
@@ -256,12 +278,30 @@ extern "C" EXPORT_API int watchface_editable_add_edit_ready_cb(
   if (cb == NULL)
     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
 
-  if (__container == NULL)
-    __container = new EditablesContainerStub();
+  try {
+    if (__container == NULL)
+      __container = new EditablesContainerStub();
+  } catch  (const std::bad_alloc &ba) {
+    LOGE("EditablesContainerStub::Exception bad_alloc");
+    return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
+  } catch (watchface_complication::Exception &ex) {
+    LOGE("%s %d", ex.what(), ex.GetErrorCode());;
+    return ex.GetErrorCode();
+  }
 
-  auto ci = new ReadyCallbackInfo(cb, user_data);
+  try {
+    auto ci = new ReadyCallbackInfo(cb, user_data);
+    int ret = __container->AddReadyCallbackInfo(ci);
+    if (ret != WATCHFACE_COMPLICATION_ERROR_NONE) {
+      delete ci;
+      return ret;
+    }
+  } catch (const std::bad_alloc &ba) {
+    LOGE("UpdateCallbackInfo::Exception bad_alloc");
+    return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
+  }
 
-  return   __container->AddReadyCallbackInfo(ci);
+  return WATCHFACE_COMPLICATION_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int watchface_editable_remove_edit_ready_cb(
@@ -385,12 +425,21 @@ extern "C" EXPORT_API int watchface_editable_load_current_data(
   if (selected_data == NULL)
     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
 
-  std::unique_ptr<Bundle> setting_data =
-      EditablesManager::GetInst().LoadSetting(editable_id);
-  if (setting_data != nullptr)
+  std::unique_ptr<Bundle> setting_data;
+
+  try {
+    setting_data = EditablesManager::GetInst().LoadSetting(editable_id);
+  } catch (watchface_complication::Exception &ex) {
+    LOGE("%s %d", ex.what(), ex.GetErrorCode());
+    return ex.GetErrorCode();;
+  }
+  if (setting_data != nullptr) {
     *selected_data = bundle_dup(setting_data.get()->GetRaw());
-  else
+    if (*selected_data == NULL)
+      return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
+  } else {
     return WATCHFACE_COMPLICATION_ERROR_NO_DATA;
+  }
   return WATCHFACE_COMPLICATION_ERROR_NONE;
 }
 
index fb500cc..9c2c46d 100644 (file)
@@ -39,9 +39,13 @@ EditablesEditor::EditablesEditor()
 EditablesEditor::~EditablesEditor() = default;
 EditablesEditor::Impl::Impl(EditablesEditor* parent)
   : parent_(parent) {
-  subscribe_id_ = ComplicationConnector::GetInst().SubscribeSignal(
+  try {
+    subscribe_id_ = ComplicationConnector::GetInst().SubscribeSignal(
                     ComplicationConnector::Editable,
                     ComplicationConnector::GetInst().GetAppId(), -1, this);
+  } catch (...) {
+    throw;
+  }
   LOGI("subscribe signal %d", subscribe_id_);
 }
 
@@ -108,13 +112,23 @@ void EditablesEditor::Impl::OnSignal(GDBusConnection* connection,
     const char **str_arr = NULL;
     int len = 0;
 
-    if (data == NULL)
-      throw std::runtime_error("bundle decode failed");
+    if (data == NULL) {
+      LOGE("bundle decode failed %d", get_last_result());
+      return;
+    }
 
     str_arr = bundle_get_str_array(data, "EDITABLE_LIST", &len);
     for (int i = 0; i < len; i++) {
-      e_list.emplace_back(std::unique_ptr<IEditable>(
-                  new ReceivedEditable(std::string(str_arr[i]))));
+      try {
+        e_list.emplace_back(std::unique_ptr<IEditable>(
+             new ReceivedEditable(std::string(str_arr[i]))));
+      } catch (const std::bad_alloc &ba) {
+        LOGE("ReceivedEditable::Exception bad_alloc");
+        return;
+      } catch (Exception &ex) {
+        LOGE("%s %d", ex.what(), ex.GetErrorCode());
+        return;
+      }
     }
     parent_->OnRequestEdit(std::string(appid), std::move(e_list));
     bundle_free(data);
@@ -123,8 +137,18 @@ void EditablesEditor::Impl::OnSignal(GDBusConnection* connection,
           ComplicationConnector::SetupReply)) == 0) {
     int edit_id;
     char* raw_str;
+
     g_variant_get(parameters, "(i&s)", &edit_id, &raw_str);
-    parent_->OnSetupReply(sender_appid, edit_id, std::unique_ptr<Bundle>(new Bundle(std::string(raw_str))));
+    try {
+      parent_->OnSetupReply(sender_appid, edit_id,
+              std::unique_ptr<Bundle>(new Bundle(std::string(raw_str))));
+    } catch (const std::bad_alloc &ba) {
+      LOGE("Bundle::Exception bad_alloc");
+      return;
+    } catch (Exception &ex) {
+      LOGE("%s %d", ex.what(), ex.GetErrorCode());
+      return;
+    }
   }
 }
 
@@ -138,6 +162,7 @@ void EditablesEditor::OnRequestEdit(const std::string& appid,
 }
 
 int EditablesEditor::EditPreview(IEditable& ed, int cur_data_idx) {
+  bool emit_result;
   int ret;
   if (impl_->edit_appid_.empty()) {
     LOGE("Editing is not ready");
@@ -152,20 +177,30 @@ int EditablesEditor::EditPreview(IEditable& ed, int cur_data_idx) {
   re.SetCurDataIdx(cur_data_idx);
 
   Bundle *context = re.GetContext().get();
-  ComplicationConnector::GetInst().EmitSignal(
-    ComplicationConnector::Editable,
-    impl_->edit_appid_.c_str(),
-    impl_->edit_appid_.c_str(),
-    -1,
-    ComplicationConnector::GetInst().GetCmdStr(
-        ComplicationConnector::EditableEditPreview),
-    g_variant_new("(iis)", cur_data_idx, ed.GetEditableId(),
-        (context == nullptr) ? "" : context->ToString()));
-
-  return WATCHFACE_COMPLICATION_ERROR_NONE;
+  try {
+    emit_result = ComplicationConnector::GetInst().EmitSignal(
+      ComplicationConnector::Editable,
+      impl_->edit_appid_.c_str(),
+      impl_->edit_appid_.c_str(),
+      -1,
+      ComplicationConnector::GetInst().GetCmdStr(
+          ComplicationConnector::EditableEditPreview),
+      g_variant_new("(iis)", cur_data_idx, ed.GetEditableId(),
+          (context == nullptr) ? "" : context->ToString()));
+  } catch (Exception &ex) {
+    LOGE("%s %d", ex.what(), ex.GetErrorCode());
+    return ex.GetErrorCode();
+  }
+
+  if (emit_result)
+    return WATCHFACE_COMPLICATION_ERROR_NONE;
+  else
+    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+
 }
 
 int EditablesEditor::EditComplete() {
+  bool emit_result;
   int ret;
 
   if (impl_->edit_appid_.empty()) {
@@ -177,18 +212,28 @@ int EditablesEditor::EditComplete() {
   if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
     return ret;
 
-  ComplicationConnector::GetInst().EmitSignal(
-    ComplicationConnector::Editable,
-    impl_->edit_appid_.c_str(),
-    impl_->edit_appid_.c_str(),
-    -1,
-    ComplicationConnector::GetInst().GetCmdStr(
-        ComplicationConnector::EditableEditComplete), NULL);
+  try {
+    emit_result = ComplicationConnector::GetInst().EmitSignal(
+      ComplicationConnector::Editable,
+      impl_->edit_appid_.c_str(),
+      impl_->edit_appid_.c_str(),
+      -1,
+      ComplicationConnector::GetInst().GetCmdStr(
+          ComplicationConnector::EditableEditComplete), NULL);
+  } catch (Exception &ex) {
+    LOGE("%s %d", ex.what(), ex.GetErrorCode());
+    return ex.GetErrorCode();
+  }
+
+  if (emit_result)
+    return WATCHFACE_COMPLICATION_ERROR_NONE;
+  else
+    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
 
-  return WATCHFACE_COMPLICATION_ERROR_NONE;
 }
 
 int EditablesEditor::EditCancel() {
+  bool emit_result;
   int ret;
 
   if (impl_->edit_appid_.empty()) {
@@ -200,18 +245,28 @@ int EditablesEditor::EditCancel() {
   if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
     return ret;
 
-  ComplicationConnector::GetInst().EmitSignal(
-    ComplicationConnector::Editable,
-    impl_->edit_appid_.c_str(),
-    impl_->edit_appid_.c_str(),
-    -1,
-    ComplicationConnector::GetInst().GetCmdStr(
-        ComplicationConnector::EditableEditCancel), NULL);
+  try {
+    emit_result = ComplicationConnector::GetInst().EmitSignal(
+      ComplicationConnector::Editable,
+      impl_->edit_appid_.c_str(),
+      impl_->edit_appid_.c_str(),
+      -1,
+      ComplicationConnector::GetInst().GetCmdStr(
+          ComplicationConnector::EditableEditCancel), NULL);
+  } catch (Exception &ex) {
+    LOGE("%s %d", ex.what(), ex.GetErrorCode());
+    return ex.GetErrorCode();
+  }
+
+  if (emit_result)
+    return WATCHFACE_COMPLICATION_ERROR_NONE;
+  else
+    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
 
-  return WATCHFACE_COMPLICATION_ERROR_NONE;
 }
 
 int EditablesEditor::NotifyEditReady(std::string appid) {
+  bool emit_result;
   int ret;
 
   if (appid.empty())
@@ -221,16 +276,26 @@ int EditablesEditor::NotifyEditReady(std::string appid) {
   if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
     return ret;
 
-  ComplicationConnector::GetInst().EmitSignal(
-    ComplicationConnector::Editable,
-    appid,
-    appid,
-    -1,
-    ComplicationConnector::GetInst().GetCmdStr(
-        ComplicationConnector::EditableEditReady),
-    g_variant_new("(s)", ComplicationConnector::GetInst().GetAppId().c_str()));
-  impl_->edit_appid_ = appid;
-  return WATCHFACE_COMPLICATION_ERROR_NONE;
+  try {
+    emit_result = ComplicationConnector::GetInst().EmitSignal(
+      ComplicationConnector::Editable,
+      appid,
+      appid,
+      -1,
+      ComplicationConnector::GetInst().GetCmdStr(
+          ComplicationConnector::EditableEditReady),
+      g_variant_new("(s)", ComplicationConnector::GetInst().GetAppId().c_str()));
+  } catch (Exception &ex) {
+    LOGE("%s %d", ex.what(), ex.GetErrorCode());
+    return ex.GetErrorCode();
+  }
+
+  if (emit_result) {
+    impl_->edit_appid_ = appid;
+    return WATCHFACE_COMPLICATION_ERROR_NONE;
+  } else {
+    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+  }
 }
 
 }  // namespace watchface_complication
index 6212179..dcc181d 100644 (file)
@@ -44,6 +44,10 @@ class CallbackInfo {
     cb_(appid.c_str(), list_h, user_data_);
   }
 
+  watchface_editor_request_edit_cb GetCallback() {
+    return cb_;
+  }
+
  private:
   watchface_editor_request_edit_cb cb_;
   void* user_data_;
@@ -124,17 +128,26 @@ class EditablesEditorStub : public EditablesEditor {
     }
   }
 
-  void AddCallbackInfo(CallbackInfo* ci) {
+  int AddCallbackInfo(CallbackInfo* ci) {
+    for (auto& i : cb_list_) {
+      if (i.get()->GetCallback() == ci->GetCallback()) {
+        LOGI("already registered callback");
+        return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
+      }
+    }
+
     cb_list_.emplace_back(ci);
+    return WATCHFACE_COMPLICATION_ERROR_NONE;
   }
 
-  void RemoveCallbackInfo(CallbackInfo* ci) {
+  int RemoveCallbackInfo(watchface_editor_request_edit_cb ci) {
     for (auto& i : cb_list_) {
-      if (i.get() == ci) {
+      if (i.get()->GetCallback() == ci) {
         cb_list_.remove(i);
-        break;
+        return WATCHFACE_COMPLICATION_ERROR_NONE;
       }
     }
+    return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
   }
 
   void ClearEditableList() {
@@ -150,28 +163,45 @@ class EditablesEditorStub : public EditablesEditor {
 static std::unique_ptr<EditablesEditorStub> __stub = nullptr;
 extern "C" EXPORT_API int watchface_editor_add_request_edit_cb(
     watchface_editor_request_edit_cb cb, void *user_data) {
+  int ret;
   if (cb == NULL) {
     LOGE("Invalid parameter");
     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
   }
 
-  if (__stub == nullptr)
-    __stub = std::unique_ptr<EditablesEditorStub>(new EditablesEditorStub());
+  if (__stub == nullptr) {
+    try {
+      __stub = std::unique_ptr<EditablesEditorStub>(new EditablesEditorStub());
+    } catch (const std::bad_alloc &ba) {
+       LOGE("EditablesEditorStub::Exception bad_alloc");
+       return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
+    } catch (Exception &ex) {
+      LOGE("%s %d", ex.what(), ex.GetErrorCode());
+      return ex.GetErrorCode();
+    }
+  }
 
-  auto ci = new CallbackInfo(cb, user_data);
-  __stub->AddCallbackInfo(ci);
+  try {
+    auto ci = new CallbackInfo(cb, user_data);
+    ret = __stub->AddCallbackInfo(ci);
+    if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
+      delete ci;
+  } catch (const std::bad_alloc &ba) {
+    LOGE("CallbackInfo::Exception bad_alloc");
+    return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
+  }
 
-  return WATCHFACE_COMPLICATION_ERROR_NONE;
+  return ret;
 }
 
 extern "C" EXPORT_API int watchface_editor_remove_request_edit_cb(
     watchface_editor_request_edit_cb cb) {
-  if (cb == NULL) {
+  if (cb == NULL || __stub == nullptr) {
     LOGE("Invalid parameter");
     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
   }
 
-  return WATCHFACE_COMPLICATION_ERROR_NONE;
+  return __stub->RemoveCallbackInfo(cb);
 }
 
 extern "C" EXPORT_API int watchface_editor_edit_preview(
@@ -188,10 +218,34 @@ extern "C" EXPORT_API int watchface_editor_edit_preview(
 }
 
 extern "C" EXPORT_API int watchface_editor_edit_complete(void) {
+  if (__stub == nullptr) {
+    try {
+      __stub = std::unique_ptr<EditablesEditorStub>(new EditablesEditorStub());
+    } catch (const std::bad_alloc &ba) {
+      LOGE("EditablesEditorStub::Exception bad_alloc");
+      return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
+    } catch (Exception &ex) {
+      LOGE("%s %d", ex.what(), ex.GetErrorCode());
+      return ex.GetErrorCode();
+    }
+  }
+
   return __stub->EditComplete();
 }
 
 extern "C" EXPORT_API int watchface_editor_edit_cancel(void) {
+  if (__stub == nullptr) {
+    try {
+      __stub = std::unique_ptr<EditablesEditorStub>(new EditablesEditorStub());
+    } catch (const std::bad_alloc &ba) {
+      LOGE("EditablesEditorStub::Exception bad_alloc");
+      return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
+    } catch (Exception &ex) {
+      LOGE("%s %d", ex.what(), ex.GetErrorCode());
+      return ex.GetErrorCode();
+    }
+  }
+
   return __stub->EditCancel();
 }
 
@@ -202,13 +256,21 @@ extern "C" EXPORT_API int watchface_editor_notify_edit_ready(
     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
   }
 
-  if (__stub == nullptr)
-    __stub = std::unique_ptr<EditablesEditorStub>(new EditablesEditorStub());
-  else
+  if (__stub == nullptr) {
+    try {
+      __stub = std::unique_ptr<EditablesEditorStub>(new EditablesEditorStub());
+    } catch (const std::bad_alloc &ba) {
+      LOGE("EditablesEditorStub::Exception bad_alloc");
+      return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
+    } catch (Exception &ex) {
+      LOGE("%s %d", ex.what(), ex.GetErrorCode());
+      return ex.GetErrorCode();
+    }
+  } else {
     __stub->ClearEditableList();
-  __stub->NotifyEditReady(std::string(appid));
+  }
 
-  return WATCHFACE_COMPLICATION_ERROR_NONE;
+  return __stub->NotifyEditReady(std::string(appid));
 }
 
 extern "C" EXPORT_API int watchface_editor_editable_list_dup(
@@ -323,10 +385,16 @@ extern "C" EXPORT_API int watchface_editor_set_context(
   int re = WATCHFACE_COMPLICATION_ERROR_NONE;
   IEditable* ed = static_cast<IEditable*>(handle);
   if (new_context) {
-    std::unique_ptr<Bundle> b(new Bundle(new_context));
-    if (b.get() == nullptr)
+    try {
+      std::unique_ptr<Bundle> b(new Bundle(new_context));
+      re = ed->SetContext(std::move(b));
+    } catch (const std::bad_alloc &ba) {
+      LOGE("Out of memory");
       return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
-    re = ed->SetContext(std::move(b));
+    } catch (Exception &ex) {
+      LOGE("%s %d", ex.what(), ex.GetErrorCode());
+      return ex.GetErrorCode();
+    }
   } else {
     re = ed->SetContext(std::unique_ptr<Bundle>{});
   }
@@ -409,11 +477,19 @@ extern "C" EXPORT_API int watchface_editor_launch_setup_app(
   }
   app_control_destroy(service);
 
-  if (__stub == nullptr)
-    __stub = std::unique_ptr<EditablesEditorStub>(new EditablesEditorStub());
+  try {
+    if (__stub == nullptr)
+        __stub = std::unique_ptr<EditablesEditorStub>(new EditablesEditorStub());
 
-  auto ci = new SetupCallbackInfo(appid, ed->GetEditableId(), cb, user_data);
-  __stub->AddSetupCallbackInfo(ci);
+    auto ci = new SetupCallbackInfo(appid, ed->GetEditableId(), cb, user_data);
+    __stub->AddSetupCallbackInfo(ci);
+  } catch (const std::bad_alloc &ba) {
+    LOGE("Out of memory");
+    return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
+  } catch (Exception &ex) {
+    LOGE("%s %d", ex.what(), ex.GetErrorCode());
+    return ex.GetErrorCode();
+  }
 
   return WATCHFACE_COMPLICATION_ERROR_NONE;
 }