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 
25 using android::binder::Status;
26 using android::os::IUpdateEngineCallback;
27 
28 namespace {
ErrorPtrToStatus(const brillo::ErrorPtr & error)29 Status ErrorPtrToStatus(const brillo::ErrorPtr& error) {
30   return Status::fromServiceSpecificError(
31       1, android::String8{error->GetMessage().c_str()});
32 }
33 }  // namespace
34 
35 namespace chromeos_update_engine {
36 
BinderUpdateEngineAndroidService(ServiceDelegateAndroidInterface * service_delegate)37 BinderUpdateEngineAndroidService::BinderUpdateEngineAndroidService(
38     ServiceDelegateAndroidInterface* service_delegate)
39     : service_delegate_(service_delegate) {
40 }
41 
SendStatusUpdate(int64_t,double progress,update_engine::UpdateStatus status,const std::string &,int64_t)42 void BinderUpdateEngineAndroidService::SendStatusUpdate(
43     int64_t /* last_checked_time */,
44     double progress,
45     update_engine::UpdateStatus status,
46     const std::string& /* new_version  */,
47     int64_t /* new_size */) {
48   last_status_ = static_cast<int>(status);
49   last_progress_ = progress;
50   for (auto& callback : callbacks_) {
51     callback->onStatusUpdate(last_status_, last_progress_);
52   }
53 }
54 
SendPayloadApplicationComplete(ErrorCode error_code)55 void BinderUpdateEngineAndroidService::SendPayloadApplicationComplete(
56     ErrorCode error_code) {
57   for (auto& callback : callbacks_) {
58     callback->onPayloadApplicationComplete(static_cast<int>(error_code));
59   }
60 }
61 
bind(const android::sp<IUpdateEngineCallback> & callback,bool * return_value)62 Status BinderUpdateEngineAndroidService::bind(
63     const android::sp<IUpdateEngineCallback>& callback, bool* return_value) {
64   callbacks_.emplace_back(callback);
65 
66   auto binder_wrapper = android::BinderWrapper::Get();
67   binder_wrapper->RegisterForDeathNotifications(
68       IUpdateEngineCallback::asBinder(callback),
69       base::Bind(&BinderUpdateEngineAndroidService::UnbindCallback,
70                  base::Unretained(this),
71                  base::Unretained(callback.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 
applyPayload(const android::String16 & url,int64_t payload_offset,int64_t payload_size,const std::vector<android::String16> & header_kv_pairs)83 Status BinderUpdateEngineAndroidService::applyPayload(
84     const android::String16& url,
85     int64_t payload_offset,
86     int64_t payload_size,
87     const std::vector<android::String16>& header_kv_pairs) {
88   const std::string payload_url{android::String8{url}.string()};
89   std::vector<std::string> str_headers;
90   str_headers.reserve(header_kv_pairs.size());
91   for (const auto& header : header_kv_pairs) {
92     str_headers.emplace_back(android::String8{header}.string());
93   }
94 
95   brillo::ErrorPtr error;
96   if (!service_delegate_->ApplyPayload(
97           payload_url, payload_offset, payload_size, str_headers, &error)) {
98     return ErrorPtrToStatus(error);
99   }
100   return Status::ok();
101 }
102 
suspend()103 Status BinderUpdateEngineAndroidService::suspend() {
104   brillo::ErrorPtr error;
105   if (!service_delegate_->SuspendUpdate(&error))
106     return ErrorPtrToStatus(error);
107   return Status::ok();
108 }
109 
resume()110 Status BinderUpdateEngineAndroidService::resume() {
111   brillo::ErrorPtr error;
112   if (!service_delegate_->ResumeUpdate(&error))
113     return ErrorPtrToStatus(error);
114   return Status::ok();
115 }
116 
cancel()117 Status BinderUpdateEngineAndroidService::cancel() {
118   brillo::ErrorPtr error;
119   if (!service_delegate_->CancelUpdate(&error))
120     return ErrorPtrToStatus(error);
121   return Status::ok();
122 }
123 
resetStatus()124 Status BinderUpdateEngineAndroidService::resetStatus() {
125   brillo::ErrorPtr error;
126   if (!service_delegate_->ResetStatus(&error))
127     return ErrorPtrToStatus(error);
128   return Status::ok();
129 }
130 
UnbindCallback(IUpdateEngineCallback * callback)131 void BinderUpdateEngineAndroidService::UnbindCallback(
132     IUpdateEngineCallback* callback) {
133   auto it =
134       std::find_if(callbacks_.begin(),
135                    callbacks_.end(),
136                    [&callback](const android::sp<IUpdateEngineCallback>& elem) {
137                      return elem.get() == callback;
138                    });
139   if (it == callbacks_.end()) {
140     LOG(ERROR) << "Got death notification for unknown callback.";
141     return;
142   }
143   callbacks_.erase(it);
144 }
145 
146 }  // namespace chromeos_update_engine
147