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