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"
18 // D-Bus Interface implemented by the manager object of running applications.
22 // Launch(string app_id) -> ObjectPath
23 // Launches the application with 'app_id'.
24 const char kRunningManagerDBusInterface[] =
25 "org.crosswalkproject.Running.Manager1";
27 const char kRunningManagerDBusError[] =
28 "org.crosswalkproject.Running.Manager.Error";
30 const dbus::ObjectPath kRunningManagerDBusPath("/running1");
36 namespace application {
38 // The [tizen_app_id] contains a dot, making it an invalid object path.
39 // For this reason we replace it with an underscore '_'.
40 std::string GetAppObjectPathFromAppId(const std::string& app_id) {
42 std::string ret(app_id);
43 std::replace(ret.begin(), ret.end(), '.', '_');
50 dbus::ObjectPath GetRunningPathForAppID(const std::string& app_id) {
51 return dbus::ObjectPath(kRunningManagerDBusPath.value() + "/" +
52 GetAppObjectPathFromAppId(app_id));
55 RunningApplicationsManager::RunningApplicationsManager(
56 scoped_refptr<dbus::Bus> bus, ApplicationService* service)
57 : weak_factory_(this),
58 application_service_(service),
59 adaptor_(bus, kRunningManagerDBusPath) {
60 application_service_->AddObserver(this);
62 adaptor_.manager_object()->ExportMethod(
63 kRunningManagerDBusInterface, "EnableRemoteDebugging",
64 base::Bind(&RunningApplicationsManager::OnRemoteDebuggingEnabled,
65 weak_factory_.GetWeakPtr()),
66 base::Bind(&RunningApplicationsManager::OnExported,
67 weak_factory_.GetWeakPtr()));
69 adaptor_.manager_object()->ExportMethod(
70 kRunningManagerDBusInterface, "Launch",
71 base::Bind(&RunningApplicationsManager::OnLaunch,
72 weak_factory_.GetWeakPtr()),
73 base::Bind(&RunningApplicationsManager::OnExported,
74 weak_factory_.GetWeakPtr()));
76 adaptor_.manager_object()->ExportMethod(
77 kRunningManagerDBusInterface, "TerminateIfRunning",
78 base::Bind(&RunningApplicationsManager::OnTerminateIfRunning,
79 weak_factory_.GetWeakPtr()),
80 base::Bind(&RunningApplicationsManager::OnExported,
81 weak_factory_.GetWeakPtr()));
84 RunningApplicationsManager::~RunningApplicationsManager() {}
86 RunningApplicationObject* RunningApplicationsManager::GetRunningApp(
87 const std::string& app_id) {
88 dbus::ManagedObject* managed_object =
89 adaptor_.GetManagedObject(GetRunningPathForAppID(app_id));
90 DCHECK(managed_object);
91 return static_cast<RunningApplicationObject*>(managed_object);
96 scoped_ptr<dbus::Response> CreateError(dbus::MethodCall* method_call,
97 const std::string& message) {
98 scoped_ptr<dbus::ErrorResponse> error_response =
99 dbus::ErrorResponse::FromMethodCall(
100 method_call, kRunningManagerDBusError, message);
101 return error_response.PassAs<dbus::Response>();
106 void RunningApplicationsManager::OnRemoteDebuggingEnabled(
107 dbus::MethodCall* method_call,
108 dbus::ExportedObject::ResponseSender response_sender) {
109 dbus::MessageReader reader(method_call);
110 unsigned int debugging_port;
112 if (!reader.PopUint32(&debugging_port)) {
113 scoped_ptr<dbus::Response> response =
114 CreateError(method_call,
115 "Error parsing message. Missing arguments.");
116 response_sender.Run(response.Pass());
120 if (debugging_port != 0) {
121 XWalkRunner::GetInstance()->EnableRemoteDebugging(debugging_port);
123 XWalkRunner::GetInstance()->DisableRemoteDebugging();
126 scoped_ptr<dbus::Response> response =
127 dbus::Response::FromMethodCall(method_call);
128 dbus::MessageWriter writer(response.get());
129 writer.AppendUint32(debugging_port);
130 response_sender.Run(response.Pass());
133 void RunningApplicationsManager::OnLaunch(
134 dbus::MethodCall* method_call,
135 dbus::ExportedObject::ResponseSender response_sender) {
137 dbus::MessageReader reader(method_call);
138 std::string app_id_or_url;
139 // We might want to pass key-value pairs if have more parameters in future.
140 unsigned int launcher_pid;
143 if (!reader.PopString(&app_id_or_url) ||
144 !reader.PopUint32(&launcher_pid) ||
145 !reader.PopBool(&fullscreen)) {
146 scoped_ptr<dbus::Response> response =
147 CreateError(method_call,
148 "Error parsing message. Missing arguments.");
149 response_sender.Run(response.Pass());
153 Application::LaunchParams params;
154 params.launcher_pid = launcher_pid;
155 params.force_fullscreen = fullscreen;
157 Application* application;
158 if (GURL(app_id_or_url).spec().empty()) {
159 application = application_service_->Launch(app_id_or_url, params);
161 params.entry_points = Application::StartURLKey;
163 scoped_refptr<ApplicationData> application_data =
164 ApplicationData::Create(GURL(app_id_or_url), &error);
165 if (!application_data) {
166 scoped_ptr<dbus::Response> response = CreateError(method_call, error);
167 response_sender.Run(response.Pass());
171 application = application_service_->Launch(application_data, params);
175 scoped_ptr<dbus::Response> response =
176 CreateError(method_call,
177 "Error launching application with id or url"
179 response_sender.Run(response.Pass());
183 // FIXME(cmarcelo): ApplicationService will tell us when new applications
184 // appear (with DidLaunchApplication()) and we create new managed objects
185 // in D-Bus based on that.
186 dbus::ObjectPath path =
187 AddObject(GetAppObjectPathFromAppId(application->id()),
188 method_call->GetSender(),
191 scoped_ptr<dbus::Response> response =
192 dbus::Response::FromMethodCall(method_call);
193 dbus::MessageWriter writer(response.get());
194 writer.AppendObjectPath(path);
195 response_sender.Run(response.Pass());
198 void RunningApplicationsManager::OnTerminateIfRunning(
199 dbus::MethodCall* method_call,
200 dbus::ExportedObject::ResponseSender response_sender) {
202 dbus::MessageReader reader(method_call);
205 if (!reader.PopString(&app_id)) {
206 scoped_ptr<dbus::Response> response =
207 CreateError(method_call,
208 "Error parsing message. Missing argument.");
209 response_sender.Run(response.Pass());
213 if (Application* app = application_service_->GetApplicationByID(app_id)) {
214 CHECK(app_id == app->id());
218 scoped_ptr<dbus::Response> response =
219 dbus::Response::FromMethodCall(method_call);
220 response_sender.Run(response.Pass());
223 void RunningApplicationsManager::OnExported(
224 const std::string& interface_name,
225 const std::string& method_name,
228 LOG(WARNING) << "Error exporting method '" << interface_name
229 << "." << method_name << "' in '"
230 << kRunningManagerDBusPath.value() << "'.";
234 void RunningApplicationsManager::WillDestroyApplication(Application* app) {
235 dbus::ObjectPath path = GetRunningPathForAppID(app->id());
237 adaptor_.RemoveManagedObject(path);
240 dbus::ObjectPath RunningApplicationsManager::AddObject(
241 const std::string& app_id, const std::string& launcher_name,
242 Application* application) {
243 scoped_ptr<RunningApplicationObject> running_application(
244 new RunningApplicationObject(adaptor_.bus(), app_id,
245 launcher_name, application));
247 dbus::ObjectPath path = running_application->path();
249 adaptor_.AddManagedObject(running_application.PassAs<dbus::ManagedObject>());
254 } // namespace application