diff options
author | Alex Vakulenko <avakulenko@google.com> | 2015-10-07 17:04:00 -0700 |
---|---|---|
committer | Alex Vakulenko <avakulenko@google.com> | 2015-10-07 17:27:11 -0700 |
commit | 2915a7b9a45821a7530d2fea8a982bc1b6efc7d3 (patch) | |
tree | a644d2edae3063f698c190f533e85db2a4dede2e | |
parent | f1d01ac3f2dcb9162b04402bc8091b6b2c15f88f (diff) | |
download | weaved-2915a7b9a45821a7530d2fea8a982bc1b6efc7d3.tar.gz |
Merge latest version of libweave and update weaved to reflect changes
libweave has a number of interafce changes which need to be reflected in
weaved's implementation of the interfaces. This commit brings weaved in
sync with the current version of libweave.
Change-Id: If6355ef2c19e38b56f96b027038e2d6da0f44709
-rw-r--r-- | Android.mk | 10 | ||||
-rw-r--r-- | buffet/buffet_config.cc | 84 | ||||
-rw-r--r-- | buffet/buffet_config.h | 9 | ||||
-rw-r--r-- | buffet/dbus_bindings/com.android.Weave.Command.dbus-xml | 6 | ||||
-rw-r--r-- | buffet/dbus_command_dispatcher.cc | 11 | ||||
-rw-r--r-- | buffet/dbus_command_dispatcher.h | 10 | ||||
-rw-r--r-- | buffet/dbus_command_proxy.cc | 120 | ||||
-rw-r--r-- | buffet/dbus_command_proxy.h | 21 | ||||
-rw-r--r-- | buffet/dbus_command_proxy_unittest.cc | 79 | ||||
-rw-r--r-- | buffet/dbus_conversion.cc | 2 | ||||
-rw-r--r-- | buffet/etc/weaved/commands/weaved.json | 6 | ||||
-rw-r--r-- | buffet/main.cc | 36 | ||||
-rw-r--r-- | buffet/manager.cc | 138 | ||||
-rw-r--r-- | buffet/manager.h | 15 | ||||
-rw-r--r-- | buffet/test_daemon/main.cc | 6 |
15 files changed, 278 insertions, 275 deletions
@@ -88,7 +88,6 @@ include $(CLEAR_VARS) LOCAL_MODULE := weaved LOCAL_REQUIRED_MODULES := \ avahi-daemon \ - weaved.json \ com.android.Weave.conf \ webservd \ @@ -153,15 +152,6 @@ LOCAL_SRC_FILES := \ include $(BUILD_NATIVE_TEST) -# Config files for /etc/weaved -# ======================================================== -include $(CLEAR_VARS) -LOCAL_MODULE := weaved.json -LOCAL_MODULE_CLASS := ETC -LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/weaved/commands -LOCAL_SRC_FILES := buffet/etc/weaved/commands/weaved.json -include $(BUILD_PREBUILT) - # DBus config files for /etc/dbus-1 # ======================================================== include $(CLEAR_VARS) diff --git a/buffet/buffet_config.cc b/buffet/buffet_config.cc index a31dde8..fde6f0e 100644 --- a/buffet/buffet_config.cc +++ b/buffet/buffet_config.cc @@ -7,7 +7,6 @@ #include <map> #include <set> -#include <base/files/file_enumerator.h> #include <base/files/file_util.h> #include <base/files/important_file_writer.h> #include <base/logging.h> @@ -19,26 +18,6 @@ namespace buffet { -namespace { - -const char kErrorDomain[] = "buffet"; -const char kFileReadError[] = "file_read_error"; - -bool LoadFile(const base::FilePath& file_path, - std::string* data, - chromeos::ErrorPtr* error) { - if (!base::ReadFileToString(file_path, data)) { - chromeos::errors::system::AddSystemError(error, FROM_HERE, errno); - chromeos::Error::AddToPrintf(error, FROM_HERE, kErrorDomain, kFileReadError, - "Failed to read file '%s'", - file_path.value().c_str()); - return false; - } - return true; -} - -} // namespace - namespace config_keys { const char kClientId[] = "client_id"; @@ -64,8 +43,8 @@ const char kPairingModes[] = "pairing_modes"; BuffetConfig::BuffetConfig(const Options& options) : options_(options) {} bool BuffetConfig::LoadDefaults(weave::Settings* settings) { - // Keep this hard coded default for sometime. This previously was set by - // libweave. It should be set by overlays buffet.conf. + // Keep this hardcoded default for sometime. This previously was set by + // libweave. It should be set by overlay's buffet.conf. settings->client_id = "58855907228.apps.googleusercontent.com"; settings->client_secret = "eHSAREAHrIqPsHBxCE9zPPBi"; settings->api_key = "AIzaSyDSq46gG-AxUnC3zoqD9COIPrjolFsMfMA"; @@ -83,57 +62,18 @@ bool BuffetConfig::LoadDefaults(weave::Settings* settings) { bool result = LoadDefaults(store, settings); settings->disable_security = options_.disable_security; settings->test_privet_ssid = options_.test_privet_ssid; - return result; -} -std::map<std::string, std::string> BuffetConfig::LoadCommandDefs() { - std::map<std::string, std::string> result; - auto load_packages = [&result](const base::FilePath& root, - const base::FilePath::StringType& pattern) { - base::FilePath dir{root.Append("commands")}; - VLOG(2) << "Looking for commands in " << dir.value(); - base::FileEnumerator enumerator(dir, false, base::FileEnumerator::FILES, - pattern); - for (base::FilePath path = enumerator.Next(); !path.empty(); - path = enumerator.Next()) { - LOG(INFO) << "Loading command schema from " << path.value(); - std::string category = path.BaseName().RemoveExtension().value(); - CHECK(LoadFile(path, &result[category], nullptr)); - } - }; - load_packages(options_.definitions, FILE_PATH_LITERAL("*.json")); - load_packages(options_.test_definitions, FILE_PATH_LITERAL("*test.json")); - return result; -} + if (!options_.client_id.empty()) + settings->client_id = options_.client_id; + if (!options_.client_secret.empty()) + settings->client_secret = options_.client_secret; + if (!options_.api_key.empty()) + settings->api_key = options_.api_key; + if (!options_.oauth_url.empty()) + settings->oauth_url = options_.oauth_url; + if (!options_.service_url.empty()) + settings->service_url = options_.service_url; -std::map<std::string, std::string> BuffetConfig::LoadStateDefs() { - // Load component-specific device state definitions. - base::FilePath dir{options_.definitions.Append("states")}; - base::FileEnumerator enumerator(dir, false, base::FileEnumerator::FILES, - FILE_PATH_LITERAL("*.schema.json")); - std::map<std::string, std::string> result; - for (base::FilePath path = enumerator.Next(); !path.empty(); - path = enumerator.Next()) { - LOG(INFO) << "Loading state definition from " << path.value(); - std::string category = path.BaseName().RemoveExtension().value(); - CHECK(LoadFile(path, &result[category], nullptr)); - } - return result; -} - -std::vector<std::string> BuffetConfig::LoadStateDefaults() { - // Load component-specific device state defaults. - base::FilePath dir{options_.definitions.Append("states")}; - base::FileEnumerator enumerator(dir, false, base::FileEnumerator::FILES, - FILE_PATH_LITERAL("*.defaults.json")); - std::vector<std::string> result; - for (base::FilePath path = enumerator.Next(); !path.empty(); - path = enumerator.Next()) { - LOG(INFO) << "Loading state defaults from " << path.value(); - std::string json; - CHECK(LoadFile(path, &json, nullptr)); - result.push_back(json); - } return result; } diff --git a/buffet/buffet_config.h b/buffet/buffet_config.h index 20dea47..a286bf8 100644 --- a/buffet/buffet_config.h +++ b/buffet/buffet_config.h @@ -23,6 +23,12 @@ class StorageInterface; class BuffetConfig final : public weave::provider::ConfigStore { public: struct Options { + std::string client_id; + std::string client_secret; + std::string api_key; + std::string oauth_url; + std::string service_url; + base::FilePath defaults; base::FilePath settings; @@ -41,9 +47,6 @@ class BuffetConfig final : public weave::provider::ConfigStore { bool LoadDefaults(weave::Settings* settings) override; std::string LoadSettings() override; void SaveSettings(const std::string& settings) override; - std::map<std::string, std::string> LoadCommandDefs() override; - std::map<std::string, std::string> LoadStateDefs() override; - std::vector<std::string> LoadStateDefaults() override; bool LoadDefaults(const chromeos::KeyValueStore& store, weave::Settings* settings); diff --git a/buffet/dbus_bindings/com.android.Weave.Command.dbus-xml b/buffet/dbus_bindings/com.android.Weave.Command.dbus-xml index 8bb519a..5fb2940 100644 --- a/buffet/dbus_bindings/com.android.Weave.Command.dbus-xml +++ b/buffet/dbus_bindings/com.android.Weave.Command.dbus-xml @@ -15,20 +15,20 @@ Mark the command as aborted. This tells the cloud that the device did not successfully complete executing the command. </tp:docstring> - <annotation name="org.chromium.DBus.Method.Kind" value="simple"/> + <annotation name="org.chromium.DBus.Method.Kind" value="normal"/> </method> <method name="Cancel"> <tp:docstring> Mark the command as cancelled. Unlike Abort() this should be used when the device detects a user request to cancel a command. </tp:docstring> - <annotation name="org.chromium.DBus.Method.Kind" value="simple"/> + <annotation name="org.chromium.DBus.Method.Kind" value="normal"/> </method> <method name="Done"> <tp:docstring> Mark the command as successfully completed. </tp:docstring> - <annotation name="org.chromium.DBus.Method.Kind" value="simple"/> + <annotation name="org.chromium.DBus.Method.Kind" value="normal"/> </method> <property name="Name" type="s" access="read"/> <property name="Category" type="s" access="read"/> diff --git a/buffet/dbus_command_dispatcher.cc b/buffet/dbus_command_dispatcher.cc index 03f4789..0edb92a 100644 --- a/buffet/dbus_command_dispatcher.cc +++ b/buffet/dbus_command_dispatcher.cc @@ -6,6 +6,7 @@ #include <chromeos/dbus/exported_object_manager.h> #include <weave/command.h> +#include <weave/device.h> #include "buffet/dbus_command_proxy.h" #include "buffet/dbus_constants.h" @@ -17,14 +18,16 @@ namespace buffet { DBusCommandDispacher::DBusCommandDispacher( const base::WeakPtr<ExportedObjectManager>& object_manager, - weave::Commands* command_manager) + weave::Device* device) : object_manager_{object_manager} { - command_manager->AddOnCommandAddedCallback(base::Bind( + device->AddCommandHandler("", base::Bind( &DBusCommandDispacher::OnCommandAdded, weak_ptr_factory_.GetWeakPtr())); } -void DBusCommandDispacher::OnCommandAdded(weave::Command* command) { - if (!object_manager_) +void DBusCommandDispacher::OnCommandAdded( + const std::weak_ptr<weave::Command>& cmd) { + auto command = cmd.lock(); + if (!object_manager_ || !command) return; std::unique_ptr<DBusCommandProxy> proxy{new DBusCommandProxy( object_manager_.get(), object_manager_->GetBus(), command, diff --git a/buffet/dbus_command_dispatcher.h b/buffet/dbus_command_dispatcher.h index fa17ad6..082576a 100644 --- a/buffet/dbus_command_dispatcher.h +++ b/buffet/dbus_command_dispatcher.h @@ -10,7 +10,11 @@ #include <base/macros.h> #include <base/memory/weak_ptr.h> -#include <weave/commands.h> + +namespace weave { +class Command; +class Device; +} namespace chromeos { namespace dbus_utils { @@ -32,10 +36,10 @@ class DBusCommandDispacher final { explicit DBusCommandDispacher( const base::WeakPtr<chromeos::dbus_utils::ExportedObjectManager>& object_manager, - weave::Commands* command_manager); + weave::Device* device); private: - void OnCommandAdded(weave::Command* command); + void OnCommandAdded(const std::weak_ptr<weave::Command>& cmd); base::WeakPtr<chromeos::dbus_utils::ExportedObjectManager> object_manager_; int next_id_{0}; diff --git a/buffet/dbus_command_proxy.cc b/buffet/dbus_command_proxy.cc index d079392..71196e8 100644 --- a/buffet/dbus_command_proxy.cc +++ b/buffet/dbus_command_proxy.cc @@ -14,103 +14,137 @@ using chromeos::dbus_utils::AsyncEventSequencer; using chromeos::dbus_utils::ExportedObjectManager; +namespace errors { +namespace commands { +const char kDomain[] = "weaved"; +const char kCommandDestroyed[] = "command_destroyed"; +} // namespace commands +} // namespace errors + namespace buffet { +namespace { + +bool ReportDestroyedError(chromeos::ErrorPtr* error) { + chromeos::Error::AddTo(error, FROM_HERE, errors::commands::kDomain, + errors::commands::kCommandDestroyed, + "Command has been destroyed"); + return false; +} + +} // anonymous namespace + DBusCommandProxy::DBusCommandProxy(ExportedObjectManager* object_manager, const scoped_refptr<dbus::Bus>& bus, - weave::Command* command, + const std::weak_ptr<weave::Command>& command, std::string object_path) : command_{command}, - dbus_object_{object_manager, bus, dbus::ObjectPath{object_path}} { - observer_.Add(command); -} + dbus_object_{object_manager, bus, dbus::ObjectPath{object_path}} {} void DBusCommandProxy::RegisterAsync( const AsyncEventSequencer::CompletionAction& completion_callback) { + auto command = command_.lock(); + if (!command) + return; + dbus_adaptor_.RegisterWithDBusObject(&dbus_object_); // Set the initial property values before registering the DBus object. - dbus_adaptor_.SetName(command_->GetName()); - dbus_adaptor_.SetCategory(command_->GetCategory()); - dbus_adaptor_.SetId(command_->GetID()); - dbus_adaptor_.SetStatus(EnumToString(command_->GetStatus())); + dbus_adaptor_.SetName(command->GetName()); + dbus_adaptor_.SetId(command->GetID()); + dbus_adaptor_.SetStatus(EnumToString(command->GetStatus())); dbus_adaptor_.SetProgress( - DictionaryToDBusVariantDictionary(*command_->GetProgress())); - dbus_adaptor_.SetOrigin(EnumToString(command_->GetOrigin())); + DictionaryToDBusVariantDictionary(*command->GetProgress())); + dbus_adaptor_.SetOrigin(EnumToString(command->GetOrigin())); dbus_adaptor_.SetParameters( - DictionaryToDBusVariantDictionary(*command_->GetParameters())); + DictionaryToDBusVariantDictionary(*command->GetParameters())); dbus_adaptor_.SetResults( - DictionaryToDBusVariantDictionary(*command_->GetResults())); + DictionaryToDBusVariantDictionary(*command->GetResults())); // Register the command DBus object and expose its methods and properties. dbus_object_.RegisterAsync(completion_callback); } -void DBusCommandProxy::OnResultsChanged() { - dbus_adaptor_.SetResults( - DictionaryToDBusVariantDictionary(*command_->GetResults())); -} - -void DBusCommandProxy::OnStatusChanged() { - dbus_adaptor_.SetStatus(EnumToString(command_->GetStatus())); -} - -void DBusCommandProxy::OnProgressChanged() { - dbus_adaptor_.SetProgress( - DictionaryToDBusVariantDictionary(*command_->GetProgress())); -} - -void DBusCommandProxy::OnCommandDestroyed() { - delete this; -} - bool DBusCommandProxy::SetProgress( chromeos::ErrorPtr* error, const chromeos::VariantDictionary& progress) { - LOG(INFO) << "Received call to Command<" << command_->GetName() + auto command = command_.lock(); + if (!command) + return ReportDestroyedError(error); + + LOG(INFO) << "Received call to Command<" << command->GetName() << ">::SetProgress()"; auto dictionary = DictionaryFromDBusVariantDictionary(progress, error); if (!dictionary) return false; weave::ErrorPtr weave_error; - if (!command_->SetProgress(*dictionary, &weave_error)) { + if (!command->SetProgress(*dictionary, &weave_error)) { ConvertError(*weave_error, error); return false; } + dbus_adaptor_.SetProgress( + DictionaryToDBusVariantDictionary(*command->GetProgress())); + dbus_adaptor_.SetStatus(EnumToString(command->GetStatus())); return true; } bool DBusCommandProxy::SetResults(chromeos::ErrorPtr* error, const chromeos::VariantDictionary& results) { - LOG(INFO) << "Received call to Command<" << command_->GetName() + auto command = command_.lock(); + if (!command) + return ReportDestroyedError(error); + + LOG(INFO) << "Received call to Command<" << command->GetName() << ">::SetResults()"; auto dictionary = DictionaryFromDBusVariantDictionary(results, error); if (!dictionary) return false; weave::ErrorPtr weave_error; - if (!command_->SetResults(*dictionary, &weave_error)) { + if (!command->SetResults(*dictionary, &weave_error)) { ConvertError(*weave_error, error); return false; } + dbus_adaptor_.SetProgress( + DictionaryToDBusVariantDictionary(*command->GetProgress())); return true; } -void DBusCommandProxy::Abort() { - LOG(INFO) << "Received call to Command<" << command_->GetName() +bool DBusCommandProxy::Abort(chromeos::ErrorPtr* error) { + auto command = command_.lock(); + if (!command) + return ReportDestroyedError(error); + + LOG(INFO) << "Received call to Command<" << command->GetName() << ">::Abort()"; - command_->Abort(); + command->Abort(); + dbus_adaptor_.SetStatus(EnumToString(command->GetStatus())); + return true; } -void DBusCommandProxy::Cancel() { - LOG(INFO) << "Received call to Command<" << command_->GetName() +bool DBusCommandProxy::Cancel(chromeos::ErrorPtr* error) { + auto command = command_.lock(); + if (!command) + return ReportDestroyedError(error); + + LOG(INFO) << "Received call to Command<" << command->GetName() << ">::Cancel()"; - command_->Cancel(); + command->Cancel(); + dbus_adaptor_.SetStatus(EnumToString(command->GetStatus())); + return true; } -void DBusCommandProxy::Done() { - LOG(INFO) << "Received call to Command<" << command_->GetName() +bool DBusCommandProxy::Done(chromeos::ErrorPtr* error) { + auto command = command_.lock(); + if (!command) + return ReportDestroyedError(error); + + LOG(INFO) << "Received call to Command<" << command->GetName() << ">::Done()"; - command_->Done(); + command->Done(); + dbus_adaptor_.SetProgress( + DictionaryToDBusVariantDictionary(*command->GetProgress())); + dbus_adaptor_.SetStatus(EnumToString(command->GetStatus())); + return true; } } // namespace buffet diff --git a/buffet/dbus_command_proxy.h b/buffet/dbus_command_proxy.h index dc45738..bf2868d 100644 --- a/buffet/dbus_command_proxy.h +++ b/buffet/dbus_command_proxy.h @@ -23,12 +23,11 @@ class ExportedObjectManager; namespace buffet { -class DBusCommandProxy : public weave::Command::Observer, - public com::android::Weave::CommandInterface { +class DBusCommandProxy : public com::android::Weave::CommandInterface { public: DBusCommandProxy(chromeos::dbus_utils::ExportedObjectManager* object_manager, const scoped_refptr<dbus::Bus>& bus, - weave::Command* command, + const std::weak_ptr<weave::Command>& command, std::string object_path); ~DBusCommandProxy() override = default; @@ -36,12 +35,6 @@ class DBusCommandProxy : public weave::Command::Observer, const chromeos::dbus_utils::AsyncEventSequencer::CompletionAction& completion_callback); - // CommandProxyInterface implementation/overloads. - void OnResultsChanged() override; - void OnStatusChanged() override; - void OnProgressChanged() override; - void OnCommandDestroyed() override; - private: // Handles calls to com.android.Weave.Command.SetProgress(progress). bool SetProgress(chromeos::ErrorPtr* error, @@ -50,18 +43,16 @@ class DBusCommandProxy : public weave::Command::Observer, bool SetResults(chromeos::ErrorPtr* error, const chromeos::VariantDictionary& results) override; // Handles calls to com.android.Weave.Command.Abort(). - void Abort() override; + bool Abort(chromeos::ErrorPtr* error) override; // Handles calls to com.android.Weave.Command.Cancel(). - void Cancel() override; + bool Cancel(chromeos::ErrorPtr* error) override; // Handles calls to com.android.Weave.Command.Done(). - void Done() override; + bool Done(chromeos::ErrorPtr* error) override; - weave::Command* command_; + std::weak_ptr<weave::Command> command_; com::android::Weave::CommandAdaptor dbus_adaptor_{this}; chromeos::dbus_utils::DBusObject dbus_object_; - ScopedObserver<weave::Command, weave::Command::Observer> observer_{this}; - friend class DBusCommandProxyTest; friend class DBusCommandDispacherTest; DISALLOW_COPY_AND_ASSIGN(DBusCommandProxy); diff --git a/buffet/dbus_command_proxy_unittest.cc b/buffet/dbus_command_proxy_unittest.cc index 265e5f5..1e156e4 100644 --- a/buffet/dbus_command_proxy_unittest.cc +++ b/buffet/dbus_command_proxy_unittest.cc @@ -17,7 +17,6 @@ #include <weave/command.h> #include <weave/enum_to_string.h> #include <weave/test/mock_command.h> -#include <weave/test/mock_commands.h> #include <weave/test/unittest_utils.h> #include "buffet/dbus_constants.h" @@ -37,7 +36,6 @@ using weave::test::IsEqualValue; namespace { -const char kTestCommandCategoty[] = "test_command_category"; const char kTestCommandId[] = "cmd_1"; MATCHER_P(EqualToJson, json, "") { @@ -50,8 +48,7 @@ MATCHER_P(EqualToJson, json, "") { class DBusCommandProxyTest : public ::testing::Test { public: void SetUp() override { - EXPECT_CALL(command_, AddObserver(_)).Times(1); - EXPECT_CALL(command_, RemoveObserver(_)).Times(1); + command_ = std::make_shared<StrictMock<weave::test::MockCommand>>(); // Set up a mock DBus bus object. dbus::Bus::Options options; options.bus_type = dbus::Bus::SYSTEM; @@ -60,25 +57,23 @@ class DBusCommandProxyTest : public ::testing::Test { EXPECT_CALL(*bus_, AssertOnOriginThread()).Times(AnyNumber()); EXPECT_CALL(*bus_, AssertOnDBusThread()).Times(AnyNumber()); - EXPECT_CALL(command_, GetID()) + EXPECT_CALL(*command_, GetID()) .WillOnce(ReturnRefOfCopy<std::string>(kTestCommandId)); - // Use WillRepeatedly becase GetName is used for logging. - EXPECT_CALL(command_, GetName()) + // Use WillRepeatedly because GetName is used for logging. + EXPECT_CALL(*command_, GetName()) .WillRepeatedly(ReturnRefOfCopy<std::string>("robot.jump")); - EXPECT_CALL(command_, GetCategory()) - .WillOnce(ReturnRefOfCopy<std::string>(kTestCommandCategoty)); - EXPECT_CALL(command_, GetStatus()) - .WillOnce(Return(weave::CommandStatus::kQueued)); - EXPECT_CALL(command_, GetOrigin()) + EXPECT_CALL(*command_, GetStatus()) + .WillRepeatedly(Return(weave::CommandStatus::kQueued)); + EXPECT_CALL(*command_, GetOrigin()) .WillOnce(Return(weave::CommandOrigin::kLocal)); - EXPECT_CALL(command_, MockGetParameters()) + EXPECT_CALL(*command_, MockGetParameters()) .WillOnce(ReturnRefOfCopy<std::string>(R"({ 'height': 53, '_jumpType': '_withKick' })")); - EXPECT_CALL(command_, MockGetProgress()) - .WillOnce(ReturnRefOfCopy<std::string>("{}")); - EXPECT_CALL(command_, MockGetResults()) + EXPECT_CALL(*command_, MockGetProgress()) + .WillRepeatedly(ReturnRefOfCopy<std::string>("{}")); + EXPECT_CALL(*command_, MockGetResults()) .WillOnce(ReturnRefOfCopy<std::string>("{}")); // Set up a mock ExportedObject to be used with the DBus command proxy. @@ -94,7 +89,8 @@ class DBusCommandProxyTest : public ::testing::Test { EXPECT_CALL(*mock_exported_object_command_, ExportMethod(_, _, _, _)) .Times(AnyNumber()); - proxy_.reset(new DBusCommandProxy(nullptr, bus_, &command_, cmd_path)); + proxy_.reset(new DBusCommandProxy{ + nullptr, bus_, std::weak_ptr<weave::Command>{command_}, cmd_path}); GetCommandProxy()->RegisterAsync( AsyncEventSequencer::GetDefaultCompletionAction()); } @@ -124,7 +120,7 @@ class DBusCommandProxyTest : public ::testing::Test { scoped_refptr<dbus::MockExportedObject> mock_exported_object_command_; scoped_refptr<dbus::MockBus> bus_; - StrictMock<weave::test::MockCommand> command_; + std::shared_ptr<StrictMock<weave::test::MockCommand>> command_; std::unique_ptr<DBusCommandProxy> proxy_; }; @@ -137,42 +133,11 @@ TEST_F(DBusCommandProxyTest, Init) { EXPECT_EQ(VariantDictionary{}, GetCommandAdaptor()->GetProgress()); EXPECT_EQ(VariantDictionary{}, GetCommandAdaptor()->GetResults()); EXPECT_EQ("robot.jump", GetCommandAdaptor()->GetName()); - EXPECT_EQ(kTestCommandCategoty, GetCommandAdaptor()->GetCategory()); EXPECT_EQ(kTestCommandId, GetCommandAdaptor()->GetId()); } -TEST_F(DBusCommandProxyTest, OnProgressChanged) { - EXPECT_CALL(*mock_exported_object_command_, SendSignal(_)).Times(1); - EXPECT_CALL(command_, MockGetProgress()) - .WillOnce(ReturnRefOfCopy<std::string>("{'progress': 10}")); - proxy_->OnProgressChanged(); - EXPECT_EQ((VariantDictionary{{"progress", int32_t{10}}}), - GetCommandAdaptor()->GetProgress()); -} - -TEST_F(DBusCommandProxyTest, OnResultsChanged) { - EXPECT_CALL(*mock_exported_object_command_, SendSignal(_)).Times(1); - EXPECT_CALL(command_, MockGetResults()) - .WillOnce(ReturnRefOfCopy<std::string>( - "{'foo': 42, 'bar': 'foobar', 'resultList': [1, 2, 3]}")); - proxy_->OnResultsChanged(); - - EXPECT_EQ((VariantDictionary{{"foo", int32_t{42}}, - {"bar", std::string{"foobar"}}, - {"resultList", std::vector<int>{1, 2, 3}}}), - GetCommandAdaptor()->GetResults()); -} - -TEST_F(DBusCommandProxyTest, OnStatusChanged) { - EXPECT_CALL(*mock_exported_object_command_, SendSignal(_)).Times(1); - EXPECT_CALL(command_, GetStatus()) - .WillOnce(Return(weave::CommandStatus::kInProgress)); - proxy_->OnStatusChanged(); - EXPECT_EQ(weave::CommandStatus::kInProgress, GetCommandStatus()); -} - TEST_F(DBusCommandProxyTest, SetProgress) { - EXPECT_CALL(command_, SetProgress(EqualToJson("{'progress': 10}"), _)) + EXPECT_CALL(*command_, SetProgress(EqualToJson("{'progress': 10}"), _)) .WillOnce(Return(true)); EXPECT_TRUE( GetCommandInterface()->SetProgress(nullptr, {{"progress", int32_t{10}}})); @@ -180,7 +145,7 @@ TEST_F(DBusCommandProxyTest, SetProgress) { TEST_F(DBusCommandProxyTest, SetResults) { EXPECT_CALL( - command_, + *command_, SetResults( EqualToJson("{'foo': 42, 'bar': 'foobar', 'resultList': [1, 2, 3]}"), _)) @@ -192,18 +157,18 @@ TEST_F(DBusCommandProxyTest, SetResults) { } TEST_F(DBusCommandProxyTest, Abort) { - EXPECT_CALL(command_, Abort()); - GetCommandInterface()->Abort(); + EXPECT_CALL(*command_, Abort()); + EXPECT_TRUE(GetCommandInterface()->Abort(nullptr)); } TEST_F(DBusCommandProxyTest, Cancel) { - EXPECT_CALL(command_, Cancel()); - GetCommandInterface()->Cancel(); + EXPECT_CALL(*command_, Cancel()); + EXPECT_TRUE(GetCommandInterface()->Cancel(nullptr)); } TEST_F(DBusCommandProxyTest, Done) { - EXPECT_CALL(command_, Done()); - GetCommandInterface()->Done(); + EXPECT_CALL(*command_, Done()); + EXPECT_TRUE(GetCommandInterface()->Done(nullptr)); } } // namespace buffet diff --git a/buffet/dbus_conversion.cc b/buffet/dbus_conversion.cc index 51d35f1..e943ad7 100644 --- a/buffet/dbus_conversion.cc +++ b/buffet/dbus_conversion.cc @@ -237,7 +237,7 @@ std::unique_ptr<base::DictionaryValue> DictionaryFromDBusVariantDictionary( auto value = CreateValue(pair.second, error); if (!value) return nullptr; - result->SetWithoutPathExpansion(pair.first, value.release()); + result->Set(pair.first, value.release()); } return result; diff --git a/buffet/etc/weaved/commands/weaved.json b/buffet/etc/weaved/commands/weaved.json deleted file mode 100644 index 4196a22..0000000 --- a/buffet/etc/weaved/commands/weaved.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "base": { - "updateBaseConfiguration": { }, - "updateDeviceInfo": { } - } -} diff --git a/buffet/main.cc b/buffet/main.cc index bda526b..616542d 100644 --- a/buffet/main.cc +++ b/buffet/main.cc @@ -27,26 +27,19 @@ namespace buffet { class Daemon final : public DBusServiceDaemon { public: - Daemon(const Manager::Options& options, - const BuffetConfig::Options& config_options, - const std::set<std::string>& device_whitelist) - : DBusServiceDaemon(kServiceName, kRootServicePath), - options_{options}, - config_options_{config_options}, - device_whitelist_{device_whitelist} {} + explicit Daemon(const Manager::Options& options) + : DBusServiceDaemon(kServiceName, kRootServicePath), options_{options} {} protected: void RegisterDBusObjectsAsync(AsyncEventSequencer* sequencer) override { - manager_.reset(new Manager(object_manager_->AsWeakPtr())); - manager_->Start(options_, config_options_, device_whitelist_, sequencer); + manager_.reset(new Manager(options_, object_manager_->AsWeakPtr())); + manager_->Start(sequencer); } void OnShutdown(int* return_code) override { manager_->Stop(); } private: Manager::Options options_; - BuffetConfig::Options config_options_; - std::set<std::string> device_whitelist_; std::unique_ptr<buffet::Manager> manager_; DISALLOW_COPY_AND_ASSIGN(Daemon); @@ -101,21 +94,20 @@ int main(int argc, char* argv[]) { // Mark it to be ignored. signal(SIGPIPE, SIG_IGN); - buffet::BuffetConfig::Options config_options; - config_options.defaults = base::FilePath{FLAGS_config_path}; - config_options.settings = base::FilePath{FLAGS_state_path}; - config_options.definitions = base::FilePath{"/etc/weaved"}; - config_options.test_definitions = base::FilePath{FLAGS_test_definitions_path}; - config_options.disable_security = FLAGS_disable_security; - config_options.test_privet_ssid = FLAGS_test_privet_ssid; - buffet::Manager::Options options; options.xmpp_enabled = FLAGS_enable_xmpp; options.disable_privet = FLAGS_disable_privet; options.enable_ping = FLAGS_enable_ping; + options.device_whitelist = {device_whitelist.begin(), device_whitelist.end()}; + + options.config_options.defaults = base::FilePath{FLAGS_config_path}; + options.config_options.settings = base::FilePath{FLAGS_state_path}; + options.config_options.definitions = base::FilePath{"/etc/weaved"}; + options.config_options.test_definitions = + base::FilePath{FLAGS_test_definitions_path}; + options.config_options.disable_security = FLAGS_disable_security; + options.config_options.test_privet_ssid = FLAGS_test_privet_ssid; - buffet::Daemon daemon{ - options, config_options, - std::set<std::string>{device_whitelist.begin(), device_whitelist.end()}}; + buffet::Daemon daemon{options}; return daemon.Run(); } diff --git a/buffet/manager.cc b/buffet/manager.cc index f471ded..c3cbc87 100644 --- a/buffet/manager.cc +++ b/buffet/manager.cc @@ -10,6 +10,8 @@ #include <base/bind.h> #include <base/bind_helpers.h> +#include <base/files/file_enumerator.h> +#include <base/files/file_util.h> #include <base/json/json_reader.h> #include <base/json/json_writer.h> #include <base/message_loop/message_loop.h> @@ -50,6 +52,74 @@ const char kPairingModeKey[] = "mode"; const char kPairingCodeKey[] = "code"; const char kErrorDomain[] = "buffet"; +const char kFileReadError[] = "file_read_error"; + +bool LoadFile(const base::FilePath& file_path, + std::string* data, + chromeos::ErrorPtr* error) { + if (!base::ReadFileToString(file_path, data)) { + chromeos::errors::system::AddSystemError(error, FROM_HERE, errno); + chromeos::Error::AddToPrintf(error, FROM_HERE, kErrorDomain, kFileReadError, + "Failed to read file '%s'", + file_path.value().c_str()); + return false; + } + return true; +} + +void LoadCommandDefinitions(const BuffetConfig::Options& options, + weave::Device* device) { + auto load_packages = [device](const base::FilePath& root, + const base::FilePath::StringType& pattern) { + base::FilePath dir{root.Append("commands")}; + LOG(INFO) << "Looking for command schemas in " << dir.value(); + base::FileEnumerator enumerator(dir, false, base::FileEnumerator::FILES, + pattern); + for (base::FilePath path = enumerator.Next(); !path.empty(); + path = enumerator.Next()) { + LOG(INFO) << "Loading command schema from " << path.value(); + std::string json; + CHECK(LoadFile(path, &json, nullptr)); + device->AddCommandDefinitionsFromJson(json); + } + }; + load_packages(options.definitions, FILE_PATH_LITERAL("*.json")); + load_packages(options.test_definitions, FILE_PATH_LITERAL("*test.json")); +} + +void LoadStateDefinitions(const BuffetConfig::Options& options, + weave::Device* device) { + // Load component-specific device state definitions. + base::FilePath dir{options.definitions.Append("states")}; + LOG(INFO) << "Looking for state definitions in " << dir.value(); + base::FileEnumerator enumerator(dir, false, base::FileEnumerator::FILES, + FILE_PATH_LITERAL("*.schema.json")); + std::vector<std::string> result; + for (base::FilePath path = enumerator.Next(); !path.empty(); + path = enumerator.Next()) { + LOG(INFO) << "Loading state definition from " << path.value(); + std::string json; + CHECK(LoadFile(path, &json, nullptr)); + device->AddStateDefinitionsFromJson(json); + } +} + +void LoadStateDefaults(const BuffetConfig::Options& options, + weave::Device* device) { + // Load component-specific device state defaults. + base::FilePath dir{options.definitions.Append("states")}; + LOG(INFO) << "Looking for state defaults in " << dir.value(); + base::FileEnumerator enumerator(dir, false, base::FileEnumerator::FILES, + FILE_PATH_LITERAL("*.defaults.json")); + std::vector<std::string> result; + for (base::FilePath path = enumerator.Next(); !path.empty(); + path = enumerator.Next()) { + LOG(INFO) << "Loading state defaults from " << path.value(); + std::string json; + CHECK(LoadFile(path, &json, nullptr)); + CHECK(device->SetStatePropertiesFromJson(json, nullptr)); + } +} } // anonymous namespace @@ -62,32 +132,42 @@ class Manager::TaskRunner : public weave::provider::TaskRunner { } }; -Manager::Manager(const base::WeakPtr<ExportedObjectManager>& object_manager) - : dbus_object_(object_manager.get(), +Manager::Manager(const Options& options, + const base::WeakPtr<ExportedObjectManager>& object_manager) + : options_{options}, + dbus_object_(object_manager.get(), object_manager->GetBus(), - com::android::Weave::ManagerAdaptor::GetObjectPath()) { -} + com::android::Weave::ManagerAdaptor::GetObjectPath()) {} Manager::~Manager() { } -void Manager::Start(const Options& options, - const BuffetConfig::Options& paths, - const std::set<std::string>& device_whitelist, - AsyncEventSequencer* sequencer) { +void Manager::Start(AsyncEventSequencer* sequencer) { + RestartWeave(sequencer); + + dbus_adaptor_.RegisterWithDBusObject(&dbus_object_); + dbus_object_.RegisterAsync( + sequencer->GetHandler("Manager.RegisterAsync() failed.", true)); +} + +void Manager::RestartWeave(AsyncEventSequencer* sequencer) { + Stop(); + task_runner_.reset(new TaskRunner{}); + config_.reset(new BuffetConfig{options_.config_options}); http_client_.reset(new HttpTransportClient); - shill_client_.reset(new ShillClient{dbus_object_.GetBus(), device_whitelist, - !options.xmpp_enabled}); + shill_client_.reset(new ShillClient{dbus_object_.GetBus(), + options_.device_whitelist, + !options_.xmpp_enabled}); weave::provider::HttpServer* http_server{nullptr}; #ifdef BUFFET_USE_WIFI_BOOTSTRAPPING - if (!options.disable_privet) { + if (!options_.disable_privet) { mdns_client_ = MdnsClient::CreateInstance(dbus_object_.GetBus()); web_serv_client_.reset(new WebServClient{dbus_object_.GetBus(), sequencer}); bluetooth_client_ = BluetoothClient::CreateInstance(); http_server = web_serv_client_.get(); - if (options.enable_ping) { + if (options_.enable_ping) { http_server->AddRequestHandler( "/privet/ping", base::Bind( @@ -100,17 +180,20 @@ void Manager::Start(const Options& options, } #endif // BUFFET_USE_WIFI_BOOTSTRAPPING - config_.reset(new BuffetConfig{paths}); device_ = weave::Device::Create(config_.get(), task_runner_.get(), http_client_.get(), shill_client_.get(), mdns_client_.get(), web_serv_client_.get(), shill_client_.get(), bluetooth_client_.get()); + LoadCommandDefinitions(options_.config_options, device_.get()); + LoadStateDefinitions(options_.config_options, device_.get()); + LoadStateDefaults(options_.config_options, device_.get()); + device_->AddSettingsChangedCallback( base::Bind(&Manager::OnConfigChanged, weak_ptr_factory_.GetWeakPtr())); - command_dispatcher_.reset(new DBusCommandDispacher{ - dbus_object_.GetObjectManager(), device_->GetCommands()}); + command_dispatcher_.reset( + new DBusCommandDispacher{dbus_object_.GetObjectManager(), device_.get()}); device_->AddStateChangedCallback( base::Bind(&Manager::OnStateChanged, weak_ptr_factory_.GetWeakPtr())); @@ -118,19 +201,22 @@ void Manager::Start(const Options& options, device_->AddGcdStateChangedCallback( base::Bind(&Manager::OnGcdStateChanged, weak_ptr_factory_.GetWeakPtr())); - if (!options.disable_privet) { - device_->AddPairingChangedCallbacks( - base::Bind(&Manager::OnPairingStart, weak_ptr_factory_.GetWeakPtr()), - base::Bind(&Manager::OnPairingEnd, weak_ptr_factory_.GetWeakPtr())); - } - - dbus_adaptor_.RegisterWithDBusObject(&dbus_object_); - dbus_object_.RegisterAsync( - sequencer->GetHandler("Manager.RegisterAsync() failed.", true)); + device_->AddPairingChangedCallbacks( + base::Bind(&Manager::OnPairingStart, weak_ptr_factory_.GetWeakPtr()), + base::Bind(&Manager::OnPairingEnd, weak_ptr_factory_.GetWeakPtr())); } void Manager::Stop() { + command_dispatcher_.reset(); device_.reset(); +#ifdef BUFFET_USE_WIFI_BOOTSTRAPPING + web_serv_client_.reset(); + mdns_client_.reset(); +#endif // BUFFET_USE_WIFI_BOOTSTRAPPING + shill_client_.reset(); + http_client_.reset(); + config_.reset(); + task_runner_.reset(); } void Manager::RegisterDevice(DBusMethodResponsePtr<std::string> response, @@ -188,7 +274,7 @@ void Manager::AddCommand(DBusMethodResponsePtr<std::string> response, std::string id; weave::ErrorPtr error; - if (!device_->GetCommands()->AddCommand(*command, &id, &error)) { + if (!device_->AddCommand(*command, &id, &error)) { chromeos::ErrorPtr chromeos_error; ConvertError(*error, &chromeos_error); return response->ReplyWithError(chromeos_error.get()); @@ -199,7 +285,7 @@ void Manager::AddCommand(DBusMethodResponsePtr<std::string> response, void Manager::GetCommand(DBusMethodResponsePtr<std::string> response, const std::string& id) { - const weave::Command* command = device_->GetCommands()->FindCommand(id); + const weave::Command* command = device_->FindCommand(id); if (!command) { response->ReplyWithError(FROM_HERE, kErrorDomain, "unknown_command", "Can't find command with id: " + id); diff --git a/buffet/manager.h b/buffet/manager.h index d7e8377..9ae5b17 100644 --- a/buffet/manager.h +++ b/buffet/manager.h @@ -55,21 +55,24 @@ class Manager final : public com::android::Weave::ManagerInterface { bool xmpp_enabled = true; bool disable_privet = false; bool enable_ping = false; + std::set<std::string> device_whitelist; + + BuffetConfig::Options config_options; }; explicit Manager( + const Options& options, const base::WeakPtr<chromeos::dbus_utils::ExportedObjectManager>& object_manager); ~Manager(); - void Start(const Options& options, - const BuffetConfig::Options& config_options, - const std::set<std::string>& device_whitelist, - chromeos::dbus_utils::AsyncEventSequencer* sequencer); + void Start(chromeos::dbus_utils::AsyncEventSequencer* sequencer); void Stop(); private: + void RestartWeave(chromeos::dbus_utils::AsyncEventSequencer* sequencer); + // DBus methods: void RegisterDevice(DBusMethodResponsePtr<std::string> response, const std::string& ticket_id) override; @@ -93,17 +96,19 @@ class Manager final : public com::android::Weave::ManagerInterface { const std::vector<uint8_t>& code); void OnPairingEnd(const std::string& session_id); + Options options_; + com::android::Weave::ManagerAdaptor dbus_adaptor_{this}; chromeos::dbus_utils::DBusObject dbus_object_; class TaskRunner; std::unique_ptr<TaskRunner> task_runner_; std::unique_ptr<BluetoothClient> bluetooth_client_; + std::unique_ptr<BuffetConfig> config_; std::unique_ptr<HttpTransportClient> http_client_; std::unique_ptr<ShillClient> shill_client_; std::unique_ptr<MdnsClient> mdns_client_; std::unique_ptr<WebServClient> web_serv_client_; - std::unique_ptr<BuffetConfig> config_; std::unique_ptr<weave::Device> device_; std::unique_ptr<DBusCommandDispacher> command_dispatcher_; diff --git a/buffet/test_daemon/main.cc b/buffet/test_daemon/main.cc index a25a4ac..5016b0b 100644 --- a/buffet/test_daemon/main.cc +++ b/buffet/test_daemon/main.cc @@ -22,7 +22,6 @@ #include "buffet/dbus-proxies.h" namespace { -const char kTestCommandCategory[] = "test"; std::unique_ptr<base::DictionaryValue> DictionaryToJson( const chromeos::VariantDictionary& dictionary); @@ -125,17 +124,14 @@ void Daemon::OnPropertyChange(com::android::Weave::CommandProxy* command, void Daemon::OnBuffetCommand(com::android::Weave::CommandProxy* command) { // "Handle" only commands that belong to this daemon's category. - if (command->category() != kTestCommandCategory || - command->status() == "done") { + if (command->status() == "done") return; - } command->SetPropertyChangedCallback(base::Bind(&Daemon::OnPropertyChange, base::Unretained(this))); printf("++++++++++++++++++++++++++++++++++++++++++++++++\n"); printf("Command received: %s\n", command->name().c_str()); printf("DBus Object Path: %s\n", command->GetObjectPath().value().c_str()); - printf(" category: %s\n", command->category().c_str()); printf(" ID: %s\n", command->id().c_str()); printf(" status: %s\n", command->status().c_str()); printf(" origin: %s\n", command->origin().c_str()); |