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

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 resource management 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(const OnReadDirectoryCallback& callback)
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,
125 const 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 // The current filesystem backend always returns false.
154 DCHECK(!has_more);
155 if (result == PP_OK && !AddNewEntries(entries))
156 result = PP_ERROR_FAILED;
157 SendGetEntriesReply(result);
158 }
159
160 bool PepperDirectoryReaderHost::AddNewEntries(const Entries& entries) {
161 std::string dir_path = directory_ref_->GetCreateInfo().path;
162 if (dir_path[dir_path.size() - 1] != '/')
163 dir_path += '/';
164 FilePath::StringType dir_file_path = UTF8StringToFilePathString(dir_path);
165
166 for (Entries::const_iterator it = entries.begin();
167 it != entries.end();
168 ++it) {
169 scoped_refptr<PPB_FileRef_Impl> file_ref = PPB_FileRef_Impl::CreateInternal(
170 directory_ref_->file_system()->pp_resource(),
171 FilePathStringToUTF8String(dir_file_path + it->name));
172 file_refs_.push_back(file_ref);
173
174 if (!file_ref) {
175 host_resources_.clear();
176 file_types_.clear();
177 ReleaseResources();
178 return false;
179 }
180
181 // Add a ref count on behalf of the plugin side. If the resources are not
182 // sent for some reason, we should ensure the release of them.
183 file_ref->GetReference();
yzshen1 2013/02/01 23:57:47 Is it better to do line 181-186 in SendGetEntriesR
nhiroki 2013/02/02 05:14:58 Done.
184
185 host_resources_.push_back(file_ref->GetCreateInfo());
186 file_types_.push_back(it->is_directory ?
187 PP_FILETYPE_DIRECTORY : PP_FILETYPE_REGULAR);
188 }
189
190 return true;
191 }
192
193 void PepperDirectoryReaderHost::ReleaseResources() {
194 ppapi::ResourceTracker* tracker =
195 ppapi::PpapiGlobals::Get()->GetResourceTracker();
196 for (FileRefs::iterator it = file_refs_.begin();
197 it != file_refs_.end(); ++it)
198 tracker->ReleaseResource((*it)->pp_resource());
199 file_refs_.clear();
200 }
201
202 void PepperDirectoryReaderHost::SendGetEntriesReply(int32_t result) {
203 reply_context_.params.set_result(result);
204 host()->SendReply(
205 reply_context_,
206 PpapiPluginMsg_DirectoryReader_GetEntriesReply(host_resources_,
207 file_types_));
208 host_resources_.clear();
209 file_types_.clear();
210 }
211
212 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698