6a706258f6e1147e94aabaf93853f41d9b399812
[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
14 namespace {
15
16 // D-Bus Interface implemented by the manager object of running applications.
17 //
18 // Methods:
19 //
20 //   Launch(string app_id) -> ObjectPath
21 //     Launches the application with 'app_id'.
22 const char kRunningManagerDBusInterface[] =
23     "org.crosswalkproject.Running.Manager1";
24
25 const char kRunningManagerDBusError[] =
26     "org.crosswalkproject.Running.Manager.Error";
27
28 const dbus::ObjectPath kRunningManagerDBusPath("/running1");
29
30
31 }  // namespace
32
33 namespace xwalk {
34 namespace application {
35
36 dbus::ObjectPath GetRunningPathForAppID(const std::string& app_id) {
37   return dbus::ObjectPath(kRunningManagerDBusPath.value() + "/" + app_id);
38 }
39
40 RunningApplicationsManager::RunningApplicationsManager(
41     scoped_refptr<dbus::Bus> bus, ApplicationService* service)
42     : weak_factory_(this),
43       application_service_(service),
44       adaptor_(bus, kRunningManagerDBusPath) {
45   application_service_->AddObserver(this);
46
47   adaptor_.manager_object()->ExportMethod(
48       kRunningManagerDBusInterface, "Launch",
49       base::Bind(&RunningApplicationsManager::OnLaunch,
50                  weak_factory_.GetWeakPtr()),
51       base::Bind(&RunningApplicationsManager::OnExported,
52                  weak_factory_.GetWeakPtr()));
53 }
54
55 RunningApplicationsManager::~RunningApplicationsManager() {}
56
57 RunningApplicationObject* RunningApplicationsManager::GetRunningApp(
58     const std::string& app_id) {
59   dbus::ManagedObject* managed_object =
60       adaptor_.GetManagedObject(GetRunningPathForAppID(app_id));
61   DCHECK(managed_object);
62   return static_cast<RunningApplicationObject*>(managed_object);
63 }
64
65 namespace {
66
67 scoped_ptr<dbus::Response> CreateError(dbus::MethodCall* method_call,
68                                        const std::string& message) {
69     scoped_ptr<dbus::ErrorResponse> error_response =
70         dbus::ErrorResponse::FromMethodCall(
71             method_call, kRunningManagerDBusError, message);
72     return error_response.PassAs<dbus::Response>();
73 }
74
75 }  // namespace
76
77 void RunningApplicationsManager::OnLaunch(
78     dbus::MethodCall* method_call,
79     dbus::ExportedObject::ResponseSender response_sender) {
80
81   dbus::MessageReader reader(method_call);
82   std::string app_id;
83   // We might want to pass key-value pairs if have more parameters in future.
84   unsigned int launcher_pid;
85   bool fullscreen;
86
87   if (!reader.PopString(&app_id) ||
88       !reader.PopUint32(&launcher_pid) ||
89       !reader.PopBool(&fullscreen)) {
90     scoped_ptr<dbus::Response> response =
91         CreateError(method_call,
92                     "Error parsing message. Missing arguments.");
93     response_sender.Run(response.Pass());
94     return;
95   }
96
97   Application::LaunchParams params;
98   params.launcher_pid = launcher_pid;
99   params.force_fullscreen = fullscreen;
100
101   Application* application = application_service_->Launch(app_id, params);
102   if (!application) {
103     scoped_ptr<dbus::Response> response =
104         CreateError(method_call,
105                     "Error launching application with id " + app_id);
106     response_sender.Run(response.Pass());
107     return;
108   }
109   CHECK(app_id == application->id());
110   // FIXME(cmarcelo): ApplicationService will tell us when new applications
111   // appear (with DidLaunchApplication()) and we create new managed objects
112   // in D-Bus based on that.
113   dbus::ObjectPath path = AddObject(app_id, method_call->GetSender(),
114                                     application);
115
116   scoped_ptr<dbus::Response> response =
117       dbus::Response::FromMethodCall(method_call);
118   dbus::MessageWriter writer(response.get());
119   writer.AppendObjectPath(path);
120   response_sender.Run(response.Pass());
121 }
122
123 void RunningApplicationsManager::OnExported(
124     const std::string& interface_name,
125     const std::string& method_name,
126     bool success) {
127   if (!success) {
128     LOG(WARNING) << "Error exporting method '" << interface_name
129                  << "." << method_name << "' in '"
130                  << kRunningManagerDBusPath.value() << "'.";
131   }
132 }
133
134 void RunningApplicationsManager::WillDestroyApplication(Application* app) {
135   dbus::ObjectPath path = GetRunningPathForAppID(app->id());
136
137   adaptor_.RemoveManagedObject(path);
138 }
139
140 dbus::ObjectPath RunningApplicationsManager::AddObject(
141     const std::string& app_id, const std::string& launcher_name,
142     Application* application) {
143   scoped_ptr<RunningApplicationObject> running_application(
144       new RunningApplicationObject(adaptor_.bus(), app_id,
145                                    launcher_name, application));
146
147   dbus::ObjectPath path = running_application->path();
148
149   adaptor_.AddManagedObject(running_application.PassAs<dbus::ManagedObject>());
150
151   return path;
152 }
153
154 }  // namespace application
155 }  // namespace xwalk