NaCl: Update revision in DEPS, r12770 -> r12773
[chromium-blink-merge.git] / device / media_transfer_protocol / media_transfer_protocol_daemon_client.cc
blob41ac37e0c8bf9a239f2f420f9f5b584205f52549
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: ";
23 // The MediaTransferProtocolDaemonClient implementation.
24 class MediaTransferProtocolDaemonClientImpl
25 : public MediaTransferProtocolDaemonClient {
26 public:
27 explicit MediaTransferProtocolDaemonClientImpl(dbus::Bus* bus)
28 : proxy_(bus->GetObjectProxy(
29 mtpd::kMtpdServiceName,
30 dbus::ObjectPath(mtpd::kMtpdServicePath))),
31 listen_for_changes_called_(false),
32 weak_ptr_factory_(this) {
35 // MediaTransferProtocolDaemonClient override.
36 virtual void EnumerateStorages(const EnumerateStoragesCallback& callback,
37 const ErrorCallback& error_callback) OVERRIDE {
38 dbus::MethodCall method_call(mtpd::kMtpdInterface,
39 mtpd::kEnumerateStorages);
40 proxy_->CallMethod(
41 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
42 base::Bind(&MediaTransferProtocolDaemonClientImpl::OnEnumerateStorages,
43 weak_ptr_factory_.GetWeakPtr(),
44 callback,
45 error_callback));
48 // MediaTransferProtocolDaemonClient override.
49 virtual void GetStorageInfo(const std::string& storage_name,
50 const GetStorageInfoCallback& callback,
51 const ErrorCallback& error_callback) OVERRIDE {
52 dbus::MethodCall method_call(mtpd::kMtpdInterface, mtpd::kGetStorageInfo);
53 dbus::MessageWriter writer(&method_call);
54 writer.AppendString(storage_name);
55 proxy_->CallMethod(
56 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
57 base::Bind(&MediaTransferProtocolDaemonClientImpl::OnGetStorageInfo,
58 weak_ptr_factory_.GetWeakPtr(),
59 storage_name,
60 callback,
61 error_callback));
64 // MediaTransferProtocolDaemonClient override.
65 virtual void OpenStorage(const std::string& storage_name,
66 const std::string& mode,
67 const OpenStorageCallback& callback,
68 const ErrorCallback& error_callback) OVERRIDE {
69 dbus::MethodCall method_call(mtpd::kMtpdInterface, mtpd::kOpenStorage);
70 dbus::MessageWriter writer(&method_call);
71 writer.AppendString(storage_name);
72 DCHECK_EQ(mtpd::kReadOnlyMode, mode);
73 writer.AppendString(mtpd::kReadOnlyMode);
74 proxy_->CallMethod(
75 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
76 base::Bind(&MediaTransferProtocolDaemonClientImpl::OnOpenStorage,
77 weak_ptr_factory_.GetWeakPtr(),
78 callback,
79 error_callback));
82 // MediaTransferProtocolDaemonClient override.
83 virtual void CloseStorage(const std::string& handle,
84 const CloseStorageCallback& callback,
85 const ErrorCallback& error_callback) OVERRIDE {
86 dbus::MethodCall method_call(mtpd::kMtpdInterface, mtpd::kCloseStorage);
87 dbus::MessageWriter writer(&method_call);
88 writer.AppendString(handle);
89 proxy_->CallMethod(
90 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
91 base::Bind(&MediaTransferProtocolDaemonClientImpl::OnCloseStorage,
92 weak_ptr_factory_.GetWeakPtr(),
93 callback,
94 error_callback));
97 // MediaTransferProtocolDaemonClient override.
98 virtual void ReadDirectoryByPath(
99 const std::string& handle,
100 const std::string& path,
101 const ReadDirectoryCallback& callback,
102 const ErrorCallback& error_callback) OVERRIDE {
103 dbus::MethodCall method_call(mtpd::kMtpdInterface,
104 mtpd::kReadDirectoryByPath);
105 dbus::MessageWriter writer(&method_call);
106 writer.AppendString(handle);
107 writer.AppendString(path);
108 proxy_->CallMethod(
109 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
110 base::Bind(&MediaTransferProtocolDaemonClientImpl::OnReadDirectory,
111 weak_ptr_factory_.GetWeakPtr(),
112 callback,
113 error_callback));
116 // MediaTransferProtocolDaemonClient override.
117 virtual void ReadDirectoryById(
118 const std::string& handle,
119 uint32 file_id,
120 const ReadDirectoryCallback& callback,
121 const ErrorCallback& error_callback) OVERRIDE {
122 dbus::MethodCall method_call(mtpd::kMtpdInterface,
123 mtpd::kReadDirectoryById);
124 dbus::MessageWriter writer(&method_call);
125 writer.AppendString(handle);
126 writer.AppendUint32(file_id);
127 proxy_->CallMethod(
128 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
129 base::Bind(&MediaTransferProtocolDaemonClientImpl::OnReadDirectory,
130 weak_ptr_factory_.GetWeakPtr(),
131 callback,
132 error_callback));
135 // MediaTransferProtocolDaemonClient override.
136 virtual void ReadFileChunkByPath(
137 const std::string& handle,
138 const std::string& path,
139 uint32 offset,
140 uint32 bytes_to_read,
141 const ReadFileCallback& callback,
142 const ErrorCallback& error_callback) OVERRIDE {
143 dbus::MethodCall method_call(mtpd::kMtpdInterface,
144 mtpd::kReadFileChunkByPath);
145 dbus::MessageWriter writer(&method_call);
146 writer.AppendString(handle);
147 writer.AppendString(path);
148 writer.AppendUint32(offset);
149 writer.AppendUint32(bytes_to_read);
150 proxy_->CallMethod(
151 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
152 base::Bind(&MediaTransferProtocolDaemonClientImpl::OnReadFile,
153 weak_ptr_factory_.GetWeakPtr(),
154 callback,
155 error_callback));
158 // MediaTransferProtocolDaemonClient override.
159 virtual void ReadFileChunkById(const std::string& handle,
160 uint32 file_id,
161 uint32 offset,
162 uint32 bytes_to_read,
163 const ReadFileCallback& callback,
164 const ErrorCallback& error_callback) OVERRIDE {
165 dbus::MethodCall method_call(mtpd::kMtpdInterface,
166 mtpd::kReadFileChunkById);
167 dbus::MessageWriter writer(&method_call);
168 writer.AppendString(handle);
169 writer.AppendUint32(file_id);
170 writer.AppendUint32(offset);
171 writer.AppendUint32(bytes_to_read);
172 proxy_->CallMethod(
173 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
174 base::Bind(&MediaTransferProtocolDaemonClientImpl::OnReadFile,
175 weak_ptr_factory_.GetWeakPtr(),
176 callback,
177 error_callback));
180 // MediaTransferProtocolDaemonClient override.
181 virtual void GetFileInfoByPath(const std::string& handle,
182 const std::string& path,
183 const GetFileInfoCallback& callback,
184 const ErrorCallback& error_callback) OVERRIDE {
185 dbus::MethodCall method_call(mtpd::kMtpdInterface,
186 mtpd::kGetFileInfoByPath);
187 dbus::MessageWriter writer(&method_call);
188 writer.AppendString(handle);
189 writer.AppendString(path);
190 proxy_->CallMethod(
191 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
192 base::Bind(&MediaTransferProtocolDaemonClientImpl::OnGetFileInfo,
193 weak_ptr_factory_.GetWeakPtr(),
194 callback,
195 error_callback));
198 // MediaTransferProtocolDaemonClient override.
199 virtual void GetFileInfoById(const std::string& handle,
200 uint32 file_id,
201 const GetFileInfoCallback& callback,
202 const ErrorCallback& error_callback) OVERRIDE {
203 dbus::MethodCall method_call(mtpd::kMtpdInterface, mtpd::kGetFileInfoById);
204 dbus::MessageWriter writer(&method_call);
205 writer.AppendString(handle);
206 writer.AppendUint32(file_id);
207 proxy_->CallMethod(
208 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
209 base::Bind(&MediaTransferProtocolDaemonClientImpl::OnGetFileInfo,
210 weak_ptr_factory_.GetWeakPtr(),
211 callback,
212 error_callback));
215 // MediaTransferProtocolDaemonClient override.
216 virtual void ListenForChanges(
217 const MTPStorageEventHandler& handler) OVERRIDE {
218 DCHECK(!listen_for_changes_called_);
219 listen_for_changes_called_ = true;
221 static const SignalEventTuple kSignalEventTuples[] = {
222 { mtpd::kMTPStorageAttached, true },
223 { mtpd::kMTPStorageDetached, false },
225 const size_t kNumSignalEventTuples = arraysize(kSignalEventTuples);
227 for (size_t i = 0; i < kNumSignalEventTuples; ++i) {
228 proxy_->ConnectToSignal(
229 mtpd::kMtpdInterface,
230 kSignalEventTuples[i].signal_name,
231 base::Bind(&MediaTransferProtocolDaemonClientImpl::OnMTPStorageSignal,
232 weak_ptr_factory_.GetWeakPtr(),
233 handler,
234 kSignalEventTuples[i].is_attach),
235 base::Bind(&MediaTransferProtocolDaemonClientImpl::OnSignalConnected,
236 weak_ptr_factory_.GetWeakPtr()));
240 private:
241 // A struct to contain a pair of signal name and attachment event type.
242 // Used by SetUpConnections.
243 struct SignalEventTuple {
244 const char *signal_name;
245 bool is_attach;
248 // Handles the result of EnumerateStorages and calls |callback| or
249 // |error_callback|.
250 void OnEnumerateStorages(const EnumerateStoragesCallback& callback,
251 const ErrorCallback& error_callback,
252 dbus::Response* response) {
253 if (!response) {
254 error_callback.Run();
255 return;
257 dbus::MessageReader reader(response);
258 std::vector<std::string> storage_names;
259 if (!reader.PopArrayOfStrings(&storage_names)) {
260 LOG(ERROR) << kInvalidResponseMsg << response->ToString();
261 error_callback.Run();
262 return;
264 callback.Run(storage_names);
267 // Handles the result of GetStorageInfo and calls |callback| or
268 // |error_callback|.
269 void OnGetStorageInfo(const std::string& storage_name,
270 const GetStorageInfoCallback& callback,
271 const ErrorCallback& error_callback,
272 dbus::Response* response) {
273 if (!response) {
274 error_callback.Run();
275 return;
278 dbus::MessageReader reader(response);
279 MtpStorageInfo protobuf;
280 if (!reader.PopArrayOfBytesAsProto(&protobuf)) {
281 LOG(ERROR) << kInvalidResponseMsg << response->ToString();
282 error_callback.Run();
283 return;
285 callback.Run(protobuf);
288 // Handles the result of OpenStorage and calls |callback| or |error_callback|.
289 void OnOpenStorage(const OpenStorageCallback& callback,
290 const ErrorCallback& error_callback,
291 dbus::Response* response) {
292 if (!response) {
293 error_callback.Run();
294 return;
296 dbus::MessageReader reader(response);
297 std::string handle;
298 if (!reader.PopString(&handle)) {
299 LOG(ERROR) << kInvalidResponseMsg << response->ToString();
300 error_callback.Run();
301 return;
303 callback.Run(handle);
306 // Handles the result of CloseStorage and calls |callback| or
307 // |error_callback|.
308 void OnCloseStorage(const CloseStorageCallback& callback,
309 const ErrorCallback& error_callback,
310 dbus::Response* response) {
311 if (!response) {
312 error_callback.Run();
313 return;
315 callback.Run();
318 // Handles the result of ReadDirectoryByPath/Id and calls |callback| or
319 // |error_callback|.
320 void OnReadDirectory(const ReadDirectoryCallback& callback,
321 const ErrorCallback& error_callback,
322 dbus::Response* response) {
323 if (!response) {
324 error_callback.Run();
325 return;
328 std::vector<MtpFileEntry> file_entries;
329 dbus::MessageReader reader(response);
330 MtpFileEntries entries_protobuf;
331 if (!reader.PopArrayOfBytesAsProto(&entries_protobuf)) {
332 LOG(ERROR) << kInvalidResponseMsg << response->ToString();
333 error_callback.Run();
334 return;
337 for (int i = 0; i < entries_protobuf.file_entries_size(); ++i)
338 file_entries.push_back(entries_protobuf.file_entries(i));
339 callback.Run(file_entries);
342 // Handles the result of ReadFileChunkByPath/Id and calls |callback| or
343 // |error_callback|.
344 void OnReadFile(const ReadFileCallback& callback,
345 const ErrorCallback& error_callback,
346 dbus::Response* response) {
347 if (!response) {
348 error_callback.Run();
349 return;
352 uint8* data_bytes = NULL;
353 size_t data_length = 0;
354 dbus::MessageReader reader(response);
355 if (!reader.PopArrayOfBytes(&data_bytes, &data_length)) {
356 error_callback.Run();
357 return;
359 std::string data(reinterpret_cast<const char*>(data_bytes), data_length);
360 callback.Run(data);
363 // Handles the result of GetFileInfoByPath/Id and calls |callback| or
364 // |error_callback|.
365 void OnGetFileInfo(const GetFileInfoCallback& callback,
366 const ErrorCallback& error_callback,
367 dbus::Response* response) {
368 if (!response) {
369 error_callback.Run();
370 return;
373 dbus::MessageReader reader(response);
374 MtpFileEntry protobuf;
375 if (!reader.PopArrayOfBytesAsProto(&protobuf)) {
376 LOG(ERROR) << kInvalidResponseMsg << response->ToString();
377 error_callback.Run();
378 return;
380 callback.Run(protobuf);
383 // Handles MTPStorageAttached/Dettached signals and calls |handler|.
384 void OnMTPStorageSignal(MTPStorageEventHandler handler,
385 bool is_attach,
386 dbus::Signal* signal) {
387 dbus::MessageReader reader(signal);
388 std::string storage_name;
389 if (!reader.PopString(&storage_name)) {
390 LOG(ERROR) << "Invalid signal: " << signal->ToString();
391 return;
393 DCHECK(!storage_name.empty());
394 handler.Run(is_attach, storage_name);
398 // Handles the result of signal connection setup.
399 void OnSignalConnected(const std::string& interface,
400 const std::string& signal,
401 bool succeeded) {
402 LOG_IF(ERROR, !succeeded) << "Connect to " << interface << " "
403 << signal << " failed.";
406 dbus::ObjectProxy* proxy_;
408 bool listen_for_changes_called_;
410 // Note: This should remain the last member so it'll be destroyed and
411 // invalidate its weak pointers before any other members are destroyed.
412 base::WeakPtrFactory<MediaTransferProtocolDaemonClientImpl> weak_ptr_factory_;
414 DISALLOW_COPY_AND_ASSIGN(MediaTransferProtocolDaemonClientImpl);
417 } // namespace
419 ////////////////////////////////////////////////////////////////////////////////
420 // MediaTransferProtocolDaemonClient
422 MediaTransferProtocolDaemonClient::MediaTransferProtocolDaemonClient() {}
424 MediaTransferProtocolDaemonClient::~MediaTransferProtocolDaemonClient() {}
426 // static
427 MediaTransferProtocolDaemonClient* MediaTransferProtocolDaemonClient::Create(
428 dbus::Bus* bus) {
429 return new MediaTransferProtocolDaemonClientImpl(bus);
432 } // namespace device