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/running_applications_manager.h"
10 #include "dbus/message.h"
12 #include "xwalk/application/browser/linux/running_application_object.h"
13 #include "xwalk/application/common/application_data.h"
17 // D-Bus Interface implemented by the manager object of running applications.
21 // Launch(string app_id) -> ObjectPath
22 // Launches the application with 'app_id'.
23 const char kRunningManagerDBusInterface[] =
24 "org.crosswalkproject.Running.Manager1";
26 const char kRunningManagerDBusError[] =
27 "org.crosswalkproject.Running.Manager.Error";
29 const dbus::ObjectPath kRunningManagerDBusPath("/running1");
35 namespace application {
37 // The [tizen_app_id] contains a dot, making it an invalid object path.
38 // For this reason we replace it with an underscore '_'.
39 std::string GetAppObjectPathFromAppId(const std::string& app_id) {
41 std::string ret(app_id);
42 std::replace(ret.begin(), ret.end(), '.', '_');
49 dbus::ObjectPath GetRunningPathForAppID(const std::string& app_id) {
50 return dbus::ObjectPath(kRunningManagerDBusPath.value() + "/" +
51 GetAppObjectPathFromAppId(app_id));
54 RunningApplicationsManager::RunningApplicationsManager(
55 scoped_refptr<dbus::Bus> bus, ApplicationService* service)
56 : weak_factory_(this),
57 application_service_(service),
58 adaptor_(bus, kRunningManagerDBusPath) {
59 application_service_->AddObserver(this);
61 adaptor_.manager_object()->ExportMethod(
62 kRunningManagerDBusInterface, "Launch",
63 base::Bind(&RunningApplicationsManager::OnLaunch,
64 weak_factory_.GetWeakPtr()),
65 base::Bind(&RunningApplicationsManager::OnExported,
66 weak_factory_.GetWeakPtr()));
68 adaptor_.manager_object()->ExportMethod(
69 kRunningManagerDBusInterface, "TerminateIfRunning",
70 base::Bind(&RunningApplicationsManager::OnTerminateIfRunning,
71 weak_factory_.GetWeakPtr()),
72 base::Bind(&RunningApplicationsManager::OnExported,
73 weak_factory_.GetWeakPtr()));
76 RunningApplicationsManager::~RunningApplicationsManager() {}
78 RunningApplicationObject* RunningApplicationsManager::GetRunningApp(
79 const std::string& app_id) {
80 dbus::ManagedObject* managed_object =
81 adaptor_.GetManagedObject(GetRunningPathForAppID(app_id));
82 DCHECK(managed_object);
83 return static_cast<RunningApplicationObject*>(managed_object);
88 scoped_ptr<dbus::Response> CreateError(dbus::MethodCall* method_call,
89 const std::string& message) {
90 scoped_ptr<dbus::ErrorResponse> error_response =
91 dbus::ErrorResponse::FromMethodCall(
92 method_call, kRunningManagerDBusError, message);
93 return error_response.PassAs<dbus::Response>();
98 void RunningApplicationsManager::OnLaunch(
99 dbus::MethodCall* method_call,
100 dbus::ExportedObject::ResponseSender response_sender) {
102 dbus::MessageReader reader(method_call);
103 std::string app_id_or_url;
104 // We might want to pass key-value pairs if have more parameters in future.
105 unsigned int launcher_pid;
108 if (!reader.PopString(&app_id_or_url) ||
109 !reader.PopUint32(&launcher_pid) ||
110 !reader.PopBool(&fullscreen)) {
111 scoped_ptr<dbus::Response> response =
112 CreateError(method_call,
113 "Error parsing message. Missing arguments.");
114 response_sender.Run(response.Pass());
118 Application::LaunchParams params;
119 params.launcher_pid = launcher_pid;
120 params.force_fullscreen = fullscreen;
122 Application* application;
123 if (GURL(app_id_or_url).spec().empty()) {
124 application = application_service_->Launch(app_id_or_url, params);
126 params.entry_points = Application::StartURLKey;
128 scoped_refptr<ApplicationData> application_data =
129 ApplicationData::Create(GURL(app_id_or_url), &error);
130 if (!application_data) {
131 scoped_ptr<dbus::Response> response = CreateError(method_call, error);
132 response_sender.Run(response.Pass());
136 application = application_service_->Launch(application_data, params);
140 scoped_ptr<dbus::Response> response =
141 CreateError(method_call,
142 "Error launching application with id or url"
144 response_sender.Run(response.Pass());
148 // FIXME(cmarcelo): ApplicationService will tell us when new applications
149 // appear (with DidLaunchApplication()) and we create new managed objects
150 // in D-Bus based on that.
151 dbus::ObjectPath path =
152 AddObject(GetAppObjectPathFromAppId(application->id()),
153 method_call->GetSender(),
156 scoped_ptr<dbus::Response> response =
157 dbus::Response::FromMethodCall(method_call);
158 dbus::MessageWriter writer(response.get());
159 writer.AppendObjectPath(path);
160 response_sender.Run(response.Pass());
163 void RunningApplicationsManager::OnTerminateIfRunning(
164 dbus::MethodCall* method_call,
165 dbus::ExportedObject::ResponseSender response_sender) {
167 dbus::MessageReader reader(method_call);
170 if (!reader.PopString(&app_id)) {
171 scoped_ptr<dbus::Response> response =
172 CreateError(method_call,
173 "Error parsing message. Missing argument.");
174 response_sender.Run(response.Pass());
178 if (Application* app = application_service_->GetApplicationByID(app_id)) {
179 CHECK(app_id == app->id());
183 scoped_ptr<dbus::Response> response =
184 dbus::Response::FromMethodCall(method_call);
185 response_sender.Run(response.Pass());
188 void RunningApplicationsManager::OnExported(
189 const std::string& interface_name,
190 const std::string& method_name,
193 LOG(WARNING) << "Error exporting method '" << interface_name
194 << "." << method_name << "' in '"
195 << kRunningManagerDBusPath.value() << "'.";
199 void RunningApplicationsManager::WillDestroyApplication(Application* app) {
200 dbus::ObjectPath path = GetRunningPathForAppID(app->id());
202 adaptor_.RemoveManagedObject(path);
205 dbus::ObjectPath RunningApplicationsManager::AddObject(
206 const std::string& app_id, const std::string& launcher_name,
207 Application* application) {
208 scoped_ptr<RunningApplicationObject> running_application(
209 new RunningApplicationObject(adaptor_.bus(), app_id,
210 launcher_name, application));
212 dbus::ObjectPath path = running_application->path();
214 adaptor_.AddManagedObject(running_application.PassAs<dbus::ManagedObject>());
219 } // namespace application