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), Application::Normal),
62 base::Bind(&RunningApplicationObject::OnExported,
63 base::Unretained(this)));
65 dbus_object()->ExportMethod(
66 kRunningApplicationDBusInterface, "ForceTerminate",
67 base::Bind(&RunningApplicationObject::OnTerminate,
68 base::Unretained(this), Application::Immediate),
69 base::Bind(&RunningApplicationObject::OnExported,
70 base::Unretained(this)));
72 dbus_object()->ExportMethod(
73 kRunningApplicationDBusInterface, "GetEPChannel",
74 base::Bind(&RunningApplicationObject::OnGetExtensionProcessChannel,
75 base::Unretained(this)),
76 base::Bind(&RunningApplicationObject::OnExported,
77 base::Unretained(this)));
80 dbus_object()->ExportMethod(
81 kRunningApplicationDBusInterface, "Hide",
82 base::Bind(&RunningApplicationObject::OnHide,
83 base::Unretained(this)),
84 base::Bind(&RunningApplicationObject::OnExported,
85 base::Unretained(this)));
89 RunningApplicationObject::~RunningApplicationObject() {
90 UnlistenForOwnerChange();
93 void RunningApplicationObject::TerminateApplication(
94 Application::TerminationMode mode) {
95 // The application might be still running after 'Terminate' call
96 // (if 'mode == Normal' and it contains 'OnSuspend' handlers),
97 // so we do not call 'UnlistenForOwnerChange' here - it will
98 // be called anyway right before the actual 'Application' instance
100 application_->Terminate(mode);
103 void RunningApplicationObject::OnExported(const std::string& interface_name,
104 const std::string& method_name,
107 LOG(WARNING) << "Error exporting method '" << interface_name
108 << "." << method_name << "' in '"
109 << path().value() << "'.";
113 void RunningApplicationObject::OnTerminate(
114 Application::TerminationMode mode,
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(mode);
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());
167 void RunningApplicationObject::ListenForOwnerChange() {
168 owner_change_callback_ =
169 base::Bind(&RunningApplicationObject::OnNameOwnerChanged,
170 base::Unretained(this));
171 bus_->ListenForServiceOwnerChange(launcher_name_, owner_change_callback_);
174 void RunningApplicationObject::UnlistenForOwnerChange() {
175 if (owner_change_callback_.is_null())
177 bus_->UnlistenForServiceOwnerChange(launcher_name_, owner_change_callback_);
178 owner_change_callback_.Reset();
181 void RunningApplicationObject::OnNameOwnerChanged(
182 const std::string& service_owner) {
183 if (service_owner.empty()) {
184 // The process that sent the 'Launch' message has exited the session bus,
185 // we should kill the Running Application.
186 OnLauncherDisappeared();
190 void RunningApplicationObject::OnLauncherDisappeared() {
191 // Do not care about 'OnSuspend' handlers if the launcher is already killed.
192 TerminateApplication(Application::Immediate);
195 void RunningApplicationObject::SendChannel(
196 dbus::MethodCall* method_call,
197 dbus::ExportedObject::ResponseSender response_sender) {
198 scoped_ptr<dbus::Response> response =
199 dbus::Response::FromMethodCall(method_call);
201 int fd = ep_bp_channel_.socket.fd;
202 if (fd == -1) { // EP was not yet created, return empty response.
203 response_sender.Run(response.Pass());
207 dbus::MessageWriter writer(response.get());
208 writer.AppendString(ep_bp_channel_.name);
210 scoped_ptr<dbus::FileDescriptor> client_fd(new dbus::FileDescriptor(fd));
211 client_fd->CheckValidity();
212 CHECK(client_fd->is_valid());
213 writer.AppendFileDescriptor(*client_fd);
215 response_sender.Run(response.Pass());
218 void RunningApplicationObject::ExtensionProcessCreated(
219 const IPC::ChannelHandle& handle) {
220 ep_bp_channel_ = handle;
221 dbus::Signal signal(kRunningApplicationDBusInterface, "EPChannelCreated");
222 dbus_object()->SendSignal(&signal);
225 } // namespace application