privileges.cc
app_installer.cc
certificate_validation.cc
+ external_mount.cc
external_storage.cc
feature_validator.cc
installer_context.cc
step/filesystem/step_create_legacy_directories.cc
step/filesystem/step_create_storage_directories.cc
step/filesystem/step_delta_patch.cc
+ step/filesystem/step_disable_external_mount.cc
+ step/filesystem/step_enable_external_mount.cc
step/filesystem/step_move_installed_storage.cc
step/filesystem/step_recover_files.cc
step/filesystem/step_recover_icons.cc
--- /dev/null
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache 2.0 license that can be
+// found in the LICENSE file.
+
+#include "common/external_mount.h"
+
+#include <app2ext_interface.h>
+#include <manifest_parser/utils/logging.h>
+
+namespace common_installer {
+
+ExternalMount::ExternalMount(const std::string& pkgid, uid_t uid)
+ : pkgid_(pkgid),
+ uid_(uid),
+ mounted_(false) {
+}
+
+ExternalMount::~ExternalMount() {
+ if (mounted_) {
+ int ret = app2ext_usr_disable_external_pkg(pkgid_.c_str(), uid_);
+ if (ret < 0) {
+ LOG(ERROR) << "app2ext_usr_disable_external_pkg failed with error code: "
+ << ret;
+ }
+ }
+}
+
+bool ExternalMount::IsAvailable() const {
+ return app2ext_usr_get_app_location(pkgid_.c_str(), uid_) == APP2EXT_SD_CARD;
+}
+
+bool ExternalMount::Mount() {
+ if (mounted_)
+ return true;
+ int ret = app2ext_usr_enable_external_pkg(pkgid_.c_str(), uid_);
+ if (ret < 0) {
+ LOG(ERROR) << "app2ext_usr_enable_external_pkg failed with error code: "
+ << ret;
+ return false;
+ }
+ mounted_ = true;
+ return true;
+}
+
+bool ExternalMount::Umount() {
+ if (!mounted_)
+ return true;
+ int ret = app2ext_usr_disable_external_pkg(pkgid_.c_str(), uid_);
+ if (ret < 0) {
+ LOG(ERROR) << "app2ext_usr_disable_external_pkg failed with error code: "
+ << ret;
+ return false;
+ }
+ mounted_ = false;
+ return true;
+}
+
+} // namespace common_installer
--- /dev/null
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache 2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_EXTERNAL_MOUNT_H_
+#define COMMON_EXTERNAL_MOUNT_H_
+
+#include <unistd.h>
+
+#include <string>
+
+namespace common_installer {
+
+/**
+ * @brief The ExternalMount class
+ * Class used to mount package content for runtime.
+ *
+ * This class is used by delta update mode to get old content of package to
+ * create the new content of package.
+ */
+class ExternalMount {
+ public:
+ ExternalMount(const std::string& pkgid, uid_t uid);
+ ~ExternalMount();
+
+ bool IsAvailable() const;
+ bool Mount();
+ bool Umount();
+
+ private:
+ std::string pkgid_;
+ uid_t uid_;
+ bool mounted_;
+};
+
+} // namespace common_installer
+
+#endif // COMMON_EXTERNAL_MOUNT_H_
bool ExternalStorage::Finalize(bool success) {
int ret = APP2EXT_STATUS_SUCCESS;
switch (type_) {
- case RequestType::Install: {
+ case RequestType::Install:
ret = handle_->interface.client_usr_post_install(pkgid_.c_str(),
success ? APP2EXT_STATUS_SUCCESS : APP2EXT_STATUS_FAILED, uid_);
break;
- }
- case RequestType::Update: {
+ case RequestType::Update:
+ case RequestType::Delta:
ret = handle_->interface.client_usr_post_upgrade(pkgid_.c_str(),
success ? APP2EXT_STATUS_SUCCESS : APP2EXT_STATUS_FAILED, uid_);
break;
- }
- case RequestType::Uninstall: {
+ case RequestType::Uninstall:
ret = handle_->interface.client_usr_post_uninstall(pkgid_.c_str(), uid_);
break;
- }
- case RequestType::Move: {
+ case RequestType::Move:
ret = handle_->interface.client_usr_post_move(pkgid_.c_str(),
static_cast<app2ext_move_type_t>(move_type_),
uid_);
break;
- }
default:
assert(false && "Not supported installation mode");
}
namespace common_installer {
+/**
+ * @brief The ExternalStorage class
+ * Encapsulates mounting package in external memory for performing
+ * installation request.
+ */
class ExternalStorage final {
public:
static std::unique_ptr<ExternalStorage> MoveInstalledStorage(
#include <utility>
#include <vector>
+#include "common/external_mount.h"
#include "common/external_storage.h"
#include "common/pkgmgr_interface.h"
#include "common/recovery_file.h"
* @brief External Storage object if installing in external
*/
std::unique_ptr<ExternalStorage> external_storage;
+
+ /**
+ * @brief External package mount object if delta update with external
+ */
+ std::unique_ptr<ExternalMount> external_mount;
};
} // namespace common_installer
#include <sys/wait.h>
#include <unistd.h>
+#include <algorithm>
#include <cstdlib>
#include "common/utils/file_util.h"
const char kDeltaFile[] = "delta_info.xml";
const char kXDeltaBinary[] = "/usr/bin/xdelta3";
+const char kExternalMemoryMountPoint[] = ".mmc";
+
bool ValidateDeltaInfo(const delta::DeltaInfo& info) {
for (auto& item : info.added()) {
if (ci::HasDirectoryClimbing(item))
return true;
}
+bool CopySkipMount(const bf::path& from, const bf::path& to) {
+ bs::error_code error;
+ bf::create_directory(to, error);
+ if (error) {
+ LOG(ERROR) << "Failed to create target directory";
+ return false;
+ }
+ for (bf::directory_iterator iter(from); iter != bf::directory_iterator();
+ ++iter) {
+ if (iter->path().filename() == kExternalMemoryMountPoint)
+ continue;
+
+ if (bf::is_directory(iter->path())) {
+ if (!ci::CopyDir(iter->path(), to / iter->path().filename())) {
+ LOG(ERROR) << "Failed to create copy of: " << iter->path();
+ return false;
+ }
+ } else {
+ bs::error_code error;
+ bf::copy(iter->path(), to / iter->path().filename(), error);
+ if (error) {
+ LOG(ERROR) << "Failed to create copy of: " << iter->path();
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
} // namespace
namespace common_installer {
return Status::DELTA_ERROR;
}
- if (!CopyDir(context_->root_application_path.get() / context_->pkgid.get()
- / delta_root_, context_->unpacked_dir_path.get())) {
+ if (!CopySkipMount(
+ context_->root_application_path.get() / context_->pkgid.get()
+ / delta_root_,
+ context_->unpacked_dir_path.get())) {
LOG(ERROR) << "Failed to copy package files";
return Status::DELTA_ERROR;
}
--- /dev/null
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache 2.0 license that can be
+// found in the LICENSE file.
+
+#include "common/step/filesystem/step_disable_external_mount.h"
+
+namespace common_installer {
+namespace filesystem {
+
+Step::Status StepDisableExternalMount::process() {
+ if (context_->external_mount) {
+ if (!context_->external_mount->Umount()) {
+ LOG(ERROR) << "Failed to unmount package for request";
+ return Status::APP_DIR_ERROR;
+ }
+ }
+ context_->external_mount.reset();
+ LOG(DEBUG) << "External mount removed";
+ return Status::OK;
+}
+
+} // namespace filesystem
+} // namespace common_installer
--- /dev/null
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache 2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_STEP_FILESYSTEM_STEP_DISABLE_EXTERNAL_MOUNT_H_
+#define COMMON_STEP_FILESYSTEM_STEP_DISABLE_EXTERNAL_MOUNT_H_
+
+#include <manifest_parser/utils/logging.h>
+
+#include "common/installer_context.h"
+#include "common/step/step.h"
+
+namespace common_installer {
+namespace filesystem {
+
+class StepDisableExternalMount : public Step {
+ public:
+ using Step::Step;
+
+ Status process() override;
+ Status clean() override { return Status::OK; }
+ Status undo() override { return Status::OK; }
+ Status precheck() override { return Status::OK; }
+
+ STEP_NAME(StepDisableExternalMount)
+};
+
+} // namespace filesystem
+} // namespace common_installer
+
+#endif // COMMON_STEP_FILESYSTEM_STEP_DISABLE_EXTERNAL_MOUNT_H_
--- /dev/null
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache 2.0 license that can be
+// found in the LICENSE file.
+
+#include "common/step/filesystem/step_enable_external_mount.h"
+
+#include "common/external_mount.h"
+
+namespace common_installer {
+namespace filesystem {
+
+Step::Status StepEnableExternalMount::process() {
+ std::unique_ptr<ExternalMount> mount(new ExternalMount(context_->pkgid.get(),
+ context_->uid.get()));
+ if (!mount->IsAvailable()) {
+ LOG(DEBUG) << "External mount not available for package";
+ return Status::OK;
+ }
+
+ if (!mount->Mount()) {
+ LOG(ERROR) << "Failed to mount package for request";
+ return Status::APP_DIR_ERROR;
+ }
+ context_->external_mount = std::move(mount);
+ LOG(DEBUG) << "External mount created";
+ return Status::OK;
+}
+
+Step::Status StepEnableExternalMount::undo() {
+ if (context_->external_mount) {
+ if (!context_->external_mount->Umount()) {
+ LOG(ERROR) << "Failed to unmount package";
+ return Status::APP_DIR_ERROR;
+ }
+ }
+ return Status::OK;
+}
+
+} // namespace filesystem
+} // namespace common_installer
+
--- /dev/null
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache 2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_STEP_FILESYSTEM_STEP_ENABLE_EXTERNAL_MOUNT_H_
+#define COMMON_STEP_FILESYSTEM_STEP_ENABLE_EXTERNAL_MOUNT_H_
+
+#include <manifest_parser/utils/logging.h>
+
+#include "common/installer_context.h"
+#include "common/step/step.h"
+
+namespace common_installer {
+namespace filesystem {
+
+class StepEnableExternalMount : public Step {
+ public:
+ using Step::Step;
+
+ Status process() override;
+ Status clean() override { return Status::OK; }
+ Status undo() override;
+ Status precheck() override { return Status::OK; }
+
+ STEP_NAME(StepEnableExternalMount)
+};
+
+} // namespace filesystem
+} // namespace common_installer
+
+#endif // COMMON_STEP_FILESYSTEM_STEP_ENABLE_EXTERNAL_MOUNT_H_