Roll src/third_party/WebKit 6c137a7:4aace46 (svn 202008:202009)
[chromium-blink-merge.git] / ppapi / proxy / file_chooser_resource.cc
blobf1d045bac911baf3eab69d95959cefac76567386
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 "ppapi/proxy/file_chooser_resource.h"
7 #include "base/bind.h"
8 #include "base/strings/string_split.h"
9 #include "ipc/ipc_message.h"
10 #include "ppapi/c/pp_errors.h"
11 #include "ppapi/proxy/dispatch_reply_message.h"
12 #include "ppapi/proxy/file_ref_resource.h"
13 #include "ppapi/proxy/ppapi_messages.h"
14 #include "ppapi/shared_impl/var.h"
16 namespace ppapi {
17 namespace proxy {
19 FileChooserResource::FileChooserResource(Connection connection,
20 PP_Instance instance,
21 PP_FileChooserMode_Dev mode,
22 const std::string& accept_types)
23 : PluginResource(connection, instance),
24 mode_(mode) {
25 PopulateAcceptTypes(accept_types, &accept_types_);
28 FileChooserResource::~FileChooserResource() {
31 thunk::PPB_FileChooser_API* FileChooserResource::AsPPB_FileChooser_API() {
32 return this;
35 int32_t FileChooserResource::Show(const PP_ArrayOutput& output,
36 scoped_refptr<TrackedCallback> callback) {
37 return ShowWithoutUserGesture(PP_FALSE, PP_MakeUndefined(), output, callback);
40 int32_t FileChooserResource::ShowWithoutUserGesture(
41 PP_Bool save_as,
42 PP_Var suggested_file_name,
43 const PP_ArrayOutput& output,
44 scoped_refptr<TrackedCallback> callback) {
45 int32_t result = ShowInternal(save_as, suggested_file_name, callback);
46 if (result == PP_OK_COMPLETIONPENDING)
47 output_.set_pp_array_output(output);
48 return result;
51 int32_t FileChooserResource::Show0_5(scoped_refptr<TrackedCallback> callback) {
52 return ShowInternal(PP_FALSE, PP_MakeUndefined(), callback);
55 PP_Resource FileChooserResource::GetNextChosenFile() {
56 if (file_queue_.empty())
57 return 0;
59 // Return the next resource in the queue. It will already have been addrefed
60 // (they're currently owned by the FileChooser) and returning it transfers
61 // ownership of that reference to the plugin.
62 PP_Resource next = file_queue_.front();
63 file_queue_.pop();
64 return next;
67 int32_t FileChooserResource::ShowWithoutUserGesture0_5(
68 PP_Bool save_as,
69 PP_Var suggested_file_name,
70 scoped_refptr<TrackedCallback> callback) {
71 return ShowInternal(save_as, suggested_file_name, callback);
74 // static
75 void FileChooserResource::PopulateAcceptTypes(
76 const std::string& input,
77 std::vector<std::string>* output) {
78 if (input.empty())
79 return;
81 std::vector<std::string> type_list = base::SplitString(
82 input, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
83 output->reserve(type_list.size());
85 for (size_t i = 0; i < type_list.size(); ++i) {
86 std::string type = type_list[i];
87 base::TrimWhitespaceASCII(type, base::TRIM_ALL, &type);
89 // If the type is a single character, it definitely cannot be valid. In the
90 // case of a file extension it would be a single ".". In the case of a MIME
91 // type it would just be a "/".
92 if (type.length() < 2)
93 continue;
94 if (type.find_first_of('/') == std::string::npos && type[0] != '.')
95 continue;
96 output->push_back(base::ToLowerASCII(type));
100 void FileChooserResource::OnPluginMsgShowReply(
101 const ResourceMessageReplyParams& params,
102 const std::vector<FileRefCreateInfo>& chosen_files) {
103 if (output_.is_valid()) {
104 // Using v0.6 of the API with the output array.
105 std::vector<PP_Resource> files;
106 for (size_t i = 0; i < chosen_files.size(); i++) {
107 files.push_back(FileRefResource::CreateFileRef(
108 connection(),
109 pp_instance(),
110 chosen_files[i]));
112 output_.StoreResourceVector(files);
113 } else {
114 // Convert each of the passed in file infos to resources. These will be
115 // owned by the FileChooser object until they're passed to the plugin.
116 DCHECK(file_queue_.empty());
117 for (size_t i = 0; i < chosen_files.size(); i++) {
118 file_queue_.push(FileRefResource::CreateFileRef(
119 connection(),
120 pp_instance(),
121 chosen_files[i]));
125 // Notify the plugin of the new data.
126 callback_->Run(params.result());
127 // DANGER: May delete |this|!
130 int32_t FileChooserResource::ShowInternal(
131 PP_Bool save_as,
132 const PP_Var& suggested_file_name,
133 scoped_refptr<TrackedCallback> callback) {
134 if (TrackedCallback::IsPending(callback_))
135 return PP_ERROR_INPROGRESS;
137 if (!sent_create_to_renderer())
138 SendCreate(RENDERER, PpapiHostMsg_FileChooser_Create());
140 callback_ = callback;
141 StringVar* sugg_str = StringVar::FromPPVar(suggested_file_name);
143 PpapiHostMsg_FileChooser_Show msg(
144 PP_ToBool(save_as),
145 mode_ == PP_FILECHOOSERMODE_OPENMULTIPLE,
146 sugg_str ? sugg_str->value() : std::string(),
147 accept_types_);
148 Call<PpapiPluginMsg_FileChooser_ShowReply>(RENDERER, msg,
149 base::Bind(&FileChooserResource::OnPluginMsgShowReply, this));
150 return PP_OK_COMPLETIONPENDING;
153 } // namespace proxy
154 } // namespace ppapi