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 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 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 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 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 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 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 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 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 226 BinderStatus ApexService::markBootCompleted() { 227 ::android::apex::OnBootCompleted(); 228 return BinderStatus::ok(); 229 } 230 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 } 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 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 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 1057 void AllowServiceShutdown() { 1058 auto lazy_registrar = LazyServiceRegistrar::getInstance(); 1059 lazy_registrar.forcePersist(false); 1060 } 1061 1062 void StartThreadPool() { 1063 sp<ProcessState> ps(ProcessState::self()); 1064 1065 // Start threadpool, wait for IPC 1066 ps->startThreadPool(); 1067 } 1068 1069 void JoinThreadPool() { 1070 IPCThreadState::self()->joinThreadPool(); // should not return 1071 } 1072 1073 } // namespace binder 1074 } // namespace apex 1075 } // namespace android 1076