Revert of Adding a router class to handle messages that expect responses. (https...
[chromium-blink-merge.git] / device / media_transfer_protocol / media_transfer_protocol_daemon_client.cc
blob062a37c45f8144e41bf94e0048471f202d06ea88
1 // Copyright (c) 2012 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.
5 #include "device/media_transfer_protocol/media_transfer_protocol_daemon_client.h"
7 #include "base/bind.h"
8 #include "base/memory/weak_ptr.h"
9 #include "dbus/bus.h"
10 #include "dbus/message.h"
11 #include "dbus/object_path.h"
12 #include "dbus/object_proxy.h"
13 #include "device/media_transfer_protocol/mtp_file_entry.pb.h"
14 #include "device/media_transfer_protocol/mtp_storage_info.pb.h"
15 #include "third_party/cros_system_api/dbus/service_constants.h"
17 namespace device {
19 namespace {
21 const char kInvalidResponseMsg[] = "Invalid Response: ";
22 uint32 kMaxChunkSize = 1024*1024; // D-Bus has message size limits.
24 // The MediaTransferProtocolDaemonClient implementation.
25 class MediaTransferProtocolDaemonClientImpl
26 : public MediaTransferProtocolDaemonClient {
27 public:
28 explicit MediaTransferProtocolDaemonClientImpl(dbus::Bus* bus)
29 : proxy_(bus->GetObjectProxy(
30 mtpd::kMtpdServiceName,
31 dbus::ObjectPath(mtpd::kMtpdServicePath))),
32 listen_for_changes_called_(false),
33 weak_ptr_factory_(this) {
36 // MediaTransferProtocolDaemonClient override.
37 virtual void EnumerateStorages(const EnumerateStoragesCallback& callback,
38 const ErrorCallback& error_callback) OVERRIDE {
39 dbus::MethodCall method_call(mtpd::kMtpdInterface,
40 mtpd::kEnumerateStorages);
41 proxy_->CallMethod(
42 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
43 base::Bind(&MediaTransferProtocolDaemonClientImpl::OnEnumerateStorages,
44 weak_ptr_factory_.GetWeakPtr(),
45 callback,
46 error_callback));
49 // MediaTransferProtocolDaemonClient override.
50 virtual void GetStorageInfo(const std::string& storage_name,
51 const GetStorageInfoCallback& callback,
52 const ErrorCallback& error_callback) OVERRIDE {
53 dbus::MethodCall method_call(mtpd::kMtpdInterface, mtpd::kGetStorageInfo);
54 dbus::MessageWriter writer(&method_call);
55 writer.AppendString(storage_name);
56 proxy_->CallMethod(
57 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
58 base::Bind(&MediaTransferProtocolDaemonClientImpl::OnGetStorageInfo,
59 weak_ptr_factory_.GetWeakPtr(),
60 storage_name,
61 callback,
62 error_callback));
65 // MediaTransferProtocolDaemonClient override.
66 virtual void OpenStorage(const std::string& storage_name,
67 const std::string& mode,
68 const OpenStorageCallback& callback,
69 const ErrorCallback& error_callback) OVERRIDE {
70 dbus::MethodCall method_call(mtpd::kMtpdInterface, mtpd::kOpenStorage);
71 dbus::MessageWriter writer(&method_call);
72 writer.AppendString(storage_name);
73 DCHECK_EQ(mtpd::kReadOnlyMode, mode);
74 writer.AppendString(mtpd::kReadOnlyMode);
75 proxy_->CallMethod(
76 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
77 base::Bind(&MediaTransferProtocolDaemonClientImpl::OnOpenStorage,
78 weak_ptr_factory_.GetWeakPtr(),
79 callback,
80 error_callback));
83 // MediaTransferProtocolDaemonClient override.
84 virtual void CloseStorage(const std::string& handle,
85 const CloseStorageCallback& callback,
86 const ErrorCallback& error_callback) OVERRIDE {
87 dbus::MethodCall method_call(mtpd::kMtpdInterface, mtpd::kCloseStorage);
88 dbus::MessageWriter writer(&method_call);
89 writer.AppendString(handle);
90 proxy_->CallMethod(
91 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
92 base::Bind(&MediaTransferProtocolDaemonClientImpl::OnCloseStorage,
93 weak_ptr_factory_.GetWeakPtr(),
94 callback,
95 error_callback));
98 // MediaTransferProtocolDaemonClient override.
99 virtual void ReadDirectoryById(
100 const std::string& handle,
101 uint32 file_id,
102 const ReadDirectoryCallback& callback,
103 const ErrorCallback& error_callback) OVERRIDE {
104 dbus::MethodCall method_call(mtpd::kMtpdInterface,
105 mtpd::kReadDirectoryById);
106 dbus::MessageWriter writer(&method_call);
107 writer.AppendString(handle);
108 writer.AppendUint32(file_id);
109 proxy_->CallMethod(
110 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
111 base::Bind(&MediaTransferProtocolDaemonClientImpl::OnReadDirectory,
112 weak_ptr_factory_.GetWeakPtr(),
113 callback,
114 error_callback));
117 // MediaTransferProtocolDaemonClient override.
118 virtual void ReadFileChunkById(const std::string& handle,
119 uint32 file_id,
120 uint32 offset,
121 uint32 bytes_to_read,
122 const ReadFileCallback& callback,
123 const ErrorCallback& error_callback) OVERRIDE {
124 DCHECK_LE(bytes_to_read, kMaxChunkSize);
125 dbus::MethodCall method_call(mtpd::kMtpdInterface,
126 mtpd::kReadFileChunkById);
127 dbus::MessageWriter writer(&method_call);
128 writer.AppendString(handle);
129 writer.AppendUint32(file_id);
130 writer.AppendUint32(offset);
131 writer.AppendUint32(bytes_to_read);
132 proxy_->CallMethod(
133 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
134 base::Bind(&MediaTransferProtocolDaemonClientImpl::OnReadFile,
135 weak_ptr_factory_.GetWeakPtr(),
136 callback,
137 error_callback));
140 // MediaTransferProtocolDaemonClient override.
141 virtual void GetFileInfoById(const std::string& handle,
142 uint32 file_id,
143 const GetFileInfoCallback& callback,
144 const ErrorCallback& error_callback) OVERRIDE {
145 dbus::MethodCall method_call(mtpd::kMtpdInterface, mtpd::kGetFileInfoById);
146 dbus::MessageWriter writer(&method_call);
147 writer.AppendString(handle);
148 writer.AppendUint32(file_id);
149 proxy_->CallMethod(
150 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
151 base::Bind(&MediaTransferProtocolDaemonClientImpl::OnGetFileInfo,
152 weak_ptr_factory_.GetWeakPtr(),
153 callback,
154 error_callback));
157 // MediaTransferProtocolDaemonClient override.
158 virtual void ListenForChanges(
159 const MTPStorageEventHandler& handler) OVERRIDE {
160 DCHECK(!listen_for_changes_called_);
161 listen_for_changes_called_ = true;
163 static const SignalEventTuple kSignalEventTuples[] = {
164 { mtpd::kMTPStorageAttached, true },
165 { mtpd::kMTPStorageDetached, false },
167 const size_t kNumSignalEventTuples = arraysize(kSignalEventTuples);
169 for (size_t i = 0; i < kNumSignalEventTuples; ++i) {
170 proxy_->ConnectToSignal(
171 mtpd::kMtpdInterface,
172 kSignalEventTuples[i].signal_name,
173 base::Bind(&MediaTransferProtocolDaemonClientImpl::OnMTPStorageSignal,
174 weak_ptr_factory_.GetWeakPtr(),
175 handler,
176 kSignalEventTuples[i].is_attach),
177 base::Bind(&MediaTransferProtocolDaemonClientImpl::OnSignalConnected,
178 weak_ptr_factory_.GetWeakPtr()));
182 private:
183 // A struct to contain a pair of signal name and attachment event type.
184 // Used by SetUpConnections.
185 struct SignalEventTuple {
186 const char *signal_name;
187 bool is_attach;
190 // Handles the result of EnumerateStorages and calls |callback| or
191 // |error_callback|.
192 void OnEnumerateStorages(const EnumerateStoragesCallback& callback,
193 const ErrorCallback& error_callback,
194 dbus::Response* response) {
195 if (!response) {
196 error_callback.Run();
197 return;
199 dbus::MessageReader reader(response);
200 std::vector<std::string> storage_names;
201 if (!reader.PopArrayOfStrings(&storage_names)) {
202 LOG(ERROR) << kInvalidResponseMsg << response->ToString();
203 error_callback.Run();
204 return;
206 callback.Run(storage_names);
209 // Handles the result of GetStorageInfo and calls |callback| or
210 // |error_callback|.
211 void OnGetStorageInfo(const std::string& storage_name,
212 const GetStorageInfoCallback& callback,
213 const ErrorCallback& error_callback,
214 dbus::Response* response) {
215 LOG(ERROR) << "Client OnGetStorageInfo " << storage_name;
216 if (!response) {
217 error_callback.Run();
218 return;
221 dbus::MessageReader reader(response);
222 MtpStorageInfo protobuf;
223 if (!reader.PopArrayOfBytesAsProto(&protobuf)) {
224 LOG(ERROR) << kInvalidResponseMsg << response->ToString();
225 error_callback.Run();
226 return;
228 callback.Run(protobuf);
231 // Handles the result of OpenStorage and calls |callback| or |error_callback|.
232 void OnOpenStorage(const OpenStorageCallback& callback,
233 const ErrorCallback& error_callback,
234 dbus::Response* response) {
235 if (!response) {
236 error_callback.Run();
237 return;
239 dbus::MessageReader reader(response);
240 std::string handle;
241 if (!reader.PopString(&handle)) {
242 LOG(ERROR) << kInvalidResponseMsg << response->ToString();
243 error_callback.Run();
244 return;
246 callback.Run(handle);
249 // Handles the result of CloseStorage and calls |callback| or
250 // |error_callback|.
251 void OnCloseStorage(const CloseStorageCallback& callback,
252 const ErrorCallback& error_callback,
253 dbus::Response* response) {
254 if (!response) {
255 error_callback.Run();
256 return;
258 callback.Run();
261 // Handles the result of ReadDirectoryById and calls |callback| or
262 // |error_callback|.
263 void OnReadDirectory(const ReadDirectoryCallback& callback,
264 const ErrorCallback& error_callback,
265 dbus::Response* response) {
266 if (!response) {
267 error_callback.Run();
268 return;
271 std::vector<MtpFileEntry> file_entries;
272 dbus::MessageReader reader(response);
273 MtpFileEntries entries_protobuf;
274 if (!reader.PopArrayOfBytesAsProto(&entries_protobuf)) {
275 LOG(ERROR) << kInvalidResponseMsg << response->ToString();
276 error_callback.Run();
277 return;
280 for (int i = 0; i < entries_protobuf.file_entries_size(); ++i)
281 file_entries.push_back(entries_protobuf.file_entries(i));
282 callback.Run(file_entries);
285 // Handles the result of ReadFileChunkById and calls |callback| or
286 // |error_callback|.
287 void OnReadFile(const ReadFileCallback& callback,
288 const ErrorCallback& error_callback,
289 dbus::Response* response) {
290 if (!response) {
291 error_callback.Run();
292 return;
295 const uint8* data_bytes = NULL;
296 size_t data_length = 0;
297 dbus::MessageReader reader(response);
298 if (!reader.PopArrayOfBytes(&data_bytes, &data_length)) {
299 error_callback.Run();
300 return;
302 std::string data(reinterpret_cast<const char*>(data_bytes), data_length);
303 callback.Run(data);
306 // Handles the result of GetFileInfoById and calls |callback| or
307 // |error_callback|.
308 void OnGetFileInfo(const GetFileInfoCallback& callback,
309 const ErrorCallback& error_callback,
310 dbus::Response* response) {
311 if (!response) {
312 error_callback.Run();
313 return;
316 dbus::MessageReader reader(response);
317 MtpFileEntry protobuf;
318 if (!reader.PopArrayOfBytesAsProto(&protobuf)) {
319 LOG(ERROR) << kInvalidResponseMsg << response->ToString();
320 error_callback.Run();
321 return;
323 callback.Run(protobuf);
326 // Handles MTPStorageAttached/Dettached signals and calls |handler|.
327 void OnMTPStorageSignal(MTPStorageEventHandler handler,
328 bool is_attach,
329 dbus::Signal* signal) {
330 dbus::MessageReader reader(signal);
331 std::string storage_name;
332 if (!reader.PopString(&storage_name)) {
333 LOG(ERROR) << "Invalid signal: " << signal->ToString();
334 return;
336 DCHECK(!storage_name.empty());
337 handler.Run(is_attach, storage_name);
341 // Handles the result of signal connection setup.
342 void OnSignalConnected(const std::string& interface,
343 const std::string& signal,
344 bool succeeded) {
345 LOG_IF(ERROR, !succeeded) << "Connect to " << interface << " "
346 << signal << " failed.";
349 dbus::ObjectProxy* proxy_;
351 bool listen_for_changes_called_;
353 // Note: This should remain the last member so it'll be destroyed and
354 // invalidate its weak pointers before any other members are destroyed.
355 base::WeakPtrFactory<MediaTransferProtocolDaemonClientImpl> weak_ptr_factory_;
357 DISALLOW_COPY_AND_ASSIGN(MediaTransferProtocolDaemonClientImpl);
360 } // namespace
362 ////////////////////////////////////////////////////////////////////////////////
363 // MediaTransferProtocolDaemonClient
365 MediaTransferProtocolDaemonClient::MediaTransferProtocolDaemonClient() {}
367 MediaTransferProtocolDaemonClient::~MediaTransferProtocolDaemonClient() {}
369 // static
370 MediaTransferProtocolDaemonClient* MediaTransferProtocolDaemonClient::Create(
371 dbus::Bus* bus) {
372 return new MediaTransferProtocolDaemonClientImpl(bus);
375 } // namespace device