buffet: Add DeviceId DBus property

Privetd needs to be notified when GCD ID is changed.

CQ-DEPEND=CL:260681
BUG=brillo:572
TEST=manual, register device using privetd, edit id in buffet.state, restart
             buffet, check if privetd has new id

Change-Id: I590ee22f134261711f78da75a4766043e0867bf5
Reviewed-on: https://chromium-review.googlesource.com/260303
Reviewed-by: Vitaly Buka <vitalybuka@chromium.org>
Tested-by: Vitaly Buka <vitalybuka@chromium.org>
Commit-Queue: Vitaly Buka <vitalybuka@chromium.org>
diff --git a/buffet/dbus_bindings/org.chromium.Buffet.Manager.xml b/buffet/dbus_bindings/org.chromium.Buffet.Manager.xml
index 2e23802..7ec49a7 100644
--- a/buffet/dbus_bindings/org.chromium.Buffet.Manager.xml
+++ b/buffet/dbus_bindings/org.chromium.Buffet.Manager.xml
@@ -56,5 +56,10 @@
                                  valid.
       </tp:docstring>
     </property>
+    <property name="DeviceId" type="s" access="read">
+      <tp:docstring>
+        GCD ID if the device is registered or empty otherwise.
+      </tp:docstring>
+    </property>
   </interface>
 </node>
diff --git a/buffet/device_registration_info.cc b/buffet/device_registration_info.cc
index 3b9fdc9..f14ca21 100644
--- a/buffet/device_registration_info.cc
+++ b/buffet/device_registration_info.cc
@@ -171,8 +171,8 @@
   return BuildURL(oauth_url_, {subpath}, params);
 }
 
-std::string DeviceRegistrationInfo::GetDeviceId(chromeos::ErrorPtr* error) {
-  return CheckRegistration(error) ? device_id_ : std::string();
+const std::string& DeviceRegistrationInfo::GetDeviceId() const {
+  return device_id_;
 }
 
 bool DeviceRegistrationInfo::Load() {
@@ -233,7 +233,6 @@
   client_secret_        = client_secret;
   api_key_              = api_key;
   refresh_token_        = refresh_token;
-  device_id_            = device_id;
   oauth_url_            = oauth_url;
   service_url_          = service_url;
   device_robot_account_ = device_robot_account;
@@ -243,6 +242,8 @@
   description_          = description;
   location_             = location;
 
+  SetDeviceId(device_id);
+
   if (HaveRegistrationCredentials(nullptr)) {
     // Wait a significant amount of time for local daemons to publish their
     // state to Buffet before publishing it to the cloud.
@@ -544,14 +545,16 @@
   }
 
   std::string auth_code;
+  std::string device_id;
   if (!json_resp->GetString("robotAccountEmail", &device_robot_account_) ||
       !json_resp->GetString("robotAccountAuthorizationCode", &auth_code) ||
-      !json_resp->GetString("deviceDraft.id", &device_id_)) {
+      !json_resp->GetString("deviceDraft.id", &device_id)) {
     chromeos::Error::AddTo(error, FROM_HERE, kErrorDomainGCD,
                            "unexpected_response",
                            "Device account missing in response");
     return std::string();
   }
+  SetDeviceId(device_id);
 
   // Now get access_token and refresh_token
   response = chromeos::http::PostFormDataAndBlock(GetOAuthURL("token"), {
@@ -994,7 +997,15 @@
   VLOG(1) << "Changing registration status to " << StatusToString(new_status);
   registration_status_ = new_status;
   if (!registration_status_handler_.is_null())
-    registration_status_handler_.Run(registration_status_);
+    registration_status_handler_.Run();
+}
+
+void DeviceRegistrationInfo::SetDeviceId(const std::string& device_id) {
+  if (device_id == device_id_)
+    return;
+  device_id_ = device_id;
+  if (!registration_status_handler_.is_null())
+    registration_status_handler_.Run();
 }
 
 }  // namespace buffet
diff --git a/buffet/device_registration_info.h b/buffet/device_registration_info.h
index 648bcd6..c519048 100644
--- a/buffet/device_registration_info.h
+++ b/buffet/device_registration_info.h
@@ -45,7 +45,7 @@
  public:
   // This is a helper class for unit testing.
   class TestHelper;
-  using StatusHandler = base::Callback<void(RegistrationStatus)>;
+  using StatusHandler = base::Closure;
 
   DeviceRegistrationInfo(
       const std::shared_ptr<CommandManager>& command_manager,
@@ -100,8 +100,8 @@
     const std::string& subpath = {},
     const chromeos::data_encoding::WebParamList& params = {}) const;
 
-  // Returns the registered device ID (GUID) or empty string if failed
-  std::string GetDeviceId(chromeos::ErrorPtr* error);
+  // Returns the registered device ID (GUID) or empty string.
+  const std::string& GetDeviceId() const;
 
   // Loads the device registration information from cache.
   bool Load();
@@ -218,6 +218,7 @@
       chromeos::ErrorPtr* error);
 
   void SetRegistrationStatus(RegistrationStatus new_status);
+  void SetDeviceId(const std::string& device_id);
 
   std::unique_ptr<XmppClient> xmpp_client_;
   base::MessageLoopForIO::FileDescriptorWatcher fd_watcher_;
diff --git a/buffet/device_registration_info_unittest.cc b/buffet/device_registration_info_unittest.cc
index 7909713..0823e77 100644
--- a/buffet/device_registration_info_unittest.cc
+++ b/buffet/device_registration_info_unittest.cc
@@ -221,7 +221,7 @@
                                    mock_callback));
   }
 
-  MOCK_METHOD1(OnRegistrationStatusChange, void(RegistrationStatus));
+  MOCK_METHOD0(OnRegistrationStatusChange, void());
 
   base::DictionaryValue data_;
   std::shared_ptr<MemStorage> storage_;
@@ -385,8 +385,7 @@
   transport_->AddHandler(dev_reg_->GetDeviceURL(),
                          chromeos::http::request_type::kGet,
                          base::Bind(DeviceInfoHandler));
-  std::string id = dev_reg_->GetDeviceId(nullptr);
-  EXPECT_EQ(test_data::kDeviceId, id);
+  EXPECT_EQ(test_data::kDeviceId, dev_reg_->GetDeviceId());
 }
 
 TEST_F(DeviceRegistrationInfoTest, RegisterDevice) {
diff --git a/buffet/manager.cc b/buffet/manager.cc
index 7a4a9ca..53ec9c9 100644
--- a/buffet/manager.cc
+++ b/buffet/manager.cc
@@ -72,7 +72,7 @@
           base::Bind(&Manager::OnRegistrationStatusChange,
                      base::Unretained(this))));
   // Reset D-Bus properties.
-  OnRegistrationStatusChange(device_info_->GetRegistrationStatus());
+  OnRegistrationStatusChange();
   device_info_->Load();
   dbus_adaptor_.RegisterWithDBusObject(&dbus_object_);
   dbus_object_.RegisterAsync(cb);
@@ -90,17 +90,7 @@
     return;
   }
 
-  std::string device_id;
-  if (registered) {
-    error.reset();
-    device_id = device_info_->GetDeviceId(&error);
-    if (error) {
-      response->ReplyWithError(error.get());
-      return;
-    }
-  }
-
-  response->Return(device_id);
+  response->Return(registered ? device_info_->GetDeviceId() : std::string());
 }
 
 void Manager::GetDeviceInfo(DBusMethodResponse<std::string> response) {
@@ -205,8 +195,10 @@
   return message;
 }
 
-void Manager::OnRegistrationStatusChange(RegistrationStatus status) {
-  dbus_adaptor_.SetStatus(StatusToString(status));
+void Manager::OnRegistrationStatusChange() {
+  dbus_adaptor_.SetStatus(
+      StatusToString(device_info_->GetRegistrationStatus()));
+  dbus_adaptor_.SetDeviceId(device_info_->GetDeviceId());
 }
 
 }  // namespace buffet
diff --git a/buffet/manager.h b/buffet/manager.h
index 03bd68a..da3c044 100644
--- a/buffet/manager.h
+++ b/buffet/manager.h
@@ -73,7 +73,7 @@
   // Handles calls to org.chromium.Buffet.Manager.Test()
   std::string TestMethod(const std::string& message) override;
 
-  void OnRegistrationStatusChange(RegistrationStatus status);
+  void OnRegistrationStatusChange();
 
   org::chromium::Buffet::ManagerAdaptor dbus_adaptor_{this};
   chromeos::dbus_utils::DBusObject dbus_object_;