buffet: Add base.updateBaseConfiguration implementation Required base command handled by buffet. BUG=brillo:810 TEST=`FEATURES=test emerge-gizmo buffet` Change-Id: I97ecd9f5d792cc636e76bbff92899a7ddfa4a605 Reviewed-on: https://chromium-review.googlesource.com/273618 Reviewed-by: Vitaly Buka <vitalybuka@chromium.org> Commit-Queue: Vitaly Buka <vitalybuka@chromium.org> Tested-by: Vitaly Buka <vitalybuka@chromium.org>
diff --git a/buffet/base_api_handler.cc b/buffet/base_api_handler.cc index 69ed67c..16e9ec3 100644 --- a/buffet/base_api_handler.cc +++ b/buffet/base_api_handler.cc
@@ -7,6 +7,7 @@ #include "buffet/commands/command_instance.h" #include "buffet/commands/command_manager.h" #include "buffet/device_registration_info.h" +#include "buffet/states/state_manager.h" namespace buffet { @@ -30,6 +31,17 @@ return true; } + bool GetParameter(const std::string& name, bool* value) const { + auto it = parameters_->find(name); + if (it == parameters_->end()) + return false; + const BooleanValue* bool_value = it->second->GetBoolean(); + if (!bool_value) + return false; + *value = bool_value->GetValue(); + return true; + } + private: const native_types::Object* parameters_; }; @@ -38,8 +50,9 @@ BaseApiHandler::BaseApiHandler( const base::WeakPtr<DeviceRegistrationInfo>& device_info, + const std::shared_ptr<StateManager>& state_manager, const std::shared_ptr<CommandManager>& command_manager) - : device_info_{device_info} { + : device_info_{device_info}, state_manager_{state_manager} { command_manager->AddOnCommandAddedCallback(base::Bind( &BaseApiHandler::OnCommandAdded, weak_ptr_factory_.GetWeakPtr())); } @@ -48,10 +61,44 @@ if (command->GetStatus() != CommandInstance::kStatusQueued) return; + if (command->GetName() == "base.updateBaseConfiguration") + return UpdateBaseConfiguration(command); + if (command->GetName() == "base.updateDeviceInfo") return UpdateDeviceInfo(command); } +void BaseApiHandler::UpdateBaseConfiguration(CommandInstance* command) { + command->SetProgress({}); + + const BuffetConfig& config{device_info_->GetConfig()}; + std::string anonymous_access_role{config.local_anonymous_access_role()}; + bool discovery_enabled{config.local_discovery_enabled()}; + bool pairing_enabled{config.local_pairing_enabled()}; + + ParametersReader parameters{&command->GetParameters()}; + parameters.GetParameter("localAnonymousAccessMaxRole", + &anonymous_access_role); + parameters.GetParameter("localDiscoveryEnabled", &discovery_enabled); + parameters.GetParameter("localPairingEnabled", &pairing_enabled); + + chromeos::VariantDictionary state{ + {"base.localAnonymousAccessMaxRole", anonymous_access_role}, + {"base.localDiscoveryEnabled", discovery_enabled}, + {"base.localPairingEnabled", pairing_enabled}, + }; + if (!state_manager_->SetProperties(state, nullptr)) { + return command->Abort(); + } + + if (!device_info_->UpdateBaseConfig(anonymous_access_role, discovery_enabled, + pairing_enabled, nullptr)) { + return command->Abort(); + } + + command->Done(); +} + void BaseApiHandler::UpdateDeviceInfo(CommandInstance* command) { command->SetProgress({});
diff --git a/buffet/base_api_handler.h b/buffet/base_api_handler.h index 8743bcf..9c9bcb0 100644 --- a/buffet/base_api_handler.h +++ b/buffet/base_api_handler.h
@@ -15,22 +15,27 @@ class CommandInstance; class CommandManager; class DeviceRegistrationInfo; +class StateManager; // Handles commands from 'base' package. // Objects of the class subscribe for notification from CommandManager and // execute incoming commands. // Handled commands: // base.updateDeviceInfo +// base.updateBaseConfiguration class BaseApiHandler final { public: BaseApiHandler(const base::WeakPtr<DeviceRegistrationInfo>& device_info, + const std::shared_ptr<StateManager>& state_manager, const std::shared_ptr<CommandManager>& command_manager); private: void OnCommandAdded(CommandInstance* command); + void UpdateBaseConfiguration(CommandInstance* command); void UpdateDeviceInfo(CommandInstance* command); base::WeakPtr<DeviceRegistrationInfo> device_info_; + std::shared_ptr<StateManager> state_manager_; base::WeakPtrFactory<BaseApiHandler> weak_ptr_factory_{this}; DISALLOW_COPY_AND_ASSIGN(BaseApiHandler);
diff --git a/buffet/base_api_handler_unittest.cc b/buffet/base_api_handler_unittest.cc index d1de49f..cde0c41 100644 --- a/buffet/base_api_handler_unittest.cc +++ b/buffet/base_api_handler_unittest.cc
@@ -25,13 +25,37 @@ transport_ = std::make_shared<chromeos::http::fake::Transport>(); command_manager_ = std::make_shared<CommandManager>(); state_manager_ = std::make_shared<StateManager>(&mock_state_change_queue_); - state_manager_->Startup(); + auto state_definition = unittests::CreateDictionaryValue(R"({ + 'base': { + 'firmwareVersion': 'string', + 'localDiscoveryEnabled': 'boolean', + 'localAnonymousAccessMaxRole': [ 'none', 'viewer', 'user' ], + 'localPairingEnabled': 'boolean', + 'network': { + 'properties': { + 'name': 'string' + } + } + } + })"); + auto state_defaults = unittests::CreateDictionaryValue(R"({ + 'base': { + 'firmwareVersion': '123123', + 'localDiscoveryEnabled': false, + 'localAnonymousAccessMaxRole': 'none', + 'localPairingEnabled': false + } + })"); + ASSERT_TRUE(state_manager_->LoadStateDefinition(*state_definition, "base", + nullptr)); + ASSERT_TRUE(state_manager_->LoadStateDefaults(*state_defaults, nullptr)); dev_reg_.reset(new DeviceRegistrationInfo( command_manager_, state_manager_, std::unique_ptr<BuffetConfig>{new BuffetConfig{ std::unique_ptr<StorageInterface>{new MemStorage}}}, transport_, true)); - handler_.reset(new BaseApiHandler{dev_reg_->AsWeakPtr(), command_manager_}); + handler_.reset(new BaseApiHandler{ + dev_reg_->AsWeakPtr(), state_manager_, command_manager_}); } void LoadCommands(const std::string& command_definitions) { @@ -63,6 +87,68 @@ int command_id_{0}; }; +TEST_F(BaseApiHandlerTest, UpdateBaseConfiguration) { + LoadCommands(R"({ + 'base': { + 'updateBaseConfiguration': { + 'parameters': { + 'localDiscoveryEnabled': 'boolean', + 'localAnonymousAccessMaxRole': [ 'none', 'viewer', 'user' ], + 'localPairingEnabled': 'boolean' + }, + 'results': {} + } + } + })"); + + const BuffetConfig& config{dev_reg_->GetConfig()}; + + AddCommand(R"({ + 'name' : 'base.updateBaseConfiguration', + 'parameters': { + 'localDiscoveryEnabled': false, + 'localAnonymousAccessMaxRole': 'none', + 'localPairingEnabled': false + } + })"); + EXPECT_EQ("none", config.local_anonymous_access_role()); + EXPECT_FALSE(config.local_discovery_enabled()); + EXPECT_FALSE(config.local_pairing_enabled()); + + auto expected = R"({ + 'base': { + 'firmwareVersion': '123123', + 'localAnonymousAccessMaxRole': 'none', + 'localDiscoveryEnabled': false, + 'localPairingEnabled': false, + 'network': {} + } + })"; + EXPECT_JSON_EQ(expected, *state_manager_->GetStateValuesAsJson(nullptr)); + + AddCommand(R"({ + 'name' : 'base.updateBaseConfiguration', + 'parameters': { + 'localDiscoveryEnabled': true, + 'localAnonymousAccessMaxRole': 'user', + 'localPairingEnabled': true + } + })"); + EXPECT_EQ("user", config.local_anonymous_access_role()); + EXPECT_TRUE(config.local_discovery_enabled()); + EXPECT_TRUE(config.local_pairing_enabled()); + expected = R"({ + 'base': { + 'firmwareVersion': '123123', + 'localAnonymousAccessMaxRole': 'user', + 'localDiscoveryEnabled': true, + 'localPairingEnabled': true, + 'network': {} + } + })"; + EXPECT_JSON_EQ(expected, *state_manager_->GetStateValuesAsJson(nullptr)); +} + TEST_F(BaseApiHandlerTest, UpdateDeviceInfo) { LoadCommands(R"({ 'base': {
diff --git a/buffet/device_registration_info.cc b/buffet/device_registration_info.cc index 1fc329f..bd99917 100644 --- a/buffet/device_registration_info.cc +++ b/buffet/device_registration_info.cc
@@ -672,6 +672,25 @@ return true; } +bool DeviceRegistrationInfo::UpdateBaseConfig( + const std::string& anonymous_access_role, + bool local_discovery_enabled, + bool local_pairing_enabled, + chromeos::ErrorPtr* error) { + BuffetConfig::Transaction change(config_.get()); + if (!change.set_local_anonymous_access_role(anonymous_access_role)) { + chromeos::Error::AddToPrintf(error, FROM_HERE, kErrorDomainBuffet, + "invalid_parameter", "Invalid role: %s", + anonymous_access_role.c_str()); + return false; + } + + change.set_local_discovery_enabled(local_discovery_enabled); + change.set_local_pairing_enabled(local_pairing_enabled); + + return true; +} + bool DeviceRegistrationInfo::UpdateServiceConfig( const std::string& client_id, const std::string& client_secret,
diff --git a/buffet/device_registration_info.h b/buffet/device_registration_info.h index fe11d87..f8c2292 100644 --- a/buffet/device_registration_info.h +++ b/buffet/device_registration_info.h
@@ -122,6 +122,12 @@ const std::string& location, chromeos::ErrorPtr* error); + // Updates base device config. + bool UpdateBaseConfig(const std::string& anonymous_access_role, + bool local_discovery_enabled, + bool local_pairing_enabled, + chromeos::ErrorPtr* error); + // Updates GCD service configuration. Usually for testing. bool UpdateServiceConfig(const std::string& client_id, const std::string& client_secret,
diff --git a/buffet/manager.cc b/buffet/manager.cc index c69dfdd..1fd85c2 100644 --- a/buffet/manager.cc +++ b/buffet/manager.cc
@@ -77,8 +77,8 @@ device_info_->AddOnRegistrationChangedCallback(base::Bind( &Manager::OnRegistrationChanged, weak_ptr_factory_.GetWeakPtr())); - base_api_handler_.reset( - new BaseApiHandler{device_info_->AsWeakPtr(), command_manager_}); + base_api_handler_.reset(new BaseApiHandler{ + device_info_->AsWeakPtr(), state_manager_, command_manager_}); device_info_->Start(); dbus_adaptor_.RegisterWithDBusObject(&dbus_object_);
diff --git a/buffet/states/state_manager.h b/buffet/states/state_manager.h index cf2c60a..a34f7c1 100644 --- a/buffet/states/state_manager.h +++ b/buffet/states/state_manager.h
@@ -61,6 +61,7 @@ std::vector<StateChange> GetAndClearRecordedStateChanges(); private: + friend class BaseApiHandlerTest; friend class StateManagerTest; // Updates a single property value. |full_property_name| must be the full