1 // Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by an apache-2.0 license that can be
3 // found in the LICENSE file.
5 #include "common/external_storage.h"
9 #include <manifest_parser/utils/logging.h>
11 #include "common/utils/byte_size_literals.h"
12 #include "common/utils/file_util.h"
14 namespace bf = boost::filesystem;
18 const char kWgtType[] = "wgt";
19 const char kExternalDirForWgt[] = "res";
21 const std::vector<std::string> kExternalDirsForTpk = {
27 int64_t SizeInMB(int64_t size) {
28 return (size + 1_MB - 1) / 1_MB;
33 namespace common_installer {
35 ExternalStorage::ExternalStorage(RequestType type,
36 const std::string& pkgid, const std::string& package_type,
37 const boost::filesystem::path& application_root, uid_t uid)
40 package_type_(package_type),
41 application_root_(application_root),
44 if (package_type_ == kWgtType) {
45 external_dirs_.push_back(kExternalDirForWgt);
47 external_dirs_ = kExternalDirsForTpk;
51 ExternalStorage::~ExternalStorage() {
53 app2ext_deinit(handle_);
56 bool ExternalStorage::Finalize(bool success) {
57 int ret = APP2EXT_STATUS_SUCCESS;
59 case RequestType::Install: {
60 ret = handle_->interface.client_usr_post_install(pkgid_.c_str(),
61 success ? APP2EXT_STATUS_SUCCESS : APP2EXT_STATUS_FAILED, uid_);
64 case RequestType::Update: {
65 ret = handle_->interface.client_usr_post_upgrade(pkgid_.c_str(),
66 success ? APP2EXT_STATUS_SUCCESS : APP2EXT_STATUS_FAILED, uid_);
69 case RequestType::Uninstall: {
70 ret = handle_->interface.client_usr_post_uninstall(pkgid_.c_str(), uid_);
74 assert(false && "Not supported installation mode");
76 return ret == APP2EXT_STATUS_SUCCESS;
79 bool ExternalStorage::Commit() {
80 return Finalize(true);
83 bool ExternalStorage::Abort() {
84 return Finalize(false);
87 const std::vector<std::string>& ExternalStorage::external_dirs() const {
88 return external_dirs_;
91 bool ExternalStorage::Initialize(
92 const boost::filesystem::path& space_requirement) {
93 // external size in MB, set any-non zero size as default
94 int external_size = 1;
96 if (!space_requirement.empty()) {
97 if (package_type_ == kWgtType) {
98 for (auto& dir : kExternalDirsForTpk) {
99 bf::path requirement = space_requirement / dir;
100 if (!bf::exists(requirement))
103 SizeInMB(GetDirectorySize(requirement));
106 // for wgt whole content of package goes to res/
108 SizeInMB(GetDirectorySize(space_requirement));
112 if (external_size == 0)
115 handle_ = app2ext_init(APP2EXT_SD_CARD);
117 LOG(ERROR) << "app2ext_init() failed";
121 GList* glist = nullptr;
122 for (auto& dir : external_dirs_) {
123 app2ext_dir_details* dir_detail = reinterpret_cast<app2ext_dir_details*>(
124 calloc(1, sizeof(app2ext_dir_details)));
125 dir_detail->name = strdup(dir.c_str());
126 dir_detail->type = APP2EXT_DIR_RO;
127 glist = g_list_append(glist, dir_detail);
132 case RequestType::Install:
133 ret = handle_->interface.client_usr_pre_install(pkgid_.c_str(), glist,
134 external_size, uid_);
136 case RequestType::Update:
137 case RequestType::Delta:
138 ret = handle_->interface.client_usr_pre_upgrade(pkgid_.c_str(), glist,
139 external_size, uid_);
141 case RequestType::Uninstall:
142 ret = handle_->interface.client_usr_pre_uninstall(pkgid_.c_str(), uid_);
144 case RequestType::Clear:
145 case RequestType::Reinstall:
146 case RequestType::Recovery:
147 case RequestType::ManifestDirectInstall:
148 case RequestType::ManifestDirectUpdate:
149 case RequestType::MountInstall:
150 case RequestType::MountUpdate:
151 LOG(ERROR) << "Installation type is not supported by external installation";
155 assert(false && "Invalid installation mode");
158 g_list_free_full(glist, [](gpointer data) {
159 app2ext_dir_details* dir_detail =
160 reinterpret_cast<app2ext_dir_details*>(data);
161 free(dir_detail->name);
167 std::unique_ptr<ExternalStorage> ExternalStorage::AcquireExternalStorage(
168 RequestType type, const boost::filesystem::path& application_root,
169 const std::string& pkgid, const std::string& package_type,
170 const boost::filesystem::path& space_requirement,
172 std::unique_ptr<ExternalStorage> external_storage(
173 new ExternalStorage(type, pkgid, package_type, application_root, uid));
174 if (!external_storage->Initialize(space_requirement)) {
175 LOG(WARNING) << "Cannot initialize external storage for request";
178 return external_storage;
181 } // namespace common_installer