Upstream version 7.35.138.0
[platform/framework/web/crosswalk.git] / src / xwalk / application / browser / linux / installed_applications_manager.cc
1 // Copyright (c) 2013 Intel Corporation. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "xwalk/application/browser/linux/installed_applications_manager.h"
6
7 #include <string>
8 #include "base/bind.h"
9 #include "base/files/file_path.h"
10 #include "dbus/bus.h"
11 #include "dbus/message.h"
12 #include "xwalk/application/browser/application_storage.h"
13 #include "xwalk/application/browser/linux/installed_application_object.h"
14
15 namespace {
16
17 // D-Bus Interface implemented by the manager object of installed applications.
18 //
19 // Methods:
20 //
21 //   Install(string path) -> ObjectPath
22 //     Will install application at "path", that should be an absolute path to
23 //     the package file. If installation is successful, returns the ObjectPath
24 //     of the InstalledApplication object that represents it.
25 const char kInstalledManagerDBusInterface[] =
26     "org.crosswalkproject.Installed.Manager1";
27
28 const char kInstalledManagerDBusError[] =
29     "org.crosswalkproject.Installed.Manager.Error";
30
31 const dbus::ObjectPath kInstalledManagerDBusPath("/installed1");
32
33 dbus::ObjectPath GetInstalledPathForAppID(const std::string& app_id) {
34   return dbus::ObjectPath(kInstalledManagerDBusPath.value() + "/" + app_id);
35 }
36
37 }  // namespace
38
39 namespace xwalk {
40 namespace application {
41
42 InstalledApplicationsManager::InstalledApplicationsManager(
43     scoped_refptr<dbus::Bus> bus, ApplicationService* service,
44     ApplicationStorage* app_storage)
45     : weak_factory_(this),
46       application_service_(service),
47       app_storage_(app_storage),
48       adaptor_(bus, kInstalledManagerDBusPath) {
49   application_service_->AddObserver(this);
50
51   adaptor_.manager_object()->ExportMethod(
52       kInstalledManagerDBusInterface, "Install",
53       base::Bind(&InstalledApplicationsManager::OnInstall,
54                  weak_factory_.GetWeakPtr()),
55       base::Bind(&InstalledApplicationsManager::OnExported,
56                  weak_factory_.GetWeakPtr()));
57
58   AddInitialObjects();
59 }
60
61 InstalledApplicationsManager::~InstalledApplicationsManager() {
62   application_service_->RemoveObserver(this);
63 }
64
65 void InstalledApplicationsManager::OnApplicationInstalled(
66     const std::string& app_id) {
67   AddObject(app_storage_->GetApplicationData(app_id));
68 }
69
70 void InstalledApplicationsManager::OnApplicationUninstalled(
71     const std::string& app_id) {
72   adaptor_.RemoveManagedObject(GetInstalledPathForAppID(app_id));
73 }
74
75 void InstalledApplicationsManager::OnApplicationUpdated(
76     const std::string& app_id) {
77   if (scoped_refptr<ApplicationData> app =
78       app_storage_->GetApplicationData(app_id))
79     OnApplicationNameChanged(app_id, app->Name());
80 }
81
82 void InstalledApplicationsManager::OnApplicationNameChanged(
83     const std::string& app_id, const std::string& app_name) {
84   InstalledApplicationObject* object =
85       static_cast<InstalledApplicationObject*>(
86           adaptor_.GetManagedObject(GetInstalledPathForAppID(app_id)));
87   object->OnApplicationNameChanged(app_name);
88 }
89
90 void InstalledApplicationsManager::AddInitialObjects() {
91   const ApplicationData::ApplicationDataMap& apps =
92       app_storage_->GetInstalledApplications();
93   ApplicationData::ApplicationDataMap::const_iterator it;
94   for (it = apps.begin(); it != apps.end(); ++it)
95     AddObject(it->second);
96 }
97
98 void InstalledApplicationsManager::AddObject(
99     scoped_refptr<const ApplicationData> app) {
100   scoped_ptr<InstalledApplicationObject> object(
101       new InstalledApplicationObject(
102           adaptor_.bus(), GetInstalledPathForAppID(app->ID()), app));
103
104   // See comment in InstalledApplicationsManager::OnUninstall().
105   object->ExportUninstallMethod(
106       base::Bind(&InstalledApplicationsManager::OnUninstall,
107                  weak_factory_.GetWeakPtr(),
108                  base::Unretained(object.get())),
109       base::Bind(&InstalledApplicationsManager::OnExported,
110                  weak_factory_.GetWeakPtr()));
111
112   adaptor_.AddManagedObject(object.PassAs<dbus::ManagedObject>());
113 }
114
115 namespace {
116
117 scoped_ptr<dbus::Response> CreateError(dbus::MethodCall* method_call,
118                                        const std::string& message) {
119     scoped_ptr<dbus::ErrorResponse> error_response =
120         dbus::ErrorResponse::FromMethodCall(
121             method_call, kInstalledManagerDBusError, message);
122     return error_response.PassAs<dbus::Response>();
123 }
124
125 }  // namespace
126
127 void InstalledApplicationsManager::OnInstall(
128     dbus::MethodCall* method_call,
129     dbus::ExportedObject::ResponseSender response_sender) {
130   dbus::MessageReader reader(method_call);
131   std::string file_path_str;
132   if (!reader.PopString(&file_path_str)) {
133     scoped_ptr<dbus::Response> response =
134         CreateError(method_call, "Error parsing message.");
135     response_sender.Run(response.Pass());
136     return;
137   }
138
139   const base::FilePath file_path(file_path_str);
140   if (!file_path.IsAbsolute()) {
141     scoped_ptr<dbus::Response> response =
142         CreateError(method_call, "Path to install must be absolute.");
143     response_sender.Run(response.Pass());
144     return;
145   }
146
147   std::string app_id;
148   if (!application_service_->Install(file_path, &app_id) &&
149       (app_id.empty() || !application_service_->Update(app_id, file_path))) {
150     scoped_ptr<dbus::Response> response =
151         CreateError(method_call,
152                     "Error installing/updating application with path: "
153                     + file_path_str);
154     response_sender.Run(response.Pass());
155     return;
156   }
157
158   dbus::ManagedObject* managed_object =
159       adaptor_.GetManagedObject(GetInstalledPathForAppID(app_id));
160   CHECK(managed_object);
161
162   scoped_ptr<dbus::Response> response =
163       dbus::Response::FromMethodCall(method_call);
164   dbus::MessageWriter writer(response.get());
165   writer.AppendObjectPath(managed_object->path());
166   response_sender.Run(response.Pass());
167 }
168
169 // InstalledApplicationsManager implements the callback exposed in the child
170 // objects interface, we bind the actual child to the first parameter. There are
171 // two reasons to do this: we save the need of creating WeakPtrFactories for all
172 // individual objects, and we ensure that is safe to destroy the object when
173 // handling the callback -- which is done by our OnApplicationUninstalled
174 // implementation.
175 void InstalledApplicationsManager::OnUninstall(
176     InstalledApplicationObject* installed_app_object,
177     dbus::MethodCall* method_call,
178     dbus::ExportedObject::ResponseSender response_sender) {
179   if (!application_service_->Uninstall(installed_app_object->app_id())) {
180     scoped_ptr<dbus::ErrorResponse> error_response =
181         dbus::ErrorResponse::FromMethodCall(
182             method_call, kInstalledApplicationDBusError,
183             "Error trying to uninstall application with id "
184             + installed_app_object->app_id());
185     response_sender.Run(error_response.PassAs<dbus::Response>());
186     return;
187   }
188
189   scoped_ptr<dbus::Response> response =
190       dbus::Response::FromMethodCall(method_call);
191   response_sender.Run(response.Pass());
192 }
193
194 void InstalledApplicationsManager::OnExported(
195     const std::string& interface_name,
196     const std::string& method_name,
197     bool success) {
198   if (!success) {
199     LOG(WARNING) << "Error exporting method '" << interface_name
200                  << "." << method_name << "' in '"
201                  << kInstalledManagerDBusPath.value() << "'.";
202   }
203 }
204
205 }  // namespace application
206 }  // namespace xwalk