Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / xwalk / application / browser / linux / running_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/running_applications_manager.h"
6
7 #include <string>
8 #include "base/bind.h"
9 #include "dbus/bus.h"
10 #include "dbus/message.h"
11
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"
15
16 #if defined(OS_TIZEN)
17 #include "xwalk/application/browser/application_service_tizen.h"
18 #endif
19
20 namespace {
21
22 // D-Bus Interface implemented by the manager object of running applications.
23 //
24 // Methods:
25 //
26 //   Launch(string app_id) -> ObjectPath
27 //     Launches the application with 'app_id'.
28 const char kRunningManagerDBusInterface[] =
29     "org.crosswalkproject.Running.Manager1";
30
31 const char kRunningManagerDBusError[] =
32     "org.crosswalkproject.Running.Manager.Error";
33
34 const dbus::ObjectPath kRunningManagerDBusPath("/running1");
35
36
37 }  // namespace
38
39 namespace xwalk {
40 namespace application {
41
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) {
45 #if defined(OS_TIZEN)
46   std::string ret(app_id);
47   std::replace(ret.begin(), ret.end(), '.', '_');
48   return ret;
49 #else
50   return app_id;
51 #endif
52 }
53
54 dbus::ObjectPath GetRunningPathForAppID(const std::string& app_id) {
55   return dbus::ObjectPath(kRunningManagerDBusPath.value() + "/" +
56                           GetAppObjectPathFromAppId(app_id));
57 }
58
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);
65
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()));
72
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()));
79
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()));
86 }
87
88 RunningApplicationsManager::~RunningApplicationsManager() {}
89
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);
96 }
97
98 namespace {
99
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();
106 }
107
108 }  // namespace
109
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;
115
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());
121     return;
122   }
123
124   if (debugging_port != 0) {
125     XWalkRunner::GetInstance()->EnableRemoteDebugging(debugging_port);
126   } else {
127     XWalkRunner::GetInstance()->DisableRemoteDebugging();
128   }
129
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());
135 }
136
137 void RunningApplicationsManager::OnLaunch(
138     dbus::MethodCall* method_call,
139     dbus::ExportedObject::ResponseSender response_sender) {
140
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;
145   bool fullscreen;
146   bool remote_debugging;
147
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());
156     return;
157   }
158
159   Application::LaunchParams params;
160   params.launcher_pid = launcher_pid;
161   params.force_fullscreen = fullscreen;
162   params.remote_debugging = remote_debugging;
163
164   Application* application = NULL;
165   GURL url(app_id_or_url);
166   if (!url.spec().empty())
167     application = application_service_->LaunchHostedURL(url, params);
168
169 #if defined(OS_TIZEN)
170   if (!application)
171     application = ToApplicationServiceTizen(
172         application_service_)->LaunchFromAppID(app_id_or_url, params);
173 #endif
174
175   if (!application) {
176     scoped_ptr<dbus::Response> response =
177         CreateError(method_call,
178                     "Error launching application with id or url"
179                     + app_id_or_url);
180     response_sender.Run(response.Pass());
181     return;
182   }
183
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(),
190                 application);
191
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());
197 }
198
199 void RunningApplicationsManager::OnTerminateIfRunning(
200     dbus::MethodCall* method_call,
201     dbus::ExportedObject::ResponseSender response_sender) {
202
203   dbus::MessageReader reader(method_call);
204   std::string app_id;
205
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());
211     return;
212   }
213
214   if (Application* app = application_service_->GetApplicationByID(app_id)) {
215     CHECK(app_id == app->id());
216     app->Terminate();
217   }
218
219   scoped_ptr<dbus::Response> response =
220       dbus::Response::FromMethodCall(method_call);
221   response_sender.Run(response.Pass());
222 }
223
224 void RunningApplicationsManager::OnExported(
225     const std::string& interface_name,
226     const std::string& method_name,
227     bool success) {
228   if (!success) {
229     LOG(WARNING) << "Error exporting method '" << interface_name
230                  << "." << method_name << "' in '"
231                  << kRunningManagerDBusPath.value() << "'.";
232   }
233 }
234
235 void RunningApplicationsManager::WillDestroyApplication(Application* app) {
236   dbus::ObjectPath path = GetRunningPathForAppID(app->id());
237
238   adaptor_.RemoveManagedObject(path);
239 }
240
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));
247
248   dbus::ObjectPath path = running_application->path();
249
250   adaptor_.AddManagedObject(running_application.Pass());
251
252   return path;
253 }
254
255 }  // namespace application
256 }  // namespace xwalk