Build update_engine_sideload.

Add a new "sideload" executable target that applies an update payload
directly using the UpdateAttempterAndroid.

This initial CL buils a dynamically linked program that's targeted to
run in the system image for now, but will later be transformed into a
static binary to run from the recovery environment.

Bug: 27178350
TEST=Applied a payload directly on a device using:
`update_engine_sideload --payload=file://foo/bar ...`

Change-Id: I289a724d013abdc390187d669dccd3edf2fd3434
diff --git a/Android.mk b/Android.mk
index e7847d8..bf84547 100644
--- a/Android.mk
+++ b/Android.mk
@@ -472,6 +472,53 @@
 LOCAL_INIT_RC := update_engine.rc
 include $(BUILD_EXECUTABLE)
 
+# update_engine_sideload (type: executable)
+# ========================================================
+# A static binary equivalent to update_engine daemon that installs an update
+# from a local file directly instead of running in the background.
+include $(CLEAR_VARS)
+LOCAL_MODULE := update_engine_sideload
+# TODO(deymo): Make this binary a static binary and move it to recovery.
+# LOCAL_FORCE_STATIC_EXECUTABLE := true
+# LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
+LOCAL_MODULE_CLASS := EXECUTABLES
+LOCAL_REQUIRED_MODULES := \
+    bspatch
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_CLANG := true
+LOCAL_CFLAGS := $(ue_common_cflags)
+LOCAL_CPPFLAGS := $(ue_common_cppflags)
+LOCAL_LDFLAGS := $(ue_common_ldflags)
+LOCAL_C_INCLUDES := \
+    $(ue_common_c_includes) \
+    bootable/recovery
+#TODO(deymo): Remove external/cros/system_api/dbus once the strings are moved
+# out of the DBus interface.
+LOCAL_C_INCLUDES += \
+    external/cros/system_api/dbus
+LOCAL_SRC_FILES := \
+    boot_control_android.cc \
+    hardware_android.cc \
+    network_selector_stub.cc \
+    proxy_resolver.cc \
+    sideload_main.cc \
+    update_attempter_android.cc \
+    update_status_utils.cc \
+    utils_android.cc
+LOCAL_STATIC_LIBRARIES := \
+    libfs_mgr \
+    libpayload_consumer \
+    update_metadata-protos \
+    $(ue_libpayload_consumer_exported_static_libraries:-host=) \
+    $(ue_update_metadata_protos_exported_static_libraries)
+LOCAL_SHARED_LIBRARIES := \
+    $(ue_common_shared_libraries) \
+    libhardware \
+    libcutils \
+    $(ue_libpayload_consumer_exported_shared_libraries:-host=) \
+    $(ue_update_metadata_protos_exported_shared_libraries)
+include $(BUILD_EXECUTABLE)
+
 # libupdate_engine_client (type: shared_library)
 # ========================================================
 include $(CLEAR_VARS)
diff --git a/daemon_state_android.h b/daemon_state_android.h
index 69180bc..fc8be19 100644
--- a/daemon_state_android.h
+++ b/daemon_state_android.h
@@ -43,7 +43,7 @@
   void AddObserver(ServiceObserverInterface* observer) override;
   void RemoveObserver(ServiceObserverInterface* observer) override;
 
-  const std::set<ServiceObserverInterface*>& service_observers() {
+  const std::set<ServiceObserverInterface*>& service_observers() override {
     return service_observers_;
   }
 
diff --git a/daemon_state_interface.h b/daemon_state_interface.h
index a0944aa..2356816 100644
--- a/daemon_state_interface.h
+++ b/daemon_state_interface.h
@@ -20,6 +20,7 @@
 #include "update_engine/service_observer_interface.h"
 
 #include <memory>
+#include <set>
 
 namespace chromeos_update_engine {
 
@@ -36,6 +37,9 @@
   virtual void AddObserver(ServiceObserverInterface* observer) = 0;
   virtual void RemoveObserver(ServiceObserverInterface* observer) = 0;
 
+  // Return the set of current observers.
+  virtual const std::set<ServiceObserverInterface*>& service_observers() = 0;
+
  protected:
   DaemonStateInterface() = default;
 };
diff --git a/real_system_state.h b/real_system_state.h
index d6a9a95..ec17117 100644
--- a/real_system_state.h
+++ b/real_system_state.h
@@ -20,6 +20,7 @@
 #include "update_engine/system_state.h"
 
 #include <memory>
+#include <set>
 
 #include <metrics/metrics_library.h>
 #include <policy/device_policy.h>
@@ -60,6 +61,10 @@
 
   void AddObserver(ServiceObserverInterface* observer) override;
   void RemoveObserver(ServiceObserverInterface* observer) override;
+  const std::set<ServiceObserverInterface*>& service_observers() override {
+    CHECK(update_attempter_.get());
+    return update_attempter_->service_observers();
+  }
 
   // SystemState overrides.
   inline void set_device_policy(
diff --git a/sideload_main.cc b/sideload_main.cc
new file mode 100644
index 0000000..eae9539
--- /dev/null
+++ b/sideload_main.cc
@@ -0,0 +1,170 @@
+//
+// Copyright (C) 2016 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 <xz.h>
+
+#include <string>
+#include <vector>
+
+#include <base/command_line.h>
+#include <base/logging.h>
+#include <base/strings/string_split.h>
+#include <brillo/flag_helper.h>
+#include <brillo/message_loops/base_message_loop.h>
+
+#include "update_engine/common/boot_control.h"
+#include "update_engine/common/hardware.h"
+#include "update_engine/common/prefs.h"
+#include "update_engine/common/terminator.h"
+#include "update_engine/common/utils.h"
+#include "update_engine/update_attempter_android.h"
+
+using std::string;
+using std::vector;
+
+namespace chromeos_update_engine {
+namespace {
+
+void SetupLogging() {
+  string log_file;
+  logging::LoggingSettings log_settings;
+  log_settings.lock_log = logging::DONT_LOCK_LOG_FILE;
+  log_settings.delete_old = logging::APPEND_TO_OLD_LOG_FILE;
+  log_settings.log_file = nullptr;
+  log_settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
+
+  logging::InitLogging(log_settings);
+}
+
+class SideloadDaemonState : public DaemonStateInterface,
+                            public ServiceObserverInterface {
+ public:
+  SideloadDaemonState() {
+    // Add this class as the only observer.
+    observers_.insert(this);
+  }
+  ~SideloadDaemonState() override = default;
+
+  // DaemonStateInterface overrides.
+  bool StartUpdater() override { return true; }
+  void AddObserver(ServiceObserverInterface* observer) override {}
+  void RemoveObserver(ServiceObserverInterface* observer) override {}
+  const std::set<ServiceObserverInterface*>& service_observers() override {
+    return observers_;
+  }
+
+  // ServiceObserverInterface overrides.
+  void SendStatusUpdate(int64_t last_checked_time,
+                        double progress,
+                        update_engine::UpdateStatus status,
+                        const string& new_version,
+                        int64_t new_size) override {
+    status_ = status;
+  }
+
+  void SendPayloadApplicationComplete(ErrorCode error_code) override {
+    error_code_ = error_code;
+    brillo::MessageLoop::current()->BreakLoop();
+  }
+
+  void SendChannelChangeUpdate(const string& tracking_channel) override {}
+
+  // Getters.
+  update_engine::UpdateStatus status() { return status_; }
+  ErrorCode error_code() { return error_code_; }
+
+ private:
+  std::set<ServiceObserverInterface*> observers_;
+
+  // The last status and error code reported.
+  update_engine::UpdateStatus status_{update_engine::UpdateStatus::IDLE};
+  ErrorCode error_code_{ErrorCode::kSuccess};
+};
+
+// Apply an update payload directly from the given payload URI.
+bool ApplyUpdatePayload(const string& payload,
+                        int64_t payload_offset,
+                        int64_t payload_size,
+                        const vector<string>& headers) {
+  brillo::BaseMessageLoop loop;
+  loop.SetAsCurrent();
+
+  SideloadDaemonState sideload_daemon_state;
+
+  // During the sideload we don't access the prefs persisted on disk but instead
+  // use a temporary memory storage.
+  MemoryPrefs prefs;
+
+  std::unique_ptr<BootControlInterface> boot_control =
+      boot_control::CreateBootControl();
+  if (!boot_control) {
+    LOG(ERROR) << "Error initializing the BootControlInterface.";
+    return false;
+  }
+
+  std::unique_ptr<HardwareInterface> hardware = hardware::CreateHardware();
+  if (!hardware) {
+    LOG(ERROR) << "Error initializing the HardwareInterface.";
+    return false;
+  }
+
+  UpdateAttempterAndroid update_attempter(
+      &sideload_daemon_state, &prefs, boot_control.get(), hardware.get());
+  update_attempter.Init();
+
+  TEST_AND_RETURN_FALSE(update_attempter.ApplyPayload(
+      payload, payload_offset, payload_size, headers, nullptr));
+
+  loop.Run();
+  return sideload_daemon_state.status() ==
+         update_engine::UpdateStatus::UPDATED_NEED_REBOOT;
+}
+
+}  // namespace
+}  // namespace chromeos_update_engine
+
+int main(int argc, char** argv) {
+  DEFINE_string(payload,
+                "file:///data/payload.bin",
+                "The URI to the update payload to use.");
+  DEFINE_int64(
+      offset, 0, "The offset in the payload where the CrAU update starts. ");
+  DEFINE_int64(size,
+               0,
+               "The size of the CrAU part of the payload. If 0 is passed, it "
+               "will be autodetected.");
+  DEFINE_string(headers,
+                "",
+                "A list of key-value pairs, one element of the list per line.");
+
+  chromeos_update_engine::Terminator::Init();
+  chromeos_update_engine::SetupLogging();
+  brillo::FlagHelper::Init(argc, argv, "Update Engine Sideload");
+
+  LOG(INFO) << "Update Engine Sideloading starting";
+
+  // xz-embedded requires to initialize its CRC-32 table once on startup.
+  xz_crc32_init();
+
+  vector<string> headers = base::SplitString(
+      FLAGS_headers, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+
+  if (!chromeos_update_engine::ApplyUpdatePayload(
+          FLAGS_payload, FLAGS_offset, FLAGS_size, headers))
+    return 1;
+
+  return 0;
+}
diff --git a/update_attempter.h b/update_attempter.h
index 0b83d5b..af56f55 100644
--- a/update_attempter.h
+++ b/update_attempter.h
@@ -244,6 +244,10 @@
     service_observers_.erase(observer);
   }
 
+  const std::set<ServiceObserverInterface*>& service_observers() {
+    return service_observers_;
+  }
+
   // Remove all the observers.
   void ClearObservers() { service_observers_.clear(); }
 
diff --git a/update_attempter_android.cc b/update_attempter_android.cc
index c823e34..61d2828 100644
--- a/update_attempter_android.cc
+++ b/update_attempter_android.cc
@@ -32,7 +32,7 @@
 #include "update_engine/common/libcurl_http_fetcher.h"
 #include "update_engine/common/multi_range_http_fetcher.h"
 #include "update_engine/common/utils.h"
-#include "update_engine/daemon_state_android.h"
+#include "update_engine/daemon_state_interface.h"
 #include "update_engine/network_selector.h"
 #include "update_engine/payload_consumer/download_action.h"
 #include "update_engine/payload_consumer/filesystem_verifier_action.h"
@@ -72,7 +72,7 @@
 }  // namespace
 
 UpdateAttempterAndroid::UpdateAttempterAndroid(
-    DaemonStateAndroid* daemon_state,
+    DaemonStateInterface* daemon_state,
     PrefsInterface* prefs,
     BootControlInterface* boot_control,
     HardwareInterface* hardware)
@@ -300,7 +300,7 @@
     default:
       // Ignore all other error codes.
       break;
- }
+  }
 
   TerminateUpdateAndNotify(code);
 }
diff --git a/update_attempter_android.h b/update_attempter_android.h
index 9e91dca..2617318 100644
--- a/update_attempter_android.h
+++ b/update_attempter_android.h
@@ -31,6 +31,7 @@
 #include "update_engine/common/cpu_limiter.h"
 #include "update_engine/common/hardware_interface.h"
 #include "update_engine/common/prefs_interface.h"
+#include "update_engine/daemon_state_interface.h"
 #include "update_engine/network_selector_interface.h"
 #include "update_engine/payload_consumer/download_action.h"
 #include "update_engine/payload_consumer/postinstall_runner_action.h"
@@ -39,8 +40,6 @@
 
 namespace chromeos_update_engine {
 
-class DaemonStateAndroid;
-
 class UpdateAttempterAndroid
     : public ServiceDelegateAndroidInterface,
       public ActionProcessorDelegate,
@@ -49,7 +48,7 @@
  public:
   using UpdateStatus = update_engine::UpdateStatus;
 
-  UpdateAttempterAndroid(DaemonStateAndroid* daemon_state,
+  UpdateAttempterAndroid(DaemonStateInterface* daemon_state,
                          PrefsInterface* prefs,
                          BootControlInterface* boot_control_,
                          HardwareInterface* hardware_);
@@ -123,7 +122,7 @@
   // Returns whether an update was completed in the current boot.
   bool UpdateCompletedOnThisBoot();
 
-  DaemonStateAndroid* daemon_state_;
+  DaemonStateInterface* daemon_state_;
 
   // DaemonStateAndroid pointers.
   PrefsInterface* prefs_;