Improve testability 99/188799/17
authorhyunho <hhstark.kang@samsung.com>
Thu, 20 Sep 2018 05:20:40 +0000 (14:20 +0900)
committerhyunho <hhstark.kang@samsung.com>
Fri, 21 Sep 2018 07:02:59 +0000 (16:02 +0900)
Change-Id: Iff7025a3248310118d61bc4db608388ed2184c00
Signed-off-by: hyunho <hhstark.kang@samsung.com>
57 files changed:
packaging/libwatchface-complication.spec
unittest/res/org.tizen.gmock_comp_provider-1.0.0-arm.tpk [moved from unittest/res/org.tizen.watchface_sample_provider-1.0.0-arm.tpk with 57% similarity]
unittest/res/org.tizen.gmock_comp_provider-1.0.0-x86.tpk [moved from unittest/res/org.tizen.watchface_sample_provider-1.0.0-x86.tpk with 57% similarity]
unittest/res/org.tizen.gmock_comp_provider2-1.0.0-arm.tpk [new file with mode: 0644]
unittest/res/org.tizen.gmock_comp_provider2-1.0.0-x86.tpk [new file with mode: 0644]
unittest/src/test-complication-bundle.cc [moved from unittest/src/test_tools.cc with 65% similarity]
unittest/src/test-complication-provider.cc [moved from unittest/src/test_complication_provider.cc with 65% similarity]
unittest/src/test-complication.cc [new file with mode: 0644]
unittest/src/test-db-manager.cc [new file with mode: 0644]
unittest/src/test-design-element.cc [moved from unittest/src/test_design_element.cc with 75% similarity]
unittest/src/test-editables-container.cc [moved from unittest/src/test_editables_container.cc with 74% similarity]
unittest/src/test-editables-manager.cc [new file with mode: 0644]
unittest/src/test-editor.cc [moved from unittest/src/test_editor.cc with 76% similarity]
unittest/src/test-main.cc [moved from unittest/src/test_main.cc with 95% similarity]
unittest/src/test-received-editable.cc [moved from unittest/src/test_received_editable.cc with 73% similarity]
unittest/src/test_complication.cc [deleted file]
watchface-common/watchface-exception.h
watchface-common/watchface-util.cc
watchface-common/watchface-util.h
watchface-complication-provider/complication-provider-implementation.h
watchface-complication-provider/complication-provider.cc
watchface-complication-provider/complication-provider.h
watchface-complication-provider/watchface-complication-provider.cc
watchface-complication/complication-connector-implementation.h
watchface-complication/complication-connector.cc
watchface-complication/complication-connector.h
watchface-complication/complication-implementation.h
watchface-complication/complication.cc
watchface-complication/complication.h
watchface-complication/db-manager.cc
watchface-complication/db-manager.h
watchface-complication/design-element-implementation.h
watchface-complication/design-element.cc
watchface-complication/design-element.h
watchface-complication/editable-interface.h
watchface-complication/editables-container-implementation.h
watchface-complication/editables-container.cc
watchface-complication/editables-container.h
watchface-complication/editables-manager-implementation.h
watchface-complication/editables-manager.cc
watchface-complication/editables-manager.h
watchface-complication/gdbus-interface.h [new file with mode: 0644]
watchface-complication/gdbus-mock.h [new file with mode: 0644]
watchface-complication/gdbus.h [new file with mode: 0644]
watchface-complication/package-manager-interface.h [new file with mode: 0644]
watchface-complication/package-manager-mock.h [new file with mode: 0644]
watchface-complication/package-manager.h [new file with mode: 0644]
watchface-complication/received-editable.cc
watchface-complication/received-editable.h
watchface-complication/watchface-complication-internal.cc [deleted file]
watchface-complication/watchface-complication.cc
watchface-complication/watchface-editable.cc
watchface-editor/editables-editor-event-interface.h
watchface-editor/editables-editor-implementation.h
watchface-editor/editables-editor.cc
watchface-editor/editables-editor.h
watchface-editor/watchface-editor.cc

index a2847cb..e991f2d 100644 (file)
@@ -194,7 +194,7 @@ Group: Development/Libraries
 Requires: libwatchface-common
 
 %description -n libwatchface-common-devel
-Header & package configuration files to support development of the watchface editor.
+Header & package configuration files to support development of the watchface library.
 
 %post -n libwatchface-common -p /sbin/ldconfig
 %postun -n libwatchface-common -p /sbin/ldconfig
similarity index 57%
rename from unittest/res/org.tizen.watchface_sample_provider-1.0.0-arm.tpk
rename to unittest/res/org.tizen.gmock_comp_provider-1.0.0-arm.tpk
index 9e43061..2fea692 100644 (file)
Binary files a/unittest/res/org.tizen.watchface_sample_provider-1.0.0-arm.tpk and b/unittest/res/org.tizen.gmock_comp_provider-1.0.0-arm.tpk differ
similarity index 57%
rename from unittest/res/org.tizen.watchface_sample_provider-1.0.0-x86.tpk
rename to unittest/res/org.tizen.gmock_comp_provider-1.0.0-x86.tpk
index 3433194..de02aee 100644 (file)
Binary files a/unittest/res/org.tizen.watchface_sample_provider-1.0.0-x86.tpk and b/unittest/res/org.tizen.gmock_comp_provider-1.0.0-x86.tpk differ
diff --git a/unittest/res/org.tizen.gmock_comp_provider2-1.0.0-arm.tpk b/unittest/res/org.tizen.gmock_comp_provider2-1.0.0-arm.tpk
new file mode 100644 (file)
index 0000000..bf14670
Binary files /dev/null and b/unittest/res/org.tizen.gmock_comp_provider2-1.0.0-arm.tpk differ
diff --git a/unittest/res/org.tizen.gmock_comp_provider2-1.0.0-x86.tpk b/unittest/res/org.tizen.gmock_comp_provider2-1.0.0-x86.tpk
new file mode 100644 (file)
index 0000000..0360c54
Binary files /dev/null and b/unittest/res/org.tizen.gmock_comp_provider2-1.0.0-x86.tpk differ
similarity index 65%
rename from unittest/src/test_tools.cc
rename to unittest/src/test-complication-bundle.cc
index 9709d2b..dc8352e 100644 (file)
@@ -36,15 +36,14 @@ using namespace watchface_complication;
 class BUNDLE : public ::testing::Test {
  public:
   Bundle *b = nullptr;
-  virtual void SetUp(){
+  virtual void SetUp() {
     b = new Bundle();
   }
-  virtual void TearDown(){
+  virtual void TearDown() {
     delete b;
   }
 };
 
-
 TEST_F(BUNDLE, Create1)
 {
   EXPECT_NE(BUNDLE::b, nullptr);
@@ -90,3 +89,49 @@ TEST_F(BUNDLE, ToString)
 {
   EXPECT_NE(BUNDLE::b->ToString(), "");
 }
+
+TEST_F(BUNDLE, Copy)
+{
+  Bundle b;
+  bundle_add_str(b.GetRaw(), "TEST_KEY", "TEST_VALUE");
+
+  char* value;
+  Bundle b2 = b;
+  bundle_get_str(b2.GetRaw(), "TEST_KEY", &value);
+  EXPECT_STREQ(value, "TEST_VALUE");
+}
+
+TEST_F(BUNDLE, Copy2)
+{
+  Bundle b;
+  bundle_add_str(b.GetRaw(), "TEST_KEY", "TEST_VALUE");
+
+  char* value;
+  Bundle b2;
+  b2 = b;
+  bundle_get_str(b2.GetRaw(), "TEST_KEY", &value);
+  EXPECT_STREQ(value, "TEST_VALUE");
+}
+
+TEST_F(BUNDLE, Move)
+{
+  Bundle b;
+  bundle_add_str(b.GetRaw(), "TEST_KEY", "TEST_VALUE");
+
+  char* value;
+  Bundle b2 = std::move(b);
+  bundle_get_str(b2.GetRaw(), "TEST_KEY", &value);
+  EXPECT_STREQ(value, "TEST_VALUE");
+}
+
+TEST_F(BUNDLE, Move2)
+{
+  Bundle b;
+  bundle_add_str(b.GetRaw(), "TEST_KEY", "TEST_VALUE");
+
+  char* value;
+  Bundle b2;
+  b2 = std::move(b);
+  bundle_get_str(b2.GetRaw(), "TEST_KEY", &value);
+  EXPECT_STREQ(value, "TEST_VALUE");
+}
\ No newline at end of file
similarity index 65%
rename from unittest/src/test_complication_provider.cc
rename to unittest/src/test-complication-provider.cc
index fb6672f..edbdd32 100644 (file)
 using namespace std;
 using namespace watchface_complication;
 
-string providerId = "org.tizen.sample";
-
 class WCP : public ::testing::Test {
  public:
   ComplicationProvider* provider;
+  string providerId = "org.tizen.gmock_comp_provider/test";
 
   virtual void SetUp(){
-    provider = new ComplicationProvider(providerId.c_str());
+    provider = new ComplicationProvider(providerId.c_str(), true);
   }
   virtual void TearDown(){
     delete provider;
   }
 };
 
-void _on_update_request_cb(const char *provider_id, const char *req_appid,
-                        watchface_complication_type_e type, const bundle *context,
-                        bundle *share_data, void *user_data) {
-}
-
 TEST_F(WCP, Create)
 {
   EXPECT_NE(WCP::provider, nullptr);
@@ -57,13 +51,8 @@ TEST_F(WCP, GetProviderId)
   EXPECT_EQ(WCP::provider->GetProviderId(), providerId.c_str());
 }
 
-TEST_F(WCP, UpdateRequestCb)
-{
-  EXPECT_EQ(watchface_complication_provider_add_update_requested_cb(providerId.c_str(), _on_update_request_cb, NULL), 0);
-  EXPECT_EQ(watchface_complication_provider_remove_update_requested_cb(providerId.c_str(), _on_update_request_cb), 0);
-}
 
 TEST_F(WCP, NotifyUpdate)
 {
-  EXPECT_EQ(watchface_complication_provider_notify_update("test"), WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER);
+  WCP::provider->NotifyDataUpdate();
 }
diff --git a/unittest/src/test-complication.cc b/unittest/src/test-complication.cc
new file mode 100644 (file)
index 0000000..62a8f24
--- /dev/null
@@ -0,0 +1,244 @@
+/*
+ * 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.
+ */
+
+#include <stdbool.h>
+#include <stdexcept>
+#include <iostream>
+#include <glib.h>
+#include <dlog.h>
+#include <memory>
+#include <string>
+#include <list>
+
+#include <gtest/gtest.h>
+#include <gmock/gmock.h>
+
+#include "watchface-complication/complication.h"
+
+using namespace std;
+using namespace watchface_complication;
+
+GMainLoop *mainloop = NULL;
+class WatchComplication : public Complication {
+ public:
+  WatchComplication(int id, int supported_types, int supported_event_types,
+                        const std::string& default_provider_id,
+                        ComplicationType default_type)
+    : Complication(id, supported_types, supported_event_types,
+        default_provider_id, default_type, true) {
+  }
+  void OnProviderError(const std::string& provider_id,
+      ComplicationType type, int error) override {
+    cout << "provider error : " << provider_id << "(" << error << ")" << endl;
+    g_main_loop_quit(mainloop);
+    if (error == WATCHFACE_COMPLICATION_ERROR_PROVIDER_NOT_AVAILABLE)
+      not_available_ = true;
+  }
+  virtual ~WatchComplication() = default;
+
+ public:
+  bool not_available_;
+};
+
+class WC : public ::testing::Test {
+ public:
+  ComplicationType default_type = ShortText;
+  WatchComplication* complication = NULL;
+  WatchComplication* complication2 = NULL;
+  string providerId = "org.tizen.gmock_comp_provider/test";
+  string providerId2 = "org.tizen.gmock_comp_provider2/test";
+  ~WC() { }
+  void RunMainLoop() {
+    g_main_loop_run(mainloop);
+  }
+  virtual void SetUp() {
+    mainloop = g_main_loop_new(NULL, FALSE);
+    complication = new WatchComplication(0, default_type, EventTap,
+        providerId.c_str(), ShortText);
+    complication->Init();
+    complication->SetLabel("TestComplication");
+    complication->SetHighlight(std::unique_ptr<IEditable::Highlight>(
+        new IEditable::Highlight(
+          std::unique_ptr<IEditable::Geometry>(new IEditable::Geometry(0, 0, 100, 100)),
+          IEditable::EditableShapeType::Circle)));
+
+    complication2 = new WatchComplication(0, default_type, EventTap,
+        providerId2.c_str(), ShortText);
+    complication2->Init();
+  }
+  virtual void TearDown() {
+    delete complication;
+    g_main_loop_unref(mainloop);
+    mainloop = NULL;
+  }
+};
+
+TEST_F(WC, Create)
+{
+  EXPECT_NE(WC::complication, nullptr);
+}
+
+TEST_F(WC, GetEditableId)
+{
+  EXPECT_EQ(WC::complication->SetEditableId(1), 0);
+  EXPECT_EQ(WC::complication->GetEditableId(), 1);
+}
+
+TEST_F(WC, DataIdx)
+{
+  EXPECT_EQ(WC::complication->SetCurDataIdx(0), 0);
+  EXPECT_EQ(WC::complication->GetCurDataIdx(), 0);
+  EXPECT_EQ(WC::complication->UpdateLastData(), 0);
+  EXPECT_EQ(WC::complication->GetLastDataIdx(), 0);
+}
+
+TEST_F(WC, SetCurDataIdx)
+{
+  EXPECT_EQ(WC::complication->SetCurDataIdx(1), 0);
+  EXPECT_EQ(WC::complication->GetCurDataIdx(), 1);
+}
+
+TEST_F(WC, Name)
+{
+  EXPECT_EQ(WC::complication->GetLabel(), "TestComplication");
+}
+
+TEST_F(WC, ShapeType)
+{
+  WC::complication->GetHighlight()->SetShapeType(IEditable::EditableShapeType::Circle);
+  EXPECT_EQ(WC::complication->GetHighlight()->GetShapeType(), IEditable::EditableShapeType::Circle);
+}
+
+TEST_F(WC, State)
+{
+  WC::complication->SetState(IEditable::EditableState::Complete);
+  EXPECT_EQ(WC::complication->GetState(), IEditable::EditableState::Complete);
+}
+
+TEST_F(WC, Key)
+{
+  EXPECT_STREQ(WC::complication->GetProviderIdKey(), "__PROVIDER_ID_KEY__");
+  EXPECT_STREQ(WC::complication->GetProviderTypeKey(), "__PROVIDER_TYPE_KEY__");
+}
+
+TEST_F(WC, SendDataUpdateRequest)
+{
+  EXPECT_EQ(WC::complication->SendDataUpdateRequest(), 0);
+}
+
+TEST_F(WC, GetCurType)
+{
+  EXPECT_EQ(WC::complication->GetCurType(), default_type);
+}
+
+TEST_F(WC, GetCurData)
+{
+  const Bundle* data = WC::complication->GetCurData();
+  EXPECT_NE(data, nullptr);
+}
+
+TEST_F(WC, GetNthData)
+{
+  const Bundle* data = WC::complication->GetNthData(0);
+  EXPECT_NE(data, nullptr);
+}
+
+TEST_F(WC, Disabled)
+{
+  std::list<std::unique_ptr<Bundle>> const& list = complication2->GetCandidates();
+  for (unsigned int i = 0; i < list.size(); i++) {
+    complication2->SetCurDataIdx(i);
+    if (strcmp(complication2->GetCurProviderId(), "org.tizen.gmock_comp_provider/test") == 0)
+      break;
+  }
+  WC::complication->not_available_ = false;
+  RunMainLoop();
+  EXPECT_EQ(WC::complication->not_available_, true);
+}
+
+TEST_F(WC, DisabledRecovery)
+{
+  std::list<std::unique_ptr<Bundle>> const& list = complication2->GetCandidates();
+  for (unsigned int i = 0; i < list.size(); i++) {
+    complication2->SetCurDataIdx(i);
+    if (strcmp(complication2->GetCurProviderId(), WC::providerId.c_str()) == 0) {
+      RunMainLoop();
+      break;
+    }
+  }
+
+  cout << "??" << complication2->GetCurProviderId() << endl;
+  EXPECT_EQ(strcmp(complication2->GetCurProviderId(), WC::providerId2.c_str()), 0);
+}
+
+TEST_F(WC, GetProviderId)
+{
+  const Bundle* data = WC::complication->GetCurData();
+  const char* provider_id = WC::complication->GetProviderId(data);
+  EXPECT_EQ(strcmp(complication->GetCurProviderId(), provider_id), 0);
+}
+
+TEST_F(WC, GetProviderType)
+{
+  const Bundle* data = WC::complication->GetCurData();
+
+  EXPECT_EQ(WC::complication->GetProviderType(data), WC::complication->GetCurType());
+}
+
+TEST_F(WC, GetSetupAppId)
+{
+  const std::string setup_appid = WC::complication->GetSetupAppId();
+  EXPECT_EQ(strcmp("org.tizen.watchface-complication-native-utc", setup_appid.c_str()), 0);
+}
+
+TEST_F(WC, GetSupportedEventsErrorKey)
+{
+  EXPECT_STREQ(WC::complication->GetSupportedEventsErrorKey(), "__SUPPORTED_EVENTS_ERROR_KEY__");
+}
+
+TEST_F(WC, GetPrivilegeErrorKey)
+{
+  EXPECT_STREQ(WC::complication->GetPrivilegeErrorKey(), "__PRIVILEGE_ERROR_KEY__");
+}
+
+TEST_F(WC, SetContext)
+{
+  bundle* b = bundle_create();
+  bundle_add_str(b, "TEST_KEY", "TEST_VALUE");
+
+  Bundle* bundle = new Bundle(b);
+  WC::complication->SetContext(std::unique_ptr<Bundle>(bundle));
+  std::unique_ptr<Bundle>& ctx = WC::complication->GetContext();
+
+  char* value;
+  bundle_get_str(ctx.get()->GetRaw(), "TEST_KEY", &value);
+  EXPECT_STREQ(value, "TEST_VALUE");
+}
+
+TEST_F(WC, GetLastContext)
+{
+  bundle* b = bundle_create();
+  bundle_add_str(b, "TEST_KEY", "TEST_VALUE");
+
+  Bundle* bundle = new Bundle(b);
+  WC::complication->SetContext(std::unique_ptr<Bundle>(bundle));
+  WC::complication->UpdateLastContext();
+  std::unique_ptr<Bundle>& ctx = WC::complication->GetLastContext();
+
+  char* value;
+  bundle_get_str(ctx.get()->GetRaw(), "TEST_KEY", &value);
+  EXPECT_STREQ(value, "TEST_VALUE");
+}
\ No newline at end of file
diff --git a/unittest/src/test-db-manager.cc b/unittest/src/test-db-manager.cc
new file mode 100644 (file)
index 0000000..404f6f0
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+#include <stdbool.h>
+#include <stdexcept>
+#include <iostream>
+#include <glib.h>
+#include <dlog.h>
+
+#include <memory>
+#include <string>
+#include <list>
+
+#include <gtest/gtest.h>
+#include <gmock/gmock.h>
+
+#include "watchface-complication/db-manager.h"
+
+using namespace std;
+using namespace watchface_complication;
+
+class DB_MANAGER : public ::testing::Test {
+ public:
+  virtual void SetUp() {
+  }
+  virtual void TearDown() {
+  }
+};
+
+TEST_F(DB_MANAGER, GetProviderListWithAppId)
+{
+  std::list<std::string> list =
+      DBManager::GetProviderListWithAppId("org.tizen.gmock_comp_provider");
+
+  EXPECT_NE(list.size(), 0);
+}
\ No newline at end of file
similarity index 75%
rename from unittest/src/test_design_element.cc
rename to unittest/src/test-design-element.cc
index 1a1d2ad..eb6fda1 100644 (file)
@@ -36,7 +36,7 @@ using namespace watchface_complication;
 class Element : public DesignElement {
  public:
   Element(int id, int cur_data_idx)
-    : DesignElement(id, cur_data_idx){
+    : DesignElement(id, cur_data_idx, true){
     SetLabel("Test");
     SetHighlight(std::unique_ptr<IEditable::Highlight>(
         new Highlight(
@@ -96,13 +96,13 @@ TEST_F(DE, DataIdx)
 {
   EXPECT_EQ(DE::element->SetCurDataIdx(0), 0);
   EXPECT_EQ(DE::element->GetCurDataIdx(), 0);
-  EXPECT_EQ(DE::element->UpdateLastData(), -1);
+  EXPECT_EQ(DE::element->UpdateLastData(), 0);
   EXPECT_EQ(DE::element->GetLastDataIdx(), 0);
 }
 
-TEST_F(DE, GetName)
+TEST_F(DE, GetLabel)
 {
-  EXPECT_EQ(DE::element->GetName(), "Test");
+  EXPECT_EQ(DE::element->GetLabel(), "Test");
 }
 
 TEST_F(DE, GetShapeType)
@@ -126,3 +126,37 @@ TEST_F(DE, OnEditableUpdated)
   DE::element->OnEditableUpdated(1, IEditable::EditableState::OnGoing);
   DE::element->OnEditableUpdated(1, IEditable::EditableState::Complete);
 }
+
+TEST_F(DE, GetSetupAppId)
+{
+  EXPECT_EQ(DE::element->GetSetupAppId(), "");
+}
+
+TEST_F(DE, SetContext)
+{
+  bundle* b = bundle_create();
+  bundle_add_str(b, "TEST_KEY", "TEST_VALUE");
+
+  Bundle* bundle = new Bundle(b);
+  DE::element->SetContext(std::unique_ptr<Bundle>(bundle));
+  std::unique_ptr<Bundle>& ctx = DE::element->GetContext();
+
+  char* value;
+  bundle_get_str(ctx.get()->GetRaw(), "TEST_KEY", &value);
+  EXPECT_STREQ(value, "TEST_VALUE");
+}
+
+TEST_F(DE, GetLastContext)
+{
+  bundle* b = bundle_create();
+  bundle_add_str(b, "TEST_KEY", "TEST_VALUE");
+
+  Bundle* bundle = new Bundle(b);
+  DE::element->SetContext(std::unique_ptr<Bundle>(bundle));
+  DE::element->UpdateLastContext();
+  std::unique_ptr<Bundle>& ctx = DE::element->GetLastContext();
+
+  char* value;
+  bundle_get_str(ctx.get()->GetRaw(), "TEST_KEY", &value);
+  EXPECT_STREQ(value, "TEST_VALUE");
+}
\ No newline at end of file
similarity index 74%
rename from unittest/src/test_editables_container.cc
rename to unittest/src/test-editables-container.cc
index 3b36522..ca5efb2 100644 (file)
 using namespace std;
 using namespace watchface_complication;
 
+class MyContainer : public EditablesContainer {
+ public:
+  MyContainer()
+    : EditablesContainer(true) {
+  }
+
+  void OnUpdate(const IEditable& ed, int selected_idx,
+      IEditable::EditableState state) override {
+  }
+
+  void OnEditReady(const std::string& editor_id) override {
+
+  }
+
+  virtual ~MyContainer() = default;
+};
+
 class EC : public ::testing::Test {
  public:
-  EditablesContainer* container;
+  MyContainer* container;
   ReceivedEditable* received;
 
   virtual void SetUp() {
@@ -67,14 +84,14 @@ class EC : public ::testing::Test {
     bundle_encode(data, &raw_data, &len);
 
     received = new ReceivedEditable(std::string(reinterpret_cast<char*>(raw_data)));
-
-    container = new EditablesContainer();
+    container = new MyContainer();
 
     delete candidate1;
     delete candidate2;
     bundle_free(data);
     free(raw_data);
   }
+
   virtual void TearDown() {
     delete received;
     delete container;
@@ -124,44 +141,3 @@ TEST_F(EC, AddRemove)
   EXPECT_EQ(EC::container->Add(ed, 1), 0);
   EXPECT_EQ(EC::container->Remove(ed), 0);
 }
-
-TEST_F(EC, RequestEdit)
-{
-  EXPECT_EQ(EC::container->RequestEdit(), 0);
-}
-
-void _on_edit_ready_cb(watchface_editable_container_h handle, const char *editor_appid, void *user_data) {
-  /* to do
-  editable_add_design_element
-  editable_add_complication
-  editable_request_edit
-  */
-}
-
-TEST_F(EC, EditReadyCb)
-{
-  EXPECT_EQ(watchface_editable_add_edit_ready_cb(_on_edit_ready_cb, NULL), 0);
-  EXPECT_EQ(watchface_editable_remove_edit_ready_cb(_on_edit_ready_cb), 0);
-}
-
-TEST_F(EC, GetData)
-{
-  int idx = 0;
-  int idx_check;
-  int id;
-  bundle* data = nullptr;
-  bundle* nthdata = nullptr;
-  char* get_editable_name = NULL;
-
-  EXPECT_EQ(watchface_editable_get_current_data_idx(EC::received, &idx_check), 0);
-  EXPECT_EQ(idx, idx_check);
-
-  EXPECT_EQ(watchface_editable_get_current_data(EC::received, &data), WATCHFACE_COMPLICATION_ERROR_NONE);
-  bundle_free(data);
-  EXPECT_EQ(watchface_editable_get_nth_data(EC::received, 1, &nthdata), WATCHFACE_COMPLICATION_ERROR_NONE);
-  bundle_free(nthdata);
-  EXPECT_EQ(watchface_editable_get_editable_id(EC::received, &id), WATCHFACE_COMPLICATION_ERROR_NONE);
-  EXPECT_EQ(id, 0);
-  EXPECT_EQ(watchface_editable_get_editable_name(EC::received, &get_editable_name), 0);
-  free(get_editable_name);
-}
diff --git a/unittest/src/test-editables-manager.cc b/unittest/src/test-editables-manager.cc
new file mode 100644 (file)
index 0000000..d9f2010
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+#include <stdbool.h>
+#include <stdexcept>
+#include <iostream>
+#include <glib.h>
+#include <dlog.h>
+
+#include <memory>
+#include <string>
+#include <list>
+
+#include <gtest/gtest.h>
+#include <gmock/gmock.h>
+
+#include "watchface-complication/editables-manager.h"
+
+using namespace std;
+using namespace watchface_complication;
+
+class EDITABLES_MANAGER : public ::testing::Test {
+ public:
+  virtual void SetUp() {
+  }
+  virtual void TearDown() {
+  }
+};
+
+TEST_F(EDITABLES_MANAGER, StoreContext)
+{
+  bundle* b = bundle_create();
+  bundle_add_str(b, "TEST_KEY", "TEST_VALUE");
+
+  Bundle* bundle = new Bundle(b);
+  EditablesManager::GetInst(true).StoreContext(10, "org.tizen.mock_provider/test",
+        *bundle);
+  int ret = EditablesManager::GetInst(true).DeleteContext(
+        10, "org.tizen.mock_provider/test");
+  EXPECT_EQ(ret, 0);
+}
\ No newline at end of file
similarity index 76%
rename from unittest/src/test_editor.cc
rename to unittest/src/test-editor.cc
index dfc5bc6..8d5fb23 100644 (file)
@@ -35,7 +35,7 @@ class WE : public ::testing::Test {
   EditablesEditor* editor;
 
   virtual void SetUp(){
-    editor = new EditablesEditor();
+    editor = new EditablesEditor(true);
   }
   virtual void TearDown(){
     delete editor;
@@ -83,12 +83,6 @@ TEST_F(WE, NotifyEditReady)
   EXPECT_EQ(WE::editor->NotifyEditReady("sample_provider"), 0);
 }
 
-TEST_F(WE, RequestEditCb)
-{
-  EXPECT_EQ(watchface_editor_add_request_edit_cb(_on_request_edit_cb, NULL), 0);
-  EXPECT_EQ(watchface_editor_remove_request_edit_cb(_on_request_edit_cb), 0);
-}
-
 class WEL : public ::testing::Test {
  public:
   GList* editables = NULL;
@@ -130,36 +124,4 @@ class WEL : public ::testing::Test {
     delete received;
     g_list_free(editables);
   }
-};
-
-TEST_F(WEL, EditPreview)
-{
-  IEditable* ed = static_cast<IEditable*>(WEL::received);
-  EXPECT_EQ(watchface_editor_edit_preview(ed, 0), WATCHFACE_COMPLICATION_ERROR_EDIT_NOT_READY);
-}
-
-TEST_F(WEL, EditReady)
-{
-  EXPECT_EQ(watchface_editor_notify_edit_ready("sample_provide"), 0);
-}
-
-TEST_F(WEL, EditableList)
-{
-  editable_list_h duplist = NULL;
-  watchface_editable_h nthEditor;
-  int size = 0;
-
-  watchface_editor_editable_list_dup(WEL::editables, &duplist);
-  EXPECT_NE(duplist, nullptr);
-  watchface_editor_editable_list_get_size(WEL::editables, &size);
-  EXPECT_GT(size, 0);
-
-  watchface_editor_editable_list_get_nth(WEL::editables, 0, &nthEditor);
-  EXPECT_NE(nthEditor, nullptr);
-  watchface_editor_editable_candidate_list_get_size(nthEditor, &size);
-  EXPECT_GT(size, 0);
-
-  watchface_editor_editable_list_get_nth(WEL::editables, 0, &nthEditor);
-  EXPECT_NE(nthEditor, nullptr);
-  EXPECT_EQ(watchface_editor_editable_list_destroy(duplist), 0);
-}
+};
\ No newline at end of file
similarity index 95%
rename from unittest/src/test_main.cc
rename to unittest/src/test-main.cc
index 9579b93..c9223a4 100644 (file)
 
 #include <gtest/gtest.h>
 #include <gmock/gmock.h>
+#include <glib.h>
 
 int main(int argc, char** argv){
   int ret = -1;
-
+  setenv("GCOV_PREFIX", "/tmp/", 1);
   try {
     testing::InitGoogleTest(&argc, argv);
   } catch(...) {
similarity index 73%
rename from unittest/src/test_received_editable.cc
rename to unittest/src/test-received-editable.cc
index 32e06ba..4eb23d0 100644 (file)
@@ -110,9 +110,9 @@ TEST_F(RE, DataIdx)
   EXPECT_EQ(RE::received->GetLastDataIdx(), 0);
 }
 
-TEST_F(RE, GetName)
+TEST_F(RE, GetLabel)
 {
-  EXPECT_EQ(RE::received->GetName(), "sample");
+  EXPECT_EQ(RE::received->GetLabel(), "sample");
 }
 
 TEST_F(RE, GetShapeType)
@@ -136,3 +136,42 @@ TEST_F(RE, OnEditableUpdated)
   RE::received->OnEditableUpdated(1, IEditable::EditableState::OnGoing);
   RE::received->OnEditableUpdated(1, IEditable::EditableState::Complete);
 }
+
+TEST_F(RE, SetContext)
+{
+  bundle* b = bundle_create();
+  bundle_add_str(b, "TEST_KEY", "TEST_VALUE");
+
+  Bundle* bundle = new Bundle(b);
+  RE::received->SetContext(std::unique_ptr<Bundle>(bundle));
+  std::unique_ptr<Bundle>& ctx = RE::received->GetContext();
+  RE::received->UpdateLastContext();
+
+  char* value;
+  bundle_get_str(ctx.get()->GetRaw(), "TEST_KEY", &value);
+  EXPECT_STREQ(value, "TEST_VALUE");
+}
+
+TEST_F(RE, SetHighlight)
+{
+  RE::received->SetHighlight(
+          std::unique_ptr<IEditable::Highlight>(new IEditable::Highlight(
+            std::unique_ptr<IEditable::Geometry>(new IEditable::Geometry(10, 20, 100, 120)),
+              IEditable::EditableShapeType::Rectangle)));
+  EXPECT_EQ(RE::received->GetHighlight()->GetShapeType(), IEditable::EditableShapeType::Rectangle);
+  EXPECT_EQ(RE::received->GetHighlight()->GetGeometry()->GetX(), 10);
+  EXPECT_EQ(RE::received->GetHighlight()->GetGeometry()->GetY(), 20);
+  EXPECT_EQ(RE::received->GetHighlight()->GetGeometry()->GetW(), 100);
+  EXPECT_EQ(RE::received->GetHighlight()->GetGeometry()->GetH(), 120);
+}
+
+TEST_F(RE, SetCandidates)
+{
+  EXPECT_EQ(RE::received->SetHighlight(nullptr), WATCHFACE_COMPLICATION_ERROR_NONE);
+}
+
+TEST_F(RE, SetLabel)
+{
+  RE::received->SetLabel("test label");
+  EXPECT_STREQ(RE::received->GetLabel().c_str(), "test label");
+}
diff --git a/unittest/src/test_complication.cc b/unittest/src/test_complication.cc
deleted file mode 100644 (file)
index ef288a9..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * 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.
- */
-
-#include <stdbool.h>
-#include <stdexcept>
-#include <iostream>
-#include <glib.h>
-#include <dlog.h>
-
-#include <memory>
-#include <string>
-#include <list>
-
-#include <gtest/gtest.h>
-#include <gmock/gmock.h>
-
-#include "watchface-complication/complication.h"
-#include "watchface-complication/include/watchface-complication.h"
-#include "watchface-complication/include/watchface-editable.h"
-
-using namespace std;
-using namespace watchface_complication;
-
-class WatchComplication : public Complication {
- public:
-  WatchComplication(int id, int supported_types, int supported_event_types,
-                        const std::string& default_provider_id,
-                        ComplicationType default_type)
-    : Complication(id, supported_types, supported_event_types,
-        default_provider_id, default_type) {
-    SetCurDataIdx(0);
-    SetLabel("TestComplication");
-    SetHighlight(std::unique_ptr<IEditable::Highlight>(
-        new Highlight(
-          std::unique_ptr<IEditable::Geometry>(new IEditable::Geometry(0, 0, 100, 100)),
-          IEditable::EditableShapeType::Circle)));
-  }
-
-  virtual ~WatchComplication() = default;
-};
-
-class WC : public ::testing::Test {
- public:
-  WatchComplication* complication = NULL;
-  string providerId = "org.tizen.watchface_sample_provider/test";
-
-  virtual void SetUp() {
-    complication = new WatchComplication(0, ShortText, EventTap,
-        providerId.c_str(), ShortText);
-  }
-  virtual void TearDown() {
-    delete complication;
-  }
-};
-
-TEST_F(WC, Create)
-{
-  EXPECT_NE(WC::complication, nullptr);
-}
-
-TEST_F(WC, GetEditableId)
-{
-  EXPECT_EQ(WC::complication->SetEditableId(1), 0);
-  EXPECT_EQ(WC::complication->GetEditableId(), 1);
-}
-
-TEST_F(WC, DataIdx)
-{
-  EXPECT_EQ(WC::complication->GetCurDataIdx(), 0);
-  EXPECT_EQ(WC::complication->GetLastDataIdx(), -1);
-  EXPECT_EQ(WC::complication->UpdateLastData(), -1);
-}
-
-TEST_F(WC, Name)
-{
-  EXPECT_EQ(WC::complication->GetName(), "TestComplication");
-}
-
-TEST_F(WC, ShapeType)
-{
-  WC::complication->GetHighlight()->SetShapeType(IEditable::EditableShapeType::Circle);
-  EXPECT_EQ(WC::complication->GetHighlight()->GetShapeType(), IEditable::EditableShapeType::Circle);
-}
-
-TEST_F(WC, State)
-{
-  WC::complication->SetState(IEditable::EditableState::Complete);
-  EXPECT_EQ(WC::complication->GetState(), IEditable::EditableState::Complete);
-}
-
-TEST_F(WC, Key)
-{
-  EXPECT_STREQ(WC::complication->GetProviderIdKey(), "__PROVIDER_ID_KEY__");
-  EXPECT_STREQ(WC::complication->GetProviderTypeKey(), "__PROVIDER_TYPE_KEY__");
-}
-class WFC : public ::testing::Test {
- public:
-  complication_h complication;
-  int comp_id = 1;
-  virtual void SetUp() {
-    watchface_complication_create(comp_id, "org.tizen.sample",
-                       WATCHFACE_COMPLICATION_TYPE_SHORT_TEXT,
-                       WATCHFACE_COMPLICATION_TYPE_SHORT_TEXT,
-                       WATCHFACE_COMPLICATION_EVENT_TAP,
-                       &complication);
-  }
-  virtual void TearDown() {
-    watchface_complication_destroy(complication);
-  }
-};
-
-void _on_complication_update_cb(int complication_id, const char* provider_id,
-                             watchface_complication_type_e type, const bundle* data,
-                             void* user_data) {
-}
-
-void _on_complication_error_cb(int complication_id, const char* provider_id,
-                             watchface_complication_type_e type,
-                             watchface_complication_error_e error,
-                             void* user_data) {
-}
-
-TEST_F(WFC, Create)
-{
-  EXPECT_NE(WFC::complication, nullptr);
-}
-
-TEST_F(WFC, Callback)
-{
-  EXPECT_EQ(watchface_complication_add_updated_cb(WFC::complication, _on_complication_update_cb, _on_complication_error_cb, NULL), 0);
-  EXPECT_EQ(watchface_complication_send_update_request(WFC::complication), WATCHFACE_COMPLICATION_ERROR_IO_ERROR);
-  EXPECT_EQ(watchface_complication_remove_updated_cb(WFC::complication, _on_complication_update_cb), 0);
-}
-
-TEST_F(WFC, GetData)
-{
-  watchface_complication_type_e cur_type;
-
-  EXPECT_EQ(watchface_complication_get_current_type(WFC::complication, &cur_type), 0);
-  EXPECT_EQ(cur_type, WATCHFACE_COMPLICATION_TYPE_SHORT_TEXT);
-}
-
-TEST_F(WFC, UpdateRequest)
-{
-  EXPECT_EQ(watchface_complication_send_update_request(WFC::complication), WATCHFACE_COMPLICATION_ERROR_IO_ERROR);
-}
index f611b29..4504fbd 100644 (file)
@@ -25,7 +25,7 @@
 #define THROW(error_code) throw Exception(error_code, __FILE__, __LINE__)
 
 namespace watchface_complication {
-
+/* LCOV_EXCL_START */
 class Exception : public std::exception {
  public:
   explicit Exception(int error_code, std::string file = __FILE__,
@@ -74,7 +74,7 @@ class Exception : public std::exception {
     }
   }
 };
-
+/* LCOV_EXCL_STOP */
 }  // namespace watchface_complication
 
 #endif  // WATCHFACE_COMMON_WATCHFACE_EXCEPTION_H_
index bb5c75f..965db1a 100644 (file)
 
 #define MAX_PACKAGE_STR_SIZE 512
 #define SMACK_LABEL_LEN 255
+#define COMPLICATION_BUS_NAME_PREFIX "org.tizen.watchface_complication._"
+#define COMPLICATION_PATH_PREFIX "/org/tizen/watchface_complication_"
+#define EDITABLE_PATH_PREFIX "/org/tizen/watchface_editable_"
+#define COMPLICATION_OBJECT_PATH "/org/tizen/watchface_complication"
 #define MAX_CACHE_COUNT 10
 
 #define LOG_TAG "WATCHFACE_COMPLICATION"
@@ -254,7 +258,7 @@ out:
       return cp->second;
 
     pkgmgrinfo_cert_compare_result_type_e res;
-    char* app_id = GetAppID();
+    const char* app_id = GetAppId().c_str();
     int cert_ret = pkgmgrinfo_pkginfo_compare_usr_app_cert_info(app_id,
                       provider_app_id.c_str(), getuid(), &res);
     if (cert_ret < 0) {
@@ -276,23 +280,95 @@ out:
     return ret;
   }
 
-  char* GetAppID() {
-    int pid = getpid();
-    int ret = 0;
-    char buffer[MAX_PACKAGE_STR_SIZE] = {0, };
-    static char* app_id = NULL;
+  std::string EncodeStr(EncodeType type, std::string appid) {
+    char* encoded_path;
+    std::string encoded_path_str;
+    std::string encoded_str;
 
-    if (app_id == NULL) {
-      ret = aul_app_get_appid_bypid(pid, buffer, sizeof(buffer));
-      if (ret != AUL_R_OK) {
-        LOGE("Failed to get the application ID: %d", ret);
-        return NULL;
-      }
+    if (appid.empty())
+      return "";
+
+    encoded_path = g_compute_checksum_for_string(G_CHECKSUM_MD5,
+                  appid.c_str(), -1);
+    if (encoded_path == NULL)
+      return "";
+
+    encoded_path_str = std::string(encoded_path);
+    if (type == EncodeType::CompPath)
+      encoded_str = COMPLICATION_PATH_PREFIX + encoded_path_str;
+    else if (type == EncodeType::EditablePath)
+      encoded_str = EDITABLE_PATH_PREFIX + encoded_path_str;
+    else
+      encoded_str = COMPLICATION_BUS_NAME_PREFIX + encoded_path_str;
+
+    free(encoded_path);
+
+    return encoded_str;
+  }
+
+  std::string EncodeStr(EncodeType type, std::string appid, int compid) {
+    if (appid.empty())
+      return "";
+    std::string str = appid + "_" + std::to_string(compid);
+
+    return EncodeStr(type, str);
+  }
 
-      app_id = strdup(buffer);
+  std::string GetCmdStr(CmdType type) {
+    std::string ret;
+    switch (type) {
+    case CompUpdateRequest :
+      ret = "__COMP_UPDATE_REQUEST__";
+      break;
+    case CompUpdated :
+      ret = "__COMP_UPDATED__";
+      break;
+    case CompNotifyDataUpdate :
+      ret = "__COMP_NOTIFY_DATA_UPDATE__";
+      break;
+    case EditableEditRequest :
+      ret = "__EDITABLE_EDIT_REQUEST__";
+      break;
+    case EditableEditPreview :
+      ret = "__EDITABLE_EDIT_PREVIEW__";
+      break;
+    case EditableEditComplete :
+      ret = "__EDITABLE_EDIT_COMPLETE__";
+      break;
+    case EditableEditCancel :
+      ret = "__EDITABLE_EDIT_CANCEL__";
+      break;
+    case EditableEditReady :
+      ret = "__EDITABLE_EDIT_READY__";
+      break;
+    case SetupReply :
+      ret = "__SETUP_REPLY__";
+      break;
+    default :
+      break;
     }
 
-    return app_id;
+    return ret;
   }
+
+  std::string GetAppId() {
+    static std::string appid = "";
+    char appid_buf[MAX_PACKAGE_STR_SIZE] = {0, };
+
+    if (!appid.empty()) {
+      LOGI("appid(%s)", appid.c_str());
+      return appid;
+    }
+
+    int pid = getpid();
+    int ret = aul_app_get_appid_bypid(pid, appid_buf, sizeof(appid_buf));
+    if (ret != AUL_R_OK) {
+      LOGE("Fail to get appid");
+      return "";
+    }
+    appid = std::string(appid_buf);
+    return appid;
+  }
+
 }  // namespace util
 }  // namespace watchface_complication
index 962db08..66fee5d 100644 (file)
@@ -31,6 +31,24 @@ enum cynara_result {
 
 namespace watchface_complication {
 namespace util {
+  enum CmdType {
+    CompUpdateRequest,
+    CompUpdated,
+    CompNotifyDataUpdate,
+    EditableEditRequest,
+    EditableEditComplete,
+    EditableEditPreview,
+    EditableEditCancel,
+    EditableEditReady,
+    SetupReply
+  };
+
+  enum EncodeType {
+    Name,
+    CompPath,
+    EditablePath
+  };
+
   EXPORT_API bool CheckWatchFeatureEnabled();
   EXPORT_API int CheckPrivilege(const char* privilege);
   EXPORT_API int CheckPrivilege(std::string& privilege,
@@ -44,8 +62,11 @@ namespace util {
                                 const std::string& sender_name,
                                 GDBusConnection* conn);
   EXPORT_API bool CheckComplicationType(int type);
+  EXPORT_API std::string EncodeStr(EncodeType type, std::string appid);
+  EXPORT_API std::string EncodeStr(EncodeType type, std::string appid, int compid);
+  EXPORT_API std::string GetAppId();
+  EXPORT_API std::string GetCmdStr(CmdType type);
   EXPORT_API bool CheckCertificate(const std::string& provider_app_id);
-  EXPORT_API char* GetAppID();
 }  // namespace util
 }  // namespace watchface_complication
 
index 7c73643..01f775b 100644 (file)
 
 #include "watchface-complication/complication.h"
 #include "watchface-complication/complication-connector.h"
+#include "watchface-complication/gdbus-interface.h"
 #include "watchface-common/watchface-util.h"
 
 namespace watchface_complication {
 
-class ComplicationProvider::Impl : ComplicationConnector::IEventListener {
+class ComplicationProvider::Impl : IGDBus::IGDBusEvent {
  public:
   virtual ~Impl() = default;
 
@@ -46,7 +47,7 @@ class ComplicationProvider::Impl : ComplicationConnector::IEventListener {
   void OnVanish(const std::string& name) override;
   void OnAppear(const std::string& name, const std::string& name_owner) override;
   std::list<std::string>& GetRequiredPrivileges();
-  Impl(ComplicationProvider* parent, const std::string& provider_id);
+  Impl(ComplicationProvider* parent, const std::string& provider_id, bool mock);
   class SenderInfo {
    public:
     SenderInfo(const std::string& sender_name, const char* sender_app_id,
@@ -74,7 +75,9 @@ class ComplicationProvider::Impl : ComplicationConnector::IEventListener {
   int supported_types_;
   std::map<std::string, SenderInfo*> sender_info_;
   std::list<std::string> required_privileges_;
+  std::unique_ptr<IGDBus> gdbus_ = nullptr;
   bool trusted_;
+  bool mock_ = false;
 };
 
 }  // namespace watchface_complication
index 2473b3a..79d0cef 100644 (file)
 
 namespace watchface_complication {
 
-ComplicationProvider::ComplicationProvider(const std::string& provider_id)
-                                       : impl_(new Impl(this, provider_id)) {
+ComplicationProvider::ComplicationProvider(const std::string& provider_id, bool mock)
+                                       : impl_(new Impl(this, provider_id, mock)) {
 }
 
 ComplicationProvider::~ComplicationProvider() = default;
 
 ComplicationProvider::Impl::Impl(ComplicationProvider* parent,
-                                 const std::string& provider_id)
-  : parent_(parent), provider_id_(provider_id) {
-  int ret;
-  try {
-    subscribe_id_ = ComplicationConnector::GetInst().SubscribeSignal(
-      ComplicationConnector::Complication, provider_id_, -1, this);
-  } catch (...) {
-    throw;
-  }
+                                 const std::string& provider_id, bool mock)
+  : parent_(parent), provider_id_(provider_id),
+  gdbus_(std::unique_ptr<IGDBus>(ComplicationConnector::GetInst(mock).CreateGDBus(mock))),
+  mock_(mock) {
+  subscribe_id_ = gdbus_.get()->SubscribeSignal(
+    IGDBus::Complication, provider_id_, -1, this);
 
   std::list<std::string> privilege_list;
   required_privileges_.push_back(std::string(PRIVILEGE_DATASHARING));
 
-  ret = DBManager::GetSupportTypes(provider_id_, &supported_types_);
-  if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
+  int ret = DBManager::GetSupportTypes(provider_id_, &supported_types_);
+  if (ret != WATCHFACE_COMPLICATION_ERROR_NONE) {
+    LOGE("fail to get support types");
     THROW(ret);
+  }
 
   ret = DBManager::GetTrustedInfo(provider_id_, &trusted_);
-  if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
+  if (ret != WATCHFACE_COMPLICATION_ERROR_NONE) {
+    LOGE("fail to get trusted info");
     THROW(ret);
+  }
 
   privilege_list = DBManager::GetRequiredPrivilegeList(provider_id_);
   for (auto& i : privilege_list) {
@@ -133,7 +134,7 @@ void ComplicationProvider::Impl::OnVanish(const std::string& name) {
   if (sender_info == sender_info_.end())
     return;
 
-  ComplicationConnector::GetInst().UnWatch(si->GetWatcherID());
+  gdbus_.get()->UnWatch(si->GetWatcherID());
   sender_info_.erase(name);
   delete si;
 }
@@ -163,24 +164,19 @@ void ComplicationProvider::Impl::OnSignal(GDBusConnection* connection,
   if (sender_info == sender_info_.end()) {
     char* sender_app_id = NULL;
     int watcher_id = 0;
-    g_variant_get_child(parameters, 0, "&s", &sender_app_id);
 
+    g_variant_get_child(parameters, 0, "&s", &sender_app_id);
     if (sender_app_id == NULL  ||
         !util::CheckSender(sender_app_id, sender_name, connection)) {
       LOGE("sender_app_id %s", sender_app_id);
       return;
     }
+
+    watcher_id = gdbus_.get()->Watch(std::string(sender_app_id), this);
     try {
-      watcher_id = ComplicationConnector::GetInst().Watch(
-                                      std::string(sender_app_id), this);
-    } catch (...) {
-    }
-    try {
-      if (trusted_) {
-        if (util::CheckCertificate(sender_app_id) == false) {
-          LOGE("Permission denied");
-          return;
-        }
+      if (trusted_ && !util::CheckCertificate(sender_app_id)) {
+        LOGE("Permission denied");
+        return;
       }
       si = new SenderInfo(sender_name, sender_app_id, watcher_id);
     } catch (const std::bad_alloc &ba) {
@@ -213,9 +209,8 @@ void ComplicationProvider::Impl::OnSignal(GDBusConnection* connection,
     si->SetPrivilegeResult(COMPLICATION_CYNARA_ALLOWED);
   }
 
-  if (signal_name.compare(
-      ComplicationConnector::GetInst().GetCmdStr(
-          ComplicationConnector::CompUpdateRequest)) == 0) {
+  if (signal_name.compare(util::GetCmdStr(
+      util::CmdType::CompUpdateRequest)) == 0) {
     g_variant_get(parameters, "(&sii&s)", &sender_app_id,
                   &complication_id, &type, &context_raw);
 
@@ -251,22 +246,16 @@ void ComplicationProvider::Impl::OnSignal(GDBusConnection* connection,
     parent_->OnDataUpdateRequest(sender_app_id, (ComplicationType)type,
                                 context_data, shared_data);
     delete context_data;
-    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;
-  }
+    ret = gdbus_.get()->EmitSignal(
+          IGDBus::Complication,
+          std::string(sender_app_id),
+          provider_id_, -1,
+          util::GetCmdStr(util::CompUpdated),
+          g_variant_new("(siis)",
+                        (provider_id_).c_str(),
+                        type,
+                        complication_id,
+                        shared_data->ToString()));
     delete shared_data;
     if (ret == false)
       LOGE("EmitSignal failed %s %s %d", sender_app_id, (provider_id_).c_str(),
@@ -274,9 +263,11 @@ void ComplicationProvider::Impl::OnSignal(GDBusConnection* connection,
   }
 }
 
+/* LCOV_EXCL_START */
 void ComplicationProvider::OnDataUpdateRequest(const std::string& sender_appid,
     ComplicationType type, const Bundle* context, Bundle* shared_data) {
 }
+/* LCOV_EXCL_STOP */
 
 const std::string& ComplicationProvider::GetProviderId() const {
   return impl_->provider_id_;
@@ -288,8 +279,6 @@ int ComplicationProvider::NotifyDataUpdate() {
   static cynara_result pcr = COMPLICATION_CYNARA_UNKNOWN;
 
   int ret = WATCHFACE_COMPLICATION_ERROR_NONE;
-  bool emit_ret;
-
   if (pcr == COMPLICATION_CYNARA_DENIED) {
     LOGE("Permission denied");
     return WATCHFACE_COMPLICATION_ERROR_PERMISSION_DENIED;
@@ -306,24 +295,26 @@ int ComplicationProvider::NotifyDataUpdate() {
     }
   }
 
+  if (!impl_->gdbus_.get()->EmitSignal(IGDBus::Complication, "",
+      impl_->provider_id_, -1, util::GetCmdStr(util::CompNotifyDataUpdate),
+      g_variant_new("(s)", impl_->provider_id_.c_str())))
+    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+  return ret;
+}
+
+bool ComplicationProvider::SetupReplyToEditor(std::string editor_appid, int editable_id, const char* raw) {
+  bool emit_signal_ret = false;
   try {
-    emit_ret = ComplicationConnector::GetInst().EmitSignal(
-                            ComplicationConnector::Complication,
-                            "",
-                            impl_->provider_id_, -1,
-                            ComplicationConnector::GetInst().GetCmdStr(
-                                 ComplicationConnector::CompNotifyDataUpdate),
-                            g_variant_new("(s)",
-                                impl_->provider_id_.c_str()));
+    emit_signal_ret = ComplicationConnector::GetInst().EmitSignal(
+      IGDBus::SigType::Editable,
+      editor_appid,
+      editor_appid, -1,
+      util::GetCmdStr(util::CmdType::SetupReply),
+      g_variant_new("(is)", editable_id, raw == NULL ? "" : raw));
   } catch (Exception &ex) {
     LOGE("%s %d", ex.what(), ex.GetErrorCode());
-    return ex.GetErrorCode();
   }
-
-  if (emit_ret == false)
-    ret = WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
-
-  return ret;
+  return emit_signal_ret;
 }
 
 }  // namespace watchface_complication
index 0fbaf06..faef2a1 100644 (file)
@@ -28,8 +28,8 @@ namespace watchface_complication {
 
 class EXPORT_API ComplicationProvider : public IComplicationEvent {
  public:
-  explicit ComplicationProvider(const std::string& provider_id);
-  virtual ~ComplicationProvider();
+  explicit ComplicationProvider(const std::string& provider_id, bool mock);
+  virtual ~ComplicationProvider(); /* LCOV_EXCL_LINE */
 
  public:
   void OnDataUpdateRequest(const std::string& sender_appid,
@@ -39,6 +39,7 @@ class EXPORT_API ComplicationProvider : public IComplicationEvent {
 
   int NotifyDataUpdate();
   const std::string& GetProviderId() const;
+  static bool SetupReplyToEditor(std::string editor_appid, int editable_id, const char* raw);
 
  private:
   class Impl;
index 4cad514..680ef8f 100644 (file)
@@ -76,10 +76,9 @@ class CallbackInfo {
 class WatchComplicationProviderStub : public ComplicationProvider {
  public:
   explicit WatchComplicationProviderStub(const std::string& provider_id)
-    : ComplicationProvider(provider_id) {
+    : ComplicationProvider(provider_id, false) {
   }
 
-  virtual ~WatchComplicationProviderStub() = default;
   void OnDataUpdateRequest(const std::string& sender_appid,
                            ComplicationType type, const Bundle* context,
                            Bundle* shared_data) override {
@@ -133,7 +132,7 @@ extern "C" EXPORT_API int watchface_complication_provider_add_update_requested_c
     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
 
   std::string appid = DBManager::GetProviderAppId(provider_id);
-  if (appid.compare(ComplicationConnector::GetInst().GetAppId()) != 0) {
+  if (appid.compare(util::GetAppId()) != 0) {
     LOGE("Invalid provider id : %s", provider_id);
     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
   }
@@ -244,19 +243,10 @@ extern "C" EXPORT_API int watchface_complication_provider_setup_reply_to_editor(
     }
   }
 
-  try {
-    emit_signal_ret = ComplicationConnector::GetInst().EmitSignal(
-      ComplicationConnector::Editable,
+  emit_signal_ret = ComplicationProvider::SetupReplyToEditor(
       std::string(editor_appid),
-      std::string(editor_appid), -1,
-      ComplicationConnector::GetInst().GetCmdStr(
-          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;
-  }
+      strtol(editable_id, NULL, 10),
+      raw_data == NULL ? "" : reinterpret_cast<const char*>(raw_data));
   free(editor_appid);
   free(editable_id);
   free(raw_data);
index 686e52b..1890375 100644 (file)
@@ -38,37 +38,17 @@ namespace watchface_complication {
 
 class ComplicationConnector::Impl {
  public:
-  virtual ~Impl() = default;
+  virtual ~Impl() {
+    if (conn_)
+      g_object_unref(conn_);
+    if (pkgmgr_client_)
+      pkgmgr_client_free(pkgmgr_client_);
+  }
 
  private:
   friend class ComplicationConnector;
-
   Impl();
-  static void SignalCb(GDBusConnection* connection,
-                      const gchar* sender_name,
-                      const gchar* object_path,
-                      const gchar* interface_name,
-                      const gchar* signal_name,
-                      GVariant* parameters,
-                      void* user_data) {
-    IEventListener* rs = static_cast<IEventListener*>(user_data);
-
-    rs->OnSignal(connection, sender_name, object_path, interface_name,
-                 signal_name, parameters);
-  }
-
-  static void VanishCb(GDBusConnection* connection,
-      const gchar* name, gpointer user_data) {
-    IEventListener* rs = static_cast<IEventListener*>(user_data);
-    rs->OnVanish(name);
-  }
-
-  static void AppearCb(GDBusConnection* connection,
-      const gchar* name, const gchar* name_owner, gpointer user_data) {
-    IEventListener* rs = static_cast<IEventListener*>(user_data);
-    rs->OnAppear(name, name_owner);
-  }
-
+  /* LCOV_EXCL_START */
   static int PackageAppinfoCallback(const pkgmgrinfo_appinfo_h handle,
       void* user_data) {
     char* appid = NULL;
@@ -127,7 +107,7 @@ class ComplicationConnector::Impl {
           strcmp(current_pkg_event_.c_str(), "uninstall") == 0)) {
         LOGW("handling package event (%s)", current_pkg_event_.c_str());
         for (std::string& appid : package_app_list_) {
-          for (IPackageEventListener* pe : package_listener_list_) {
+          for (IPackageManager::IPackageEvent* pe : package_listener_list_) {
             if (strcmp(current_pkg_event_.c_str(), "disable_app") == 0) {
               LOGI("disabled cb (%s)", appid.c_str());
               pe->OnAppDisabled(appid);
@@ -143,13 +123,15 @@ class ComplicationConnector::Impl {
 
     return 0;
   }
+  /* LCOV_EXCL_STOP */
 
  private:
+  GDBusConnection* conn_ = NULL;
   pkgmgr_client* pkgmgr_client_ = NULL;
-  GDBusConnection* conn_ = nullptr;
-  IEventListener* listener_ = nullptr;
   std::string appid_;
-  static std::list<IPackageEventListener*> package_listener_list_;
+
+ private:
+  static std::list<IPackageManager::IPackageEvent*> package_listener_list_;
   static std::list<std::string> package_app_list_;
   static std::string current_pkg_event_;
 };
index 1cb0cd5..e434bda 100644 (file)
 #include "watchface-complication/complication-connector.h"
 #include "watchface-complication/complication-connector-implementation.h"
 #include "watchface-common/watchface-exception.h"
+#include "watchface-complication/gdbus-mock.h"
+#include "watchface-complication/package-manager-mock.h"
+#include "watchface-complication/package-manager.h"
+#include "watchface-complication/gdbus.h"
 
 #ifdef LOG_TAG
 #undef LOG_TAG
 #define LOG_TAG "WATCHFACE_COMPLICATION"
 #define LOG_TAG "WATCHFACE_COMPLICATION"
 
-#define COMPLICATION_BUS_NAME_PREFIX "org.tizen.watchface_complication._"
-#define COMPLICATION_PATH_PREFIX "/org/tizen/watchface_complication_"
-#define EDITABLE_PATH_PREFIX "/org/tizen/watchface_editable_"
-#define COMPLICATION_OBJECT_PATH "/org/tizen/watchface_complication"
-#define COMPLICATION_INTERFACE "org.tizen.watchface_complication"
-
 #define MAX_PACKAGE_STR_SIZE 512
 
 namespace watchface_complication {
-std::list<ComplicationConnector::IPackageEventListener*> ComplicationConnector::Impl::package_listener_list_;
+std::list<IPackageManager::IPackageEvent*> ComplicationConnector::Impl::package_listener_list_;
 std::list<std::string> ComplicationConnector::Impl::package_app_list_;
 std::string ComplicationConnector::Impl::current_pkg_event_;
 
-ComplicationConnector& ComplicationConnector::GetInst() {
+ComplicationConnector& ComplicationConnector::GetInst(bool mock) {
   static ComplicationConnector w_inst;
   int ret;
-  if (w_inst.impl_ == nullptr) {
+  if (w_inst.impl_ == nullptr && !mock) {
     ret = w_inst.Init();
     if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
       THROW(ret);
@@ -58,196 +56,83 @@ ComplicationConnector& ComplicationConnector::GetInst() {
 }
 
 ComplicationConnector::ComplicationConnector() = default;
-ComplicationConnector::~ComplicationConnector() = default;
 ComplicationConnector::Impl::Impl() = default;
 
-void ComplicationConnector::AddPackageEventListener(IPackageEventListener* pe) {
-  if (impl_->pkgmgr_client_ == NULL) {
-    impl_->pkgmgr_client_ = pkgmgr_client_new(PC_LISTENING);
-
-    if (impl_->pkgmgr_client_ == NULL) {
-      LOGE("fail to create pkgmgr client");
-      return;
-    }
-
-    if (pkgmgr_client_listen_status(impl_->pkgmgr_client_ ,
-        impl_->PkgmgrPackageStatusCb, NULL) <= 0) {
-      LOGE("fail to listen pkg status");
-      pkgmgr_client_free(impl_->pkgmgr_client_);
-      return;
-    }
-    LOGI("listen pkg status");
-  }
-
-  impl_->package_listener_list_.push_back(pe);
-}
-
-void ComplicationConnector::RemovePackageEventListener(IPackageEventListener* pe) {
-  impl_->package_listener_list_.remove(pe);
-  if (impl_->package_listener_list_.size() == 0) {
-    pkgmgr_client_free(impl_->pkgmgr_client_);
-    impl_->pkgmgr_client_ = NULL;
-  }
-}
-
-std::string ComplicationConnector::GetAppId() {
-  return impl_->appid_;
-}
-
-int ComplicationConnector::Watch(std::string appid, IEventListener* listener) {
-  int watcher_id;
-  std::string name;
-
-  LOGI("watch on : %s", appid.c_str());
-  try {
-    name = ComplicationConnector::GetInst().EncodeStr(Name, appid);
-  } catch (...) {
-    throw;
-  }
-
-  watcher_id = g_bus_watch_name_on_connection(
-      impl_->conn_,
-      name.c_str(),
-      G_BUS_NAME_WATCHER_FLAGS_NONE,
-      impl_->AppearCb,
-      impl_->VanishCb,
-      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;
-}
-
-void ComplicationConnector::UnWatch(int watcher_id) {
-  LOGI("unwatch : %d", watcher_id);
-  g_bus_unwatch_name(watcher_id);
-}
-
-bool ComplicationConnector::EmitSignal(SigType type, std::string target_id,
-                                       std::string id, int sub_id,
-                                       std::string cmd, GVariant* data) {
+bool ComplicationConnector::EmitSignal(IGDBus::SigType type,
+    std::string target_id, std::string id, int sub_id, std::string cmd,
+    GVariant* data) {
   GError* err = NULL;
   gboolean result = TRUE;
-  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);
+  std::string path = util::EncodeStr(
+      type == IGDBus::Complication ?
+        util::EncodeType::CompPath : util::EncodeType::EditablePath,
+        id, sub_id);
+  std::string name = util::EncodeStr(util::EncodeType::Name, target_id);
 
   LOGI("emit : %s, %s, %d, %s", target_id.c_str(), id.c_str(), sub_id,
                                 cmd.c_str());
   LOGI("emit signal %s, %s", name.empty() ? NULL : name.c_str(), path.c_str());
   result = g_dbus_connection_emit_signal(
-             impl_->conn_,
-             name.empty() ? NULL : name.c_str(),
-             path.c_str(),
-             COMPLICATION_INTERFACE,
-             cmd.c_str(), data, &err);
+            impl_->conn_,
+            name.empty() ? NULL : name.c_str(),
+            path.c_str(),
+            COMPLICATION_INTERFACE,
+            cmd.c_str(), data, &err);
   if (result == FALSE) {
     LOGE("g_dbus_connection_emit_signal() is failed");
     if (err != NULL) {
       LOGE("g_dbus_connection_emit_signal() err : %s",
-           err->message);
+          err->message);
       g_error_free(err);
     }
   } else {
     LOGI("Successfully emit signal to %s, %s, %s", name.c_str(), path.c_str(),
-         cmd.c_str());
+        cmd.c_str());
   }
   return result;
 }
 
-int ComplicationConnector::SubscribeSignal(SigType type, std::string id,
-    int sub_id, IEventListener* listener) {
-  int subscribe_id;
-
-  LOGI("subscribe : %s, %d", id.c_str(), sub_id);
-  std::string path;
-  try {
-    path = ComplicationConnector::GetInst().EncodeStr(
-                   type == Complication ? CompPath : EditablePath,
-                   id, sub_id);
-  } catch (...) {
-    throw;
-  }
-
-  subscribe_id = g_dbus_connection_signal_subscribe(
-                   impl_->conn_,
-                   NULL,
-                   COMPLICATION_INTERFACE,
-                   NULL,
-                   path.c_str(),
-                   NULL,
-                   G_DBUS_SIGNAL_FLAGS_NONE,
-                   impl_->SignalCb,
-                   listener,
-                   NULL);
-  if (subscribe_id == 0) {
-    LOGE("invalid 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;
+IGDBus* ComplicationConnector::CreateGDBus(bool mock) {
+  return mock ?
+         static_cast<IGDBus*>(new test::GDBusMock()) :
+         static_cast<IGDBus*>(new GDBus(impl_->conn_));
 }
 
-void ComplicationConnector::UnSubscribeSignal(int subscribe_id) {
-  if (subscribe_id > 0)
-    g_dbus_connection_signal_unsubscribe(impl_->conn_, subscribe_id);
+IPackageManager* ComplicationConnector::CreatePackageManager(bool mock) {
+  return mock ?
+         static_cast<IPackageManager*>(new test::PackageManagerMock()) :
+         static_cast<IPackageManager*>(new PackageManager());
 }
 
-std::string ComplicationConnector::EncodeStr(EncodeType type,
-    std::string appid) {
-  char* encoded_path;
-  std::string encoded_path_str;
-  std::string encoded_str;
-
-  if (appid.empty())
-    return "";
-
-  encoded_path = g_compute_checksum_for_string(G_CHECKSUM_MD5,
-                 appid.c_str(), -1);
-  if (encoded_path == NULL)
-    return "";
-
-  encoded_path_str = std::string(encoded_path);
-  if (type == ComplicationConnector::CompPath)
-    encoded_str = COMPLICATION_PATH_PREFIX + encoded_path_str;
-  else if (type == ComplicationConnector::EditablePath)
-    encoded_str = EDITABLE_PATH_PREFIX + encoded_path_str;
-  else
-    encoded_str = COMPLICATION_BUS_NAME_PREFIX + encoded_path_str;
-
-  free(encoded_path);
+void ComplicationConnector::WatchPackageEvent(IPackageManager::IPackageEvent* pe) {
+  if (impl_->pkgmgr_client_ == NULL) {
+    impl_->pkgmgr_client_ = pkgmgr_client_new(PC_LISTENING);
+    if (impl_->pkgmgr_client_ == NULL) {
+      LOGE("fail to create pkgmgr client");
+      return;
+    }
 
-  return encoded_str;
+    if (pkgmgr_client_listen_status(impl_->pkgmgr_client_ ,
+        impl_->PkgmgrPackageStatusCb, NULL) <= 0) {
+      LOGE("fail to listen pkg status");
+      pkgmgr_client_free(impl_->pkgmgr_client_);
+      return;
+    }
+    LOGI("listen pkg status");
+  }
+  impl_->package_listener_list_.push_back(pe);
 }
 
-std::string ComplicationConnector::EncodeStr(EncodeType type, std::string appid,
-    int compid) {
-  if (appid.empty())
-    return "";
-  std::string str = appid + "_" + std::to_string(compid);
-
-  return EncodeStr(type, str);
+void ComplicationConnector::UnWatchPackageEvent(IPackageManager::IPackageEvent* pe) {
+  impl_->package_listener_list_.remove(pe);
+  if (impl_->package_listener_list_.size() == 0) {
+    pkgmgr_client_free(impl_->pkgmgr_client_);
+    impl_->pkgmgr_client_ = NULL;
+  }
 }
 
 int ComplicationConnector::Init() {
   GError* error = NULL;
-  int pid = getpid();
-  int ret;
-  char appid[MAX_PACKAGE_STR_SIZE] = {0, };
   std::string encoded_name;
   int owner_id;
   std::unique_ptr<Impl> tmp_impl;
@@ -268,14 +153,19 @@ int ComplicationConnector::Init() {
     return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
   }
 
-  ret = aul_app_get_appid_bypid(pid, appid, sizeof(appid));
-  if (ret != AUL_R_OK) {
-    g_object_unref(tmp_impl->conn_);
-    LOGE("Fail to get appid %d", ret);
-    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;;
+  tmp_impl->pkgmgr_client_ = pkgmgr_client_new(PC_LISTENING);
+  if (tmp_impl->pkgmgr_client_ == NULL) {
+    LOGE("fail to create pkgmgr client");
+    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+  }
+
+  std::string appid = util::GetAppId();
+  if (appid.empty()) {
+    LOGE("fail to get appid");
+    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
   }
-  tmp_impl->appid_ = std::string(appid);
-  encoded_name = EncodeStr(ComplicationConnector::Name, tmp_impl->appid_);
+
+  encoded_name = util::EncodeStr(util::EncodeType::Name, appid);
   LOGI("own name %s", encoded_name.c_str());
   owner_id = g_bus_own_name_on_connection(tmp_impl->conn_, encoded_name.c_str(),
                                           G_BUS_NAME_OWNER_FLAGS_NONE,
@@ -290,41 +180,4 @@ int ComplicationConnector::Init() {
   return WATCHFACE_COMPLICATION_ERROR_NONE;
 }
 
-std::string ComplicationConnector::GetCmdStr(CmdType type) {
-  std::string ret;
-  switch (type) {
-  case CompUpdateRequest :
-    ret = "__COMP_UPDATE_REQUEST__";
-    break;
-  case CompUpdated :
-    ret = "__COMP_UPDATED__";
-    break;
-  case CompNotifyDataUpdate :
-    ret = "__COMP_NOTIFY_DATA_UPDATE__";
-    break;
-  case EditableEditRequest :
-    ret = "__EDITABLE_EDIT_REQUEST__";
-    break;
-  case EditableEditPreview :
-    ret = "__EDITABLE_EDIT_PREVIEW__";
-    break;
-  case EditableEditComplete :
-    ret = "__EDITABLE_EDIT_COMPLETE__";
-    break;
-  case EditableEditCancel :
-    ret = "__EDITABLE_EDIT_CANCEL__";
-    break;
-  case EditableEditReady :
-    ret = "__EDITABLE_EDIT_READY__";
-    break;
-  case SetupReply :
-    ret = "__SETUP_REPLY__";
-    break;
-  default :
-    break;
-  }
-
-  return ret;
-}
-
 }  // namespace watchface_complication
index a93af45..c8dbbf1 100644 (file)
 
 #include "watchface-complication/include/watchface-complication-internal.h"
 #include "watchface-common/watchface-exception.h"
+#include "watchface-complication/gdbus-interface.h"
+#include "watchface-complication/package-manager-interface.h"
 
 namespace watchface_complication {
 
 class EXPORT_API ComplicationConnector {
  public:
-  enum SigType {
-    Complication,
-    Editable
-  };
-
-  enum CmdType {
-    CompUpdateRequest,
-    CompUpdated,
-    CompNotifyDataUpdate,
-    EditableEditRequest,
-    EditableEditComplete,
-    EditableEditPreview,
-    EditableEditCancel,
-    EditableEditReady,
-    SetupReply
-  };
-
-  class IEventListener {
-   public:
-    virtual void OnSignal(GDBusConnection* connection,
-                          const std::string& sender_name,
-                          const std::string& object_path,
-                          const std::string& interface_name,
-                          const std::string& signal_name,
-                          GVariant* parameters) = 0;
-    virtual void OnVanish(const std::string& name) = 0;
-    virtual void OnAppear(const std::string& name,
-                        const std::string& name_owner) = 0;
-  };
-
-  class IPackageEventListener {
-   public:
-    virtual void OnAppDisabled(const std::string& appid) = 0;
-    virtual void OnAppUninstalled(const std::string& appid) = 0;
-  };
-
-  static ComplicationConnector& GetInst();
-  int Watch(std::string id, IEventListener* listener);
-  void UnWatch(int watcher_id);
-  bool EmitSignal(SigType type, std::string target_id, std::string id,
-                  int sub_id, std::string cmd, GVariant* data);
-  int SubscribeSignal(SigType type, std::string id, int sub_id,
-                      IEventListener* listener);
-  void UnSubscribeSignal(int subscribe_id);
-  std::string GetAppId();
-  std::string GetCmdStr(CmdType type);
-  void AddPackageEventListener(IPackageEventListener* pe);
-  void RemovePackageEventListener(IPackageEventListener* pe);
+  static ComplicationConnector& GetInst(bool mock = false);
+  IGDBus* CreateGDBus(bool mock);
+  IPackageManager* CreatePackageManager(bool mock);
+  bool EmitSignal(IGDBus::SigType type, std::string target_id, std::string id,
+    int sub_id, std::string cmd, GVariant* data);
+  void WatchPackageEvent(IPackageManager::IPackageEvent* pe);
+  void UnWatchPackageEvent(IPackageManager::IPackageEvent* pe);
 
  private:
   ComplicationConnector();
-  virtual ~ComplicationConnector();
   int Init();
 
  private:
-  enum EncodeType {
-    Name,
-    CompPath,
-    EditablePath
-  };
-  std::string EncodeStr(EncodeType type, std::string appid);
-  std::string EncodeStr(EncodeType type, std::string appid, int compid);
-
   class Impl;
   std::unique_ptr<Impl> impl_;
 };
index 4482b61..15232be 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "watchface-complication/complication.h"
 #include "watchface-complication/complication-connector.h"
+#include "watchface-complication/gdbus-interface.h"
 
 #ifdef LOG_TAG
 #undef LOG_TAG
@@ -36,8 +37,7 @@
 
 namespace watchface_complication {
 
-class Complication::Impl : ComplicationConnector::IEventListener,
-  ComplicationConnector::IPackageEventListener {
+class Complication::Impl : IGDBus::IGDBusEvent, IPackageManager::IPackageEvent {
  public:
   void OnSignal(GDBusConnection* connection,
                 const std::string& sender_name,
@@ -56,8 +56,7 @@ class Complication::Impl : ComplicationConnector::IEventListener,
 
   Impl(Complication* parent, int id, int supported_types, int supported_event_types,
        const std::string& default_provider_id,
-       ComplicationType default_type);
-  int FindCandidateDataIdx(std::string provider_id, int type);
+       ComplicationType default_type, bool mock);
   void RestoreStateOrSetDefault();
   int StoreSetting(int comp_id, std::string& provider_id,
                 ComplicationType type);
@@ -68,13 +67,11 @@ class Complication::Impl : ComplicationConnector::IEventListener,
   int UpdateCandidatesInfo();
   int MakeCandidatesList();
   int LoadPeriod();
-  int LoadLabel();
+  void LoadLabel();
   int LoadContext();
-  int LoadCurProviderAppid();
-  int LoadCurDataIdx();
-  int LoadPrevProviderInfo();
-  int LoadDefaultProviderInfo();
-  int UpdateLastDataFields();
+  int LoadCurProviderFromPrev();
+  int LoadCurProviderFromDefault();
+  void UpdateLastDataFields();
   int UpdateProviderInfo();
   int DeleteAppContext(const char* appid);
   int ReplaceUnavailableProvider(const char* deleted_appid);
@@ -82,6 +79,10 @@ class Complication::Impl : ComplicationConnector::IEventListener,
   int CheckNotSupported(std::string provider_id);
   int GetNotSupportedEvents(std::string provider_id);
   std::string GetNotSupportedPrivileges(std::string provider_id);
+  bool IsValidSender(GDBusConnection* connection,
+                    const std::string& sender_name);
+  void UpdatedProcess(GVariant* parameters);
+  void NotifyDataUpdateProcess(GVariant* parameters);
 
  private:
   Complication* parent_;
@@ -115,6 +116,9 @@ class Complication::Impl : ComplicationConnector::IEventListener,
   IEditable::EditableState ed_state_ = Complete;
   guint periodic_timer_ = 0;
   std::map<std::string, int> sender_info_;
+  std::unique_ptr<IGDBus> gdbus_ = nullptr;
+  std::unique_ptr<IPackageManager> package_ = nullptr;
+  bool mock_ = false;
 };
 
 }  // namespace watchface_complication
index 00af3c9..d02dd60 100644 (file)
@@ -43,62 +43,131 @@ const std::string Complication::Impl::supported_events_error_key_ = "__SUPPORTED
 const std::string Complication::Impl::privilege_error_key_ = "__PRIVILEGE_ERROR_KEY__";
 Complication::Complication(int id, int supported_types, int supported_event_types,
                            const std::string& default_provider_id,
-                           ComplicationType default_type)
+                           ComplicationType default_type, bool mock)
   : impl_(new Impl(this, id, supported_types, supported_event_types,
-      default_provider_id, default_type)) {
-  ComplicationConnector::GetInst().AddPackageEventListener(impl_.get());
+      default_provider_id, default_type, mock)) {
 }
 
 Complication::~Complication() {
+}
+
+int Complication::Impl::LoadCurProviderFromPrev() {
+  char* prev_provider_id = NULL;
+  char* prev_provider_type = NULL;
+  std::string prev_provider_id_str;
+  std::unique_ptr<Bundle> setting_data;
+
   try {
-    ComplicationConnector::GetInst().RemovePackageEventListener(impl_.get());
-  } catch (Exception &ex) {
+    setting_data = EditablesManager::GetInst(mock_).LoadSetting(complication_id_);
+  } catch (watchface_complication::Exception &ex) {
     LOGE("%s %d", ex.what(), ex.GetErrorCode());
+    return ex.GetErrorCode();
   }
+
+  if (setting_data == nullptr) {
+    LOGW("no prev setting info");
+    return WATCHFACE_COMPLICATION_ERROR_PROVIDER_NOT_AVAILABLE;
+  }
+
+  bundle_get_str(setting_data.get()->GetRaw(), provider_id_key_.c_str(),
+      &prev_provider_id);
+  bundle_get_str(setting_data.get()->GetRaw(), provider_type_key_.c_str(),
+      &prev_provider_type);
+
+  if (prev_provider_id == NULL) {
+    LOGW("No prev provider id");
+    return WATCHFACE_COMPLICATION_ERROR_PROVIDER_NOT_AVAILABLE;
+  }
+
+  if (prev_provider_id)
+    prev_provider_id_str = std::string(prev_provider_id);
+
+  LOGI("get setting from bundle %s, %s", prev_provider_id, prev_provider_type);
+
+  std::string appid = DBManager::GetProviderAppId(prev_provider_id);
+  if (appid.empty() || !DBManager::IsProviderExist(prev_provider_id_str,
+          strtol((const char*)prev_provider_type, NULL, 10))) {
+    LOGE("Fail to get provider appid");
+    return WATCHFACE_COMPLICATION_ERROR_PROVIDER_NOT_AVAILABLE;
+  }
+  cur_provider_appid_ = appid;
+
+  int ret = CheckNotSupported(prev_provider_id_str);
+  if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
+    return ret;
+
+  cur_provider_id_ = prev_provider_id_str;
+  cur_type_ = static_cast<ComplicationType>(
+    strtol((const char*)prev_provider_type, NULL, 10));
+  LOGI("Successfully get previous provider info");
+  return WATCHFACE_COMPLICATION_ERROR_NONE;
 }
 
-Complication::Impl::Impl(Complication* parent, int id,
-                         int supported_types,
-                         int supported_event_types,
-                         const std::string& default_provider_id,
-                         ComplicationType default_type)
-  : parent_(parent), complication_id_(id), supported_types_(supported_types),
-    supported_event_types_(supported_event_types | EventNone),
-    default_provider_id_(default_provider_id), default_type_(default_type) {
-  int ret;
-  ret = LoadPrevProviderInfo();
+int Complication::Impl::LoadCurProviderFromDefault() {
+  cur_type_ = default_type_;
+  cur_provider_id_ = default_provider_id_;
+
+  if (!DBManager::IsProviderExist(default_provider_id_,
+          static_cast<int>(default_type_))) {
+    LOGE("Default provider do not exist (%s)(%d)",
+        default_provider_id_.c_str(), default_type_);
+    return WATCHFACE_COMPLICATION_ERROR_PROVIDER_NOT_AVAILABLE;
+  }
+
+  int ret = CheckNotSupported(default_provider_id_);
+  if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
+    return ret;
+
+  default_provider_appid_ =
+          DBManager::GetProviderAppId(default_provider_id_.c_str());
+  if (default_provider_appid_.empty()) {
+    LOGE("fail to get appid");
+    return WATCHFACE_COMPLICATION_ERROR_PROVIDER_NOT_AVAILABLE;
+  }
+
+  LOGI("Successfully get default provider info");
+  return WATCHFACE_COMPLICATION_ERROR_NONE;
+}
+
+int Complication::Init() {
+  int ret = impl_->LoadCurProviderFromPrev();
   if (ret == WATCHFACE_COMPLICATION_ERROR_PROVIDER_NOT_AVAILABLE) {
-    ret = LoadDefaultProviderInfo();
+    ret = impl_->LoadCurProviderFromDefault();
     if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
       LOGE("cannot load default provider info (%d)", ret);
   }
+  if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
+    return ret;
+  impl_->UpdateLastDataFields();
+  ret = impl_->LoadPeriod();
+  if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
+    return ret;
 
-  if (ret == WATCHFACE_COMPLICATION_ERROR_NONE) {
-    /* Make candidates and set current index */
-    UpdateCandidatesInfo();
-    ret = UpdateProviderInfo();
-    if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
-      THROW(ret);
+  impl_->package_.get()->Watch(impl_.get());
 
-    default_provider_appid_ =
-          DBManager::GetProviderAppId(default_provider_id_.c_str());
-    if (default_provider_appid_.empty())
-      LOGE("fail to get default provider info");
-  }
+  return impl_->UpdateProviderInfo();
+}
+
+Complication::Impl::Impl(Complication* parent, int id,
+                         int supported_types,
+                         int supported_event_types,
+                         const std::string& default_provider_id,
+                         ComplicationType default_type, bool mock)
+  : parent_(parent), complication_id_(id), supported_types_(supported_types),
+    supported_event_types_(supported_event_types | 1),
+    default_provider_id_(default_provider_id),
+    default_type_(default_type),
+    gdbus_(std::unique_ptr<IGDBus>(ComplicationConnector::GetInst(mock).CreateGDBus(mock))),
+    package_(std::unique_ptr<IPackageManager>(ComplicationConnector::GetInst(mock).CreatePackageManager(mock))),
+    mock_(mock) {
+  LOGI("complication create %d", complication_id_);
 }
 
 Complication::Impl::~Impl() {
   LOGI("complication destroy %d", complication_id_);
-  if (subscribe_id_ > 0) {
-    try {
-      ComplicationConnector::GetInst().UnSubscribeSignal(subscribe_id_);
-    } catch (Exception &ex) {
-      LOGE("%s %d", ex.what(), ex.GetErrorCode());
-    }
-  }
-
   if (periodic_timer_)
     g_source_remove(periodic_timer_);
+  package_.get()->UnWatch(this);
 }
 
 void Complication::Impl::OnVanish(const std::string& name) {
@@ -108,7 +177,7 @@ void Complication::Impl::OnVanish(const std::string& name) {
   if (sender_info == sender_info_.end())
     return;
 
-  ComplicationConnector::GetInst().UnWatch(si);
+  gdbus_.get()->UnWatch(si);
   sender_info_.erase(name);
 }
 
@@ -116,201 +185,90 @@ void Complication::Impl::OnAppear(const std::string& name,
     const std::string& name_owner) {
 }
 
-void Complication::Impl::OnSignal(GDBusConnection* connection,
-                                  const std::string& sender_name,
-                                  const std::string& object_path,
-                                  const std::string& interface_name,
-                                  const std::string& signal_name,
-                                  GVariant* parameters) {
+bool Complication::Impl::IsValidSender(GDBusConnection* connection,
+                                  const std::string& sender_name) {
+  std::string sender_appid = util::GetSenderAppid(connection, sender_name);
+  if (sender_appid.empty()) {
+    LOGI("invalid sender_appid");
+    return false;
+  }
+
+  std::string provider_appid =
+      DBManager::GetProviderAppId(cur_provider_id_.c_str());
+  if (provider_appid.empty()) {
+    LOGI("invalid provider_appid");
+    return false;
+  }
+
+  if (provider_appid.compare(sender_appid) != 0) {
+    LOGI("invalid sender_appid %s", sender_appid.c_str());
+    return false;
+  }
+
+  int watcher_id = gdbus_.get()->Watch(sender_appid, this);
+  sender_info_[sender_name] = watcher_id;
+
+  return true;
+}
+
+void Complication::Impl::UpdatedProcess(GVariant* parameters) {
   char* provider_id;
   int type;
   int complication_id;
   bundle_raw* raw = NULL;
-  LOGI("signal_name: %s , %s ", signal_name.c_str(), sender_name.c_str());
 
-  auto sender_info = sender_info_.find(sender_name);
-  if (sender_info == sender_info_.end()) {
-    std::string sender_appid = util::GetSenderAppid(connection, sender_name);
-    if (sender_appid.empty()) {
-      LOGI("invalid sender_appid");
-      return;
-    }
-    std::string provider_appid =
-        DBManager::GetProviderAppId(cur_provider_id_.c_str());
-    if (provider_appid.empty()) {
-      LOGI("invalid provider_appid");
-      return;
-    }
-    if (provider_appid.compare(sender_appid) != 0) {
-      LOGI("invalid sender_appid %s", sender_appid.c_str());
-      return;
-    }
-
-    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;
-    } catch (...) {
-    }
-  }
-
-  if (signal_name.compare(ComplicationConnector::GetInst().GetCmdStr(
-          ComplicationConnector::CompUpdated)) == 0) {
-    g_variant_get(parameters, "(&sii&s)", &provider_id, &type,
+  g_variant_get(parameters, "(&sii&s)", &provider_id, &type,
         &complication_id, &raw);
-    if (complication_id != complication_id_
-         || type != cur_type_
-         || strcmp(cur_provider_id_.c_str(), provider_id) != 0) {
-      LOGI("It's not mine %d:%d, %d:%d", complication_id, complication_id_,
-          type, cur_type_);
-      return;
-    }
+  if (complication_id != complication_id_
+        || type != cur_type_
+        || strcmp(cur_provider_id_.c_str(), provider_id) != 0) {
+    LOGI("It's not mine %d:%d, %d:%d", complication_id, complication_id_,
+        type, cur_type_);
+    return;
+  }
 
+  if (raw != NULL) {
     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;
+        LOGI("data: %s, %d, cur_type :%d",
+            provider_id, complication_id, cur_type_);
+        parent_->OnDataUpdated(std::string(provider_id), cur_type_, last_data_);
     } 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(
-          std::string(provider_id), cur_type_, last_data_);
-    }
-  } else if (signal_name.compare(ComplicationConnector::GetInst().GetCmdStr(
-          ComplicationConnector::CompNotifyDataUpdate)) == 0) {
-    g_variant_get(parameters, "(&s)", &provider_id);
-    if (strcmp(cur_provider_id_.c_str(), provider_id) != 0) {
-      LOGI("It's not mine %s", provider_id);
-      return;
-    }
-    parent_->OnNotifyDataUpdate();
   }
 }
 
-int Complication::Impl::FindCandidateDataIdx(std::string provider_id,
-    int type) {
-  int idx = 0;
-  int ret = -1;
-  for (auto& i : candidates_list_) {
-    char* temp_provider_id = NULL;
-    char* temp_type = NULL;
-    Bundle& data = *(i.get());
-    bundle_get_str(data.GetRaw(), provider_id_key_.c_str(), &temp_provider_id);
-    bundle_get_str(data.GetRaw(), provider_type_key_.c_str(), &temp_type);
-    if (temp_provider_id != NULL && temp_type != NULL) {
-      if (strcmp(temp_provider_id, provider_id.c_str()) == 0
-          && atoi(temp_type) == type) {
-        ret = idx;
-        LOGI("find cur idx %d", ret);
-        break;
-      }
-    }
-    idx++;
-  }
-  return ret;
-}
-
-int Complication::Impl::LoadContext() {
-  context_data_ = EditablesManager::GetInst().LoadContext(complication_id_,
-      cur_provider_id_.c_str());
-  try {
-    if (context_data_ != nullptr)
-      last_context_data_.reset(new Bundle(context_data_.get()->GetRaw()));
-  } catch (...) {
-    LOGE("Out of memory");
-    return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
-  }
-  return WATCHFACE_COMPLICATION_ERROR_NONE;
-}
-
-int Complication::Impl::LoadCurProviderAppid() {
-  std::string appid = DBManager::GetProviderAppId(cur_provider_id_.c_str());
-  if (appid.empty()) {
-    LOGE("Fail to get provider appid");
-    return WATCHFACE_COMPLICATION_ERROR_PROVIDER_NOT_AVAILABLE;
-  }
-  cur_provider_appid_ = appid;
-  LOGI("cur provider appid (%s)", cur_provider_appid_.c_str());
-  return WATCHFACE_COMPLICATION_ERROR_NONE;
-}
-
-int Complication::Impl::LoadCurDataIdx() {
-  int ret = FindCandidateDataIdx(cur_provider_id_, cur_type_);
-  if (ret == -1) {
-    LOGE("Fail to find data index (%s)(%d)", cur_provider_id_.c_str(), cur_type_);
-    return WATCHFACE_COMPLICATION_ERROR_NO_DATA;
+void Complication::Impl::NotifyDataUpdateProcess(GVariant* parameters) {
+  char* provider_id;
+  g_variant_get(parameters, "(&s)", &provider_id);
+  if (strcmp(cur_provider_id_.c_str(), provider_id) != 0) {
+    LOGI("It's not mine %s", provider_id);
+    return;
   }
-
-  cur_data_idx_ = ret;
-  return WATCHFACE_COMPLICATION_ERROR_NONE;
+  parent_->OnNotifyDataUpdate();
 }
 
-int Complication::Impl::LoadPrevProviderInfo() {
-  char* prev_provider_id = NULL;
-  char* prev_provider_type = NULL;
-  std::string prev_provider_id_str;
-  std::unique_ptr<Bundle> setting_data;
-
-  try {
-    setting_data = EditablesManager::GetInst().LoadSetting(complication_id_);
-  } catch (watchface_complication::Exception &ex) {
-    LOGE("%s %d", ex.what(), ex.GetErrorCode());
-    return ex.GetErrorCode();
-  }
-
-  if (setting_data != nullptr) {
-    bundle_get_str(setting_data.get()->GetRaw(), provider_id_key_.c_str(),
-        &prev_provider_id);
-    bundle_get_str(setting_data.get()->GetRaw(), provider_type_key_.c_str(),
-        &prev_provider_type);
-    if (prev_provider_id)
-      prev_provider_id_str = std::string(prev_provider_id);
-
-    LOGI("get setting from bundle %s, %s", prev_provider_id, prev_provider_type);
-  }
-
-  if (prev_provider_id &&
-      DBManager::IsProviderExist(prev_provider_id_str,
-          atoi((const char*)prev_provider_type))) {
-
-    int ret = CheckNotSupported(prev_provider_id_str);
-    if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
-      return ret;
-
-    cur_provider_id_ = std::string(prev_provider_id);
-    cur_type_ = static_cast<ComplicationType>(atoi((const char*)prev_provider_type));
-    LOGI("Successfully get previous provider info");
-    return WATCHFACE_COMPLICATION_ERROR_NONE;
-  }
-
-  return WATCHFACE_COMPLICATION_ERROR_PROVIDER_NOT_AVAILABLE;
-}
+void Complication::Impl::OnSignal(GDBusConnection* connection,
+                                  const std::string& sender_name,
+                                  const std::string& object_path,
+                                  const std::string& interface_name,
+                                  const std::string& signal_name,
+                                  GVariant* parameters) {
+  LOGI("signal_name: %s , %s ", signal_name.c_str(), sender_name.c_str());
 
-int Complication::Impl::LoadDefaultProviderInfo() {
-  cur_type_ = default_type_;
-  cur_provider_id_ = default_provider_id_;
+  auto sender_info = sender_info_.find(sender_name);
+  if (sender_info == sender_info_.end() &&
+      !IsValidSender(connection, sender_name))
+    return;
 
-  if (!DBManager::IsProviderExist(default_provider_id_,
-          static_cast<int>(default_type_))) {
-    LOGE("Default provider do not exist (%s)(%d)",
-        default_provider_id_.c_str(), default_type_);
-    return WATCHFACE_COMPLICATION_ERROR_PROVIDER_NOT_AVAILABLE;
+  if (signal_name.compare(util::GetCmdStr(util::CompUpdated)) == 0) {
+    UpdatedProcess(parameters);
+  } else if (signal_name.compare(
+      util::GetCmdStr(util::CompNotifyDataUpdate)) == 0) {
+    NotifyDataUpdateProcess(parameters);
   }
-
-  int ret = CheckNotSupported(default_provider_id_);
-  if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
-    return ret;
-
-  LOGI("Successfully get default provider info");
-  return WATCHFACE_COMPLICATION_ERROR_NONE;
 }
 
 int Complication::Impl::StoreSetting(int comp_id, std::string& provider_id,
@@ -337,7 +295,7 @@ int Complication::Impl::StoreSetting(int comp_id, std::string& provider_id,
   bundle_free(setting_data);
 
   try {
-    ret = EditablesManager::GetInst().StoreSetting(comp_id, raw_data);
+    ret = EditablesManager::GetInst(mock_).StoreSetting(comp_id, raw_data);
     if (ret != WATCHFACE_COMPLICATION_ERROR_NONE) {
       free(raw_data);
       return ret;
@@ -374,9 +332,12 @@ IEditable::Highlight* Complication::GetHighlight() {
   return impl_->highlight_.get();
 }
 
+/*
+Complication make candidates automatically, so we don't need it
+*/
 int Complication::SetCandidates(
     std::list<std::unique_ptr<Bundle>> candidates_list) {
-  return impl_->UpdateCandidatesInfo();
+  return WATCHFACE_COMPLICATION_ERROR_NONE;
 }
 
 std::list<std::unique_ptr<Bundle>> const& Complication::GetCandidates() const {
@@ -423,7 +384,7 @@ int Complication::Impl::DeleteAppContext(const char* appid) {
   int ret = WATCHFACE_COMPLICATION_ERROR_NONE;
   std::list<std::string> list = DBManager::GetProviderListWithAppId(appid);
   for (std::string& info : list) {
-    ret = EditablesManager::GetInst().DeleteContext(editable_id_, info.c_str());
+    ret = EditablesManager::GetInst(mock_).DeleteContext(editable_id_, info.c_str());
     if (ret != WATCHFACE_COMPLICATION_ERROR_NONE) {
       LOGE("delete editable context fail %d", ret);
       return ret;
@@ -454,7 +415,7 @@ int Complication::Impl::ReplaceUnavailableProvider(const char* deleted_appid) {
         default_provider_appid_.c_str());
     ret = WATCHFACE_COMPLICATION_ERROR_PROVIDER_NOT_AVAILABLE;
   } else {
-    ret = LoadDefaultProviderInfo();
+    ret = LoadCurProviderFromDefault();
   }
 
   if (ret == WATCHFACE_COMPLICATION_ERROR_PROVIDER_NOT_AVAILABLE) {
@@ -472,82 +433,44 @@ void Complication::Impl::OnAppDisabled(const std::string& appid) {
 }
 
 void Complication::Impl::OnAppUninstalled(const std::string& appid) {
-  pkgmgrinfo_appinfo_h app_handle;
-
-  int ret = pkgmgrinfo_appinfo_get_disabled_appinfo(appid.c_str(), &app_handle);
-  if (ret != PMINFO_R_OK)
+  if (package_.get()->CheckDisabled(appid))
     DeleteAppContext(appid.c_str());
 
   ReplaceUnavailableProvider(appid.c_str());
 }
 
-int Complication::Impl::UpdateLastDataFields() {
-  int ret;
-
-  last_provider_id_ = cur_provider_id_;
-  last_type_ = cur_type_;
-  last_data_idx_ = cur_data_idx_;
-  ret = LoadPeriod();
-  if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
-    return ret;
-  ret = LoadLabel();
-  return ret;
-}
-
 /*
 * update provider relate information according to
-* cur_provider_id_, cur_provider_type_
+* cur_provider_id_, cur_provider_type_ except peiod.
+* period will be updated when
 */
 int Complication::Impl::UpdateProviderInfo() {
   /* Update cur_data_idx_ */
-  int ret = LoadCurDataIdx();
+  int ret = UpdateCandidatesInfo();
   if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
     return ret;
 
-  /* Update cur_provider_appid_ */
-  ret = LoadCurProviderAppid();
-  if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
-    return ret;
-
-  /* Update cur_provider_appid_ */
+  LoadLabel();
+  /* Update context info */
   ret = LoadContext();
   if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
     return ret;
 
-  /* Update periodic_timer_ */
-  ret = LoadPeriod();
-  if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
-    return ret;
-
-  /* Update name_ */
-  ret = LoadLabel();
-  if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
-    return ret;
-
-  if (cur_type_ != NoData) {
-    try {
-      subscribe_id_ = ComplicationConnector::GetInst().SubscribeSignal(
-                      ComplicationConnector::Complication, cur_provider_id_,
-                      -1, this);
-    } catch (Exception &ex) {
-      LOGE("%s %d", ex.what(), ex.GetErrorCode());
-      return ex.GetErrorCode();
-    }
-    LOGI("subscribe signal %d %d ", subscribe_id_, cur_type_);
-  }
+  subscribe_id_ = gdbus_.get()->SubscribeSignal(
+      IGDBus::Complication, cur_provider_id_, -1, this);
+  if (subscribe_id_ == 0)
+    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
+  LOGI("subscribe signal %d %d ", subscribe_id_, cur_type_);
 
   return ret;
 }
 
-int Complication::Impl::LoadLabel() {
+void Complication::Impl::LoadLabel() {
   std::string label = DBManager::GetLabel(cur_provider_id_.c_str());
-  if (!label.empty()) {
+  if (!label.empty())
     name_ =  label;
-  } else {
+  else
     LOGW("Fail to load label");
-    return WATCHFACE_COMPLICATION_ERROR_NO_DATA;
-  }
-  return WATCHFACE_COMPLICATION_ERROR_NONE;
 }
 
 int Complication::Impl::LoadPeriod() {
@@ -574,13 +497,23 @@ gboolean Complication::PeriodCallback(gpointer user_data) {
   return G_SOURCE_CONTINUE;
 }
 
+void Complication::Impl::UpdateLastDataFields() {
+  last_provider_id_ = cur_provider_id_;
+  last_type_ = cur_type_;
+  last_data_idx_ = cur_data_idx_;
+}
+
+/*
+Store current provider info in DB & update periodic timer
+*/
 int Complication::UpdateLastData() {
   int ret = impl_->StoreSetting(impl_->complication_id_,
       impl_->cur_provider_id_, impl_->cur_type_);
   if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
     return ret;
 
-  ret = impl_->UpdateLastDataFields();
+  impl_->UpdateLastDataFields();
+  ret = impl_->LoadPeriod();
   if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
     return ret;
 
@@ -618,22 +551,15 @@ int Complication::SetCurDataIdx(int cur_data_idx) {
     if (provider_id != NULL)
       impl_->cur_provider_id_ = std::string(provider_id);
     if (type != NULL)
-      impl_->cur_type_ = static_cast<ComplicationType>(atoi(type));
+      impl_->cur_type_ = static_cast<ComplicationType>(strtol(type, NULL, 10));
   }
 
   impl_->cur_data_idx_ = cur_data_idx;
   LOGI("cur idx %d, cur provider %s, cur type %d", impl_->cur_data_idx_,
     impl_->cur_provider_id_.c_str(), impl_->cur_type_);
-
-  try {
-    ComplicationConnector::GetInst().UnSubscribeSignal(impl_->subscribe_id_);
-  } catch (Exception &ex) {
-    LOGE("%s %d", ex.what(), ex.GetErrorCode());
-    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
-  }
-
+  impl_->gdbus_.get()->UnSubscribeSignal(impl_->subscribe_id_);
   if (impl_->cur_type_ == NoData) {
-    impl_->subscribe_id_ = -1;
+    impl_->subscribe_id_ = 0;
   } else {
     ret = impl_->UpdateProviderInfo();
     LOGI("subscribe signal %d", impl_->subscribe_id_);
@@ -649,23 +575,39 @@ const char* Complication::GetCurProviderId() {
   return NULL;
 }
 
-const char* Complication::GetProviderId(const Bundle* data) {
+const char* Complication::GetProviderId(const Bundle* candidate_data) {
   char* provider_id = NULL;
 
-  if (data == NULL)
+  if (candidate_data == NULL)
     return NULL;
 
-  bundle_get_str(const_cast<Bundle*>(data)->GetRaw(),
+  bundle_get_str(const_cast<Bundle*>(candidate_data)->GetRaw(),
       impl_->provider_id_key_.c_str(), &provider_id);
 
   return provider_id;
 }
 
+int Complication::GetProviderType(const Bundle* candidate_data) {
+  char* provider_type = NULL;
+  int ret = 0;
+
+  if (candidate_data == NULL)
+    return ret;
+
+  bundle_get_str(const_cast<Bundle*>(candidate_data)->GetRaw(),
+      impl_->provider_type_key_.c_str(), &provider_type);
+
+  if (provider_type)
+    ret = strtol(provider_type, NULL, 10);
+
+  return ret;
+}
+
 int Complication::GetCurType() {
   return static_cast<int>(impl_->cur_type_);
 }
 
-const std::string& Complication::GetName() {
+const std::string& Complication::GetLabel() {
   return impl_->name_;
 }
 
@@ -678,6 +620,7 @@ void Complication::SetLabel(const std::string& name) {
 
 void Complication::OnEditableUpdated(int selected_idx,
     IEditable::EditableState state) {
+
   if (state == OnGoing) {
     LOGI("ongoing editing : %d", impl_->complication_id_);
     std::unique_ptr<Bundle> ptr = nullptr;
@@ -703,10 +646,12 @@ void Complication::OnProviderError(const std::string& provider_id,
     ComplicationType type, int error) {
 }
 
+/* LCOV_EXCL_START */
 void Complication::OnDataUpdated(const std::string& provider_id,
                                  ComplicationType type,
                                  const std::unique_ptr<Bundle>& data) {
 }
+/* LCOV_EXCL_STOP */
 
 void Complication::OnNotifyDataUpdate() {
   SendDataUpdateRequest();
@@ -750,8 +695,16 @@ int Complication::SendDataUpdateRequest() {
     return WATCHFACE_COMPLICATION_ERROR_PROVIDER_NOT_AVAILABLE;
   }
 
+  if (impl_->mock_) {
+    std::unique_ptr<Bundle> ptr = nullptr;
+    ptr = DBManager::GetDefaultData(impl_->cur_provider_id_.c_str(),
+        static_cast<int>(impl_->cur_type_));
+    OnDataUpdated(impl_->cur_provider_id_, impl_->cur_type_, ptr);
+    return WATCHFACE_COMPLICATION_ERROR_NONE;
+  }
+
   ret = aul_complication_update_request(
-            ComplicationConnector::GetInst().GetAppId().c_str(),
+            util::GetAppId().c_str(),
             provider_appid.c_str(), getuid());
   LOGI("Launch the provider app: %d, %s", ret, provider_appid.c_str());
 
@@ -766,23 +719,19 @@ 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();
-  }
+
+  emit_ret = impl_->gdbus_.get()->EmitSignal(
+    IGDBus::SigType::Complication,
+    provider_appid,
+    impl_->cur_provider_id_,
+    -1,
+    util::GetCmdStr(util::CompUpdateRequest),
+    g_variant_new("(siis)",
+                  util::GetAppId().c_str(),
+                  impl_->complication_id_,
+                  impl_->cur_type_,
+                  context_data_raw));
+
 
   if (emit_ret == false)
     ret = WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
@@ -836,20 +785,13 @@ int Complication::UpdateLastContext() {
   }
 
   try {
-    int ret = EditablesManager::GetInst().StoreContext(impl_->complication_id_,
-        impl_->cur_provider_id_.c_str(), *impl_->context_data_.get());
+    int ret = EditablesManager::GetInst(impl_->mock_).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;
+    impl_->last_context_data_.reset(
+        new Bundle((impl_->context_data_.get())->GetRaw()));
   } catch (Exception &ex) {
     LOGE("%s %d", ex.what(), ex.GetErrorCode());
     return ex.GetErrorCode();
@@ -902,18 +844,14 @@ int Complication::TouchLaunch(watchface_complication_event_type_e event_type) {
     LOGE("Fail to encode bundle");
     return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
   }
-  try {
-    ret = aul_complication_launch_with_extra_data(
-            ComplicationConnector::GetInst().GetAppId().c_str(),
-            provider_appid.c_str(), getuid(), TOUCH_LAUNCH_DATA_KEY,
-            reinterpret_cast<char*>(raw_data));
-  } catch (Exception &ex) {
-    LOGE("%s %d", ex.what(), ex.GetErrorCode());
-    ret = ex.GetErrorCode();
-  }
+
+  ret = aul_complication_launch_with_extra_data(
+          util::GetAppId().c_str(),
+          provider_appid.c_str(), getuid(), TOUCH_LAUNCH_DATA_KEY,
+          reinterpret_cast<char*>(raw_data));
   free(raw_data);
 
-  LOGI("Touch launch the provider app: %d, %s", ret, provider_appid.c_str());
+  LOGI("Touch launch the %s : %d", provider_appid.c_str(), ret);
   if (ret != AUL_R_OK) {
     if (ret == AUL_R_EILLACC)
       return WATCHFACE_COMPLICATION_ERROR_PERMISSION_DENIED;
@@ -956,16 +894,21 @@ std::string Complication::Impl::GetNotSupportedPrivileges(
 
 int Complication::Impl::GetNotSupportedEvents(
     std::string provider_id) {
+
   int required_events = DBManager::GetRequiredSupportEvents(provider_id);
+  int not_supported_events = 0;
 
   LOGI("required events (%d) supported events(%d)",
       required_events, supported_event_types_);
   if (required_events > 0) {
-    return (required_events & supported_event_types_) ^ required_events;
+    not_supported_events =
+      (required_events & supported_event_types_) ^ required_events;
   } else {
     LOGE("fail to get required events");
     return -1;
   }
+
+  return not_supported_events;
 }
 
 int Complication::Impl::AddCandidate(std::string provider_id, int type) {
@@ -1023,7 +966,6 @@ int Complication::Impl::AddCandidates(std::string provider_id, int types) {
 int Complication::Impl::AddCandidates(int types) {
   std::list<std::unique_ptr<DBManager::ProviderInfo>> provider_list
       = DBManager::GetProviderListWithTypes(types);
-
   for (auto& info : provider_list) {
     int ret = AddCandidate(info.get()->GetProviderId(), info.get()->GetType());
     if (ret != WATCHFACE_COMPLICATION_ERROR_NONE) {
@@ -1031,7 +973,6 @@ int Complication::Impl::AddCandidates(int types) {
       return ret;
     }
   }
-
   return WATCHFACE_COMPLICATION_ERROR_NONE;
 }
 
@@ -1066,15 +1007,40 @@ int Complication::Impl::MakeCandidatesList() {
   return WATCHFACE_COMPLICATION_ERROR_NONE;
 }
 
+int Complication::Impl::LoadContext() {
+  context_data_ = EditablesManager::GetInst(mock_).LoadContext(complication_id_,
+      cur_provider_id_.c_str());
+  try {
+    if (context_data_ != nullptr)
+      last_context_data_.reset(new Bundle(context_data_.get()->GetRaw()));
+  } catch (...) {
+    LOGE("Out of memory");
+    return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
+  }
+  return WATCHFACE_COMPLICATION_ERROR_NONE;
+}
+
 int Complication::Impl::UpdateCandidatesInfo() {
   int ret = MakeCandidatesList();
   if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
       return ret;
 
-  int idx = FindCandidateDataIdx(cur_provider_id_, cur_type_);
-  if (idx != -1) {
-    cur_data_idx_ = idx;
-    ret = UpdateLastDataFields();
+  int idx = 0;
+  for (auto& i : candidates_list_) {
+    char* temp_provider_id = NULL;
+    char* temp_type = NULL;
+    Bundle& data = *(i.get());
+    bundle_get_str(data.GetRaw(), provider_id_key_.c_str(), &temp_provider_id);
+    bundle_get_str(data.GetRaw(), provider_type_key_.c_str(), &temp_type);
+    if (temp_provider_id != NULL && temp_type != NULL) {
+      if (strcmp(temp_provider_id, cur_provider_id_.c_str()) == 0
+          && strtol(temp_type, NULL, 10) == cur_type_) {
+        cur_data_idx_ = idx;
+        LOGI("find cur idx %d", idx);
+        break;
+      }
+    }
+    idx++;
   }
 
   return ret;
@@ -1084,7 +1050,7 @@ int Complication::ApplyAllowedList(
       std::list<std::unique_ptr<ProviderInfo>> allowed_list) {
   impl_->allowed_list_ = std::move(allowed_list);
   impl_->candidates_list_.clear();
-  return impl_->UpdateCandidatesInfo();
+  return impl_->UpdateProviderInfo();
 }
 
 int Complication::ClearAllowedList() {
index 5cb7869..baa8c47 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "watchface-complication-provider/complication-provider-event-interface.h"
 #include "watchface-complication/editable-interface.h"
+#include "watchface-complication/gdbus-interface.h"
 #include "watchface-complication/complication-connector.h"
 #include "watchface-complication/editables-manager.h"
 #include "watchface-complication/db-manager.h"
@@ -37,7 +38,7 @@ class EXPORT_API Complication : public IEditable
  public:
   Complication(int id, int supported_types, int supported_event_types,
                const std::string& default_provider_id,
-               ComplicationType default_type);
+               ComplicationType default_type, bool mock);
   virtual ~Complication();
 
  public:
@@ -59,14 +60,13 @@ class EXPORT_API Complication : public IEditable
   IEditable::Highlight* GetHighlight() override;
   std::list<std::unique_ptr<Bundle>> const& GetCandidates() const override;
   int SetCandidates(std::list<std::unique_ptr<Bundle>> candidates_list) override;
-  int UpdateCandidatesInfo();
   const Bundle* GetCurData() override;
   const Bundle* GetNthData(int nth) override;
   int GetCurDataIdx() override;
   int SetCurDataIdx(int cur_data_idx) override;
   int GetLastDataIdx() override;
   int UpdateLastData() override;
-  const std::string& GetName() override;
+  const std::string& GetLabel() override;
   void OnEditableUpdated(int selected_idx,
                     IEditable::EditableState state) override;
   void OnDataUpdated(const std::string& provider_id,
@@ -89,12 +89,14 @@ class EXPORT_API Complication : public IEditable
 
   int SendDataUpdateRequest();
   const char* GetCurProviderId();
-  const char* GetProviderId(const Bundle* data);
+  const char* GetProviderId(const Bundle* candidate_data);
+  int GetProviderType(const Bundle* candidate_data);
   int GetCurType();
   int TouchLaunch(watchface_complication_event_type_e event_type);
   int ApplyAllowedList(
       std::list<std::unique_ptr<ProviderInfo>> allowed_list);
   int ClearAllowedList();
+  int Init();
 
  public:
   static const char* GetProviderIdKey();
index 605f70b..a9cf848 100644 (file)
@@ -276,48 +276,6 @@ DBManager::GetProviderListWithTypes(int supported_types) {
   return std::move(provider_list);
 }
 
-std::list<std::string> DBManager::GetProviderList(int support_type) {
-  char* provider_id = NULL;
-  sqlite3_stmt* stmt;
-  sqlite3* db;
-  std::list<std::string> provider_list;
-  int trusted;
-  std::string provider_app_id;
-
-  static const char query[] =
-    "SELECT trusted, appid, provider_id FROM complication_provider "
-    "WHERE support_type=?";
-
-  db = OpenDB();
-  if (db == NULL) {
-    LOGE("parser db not exist");
-    return provider_list;
-  }
-
-  if (sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL) != SQLITE_OK) {
-    LOGE("prepare error: %s", sqlite3_errmsg(db));
-    CloseDB(db);
-    return provider_list;
-  }
-
-  sqlite3_bind_int(stmt, 1, support_type);
-
-  while (sqlite3_step(stmt) == SQLITE_ROW) {
-    trusted = sqlite3_column_int(stmt, 0);
-    provider_app_id = std::string((char*)sqlite3_column_text(stmt, 1));
-    if (trusted && util::CheckCertificate(provider_app_id) == false)
-      continue;
-
-    provider_id = (char*)sqlite3_column_text(stmt, 2);
-    provider_list.push_back(std::string(provider_id));
-  }
-
-  sqlite3_finalize(stmt);
-  CloseDB(db);
-
-  return provider_list;
-}
-
 std::list<std::string> DBManager::GetProviderListWithAppId(
     const char* provider_app_id) {
   char* provider = NULL;
index b19d446..17b26a2 100644 (file)
@@ -48,7 +48,6 @@ class EXPORT_API DBManager {
   static std::unique_ptr<Bundle> GetDefaultData(const char* provider_id,
                                         int support_type);
   static std::string GetProviderAppId(const char* provider_id);
-  static std::list<std::string> GetProviderList(int support_type);
   static std::list<std::string> GetRequiredPrivilegeList(
                   std::string& provider_id);
   static int GetRequiredSupportEvents(std::string& provider_id);
@@ -63,8 +62,8 @@ class EXPORT_API DBManager {
   static int GetTrustedInfo(std::string& provider_id, bool* trusted);
 
  private:
-  DBManager();
-  virtual ~DBManager();
+  DBManager(); /* LCOV_EXCL_LINE */
+  virtual ~DBManager(); /* LCOV_EXCL_LINE */
   static sqlite3* OpenDB();
   static void CloseDB(sqlite3* db);
   static const char* GetParserDataPath();
index cfd1e39..22e94af 100644 (file)
@@ -34,7 +34,7 @@ class DesignElement::Impl {
 
  private:
   friend class DesignElement;
-  Impl(DesignElement* parent, int id, int cur_data_idx);
+  Impl(DesignElement* parent, int id, int cur_data_idx, bool mock);
   Impl(Impl const& other) = default;
   Impl(Impl && other) = default;
   Impl& operator=(Impl const& other) = default;
@@ -52,6 +52,7 @@ class DesignElement::Impl {
   IEditable::EditableState ed_state_ = Complete;
   std::unique_ptr<Bundle> context_data_;
   std::unique_ptr<Bundle> last_context_data_ = nullptr;
+  bool mock_;
 };
 
 }  // namespace watchface_complication
index d789bfb..fc5e821 100644 (file)
 
 namespace watchface_complication {
 
-DesignElement::DesignElement(int id, int cur_data_idx)
-  : impl_(new Impl(this, id, cur_data_idx)) {
+DesignElement::DesignElement(int id, int cur_data_idx, bool mock)
+  : impl_(new Impl(this, id, cur_data_idx, mock)) {
 }
 
+/* LCOV_EXCL_START */
 DesignElement::~DesignElement() {
   LOGE("design element destroy %d", impl_->id_);
 }
+/* LCOV_EXCL_STOP */
+
 DesignElement::Impl::Impl(DesignElement* parent, int id,
-                          int cur_data_idx)
-  : parent_(parent), id_(id), cur_data_idx_(cur_data_idx) {
+                          int cur_data_idx, bool mock)
+  : parent_(parent), id_(id), cur_data_idx_(cur_data_idx), mock_(mock) {
   last_data_idx_ = cur_data_idx_;
 }
 
@@ -123,7 +126,8 @@ int DesignElement::UpdateLastData() {
     }
   }
   try {
-    ret = EditablesManager::GetInst().StoreSetting(impl_->id_, raw_data);
+    ret = EditablesManager::GetInst(impl_->mock_)
+        .StoreSetting(impl_->id_, raw_data);
     free(raw_data);
 
     if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
@@ -150,7 +154,7 @@ int DesignElement::SetCurDataIdx(int cur_data_idx) {
   return WATCHFACE_COMPLICATION_ERROR_NONE;
 }
 
-const std::string& DesignElement::GetName() {
+const std::string& DesignElement::GetLabel() {
   return impl_->name_;
 }
 
index e6d3b6b..7924097 100644 (file)
@@ -29,7 +29,7 @@ namespace watchface_complication {
 
 class EXPORT_API DesignElement : public IEditable {
  public:
-  DesignElement(int id, int cur_data_idx);
+  DesignElement(int id, int cur_data_idx, bool mock);
   virtual ~DesignElement();
   DesignElement(DesignElement const& other) = default;
   DesignElement(DesignElement && other) = default;
@@ -47,7 +47,7 @@ class EXPORT_API DesignElement : public IEditable {
   int SetCurDataIdx(int cur_data_idx) override;
   int GetLastDataIdx() override;
   int UpdateLastData() override;
-  const std::string& GetName() override;
+  const std::string& GetLabel() override;
   void OnEditableUpdated(int selected_idx,
                     IEditable::EditableState state) override;
   int GetEditableId() override;
index f6201cf..def9b9f 100644 (file)
@@ -133,7 +133,7 @@ class IEditable {
   virtual int SetCurDataIdx(int cur_data_idx) = 0;
   virtual int GetLastDataIdx() = 0;
   virtual int UpdateLastData() = 0;
-  virtual const std::string& GetName() = 0;
+  virtual const std::string& GetLabel() = 0;
   virtual void SetLabel(const std::string& name) = 0;
   virtual void OnEditableUpdated(int selected_idx, EditableState state) = 0;
   virtual void SetState(EditableState state) = 0;
index a888150..cf7d76a 100644 (file)
 
 #include "watchface-complication/editables-container.h"
 #include "watchface-complication/complication-connector.h"
+#include "watchface-complication/gdbus-interface.h"
 
 namespace watchface_complication {
 
-class EditablesContainer::Impl : ComplicationConnector::IEventListener {
+class EditablesContainer::Impl : IGDBus::IGDBusEvent {
  public:
   virtual ~Impl() = default;
 
@@ -44,7 +45,7 @@ class EditablesContainer::Impl : ComplicationConnector::IEventListener {
   void OnVanish(const std::string& name) override;
   void OnAppear(const std::string& name, const std::string& name_owner) override;
   void CancelEditing();
-  explicit Impl(EditablesContainer* parent);
+  explicit Impl(EditablesContainer* parent, bool mock);
   Impl(Impl const& other) = default;
   Impl(Impl && other) = default;
   Impl& operator=(Impl const& other) = default;
@@ -64,6 +65,7 @@ class EditablesContainer::Impl : ComplicationConnector::IEventListener {
   std::string sender_name_;
   int watcher_id_ = -1;
   std::list<std::shared_ptr<IEditable>> ed_list_;
+  std::unique_ptr<IGDBus> gdbus_;
 };
 
 }  // namespace watchface_complication
index 9dada54..9e5f53a 100644 (file)
@@ -25,6 +25,7 @@
 #include "watchface-complication/editables-container-implementation.h"
 #include "watchface-complication/include/watchface-complication-internal.h"
 #include "watchface-common/watchface-util.h"
+#include "watchface-complication/gdbus-interface.h"
 
 #ifdef LOG_TAG
 #undef LOG_TAG
 
 namespace watchface_complication {
 
-EditablesContainer::EditablesContainer()
-  : impl_(new Impl(this)) {
+EditablesContainer::EditablesContainer(bool mock)
+  : impl_(new Impl(this, mock)) {
 }
 
 EditablesContainer::~EditablesContainer() = default;
-EditablesContainer::Impl::Impl(EditablesContainer* parent)
-  : parent_(parent) {
-  subscribe_id_ = ComplicationConnector::GetInst().SubscribeSignal(
-                    ComplicationConnector::Editable,
-                    ComplicationConnector::GetInst().GetAppId(), -1, this);
+EditablesContainer::Impl::Impl(EditablesContainer* parent, bool mock)
+  : parent_(parent),
+  gdbus_(std::unique_ptr<IGDBus>(ComplicationConnector::GetInst(mock).CreateGDBus(mock))) {
+  subscribe_id_ = gdbus_.get()->SubscribeSignal(
+                    IGDBus::Editable,
+                    util::GetAppId(), -1, this);
   LOGI("subscribe signal %d", subscribe_id_);
 }
 
@@ -58,9 +60,7 @@ void EditablesContainer::Impl::OnSignal(GDBusConnection* connection,
   std::shared_ptr<const Bundle> updated_data;
 
   LOGI("signal_name: %s ,%s", signal_name.c_str(), sender_name.c_str());
-  if (signal_name.compare(
-      ComplicationConnector::GetInst().GetCmdStr(
-          ComplicationConnector::EditableEditReady)) == 0) {
+  if (signal_name.compare(util::GetCmdStr(util::EditableEditReady)) == 0) {
     g_variant_get(parameters, "(&s)", &editor_id);
     std::string sender_appid = util::GetSenderAppid(connection, sender_name);
 
@@ -81,8 +81,7 @@ void EditablesContainer::Impl::OnSignal(GDBusConnection* connection,
     parent_->OnEditReady(editor_id_);
 
   } else if (signal_name.compare(
-      ComplicationConnector::GetInst().GetCmdStr(
-          ComplicationConnector::EditableEditPreview)) == 0) {
+      util::GetCmdStr(util::EditableEditPreview)) == 0) {
     int editable_id;
     int selected_idx;
     char* context = NULL;
@@ -110,8 +109,7 @@ void EditablesContainer::Impl::OnSignal(GDBusConnection* connection,
       }
     }
   } else if (signal_name.compare(
-      ComplicationConnector::GetInst().GetCmdStr(
-          ComplicationConnector::EditableEditComplete)) == 0) {
+      util::GetCmdStr(util::EditableEditComplete)) == 0) {
     if (sender_name_.compare(sender_name) != 0)
       return;
 
@@ -123,8 +121,8 @@ void EditablesContainer::Impl::OnSignal(GDBusConnection* connection,
       i.get()->OnEditableUpdated(i.get()->GetCurDataIdx(), IEditable::Complete);
       parent_->OnUpdate(*i.get(), i.get()->GetCurDataIdx(), IEditable::Complete);
     }
-  } else if (signal_name.compare(ComplicationConnector::GetInst().GetCmdStr(
-          ComplicationConnector::EditableEditCancel)) == 0) {
+  } else if (signal_name.compare(util::GetCmdStr(
+          util::EditableEditCancel)) == 0) {
     if (sender_name_.compare(sender_name) != 0) {
       LOGE("invalid sender_name %s", sender_name.c_str());
       return;
@@ -221,8 +219,8 @@ int EditablesContainer::RequestEdit() {
       LOGW("Null highlight info !!");
     }
 
-    if (!i.get()->GetName().empty())
-      bundle_add(ed, "NAME", i.get()->GetName().c_str());
+    if (!i.get()->GetLabel().empty())
+      bundle_add(ed, "NAME", i.get()->GetLabel().c_str());
 
     bundle_encode(ed, &str_raw, &str_len);
     list_arr[list_idx++] = reinterpret_cast<char*>(str_raw);
@@ -240,22 +238,15 @@ int EditablesContainer::RequestEdit() {
             const_cast<const char**>(list_arr), list_idx);
   impl_->FreeList(list_arr, impl_->ed_list_.size());
   bundle_encode(container, &str_raw, &str_len);
-
-  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;
-  }
+  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(),
+                  str_raw));
 
   bundle_free_encoded_rawdata(&str_raw);
   bundle_free(container);
@@ -263,23 +254,19 @@ int EditablesContainer::RequestEdit() {
   if (emit_ret == false)
     return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
 
-  try {
-  impl_->watcher_id_ = ComplicationConnector::GetInst().Watch(impl_->editor_id_,
+  impl_->watcher_id_ = impl_->gdbus_.get()->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;
 }
 
+/* LCOV_EXCL_START */
 void EditablesContainer::OnUpdate(const IEditable& ed, int selected_idx,
                                         IEditable::EditableState state) {
 }
-
 void EditablesContainer::OnEditReady(const std::string& editor_id) {
 }
+/* LCOV_EXCL_STOP */
 
 int EditablesContainer::Add(std::shared_ptr<IEditable> ed, int editable_id) {
   if (ed == nullptr)
index 75fa35b..5f948bd 100644 (file)
@@ -29,13 +29,13 @@ namespace watchface_complication {
 
 class EXPORT_API EditablesContainer : IEditablesEditorEvent {
  public:
-  EditablesContainer();
-  virtual ~EditablesContainer();
+  EditablesContainer(bool mock);
+  virtual ~EditablesContainer(); /* LCOV_EXCL_LINE */
   int Add(std::shared_ptr<IEditable> ed, int editable_id);
   int Remove(std::shared_ptr<IEditable> ed);
   int RequestEdit();
-  virtual void OnUpdate(const IEditable& ed, int selected_idx,
-      IEditable::EditableState state);
+  void OnUpdate(const IEditable& ed, int selected_idx,
+      IEditable::EditableState state) override;
   void OnEditReady(const std::string& editor_id) override;
   bool IsExist(int editable_id);
 
index a1663b1..81103dd 100644 (file)
@@ -41,15 +41,16 @@ class EditablesManager::Impl {
  private:
   friend class EditablesManager;
   Impl();
-  static std::string GetEditablesDataPath() {
-    char* app_data_path = app_get_data_path();
+  static std::string GetEditablesDataPath(bool mock) {
+    char* app_data_path = mock ? (char*)"/tmp/" : app_get_data_path();
     char setting_data_path[PATH_MAX] = {0, };
 
     if (app_data_path != NULL) {
       snprintf(setting_data_path, PATH_MAX, "%s.watchface_editables.db",
           app_data_path);
       LOGI("get setting data path %s", setting_data_path);
-      free(app_data_path);
+      if (!mock)
+        free(app_data_path);
     }
 
     return std::string(setting_data_path);
index 90623b9..7a1a210 100644 (file)
 
 namespace watchface_complication {
 
-EditablesManager& EditablesManager::GetInst() {
+EditablesManager& EditablesManager::GetInst(bool mock) {
   static EditablesManager w_inst;
   int ret;
 
   if (w_inst.impl_ == nullptr) {
-    ret = w_inst.Init();
+    ret = w_inst.Init(mock);
     if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
       THROW(ret);
   }
@@ -50,7 +50,7 @@ EditablesManager::EditablesManager() = default;
 EditablesManager::~EditablesManager() = default;
 EditablesManager::Impl::Impl() = default;
 
-int EditablesManager::Init() {
+int EditablesManager::Init(bool mock) {
   int ret;
   int open_flags = (SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
   std::unique_ptr<Impl> tmp_impl;
@@ -72,7 +72,7 @@ int EditablesManager::Init() {
     "CREATE TABLE IF NOT EXISTS editable_setting" \
     "(editable_id INTEGER NOT NULL, setting_data TEXT NOT NULL, "\
     "PRIMARY KEY(editable_id))";
-  std::string db_path = tmp_impl->GetEditablesDataPath();
+  std::string db_path = tmp_impl->GetEditablesDataPath(mock);
   if (db_path.empty()) {
     LOGE("GetSettingDataPath failed");
     return WATCHFACE_COMPLICATION_ERROR_DB;
index 9c8a0f1..db3f66d 100644 (file)
@@ -29,7 +29,7 @@ namespace watchface_complication {
 
 class EXPORT_API EditablesManager {
  public:
-  static EditablesManager& GetInst();
+  static EditablesManager& GetInst(bool mock = false);
   int StoreSetting(int editable_id, bundle_raw* raw_data);
   std::unique_ptr<Bundle> LoadSetting(int editable_id);
   int StoreContext(int editable_id, const char* provider_id, Bundle& context);
@@ -39,7 +39,7 @@ class EXPORT_API EditablesManager {
  private:
   EditablesManager();
   virtual ~EditablesManager();
-  int Init();
+  int Init(bool mock);
 
  private:
   class Impl;
diff --git a/watchface-complication/gdbus-interface.h b/watchface-complication/gdbus-interface.h
new file mode 100644 (file)
index 0000000..66c3033
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * 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_GDBUS_INTERFACE_H_
+#define WATCHFACE_COMPLICATION_GDBUS_INTERFACE_H_
+
+#include <string>
+
+namespace watchface_complication {
+
+class IGDBus {
+ public:
+  enum SigType {
+    Complication,
+    Editable
+  };
+  class IGDBusEvent {
+   public:
+    virtual void OnSignal(GDBusConnection* connection,
+                              const std::string& sender_name,
+                              const std::string& object_path,
+                              const std::string& interface_name,
+                              const std::string& signal_name,
+                              GVariant* parameters) = 0;
+    virtual void OnVanish(const std::string& name) = 0;
+    virtual void OnAppear(const std::string& name,
+                              const std::string& name_owner) = 0;
+  };
+  virtual ~IGDBus() = default;
+  virtual int Watch(std::string id, IGDBusEvent* listener) = 0;
+  virtual void UnWatch(int watcher_id) = 0;
+  virtual bool EmitSignal(SigType type, std::string target_id, std::string id,
+                  int sub_id, std::string cmd, GVariant* data) = 0;
+  virtual int SubscribeSignal(SigType type, std::string id, int sub_id,
+                  IGDBusEvent* listener) = 0;
+  virtual void UnSubscribeSignal(int subscribe_id) = 0;
+};
+
+}  // namespace watchface_complication
+
+#endif  // WATCHFACE_COMPLICATION_GDBUS_INTERFACE_H_
diff --git a/watchface-complication/gdbus-mock.h b/watchface-complication/gdbus-mock.h
new file mode 100644 (file)
index 0000000..04e00ea
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * 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_GDBUS_MOCK_H_
+#define WATCHFACE_COMPLICATION_GDBUS_MOCK_H_
+
+#include <glib.h>
+
+#include <memory>
+
+#include "watchface-complication/gdbus-interface.h"
+
+namespace watchface_complication {
+namespace test {
+
+class GDBusMock : public IGDBus {
+ public:
+  GDBusMock() { }
+
+  virtual ~GDBusMock() {
+  }
+
+  int Watch(std::string appid, IGDBus::IGDBusEvent* listener) {
+    return 0;
+  }
+
+  void UnWatch(int watcher_id) {
+  }
+
+  bool EmitSignal(SigType type, std::string target_id, std::string id,
+      int sub_id, std::string cmd, GVariant* data) {
+    return true;
+  }
+
+  void UnSubscribeSignal(int subscribe_id) {
+
+  }
+
+  int SubscribeSignal(SigType type, std::string id,
+      int sub_id, IGDBus::IGDBusEvent* listener) {
+    return 1;
+  }
+
+ private:
+  static void SignalCb(GDBusConnection* connection,
+                      const gchar* sender_name,
+                      const gchar* object_path,
+                      const gchar* interface_name,
+                      const gchar* signal_name,
+                      GVariant* parameters,
+                      void* user_data) {
+    IGDBus::IGDBusEvent* rs = static_cast<IGDBus::IGDBusEvent*>(user_data);
+
+    rs->OnSignal(connection, sender_name, object_path, interface_name,
+                 signal_name, parameters);
+  }
+
+  static void VanishCb(GDBusConnection* connection,
+      const gchar* name, gpointer user_data) {
+    IGDBus::IGDBusEvent* rs = static_cast<IGDBus::IGDBusEvent*>(user_data);
+    rs->OnVanish(name);
+  }
+
+  static void AppearCb(GDBusConnection* connection,
+      const gchar* name, const gchar* name_owner, gpointer user_data) {
+    IGDBus::IGDBusEvent* rs = static_cast<IGDBus::IGDBusEvent*>(user_data);
+    rs->OnAppear(name, name_owner);
+  }
+
+ private:
+};
+
+}  // namespace test
+}  // namespace watchface_complication
+
+#endif  // WATCHFACE_COMPLICATION_GDBUS_MOCK_H_
diff --git a/watchface-complication/gdbus.h b/watchface-complication/gdbus.h
new file mode 100644 (file)
index 0000000..10d0dd8
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * 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_GDBUS_H_
+#define WATCHFACE_COMPLICATION_GDBUS_H_
+
+#include <unistd.h>
+#include <dlog.h>
+
+#include <memory>
+#include <list>
+
+#include "watchface-common/watchface-util.h"
+#include "watchface-complication/gdbus-interface.h"
+
+#define COMPLICATION_INTERFACE "org.tizen.watchface_complication"
+
+namespace watchface_complication {
+
+class GDBus : public IGDBus {
+ public:
+  GDBus(GDBusConnection* conn)
+      : conn_(conn) { }
+
+  virtual ~GDBus() {
+    for(auto& id : subscribe_list_) {
+      g_dbus_connection_signal_unsubscribe(conn_, id);
+    }
+  }
+
+  int Watch(std::string appid, IGDBus::IGDBusEvent* listener) {
+    int watcher_id;
+    std::string name;
+
+    LOGI("watch on : %s", appid.c_str());
+    name = util::EncodeStr(util::EncodeType::Name, appid);
+    watcher_id = g_bus_watch_name_on_connection(
+        conn_,
+        name.c_str(),
+        G_BUS_NAME_WATCHER_FLAGS_NONE,
+        AppearCb,
+        VanishCb,
+        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;
+  }
+
+  void UnWatch(int watcher_id) {
+    LOGI("unwatch : %d", watcher_id);
+    g_bus_unwatch_name(watcher_id);
+  }
+
+  bool EmitSignal(SigType type, std::string target_id, std::string id,
+      int sub_id, std::string cmd, GVariant* data) {
+    GError* err = NULL;
+    gboolean result = TRUE;
+    std::string path = util::EncodeStr(
+        type == Complication ?
+          util::EncodeType::CompPath : util::EncodeType::EditablePath,
+          id, sub_id);
+    std::string name = util::EncodeStr(util::EncodeType::Name, target_id);
+
+    LOGI("emit : %s, %s, %d, %s", target_id.c_str(), id.c_str(), sub_id,
+                                  cmd.c_str());
+    LOGI("emit signal %s, %s", name.empty() ? NULL : name.c_str(), path.c_str());
+    result = g_dbus_connection_emit_signal(
+              conn_,
+              name.empty() ? NULL : name.c_str(),
+              path.c_str(),
+              COMPLICATION_INTERFACE,
+              cmd.c_str(), data, &err);
+    if (result == FALSE) {
+      LOGE("g_dbus_connection_emit_signal() is failed");
+      if (err != NULL) {
+        LOGE("g_dbus_connection_emit_signal() err : %s",
+            err->message);
+        g_error_free(err);
+      }
+    } else {
+      LOGI("Successfully emit signal to %s, %s, %s", name.c_str(), path.c_str(),
+          cmd.c_str());
+    }
+    return result;
+  }
+
+  void UnSubscribeSignal(int subscribe_id) {
+    LOGI("unsubscribe : %d", subscribe_id);
+    g_dbus_connection_signal_unsubscribe(conn_, subscribe_id);
+  }
+
+  int SubscribeSignal(SigType type, std::string id,
+      int sub_id, IGDBus::IGDBusEvent* listener) {
+
+    LOGI("subscribe : %s, %d", id.c_str(), sub_id);
+    std::string path = util::EncodeStr(
+                  type == Complication ?
+                    util::EncodeType::CompPath : util::EncodeType::EditablePath,
+                    id, sub_id);
+    int subscribe_id = g_dbus_connection_signal_subscribe(
+                    conn_,
+                    NULL,
+                    COMPLICATION_INTERFACE,
+                    NULL,
+                    path.c_str(),
+                    NULL,
+                    G_DBUS_SIGNAL_FLAGS_NONE,
+                    SignalCb,
+                    listener,
+                    NULL);
+    if (subscribe_id == 0) {
+      LOGE("subscribe fail (%s)", path.c_str());
+      return 0;
+    }
+
+    LOGI("subscribe %s, %d", path.c_str(), subscribe_id);
+    subscribe_list_.push_back(subscribe_id);
+
+    return subscribe_id;
+  }
+
+ private:
+  static void SignalCb(GDBusConnection* connection,
+                      const gchar* sender_name,
+                      const gchar* object_path,
+                      const gchar* interface_name,
+                      const gchar* signal_name,
+                      GVariant* parameters,
+                      void* user_data) {
+    IGDBus::IGDBusEvent* rs = static_cast<IGDBus::IGDBusEvent*>(user_data);
+
+    rs->OnSignal(connection, sender_name, object_path, interface_name,
+                 signal_name, parameters);
+  }
+
+  static void VanishCb(GDBusConnection* connection,
+      const gchar* name, gpointer user_data) {
+    IGDBus::IGDBusEvent* rs = static_cast<IGDBus::IGDBusEvent*>(user_data);
+    rs->OnVanish(name);
+  }
+
+  static void AppearCb(GDBusConnection* connection,
+      const gchar* name, const gchar* name_owner, gpointer user_data) {
+    IGDBus::IGDBusEvent* rs = static_cast<IGDBus::IGDBusEvent*>(user_data);
+    rs->OnAppear(name, name_owner);
+  }
+
+ private:
+  std::list<int> subscribe_list_;
+  GDBusConnection* conn_ = nullptr;
+};
+
+}  // namespace watchface_complication
+
+#endif  // WATCHFACE_COMPLICATION_GDBUS_H_
\ No newline at end of file
diff --git a/watchface-complication/package-manager-interface.h b/watchface-complication/package-manager-interface.h
new file mode 100644 (file)
index 0000000..c1ce353
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * 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_PACKAGE_MANAGER_INTERFACE_H_
+#define WATCHFACE_COMPLICATION_PACKAGE_MANAGER_INTERFACE_H_
+
+#include <string>
+
+namespace watchface_complication {
+
+class IPackageManager {
+ public:
+  class IPackageEvent {
+   public:
+    virtual void OnAppDisabled(const std::string& appid) = 0;
+    virtual void OnAppUninstalled(const std::string& appid) = 0;
+  };
+  virtual void Watch(IPackageEvent* pe) = 0;
+  virtual void UnWatch(IPackageEvent* pe) = 0;
+  virtual bool CheckDisabled(const std::string& appid) = 0;
+
+};
+
+}  // namespace watchface_complication
+
+#endif  // WATCHFACE_COMPLICATION_PACKAGE_MANAGER_INTERFACE_H_
diff --git a/watchface-complication/package-manager-mock.h b/watchface-complication/package-manager-mock.h
new file mode 100644 (file)
index 0000000..7a50d1a
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * 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_PACKAGE_MANAGER_MOCK_H_
+#define WATCHFACE_COMPLICATION_PACKAGE_MANAGER_MOCK_H_
+
+#include <unistd.h>
+#include <dlog.h>
+
+#include <memory>
+#include <list>
+
+#include "watchface-common/watchface-util.h"
+#include "watchface-complication/gdbus-interface.h"
+
+#define COMPLICATION_INTERFACE "org.tizen.watchface_complication"
+
+namespace watchface_complication {
+namespace test {
+
+class PackageManagerMock : public IPackageManager {
+ public:
+  PackageManagerMock() {
+  }
+
+  void Watch(IPackageEvent* pe) override {
+    pe_list_.push_back(pe);
+    if (event_timer_ > 0)
+      g_source_remove(event_timer_);
+
+    event_timer_ = g_timeout_add(1000, [](gpointer user_data)->gboolean {
+          PackageManagerMock* mock = static_cast<PackageManagerMock*>(user_data);
+          static int seq = 0;
+          for (IPackageManager::IPackageEvent* pe : mock->pe_list_) {
+            if (seq++ % 2 == 0)
+              pe->OnAppDisabled("org.tizen.gmock_comp_provider");
+            else
+              pe->OnAppUninstalled("org.tizen.gmock_comp_provider");
+          }
+          return G_SOURCE_CONTINUE;
+        }, this);
+  }
+
+  void UnWatch(IPackageEvent* pe) override {
+    for (IPackageManager::IPackageEvent* i : pe_list_) {
+      if (i == pe) {
+        pe_list_.remove(i);
+        if (event_timer_ > 0) {
+          g_source_remove(event_timer_);
+        }
+        return;
+      }
+    }
+  }
+
+  bool CheckDisabled(const std::string& appid) override {
+    return true;
+  }
+
+  ~PackageManagerMock() {
+  }
+
+ public:
+  std::list<IPackageEvent*> pe_list_;
+
+ private:
+  unsigned int event_timer_ = 0;
+};
+
+}  // namespace test
+}  // namespace watchface_complication
+
+#endif  // WATCHFACE_COMPLICATION_PACKAGE_MANAGER_MOCK_H_
\ No newline at end of file
diff --git a/watchface-complication/package-manager.h b/watchface-complication/package-manager.h
new file mode 100644 (file)
index 0000000..b926e61
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * 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_PACKAGE_MANAGER_H_
+#define WATCHFACE_COMPLICATION_PACKAGE_MANAGER_H_
+
+#include <unistd.h>
+#include <dlog.h>
+
+#include <memory>
+#include <list>
+
+namespace watchface_complication {
+
+class PackageManager : public IPackageManager {
+ public:
+  PackageManager() { }
+  void Watch(IPackageEvent* pe) override {
+    ComplicationConnector::GetInst().WatchPackageEvent(pe);
+  }
+  void UnWatch(IPackageEvent* pe) override {
+    ComplicationConnector::GetInst().UnWatchPackageEvent(pe);
+  }
+  bool CheckDisabled(const std::string& appid) override {
+    pkgmgrinfo_appinfo_h app_handle;
+    int ret = pkgmgrinfo_appinfo_get_disabled_appinfo(appid.c_str(), &app_handle);
+    if (ret != PMINFO_R_OK)
+      return false;
+    pkgmgrinfo_appinfo_destroy_appinfo(app_handle);
+    return true;
+  }
+ private:
+
+};
+
+}  // namespace watchface_complication
+
+#endif  // WATCHFACE_COMPLICATION_PACKAGE_MANAGER_H_
\ No newline at end of file
index 141d5fb..7723e90 100644 (file)
@@ -206,7 +206,7 @@ int ReceivedEditable::SetCurDataIdx(int cur_data_idx) {
   return WATCHFACE_COMPLICATION_ERROR_NONE;
 }
 
-const std::string& ReceivedEditable::GetName() {
+const std::string& ReceivedEditable::GetLabel() {
   return impl_->name_;
 }
 
index a309f3b..f96e878 100644 (file)
@@ -47,7 +47,7 @@ class EXPORT_API ReceivedEditable : public IEditable {
   int SetCurDataIdx(int cur_data_idx) override;
   int GetLastDataIdx() override;
   int UpdateLastData() override;
-  const std::string& GetName() override;
+  const std::string& GetLabel() override;
   void OnEditableUpdated(int selected_idx,
                     IEditable::EditableState state) override;
   int GetEditableId() override;
diff --git a/watchface-complication/watchface-complication-internal.cc b/watchface-complication/watchface-complication-internal.cc
deleted file mode 100644 (file)
index 1132bda..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * 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.
- */
-
index d548422..e30cbbb 100644 (file)
@@ -108,11 +108,9 @@ class WatchComplicationStub : public Complication {
                         const std::string& default_provider_id,
                         ComplicationType default_type)
     : Complication(id, supported_types, supported_event_types,
-        default_provider_id, default_type) {
+        default_provider_id, default_type, false) {
   }
-
-  virtual ~WatchComplicationStub() = default;
-
+  /* LCOV_EXCL_START */
   void OnProviderError(const std::string& provider_id, ComplicationType type,
       int error) override {
     for (auto& i : cb_list_) {
@@ -120,6 +118,7 @@ class WatchComplicationStub : public Complication {
     }
     LOGI("update call!! done");
   }
+  /* LCOV_EXCL_STOP */
 
   void OnDataUpdated(const std::string& provider_id, ComplicationType type,
       const std::unique_ptr<Bundle>& data) override {
@@ -263,7 +262,8 @@ extern "C" EXPORT_API int watchface_complication_create(int complication_id,
               supported_event_types,
               default_provider_id,
               static_cast<ComplicationType>(default_type));
-    LOGI("comp created");
+    LOGI("comp created (%d)", complication_id);
+    ws->Init();
     auto sh = SharedHandle<WatchComplicationStub>::Make(ws);
     *created_handle = static_cast<void*>(sh);
   } catch (const std::bad_alloc &ba) {
index d891567..c3bc1fc 100644 (file)
@@ -92,10 +92,9 @@ class UpdateCallbackInfo {
 class EditablesContainerStub : public EditablesContainer {
  public:
   EditablesContainerStub()
-    : EditablesContainer() {
+    : EditablesContainer(false) {
   }
 
-  virtual ~EditablesContainerStub() = default;
   void OnEditReady(const std::string& editor_id) override {
     for (auto& i : ready_cb_list_) {
       i->Invoke(static_cast<void*>(this), editor_id);
@@ -213,7 +212,8 @@ extern "C" EXPORT_API int watchface_editable_add_design_element(
   }
 
   try {
-    auto de = std::shared_ptr<IEditable>(new DesignElement(edit_id, cur_data_idx));
+    auto de = std::shared_ptr<IEditable>(
+      new DesignElement(edit_id, cur_data_idx, false));
     if (highlight) {
       std::unique_ptr<IEditable::Highlight> hi_ptr =
           __get_highlight_unique_ptr(highlight);
@@ -456,8 +456,8 @@ extern "C" EXPORT_API int watchface_editable_get_editable_name(
     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
 
   IEditable* ie = static_cast<IEditable*>(handle);
-  if (!ie->GetName().empty()) {
-    *editable_name = strdup(ie->GetName().c_str());
+  if (!ie->GetLabel().empty()) {
+    *editable_name = strdup(ie->GetLabel().c_str());
     if (*editable_name == NULL) {
       LOGE("Out of memory");
       return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
index 2ac2c83..0d0b12c 100644 (file)
@@ -27,6 +27,8 @@ namespace watchface_complication {
 class EXPORT_API IEditablesEditorEvent {
  public:
   virtual void OnEditReady(const std::string& editor_id) = 0;
+  virtual void OnUpdate(const IEditable& ed, int selected_idx,
+      IEditable::EditableState state) = 0;
 };
 
 }  // namespace watchface_complication
index 4dedcb4..60b526e 100644 (file)
 
 #include "watchface-complication/editables-container.h"
 #include "watchface-complication/complication-connector.h"
+#include "watchface-complication/gdbus-interface.h"
 #include "watchface-common/watchface-util.h"
 
 namespace watchface_complication {
 
-class EditablesEditor::Impl : ComplicationConnector::IEventListener {
+class EditablesEditor::Impl : IGDBus::IGDBusEvent {
  public:
   virtual ~Impl() = default;
 
@@ -45,7 +46,7 @@ class EditablesEditor::Impl : ComplicationConnector::IEventListener {
   void OnVanish(const std::string& name) override;
   void OnAppear(const std::string& name, const std::string& name_owner) override;
   int CheckPrivilege();
-  explicit Impl(EditablesEditor* parent);
+  explicit Impl(EditablesEditor* parent, bool mock);
   Impl(Impl const& other) = default;
   Impl(Impl && other) = default;
   Impl& operator=(Impl const& other) = default;
@@ -55,6 +56,7 @@ class EditablesEditor::Impl : ComplicationConnector::IEventListener {
   EditablesEditor* parent_;
   int subscribe_id_;
   std::string edit_appid_;
+  std::unique_ptr<IGDBus> gdbus_ = nullptr;
 };
 
 }  // namespace watchface_complication
index e2f28dc..d761a75 100644 (file)
@@ -24,6 +24,8 @@
 #include "watchface-complication/received-editable.h"
 #include "watchface-common/watchface-util.h"
 
+#include "watchface-complication/gdbus-interface.h"
+
 #ifdef LOG_TAG
 #undef LOG_TAG
 #endif
 
 namespace watchface_complication {
 
-EditablesEditor::EditablesEditor()
-  : impl_(new Impl(this)) {
+EditablesEditor::EditablesEditor(bool mock)
+  : impl_(new Impl(this, mock)) {
 }
 
 EditablesEditor::~EditablesEditor() = default;
-EditablesEditor::Impl::Impl(EditablesEditor* parent)
-  : parent_(parent) {
-  try {
-    subscribe_id_ = ComplicationConnector::GetInst().SubscribeSignal(
-                    ComplicationConnector::Editable,
-                    ComplicationConnector::GetInst().GetAppId(), -1, this);
-  } catch (...) {
-    throw;
-  }
+EditablesEditor::Impl::Impl(EditablesEditor* parent, bool mock)
+  : parent_(parent),
+  gdbus_(std::unique_ptr<IGDBus>(ComplicationConnector::GetInst(mock).CreateGDBus(mock))) {
+  subscribe_id_ = gdbus_.get()->SubscribeSignal(IGDBus::Editable,
+                    util::GetAppId(), -1, this);
   LOGI("subscribe signal %d", subscribe_id_);
 }
 
@@ -94,8 +92,7 @@ void EditablesEditor::Impl::OnSignal(GDBusConnection* connection,
 
   LOGI("signal_name: %s", signal_name.c_str());
   if (signal_name.compare(
-      ComplicationConnector::GetInst().GetCmdStr(
-          ComplicationConnector::EditableEditRequest)) == 0) {
+      util::GetCmdStr(util::CmdType::EditableEditRequest)) == 0) {
     g_variant_get(parameters, "(&s&s)", &appid, &raw);
     LOGI("appid: %s", appid);
 
@@ -131,8 +128,7 @@ void EditablesEditor::Impl::OnSignal(GDBusConnection* connection,
     parent_->OnRequestEdit(std::string(appid), std::move(e_list));
     bundle_free(data);
   } else if (signal_name.compare(
-      ComplicationConnector::GetInst().GetCmdStr(
-          ComplicationConnector::SetupReply)) == 0) {
+      util::GetCmdStr(util::CmdType::SetupReply)) == 0) {
     int edit_id;
     char* raw_str;
 
@@ -176,20 +172,14 @@ int EditablesEditor::EditPreview(IEditable& ed, int cur_data_idx) {
     return ret;
 
   Bundle* context = re.GetContext().get();
-  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();
-  }
+  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) ? "" : context->ToString()));
 
   if (emit_result)
     return WATCHFACE_COMPLICATION_ERROR_NONE;
@@ -210,18 +200,12 @@ int EditablesEditor::EditComplete() {
   if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
     return ret;
 
-  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();
-  }
+  emit_result = impl_->gdbus_.get()->EmitSignal(
+    IGDBus::Editable,
+    impl_->edit_appid_.c_str(),
+    impl_->edit_appid_.c_str(),
+    -1,
+    util::GetCmdStr(util::CmdType::EditableEditComplete), NULL);
 
   if (emit_result)
     return WATCHFACE_COMPLICATION_ERROR_NONE;
@@ -242,18 +226,12 @@ int EditablesEditor::EditCancel() {
   if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
     return ret;
 
-  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();
-  }
+  emit_result = impl_->gdbus_.get()->EmitSignal(
+    IGDBus::Editable,
+    impl_->edit_appid_.c_str(),
+    impl_->edit_appid_.c_str(),
+    -1,
+    util::GetCmdStr(util::CmdType::EditableEditCancel), NULL);
 
   if (emit_result)
     return WATCHFACE_COMPLICATION_ERROR_NONE;
@@ -262,7 +240,6 @@ int EditablesEditor::EditCancel() {
 }
 
 int EditablesEditor::NotifyEditReady(std::string appid) {
-  bool emit_result;
   int ret;
 
   if (appid.empty())
@@ -272,22 +249,14 @@ int EditablesEditor::NotifyEditReady(std::string appid) {
   if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
     return ret;
 
-  try {
-    emit_result = ComplicationConnector::GetInst().EmitSignal(
-      ComplicationConnector::Editable,
+  if (impl_->gdbus_.get()->EmitSignal(
+      IGDBus::Editable,
       appid,
       appid,
       -1,
-      ComplicationConnector::GetInst().GetCmdStr(
-          ComplicationConnector::EditableEditReady),
+      util::GetCmdStr(util::CmdType::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) {
+        util::GetAppId().c_str()))) {
     impl_->edit_appid_ = appid;
     return WATCHFACE_COMPLICATION_ERROR_NONE;
   } else {
index adb0019..ef66289 100644 (file)
@@ -29,7 +29,7 @@ namespace watchface_complication {
 
 class EXPORT_API EditablesEditor : IEditablesContainerEvent {
  public:
-  EditablesEditor();
+  EditablesEditor(bool mock);
   virtual ~EditablesEditor();
   void OnRequestEdit(const std::string& appid,
                      std::list<std::unique_ptr<IEditable>> e_list) override;
index 60bfafa..a399258 100644 (file)
@@ -83,7 +83,7 @@ class SetupCallbackInfo {
 class EditablesEditorStub : public EditablesEditor {
  public:
   EditablesEditorStub()
-    : EditablesEditor() {
+    : EditablesEditor(false) {
   }
 
   virtual ~EditablesEditorStub() = default;
@@ -524,7 +524,7 @@ extern "C" EXPORT_API int watchface_editor_launch_setup_app(
   app_control_set_app_id(service, appid.c_str());
 
   int ret = _add_extra_data(&service, SETUP_EDITOR_APPID_KEY,
-      ComplicationConnector::GetInst().GetAppId().c_str());
+      util::GetAppId().c_str());
   if (ret != WATCHFACE_COMPLICATION_ERROR_NONE) {
     LOGE("Fail to add appid ");
     app_control_destroy(service);
@@ -661,6 +661,10 @@ extern "C" EXPORT_API int watchface_editor_get_complication_is_supported(
   if (!watchface_complication::util::CheckWatchFeatureEnabled())
     return WATCHFACE_COMPLICATION_ERROR_NOT_SUPPORTED;
 
+  if (candidate_data == NULL || is_supported == NULL ||
+      error == NULL || error_message == NULL)
+    return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
+
   bundle_get_str(const_cast<bundle*>(candidate_data),
       Complication::GetPrivilegeErrorKey(), &val);
   if (val != NULL) {