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

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

Issue 7863003: Mouse lock implementation, including the renderer side and the Windows version of the browser side. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 3 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
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 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 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 #include "content/renderer/pepper_plugin_delegate_impl.h" 5 #include "content/renderer/pepper_plugin_delegate_impl.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 #include <queue> 8 #include <queue>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 #include "content/renderer/webplugin_delegate_proxy.h" 45 #include "content/renderer/webplugin_delegate_proxy.h"
46 #include "ipc/ipc_channel_handle.h" 46 #include "ipc/ipc_channel_handle.h"
47 #include "media/video/capture/video_capture_proxy.h" 47 #include "media/video/capture/video_capture_proxy.h"
48 #include "ppapi/c/dev/pp_video_dev.h" 48 #include "ppapi/c/dev/pp_video_dev.h"
49 #include "ppapi/c/pp_errors.h" 49 #include "ppapi/c/pp_errors.h"
50 #include "ppapi/c/private/ppb_flash.h" 50 #include "ppapi/c/private/ppb_flash.h"
51 #include "ppapi/c/private/ppb_flash_net_connector.h" 51 #include "ppapi/c/private/ppb_flash_net_connector.h"
52 #include "ppapi/proxy/host_dispatcher.h" 52 #include "ppapi/proxy/host_dispatcher.h"
53 #include "ppapi/proxy/ppapi_messages.h" 53 #include "ppapi/proxy/ppapi_messages.h"
54 #include "ppapi/shared_impl/ppapi_preferences.h" 54 #include "ppapi/shared_impl/ppapi_preferences.h"
55 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h"
55 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFileChooserComplet ion.h" 56 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFileChooserComplet ion.h"
56 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFileChooserParams. h" 57 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFileChooserParams. h"
58 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
57 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h" 59 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h"
58 #include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h" 60 #include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h"
59 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" 61 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
60 #include "ui/gfx/size.h" 62 #include "ui/gfx/size.h"
61 #include "ui/gfx/surface/transport_dib.h" 63 #include "ui/gfx/surface/transport_dib.h"
62 #include "webkit/fileapi/file_system_callback_dispatcher.h" 64 #include "webkit/fileapi/file_system_callback_dispatcher.h"
63 #include "webkit/glue/context_menu.h" 65 #include "webkit/glue/context_menu.h"
64 #include "webkit/plugins/npapi/webplugin.h" 66 #include "webkit/plugins/npapi/webplugin.h"
65 #include "webkit/plugins/ppapi/file_path.h" 67 #include "webkit/plugins/ppapi/file_path.h"
66 #include "webkit/plugins/ppapi/ppb_file_io_impl.h" 68 #include "webkit/plugins/ppapi/ppb_file_io_impl.h"
(...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 // saved pipe handle. 645 // saved pipe handle.
644 // Temporarily, just call back. 646 // Temporarily, just call back.
645 client->BrokerConnected(PlatformFileToInt(plugin_handle), result); 647 client->BrokerConnected(PlatformFileToInt(plugin_handle), result);
646 } 648 }
647 649
648 PepperPluginDelegateImpl::PepperPluginDelegateImpl(RenderView* render_view) 650 PepperPluginDelegateImpl::PepperPluginDelegateImpl(RenderView* render_view)
649 : render_view_(render_view), 651 : render_view_(render_view),
650 has_saved_context_menu_action_(false), 652 has_saved_context_menu_action_(false),
651 saved_context_menu_action_(0), 653 saved_context_menu_action_(0),
652 id_generator_(0), 654 id_generator_(0),
653 is_pepper_plugin_focused_(false) { 655 is_pepper_plugin_focused_(false),
656 mouse_lock_owner_(NULL),
657 mouse_locked_(false),
658 pending_lock_request_(false),
659 pending_unlock_request_(false) {
654 } 660 }
655 661
656 PepperPluginDelegateImpl::~PepperPluginDelegateImpl() { 662 PepperPluginDelegateImpl::~PepperPluginDelegateImpl() {
663 DCHECK(!mouse_lock_owner_);
657 } 664 }
658 665
659 scoped_refptr<webkit::ppapi::PluginModule> 666 scoped_refptr<webkit::ppapi::PluginModule>
660 PepperPluginDelegateImpl::CreatePepperPluginModule( 667 PepperPluginDelegateImpl::CreatePepperPluginModule(
661 const webkit::WebPluginInfo& webplugin_info, 668 const webkit::WebPluginInfo& webplugin_info,
662 bool* pepper_plugin_was_registered) { 669 bool* pepper_plugin_was_registered) {
663 *pepper_plugin_was_registered = true; 670 *pepper_plugin_was_registered = true;
664 671
665 // See if a module has already been loaded for this plugin. 672 // See if a module has already been loaded for this plugin.
666 FilePath path(webplugin_info.path); 673 FilePath path(webplugin_info.path);
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
844 active_instances_.insert(instance); 851 active_instances_.insert(instance);
845 852
846 // Set the initial focus. 853 // Set the initial focus.
847 instance->SetContentAreaFocus(render_view_->has_focus()); 854 instance->SetContentAreaFocus(render_view_->has_focus());
848 } 855 }
849 856
850 void PepperPluginDelegateImpl::InstanceDeleted( 857 void PepperPluginDelegateImpl::InstanceDeleted(
851 webkit::ppapi::PluginInstance* instance) { 858 webkit::ppapi::PluginInstance* instance) {
852 active_instances_.erase(instance); 859 active_instances_.erase(instance);
853 subscribed_to_policy_updates_.erase(instance); 860 subscribed_to_policy_updates_.erase(instance);
861
862 // TODO(yzshen): do I need to do anything when PluginCrashed?
863 if (mouse_lock_owner_ && mouse_lock_owner_ == instance) {
864 // UnlockMouse() will determine whether a ViewHostMsg_UnlockMouse needs to
865 // be sent, and set internal state properly. We only need to forget about
866 // the current |mouse_lock_owner_|.
867 UnlockMouse(mouse_lock_owner_);
868 mouse_lock_owner_ = NULL;
869 }
854 } 870 }
855 871
856 SkBitmap* PepperPluginDelegateImpl::GetSadPluginBitmap() { 872 SkBitmap* PepperPluginDelegateImpl::GetSadPluginBitmap() {
857 return content::GetContentClient()->renderer()->GetSadPluginBitmap(); 873 return content::GetContentClient()->renderer()->GetSadPluginBitmap();
858 } 874 }
859 875
860 webkit::ppapi::PluginDelegate::PlatformImage2D* 876 webkit::ppapi::PluginDelegate::PlatformImage2D*
861 PepperPluginDelegateImpl::CreateImage2D(int width, int height) { 877 PepperPluginDelegateImpl::CreateImage2D(int width, int height) {
862 uint32 buffer_size = width * height * 4; 878 uint32 buffer_size = width * height * 4;
863 879
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
1004 messages_waiting_replies_.Remove(message_id); 1020 messages_waiting_replies_.Remove(message_id);
1005 callback->Run(error_code, base::PassPlatformFile(&file)); 1021 callback->Run(error_code, base::PassPlatformFile(&file));
1006 // Make sure we won't leak file handle if the requester has died. 1022 // Make sure we won't leak file handle if the requester has died.
1007 if (file != base::kInvalidPlatformFileValue) 1023 if (file != base::kInvalidPlatformFileValue)
1008 base::FileUtilProxy::Close(GetFileThreadMessageLoopProxy(), file, NULL); 1024 base::FileUtilProxy::Close(GetFileThreadMessageLoopProxy(), file, NULL);
1009 delete callback; 1025 delete callback;
1010 } 1026 }
1011 1027
1012 void PepperPluginDelegateImpl::OnSetFocus(bool has_focus) { 1028 void PepperPluginDelegateImpl::OnSetFocus(bool has_focus) {
1013 for (std::set<webkit::ppapi::PluginInstance*>::iterator i = 1029 for (std::set<webkit::ppapi::PluginInstance*>::iterator i =
1014 active_instances_.begin(); 1030 active_instances_.begin();
1015 i != active_instances_.end(); ++i) 1031 i != active_instances_.end(); ++i)
1016 (*i)->SetContentAreaFocus(has_focus); 1032 (*i)->SetContentAreaFocus(has_focus);
1017 } 1033 }
1018 1034
1019 bool PepperPluginDelegateImpl::IsPluginFocused() const { 1035 bool PepperPluginDelegateImpl::IsPluginFocused() const {
1020 return is_pepper_plugin_focused_; 1036 return is_pepper_plugin_focused_;
1021 } 1037 }
1022 1038
1039 void PepperPluginDelegateImpl::OnLockMouseACK(bool succeeded) {
1040 DCHECK(!mouse_locked_ && pending_lock_request_);
1041
1042 mouse_locked_ = succeeded;
1043 pending_lock_request_ = false;
1044 if (pending_unlock_request_ && !succeeded) {
1045 // We have sent an unlock request after the lock request. However, since
1046 // the lock request has failed, the unlock request will be ignored by the
1047 // browser side and there won't be any response to it.
1048 pending_unlock_request_ = false;
1049 }
1050 // If the PluginInstance has been deleted, |mouse_lock_owner_| can be NULL.
1051 if (mouse_lock_owner_) {
1052 webkit::ppapi::PluginInstance* temp = mouse_lock_owner_;
scheib 2011/09/09 22:00:06 nit: but perhaps rename "temp" to "last_mouse_lock
yzshen1 2011/09/09 23:16:04 Done.
1053 if (!succeeded) {
1054 // Reset |mouse_lock_owner_| to NULL before calling OnLockMouseACK(), so
1055 // that if OnLockMouseACK() results in calls to any mouse lock method
1056 // (e.g., LockMouse()), the method will see consistent internal state.
1057 mouse_lock_owner_ = NULL;
1058 }
1059
1060 temp->OnLockMouseACK(succeeded ? PP_OK : PP_ERROR_FAILED);
1061 }
1062 }
1063
1064 void PepperPluginDelegateImpl::OnMouseLockLost() {
1065 DCHECK(mouse_locked_ && !pending_lock_request_);
1066
1067 mouse_locked_ = false;
1068 pending_unlock_request_ = false;
1069 // If the PluginInstance has been deleted, |mouse_lock_owner_| can be NULL.
1070 if (mouse_lock_owner_) {
1071 // Reset |mouse_lock_owner_| to NULL before calling OnMouseLockLost(), so
1072 // that if OnMouseLockLost() results in calls to any mouse lock method
1073 // (e.g., LockMouse()), the method will see consistent internal state.
1074 webkit::ppapi::PluginInstance* temp = mouse_lock_owner_;
1075 mouse_lock_owner_ = NULL;
1076
1077 temp->OnMouseLockLost();
1078 }
1079 }
1080
1081 bool PepperPluginDelegateImpl::DispatchLockedMouseEvent(
1082 const WebKit::WebInputEvent& event) {
1083 if (mouse_locked_ && WebKit::WebInputEvent::isMouseEventType(event.type)) {
1084 if (mouse_lock_owner_) {
1085 // |cursor_info| is ignored since it is hidden when the mouse is locked.
1086 WebKit::WebCursorInfo cursor_info;
1087 mouse_lock_owner_->HandleInputEvent(event, &cursor_info);
1088 }
1089
1090 // If the mouse is locked, only the current owner of the mouse lock can
1091 // process mouse events.
1092 return true;
1093 }
1094 return false;
1095 }
1096
1023 bool PepperPluginDelegateImpl::OpenFileSystem( 1097 bool PepperPluginDelegateImpl::OpenFileSystem(
1024 const GURL& url, 1098 const GURL& url,
1025 fileapi::FileSystemType type, 1099 fileapi::FileSystemType type,
1026 long long size, 1100 long long size,
1027 fileapi::FileSystemCallbackDispatcher* dispatcher) { 1101 fileapi::FileSystemCallbackDispatcher* dispatcher) {
1028 FileSystemDispatcher* file_system_dispatcher = 1102 FileSystemDispatcher* file_system_dispatcher =
1029 ChildThread::current()->file_system_dispatcher(); 1103 ChildThread::current()->file_system_dispatcher();
1030 return file_system_dispatcher->OpenFileSystem( 1104 return file_system_dispatcher->OpenFileSystem(
1031 url.GetWithEmptyPath(), type, size, true /* create */, dispatcher); 1105 url.GetWithEmptyPath(), type, size, true /* create */, dispatcher);
1032 } 1106 }
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after
1467 DLOG(WARNING) << "Browser failed to allocate shared memory"; 1541 DLOG(WARNING) << "Browser failed to allocate shared memory";
1468 return NULL; 1542 return NULL;
1469 } 1543 }
1470 return new base::SharedMemory(handle, false); 1544 return new base::SharedMemory(handle, false);
1471 } 1545 }
1472 1546
1473 ppapi::Preferences PepperPluginDelegateImpl::GetPreferences() { 1547 ppapi::Preferences PepperPluginDelegateImpl::GetPreferences() {
1474 return ppapi::Preferences(render_view_->webkit_preferences()); 1548 return ppapi::Preferences(render_view_->webkit_preferences());
1475 } 1549 }
1476 1550
1551 void PepperPluginDelegateImpl::LockMouse(
1552 webkit::ppapi::PluginInstance* instance) {
1553 DCHECK(instance);
1554 if (!UsingMouseLock()) {
1555 DCHECK(!mouse_lock_owner_);
1556 pending_lock_request_ = true;
1557 mouse_lock_owner_ = instance;
1558
1559 render_view_->Send(
1560 new ViewHostMsg_LockMouse(render_view_->routing_id()));
1561 } else if (instance != mouse_lock_owner_) {
1562 // Another plugin instance is using mouse lock. Fail immediately.
1563 instance->OnLockMouseACK(PP_ERROR_FAILED);
1564 } else {
scheib 2011/09/09 22:00:06 nit: Following logic segments are for when mouse_l
yzshen1 2011/09/09 23:16:04 Good idea! On 2011/09/09 22:00:06, scheib wrote:
1565 if (mouse_locked_) {
1566 mouse_lock_owner_->OnLockMouseACK(PP_OK);
1567 } else if (pending_lock_request_) {
1568 mouse_lock_owner_->OnLockMouseACK(PP_ERROR_INPROGRESS);
1569 } else {
1570 // The only case left here is
1571 // !mouse_locked_ && !pending_lock_request_ && pending_unlock_request_,
1572 // which is not possible.
1573 NOTREACHED();
1574 mouse_lock_owner_->OnLockMouseACK(PP_ERROR_FAILED);
1575 }
1576 }
1577 }
1578
1579 void PepperPluginDelegateImpl::UnlockMouse(
1580 webkit::ppapi::PluginInstance* instance) {
1581 DCHECK(instance);
1582
1583 // If no one is using mouse lock or the user is not |instance|, ignore
1584 // the unlock request.
1585 if (UsingMouseLock() && mouse_lock_owner_ == instance) {
1586 if (mouse_locked_ || pending_lock_request_) {
1587 DCHECK(!mouse_locked_ || !pending_lock_request_);
1588 if (!pending_unlock_request_) {
1589 pending_unlock_request_ = true;
1590
1591 render_view_->Send(
1592 new ViewHostMsg_UnlockMouse(render_view_->routing_id()));
1593 }
1594 } else {
1595 // The only case left here is
1596 // !mouse_locked_ && !pending_lock_request_ && pending_unlock_request_,
1597 // which is not possible.
1598 NOTREACHED();
1599 }
1600 }
1601 }
1602
1477 int PepperPluginDelegateImpl::GetRoutingId() const { 1603 int PepperPluginDelegateImpl::GetRoutingId() const {
1478 return render_view_->routing_id(); 1604 return render_view_->routing_id();
1479 } 1605 }
1480 1606
1481 void PepperPluginDelegateImpl::PublishInitialPolicy( 1607 void PepperPluginDelegateImpl::PublishInitialPolicy(
1482 scoped_refptr<webkit::ppapi::PluginInstance> instance, 1608 scoped_refptr<webkit::ppapi::PluginInstance> instance,
1483 const std::string& policy) { 1609 const std::string& policy) {
1484 instance->HandlePolicyUpdate(policy); 1610 instance->HandlePolicyUpdate(policy);
1485 } 1611 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698