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.
5 #include "xwalk/application/browser/linux/installed_applications_manager.h"
9 #include "base/files/file_path.h"
11 #include "dbus/message.h"
12 #include "xwalk/application/browser/application_storage.h"
13 #include "xwalk/application/browser/linux/installed_application_object.h"
17 // D-Bus Interface implemented by the manager object of installed applications.
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";
28 const char kInstalledManagerDBusError[] =
29 "org.crosswalkproject.Installed.Manager.Error";
31 const dbus::ObjectPath kInstalledManagerDBusPath("/installed1");
33 dbus::ObjectPath GetInstalledPathForAppID(const std::string& app_id) {
34 return dbus::ObjectPath(kInstalledManagerDBusPath.value() + "/" + app_id);
40 namespace application {
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);
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()));
61 InstalledApplicationsManager::~InstalledApplicationsManager() {
62 application_service_->RemoveObserver(this);
65 void InstalledApplicationsManager::OnApplicationInstalled(
66 const std::string& app_id) {
67 AddObject(app_storage_->GetApplicationData(app_id));
70 void InstalledApplicationsManager::OnApplicationUninstalled(
71 const std::string& app_id) {
72 adaptor_.RemoveManagedObject(GetInstalledPathForAppID(app_id));
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());
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);
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);
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));
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()));
112 adaptor_.AddManagedObject(object.PassAs<dbus::ManagedObject>());
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>();
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());
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());
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: "
154 response_sender.Run(response.Pass());
158 dbus::ManagedObject* managed_object =
159 adaptor_.GetManagedObject(GetInstalledPathForAppID(app_id));
160 CHECK(managed_object);
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());
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
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>());
189 scoped_ptr<dbus::Response> response =
190 dbus::Response::FromMethodCall(method_call);
191 response_sender.Run(response.Pass());
194 void InstalledApplicationsManager::OnExported(
195 const std::string& interface_name,
196 const std::string& method_name,
199 LOG(WARNING) << "Error exporting method '" << interface_name
200 << "." << method_name << "' in '"
201 << kInstalledManagerDBusPath.value() << "'.";
205 } // namespace application