1 // Copyright 2020 The Chromium Authors. 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 "chromeos/dbus/ip_peripheral/ip_peripheral_service_client.h"
6 
7 #include <utility>
8 
9 #include "base/bind.h"
10 #include "base/callback_helpers.h"
11 #include "base/logging.h"
12 #include "base/macros.h"
13 #include "chromeos/dbus/ip_peripheral/fake_ip_peripheral_service_client.h"
14 #include "dbus/bus.h"
15 #include "dbus/message.h"
16 #include "dbus/object_proxy.h"
17 
18 #include "third_party/cros_system_api/dbus/service_constants.h"
19 
20 namespace chromeos {
21 namespace {
22 
23 IpPeripheralServiceClient* g_instance = nullptr;
24 
OnGetMethod(IpPeripheralServiceClient::GetCallback callback,dbus::Response * response)25 void OnGetMethod(IpPeripheralServiceClient::GetCallback callback,
26                  dbus::Response* response) {
27   int32_t value = 0;
28   int32_t min = 0;
29   int32_t max = 0;
30 
31   if (!response) {
32     LOG(ERROR) << "Unable to get pan/tilt/zoom value. Call failed, no response";
33     std::move(callback).Run(false, value, min, max);
34     return;
35   }
36 
37   dbus::MessageReader reader(response);
38 
39   if (!reader.PopInt32(&value)) {
40     LOG(ERROR) << "Unable to read pan/tilt/zoom value.";
41     std::move(callback).Run(false, value, min, max);
42     return;
43   }
44 
45   if (!reader.PopInt32(&min)) {
46     LOG(ERROR) << "Unable to read pan/tilt/zoom min value.";
47     std::move(callback).Run(false, value, min, max);
48     return;
49   }
50 
51   if (!reader.PopInt32(&max)) {
52     LOG(ERROR) << "Unable to read pan/tilt/zoom max value.";
53     std::move(callback).Run(false, value, min, max);
54     return;
55   }
56 
57   std::move(callback).Run(true, value, min, max);
58 }
59 
OnSetMethod(IpPeripheralServiceClient::SetCallback callback,dbus::Response * response)60 void OnSetMethod(IpPeripheralServiceClient::SetCallback callback,
61                  dbus::Response* response) {
62   if (!response) {
63     LOG(ERROR) << "Unable to set pan/tilt/zoom value. Call failed, no response";
64     std::move(callback).Run(false);
65     return;
66   }
67   std::move(callback).Run(true);
68 }
69 
70 // Real implementation of IpPeripheralServiceClient.
71 class IpPeripheralServiceClientImpl : public IpPeripheralServiceClient {
72  public:
73   IpPeripheralServiceClientImpl() = default;
74   IpPeripheralServiceClientImpl(const IpPeripheralServiceClientImpl&) = delete;
75   IpPeripheralServiceClientImpl& operator=(
76       const IpPeripheralServiceClientImpl&) = delete;
77   ~IpPeripheralServiceClientImpl() override = default;
78 
GetPan(const std::string & ip,GetCallback callback)79   void GetPan(const std::string& ip, GetCallback callback) override {
80     dbus::MethodCall method_call(ip_peripheral::kIpPeripheralServiceInterface,
81                                  ip_peripheral::kGetPanMethod);
82     dbus::MessageWriter writer(&method_call);
83     writer.AppendString(ip);
84     ip_peripheral_service_proxy_->CallMethod(
85         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
86         base::BindOnce(&OnGetMethod, std::move(callback)));
87   }
88 
GetTilt(const std::string & ip,GetCallback callback)89   void GetTilt(const std::string& ip, GetCallback callback) override {
90     dbus::MethodCall method_call(ip_peripheral::kIpPeripheralServiceInterface,
91                                  ip_peripheral::kGetTiltMethod);
92     dbus::MessageWriter writer(&method_call);
93     writer.AppendString(ip);
94     ip_peripheral_service_proxy_->CallMethod(
95         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
96         base::BindOnce(&OnGetMethod, std::move(callback)));
97   }
98 
GetZoom(const std::string & ip,GetCallback callback)99   void GetZoom(const std::string& ip, GetCallback callback) override {
100     dbus::MethodCall method_call(ip_peripheral::kIpPeripheralServiceInterface,
101                                  ip_peripheral::kGetZoomMethod);
102     dbus::MessageWriter writer(&method_call);
103     writer.AppendString(ip);
104     ip_peripheral_service_proxy_->CallMethod(
105         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
106         base::BindOnce(&OnGetMethod, std::move(callback)));
107   }
108 
SetPan(const std::string & ip,int32_t pan,SetCallback callback)109   void SetPan(const std::string& ip,
110               int32_t pan,
111               SetCallback callback) override {
112     dbus::MethodCall method_call(ip_peripheral::kIpPeripheralServiceInterface,
113                                  ip_peripheral::kSetPanMethod);
114     dbus::MessageWriter writer(&method_call);
115     writer.AppendString(ip);
116     writer.AppendInt32(pan);
117     ip_peripheral_service_proxy_->CallMethod(
118         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
119         base::BindOnce(&OnSetMethod, std::move(callback)));
120   }
121 
SetTilt(const std::string & ip,int32_t tilt,SetCallback callback)122   void SetTilt(const std::string& ip,
123                int32_t tilt,
124                SetCallback callback) override {
125     dbus::MethodCall method_call(ip_peripheral::kIpPeripheralServiceInterface,
126                                  ip_peripheral::kSetTiltMethod);
127     dbus::MessageWriter writer(&method_call);
128     writer.AppendString(ip);
129     writer.AppendInt32(tilt);
130     ip_peripheral_service_proxy_->CallMethod(
131         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
132         base::BindOnce(&OnSetMethod, std::move(callback)));
133   }
134 
SetZoom(const std::string & ip,int32_t zoom,SetCallback callback)135   void SetZoom(const std::string& ip,
136                int32_t zoom,
137                SetCallback callback) override {
138     dbus::MethodCall method_call(ip_peripheral::kIpPeripheralServiceInterface,
139                                  ip_peripheral::kSetZoomMethod);
140     dbus::MessageWriter writer(&method_call);
141     writer.AppendString(ip);
142     writer.AppendInt32(zoom);
143     ip_peripheral_service_proxy_->CallMethod(
144         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
145         base::BindOnce(&OnSetMethod, std::move(callback)));
146   }
147 
Init(dbus::Bus * bus)148   void Init(dbus::Bus* bus) {
149     ip_peripheral_service_proxy_ = bus->GetObjectProxy(
150         ip_peripheral::kIpPeripheralServiceName,
151         dbus::ObjectPath(ip_peripheral::kIpPeripheralServicePath));
152   }
153 
154  private:
155   dbus::ObjectProxy* ip_peripheral_service_proxy_ = nullptr;
156 };
157 
158 }  // namespace
159 
IpPeripheralServiceClient()160 IpPeripheralServiceClient::IpPeripheralServiceClient() {
161   CHECK(!g_instance);
162   g_instance = this;
163 }
164 
~IpPeripheralServiceClient()165 IpPeripheralServiceClient::~IpPeripheralServiceClient() {
166   CHECK_EQ(this, g_instance);
167   g_instance = nullptr;
168 }
169 
170 // static
Initialize(dbus::Bus * bus)171 void IpPeripheralServiceClient::Initialize(dbus::Bus* bus) {
172   CHECK(bus);
173   (new IpPeripheralServiceClientImpl())->Init(bus);
174 }
175 
176 // static
InitializeFake()177 void IpPeripheralServiceClient::InitializeFake() {
178   new FakeIpPeripheralServiceClient();
179 }
180 
181 // static
Shutdown()182 void IpPeripheralServiceClient::Shutdown() {
183   CHECK(g_instance);
184   delete g_instance;
185 }
186 
187 // static
Get()188 IpPeripheralServiceClient* IpPeripheralServiceClient::Get() {
189   return g_instance;
190 }
191 
192 }  // namespace chromeos
193