1 /*
2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "bundle_installer_proxy.h"
17
18 #include <cerrno>
19 #include <fcntl.h>
20 #include <sys/sendfile.h>
21 #include <sys/stat.h>
22 #include <unistd.h>
23
24 #include "app_log_tag_wrapper.h"
25 #include "app_log_wrapper.h"
26 #include "appexecfwk_errors.h"
27 #include "bundle_file_util.h"
28 #include "directory_ex.h"
29 #include "hitrace_meter.h"
30 #include "ipc_types.h"
31 #include "parcel.h"
32 #include "string_ex.h"
33
34 namespace OHOS {
35 namespace AppExecFwk {
36 namespace {
37 const char* SEPARATOR = "/";
38 } // namespace
39
BundleInstallerProxy(const sptr<IRemoteObject> & object)40 BundleInstallerProxy::BundleInstallerProxy(const sptr<IRemoteObject> &object) : IRemoteProxy<IBundleInstaller>(object)
41 {
42 LOG_D(BMS_TAG_INSTALLER, "create bundle installer proxy instance");
43 }
44
~BundleInstallerProxy()45 BundleInstallerProxy::~BundleInstallerProxy()
46 {
47 LOG_D(BMS_TAG_INSTALLER, "destroy bundle installer proxy instance");
48 }
49
Install(const std::string & bundlePath,const InstallParam & installParam,const sptr<IStatusReceiver> & statusReceiver)50 bool BundleInstallerProxy::Install(
51 const std::string &bundlePath, const InstallParam &installParam, const sptr<IStatusReceiver> &statusReceiver)
52 {
53 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
54 MessageParcel data;
55 MessageParcel reply;
56 MessageOption option(MessageOption::TF_SYNC);
57
58 PARCEL_WRITE_INTERFACE_TOKEN(data, GetDescriptor());
59 PARCEL_WRITE(data, String16, Str8ToStr16(bundlePath));
60 PARCEL_WRITE(data, Parcelable, &installParam);
61
62 if (statusReceiver == nullptr) {
63 LOG_E(BMS_TAG_INSTALLER, "fail to install, for statusReceiver is nullptr");
64 return false;
65 }
66 if (!data.WriteRemoteObject(statusReceiver->AsObject())) {
67 LOG_E(BMS_TAG_INSTALLER, "write parcel failed");
68 return false;
69 }
70
71 return SendInstallRequest(BundleInstallerInterfaceCode::INSTALL, data, reply, option);
72 }
73
Install(const std::vector<std::string> & bundleFilePaths,const InstallParam & installParam,const sptr<IStatusReceiver> & statusReceiver)74 bool BundleInstallerProxy::Install(const std::vector<std::string> &bundleFilePaths, const InstallParam &installParam,
75 const sptr<IStatusReceiver> &statusReceiver)
76 {
77 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
78 MessageParcel data;
79 MessageParcel reply;
80 MessageOption option(MessageOption::TF_SYNC);
81
82 PARCEL_WRITE_INTERFACE_TOKEN(data, GetDescriptor());
83 auto size = bundleFilePaths.size();
84 PARCEL_WRITE(data, Int32, size);
85 for (uint32_t i = 0; i < size; ++i) {
86 PARCEL_WRITE(data, String16, Str8ToStr16(bundleFilePaths[i]));
87 }
88 PARCEL_WRITE(data, Parcelable, &installParam);
89
90 if (statusReceiver == nullptr) {
91 LOG_E(BMS_TAG_INSTALLER, "fail to install, for statusReceiver is nullptr");
92 return false;
93 }
94 if (!data.WriteRemoteObject(statusReceiver->AsObject())) {
95 LOG_E(BMS_TAG_INSTALLER, "write parcel failed");
96 return false;
97 }
98
99 return SendInstallRequest(BundleInstallerInterfaceCode::INSTALL_MULTIPLE_HAPS, data, reply,
100 option);
101 }
102
Recover(const std::string & bundleName,const InstallParam & installParam,const sptr<IStatusReceiver> & statusReceiver)103 bool BundleInstallerProxy::Recover(const std::string &bundleName,
104 const InstallParam &installParam, const sptr<IStatusReceiver> &statusReceiver)
105 {
106 MessageParcel data;
107 MessageParcel reply;
108 MessageOption option(MessageOption::TF_SYNC);
109
110 PARCEL_WRITE_INTERFACE_TOKEN(data, GetDescriptor());
111 PARCEL_WRITE(data, String16, Str8ToStr16(bundleName));
112 PARCEL_WRITE(data, Parcelable, &installParam);
113
114 if (statusReceiver == nullptr) {
115 LOG_E(BMS_TAG_INSTALLER, "fail to install, for statusReceiver is nullptr");
116 return false;
117 }
118 if (!data.WriteRemoteObject(statusReceiver->AsObject())) {
119 LOG_E(BMS_TAG_INSTALLER, "write parcel failed");
120 return false;
121 }
122
123 return SendInstallRequest(BundleInstallerInterfaceCode::RECOVER, data, reply,
124 option);
125 }
126
Uninstall(const std::string & bundleName,const InstallParam & installParam,const sptr<IStatusReceiver> & statusReceiver)127 bool BundleInstallerProxy::Uninstall(
128 const std::string &bundleName, const InstallParam &installParam, const sptr<IStatusReceiver> &statusReceiver)
129 {
130 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
131 MessageParcel data;
132 MessageParcel reply;
133 MessageOption option(MessageOption::TF_SYNC);
134
135 PARCEL_WRITE_INTERFACE_TOKEN(data, GetDescriptor());
136 PARCEL_WRITE(data, String16, Str8ToStr16(bundleName));
137 PARCEL_WRITE(data, Parcelable, &installParam);
138 if (statusReceiver == nullptr) {
139 LOG_E(BMS_TAG_INSTALLER, "fail to uninstall, for statusReceiver is nullptr");
140 return false;
141 }
142 if (!data.WriteRemoteObject(statusReceiver->AsObject())) {
143 LOG_E(BMS_TAG_INSTALLER, "write parcel failed");
144 return false;
145 }
146
147 return SendInstallRequest(BundleInstallerInterfaceCode::UNINSTALL, data, reply, option);
148 }
149
Uninstall(const std::string & bundleName,const std::string & modulePackage,const InstallParam & installParam,const sptr<IStatusReceiver> & statusReceiver)150 bool BundleInstallerProxy::Uninstall(const std::string &bundleName, const std::string &modulePackage,
151 const InstallParam &installParam, const sptr<IStatusReceiver> &statusReceiver)
152 {
153 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
154 MessageParcel data;
155 MessageParcel reply;
156 MessageOption option(MessageOption::TF_SYNC);
157
158 PARCEL_WRITE_INTERFACE_TOKEN(data, GetDescriptor());
159 PARCEL_WRITE(data, String16, Str8ToStr16(bundleName));
160 PARCEL_WRITE(data, String16, Str8ToStr16(modulePackage));
161 PARCEL_WRITE(data, Parcelable, &installParam);
162 if (statusReceiver == nullptr) {
163 LOG_E(BMS_TAG_INSTALLER, "fail to uninstall, for statusReceiver is nullptr");
164 return false;
165 }
166 if (!data.WriteRemoteObject(statusReceiver->AsObject())) {
167 LOG_E(BMS_TAG_INSTALLER, "write parcel failed");
168 return false;
169 }
170
171 return SendInstallRequest(BundleInstallerInterfaceCode::UNINSTALL_MODULE, data, reply, option);
172 }
173
Uninstall(const UninstallParam & uninstallParam,const sptr<IStatusReceiver> & statusReceiver)174 bool BundleInstallerProxy::Uninstall(const UninstallParam &uninstallParam,
175 const sptr<IStatusReceiver> &statusReceiver)
176 {
177 MessageParcel data;
178 MessageParcel reply;
179 MessageOption option(MessageOption::TF_SYNC);
180 PARCEL_WRITE_INTERFACE_TOKEN(data, GetDescriptor());
181 PARCEL_WRITE(data, Parcelable, &uninstallParam);
182 if (statusReceiver == nullptr) {
183 LOG_E(BMS_TAG_INSTALLER, "fail to uninstall, for statusReceiver is nullptr");
184 return false;
185 }
186 if (!data.WriteRemoteObject(statusReceiver->AsObject())) {
187 LOG_E(BMS_TAG_INSTALLER, "write parcel failed");
188 return false;
189 }
190 return SendInstallRequest(BundleInstallerInterfaceCode::UNINSTALL_BY_UNINSTALL_PARAM, data, reply, option);
191 }
192
InstallSandboxApp(const std::string & bundleName,int32_t dlpType,int32_t userId,int32_t & appIndex)193 ErrCode BundleInstallerProxy::InstallSandboxApp(const std::string &bundleName, int32_t dlpType, int32_t userId,
194 int32_t &appIndex)
195 {
196 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
197 MessageParcel data;
198 MessageParcel reply;
199 MessageOption option(MessageOption::TF_SYNC);
200
201 if (!data.WriteInterfaceToken(GetDescriptor())) {
202 LOG_E(BMS_TAG_INSTALLER, "failed to InstallSandboxApp due to write MessageParcel fail");
203 return ERR_APPEXECFWK_SANDBOX_INSTALL_WRITE_PARCEL_ERROR;
204 }
205 if (!data.WriteString16(Str8ToStr16(bundleName))) {
206 LOG_E(BMS_TAG_INSTALLER, "failed to InstallSandboxApp due to write bundleName fail");
207 return ERR_APPEXECFWK_SANDBOX_INSTALL_WRITE_PARCEL_ERROR;
208 }
209 if (!data.WriteInt32(dlpType)) {
210 LOG_E(BMS_TAG_INSTALLER, "failed to InstallSandboxApp due to write appIndex fail");
211 return ERR_APPEXECFWK_SANDBOX_INSTALL_WRITE_PARCEL_ERROR;
212 }
213 if (!data.WriteInt32(userId)) {
214 LOG_E(BMS_TAG_INSTALLER, "failed to InstallSandboxApp due to write userId fail");
215 return ERR_APPEXECFWK_SANDBOX_INSTALL_WRITE_PARCEL_ERROR;
216 }
217
218 auto ret =
219 SendInstallRequest(BundleInstallerInterfaceCode::INSTALL_SANDBOX_APP, data, reply, option);
220 if (!ret) {
221 LOG_E(BMS_TAG_INSTALLER, "install sandbox app failed due to send request fail");
222 return ERR_APPEXECFWK_SANDBOX_INSTALL_SEND_REQUEST_ERROR;
223 }
224
225 auto res = reply.ReadInt32();
226 if (res == ERR_OK) {
227 appIndex = reply.ReadInt32();
228 }
229 return res;
230 }
231
UninstallSandboxApp(const std::string & bundleName,int32_t appIndex,int32_t userId)232 ErrCode BundleInstallerProxy::UninstallSandboxApp(const std::string &bundleName, int32_t appIndex, int32_t userId)
233 {
234 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
235 MessageParcel data;
236 MessageParcel reply;
237 MessageOption option(MessageOption::TF_SYNC);
238
239 if (!data.WriteInterfaceToken(GetDescriptor())) {
240 LOG_E(BMS_TAG_INSTALLER, "failed to InstallSandboxApp due to write MessageParcel fail");
241 return ERR_APPEXECFWK_SANDBOX_INSTALL_WRITE_PARCEL_ERROR;
242 }
243 if (!data.WriteString16(Str8ToStr16(bundleName))) {
244 LOG_E(BMS_TAG_INSTALLER, "failed to InstallSandboxApp due to write bundleName fail");
245 return ERR_APPEXECFWK_SANDBOX_INSTALL_WRITE_PARCEL_ERROR;
246 }
247 if (!data.WriteInt32(appIndex)) {
248 LOG_E(BMS_TAG_INSTALLER, "failed to InstallSandboxApp due to write appIndex fail");
249 return ERR_APPEXECFWK_SANDBOX_INSTALL_WRITE_PARCEL_ERROR;
250 }
251 if (!data.WriteInt32(userId)) {
252 LOG_E(BMS_TAG_INSTALLER, "failed to InstallSandboxApp due to write userId fail");
253 return ERR_APPEXECFWK_SANDBOX_INSTALL_WRITE_PARCEL_ERROR;
254 }
255
256 auto ret =
257 SendInstallRequest(BundleInstallerInterfaceCode::UNINSTALL_SANDBOX_APP, data, reply, option);
258 if (!ret) {
259 LOG_E(BMS_TAG_INSTALLER, "uninstall sandbox app failed due to send request fail");
260 return ERR_APPEXECFWK_SANDBOX_INSTALL_SEND_REQUEST_ERROR;
261 }
262 return reply.ReadInt32();
263 }
264
CreateStreamInstaller(const InstallParam & installParam,const sptr<IStatusReceiver> & statusReceiver,const std::vector<std::string> & originHapPaths)265 sptr<IBundleStreamInstaller> BundleInstallerProxy::CreateStreamInstaller(const InstallParam &installParam,
266 const sptr<IStatusReceiver> &statusReceiver, const std::vector<std::string> &originHapPaths)
267 {
268 LOG_D(BMS_TAG_INSTALLER, "create stream installer begin");
269 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
270 MessageParcel data;
271 MessageParcel reply;
272 MessageOption option(MessageOption::TF_SYNC);
273
274 if (statusReceiver == nullptr) {
275 LOG_E(BMS_TAG_INSTALLER, "fail to install, for receiver is nullptr");
276 return nullptr;
277 }
278
279 bool ret = data.WriteInterfaceToken(GetDescriptor());
280 if (!ret) {
281 LOG_E(BMS_TAG_INSTALLER, "fail to write interface token into the parcel");
282 statusReceiver->OnFinished(ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR, "");
283 return nullptr;
284 }
285 ret = data.WriteParcelable(&installParam);
286 if (!ret) {
287 LOG_E(BMS_TAG_INSTALLER, "fail to write parameter into the parcel");
288 statusReceiver->OnFinished(ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR, "");
289 return nullptr;
290 }
291 if (!data.WriteRemoteObject(statusReceiver->AsObject())) {
292 LOG_E(BMS_TAG_INSTALLER, "write parcel failed");
293 statusReceiver->OnFinished(ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR, "");
294 return nullptr;
295 }
296 if (!data.WriteStringVector(originHapPaths)) {
297 LOG_E(BMS_TAG_INSTALLER, "write parcel failed");
298 statusReceiver->OnFinished(ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR, "");
299 return nullptr;
300 }
301 bool res = SendInstallRequest(BundleInstallerInterfaceCode::CREATE_STREAM_INSTALLER, data, reply, option);
302 if (!res) {
303 LOG_E(BMS_TAG_INSTALLER, "CreateStreamInstaller failed due to send request fail");
304 statusReceiver->OnFinished(ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR, "");
305 return nullptr;
306 }
307 if (!reply.ReadBool()) {
308 LOG_E(BMS_TAG_INSTALLER, "CreateStreamInstaller failed");
309 return nullptr;
310 }
311 uint32_t streamInstallerId = reply.ReadUint32();
312 sptr<IRemoteObject> object = reply.ReadRemoteObject();
313 if (object == nullptr) {
314 LOG_E(BMS_TAG_INSTALLER, "CreateStreamInstaller create nullptr remote object");
315 return nullptr;
316 }
317 sptr<IBundleStreamInstaller> streamInstaller = iface_cast<IBundleStreamInstaller>(object);
318 if (streamInstaller == nullptr) {
319 LOG_E(BMS_TAG_INSTALLER, "CreateStreamInstaller failed");
320 return streamInstaller;
321 }
322 streamInstaller->SetInstallerId(streamInstallerId);
323 LOG_D(BMS_TAG_INSTALLER, "create stream installer successfully");
324 return streamInstaller;
325 }
326
DestoryBundleStreamInstaller(uint32_t streamInstallerId)327 bool BundleInstallerProxy::DestoryBundleStreamInstaller(uint32_t streamInstallerId)
328 {
329 LOG_D(BMS_TAG_INSTALLER, "destory stream installer begin");
330 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
331 MessageParcel data;
332 MessageParcel reply;
333 MessageOption option(MessageOption::TF_SYNC);
334
335 PARCEL_WRITE_INTERFACE_TOKEN(data, GetDescriptor());
336 PARCEL_WRITE(data, Uint32, streamInstallerId);
337 bool res = SendInstallRequest(BundleInstallerInterfaceCode::DESTORY_STREAM_INSTALLER, data, reply, option);
338 if (!res) {
339 LOG_E(BMS_TAG_INSTALLER, "CreateStreamInstaller failed due to send request fail");
340 return false;
341 }
342 LOG_D(BMS_TAG_INSTALLER, "destory stream installer successfully");
343 return true;
344 }
345
UninstallAndRecover(const std::string & bundleName,const InstallParam & installParam,const sptr<IStatusReceiver> & statusReceiver)346 bool BundleInstallerProxy::UninstallAndRecover(const std::string &bundleName, const InstallParam &installParam,
347 const sptr<IStatusReceiver> &statusReceiver)
348 {
349 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
350 MessageParcel reply;
351 MessageParcel data;
352 MessageOption option(MessageOption::TF_SYNC);
353
354 PARCEL_WRITE_INTERFACE_TOKEN(data, GetDescriptor());
355 PARCEL_WRITE(data, String16, Str8ToStr16(bundleName));
356 PARCEL_WRITE(data, Parcelable, &installParam);
357 if (statusReceiver == nullptr) {
358 LOG_E(BMS_TAG_INSTALLER, "fail to uninstall quick fix, for statusReceiver is nullptr");
359 return false;
360 }
361 if (!data.WriteRemoteObject(statusReceiver->AsObject())) {
362 LOG_E(BMS_TAG_INSTALLER, "write parcel failed");
363 return false;
364 }
365
366 return SendInstallRequest(BundleInstallerInterfaceCode::UNINSTALL_AND_RECOVER, data, reply, option);
367 }
368
StreamInstall(const std::vector<std::string> & bundleFilePaths,const InstallParam & installParam,const sptr<IStatusReceiver> & statusReceiver)369 ErrCode BundleInstallerProxy::StreamInstall(const std::vector<std::string> &bundleFilePaths,
370 const InstallParam &installParam, const sptr<IStatusReceiver> &statusReceiver)
371 {
372 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
373 LOG_D(BMS_TAG_INSTALLER, "stream install start");
374 if (statusReceiver == nullptr) {
375 LOG_E(BMS_TAG_INSTALLER, "stream install failed due to nullptr status receiver");
376 return ERR_APPEXECFWK_INSTALL_PARAM_ERROR;
377 }
378
379 std::vector<std::string> realPaths;
380 if (!bundleFilePaths.empty() && !BundleFileUtil::CheckFilePath(bundleFilePaths, realPaths)) {
381 LOG_E(BMS_TAG_INSTALLER, "stream install failed due to check file failed");
382 return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID;
383 }
384
385 sptr<IBundleStreamInstaller> streamInstaller = CreateStreamInstaller(installParam, statusReceiver, realPaths);
386 if (streamInstaller == nullptr) {
387 LOG_E(BMS_TAG_INSTALLER, "stream install failed due to nullptr stream installer");
388 return ERR_OK;
389 }
390 ErrCode res = ERR_OK;
391 // copy hap or hsp file to bms service
392 if (!installParam.IsRenameInstall()) {
393 for (const auto &path : realPaths) {
394 res = WriteHapFileToStream(streamInstaller, path);
395 if (res != ERR_OK) {
396 DestoryBundleStreamInstaller(streamInstaller->GetInstallerId());
397 LOG_E(BMS_TAG_INSTALLER, "WriteHapFileToStream failed due to %{public}d", res);
398 return res;
399 }
400 }
401 }
402 // copy sig file to bms service
403 if (!realPaths.empty() && !installParam.verifyCodeParams.empty() &&
404 (realPaths.size() != installParam.verifyCodeParams.size())) {
405 DestoryBundleStreamInstaller(streamInstaller->GetInstallerId());
406 LOG_E(BMS_TAG_INSTALLER, "size of hapFiles is not same with size of verifyCodeParams");
407 return ERR_BUNDLEMANAGER_INSTALL_CODE_SIGNATURE_FILE_IS_INVALID;
408 }
409 if ((res = CopySignatureFileToService(streamInstaller, installParam)) != ERR_OK) {
410 DestoryBundleStreamInstaller(streamInstaller->GetInstallerId());
411 LOG_E(BMS_TAG_INSTALLER, "CopySignatureFileToService failed due to %{public}d", res);
412 return res;
413 }
414 // copy pgo file to bms service
415 res = CopyPgoFileToService(streamInstaller, installParam);
416 if (res != ERR_OK) {
417 LOG_W(BMS_TAG_INSTALLER, "CopyPgoFileToService failed due to %{public}d", res);
418 }
419
420 // write shared bundles
421 uint32_t size = static_cast<uint32_t>(installParam.sharedBundleDirPaths.size());
422 for (uint32_t i = 0; i < size; ++i) {
423 realPaths.clear();
424 std::vector<std::string> sharedBundleDir = {installParam.sharedBundleDirPaths[i]};
425 if (!BundleFileUtil::CheckFilePath(sharedBundleDir, realPaths)) {
426 LOG_E(BMS_TAG_INSTALLER, "stream install failed due to check shared package files failed");
427 DestoryBundleStreamInstaller(streamInstaller->GetInstallerId());
428 return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID;
429 }
430 for (const auto &path : realPaths) {
431 res = WriteSharedFileToStream(streamInstaller, path, i);
432 if (res != ERR_OK) {
433 DestoryBundleStreamInstaller(streamInstaller->GetInstallerId());
434 LOG_E(BMS_TAG_INSTALLER, "WriteSharedFileToStream(sharedBundleDirPaths) failed due to %{public}d", res);
435 return res;
436 }
437 }
438 }
439
440 // start install haps
441 if (!streamInstaller->Install()) {
442 LOG_E(BMS_TAG_INSTALLER, "stream install failed");
443 DestoryBundleStreamInstaller(streamInstaller->GetInstallerId());
444 statusReceiver->OnFinished(ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR, "");
445 return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
446 }
447 LOG_D(BMS_TAG_INSTALLER, "stream install end");
448 return ERR_OK;
449 }
450
WriteFile(const std::string & path,int32_t outputFd)451 ErrCode BundleInstallerProxy::WriteFile(const std::string &path, int32_t outputFd)
452 {
453 LOG_D(BMS_TAG_INSTALLER, "write file stream to service terminal start");
454 std::string realPath;
455 if (!PathToRealPath(path, realPath)) {
456 LOG_E(BMS_TAG_INSTALLER, "file is not real path, file path: %{private}s", path.c_str());
457 return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID;
458 }
459 int32_t inputFd = open(realPath.c_str(), O_RDONLY);
460 if (inputFd < 0) {
461 LOG_E(BMS_TAG_INSTALLER, "write file to stream failed due to open the hap file, errno:%{public}d", errno);
462 return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID;
463 }
464
465 struct stat sourceStat;
466 if (fstat(inputFd, &sourceStat) == -1) {
467 LOG_E(BMS_TAG_INSTALLER, "fstat failed, errno : %{public}d", errno);
468 close(inputFd);
469 return ERR_APPEXECFWK_INSTALL_DISK_MEM_INSUFFICIENT;
470 }
471 if (sourceStat.st_size < 0) {
472 LOG_E(BMS_TAG_INSTALLER, "invalid st_size");
473 close(inputFd);
474 return ERR_APPEXECFWK_INSTALL_DISK_MEM_INSUFFICIENT;
475 }
476
477 size_t buffer = 524288; // 0.5M
478 size_t transferCount = 0;
479 ssize_t singleTransfer = 0;
480 while ((singleTransfer = sendfile(outputFd, inputFd, nullptr, buffer)) > 0) {
481 transferCount += static_cast<size_t>(singleTransfer);
482 }
483
484 if (singleTransfer == -1 || transferCount != static_cast<size_t>(sourceStat.st_size)) {
485 LOG_E(BMS_TAG_INSTALLER, "errno: %{public}d, send count: %{public}zu, file size: %{public}zu",
486 errno, transferCount, static_cast<size_t>(sourceStat.st_size));
487 close(inputFd);
488 return ERR_APPEXECFWK_INSTALL_DISK_MEM_INSUFFICIENT;
489 }
490
491 close(inputFd);
492 fsync(outputFd);
493
494 LOG_D(BMS_TAG_INSTALLER, "write file stream to service terminal end");
495 return ERR_OK;
496 }
497
WriteHapFileToStream(sptr<IBundleStreamInstaller> & streamInstaller,const std::string & path)498 ErrCode BundleInstallerProxy::WriteHapFileToStream(sptr<IBundleStreamInstaller> &streamInstaller,
499 const std::string &path)
500 {
501 if (streamInstaller == nullptr) {
502 LOG_E(BMS_TAG_INSTALLER, "write file to stream failed due to nullptr stream installer");
503 return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
504 }
505 std::string fileName;
506 ErrCode ret = ERR_OK;
507 ret = GetFileNameByFilePath(path, fileName);
508 if (ret != ERR_OK) {
509 LOG_E(BMS_TAG_INSTALLER, "invalid file path");
510 return ret;
511 }
512 LOG_D(BMS_TAG_INSTALLER, "write file stream of hap path %{public}s", path.c_str());
513
514 int32_t outputFd = streamInstaller->CreateStream(fileName);
515 if (outputFd < 0) {
516 LOG_E(BMS_TAG_INSTALLER, "write file to stream failed due to invalid file descriptor");
517 return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID;
518 }
519
520 ret = WriteFile(path, outputFd);
521 close(outputFd);
522
523 return ret;
524 }
525
WriteSignatureFileToStream(sptr<IBundleStreamInstaller> & streamInstaller,const std::string & path,const std::string & moduleName)526 ErrCode BundleInstallerProxy::WriteSignatureFileToStream(sptr<IBundleStreamInstaller> &streamInstaller,
527 const std::string &path, const std::string &moduleName)
528 {
529 if (streamInstaller == nullptr) {
530 LOG_E(BMS_TAG_INSTALLER, "write file to stream failed due to nullptr stream installer");
531 return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
532 }
533 std::string fileName;
534 ErrCode ret = ERR_OK;
535 ret = GetFileNameByFilePath(path, fileName);
536 if (ret != ERR_OK) {
537 LOG_E(BMS_TAG_INSTALLER, "invalid file path");
538 return ret;
539 }
540 LOG_D(BMS_TAG_INSTALLER, "write file stream of signature path %{public}s", path.c_str());
541
542 int32_t outputFd = streamInstaller->CreateSignatureFileStream(moduleName, fileName);
543 if (outputFd < 0) {
544 LOG_E(BMS_TAG_INSTALLER, "write file to stream failed due to invalid file descriptor");
545 return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID;
546 }
547
548 ret = WriteFile(path, outputFd);
549 close(outputFd);
550
551 return ret;
552 }
553
WriteSharedFileToStream(sptr<IBundleStreamInstaller> & streamInstaller,const std::string & path,uint32_t index)554 ErrCode BundleInstallerProxy::WriteSharedFileToStream(sptr<IBundleStreamInstaller> &streamInstaller,
555 const std::string &path, uint32_t index)
556 {
557 if (streamInstaller == nullptr) {
558 LOG_E(BMS_TAG_INSTALLER, "write file to stream failed due to nullptr stream installer");
559 return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
560 }
561
562 std::string hspName;
563 ErrCode ret = ERR_OK;
564 ret = GetFileNameByFilePath(path, hspName);
565 if (ret != ERR_OK) {
566 LOG_E(BMS_TAG_INSTALLER, "invalid file path");
567 return ret;
568 }
569
570 LOG_D(BMS_TAG_INSTALLER, "write file stream of shared path %{public}s", path.c_str());
571 int32_t outputFd = streamInstaller->CreateSharedBundleStream(hspName, index);
572 if (outputFd < 0) {
573 LOG_E(BMS_TAG_INSTALLER, "write file to stream failed due to invalid file descriptor");
574 return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID;
575 }
576
577 ret = WriteFile(path, outputFd);
578 close(outputFd);
579
580 return ret;
581 }
582
WritePgoFileToStream(sptr<IBundleStreamInstaller> & streamInstaller,const std::string & path,const std::string & moduleName)583 ErrCode BundleInstallerProxy::WritePgoFileToStream(sptr<IBundleStreamInstaller> &streamInstaller,
584 const std::string &path, const std::string &moduleName)
585 {
586 if (streamInstaller == nullptr) {
587 LOG_E(BMS_TAG_INSTALLER, "write file to stream failed due to nullptr stream installer");
588 return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
589 }
590
591 std::string fileName;
592 ErrCode ret = ERR_OK;
593 ret = GetFileNameByFilePath(path, fileName);
594 if (ret != ERR_OK) {
595 LOG_E(BMS_TAG_INSTALLER, "invalid file path");
596 return ret;
597 }
598 LOG_D(BMS_TAG_INSTALLER, "write file stream of pgo path %{public}s", path.c_str());
599
600 int32_t outputFd = streamInstaller->CreatePgoFileStream(moduleName, fileName);
601 if (outputFd < 0) {
602 LOG_E(BMS_TAG_INSTALLER, "write file to stream failed due to invalid file descriptor");
603 return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID;
604 }
605
606 ret = WriteFile(path, outputFd);
607 close(outputFd);
608
609 return ret;
610 }
611
CopySignatureFileToService(sptr<IBundleStreamInstaller> & streamInstaller,const InstallParam & installParam)612 ErrCode BundleInstallerProxy::CopySignatureFileToService(sptr<IBundleStreamInstaller> &streamInstaller,
613 const InstallParam &installParam)
614 {
615 if (streamInstaller == nullptr) {
616 LOG_E(BMS_TAG_INSTALLER, "copy file failed due to nullptr stream installer");
617 return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
618 }
619
620 if (installParam.verifyCodeParams.empty()) {
621 return ERR_OK;
622 }
623 for (const auto ¶m : installParam.verifyCodeParams) {
624 std::string realPath;
625 if (param.first.empty() || !BundleFileUtil::CheckFilePath(param.second, realPath)) {
626 LOG_E(BMS_TAG_INSTALLER, "CheckFilePath signature file dir %{public}s failed", param.second.c_str());
627 DestoryBundleStreamInstaller(streamInstaller->GetInstallerId());
628 return ERR_BUNDLEMANAGER_INSTALL_CODE_SIGNATURE_FILE_IS_INVALID;
629 }
630 ErrCode res = WriteSignatureFileToStream(streamInstaller, realPath, param.first);
631 if (res != ERR_OK) {
632 DestoryBundleStreamInstaller(streamInstaller->GetInstallerId());
633 LOG_E(BMS_TAG_INSTALLER, "WriteSignatureFileToStream failed due to %{public}d", res);
634 return ERR_BUNDLEMANAGER_INSTALL_CODE_SIGNATURE_FILE_IS_INVALID;
635 }
636 }
637
638 return ERR_OK;
639 }
640
CopyPgoFileToService(sptr<IBundleStreamInstaller> & streamInstaller,const InstallParam & installParam)641 ErrCode BundleInstallerProxy::CopyPgoFileToService(sptr<IBundleStreamInstaller> &streamInstaller,
642 const InstallParam &installParam)
643 {
644 if (streamInstaller == nullptr) {
645 LOG_E(BMS_TAG_INSTALLER, "copy file failed due to nullptr stream installer");
646 return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
647 }
648 if (installParam.pgoParams.empty()) {
649 return ERR_OK;
650 }
651 for (const auto ¶m : installParam.pgoParams) {
652 std::string realPath;
653 if (param.first.empty() || !BundleFileUtil::CheckFilePath(param.second, realPath)) {
654 LOG_W(BMS_TAG_INSTALLER, "CheckFilePath pgo file path %{public}s failed", param.second.c_str());
655 continue;
656 }
657 ErrCode res = WritePgoFileToStream(streamInstaller, realPath, param.first);
658 if (res != ERR_OK) {
659 LOG_W(BMS_TAG_INSTALLER, "WritePgoFileToStream failed due to %{public}d", res);
660 continue;
661 }
662 }
663
664 return ERR_OK;
665 }
666
GetFileNameByFilePath(const std::string & filePath,std::string & fileName)667 ErrCode BundleInstallerProxy::GetFileNameByFilePath(const std::string &filePath, std::string &fileName)
668 {
669 size_t pos = filePath.find_last_of(SEPARATOR);
670 if (pos == std::string::npos) {
671 LOG_E(BMS_TAG_INSTALLER, "write file to stream failed due to invalid file path");
672 return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID;
673 }
674 fileName = filePath.substr(pos + 1);
675 if (fileName.empty()) {
676 LOG_E(BMS_TAG_INSTALLER, "write file to stream failed due to invalid file path");
677 return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID;
678 }
679 return ERR_OK;
680 }
681
SendInstallRequest(BundleInstallerInterfaceCode code,MessageParcel & data,MessageParcel & reply,MessageOption & option)682 bool BundleInstallerProxy::SendInstallRequest(
683 BundleInstallerInterfaceCode code, MessageParcel& data, MessageParcel& reply, MessageOption& option)
684 {
685 sptr<IRemoteObject> remote = Remote();
686 if (remote == nullptr) {
687 LOG_E(BMS_TAG_INSTALLER, "fail to uninstall, for Remote() is nullptr");
688 return false;
689 }
690
691 int32_t ret = remote->SendRequest(static_cast<uint32_t>(code), data, reply, option);
692 if (ret != NO_ERROR) {
693 LOG_E(BMS_TAG_INSTALLER, "fail to sendRequest, for transact is failed and error code is: %{public}d", ret);
694 return false;
695 }
696 return true;
697 }
698
InstallCloneApp(const std::string & bundleName,int32_t userId,int32_t & appIndex)699 ErrCode BundleInstallerProxy::InstallCloneApp(const std::string &bundleName, int32_t userId, int32_t& appIndex)
700 {
701 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
702 MessageParcel data;
703 MessageParcel reply;
704 MessageOption option(MessageOption::TF_SYNC);
705
706 if (!data.WriteInterfaceToken(GetDescriptor())) {
707 LOG_E(BMS_TAG_INSTALLER, "failed to InstallCloneApp due to write MessageParcel fail");
708 return ERR_APPEXECFWK_CLONE_INSTALL_WRITE_PARCEL_ERROR;
709 }
710 if (!data.WriteString16(Str8ToStr16(bundleName))) {
711 LOG_E(BMS_TAG_INSTALLER, "failed to InstallCloneApp due to write bundleName fail");
712 return ERR_APPEXECFWK_CLONE_INSTALL_WRITE_PARCEL_ERROR;
713 }
714 if (!data.WriteInt32(userId)) {
715 LOG_E(BMS_TAG_INSTALLER, "failed to InstallCloneApp due to write userId fail");
716 return ERR_APPEXECFWK_CLONE_INSTALL_WRITE_PARCEL_ERROR;
717 }
718 if (!data.WriteInt32(appIndex)) {
719 LOG_E(BMS_TAG_INSTALLER, "failed to InstallCloneApp due to write appIndex fail");
720 return ERR_APPEXECFWK_CLONE_INSTALL_WRITE_PARCEL_ERROR;
721 }
722
723 auto ret =
724 SendInstallRequest(BundleInstallerInterfaceCode::INSTALL_CLONE_APP, data, reply, option);
725 if (!ret) {
726 LOG_E(BMS_TAG_INSTALLER, "install clone app failed due to send request fail");
727 return ERR_APPEXECFWK_CLONE_INSTALL_SEND_REQUEST_ERROR;
728 }
729
730 auto res = reply.ReadInt32();
731 if (res == ERR_OK) {
732 appIndex = reply.ReadInt32();
733 }
734 return res;
735 }
736
UninstallCloneApp(const std::string & bundleName,int32_t userId,int32_t appIndex)737 ErrCode BundleInstallerProxy::UninstallCloneApp(const std::string &bundleName, int32_t userId, int32_t appIndex)
738 {
739 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
740 MessageParcel data;
741 MessageParcel reply;
742 MessageOption option(MessageOption::TF_SYNC);
743
744 if (!data.WriteInterfaceToken(GetDescriptor())) {
745 LOG_E(BMS_TAG_INSTALLER, "failed to UninstallCloneApp due to write MessageParcel fail");
746 return ERR_APPEXECFWK_CLONE_UNINSTALL_WRITE_PARCEL_ERROR;
747 }
748 if (!data.WriteString16(Str8ToStr16(bundleName))) {
749 LOG_E(BMS_TAG_INSTALLER, "failed to UninstallCloneApp due to write bundleName fail");
750 return ERR_APPEXECFWK_CLONE_UNINSTALL_WRITE_PARCEL_ERROR;
751 }
752 if (!data.WriteInt32(userId)) {
753 LOG_E(BMS_TAG_INSTALLER, "failed to UninstallCloneApp due to write userId fail");
754 return ERR_APPEXECFWK_CLONE_UNINSTALL_WRITE_PARCEL_ERROR;
755 }
756 if (!data.WriteInt32(appIndex)) {
757 LOG_E(BMS_TAG_INSTALLER, "failed to UninstallCloneApp due to write appIndex fail");
758 return ERR_APPEXECFWK_CLONE_UNINSTALL_WRITE_PARCEL_ERROR;
759 }
760
761 auto ret =
762 SendInstallRequest(BundleInstallerInterfaceCode::UNINSTALL_CLONE_APP, data, reply, option);
763 if (!ret) {
764 LOG_E(BMS_TAG_INSTALLER, "uninstall clone app failed due to send request fail");
765 return ERR_APPEXECFWK_CLONE_UNINSTALL_SEND_REQUEST_ERROR;
766 }
767 return reply.ReadInt32();
768 }
769
InstallExisted(const std::string & bundleName,int32_t userId)770 ErrCode BundleInstallerProxy::InstallExisted(const std::string &bundleName, int32_t userId)
771 {
772 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
773 MessageParcel data;
774 MessageParcel reply;
775 MessageOption option(MessageOption::TF_SYNC);
776
777 if (!data.WriteInterfaceToken(GetDescriptor())) {
778 LOG_E(BMS_TAG_INSTALLER, "failed to write descriptor");
779 return ERR_APPEXECFWK_INSTALL_EXISTED_WRITE_PARCEL_ERROR;
780 }
781 if (!data.WriteString16(Str8ToStr16(bundleName))) {
782 LOG_E(BMS_TAG_INSTALLER, "failed to write bundleName");
783 return ERR_APPEXECFWK_INSTALL_EXISTED_WRITE_PARCEL_ERROR;
784 }
785 if (!data.WriteInt32(userId)) {
786 LOG_E(BMS_TAG_INSTALLER, "failed to write userId");
787 return ERR_APPEXECFWK_INSTALL_EXISTED_WRITE_PARCEL_ERROR;
788 }
789
790 auto ret =
791 SendInstallRequest(BundleInstallerInterfaceCode::INSTALL_EXISTED, data, reply, option);
792 if (!ret) {
793 LOG_E(BMS_TAG_INSTALLER, "installExisted failed due to send request fail");
794 return ERR_APPEXECFWK_INSTALL_EXISTED_WRITE_PARCEL_ERROR;
795 }
796
797 return reply.ReadInt32();
798 }
799 } // namespace AppExecFwk
800 } // namespace OHOS
801