Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1004)

Side by Side Diff: content/renderer/pepper/pepper_directory_reader_host.cc

Issue 11958033: Implement Pepper proxy for PPB_DirectoryReader (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix test failure Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2013 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 "content/renderer/pepper/pepper_directory_reader_host.h"
6
7 #include "base/compiler_specific.h"
8 #include "base/utf_string_conversions.h"
9 #include "content/public/renderer/renderer_ppapi_host.h"
10 #include "ppapi/c/pp_errors.h"
11 #include "ppapi/host/dispatch_host_message.h"
12 #include "ppapi/host/ppapi_host.h"
13 #include "ppapi/proxy/ppapi_messages.h"
14 #include "ppapi/shared_impl/file_type_conversion.h"
15 #include "ppapi/shared_impl/ppb_file_ref_shared.h"
16 #include "ppapi/thunk/enter.h"
17 #include "webkit/fileapi/file_system_callback_dispatcher.h"
18 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
19 #include "webkit/plugins/ppapi/ppb_file_ref_impl.h"
20 #include "webkit/plugins/ppapi/ppb_file_system_impl.h"
21 #include "webkit/plugins/ppapi/resource_helper.h"
22
23 using ppapi::thunk::EnterResource;
24 using ppapi::thunk::PPB_FileRef_API;
25 using webkit::ppapi::PPB_FileRef_Impl;
26
27 namespace content {
28
29 namespace {
30
31 std::string FilePathStringToUTF8String(const FilePath::StringType& str) {
32 #if defined(OS_WIN)
33 return WideToUTF8(str);
34 #elif defined(OS_POSIX)
35 return str;
36 #else
37 #error "Unsupported platform."
38 #endif
39 }
40
41 FilePath::StringType UTF8StringToFilePathString(const std::string& str) {
42 #if defined(OS_WIN)
43 return UTF8ToWide(str);
44 #elif defined(OS_POSIX)
45 return str;
46 #else
47 #error "Unsupported platform."
48 #endif
49 }
50
51 class ReadDirectoryCallback : public fileapi::FileSystemCallbackDispatcher {
52 public:
53 typedef base::Callback<void (const PepperDirectoryReaderHost::Entries&,
54 bool, int32_t)>
55 OnReadDirectoryCallback;
56
57 explicit ReadDirectoryCallback(OnReadDirectoryCallback callback)
yzshen1 2013/01/31 08:50:54 Please use const ref.
nhiroki 2013/02/01 08:19:47 Done.
58 : callback_(callback) {}
59 virtual ~ReadDirectoryCallback() {}
60
61 virtual void DidSucceed() OVERRIDE {
62 NOTREACHED();
63 }
64
65 virtual void DidReadMetadata(const base::PlatformFileInfo& file_info,
66 const FilePath& platform_path) OVERRIDE {
67 NOTREACHED();
68 }
69
70 virtual void DidReadDirectory(
71 const std::vector<base::FileUtilProxy::Entry>& entries,
72 bool has_more) OVERRIDE {
73 callback_.Run(entries, has_more, PP_OK);
74 }
75
76 virtual void DidOpenFileSystem(const std::string& name,
77 const GURL& root) OVERRIDE {
78 NOTREACHED();
79 }
80
81 virtual void DidFail(base::PlatformFileError error) OVERRIDE {
82 callback_.Run(PepperDirectoryReaderHost::Entries(),
83 false,
84 ppapi::PlatformFileErrorToPepperError(error));
85 }
86
87 virtual void DidWrite(int64 bytes, bool complete) OVERRIDE {
88 NOTREACHED();
89 }
90
91 virtual void DidOpenFile(base::PlatformFile file) OVERRIDE {
92 NOTREACHED();
93 }
94
95 private:
96 OnReadDirectoryCallback callback_;
97 };
98
99 } // namespace
100
101 PepperDirectoryReaderHost::PepperDirectoryReaderHost(
102 RendererPpapiHost* host,
103 PP_Instance instance,
104 PP_Resource resource)
105 : ResourceHost(host->GetPpapiHost(), instance, resource),
106 renderer_ppapi_host_(host),
107 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
108 }
109
110 PepperDirectoryReaderHost::~PepperDirectoryReaderHost() {
111 }
112
113 int32_t PepperDirectoryReaderHost::OnResourceMessageReceived(
114 const IPC::Message& msg,
115 ppapi::host::HostMessageContext* context) {
116 IPC_BEGIN_MESSAGE_MAP(PepperDirectoryReaderHost, msg)
117 PPAPI_DISPATCH_HOST_RESOURCE_CALL(
118 PpapiHostMsg_DirectoryReader_GetEntries, OnGetEntries)
119 IPC_END_MESSAGE_MAP()
120 return PP_ERROR_FAILED;
121 }
122
123 int32_t PepperDirectoryReaderHost::OnGetEntries(
124 ppapi::host::HostMessageContext* host_context,
yzshen1 2013/01/31 08:50:54 wrong indent.
nhiroki 2013/02/01 08:19:47 Done.
125 ppapi::HostResource resource) {
126 reply_context_ = host_context->MakeReplyMessageContext();
127
128 EnterResource<PPB_FileRef_API> enter(resource.host_resource(), true);
129 if (enter.failed())
130 return PP_ERROR_FAILED;
131 directory_ref_ = static_cast<PPB_FileRef_Impl*>(enter.object());
132
133 if (directory_ref_->GetFileSystemType() == PP_FILESYSTEMTYPE_EXTERNAL)
134 return PP_ERROR_FAILED;
135
136 webkit::ppapi::PluginInstance* plugin_instance =
137 renderer_ppapi_host_->GetPluginInstance(pp_instance());
138 if (!plugin_instance)
139 return PP_ERROR_FAILED;
140
141 if (!plugin_instance->delegate()->ReadDirectory(
142 directory_ref_->GetFileSystemURL(),
143 new ReadDirectoryCallback(
144 base::Bind(&PepperDirectoryReaderHost::OnReadDirectory,
145 weak_factory_.GetWeakPtr()))))
146 return PP_ERROR_FAILED;
147 return PP_OK_COMPLETIONPENDING;
148 }
149
150 void PepperDirectoryReaderHost::OnReadDirectory(const Entries& entries,
151 bool has_more,
152 int32_t result) {
153 DCHECK(!entries.empty() || !has_more);
154
yzshen1 2013/01/31 08:50:54 Is it better to simplify the code like this? if (
nhiroki 2013/02/01 08:19:47 Done.
155 if (result != PP_OK) {
156 SendGetEntriesReply(result);
157 return;
158 }
159
160 if (!AddNewEntries(entries, has_more)) {
161 SendGetEntriesReply(PP_ERROR_FAILED);
162 return;
163 }
164
165 SendGetEntriesReply(result);
166 }
167
168 bool PepperDirectoryReaderHost::AddNewEntries(const Entries& entries,
169 bool has_more) {
170 std::string dir_path = directory_ref_->GetCreateInfo().path;
171 if (dir_path[dir_path.size() - 1] != '/')
172 dir_path += '/';
173 FilePath::StringType dir_file_path = UTF8StringToFilePathString(dir_path);
174 DCHECK(!entries.empty());
yzshen1 2013/01/31 08:50:54 It is possible, according to the logic of the prev
nhiroki 2013/02/01 08:19:47 It's an intended case. Removed this check.
175
176 for (Entries::const_iterator it = entries.begin();
yzshen1 2013/01/31 08:50:54 The ref count handling is wrong in the code below.
nhiroki 2013/02/01 08:19:47 Thanks for the explanation. I read related sourcec
yzshen1 2013/02/01 23:57:47 Correct. Thanks! :)
177 it != entries.end();
178 ++it) {
179 scoped_refptr<PPB_FileRef_Impl> file_ref = PPB_FileRef_Impl::CreateInternal(
180 directory_ref_->file_system()->pp_resource(),
181 FilePathStringToUTF8String(dir_file_path + it->name));
182 file_refs_.push_back(file_ref);
183
184 if (!file_ref) {
185 host_resources_.clear();
186 file_types_.clear();
187 file_refs_.clear();
188 return false;
189 }
190
191 EnterResource<PPB_FileRef_API> enter(file_ref->GetReference(), false);
192 if (enter.failed()) {
193 host_resources_.clear();
194 file_types_.clear();
195 file_refs_.clear();
196 return false;
197 }
198
199 host_resources_.push_back(enter.object()->GetCreateInfo());
200 file_types_.push_back(it->is_directory ?
201 PP_FILETYPE_DIRECTORY : PP_FILETYPE_REGULAR);
202 }
203
204 return true;
205 }
206
207 void PepperDirectoryReaderHost::SendGetEntriesReply(int32_t result) {
208 reply_context_.params.set_result(result);
209 host()->SendReply(
210 reply_context_,
211 PpapiPluginMsg_DirectoryReader_GetEntriesReply(host_resources_,
212 file_types_));
213 host_resources_.clear();
214 file_types_.clear();
215 }
216
217 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698