binder_service_android.cc revision 07fbb1b7dff86d8b26bf976b72f2722fde66b603
1//
2// Copyright (C) 2015 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 "update_engine/binder_service_android.h"
18
19#include <base/bind.h>
20#include <base/logging.h>
21#include <binderwrapper/binder_wrapper.h>
22#include <brillo/errors/error.h>
23#include <utils/String8.h>
24
25using android::binder::Status;
26using android::os::IUpdateEngineCallback;
27using update_engine::UpdateEngineStatus;
28
29namespace {
30Status ErrorPtrToStatus(const brillo::ErrorPtr& error) {
31  return Status::fromServiceSpecificError(
32      1, android::String8{error->GetMessage().c_str()});
33}
34}  // namespace
35
36namespace chromeos_update_engine {
37
38BinderUpdateEngineAndroidService::BinderUpdateEngineAndroidService(
39    ServiceDelegateAndroidInterface* service_delegate)
40    : service_delegate_(service_delegate) {
41}
42
43void BinderUpdateEngineAndroidService::SendStatusUpdate(
44    const UpdateEngineStatus& update_engine_status) {
45  last_status_ = static_cast<int>(update_engine_status.status);
46  last_progress_ = update_engine_status.progress;
47  for (auto& callback : callbacks_) {
48    callback->onStatusUpdate(last_status_, last_progress_);
49  }
50}
51
52void BinderUpdateEngineAndroidService::SendPayloadApplicationComplete(
53    ErrorCode error_code) {
54  for (auto& callback : callbacks_) {
55    callback->onPayloadApplicationComplete(static_cast<int>(error_code));
56  }
57}
58
59Status BinderUpdateEngineAndroidService::bind(
60    const android::sp<IUpdateEngineCallback>& callback, bool* return_value) {
61  callbacks_.emplace_back(callback);
62
63  const android::sp<IBinder>& callback_binder =
64      IUpdateEngineCallback::asBinder(callback);
65  auto binder_wrapper = android::BinderWrapper::Get();
66  binder_wrapper->RegisterForDeathNotifications(
67      callback_binder,
68      base::Bind(
69          base::IgnoreResult(&BinderUpdateEngineAndroidService::UnbindCallback),
70          base::Unretained(this),
71          base::Unretained(callback_binder.get())));
72
73  // Send an status update on connection (except when no update sent so far),
74  // since the status update is oneway and we don't need to wait for the
75  // response.
76  if (last_status_ != -1)
77    callback->onStatusUpdate(last_status_, last_progress_);
78
79  *return_value = true;
80  return Status::ok();
81}
82
83Status BinderUpdateEngineAndroidService::unbind(
84    const android::sp<IUpdateEngineCallback>& callback, bool* return_value) {
85  const android::sp<IBinder>& callback_binder =
86      IUpdateEngineCallback::asBinder(callback);
87  auto binder_wrapper = android::BinderWrapper::Get();
88  binder_wrapper->UnregisterForDeathNotifications(callback_binder);
89
90  *return_value = UnbindCallback(callback_binder.get());
91  return Status::ok();
92}
93
94Status BinderUpdateEngineAndroidService::applyPayload(
95    const android::String16& url,
96    int64_t payload_offset,
97    int64_t payload_size,
98    const std::vector<android::String16>& header_kv_pairs) {
99  const std::string payload_url{android::String8{url}.string()};
100  std::vector<std::string> str_headers;
101  str_headers.reserve(header_kv_pairs.size());
102  for (const auto& header : header_kv_pairs) {
103    str_headers.emplace_back(android::String8{header}.string());
104  }
105
106  brillo::ErrorPtr error;
107  if (!service_delegate_->ApplyPayload(
108          payload_url, payload_offset, payload_size, str_headers, &error)) {
109    return ErrorPtrToStatus(error);
110  }
111  return Status::ok();
112}
113
114Status BinderUpdateEngineAndroidService::suspend() {
115  brillo::ErrorPtr error;
116  if (!service_delegate_->SuspendUpdate(&error))
117    return ErrorPtrToStatus(error);
118  return Status::ok();
119}
120
121Status BinderUpdateEngineAndroidService::resume() {
122  brillo::ErrorPtr error;
123  if (!service_delegate_->ResumeUpdate(&error))
124    return ErrorPtrToStatus(error);
125  return Status::ok();
126}
127
128Status BinderUpdateEngineAndroidService::cancel() {
129  brillo::ErrorPtr error;
130  if (!service_delegate_->CancelUpdate(&error))
131    return ErrorPtrToStatus(error);
132  return Status::ok();
133}
134
135Status BinderUpdateEngineAndroidService::resetStatus() {
136  brillo::ErrorPtr error;
137  if (!service_delegate_->ResetStatus(&error))
138    return ErrorPtrToStatus(error);
139  return Status::ok();
140}
141
142Status BinderUpdateEngineAndroidService::verifyPayloadApplicable(
143    const android::String16& metadata_filename, bool* return_value) {
144  const std::string payload_metadata{
145      android::String8{metadata_filename}.string()};
146  LOG(INFO) << "Received a request of verifying payload metadata in "
147            << payload_metadata << ".";
148
149  // FIXME: Do the actual verification work.
150  *return_value = true;
151  return Status::ok();
152}
153
154bool BinderUpdateEngineAndroidService::UnbindCallback(const IBinder* callback) {
155  auto it = std::find_if(
156      callbacks_.begin(),
157      callbacks_.end(),
158      [&callback](const android::sp<IUpdateEngineCallback>& elem) {
159        return IUpdateEngineCallback::asBinder(elem).get() == callback;
160      });
161  if (it == callbacks_.end()) {
162    LOG(ERROR) << "Unable to unbind unknown callback.";
163    return false;
164  }
165  callbacks_.erase(it);
166  return true;
167}
168
169}  // namespace chromeos_update_engine
170