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_application_object.h"
8 #include "base/values.h"
10 #include "content/public/browser/browser_thread.h"
12 #include "dbus/message.h"
13 #include "dbus/exported_object.h"
14 #include "xwalk/application/browser/application_tizen.h"
15 #include "xwalk/application/browser/linux/running_applications_manager.h"
19 // D-Bus Interface implemented by objects that represent running
25 // Will terminate the running application. This object will be unregistered
30 // readonly string AppID
31 const char kRunningApplicationDBusInterface[] =
32 "org.crosswalkproject.Running.Application1";
34 const char kRunningApplicationDBusError[] =
35 "org.crosswalkproject.Running.Application.Error";
41 namespace application {
43 RunningApplicationObject::RunningApplicationObject(
44 scoped_refptr<dbus::Bus> bus,
45 const std::string& app_id,
46 const std::string& launcher_name,
47 Application* application)
48 : dbus::ManagedObject(bus, GetRunningPathForAppID(app_id)),
50 launcher_name_(launcher_name),
51 application_(application) {
52 ListenForOwnerChange();
55 kRunningApplicationDBusInterface, "AppID",
56 scoped_ptr<base::Value>(base::Value::CreateStringValue(app_id)));
58 dbus_object()->ExportMethod(
59 kRunningApplicationDBusInterface, "Terminate",
60 base::Bind(&RunningApplicationObject::OnTerminate,
61 base::Unretained(this)),
62 base::Bind(&RunningApplicationObject::OnExported,
63 base::Unretained(this)));
65 dbus_object()->ExportMethod(
66 kRunningApplicationDBusInterface, "GetEPChannel",
67 base::Bind(&RunningApplicationObject::OnGetExtensionProcessChannel,
68 base::Unretained(this)),
69 base::Bind(&RunningApplicationObject::OnExported,
70 base::Unretained(this)));
73 dbus_object()->ExportMethod(
74 kRunningApplicationDBusInterface, "Hide",
75 base::Bind(&RunningApplicationObject::OnHide,
76 base::Unretained(this)),
77 base::Bind(&RunningApplicationObject::OnExported,
78 base::Unretained(this)));
80 dbus_object()->ExportMethod(
81 kRunningApplicationDBusInterface, "Suspend",
82 base::Bind(&RunningApplicationObject::OnSuspend,
83 base::Unretained(this)),
84 base::Bind(&RunningApplicationObject::OnExported,
85 base::Unretained(this)));
87 dbus_object()->ExportMethod(
88 kRunningApplicationDBusInterface, "Resume",
89 base::Bind(&RunningApplicationObject::OnResume,
90 base::Unretained(this)),
91 base::Bind(&RunningApplicationObject::OnExported,
92 base::Unretained(this)));
96 RunningApplicationObject::~RunningApplicationObject() {
97 UnlistenForOwnerChange();
100 void RunningApplicationObject::TerminateApplication() {
101 application_->Terminate();
104 void RunningApplicationObject::OnExported(const std::string& interface_name,
105 const std::string& method_name,
108 LOG(WARNING) << "Error exporting method '" << interface_name
109 << "." << method_name << "' in '"
110 << path().value() << "'.";
114 void RunningApplicationObject::OnTerminate(
115 dbus::MethodCall* method_call,
116 dbus::ExportedObject::ResponseSender response_sender) {
117 // We only allow the caller of Launch() to call Terminate().
118 if (method_call->GetSender() != launcher_name_) {
119 scoped_ptr<dbus::ErrorResponse> error_response =
120 dbus::ErrorResponse::FromMethodCall(method_call,
121 kRunningApplicationDBusError,
123 response_sender.Run(error_response.PassAs<dbus::Response>());
127 TerminateApplication();
129 scoped_ptr<dbus::Response> response =
130 dbus::Response::FromMethodCall(method_call);
131 response_sender.Run(response.Pass());
134 void RunningApplicationObject::OnGetExtensionProcessChannel(
135 dbus::MethodCall* method_call,
136 dbus::ExportedObject::ResponseSender response_sender) {
137 content::BrowserThread::PostTask(
138 content::BrowserThread::FILE,
140 base::Bind(&RunningApplicationObject::SendChannel,
141 base::Unretained(this),
146 #if defined(OS_TIZEN)
147 void RunningApplicationObject::OnHide(
148 dbus::MethodCall* method_call,
149 dbus::ExportedObject::ResponseSender response_sender) {
150 if (method_call->GetSender() != launcher_name_) {
151 scoped_ptr<dbus::ErrorResponse> error_response =
152 dbus::ErrorResponse::FromMethodCall(method_call,
153 kRunningApplicationDBusError,
155 response_sender.Run(error_response.PassAs<dbus::Response>());
159 ToApplicationTizen(application_)->Hide();
161 scoped_ptr<dbus::Response> response =
162 dbus::Response::FromMethodCall(method_call);
163 response_sender.Run(response.Pass());
166 void RunningApplicationObject::OnSuspend(
167 dbus::MethodCall* method_call,
168 dbus::ExportedObject::ResponseSender response_sender) {
169 if (method_call->GetSender() != launcher_name_) {
170 scoped_ptr<dbus::ErrorResponse> error_response =
171 dbus::ErrorResponse::FromMethodCall(method_call,
172 kRunningApplicationDBusError,
174 response_sender.Run(error_response.PassAs<dbus::Response>());
178 ToApplicationTizen(application_)->Suspend();
180 scoped_ptr<dbus::Response> response =
181 dbus::Response::FromMethodCall(method_call);
182 response_sender.Run(response.Pass());
185 void RunningApplicationObject::OnResume(
186 dbus::MethodCall* method_call,
187 dbus::ExportedObject::ResponseSender response_sender) {
188 if (method_call->GetSender() != launcher_name_) {
189 scoped_ptr<dbus::ErrorResponse> error_response =
190 dbus::ErrorResponse::FromMethodCall(method_call,
191 kRunningApplicationDBusError,
193 response_sender.Run(error_response.PassAs<dbus::Response>());
197 ToApplicationTizen(application_)->Resume();
199 scoped_ptr<dbus::Response> response =
200 dbus::Response::FromMethodCall(method_call);
201 response_sender.Run(response.Pass());
205 void RunningApplicationObject::ListenForOwnerChange() {
206 owner_change_callback_ =
207 base::Bind(&RunningApplicationObject::OnNameOwnerChanged,
208 base::Unretained(this));
209 bus_->ListenForServiceOwnerChange(launcher_name_, owner_change_callback_);
212 void RunningApplicationObject::UnlistenForOwnerChange() {
213 if (owner_change_callback_.is_null())
215 bus_->UnlistenForServiceOwnerChange(launcher_name_, owner_change_callback_);
216 owner_change_callback_.Reset();
219 void RunningApplicationObject::OnNameOwnerChanged(
220 const std::string& service_owner) {
221 if (service_owner.empty()) {
222 // The process that sent the 'Launch' message has exited the session bus,
223 // we should kill the Running Application.
224 OnLauncherDisappeared();
228 void RunningApplicationObject::OnLauncherDisappeared() {
229 TerminateApplication();
232 void RunningApplicationObject::SendChannel(
233 dbus::MethodCall* method_call,
234 dbus::ExportedObject::ResponseSender response_sender) {
235 scoped_ptr<dbus::Response> response =
236 dbus::Response::FromMethodCall(method_call);
238 int fd = ep_bp_channel_.socket.fd;
239 if (fd == -1) { // EP was not yet created, return empty response.
240 response_sender.Run(response.Pass());
244 dbus::MessageWriter writer(response.get());
245 writer.AppendString(ep_bp_channel_.name);
247 scoped_ptr<dbus::FileDescriptor> client_fd(new dbus::FileDescriptor(fd));
248 client_fd->CheckValidity();
249 CHECK(client_fd->is_valid());
250 writer.AppendFileDescriptor(*client_fd);
252 response_sender.Run(response.Pass());
255 void RunningApplicationObject::ExtensionProcessCreated(
256 const IPC::ChannelHandle& handle) {
257 ep_bp_channel_ = handle;
258 dbus::Signal signal(kRunningApplicationDBusInterface, "EPChannelCreated");
259 dbus_object()->SendSignal(&signal);
262 } // namespace application