1 //
2 // Copyright (C) 2015 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #include "apmanager/dbus/manager_dbus_adaptor.h"
18 
19 #if !defined(__ANDROID__)
20 #include <chromeos/dbus/service_constants.h>
21 #else
22 #include <dbus/apmanager/dbus-constants.h>
23 #endif  // __ANDROID__
24 
25 #include "apmanager/manager.h"
26 
27 using brillo::dbus_utils::ExportedObjectManager;
28 using org::chromium::apmanager::ManagerAdaptor;
29 using std::string;
30 
31 namespace apmanager {
32 
ManagerDBusAdaptor(const scoped_refptr<dbus::Bus> & bus,ExportedObjectManager * object_manager,Manager * manager)33 ManagerDBusAdaptor::ManagerDBusAdaptor(
34     const scoped_refptr<dbus::Bus>& bus,
35     ExportedObjectManager* object_manager,
36     Manager* manager)
37     : adaptor_(this),
38       dbus_object_(object_manager, bus, ManagerAdaptor::GetObjectPath()),
39       bus_(bus),
40       manager_(manager) {}
41 
~ManagerDBusAdaptor()42 ManagerDBusAdaptor::~ManagerDBusAdaptor() {}
43 
RegisterAsync(const base::Callback<void (bool)> & completion_callback)44 void ManagerDBusAdaptor::RegisterAsync(
45     const base::Callback<void(bool)>& completion_callback) {
46   adaptor_.RegisterWithDBusObject(&dbus_object_);
47   dbus_object_.RegisterAsync(completion_callback);
48 }
49 
CreateService(brillo::ErrorPtr * dbus_error,dbus::Message * message,dbus::ObjectPath * out_service)50 bool ManagerDBusAdaptor::CreateService(brillo::ErrorPtr* dbus_error,
51                                        dbus::Message* message,
52                                        dbus::ObjectPath* out_service) {
53   auto service = manager_->CreateService();
54   if (!service) {
55     brillo::Error::AddTo(dbus_error,
56                          FROM_HERE,
57                          brillo::errors::dbus::kDomain,
58                          kErrorInternalError,
59                          "Failed to create new service");
60     return false;
61   }
62 
63   *out_service = service->adaptor()->GetRpcObjectIdentifier();
64 
65   // Setup monitoring for the service's remote owner.
66   service_owner_watchers_[*out_service] =
67       ServiceOwnerWatcherContext(
68           service,
69           std::unique_ptr<DBusServiceWatcher>(
70               new DBusServiceWatcher(
71                   bus_,
72                   message->GetSender(),
73                   base::Bind(&ManagerDBusAdaptor::OnServiceOwnerVanished,
74                              base::Unretained(this),
75                              *out_service))));
76   return true;
77 }
78 
RemoveService(brillo::ErrorPtr * dbus_error,dbus::Message * message,const dbus::ObjectPath & in_service)79 bool ManagerDBusAdaptor::RemoveService(brillo::ErrorPtr* dbus_error,
80                                        dbus::Message* message,
81                                        const dbus::ObjectPath& in_service) {
82   auto watcher_context = service_owner_watchers_.find(in_service);
83   if (watcher_context == service_owner_watchers_.end()) {
84     brillo::Error::AddToPrintf(
85         dbus_error,
86         FROM_HERE,
87         brillo::errors::dbus::kDomain,
88         kErrorInvalidArguments,
89         "Service %s not found",
90         in_service.value().c_str());
91     return false;
92   }
93 
94   Error error;
95   manager_->RemoveService(watcher_context->second.service, &error);
96   service_owner_watchers_.erase(watcher_context);
97   return !error.ToDBusError(dbus_error);
98 }
99 
OnServiceOwnerVanished(const dbus::ObjectPath & service_path)100 void ManagerDBusAdaptor::OnServiceOwnerVanished(
101     const dbus::ObjectPath& service_path) {
102   LOG(INFO) << "Owner for service " << service_path.value() << " vanished";
103   // Remove service watcher.
104   auto watcher_context = service_owner_watchers_.find(service_path);
105   CHECK(watcher_context != service_owner_watchers_.end())
106       << "Owner vanished without watcher setup.";
107 
108   // Tell Manager to remove this service.
109   manager_->RemoveService(watcher_context->second.service, nullptr);
110   service_owner_watchers_.erase(watcher_context);
111 }
112 
113 }  // namespace apmanager
114