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"
14 #include "xwalk/runtime/browser/xwalk_runner.h"
17 #include "xwalk/application/browser/application_service_tizen.h"
22 // D-Bus Interface implemented by the manager object of running applications.
26 // Launch(string app_id) -> ObjectPath
27 // Launches the application with 'app_id'.
28 const char kRunningManagerDBusInterface[] =
29 "org.crosswalkproject.Running.Manager1";
31 const char kRunningManagerDBusError[] =
32 "org.crosswalkproject.Running.Manager.Error";
34 const dbus::ObjectPath kRunningManagerDBusPath("/running1");
40 namespace application {
42 // The [tizen_app_id] contains a dot, making it an invalid object path.
43 // For this reason we replace it with an underscore '_'.
44 std::string GetAppObjectPathFromAppId(const std::string& app_id) {
46 std::string ret(app_id);
47 std::replace(ret.begin(), ret.end(), '.', '_');
54 dbus::ObjectPath GetRunningPathForAppID(const std::string& app_id) {
55 return dbus::ObjectPath(kRunningManagerDBusPath.value() + "/" +
56 GetAppObjectPathFromAppId(app_id));
59 RunningApplicationsManager::RunningApplicationsManager(
60 scoped_refptr<dbus::Bus> bus, ApplicationService* service)
61 : weak_factory_(this),
62 application_service_(service),
63 adaptor_(bus, kRunningManagerDBusPath) {
64 application_service_->AddObserver(this);
66 adaptor_.manager_object()->ExportMethod(
67 kRunningManagerDBusInterface, "EnableRemoteDebugging",
68 base::Bind(&RunningApplicationsManager::OnRemoteDebuggingEnabled,
69 weak_factory_.GetWeakPtr()),
70 base::Bind(&RunningApplicationsManager::OnExported,
71 weak_factory_.GetWeakPtr()));
73 adaptor_.manager_object()->ExportMethod(
74 kRunningManagerDBusInterface, "Launch",
75 base::Bind(&RunningApplicationsManager::OnLaunch,
76 weak_factory_.GetWeakPtr()),
77 base::Bind(&RunningApplicationsManager::OnExported,
78 weak_factory_.GetWeakPtr()));
80 adaptor_.manager_object()->ExportMethod(
81 kRunningManagerDBusInterface, "TerminateIfRunning",
82 base::Bind(&RunningApplicationsManager::OnTerminateIfRunning,
83 weak_factory_.GetWeakPtr()),
84 base::Bind(&RunningApplicationsManager::OnExported,
85 weak_factory_.GetWeakPtr()));
88 RunningApplicationsManager::~RunningApplicationsManager() {}
90 RunningApplicationObject* RunningApplicationsManager::GetRunningApp(
91 const std::string& app_id) {
92 dbus::ManagedObject* managed_object =
93 adaptor_.GetManagedObject(GetRunningPathForAppID(app_id));
94 DCHECK(managed_object);
95 return static_cast<RunningApplicationObject*>(managed_object);
100 scoped_ptr<dbus::Response> CreateError(dbus::MethodCall* method_call,
101 const std::string& message) {
102 scoped_ptr<dbus::ErrorResponse> error_response =
103 dbus::ErrorResponse::FromMethodCall(
104 method_call, kRunningManagerDBusError, message);
105 return error_response.Pass();
110 void RunningApplicationsManager::OnRemoteDebuggingEnabled(
111 dbus::MethodCall* method_call,
112 dbus::ExportedObject::ResponseSender response_sender) {
113 dbus::MessageReader reader(method_call);
114 unsigned int debugging_port;
116 if (!reader.PopUint32(&debugging_port)) {
117 scoped_ptr<dbus::Response> response =
118 CreateError(method_call,
119 "Error parsing message. Missing arguments.");
120 response_sender.Run(response.Pass());
124 if (debugging_port != 0) {
125 XWalkRunner::GetInstance()->EnableRemoteDebugging(debugging_port);
127 XWalkRunner::GetInstance()->DisableRemoteDebugging();
130 scoped_ptr<dbus::Response> response =
131 dbus::Response::FromMethodCall(method_call);
132 dbus::MessageWriter writer(response.get());
133 writer.AppendUint32(debugging_port);
134 response_sender.Run(response.Pass());
137 void RunningApplicationsManager::OnLaunch(
138 dbus::MethodCall* method_call,
139 dbus::ExportedObject::ResponseSender response_sender) {
141 dbus::MessageReader reader(method_call);
142 std::string app_id_or_url;
143 // We might want to pass key-value pairs if have more parameters in future.
144 unsigned int launcher_pid;
146 bool remote_debugging;
148 if (!reader.PopString(&app_id_or_url) ||
149 !reader.PopUint32(&launcher_pid) ||
150 !reader.PopBool(&fullscreen) ||
151 !reader.PopBool(&remote_debugging)) {
152 scoped_ptr<dbus::Response> response =
153 CreateError(method_call,
154 "Error parsing message. Missing arguments.");
155 response_sender.Run(response.Pass());
159 Application::LaunchParams params;
160 params.launcher_pid = launcher_pid;
161 params.force_fullscreen = fullscreen;
162 params.remote_debugging = remote_debugging;
164 Application* application = NULL;
165 GURL url(app_id_or_url);
166 if (!url.spec().empty())
167 application = application_service_->LaunchHostedURL(url, params);
169 #if defined(OS_TIZEN)
171 application = ToApplicationServiceTizen(
172 application_service_)->LaunchFromAppID(app_id_or_url, params);
176 scoped_ptr<dbus::Response> response =
177 CreateError(method_call,
178 "Error launching application with id or url"
180 response_sender.Run(response.Pass());
184 // FIXME(cmarcelo): ApplicationService will tell us when new applications
185 // appear (with DidLaunchApplication()) and we create new managed objects
186 // in D-Bus based on that.
187 dbus::ObjectPath path =
188 AddObject(GetAppObjectPathFromAppId(application->id()),
189 method_call->GetSender(),
192 scoped_ptr<dbus::Response> response =
193 dbus::Response::FromMethodCall(method_call);
194 dbus::MessageWriter writer(response.get());
195 writer.AppendObjectPath(path);
196 response_sender.Run(response.Pass());
199 void RunningApplicationsManager::OnTerminateIfRunning(
200 dbus::MethodCall* method_call,
201 dbus::ExportedObject::ResponseSender response_sender) {
203 dbus::MessageReader reader(method_call);
206 if (!reader.PopString(&app_id)) {
207 scoped_ptr<dbus::Response> response =
208 CreateError(method_call,
209 "Error parsing message. Missing argument.");
210 response_sender.Run(response.Pass());
214 if (Application* app = application_service_->GetApplicationByID(app_id)) {
215 CHECK(app_id == app->id());
219 scoped_ptr<dbus::Response> response =
220 dbus::Response::FromMethodCall(method_call);
221 response_sender.Run(response.Pass());
224 void RunningApplicationsManager::OnExported(
225 const std::string& interface_name,
226 const std::string& method_name,
229 LOG(WARNING) << "Error exporting method '" << interface_name
230 << "." << method_name << "' in '"
231 << kRunningManagerDBusPath.value() << "'.";
235 void RunningApplicationsManager::WillDestroyApplication(Application* app) {
236 dbus::ObjectPath path = GetRunningPathForAppID(app->id());
238 adaptor_.RemoveManagedObject(path);
241 dbus::ObjectPath RunningApplicationsManager::AddObject(
242 const std::string& app_id, const std::string& launcher_name,
243 Application* application) {
244 scoped_ptr<RunningApplicationObject> running_application(
245 new RunningApplicationObject(adaptor_.bus(), app_id,
246 launcher_name, application));
248 dbus::ObjectPath path = running_application->path();
250 adaptor_.AddManagedObject(running_application.Pass());
255 } // namespace application