1 // Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by a apache 2.0 license that can be
3 // found in the LICENSE file.
5 #include "common/step/configuration/step_parse_preload.h"
7 #include <pkgmgr-info.h>
14 #include "common/pkgmgr_interface.h"
15 #include "common/utils/pkgmgr_query.h"
16 #include "common/utils/file_util.h"
18 namespace ci = common_installer;
20 namespace common_installer {
21 namespace configuration {
23 StepParsePreload::StepParsePreload(ci::InstallerContext* context)
24 : Step(context), req_type_(RequestType::Unknown), pkg_query_(nullptr) {
27 ci::Step::Status StepParsePreload::AdjustReadonly() {
28 if (context_->manifest_data.get()->readonly &&
29 strlen(context_->manifest_data.get()->readonly) != 0)
32 free(context_->manifest_data.get()->readonly);
34 if (context_->is_readonly_package.get()) {
35 context_->manifest_data.get()->readonly = strdup("true");
36 if (getuid() != 0 && req_type_ != RequestType::ReadonlyUpdateUninstall) {
37 LOG(ERROR) << "You're not authorized to install readonly app: "
38 << context_->pkgid.get().c_str();
39 return Status::OPERATION_NOT_ALLOWED;
42 context_->manifest_data.get()->readonly = strdup("false");
45 if (!context_->manifest_data.get()->readonly) {
46 LOG(ERROR) << "Out of memory";
53 ci::Step::Status StepParsePreload::AdjustPreload() {
54 if (context_->manifest_data.get()->preload &&
55 strlen(context_->manifest_data.get()->preload) != 0)
58 free(context_->manifest_data.get()->preload);
59 if (req_type_ == RequestType::Update ||
60 req_type_ == RequestType::Delta ||
61 req_type_ == RequestType::MountUpdate ||
62 req_type_ == RequestType::ReadonlyUpdateInstall) {
63 // In case of update, keep preload value
64 bool is_preload = pkg_query_->IsPreloadPackage();
65 context_->manifest_data.get()->preload =
66 strdup(is_preload ? "true" : "false");
67 } else if (req_type_ == RequestType::ManifestDirectUpdate &&
68 pkg_query_->IsPreloadPackage() &&
69 !context_->is_readonly_package.get()) {
70 context_->manifest_data.get()->preload = strdup("true");
72 if (context_->is_readonly_package.get() ||
73 context_->is_preload_rw_package.get())
74 context_->manifest_data.get()->preload = strdup("true");
76 context_->manifest_data.get()->preload = strdup("false");
79 if (!context_->manifest_data.get()->preload) {
80 LOG(ERROR) << "Out of memory";
87 ci::Step::Status StepParsePreload::AdjustRemovable() {
88 // In case of update, keep removable value
89 if (req_type_ == RequestType::Update ||
90 req_type_ == RequestType::Delta ||
91 req_type_ == RequestType::MountUpdate) {
92 bool is_removable = pkg_query_->IsRemovablePackage();
93 context_->manifest_data.get()->removable =
94 strdup(is_removable ? "true" : "false");
95 if (!context_->manifest_data.get()->removable) {
96 LOG(ERROR) << "Out of memoery";
102 const char* removable_val = context_->manifest_data.get()->removable;
103 if (removable_val && strlen(removable_val) != 0)
106 free(context_->manifest_data.get()->removable);
107 if (context_->no_remove.get() ||
108 context_->is_readonly_package.get())
109 context_->manifest_data.get()->removable = strdup("false");
111 context_->manifest_data.get()->removable = strdup("true");
113 if (!context_->manifest_data.get()->removable) {
114 LOG(ERROR) << "Out of memoery";
115 return Status::ERROR;
121 bool StepParsePreload::ValidateAttrs() {
123 (strcmp(context_->manifest_data.get()->readonly, "true") == 0);
125 (strcmp(context_->manifest_data.get()->preload, "true") == 0);
127 (strcmp(context_->manifest_data.get()->removable, "true") == 0);
129 if (is_readonly && !is_preload) {
130 LOG(ERROR) << "invalid preload attribute, readonly but not preload!";
134 if (is_readonly && is_removable) {
135 LOG(ERROR) << "invalid preload attribute, readonly but removable!";
139 if (!is_preload && !is_removable) {
140 LOG(ERROR) << "invalid preload attribute, no preload but not removable!";
147 ci::Step::Status StepParsePreload::AdjustUpdate() {
148 manifest_x* manifest = context_->manifest_data.get();
150 free(manifest->update);
151 // set update false when ReadonlyUpdateUninstall
152 if (req_type_ == RequestType::ReadonlyUpdateUninstall)
153 manifest->update = strdup("false");
154 // set update true if package is updated preload package
155 else if (pkg_query_->IsUpdatedPackage())
156 manifest->update = strdup("true");
157 // set update true when update non-removable preload package
158 else if (pkg_query_->IsPreloadPackage() &&
159 (req_type_ == RequestType::Update ||
160 req_type_ == RequestType::Delta ||
161 req_type_ == RequestType::MountUpdate ||
162 req_type_ == RequestType::ReadonlyUpdateInstall ||
163 (req_type_ == RequestType::ManifestDirectUpdate &&
164 !context_->is_readonly_package.get())))
165 manifest->update = strdup("true");
167 manifest->update = strdup("false");
169 if (!manifest->update) {
170 LOG(ERROR) << "Out of memory";
171 return Status::ERROR;
177 ci::Step::Status StepParsePreload::AdjustSystem() {
178 manifest_x* manifest = context_->manifest_data.get();
180 free(manifest->system);
181 // set system true when install RO preload package
182 if (context_->is_readonly_package.get() ||
183 (manifest->readonly && !strcmp(manifest->readonly, "true")))
184 manifest->system = strdup("true");
185 // set system true when install non-removable RW preload package
187 (context_->is_preload_rw_package.get() ||
188 (manifest->preload && !strcmp(manifest->preload, "true"))) &&
189 (context_->no_remove.get() ||
190 (manifest->removable && !strcmp(manifest->removable, "false"))))
191 manifest->system = strdup("true");
192 // set system false when update non-removable RW preload package
193 else if (pkg_query_->IsSystemPackage() &&
194 !pkg_query_->IsReadonlyPackage() &&
195 !pkg_query_->IsUpdatedPackage())
196 manifest->system = strdup("false");
197 // set system true when update RO preload package
198 else if (req_type_ == RequestType::ReadonlyUpdateInstall ||
199 req_type_ == RequestType::ReadonlyUpdateUninstall ||
200 pkg_query_->IsSystemPackage())
201 manifest->system = strdup("true");
203 manifest->system = strdup("false");
205 if (!manifest->system) {
206 LOG(ERROR) << "Out of memory";
207 return Status::ERROR;
213 ci::Step::Status StepParsePreload::AdjustOldManifest() {
214 manifest_x* old_manifest = context_->old_manifest_data.get();
218 free(old_manifest->system);
219 // keep system value for undo operation
220 if (pkg_query_->IsSystemPackage())
221 old_manifest->system = strdup("true");
223 old_manifest->system = strdup("false");
224 if (!old_manifest->system) {
225 LOG(ERROR) << "Out of memory";
226 return Status::ERROR;
229 free(old_manifest->update);
230 // keep update value for undo operation
231 if (pkg_query_->IsUpdatedPackage())
232 old_manifest->update = strdup("true");
234 old_manifest->update = strdup("false");
235 if (!old_manifest->update) {
236 LOG(ERROR) << "Out of memory";
237 return Status::ERROR;
243 ci::Step::Status StepParsePreload::process() {
244 req_type_ = context_->request_type.get();
246 new PkgQueryInterface(context_->pkgid.get(), context_->uid.get()));
248 Status ret = AdjustReadonly();
249 if (ret != Status::OK)
252 ret = AdjustPreload();
253 if (ret != Status::OK)
256 ret = AdjustRemovable();
257 if (ret != Status::OK)
260 if (!ValidateAttrs())
261 return Status::MANIFEST_ERROR;
263 ret = AdjustUpdate();
264 if (ret != Status::OK)
267 ret = AdjustSystem();
268 if (ret != Status::OK)
271 ret = AdjustOldManifest();
272 if (ret != Status::OK)
278 } // namespace configuration
279 } // namespace common_installer