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