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

Side by Side Diff: chrome/renderer/pepper_plugin_delegate_impl.cc

Issue 6685072: Move a bunch more random files from chrome\renderer to content\renderer. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 9 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
« no previous file with comments | « chrome/renderer/pepper_plugin_delegate_impl.h ('k') | chrome/renderer/render_view.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 "chrome/renderer/pepper_plugin_delegate_impl.h"
6
7 #include <cmath>
8 #include <queue>
9
10 #include "app/surface/transport_dib.h"
11 #include "base/callback.h"
12 #include "base/file_path.h"
13 #include "base/logging.h"
14 #include "base/scoped_ptr.h"
15 #include "base/string_split.h"
16 #include "base/task.h"
17 #include "base/time.h"
18 #include "chrome/common/pepper_plugin_registry.h"
19 #include "chrome/common/render_messages.h"
20 #include "chrome/common/render_messages_params.h"
21 #include "chrome/renderer/pepper_platform_context_3d_impl.h"
22 #include "chrome/renderer/render_thread.h"
23 #include "chrome/renderer/render_view.h"
24 #include "content/common/child_process_messages.h"
25 #include "content/common/child_thread.h"
26 #include "content/common/file_system/file_system_dispatcher.h"
27 #include "content/common/pepper_file_messages.h"
28 #include "content/common/pepper_messages.h"
29 #include "content/renderer/audio_message_filter.h"
30 #include "content/renderer/command_buffer_proxy.h"
31 #include "content/renderer/ggl.h"
32 #include "content/renderer/gpu_channel_host.h"
33 #include "content/renderer/webgraphicscontext3d_command_buffer_impl.h"
34 #include "content/renderer/webplugin_delegate_proxy.h"
35 #include "grit/locale_settings.h"
36 #include "ipc/ipc_channel_handle.h"
37 #include "ppapi/c/dev/pp_video_dev.h"
38 #include "ppapi/c/pp_errors.h"
39 #include "ppapi/c/private/ppb_flash.h"
40 #include "ppapi/c/private/ppb_flash_net_connector.h"
41 #include "ppapi/proxy/host_dispatcher.h"
42 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFileChooserComplet ion.h"
43 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFileChooserParams. h"
44 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h"
45 #include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h"
46 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
47 #include "ui/base/l10n/l10n_util.h"
48 #include "ui/gfx/size.h"
49 #include "webkit/fileapi/file_system_callback_dispatcher.h"
50 #include "webkit/glue/context_menu.h"
51 #include "webkit/plugins/npapi/webplugin.h"
52 #include "webkit/plugins/ppapi/file_path.h"
53 #include "webkit/plugins/ppapi/ppb_file_io_impl.h"
54 #include "webkit/plugins/ppapi/plugin_module.h"
55 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
56 #include "webkit/plugins/ppapi/ppb_flash_impl.h"
57 #include "webkit/plugins/ppapi/ppb_flash_net_connector_impl.h"
58
59 using WebKit::WebView;
60
61 namespace {
62
63 const int32 kDefaultCommandBufferSize = 1024 * 1024;
64
65 // Implements the Image2D using a TransportDIB.
66 class PlatformImage2DImpl
67 : public webkit::ppapi::PluginDelegate::PlatformImage2D {
68 public:
69 // This constructor will take ownership of the dib pointer.
70 // On Mac, we assume that the dib is cached by the browser, so on destruction
71 // we'll tell the browser to free it.
72 PlatformImage2DImpl(int width, int height, TransportDIB* dib)
73 : width_(width),
74 height_(height),
75 dib_(dib) {
76 }
77
78 #if defined(OS_MACOSX)
79 // On Mac, we have to tell the browser to free the transport DIB.
80 virtual ~PlatformImage2DImpl() {
81 if (dib_.get()) {
82 RenderThread::current()->Send(
83 new ViewHostMsg_FreeTransportDIB(dib_->id()));
84 }
85 }
86 #endif
87
88 virtual skia::PlatformCanvas* Map() {
89 return dib_->GetPlatformCanvas(width_, height_);
90 }
91
92 virtual intptr_t GetSharedMemoryHandle(uint32* byte_count) const {
93 *byte_count = dib_->size();
94 #if defined(OS_WIN)
95 return reinterpret_cast<intptr_t>(dib_->handle());
96 #elif defined(OS_MACOSX)
97 return static_cast<intptr_t>(dib_->handle().fd);
98 #elif defined(OS_LINUX)
99 return static_cast<intptr_t>(dib_->handle());
100 #endif
101 }
102
103 virtual TransportDIB* GetTransportDIB() const {
104 return dib_.get();
105 }
106
107 private:
108 int width_;
109 int height_;
110 scoped_ptr<TransportDIB> dib_;
111
112 DISALLOW_COPY_AND_ASSIGN(PlatformImage2DImpl);
113 };
114
115
116 class PlatformAudioImpl
117 : public webkit::ppapi::PluginDelegate::PlatformAudio,
118 public AudioMessageFilter::Delegate,
119 public base::RefCountedThreadSafe<PlatformAudioImpl> {
120 public:
121 explicit PlatformAudioImpl(scoped_refptr<AudioMessageFilter> filter)
122 : client_(NULL), filter_(filter), stream_id_(0),
123 main_message_loop_(MessageLoop::current()) {
124 DCHECK(filter_);
125 }
126
127 virtual ~PlatformAudioImpl() {
128 // Make sure we have been shut down. Warning: this will usually happen on
129 // the I/O thread!
130 DCHECK_EQ(0, stream_id_);
131 DCHECK(!client_);
132 }
133
134 // Initialize this audio context. StreamCreated() will be called when the
135 // stream is created.
136 bool Initialize(uint32_t sample_rate, uint32_t sample_count,
137 webkit::ppapi::PluginDelegate::PlatformAudio::Client* client);
138
139 // PlatformAudio implementation (called on main thread).
140 virtual bool StartPlayback();
141 virtual bool StopPlayback();
142 virtual void ShutDown();
143
144 private:
145 // I/O thread backends to above functions.
146 void InitializeOnIOThread(
147 const ViewHostMsg_Audio_CreateStream_Params& params);
148 void StartPlaybackOnIOThread();
149 void StopPlaybackOnIOThread();
150 void ShutDownOnIOThread();
151
152 virtual void OnRequestPacket(AudioBuffersState buffers_state) {
153 LOG(FATAL) << "Should never get OnRequestPacket in PlatformAudioImpl";
154 }
155
156 virtual void OnStateChanged(const ViewMsg_AudioStreamState_Params& state) {}
157
158 virtual void OnCreated(base::SharedMemoryHandle handle, uint32 length) {
159 LOG(FATAL) << "Should never get OnCreated in PlatformAudioImpl";
160 }
161
162 virtual void OnLowLatencyCreated(base::SharedMemoryHandle handle,
163 base::SyncSocket::Handle socket_handle,
164 uint32 length);
165
166 virtual void OnVolume(double volume) {}
167
168 // The client to notify when the stream is created. THIS MUST ONLY BE
169 // ACCESSED ON THE MAIN THREAD.
170 webkit::ppapi::PluginDelegate::PlatformAudio::Client* client_;
171
172 // MessageFilter used to send/receive IPC. THIS MUST ONLY BE ACCESSED ON THE
173 // I/O thread except to send messages and get the message loop.
174 scoped_refptr<AudioMessageFilter> filter_;
175
176 // Our ID on the MessageFilter. THIS MUST ONLY BE ACCESSED ON THE I/O THREAD
177 // or else you could race with the initialize function which sets it.
178 int32 stream_id_;
179
180 MessageLoop* main_message_loop_;
181
182 DISALLOW_COPY_AND_ASSIGN(PlatformAudioImpl);
183 };
184
185 bool PlatformAudioImpl::Initialize(
186 uint32_t sample_rate, uint32_t sample_count,
187 webkit::ppapi::PluginDelegate::PlatformAudio::Client* client) {
188
189 DCHECK(client);
190 // Make sure we don't call init more than once.
191 DCHECK_EQ(0, stream_id_);
192
193 client_ = client;
194
195 ViewHostMsg_Audio_CreateStream_Params params;
196 params.params.format = AudioParameters::AUDIO_PCM_LINEAR;
197 params.params.channels = 2;
198 params.params.sample_rate = sample_rate;
199 params.params.bits_per_sample = 16;
200 params.params.samples_per_packet = sample_count;
201
202 filter_->message_loop()->PostTask(FROM_HERE,
203 NewRunnableMethod(this, &PlatformAudioImpl::InitializeOnIOThread,
204 params));
205 return true;
206 }
207
208 bool PlatformAudioImpl::StartPlayback() {
209 if (filter_) {
210 filter_->message_loop()->PostTask(FROM_HERE,
211 NewRunnableMethod(this, &PlatformAudioImpl::StartPlaybackOnIOThread));
212 return true;
213 }
214 return false;
215 }
216
217 bool PlatformAudioImpl::StopPlayback() {
218 if (filter_) {
219 filter_->message_loop()->PostTask(FROM_HERE,
220 NewRunnableMethod(this, &PlatformAudioImpl::StopPlaybackOnIOThread));
221 return true;
222 }
223 return false;
224 }
225
226 void PlatformAudioImpl::ShutDown() {
227 // Called on the main thread to stop all audio callbacks. We must only change
228 // the client on the main thread, and the delegates from the I/O thread.
229 client_ = NULL;
230 filter_->message_loop()->PostTask(FROM_HERE,
231 NewRunnableMethod(this, &PlatformAudioImpl::ShutDownOnIOThread));
232 }
233
234 void PlatformAudioImpl::InitializeOnIOThread(
235 const ViewHostMsg_Audio_CreateStream_Params& params) {
236 stream_id_ = filter_->AddDelegate(this);
237 filter_->Send(new ViewHostMsg_CreateAudioStream(0, stream_id_, params, true));
238 }
239
240 void PlatformAudioImpl::StartPlaybackOnIOThread() {
241 if (stream_id_)
242 filter_->Send(new ViewHostMsg_PlayAudioStream(0, stream_id_));
243 }
244
245 void PlatformAudioImpl::StopPlaybackOnIOThread() {
246 if (stream_id_)
247 filter_->Send(new ViewHostMsg_PauseAudioStream(0, stream_id_));
248 }
249
250 void PlatformAudioImpl::ShutDownOnIOThread() {
251 // Make sure we don't call shutdown more than once.
252 if (!stream_id_)
253 return;
254
255 filter_->Send(new ViewHostMsg_CloseAudioStream(0, stream_id_));
256 filter_->RemoveDelegate(stream_id_);
257 stream_id_ = 0;
258
259 Release(); // Release for the delegate, balances out the reference taken in
260 // PepperPluginDelegateImpl::CreateAudio.
261 }
262
263 void PlatformAudioImpl::OnLowLatencyCreated(
264 base::SharedMemoryHandle handle, base::SyncSocket::Handle socket_handle,
265 uint32 length) {
266 #if defined(OS_WIN)
267 DCHECK(handle);
268 DCHECK(socket_handle);
269 #else
270 DCHECK_NE(-1, handle.fd);
271 DCHECK_NE(-1, socket_handle);
272 #endif
273 DCHECK(length);
274
275 if (MessageLoop::current() == main_message_loop_) {
276 // Must dereference the client only on the main thread. Shutdown may have
277 // occurred while the request was in-flight, so we need to NULL check.
278 if (client_)
279 client_->StreamCreated(handle, length, socket_handle);
280 } else {
281 main_message_loop_->PostTask(FROM_HERE,
282 NewRunnableMethod(this, &PlatformAudioImpl::OnLowLatencyCreated,
283 handle, socket_handle, length));
284 }
285 }
286
287 // Implements the VideoDecoder.
288 class PlatformVideoDecoderImpl
289 : public webkit::ppapi::PluginDelegate::PlatformVideoDecoder {
290 public:
291 PlatformVideoDecoderImpl()
292 : input_buffer_size_(0),
293 next_dib_id_(0),
294 dib_(NULL) {
295 memset(&decoder_config_, 0, sizeof(decoder_config_));
296 memset(&flush_callback_, 0, sizeof(flush_callback_));
297 }
298
299 virtual bool Init(const PP_VideoDecoderConfig_Dev& decoder_config) {
300 decoder_config_ = decoder_config;
301 input_buffer_size_ = 1024 << 4;
302
303 // Allocate the transport DIB.
304 TransportDIB* dib = TransportDIB::Create(input_buffer_size_,
305 next_dib_id_++);
306 if (!dib)
307 return false;
308
309 // TODO(wjia): Create video decoder in GPU process.
310 // Meanwhile, delete |dib| to free the resource.
311 delete dib;
312
313 return true;
314 }
315
316 virtual bool Decode(PP_VideoCompressedDataBuffer_Dev& input_buffer) {
317 // TODO(wjia): Implement me!
318 NOTIMPLEMENTED();
319
320 input_buffers_.push(&input_buffer);
321
322 // Copy input data to dib_ and send it to GPU video decoder.
323
324 return false;
325 }
326
327 virtual int32_t Flush(PP_CompletionCallback& callback) {
328 // TODO(wjia): Implement me!
329 NOTIMPLEMENTED();
330
331 // Do nothing if there is a flush pending.
332 if (flush_callback_.func)
333 return PP_ERROR_BADARGUMENT;
334
335 flush_callback_ = callback;
336
337 // Call GPU video decoder to flush.
338
339 return PP_ERROR_WOULDBLOCK;
340 }
341
342 virtual bool ReturnUncompressedDataBuffer(
343 PP_VideoUncompressedDataBuffer_Dev& buffer) {
344 // TODO(wjia): Implement me!
345 NOTIMPLEMENTED();
346
347 // Deliver the buffer to GPU video decoder.
348
349 return false;
350 }
351
352 void OnFlushDone() {
353 if (!flush_callback_.func)
354 return;
355
356 flush_callback_.func(flush_callback_.user_data, PP_OK);
357 flush_callback_.func = NULL;
358 }
359
360 virtual intptr_t GetSharedMemoryHandle() const {
361 return reinterpret_cast<intptr_t>(dib_.get());
362 }
363
364 private:
365 size_t input_buffer_size_;
366 int next_dib_id_;
367 scoped_ptr<TransportDIB> dib_;
368 PP_VideoDecoderConfig_Dev decoder_config_;
369 std::queue<PP_VideoCompressedDataBuffer_Dev*> input_buffers_;
370 PP_CompletionCallback flush_callback_;
371
372 DISALLOW_COPY_AND_ASSIGN(PlatformVideoDecoderImpl);
373 };
374
375 class DispatcherWrapper
376 : public webkit::ppapi::PluginDelegate::OutOfProcessProxy {
377 public:
378 DispatcherWrapper() {}
379 virtual ~DispatcherWrapper() {}
380
381 bool Init(base::ProcessHandle plugin_process_handle,
382 IPC::ChannelHandle channel_handle,
383 PP_Module pp_module,
384 pp::proxy::Dispatcher::GetInterfaceFunc local_get_interface);
385
386 // OutOfProcessProxy implementation.
387 virtual const void* GetProxiedInterface(const char* name) {
388 return dispatcher_->GetProxiedInterface(name);
389 }
390 virtual void AddInstance(PP_Instance instance) {
391 pp::proxy::HostDispatcher::SetForInstance(instance, dispatcher_.get());
392 }
393 virtual void RemoveInstance(PP_Instance instance) {
394 pp::proxy::HostDispatcher::RemoveForInstance(instance);
395 }
396
397 private:
398 scoped_ptr<pp::proxy::HostDispatcher> dispatcher_;
399 };
400
401 bool DispatcherWrapper::Init(
402 base::ProcessHandle plugin_process_handle,
403 IPC::ChannelHandle channel_handle,
404 PP_Module pp_module,
405 pp::proxy::Dispatcher::GetInterfaceFunc local_get_interface) {
406 dispatcher_.reset(new pp::proxy::HostDispatcher(
407 plugin_process_handle, pp_module, local_get_interface));
408
409 if (!dispatcher_->InitWithChannel(PepperPluginRegistry::GetInstance(),
410 channel_handle, true)) {
411 dispatcher_.reset();
412 return false;
413 }
414 return true;
415 }
416
417 } // namespace
418
419 PepperPluginDelegateImpl::PepperPluginDelegateImpl(RenderView* render_view)
420 : render_view_(render_view),
421 has_saved_context_menu_action_(false),
422 saved_context_menu_action_(0),
423 id_generator_(0) {
424 }
425
426 PepperPluginDelegateImpl::~PepperPluginDelegateImpl() {
427 }
428
429 scoped_refptr<webkit::ppapi::PluginModule>
430 PepperPluginDelegateImpl::CreatePepperPlugin(const FilePath& path) {
431 // See if a module has already been loaded for this plugin.
432 scoped_refptr<webkit::ppapi::PluginModule> module =
433 PepperPluginRegistry::GetInstance()->GetLiveModule(path);
434 if (module)
435 return module;
436
437 // In-process plugins will have always been created up-front to avoid the
438 // sandbox restrictions. So gettin here implies it doesn't exist or should
439 // be out of process.
440 const PepperPluginInfo* info =
441 PepperPluginRegistry::GetInstance()->GetInfoForPlugin(path);
442 if (!info || !info->is_out_of_process)
443 return module; // Return the NULL module.
444
445 // Out of process: have the browser start the plugin process for us.
446 base::ProcessHandle plugin_process_handle = base::kNullProcessHandle;
447 IPC::ChannelHandle channel_handle;
448 render_view_->Send(new ViewHostMsg_OpenChannelToPepperPlugin(
449 path, &plugin_process_handle, &channel_handle));
450 if (channel_handle.name.empty()) {
451 // Couldn't be initialized.
452 return scoped_refptr<webkit::ppapi::PluginModule>();
453 }
454
455 // Create a new HostDispatcher for the proxying, and hook it to a new
456 // PluginModule. Note that AddLiveModule must be called before any early
457 // returns since the module's destructor will remove itself.
458 module = new webkit::ppapi::PluginModule(info->name,
459 PepperPluginRegistry::GetInstance());
460 PepperPluginRegistry::GetInstance()->AddLiveModule(path, module);
461 scoped_ptr<DispatcherWrapper> dispatcher(new DispatcherWrapper);
462 if (!dispatcher->Init(
463 plugin_process_handle, channel_handle,
464 module->pp_module(),
465 webkit::ppapi::PluginModule::GetLocalGetInterfaceFunc()))
466 return scoped_refptr<webkit::ppapi::PluginModule>();
467 module->InitAsProxied(dispatcher.release());
468 return module;
469 }
470
471 void PepperPluginDelegateImpl::ViewInitiatedPaint() {
472 // Notify all of our instances that we started painting. This is used for
473 // internal bookkeeping only, so we know that the set can not change under
474 // us.
475 for (std::set<webkit::ppapi::PluginInstance*>::iterator i =
476 active_instances_.begin();
477 i != active_instances_.end(); ++i)
478 (*i)->ViewInitiatedPaint();
479 }
480
481 void PepperPluginDelegateImpl::ViewFlushedPaint() {
482 // Notify all instances that we painted. This will call into the plugin, and
483 // we it may ask to close itself as a result. This will, in turn, modify our
484 // set, possibly invalidating the iterator. So we iterate on a copy that
485 // won't change out from under us.
486 std::set<webkit::ppapi::PluginInstance*> plugins = active_instances_;
487 for (std::set<webkit::ppapi::PluginInstance*>::iterator i = plugins.begin();
488 i != plugins.end(); ++i) {
489 // The copy above makes sure our iterator is never invalid if some plugins
490 // are destroyed. But some plugin may decide to close all of its views in
491 // response to a paint in one of them, so we need to make sure each one is
492 // still "current" before using it.
493 //
494 // It's possible that a plugin was destroyed, but another one was created
495 // with the same address. In this case, we'll call ViewFlushedPaint on that
496 // new plugin. But that's OK for this particular case since we're just
497 // notifying all of our instances that the view flushed, and the new one is
498 // one of our instances.
499 //
500 // What about the case where a new one is created in a callback at a new
501 // address and we don't issue the callback? We're still OK since this
502 // callback is used for flush callbacks and we could not have possibly
503 // started a new paint (ViewInitiatedPaint) for the new plugin while
504 // processing a previous paint for an existing one.
505 if (active_instances_.find(*i) != active_instances_.end())
506 (*i)->ViewFlushedPaint();
507 }
508 }
509
510 webkit::ppapi::PluginInstance*
511 PepperPluginDelegateImpl::GetBitmapForOptimizedPluginPaint(
512 const gfx::Rect& paint_bounds,
513 TransportDIB** dib,
514 gfx::Rect* location,
515 gfx::Rect* clip) {
516 for (std::set<webkit::ppapi::PluginInstance*>::iterator i =
517 active_instances_.begin();
518 i != active_instances_.end(); ++i) {
519 webkit::ppapi::PluginInstance* instance = *i;
520 if (instance->GetBitmapForOptimizedPluginPaint(
521 paint_bounds, dib, location, clip))
522 return *i;
523 }
524 return NULL;
525 }
526
527 void PepperPluginDelegateImpl::InstanceCreated(
528 webkit::ppapi::PluginInstance* instance) {
529 active_instances_.insert(instance);
530
531 // Set the initial focus.
532 instance->SetContentAreaFocus(render_view_->has_focus());
533 }
534
535 void PepperPluginDelegateImpl::InstanceDeleted(
536 webkit::ppapi::PluginInstance* instance) {
537 active_instances_.erase(instance);
538 }
539
540 webkit::ppapi::PluginDelegate::PlatformImage2D*
541 PepperPluginDelegateImpl::CreateImage2D(int width, int height) {
542 uint32 buffer_size = width * height * 4;
543
544 // Allocate the transport DIB and the PlatformCanvas pointing to it.
545 #if defined(OS_MACOSX)
546 // On the Mac, shared memory has to be created in the browser in order to
547 // work in the sandbox. Do this by sending a message to the browser
548 // requesting a TransportDIB (see also
549 // chrome/renderer/webplugin_delegate_proxy.cc, method
550 // WebPluginDelegateProxy::CreateBitmap() for similar code). The TransportDIB
551 // is cached in the browser, and is freed (in typical cases) by the
552 // PlatformImage2DImpl's destructor.
553 TransportDIB::Handle dib_handle;
554 IPC::Message* msg = new ViewHostMsg_AllocTransportDIB(buffer_size,
555 true,
556 &dib_handle);
557 if (!RenderThread::current()->Send(msg))
558 return NULL;
559 if (!TransportDIB::is_valid(dib_handle))
560 return NULL;
561
562 TransportDIB* dib = TransportDIB::Map(dib_handle);
563 #else
564 static int next_dib_id = 0;
565 TransportDIB* dib = TransportDIB::Create(buffer_size, next_dib_id++);
566 if (!dib)
567 return NULL;
568 #endif
569
570 return new PlatformImage2DImpl(width, height, dib);
571 }
572
573 webkit::ppapi::PluginDelegate::PlatformContext3D*
574 PepperPluginDelegateImpl::CreateContext3D() {
575 #ifdef ENABLE_GPU
576 // If accelerated compositing of plugins is disabled, fail to create a 3D
577 // context, because it won't be visible. This allows graceful fallback in the
578 // modules.
579 if (!render_view_->webkit_preferences().accelerated_plugins_enabled)
580 return NULL;
581 WebGraphicsContext3DCommandBufferImpl* context =
582 static_cast<WebGraphicsContext3DCommandBufferImpl*>(
583 render_view_->webview()->graphicsContext3D());
584 if (!context)
585 return NULL;
586
587 ggl::Context* parent_context = context->context();
588 if (!parent_context)
589 return NULL;
590
591 return new PlatformContext3DImpl(parent_context);
592 #else
593 return NULL;
594 #endif
595 }
596
597 webkit::ppapi::PluginDelegate::PlatformVideoDecoder*
598 PepperPluginDelegateImpl::CreateVideoDecoder(
599 const PP_VideoDecoderConfig_Dev& decoder_config) {
600 scoped_ptr<PlatformVideoDecoderImpl> decoder(new PlatformVideoDecoderImpl());
601
602 if (!decoder->Init(decoder_config))
603 return NULL;
604
605 return decoder.release();
606 }
607
608 void PepperPluginDelegateImpl::NumberOfFindResultsChanged(int identifier,
609 int total,
610 bool final_result) {
611 render_view_->reportFindInPageMatchCount(identifier, total, final_result);
612 }
613
614 void PepperPluginDelegateImpl::SelectedFindResultChanged(int identifier,
615 int index) {
616 render_view_->reportFindInPageSelection(
617 identifier, index + 1, WebKit::WebRect());
618 }
619
620 webkit::ppapi::PluginDelegate::PlatformAudio*
621 PepperPluginDelegateImpl::CreateAudio(
622 uint32_t sample_rate, uint32_t sample_count,
623 webkit::ppapi::PluginDelegate::PlatformAudio::Client* client) {
624 scoped_refptr<PlatformAudioImpl> audio(
625 new PlatformAudioImpl(render_view_->audio_message_filter()));
626 if (audio->Initialize(sample_rate, sample_count, client)) {
627 // Balanced by Release invoked in PlatformAudioImpl::ShutDownOnIOThread().
628 return audio.release();
629 } else {
630 return NULL;
631 }
632 }
633
634 bool PepperPluginDelegateImpl::RunFileChooser(
635 const WebKit::WebFileChooserParams& params,
636 WebKit::WebFileChooserCompletion* chooser_completion) {
637 return render_view_->runFileChooser(params, chooser_completion);
638 }
639
640 bool PepperPluginDelegateImpl::AsyncOpenFile(const FilePath& path,
641 int flags,
642 AsyncOpenFileCallback* callback) {
643 int message_id = id_generator_++;
644 DCHECK(!messages_waiting_replies_.Lookup(message_id));
645 messages_waiting_replies_.AddWithID(callback, message_id);
646 IPC::Message* msg = new ViewHostMsg_AsyncOpenFile(
647 render_view_->routing_id(), path, flags, message_id);
648 return render_view_->Send(msg);
649 }
650
651 void PepperPluginDelegateImpl::OnAsyncFileOpened(
652 base::PlatformFileError error_code,
653 base::PlatformFile file,
654 int message_id) {
655 AsyncOpenFileCallback* callback =
656 messages_waiting_replies_.Lookup(message_id);
657 DCHECK(callback);
658 messages_waiting_replies_.Remove(message_id);
659 callback->Run(error_code, file);
660 delete callback;
661 }
662
663 void PepperPluginDelegateImpl::OnSetFocus(bool has_focus) {
664 for (std::set<webkit::ppapi::PluginInstance*>::iterator i =
665 active_instances_.begin();
666 i != active_instances_.end(); ++i)
667 (*i)->SetContentAreaFocus(has_focus);
668 }
669
670 bool PepperPluginDelegateImpl::OpenFileSystem(
671 const GURL& url,
672 fileapi::FileSystemType type,
673 long long size,
674 fileapi::FileSystemCallbackDispatcher* dispatcher) {
675 FileSystemDispatcher* file_system_dispatcher =
676 ChildThread::current()->file_system_dispatcher();
677 return file_system_dispatcher->OpenFileSystem(
678 url, type, size, true /* create */, dispatcher);
679 }
680
681 bool PepperPluginDelegateImpl::MakeDirectory(
682 const FilePath& path,
683 bool recursive,
684 fileapi::FileSystemCallbackDispatcher* dispatcher) {
685 FileSystemDispatcher* file_system_dispatcher =
686 ChildThread::current()->file_system_dispatcher();
687 return file_system_dispatcher->Create(
688 path, false, true, recursive, dispatcher);
689 }
690
691 bool PepperPluginDelegateImpl::Query(
692 const FilePath& path,
693 fileapi::FileSystemCallbackDispatcher* dispatcher) {
694 FileSystemDispatcher* file_system_dispatcher =
695 ChildThread::current()->file_system_dispatcher();
696 return file_system_dispatcher->ReadMetadata(path, dispatcher);
697 }
698
699 bool PepperPluginDelegateImpl::Touch(
700 const FilePath& path,
701 const base::Time& last_access_time,
702 const base::Time& last_modified_time,
703 fileapi::FileSystemCallbackDispatcher* dispatcher) {
704 FileSystemDispatcher* file_system_dispatcher =
705 ChildThread::current()->file_system_dispatcher();
706 return file_system_dispatcher->TouchFile(path, last_access_time,
707 last_modified_time, dispatcher);
708 }
709
710 bool PepperPluginDelegateImpl::Delete(
711 const FilePath& path,
712 fileapi::FileSystemCallbackDispatcher* dispatcher) {
713 FileSystemDispatcher* file_system_dispatcher =
714 ChildThread::current()->file_system_dispatcher();
715 return file_system_dispatcher->Remove(path, false /* recursive */,
716 dispatcher);
717 }
718
719 bool PepperPluginDelegateImpl::Rename(
720 const FilePath& file_path,
721 const FilePath& new_file_path,
722 fileapi::FileSystemCallbackDispatcher* dispatcher) {
723 FileSystemDispatcher* file_system_dispatcher =
724 ChildThread::current()->file_system_dispatcher();
725 return file_system_dispatcher->Move(file_path, new_file_path, dispatcher);
726 }
727
728 bool PepperPluginDelegateImpl::ReadDirectory(
729 const FilePath& directory_path,
730 fileapi::FileSystemCallbackDispatcher* dispatcher) {
731 FileSystemDispatcher* file_system_dispatcher =
732 ChildThread::current()->file_system_dispatcher();
733 return file_system_dispatcher->ReadDirectory(directory_path, dispatcher);
734 }
735
736 base::PlatformFileError PepperPluginDelegateImpl::OpenFile(
737 const webkit::ppapi::PepperFilePath& path,
738 int flags,
739 base::PlatformFile* file) {
740 IPC::PlatformFileForTransit transit_file;
741 base::PlatformFileError error;
742 IPC::Message* msg = new PepperFileMsg_OpenFile(
743 path, flags, &error, &transit_file);
744 if (!render_view_->Send(msg)) {
745 *file = base::kInvalidPlatformFileValue;
746 return base::PLATFORM_FILE_ERROR_FAILED;
747 }
748 *file = IPC::PlatformFileForTransitToPlatformFile(transit_file);
749 return error;
750 }
751
752 base::PlatformFileError PepperPluginDelegateImpl::RenameFile(
753 const webkit::ppapi::PepperFilePath& from_path,
754 const webkit::ppapi::PepperFilePath& to_path) {
755 base::PlatformFileError error;
756 IPC::Message* msg = new PepperFileMsg_RenameFile(from_path, to_path, &error);
757 if (!render_view_->Send(msg))
758 return base::PLATFORM_FILE_ERROR_FAILED;
759 return error;
760 }
761
762 base::PlatformFileError PepperPluginDelegateImpl::DeleteFileOrDir(
763 const webkit::ppapi::PepperFilePath& path,
764 bool recursive) {
765 base::PlatformFileError error;
766 IPC::Message* msg = new PepperFileMsg_DeleteFileOrDir(
767 path, recursive, &error);
768 if (!render_view_->Send(msg))
769 return base::PLATFORM_FILE_ERROR_FAILED;
770 return error;
771 }
772
773 base::PlatformFileError PepperPluginDelegateImpl::CreateDir(
774 const webkit::ppapi::PepperFilePath& path) {
775 base::PlatformFileError error;
776 IPC::Message* msg = new PepperFileMsg_CreateDir(path, &error);
777 if (!render_view_->Send(msg))
778 return base::PLATFORM_FILE_ERROR_FAILED;
779 return error;
780 }
781
782 base::PlatformFileError PepperPluginDelegateImpl::QueryFile(
783 const webkit::ppapi::PepperFilePath& path,
784 base::PlatformFileInfo* info) {
785 base::PlatformFileError error;
786 IPC::Message* msg = new PepperFileMsg_QueryFile(path, info, &error);
787 if (!render_view_->Send(msg))
788 return base::PLATFORM_FILE_ERROR_FAILED;
789 return error;
790 }
791
792 base::PlatformFileError PepperPluginDelegateImpl::GetDirContents(
793 const webkit::ppapi::PepperFilePath& path,
794 webkit::ppapi::DirContents* contents) {
795 base::PlatformFileError error;
796 IPC::Message* msg = new PepperFileMsg_GetDirContents(path, contents, &error);
797 if (!render_view_->Send(msg))
798 return base::PLATFORM_FILE_ERROR_FAILED;
799 return error;
800 }
801
802 scoped_refptr<base::MessageLoopProxy>
803 PepperPluginDelegateImpl::GetFileThreadMessageLoopProxy() {
804 return RenderThread::current()->GetFileThreadMessageLoopProxy();
805 }
806
807 int32_t PepperPluginDelegateImpl::ConnectTcp(
808 webkit::ppapi::PPB_Flash_NetConnector_Impl* connector,
809 const char* host,
810 uint16_t port) {
811 int request_id = pending_connect_tcps_.Add(
812 new scoped_refptr<webkit::ppapi::PPB_Flash_NetConnector_Impl>(connector));
813 IPC::Message* msg =
814 new PepperMsg_ConnectTcp(render_view_->routing_id(),
815 request_id,
816 std::string(host),
817 port);
818 if (!render_view_->Send(msg)) {
819 pending_connect_tcps_.Remove(request_id);
820 return PP_ERROR_FAILED;
821 }
822
823 return PP_ERROR_WOULDBLOCK;
824 }
825
826 int32_t PepperPluginDelegateImpl::ConnectTcpAddress(
827 webkit::ppapi::PPB_Flash_NetConnector_Impl* connector,
828 const struct PP_Flash_NetAddress* addr) {
829 int request_id = pending_connect_tcps_.Add(
830 new scoped_refptr<webkit::ppapi::PPB_Flash_NetConnector_Impl>(connector));
831 IPC::Message* msg =
832 new PepperMsg_ConnectTcpAddress(render_view_->routing_id(),
833 request_id,
834 *addr);
835 if (!render_view_->Send(msg)) {
836 pending_connect_tcps_.Remove(request_id);
837 return PP_ERROR_FAILED;
838 }
839
840 return PP_ERROR_WOULDBLOCK;
841 }
842
843 void PepperPluginDelegateImpl::OnConnectTcpACK(
844 int request_id,
845 base::PlatformFile socket,
846 const PP_Flash_NetAddress& local_addr,
847 const PP_Flash_NetAddress& remote_addr) {
848 scoped_refptr<webkit::ppapi::PPB_Flash_NetConnector_Impl> connector =
849 *pending_connect_tcps_.Lookup(request_id);
850 pending_connect_tcps_.Remove(request_id);
851
852 connector->CompleteConnectTcp(socket, local_addr, remote_addr);
853 }
854
855 int32_t PepperPluginDelegateImpl::ShowContextMenu(
856 webkit::ppapi::PPB_Flash_Menu_Impl* menu,
857 const gfx::Point& position) {
858 int request_id = pending_context_menus_.Add(
859 new scoped_refptr<webkit::ppapi::PPB_Flash_Menu_Impl>(menu));
860
861 ContextMenuParams params;
862 params.x = position.x();
863 params.y = position.y();
864 params.custom_context.is_pepper_menu = true;
865 params.custom_context.request_id = request_id;
866 params.custom_items = menu->menu_data();
867
868 IPC::Message* msg = new ViewHostMsg_ContextMenu(render_view_->routing_id(),
869 params);
870 if (!render_view_->Send(msg)) {
871 pending_context_menus_.Remove(request_id);
872 return PP_ERROR_FAILED;
873 }
874
875 return PP_ERROR_WOULDBLOCK;
876 }
877
878 void PepperPluginDelegateImpl::OnContextMenuClosed(
879 const webkit_glue::CustomContextMenuContext& custom_context) {
880 int request_id = custom_context.request_id;
881 scoped_refptr<webkit::ppapi::PPB_Flash_Menu_Impl> menu =
882 *pending_context_menus_.Lookup(request_id);
883 if (!menu) {
884 NOTREACHED() << "CompleteShowContextMenu() called twice for the same menu.";
885 return;
886 }
887 pending_context_menus_.Remove(request_id);
888
889 if (has_saved_context_menu_action_) {
890 menu->CompleteShow(PP_OK, saved_context_menu_action_);
891 has_saved_context_menu_action_ = false;
892 saved_context_menu_action_ = 0;
893 } else {
894 menu->CompleteShow(PP_ERROR_USERCANCEL, 0);
895 }
896 }
897
898 void PepperPluginDelegateImpl::OnCustomContextMenuAction(
899 const webkit_glue::CustomContextMenuContext& custom_context,
900 unsigned action) {
901 // Just save the action.
902 DCHECK(!has_saved_context_menu_action_);
903 has_saved_context_menu_action_ = true;
904 saved_context_menu_action_ = action;
905 }
906
907 webkit::ppapi::FullscreenContainer*
908 PepperPluginDelegateImpl::CreateFullscreenContainer(
909 webkit::ppapi::PluginInstance* instance) {
910 return render_view_->CreatePepperFullscreenContainer(instance);
911 }
912
913 gfx::Size PepperPluginDelegateImpl::GetScreenSize() {
914 WebKit::WebScreenInfo info = render_view_->screenInfo();
915 return gfx::Size(info.rect.width, info.rect.height);
916 }
917
918 std::string PepperPluginDelegateImpl::GetDefaultEncoding() {
919 // TODO(brettw) bug 56615: Somehow get the preference for the default
920 // encoding here rather than using the global default for the UI language.
921 return l10n_util::GetStringUTF8(IDS_DEFAULT_ENCODING);
922 }
923
924 void PepperPluginDelegateImpl::ZoomLimitsChanged(double minimum_factor,
925 double maximum_factor) {
926 double minimum_level = WebView::zoomFactorToZoomLevel(minimum_factor);
927 double maximum_level = WebView::zoomFactorToZoomLevel(maximum_factor);
928 render_view_->webview()->zoomLimitsChanged(minimum_level, maximum_level);
929 }
930
931 std::string PepperPluginDelegateImpl::ResolveProxy(const GURL& url) {
932 int net_error;
933 std::string proxy_result;
934 RenderThread::current()->Send(
935 new ChildProcessHostMsg_ResolveProxy(url, &net_error, &proxy_result));
936 return proxy_result;
937 }
938
939 void PepperPluginDelegateImpl::DidStartLoading() {
940 render_view_->DidStartLoadingForPlugin();
941 }
942
943 void PepperPluginDelegateImpl::DidStopLoading() {
944 render_view_->DidStopLoadingForPlugin();
945 }
946
947 void PepperPluginDelegateImpl::SetContentRestriction(int restrictions) {
948 render_view_->Send(new ViewHostMsg_UpdateContentRestrictions(
949 render_view_->routing_id(), restrictions));
950 }
951
952 void PepperPluginDelegateImpl::HasUnsupportedFeature() {
953 render_view_->Send(new ViewHostMsg_PDFHasUnsupportedFeature(
954 render_view_->routing_id()));
955 }
956
957 P2PSocketDispatcher* PepperPluginDelegateImpl::GetP2PSocketDispatcher() {
958 return render_view_->p2p_socket_dispatcher();
959 }
OLDNEW
« no previous file with comments | « chrome/renderer/pepper_plugin_delegate_impl.h ('k') | chrome/renderer/render_view.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698