Handling OOM error 77/206477/6
authorhyunho <hhstark.kang@samsung.com>
Mon, 20 May 2019 09:47:10 +0000 (18:47 +0900)
committerHyunho Kang <hhstark.kang@samsung.com>
Wed, 22 May 2019 02:48:57 +0000 (02:48 +0000)
Change-Id: I3cc7cb7788a5a4f03e4445d9520d73e25c1fd017
Signed-off-by: hyunho <hhstark.kang@samsung.com>
13 files changed:
parser/complication_parser_plugin.cc
watchface-complication-provider/complication-provider.cc
watchface-complication-provider/watchface-complication-provider.cc
watchface-complication/complication-connector.cc
watchface-complication/complication.cc
watchface-complication/db-manager.cc
watchface-complication/design-element.cc
watchface-complication/editables-container.cc
watchface-complication/editables-manager.cc
watchface-complication/received-editable.cc
watchface-complication/watchface-editable.cc
watchface-editor/editables-editor.cc
watchface-editor/watchface-editor.cc

index 68af55e8e21bc036fd6139fa745b7810d52fef5e..3a6090ed94e2259658425a34d1ea6ab1eea39217 100644 (file)
@@ -306,6 +306,135 @@ static int _get_time_value(const char* time_type, const char* time_val,
   return WATCHFACE_COMPLICATION_ERROR_NONE;
 }
 
+static string _get_defalut_value(xmlNode* n_data, string prev_value,
+    const char* bundle_key) {
+  string default_value;
+  if (strcmp(bundle_key, TIME_KEY) == 0) {
+    char* dup_val = nullptr;
+    int ret = _get_time_value(
+        (const char*)n_data->name,
+        (const char*)n_data->children->content,
+        prev_value, &dup_val);
+    if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
+      return "";
+
+    default_value = string(dup_val);
+    free(dup_val);
+  } else {
+    default_value =
+      string(reinterpret_cast<char*>(n_data->children->content));
+  }
+  return default_value;
+}
+
+static string _make_raw_default_data(xmlNode* node, int support_type) {
+  try {
+    Bundle default_data;
+    xmlNode* n_data;
+    for (n_data = node->children; n_data; n_data = n_data->next) {
+      if (n_data->children == nullptr ||
+          n_data->children->content == nullptr)
+        continue;
+      if (!_is_valid_element(support_type, (char*)n_data->name))
+        return "";
+
+      const char* bundle_key = _get_bundle_key((const char*)n_data->name);
+      if (bundle_key == nullptr) {
+        LOGE("wrong element name (%s)", (const char*)n_data->name);
+        return "";
+      }
+
+      string prev_value = default_data.GetString(bundle_key);
+      if (!prev_value.empty())
+        default_data.Delete(bundle_key);
+
+      string val = _get_defalut_value(n_data, prev_value, bundle_key);
+      if (val.empty()) {
+        LOGE("fail to get default value");
+        return "";
+      }
+
+      int ret = default_data.Add(bundle_key, val);
+      if (ret != BUNDLE_ERROR_NONE) {
+        LOGE("bundle add error : %d", ret);
+        return "";
+      }
+    }
+
+    return string(reinterpret_cast<char*>(default_data.ToRaw().first.get()));
+  } catch (const std::exception& e) {
+    LOGE("Exception (%s)", e.what());
+    return "";
+  }
+  return "";
+}
+
+static int _insert_parsed_data(sqlite3* db, sqlite3_stmt* stmt, xmlNode* node,
+    int support_type, const char* pkgid, const char* appid,
+    const char* providerid, int period, bool trusted) {
+  int idx = 1;
+  int ret = sqlite3_bind_text(stmt, idx++, pkgid, -1, SQLITE_TRANSIENT);
+  if (ret != SQLITE_OK) {
+    LOGE("sqlite3_bind_text() error: %d(%s)", ret, sqlite3_errmsg(db));
+    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+  }
+
+  ret = sqlite3_bind_text(stmt, idx++, appid, -1, SQLITE_TRANSIENT);
+  if (ret != SQLITE_OK) {
+    LOGE("sqlite3_bind_text() error: %d(%s)", ret, sqlite3_errmsg(db));
+    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+  }
+
+  ret = sqlite3_bind_text(stmt, idx++, providerid, -1, SQLITE_TRANSIENT);
+  if (ret != SQLITE_OK) {
+    LOGE("sqlite3_bind_text() error: %d(%s)", ret, sqlite3_errmsg(db));
+    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+  }
+
+  ret = sqlite3_bind_int(stmt, idx++, trusted ? 1 : 0);
+  if (ret != SQLITE_OK) {
+    LOGE("sqlite3_bind_int() error: %d(%s)", ret, sqlite3_errmsg(db));
+    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+  }
+
+  ret = sqlite3_bind_int(stmt, idx++, period);
+  if (ret != SQLITE_OK) {
+    LOGE("sqlite3_bind_int() error: %d(%s)", ret, sqlite3_errmsg(db));
+    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+  }
+
+  ret = sqlite3_bind_int(stmt, idx++, support_type);
+  if (ret != SQLITE_OK) {
+    LOGE("sqlite3_bind_int() error: %d(%s)", ret, sqlite3_errmsg(db));
+    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+  }
+
+  string raw_default_data = _make_raw_default_data(node, support_type);
+  if (raw_default_data.empty())
+    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+
+  ret = sqlite3_bind_text(stmt, idx, raw_default_data.c_str(),
+      -1, SQLITE_TRANSIENT);
+  if (ret != SQLITE_OK) {
+    LOGE("sqlite3_bind_text() error: %d(%s)", ret, sqlite3_errmsg(db));
+    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+  }
+
+  ret = sqlite3_step(stmt);
+  if (ret != SQLITE_DONE) {
+    LOGE("step error: %d(%s)", ret, sqlite3_errmsg(db));
+    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+  }
+
+  ret = sqlite3_reset(stmt);
+  if (ret != SQLITE_OK) {
+    LOGE("sqlite3_reset() error: %d", ret);
+    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+  }
+  sqlite3_clear_bindings(stmt);
+  return WATCHFACE_COMPLICATION_ERROR_NONE;
+}
+
 static int _parse_support_type(xmlNode* node, sqlite3* db, const char* pkgid,
       const char* appid, const char* providerid, int period, bool trusted) {
   int ret;
@@ -318,133 +447,35 @@ static int _parse_support_type(xmlNode* node, sqlite3* db, const char* pkgid,
     "VALUES (?, ?, ?, ?, ?, ?, ?)";
 
   if (node->children == NULL)
-    return -1;
+    return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
 
   ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
   if (ret != SQLITE_OK) {
     LOGE("prepare error: %d(%s)", ret, sqlite3_errmsg(db));
-    goto out;
+    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
   }
 
-  xmlNode* tmp;
-  for (tmp = node->children; tmp; tmp = tmp->next) {
-    if (tmp->children == NULL
-      || tmp->children->content == NULL)
+  xmlNode* c_node;
+  for (c_node = node->children; c_node; c_node = c_node->next) {
+    if (c_node->children == NULL
+      || c_node->children->content == NULL)
       continue;
 
-    int support_type = _get_support_type_tag(tmp);
+    int support_type = _get_support_type_tag(c_node);
     if (!support_type) {
       LOGE("not supported type");
-      goto out;
-    }
-
-    xmlNode* tmpdata;
-    Bundle default_data;
-    for (tmpdata = tmp->children; tmpdata; tmpdata = tmpdata->next) {
-      if (tmpdata->children == nullptr || tmpdata->children->content == nullptr)
-        continue;
-      if (!_is_valid_element(support_type, (char*)tmpdata->name))
-        goto out;
-
-      const char* bundle_key = _get_bundle_key((const char*)tmpdata->name);
-      if (bundle_key == nullptr) {
-        LOGE("wrong element name (%s)", (const char*)tmpdata->name);
-        goto out;
-      }
-
-      string default_value;
-      if (strcmp(bundle_key, TIME_KEY) == 0) {
-        string prev_value = default_data.GetString(TIME_KEY);
-
-        char* dup_val = nullptr;
-        ret = _get_time_value(
-            (const char*)tmpdata->name,
-            (const char*)tmpdata->children->content,
-            prev_value, &dup_val);
-        if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
-          goto out;
-
-        default_value = string(dup_val);
-        free(dup_val);
-
-        if (!prev_value.empty())
-          default_data.Delete(TIME_KEY);
-      } else {
-        default_value =
-          string(reinterpret_cast<char*>(tmpdata->children->content));
-      }
-
-      ret = default_data.Add(bundle_key, default_value);
-      if (ret != BUNDLE_ERROR_NONE) {
-        LOGE("bundle add error : %d", ret);
-        goto out;
-      }
-    }
-
-    int idx = 1;
-    ret = sqlite3_bind_text(stmt, idx++, pkgid, -1, SQLITE_TRANSIENT);
-    if (ret != SQLITE_OK) {
-      LOGE("sqlite3_bind_text() error: %d(%s)", ret, sqlite3_errmsg(db));
-      goto out;
-    }
-
-    ret = sqlite3_bind_text(stmt, idx++, appid, -1, SQLITE_TRANSIENT);
-    if (ret != SQLITE_OK) {
-      LOGE("sqlite3_bind_text() error: %d(%s)", ret, sqlite3_errmsg(db));
-      goto out;
-    }
-
-    ret = sqlite3_bind_text(stmt, idx++, providerid, -1, SQLITE_TRANSIENT);
-    if (ret != SQLITE_OK) {
-      LOGE("sqlite3_bind_text() error: %d(%s)", ret, sqlite3_errmsg(db));
-      goto out;
-    }
-
-    ret = sqlite3_bind_int(stmt, idx++, trusted ? 1 : 0);
-    if (ret != SQLITE_OK) {
-      LOGE("sqlite3_bind_int() error: %d(%s)", ret, sqlite3_errmsg(db));
-      goto out;
-    }
-
-    ret = sqlite3_bind_int(stmt, idx++, period);
-    if (ret != SQLITE_OK) {
-      LOGE("sqlite3_bind_int() error: %d(%s)", ret, sqlite3_errmsg(db));
-      goto out;
-    }
-
-    ret = sqlite3_bind_int(stmt, idx++, support_type);
-    if (ret != SQLITE_OK) {
-      LOGE("sqlite3_bind_int() error: %d(%s)", ret, sqlite3_errmsg(db));
-      goto out;
-    }
-
-    ret = sqlite3_bind_text(stmt, idx,
-        reinterpret_cast<char*>(default_data.ToRaw().first.get()),
-        -1, SQLITE_TRANSIENT);
-    if (ret != SQLITE_OK) {
-      LOGE("sqlite3_bind_text() error: %d(%s)", ret, sqlite3_errmsg(db));
-      goto out;
-    }
-
-    ret = sqlite3_step(stmt);
-    if (ret != SQLITE_DONE) {
-      LOGE("step error: %d(%s)", ret, sqlite3_errmsg(db));
-      goto out;
+      sqlite3_finalize(stmt);
+      return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
     }
 
-    ret = sqlite3_reset(stmt);
-    if (ret != SQLITE_OK) {
-      LOGE("sqlite3_reset() error: %d", ret);
-      goto out;
+    ret = _insert_parsed_data(db,
+        stmt, c_node, support_type, pkgid, appid, providerid, period, trusted);
+    if (ret != WATCHFACE_COMPLICATION_ERROR_NONE) {
+      sqlite3_finalize(stmt);
+      return ret;
     }
-
-    sqlite3_clear_bindings(stmt);
   }
-
-  ret = 0;
-out:
-  if (stmt)
-    sqlite3_finalize(stmt);
+  sqlite3_finalize(stmt);
 
   return ret;
 }
index 32eb92f455e1a44cf070c91dd99247e65c735f62..748bdd4c0fcdee6468339341d3815973094b5b05 100644 (file)
@@ -277,15 +277,22 @@ void ComplicationProvider::Impl::OnSignal(GDBusConnection* connection,
       Bundle context_data(context_raw);
       Bundle shared_data;
       string received_type = std::to_string(type);
-      shared_data.Add(DATA_TYPE_KEY, received_type);
+      int ret = shared_data.Add(DATA_TYPE_KEY, received_type);
+      if (ret != BUNDLE_ERROR_NONE)
+        return;
 
       /* Call update request callback and fill shared data */
       parent_->OnDataUpdateRequest(sender_app_id, (ComplicationType)type,
                                 context_data, &shared_data);
       string shared_type = shared_data.GetString(DATA_TYPE_KEY);
       if (shared_type.empty() || shared_type != received_type) {
-        shared_data.Delete(DATA_TYPE_KEY);
-        shared_data.Add(DATA_TYPE_KEY, received_type);
+        ret = shared_data.Delete(DATA_TYPE_KEY);
+        if (ret != BUNDLE_ERROR_NONE)
+          return;
+
+        ret = shared_data.Add(DATA_TYPE_KEY, received_type);
+        if (ret != BUNDLE_ERROR_NONE)
+          return;
         LOGW("DATA_TYPE_KEY repaired : %s %s",
             shared_type.c_str(), received_type.c_str());
       }
@@ -295,7 +302,7 @@ void ComplicationProvider::Impl::OnSignal(GDBusConnection* connection,
         return;
       }
       util::ConvertPathToAppPath(util::GetAppId().c_str(), shared_data.GetHandle());
-      bool ret = gdbus_.get()->EmitSignal(
+      bool result = gdbus_.get()->EmitSignal(
             IGDBus::Complication,
             std::string(sender_app_id),
             provider_id_, -1,
@@ -305,7 +312,7 @@ void ComplicationProvider::Impl::OnSignal(GDBusConnection* connection,
                           type,
                           complication_id,
                           shared_data.ToRaw().first.get()));
-      if (ret == false)
+      if (!result)
         LOGE("EmitSignal failed %s %s %d", sender_app_id, (provider_id_).c_str(),
                             complication_id);
     } catch (const std::bad_alloc &ba) {
index 8564c1b1254707114bb7c97f5a1e0c03c13afb00..65d3de91f88bf6423fd8e42a7267278a16d55bf2 100644 (file)
@@ -361,13 +361,18 @@ static int _add_bundle_data(bundle* shared_data, const char* key,
 
 static int _get_data_type(bundle* shared_data,
     watchface_complication_type_e* type) {
-  Bundle b(shared_data);
-  int data_type = util::GetDataType(b);
-  if (!util::CheckComplicationType(data_type)) {
-    LOGE("Invalid param");
-    return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
+  try {
+    Bundle b(shared_data);
+    int data_type = util::GetDataType(b);
+    if (!util::CheckComplicationType(data_type)) {
+      LOGE("Invalid param");
+      return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
+    }
+    *type = static_cast<watchface_complication_type_e>(data_type);
+  } catch (const std::exception &e) {
+    LOGE("Exception (%s)", e.what());
+    return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
   }
-  *type = static_cast<watchface_complication_type_e>(data_type);
 
   return WATCHFACE_COMPLICATION_ERROR_NONE;
 }
@@ -620,11 +625,16 @@ extern "C" EXPORT_API int watchface_complication_provider_data_is_valid(
     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
   }
 
-  Bundle b(shared_data, false, false);
-  int result = util::GetDataType(b);
-  if (!util::CheckComplicationType(result))
-    return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
-  *is_valid = util::IsValidData(b);
+  try {
+    Bundle b(shared_data, false, false);
+    int result = util::GetDataType(b);
+    if (!util::CheckComplicationType(result))
+      return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
+    *is_valid = util::IsValidData(b);
+  } catch (const std::exception &e) {
+    LOGE("Exception (%s)", e.what());
+    return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
+  }
 
   return WATCHFACE_COMPLICATION_ERROR_NONE;
 }
index 0436f9086919fb0c00d2eee4e3179e3e93828f13..f34c4dade8c3e93748adeb314096926efddb458a 100644 (file)
 #include "watchface-complication/package-manager.h"
 #include "watchface-complication/gdbus.h"
 
-#include <iostream>
-#ifdef LOGE
-#undef LOGE
-#endif
-#define LOGE printf
-
 #ifdef LOG_TAG
 #undef LOG_TAG
 #endif
index c2b7547501c9d77e81ca83bdb217e9d7d63b386c..4687b6d640a00614c70a2fc78c9bcc32cd687649 100644 (file)
@@ -57,9 +57,8 @@ Complication::~Complication() = default;
 int Complication::Impl::LoadCurProviderFromPrev() {
   string prev_provider_type;
   string prev_provider_id;
-  unique_ptr<Bundle> setting_data;
-
-  setting_data = editables_manager_.LoadSetting(complication_id_);
+  unique_ptr<Bundle> setting_data =
+      editables_manager_.LoadSetting(complication_id_);
   if (setting_data == nullptr) {
     LOGW("no prev setting info");
     return WATCHFACE_COMPLICATION_ERROR_PROVIDER_NOT_AVAILABLE;
@@ -265,14 +264,24 @@ int Complication::Impl::StoreSetting(int comp_id, std::string& provider_id,
     ComplicationType type) {
   if (provider_id.empty() && type != NoData)
     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
+  try {
+    Bundle setting_data;
+    int ret = setting_data.Add(provider_id_key_, provider_id);
+    if (ret != BUNDLE_ERROR_NONE)
+      return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
 
-  Bundle setting_data;
-  setting_data.Add(provider_id_key_, provider_id);
-  setting_data.Add(provider_type_key_, to_string(type));
-  int ret = editables_manager_.StoreSetting(comp_id,
-      setting_data.ToRaw().first.get());
-  if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
-    return ret;
+    ret = setting_data.Add(provider_type_key_, to_string(type));
+    if (ret != BUNDLE_ERROR_NONE)
+      return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+
+    ret = editables_manager_.StoreSetting(
+        comp_id, setting_data.ToRaw().first.get());
+    if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
+      return ret;
+  } catch(const std::bad_alloc &ba) {
+    LOGE("Exception bad_alloc");
+    return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
+  }
   return WATCHFACE_COMPLICATION_ERROR_NONE;
 }
 
@@ -674,9 +683,15 @@ int Complication::SendDataUpdateRequest(bool launch_option) {
       return ret;
   }
 
-  if (impl_->context_data_ != nullptr)
-    context_data_raw =
-        reinterpret_cast<const char*>(impl_->context_data_->ToRaw().first.get());
+  if (impl_->context_data_ != nullptr) {
+    try {
+      context_data_raw = reinterpret_cast<const char*>(
+          impl_->context_data_->ToRaw().first.get());
+    } catch (const std::bad_alloc &ba) {
+      LOGE("Exception bad_alloc");
+      return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
+    }
+  }
 
   emit_ret = impl_->gdbus_.get()->EmitSignal(
     IGDBus::SigType::Complication,
@@ -689,8 +704,8 @@ int Complication::SendDataUpdateRequest(bool launch_option) {
                   impl_->complication_id_,
                   impl_->cur_type_,
                   context_data_raw));
-  if (emit_ret == false)
-    ret = WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+  if (!emit_ret)
+    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
 
   LOGI("emit signal done");
   return ret;
@@ -766,22 +781,39 @@ int Complication::TouchLaunch(watchface_complication_event_type_e event_type) {
     return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
   }
 
-  Bundle launch_data;
-  launch_data.Add(TOUCH_LAUNCH_EVENT_KEY, to_string(event_type));
-  launch_data.Add(TOUCH_LAUNCH_PROVIDER_ID_KEY, impl_->cur_provider_id_);
-  launch_data.Add(TOUCH_LAUNCH_TYPE_KEY, to_string(impl_->cur_type_));
-  if (impl_->context_data_ != nullptr) {
-    launch_data.Add(TOUCH_LAUNCH_CONTEXT_KEY,
-        reinterpret_cast<char*>(impl_->context_data_->ToRaw().first.get()));
-  }
-  int ret = aul_complication_launch_with_extra_data(
-          util::GetAppId().c_str(),
-          provider_appid.c_str(), getuid(), TOUCH_LAUNCH_DATA_KEY,
-          reinterpret_cast<char*>(launch_data.ToRaw().first.get()));
+  try {
+    Bundle launch_data;
+    int ret = launch_data.Add(TOUCH_LAUNCH_EVENT_KEY, to_string(event_type));
+    if (ret != BUNDLE_ERROR_NONE)
+      return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
 
-  LOGI("Touch launch the %s : %d", provider_appid.c_str(), ret);
+    ret = launch_data.Add(TOUCH_LAUNCH_PROVIDER_ID_KEY, impl_->cur_provider_id_);
+    if (ret != BUNDLE_ERROR_NONE)
+      return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+
+    ret = launch_data.Add(TOUCH_LAUNCH_TYPE_KEY, to_string(impl_->cur_type_));
+    if (ret != BUNDLE_ERROR_NONE)
+      return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+
+    if (impl_->context_data_ != nullptr) {
+      ret = launch_data.Add(TOUCH_LAUNCH_CONTEXT_KEY,
+          reinterpret_cast<char*>(impl_->context_data_->ToRaw().first.get()));
+      if (ret != BUNDLE_ERROR_NONE)
+        return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+    }
+
+    ret = aul_complication_launch_with_extra_data(
+            util::GetAppId().c_str(),
+            provider_appid.c_str(), getuid(), TOUCH_LAUNCH_DATA_KEY,
+            reinterpret_cast<char*>(launch_data.ToRaw().first.get()));
 
-  return util::ConvertAulError(ret);
+    LOGI("Touch launch the %s : %d", provider_appid.c_str(), ret);
+    return util::ConvertAulError(ret);
+
+  } catch (const std::bad_alloc &ba) {
+    LOGE("Exception bad_alloc");
+    return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
+  }
 }
 
 bool Complication::Impl::CheckCachedPrivilege(std::string privilege) {
@@ -837,17 +869,28 @@ int Complication::Impl::AddCandidate(std::string provider_id, int type) {
     LOGE("Out of memory");
     return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
   }
-  data->Add(provider_id_key_, provider_id);
-  data->Add(provider_type_key_, std::to_string(type));
+
+  int ret = data->Add(provider_id_key_, provider_id);
+  if (ret != BUNDLE_ERROR_NONE)
+    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+
+  ret = data->Add(provider_type_key_, std::to_string(type));
+  if (ret != BUNDLE_ERROR_NONE)
+    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
 
   std::string error_msg = GetNotSupportedPrivileges(provider_id);
-  if (!error_msg.empty())
-    data->Add(privilege_error_key_, error_msg);
+  if (!error_msg.empty()) {
+    ret = data->Add(privilege_error_key_, error_msg);
+    if (ret != BUNDLE_ERROR_NONE)
+      return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+  }
 
   int not_supported_events = GetNotSupportedEvents(provider_id);
   if (not_supported_events > 0) {
-      data->Add(supported_events_error_key_,
+    ret = data->Add(supported_events_error_key_,
           std::to_string(not_supported_events));
+    if (ret != BUNDLE_ERROR_NONE)
+      return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
   } else if (not_supported_events < 0) {
     LOGE("fail to get required events");
     return WATCHFACE_COMPLICATION_ERROR_DB;
index b70a0b82a0a9dd76add7fb40fb03f94a6f0735e7..b650765444777c1740df48a2e3abd571974095df 100644 (file)
@@ -125,7 +125,13 @@ std::unique_ptr<Bundle> DBManager::GetDefaultData(const char* provider_id,
       LOGE("raw_data is nullptr");
       goto out;
     }
-    default_data = std::unique_ptr<Bundle>(new Bundle(std::string(raw_data)));
+
+    default_data = std::unique_ptr<Bundle>(
+        new (std::nothrow) Bundle(std::string(raw_data)));
+    if (default_data.get() == nullptr) {
+      LOGE("fail to create default data");
+      goto out;
+    }
     util::ConvertPathToAppPath(
         provider_app_id.c_str(), default_data.get()->GetHandle());
   }
index 8e3715c4efcef7a037e457a72040f71d71e10660..6b95681fc288d7c70db5740ee9f8add33571671e 100644 (file)
@@ -111,10 +111,15 @@ int DesignElement::UpdateLastData() {
   if (cur_data.get() == nullptr)
     return WATCHFACE_COMPLICATION_ERROR_NO_DATA;
 
-  int ret = impl_->editables_manager_.StoreSetting(
-      impl_->id_, cur_data->ToRaw().first.get());
-  if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
-    return ret;
+  try {
+    int ret = impl_->editables_manager_.StoreSetting(
+        impl_->id_, cur_data->ToRaw().first.get());
+    if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
+      return ret;
+  } catch (const std::bad_alloc &ba) {
+    LOGE("Exception bad_alloc");
+    return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
+  }
 
   impl_->last_data_idx_ = impl_->cur_data_idx_;
   return WATCHFACE_COMPLICATION_ERROR_NONE;
index 07461bb2dace6c91e6d876be93fb7598a534d821..02699e0b142a733cebdea969df27b53d647e3793 100644 (file)
@@ -97,7 +97,6 @@ void EditablesContainer::Impl::OnSignal(GDBusConnection* connection,
     int editable_id;
     int selected_idx;
     char* context = NULL;
-    std::string ctx_str;
 
     if (sender_name_.compare(sender_name) != 0) {
       LOGE("invalid sender_name %s", sender_name.c_str());
@@ -108,14 +107,22 @@ void EditablesContainer::Impl::OnSignal(GDBusConnection* connection,
     LOGI("preview selected_idx, editable_id, state: %d, %d", selected_idx,
         editable_id);
 
-    if (context != NULL)
-      ctx_str = std::string(context);
+    unique_ptr<Bundle> ctx_ptr;
+    if (context != NULL) {
+      std::string ctx_str = std::string(context);
+      ctx_ptr = std::unique_ptr<Bundle>(new (std::nothrow) Bundle(ctx_str));
+      if (ctx_ptr.get() == nullptr) {
+        LOGE("Out of memory");
+        return;
+      }
+    }
     for (auto& i : ed_list_) {
       if (i.get()->GetEditableId() == editable_id) {
         i.get()->SetState(IEditable::OnGoing);
         i.get()->SetCurDataIdx(selected_idx);
-        if (!ctx_str.empty())
-          i.get()->SetContext(std::unique_ptr<Bundle>(new Bundle(ctx_str)));
+        if (ctx_ptr != nullptr)
+          i.get()->SetContext(move(ctx_ptr));
+
         i.get()->OnEditableUpdated(i.get()->GetCurDataIdx(), IEditable::OnGoing);
         parent_->OnUpdate(*i.get(), i.get()->GetCurDataIdx(), IEditable::OnGoing);
       }
@@ -171,69 +178,103 @@ void EditablesContainer::Impl::OnAppear(const std::string& name,
 
 int EditablesContainer::RequestEdit() {
   if (impl_->editor_id_.empty())
-    return -1;
+    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
 
-  vector<string> encoded_list;
-  for (auto& i : impl_->ed_list_) {
-    i.get()->SetState(IEditable::OnGoing);
-    Bundle b;
-    b.Add("SETUP_APPID", i.get()->GetSetupAppId());
-    b.Add("EDITABLE_ID",
-                        std::to_string(i.get()->GetEditableId()));
-
-    int cur_data_idx = i.get()->GetCurDataIdx();
-    b.Add("CUR_DATA_IDX", std::to_string(cur_data_idx));
-
-    vector<string> candidate_list;
-    for (auto& data : i.get()->GetCandidates()) {
-      candidate_list.push_back(
-          reinterpret_cast<char*>(data->ToRaw().first.get()));
-    }
-    b.Add("CANDIDATES_LIST", candidate_list);
-    b.Add("CANDIDATES_LIST_SIZE",
-               std::to_string(i.get()->GetCandidates().size()));
-
-    IEditable::Highlight* hi = i->GetHighlight();
-    if (hi) {
-      if (hi->GetGeometry()) {
-        b.Add("GEO_X", std::to_string(hi->GetGeometry()->GetX()));
-        b.Add("GEO_Y", std::to_string(hi->GetGeometry()->GetY()));
-        b.Add("GEO_W", std::to_string(hi->GetGeometry()->GetW()));
-        b.Add("GEO_H", std::to_string(hi->GetGeometry()->GetH()));
-        LOGI("hi %d %d %d %d", hi->GetGeometry()->GetX(), hi->GetGeometry()->GetY(),
-            hi->GetGeometry()->GetW(), hi->GetGeometry()->GetH());
+  try {
+    int ret;
+    vector<string> encoded_list;
+    for (auto& i : impl_->ed_list_) {
+      i.get()->SetState(IEditable::OnGoing);
+      Bundle b;
+      ret = b.Add("SETUP_APPID", i.get()->GetSetupAppId());
+      if (ret != BUNDLE_ERROR_NONE)
+        return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+      ret = b.Add("EDITABLE_ID", std::to_string(i.get()->GetEditableId()));
+      if (ret != BUNDLE_ERROR_NONE)
+        return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+
+      int cur_data_idx = i.get()->GetCurDataIdx();
+      ret = b.Add("CUR_DATA_IDX", std::to_string(cur_data_idx));
+      if (ret != BUNDLE_ERROR_NONE)
+        return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+
+      vector<string> candidate_list;
+      for (auto& data : i.get()->GetCandidates()) {
+        candidate_list.push_back(
+            reinterpret_cast<char*>(data->ToRaw().first.get()));
+      }
+      ret = b.Add("CANDIDATES_LIST", candidate_list);
+      if (ret != BUNDLE_ERROR_NONE)
+        return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+
+      ret = b.Add("CANDIDATES_LIST_SIZE",
+                std::to_string(i.get()->GetCandidates().size()));
+      if (ret != BUNDLE_ERROR_NONE)
+        return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+
+      IEditable::Highlight* hi = i->GetHighlight();
+      if (hi) {
+        if (hi->GetGeometry()) {
+          ret = b.Add("GEO_X", std::to_string(hi->GetGeometry()->GetX()));
+          if (ret != BUNDLE_ERROR_NONE)
+            return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+
+          ret = b.Add("GEO_Y", std::to_string(hi->GetGeometry()->GetY()));
+          if (ret != BUNDLE_ERROR_NONE)
+            return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+
+          ret = b.Add("GEO_W", std::to_string(hi->GetGeometry()->GetW()));
+          if (ret != BUNDLE_ERROR_NONE)
+            return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+
+          ret = b.Add("GEO_H", std::to_string(hi->GetGeometry()->GetH()));
+          if (ret != BUNDLE_ERROR_NONE)
+            return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+
+          LOGI("hi %d %d %d %d", hi->GetGeometry()->GetX(), hi->GetGeometry()->GetY(),
+              hi->GetGeometry()->GetW(), hi->GetGeometry()->GetH());
+        }
+
+        IEditable::EditableShapeType type = hi->GetShapeType();
+        ret = b.Add("SHAPE_TYPE", std::to_string(type));
+        if (ret != BUNDLE_ERROR_NONE)
+          return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+      } else {
+        LOGW("Null highlight info !!");
       }
 
-      IEditable::EditableShapeType type = hi->GetShapeType();
-      b.Add("SHAPE_TYPE", std::to_string(type));
-    } else {
-      LOGW("Null highlight info !!");
+      if (!i.get()->GetLabel().empty()) {
+        ret = b.Add("NAME", i.get()->GetLabel());
+        if (ret != BUNDLE_ERROR_NONE)
+          return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+      }
+      encoded_list.push_back(reinterpret_cast<char*>(b.ToRaw().first.get()));
     }
 
-    if (!i.get()->GetLabel().empty())
-      b.Add("NAME", i.get()->GetLabel());
-
-    encoded_list.push_back(reinterpret_cast<char*>(b.ToRaw().first.get()));
+    Bundle container;
+    ret = container.Add("EDITABLE_LIST", encoded_list);
+    if (ret != BUNDLE_ERROR_NONE)
+      return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+
+    bool emit_ret = impl_->gdbus_.get()->EmitSignal(
+      IGDBus::SigType::Editable,
+      impl_->editor_id_,
+      impl_->editor_id_,
+      -1,
+      util::GetCmdStr(util::EditableEditRequest),
+      g_variant_new("(ss)",
+          util::GetAppId().c_str(), container.ToRaw().first.get()));
+
+    if (!emit_ret)
+      return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+
+    impl_->watcher_id_ = impl_->gdbus_.get()->Watch(impl_->editor_id_,
+        this->impl_.get());
+  } catch (const std::bad_alloc &ba) {
+    LOGE("Exception bad_alloc");
+    return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
   }
 
-  Bundle container;
-  container.Add("EDITABLE_LIST", encoded_list);
-  bool emit_ret = impl_->gdbus_.get()->EmitSignal(
-    IGDBus::SigType::Editable,
-    impl_->editor_id_,
-    impl_->editor_id_,
-    -1,
-    util::GetCmdStr(util::EditableEditRequest),
-    g_variant_new("(ss)",
-                  util::GetAppId().c_str(),
-                  container.ToRaw().first.get()));
-
-  if (emit_ret == false)
-    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
-
-  impl_->watcher_id_ = impl_->gdbus_.get()->Watch(impl_->editor_id_,
-      this->impl_.get());
-
   return WATCHFACE_COMPLICATION_ERROR_NONE;
 }
 
index f8acdff2063b68b9db3b62a8ccd11121f28a779d..b18dae79cbbadfe28aca4ccd632911c7831f0928 100644 (file)
@@ -167,22 +167,28 @@ std::unique_ptr<Bundle> EditablesManager::LoadSetting(int editable_id) {
 int EditablesManager::StoreContext(int editable_id, const char* provider_id,
     Bundle* context) {
   char query[QUERY_MAXLEN] = {0, };
-  char* error = NULL;
+  char* error = nullptr;
 
-  if (impl_->setting_db_ == NULL) {
+  if (impl_->setting_db_ == nullptr) {
     LOGE("DB is not initialized.");
     return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
   }
 
-  sqlite3_snprintf(QUERY_MAXLEN, query,
-      "INSERT OR REPLACE INTO editable_context(editable_id, provider_id, " \
-      "context_data) VALUES (%d, %Q, %Q)",
-      editable_id, provider_id, context->ToRaw().first.get());
-  if (sqlite3_exec(impl_->context_db_, query, NULL, NULL, &error) != SQLITE_OK) {
-    LOGE("sqlite3_exec error(editable_id : %d, provider_id : %s, error = %s)",
-        editable_id, provider_id, error);
-    sqlite3_free(error);
-    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+  try {
+    sqlite3_snprintf(QUERY_MAXLEN, query,
+        "INSERT OR REPLACE INTO editable_context(editable_id, provider_id, " \
+        "context_data) VALUES (%d, %Q, %Q)",
+        editable_id, provider_id, context->ToRaw().first.get());
+    if (sqlite3_exec(
+          impl_->context_db_, query, nullptr, nullptr, &error) != SQLITE_OK) {
+      LOGE("sqlite3_exec error(editable_id : %d, provider_id : %s, error = %s)",
+          editable_id, provider_id, error);
+      sqlite3_free(error);
+      return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+    }
+  } catch (const std::bad_alloc &ba) {
+    LOGE("Exception bad_alloc");
+    return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
   }
   return WATCHFACE_COMPLICATION_ERROR_NONE;
 }
@@ -211,7 +217,12 @@ std::unique_ptr<Bundle> EditablesManager::LoadContext(int editable_id,
 
   if (sqlite3_step(stmt) == SQLITE_ROW) {
     raw_data = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0));
-    context_data = std::unique_ptr<Bundle>(new Bundle(std::string(raw_data)));
+    context_data = std::unique_ptr<Bundle>(
+        new (std::nothrow) Bundle(std::string(raw_data)));
+    if (context_data.get() == nullptr) {
+      LOGE("Out of memory");
+      return nullptr;
+    }
   }
   sqlite3_finalize(stmt);
 
index 7c45fa5e2c95010e6fc5c2aa99342d4dca35dc3f..fb6da37f7ed387d35e5144449d1f2ed62955a214 100644 (file)
@@ -222,7 +222,8 @@ int ReceivedEditable::UpdateLastContext() {
     return WATCHFACE_COMPLICATION_ERROR_NONE;
   }
 
-  Bundle* ctx = new Bundle((impl_->context_data_.get())->GetHandle());
+  Bundle* ctx = new (std::nothrow) Bundle(
+      (impl_->context_data_.get())->GetHandle());
   if (ctx == nullptr) {
     LOGE("Out of memory");
     return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
index 1d245d3e75ef46a407b184b97cda2bb277fd2342..c10d185d2a591f1bd35bcd6aba9b384441146e16 100644 (file)
@@ -204,7 +204,7 @@ extern "C" EXPORT_API int watchface_editable_add_design_element(
     if (data == nullptr)
       continue;
 
-    Bundle* new_data = new Bundle(data);
+    Bundle* new_data = new (std::nothrow) Bundle(data);
     if (new_data == nullptr) {
       LOGE("Out of memory");
       return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
index 6fc3bceb8242fd103240d8d9dee0315003379cd0..2752e27f8b7e229445a1fdae8adad78160603b44 100644 (file)
@@ -78,42 +78,43 @@ void EditablesEditor::Impl::OnSignal(GDBusConnection* connection,
     return;
 
   LOGI("signal_name: %s", signal_name.c_str());
-  if (signal_name.compare(
-      util::GetCmdStr(util::CmdType::EditableEditRequest)) == 0) {
-    g_variant_get(parameters, "(&s&s)", &appid, &raw);
-    LOGI("appid: %s", appid);
-
-    if (edit_appid_.compare(sender_appid) != 0 ||
-         edit_appid_.compare(appid) != 0) {
-      LOGE("edit_appid %s, sender_appid: %s, appid : %s ", edit_appid_.c_str(),
-                               sender_appid.c_str(), appid);
-      return;
-    }
-
-    Bundle data(reinterpret_cast<char*>(raw));
-    vector<string> raw_arr = data.GetStringArray("EDITABLE_LIST");
-    for (auto& i : raw_arr) {
-      std::unique_ptr<IEditable> received = std::unique_ptr<IEditable>(
-          new ReceivedEditable(i));
-      if (received.get() == nullptr) {
-        LOGE("Out of memory");
+  try {
+    if (signal_name.compare(
+        util::GetCmdStr(util::CmdType::EditableEditRequest)) == 0) {
+      g_variant_get(parameters, "(&s&s)", &appid, &raw);
+      LOGI("appid: %s", appid);
+
+      if (edit_appid_.compare(sender_appid) != 0 ||
+          edit_appid_.compare(appid) != 0) {
+        LOGE("edit_appid %s, sender_appid: %s, appid : %s ", edit_appid_.c_str(),
+                                sender_appid.c_str(), appid);
         return;
       }
-      e_list.emplace_back(move(received));
-    }
-    parent_->OnRequestEdit(std::string(appid), std::move(e_list));
-  } else if (signal_name.compare(
-      util::GetCmdStr(util::CmdType::SetupReply)) == 0) {
-    int edit_id;
-    char* raw_str;
-    g_variant_get(parameters, "(i&s)", &edit_id, &raw_str);
-    unique_ptr<Bundle> reply_data =
-        unique_ptr<Bundle>(new (std::nothrow) Bundle(std::string(raw_str)));
-    if (reply_data.get() == nullptr) {
-      LOGE("Out of memory");
-      return;
+
+      Bundle data(reinterpret_cast<char*>(raw));
+      vector<string> raw_arr = data.GetStringArray("EDITABLE_LIST");
+      for (auto& i : raw_arr) {
+        std::unique_ptr<IEditable> received = std::unique_ptr<IEditable>(
+            new ReceivedEditable(i));
+        if (received.get() == nullptr) {
+          LOGE("Out of memory");
+          return;
+        }
+        e_list.emplace_back(move(received));
+      }
+      parent_->OnRequestEdit(std::string(appid), std::move(e_list));
+    } else if (signal_name.compare(
+        util::GetCmdStr(util::CmdType::SetupReply)) == 0) {
+      int edit_id;
+      char* raw_str;
+      g_variant_get(parameters, "(i&s)", &edit_id, &raw_str);
+      unique_ptr<Bundle> reply_data =
+          unique_ptr<Bundle>(new Bundle(std::string(raw_str)));
+      parent_->OnSetupReply(sender_appid, edit_id, move(reply_data));
     }
-    parent_->OnSetupReply(sender_appid, edit_id, move(reply_data));
+  } catch (const std::bad_alloc &e) {
+    LOGE("Exception (%s)", e.what());
+    return;
   }
 }
 
@@ -145,17 +146,23 @@ int EditablesEditor::EditPreview(IEditable& ed, int cur_data_idx) {
     return ret;
 
   Bundle* context = re.GetContext().get();
+  string ctx_str = "";
+  if (context != nullptr) {
+    try {
+      ctx_str = string(reinterpret_cast<char*>(context->ToRaw().first.get()));
+    } catch (const std::bad_alloc &ba) {
+      LOGE("Exception bad_alloc");
+      return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
+    }
+  }
+
   emit_result = impl_->gdbus_.get()->EmitSignal(
     IGDBus::Editable,
     impl_->edit_appid_.c_str(),
     impl_->edit_appid_.c_str(),
     -1,
     util::GetCmdStr(util::CmdType::EditableEditPreview),
-    g_variant_new("(iis)", cur_data_idx, ed.GetEditableId(),
-        (context == nullptr) ? "" :
-            reinterpret_cast<char*>(context->ToRaw().first.get()
-        )
-    )
+    g_variant_new("(iis)", cur_data_idx, ed.GetEditableId(), ctx_str.c_str())
   );
 
   if (emit_result)
index cfb7b7d50e3115d737ee582e829777005eeccf82..558bae1fd9bfd5a67a1ec8002bdfbe89cbb2d15e 100644 (file)
@@ -494,57 +494,60 @@ extern "C" EXPORT_API int watchface_editor_launch_setup_app(
 
   IEditable* ed = static_cast<IEditable*>(handle);
   std::string appid = ed->GetSetupAppId();
-  app_control_h service = NULL;
   Bundle* context_data;
   char ed_id[256] = {0, };
+  app_control_h service = nullptr;
   if (APP_CONTROL_ERROR_NONE != app_control_create(&service)) {
     LOGE("Fail to create app control");
     return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
   }
 
+  auto ptr = unique_ptr<app_control_s,
+    decltype(app_control_destroy)*>(service, app_control_destroy);
+
   LOGI("LAUNCH !!! %s", appid.c_str());
-  int ret = app_control_set_app_id(service, appid.c_str());
+  int ret = app_control_set_app_id(ptr.get(), appid.c_str());
   if (ret != APP_CONTROL_ERROR_NONE) {
     LOGE("Fail to set appid");
-    app_control_destroy(service);
     return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
   }
 
-  ret = _add_extra_data(service, SETUP_EDITOR_APPID_KEY,
+  ret = _add_extra_data(ptr.get(), SETUP_EDITOR_APPID_KEY,
       util::GetAppId().c_str());
   if (ret != WATCHFACE_COMPLICATION_ERROR_NONE) {
     LOGE("Fail to add setup appid ");
-    app_control_destroy(service);
     return ret;
   }
 
   snprintf(ed_id, sizeof(ed_id), "%d", ed->GetEditableId());
   LOGI("add ed_id %s", ed_id);
-  ret = _add_extra_data(service, SETUP_EDITABLE_ID_KEY, ed_id);
+  ret = _add_extra_data(ptr.get(), SETUP_EDITABLE_ID_KEY, ed_id);
   if (ret != WATCHFACE_COMPLICATION_ERROR_NONE) {
     LOGE("Fail to add ed_id %s", ed_id);
-    app_control_destroy(service);
     return ret;
   }
 
   context_data = (ed->GetContext()).get();
   if (context_data != nullptr) {
-    ret = _add_extra_data(service, SETUP_CONTEXT_DATA_KEY,
-        reinterpret_cast<char*>(context_data->ToRaw().first.get()));
+    try {
+      ret = _add_extra_data(ptr.get(), SETUP_CONTEXT_DATA_KEY,
+          reinterpret_cast<char*>(context_data->ToRaw().first.get()));
+    } catch (const std::bad_alloc &ba) {
+      LOGE("Exception bad_alloc");
+      return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
+    }
+
     if (ret != WATCHFACE_COMPLICATION_ERROR_NONE) {
       LOGE("Fail to add setup_context_data %d", ret);
-      app_control_destroy(service);
       return ret;
     }
   }
 
-  ret = app_control_send_launch_request(service, NULL, NULL);
+  ret = app_control_send_launch_request(ptr.get(), nullptr, nullptr);
   if (ret != APP_CONTROL_ERROR_NONE) {
     LOGE("Failed to launch:%d", ret);
-    app_control_destroy(service);
     return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
   }
-  app_control_destroy(service);
 
   unique_ptr<SetupCallbackInfo> ci = unique_ptr<SetupCallbackInfo>(
       new (std::nothrow) SetupCallbackInfo(