1// Copyright 2014 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 "chrome/browser/chromeos/file_system_provider/operations/read_directory.h"
6
7#include <string>
8
9#include "base/memory/linked_ptr.h"
10#include "chrome/common/extensions/api/file_system_provider.h"
11#include "chrome/common/extensions/api/file_system_provider_internal.h"
12
13namespace chromeos {
14namespace file_system_provider {
15namespace operations {
16namespace {
17
18// Convert |input| into |output|. If parsing fails, then returns false.
19bool ConvertRequestValueToEntryList(scoped_ptr<RequestValue> value,
20                                    storage::AsyncFileUtil::EntryList* output) {
21  using extensions::api::file_system_provider::EntryMetadata;
22  using extensions::api::file_system_provider_internal::
23      ReadDirectoryRequestedSuccess::Params;
24
25  const Params* params = value->read_directory_success_params();
26  if (!params)
27    return false;
28
29  for (size_t i = 0; i < params->entries.size(); ++i) {
30    const linked_ptr<EntryMetadata> entry_metadata = params->entries[i];
31
32    storage::DirectoryEntry output_entry;
33    output_entry.is_directory = entry_metadata->is_directory;
34    output_entry.name = entry_metadata->name;
35    output_entry.size = static_cast<int64>(entry_metadata->size);
36
37    std::string input_modification_time;
38    if (!entry_metadata->modification_time.additional_properties.GetString(
39            "value", &input_modification_time)) {
40      return false;
41    }
42    if (!base::Time::FromString(input_modification_time.c_str(),
43                                &output_entry.last_modified_time)) {
44      return false;
45    }
46
47    output->push_back(output_entry);
48  }
49
50  return true;
51}
52
53}  // namespace
54
55ReadDirectory::ReadDirectory(
56    extensions::EventRouter* event_router,
57    const ProvidedFileSystemInfo& file_system_info,
58    const base::FilePath& directory_path,
59    const storage::AsyncFileUtil::ReadDirectoryCallback& callback)
60    : Operation(event_router, file_system_info),
61      directory_path_(directory_path),
62      callback_(callback) {
63}
64
65ReadDirectory::~ReadDirectory() {
66}
67
68bool ReadDirectory::Execute(int request_id) {
69  using extensions::api::file_system_provider::ReadDirectoryRequestedOptions;
70
71  ReadDirectoryRequestedOptions options;
72  options.file_system_id = file_system_info_.file_system_id();
73  options.request_id = request_id;
74  options.directory_path = directory_path_.AsUTF8Unsafe();
75
76  return SendEvent(
77      request_id,
78      extensions::api::file_system_provider::OnReadDirectoryRequested::
79          kEventName,
80      extensions::api::file_system_provider::OnReadDirectoryRequested::Create(
81          options));
82}
83
84void ReadDirectory::OnSuccess(int /* request_id */,
85                              scoped_ptr<RequestValue> result,
86                              bool has_more) {
87  storage::AsyncFileUtil::EntryList entry_list;
88  const bool convert_result =
89      ConvertRequestValueToEntryList(result.Pass(), &entry_list);
90
91  if (!convert_result) {
92    LOG(ERROR)
93        << "Failed to parse a response for the read directory operation.";
94    callback_.Run(base::File::FILE_ERROR_IO,
95                  storage::AsyncFileUtil::EntryList(),
96                  false /* has_more */);
97    return;
98  }
99
100  callback_.Run(base::File::FILE_OK, entry_list, has_more);
101}
102
103void ReadDirectory::OnError(int /* request_id */,
104                            scoped_ptr<RequestValue> /* result */,
105                            base::File::Error error) {
106  callback_.Run(
107      error, storage::AsyncFileUtil::EntryList(), false /* has_more */);
108}
109
110}  // namespace operations
111}  // namespace file_system_provider
112}  // namespace chromeos
113