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>
11 #include <dbus/dbus.h>
15 namespace bf = boost::filesystem;
19 const char kTzipBusName[] = "org.tizen.system.deviced";
20 const char kTzipObjectPath[] = "/Org/Tizen/System/DeviceD/Tzip";
21 const char kTzipInterfaceName[] = "org.tizen.system.deviced.Tzip";
22 const char kTzipMountMethod[] = "Mount";
23 const char kTzipUnmountMethod[] = "Unmount";
24 const char kTzipIsMountedMethod[] = "IsMounted";
25 const char kTzipSmackRule[] = "User::Home";
26 const int kTzipMountMaximumRetryCount = 15;
30 void DBusMessageDeleter(DBusMessage* message) {
31 dbus_message_unref(message);
34 void DBusErrorDeleter(DBusError* error) {
35 dbus_error_free(error);
36 std::default_delete<DBusError>();
39 namespace common_installer {
41 class TzipInterface::Pimpl {
43 explicit Pimpl(const boost::filesystem::path& mount_path) :
44 mount_path_(mount_path) { }
46 bool MountZip(const boost::filesystem::path& zip_path) {
49 DBusConnection *conn = dbus_bus_get(DBUS_BUS_SYSTEM, nullptr);
54 if (bf::exists(mount_path_)) {
55 LOG(WARNING) << "Mount path(" << mount_path_ << ") already exists! "
56 << "We will remove it...";
57 bf::remove(mount_path_);
60 std::unique_ptr<DBusMessage, void(*)(DBusMessage*)> msg(
61 dbus_message_new_method_call(kTzipBusName, kTzipObjectPath,
66 LOG(ERROR) << "Could not create new dbus message";
70 const char* mount_path_str = mount_path_.string().c_str();
71 const char* zip_path_str = zip_path_.string().c_str();
72 const char* tzip_smack_rule = kTzipSmackRule;
74 if (!dbus_message_append_args(msg.get(),
75 DBUS_TYPE_STRING, &mount_path_str,
76 DBUS_TYPE_STRING, &zip_path_str,
77 DBUS_TYPE_STRING, &tzip_smack_rule,
82 if (dbus_connection_send(conn, msg.get(), nullptr) == FALSE) {
83 LOG(ERROR) << "Could not send DBUS message when mounting zip file";
86 return WaitForMounted();
90 DBusConnection *conn = dbus_bus_get(DBUS_BUS_SYSTEM, nullptr);
95 std::unique_ptr<DBusMessage, void(*)(DBusMessage*)> msg(
96 dbus_message_new_method_call(kTzipBusName, kTzipObjectPath,
101 LOG(ERROR) << "Could not create new dbus message";
105 const char* mount_path_str = mount_path_.string().c_str();
106 if (!dbus_message_append_args(msg.get(),
107 DBUS_TYPE_STRING, &mount_path_str,
108 DBUS_TYPE_INVALID)) {
112 if (dbus_connection_send(conn, msg.get(), nullptr) == FALSE) {
113 LOG(ERROR) << "Could not send DBUS message when unmounting zip file";
125 std::unique_ptr<DBusError, void(*)(DBusError*)> err(new DBusError(),
128 DBusConnection* conn = dbus_bus_get(DBUS_BUS_SYSTEM, nullptr);
132 std::unique_ptr<DBusMessage, void(*)(DBusMessage*)> msg(
133 dbus_message_new_method_call(kTzipBusName, kTzipObjectPath,
135 kTzipIsMountedMethod),
141 const char* mount_path_str = mount_path_.string().c_str();
142 if (!dbus_message_append_args(msg.get(),
143 DBUS_TYPE_STRING, &mount_path_str,
144 DBUS_TYPE_INVALID)) {
148 dbus_error_init(err.get());
149 reply = dbus_connection_send_with_reply_and_block(conn, msg.get(), 500,
155 r = dbus_message_get_args(reply, err.get(), DBUS_TYPE_INT32, &ret,
164 bool WaitForMounted() {
165 if (!mount_path_.empty()) {
168 while (cnt < kTzipMountMaximumRetryCount) {
183 boost::filesystem::path mount_path_;
184 boost::filesystem::path zip_path_;
188 TzipInterface::TzipInterface(const boost::filesystem::path& mount_path)
189 : impl_(new Pimpl(mount_path)) {}
191 TzipInterface::~TzipInterface() { }
193 bool TzipInterface::MountZip(const boost::filesystem::path& zip_path) {
194 return impl_->MountZip(zip_path);
197 bool TzipInterface::UnmountZip() {
198 return impl_->UnmountZip();
201 } // namespace common_installer