15f52811e5afda03e374a28233500e151f1e706f4Alex Deymo//
25f52811e5afda03e374a28233500e151f1e706f4Alex Deymo// Copyright (C) 2016 The Android Open Source Project
35f52811e5afda03e374a28233500e151f1e706f4Alex Deymo//
45f52811e5afda03e374a28233500e151f1e706f4Alex Deymo// Licensed under the Apache License, Version 2.0 (the "License");
55f52811e5afda03e374a28233500e151f1e706f4Alex Deymo// you may not use this file except in compliance with the License.
65f52811e5afda03e374a28233500e151f1e706f4Alex Deymo// You may obtain a copy of the License at
75f52811e5afda03e374a28233500e151f1e706f4Alex Deymo//
85f52811e5afda03e374a28233500e151f1e706f4Alex Deymo//      http://www.apache.org/licenses/LICENSE-2.0
95f52811e5afda03e374a28233500e151f1e706f4Alex Deymo//
105f52811e5afda03e374a28233500e151f1e706f4Alex Deymo// Unless required by applicable law or agreed to in writing, software
115f52811e5afda03e374a28233500e151f1e706f4Alex Deymo// distributed under the License is distributed on an "AS IS" BASIS,
125f52811e5afda03e374a28233500e151f1e706f4Alex Deymo// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135f52811e5afda03e374a28233500e151f1e706f4Alex Deymo// See the License for the specific language governing permissions and
145f52811e5afda03e374a28233500e151f1e706f4Alex Deymo// limitations under the License.
155f52811e5afda03e374a28233500e151f1e706f4Alex Deymo//
165f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
175f52811e5afda03e374a28233500e151f1e706f4Alex Deymo#include <sysexits.h>
185f52811e5afda03e374a28233500e151f1e706f4Alex Deymo#include <unistd.h>
195f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
205f52811e5afda03e374a28233500e151f1e706f4Alex Deymo#include <string>
215f52811e5afda03e374a28233500e151f1e706f4Alex Deymo#include <vector>
225f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
235f52811e5afda03e374a28233500e151f1e706f4Alex Deymo#include <base/bind.h>
245f52811e5afda03e374a28233500e151f1e706f4Alex Deymo#include <base/callback.h>
255f52811e5afda03e374a28233500e151f1e706f4Alex Deymo#include <base/command_line.h>
265f52811e5afda03e374a28233500e151f1e706f4Alex Deymo#include <base/logging.h>
275f52811e5afda03e374a28233500e151f1e706f4Alex Deymo#include <base/strings/string_split.h>
285f52811e5afda03e374a28233500e151f1e706f4Alex Deymo#include <binder/IServiceManager.h>
292130ee03a1b05c923e3ad44b4beef9849ff939e5Alex Deymo#include <binderwrapper/binder_wrapper.h>
305f52811e5afda03e374a28233500e151f1e706f4Alex Deymo#include <brillo/binder_watcher.h>
315f52811e5afda03e374a28233500e151f1e706f4Alex Deymo#include <brillo/daemons/daemon.h>
325f52811e5afda03e374a28233500e151f1e706f4Alex Deymo#include <brillo/flag_helper.h>
335f52811e5afda03e374a28233500e151f1e706f4Alex Deymo#include <brillo/message_loops/message_loop.h>
345f52811e5afda03e374a28233500e151f1e706f4Alex Deymo#include <brillo/syslog_logging.h>
355f52811e5afda03e374a28233500e151f1e706f4Alex Deymo#include <utils/String16.h>
365f52811e5afda03e374a28233500e151f1e706f4Alex Deymo#include <utils/StrongPointer.h>
375f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
385f52811e5afda03e374a28233500e151f1e706f4Alex Deymo#include "android/os/BnUpdateEngineCallback.h"
395f52811e5afda03e374a28233500e151f1e706f4Alex Deymo#include "android/os/IUpdateEngine.h"
405f52811e5afda03e374a28233500e151f1e706f4Alex Deymo#include "update_engine/client_library/include/update_engine/update_status.h"
415f52811e5afda03e374a28233500e151f1e706f4Alex Deymo#include "update_engine/common/error_code.h"
42e88e9feb5a64c1358baeb1c8547e82aa08e1cd83Alex Deymo#include "update_engine/common/error_code_utils.h"
432130ee03a1b05c923e3ad44b4beef9849ff939e5Alex Deymo#include "update_engine/update_status_utils.h"
445f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
455f52811e5afda03e374a28233500e151f1e706f4Alex Deymousing android::binder::Status;
465f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
475f52811e5afda03e374a28233500e151f1e706f4Alex Deymonamespace chromeos_update_engine {
485f52811e5afda03e374a28233500e151f1e706f4Alex Deymonamespace internal {
495f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
505f52811e5afda03e374a28233500e151f1e706f4Alex Deymoclass UpdateEngineClientAndroid : public brillo::Daemon {
515f52811e5afda03e374a28233500e151f1e706f4Alex Deymo public:
525f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  UpdateEngineClientAndroid(int argc, char** argv) : argc_(argc), argv_(argv) {
535f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  }
545f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
555f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  int ExitWhenIdle(const Status& status);
565f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  int ExitWhenIdle(int return_code);
575f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
585f52811e5afda03e374a28233500e151f1e706f4Alex Deymo private:
595f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  class UECallback : public android::os::BnUpdateEngineCallback {
605f52811e5afda03e374a28233500e151f1e706f4Alex Deymo   public:
61e88e9feb5a64c1358baeb1c8547e82aa08e1cd83Alex Deymo    explicit UECallback(UpdateEngineClientAndroid* client) : client_(client) {}
625f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
635f52811e5afda03e374a28233500e151f1e706f4Alex Deymo    // android::os::BnUpdateEngineCallback overrides.
645f52811e5afda03e374a28233500e151f1e706f4Alex Deymo    Status onStatusUpdate(int status_code, float progress) override;
655f52811e5afda03e374a28233500e151f1e706f4Alex Deymo    Status onPayloadApplicationComplete(int error_code) override;
665f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
675f52811e5afda03e374a28233500e151f1e706f4Alex Deymo   private:
685f52811e5afda03e374a28233500e151f1e706f4Alex Deymo    UpdateEngineClientAndroid* client_;
695f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  };
705f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
715f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  int OnInit() override;
725f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
732130ee03a1b05c923e3ad44b4beef9849ff939e5Alex Deymo  // Called whenever the UpdateEngine daemon dies.
742130ee03a1b05c923e3ad44b4beef9849ff939e5Alex Deymo  void UpdateEngineServiceDied();
752130ee03a1b05c923e3ad44b4beef9849ff939e5Alex Deymo
765f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  // Copy of argc and argv passed to main().
775f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  int argc_;
785f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  char** argv_;
795f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
805f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  android::sp<android::os::IUpdateEngine> service_;
815f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  android::sp<android::os::BnUpdateEngineCallback> callback_;
825f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
835f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  brillo::BinderWatcher binder_watcher_;
845f52811e5afda03e374a28233500e151f1e706f4Alex Deymo};
855f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
865f52811e5afda03e374a28233500e151f1e706f4Alex DeymoStatus UpdateEngineClientAndroid::UECallback::onStatusUpdate(
875f52811e5afda03e374a28233500e151f1e706f4Alex Deymo    int status_code, float progress) {
885f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  update_engine::UpdateStatus status =
895f52811e5afda03e374a28233500e151f1e706f4Alex Deymo      static_cast<update_engine::UpdateStatus>(status_code);
905f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  LOG(INFO) << "onStatusUpdate(" << UpdateStatusToString(status) << " ("
915f52811e5afda03e374a28233500e151f1e706f4Alex Deymo            << status_code << "), " << progress << ")";
925f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  return Status::ok();
935f52811e5afda03e374a28233500e151f1e706f4Alex Deymo}
945f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
955f52811e5afda03e374a28233500e151f1e706f4Alex DeymoStatus UpdateEngineClientAndroid::UECallback::onPayloadApplicationComplete(
965f52811e5afda03e374a28233500e151f1e706f4Alex Deymo    int error_code) {
975f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  ErrorCode code = static_cast<ErrorCode>(error_code);
98e88e9feb5a64c1358baeb1c8547e82aa08e1cd83Alex Deymo  LOG(INFO) << "onPayloadApplicationComplete(" << utils::ErrorCodeToString(code)
99e88e9feb5a64c1358baeb1c8547e82aa08e1cd83Alex Deymo            << " (" << error_code << "))";
1005f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  client_->ExitWhenIdle(code == ErrorCode::kSuccess ? EX_OK : 1);
1015f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  return Status::ok();
1025f52811e5afda03e374a28233500e151f1e706f4Alex Deymo}
1035f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
1045f52811e5afda03e374a28233500e151f1e706f4Alex Deymoint UpdateEngineClientAndroid::OnInit() {
1055f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  int ret = Daemon::OnInit();
1065f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  if (ret != EX_OK)
1075f52811e5afda03e374a28233500e151f1e706f4Alex Deymo    return ret;
1085f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
1095f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  DEFINE_bool(update, false, "Start a new update, if no update in progress.");
1105f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  DEFINE_string(payload,
1115f52811e5afda03e374a28233500e151f1e706f4Alex Deymo                "http://127.0.0.1:8080/payload",
1125f52811e5afda03e374a28233500e151f1e706f4Alex Deymo                "The URI to the update payload to use.");
11395b8f248088934180732cd7e166e70a7d8fe4d0cAlex Deymo  DEFINE_int64(offset, 0,
11495b8f248088934180732cd7e166e70a7d8fe4d0cAlex Deymo               "The offset in the payload where the CrAU update starts. "
11595b8f248088934180732cd7e166e70a7d8fe4d0cAlex Deymo               "Used when --update is passed.");
11695b8f248088934180732cd7e166e70a7d8fe4d0cAlex Deymo  DEFINE_int64(size, 0,
11795b8f248088934180732cd7e166e70a7d8fe4d0cAlex Deymo               "The size of the CrAU part of the payload. If 0 is passed, it "
11895b8f248088934180732cd7e166e70a7d8fe4d0cAlex Deymo               "will be autodetected. Used when --update is passed.");
1195f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  DEFINE_string(headers,
1205f52811e5afda03e374a28233500e151f1e706f4Alex Deymo                "",
12195b8f248088934180732cd7e166e70a7d8fe4d0cAlex Deymo                "A list of key-value pairs, one element of the list per line. "
12295b8f248088934180732cd7e166e70a7d8fe4d0cAlex Deymo                "Used when --update is passed.");
1235f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
1245f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  DEFINE_bool(suspend, false, "Suspend an ongoing update and exit.");
1255f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  DEFINE_bool(resume, false, "Resume a suspended update.");
1265f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  DEFINE_bool(cancel, false, "Cancel the ongoing update and exit.");
12728618b1b79163b66a7c4623957b869901e4022d4Alex Deymo  DEFINE_bool(reset_status, false, "Reset an already applied update and exit.");
1285f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  DEFINE_bool(follow,
1295f52811e5afda03e374a28233500e151f1e706f4Alex Deymo              false,
1305f52811e5afda03e374a28233500e151f1e706f4Alex Deymo              "Follow status update changes until a final state is reached. "
1315f52811e5afda03e374a28233500e151f1e706f4Alex Deymo              "Exit status is 0 if the update succeeded, and 1 otherwise.");
1325f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
1335f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  // Boilerplate init commands.
1345f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  base::CommandLine::Init(argc_, argv_);
1355f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  brillo::FlagHelper::Init(argc_, argv_, "Android Update Engine Client");
1365f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  if (argc_ == 1) {
1375f52811e5afda03e374a28233500e151f1e706f4Alex Deymo    LOG(ERROR) << "Nothing to do. Run with --help for help.";
1385f52811e5afda03e374a28233500e151f1e706f4Alex Deymo    return 1;
1395f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  }
1405f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
1415f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  // Ensure there are no positional arguments.
1425f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  const std::vector<std::string> positional_args =
1435f52811e5afda03e374a28233500e151f1e706f4Alex Deymo      base::CommandLine::ForCurrentProcess()->GetArgs();
1445f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  if (!positional_args.empty()) {
1455f52811e5afda03e374a28233500e151f1e706f4Alex Deymo    LOG(ERROR) << "Found a positional argument '" << positional_args.front()
1465f52811e5afda03e374a28233500e151f1e706f4Alex Deymo               << "'. If you want to pass a value to a flag, pass it as "
1475f52811e5afda03e374a28233500e151f1e706f4Alex Deymo                  "--flag=value.";
1485f52811e5afda03e374a28233500e151f1e706f4Alex Deymo    return 1;
1495f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  }
1505f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
1515f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  bool keep_running = false;
15295224ddce0671a569095622b4817a34dfbaa8830Alex Deymo  brillo::InitLog(brillo::kLogToStderr);
1532130ee03a1b05c923e3ad44b4beef9849ff939e5Alex Deymo
1542130ee03a1b05c923e3ad44b4beef9849ff939e5Alex Deymo  // Initialize a binder watcher early in the process before any interaction
1552130ee03a1b05c923e3ad44b4beef9849ff939e5Alex Deymo  // with the binder driver.
1562130ee03a1b05c923e3ad44b4beef9849ff939e5Alex Deymo  binder_watcher_.Init();
1572130ee03a1b05c923e3ad44b4beef9849ff939e5Alex Deymo
1585f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  android::status_t status = android::getService(
1595f52811e5afda03e374a28233500e151f1e706f4Alex Deymo      android::String16("android.os.UpdateEngineService"), &service_);
1605f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  if (status != android::OK) {
1615f52811e5afda03e374a28233500e151f1e706f4Alex Deymo    LOG(ERROR) << "Failed to get IUpdateEngine binder from service manager: "
1625f52811e5afda03e374a28233500e151f1e706f4Alex Deymo               << Status::fromStatusT(status).toString8();
1632130ee03a1b05c923e3ad44b4beef9849ff939e5Alex Deymo    return ExitWhenIdle(1);
1645f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  }
1655f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
1665f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  if (FLAGS_suspend) {
1675f52811e5afda03e374a28233500e151f1e706f4Alex Deymo    return ExitWhenIdle(service_->suspend());
1685f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  }
1695f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
1705f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  if (FLAGS_resume) {
1715f52811e5afda03e374a28233500e151f1e706f4Alex Deymo    return ExitWhenIdle(service_->resume());
1725f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  }
1735f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
1745f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  if (FLAGS_cancel) {
1755f52811e5afda03e374a28233500e151f1e706f4Alex Deymo    return ExitWhenIdle(service_->cancel());
1765f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  }
1775f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
17828618b1b79163b66a7c4623957b869901e4022d4Alex Deymo  if (FLAGS_reset_status) {
17928618b1b79163b66a7c4623957b869901e4022d4Alex Deymo    return ExitWhenIdle(service_->resetStatus());
18028618b1b79163b66a7c4623957b869901e4022d4Alex Deymo  }
18128618b1b79163b66a7c4623957b869901e4022d4Alex Deymo
1825f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  if (FLAGS_follow) {
1835f52811e5afda03e374a28233500e151f1e706f4Alex Deymo    // Register a callback object with the service.
1845f52811e5afda03e374a28233500e151f1e706f4Alex Deymo    callback_ = new UECallback(this);
1855f52811e5afda03e374a28233500e151f1e706f4Alex Deymo    bool bound;
1865f52811e5afda03e374a28233500e151f1e706f4Alex Deymo    if (!service_->bind(callback_, &bound).isOk() || !bound) {
1875f52811e5afda03e374a28233500e151f1e706f4Alex Deymo      LOG(ERROR) << "Failed to bind() the UpdateEngine daemon.";
1885f52811e5afda03e374a28233500e151f1e706f4Alex Deymo      return 1;
1895f52811e5afda03e374a28233500e151f1e706f4Alex Deymo    }
1905f52811e5afda03e374a28233500e151f1e706f4Alex Deymo    keep_running = true;
1915f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  }
1925f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
1935f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  if (FLAGS_update) {
1945f52811e5afda03e374a28233500e151f1e706f4Alex Deymo    std::vector<std::string> headers = base::SplitString(
1955f52811e5afda03e374a28233500e151f1e706f4Alex Deymo        FLAGS_headers, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
1965f52811e5afda03e374a28233500e151f1e706f4Alex Deymo    std::vector<android::String16> and_headers;
1975f52811e5afda03e374a28233500e151f1e706f4Alex Deymo    for (const auto& header : headers) {
1985f52811e5afda03e374a28233500e151f1e706f4Alex Deymo      and_headers.push_back(android::String16{header.data(), header.size()});
1995f52811e5afda03e374a28233500e151f1e706f4Alex Deymo    }
2005f52811e5afda03e374a28233500e151f1e706f4Alex Deymo    Status status = service_->applyPayload(
2015f52811e5afda03e374a28233500e151f1e706f4Alex Deymo        android::String16{FLAGS_payload.data(), FLAGS_payload.size()},
20295b8f248088934180732cd7e166e70a7d8fe4d0cAlex Deymo        FLAGS_offset,
20395b8f248088934180732cd7e166e70a7d8fe4d0cAlex Deymo        FLAGS_size,
2045f52811e5afda03e374a28233500e151f1e706f4Alex Deymo        and_headers);
2055f52811e5afda03e374a28233500e151f1e706f4Alex Deymo    if (!status.isOk())
2065f52811e5afda03e374a28233500e151f1e706f4Alex Deymo      return ExitWhenIdle(status);
2075f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  }
2085f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
2095f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  if (!keep_running)
2105f52811e5afda03e374a28233500e151f1e706f4Alex Deymo    return ExitWhenIdle(EX_OK);
2115f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
2122130ee03a1b05c923e3ad44b4beef9849ff939e5Alex Deymo  // When following updates status changes, exit if the update_engine daemon
2132130ee03a1b05c923e3ad44b4beef9849ff939e5Alex Deymo  // dies.
2142130ee03a1b05c923e3ad44b4beef9849ff939e5Alex Deymo  android::BinderWrapper::Create();
2152130ee03a1b05c923e3ad44b4beef9849ff939e5Alex Deymo  android::BinderWrapper::Get()->RegisterForDeathNotifications(
2162130ee03a1b05c923e3ad44b4beef9849ff939e5Alex Deymo      android::os::IUpdateEngine::asBinder(service_),
2172130ee03a1b05c923e3ad44b4beef9849ff939e5Alex Deymo      base::Bind(&UpdateEngineClientAndroid::UpdateEngineServiceDied,
2182130ee03a1b05c923e3ad44b4beef9849ff939e5Alex Deymo                 base::Unretained(this)));
2192130ee03a1b05c923e3ad44b4beef9849ff939e5Alex Deymo
2205f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  return EX_OK;
2215f52811e5afda03e374a28233500e151f1e706f4Alex Deymo}
2225f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
2235f52811e5afda03e374a28233500e151f1e706f4Alex Deymoint UpdateEngineClientAndroid::ExitWhenIdle(const Status& status) {
2245f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  if (status.isOk())
2255f52811e5afda03e374a28233500e151f1e706f4Alex Deymo    return ExitWhenIdle(EX_OK);
2265f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  LOG(ERROR) << status.toString8();
2275f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  return ExitWhenIdle(status.exceptionCode());
2285f52811e5afda03e374a28233500e151f1e706f4Alex Deymo}
2295f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
2305f52811e5afda03e374a28233500e151f1e706f4Alex Deymoint UpdateEngineClientAndroid::ExitWhenIdle(int return_code) {
2315f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  auto delayed_exit = base::Bind(
2325f52811e5afda03e374a28233500e151f1e706f4Alex Deymo      &Daemon::QuitWithExitCode, base::Unretained(this), return_code);
2335f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  if (!brillo::MessageLoop::current()->PostTask(delayed_exit))
2345f52811e5afda03e374a28233500e151f1e706f4Alex Deymo    return 1;
2355f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  return EX_OK;
2365f52811e5afda03e374a28233500e151f1e706f4Alex Deymo}
2375f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
2382130ee03a1b05c923e3ad44b4beef9849ff939e5Alex Deymovoid UpdateEngineClientAndroid::UpdateEngineServiceDied() {
2392130ee03a1b05c923e3ad44b4beef9849ff939e5Alex Deymo  LOG(ERROR) << "UpdateEngineService died.";
2402130ee03a1b05c923e3ad44b4beef9849ff939e5Alex Deymo  QuitWithExitCode(1);
2412130ee03a1b05c923e3ad44b4beef9849ff939e5Alex Deymo}
2422130ee03a1b05c923e3ad44b4beef9849ff939e5Alex Deymo
2435f52811e5afda03e374a28233500e151f1e706f4Alex Deymo}  // namespace internal
2445f52811e5afda03e374a28233500e151f1e706f4Alex Deymo}  // namespace chromeos_update_engine
2455f52811e5afda03e374a28233500e151f1e706f4Alex Deymo
2465f52811e5afda03e374a28233500e151f1e706f4Alex Deymoint main(int argc, char** argv) {
2475f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  chromeos_update_engine::internal::UpdateEngineClientAndroid client(
2485f52811e5afda03e374a28233500e151f1e706f4Alex Deymo      argc, argv);
2495f52811e5afda03e374a28233500e151f1e706f4Alex Deymo  return client.Run();
2505f52811e5afda03e374a28233500e151f1e706f4Alex Deymo}
251