aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlex Vakulenko <avakulenko@google.com>2016-01-04 09:27:50 -0800
committerAlex Vakulenko <avakulenko@google.com>2016-01-04 17:49:43 +0000
commitce850b557cd406e4dc546557acbf756484aac198 (patch)
treee09ea69ee2298bb82c932fbb308cc919629ab53a /src
parente0df73aab852fc7ea6f9f2620bed0d596a77c1b8 (diff)
downloadlibweave-ce850b557cd406e4dc546557acbf756484aac198.tar.gz
Add the ability to remove a component from component tree
This functionality will be neaded on Brillo side to remove components added by vendor daemons when those daemons exit (normally or abnormally). This will allow those daemons to re-add the same component when they get restarted. Change-Id: Ida350cfa38d4f1265d1e86fccca893cdf7f5030c Reviewed-on: https://weave-review.googlesource.com/2087 Reviewed-by: Vitaly Buka <vitalybuka@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/component_manager.h16
-rw-r--r--src/component_manager_impl.cc57
-rw-r--r--src/component_manager_impl.h17
-rw-r--r--src/component_manager_unittest.cc46
-rw-r--r--src/device_manager.cc4
-rw-r--r--src/device_manager.h1
-rw-r--r--src/mock_component_manager.h9
7 files changed, 150 insertions, 0 deletions
diff --git a/src/component_manager.h b/src/component_manager.h
index cf16720..832b274 100644
--- a/src/component_manager.h
+++ b/src/component_manager.h
@@ -85,6 +85,22 @@ class ComponentManager {
const std::vector<std::string>& traits,
ErrorPtr* error) = 0;
+ // Removes an existing component instance from device.
+ // |path| is a path to the parent component (or empty string if a root-level
+ // component is being removed).
+ // |name| is a name of the component to be removed.
+ virtual bool RemoveComponent(const std::string& path,
+ const std::string& name,
+ ErrorPtr* error) = 0;
+
+ // Removes an element from component array.
+ // |path| is a path to the parent component.
+ // |index| is a zero-based element index in the component array.
+ virtual bool RemoveComponentArrayItem(const std::string& path,
+ const std::string& name,
+ size_t index,
+ ErrorPtr* error) = 0;
+
// Sets callback which is called when new components are added.
virtual void AddComponentTreeChangedCallback(
const base::Closure& callback) = 0;
diff --git a/src/component_manager_impl.cc b/src/component_manager_impl.cc
index b1f3289..3f6ebf9 100644
--- a/src/component_manager_impl.cc
+++ b/src/component_manager_impl.cc
@@ -99,6 +99,63 @@ bool ComponentManagerImpl::AddComponentArrayItem(
return true;
}
+bool ComponentManagerImpl::RemoveComponent(const std::string& path,
+ const std::string& name,
+ ErrorPtr* error) {
+ base::DictionaryValue* root = &components_;
+ if (!path.empty()) {
+ root = FindComponentGraftNode(path, error);
+ if (!root)
+ return false;
+ }
+
+ if (!root->RemoveWithoutPathExpansion(name, nullptr)) {
+ Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
+ errors::commands::kInvalidState,
+ "Component '%s' does not exist at path '%s'",
+ name.c_str(), path.c_str());
+ return false;
+ }
+
+ for (const auto& cb : on_componet_tree_changed_)
+ cb.Run();
+ return true;
+}
+
+bool ComponentManagerImpl::RemoveComponentArrayItem(const std::string& path,
+ const std::string& name,
+ size_t index,
+ ErrorPtr* error) {
+ base::DictionaryValue* root = &components_;
+ if (!path.empty()) {
+ root = FindComponentGraftNode(path, error);
+ if (!root)
+ return false;
+ }
+
+ base::ListValue* array_value = nullptr;
+ if (!root->GetListWithoutPathExpansion(name, &array_value)) {
+ Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
+ errors::commands::kInvalidState,
+ "There is no component array named '%s' at path '%s'",
+ name.c_str(), path.c_str());
+ return false;
+ }
+
+ if (!array_value->Remove(index, nullptr)) {
+ Error::AddToPrintf(
+ error, FROM_HERE, errors::commands::kDomain,
+ errors::commands::kInvalidState,
+ "Component array '%s' at path '%s' does not have an element %zu",
+ name.c_str(), path.c_str(), index);
+ return false;
+ }
+
+ for (const auto& cb : on_componet_tree_changed_)
+ cb.Run();
+ return true;
+}
+
void ComponentManagerImpl::AddComponentTreeChangedCallback(
const base::Closure& callback) {
on_componet_tree_changed_.push_back(callback);
diff --git a/src/component_manager_impl.h b/src/component_manager_impl.h
index 97d302d..8c4ad16 100644
--- a/src/component_manager_impl.h
+++ b/src/component_manager_impl.h
@@ -47,6 +47,23 @@ class ComponentManagerImpl final : public ComponentManager {
const std::vector<std::string>& traits,
ErrorPtr* error) override;
+ // Removes an existing component instance from device.
+ // |path| is a path to the parent component (or empty string if a root-level
+ // component is being removed).
+ // |name| is a name of the component to be removed.
+ bool RemoveComponent(const std::string& path,
+ const std::string& name,
+ ErrorPtr* error) override;
+
+ // Removes an element from component array.
+ // |path| is a path to the parent component.
+ // |name| is an array root element inside the child components.
+ // |index| is a zero-based element index in the component array.
+ bool RemoveComponentArrayItem(const std::string& path,
+ const std::string& name,
+ size_t index,
+ ErrorPtr* error) override;
+
// Sets callback which is called when new components are added.
void AddComponentTreeChangedCallback(const base::Closure& callback) override;
diff --git a/src/component_manager_unittest.cc b/src/component_manager_unittest.cc
index 6b660b1..519b80a 100644
--- a/src/component_manager_unittest.cc
+++ b/src/component_manager_unittest.cc
@@ -519,6 +519,48 @@ TEST_F(ComponentManagerTest, AddComponentArrayItem) {
EXPECT_JSON_EQ(kExpected, manager_.GetComponents());
}
+TEST_F(ComponentManagerTest, RemoveComponent) {
+ CreateTestComponentTree(&manager_);
+ EXPECT_TRUE(manager_.RemoveComponent("comp1.comp2[1].comp3", "comp4",
+ nullptr));
+ const char kExpected1[] = R"({
+ "comp1": {
+ "traits": [ "t1" ],
+ "components": {
+ "comp2": [
+ {
+ "traits": [ "t2" ]
+ },
+ {
+ "traits": [ "t3" ],
+ "components": {
+ "comp3": {
+ "traits": [ "t4" ],
+ "components": {}
+ }
+ }
+ }
+ ]
+ }
+ }
+ })";
+ EXPECT_JSON_EQ(kExpected1, manager_.GetComponents());
+ EXPECT_TRUE(manager_.RemoveComponentArrayItem("comp1", "comp2", 1, nullptr));
+ const char kExpected2[] = R"({
+ "comp1": {
+ "traits": [ "t1" ],
+ "components": {
+ "comp2": [
+ {
+ "traits": [ "t2" ]
+ }
+ ]
+ }
+ }
+ })";
+ EXPECT_JSON_EQ(kExpected2, manager_.GetComponents());
+}
+
TEST_F(ComponentManagerTest, AddComponentExist) {
EXPECT_TRUE(manager_.AddComponent("", "comp1", {}, nullptr));
EXPECT_FALSE(manager_.AddComponent("", "comp1", {}, nullptr));
@@ -548,6 +590,10 @@ TEST_F(ComponentManagerTest, AddComponentTreeChangedCallback) {
EXPECT_EQ(5, count);
EXPECT_TRUE(manager_.AddComponentArrayItem("comp1", "comp3", {}, nullptr));
EXPECT_EQ(6, count);
+ EXPECT_TRUE(manager_.RemoveComponentArrayItem("comp1", "comp3", 1, nullptr));
+ EXPECT_EQ(7, count);
+ EXPECT_TRUE(manager_.RemoveComponent("", "comp1", nullptr));
+ EXPECT_EQ(8, count);
// Make sure both callbacks were called the same number of times.
EXPECT_EQ(count2, count);
}
diff --git a/src/device_manager.cc b/src/device_manager.cc
index 67a2c86..1158df7 100644
--- a/src/device_manager.cc
+++ b/src/device_manager.cc
@@ -106,6 +106,10 @@ bool DeviceManager::AddComponent(const std::string& name,
return component_manager_->AddComponent("", name, traits, error);
}
+bool DeviceManager::RemoveComponent(const std::string& name, ErrorPtr* error) {
+ return component_manager_->RemoveComponent("", name, error);
+}
+
void DeviceManager::AddComponentTreeChangedCallback(
const base::Closure& callback) {
component_manager_->AddComponentTreeChangedCallback(callback);
diff --git a/src/device_manager.h b/src/device_manager.h
index d21f398..d40ba8e 100644
--- a/src/device_manager.h
+++ b/src/device_manager.h
@@ -43,6 +43,7 @@ class DeviceManager final : public Device {
bool AddComponent(const std::string& name,
const std::vector<std::string>& traits,
ErrorPtr* error) override;
+ bool RemoveComponent(const std::string& name, ErrorPtr* error) override;
void AddComponentTreeChangedCallback(const base::Closure& callback) override;
const base::DictionaryValue& GetComponents() const override;
bool SetStatePropertiesFromJson(const std::string& component,
diff --git a/src/mock_component_manager.h b/src/mock_component_manager.h
index 08c1e59..addd6f0 100644
--- a/src/mock_component_manager.h
+++ b/src/mock_component_manager.h
@@ -28,6 +28,15 @@ class MockComponentManager : public ComponentManager {
const std::string& name,
const std::vector<std::string>& traits,
ErrorPtr* error));
+ MOCK_METHOD3(RemoveComponent,
+ bool(const std::string& path,
+ const std::string& name,
+ ErrorPtr* error));
+ MOCK_METHOD4(RemoveComponentArrayItem,
+ bool(const std::string& path,
+ const std::string& name,
+ size_t index,
+ ErrorPtr* error));
MOCK_METHOD1(AddComponentTreeChangedCallback,
void(const base::Closure& callback));
MOCK_METHOD1(MockAddCommand, void(CommandInstance* command_instance));