blob: dc70cbde55ab1f3db78ea5366b9d738015f5edf8 [file] [log] [blame]
[email protected]eccf80312012-07-14 15:43:421// 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
avie029c4132015-12-23 06:45:227#include <stddef.h>
8
[email protected]e1f5c9b2012-10-04 00:07:449#include "base/bind.h"
[email protected]d778e0422013-03-06 18:10:2210#include "base/strings/string_split.h"
[email protected]eccf80312012-07-14 15:43:4211#include "ipc/ipc_message.h"
12#include "ppapi/c/pp_errors.h"
[email protected]93df81e2012-08-10 22:22:4613#include "ppapi/proxy/dispatch_reply_message.h"
[email protected]c6420f082013-09-18 22:42:4114#include "ppapi/proxy/file_ref_resource.h"
[email protected]eccf80312012-07-14 15:43:4215#include "ppapi/proxy/ppapi_messages.h"
[email protected]eccf80312012-07-14 15:43:4216#include "ppapi/shared_impl/var.h"
17
18namespace ppapi {
19namespace proxy {
20
[email protected]93df81e2012-08-10 22:22:4621FileChooserResource::FileChooserResource(Connection connection,
[email protected]eccf80312012-07-14 15:43:4222 PP_Instance instance,
23 PP_FileChooserMode_Dev mode,
24 const std::string& accept_types)
[email protected]93df81e2012-08-10 22:22:4625 : PluginResource(connection, instance),
[email protected]eccf80312012-07-14 15:43:4226 mode_(mode) {
27 PopulateAcceptTypes(accept_types, &accept_types_);
28}
29
30FileChooserResource::~FileChooserResource() {
31}
32
33thunk::PPB_FileChooser_API* FileChooserResource::AsPPB_FileChooser_API() {
34 return this;
35}
36
37int32_t FileChooserResource::Show(const PP_ArrayOutput& output,
38 scoped_refptr<TrackedCallback> callback) {
39 return ShowWithoutUserGesture(PP_FALSE, PP_MakeUndefined(), output, callback);
40}
41
42int32_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]a20d375c2012-07-17 18:16:0547 int32_t result = ShowInternal(save_as, suggested_file_name, callback);
[email protected]eccf80312012-07-14 15:43:4248 if (result == PP_OK_COMPLETIONPENDING)
49 output_.set_pp_array_output(output);
50 return result;
51}
52
53int32_t FileChooserResource::Show0_5(scoped_refptr<TrackedCallback> callback) {
54 return ShowInternal(PP_FALSE, PP_MakeUndefined(), callback);
55}
56
57PP_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
69int32_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
77void FileChooserResource::PopulateAcceptTypes(
78 const std::string& input,
79 std::vector<std::string>* output) {
80 if (input.empty())
81 return;
82
brettw83dc1612015-08-12 07:31:1883 std::vector<std::string> type_list = base::SplitString(
84 input, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
[email protected]eccf80312012-07-14 15:43:4285 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]8af69c6c2014-03-03 19:05:3189 base::TrimWhitespaceASCII(type, base::TRIM_ALL, &type);
[email protected]eccf80312012-07-14 15:43:4290
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;
brettw8e2106d2015-08-11 19:30:2298 output->push_back(base::ToLowerASCII(type));
[email protected]eccf80312012-07-14 15:43:4299 }
100}
101
[email protected]93df81e2012-08-10 22:22:46102void FileChooserResource::OnPluginMsgShowReply(
103 const ResourceMessageReplyParams& params,
[email protected]c6420f082013-09-18 22:42:41104 const std::vector<FileRefCreateInfo>& chosen_files) {
[email protected]eccf80312012-07-14 15:43:42105 if (output_.is_valid()) {
106 // Using v0.6 of the API with the output array.
107 std::vector<PP_Resource> files;
[email protected]c6420f082013-09-18 22:42:41108 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]eccf80312012-07-14 15:43:42114 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]c6420f082013-09-18 22:42:41120 file_queue_.push(FileRefResource::CreateFileRef(
121 connection(),
122 pp_instance(),
[email protected]eccf80312012-07-14 15:43:42123 chosen_files[i]));
124 }
125 }
126
127 // Notify the plugin of the new data.
[email protected]c9eb50582012-11-05 20:08:24128 callback_->Run(params.result());
[email protected]eccf80312012-07-14 15:43:42129 // DANGER: May delete |this|!
130}
131
132int32_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]9164da32012-10-16 03:40:57140 SendCreate(RENDERER, PpapiHostMsg_FileChooser_Create());
[email protected]eccf80312012-07-14 15:43:42141
142 callback_ = callback;
143 StringVar* sugg_str = StringVar::FromPPVar(suggested_file_name);
144
[email protected]e1f5c9b2012-10-04 00:07:44145 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]9164da32012-10-16 03:40:57150 Call<PpapiPluginMsg_FileChooser_ShowReply>(RENDERER, msg,
[email protected]e1f5c9b2012-10-04 00:07:44151 base::Bind(&FileChooserResource::OnPluginMsgShowReply, this));
[email protected]eccf80312012-07-14 15:43:42152 return PP_OK_COMPLETIONPENDING;
153}
154
155} // namespace proxy
156} // namespace ppapi