Home | History | Annotate | Download | only in update_engine
      1 //
      2 // Copyright (C) 2016 The Android Open Source Project
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 //
     16 
     17 #include <sysexits.h>
     18 #include <unistd.h>
     19 
     20 #include <string>
     21 #include <vector>
     22 
     23 #include <base/bind.h>
     24 #include <base/callback.h>
     25 #include <base/command_line.h>
     26 #include <base/logging.h>
     27 #include <base/strings/string_split.h>
     28 #include <binder/IServiceManager.h>
     29 #include <binderwrapper/binder_wrapper.h>
     30 #include <brillo/binder_watcher.h>
     31 #include <brillo/daemons/daemon.h>
     32 #include <brillo/flag_helper.h>
     33 #include <brillo/message_loops/message_loop.h>
     34 #include <brillo/syslog_logging.h>
     35 #include <utils/String16.h>
     36 #include <utils/StrongPointer.h>
     37 
     38 #include "android/os/BnUpdateEngineCallback.h"
     39 #include "android/os/IUpdateEngine.h"
     40 #include "update_engine/client_library/include/update_engine/update_status.h"
     41 #include "update_engine/common/error_code.h"
     42 #include "update_engine/common/error_code_utils.h"
     43 #include "update_engine/update_status_utils.h"
     44 
     45 using android::binder::Status;
     46 
     47 namespace chromeos_update_engine {
     48 namespace internal {
     49 
     50 class UpdateEngineClientAndroid : public brillo::Daemon {
     51  public:
     52   UpdateEngineClientAndroid(int argc, char** argv) : argc_(argc), argv_(argv) {
     53   }
     54 
     55   int ExitWhenIdle(const Status& status);
     56   int ExitWhenIdle(int return_code);
     57 
     58  private:
     59   class UECallback : public android::os::BnUpdateEngineCallback {
     60    public:
     61     explicit UECallback(UpdateEngineClientAndroid* client) : client_(client) {}
     62 
     63     // android::os::BnUpdateEngineCallback overrides.
     64     Status onStatusUpdate(int status_code, float progress) override;
     65     Status onPayloadApplicationComplete(int error_code) override;
     66 
     67    private:
     68     UpdateEngineClientAndroid* client_;
     69   };
     70 
     71   int OnInit() override;
     72 
     73   // Called whenever the UpdateEngine daemon dies.
     74   void UpdateEngineServiceDied();
     75 
     76   // Copy of argc and argv passed to main().
     77   int argc_;
     78   char** argv_;
     79 
     80   android::sp<android::os::IUpdateEngine> service_;
     81   android::sp<android::os::BnUpdateEngineCallback> callback_;
     82 
     83   brillo::BinderWatcher binder_watcher_;
     84 };
     85 
     86 Status UpdateEngineClientAndroid::UECallback::onStatusUpdate(
     87     int status_code, float progress) {
     88   update_engine::UpdateStatus status =
     89       static_cast<update_engine::UpdateStatus>(status_code);
     90   LOG(INFO) << "onStatusUpdate(" << UpdateStatusToString(status) << " ("
     91             << status_code << "), " << progress << ")";
     92   return Status::ok();
     93 }
     94 
     95 Status UpdateEngineClientAndroid::UECallback::onPayloadApplicationComplete(
     96     int error_code) {
     97   ErrorCode code = static_cast<ErrorCode>(error_code);
     98   LOG(INFO) << "onPayloadApplicationComplete(" << utils::ErrorCodeToString(code)
     99             << " (" << error_code << "))";
    100   client_->ExitWhenIdle(code == ErrorCode::kSuccess ? EX_OK : 1);
    101   return Status::ok();
    102 }
    103 
    104 int UpdateEngineClientAndroid::OnInit() {
    105   int ret = Daemon::OnInit();
    106   if (ret != EX_OK)
    107     return ret;
    108 
    109   DEFINE_bool(update, false, "Start a new update, if no update in progress.");
    110   DEFINE_string(payload,
    111                 "http://127.0.0.1:8080/payload",
    112                 "The URI to the update payload to use.");
    113   DEFINE_int64(offset, 0,
    114                "The offset in the payload where the CrAU update starts. "
    115                "Used when --update is passed.");
    116   DEFINE_int64(size, 0,
    117                "The size of the CrAU part of the payload. If 0 is passed, it "
    118                "will be autodetected. Used when --update is passed.");
    119   DEFINE_string(headers,
    120                 "",
    121                 "A list of key-value pairs, one element of the list per line. "
    122                 "Used when --update is passed.");
    123 
    124   DEFINE_bool(suspend, false, "Suspend an ongoing update and exit.");
    125   DEFINE_bool(resume, false, "Resume a suspended update.");
    126   DEFINE_bool(cancel, false, "Cancel the ongoing update and exit.");
    127   DEFINE_bool(reset_status, false, "Reset an already applied update and exit.");
    128   DEFINE_bool(follow,
    129               false,
    130               "Follow status update changes until a final state is reached. "
    131               "Exit status is 0 if the update succeeded, and 1 otherwise.");
    132 
    133   // Boilerplate init commands.
    134   base::CommandLine::Init(argc_, argv_);
    135   brillo::FlagHelper::Init(argc_, argv_, "Android Update Engine Client");
    136   if (argc_ == 1) {
    137     LOG(ERROR) << "Nothing to do. Run with --help for help.";
    138     return 1;
    139   }
    140 
    141   // Ensure there are no positional arguments.
    142   const std::vector<std::string> positional_args =
    143       base::CommandLine::ForCurrentProcess()->GetArgs();
    144   if (!positional_args.empty()) {
    145     LOG(ERROR) << "Found a positional argument '" << positional_args.front()
    146                << "'. If you want to pass a value to a flag, pass it as "
    147                   "--flag=value.";
    148     return 1;
    149   }
    150 
    151   bool keep_running = false;
    152   brillo::InitLog(brillo::kLogToStderr);
    153 
    154   // Initialize a binder watcher early in the process before any interaction
    155   // with the binder driver.
    156   binder_watcher_.Init();
    157 
    158   android::status_t status = android::getService(
    159       android::String16("android.os.UpdateEngineService"), &service_);
    160   if (status != android::OK) {
    161     LOG(ERROR) << "Failed to get IUpdateEngine binder from service manager: "
    162                << Status::fromStatusT(status).toString8();
    163     return ExitWhenIdle(1);
    164   }
    165 
    166   if (FLAGS_suspend) {
    167     return ExitWhenIdle(service_->suspend());
    168   }
    169 
    170   if (FLAGS_resume) {
    171     return ExitWhenIdle(service_->resume());
    172   }
    173 
    174   if (FLAGS_cancel) {
    175     return ExitWhenIdle(service_->cancel());
    176   }
    177 
    178   if (FLAGS_reset_status) {
    179     return ExitWhenIdle(service_->resetStatus());
    180   }
    181 
    182   if (FLAGS_follow) {
    183     // Register a callback object with the service.
    184     callback_ = new UECallback(this);
    185     bool bound;
    186     if (!service_->bind(callback_, &bound).isOk() || !bound) {
    187       LOG(ERROR) << "Failed to bind() the UpdateEngine daemon.";
    188       return 1;
    189     }
    190     keep_running = true;
    191   }
    192 
    193   if (FLAGS_update) {
    194     std::vector<std::string> headers = base::SplitString(
    195         FLAGS_headers, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
    196     std::vector<android::String16> and_headers;
    197     for (const auto& header : headers) {
    198       and_headers.push_back(android::String16{header.data(), header.size()});
    199     }
    200     Status status = service_->applyPayload(
    201         android::String16{FLAGS_payload.data(), FLAGS_payload.size()},
    202         FLAGS_offset,
    203         FLAGS_size,
    204         and_headers);
    205     if (!status.isOk())
    206       return ExitWhenIdle(status);
    207   }
    208 
    209   if (!keep_running)
    210     return ExitWhenIdle(EX_OK);
    211 
    212   // When following updates status changes, exit if the update_engine daemon
    213   // dies.
    214   android::BinderWrapper::Create();
    215   android::BinderWrapper::Get()->RegisterForDeathNotifications(
    216       android::os::IUpdateEngine::asBinder(service_),
    217       base::Bind(&UpdateEngineClientAndroid::UpdateEngineServiceDied,
    218                  base::Unretained(this)));
    219 
    220   return EX_OK;
    221 }
    222 
    223 int UpdateEngineClientAndroid::ExitWhenIdle(const Status& status) {
    224   if (status.isOk())
    225     return ExitWhenIdle(EX_OK);
    226   LOG(ERROR) << status.toString8();
    227   return ExitWhenIdle(status.exceptionCode());
    228 }
    229 
    230 int UpdateEngineClientAndroid::ExitWhenIdle(int return_code) {
    231   auto delayed_exit = base::Bind(
    232       &Daemon::QuitWithExitCode, base::Unretained(this), return_code);
    233   if (!brillo::MessageLoop::current()->PostTask(delayed_exit))
    234     return 1;
    235   return EX_OK;
    236 }
    237 
    238 void UpdateEngineClientAndroid::UpdateEngineServiceDied() {
    239   LOG(ERROR) << "UpdateEngineService died.";
    240   QuitWithExitCode(1);
    241 }
    242 
    243 }  // namespace internal
    244 }  // namespace chromeos_update_engine
    245 
    246 int main(int argc, char** argv) {
    247   chromeos_update_engine::internal::UpdateEngineClientAndroid client(
    248       argc, argv);
    249   return client.Run();
    250 }
    251