blob: b8aced60ba5066dcf128fb58f76fe64ac817d9fd [file] [log] [blame]
Martijn Coenene6f6b8f2018-08-17 09:48:33 +02001/*
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
Andreas Gampe66b5dcd2018-10-17 19:20:00 -070017#include "apexservice.h"
18
Dario Freni8e88b682018-10-25 13:06:21 +010019#include <dirent.h>
Dario Freni6ed63322018-10-03 11:37:08 +010020#include <stdio.h>
Dario Freni8e88b682018-10-25 13:06:21 +010021#include <stdlib.h>
Dario Freni6ed63322018-10-03 11:37:08 +010022
Andreas Gampe66b5dcd2018-10-17 19:20:00 -070023#include <android-base/file.h>
24#include <android-base/logging.h>
Andreas Gampe8eb187a2018-10-19 21:18:03 -070025#include <android-base/properties.h>
Mohammad Samiul Islambd6ab0f2019-06-20 15:55:27 +010026#include <android-base/result.h>
Andreas Gampe66b5dcd2018-10-17 19:20:00 -070027#include <android-base/stringprintf.h>
Dario Freni8e88b682018-10-25 13:06:21 +010028#include <android-base/strings.h>
Andreas Gampe602ef782018-11-12 16:51:31 -080029#include <binder/IPCThreadState.h>
Andreas Gampe66b5dcd2018-10-17 19:20:00 -070030#include <binder/IResultReceiver.h>
Andreas Gampe602ef782018-11-12 16:51:31 -080031#include <binder/IServiceManager.h>
Jon Spivack1b840302020-02-06 18:34:30 -080032#include <binder/LazyServiceRegistrar.h>
Andreas Gampe602ef782018-11-12 16:51:31 -080033#include <binder/ProcessState.h>
Andreas Gampe17739142019-01-09 16:00:26 -080034#include <binder/Status.h>
Nikita Ioffe78d2bce2020-05-02 01:28:30 +010035#include <private/android_filesystem_config.h>
Andreas Gampe602ef782018-11-12 16:51:31 -080036#include <utils/String16.h>
Dario Freni6ed63322018-10-03 11:37:08 +010037
Nikita Ioffed49bcd12019-08-30 11:56:52 +010038#include "apex_file.h"
Dario Freni9d576242019-10-13 10:09:32 +010039#include "apex_preinstalled_data.h"
Andreas Gampeb99abdd2018-10-19 19:59:17 -070040#include "apexd.h"
Dario Frenid2437642019-01-11 14:35:23 +000041#include "apexd_session.h"
Jiyong Park9b800482018-12-03 22:16:40 +090042#include "string_log.h"
Dario Freni6ed63322018-10-03 11:37:08 +010043
Andreas Gampe602ef782018-11-12 16:51:31 -080044#include <android/apex/BnApexService.h>
45
Mohammad Samiul Islambd6ab0f2019-06-20 15:55:27 +010046using android::base::Result;
47
Martijn Coenene6f6b8f2018-08-17 09:48:33 +020048namespace android {
49namespace apex {
Andreas Gampe602ef782018-11-12 16:51:31 -080050namespace binder {
51namespace {
Martijn Coenene6f6b8f2018-08-17 09:48:33 +020052
Andreas Gampec9a01e42018-10-22 12:50:19 -070053using BinderStatus = ::android::binder::Status;
54
Nikita Ioffe78d2bce2020-05-02 01:28:30 +010055BinderStatus CheckCallerIsRoot(const std::string& name) {
56 uid_t uid = IPCThreadState::self()->getCallingUid();
57 if (uid != AID_ROOT) {
58 std::string msg = "Only root is allowed to call " + name;
59 return BinderStatus::fromExceptionCode(BinderStatus::EX_SECURITY,
60 String8(name.c_str()));
61 }
62 return BinderStatus::ok();
63}
64
Andreas Gampe602ef782018-11-12 16:51:31 -080065class ApexService : public BnApexService {
66 public:
67 using BinderStatus = ::android::binder::Status;
Martijn Coenen610909b2019-01-18 13:49:38 +010068 using SessionState = ::apex::proto::SessionState;
Andreas Gampe602ef782018-11-12 16:51:31 -080069
70 ApexService(){};
71
Nikita Ioffed90eda02019-07-11 17:56:01 +010072 BinderStatus stagePackages(const std::vector<std::string>& paths) override;
Nikita Ioffe496a4a42019-03-05 16:32:51 +000073 BinderStatus unstagePackages(const std::vector<std::string>& paths) override;
Oli Lan123d9d02019-12-02 14:08:24 +000074 BinderStatus submitStagedSession(const ApexSessionParams& params,
Nikita Ioffe7efdbd72019-07-05 15:46:38 +010075 ApexInfoList* apex_info_list) override;
Nikita Ioffe0c1d4b12019-07-09 20:48:17 +010076 BinderStatus markStagedSessionReady(int session_id) override;
Nikita Ioffea0c0ccb2019-02-12 22:00:41 +000077 BinderStatus markStagedSessionSuccessful(int session_id) override;
Martijn Coenen4d206422019-01-31 15:58:55 +010078 BinderStatus getSessions(std::vector<ApexSessionInfo>* aidl_return) override;
Dario Frenid2437642019-01-11 14:35:23 +000079 BinderStatus getStagedSessionInfo(
80 int session_id, ApexSessionInfo* apex_session_info) override;
Andreas Gampe602ef782018-11-12 16:51:31 -080081 BinderStatus activatePackage(const std::string& packagePath) override;
82 BinderStatus deactivatePackage(const std::string& packagePath) override;
Dario Frenidded6c12018-11-19 16:02:26 +000083 BinderStatus getActivePackages(std::vector<ApexInfo>* aidl_return) override;
Narayan Kamath5ea57782019-01-03 18:17:05 +000084 BinderStatus getActivePackage(const std::string& packageName,
85 ApexInfo* aidl_return) override;
Gavin Corkeryd6ef0302019-03-21 11:52:06 +000086 BinderStatus getAllPackages(std::vector<ApexInfo>* aidl_return) override;
Andreas Gampe17739142019-01-09 16:00:26 -080087 BinderStatus preinstallPackages(
88 const std::vector<std::string>& paths) override;
Andreas Gampef4c7e7c2019-01-14 12:33:34 -080089 BinderStatus postinstallPackages(
90 const std::vector<std::string>& paths) override;
Mohammad Samiul Islam4654f772019-11-20 15:19:07 +000091 BinderStatus abortStagedSession(int session_id) override;
Mohammad Samiul Islam2401ae12019-11-20 17:12:31 +000092 BinderStatus revertActiveSessions() override;
Mohammad Samiul Islamca852e32019-11-20 13:37:14 +000093 BinderStatus resumeRevertIfNeeded() override;
Oli Lan2d59dfa2020-01-14 20:25:09 +000094 BinderStatus snapshotCeData(int user_id, int rollback_id,
95 const std::string& apex_name,
96 int64_t* _aidl_return) override;
97 BinderStatus restoreCeData(int user_id, int rollback_id,
98 const std::string& apex_name) override;
Oli Lan042fbcf2020-01-17 11:14:16 +000099 BinderStatus destroyDeSnapshots(int rollback_id) override;
Oli Lan2993ccc2020-03-06 18:06:40 +0000100 BinderStatus destroyCeSnapshotsNotSpecified(
101 int user_id, const std::vector<int>& retain_rollback_ids) override;
Nikita Ioffe78d2bce2020-05-02 01:28:30 +0100102 BinderStatus remountPackages() override;
Andreas Gampe17739142019-01-09 16:00:26 -0800103
Abhijeet Kaur54695d32019-01-15 13:07:20 +0000104 status_t dump(int fd, const Vector<String16>& args) override;
Andreas Gampe602ef782018-11-12 16:51:31 -0800105
106 // Override onTransact so we can handle shellCommand.
107 status_t onTransact(uint32_t _aidl_code, const Parcel& _aidl_data,
Nikita Ioffe6bea4e52019-02-10 22:46:05 +0000108 Parcel* _aidl_reply, uint32_t _aidl_flags) override;
Andreas Gampe602ef782018-11-12 16:51:31 -0800109
110 status_t shellCommand(int in, int out, int err, const Vector<String16>& args);
111};
Andreas Gampe8eb187a2018-10-19 21:18:03 -0700112
Andreas Gamped6c3df82018-11-08 15:34:06 -0800113BinderStatus CheckDebuggable(const std::string& name) {
Andreas Gampe8eb187a2018-10-19 21:18:03 -0700114 if (!::android::base::GetBoolProperty("ro.debuggable", false)) {
Andreas Gamped6c3df82018-11-08 15:34:06 -0800115 std::string tmp = name + " unavailable";
116 return BinderStatus::fromExceptionCode(BinderStatus::EX_SECURITY,
117 String8(tmp.c_str()));
Andreas Gampe8eb187a2018-10-19 21:18:03 -0700118 }
119 return BinderStatus::ok();
120}
121
Nikita Ioffed90eda02019-07-11 17:56:01 +0100122BinderStatus ApexService::stagePackages(const std::vector<std::string>& paths) {
Nikita Ioffe69309882019-02-13 01:31:15 +0000123 BinderStatus debugCheck = CheckDebuggable("stagePackages");
124 if (!debugCheck.isOk()) {
125 return debugCheck;
126 }
Andreas Gampea00c5452018-12-10 13:38:33 -0800127 LOG(DEBUG) << "stagePackages() received by ApexService, paths "
128 << android::base::Join(paths, ',');
Dario Freni6ed63322018-10-03 11:37:08 +0100129
Mohammad Samiul Islambd6ab0f2019-06-20 15:55:27 +0100130 Result<void> res = ::android::apex::stagePackages(paths);
Dario Freni6ed63322018-10-03 11:37:08 +0100131
Bernie Innocentid04d5d02020-02-06 22:01:51 +0900132 if (res.ok()) {
Andreas Gampec9a01e42018-10-22 12:50:19 -0700133 return BinderStatus::ok();
Dario Freni6ed63322018-10-03 11:37:08 +0100134 }
Dario Freni6ed63322018-10-03 11:37:08 +0100135
Andreas Gampeb99abdd2018-10-19 19:59:17 -0700136 // TODO: Get correct binder error status.
Andreas Gampea00c5452018-12-10 13:38:33 -0800137 LOG(ERROR) << "Failed to stage " << android::base::Join(paths, ',') << ": "
Mohammad Samiul Islambd6ab0f2019-06-20 15:55:27 +0100138 << res.error();
139 return BinderStatus::fromExceptionCode(
140 BinderStatus::EX_ILLEGAL_ARGUMENT,
141 String8(res.error().message().c_str()));
Martijn Coenene6f6b8f2018-08-17 09:48:33 +0200142}
143
Nikita Ioffe496a4a42019-03-05 16:32:51 +0000144BinderStatus ApexService::unstagePackages(
145 const std::vector<std::string>& paths) {
Mohammad Samiul Islambd6ab0f2019-06-20 15:55:27 +0100146 Result<void> res = ::android::apex::unstagePackages(paths);
Bernie Innocentid04d5d02020-02-06 22:01:51 +0900147 if (res.ok()) {
Nikita Ioffe496a4a42019-03-05 16:32:51 +0000148 return BinderStatus::ok();
149 }
150
151 // TODO: Get correct binder error status.
152 LOG(ERROR) << "Failed to unstage " << android::base::Join(paths, ',') << ": "
Mohammad Samiul Islambd6ab0f2019-06-20 15:55:27 +0100153 << res.error();
154 return BinderStatus::fromExceptionCode(
155 BinderStatus::EX_ILLEGAL_ARGUMENT,
156 String8(res.error().message().c_str()));
Nikita Ioffe496a4a42019-03-05 16:32:51 +0000157}
158
Oli Lan123d9d02019-12-02 14:08:24 +0000159BinderStatus ApexService::submitStagedSession(const ApexSessionParams& params,
160 ApexInfoList* apex_info_list) {
Dario Freni56231b42019-01-04 11:58:17 +0000161 LOG(DEBUG) << "submitStagedSession() received by ApexService, session id "
Oli Lan123d9d02019-12-02 14:08:24 +0000162 << params.sessionId << " child sessions: ["
163 << android::base::Join(params.childSessionIds, ',') << "]";
Dario Freni56231b42019-01-04 11:58:17 +0000164
Oli Lan123d9d02019-12-02 14:08:24 +0000165 Result<std::vector<ApexFile>> packages = ::android::apex::submitStagedSession(
166 params.sessionId, params.childSessionIds, params.hasRollbackEnabled,
167 params.isRollback, params.rollbackId);
Bernie Innocentid04d5d02020-02-06 22:01:51 +0900168 if (!packages.ok()) {
Oli Lan123d9d02019-12-02 14:08:24 +0000169 LOG(ERROR) << "Failed to submit session id " << params.sessionId << ": "
Mohammad Samiul Islambd6ab0f2019-06-20 15:55:27 +0100170 << packages.error();
Nikita Ioffe7efdbd72019-07-05 15:46:38 +0100171 return BinderStatus::fromExceptionCode(
172 BinderStatus::EX_SERVICE_SPECIFIC,
173 String8(packages.error().message().c_str()));
Dario Freni56231b42019-01-04 11:58:17 +0000174 }
175
176 for (const auto& package : *packages) {
177 ApexInfo out;
Nikita Ioffe2cb7f8f2019-06-28 15:42:51 +0100178 out.moduleName = package.GetManifest().name();
179 out.modulePath = package.GetPath();
Abhijeet Kaur216e36c2019-01-04 10:15:01 +0000180 out.versionCode = package.GetManifest().version();
Dario Frenia6ad33e2019-01-09 14:35:43 +0000181 apex_info_list->apexInfos.push_back(out);
Dario Freni56231b42019-01-04 11:58:17 +0000182 }
183 return BinderStatus::ok();
184}
185
Nikita Ioffe0c1d4b12019-07-09 20:48:17 +0100186BinderStatus ApexService::markStagedSessionReady(int session_id) {
Dario Frenif36c9622019-01-25 11:30:00 +0000187 LOG(DEBUG) << "markStagedSessionReady() received by ApexService, session id "
188 << session_id;
Mohammad Samiul Islambd6ab0f2019-06-20 15:55:27 +0100189 Result<void> success = ::android::apex::markStagedSessionReady(session_id);
Bernie Innocentid04d5d02020-02-06 22:01:51 +0900190 if (!success.ok()) {
Dario Frenif36c9622019-01-25 11:30:00 +0000191 LOG(ERROR) << "Failed to mark session id " << session_id
Mohammad Samiul Islambd6ab0f2019-06-20 15:55:27 +0100192 << " as ready: " << success.error();
Nikita Ioffe0c1d4b12019-07-09 20:48:17 +0100193 return BinderStatus::fromExceptionCode(
194 BinderStatus::EX_SERVICE_SPECIFIC,
195 String8(success.error().message().c_str()));
Dario Frenif36c9622019-01-25 11:30:00 +0000196 }
Dario Frenif36c9622019-01-25 11:30:00 +0000197 return BinderStatus::ok();
198}
199
Nikita Ioffea0c0ccb2019-02-12 22:00:41 +0000200BinderStatus ApexService::markStagedSessionSuccessful(int session_id) {
201 LOG(DEBUG)
202 << "markStagedSessionSuccessful() received by ApexService, session id "
203 << session_id;
Mohammad Samiul Islambd6ab0f2019-06-20 15:55:27 +0100204 Result<void> ret = ::android::apex::markStagedSessionSuccessful(session_id);
Bernie Innocentid04d5d02020-02-06 22:01:51 +0900205 if (!ret.ok()) {
Nikita Ioffea0c0ccb2019-02-12 22:00:41 +0000206 LOG(ERROR) << "Failed to mark session " << session_id
Mohammad Samiul Islambd6ab0f2019-06-20 15:55:27 +0100207 << " as SUCCESS: " << ret.error();
208 return BinderStatus::fromExceptionCode(
209 BinderStatus::EX_ILLEGAL_ARGUMENT,
210 String8(ret.error().message().c_str()));
Nikita Ioffea0c0ccb2019-02-12 22:00:41 +0000211 }
212 return BinderStatus::ok();
213}
214
Nikita Ioffe9ae986a2019-02-18 22:39:27 +0000215static void ClearSessionInfo(ApexSessionInfo* session_info) {
216 session_info->sessionId = -1;
Martijn Coenen4d206422019-01-31 15:58:55 +0100217 session_info->isUnknown = false;
218 session_info->isVerified = false;
219 session_info->isStaged = false;
220 session_info->isActivated = false;
Mohammad Samiul Islamca852e32019-11-20 13:37:14 +0000221 session_info->isRevertInProgress = false;
Martijn Coenen4d206422019-01-31 15:58:55 +0100222 session_info->isActivationFailed = false;
Nikita Ioffea0c0ccb2019-02-12 22:00:41 +0000223 session_info->isSuccess = false;
Mohammad Samiul Islamca852e32019-11-20 13:37:14 +0000224 session_info->isReverted = false;
225 session_info->isRevertFailed = false;
Nikita Ioffe9ae986a2019-02-18 22:39:27 +0000226}
227
228void convertToApexSessionInfo(const ApexSession& session,
229 ApexSessionInfo* session_info) {
230 using SessionState = ::apex::proto::SessionState;
231
232 ClearSessionInfo(session_info);
233 session_info->sessionId = session.GetId();
Gavin Corkery879fe9b2020-01-29 19:13:50 +0000234 session_info->crashingNativeProcess = session.GetCrashingNativeProcess();
Martijn Coenen4d206422019-01-31 15:58:55 +0100235
236 switch (session.GetState()) {
237 case SessionState::VERIFIED:
238 session_info->isVerified = true;
239 break;
240 case SessionState::STAGED:
241 session_info->isStaged = true;
242 break;
243 case SessionState::ACTIVATED:
244 session_info->isActivated = true;
245 break;
Martijn Coenen4d206422019-01-31 15:58:55 +0100246 case SessionState::ACTIVATION_FAILED:
247 session_info->isActivationFailed = true;
248 break;
Nikita Ioffea0c0ccb2019-02-12 22:00:41 +0000249 case SessionState::SUCCESS:
250 session_info->isSuccess = true;
251 break;
Mohammad Samiul Islamca852e32019-11-20 13:37:14 +0000252 case SessionState::REVERT_IN_PROGRESS:
253 session_info->isRevertInProgress = true;
Nikita Ioffe9ae986a2019-02-18 22:39:27 +0000254 break;
Mohammad Samiul Islamca852e32019-11-20 13:37:14 +0000255 case SessionState::REVERTED:
256 session_info->isReverted = true;
Nikita Ioffe9ae986a2019-02-18 22:39:27 +0000257 break;
Mohammad Samiul Islamca852e32019-11-20 13:37:14 +0000258 case SessionState::REVERT_FAILED:
259 session_info->isRevertFailed = true;
Nikita Ioffe54f18442019-04-09 13:09:26 +0100260 break;
Martijn Coenen4d206422019-01-31 15:58:55 +0100261 case SessionState::UNKNOWN:
262 default:
263 session_info->isUnknown = true;
264 break;
265 }
266}
267
Gavin Corkeryd6ef0302019-03-21 11:52:06 +0000268static ApexInfo getApexInfo(const ApexFile& package) {
269 ApexInfo out;
Nikita Ioffe2cb7f8f2019-06-28 15:42:51 +0100270 out.moduleName = package.GetManifest().name();
271 out.modulePath = package.GetPath();
Gavin Corkeryd6ef0302019-03-21 11:52:06 +0000272 out.versionCode = package.GetManifest().version();
Gavin Corkery94638562019-04-30 10:40:12 +0100273 out.versionName = package.GetManifest().versionname();
Nikita Ioffed49bcd12019-08-30 11:56:52 +0100274 out.isFactory = package.IsBuiltin();
275 out.isActive = false;
Dario Freni9d576242019-10-13 10:09:32 +0100276 Result<std::string> preinstalledPath =
277 getApexPreinstalledPath(package.GetManifest().name());
Bernie Innocentid04d5d02020-02-06 22:01:51 +0900278 if (preinstalledPath.ok()) {
Dario Freni9d576242019-10-13 10:09:32 +0100279 out.preinstalledModulePath = *preinstalledPath;
280 }
Gavin Corkeryd6ef0302019-03-21 11:52:06 +0000281 return out;
282}
283
284static std::string toString(const ApexInfo& package) {
285 std::string msg = StringLog()
Nikita Ioffe2cb7f8f2019-06-28 15:42:51 +0100286 << "Module: " << package.moduleName
Gavin Corkeryd6ef0302019-03-21 11:52:06 +0000287 << " Version: " << package.versionCode
Gavin Corkery94638562019-04-30 10:40:12 +0100288 << " VersionName: " << package.versionName
Nikita Ioffe2cb7f8f2019-06-28 15:42:51 +0100289 << " Path: " << package.modulePath
Gavin Corkeryd6ef0302019-03-21 11:52:06 +0000290 << " IsActive: " << std::boolalpha << package.isActive
291 << " IsFactory: " << std::boolalpha << package.isFactory
292 << std::endl;
293 return msg;
294}
295
Martijn Coenen4d206422019-01-31 15:58:55 +0100296BinderStatus ApexService::getSessions(
297 std::vector<ApexSessionInfo>* aidl_return) {
298 auto sessions = ApexSession::GetSessions();
299 for (const auto& session : sessions) {
300 ApexSessionInfo sessionInfo;
301 convertToApexSessionInfo(session, &sessionInfo);
302 aidl_return->push_back(sessionInfo);
303 }
304
305 return BinderStatus::ok();
306}
307
Dario Frenid2437642019-01-11 14:35:23 +0000308BinderStatus ApexService::getStagedSessionInfo(
309 int session_id, ApexSessionInfo* apex_session_info) {
310 LOG(DEBUG) << "getStagedSessionInfo() received by ApexService, session id "
311 << session_id;
Martijn Coenen610909b2019-01-18 13:49:38 +0100312 auto session = ApexSession::GetSession(session_id);
Bernie Innocentid04d5d02020-02-06 22:01:51 +0900313 if (!session.ok()) {
Dario Frenid2437642019-01-11 14:35:23 +0000314 // Unknown session.
Nikita Ioffe9ae986a2019-02-18 22:39:27 +0000315 ClearSessionInfo(apex_session_info);
Martijn Coenen4d206422019-01-31 15:58:55 +0100316 apex_session_info->isUnknown = true;
Dario Frenid2437642019-01-11 14:35:23 +0000317 return BinderStatus::ok();
318 }
Martijn Coenen4d206422019-01-31 15:58:55 +0100319
320 convertToApexSessionInfo(*session, apex_session_info);
Dario Frenid2437642019-01-11 14:35:23 +0000321
322 return BinderStatus::ok();
323}
324
Dario Freniaf275042018-11-06 16:50:04 +0000325BinderStatus ApexService::activatePackage(const std::string& packagePath) {
Andreas Gamped6c3df82018-11-08 15:34:06 -0800326 BinderStatus debugCheck = CheckDebuggable("activatePackage");
Andreas Gampe8eb187a2018-10-19 21:18:03 -0700327 if (!debugCheck.isOk()) {
328 return debugCheck;
329 }
330
Dario Freniaf275042018-11-06 16:50:04 +0000331 LOG(DEBUG) << "activatePackage() received by ApexService, path "
332 << packagePath;
Andreas Gampe8eb187a2018-10-19 21:18:03 -0700333
Mohammad Samiul Islambd6ab0f2019-06-20 15:55:27 +0100334 Result<void> res = ::android::apex::activatePackage(packagePath);
Andreas Gampe8eb187a2018-10-19 21:18:03 -0700335
Bernie Innocentid04d5d02020-02-06 22:01:51 +0900336 if (res.ok()) {
Andreas Gampe8eb187a2018-10-19 21:18:03 -0700337 return BinderStatus::ok();
338 }
339
340 // TODO: Get correct binder error status.
Mohammad Samiul Islambd6ab0f2019-06-20 15:55:27 +0100341 LOG(ERROR) << "Failed to activate " << packagePath << ": " << res.error();
342 return BinderStatus::fromExceptionCode(
343 BinderStatus::EX_ILLEGAL_ARGUMENT,
344 String8(res.error().message().c_str()));
Andreas Gampe8eb187a2018-10-19 21:18:03 -0700345}
346
Andreas Gamped6c3df82018-11-08 15:34:06 -0800347BinderStatus 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
Mohammad Samiul Islambd6ab0f2019-06-20 15:55:27 +0100356 Result<void> res = ::android::apex::deactivatePackage(packagePath);
Andreas Gamped6c3df82018-11-08 15:34:06 -0800357
Bernie Innocentid04d5d02020-02-06 22:01:51 +0900358 if (res.ok()) {
Andreas Gamped6c3df82018-11-08 15:34:06 -0800359 return BinderStatus::ok();
360 }
361
362 // TODO: Get correct binder error status.
Mohammad Samiul Islambd6ab0f2019-06-20 15:55:27 +0100363 LOG(ERROR) << "Failed to deactivate " << packagePath << ": " << res.error();
364 return BinderStatus::fromExceptionCode(
365 BinderStatus::EX_ILLEGAL_ARGUMENT,
366 String8(res.error().message().c_str()));
Andreas Gamped6c3df82018-11-08 15:34:06 -0800367}
368
Dario Freni8e88b682018-10-25 13:06:21 +0100369BinderStatus ApexService::getActivePackages(
Dario Frenidded6c12018-11-19 16:02:26 +0000370 std::vector<ApexInfo>* aidl_return) {
Narayan Kamath5ea57782019-01-03 18:17:05 +0000371 auto packages = ::android::apex::getActivePackages();
372 for (const auto& package : packages) {
Gavin Corkeryd6ef0302019-03-21 11:52:06 +0000373 ApexInfo apexInfo = getApexInfo(package);
374 apexInfo.isActive = true;
Gavin Corkeryd6ef0302019-03-21 11:52:06 +0000375 aidl_return->push_back(std::move(apexInfo));
Narayan Kamath5ea57782019-01-03 18:17:05 +0000376 }
377
378 return BinderStatus::ok();
379}
380
381BinderStatus ApexService::getActivePackage(const std::string& packageName,
382 ApexInfo* aidl_return) {
Mohammad Samiul Islambd6ab0f2019-06-20 15:55:27 +0100383 Result<ApexFile> apex = ::android::apex::getActivePackage(packageName);
Bernie Innocentid04d5d02020-02-06 22:01:51 +0900384 if (apex.ok()) {
Nikita Ioffed49bcd12019-08-30 11:56:52 +0100385 *aidl_return = getApexInfo(*apex);
Gavin Corkeryd6ef0302019-03-21 11:52:06 +0000386 aidl_return->isActive = true;
Dario Freni8e88b682018-10-25 13:06:21 +0100387 }
388 return BinderStatus::ok();
389}
390
Gavin Corkeryd6ef0302019-03-21 11:52:06 +0000391BinderStatus ApexService::getAllPackages(std::vector<ApexInfo>* aidl_return) {
Nikita Ioffed49bcd12019-08-30 11:56:52 +0100392 const auto& active = ::android::apex::getActivePackages();
393 const auto& factory = ::android::apex::getFactoryPackages();
394 for (const ApexFile& pkg : active) {
395 ApexInfo apex_info = getApexInfo(pkg);
396 apex_info.isActive = true;
397 aidl_return->push_back(std::move(apex_info));
Gavin Corkeryd6ef0302019-03-21 11:52:06 +0000398 }
Nikita Ioffed49bcd12019-08-30 11:56:52 +0100399 for (const ApexFile& pkg : factory) {
400 const auto& same_path = [&pkg](const auto& o) {
401 return o.GetPath() == pkg.GetPath();
402 };
403 if (std::find_if(active.begin(), active.end(), same_path) == active.end()) {
404 aidl_return->push_back(getApexInfo(pkg));
Gavin Corkeryd6ef0302019-03-21 11:52:06 +0000405 }
406 }
407 return BinderStatus::ok();
408}
409
Andreas Gampe17739142019-01-09 16:00:26 -0800410BinderStatus ApexService::preinstallPackages(
411 const std::vector<std::string>& paths) {
412 BinderStatus debugCheck = CheckDebuggable("preinstallPackages");
413 if (!debugCheck.isOk()) {
414 return debugCheck;
415 }
416
Mohammad Samiul Islambd6ab0f2019-06-20 15:55:27 +0100417 Result<void> res = ::android::apex::preinstallPackages(paths);
Bernie Innocentid04d5d02020-02-06 22:01:51 +0900418 if (res.ok()) {
Andreas Gampe17739142019-01-09 16:00:26 -0800419 return BinderStatus::ok();
420 }
421
422 // TODO: Get correct binder error status.
423 LOG(ERROR) << "Failed to preinstall packages "
Mohammad Samiul Islambd6ab0f2019-06-20 15:55:27 +0100424 << android::base::Join(paths, ',') << ": " << res.error();
425 return BinderStatus::fromExceptionCode(
426 BinderStatus::EX_ILLEGAL_ARGUMENT,
427 String8(res.error().message().c_str()));
Andreas Gampe17739142019-01-09 16:00:26 -0800428}
429
Andreas Gampef4c7e7c2019-01-14 12:33:34 -0800430BinderStatus ApexService::postinstallPackages(
431 const std::vector<std::string>& paths) {
432 BinderStatus debugCheck = CheckDebuggable("postinstallPackages");
433 if (!debugCheck.isOk()) {
434 return debugCheck;
435 }
436
Mohammad Samiul Islambd6ab0f2019-06-20 15:55:27 +0100437 Result<void> res = ::android::apex::postinstallPackages(paths);
Bernie Innocentid04d5d02020-02-06 22:01:51 +0900438 if (res.ok()) {
Andreas Gampef4c7e7c2019-01-14 12:33:34 -0800439 return BinderStatus::ok();
440 }
441
442 // TODO: Get correct binder error status.
443 LOG(ERROR) << "Failed to postinstall packages "
Mohammad Samiul Islambd6ab0f2019-06-20 15:55:27 +0100444 << android::base::Join(paths, ',') << ": " << res.error();
445 return BinderStatus::fromExceptionCode(
446 BinderStatus::EX_ILLEGAL_ARGUMENT,
447 String8(res.error().message().c_str()));
Andreas Gampef4c7e7c2019-01-14 12:33:34 -0800448}
449
Mohammad Samiul Islam4654f772019-11-20 15:19:07 +0000450BinderStatus ApexService::abortStagedSession(int session_id) {
451 LOG(DEBUG) << "abortStagedSession() received by ApexService.";
452 Result<void> res = ::android::apex::abortStagedSession(session_id);
Bernie Innocentid04d5d02020-02-06 22:01:51 +0900453 if (!res.ok()) {
Mohammad Samiul Islam4654f772019-11-20 15:19:07 +0000454 return BinderStatus::fromExceptionCode(
455 BinderStatus::EX_ILLEGAL_ARGUMENT,
456 String8(res.error().message().c_str()));
457 }
458 return BinderStatus::ok();
459}
460
Mohammad Samiul Islam2401ae12019-11-20 17:12:31 +0000461BinderStatus ApexService::revertActiveSessions() {
462 LOG(DEBUG) << "revertActiveSessions() received by ApexService.";
Gavin Corkery92cd7b82020-01-13 12:35:38 +0000463 Result<void> res = ::android::apex::revertActiveSessions("");
Bernie Innocentid04d5d02020-02-06 22:01:51 +0900464 if (!res.ok()) {
Mohammad Samiul Islambd6ab0f2019-06-20 15:55:27 +0100465 return BinderStatus::fromExceptionCode(
466 BinderStatus::EX_ILLEGAL_ARGUMENT,
467 String8(res.error().message().c_str()));
Andreas Gampe6e13ff82019-04-01 15:23:50 -0700468 }
469 return BinderStatus::ok();
470}
471
Mohammad Samiul Islamca852e32019-11-20 13:37:14 +0000472BinderStatus ApexService::resumeRevertIfNeeded() {
473 BinderStatus debugCheck = CheckDebuggable("resumeRevertIfNeeded");
Andreas Gampe6e13ff82019-04-01 15:23:50 -0700474 if (!debugCheck.isOk()) {
475 return debugCheck;
476 }
477
Mohammad Samiul Islamca852e32019-11-20 13:37:14 +0000478 LOG(DEBUG) << "resumeRevertIfNeeded() received by ApexService.";
479 Result<void> res = ::android::apex::resumeRevertIfNeeded();
Bernie Innocentid04d5d02020-02-06 22:01:51 +0900480 if (!res.ok()) {
Mohammad Samiul Islambd6ab0f2019-06-20 15:55:27 +0100481 return BinderStatus::fromExceptionCode(
482 BinderStatus::EX_ILLEGAL_ARGUMENT,
483 String8(res.error().message().c_str()));
Andreas Gampe6e13ff82019-04-01 15:23:50 -0700484 }
485 return BinderStatus::ok();
486}
487
Oli Lan2d59dfa2020-01-14 20:25:09 +0000488BinderStatus ApexService::snapshotCeData(int user_id, int rollback_id,
489 const std::string& apex_name,
490 int64_t* _aidl_return) {
491 LOG(DEBUG) << "snapshotCeData() received by ApexService.";
492 Result<ino_t> res =
493 ::android::apex::snapshotCeData(user_id, rollback_id, apex_name);
Bernie Innocenti0ca7c922020-03-05 21:46:34 +0900494 if (!res.ok()) {
Oli Lan2d59dfa2020-01-14 20:25:09 +0000495 return BinderStatus::fromExceptionCode(
496 BinderStatus::EX_SERVICE_SPECIFIC,
497 String8(res.error().message().c_str()));
498 }
499 *_aidl_return = static_cast<uint64_t>(*res);
500 return BinderStatus::ok();
501}
502
503BinderStatus ApexService::restoreCeData(int user_id, int rollback_id,
504 const std::string& apex_name) {
505 LOG(DEBUG) << "restoreCeData() received by ApexService.";
506 Result<void> res =
507 ::android::apex::restoreCeData(user_id, rollback_id, apex_name);
Bernie Innocenti0ca7c922020-03-05 21:46:34 +0900508 if (!res.ok()) {
Oli Lan2d59dfa2020-01-14 20:25:09 +0000509 return BinderStatus::fromExceptionCode(
510 BinderStatus::EX_SERVICE_SPECIFIC,
511 String8(res.error().message().c_str()));
512 }
513 return BinderStatus::ok();
514}
515
Oli Lan042fbcf2020-01-17 11:14:16 +0000516BinderStatus ApexService::destroyDeSnapshots(int rollback_id) {
517 LOG(DEBUG) << "destroyDeSnapshots() received by ApexService.";
518 Result<void> res = ::android::apex::destroyDeSnapshots(rollback_id);
519 if (!res) {
520 return BinderStatus::fromExceptionCode(
521 BinderStatus::EX_SERVICE_SPECIFIC,
522 String8(res.error().message().c_str()));
523 }
524 return BinderStatus::ok();
525}
526
Oli Lan2993ccc2020-03-06 18:06:40 +0000527BinderStatus ApexService::destroyCeSnapshotsNotSpecified(
528 int user_id, const std::vector<int>& retain_rollback_ids) {
529 LOG(DEBUG) << "destroyCeSnapshotsNotSpecified() received by ApexService.";
530 Result<void> res = ::android::apex::destroyCeSnapshotsNotSpecified(
531 user_id, retain_rollback_ids);
532 if (!res) {
533 return BinderStatus::fromExceptionCode(
534 BinderStatus::EX_SERVICE_SPECIFIC,
535 String8(res.error().message().c_str()));
536 }
537 return BinderStatus::ok();
538}
539
Nikita Ioffe78d2bce2020-05-02 01:28:30 +0100540BinderStatus ApexService::remountPackages() {
541 LOG(DEBUG) << "remountPackages() received by ApexService";
542 if (auto debug = CheckDebuggable("remountPackages"); !debug.isOk()) {
543 return debug;
544 }
545 if (auto root = CheckCallerIsRoot("remountPackages"); !root.isOk()) {
546 return root;
547 }
548 if (auto res = ::android::apex::remountPackages(); !res.ok()) {
549 return BinderStatus::fromExceptionCode(
550 BinderStatus::EX_SERVICE_SPECIFIC,
551 String8(res.error().message().c_str()));
552 }
553 return BinderStatus::ok();
554}
555
Dario Freni8e88b682018-10-25 13:06:21 +0100556status_t ApexService::onTransact(uint32_t _aidl_code, const Parcel& _aidl_data,
557 Parcel* _aidl_reply, uint32_t _aidl_flags) {
Andreas Gampe66b5dcd2018-10-17 19:20:00 -0700558 switch (_aidl_code) {
559 case IBinder::SHELL_COMMAND_TRANSACTION: {
560 int in = _aidl_data.readFileDescriptor();
561 int out = _aidl_data.readFileDescriptor();
562 int err = _aidl_data.readFileDescriptor();
563 int argc = _aidl_data.readInt32();
564 Vector<String16> args;
565 for (int i = 0; i < argc && _aidl_data.dataAvail() > 0; i++) {
566 args.add(_aidl_data.readString16());
567 }
568 sp<IBinder> unusedCallback;
569 sp<IResultReceiver> resultReceiver;
570 status_t status;
571 if ((status = _aidl_data.readNullableStrongBinder(&unusedCallback)) != OK)
572 return status;
573 if ((status = _aidl_data.readNullableStrongBinder(&resultReceiver)) != OK)
574 return status;
575 status = shellCommand(in, out, err, args);
576 if (resultReceiver != nullptr) {
577 resultReceiver->send(status);
578 }
579 return OK;
580 }
581 }
Dario Freni8e88b682018-10-25 13:06:21 +0100582 return BnApexService::onTransact(_aidl_code, _aidl_data, _aidl_reply,
583 _aidl_flags);
Andreas Gampe66b5dcd2018-10-17 19:20:00 -0700584}
Nikita Ioffe11fa6892019-06-18 05:24:24 +0100585status_t ApexService::dump(int fd, const Vector<String16>& /*args*/) {
Abhijeet Kaur54695d32019-01-15 13:07:20 +0000586 std::vector<ApexInfo> list;
587 BinderStatus status = getActivePackages(&list);
Martijn Coenena418d312019-01-30 12:03:38 +0100588 dprintf(fd, "ACTIVE PACKAGES:\n");
589 if (!status.isOk()) {
590 std::string msg = StringLog() << "Failed to retrieve packages: "
591 << status.toString8().string() << std::endl;
592 dprintf(fd, "%s", msg.c_str());
593 return BAD_VALUE;
594 } else {
Abhijeet Kaur54695d32019-01-15 13:07:20 +0000595 for (const auto& item : list) {
Gavin Corkeryd6ef0302019-03-21 11:52:06 +0000596 std::string msg = toString(item);
Abhijeet Kaur54695d32019-01-15 13:07:20 +0000597 dprintf(fd, "%s", msg.c_str());
598 }
Abhijeet Kaur54695d32019-01-15 13:07:20 +0000599 }
Martijn Coenena418d312019-01-30 12:03:38 +0100600
601 dprintf(fd, "SESSIONS:\n");
602 std::vector<ApexSession> sessions = ApexSession::GetSessions();
603
604 for (const auto& session : sessions) {
605 std::string child_ids_str = "";
606 auto child_ids = session.GetChildSessionIds();
607 if (child_ids.size() > 0) {
608 child_ids_str = "Child IDs:";
609 for (auto childSessionId : session.GetChildSessionIds()) {
610 child_ids_str += " " + std::to_string(childSessionId);
611 }
612 }
Gavin Corkery879fe9b2020-01-29 19:13:50 +0000613 std::string revert_reason = "";
614 std::string crashing_native_process = session.GetCrashingNativeProcess();
615 if (!crashing_native_process.empty()) {
616 revert_reason = " Revert Reason: " + crashing_native_process;
617 }
Martijn Coenena418d312019-01-30 12:03:38 +0100618 std::string msg =
619 StringLog() << "Session ID: " << session.GetId() << child_ids_str
620 << " State: " << SessionState_State_Name(session.GetState())
Gavin Corkery879fe9b2020-01-29 19:13:50 +0000621 << revert_reason << std::endl;
Martijn Coenena418d312019-01-30 12:03:38 +0100622 dprintf(fd, "%s", msg.c_str());
623 }
624
625 return OK;
Abhijeet Kaur54695d32019-01-15 13:07:20 +0000626}
Andreas Gampe66b5dcd2018-10-17 19:20:00 -0700627
Dario Freni8e88b682018-10-25 13:06:21 +0100628status_t ApexService::shellCommand(int in, int out, int err,
629 const Vector<String16>& args) {
Andreas Gampe66b5dcd2018-10-17 19:20:00 -0700630 if (in == BAD_TYPE || out == BAD_TYPE || err == BAD_TYPE) {
631 return BAD_VALUE;
632 }
Andreas Gampee3864802018-12-19 14:12:59 -0800633 auto print_help = [](int fd, const char* prefix = nullptr) {
634 StringLog log;
635 if (prefix != nullptr) {
636 log << prefix << std::endl;
637 }
638 log << "ApexService:" << std::endl
639 << " help - display this help" << std::endl
Dario Freni56231b42019-01-04 11:58:17 +0000640 << " stagePackages [packagePath1] ([packagePath2]...) - stage "
641 "multiple packages from the given path"
642 << std::endl
643 << " getActivePackage [packageName] - return info for active package "
644 "with given name, if present"
645 << std::endl
Gavin Corkeryd6ef0302019-03-21 11:52:06 +0000646 << " getAllPackages - return the list of all packages" << std::endl
Andreas Gampee3864802018-12-19 14:12:59 -0800647 << " getActivePackages - return the list of active packages"
648 << std::endl
649 << " activatePackage [packagePath] - activate package from the "
650 "given path"
651 << std::endl
652 << " deactivatePackage [packagePath] - deactivate package from the "
653 "given path"
Dario Freni56231b42019-01-04 11:58:17 +0000654 << std::endl
Andreas Gampe1a48b1b2019-02-05 16:12:25 -0800655 << " preinstallPackages [packagePath1] ([packagePath2]...) - run "
656 "pre-install hooks of the given packages"
657 << std::endl
658 << " postinstallPackages [packagePath1] ([packagePath2]...) - run "
659 "post-install hooks of the given packages"
660 << std::endl
Dario Frenid2437642019-01-11 14:35:23 +0000661 << " getStagedSessionInfo [sessionId] - displays information about a "
662 "given session previously submitted"
Nikita Ioffe78d2bce2020-05-02 01:28:30 +0100663 << std::endl
Dario Freni56231b42019-01-04 11:58:17 +0000664 << " submitStagedSession [sessionId] - attempts to submit the "
665 "installer session with given id"
Nikita Ioffe78d2bce2020-05-02 01:28:30 +0100666 << std::endl
667 << " remountPackages - Force apexd to remount active packages. This "
668 "call can be used to speed up development workflow of an APEX "
669 "package. Example of usage:\n"
670 " 1. adb shell stop\n"
671 " 2. adb sync\n"
672 " 3. adb shell cmd -w apexservice remountPackages\n"
673 " 4. adb shell start\n"
674 "\n"
675 "Note: APEX package will be successfully remounted only if there "
676 "are no alive processes holding a reference to it"
Andreas Gampee3864802018-12-19 14:12:59 -0800677 << std::endl;
678 dprintf(fd, "%s", log.operator std::string().c_str());
Andreas Gampe66b5dcd2018-10-17 19:20:00 -0700679 };
680
Andreas Gampee3864802018-12-19 14:12:59 -0800681 if (args.size() == 0) {
682 print_help(err, "No command given");
683 return BAD_VALUE;
684 }
685
686 const String16& cmd = args[0];
687
Nikita Ioffe1b01b372019-07-03 16:37:08 +0100688 if (cmd == String16("stagePackages")) {
Andreas Gampe59ec1d92018-12-19 14:43:24 -0800689 if (args.size() < 2) {
Nikita Ioffe1b01b372019-07-03 16:37:08 +0100690 print_help(err, "stagePackages requires at least one packagePath");
Andreas Gampee3864802018-12-19 14:12:59 -0800691 return BAD_VALUE;
692 }
Andreas Gampe59ec1d92018-12-19 14:43:24 -0800693 std::vector<std::string> pkgs;
694 pkgs.reserve(args.size() - 1);
695 for (size_t i = 1; i != args.size(); ++i) {
696 pkgs.emplace_back(String8(args[i]).string());
697 }
Nikita Ioffed90eda02019-07-11 17:56:01 +0100698 BinderStatus status = stagePackages(pkgs);
Andreas Gampe66b5dcd2018-10-17 19:20:00 -0700699 if (status.isOk()) {
700 return OK;
701 }
Andreas Gampe59ec1d92018-12-19 14:43:24 -0800702 std::string msg = StringLog() << "Failed to stage package(s): "
703 << status.toString8().string() << std::endl;
Jiyong Park9b800482018-12-03 22:16:40 +0900704 dprintf(err, "%s", msg.c_str());
Dario Freni8e88b682018-10-25 13:06:21 +0100705 return BAD_VALUE;
706 }
Gavin Corkeryd6ef0302019-03-21 11:52:06 +0000707 if (cmd == String16("getAllPackages")) {
708 if (args.size() != 1) {
709 print_help(err, "Unrecognized options");
710 return BAD_VALUE;
711 }
712 std::vector<ApexInfo> list;
713 BinderStatus status = getAllPackages(&list);
714 if (status.isOk()) {
715 for (const auto& item : list) {
716 std::string msg = toString(item);
717 dprintf(out, "%s", msg.c_str());
718 }
719 return OK;
720 }
721 std::string msg = StringLog() << "Failed to retrieve packages: "
722 << status.toString8().string() << std::endl;
723 dprintf(err, "%s", msg.c_str());
724 return BAD_VALUE;
725 }
Andreas Gampee3864802018-12-19 14:12:59 -0800726
727 if (cmd == String16("getActivePackages")) {
728 if (args.size() != 1) {
729 print_help(err, "Unrecognized options");
730 return BAD_VALUE;
731 }
Dario Frenidded6c12018-11-19 16:02:26 +0000732 std::vector<ApexInfo> list;
Andreas Gampee3864802018-12-19 14:12:59 -0800733 BinderStatus status = getActivePackages(&list);
Dario Freni8e88b682018-10-25 13:06:21 +0100734 if (status.isOk()) {
Chih-Hung Hsieh43bb0232018-12-12 14:30:01 -0800735 for (const auto& item : list) {
Gavin Corkeryd6ef0302019-03-21 11:52:06 +0000736 std::string msg = toString(item);
Jiyong Park9b800482018-12-03 22:16:40 +0900737 dprintf(out, "%s", msg.c_str());
Dario Freni8e88b682018-10-25 13:06:21 +0100738 }
739 return OK;
740 }
Andreas Gampe17739142019-01-09 16:00:26 -0800741 std::string msg = StringLog() << "Failed to retrieve packages: "
742 << status.toString8().string() << std::endl;
Jiyong Park9b800482018-12-03 22:16:40 +0900743 dprintf(err, "%s", msg.c_str());
Andreas Gampe66b5dcd2018-10-17 19:20:00 -0700744 return BAD_VALUE;
745 }
Andreas Gampee3864802018-12-19 14:12:59 -0800746
Narayan Kamath5ea57782019-01-03 18:17:05 +0000747 if (cmd == String16("getActivePackage")) {
748 if (args.size() != 2) {
749 print_help(err, "Unrecognized options");
750 return BAD_VALUE;
751 }
752
753 ApexInfo package;
754 BinderStatus status = getActivePackage(String8(args[1]).string(), &package);
755 if (status.isOk()) {
Gavin Corkeryd6ef0302019-03-21 11:52:06 +0000756 std::string msg = toString(package);
757 dprintf(out, "%s", msg.c_str());
Narayan Kamath5ea57782019-01-03 18:17:05 +0000758 return OK;
759 }
760
761 std::string msg = StringLog() << "Failed to fetch active package: "
762 << String8(args[1]).string()
763 << ", error: " << status.toString8().string()
764 << std::endl;
765 dprintf(err, "%s", msg.c_str());
766 return BAD_VALUE;
767 }
768
Andreas Gampee3864802018-12-19 14:12:59 -0800769 if (cmd == String16("activatePackage")) {
770 if (args.size() != 2) {
771 print_help(err, "activatePackage requires one packagePath");
772 return BAD_VALUE;
773 }
774 BinderStatus status = activatePackage(String8(args[1]).string());
Andreas Gampe8eb187a2018-10-19 21:18:03 -0700775 if (status.isOk()) {
776 return OK;
777 }
Andreas Gampe17739142019-01-09 16:00:26 -0800778 std::string msg = StringLog() << "Failed to activate package: "
779 << status.toString8().string() << std::endl;
Jiyong Park9b800482018-12-03 22:16:40 +0900780 dprintf(err, "%s", msg.c_str());
Andreas Gampe8eb187a2018-10-19 21:18:03 -0700781 return BAD_VALUE;
782 }
Andreas Gampee3864802018-12-19 14:12:59 -0800783
784 if (cmd == String16("deactivatePackage")) {
785 if (args.size() != 2) {
786 print_help(err, "deactivatePackage requires one packagePath");
787 return BAD_VALUE;
788 }
789 BinderStatus status = deactivatePackage(String8(args[1]).string());
Andreas Gampea4fe1132018-11-16 11:14:31 -0800790 if (status.isOk()) {
791 return OK;
792 }
Andreas Gampe17739142019-01-09 16:00:26 -0800793 std::string msg = StringLog() << "Failed to deactivate package: "
794 << status.toString8().string() << std::endl;
Jiyong Park9b800482018-12-03 22:16:40 +0900795 dprintf(err, "%s", msg.c_str());
Andreas Gampea4fe1132018-11-16 11:14:31 -0800796 return BAD_VALUE;
797 }
Andreas Gampee3864802018-12-19 14:12:59 -0800798
Dario Frenid2437642019-01-11 14:35:23 +0000799 if (cmd == String16("getStagedSessionInfo")) {
800 if (args.size() != 2) {
801 print_help(err, "getStagedSessionInfo requires one session id");
802 return BAD_VALUE;
803 }
804 int session_id = strtol(String8(args[1]).c_str(), nullptr, 10);
805 if (session_id < 0) {
806 std::string msg = StringLog()
807 << "Failed to parse session id. Must be an integer.";
808 dprintf(err, "%s", msg.c_str());
809 return BAD_VALUE;
810 }
811
812 ApexSessionInfo session_info;
813 BinderStatus status = getStagedSessionInfo(session_id, &session_info);
814 if (status.isOk()) {
Gavin Corkery879fe9b2020-01-29 19:13:50 +0000815 std::string revert_reason = "";
816 std::string crashing_native_process = session_info.crashingNativeProcess;
817 if (!crashing_native_process.empty()) {
818 revert_reason = " revertReason: " + crashing_native_process;
819 }
Dario Frenid2437642019-01-11 14:35:23 +0000820 std::string msg = StringLog()
821 << "session_info: "
822 << " isUnknown: " << session_info.isUnknown
823 << " isVerified: " << session_info.isVerified
824 << " isStaged: " << session_info.isStaged
825 << " isActivated: " << session_info.isActivated
Dario Frenid2437642019-01-11 14:35:23 +0000826 << " isActivationFailed: "
Gavin Corkery879fe9b2020-01-29 19:13:50 +0000827 << session_info.isActivationFailed << revert_reason
828 << std::endl;
Dario Frenid2437642019-01-11 14:35:23 +0000829 dprintf(out, "%s", msg.c_str());
830 return OK;
831 }
832 std::string msg = StringLog() << "Failed to query session: "
833 << status.toString8().string() << std::endl;
834 dprintf(err, "%s", msg.c_str());
835 return BAD_VALUE;
836 }
837
Dario Freni56231b42019-01-04 11:58:17 +0000838 if (cmd == String16("submitStagedSession")) {
839 if (args.size() != 2) {
840 print_help(err, "submitStagedSession requires one session id");
841 return BAD_VALUE;
842 }
843 int session_id = strtol(String8(args[1]).c_str(), nullptr, 10);
844 if (session_id < 0) {
845 std::string msg = StringLog()
846 << "Failed to parse session id. Must be an integer.";
847 dprintf(err, "%s", msg.c_str());
848 return BAD_VALUE;
849 }
850
Dario Freniab5b6c42019-01-15 11:53:57 +0000851 ApexInfoList list;
852 std::vector<int> empty_child_session_ids;
Oli Lan123d9d02019-12-02 14:08:24 +0000853 ApexSessionParams params;
854 params.sessionId = session_id;
855 params.childSessionIds = empty_child_session_ids;
856 BinderStatus status = submitStagedSession(params, &list);
Dario Freni56231b42019-01-04 11:58:17 +0000857 if (status.isOk()) {
Dario Freniab5b6c42019-01-15 11:53:57 +0000858 for (const auto& item : list.apexInfos) {
Gavin Corkeryd6ef0302019-03-21 11:52:06 +0000859 std::string msg = toString(item);
Dario Frenia6ad33e2019-01-09 14:35:43 +0000860 dprintf(out, "%s", msg.c_str());
861 }
Dario Freni56231b42019-01-04 11:58:17 +0000862 return OK;
863 }
864 std::string msg = StringLog() << "Failed to submit session: "
865 << status.toString8().string() << std::endl;
866 dprintf(err, "%s", msg.c_str());
867 return BAD_VALUE;
868 }
869
Andreas Gampe1a48b1b2019-02-05 16:12:25 -0800870 if (cmd == String16("preinstallPackages") ||
871 cmd == String16("postinstallPackages")) {
872 if (args.size() < 2) {
873 print_help(err,
874 "preinstallPackages/postinstallPackages requires at least"
875 " one packagePath");
876 return BAD_VALUE;
877 }
878 std::vector<std::string> pkgs;
879 pkgs.reserve(args.size() - 1);
880 for (size_t i = 1; i != args.size(); ++i) {
881 pkgs.emplace_back(String8(args[i]).string());
882 }
883 BinderStatus status = cmd == String16("preinstallPackages")
884 ? preinstallPackages(pkgs)
885 : postinstallPackages(pkgs);
886 if (status.isOk()) {
887 return OK;
888 }
889 std::string msg = StringLog() << "Failed to pre/postinstall package(s): "
890 << status.toString8().string() << std::endl;
891 dprintf(err, "%s", msg.c_str());
892 return BAD_VALUE;
893 }
894
Nikita Ioffe78d2bce2020-05-02 01:28:30 +0100895 if (cmd == String16("remountPackages")) {
896 BinderStatus status = remountPackages();
897 if (status.isOk()) {
898 return OK;
899 }
900 std::string msg = StringLog() << "remountPackages failed: "
901 << status.toString8().string() << std::endl;
902 dprintf(err, "%s", msg.c_str());
903 return BAD_VALUE;
904 }
905
Andreas Gampee3864802018-12-19 14:12:59 -0800906 if (cmd == String16("help")) {
907 if (args.size() != 1) {
908 print_help(err, "Help has no options");
909 return BAD_VALUE;
910 }
Andreas Gampe66b5dcd2018-10-17 19:20:00 -0700911 print_help(out);
912 return OK;
913 }
Andreas Gampee3864802018-12-19 14:12:59 -0800914
Andreas Gampe66b5dcd2018-10-17 19:20:00 -0700915 print_help(err);
916 return BAD_VALUE;
917}
918
Andreas Gampe602ef782018-11-12 16:51:31 -0800919} // namespace
920
921static constexpr const char* kApexServiceName = "apexservice";
922
Andreas Gampe602ef782018-11-12 16:51:31 -0800923using android::IPCThreadState;
924using android::ProcessState;
925using android::sp;
Jon Spivack1b840302020-02-06 18:34:30 -0800926using android::binder::LazyServiceRegistrar;
Andreas Gampe602ef782018-11-12 16:51:31 -0800927
928void CreateAndRegisterService() {
929 sp<ProcessState> ps(ProcessState::self());
930
Jon Spivack1b840302020-02-06 18:34:30 -0800931 // Create binder service and register with LazyServiceRegistrar
Andreas Gampe602ef782018-11-12 16:51:31 -0800932 sp<ApexService> apexService = new ApexService();
Jon Spivack1b840302020-02-06 18:34:30 -0800933 auto lazyRegistrar = LazyServiceRegistrar::getInstance();
934 lazyRegistrar.forcePersist(true);
935 lazyRegistrar.registerService(apexService, kApexServiceName);
936}
937
938void AllowServiceShutdown() {
939 auto lazyRegistrar = LazyServiceRegistrar::getInstance();
940 lazyRegistrar.forcePersist(false);
Andreas Gampe602ef782018-11-12 16:51:31 -0800941}
942
Zimuzo9cc0be42019-01-09 11:37:34 +0000943void StartThreadPool() {
Andreas Gampe602ef782018-11-12 16:51:31 -0800944 sp<ProcessState> ps(ProcessState::self());
945
946 // Start threadpool, wait for IPC
947 ps->startThreadPool();
Zimuzo9cc0be42019-01-09 11:37:34 +0000948}
949
950void JoinThreadPool() {
Andreas Gampe602ef782018-11-12 16:51:31 -0800951 IPCThreadState::self()->joinThreadPool(); // should not return
952}
953
954} // namespace binder
Andreas Gampeb99abdd2018-10-19 19:59:17 -0700955} // namespace apex
956} // namespace android