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>
10 #include <boost/filesystem.hpp>
16 #include "common/pkgmgr_interface.h"
17 #include "common/utils/pkgmgr_query.h"
18 #include "common/utils/file_util.h"
20 namespace bf = boost::filesystem;
21 namespace ci = common_installer;
23 namespace common_installer {
24 namespace configuration {
26 StepParsePreload::StepParsePreload(ci::InstallerContext* context)
27 : Step(context), req_type_(RequestType::Unknown), pkg_query_(nullptr) {
30 ci::Step::Status StepParsePreload::AdjustReadonly() {
31 if (context_->manifest_data.get()->readonly &&
32 strlen(context_->manifest_data.get()->readonly) != 0)
35 free(context_->manifest_data.get()->readonly);
37 if (context_->is_readonly_package.get()) {
38 context_->manifest_data.get()->readonly = strdup("true");
39 if (getuid() != 0 && req_type_ != RequestType::ReadonlyUpdateUninstall) {
40 LOG(ERROR) << "You're not authorized to install readonly app: "
41 << context_->pkgid.get().c_str();
42 return Status::OPERATION_NOT_ALLOWED;
45 context_->manifest_data.get()->readonly = strdup("false");
48 if (!context_->manifest_data.get()->readonly) {
49 LOG(ERROR) << "Out of memory";
56 ci::Step::Status StepParsePreload::AdjustPreload() {
57 if (context_->manifest_data.get()->preload &&
58 strlen(context_->manifest_data.get()->preload) != 0)
61 free(context_->manifest_data.get()->preload);
62 if (req_type_ == RequestType::Update ||
63 req_type_ == RequestType::Delta ||
64 req_type_ == RequestType::MountUpdate ||
65 req_type_ == RequestType::ReadonlyUpdateInstall) {
66 // In case of update, keep preload value
67 bool is_preload = pkg_query_->IsPreloadPackage();
68 context_->manifest_data.get()->preload =
69 strdup(is_preload ? "true" : "false");
70 } else if (req_type_ == RequestType::ManifestDirectUpdate &&
71 pkg_query_->IsPreloadPackage() &&
72 !context_->is_readonly_package.get()) {
73 context_->manifest_data.get()->preload = strdup("true");
75 if (context_->is_readonly_package.get() ||
76 context_->is_preload_rw_package.get())
77 context_->manifest_data.get()->preload = strdup("true");
79 context_->manifest_data.get()->preload = strdup("false");
82 if (!context_->manifest_data.get()->preload) {
83 LOG(ERROR) << "Out of memory";
90 ci::Step::Status StepParsePreload::AdjustRemovable() {
91 // In case of update, keep removable value
92 if (req_type_ == RequestType::Update ||
93 req_type_ == RequestType::Delta ||
94 req_type_ == RequestType::MountUpdate) {
95 bool is_removable = pkg_query_->IsRemovablePackage();
96 context_->manifest_data.get()->removable =
97 strdup(is_removable ? "true" : "false");
98 if (!context_->manifest_data.get()->removable) {
99 LOG(ERROR) << "Out of memoery";
100 return Status::ERROR;
105 const char* removable_val = context_->manifest_data.get()->removable;
106 if (removable_val && strlen(removable_val) != 0)
109 free(context_->manifest_data.get()->removable);
110 if (context_->no_remove.get() ||
111 context_->is_readonly_package.get())
112 context_->manifest_data.get()->removable = strdup("false");
114 context_->manifest_data.get()->removable = strdup("true");
116 if (!context_->manifest_data.get()->removable) {
117 LOG(ERROR) << "Out of memoery";
118 return Status::ERROR;
124 bool StepParsePreload::ValidateAttrs() {
126 (strcmp(context_->manifest_data.get()->readonly, "true") == 0);
128 (strcmp(context_->manifest_data.get()->preload, "true") == 0);
130 (strcmp(context_->manifest_data.get()->removable, "true") == 0);
132 if (is_readonly && !is_preload) {
133 LOG(ERROR) << "invalid preload attribute, readonly but not preload!";
137 if (is_readonly && is_removable) {
138 LOG(ERROR) << "invalid preload attribute, readonly but removable!";
142 if (!is_preload && !is_removable) {
143 LOG(ERROR) << "invalid preload attribute, no preload but not removable!";
150 ci::Step::Status StepParsePreload::AdjustUpdate() {
151 manifest_x* manifest = context_->manifest_data.get();
153 free(manifest->update);
154 // set update false when ReadonlyUpdateUninstall
155 if (req_type_ == RequestType::ReadonlyUpdateUninstall)
156 manifest->update = strdup("false");
157 // set update true if package is updated preload package
158 else if (pkg_query_->IsUpdatedPackage())
159 manifest->update = strdup("true");
160 // set update true when update non-removable preload package
161 else if (pkg_query_->IsPreloadPackage() &&
162 (req_type_ == RequestType::Update ||
163 req_type_ == RequestType::Delta ||
164 req_type_ == RequestType::MountUpdate ||
165 req_type_ == RequestType::ReadonlyUpdateInstall ||
166 (req_type_ == RequestType::ManifestDirectUpdate &&
167 !context_->is_readonly_package.get())))
168 manifest->update = strdup("true");
170 manifest->update = strdup("false");
172 if (!manifest->update) {
173 LOG(ERROR) << "Out of memory";
174 return Status::ERROR;
180 ci::Step::Status StepParsePreload::AdjustSystem() {
181 manifest_x* manifest = context_->manifest_data.get();
183 free(manifest->system);
184 // set system true when install RO preload package
185 if (context_->is_readonly_package.get() ||
186 (manifest->readonly && !strcmp(manifest->readonly, "true")))
187 manifest->system = strdup("true");
188 // set system true when install non-removable RW preload package
190 (context_->is_preload_rw_package.get() ||
191 (manifest->preload && !strcmp(manifest->preload, "true"))) &&
192 (context_->no_remove.get() ||
193 (manifest->removable && !strcmp(manifest->removable, "false"))))
194 manifest->system = strdup("true");
195 // set system false when update non-removable RW preload package
196 else if (pkg_query_->IsSystemPackage() &&
197 !pkg_query_->IsReadonlyPackage() &&
198 !pkg_query_->IsUpdatedPackage())
199 manifest->system = strdup("false");
200 // set system true when update RO preload package
201 else if (req_type_ == RequestType::ReadonlyUpdateInstall ||
202 req_type_ == RequestType::ReadonlyUpdateUninstall ||
203 pkg_query_->IsSystemPackage())
204 manifest->system = strdup("true");
206 manifest->system = strdup("false");
208 if (!manifest->system) {
209 LOG(ERROR) << "Out of memory";
210 return Status::ERROR;
216 ci::Step::Status StepParsePreload::AdjustOldManifest() {
217 manifest_x* old_manifest = context_->old_manifest_data.get();
221 free(old_manifest->system);
222 // keep system value for undo operation
223 if (pkg_query_->IsSystemPackage())
224 old_manifest->system = strdup("true");
226 old_manifest->system = strdup("false");
227 if (!old_manifest->system) {
228 LOG(ERROR) << "Out of memory";
229 return Status::ERROR;
232 free(old_manifest->update);
233 // keep update value for undo operation
234 if (pkg_query_->IsUpdatedPackage())
235 old_manifest->update = strdup("true");
237 old_manifest->update = strdup("false");
238 if (!old_manifest->update) {
239 LOG(ERROR) << "Out of memory";
240 return Status::ERROR;
246 ci::Step::Status StepParsePreload::process() {
247 req_type_ = context_->request_type.get();
249 new PkgQueryInterface(context_->pkgid.get(), context_->uid.get()));
251 Status ret = AdjustReadonly();
252 if (ret != Status::OK)
255 ret = AdjustPreload();
256 if (ret != Status::OK)
259 ret = AdjustRemovable();
260 if (ret != Status::OK)
263 if (!ValidateAttrs())
264 return Status::MANIFEST_ERROR;
266 ret = AdjustUpdate();
267 if (ret != Status::OK)
270 ret = AdjustSystem();
271 if (ret != Status::OK)
274 ret = AdjustOldManifest();
275 if (ret != Status::OK)
281 } // namespace configuration
282 } // namespace common_installer