1 // Copyright (c) 2016 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/tzip_interface.h"
7 #include <manifest_parser/utils/logging.h>
16 namespace fs = std::filesystem;
20 const char kTzipBusName[] = "org.tizen.system.deviced";
21 const char kTzipObjectPath[] = "/Org/Tizen/System/DeviceD/Tzip";
22 const char kTzipInterfaceName[] = "org.tizen.system.deviced.Tzip";
23 const char kTzipMountMethod[] = "Mount";
24 const char kTzipUnmountMethod[] = "Unmount";
25 const char kTzipIsMountedMethod[] = "IsMounted";
26 const char kTzipSmackRule[] = "User::Home";
27 const int kTzipMountMaximumRetryCount = 15;
31 namespace common_installer {
35 DBusProxy() : conn_(nullptr), proxy_(nullptr) {
37 LOG(ERROR) << "Failed to initialize DBus proxy";
42 g_object_unref(proxy_);
44 g_dbus_connection_flush_sync(conn_, nullptr, nullptr);
45 g_object_unref(conn_);
50 GError* error = nullptr;
51 conn_ = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, &error);
52 if (!conn_ || error) {
53 LOG(ERROR) << "g_bus_get_sync() failed: " << error->message;
57 proxy_ = g_dbus_proxy_new_sync(conn_, G_DBUS_PROXY_FLAGS_NONE, nullptr,
58 kTzipBusName, kTzipObjectPath, kTzipInterfaceName, nullptr, &error);
59 if (!proxy_ || error) {
60 LOG(ERROR) << "g_dbus_proxy_new_sync() failed: " << error->message;
67 GVariant* ProxyCallSync(const char* method, GVariant* params) {
69 LOG(ERROR) << "DBus proxy is not initialized";
72 GError* error = nullptr;
73 GVariant* ret = g_dbus_proxy_call_sync(proxy_, method,
74 params, G_DBUS_CALL_FLAGS_NONE, -1, nullptr, &error);
76 LOG(ERROR) << "g_dbus_proxy_call_sync() of " << method << " failed: "
84 GDBusConnection* conn_;
88 class TzipInterface::Pimpl {
90 explicit Pimpl(const std::filesystem::path& mount_path) :
91 mount_path_(mount_path), dbus_proxy_(new DBusProxy()) { }
93 bool MountZip(const std::filesystem::path& zip_path) {
97 LOG(WARNING) << "Mount path(" << mount_path_
98 << ") already mounted, try to unmount";
102 if (fs::exists(mount_path_)) {
103 LOG(WARNING) << "Mount path(" << mount_path_ << ") already exists! "
104 << "We will remove it...";
105 fs::remove(mount_path_);
108 if (!fs::exists(zip_path)) {
109 LOG(WARNING) << "zip path(" << zip_path << ") doesn't exist!";
113 const char* mount_path_str = mount_path_.c_str();
114 const char* zip_path_str = zip_path_.c_str();
115 const char* tzip_smack_rule = kTzipSmackRule;
117 GVariant* r = dbus_proxy_->ProxyCallSync(kTzipMountMethod,
118 g_variant_new("(sss)", mount_path_str, zip_path_str, tzip_smack_rule));
120 LOG(ERROR) << "Could not send DBUS message when mounting zip file";
125 return WaitForCondition([=]()->bool {
131 const char* mount_path_str = mount_path_.c_str();
133 GVariant* r = dbus_proxy_->ProxyCallSync(kTzipUnmountMethod,
134 g_variant_new("(s)", mount_path_str));
136 LOG(ERROR) << "Could not send DBUS message when unmounting zip file";
141 return WaitForCondition([=]()->bool {
142 return IsUnmounted();
148 const char* mount_path_str = mount_path_.c_str();
149 GVariant* r = dbus_proxy_->ProxyCallSync(kTzipIsMountedMethod,
150 g_variant_new("(s)", mount_path_str));
155 g_variant_get(r, "(i)", &ret);
164 bool WaitForCondition(std::function<bool()> condition) {
165 if (!mount_path_.empty()) {
168 while (cnt < kTzipMountMaximumRetryCount) {
183 std::filesystem::path mount_path_;
184 std::filesystem::path zip_path_;
185 std::unique_ptr<DBusProxy> dbus_proxy_;
188 TzipInterface::TzipInterface(const std::filesystem::path& mount_path)
189 : impl_(new Pimpl(mount_path)) {}
191 TzipInterface::~TzipInterface() { }
193 bool TzipInterface::MountZip(const std::filesystem::path& zip_path) {
194 return impl_->MountZip(zip_path);
197 bool TzipInterface::UnmountZip() {
198 return impl_->UnmountZip();
201 } // namespace common_installer