Add trait/component APIs to weaved

Added new Device::AddComponent() method as well as added |component|
parameter to AddCommandHandler, SetStateProperty/SetStateProperties
methods. Added GetComponent() method to Command class.

Marked old APIs (that don't take component name) as deprecated.

Finally, made weaved load trait definitions from /etc/weaved/traits
directory.

BUG: 25917608, 25917704, 25916429, 25917604, 25917426, 25916428
Change-Id: I252f3930d1fda79e41c062d71f008210d2c116a4
diff --git a/buffet/manager.cc b/buffet/manager.cc
index 61a5d7a..85a9024 100644
--- a/buffet/manager.cc
+++ b/buffet/manager.cc
@@ -80,6 +80,23 @@
   return true;
 }
 
+void LoadTraitDefinitions(const BuffetConfig::Options& options,
+                          weave::Device* device) {
+  // Load component-specific device trait definitions.
+  base::FilePath dir{options.definitions.Append("traits")};
+  LOG(INFO) << "Looking for trait definitions in " << dir.value();
+  base::FileEnumerator enumerator(dir, false, base::FileEnumerator::FILES,
+                                  FILE_PATH_LITERAL("*.json"));
+  std::vector<std::string> result;
+  for (base::FilePath path = enumerator.Next(); !path.empty();
+       path = enumerator.Next()) {
+    LOG(INFO) << "Loading trait definition from " << path.value();
+    std::string json;
+    CHECK(LoadFile(path, &json, nullptr));
+    device->AddTraitDefinitionsFromJson(json);
+  }
+}
+
 void LoadCommandDefinitions(const BuffetConfig::Options& options,
                             weave::Device* device) {
   auto load_packages = [device](const base::FilePath& root,
@@ -97,7 +114,8 @@
     }
   };
   load_packages(options.definitions, FILE_PATH_LITERAL("*.json"));
-  load_packages(options.test_definitions, FILE_PATH_LITERAL("*test.json"));
+  if (!options.test_definitions.empty())
+    load_packages(options.test_definitions, FILE_PATH_LITERAL("*test.json"));
 }
 
 void LoadStateDefinitions(const BuffetConfig::Options& options,
@@ -207,6 +225,7 @@
                                   mdns_client_.get(), web_serv_client_.get(),
                                   shill_client_.get(), bluetooth_client_.get());
 
+  LoadTraitDefinitions(options_.config_options, device_.get());
   LoadCommandDefinitions(options_.config_options, device_.get());
   LoadStateDefinitions(options_.config_options, device_.get());
   LoadStateDefaults(options_.config_options, device_.get());
@@ -267,7 +286,20 @@
   response->Return(device_->GetSettings().cloud_id);
 }
 
+void Manager::AddComponent(DBusMethodResponsePtr<> response,
+                           const std::string& name,
+                           const std::vector<std::string>& traits) {
+  brillo::ErrorPtr brillo_error;
+  weave::ErrorPtr error;
+  if (!device_->AddComponent(name, traits, &error)) {
+    ConvertError(*error, &brillo_error);
+    return response->ReplyWithError(brillo_error.get());
+  }
+  response->Return();
+}
+
 void Manager::UpdateState(DBusMethodResponsePtr<> response,
+                          const std::string& component,
                           const brillo::VariantDictionary& property_set) {
   brillo::ErrorPtr brillo_error;
   auto properties =
@@ -276,7 +308,7 @@
     return response->ReplyWithError(brillo_error.get());
 
   weave::ErrorPtr error;
-  if (!device_->SetStateProperties(*properties, &error)) {
+  if (!device_->SetStateProperties(component, *properties, &error)) {
     ConvertError(*error, &brillo_error);
     return response->ReplyWithError(brillo_error.get());
   }