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_brillo.h"
18
19 #include <base/bind.h>
20
21 #include <binderwrapper/binder_wrapper.h>
22
23 #include <utils/String16.h>
24 #include <utils/StrongPointer.h>
25
26 #include "update_engine/update_status_utils.h"
27
28 using android::String16;
29 using android::String8;
30 using android::binder::Status;
31 using android::brillo::IUpdateEngineStatusCallback;
32 using android::brillo::ParcelableUpdateEngineStatus;
33 using android::sp;
34 using brillo::ErrorPtr;
35 using std::string;
36
37 namespace chromeos_update_engine {
38
39 namespace {
NormalString(const String16 & in)40 string NormalString(const String16& in) {
41 return string{String8{in}.string()};
42 }
43
ToStatus(ErrorPtr * error)44 Status ToStatus(ErrorPtr* error) {
45 return Status::fromServiceSpecificError(
46 1, String8{error->get()->GetMessage().c_str()});
47 }
48 } // namespace
49
50 template <typename... Parameters, typename... Arguments>
CallCommonHandler(bool (UpdateEngineService::* Handler)(ErrorPtr *,Parameters...),Arguments...arguments)51 Status BinderUpdateEngineBrilloService::CallCommonHandler(
52 bool (UpdateEngineService::*Handler)(ErrorPtr*, Parameters...),
53 Arguments... arguments) {
54 ErrorPtr error;
55 if (((common_.get())->*Handler)(&error, arguments...))
56 return Status::ok();
57 return ToStatus(&error);
58 }
59
AttemptUpdate(const String16 & app_version,const String16 & omaha_url,int flags)60 Status BinderUpdateEngineBrilloService::AttemptUpdate(
61 const String16& app_version, const String16& omaha_url, int flags) {
62 return CallCommonHandler(&UpdateEngineService::AttemptUpdate,
63 NormalString(app_version),
64 NormalString(omaha_url),
65 flags);
66 }
67
AttemptRollback(bool powerwash)68 Status BinderUpdateEngineBrilloService::AttemptRollback(bool powerwash) {
69 return CallCommonHandler(&UpdateEngineService::AttemptRollback, powerwash);
70 }
71
CanRollback(bool * out_can_rollback)72 Status BinderUpdateEngineBrilloService::CanRollback(bool* out_can_rollback) {
73 return CallCommonHandler(&UpdateEngineService::CanRollback, out_can_rollback);
74 }
75
ResetStatus()76 Status BinderUpdateEngineBrilloService::ResetStatus() {
77 return CallCommonHandler(&UpdateEngineService::ResetStatus);
78 }
79
GetStatus(ParcelableUpdateEngineStatus * status)80 Status BinderUpdateEngineBrilloService::GetStatus(
81 ParcelableUpdateEngineStatus* status) {
82 string current_op;
83 string new_version;
84
85 auto ret = CallCommonHandler(&UpdateEngineService::GetStatus,
86 &status->last_checked_time_,
87 &status->progress_,
88 ¤t_op,
89 &new_version,
90 &status->new_size_);
91
92 if (ret.isOk()) {
93 status->current_operation_ = String16{current_op.c_str()};
94 status->new_version_ = String16{new_version.c_str()};
95 }
96
97 return ret;
98 }
99
RebootIfNeeded()100 Status BinderUpdateEngineBrilloService::RebootIfNeeded() {
101 return CallCommonHandler(&UpdateEngineService::RebootIfNeeded);
102 }
103
SetChannel(const String16 & target_channel,bool powerwash)104 Status BinderUpdateEngineBrilloService::SetChannel(
105 const String16& target_channel, bool powerwash) {
106 return CallCommonHandler(&UpdateEngineService::SetChannel,
107 NormalString(target_channel),
108 powerwash);
109 }
110
GetChannel(bool get_current_channel,String16 * out_channel)111 Status BinderUpdateEngineBrilloService::GetChannel(bool get_current_channel,
112 String16* out_channel) {
113 string channel_string;
114 auto ret = CallCommonHandler(
115 &UpdateEngineService::GetChannel, get_current_channel, &channel_string);
116
117 *out_channel = String16(channel_string.c_str());
118 return ret;
119 }
120
SetP2PUpdatePermission(bool enabled)121 Status BinderUpdateEngineBrilloService::SetP2PUpdatePermission(bool enabled) {
122 return CallCommonHandler(&UpdateEngineService::SetP2PUpdatePermission,
123 enabled);
124 }
125
GetP2PUpdatePermission(bool * out_p2p_permission)126 Status BinderUpdateEngineBrilloService::GetP2PUpdatePermission(
127 bool* out_p2p_permission) {
128 return CallCommonHandler(&UpdateEngineService::GetP2PUpdatePermission,
129 out_p2p_permission);
130 }
131
SetUpdateOverCellularPermission(bool enabled)132 Status BinderUpdateEngineBrilloService::SetUpdateOverCellularPermission(
133 bool enabled) {
134 return CallCommonHandler(
135 &UpdateEngineService::SetUpdateOverCellularPermission, enabled);
136 }
137
GetUpdateOverCellularPermission(bool * out_cellular_permission)138 Status BinderUpdateEngineBrilloService::GetUpdateOverCellularPermission(
139 bool* out_cellular_permission) {
140 return CallCommonHandler(
141 &UpdateEngineService::GetUpdateOverCellularPermission,
142 out_cellular_permission);
143 }
144
GetDurationSinceUpdate(int64_t * out_duration)145 Status BinderUpdateEngineBrilloService::GetDurationSinceUpdate(
146 int64_t* out_duration) {
147 return CallCommonHandler(&UpdateEngineService::GetDurationSinceUpdate,
148 out_duration);
149 }
150
GetPrevVersion(String16 * out_prev_version)151 Status BinderUpdateEngineBrilloService::GetPrevVersion(
152 String16* out_prev_version) {
153 string version_string;
154 auto ret =
155 CallCommonHandler(&UpdateEngineService::GetPrevVersion, &version_string);
156
157 *out_prev_version = String16(version_string.c_str());
158 return ret;
159 }
160
GetRollbackPartition(String16 * out_rollback_partition)161 Status BinderUpdateEngineBrilloService::GetRollbackPartition(
162 String16* out_rollback_partition) {
163 string partition_string;
164 auto ret = CallCommonHandler(&UpdateEngineService::GetRollbackPartition,
165 &partition_string);
166
167 if (ret.isOk()) {
168 *out_rollback_partition = String16(partition_string.c_str());
169 }
170
171 return ret;
172 }
173
RegisterStatusCallback(const sp<IUpdateEngineStatusCallback> & callback)174 Status BinderUpdateEngineBrilloService::RegisterStatusCallback(
175 const sp<IUpdateEngineStatusCallback>& callback) {
176 callbacks_.emplace_back(callback);
177
178 auto binder_wrapper = android::BinderWrapper::Get();
179
180 binder_wrapper->RegisterForDeathNotifications(
181 IUpdateEngineStatusCallback::asBinder(callback),
182 base::Bind(&BinderUpdateEngineBrilloService::UnregisterStatusCallback,
183 base::Unretained(this),
184 base::Unretained(callback.get())));
185
186 return Status::ok();
187 }
188
GetLastAttemptError(int * out_last_attempt_error)189 Status BinderUpdateEngineBrilloService::GetLastAttemptError(
190 int* out_last_attempt_error) {
191 return CallCommonHandler(&UpdateEngineService::GetLastAttemptError,
192 out_last_attempt_error);
193 }
194
UnregisterStatusCallback(IUpdateEngineStatusCallback * callback)195 void BinderUpdateEngineBrilloService::UnregisterStatusCallback(
196 IUpdateEngineStatusCallback* callback) {
197 auto it = callbacks_.begin();
198
199 for (; it != callbacks_.end() && it->get() != callback; it++)
200 ;
201
202 if (it == callbacks_.end()) {
203 LOG(ERROR) << "Got death notification for unknown callback.";
204 return;
205 }
206
207 LOG(INFO) << "Erasing orphan callback";
208 callbacks_.erase(it);
209 }
210
SendStatusUpdate(int64_t last_checked_time,double progress,update_engine::UpdateStatus status,const string & new_version,int64_t new_size)211 void BinderUpdateEngineBrilloService::SendStatusUpdate(
212 int64_t last_checked_time,
213 double progress,
214 update_engine::UpdateStatus status,
215 const string& new_version,
216 int64_t new_size) {
217 const string str_status = UpdateStatusToString(status);
218 for (auto& callback : callbacks_) {
219 callback->HandleStatusUpdate(last_checked_time,
220 progress,
221 String16{str_status.c_str()},
222 String16{new_version.c_str()},
223 new_size);
224 }
225 }
226
227 } // namespace chromeos_update_engine
228