[email protected] | eccf8031 | 2012-07-14 15:43:42 | [diff] [blame] | 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. |
| 4 | |
| 5 | #include "ppapi/proxy/file_chooser_resource.h" |
| 6 | |
avi | e029c413 | 2015-12-23 06:45:22 | [diff] [blame] | 7 | #include <stddef.h> |
| 8 | |
[email protected] | e1f5c9b | 2012-10-04 00:07:44 | [diff] [blame] | 9 | #include "base/bind.h" |
[email protected] | d778e042 | 2013-03-06 18:10:22 | [diff] [blame] | 10 | #include "base/strings/string_split.h" |
[email protected] | eccf8031 | 2012-07-14 15:43:42 | [diff] [blame] | 11 | #include "ipc/ipc_message.h" |
| 12 | #include "ppapi/c/pp_errors.h" |
[email protected] | 93df81e | 2012-08-10 22:22:46 | [diff] [blame] | 13 | #include "ppapi/proxy/dispatch_reply_message.h" |
[email protected] | c6420f08 | 2013-09-18 22:42:41 | [diff] [blame] | 14 | #include "ppapi/proxy/file_ref_resource.h" |
[email protected] | eccf8031 | 2012-07-14 15:43:42 | [diff] [blame] | 15 | #include "ppapi/proxy/ppapi_messages.h" |
[email protected] | eccf8031 | 2012-07-14 15:43:42 | [diff] [blame] | 16 | #include "ppapi/shared_impl/var.h" |
| 17 | |
| 18 | namespace ppapi { |
| 19 | namespace proxy { |
| 20 | |
[email protected] | 93df81e | 2012-08-10 22:22:46 | [diff] [blame] | 21 | FileChooserResource::FileChooserResource(Connection connection, |
[email protected] | eccf8031 | 2012-07-14 15:43:42 | [diff] [blame] | 22 | PP_Instance instance, |
| 23 | PP_FileChooserMode_Dev mode, |
| 24 | const std::string& accept_types) |
[email protected] | 93df81e | 2012-08-10 22:22:46 | [diff] [blame] | 25 | : PluginResource(connection, instance), |
[email protected] | eccf8031 | 2012-07-14 15:43:42 | [diff] [blame] | 26 | mode_(mode) { |
| 27 | PopulateAcceptTypes(accept_types, &accept_types_); |
| 28 | } |
| 29 | |
| 30 | FileChooserResource::~FileChooserResource() { |
| 31 | } |
| 32 | |
| 33 | thunk::PPB_FileChooser_API* FileChooserResource::AsPPB_FileChooser_API() { |
| 34 | return this; |
| 35 | } |
| 36 | |
| 37 | int32_t FileChooserResource::Show(const PP_ArrayOutput& output, |
| 38 | scoped_refptr<TrackedCallback> callback) { |
| 39 | return ShowWithoutUserGesture(PP_FALSE, PP_MakeUndefined(), output, callback); |
| 40 | } |
| 41 | |
| 42 | int32_t FileChooserResource::ShowWithoutUserGesture( |
| 43 | PP_Bool save_as, |
| 44 | PP_Var suggested_file_name, |
| 45 | const PP_ArrayOutput& output, |
| 46 | scoped_refptr<TrackedCallback> callback) { |
[email protected] | a20d375c | 2012-07-17 18:16:05 | [diff] [blame] | 47 | int32_t result = ShowInternal(save_as, suggested_file_name, callback); |
[email protected] | eccf8031 | 2012-07-14 15:43:42 | [diff] [blame] | 48 | if (result == PP_OK_COMPLETIONPENDING) |
| 49 | output_.set_pp_array_output(output); |
| 50 | return result; |
| 51 | } |
| 52 | |
| 53 | int32_t FileChooserResource::Show0_5(scoped_refptr<TrackedCallback> callback) { |
| 54 | return ShowInternal(PP_FALSE, PP_MakeUndefined(), callback); |
| 55 | } |
| 56 | |
| 57 | PP_Resource FileChooserResource::GetNextChosenFile() { |
| 58 | if (file_queue_.empty()) |
| 59 | return 0; |
| 60 | |
| 61 | // Return the next resource in the queue. It will already have been addrefed |
| 62 | // (they're currently owned by the FileChooser) and returning it transfers |
| 63 | // ownership of that reference to the plugin. |
| 64 | PP_Resource next = file_queue_.front(); |
| 65 | file_queue_.pop(); |
| 66 | return next; |
| 67 | } |
| 68 | |
| 69 | int32_t FileChooserResource::ShowWithoutUserGesture0_5( |
| 70 | PP_Bool save_as, |
| 71 | PP_Var suggested_file_name, |
| 72 | scoped_refptr<TrackedCallback> callback) { |
| 73 | return ShowInternal(save_as, suggested_file_name, callback); |
| 74 | } |
| 75 | |
| 76 | // static |
| 77 | void FileChooserResource::PopulateAcceptTypes( |
| 78 | const std::string& input, |
| 79 | std::vector<std::string>* output) { |
| 80 | if (input.empty()) |
| 81 | return; |
| 82 | |
brettw | 83dc161 | 2015-08-12 07:31:18 | [diff] [blame] | 83 | std::vector<std::string> type_list = base::SplitString( |
| 84 | input, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); |
[email protected] | eccf8031 | 2012-07-14 15:43:42 | [diff] [blame] | 85 | output->reserve(type_list.size()); |
| 86 | |
| 87 | for (size_t i = 0; i < type_list.size(); ++i) { |
| 88 | std::string type = type_list[i]; |
[email protected] | 8af69c6c | 2014-03-03 19:05:31 | [diff] [blame] | 89 | base::TrimWhitespaceASCII(type, base::TRIM_ALL, &type); |
[email protected] | eccf8031 | 2012-07-14 15:43:42 | [diff] [blame] | 90 | |
| 91 | // If the type is a single character, it definitely cannot be valid. In the |
| 92 | // case of a file extension it would be a single ".". In the case of a MIME |
| 93 | // type it would just be a "/". |
| 94 | if (type.length() < 2) |
| 95 | continue; |
| 96 | if (type.find_first_of('/') == std::string::npos && type[0] != '.') |
| 97 | continue; |
brettw | 8e2106d | 2015-08-11 19:30:22 | [diff] [blame] | 98 | output->push_back(base::ToLowerASCII(type)); |
[email protected] | eccf8031 | 2012-07-14 15:43:42 | [diff] [blame] | 99 | } |
| 100 | } |
| 101 | |
[email protected] | 93df81e | 2012-08-10 22:22:46 | [diff] [blame] | 102 | void FileChooserResource::OnPluginMsgShowReply( |
| 103 | const ResourceMessageReplyParams& params, |
[email protected] | c6420f08 | 2013-09-18 22:42:41 | [diff] [blame] | 104 | const std::vector<FileRefCreateInfo>& chosen_files) { |
[email protected] | eccf8031 | 2012-07-14 15:43:42 | [diff] [blame] | 105 | if (output_.is_valid()) { |
| 106 | // Using v0.6 of the API with the output array. |
| 107 | std::vector<PP_Resource> files; |
[email protected] | c6420f08 | 2013-09-18 22:42:41 | [diff] [blame] | 108 | for (size_t i = 0; i < chosen_files.size(); i++) { |
| 109 | files.push_back(FileRefResource::CreateFileRef( |
| 110 | connection(), |
| 111 | pp_instance(), |
| 112 | chosen_files[i])); |
| 113 | } |
[email protected] | eccf8031 | 2012-07-14 15:43:42 | [diff] [blame] | 114 | output_.StoreResourceVector(files); |
| 115 | } else { |
| 116 | // Convert each of the passed in file infos to resources. These will be |
| 117 | // owned by the FileChooser object until they're passed to the plugin. |
| 118 | DCHECK(file_queue_.empty()); |
| 119 | for (size_t i = 0; i < chosen_files.size(); i++) { |
[email protected] | c6420f08 | 2013-09-18 22:42:41 | [diff] [blame] | 120 | file_queue_.push(FileRefResource::CreateFileRef( |
| 121 | connection(), |
| 122 | pp_instance(), |
[email protected] | eccf8031 | 2012-07-14 15:43:42 | [diff] [blame] | 123 | chosen_files[i])); |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | // Notify the plugin of the new data. |
[email protected] | c9eb5058 | 2012-11-05 20:08:24 | [diff] [blame] | 128 | callback_->Run(params.result()); |
[email protected] | eccf8031 | 2012-07-14 15:43:42 | [diff] [blame] | 129 | // DANGER: May delete |this|! |
| 130 | } |
| 131 | |
| 132 | int32_t FileChooserResource::ShowInternal( |
| 133 | PP_Bool save_as, |
| 134 | const PP_Var& suggested_file_name, |
| 135 | scoped_refptr<TrackedCallback> callback) { |
| 136 | if (TrackedCallback::IsPending(callback_)) |
| 137 | return PP_ERROR_INPROGRESS; |
| 138 | |
| 139 | if (!sent_create_to_renderer()) |
[email protected] | 9164da3 | 2012-10-16 03:40:57 | [diff] [blame] | 140 | SendCreate(RENDERER, PpapiHostMsg_FileChooser_Create()); |
[email protected] | eccf8031 | 2012-07-14 15:43:42 | [diff] [blame] | 141 | |
| 142 | callback_ = callback; |
| 143 | StringVar* sugg_str = StringVar::FromPPVar(suggested_file_name); |
| 144 | |
[email protected] | e1f5c9b | 2012-10-04 00:07:44 | [diff] [blame] | 145 | PpapiHostMsg_FileChooser_Show msg( |
| 146 | PP_ToBool(save_as), |
| 147 | mode_ == PP_FILECHOOSERMODE_OPENMULTIPLE, |
| 148 | sugg_str ? sugg_str->value() : std::string(), |
| 149 | accept_types_); |
[email protected] | 9164da3 | 2012-10-16 03:40:57 | [diff] [blame] | 150 | Call<PpapiPluginMsg_FileChooser_ShowReply>(RENDERER, msg, |
[email protected] | e1f5c9b | 2012-10-04 00:07:44 | [diff] [blame] | 151 | base::Bind(&FileChooserResource::OnPluginMsgShowReply, this)); |
[email protected] | eccf8031 | 2012-07-14 15:43:42 | [diff] [blame] | 152 | return PP_OK_COMPLETIONPENDING; |
| 153 | } |
| 154 | |
| 155 | } // namespace proxy |
| 156 | } // namespace ppapi |