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