Change weave::Device::Register API to async version
Implementation of this function is the only place using
HttpClient::SendRequestAndBlock.
BUG:24267885
Change-Id: I8ebd34537ce42214ce262795b940923f3b11da79
Reviewed-on: https://weave-review.googlesource.com/1279
Reviewed-by: Alex Vakulenko <avakulenko@google.com>
diff --git a/libweave/examples/ubuntu/main.cc b/libweave/examples/ubuntu/main.cc
index b9f0806..5a7c2fa 100644
--- a/libweave/examples/ubuntu/main.cc
+++ b/libweave/examples/ubuntu/main.cc
@@ -219,6 +219,14 @@
base::WeakPtrFactory<CommandHandler> weak_ptr_factory_{this};
};
+void RegisterDeviceSuccess(weave::Device* device) {
+ LOG(INFO) << "Device registered: " << device->GetSettings().cloud_id;
+}
+
+void RegisterDeviceError(const weave::Error* error) {
+ LOG(ERROR) << "Fail to register device: " << error->GetMessage();
+}
+
} // namespace
int main(int argc, char** argv) {
@@ -262,13 +270,9 @@
&bluetooth);
if (!registration_ticket.empty()) {
- weave::ErrorPtr error;
- auto device_id = device->Register(registration_ticket, &error);
- if (error != nullptr) {
- LOG(ERROR) << "Fail to register device: " << error->GetMessage();
- } else {
- LOG(INFO) << "Device registered: " << device_id;
- }
+ device->Register(registration_ticket,
+ base::Bind(&RegisterDeviceSuccess, device.get()),
+ base::Bind(&RegisterDeviceError));
}
CommandHandler handler(device.get(), &task_runner);
diff --git a/libweave/include/weave/device.h b/libweave/include/weave/device.h
index 7e49202..7fbe248 100644
--- a/libweave/include/weave/device.h
+++ b/libweave/include/weave/device.h
@@ -118,10 +118,11 @@
virtual void AddGcdStateChangedCallback(
const GcdStateChangedCallback& callback) = 0;
- // Registers the device. Returns a device ID on success.
+ // Registers the device.
// This is testing method and should not be used by applications.
- virtual std::string Register(const std::string& ticket_id,
- ErrorPtr* error) = 0;
+ virtual void Register(const std::string& ticket_id,
+ const SuccessCallback& success_callback,
+ const ErrorCallback& error_callback) = 0;
// Handler should display pin code to the user.
using PairingBeginCallback =
diff --git a/libweave/include/weave/test/mock_device.h b/libweave/include/weave/test/mock_device.h
index 310d5b4..0d8a6da 100644
--- a/libweave/include/weave/test/mock_device.h
+++ b/libweave/include/weave/test/mock_device.h
@@ -44,8 +44,10 @@
MOCK_CONST_METHOD0(GetGcdState, GcdState());
MOCK_METHOD1(AddGcdStateChangedCallback,
void(const GcdStateChangedCallback& callback));
- MOCK_METHOD2(Register,
- std::string(const std::string& ticket_id, ErrorPtr* error));
+ MOCK_METHOD3(Register,
+ void(const std::string& ticket_id,
+ const SuccessCallback& success_callback,
+ const ErrorCallback& error_callback));
MOCK_METHOD2(AddPairingChangedCallbacks,
void(const PairingBeginCallback& begin_callback,
const PairingEndCallback& end_callback));
diff --git a/libweave/src/device_manager.cc b/libweave/src/device_manager.cc
index 86c9150..9105352 100644
--- a/libweave/src/device_manager.cc
+++ b/libweave/src/device_manager.cc
@@ -151,9 +151,10 @@
return state_manager_->GetState();
}
-std::string DeviceManager::Register(const std::string& ticket_id,
- ErrorPtr* error) {
- return device_info_->RegisterDevice(ticket_id, error);
+void DeviceManager::Register(const std::string& ticket_id,
+ const SuccessCallback& success_callback,
+ const ErrorCallback& error_callback) {
+ device_info_->RegisterDevice(ticket_id, success_callback, error_callback);
}
void DeviceManager::AddPairingChangedCallbacks(
diff --git a/libweave/src/device_manager.h b/libweave/src/device_manager.h
index 8c85a1b..16e0601 100644
--- a/libweave/src/device_manager.h
+++ b/libweave/src/device_manager.h
@@ -58,7 +58,9 @@
const base::Value& value,
ErrorPtr* error) override;
std::unique_ptr<base::DictionaryValue> GetState() const override;
- std::string Register(const std::string& ticket_id, ErrorPtr* error) override;
+ void Register(const std::string& ticket_id,
+ const SuccessCallback& success_callback,
+ const ErrorCallback& error_callback) override;
GcdState GetGcdState() const override;
void AddGcdStateChangedCallback(
const GcdStateChangedCallback& callback) override;
diff --git a/libweave/src/device_registration_info.cc b/libweave/src/device_registration_info.cc
index e712130..adb1994 100644
--- a/libweave/src/device_registration_info.cc
+++ b/libweave/src/device_registration_info.cc
@@ -525,12 +525,22 @@
error_callback);
}
-std::string DeviceRegistrationInfo::RegisterDevice(const std::string& ticket_id,
- ErrorPtr* error) {
+void DeviceRegistrationInfo::RegisterDevice(
+ const std::string& ticket_id,
+ const SuccessCallback& success_callback,
+ const ErrorCallback& error_callback) {
+ ErrorPtr error;
+
+ auto on_error = [this, &error_callback](ErrorPtr error) {
+ task_runner_->PostDelayedTask(
+ FROM_HERE, base::Bind(error_callback, base::Owned(error.release())),
+ {});
+ };
+
std::unique_ptr<base::DictionaryValue> device_draft =
- BuildDeviceResource(error);
+ BuildDeviceResource(&error);
if (!device_draft)
- return std::string();
+ return on_error(std::move(error));
base::DictionaryValue req_json;
req_json.SetString("id", ticket_id);
@@ -542,29 +552,29 @@
RequestSender sender{http::kPatch, url, http_client_};
sender.SetJsonData(req_json);
- auto response = sender.SendAndBlock(error);
+ auto response = sender.SendAndBlock(&error);
if (!response)
- return std::string();
- auto json_resp = ParseJsonResponse(*response, error);
+ return on_error(std::move(error));
+ auto json_resp = ParseJsonResponse(*response, &error);
if (!json_resp)
- return std::string();
+ return on_error(std::move(error));
if (!IsSuccessful(*response)) {
- ParseGCDError(json_resp.get(), error);
- return std::string();
+ ParseGCDError(json_resp.get(), &error);
+ return on_error(std::move(error));
}
url = GetServiceURL("registrationTickets/" + ticket_id + "/finalize",
{{"key", GetSettings().api_key}});
- response = RequestSender{http::kPost, url, http_client_}.SendAndBlock(error);
+ response = RequestSender{http::kPost, url, http_client_}.SendAndBlock(&error);
if (!response)
- return std::string();
- json_resp = ParseJsonResponse(*response, error);
+ return on_error(std::move(error));
+ json_resp = ParseJsonResponse(*response, &error);
if (!json_resp)
- return std::string();
+ return on_error(std::move(error));
if (!IsSuccessful(*response)) {
- ParseGCDError(json_resp.get(), error);
- return std::string();
+ ParseGCDError(json_resp.get(), &error);
+ return on_error(std::move(error));
}
std::string auth_code;
@@ -575,9 +585,9 @@
!json_resp->GetString("robotAccountAuthorizationCode", &auth_code) ||
!json_resp->GetDictionary("deviceDraft", &device_draft_response) ||
!device_draft_response->GetString("id", &cloud_id)) {
- Error::AddTo(error, FROM_HERE, kErrorDomainGCD, "unexpected_response",
+ Error::AddTo(&error, FROM_HERE, kErrorDomainGCD, "unexpected_response",
"Device account missing in response");
- return std::string();
+ return on_error(std::move(error));
}
UpdateDeviceInfoTimestamp(*device_draft_response);
@@ -591,21 +601,21 @@
{"redirect_uri", "oob"},
{"scope", "https://www.googleapis.com/auth/clouddevices"},
{"grant_type", "authorization_code"}});
- response = sender2.SendAndBlock(error);
+ response = sender2.SendAndBlock(&error);
if (!response)
- return std::string();
+ return on_error(std::move(error));
- json_resp = ParseOAuthResponse(*response, error);
+ json_resp = ParseOAuthResponse(*response, &error);
int expires_in = 0;
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) {
- Error::AddTo(error, FROM_HERE, kErrorDomainGCD, "unexpected_response",
+ Error::AddTo(&error, FROM_HERE, kErrorDomainGCD, "unexpected_response",
"Device access_token missing in response");
- return std::string();
+ return on_error(std::move(error));
}
access_token_expiration_ =
@@ -617,12 +627,13 @@
change.set_refresh_token(refresh_token);
change.Commit();
+ task_runner_->PostDelayedTask(FROM_HERE, success_callback, {});
+
StartNotificationChannel();
// We're going to respond with our success immediately and we'll connect to
// cloud shortly after.
- ScheduleCloudConnection(base::TimeDelta::FromSeconds(0));
- return cloud_id;
+ ScheduleCloudConnection({});
}
void DeviceRegistrationInfo::DoCloudRequest(
diff --git a/libweave/src/device_registration_info.h b/libweave/src/device_registration_info.h
index c797102..3a57982 100644
--- a/libweave/src/device_registration_info.h
+++ b/libweave/src/device_registration_info.h
@@ -64,7 +64,9 @@
void AddGcdStateChangedCallback(
const Device::GcdStateChangedCallback& callback);
- std::string RegisterDevice(const std::string& ticket_id, ErrorPtr* error);
+ void RegisterDevice(const std::string& ticket_id,
+ const SuccessCallback& success_callback,
+ const ErrorCallback& error_callback);
void UpdateDeviceInfo(const std::string& name,
const std::string& description,
diff --git a/libweave/src/device_registration_info_unittest.cc b/libweave/src/device_registration_info_unittest.cc
index cfd5b86..5245458 100644
--- a/libweave/src/device_registration_info_unittest.cc
+++ b/libweave/src/device_registration_info_unittest.cc
@@ -482,17 +482,23 @@
return ReplyWithJson(200, json);
})));
- std::string cloud_id =
- dev_reg_->RegisterDevice(test_data::kClaimTicketId, nullptr);
+ bool done = false;
+ dev_reg_->RegisterDevice(
+ test_data::kClaimTicketId, base::Bind([this, &done]() {
+ done = true;
+ task_runner_.Break();
+ EXPECT_EQ(GcdState::kConnecting, GetGcdState());
- EXPECT_EQ(test_data::kDeviceId, cloud_id);
- EXPECT_EQ(GcdState::kConnecting, GetGcdState());
-
- // Validate the device info saved to storage...
- EXPECT_EQ(test_data::kDeviceId, dev_reg_->GetSettings().cloud_id);
- EXPECT_EQ(test_data::kRefreshToken, dev_reg_->GetSettings().refresh_token);
- EXPECT_EQ(test_data::kRobotAccountEmail,
- dev_reg_->GetSettings().robot_account);
+ // Validate the device info saved to storage...
+ EXPECT_EQ(test_data::kDeviceId, dev_reg_->GetSettings().cloud_id);
+ EXPECT_EQ(test_data::kRefreshToken,
+ dev_reg_->GetSettings().refresh_token);
+ EXPECT_EQ(test_data::kRobotAccountEmail,
+ dev_reg_->GetSettings().robot_account);
+ }),
+ base::Bind([](const Error* error) { ADD_FAILURE(); }));
+ task_runner_.Run();
+ EXPECT_TRUE(done);
}
TEST_F(DeviceRegistrationInfoTest, OOBRegistrationStatus) {
diff --git a/libweave/src/privet/cloud_delegate.cc b/libweave/src/privet/cloud_delegate.cc
index 045a235..83cb6fb 100644
--- a/libweave/src/privet/cloud_delegate.cc
+++ b/libweave/src/privet/cloud_delegate.cc
@@ -284,12 +284,21 @@
return;
}
- if (!device_->RegisterDevice(ticket_id, &error).empty()) {
- backoff_entry_.InformOfRequest(true);
- setup_state_ = SetupState(SetupState::kSuccess);
- return;
- }
+ device_->RegisterDevice(
+ ticket_id, base::Bind(&CloudDelegateImpl::RegisterDeviceSuccess,
+ setup_weak_factory_.GetWeakPtr()),
+ base::Bind(&CloudDelegateImpl::RegisterDeviceError,
+ setup_weak_factory_.GetWeakPtr(), ticket_id, deadline));
+ }
+ void RegisterDeviceSuccess() {
+ backoff_entry_.InformOfRequest(true);
+ setup_state_ = SetupState(SetupState::kSuccess);
+ }
+
+ void RegisterDeviceError(const std::string& ticket_id,
+ const base::Time& deadline,
+ const Error* error) {
// Registration failed. Retry with backoff.
backoff_entry_.InformOfRequest(false);
task_runner_->PostDelayedTask(
diff --git a/libweave/src/weave_unittest.cc b/libweave/src/weave_unittest.cc
index 3b68e3e..69250fd 100644
--- a/libweave/src/weave_unittest.cc
+++ b/libweave/src/weave_unittest.cc
@@ -329,7 +329,15 @@
InitDnsSdPublishing(true, "DB");
- EXPECT_EQ("CLOUD_ID", device_->Register("TICKET_ID", nullptr));
+ bool done = false;
+ device_->Register("TICKET_ID", base::Bind([this, &done]() {
+ done = true;
+ task_runner_.Break();
+ EXPECT_EQ("CLOUD_ID", device_->GetSettings().cloud_id);
+ }),
+ base::Bind([](const Error* error) { ADD_FAILURE(); }));
+ task_runner_.Run();
+ EXPECT_TRUE(done);
}
class WeaveWiFiSetupTest : public WeaveTest {