- update src.
[platform/framework/web/crosswalk.git] / src / xwalk / application / browser / linux / running_application_object.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_application_object.h"
6
7 #include <string>
8 #include "base/values.h"
9 #include "base/bind.h"
10 #include "dbus/bus.h"
11 #include "dbus/message.h"
12 #include "dbus/exported_object.h"
13 #include "xwalk/application/browser/application.h"
14 #include "xwalk/application/browser/linux/running_applications_manager.h"
15
16
17 namespace {
18
19 // D-Bus Interface implemented by objects that represent running
20 // applications.
21 //
22 // Methods:
23 //
24 //   Terminate()
25 //     Will terminate the running application. This object will be unregistered
26 //     from D-Bus.
27 //
28 // Properties:
29 //
30 //   readonly string AppID
31 const char kRunningApplicationDBusInterface[] =
32     "org.crosswalkproject.Running.Application1";
33
34 const char kRunningApplicationDBusError[] =
35     "org.crosswalkproject.Running.Application.Error";
36
37
38 }  // namespace
39
40 namespace xwalk {
41 namespace application {
42
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     : bus_(bus),
49       launcher_name_(launcher_name),
50       application_(application),
51       dbus::ManagedObject(bus, GetRunningPathForAppID(app_id)),
52       watching_launcher_(true) {
53   bus_->ListenForServiceOwnerChange(
54       launcher_name_,
55       base::Bind(&RunningApplicationObject::OnNameOwnerChanged,
56                  base::Unretained(this)));
57
58   properties()->Set(
59       kRunningApplicationDBusInterface, "AppID",
60       scoped_ptr<base::Value>(base::Value::CreateStringValue(app_id)));
61
62   dbus_object()->ExportMethod(
63       kRunningApplicationDBusInterface, "Terminate",
64       base::Bind(&RunningApplicationObject::OnTerminate,
65                  base::Unretained(this)),
66       base::Bind(&RunningApplicationObject::OnExported,
67                  base::Unretained(this)));
68 }
69
70 RunningApplicationObject::~RunningApplicationObject() {
71   if (watching_launcher_)
72     TerminateApplication();
73 }
74
75 void RunningApplicationObject::TerminateApplication() {
76   bus_->UnlistenForServiceOwnerChange(
77       launcher_name_,
78       base::Bind(&RunningApplicationObject::OnNameOwnerChanged,
79                  base::Unretained(this)));
80   watching_launcher_ = false;
81
82   application_->Terminate();
83 }
84
85 void RunningApplicationObject::OnExported(const std::string& interface_name,
86                                           const std::string& method_name,
87                                           bool success) {
88   if (!success) {
89     LOG(WARNING) << "Error exporting method '" << interface_name
90                  << "." << method_name << "' in '"
91                  << path().value() << "'.";
92   }
93 }
94
95 void RunningApplicationObject::OnTerminate(
96     dbus::MethodCall* method_call,
97     dbus::ExportedObject::ResponseSender response_sender) {
98   // We only allow the caller of Launch() to call Terminate().
99   if (method_call->GetSender() != launcher_name_) {
100     scoped_ptr<dbus::ErrorResponse> error_response =
101         dbus::ErrorResponse::FromMethodCall(method_call,
102                                             kRunningApplicationDBusError,
103                                             "Not permitted");
104     response_sender.Run(error_response.PassAs<dbus::Response>());
105     return;
106   }
107
108   TerminateApplication();
109
110   scoped_ptr<dbus::Response> response =
111       dbus::Response::FromMethodCall(method_call);
112   response_sender.Run(response.Pass());
113 }
114
115 void RunningApplicationObject::OnNameOwnerChanged(
116     const std::string& service_owner) {
117   if (service_owner.empty()) {
118     // The process that sent the 'Launch' message has exited the session bus,
119     // we should kill the Running Application.
120     OnLauncherDisappeared();
121   }
122 }
123
124 void RunningApplicationObject::OnLauncherDisappeared() {
125   TerminateApplication();
126 }
127
128 }  // namespace application
129 }  // namespace xwalk