blob: a12b349ba1c78bc978eb99e3a09fd222648507c0 [file] [log] [blame]
Yifan Hong2562cf22020-07-21 19:28:44 -07001//
2// Copyright (C) 2020 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_stable_android.h"
18
19#include <memory>
20
21#include <base/bind.h>
22#include <base/logging.h>
23#include <binderwrapper/binder_wrapper.h>
24#include <brillo/errors/error.h>
25#include <utils/String8.h>
26
27#include "update_engine/binder_service_android_common.h"
28
29using android::binder::Status;
30using android::os::IUpdateEngineStableCallback;
31using android::os::ParcelFileDescriptor;
32using std::string;
33using std::vector;
34using update_engine::UpdateEngineStatus;
35
36namespace chromeos_update_engine {
37
38BinderUpdateEngineAndroidStableService::BinderUpdateEngineAndroidStableService(
39 ServiceDelegateAndroidInterface* service_delegate)
40 : service_delegate_(service_delegate) {}
41
42void BinderUpdateEngineAndroidStableService::SendStatusUpdate(
43 const UpdateEngineStatus& update_engine_status) {
44 last_status_ = static_cast<int>(update_engine_status.status);
45 last_progress_ = update_engine_status.progress;
46 if (callback_) {
47 callback_->onStatusUpdate(last_status_, last_progress_);
48 }
49}
50
51void BinderUpdateEngineAndroidStableService::SendPayloadApplicationComplete(
52 ErrorCode error_code) {
53 if (callback_) {
54 callback_->onPayloadApplicationComplete(static_cast<int>(error_code));
55 }
56}
57
58Status BinderUpdateEngineAndroidStableService::bind(
59 const android::sp<IUpdateEngineStableCallback>& callback,
60 bool* return_value) {
61 // Reject binding if another callback is already bound.
62 if (callback_ != nullptr) {
63 LOG(ERROR) << "Another callback is already bound. Can't bind new callback.";
64 *return_value = false;
65 return Status::ok();
66 }
67
68 // See BinderUpdateEngineAndroidService::bind.
69 if (last_status_ != -1) {
70 auto status = callback->onStatusUpdate(last_status_, last_progress_);
71 if (!status.isOk()) {
72 LOG(ERROR) << "Failed to call onStatusUpdate() from callback: "
73 << status.toString8();
74 *return_value = false;
75 return Status::ok();
76 }
77 }
78
79 callback_ = callback;
80
81 const android::sp<IBinder>& callback_binder =
82 IUpdateEngineStableCallback::asBinder(callback);
83 auto binder_wrapper = android::BinderWrapper::Get();
84 binder_wrapper->RegisterForDeathNotifications(
85 callback_binder,
86 base::Bind(base::IgnoreResult(
87 &BinderUpdateEngineAndroidStableService::UnbindCallback),
88 base::Unretained(this),
89 base::Unretained(callback_binder.get())));
90
91 *return_value = true;
92 return Status::ok();
93}
94
95Status BinderUpdateEngineAndroidStableService::unbind(
96 const android::sp<IUpdateEngineStableCallback>& callback,
97 bool* return_value) {
98 const android::sp<IBinder>& callback_binder =
99 IUpdateEngineStableCallback::asBinder(callback);
100 auto binder_wrapper = android::BinderWrapper::Get();
101 binder_wrapper->UnregisterForDeathNotifications(callback_binder);
102
103 *return_value = UnbindCallback(callback_binder.get());
104 return Status::ok();
105}
106
107Status BinderUpdateEngineAndroidStableService::applyPayloadFd(
108 const ParcelFileDescriptor& pfd,
109 int64_t payload_offset,
110 int64_t payload_size,
111 const vector<android::String16>& header_kv_pairs) {
112 vector<string> str_headers = ToVecString(header_kv_pairs);
113
114 brillo::ErrorPtr error;
115 if (!service_delegate_->ApplyPayload(
116 pfd.get(), payload_offset, payload_size, str_headers, &error)) {
117 return ErrorPtrToStatus(error);
118 }
119 return Status::ok();
120}
121
122bool BinderUpdateEngineAndroidStableService::UnbindCallback(
123 const IBinder* callback) {
124 if (IUpdateEngineStableCallback::asBinder(callback_).get() != callback) {
125 LOG(ERROR) << "Unable to unbind unknown callback.";
126 return false;
127 }
128 callback_ = nullptr;
129 return true;
130}
131
132} // namespace chromeos_update_engine