OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // TODO : Support NP_ASFILEONLY mode | 5 // TODO : Support NP_ASFILEONLY mode |
6 // TODO : Support NP_SEEK mode | 6 // TODO : Support NP_SEEK mode |
7 // TODO : Support SEEKABLE=true in NewStream | 7 // TODO : Support SEEKABLE=true in NewStream |
8 | 8 |
9 #include "content/child/npapi/plugin_stream.h" | 9 #include "content/child/npapi/plugin_stream.h" |
10 | 10 |
11 #include <algorithm> | 11 #include <algorithm> |
12 | 12 |
13 #include "base/bind.h" | 13 #include "base/bind.h" |
14 #include "base/location.h" | 14 #include "base/location.h" |
15 #include "base/single_thread_task_runner.h" | 15 #include "base/single_thread_task_runner.h" |
16 #include "base/strings/string_util.h" | 16 #include "base/strings/string_util.h" |
17 #include "base/strings/utf_string_conversions.h" | 17 #include "base/strings/utf_string_conversions.h" |
18 #include "base/thread_task_runner_handle.h" | 18 #include "base/thread_task_runner_handle.h" |
19 #include "content/child/npapi/plugin_instance.h" | 19 #include "content/child/npapi/plugin_instance.h" |
20 #include "net/base/mime_util.h" | 20 #include "net/base/mime_util.h" |
21 #include "url/gurl.h" | 21 #include "url/gurl.h" |
22 | 22 |
23 namespace content { | 23 namespace content { |
24 | 24 |
25 PluginStream::PluginStream( | 25 PluginStream::PluginStream( |
26 PluginInstance* instance, | 26 PluginInstance* instance, |
27 const char* url, | 27 const char* url) |
28 bool need_notify, | |
29 void* notify_data) | |
30 : instance_(instance), | 28 : instance_(instance), |
31 notify_needed_(need_notify), | |
32 notify_data_(notify_data), | |
33 close_on_write_data_(false), | 29 close_on_write_data_(false), |
34 requested_plugin_mode_(NP_NORMAL), | 30 requested_plugin_mode_(NP_NORMAL), |
35 opened_(false), | 31 opened_(false), |
36 data_offset_(0), | 32 data_offset_(0), |
37 seekable_stream_(false) { | 33 seekable_stream_(false) { |
38 memset(&stream_, 0, sizeof(stream_)); | 34 memset(&stream_, 0, sizeof(stream_)); |
39 stream_.url = base::strdup(url); | 35 stream_.url = base::strdup(url); |
40 ResetTempFileHandle(); | 36 ResetTempFileHandle(); |
41 ResetTempFileName(); | 37 ResetTempFileName(); |
42 } | 38 } |
43 | 39 |
44 PluginStream::~PluginStream() { | 40 PluginStream::~PluginStream() { |
45 // always close our temporary files. | 41 // always close our temporary files. |
46 CloseTempFile(); | 42 CloseTempFile(); |
47 free(const_cast<char*>(stream_.url)); | 43 free(const_cast<char*>(stream_.url)); |
48 } | 44 } |
49 | 45 |
50 bool PluginStream::Open(const std::string& mime_type, | 46 bool PluginStream::Open(const std::string& mime_type, |
51 const std::string& headers, | 47 const std::string& headers, |
52 uint32 length, | 48 uint32 length, |
53 uint32 last_modified, | 49 uint32 last_modified, |
54 bool request_is_seekable) { | 50 bool request_is_seekable) { |
55 headers_ = headers; | 51 headers_ = headers; |
56 NPP id = instance_->npp(); | 52 NPP id = instance_->npp(); |
57 stream_.end = length; | 53 stream_.end = length; |
58 stream_.lastmodified = last_modified; | 54 stream_.lastmodified = last_modified; |
59 stream_.pdata = 0; | 55 stream_.pdata = 0; |
60 stream_.ndata = id->ndata; | 56 stream_.ndata = id->ndata; |
61 stream_.notifyData = notify_data_; | |
62 if (!headers_.empty()) | 57 if (!headers_.empty()) |
63 stream_.headers = headers_.c_str(); | 58 stream_.headers = headers_.c_str(); |
64 | 59 |
65 bool seekable_stream = false; | 60 bool seekable_stream = false; |
66 if (request_is_seekable) { | 61 if (request_is_seekable) { |
67 std::string headers_lc = base::ToLowerASCII(headers); | 62 std::string headers_lc = base::ToLowerASCII(headers); |
68 if (headers_lc.find("accept-ranges: bytes") != std::string::npos) { | 63 if (headers_lc.find("accept-ranges: bytes") != std::string::npos) { |
69 seekable_stream = true; | 64 seekable_stream = true; |
70 } | 65 } |
71 } | 66 } |
72 | 67 |
73 const char* char_mime_type = "application/x-unknown-content-type"; | 68 const char* char_mime_type = "application/x-unknown-content-type"; |
74 std::string temp_mime_type; | 69 std::string temp_mime_type; |
75 if (!mime_type.empty()) { | 70 if (!mime_type.empty()) { |
76 char_mime_type = mime_type.c_str(); | 71 char_mime_type = mime_type.c_str(); |
77 } else { | 72 } else { |
78 GURL gurl(stream_.url); | 73 GURL gurl(stream_.url); |
79 | 74 |
80 base::FilePath path = base::FilePath::FromUTF8Unsafe(gurl.path()); | 75 base::FilePath path = base::FilePath::FromUTF8Unsafe(gurl.path()); |
81 if (net::GetMimeTypeFromFile(path, &temp_mime_type)) | 76 if (net::GetMimeTypeFromFile(path, &temp_mime_type)) |
82 char_mime_type = temp_mime_type.c_str(); | 77 char_mime_type = temp_mime_type.c_str(); |
83 } | 78 } |
84 | 79 |
85 // Silverlight expects a valid mime type | 80 // Silverlight expects a valid mime type |
86 DCHECK_NE(0U, strlen(char_mime_type)); | 81 DCHECK_NE(0U, strlen(char_mime_type)); |
87 NPError err = instance_->NPP_NewStream((NPMIMEType)char_mime_type, | 82 NPError err = instance_->NPP_NewStream((NPMIMEType)char_mime_type, |
88 &stream_, seekable_stream, | 83 &stream_, seekable_stream, |
89 &requested_plugin_mode_); | 84 &requested_plugin_mode_); |
90 if (err != NPERR_NO_ERROR) { | 85 if (err != NPERR_NO_ERROR) |
91 Notify(err); | |
92 return false; | 86 return false; |
93 } | |
94 | 87 |
95 opened_ = true; | 88 opened_ = true; |
96 | 89 |
97 if (requested_plugin_mode_ == NP_SEEK) { | 90 if (requested_plugin_mode_ == NP_SEEK) { |
98 seekable_stream_ = true; | 91 seekable_stream_ = true; |
99 } | 92 } |
100 // If the plugin has requested certain modes, then we need a copy | 93 // If the plugin has requested certain modes, then we need a copy |
101 // of this file on disk. Open it and save it as we go. | 94 // of this file on disk. Open it and save it as we go. |
102 if (RequestedPluginModeIsAsFile()) { | 95 if (RequestedPluginModeIsAsFile()) { |
103 if (OpenTempFile() == false) { | 96 if (OpenTempFile() == false) { |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 if (reason == NPRES_DONE) | 244 if (reason == NPRES_DONE) |
252 WriteAsFile(); | 245 WriteAsFile(); |
253 } | 246 } |
254 | 247 |
255 if (stream_.ndata != NULL) { | 248 if (stream_.ndata != NULL) { |
256 // Stream hasn't been closed yet. | 249 // Stream hasn't been closed yet. |
257 NPError err = instance_->NPP_DestroyStream(&stream_, reason); | 250 NPError err = instance_->NPP_DestroyStream(&stream_, reason); |
258 DCHECK(err == NPERR_NO_ERROR); | 251 DCHECK(err == NPERR_NO_ERROR); |
259 } | 252 } |
260 } | 253 } |
261 | |
262 Notify(reason); | |
263 return true; | 254 return true; |
264 } | 255 } |
265 | 256 |
266 WebPluginResourceClient* PluginStream::AsResourceClient() { | 257 WebPluginResourceClient* PluginStream::AsResourceClient() { |
267 return NULL; | 258 return NULL; |
268 } | 259 } |
269 | 260 |
270 void PluginStream::Notify(NPReason reason) { | |
271 if (notify_needed_) { | |
272 instance_->NPP_URLNotify(stream_.url, reason, notify_data_); | |
273 notify_needed_ = false; | |
274 } | |
275 } | |
276 | |
277 bool PluginStream::RequestedPluginModeIsAsFile() const { | 261 bool PluginStream::RequestedPluginModeIsAsFile() const { |
278 return (requested_plugin_mode_ == NP_ASFILE || | 262 return (requested_plugin_mode_ == NP_ASFILE || |
279 requested_plugin_mode_ == NP_ASFILEONLY); | 263 requested_plugin_mode_ == NP_ASFILEONLY); |
280 } | 264 } |
281 | 265 |
282 } // namespace content | 266 } // namespace content |
OLD | NEW |