Update API: initial support

Initial pieces of the Update API callback framework.

- move the status callback params to a new object, UpdateEngineStatus to
allow for the easier addition of new params in the future.
- switch the IUpdateEngineStatusCallback to provide a
ParcelableUpdateEngineStatus instead of a series of individual params
- move the various GetStatus() methods to use the UpdateEngineStatus
object instead of a series of params (which will need future expansion)
- Add current and new product/os versions to both the UpdateEngineStatus
and the ParcelableUpdateEngineStatus.

Bug: 64808702
Test: unit tests, and performing OTAs via a test app calling
  IUpdateEngine::AttemptUpdate() via UpdateManager::performUpdateNow()

Change-Id: I53f66f3511049f0809855814e1e758023cd8cc08
(cherry picked from commit 4f96ebf85022837603f2e10100a044d234b7d86f)
diff --git a/Android.mk b/Android.mk
index 37a754d..528aa76 100644
--- a/Android.mk
+++ b/Android.mk
@@ -955,6 +955,7 @@
     p2p_manager_unittest.cc \
     payload_consumer/download_action_unittest.cc \
     payload_state_unittest.cc \
+    parcelable_update_engine_status_unittest.cc \
     update_attempter_unittest.cc \
     update_manager/boxed_value_unittest.cc \
     update_manager/chromeos_policy_unittest.cc \
diff --git a/binder_bindings/android/brillo/IUpdateEngineStatusCallback.aidl b/binder_bindings/android/brillo/IUpdateEngineStatusCallback.aidl
index 42b6438..837d44d 100644
--- a/binder_bindings/android/brillo/IUpdateEngineStatusCallback.aidl
+++ b/binder_bindings/android/brillo/IUpdateEngineStatusCallback.aidl
@@ -16,8 +16,9 @@
 
 package android.brillo;
 
+import android.brillo.ParcelableUpdateEngineStatus;
+
 interface IUpdateEngineStatusCallback {
   oneway
-  void HandleStatusUpdate(in long last_checked_time, in double progress,
-      in String current_operation, in String new_version, in long new_size);
+  void HandleStatusUpdate(in ParcelableUpdateEngineStatus status);
 }
diff --git a/binder_service_android.cc b/binder_service_android.cc
index e179c62..0305727 100644
--- a/binder_service_android.cc
+++ b/binder_service_android.cc
@@ -24,6 +24,7 @@
 
 using android::binder::Status;
 using android::os::IUpdateEngineCallback;
+using update_engine::UpdateEngineStatus;
 
 namespace {
 Status ErrorPtrToStatus(const brillo::ErrorPtr& error) {
@@ -40,13 +41,9 @@
 }
 
 void BinderUpdateEngineAndroidService::SendStatusUpdate(
-    int64_t /* last_checked_time */,
-    double progress,
-    update_engine::UpdateStatus status,
-    const std::string& /* new_version  */,
-    int64_t /* new_size */) {
-  last_status_ = static_cast<int>(status);
-  last_progress_ = progress;
+    const UpdateEngineStatus& update_engine_status) {
+  last_status_ = static_cast<int>(update_engine_status.status);
+  last_progress_ = update_engine_status.progress;
   for (auto& callback : callbacks_) {
     callback->onStatusUpdate(last_status_, last_progress_);
   }
diff --git a/binder_service_android.h b/binder_service_android.h
index 7d66fcc..eb36e4c 100644
--- a/binder_service_android.h
+++ b/binder_service_android.h
@@ -45,11 +45,8 @@
   }
 
   // ServiceObserverInterface overrides.
-  void SendStatusUpdate(int64_t last_checked_time,
-                        double progress,
-                        update_engine::UpdateStatus status,
-                        const std::string& new_version,
-                        int64_t new_size) override;
+  void SendStatusUpdate(
+      const update_engine::UpdateEngineStatus& update_engine_status) override;
   void SendPayloadApplicationComplete(ErrorCode error_code) override;
 
   // android::os::BnUpdateEngine overrides.
diff --git a/binder_service_brillo.cc b/binder_service_brillo.cc
index 5e74159..74803c4 100644
--- a/binder_service_brillo.cc
+++ b/binder_service_brillo.cc
@@ -33,6 +33,7 @@
 using android::sp;
 using brillo::ErrorPtr;
 using std::string;
+using update_engine::UpdateEngineStatus;
 
 namespace chromeos_update_engine {
 
@@ -79,19 +80,12 @@
 
 Status BinderUpdateEngineBrilloService::GetStatus(
     ParcelableUpdateEngineStatus* status) {
-  string current_op;
-  string new_version;
-
-  auto ret = CallCommonHandler(&UpdateEngineService::GetStatus,
-                               &status->last_checked_time_,
-                               &status->progress_,
-                               &current_op,
-                               &new_version,
-                               &status->new_size_);
+  UpdateEngineStatus update_engine_status;
+  auto ret =
+      CallCommonHandler(&UpdateEngineService::GetStatus, &update_engine_status);
 
   if (ret.isOk()) {
-    status->current_operation_ = String16{current_op.c_str()};
-    status->new_version_ = String16{new_version.c_str()};
+    *status = ParcelableUpdateEngineStatus(update_engine_status);
   }
 
   return ret;
@@ -228,18 +222,10 @@
 }
 
 void BinderUpdateEngineBrilloService::SendStatusUpdate(
-    int64_t last_checked_time,
-    double progress,
-    update_engine::UpdateStatus status,
-    const string& new_version,
-    int64_t new_size) {
-  const string str_status = UpdateStatusToString(status);
+    const UpdateEngineStatus& update_engine_status) {
+  ParcelableUpdateEngineStatus parcelable_status(update_engine_status);
   for (auto& callback : callbacks_) {
-    callback->HandleStatusUpdate(last_checked_time,
-                                 progress,
-                                 String16{str_status.c_str()},
-                                 String16{new_version.c_str()},
-                                 new_size);
+    callback->HandleStatusUpdate(parcelable_status);
   }
 }
 
diff --git a/binder_service_brillo.h b/binder_service_brillo.h
index 982c7b1..51f0fab 100644
--- a/binder_service_brillo.h
+++ b/binder_service_brillo.h
@@ -46,11 +46,8 @@
   }
 
   // ServiceObserverInterface overrides.
-  void SendStatusUpdate(int64_t last_checked_time,
-                        double progress,
-                        update_engine::UpdateStatus status,
-                        const std::string& new_version,
-                        int64_t new_size) override;
+  void SendStatusUpdate(
+      const update_engine::UpdateEngineStatus& update_engine_status) override;
   void SendPayloadApplicationComplete(ErrorCode error_code) override {}
 
   // android::brillo::BnUpdateEngine overrides.
diff --git a/client_library/client_binder.cc b/client_library/client_binder.cc
index e98c225..fecd9a3 100644
--- a/client_library/client_binder.cc
+++ b/client_library/client_binder.cc
@@ -143,18 +143,18 @@
 }
 
 Status BinderUpdateEngineClient::StatusUpdateCallback::HandleStatusUpdate(
-    int64_t last_checked_time,
-    double progress,
-    const String16& current_operation,
-    const String16& new_version,
-    int64_t new_size) {
+    const ParcelableUpdateEngineStatus& status) {
   UpdateStatus update_status;
 
-  StringToUpdateStatus(String8{current_operation}.string(), &update_status);
+  StringToUpdateStatus(String8{status.current_operation_}.string(),
+                       &update_status);
 
   for (auto& handler : client_->handlers_) {
-    handler->HandleStatusUpdate(last_checked_time, progress, update_status,
-                                String8{new_version}.string(), new_size);
+    handler->HandleStatusUpdate(status.last_checked_time_,
+                                status.progress_,
+                                update_status,
+                                String8{status.new_version_}.string(),
+                                status.new_size_);
   }
 
   return Status::ok();
diff --git a/client_library/client_binder.h b/client_library/client_binder.h
index b1b34da..17f2beb 100644
--- a/client_library/client_binder.h
+++ b/client_library/client_binder.h
@@ -94,11 +94,7 @@
         : client_(client) {}
 
     android::binder::Status HandleStatusUpdate(
-        int64_t last_checked_time,
-        double progress,
-        const android::String16& current_operation,
-        const android::String16& new_version,
-        int64_t new_size) override;
+        const android::brillo::ParcelableUpdateEngineStatus& status) override;
 
    private:
     BinderUpdateEngineClient* client_;
diff --git a/client_library/include/update_engine/update_status.h b/client_library/include/update_engine/update_status.h
index 3e9af5b..76dd865 100644
--- a/client_library/include/update_engine/update_status.h
+++ b/client_library/include/update_engine/update_status.h
@@ -17,6 +17,8 @@
 #ifndef UPDATE_ENGINE_CLIENT_LIBRARY_INCLUDE_UPDATE_ENGINE_UPDATE_STATUS_H_
 #define UPDATE_ENGINE_CLIENT_LIBRARY_INCLUDE_UPDATE_ENGINE_UPDATE_STATUS_H_
 
+#include <string>
+
 namespace update_engine {
 
 enum class UpdateStatus {
@@ -32,6 +34,25 @@
   DISABLED,
 };
 
+struct UpdateEngineStatus {
+  // When the update_engine last checked for updates (ms since Epoch)
+  int64_t last_checked_time_ms;
+  // the current status/operation of the update_engine
+  UpdateStatus status;
+  // the current product version (oem bundle id)
+  std::string current_version;
+  // the current system version
+  std::string current_system_version;
+  // The current progress (0.0f-1.0f).
+  double progress;
+  // the size of the update (bytes)
+  uint64_t new_size_bytes;
+  // the new product version
+  std::string new_version;
+  // the new system version, if there is one (empty, otherwise)
+  std::string new_system_version;
+};
+
 }  // namespace update_engine
 
 #endif  // UPDATE_ENGINE_CLIENT_LIBRARY_INCLUDE_UPDATE_ENGINE_UPDATE_STATUS_H_
diff --git a/common_service.cc b/common_service.cc
index 1a41b63..15feca7 100644
--- a/common_service.cc
+++ b/common_service.cc
@@ -43,6 +43,7 @@
 using brillo::string_utils::ToString;
 using std::set;
 using std::string;
+using update_engine::UpdateEngineStatus;
 
 namespace chromeos_update_engine {
 
@@ -116,16 +117,8 @@
 }
 
 bool UpdateEngineService::GetStatus(ErrorPtr* error,
-                                    int64_t* out_last_checked_time,
-                                    double* out_progress,
-                                    string* out_current_operation,
-                                    string* out_new_version,
-                                    int64_t* out_new_size) {
-  if (!system_state_->update_attempter()->GetStatus(out_last_checked_time,
-                                                    out_progress,
-                                                    out_current_operation,
-                                                    out_new_version,
-                                                    out_new_size)) {
+                                    UpdateEngineStatus* out_status) {
+  if (!system_state_->update_attempter()->GetStatus(out_status)) {
     LogAndSetError(error, FROM_HERE, "GetStatus failed.");
     return false;
   }
diff --git a/common_service.h b/common_service.h
index 69368fb..7e7fea8 100644
--- a/common_service.h
+++ b/common_service.h
@@ -24,6 +24,7 @@
 #include <base/memory/ref_counted.h>
 #include <brillo/errors/error.h>
 
+#include "update_engine/client_library/include/update_engine/update_status.h"
 #include "update_engine/system_state.h"
 
 namespace chromeos_update_engine {
@@ -63,11 +64,7 @@
   // progress, the number of operations, size to download and overall progress
   // is reported.
   bool GetStatus(brillo::ErrorPtr* error,
-                 int64_t* out_last_checked_time,
-                 double* out_progress,
-                 std::string* out_current_operation,
-                 std::string* out_new_version,
-                 int64_t* out_new_size);
+                 update_engine::UpdateEngineStatus* out_status);
 
   // Reboots the device if an update is applied and a reboot is required.
   bool RebootIfNeeded(brillo::ErrorPtr* error);
diff --git a/dbus_service.cc b/dbus_service.cc
index 0a7ad5b..3a35c71 100644
--- a/dbus_service.cc
+++ b/dbus_service.cc
@@ -25,6 +25,7 @@
 using brillo::ErrorPtr;
 using chromeos_update_engine::UpdateEngineService;
 using std::string;
+using update_engine::UpdateEngineStatus;
 
 DBusUpdateEngineService::DBusUpdateEngineService(SystemState* system_state)
     : common_(new UpdateEngineService{system_state}) {
@@ -172,14 +173,13 @@
                                         dbus::Bus::REQUIRE_PRIMARY);
 }
 
-void UpdateEngineAdaptor::SendStatusUpdate(int64_t last_checked_time,
-                                           double progress,
-                                           update_engine::UpdateStatus status,
-                                           const string& new_version,
-                                           int64_t new_size) {
-  const string str_status = UpdateStatusToString(status);
-  SendStatusUpdateSignal(
-      last_checked_time, progress, str_status, new_version, new_size);
+void UpdateEngineAdaptor::SendStatusUpdate(
+    const UpdateEngineStatus& update_engine_status) {
+  SendStatusUpdateSignal(update_engine_status.last_checked_time,
+                         update_engine_status.progress,
+                         UpdateStatusToString(update_engine_status.status),
+                         update_engine_status.new_version,
+                         update_engine_status.new_size);
 }
 
 }  // namespace chromeos_update_engine
diff --git a/dbus_service.h b/dbus_service.h
index 2b36ae9..b754661 100644
--- a/dbus_service.h
+++ b/dbus_service.h
@@ -167,11 +167,8 @@
   bool RequestOwnership();
 
   // ServiceObserverInterface overrides.
-  void SendStatusUpdate(int64_t last_checked_time,
-                        double progress,
-                        update_engine::UpdateStatus status,
-                        const std::string& new_version,
-                        int64_t new_size) override;
+  void SendStatusUpdate(
+      const update_engine::UpdateEngineStatus& update_engine_status) override;
 
   void SendPayloadApplicationComplete(ErrorCode error_code) override {}
 
diff --git a/mock_service_observer.h b/mock_service_observer.h
index 032f55a..e434eab 100644
--- a/mock_service_observer.h
+++ b/mock_service_observer.h
@@ -24,12 +24,9 @@
 
 class MockServiceObserver : public ServiceObserverInterface {
  public:
-  MOCK_METHOD5(SendStatusUpdate,
-               void(int64_t last_checked_time,
-                    double progress,
-                    update_engine::UpdateStatus status,
-                    const std::string& new_version,
-                    int64_t new_size));
+  MOCK_METHOD1(
+      SendStatusUpdate,
+      void(const update_engine::UpdateEngineStatus& update_engine_status));
   MOCK_METHOD1(SendPayloadApplicationComplete, void(ErrorCode error_code));
 };
 
diff --git a/mock_update_attempter.h b/mock_update_attempter.h
index 89f163e..9634bab 100644
--- a/mock_update_attempter.h
+++ b/mock_update_attempter.h
@@ -36,11 +36,7 @@
                             bool obey_proxies,
                             bool interactive));
 
-  MOCK_METHOD5(GetStatus, bool(int64_t* last_checked_time,
-                               double* progress,
-                               std::string* current_operation,
-                               std::string* new_version,
-                               int64_t* new_size));
+  MOCK_METHOD1(GetStatus, bool(update_engine::UpdateEngineStatus* out_status));
 
   MOCK_METHOD1(GetBootTimeAtUpdate, bool(base::Time* out_boot_time));
 
diff --git a/omaha_response_handler_action.cc b/omaha_response_handler_action.cc
index 75050e7..d23c14e 100644
--- a/omaha_response_handler_action.cc
+++ b/omaha_response_handler_action.cc
@@ -69,6 +69,7 @@
     return;
   }
 
+  // This is the url to the first package, not all packages.
   install_plan_.download_url = current_url;
   install_plan_.version = response.version;
   install_plan_.system_version = response.system_version;
diff --git a/parcelable_update_engine_status.cc b/parcelable_update_engine_status.cc
index d8eb6db..d3e7eaa 100644
--- a/parcelable_update_engine_status.cc
+++ b/parcelable_update_engine_status.cc
@@ -15,12 +15,27 @@
 //
 
 #include "update_engine/parcelable_update_engine_status.h"
+#include "update_engine/update_status_utils.h"
 
 #include <binder/Parcel.h>
 
+using update_engine::UpdateEngineStatus;
+
 namespace android {
 namespace brillo {
 
+ParcelableUpdateEngineStatus::ParcelableUpdateEngineStatus(
+    const UpdateEngineStatus& status)
+    : last_checked_time_(status.last_checked_time_ms),
+      current_operation_(
+          chromeos_update_engine::UpdateStatusToString(status.status)),
+      progress_(status.progress),
+      current_version_(String16{status.current_version.c_str()}),
+      current_system_version_(String16{status.current_system_version.c_str()}),
+      new_size_(status.new_size_bytes),
+      new_version_(String16{status.new_version.c_str()}),
+      new_system_version_(String16{status.new_system_version.c_str()}) {}
+
 status_t ParcelableUpdateEngineStatus::writeToParcel(Parcel* parcel) const {
   status_t status;
 
@@ -29,12 +44,27 @@
     return status;
   }
 
+  status = parcel->writeString16(current_operation_);
+  if (status != OK) {
+    return status;
+  }
+
   status = parcel->writeDouble(progress_);
   if (status != OK) {
     return status;
   }
 
-  status = parcel->writeString16(current_operation_);
+  status = parcel->writeString16(current_version_);
+  if (status != OK) {
+    return status;
+  }
+
+  status = parcel->writeString16(current_system_version_);
+  if (status != OK) {
+    return status;
+  }
+
+  status = parcel->writeInt64(new_size_);
   if (status != OK) {
     return status;
   }
@@ -44,7 +74,7 @@
     return status;
   }
 
-  return parcel->writeInt64(new_size_);
+  return parcel->writeString16(new_system_version_);
 }
 
 status_t ParcelableUpdateEngineStatus::readFromParcel(const Parcel* parcel) {
@@ -55,12 +85,27 @@
     return status;
   }
 
+  status = parcel->readString16(&current_operation_);
+  if (status != OK) {
+    return status;
+  }
+
   status = parcel->readDouble(&progress_);
   if (status != OK) {
     return status;
   }
 
-  status = parcel->readString16(&current_operation_);
+  status = parcel->readString16(&current_version_);
+  if (status != OK) {
+    return status;
+  }
+
+  status = parcel->readString16(&current_system_version_);
+  if (status != OK) {
+    return status;
+  }
+
+  status = parcel->readInt64(&new_size_);
   if (status != OK) {
     return status;
   }
@@ -70,7 +115,7 @@
     return status;
   }
 
-  return parcel->readInt64(&new_size_);
+  return parcel->readString16(&new_system_version_);
 }
 
 }  // namespace brillo
diff --git a/parcelable_update_engine_status.h b/parcelable_update_engine_status.h
index 2cfedd9..2050622 100644
--- a/parcelable_update_engine_status.h
+++ b/parcelable_update_engine_status.h
@@ -20,6 +20,8 @@
 #include <binder/Parcelable.h>
 #include <utils/String16.h>
 
+#include "update_engine/client_library/include/update_engine/update_status.h"
+
 namespace android {
 namespace brillo {
 
@@ -28,16 +30,31 @@
 class ParcelableUpdateEngineStatus : public Parcelable {
  public:
   ParcelableUpdateEngineStatus() = default;
+  explicit ParcelableUpdateEngineStatus(
+      const update_engine::UpdateEngineStatus& status);
   virtual ~ParcelableUpdateEngineStatus() = default;
 
   status_t writeToParcel(Parcel* parcel) const override;
   status_t readFromParcel(const Parcel* parcel) override;
 
+  // This list is kept in the Parcelable serialization order.
+
+  // When the update_engine last checked for updates (ms since Epoch)
   int64_t last_checked_time_;
-  double progress_;
+  // The current status/operation of the update_engine.
   android::String16 current_operation_;
-  android::String16 new_version_;
+  // The current progress (0.0f-1.0f).
+  double progress_;
+  // The current product version.
+  android::String16 current_version_;
+  // The current system version.
+  android::String16 current_system_version_;
+  // The size of the update (bytes).  This is int64_t for java compatibility.
   int64_t new_size_;
+  // The new product version.
+  android::String16 new_version_;
+  // The new system version, if there is one (empty, otherwise).
+  android::String16 new_system_version_;
 };
 
 }  // namespace brillo
diff --git a/parcelable_update_engine_status_unittest.cc b/parcelable_update_engine_status_unittest.cc
new file mode 100644
index 0000000..3e6f7eb
--- /dev/null
+++ b/parcelable_update_engine_status_unittest.cc
@@ -0,0 +1,93 @@
+//
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "update_engine/parcelable_update_engine_status.h"
+#include "update_engine/update_status_utils.h"
+
+#include <binder/Parcel.h>
+#include <gtest/gtest.h>
+
+using android::Parcel;
+using android::String16;
+using android::brillo::ParcelableUpdateEngineStatus;
+using android::status_t;
+using update_engine::UpdateEngineStatus;
+using update_engine::UpdateStatus;
+
+TEST(ParcelableUpdateEngineStatusTest, TestCreationFromUpdateEngineStatus) {
+  // This test creates an object and verifies that all the UpdateEngineStatus
+  // values are properly reflected in the Parcelable version of the class.
+
+  UpdateEngineStatus ue_status = {123456789,
+                                  UpdateStatus::DOWNLOADING,
+                                  "0.1.2.3",
+                                  "1.2.3.4",
+                                  0.5f,
+                                  34567,
+                                  "2.3.4.5",
+                                  "3.4.5.6"};
+  ParcelableUpdateEngineStatus parcelable_status(ue_status);
+  EXPECT_EQ(ue_status.last_checked_time_ms,
+            parcelable_status.last_checked_time_);
+  EXPECT_EQ(
+      String16{chromeos_update_engine::UpdateStatusToString(ue_status.status)},
+      parcelable_status.current_operation_);
+  EXPECT_EQ(String16{ue_status.current_version.c_str()},
+            parcelable_status.current_version_);
+  EXPECT_EQ(String16{ue_status.current_system_version.c_str()},
+            parcelable_status.current_system_version_);
+  EXPECT_EQ(ue_status.progress, parcelable_status.progress_);
+  EXPECT_EQ(static_cast<int64_t>(ue_status.new_size_bytes),
+            parcelable_status.new_size_);
+  EXPECT_EQ(String16{ue_status.new_version.c_str()},
+            parcelable_status.new_version_);
+  EXPECT_EQ(String16{ue_status.new_system_version.c_str()},
+            parcelable_status.new_system_version_);
+}
+
+TEST(ParcelableUpdateEngineStatusTest, TestParceling) {
+  // This tests the writeToParcel and readFromParcel methods for being correctly
+  // matched.
+  UpdateEngineStatus ue_status = {123456789,
+                                  UpdateStatus::DOWNLOADING,
+                                  "0.1.2.3",
+                                  "1.2.3.4",
+                                  0.5f,
+                                  34567,
+                                  "2.3.4.5",
+                                  "3.4.5.6"};
+  ParcelableUpdateEngineStatus source_status(ue_status);
+  Parcel parcel_source, parcel_target;
+  status_t status = source_status.writeToParcel(&parcel_source);
+  EXPECT_EQ(::android::OK, status);
+  size_t parcel_len = parcel_source.dataSize();
+  status = parcel_target.setData(parcel_source.data(), parcel_len);
+  EXPECT_EQ(::android::OK, status);
+  ParcelableUpdateEngineStatus target_status;
+  status = target_status.readFromParcel(&parcel_target);
+  EXPECT_EQ(::android::OK, status);
+
+  EXPECT_EQ(source_status.last_checked_time_, target_status.last_checked_time_);
+  EXPECT_EQ(source_status.current_operation_, target_status.current_operation_);
+  EXPECT_EQ(source_status.current_version_, target_status.current_version_);
+  EXPECT_EQ(source_status.current_system_version_,
+            target_status.current_system_version_);
+  EXPECT_EQ(source_status.progress_, target_status.progress_);
+  EXPECT_EQ(source_status.new_size_, target_status.new_size_);
+  EXPECT_EQ(source_status.new_version_, target_status.new_version_);
+  EXPECT_EQ(source_status.new_system_version_,
+            target_status.new_system_version_);
+}
diff --git a/service_observer_interface.h b/service_observer_interface.h
index 893df04..4edb0ac 100644
--- a/service_observer_interface.h
+++ b/service_observer_interface.h
@@ -31,11 +31,8 @@
 
   // Called whenever the value of these parameters changes. For |progress|
   // value changes, this method will be called only if it changes significantly.
-  virtual void SendStatusUpdate(int64_t last_checked_time,
-                                double progress,
-                                update_engine::UpdateStatus status,
-                                const std::string& new_version,
-                                int64_t new_size) = 0;
+  virtual void SendStatusUpdate(
+      const update_engine::UpdateEngineStatus& update_engine_status) = 0;
 
   // Called whenever an update attempt is completed.
   virtual void SendPayloadApplicationComplete(ErrorCode error_code) = 0;
diff --git a/sideload_main.cc b/sideload_main.cc
index 574d062..52f045e 100644
--- a/sideload_main.cc
+++ b/sideload_main.cc
@@ -42,6 +42,7 @@
 using std::string;
 using std::vector;
 using update_engine::UpdateStatus;
+using update_engine::UpdateEngineStatus;
 
 namespace {
 // The root directory used for temporary files in update_engine_sideload.
@@ -81,11 +82,10 @@
   }
 
   // ServiceObserverInterface overrides.
-  void SendStatusUpdate(int64_t last_checked_time,
-                        double progress,
-                        UpdateStatus status,
-                        const string& new_version,
-                        int64_t new_size) override {
+  void SendStatusUpdate(
+      const UpdateEngineStatus& update_engine_status) override {
+    UpdateStatus status = update_engine_status.status;
+    double progress = update_engine_status.progress;
     if (status_ != status && (status == UpdateStatus::DOWNLOADING ||
                               status == UpdateStatus::FINALIZING)) {
       // Split the progress bar in two parts for the two stages DOWNLOADING and
diff --git a/update_attempter.cc b/update_attempter.cc
index 9cf9368..31ebb97 100644
--- a/update_attempter.cc
+++ b/update_attempter.cc
@@ -78,6 +78,7 @@
 using std::shared_ptr;
 using std::string;
 using std::vector;
+using update_engine::UpdateEngineStatus;
 
 namespace chromeos_update_engine {
 
@@ -1034,6 +1035,7 @@
     const InstallPlan& plan = response_handler_action_->install_plan();
     UpdateLastCheckedTime();
     new_version_ = plan.version;
+    new_system_version_ = plan.system_version;
     new_payload_size_ = 0;
     for (const auto& payload : plan.payloads)
       new_payload_size_ += payload.size;
@@ -1127,16 +1129,15 @@
   }
 }
 
-bool UpdateAttempter::GetStatus(int64_t* last_checked_time,
-                                double* progress,
-                                string* current_operation,
-                                string* new_version,
-                                int64_t* new_payload_size) {
-  *last_checked_time = last_checked_time_;
-  *progress = download_progress_;
-  *current_operation = UpdateStatusToString(status_);
-  *new_version = new_version_;
-  *new_payload_size = new_payload_size_;
+bool UpdateAttempter::GetStatus(UpdateEngineStatus* out_status) {
+  out_status->last_checked_time_ms = last_checked_time_;
+  out_status->status = status_;
+  out_status->current_version = omaha_request_params_->app_version();
+  out_status->current_system_version = omaha_request_params_->system_version();
+  out_status->progress = download_progress_;
+  out_status->new_size_bytes = new_payload_size_;
+  out_status->new_version = new_version_;
+  out_status->new_system_version = new_system_version_;
   return true;
 }
 
@@ -1173,12 +1174,12 @@
 }
 
 void UpdateAttempter::BroadcastStatus() {
+  UpdateEngineStatus broadcast_status;
+  // Use common method for generating the current status.
+  GetStatus(&broadcast_status);
+
   for (const auto& observer : service_observers_) {
-    observer->SendStatusUpdate(last_checked_time_,
-                               download_progress_,
-                               status_,
-                               new_version_,
-                               new_payload_size_);
+    observer->SendStatusUpdate(broadcast_status);
   }
   last_notify_time_ = TimeTicks::Now();
 }
diff --git a/update_attempter.h b/update_attempter.h
index 9dd844d..fb975f3 100644
--- a/update_attempter.h
+++ b/update_attempter.h
@@ -114,12 +114,8 @@
   // for testing purposes.
   virtual bool ResetStatus();
 
-  // Returns the current status in the out params. Returns true on success.
-  virtual bool GetStatus(int64_t* last_checked_time,
-                         double* progress,
-                         std::string* current_operation,
-                         std::string* new_version,
-                         int64_t* new_size);
+  // Returns the current status in the out param. Returns true on success.
+  virtual bool GetStatus(update_engine::UpdateEngineStatus* out_status);
 
   // Runs chromeos-setgoodkernel, whose responsibility it is to mark the
   // currently booted partition has high priority/permanent/etc. The execution
@@ -441,7 +437,8 @@
   int64_t last_checked_time_ = 0;
   std::string prev_version_;
   std::string new_version_ = "0.0.0.0";
-  int64_t new_payload_size_ = 0;
+  std::string new_system_version_;
+  uint64_t new_payload_size_ = 0;
 
   // Common parameters for all Omaha requests.
   OmahaRequestParams* omaha_request_params_ = nullptr;
diff --git a/update_attempter_android.cc b/update_attempter_android.cc
index 5765329..e9502fe 100644
--- a/update_attempter_android.cc
+++ b/update_attempter_android.cc
@@ -50,6 +50,7 @@
 using std::shared_ptr;
 using std::string;
 using std::vector;
+using update_engine::UpdateEngineStatus;
 
 namespace chromeos_update_engine {
 
@@ -432,9 +433,12 @@
   status_ = status;
   size_t payload_size =
       install_plan_.payloads.empty() ? 0 : install_plan_.payloads[0].size;
+  UpdateEngineStatus status_to_send = {.status = status_,
+                                       .progress = download_progress_,
+                                       .new_size_bytes = payload_size};
+
   for (auto observer : daemon_state_->service_observers()) {
-    observer->SendStatusUpdate(
-        0, download_progress_, status_, "", payload_size);
+    observer->SendStatusUpdate(status_to_send);
   }
   last_notify_time_ = TimeTicks::Now();
 }
diff --git a/update_attempter_unittest.cc b/update_attempter_unittest.cc
index 911f664..dfeebcf 100644
--- a/update_attempter_unittest.cc
+++ b/update_attempter_unittest.cc
@@ -67,6 +67,7 @@
 using std::string;
 using std::unique_ptr;
 using testing::DoAll;
+using testing::Field;
 using testing::InSequence;
 using testing::Ne;
 using testing::NiceMock;
@@ -76,6 +77,7 @@
 using testing::SaveArg;
 using testing::SetArgumentPointee;
 using testing::_;
+using update_engine::UpdateEngineStatus;
 using update_engine::UpdateStatus;
 
 namespace chromeos_update_engine {
@@ -137,7 +139,7 @@
     EXPECT_EQ(0.0, attempter_.download_progress_);
     EXPECT_EQ(0, attempter_.last_checked_time_);
     EXPECT_EQ("0.0.0.0", attempter_.new_version_);
-    EXPECT_EQ(0, attempter_.new_payload_size_);
+    EXPECT_EQ(0ULL, attempter_.new_payload_size_);
     processor_ = new NiceMock<MockActionProcessor>();
     attempter_.processor_.reset(processor_);  // Transfers ownership.
     prefs_ = fake_system_state_.mock_prefs();
@@ -253,11 +255,15 @@
   attempter_.new_payload_size_ = bytes_total;
   NiceMock<MockServiceObserver> observer;
   EXPECT_CALL(observer,
-              SendStatusUpdate(
-                  _, progress_1, UpdateStatus::DOWNLOADING, _, bytes_total));
+              SendStatusUpdate(AllOf(
+                  Field(&UpdateEngineStatus::progress, progress_1),
+                  Field(&UpdateEngineStatus::status, UpdateStatus::DOWNLOADING),
+                  Field(&UpdateEngineStatus::new_size_bytes, bytes_total))));
   EXPECT_CALL(observer,
-              SendStatusUpdate(
-                  _, progress_2, UpdateStatus::DOWNLOADING, _, bytes_total));
+              SendStatusUpdate(AllOf(
+                  Field(&UpdateEngineStatus::progress, progress_2),
+                  Field(&UpdateEngineStatus::status, UpdateStatus::DOWNLOADING),
+                  Field(&UpdateEngineStatus::new_size_bytes, bytes_total))));
   attempter_.AddObserver(&observer);
   attempter_.BytesReceived(bytes_progressed_1, bytes_received_1, bytes_total);
   EXPECT_EQ(progress_1, attempter_.download_progress_);
@@ -280,9 +286,10 @@
   attempter_.new_payload_size_ = bytes_total;
   EXPECT_EQ(0.0, attempter_.download_progress_);
   NiceMock<MockServiceObserver> observer;
-  EXPECT_CALL(
-      observer,
-      SendStatusUpdate(_, _, UpdateStatus::DOWNLOADING, _, bytes_total));
+  EXPECT_CALL(observer,
+              SendStatusUpdate(AllOf(
+                  Field(&UpdateEngineStatus::status, UpdateStatus::DOWNLOADING),
+                  Field(&UpdateEngineStatus::new_size_bytes, bytes_total))));
   attempter_.AddObserver(&observer);
   attempter_.BytesReceived(bytes_progressed, bytes_received, bytes_total);
   EXPECT_EQ(UpdateStatus::DOWNLOADING, attempter_.status_);
@@ -299,9 +306,11 @@
   attempter_.new_payload_size_ = bytes_total;
   EXPECT_EQ(0.0, attempter_.download_progress_);
   NiceMock<MockServiceObserver> observer;
-  EXPECT_CALL(
-      observer,
-      SendStatusUpdate(_, 1.0, UpdateStatus::DOWNLOADING, _, bytes_total));
+  EXPECT_CALL(observer,
+              SendStatusUpdate(AllOf(
+                  Field(&UpdateEngineStatus::progress, 1.0),
+                  Field(&UpdateEngineStatus::status, UpdateStatus::DOWNLOADING),
+                  Field(&UpdateEngineStatus::new_size_bytes, bytes_total))));
   attempter_.AddObserver(&observer);
   attempter_.BytesReceived(bytes_progressed, bytes_received, bytes_total);
   EXPECT_EQ(1.0, attempter_.download_progress_);
diff --git a/update_manager/fake_updater_provider.h b/update_manager/fake_updater_provider.h
index 44389f4..a7c15b5 100644
--- a/update_manager/fake_updater_provider.h
+++ b/update_manager/fake_updater_provider.h
@@ -53,7 +53,7 @@
     return &var_new_version_;
   }
 
-  FakeVariable<int64_t>* var_payload_size() override {
+  FakeVariable<uint64_t>* var_payload_size() override {
     return &var_payload_size_;
   }
 
@@ -100,7 +100,7 @@
     "stage", kVariableModePoll};
   FakeVariable<std::string> var_new_version_{  // NOLINT(whitespace/braces)
     "new_version", kVariableModePoll};
-  FakeVariable<int64_t> var_payload_size_{  // NOLINT(whitespace/braces)
+  FakeVariable<uint64_t> var_payload_size_{// NOLINT(whitespace/braces)
     "payload_size", kVariableModePoll};
   FakeVariable<std::string> var_curr_channel_{  // NOLINT(whitespace/braces)
     "curr_channel", kVariableModePoll};
diff --git a/update_manager/real_updater_provider.cc b/update_manager/real_updater_provider.cc
index 1a3e65a..a085f42 100644
--- a/update_manager/real_updater_provider.cc
+++ b/update_manager/real_updater_provider.cc
@@ -25,10 +25,12 @@
 #include <base/time/time.h>
 #include <update_engine/dbus-constants.h>
 
+#include "update_engine/client_library/include/update_engine/update_status.h"
 #include "update_engine/common/clock_interface.h"
 #include "update_engine/common/prefs.h"
 #include "update_engine/omaha_request_params.h"
 #include "update_engine/update_attempter.h"
+#include "update_engine/update_status_utils.h"
 
 using base::StringPrintf;
 using base::Time;
@@ -36,6 +38,7 @@
 using chromeos_update_engine::OmahaRequestParams;
 using chromeos_update_engine::SystemState;
 using std::string;
+using update_engine::UpdateEngineStatus;
 
 namespace chromeos_update_manager {
 
@@ -60,27 +63,32 @@
 class GetStatusHelper {
  public:
   GetStatusHelper(SystemState* system_state, string* errmsg) {
-    is_success_ = system_state->update_attempter()->GetStatus(
-        &last_checked_time_, &progress_, &update_status_, &new_version_,
-        &payload_size_);
-    if (!is_success_ && errmsg)
+    is_success_ =
+        system_state->update_attempter()->GetStatus(&update_engine_status_);
+    if (!is_success_ && errmsg) {
       *errmsg = "Failed to get a status update from the update engine";
+    }
   }
 
   inline bool is_success() { return is_success_; }
-  inline int64_t last_checked_time() { return last_checked_time_; }
-  inline double progress() { return progress_; }
-  inline const string& update_status() { return update_status_; }
-  inline const string& new_version() { return new_version_; }
-  inline int64_t payload_size() { return payload_size_; }
+  inline int64_t last_checked_time() {
+    return update_engine_status_.last_checked_time_ms;
+  }
+  inline double progress() { return update_engine_status_.progress; }
+  inline const string update_status() {
+    return chromeos_update_engine::UpdateStatusToString(
+        update_engine_status_.status);
+  }
+  inline const string& new_version() {
+    return update_engine_status_.new_version;
+  }
+  inline uint64_t payload_size() {
+    return update_engine_status_.new_size_bytes;
+  }
 
  private:
   bool is_success_;
-  int64_t last_checked_time_;
-  double progress_;
-  string update_status_;
-  string new_version_;
-  int64_t payload_size_;
+  UpdateEngineStatus update_engine_status_;
 };
 
 // A variable reporting the time when a last update check was issued.
@@ -196,24 +204,18 @@
 };
 
 // A variable reporting the size of the update being processed in bytes.
-class PayloadSizeVariable : public UpdaterVariableBase<int64_t> {
+class PayloadSizeVariable : public UpdaterVariableBase<uint64_t> {
  public:
   PayloadSizeVariable(const string& name, SystemState* system_state)
-      : UpdaterVariableBase<int64_t>(name, kVariableModePoll, system_state) {}
+      : UpdaterVariableBase<uint64_t>(name, kVariableModePoll, system_state) {}
 
  private:
-  const int64_t* GetValue(TimeDelta /* timeout */, string* errmsg) override {
+  const uint64_t* GetValue(TimeDelta /* timeout */, string* errmsg) override {
     GetStatusHelper raw(system_state(), errmsg);
     if (!raw.is_success())
       return nullptr;
 
-    if (raw.payload_size() < 0) {
-      if (errmsg)
-        *errmsg = string("Invalid payload size: %" PRId64, raw.payload_size());
-      return nullptr;
-    }
-
-    return new int64_t(raw.payload_size());
+    return new uint64_t(raw.payload_size());
   }
 
   DISALLOW_COPY_AND_ASSIGN(PayloadSizeVariable);
diff --git a/update_manager/real_updater_provider.h b/update_manager/real_updater_provider.h
index b99bcc5..eb8b8e6 100644
--- a/update_manager/real_updater_provider.h
+++ b/update_manager/real_updater_provider.h
@@ -64,7 +64,7 @@
     return var_new_version_.get();
   }
 
-  Variable<int64_t>* var_payload_size() override {
+  Variable<uint64_t>* var_payload_size() override {
     return var_payload_size_.get();
   }
 
@@ -107,7 +107,7 @@
   std::unique_ptr<Variable<double>> var_progress_;
   std::unique_ptr<Variable<Stage>> var_stage_;
   std::unique_ptr<Variable<std::string>> var_new_version_;
-  std::unique_ptr<Variable<int64_t>> var_payload_size_;
+  std::unique_ptr<Variable<uint64_t>> var_payload_size_;
   std::unique_ptr<Variable<std::string>> var_curr_channel_;
   std::unique_ptr<Variable<std::string>> var_new_channel_;
   std::unique_ptr<Variable<bool>> var_p2p_enabled_;
diff --git a/update_manager/real_updater_provider_unittest.cc b/update_manager/real_updater_provider_unittest.cc
index 14eb30b..f128c77 100644
--- a/update_manager/real_updater_provider_unittest.cc
+++ b/update_manager/real_updater_provider_unittest.cc
@@ -38,6 +38,7 @@
 using chromeos_update_engine::OmahaRequestParams;
 using std::string;
 using std::unique_ptr;
+using testing::DoAll;
 using testing::Return;
 using testing::SetArgPointee;
 using testing::_;
@@ -67,6 +68,26 @@
   return Time::FromLocalExploded(exp);
 }
 
+ACTION_P(ActionSetUpdateEngineStatusLastCheckedTime, time_ms) {
+  arg0->last_checked_time_ms = time_ms;
+};
+
+ACTION_P(ActionSetUpdateEngineStatusProgress, progress) {
+  arg0->progress = progress;
+};
+
+ACTION_P(ActionSetUpdateEngineStatusStatus, status) {
+  arg0->status = status;
+}
+
+ACTION_P(ActionSetUpdateEngineStatusNewVersion, new_version) {
+  arg0->new_version = new_version;
+}
+
+ACTION_P(ActionSetUpdateEngineStatusNewSizeBytes, new_size_bytes) {
+  arg0->new_size_bytes = new_size_bytes;
+}
+
 }  // namespace
 
 namespace chromeos_update_manager {
@@ -116,225 +137,189 @@
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetLastCheckedTimeOkay) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
-              GetStatus(_, _, _, _, _))
-      .WillOnce(DoAll(SetArgPointee<0>(FixedTime().ToTimeT()), Return(true)));
+  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+      .WillOnce(DoAll(
+          ActionSetUpdateEngineStatusLastCheckedTime(FixedTime().ToTimeT()),
+          Return(true)));
   UmTestUtils::ExpectVariableHasValue(RoundedToSecond(FixedTime()),
                                       provider_->var_last_checked_time());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetLastCheckedTimeFailNoValue) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
-              GetStatus(_, _, _, _, _))
+  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
       .WillOnce(Return(false));
   UmTestUtils::ExpectVariableNotSet(provider_->var_last_checked_time());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetProgressOkayMin) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
-              GetStatus(_, _, _, _, _))
-      .WillOnce(DoAll(SetArgPointee<1>(0.0), Return(true)));
+  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+      .WillOnce(DoAll(ActionSetUpdateEngineStatusProgress(0.0), Return(true)));
   UmTestUtils::ExpectVariableHasValue(0.0, provider_->var_progress());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetProgressOkayMid) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
-              GetStatus(_, _, _, _, _))
-      .WillOnce(DoAll(SetArgPointee<1>(0.3), Return(true)));
+  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+      .WillOnce(DoAll(ActionSetUpdateEngineStatusProgress(0.3), Return(true)));
   UmTestUtils::ExpectVariableHasValue(0.3, provider_->var_progress());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetProgressOkayMax) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
-              GetStatus(_, _, _, _, _))
-      .WillOnce(DoAll(SetArgPointee<1>(1.0), Return(true)));
+  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+      .WillOnce(DoAll(ActionSetUpdateEngineStatusProgress(1.0), Return(true)));
   UmTestUtils::ExpectVariableHasValue(1.0, provider_->var_progress());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetProgressFailNoValue) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
-              GetStatus(_, _, _, _, _))
+  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
       .WillOnce(Return(false));
   UmTestUtils::ExpectVariableNotSet(provider_->var_progress());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetProgressFailTooSmall) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
-              GetStatus(_, _, _, _, _))
-      .WillOnce(DoAll(SetArgPointee<1>(-2.0), Return(true)));
+  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+      .WillOnce(DoAll(ActionSetUpdateEngineStatusProgress(-2.0), Return(true)));
   UmTestUtils::ExpectVariableNotSet(provider_->var_progress());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetProgressFailTooBig) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
-              GetStatus(_, _, _, _, _))
-      .WillOnce(DoAll(SetArgPointee<1>(2.0), Return(true)));
+  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+      .WillOnce(DoAll(ActionSetUpdateEngineStatusProgress(2.0), Return(true)));
   UmTestUtils::ExpectVariableNotSet(provider_->var_progress());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetStageOkayIdle) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
-              GetStatus(_, _, _, _, _))
-      .WillOnce(DoAll(SetArgPointee<2>(update_engine::kUpdateStatusIdle),
-                      Return(true)));
+  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+      .WillOnce(DoAll(
+          ActionSetUpdateEngineStatusStatus(update_engine::UpdateStatus::IDLE),
+          Return(true)));
   UmTestUtils::ExpectVariableHasValue(Stage::kIdle, provider_->var_stage());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetStageOkayCheckingForUpdate) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
-              GetStatus(_, _, _, _, _))
-      .WillOnce(DoAll(
-              SetArgPointee<2>(update_engine::kUpdateStatusCheckingForUpdate),
-              Return(true)));
+  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+      .WillOnce(DoAll(ActionSetUpdateEngineStatusStatus(
+                          update_engine::UpdateStatus::CHECKING_FOR_UPDATE),
+                      Return(true)));
   UmTestUtils::ExpectVariableHasValue(Stage::kCheckingForUpdate,
                                       provider_->var_stage());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetStageOkayUpdateAvailable) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
-              GetStatus(_, _, _, _, _))
-      .WillOnce(DoAll(
-              SetArgPointee<2>(update_engine::kUpdateStatusUpdateAvailable),
-              Return(true)));
+  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+      .WillOnce(DoAll(ActionSetUpdateEngineStatusStatus(
+                          update_engine::UpdateStatus::UPDATE_AVAILABLE),
+                      Return(true)));
   UmTestUtils::ExpectVariableHasValue(Stage::kUpdateAvailable,
                                       provider_->var_stage());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetStageOkayDownloading) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
-              GetStatus(_, _, _, _, _))
-      .WillOnce(DoAll(SetArgPointee<2>(update_engine::kUpdateStatusDownloading),
+  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+      .WillOnce(DoAll(ActionSetUpdateEngineStatusStatus(
+                          update_engine::UpdateStatus::DOWNLOADING),
                       Return(true)));
   UmTestUtils::ExpectVariableHasValue(Stage::kDownloading,
                                       provider_->var_stage());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetStageOkayVerifying) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
-              GetStatus(_, _, _, _, _))
-      .WillOnce(DoAll(SetArgPointee<2>(update_engine::kUpdateStatusVerifying),
+  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+      .WillOnce(DoAll(ActionSetUpdateEngineStatusStatus(
+                          update_engine::UpdateStatus::VERIFYING),
                       Return(true)));
   UmTestUtils::ExpectVariableHasValue(Stage::kVerifying,
                                       provider_->var_stage());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetStageOkayFinalizing) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
-              GetStatus(_, _, _, _, _))
-      .WillOnce(DoAll(SetArgPointee<2>(update_engine::kUpdateStatusFinalizing),
+  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+      .WillOnce(DoAll(ActionSetUpdateEngineStatusStatus(
+                          update_engine::UpdateStatus::FINALIZING),
                       Return(true)));
   UmTestUtils::ExpectVariableHasValue(Stage::kFinalizing,
                                       provider_->var_stage());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetStageOkayUpdatedNeedReboot) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
-              GetStatus(_, _, _, _, _))
-      .WillOnce(DoAll(
-              SetArgPointee<2>(update_engine::kUpdateStatusUpdatedNeedReboot),
-              Return(true)));
+  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+      .WillOnce(DoAll(ActionSetUpdateEngineStatusStatus(
+                          update_engine::UpdateStatus::UPDATED_NEED_REBOOT),
+                      Return(true)));
   UmTestUtils::ExpectVariableHasValue(Stage::kUpdatedNeedReboot,
                                       provider_->var_stage());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetStageOkayReportingErrorEvent) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
-              GetStatus(_, _, _, _, _))
-      .WillOnce(DoAll(
-              SetArgPointee<2>(update_engine::kUpdateStatusReportingErrorEvent),
-              Return(true)));
+  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+      .WillOnce(DoAll(ActionSetUpdateEngineStatusStatus(
+                          update_engine::UpdateStatus::REPORTING_ERROR_EVENT),
+                      Return(true)));
   UmTestUtils::ExpectVariableHasValue(Stage::kReportingErrorEvent,
                                       provider_->var_stage());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetStageOkayAttemptingRollback) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
-              GetStatus(_, _, _, _, _))
-      .WillOnce(DoAll(
-              SetArgPointee<2>(update_engine::kUpdateStatusAttemptingRollback),
-              Return(true)));
+  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+      .WillOnce(DoAll(ActionSetUpdateEngineStatusStatus(
+                          update_engine::UpdateStatus::ATTEMPTING_ROLLBACK),
+                      Return(true)));
   UmTestUtils::ExpectVariableHasValue(Stage::kAttemptingRollback,
                                       provider_->var_stage());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetStageFailNoValue) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
-              GetStatus(_, _, _, _, _))
+  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
       .WillOnce(Return(false));
   UmTestUtils::ExpectVariableNotSet(provider_->var_stage());
 }
 
-TEST_F(UmRealUpdaterProviderTest, GetStageFailUnknown) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
-              GetStatus(_, _, _, _, _))
-      .WillOnce(DoAll(SetArgPointee<2>("FooUpdateEngineState"),
-                      Return(true)));
-  UmTestUtils::ExpectVariableNotSet(provider_->var_stage());
-}
-
-TEST_F(UmRealUpdaterProviderTest, GetStageFailEmpty) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
-              GetStatus(_, _, _, _, _))
-      .WillOnce(DoAll(SetArgPointee<2>(""), Return(true)));
-  UmTestUtils::ExpectVariableNotSet(provider_->var_stage());
-}
-
 TEST_F(UmRealUpdaterProviderTest, GetNewVersionOkay) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
-              GetStatus(_, _, _, _, _))
-      .WillOnce(DoAll(SetArgPointee<3>("1.2.0"), Return(true)));
+  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+      .WillOnce(
+          DoAll(ActionSetUpdateEngineStatusNewVersion("1.2.0"), Return(true)));
   UmTestUtils::ExpectVariableHasValue(string("1.2.0"),
                                       provider_->var_new_version());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetNewVersionFailNoValue) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
-              GetStatus(_, _, _, _, _))
+  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
       .WillOnce(Return(false));
   UmTestUtils::ExpectVariableNotSet(provider_->var_new_version());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetPayloadSizeOkayZero) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
-              GetStatus(_, _, _, _, _))
-      .WillOnce(DoAll(SetArgPointee<4>(static_cast<int64_t>(0)), Return(true)));
-  UmTestUtils::ExpectVariableHasValue(static_cast<int64_t>(0),
+  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+      .WillOnce(DoAll(
+          ActionSetUpdateEngineStatusNewSizeBytes(static_cast<uint64_t>(0)),
+          Return(true)));
+  UmTestUtils::ExpectVariableHasValue(static_cast<uint64_t>(0),
                                       provider_->var_payload_size());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetPayloadSizeOkayArbitrary) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
-              GetStatus(_, _, _, _, _))
-      .WillOnce(DoAll(SetArgPointee<4>(static_cast<int64_t>(567890)),
+  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+      .WillOnce(DoAll(ActionSetUpdateEngineStatusNewSizeBytes(
+                          static_cast<uint64_t>(567890)),
                       Return(true)));
-  UmTestUtils::ExpectVariableHasValue(static_cast<int64_t>(567890),
+  UmTestUtils::ExpectVariableHasValue(static_cast<uint64_t>(567890),
                                       provider_->var_payload_size());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetPayloadSizeOkayTwoGigabytes) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
-              GetStatus(_, _, _, _, _))
-      .WillOnce(DoAll(SetArgPointee<4>(static_cast<int64_t>(1) << 31),
+  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+      .WillOnce(DoAll(ActionSetUpdateEngineStatusNewSizeBytes(
+                          static_cast<uint64_t>(1) << 31),
                       Return(true)));
-  UmTestUtils::ExpectVariableHasValue(static_cast<int64_t>(1) << 31,
+  UmTestUtils::ExpectVariableHasValue(static_cast<uint64_t>(1) << 31,
                                       provider_->var_payload_size());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetPayloadSizeFailNoValue) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
-              GetStatus(_, _, _, _, _))
+  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
       .WillOnce(Return(false));
   UmTestUtils::ExpectVariableNotSet(provider_->var_payload_size());
 }
 
-TEST_F(UmRealUpdaterProviderTest, GetPayloadSizeFailNegative) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
-              GetStatus(_, _, _, _, _))
-      .WillOnce(DoAll(SetArgPointee<4>(static_cast<int64_t>(-1024)),
-                      Return(true)));
-  UmTestUtils::ExpectVariableNotSet(provider_->var_payload_size());
-}
-
 TEST_F(UmRealUpdaterProviderTest, GetCurrChannelOkay) {
   const string kChannelName("foo-channel");
   OmahaRequestParams request_params(&fake_sys_state_);
diff --git a/update_manager/updater_provider.h b/update_manager/updater_provider.h
index 8048d38..549aea9 100644
--- a/update_manager/updater_provider.h
+++ b/update_manager/updater_provider.h
@@ -79,7 +79,7 @@
 
   // A variable returning the update payload size. The payload size is
   // guaranteed to be non-negative.
-  virtual Variable<int64_t>* var_payload_size() = 0;
+  virtual Variable<uint64_t>* var_payload_size() = 0;
 
   // A variable returning the current channel.
   virtual Variable<std::string>* var_curr_channel() = 0;