1 /*
2 * Copyright (C) 2018 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 "apexservice.h"
18
19 #include <dirent.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22
23 #include <android-base/file.h>
24 #include <android-base/logging.h>
25 #include <android-base/properties.h>
26 #include <android-base/result.h>
27 #include <android-base/stringprintf.h>
28 #include <android-base/strings.h>
29 #include <binder/IPCThreadState.h>
30 #include <binder/IResultReceiver.h>
31 #include <binder/IServiceManager.h>
32 #include <binder/LazyServiceRegistrar.h>
33 #include <binder/ProcessState.h>
34 #include <binder/Status.h>
35 #include <private/android_filesystem_config.h>
36 #include <utils/String16.h>
37
38 #include "apex_file.h"
39 #include "apex_file_repository.h"
40 #include "apexd.h"
41 #include "apexd_session.h"
42 #include "string_log.h"
43
44 #include <android/apex/BnApexService.h>
45
46 using android::base::Join;
47 using android::base::Result;
48
49 namespace android {
50 namespace apex {
51 namespace binder {
52 namespace {
53
54 using BinderStatus = ::android::binder::Status;
55
CheckCallerIsRoot(const std::string & name)56 BinderStatus CheckCallerIsRoot(const std::string& name) {
57 uid_t uid = IPCThreadState::self()->getCallingUid();
58 if (uid != AID_ROOT) {
59 std::string msg = "Only root is allowed to call " + name;
60 return BinderStatus::fromExceptionCode(BinderStatus::EX_SECURITY,
61 String8(name.c_str()));
62 }
63 return BinderStatus::ok();
64 }
65
66 class ApexService : public BnApexService {
67 public:
68 using BinderStatus = ::android::binder::Status;
69 using SessionState = ::apex::proto::SessionState;
70
ApexService()71 ApexService(){};
72
73 BinderStatus stagePackages(const std::vector<std::string>& paths) override;
74 BinderStatus unstagePackages(const std::vector<std::string>& paths) override;
75 BinderStatus submitStagedSession(const ApexSessionParams& params,
76 ApexInfoList* apex_info_list) override;
77 BinderStatus markStagedSessionReady(int session_id) override;
78 BinderStatus markStagedSessionSuccessful(int session_id) override;
79 BinderStatus getSessions(std::vector<ApexSessionInfo>* aidl_return) override;
80 BinderStatus getStagedSessionInfo(
81 int session_id, ApexSessionInfo* apex_session_info) override;
82 BinderStatus activatePackage(const std::string& package_path) override;
83 BinderStatus deactivatePackage(const std::string& package_path) override;
84 BinderStatus getActivePackages(std::vector<ApexInfo>* aidl_return) override;
85 BinderStatus getActivePackage(const std::string& package_name,
86 ApexInfo* aidl_return) override;
87 BinderStatus getAllPackages(std::vector<ApexInfo>* aidl_return) override;
88 BinderStatus preinstallPackages(
89 const std::vector<std::string>& paths) override;
90 BinderStatus postinstallPackages(
91 const std::vector<std::string>& paths) override;
92 BinderStatus abortStagedSession(int session_id) override;
93 BinderStatus revertActiveSessions() override;
94 BinderStatus resumeRevertIfNeeded() override;
95 BinderStatus snapshotCeData(int user_id, int rollback_id,
96 const std::string& apex_name) override;
97 BinderStatus restoreCeData(int user_id, int rollback_id,
98 const std::string& apex_name) override;
99 BinderStatus destroyDeSnapshots(int rollback_id) override;
100 BinderStatus destroyCeSnapshots(int user_id, int rollback_id) override;
101 BinderStatus destroyCeSnapshotsNotSpecified(
102 int user_id, const std::vector<int>& retain_rollback_ids) override;
103 BinderStatus remountPackages() override;
104 BinderStatus recollectPreinstalledData(
105 const std::vector<std::string>& paths) override;
106 BinderStatus recollectDataApex(const std::string& path,
107 const std::string& decompression_dir) override;
108 BinderStatus markBootCompleted() override;
109 BinderStatus calculateSizeForCompressedApex(
110 const CompressedApexInfoList& compressed_apex_info_list,
111 int64_t* required_size) override;
112 BinderStatus reserveSpaceForCompressedApex(
113 const CompressedApexInfoList& compressed_apex_info_list) override;
114 BinderStatus installAndActivatePackage(const std::string& package_path,
115 ApexInfo* aidl_return) override;
116
117 status_t dump(int fd, const Vector<String16>& args) override;
118
119 // Override onTransact so we can handle shellCommand.
120 status_t onTransact(uint32_t _aidl_code, const Parcel& _aidl_data,
121 Parcel* _aidl_reply, uint32_t _aidl_flags) override;
122
123 status_t shellCommand(int in, int out, int err, const Vector<String16>& args);
124 };
125
CheckDebuggable(const std::string & name)126 BinderStatus CheckDebuggable(const std::string& name) {
127 if (!::android::base::GetBoolProperty("ro.debuggable", false)) {
128 std::string tmp = name + " unavailable";
129 return BinderStatus::fromExceptionCode(BinderStatus::EX_SECURITY,
130 String8(tmp.c_str()));
131 }
132 return BinderStatus::ok();
133 }
134
stagePackages(const std::vector<std::string> & paths)135 BinderStatus ApexService::stagePackages(const std::vector<std::string>& paths) {
136 BinderStatus debug_check = CheckDebuggable("stagePackages");
137 if (!debug_check.isOk()) {
138 return debug_check;
139 }
140 LOG(DEBUG) << "stagePackages() received by ApexService, paths "
141 << android::base::Join(paths, ',');
142
143 Result<void> res = ::android::apex::StagePackages(paths);
144
145 if (res.ok()) {
146 return BinderStatus::ok();
147 }
148
149 LOG(ERROR) << "Failed to stage " << android::base::Join(paths, ',') << ": "
150 << res.error();
151 return BinderStatus::fromExceptionCode(
152 BinderStatus::EX_SERVICE_SPECIFIC,
153 String8(res.error().message().c_str()));
154 }
155
unstagePackages(const std::vector<std::string> & paths)156 BinderStatus ApexService::unstagePackages(
157 const std::vector<std::string>& paths) {
158 Result<void> res = ::android::apex::UnstagePackages(paths);
159 if (res.ok()) {
160 return BinderStatus::ok();
161 }
162
163 LOG(ERROR) << "Failed to unstage " << android::base::Join(paths, ',') << ": "
164 << res.error();
165 return BinderStatus::fromExceptionCode(
166 BinderStatus::EX_SERVICE_SPECIFIC,
167 String8(res.error().message().c_str()));
168 }
169
submitStagedSession(const ApexSessionParams & params,ApexInfoList * apex_info_list)170 BinderStatus ApexService::submitStagedSession(const ApexSessionParams& params,
171 ApexInfoList* apex_info_list) {
172 LOG(DEBUG) << "submitStagedSession() received by ApexService, session id "
173 << params.sessionId << " child sessions: ["
174 << android::base::Join(params.childSessionIds, ',') << "]";
175
176 Result<std::vector<ApexFile>> packages = ::android::apex::SubmitStagedSession(
177 params.sessionId, params.childSessionIds, params.hasRollbackEnabled,
178 params.isRollback, params.rollbackId);
179 if (!packages.ok()) {
180 LOG(ERROR) << "Failed to submit session id " << params.sessionId << ": "
181 << packages.error();
182 return BinderStatus::fromExceptionCode(
183 BinderStatus::EX_SERVICE_SPECIFIC,
184 String8(packages.error().message().c_str()));
185 }
186
187 for (const auto& package : *packages) {
188 ApexInfo out;
189 out.moduleName = package.GetManifest().name();
190 out.modulePath = package.GetPath();
191 out.versionCode = package.GetManifest().version();
192 apex_info_list->apexInfos.push_back(out);
193 }
194 return BinderStatus::ok();
195 }
196
markStagedSessionReady(int session_id)197 BinderStatus ApexService::markStagedSessionReady(int session_id) {
198 LOG(DEBUG) << "markStagedSessionReady() received by ApexService, session id "
199 << session_id;
200 Result<void> success = ::android::apex::MarkStagedSessionReady(session_id);
201 if (!success.ok()) {
202 LOG(ERROR) << "Failed to mark session id " << session_id
203 << " as ready: " << success.error();
204 return BinderStatus::fromExceptionCode(
205 BinderStatus::EX_SERVICE_SPECIFIC,
206 String8(success.error().message().c_str()));
207 }
208 return BinderStatus::ok();
209 }
210
markStagedSessionSuccessful(int session_id)211 BinderStatus ApexService::markStagedSessionSuccessful(int session_id) {
212 LOG(DEBUG)
213 << "markStagedSessionSuccessful() received by ApexService, session id "
214 << session_id;
215 Result<void> ret = ::android::apex::MarkStagedSessionSuccessful(session_id);
216 if (!ret.ok()) {
217 LOG(ERROR) << "Failed to mark session " << session_id
218 << " as SUCCESS: " << ret.error();
219 return BinderStatus::fromExceptionCode(
220 BinderStatus::EX_ILLEGAL_ARGUMENT,
221 String8(ret.error().message().c_str()));
222 }
223 return BinderStatus::ok();
224 }
225
markBootCompleted()226 BinderStatus ApexService::markBootCompleted() {
227 ::android::apex::OnBootCompleted();
228 return BinderStatus::ok();
229 }
230
calculateSizeForCompressedApex(const CompressedApexInfoList & compressed_apex_info_list,int64_t * required_size)231 BinderStatus ApexService::calculateSizeForCompressedApex(
232 const CompressedApexInfoList& compressed_apex_info_list,
233 int64_t* required_size) {
234 *required_size = 0;
235 const auto& instance = ApexFileRepository::GetInstance();
236 for (const auto& apex_info : compressed_apex_info_list.apexInfos) {
237 auto should_allocate_space = ShouldAllocateSpaceForDecompression(
238 apex_info.moduleName, apex_info.versionCode, instance);
239 if (!should_allocate_space.ok() || *should_allocate_space) {
240 *required_size += apex_info.decompressedSize;
241 }
242 }
243 return BinderStatus::ok();
244 }
245
reserveSpaceForCompressedApex(const CompressedApexInfoList & compressed_apex_info_list)246 BinderStatus ApexService::reserveSpaceForCompressedApex(
247 const CompressedApexInfoList& compressed_apex_info_list) {
248 int64_t required_size;
249 if (auto res = calculateSizeForCompressedApex(compressed_apex_info_list,
250 &required_size);
251 !res.isOk()) {
252 return res;
253 }
254 if (auto res = ReserveSpaceForCompressedApex(required_size, kOtaReservedDir);
255 !res.ok()) {
256 return BinderStatus::fromExceptionCode(
257 BinderStatus::EX_SERVICE_SPECIFIC,
258 String8(res.error().message().c_str()));
259 }
260 return BinderStatus::ok();
261 }
262
ClearSessionInfo(ApexSessionInfo * session_info)263 static void ClearSessionInfo(ApexSessionInfo* session_info) {
264 session_info->sessionId = -1;
265 session_info->isUnknown = false;
266 session_info->isVerified = false;
267 session_info->isStaged = false;
268 session_info->isActivated = false;
269 session_info->isRevertInProgress = false;
270 session_info->isActivationFailed = false;
271 session_info->isSuccess = false;
272 session_info->isReverted = false;
273 session_info->isRevertFailed = false;
274 }
275
ConvertToApexSessionInfo(const ApexSession & session,ApexSessionInfo * session_info)276 void ConvertToApexSessionInfo(const ApexSession& session,
277 ApexSessionInfo* session_info) {
278 using SessionState = ::apex::proto::SessionState;
279
280 ClearSessionInfo(session_info);
281 session_info->sessionId = session.GetId();
282 session_info->crashingNativeProcess = session.GetCrashingNativeProcess();
283 session_info->errorMessage = session.GetErrorMessage();
284
285 switch (session.GetState()) {
286 case SessionState::VERIFIED:
287 session_info->isVerified = true;
288 break;
289 case SessionState::STAGED:
290 session_info->isStaged = true;
291 break;
292 case SessionState::ACTIVATED:
293 session_info->isActivated = true;
294 break;
295 case SessionState::ACTIVATION_FAILED:
296 session_info->isActivationFailed = true;
297 break;
298 case SessionState::SUCCESS:
299 session_info->isSuccess = true;
300 break;
301 case SessionState::REVERT_IN_PROGRESS:
302 session_info->isRevertInProgress = true;
303 break;
304 case SessionState::REVERTED:
305 session_info->isReverted = true;
306 break;
307 case SessionState::REVERT_FAILED:
308 session_info->isRevertFailed = true;
309 break;
310 case SessionState::UNKNOWN:
311 default:
312 session_info->isUnknown = true;
313 break;
314 }
315 }
316
GetApexInfo(const ApexFile & package)317 static ApexInfo GetApexInfo(const ApexFile& package) {
318 auto& instance = ApexFileRepository::GetInstance();
319 ApexInfo out;
320 out.moduleName = package.GetManifest().name();
321 out.modulePath = package.GetPath();
322 out.versionCode = package.GetManifest().version();
323 out.versionName = package.GetManifest().versionname();
324 out.isFactory = instance.IsPreInstalledApex(package);
325 out.isActive = false;
326 Result<std::string> preinstalled_path =
327 instance.GetPreinstalledPath(package.GetManifest().name());
328 if (preinstalled_path.ok()) {
329 out.preinstalledModulePath = *preinstalled_path;
330 }
331 return out;
332 }
333
ToString(const ApexInfo & package)334 static std::string ToString(const ApexInfo& package) {
335 std::string msg = StringLog()
336 << "Module: " << package.moduleName
337 << " Version: " << package.versionCode
338 << " VersionName: " << package.versionName
339 << " Path: " << package.modulePath
340 << " IsActive: " << std::boolalpha << package.isActive
341 << " IsFactory: " << std::boolalpha << package.isFactory
342 << std::endl;
343 return msg;
344 }
345
getSessions(std::vector<ApexSessionInfo> * aidl_return)346 BinderStatus ApexService::getSessions(
347 std::vector<ApexSessionInfo>* aidl_return) {
348 auto sessions = ApexSession::GetSessions();
349 for (const auto& session : sessions) {
350 ApexSessionInfo session_info;
351 ConvertToApexSessionInfo(session, &session_info);
352 aidl_return->push_back(session_info);
353 }
354
355 return BinderStatus::ok();
356 }
357
getStagedSessionInfo(int session_id,ApexSessionInfo * apex_session_info)358 BinderStatus ApexService::getStagedSessionInfo(
359 int session_id, ApexSessionInfo* apex_session_info) {
360 LOG(DEBUG) << "getStagedSessionInfo() received by ApexService, session id "
361 << session_id;
362 auto session = ApexSession::GetSession(session_id);
363 if (!session.ok()) {
364 // Unknown session.
365 ClearSessionInfo(apex_session_info);
366 apex_session_info->isUnknown = true;
367 return BinderStatus::ok();
368 }
369
370 ConvertToApexSessionInfo(*session, apex_session_info);
371
372 return BinderStatus::ok();
373 }
374
activatePackage(const std::string & package_path)375 BinderStatus ApexService::activatePackage(const std::string& package_path) {
376 BinderStatus debug_check = CheckDebuggable("activatePackage");
377 if (!debug_check.isOk()) {
378 return debug_check;
379 }
380
381 LOG(DEBUG) << "activatePackage() received by ApexService, path "
382 << package_path;
383
384 Result<void> res = ::android::apex::ActivatePackage(package_path);
385
386 if (res.ok()) {
387 return BinderStatus::ok();
388 }
389
390 LOG(ERROR) << "Failed to activate " << package_path << ": " << res.error();
391 return BinderStatus::fromExceptionCode(
392 BinderStatus::EX_SERVICE_SPECIFIC,
393 String8(res.error().message().c_str()));
394 }
395
deactivatePackage(const std::string & package_path)396 BinderStatus ApexService::deactivatePackage(const std::string& package_path) {
397 BinderStatus debug_check = CheckDebuggable("deactivatePackage");
398 if (!debug_check.isOk()) {
399 return debug_check;
400 }
401
402 LOG(DEBUG) << "deactivatePackage() received by ApexService, path "
403 << package_path;
404
405 Result<void> res = ::android::apex::DeactivatePackage(package_path);
406
407 if (res.ok()) {
408 return BinderStatus::ok();
409 }
410
411 LOG(ERROR) << "Failed to deactivate " << package_path << ": " << res.error();
412 return BinderStatus::fromExceptionCode(
413 BinderStatus::EX_SERVICE_SPECIFIC,
414 String8(res.error().message().c_str()));
415 }
416
getActivePackages(std::vector<ApexInfo> * aidl_return)417 BinderStatus ApexService::getActivePackages(
418 std::vector<ApexInfo>* aidl_return) {
419 auto packages = ::android::apex::GetActivePackages();
420 for (const auto& package : packages) {
421 ApexInfo apex_info = GetApexInfo(package);
422 apex_info.isActive = true;
423 aidl_return->push_back(std::move(apex_info));
424 }
425
426 return BinderStatus::ok();
427 }
428
getActivePackage(const std::string & package_name,ApexInfo * aidl_return)429 BinderStatus ApexService::getActivePackage(const std::string& package_name,
430 ApexInfo* aidl_return) {
431 Result<ApexFile> apex = ::android::apex::GetActivePackage(package_name);
432 if (apex.ok()) {
433 *aidl_return = GetApexInfo(*apex);
434 aidl_return->isActive = true;
435 }
436 return BinderStatus::ok();
437 }
438
getAllPackages(std::vector<ApexInfo> * aidl_return)439 BinderStatus ApexService::getAllPackages(std::vector<ApexInfo>* aidl_return) {
440 const auto& active = ::android::apex::GetActivePackages();
441 const auto& factory = ::android::apex::GetFactoryPackages();
442 for (const ApexFile& pkg : active) {
443 ApexInfo apex_info = GetApexInfo(pkg);
444 apex_info.isActive = true;
445 aidl_return->push_back(std::move(apex_info));
446 }
447 for (const ApexFile& pkg : factory) {
448 const auto& same_path = [&pkg](const auto& o) {
449 return o.GetPath() == pkg.GetPath();
450 };
451 if (std::find_if(active.begin(), active.end(), same_path) == active.end()) {
452 aidl_return->push_back(GetApexInfo(pkg));
453 }
454 }
455 return BinderStatus::ok();
456 }
457
installAndActivatePackage(const std::string & package_path,ApexInfo * aidl_return)458 BinderStatus ApexService::installAndActivatePackage(
459 const std::string& package_path, ApexInfo* aidl_return) {
460 LOG(DEBUG) << "installAndActivatePackage() received by ApexService, path: "
461 << package_path;
462 auto res = InstallPackage(package_path);
463 if (!res.ok()) {
464 LOG(ERROR) << "Failed to install package " << package_path << " : "
465 << res.error();
466 return BinderStatus::fromExceptionCode(
467 BinderStatus::EX_SERVICE_SPECIFIC,
468 String8(res.error().message().c_str()));
469 }
470 *aidl_return = GetApexInfo(*res);
471 aidl_return->isActive = true;
472 return BinderStatus::ok();
473 }
474
preinstallPackages(const std::vector<std::string> & paths)475 BinderStatus ApexService::preinstallPackages(
476 const std::vector<std::string>& paths) {
477 BinderStatus debug_check = CheckDebuggable("preinstallPackages");
478 if (!debug_check.isOk()) {
479 return debug_check;
480 }
481
482 Result<void> res = ::android::apex::PreinstallPackages(paths);
483 if (res.ok()) {
484 return BinderStatus::ok();
485 }
486
487 LOG(ERROR) << "Failed to preinstall packages "
488 << android::base::Join(paths, ',') << ": " << res.error();
489 return BinderStatus::fromExceptionCode(
490 BinderStatus::EX_SERVICE_SPECIFIC,
491 String8(res.error().message().c_str()));
492 }
493
postinstallPackages(const std::vector<std::string> & paths)494 BinderStatus ApexService::postinstallPackages(
495 const std::vector<std::string>& paths) {
496 BinderStatus debug_check = CheckDebuggable("postinstallPackages");
497 if (!debug_check.isOk()) {
498 return debug_check;
499 }
500
501 Result<void> res = ::android::apex::PostinstallPackages(paths);
502 if (res.ok()) {
503 return BinderStatus::ok();
504 }
505
506 LOG(ERROR) << "Failed to postinstall packages "
507 << android::base::Join(paths, ',') << ": " << res.error();
508 return BinderStatus::fromExceptionCode(
509 BinderStatus::EX_SERVICE_SPECIFIC,
510 String8(res.error().message().c_str()));
511 }
512
abortStagedSession(int session_id)513 BinderStatus ApexService::abortStagedSession(int session_id) {
514 LOG(DEBUG) << "abortStagedSession() received by ApexService.";
515 Result<void> res = ::android::apex::AbortStagedSession(session_id);
516 if (!res.ok()) {
517 return BinderStatus::fromExceptionCode(
518 BinderStatus::EX_ILLEGAL_ARGUMENT,
519 String8(res.error().message().c_str()));
520 }
521 return BinderStatus::ok();
522 }
523
revertActiveSessions()524 BinderStatus ApexService::revertActiveSessions() {
525 LOG(DEBUG) << "revertActiveSessions() received by ApexService.";
526 Result<void> res = ::android::apex::RevertActiveSessions("", "");
527 if (!res.ok()) {
528 return BinderStatus::fromExceptionCode(
529 BinderStatus::EX_ILLEGAL_ARGUMENT,
530 String8(res.error().message().c_str()));
531 }
532 return BinderStatus::ok();
533 }
534
resumeRevertIfNeeded()535 BinderStatus ApexService::resumeRevertIfNeeded() {
536 BinderStatus debug_check = CheckDebuggable("resumeRevertIfNeeded");
537 if (!debug_check.isOk()) {
538 return debug_check;
539 }
540
541 LOG(DEBUG) << "resumeRevertIfNeeded() received by ApexService.";
542 Result<void> res = ::android::apex::ResumeRevertIfNeeded();
543 if (!res.ok()) {
544 return BinderStatus::fromExceptionCode(
545 BinderStatus::EX_ILLEGAL_ARGUMENT,
546 String8(res.error().message().c_str()));
547 }
548 return BinderStatus::ok();
549 }
550
snapshotCeData(int user_id,int rollback_id,const std::string & apex_name)551 BinderStatus ApexService::snapshotCeData(int user_id, int rollback_id,
552 const std::string& apex_name) {
553 LOG(DEBUG) << "snapshotCeData() received by ApexService.";
554 Result<void> res =
555 ::android::apex::SnapshotCeData(user_id, rollback_id, apex_name);
556 if (!res.ok()) {
557 return BinderStatus::fromExceptionCode(
558 BinderStatus::EX_SERVICE_SPECIFIC,
559 String8(res.error().message().c_str()));
560 }
561 return BinderStatus::ok();
562 }
563
restoreCeData(int user_id,int rollback_id,const std::string & apex_name)564 BinderStatus ApexService::restoreCeData(int user_id, int rollback_id,
565 const std::string& apex_name) {
566 LOG(DEBUG) << "restoreCeData() received by ApexService.";
567 Result<void> res =
568 ::android::apex::RestoreCeData(user_id, rollback_id, apex_name);
569 if (!res.ok()) {
570 return BinderStatus::fromExceptionCode(
571 BinderStatus::EX_SERVICE_SPECIFIC,
572 String8(res.error().message().c_str()));
573 }
574 return BinderStatus::ok();
575 }
576
destroyDeSnapshots(int rollback_id)577 BinderStatus ApexService::destroyDeSnapshots(int rollback_id) {
578 LOG(DEBUG) << "destroyDeSnapshots() received by ApexService.";
579 Result<void> res = ::android::apex::DestroyDeSnapshots(rollback_id);
580 if (!res.ok()) {
581 return BinderStatus::fromExceptionCode(
582 BinderStatus::EX_SERVICE_SPECIFIC,
583 String8(res.error().message().c_str()));
584 }
585 return BinderStatus::ok();
586 }
587
destroyCeSnapshots(int user_id,int rollback_id)588 BinderStatus ApexService::destroyCeSnapshots(int user_id, int rollback_id) {
589 LOG(DEBUG) << "destroyCeSnapshots() received by ApexService.";
590 Result<void> res = ::android::apex::DestroyCeSnapshots(user_id, rollback_id);
591 if (!res.ok()) {
592 return BinderStatus::fromExceptionCode(
593 BinderStatus::EX_SERVICE_SPECIFIC,
594 String8(res.error().message().c_str()));
595 }
596 return BinderStatus::ok();
597 }
598
destroyCeSnapshotsNotSpecified(int user_id,const std::vector<int> & retain_rollback_ids)599 BinderStatus ApexService::destroyCeSnapshotsNotSpecified(
600 int user_id, const std::vector<int>& retain_rollback_ids) {
601 LOG(DEBUG) << "destroyCeSnapshotsNotSpecified() received by ApexService.";
602 Result<void> res = ::android::apex::DestroyCeSnapshotsNotSpecified(
603 user_id, retain_rollback_ids);
604 if (!res.ok()) {
605 return BinderStatus::fromExceptionCode(
606 BinderStatus::EX_SERVICE_SPECIFIC,
607 String8(res.error().message().c_str()));
608 }
609 return BinderStatus::ok();
610 }
611
remountPackages()612 BinderStatus ApexService::remountPackages() {
613 LOG(DEBUG) << "remountPackages() received by ApexService";
614 if (auto debug = CheckDebuggable("remountPackages"); !debug.isOk()) {
615 return debug;
616 }
617 if (auto root = CheckCallerIsRoot("remountPackages"); !root.isOk()) {
618 return root;
619 }
620 if (auto res = ::android::apex::RemountPackages(); !res.ok()) {
621 return BinderStatus::fromExceptionCode(
622 BinderStatus::EX_SERVICE_SPECIFIC,
623 String8(res.error().message().c_str()));
624 }
625 return BinderStatus::ok();
626 }
627
recollectPreinstalledData(const std::vector<std::string> & paths)628 BinderStatus ApexService::recollectPreinstalledData(
629 const std::vector<std::string>& paths) {
630 LOG(DEBUG) << "recollectPreinstalledData() received by ApexService, paths: "
631 << Join(paths, ',');
632 if (auto debug = CheckDebuggable("recollectPreinstalledData");
633 !debug.isOk()) {
634 return debug;
635 }
636 if (auto root = CheckCallerIsRoot("recollectPreinstalledData");
637 !root.isOk()) {
638 return root;
639 }
640 ApexFileRepository& instance = ApexFileRepository::GetInstance();
641 if (auto res = instance.AddPreInstalledApex(paths); !res.ok()) {
642 return BinderStatus::fromExceptionCode(
643 BinderStatus::EX_SERVICE_SPECIFIC,
644 String8(res.error().message().c_str()));
645 }
646 return BinderStatus::ok();
647 }
648
recollectDataApex(const std::string & path,const std::string & decompression_dir)649 BinderStatus ApexService::recollectDataApex(
650 const std::string& path, const std::string& decompression_dir) {
651 LOG(DEBUG) << "recollectDataApex() received by ApexService, paths " << path
652 << " and " << decompression_dir;
653 if (auto debug = CheckDebuggable("recollectDataApex"); !debug.isOk()) {
654 return debug;
655 }
656 if (auto root = CheckCallerIsRoot("recollectDataApex"); !root.isOk()) {
657 return root;
658 }
659 ApexFileRepository& instance = ApexFileRepository::GetInstance();
660 if (auto res = instance.AddDataApex(path); !res.ok()) {
661 return BinderStatus::fromExceptionCode(
662 BinderStatus::EX_SERVICE_SPECIFIC,
663 String8(res.error().message().c_str()));
664 }
665 return BinderStatus::ok();
666 }
667
onTransact(uint32_t _aidl_code,const Parcel & _aidl_data,Parcel * _aidl_reply,uint32_t _aidl_flags)668 status_t ApexService::onTransact(uint32_t _aidl_code, const Parcel& _aidl_data,
669 Parcel* _aidl_reply, uint32_t _aidl_flags) {
670 switch (_aidl_code) {
671 case IBinder::SHELL_COMMAND_TRANSACTION: {
672 int in = _aidl_data.readFileDescriptor();
673 int out = _aidl_data.readFileDescriptor();
674 int err = _aidl_data.readFileDescriptor();
675 int argc = _aidl_data.readInt32();
676 Vector<String16> args;
677 for (int i = 0; i < argc && _aidl_data.dataAvail() > 0; i++) {
678 args.add(_aidl_data.readString16());
679 }
680 sp<IBinder> unused_callback;
681 sp<IResultReceiver> result_receiver;
682 status_t status;
683 if ((status = _aidl_data.readNullableStrongBinder(&unused_callback)) !=
684 OK)
685 return status;
686 if ((status = _aidl_data.readNullableStrongBinder(&result_receiver)) !=
687 OK)
688 return status;
689 status = shellCommand(in, out, err, args);
690 if (result_receiver != nullptr) {
691 result_receiver->send(status);
692 }
693 return OK;
694 }
695 }
696 return BnApexService::onTransact(_aidl_code, _aidl_data, _aidl_reply,
697 _aidl_flags);
698 }
dump(int fd,const Vector<String16> &)699 status_t ApexService::dump(int fd, const Vector<String16>& /*args*/) {
700 std::vector<ApexInfo> list;
701 BinderStatus status = getActivePackages(&list);
702 dprintf(fd, "ACTIVE PACKAGES:\n");
703 if (!status.isOk()) {
704 std::string msg = StringLog() << "Failed to retrieve packages: "
705 << status.toString8().string() << std::endl;
706 dprintf(fd, "%s", msg.c_str());
707 return BAD_VALUE;
708 } else {
709 for (const auto& item : list) {
710 std::string msg = ToString(item);
711 dprintf(fd, "%s", msg.c_str());
712 }
713 }
714
715 dprintf(fd, "SESSIONS:\n");
716 std::vector<ApexSession> sessions = ApexSession::GetSessions();
717
718 for (const auto& session : sessions) {
719 std::string child_ids_str = "";
720 auto child_ids = session.GetChildSessionIds();
721 if (child_ids.size() > 0) {
722 child_ids_str = "Child IDs:";
723 for (auto childSessionId : session.GetChildSessionIds()) {
724 child_ids_str += " " + std::to_string(childSessionId);
725 }
726 }
727 std::string revert_reason = "";
728 const auto& crashing_native_process = session.GetCrashingNativeProcess();
729 if (!crashing_native_process.empty()) {
730 revert_reason = " Revert Reason: " + crashing_native_process;
731 }
732 std::string error_message_dump = "";
733 const auto& error_message = session.GetErrorMessage();
734 if (!error_message.empty()) {
735 error_message_dump = " Error Message: " + error_message;
736 }
737 std::string msg =
738 StringLog() << "Session ID: " << session.GetId() << child_ids_str
739 << " State: " << SessionState_State_Name(session.GetState())
740 << revert_reason << error_message_dump << std::endl;
741 dprintf(fd, "%s", msg.c_str());
742 }
743
744 return OK;
745 }
746
shellCommand(int in,int out,int err,const Vector<String16> & args)747 status_t ApexService::shellCommand(int in, int out, int err,
748 const Vector<String16>& args) {
749 if (in == BAD_TYPE || out == BAD_TYPE || err == BAD_TYPE) {
750 return BAD_VALUE;
751 }
752 auto print_help = [](int fd, const char* prefix = nullptr) {
753 StringLog log;
754 if (prefix != nullptr) {
755 log << prefix << std::endl;
756 }
757 log << "ApexService:" << std::endl
758 << " help - display this help" << std::endl
759 << " stagePackages [package_path1] ([package_path2]...) - stage "
760 "multiple packages from the given path"
761 << std::endl
762 << " getActivePackage [package_name] - return info for active package "
763 "with given name, if present"
764 << std::endl
765 << " getAllPackages - return the list of all packages" << std::endl
766 << " getActivePackages - return the list of active packages"
767 << std::endl
768 << " activatePackage [package_path] - activate package from the "
769 "given path"
770 << std::endl
771 << " deactivatePackage [package_path] - deactivate package from the "
772 "given path"
773 << std::endl
774 << " preinstallPackages [package_path1] ([package_path2]...) - run "
775 "pre-install hooks of the given packages"
776 << std::endl
777 << " postinstallPackages [package_path1] ([package_path2]...) - run "
778 "post-install hooks of the given packages"
779 << std::endl
780 << " getStagedSessionInfo [sessionId] - displays information about a "
781 "given session previously submitted"
782 << std::endl
783 << " submitStagedSession [sessionId] - attempts to submit the "
784 "installer session with given id"
785 << std::endl
786 << " remountPackages - Force apexd to remount active packages. This "
787 "call can be used to speed up development workflow of an APEX "
788 "package. Example of usage:\n"
789 " 1. adb shell stop\n"
790 " 2. adb sync\n"
791 " 3. adb shell cmd -w apexservice remountPackages\n"
792 " 4. adb shell start\n"
793 "\n"
794 "Note: APEX package will be successfully remounted only if there "
795 "are no alive processes holding a reference to it"
796 << std::endl;
797 dprintf(fd, "%s", log.operator std::string().c_str());
798 };
799
800 if (args.size() == 0) {
801 print_help(err, "No command given");
802 return BAD_VALUE;
803 }
804
805 const String16& cmd = args[0];
806
807 if (cmd == String16("stagePackages")) {
808 if (args.size() < 2) {
809 print_help(err, "stagePackages requires at least one package_path");
810 return BAD_VALUE;
811 }
812 std::vector<std::string> pkgs;
813 pkgs.reserve(args.size() - 1);
814 for (size_t i = 1; i != args.size(); ++i) {
815 pkgs.emplace_back(String8(args[i]).string());
816 }
817 BinderStatus status = stagePackages(pkgs);
818 if (status.isOk()) {
819 return OK;
820 }
821 std::string msg = StringLog() << "Failed to stage package(s): "
822 << status.toString8().string() << std::endl;
823 dprintf(err, "%s", msg.c_str());
824 return BAD_VALUE;
825 }
826 if (cmd == String16("getAllPackages")) {
827 if (args.size() != 1) {
828 print_help(err, "Unrecognized options");
829 return BAD_VALUE;
830 }
831 std::vector<ApexInfo> list;
832 BinderStatus status = getAllPackages(&list);
833 if (status.isOk()) {
834 for (const auto& item : list) {
835 std::string msg = ToString(item);
836 dprintf(out, "%s", msg.c_str());
837 }
838 return OK;
839 }
840 std::string msg = StringLog() << "Failed to retrieve packages: "
841 << status.toString8().string() << std::endl;
842 dprintf(err, "%s", msg.c_str());
843 return BAD_VALUE;
844 }
845
846 if (cmd == String16("getActivePackages")) {
847 if (args.size() != 1) {
848 print_help(err, "Unrecognized options");
849 return BAD_VALUE;
850 }
851 std::vector<ApexInfo> list;
852 BinderStatus status = getActivePackages(&list);
853 if (status.isOk()) {
854 for (const auto& item : list) {
855 std::string msg = ToString(item);
856 dprintf(out, "%s", msg.c_str());
857 }
858 return OK;
859 }
860 std::string msg = StringLog() << "Failed to retrieve packages: "
861 << status.toString8().string() << std::endl;
862 dprintf(err, "%s", msg.c_str());
863 return BAD_VALUE;
864 }
865
866 if (cmd == String16("getActivePackage")) {
867 if (args.size() != 2) {
868 print_help(err, "Unrecognized options");
869 return BAD_VALUE;
870 }
871
872 ApexInfo package;
873 BinderStatus status = getActivePackage(String8(args[1]).string(), &package);
874 if (status.isOk()) {
875 std::string msg = ToString(package);
876 dprintf(out, "%s", msg.c_str());
877 return OK;
878 }
879
880 std::string msg = StringLog() << "Failed to fetch active package: "
881 << String8(args[1]).string()
882 << ", error: " << status.toString8().string()
883 << std::endl;
884 dprintf(err, "%s", msg.c_str());
885 return BAD_VALUE;
886 }
887
888 if (cmd == String16("activatePackage")) {
889 if (args.size() != 2) {
890 print_help(err, "activatePackage requires one package_path");
891 return BAD_VALUE;
892 }
893 BinderStatus status = activatePackage(String8(args[1]).string());
894 if (status.isOk()) {
895 return OK;
896 }
897 std::string msg = StringLog() << "Failed to activate package: "
898 << status.toString8().string() << std::endl;
899 dprintf(err, "%s", msg.c_str());
900 return BAD_VALUE;
901 }
902
903 if (cmd == String16("deactivatePackage")) {
904 if (args.size() != 2) {
905 print_help(err, "deactivatePackage requires one package_path");
906 return BAD_VALUE;
907 }
908 BinderStatus status = deactivatePackage(String8(args[1]).string());
909 if (status.isOk()) {
910 return OK;
911 }
912 std::string msg = StringLog() << "Failed to deactivate package: "
913 << status.toString8().string() << std::endl;
914 dprintf(err, "%s", msg.c_str());
915 return BAD_VALUE;
916 }
917
918 if (cmd == String16("getStagedSessionInfo")) {
919 if (args.size() != 2) {
920 print_help(err, "getStagedSessionInfo requires one session id");
921 return BAD_VALUE;
922 }
923 int session_id = strtol(String8(args[1]).c_str(), nullptr, 10);
924 if (session_id < 0) {
925 std::string msg = StringLog()
926 << "Failed to parse session id. Must be an integer.";
927 dprintf(err, "%s", msg.c_str());
928 return BAD_VALUE;
929 }
930
931 ApexSessionInfo session_info;
932 BinderStatus status = getStagedSessionInfo(session_id, &session_info);
933 if (status.isOk()) {
934 std::string revert_reason = "";
935 std::string crashing_native_process = session_info.crashingNativeProcess;
936 if (!crashing_native_process.empty()) {
937 revert_reason = " revertReason: " + crashing_native_process;
938 }
939 std::string msg = StringLog()
940 << "session_info: "
941 << " isUnknown: " << session_info.isUnknown
942 << " isVerified: " << session_info.isVerified
943 << " isStaged: " << session_info.isStaged
944 << " isActivated: " << session_info.isActivated
945 << " isActivationFailed: "
946 << session_info.isActivationFailed << revert_reason
947 << std::endl;
948 dprintf(out, "%s", msg.c_str());
949 return OK;
950 }
951 std::string msg = StringLog() << "Failed to query session: "
952 << status.toString8().string() << std::endl;
953 dprintf(err, "%s", msg.c_str());
954 return BAD_VALUE;
955 }
956
957 if (cmd == String16("submitStagedSession")) {
958 if (args.size() != 2) {
959 print_help(err, "submitStagedSession requires one session id");
960 return BAD_VALUE;
961 }
962 int session_id = strtol(String8(args[1]).c_str(), nullptr, 10);
963 if (session_id < 0) {
964 std::string msg = StringLog()
965 << "Failed to parse session id. Must be an integer.";
966 dprintf(err, "%s", msg.c_str());
967 return BAD_VALUE;
968 }
969
970 ApexInfoList list;
971 std::vector<int> empty_child_session_ids;
972 ApexSessionParams params;
973 params.sessionId = session_id;
974 params.childSessionIds = empty_child_session_ids;
975 BinderStatus status = submitStagedSession(params, &list);
976 if (status.isOk()) {
977 for (const auto& item : list.apexInfos) {
978 std::string msg = ToString(item);
979 dprintf(out, "%s", msg.c_str());
980 }
981 return OK;
982 }
983 std::string msg = StringLog() << "Failed to submit session: "
984 << status.toString8().string() << std::endl;
985 dprintf(err, "%s", msg.c_str());
986 return BAD_VALUE;
987 }
988
989 if (cmd == String16("preinstallPackages") ||
990 cmd == String16("postinstallPackages")) {
991 if (args.size() < 2) {
992 print_help(err,
993 "preinstallPackages/postinstallPackages requires at least"
994 " one package_path");
995 return BAD_VALUE;
996 }
997 std::vector<std::string> pkgs;
998 pkgs.reserve(args.size() - 1);
999 for (size_t i = 1; i != args.size(); ++i) {
1000 pkgs.emplace_back(String8(args[i]).string());
1001 }
1002 BinderStatus status = cmd == String16("preinstallPackages")
1003 ? preinstallPackages(pkgs)
1004 : postinstallPackages(pkgs);
1005 if (status.isOk()) {
1006 return OK;
1007 }
1008 std::string msg = StringLog() << "Failed to pre/postinstall package(s): "
1009 << status.toString8().string() << std::endl;
1010 dprintf(err, "%s", msg.c_str());
1011 return BAD_VALUE;
1012 }
1013
1014 if (cmd == String16("remountPackages")) {
1015 BinderStatus status = remountPackages();
1016 if (status.isOk()) {
1017 return OK;
1018 }
1019 std::string msg = StringLog() << "remountPackages failed: "
1020 << status.toString8().string() << std::endl;
1021 dprintf(err, "%s", msg.c_str());
1022 return BAD_VALUE;
1023 }
1024
1025 if (cmd == String16("help")) {
1026 if (args.size() != 1) {
1027 print_help(err, "Help has no options");
1028 return BAD_VALUE;
1029 }
1030 print_help(out);
1031 return OK;
1032 }
1033
1034 print_help(err);
1035 return BAD_VALUE;
1036 }
1037
1038 } // namespace
1039
1040 static constexpr const char* kApexServiceName = "apexservice";
1041
1042 using android::IPCThreadState;
1043 using android::ProcessState;
1044 using android::sp;
1045 using android::binder::LazyServiceRegistrar;
1046
CreateAndRegisterService()1047 void CreateAndRegisterService() {
1048 sp<ProcessState> ps(ProcessState::self());
1049
1050 // Create binder service and register with LazyServiceRegistrar
1051 sp<ApexService> apex_service = sp<ApexService>::make();
1052 auto lazy_registrar = LazyServiceRegistrar::getInstance();
1053 lazy_registrar.forcePersist(true);
1054 lazy_registrar.registerService(apex_service, kApexServiceName);
1055 }
1056
AllowServiceShutdown()1057 void AllowServiceShutdown() {
1058 auto lazy_registrar = LazyServiceRegistrar::getInstance();
1059 lazy_registrar.forcePersist(false);
1060 }
1061
StartThreadPool()1062 void StartThreadPool() {
1063 sp<ProcessState> ps(ProcessState::self());
1064
1065 // Start threadpool, wait for IPC
1066 ps->startThreadPool();
1067 }
1068
JoinThreadPool()1069 void JoinThreadPool() {
1070 IPCThreadState::self()->joinThreadPool(); // should not return
1071 }
1072
1073 } // namespace binder
1074 } // namespace apex
1075 } // namespace android
1076