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>
9 #include <boost/filesystem.hpp>
17 namespace bf = boost::filesystem;
21 const char kTzipBusName[] = "org.tizen.system.deviced";
22 const char kTzipObjectPath[] = "/Org/Tizen/System/DeviceD/Tzip";
23 const char kTzipInterfaceName[] = "org.tizen.system.deviced.Tzip";
24 const char kTzipMountMethod[] = "Mount";
25 const char kTzipUnmountMethod[] = "Unmount";
26 const char kTzipIsMountedMethod[] = "IsMounted";
27 const char kTzipSmackRule[] = "User::Home";
28 const int kTzipMountMaximumRetryCount = 15;
32 namespace common_installer {
36 DBusProxy() : conn_(nullptr), proxy_(nullptr) {
38 LOG(ERROR) << "Failed to initialize DBus proxy";
43 g_object_unref(proxy_);
45 g_dbus_connection_flush_sync(conn_, nullptr, nullptr);
46 g_object_unref(conn_);
51 GError* error = nullptr;
52 conn_ = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, &error);
53 if (!conn_ || error) {
54 LOG(ERROR) << "g_bus_get_sync() failed: " << error->message;
58 proxy_ = g_dbus_proxy_new_sync(conn_, G_DBUS_PROXY_FLAGS_NONE, nullptr,
59 kTzipBusName, kTzipObjectPath, kTzipInterfaceName, nullptr, &error);
60 if (!proxy_ || error) {
61 LOG(ERROR) << "g_dbus_proxy_new_sync() failed: " << error->message;
68 GVariant* ProxyCallSync(const char* method, GVariant* params) {
70 LOG(ERROR) << "DBus proxy is not initialized";
73 GError* error = nullptr;
74 GVariant* ret = g_dbus_proxy_call_sync(proxy_, method,
75 params, G_DBUS_CALL_FLAGS_NONE, -1, nullptr, &error);
77 LOG(ERROR) << "g_dbus_proxy_call_sync() of " << method << " failed: "
85 GDBusConnection* conn_;
89 class TzipInterface::Pimpl {
91 explicit Pimpl(const boost::filesystem::path& mount_path) :
92 mount_path_(mount_path), dbus_proxy_(new DBusProxy()) { }
94 bool MountZip(const boost::filesystem::path& zip_path) {
97 if (bf::exists(mount_path_)) {
98 LOG(WARNING) << "Mount path(" << mount_path_ << ") already exists! "
99 << "We will remove it...";
100 bf::remove(mount_path_);
103 if (!bf::exists(zip_path)) {
104 LOG(WARNING) << "zip path(" << zip_path << ") doesn't exist!";
108 const char* mount_path_str = mount_path_.string().c_str();
109 const char* zip_path_str = zip_path_.string().c_str();
110 const char* tzip_smack_rule = kTzipSmackRule;
112 GVariant* r = dbus_proxy_->ProxyCallSync(kTzipMountMethod,
113 g_variant_new("(sss)", mount_path_str, zip_path_str, tzip_smack_rule));
115 LOG(ERROR) << "Could not send DBUS message when mounting zip file";
120 return WaitForCondition([=](bool *success)->bool {
121 return IsMounted(success);
126 const char* mount_path_str = mount_path_.string().c_str();
128 GVariant* r = dbus_proxy_->ProxyCallSync(kTzipUnmountMethod,
129 g_variant_new("(s)", mount_path_str));
131 LOG(ERROR) << "Could not send DBUS message when unmounting zip file";
136 return WaitForCondition([=](bool *success)->bool {
137 return IsUnmounted(success);
142 bool IsMounted(bool *success) {
143 const char* mount_path_str = mount_path_.string().c_str();
144 GVariant* r = dbus_proxy_->ProxyCallSync(kTzipIsMountedMethod,
145 g_variant_new("(s)", mount_path_str));
152 g_variant_get(r, "(i)", &ret);
158 bool IsUnmounted(bool *success) {
159 return !IsMounted(success);
162 bool WaitForCondition(std::function<bool(bool*)> condition) {
163 if (!mount_path_.empty()) {
166 while (cnt < kTzipMountMaximumRetryCount) {
168 rv = condition(&success);
182 boost::filesystem::path mount_path_;
183 boost::filesystem::path zip_path_;
184 std::unique_ptr<DBusProxy> dbus_proxy_;
187 TzipInterface::TzipInterface(const boost::filesystem::path& mount_path)
188 : impl_(new Pimpl(mount_path)) {}
190 TzipInterface::~TzipInterface() { }
192 bool TzipInterface::MountZip(const boost::filesystem::path& zip_path) {
193 return impl_->MountZip(zip_path);
196 bool TzipInterface::UnmountZip() {
197 return impl_->UnmountZip();
200 } // namespace common_installer