buffet: Move config and buffet state logic into BuffetConfig
Load/Save logic isolated in buffet/buffet_config.* files.
Added BuffetConfig::Change helper to make sure callbacks were called
and changes were saved.
BUG=brillo:1058
TEST='FEATURES=test emerge-gizmo buffet'
Change-Id: Id8f171c2109fe834daef43658abf6881b50b5c7d
Reviewed-on: https://chromium-review.googlesource.com/271343
Tested-by: Vitaly Buka <vitalybuka@chromium.org>
Reviewed-by: Alex Vakulenko <avakulenko@chromium.org>
Commit-Queue: Vitaly Buka <vitalybuka@chromium.org>
diff --git a/buffet/device_registration_info.cc b/buffet/device_registration_info.cc
index e9f806b..3b176c3 100644
--- a/buffet/device_registration_info.cc
+++ b/buffet/device_registration_info.cc
@@ -28,7 +28,6 @@
#include "buffet/commands/schema_constants.h"
#include "buffet/device_registration_storage_keys.h"
#include "buffet/notification/xmpp_channel.h"
-#include "buffet/org.chromium.Buffet.Manager.h"
#include "buffet/states/state_manager.h"
#include "buffet/utils.h"
@@ -133,17 +132,12 @@
const std::shared_ptr<StateManager>& state_manager,
std::unique_ptr<BuffetConfig> config,
const std::shared_ptr<chromeos::http::Transport>& transport,
- const std::shared_ptr<StorageInterface>& state_store,
- bool notifications_enabled,
- org::chromium::Buffet::ManagerAdaptor* manager)
+ bool notifications_enabled)
: transport_{transport},
- storage_{state_store},
command_manager_{command_manager},
state_manager_{state_manager},
config_{std::move(config)},
- notifications_enabled_{notifications_enabled},
- manager_{manager} {
- OnConfigChanged();
+ notifications_enabled_{notifications_enabled} {
command_manager_->AddOnCommandDefChanged(
base::Bind(&DeviceRegistrationInfo::OnCommandDefsChanged,
weak_factory_.GetWeakPtr()));
@@ -165,9 +159,9 @@
std::string DeviceRegistrationInfo::GetDeviceURL(
const std::string& subpath,
const chromeos::data_encoding::WebParamList& params) const {
- CHECK(!device_id_.empty()) << "Must have a valid device ID";
+ CHECK(!config_->device_id().empty()) << "Must have a valid device ID";
return BuildURL(config_->service_url(),
- {"devices", device_id_, subpath}, params);
+ {"devices", config_->device_id(), subpath}, params);
}
std::string DeviceRegistrationInfo::GetOAuthURL(
@@ -176,56 +170,7 @@
return BuildURL(config_->oauth_url(), {subpath}, params);
}
-const std::string& DeviceRegistrationInfo::GetDeviceId() const {
- return device_id_;
-}
-
-bool DeviceRegistrationInfo::Load() {
- // Set kInvalidCredentials to trigger on_status_changed_ callback.
- registration_status_ = RegistrationStatus::kInvalidCredentials;
- SetRegistrationStatus(RegistrationStatus::kUnconfigured);
-
- auto value = storage_->Load();
- const base::DictionaryValue* dict = nullptr;
- if (!value || !value->GetAsDictionary(&dict))
- return false;
-
- // Read all available data before failing.
- std::string name;
- if (dict->GetString(storage_keys::kName, &name))
- config_->set_name(name);
-
- std::string description;
- if (dict->GetString(storage_keys::kDescription, &description))
- config_->set_description(description);
-
- std::string location;
- if (dict->GetString(storage_keys::kLocation, &location))
- config_->set_location(location);
-
- std::string access_role;
- if (dict->GetString(storage_keys::kLocalAnonymousAccessRole, &access_role))
- config_->set_local_anonymous_access_role(access_role);
-
- bool local_discovery_enabled{false};
- if (dict->GetBoolean(storage_keys::kLocalDiscoveryEnabled,
- &local_discovery_enabled))
- config_->set_local_discovery_enabled(local_discovery_enabled);
-
- bool local_pairing_enabled{false};
- if (dict->GetBoolean(storage_keys::kLocalPairingEnabled,
- &local_pairing_enabled))
- config_->set_local_pairing_enabled(local_pairing_enabled);
-
- dict->GetString(storage_keys::kRefreshToken, &refresh_token_);
- dict->GetString(storage_keys::kRobotAccount, &device_robot_account_);
-
- std::string device_id;
- if (dict->GetString(storage_keys::kDeviceId, &device_id))
- SetDeviceId(device_id);
-
- OnConfigChanged();
-
+void DeviceRegistrationInfo::Start() {
if (HaveRegistrationCredentials(nullptr)) {
// Wait a significant amount of time for local daemons to publish their
// state to Buffet before publishing it to the cloud.
@@ -235,25 +180,6 @@
// we need not wait for them.
ScheduleStartDevice(base::TimeDelta::FromSeconds(5));
}
- return true;
-}
-
-bool DeviceRegistrationInfo::Save() const {
- base::DictionaryValue dict;
- dict.SetString(storage_keys::kRefreshToken, refresh_token_);
- dict.SetString(storage_keys::kDeviceId, device_id_);
- dict.SetString(storage_keys::kRobotAccount, device_robot_account_);
- dict.SetString(storage_keys::kName, config_->name());
- dict.SetString(storage_keys::kDescription, config_->description());
- dict.SetString(storage_keys::kLocation, config_->location());
- dict.SetString(storage_keys::kLocalAnonymousAccessRole,
- config_->local_anonymous_access_role());
- dict.SetBoolean(storage_keys::kLocalDiscoveryEnabled,
- config_->local_discovery_enabled());
- dict.SetBoolean(storage_keys::kLocalPairingEnabled,
- config_->local_pairing_enabled());
-
- return storage_->Save(dict);
}
void DeviceRegistrationInfo::ScheduleStartDevice(const base::TimeDelta& later) {
@@ -283,9 +209,9 @@
bool DeviceRegistrationInfo::HaveRegistrationCredentials(
chromeos::ErrorPtr* error) {
- const bool have_credentials = !refresh_token_.empty() &&
- !device_id_.empty() &&
- !device_robot_account_.empty();
+ const bool have_credentials = !config_->refresh_token().empty() &&
+ !config_->device_id().empty() &&
+ !config_->robot_account().empty();
VLOG(1) << "Device registration record "
<< ((have_credentials) ? "found" : "not found.");
@@ -336,12 +262,15 @@
bool DeviceRegistrationInfo::RefreshAccessToken(
chromeos::ErrorPtr* error) {
LOG(INFO) << "Refreshing access token.";
- auto response = chromeos::http::PostFormDataAndBlock(GetOAuthURL("token"), {
- {"refresh_token", refresh_token_},
- {"client_id", config_->client_id()},
- {"client_secret", config_->client_secret()},
- {"grant_type", "refresh_token"},
- }, {}, transport_, error);
+ auto response = chromeos::http::PostFormDataAndBlock(
+ GetOAuthURL("token"),
+ {
+ {"refresh_token", config_->refresh_token()},
+ {"client_id", config_->client_id()},
+ {"client_secret", config_->client_secret()},
+ {"grant_type", "refresh_token"},
+ },
+ {}, transport_, error);
if (!response)
return false;
@@ -385,11 +314,18 @@
// this class completely. Also to be added the secondary (poll) notification
// channel.
primary_notification_channel_.reset(
- new XmppChannel{device_robot_account_, access_token_,
+ new XmppChannel{config_->robot_account(),
+ access_token_,
base::MessageLoop::current()->task_runner()});
primary_notification_channel_->Start(this);
}
+void DeviceRegistrationInfo::AddOnRegistrationChangedCallback(
+ const OnRegistrationChangedCallback& callback) {
+ on_registration_changed_.push_back(callback);
+ callback.Run(registration_status_);
+}
+
std::unique_ptr<base::DictionaryValue>
DeviceRegistrationInfo::BuildDeviceResource(chromeos::ErrorPtr* error) {
// Limit only to commands that are visible to the cloud.
@@ -405,8 +341,8 @@
return nullptr;
std::unique_ptr<base::DictionaryValue> resource{new base::DictionaryValue};
- if (!device_id_.empty())
- resource->SetString("id", device_id_);
+ if (!config_->device_id().empty())
+ resource->SetString("id", config_->device_id());
resource->SetString("name", config_->name());
if (!config_->description().empty())
resource->SetString("description", config_->description());
@@ -534,7 +470,8 @@
std::string auth_code;
std::string device_id;
- if (!json_resp->GetString("robotAccountEmail", &device_robot_account_) ||
+ std::string robot_account;
+ if (!json_resp->GetString("robotAccountEmail", &robot_account) ||
!json_resp->GetString("robotAccountAuthorizationCode", &auth_code) ||
!json_resp->GetString("deviceDraft.id", &device_id)) {
chromeos::Error::AddTo(error, FROM_HERE, kErrorDomainGCD,
@@ -542,7 +479,6 @@
"Device account missing in response");
return std::string();
}
- SetDeviceId(device_id);
// Now get access_token and refresh_token
response = chromeos::http::PostFormDataAndBlock(GetOAuthURL("token"), {
@@ -558,13 +494,11 @@
json_resp = ParseOAuthResponse(response.get(), error);
int expires_in = 0;
- if (!json_resp ||
- !json_resp->GetString("access_token", &access_token_) ||
- !json_resp->GetString("refresh_token", &refresh_token_) ||
+ std::string refresh_token;
+ if (!json_resp || !json_resp->GetString("access_token", &access_token_) ||
+ !json_resp->GetString("refresh_token", &refresh_token) ||
!json_resp->GetInteger("expires_in", &expires_in) ||
- access_token_.empty() ||
- refresh_token_.empty() ||
- expires_in <= 0) {
+ access_token_.empty() || refresh_token.empty() || expires_in <= 0) {
chromeos::Error::AddTo(error, FROM_HERE,
kErrorDomainGCD, "unexpected_response",
"Device access_token missing in response");
@@ -574,13 +508,18 @@
access_token_expiration_ = base::Time::Now() +
base::TimeDelta::FromSeconds(expires_in);
- Save();
+ BuffetConfig::Transaction change{config_.get()};
+ change.set_device_id(device_id);
+ change.set_robot_account(robot_account);
+ change.set_refresh_token(refresh_token);
+ change.Commit();
+
StartNotificationChannel();
// We're going to respond with our success immediately and we'll StartDevice
// shortly after.
ScheduleStartDevice(base::TimeDelta::FromSeconds(0));
- return device_id_;
+ return device_id;
}
namespace {
@@ -769,17 +708,14 @@
const std::string& description,
const std::string& location,
chromeos::ErrorPtr* error) {
- if (!config_->set_name(name)) {
- chromeos::Error::AddToPrintf(error, FROM_HERE, kErrorDomainBuffet,
- "invalid_parameter", "Invalid name: %s",
- name.c_str());
+ BuffetConfig::Transaction change{config_.get()};
+ if (!change.set_name(name)) {
+ chromeos::Error::AddTo(error, FROM_HERE, kErrorDomainBuffet,
+ "invalid_parameter", "Empty device name");
return false;
}
- config_->set_description(description);
- config_->set_location(location);
-
- Save();
- OnConfigChanged();
+ change.set_description(description);
+ change.set_location(location);
if (HaveRegistrationCredentials(nullptr)) {
UpdateDeviceResource(base::Bind(&base::DoNothing),
@@ -878,10 +814,8 @@
const CloudRequestErrorCallback& on_failure) {
DoCloudRequest(
chromeos::http::request_type::kGet,
- GetServiceURL("commands/queue", {{"deviceId", device_id_}}),
- nullptr,
- base::Bind(&HandleFetchCommandsResult, on_success),
- on_failure);
+ GetServiceURL("commands/queue", {{"deviceId", config_->device_id()}}),
+ nullptr, base::Bind(&HandleFetchCommandsResult, on_success), on_failure);
}
void DeviceRegistrationInfo::AbortLimboCommands(
@@ -1021,29 +955,11 @@
void DeviceRegistrationInfo::SetRegistrationStatus(
RegistrationStatus new_status) {
- registration_status_ = new_status;
- if (manager_)
- manager_->SetStatus(StatusToString(registration_status_));
VLOG_IF(1, new_status != registration_status_)
<< "Changing registration status to " << StatusToString(new_status);
-}
-
-void DeviceRegistrationInfo::SetDeviceId(const std::string& device_id) {
- device_id_ = device_id;
- if (manager_)
- manager_->SetDeviceId(device_id_);
-}
-
-void DeviceRegistrationInfo::OnConfigChanged() {
- if (!manager_)
- return;
- manager_->SetOemName(config_->oem_name());
- manager_->SetModelName(config_->model_name());
- manager_->SetModelId(config_->model_id());
- manager_->SetName(config_->name());
- manager_->SetDescription(config_->description());
- manager_->SetLocation(config_->location());
- manager_->SetAnonymousAccessRole(config_->local_anonymous_access_role());
+ registration_status_ = new_status;
+ for (const auto& cb : on_registration_changed_)
+ cb.Run(registration_status_);
}
void DeviceRegistrationInfo::OnCommandDefsChanged() {