103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo//
203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// Copyright (C) 2016 The Android Open Source Project
303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo//
403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// Licensed under the Apache License, Version 2.0 (the "License");
503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// you may not use this file except in compliance with the License.
603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// You may obtain a copy of the License at
703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo//
803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo//      http://www.apache.org/licenses/LICENSE-2.0
903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo//
1003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// Unless required by applicable law or agreed to in writing, software
1103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// distributed under the License is distributed on an "AS IS" BASIS,
1203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// See the License for the specific language governing permissions and
1403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// limitations under the License.
1503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo//
1603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo
1703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include <xz.h>
1803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo
1903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include <string>
2003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include <vector>
2103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo
2203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include <base/command_line.h>
2303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include <base/logging.h>
2403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include <base/strings/string_split.h>
2540a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo#include <base/strings/stringprintf.h>
2640a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo#include <brillo/asynchronous_signal_handler.h>
2703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include <brillo/flag_helper.h>
2840a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo#include <brillo/make_unique_ptr.h>
2903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include <brillo/message_loops/base_message_loop.h>
3040a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo#include <brillo/streams/file_stream.h>
3140a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo#include <brillo/streams/stream.h>
3203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo
3303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include "update_engine/common/boot_control.h"
3440a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo#include "update_engine/common/error_code_utils.h"
3503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include "update_engine/common/hardware.h"
3603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include "update_engine/common/prefs.h"
3740a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo#include "update_engine/common/subprocess.h"
3803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include "update_engine/common/terminator.h"
3903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include "update_engine/common/utils.h"
4003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include "update_engine/update_attempter_android.h"
4103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo
4203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymousing std::string;
4303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymousing std::vector;
4440a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymousing update_engine::UpdateStatus;
4503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo
463295102ed64107f966d4cf8bfe733bb936646630Alex Deymonamespace {
473295102ed64107f966d4cf8bfe733bb936646630Alex Deymo// The root directory used for temporary files in update_engine_sideload.
483295102ed64107f966d4cf8bfe733bb936646630Alex Deymoconst char kSideloadRootTempDir[] = "/tmp/update_engine_sideload";
493295102ed64107f966d4cf8bfe733bb936646630Alex Deymo}  // namespace
503295102ed64107f966d4cf8bfe733bb936646630Alex Deymo
5103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymonamespace chromeos_update_engine {
5203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymonamespace {
5303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo
5403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymovoid SetupLogging() {
5503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  string log_file;
5603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  logging::LoggingSettings log_settings;
5703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  log_settings.lock_log = logging::DONT_LOCK_LOG_FILE;
5803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  log_settings.delete_old = logging::APPEND_TO_OLD_LOG_FILE;
5903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  log_settings.log_file = nullptr;
6003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  log_settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
6103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo
6203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  logging::InitLogging(log_settings);
6303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo}
6403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo
6503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymoclass SideloadDaemonState : public DaemonStateInterface,
6603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo                            public ServiceObserverInterface {
6703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo public:
6840a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo  explicit SideloadDaemonState(brillo::StreamPtr status_stream)
6940a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo      : status_stream_(std::move(status_stream)) {
7003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo    // Add this class as the only observer.
7103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo    observers_.insert(this);
7203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  }
7303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  ~SideloadDaemonState() override = default;
7403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo
7503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  // DaemonStateInterface overrides.
7603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  bool StartUpdater() override { return true; }
7703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  void AddObserver(ServiceObserverInterface* observer) override {}
7803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  void RemoveObserver(ServiceObserverInterface* observer) override {}
7903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  const std::set<ServiceObserverInterface*>& service_observers() override {
8003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo    return observers_;
8103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  }
8203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo
8303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  // ServiceObserverInterface overrides.
8403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  void SendStatusUpdate(int64_t last_checked_time,
8503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo                        double progress,
8640a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo                        UpdateStatus status,
8703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo                        const string& new_version,
8803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo                        int64_t new_size) override {
8940a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo    if (status_ != status && (status == UpdateStatus::DOWNLOADING ||
9040a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo                              status == UpdateStatus::FINALIZING)) {
9140a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo      // Split the progress bar in two parts for the two stages DOWNLOADING and
9240a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo      // FINALIZING.
9340a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo      ReportStatus(base::StringPrintf(
9440a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo          "ui_print Step %d/2", status == UpdateStatus::DOWNLOADING ? 1 : 2));
9540a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo      ReportStatus(base::StringPrintf("progress 0.5 0"));
9640a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo    }
9740a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo    if (status_ != status || fabs(progress - progress_) > 0.005) {
9840a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo      ReportStatus(base::StringPrintf("set_progress %.lf", progress));
9940a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo    }
10040a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo    progress_ = progress;
10103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo    status_ = status;
10203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  }
10303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo
10403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  void SendPayloadApplicationComplete(ErrorCode error_code) override {
10540a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo    if (error_code != ErrorCode::kSuccess) {
10640a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo      ReportStatus(
10740a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo          base::StringPrintf("ui_print Error applying update: %d (%s)",
10840a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo                             error_code,
10940a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo                             utils::ErrorCodeToString(error_code).c_str()));
11040a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo    }
11103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo    error_code_ = error_code;
11203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo    brillo::MessageLoop::current()->BreakLoop();
11303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  }
11403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo
11503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  // Getters.
11640a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo  UpdateStatus status() { return status_; }
11703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  ErrorCode error_code() { return error_code_; }
11803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo
11903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo private:
12040a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo  // Report a status message in the status_stream_, if any. These messages
12140a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo  // should conform to the specification defined in the Android recovery.
12240a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo  void ReportStatus(const string& message) {
12340a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo    if (!status_stream_)
12440a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo      return;
12540a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo    string status_line = message + "\n";
12640a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo    status_stream_->WriteAllBlocking(
12740a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo        status_line.data(), status_line.size(), nullptr);
12840a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo  }
12940a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo
13003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  std::set<ServiceObserverInterface*> observers_;
13140a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo  brillo::StreamPtr status_stream_;
13203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo
13303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  // The last status and error code reported.
13440a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo  UpdateStatus status_{UpdateStatus::IDLE};
13503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  ErrorCode error_code_{ErrorCode::kSuccess};
13640a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo  double progress_{-1.};
13703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo};
13803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo
13903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// Apply an update payload directly from the given payload URI.
14003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymobool ApplyUpdatePayload(const string& payload,
14103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo                        int64_t payload_offset,
14203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo                        int64_t payload_size,
14340a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo                        const vector<string>& headers,
14440a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo                        int64_t status_fd) {
14503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  brillo::BaseMessageLoop loop;
14603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  loop.SetAsCurrent();
14703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo
14840a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo  // Setup the subprocess handler.
14940a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo  brillo::AsynchronousSignalHandler handler;
15040a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo  handler.Init();
15140a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo  Subprocess subprocess;
15240a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo  subprocess.Init(&handler);
15340a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo
15440a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo  SideloadDaemonState sideload_daemon_state(
15540a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo      brillo::FileStream::FromFileDescriptor(status_fd, true, nullptr));
15603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo
15703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  // During the sideload we don't access the prefs persisted on disk but instead
15803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  // use a temporary memory storage.
15903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  MemoryPrefs prefs;
16003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo
16103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  std::unique_ptr<BootControlInterface> boot_control =
16203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo      boot_control::CreateBootControl();
16303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  if (!boot_control) {
16403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo    LOG(ERROR) << "Error initializing the BootControlInterface.";
16503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo    return false;
16603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  }
16703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo
16803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  std::unique_ptr<HardwareInterface> hardware = hardware::CreateHardware();
16903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  if (!hardware) {
17003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo    LOG(ERROR) << "Error initializing the HardwareInterface.";
17103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo    return false;
17203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  }
17303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo
17403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  UpdateAttempterAndroid update_attempter(
17503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo      &sideload_daemon_state, &prefs, boot_control.get(), hardware.get());
17603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  update_attempter.Init();
17703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo
17803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  TEST_AND_RETURN_FALSE(update_attempter.ApplyPayload(
17903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo      payload, payload_offset, payload_size, headers, nullptr));
18003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo
18103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  loop.Run();
18240a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo  return sideload_daemon_state.status() == UpdateStatus::UPDATED_NEED_REBOOT;
18303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo}
18403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo
18503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo}  // namespace
18603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo}  // namespace chromeos_update_engine
18703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo
18803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymoint main(int argc, char** argv) {
18903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  DEFINE_string(payload,
19003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo                "file:///data/payload.bin",
19103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo                "The URI to the update payload to use.");
19203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  DEFINE_int64(
19303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo      offset, 0, "The offset in the payload where the CrAU update starts. ");
19403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  DEFINE_int64(size,
19503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo               0,
19603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo               "The size of the CrAU part of the payload. If 0 is passed, it "
19703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo               "will be autodetected.");
19803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  DEFINE_string(headers,
19903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo                "",
20003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo                "A list of key-value pairs, one element of the list per line.");
20140a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo  DEFINE_int64(status_fd, -1, "A file descriptor to notify the update status.");
20203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo
20303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  chromeos_update_engine::Terminator::Init();
20403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  chromeos_update_engine::SetupLogging();
20503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  brillo::FlagHelper::Init(argc, argv, "Update Engine Sideload");
20603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo
20703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  LOG(INFO) << "Update Engine Sideloading starting";
20803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo
20903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  // xz-embedded requires to initialize its CRC-32 table once on startup.
21003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  xz_crc32_init();
21103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo
2123295102ed64107f966d4cf8bfe733bb936646630Alex Deymo  // When called from recovery, /data is not accessible, so we need to use
2133295102ed64107f966d4cf8bfe733bb936646630Alex Deymo  // /tmp for temporary files.
2143295102ed64107f966d4cf8bfe733bb936646630Alex Deymo  chromeos_update_engine::utils::SetRootTempDir(kSideloadRootTempDir);
2153295102ed64107f966d4cf8bfe733bb936646630Alex Deymo
21603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  vector<string> headers = base::SplitString(
21703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo      FLAGS_headers, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
21803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo
21903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  if (!chromeos_update_engine::ApplyUpdatePayload(
22040a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo          FLAGS_payload, FLAGS_offset, FLAGS_size, headers, FLAGS_status_fd))
22103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo    return 1;
22203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo
22303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  return 0;
22403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo}
225