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 #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 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
637 | 637 |
638 virtual int CaptureFrameRate() OVERRIDE { | 638 virtual int CaptureFrameRate() OVERRIDE { |
639 return handler_proxy_->state().frame_rate; | 639 return handler_proxy_->state().frame_rate; |
640 } | 640 } |
641 | 641 |
642 private: | 642 private: |
643 scoped_ptr<media::VideoCaptureHandlerProxy> handler_proxy_; | 643 scoped_ptr<media::VideoCaptureHandlerProxy> handler_proxy_; |
644 media::VideoCapture* video_capture_; | 644 media::VideoCapture* video_capture_; |
645 }; | 645 }; |
646 | 646 |
| 647 class PluginInstanceLockTarget : public MouseLockDispatcher::LockTarget { |
| 648 public: |
| 649 PluginInstanceLockTarget(webkit::ppapi::PluginInstance* plugin) |
| 650 : plugin_(plugin) {} |
| 651 |
| 652 virtual void OnLockMouseACK(bool succeeded) OVERRIDE { |
| 653 plugin_->OnLockMouseACK(succeeded); |
| 654 } |
| 655 |
| 656 virtual void OnMouseLockLost() OVERRIDE { |
| 657 plugin_->OnMouseLockLost(); |
| 658 } |
| 659 |
| 660 virtual bool HandleMouseLockedInputEvent( |
| 661 const WebKit::WebMouseEvent &event) OVERRIDE { |
| 662 plugin_->HandleMouseLockedInputEvent(event); |
| 663 return true; |
| 664 } |
| 665 |
| 666 private: |
| 667 webkit::ppapi::PluginInstance* plugin_; |
| 668 }; |
| 669 |
647 } // namespace | 670 } // namespace |
648 | 671 |
649 BrokerDispatcherWrapper::BrokerDispatcherWrapper() { | 672 BrokerDispatcherWrapper::BrokerDispatcherWrapper() { |
650 } | 673 } |
651 | 674 |
652 BrokerDispatcherWrapper::~BrokerDispatcherWrapper() { | 675 BrokerDispatcherWrapper::~BrokerDispatcherWrapper() { |
653 } | 676 } |
654 | 677 |
655 bool BrokerDispatcherWrapper::Init( | 678 bool BrokerDispatcherWrapper::Init( |
656 base::ProcessHandle broker_process_handle, | 679 base::ProcessHandle broker_process_handle, |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
843 // Temporarily, just call back. | 866 // Temporarily, just call back. |
844 client->BrokerConnected(ppapi::PlatformFileToInt(plugin_handle), result); | 867 client->BrokerConnected(ppapi::PlatformFileToInt(plugin_handle), result); |
845 } | 868 } |
846 | 869 |
847 PepperPluginDelegateImpl::PepperPluginDelegateImpl(RenderViewImpl* render_view) | 870 PepperPluginDelegateImpl::PepperPluginDelegateImpl(RenderViewImpl* render_view) |
848 : content::RenderViewObserver(render_view), | 871 : content::RenderViewObserver(render_view), |
849 render_view_(render_view), | 872 render_view_(render_view), |
850 has_saved_context_menu_action_(false), | 873 has_saved_context_menu_action_(false), |
851 saved_context_menu_action_(0), | 874 saved_context_menu_action_(0), |
852 focused_plugin_(NULL), | 875 focused_plugin_(NULL), |
853 mouse_lock_owner_(NULL), | |
854 mouse_locked_(false), | |
855 pending_lock_request_(false), | |
856 pending_unlock_request_(false), | |
857 last_mouse_event_target_(NULL) { | 876 last_mouse_event_target_(NULL) { |
858 } | 877 } |
859 | 878 |
860 PepperPluginDelegateImpl::~PepperPluginDelegateImpl() { | 879 PepperPluginDelegateImpl::~PepperPluginDelegateImpl() { |
861 DCHECK(!mouse_lock_owner_); | 880 DCHECK(mouse_lock_instances_.empty()); |
862 } | 881 } |
863 | 882 |
864 scoped_refptr<webkit::ppapi::PluginModule> | 883 scoped_refptr<webkit::ppapi::PluginModule> |
865 PepperPluginDelegateImpl::CreatePepperPluginModule( | 884 PepperPluginDelegateImpl::CreatePepperPluginModule( |
866 const webkit::WebPluginInfo& webplugin_info, | 885 const webkit::WebPluginInfo& webplugin_info, |
867 bool* pepper_plugin_was_registered) { | 886 bool* pepper_plugin_was_registered) { |
868 *pepper_plugin_was_registered = true; | 887 *pepper_plugin_was_registered = true; |
869 | 888 |
870 // See if a module has already been loaded for this plugin. | 889 // See if a module has already been loaded for this plugin. |
871 FilePath path(webplugin_info.path); | 890 FilePath path(webplugin_info.path); |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1139 return focused_plugin_->IsPluginAcceptingCompositionEvents(); | 1158 return focused_plugin_->IsPluginAcceptingCompositionEvents(); |
1140 } | 1159 } |
1141 | 1160 |
1142 bool PepperPluginDelegateImpl::CanComposeInline() const { | 1161 bool PepperPluginDelegateImpl::CanComposeInline() const { |
1143 return IsPluginAcceptingCompositionEvents(); | 1162 return IsPluginAcceptingCompositionEvents(); |
1144 } | 1163 } |
1145 | 1164 |
1146 void PepperPluginDelegateImpl::PluginCrashed( | 1165 void PepperPluginDelegateImpl::PluginCrashed( |
1147 webkit::ppapi::PluginInstance* instance) { | 1166 webkit::ppapi::PluginInstance* instance) { |
1148 render_view_->PluginCrashed(instance->module()->path()); | 1167 render_view_->PluginCrashed(instance->module()->path()); |
1149 | 1168 UnSetAndDeleteLockTargetAdapter(instance); |
1150 UnlockMouse(instance); | |
1151 } | 1169 } |
1152 | 1170 |
1153 void PepperPluginDelegateImpl::InstanceCreated( | 1171 void PepperPluginDelegateImpl::InstanceCreated( |
1154 webkit::ppapi::PluginInstance* instance) { | 1172 webkit::ppapi::PluginInstance* instance) { |
1155 active_instances_.insert(instance); | 1173 active_instances_.insert(instance); |
1156 | 1174 |
1157 // Set the initial focus. | 1175 // Set the initial focus. |
1158 instance->SetContentAreaFocus(render_view_->has_focus()); | 1176 instance->SetContentAreaFocus(render_view_->has_focus()); |
1159 } | 1177 } |
1160 | 1178 |
1161 void PepperPluginDelegateImpl::InstanceDeleted( | 1179 void PepperPluginDelegateImpl::InstanceDeleted( |
1162 webkit::ppapi::PluginInstance* instance) { | 1180 webkit::ppapi::PluginInstance* instance) { |
1163 active_instances_.erase(instance); | 1181 active_instances_.erase(instance); |
| 1182 UnSetAndDeleteLockTargetAdapter(instance); |
1164 | 1183 |
1165 if (mouse_lock_owner_ && mouse_lock_owner_ == instance) { | |
1166 // UnlockMouse() will determine whether a ViewHostMsg_UnlockMouse needs to | |
1167 // be sent, and set internal state properly. We only need to forget about | |
1168 // the current |mouse_lock_owner_|. | |
1169 UnlockMouse(mouse_lock_owner_); | |
1170 mouse_lock_owner_ = NULL; | |
1171 } | |
1172 if (last_mouse_event_target_ == instance) | 1184 if (last_mouse_event_target_ == instance) |
1173 last_mouse_event_target_ = NULL; | 1185 last_mouse_event_target_ = NULL; |
1174 if (focused_plugin_ == instance) | 1186 if (focused_plugin_ == instance) |
1175 PluginFocusChanged(instance, false); | 1187 PluginFocusChanged(instance, false); |
1176 } | 1188 } |
1177 | 1189 |
1178 SkBitmap* PepperPluginDelegateImpl::GetSadPluginBitmap() { | 1190 SkBitmap* PepperPluginDelegateImpl::GetSadPluginBitmap() { |
1179 return content::GetContentClient()->renderer()->GetSadPluginBitmap(); | 1191 return content::GetContentClient()->renderer()->GetSadPluginBitmap(); |
1180 } | 1192 } |
1181 | 1193 |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1352 for (std::set<webkit::ppapi::PluginInstance*>::iterator i = | 1364 for (std::set<webkit::ppapi::PluginInstance*>::iterator i = |
1353 active_instances_.begin(); | 1365 active_instances_.begin(); |
1354 i != active_instances_.end(); ++i) | 1366 i != active_instances_.end(); ++i) |
1355 (*i)->PageVisibilityChanged(is_visible); | 1367 (*i)->PageVisibilityChanged(is_visible); |
1356 } | 1368 } |
1357 | 1369 |
1358 bool PepperPluginDelegateImpl::IsPluginFocused() const { | 1370 bool PepperPluginDelegateImpl::IsPluginFocused() const { |
1359 return focused_plugin_ != NULL; | 1371 return focused_plugin_ != NULL; |
1360 } | 1372 } |
1361 | 1373 |
1362 void PepperPluginDelegateImpl::OnLockMouseACK(bool succeeded) { | 1374 void PepperPluginDelegateImpl::WillHandleMouseEvent() { |
1363 DCHECK(!mouse_locked_ && pending_lock_request_); | |
1364 | |
1365 mouse_locked_ = succeeded; | |
1366 pending_lock_request_ = false; | |
1367 if (pending_unlock_request_ && !succeeded) { | |
1368 // We have sent an unlock request after the lock request. However, since | |
1369 // the lock request has failed, the unlock request will be ignored by the | |
1370 // browser side and there won't be any response to it. | |
1371 pending_unlock_request_ = false; | |
1372 } | |
1373 // If the PluginInstance has been deleted, |mouse_lock_owner_| can be NULL. | |
1374 if (mouse_lock_owner_) { | |
1375 webkit::ppapi::PluginInstance* last_mouse_lock_owner = mouse_lock_owner_; | |
1376 if (!succeeded) { | |
1377 // Reset |mouse_lock_owner_| to NULL before calling OnLockMouseACK(), so | |
1378 // that if OnLockMouseACK() results in calls to any mouse lock method | |
1379 // (e.g., LockMouse()), the method will see consistent internal state. | |
1380 mouse_lock_owner_ = NULL; | |
1381 } | |
1382 | |
1383 last_mouse_lock_owner->OnLockMouseACK(succeeded ? PP_OK : PP_ERROR_FAILED); | |
1384 } | |
1385 } | |
1386 | |
1387 void PepperPluginDelegateImpl::OnMouseLockLost() { | |
1388 DCHECK(mouse_locked_ && !pending_lock_request_); | |
1389 | |
1390 mouse_locked_ = false; | |
1391 pending_unlock_request_ = false; | |
1392 // If the PluginInstance has been deleted, |mouse_lock_owner_| can be NULL. | |
1393 if (mouse_lock_owner_) { | |
1394 // Reset |mouse_lock_owner_| to NULL before calling OnMouseLockLost(), so | |
1395 // that if OnMouseLockLost() results in calls to any mouse lock method | |
1396 // (e.g., LockMouse()), the method will see consistent internal state. | |
1397 webkit::ppapi::PluginInstance* last_mouse_lock_owner = mouse_lock_owner_; | |
1398 mouse_lock_owner_ = NULL; | |
1399 | |
1400 last_mouse_lock_owner->OnMouseLockLost(); | |
1401 } | |
1402 } | |
1403 | |
1404 bool PepperPluginDelegateImpl::HandleMouseEvent( | |
1405 const WebKit::WebMouseEvent& event) { | |
1406 // This method is called for every mouse event that the render view receives. | 1375 // This method is called for every mouse event that the render view receives. |
1407 // And then the mouse event is forwarded to WebKit, which dispatches it to the | 1376 // And then the mouse event is forwarded to WebKit, which dispatches it to the |
1408 // event target. Potentially a Pepper plugin will receive the event. | 1377 // event target. Potentially a Pepper plugin will receive the event. |
1409 // In order to tell whether a plugin gets the last mouse event and which it | 1378 // In order to tell whether a plugin gets the last mouse event and which it |
1410 // is, we set |last_mouse_event_target_| to NULL here. If a plugin gets the | 1379 // is, we set |last_mouse_event_target_| to NULL here. If a plugin gets the |
1411 // event, it will notify us via DidReceiveMouseEvent() and set itself as | 1380 // event, it will notify us via DidReceiveMouseEvent() and set itself as |
1412 // |last_mouse_event_target_|. | 1381 // |last_mouse_event_target_|. |
1413 last_mouse_event_target_ = NULL; | 1382 last_mouse_event_target_ = NULL; |
1414 | |
1415 if (mouse_locked_) { | |
1416 if (mouse_lock_owner_) { | |
1417 // |cursor_info| is ignored since it is hidden when the mouse is locked. | |
1418 WebKit::WebCursorInfo cursor_info; | |
1419 mouse_lock_owner_->HandleInputEvent(event, &cursor_info); | |
1420 } | |
1421 | |
1422 // If the mouse is locked, only the current owner of the mouse lock can | |
1423 // process mouse events. | |
1424 return true; | |
1425 } | |
1426 return false; | |
1427 } | 1383 } |
1428 | 1384 |
1429 bool PepperPluginDelegateImpl::OpenFileSystem( | 1385 bool PepperPluginDelegateImpl::OpenFileSystem( |
1430 const GURL& url, | 1386 const GURL& url, |
1431 fileapi::FileSystemType type, | 1387 fileapi::FileSystemType type, |
1432 long long size, | 1388 long long size, |
1433 fileapi::FileSystemCallbackDispatcher* dispatcher) { | 1389 fileapi::FileSystemCallbackDispatcher* dispatcher) { |
1434 FileSystemDispatcher* file_system_dispatcher = | 1390 FileSystemDispatcher* file_system_dispatcher = |
1435 ChildThread::current()->file_system_dispatcher(); | 1391 ChildThread::current()->file_system_dispatcher(); |
1436 return file_system_dispatcher->OpenFileSystem( | 1392 return file_system_dispatcher->OpenFileSystem( |
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1954 DLOG(WARNING) << "Browser failed to allocate shared memory"; | 1910 DLOG(WARNING) << "Browser failed to allocate shared memory"; |
1955 return NULL; | 1911 return NULL; |
1956 } | 1912 } |
1957 return new base::SharedMemory(handle, false); | 1913 return new base::SharedMemory(handle, false); |
1958 } | 1914 } |
1959 | 1915 |
1960 ppapi::Preferences PepperPluginDelegateImpl::GetPreferences() { | 1916 ppapi::Preferences PepperPluginDelegateImpl::GetPreferences() { |
1961 return ppapi::Preferences(render_view_->webkit_preferences()); | 1917 return ppapi::Preferences(render_view_->webkit_preferences()); |
1962 } | 1918 } |
1963 | 1919 |
1964 void PepperPluginDelegateImpl::LockMouse( | 1920 bool PepperPluginDelegateImpl::LockMouse( |
1965 webkit::ppapi::PluginInstance* instance) { | 1921 webkit::ppapi::PluginInstance* instance) { |
1966 DCHECK(instance); | |
1967 if (!MouseLockedOrPending()) { | |
1968 DCHECK(!mouse_lock_owner_); | |
1969 pending_lock_request_ = true; | |
1970 mouse_lock_owner_ = instance; | |
1971 | 1922 |
1972 render_view_->Send( | 1923 return render_view_->mouse_lock_dispatcher()->LockMouse( |
1973 new ViewHostMsg_LockMouse(render_view_->routing_id())); | 1924 GetOrCreateLockTargetAdapter(instance)); |
1974 } else if (instance != mouse_lock_owner_) { | |
1975 // Another plugin instance is using mouse lock. Fail immediately. | |
1976 instance->OnLockMouseACK(PP_ERROR_FAILED); | |
1977 } else { | |
1978 if (mouse_locked_) { | |
1979 instance->OnLockMouseACK(PP_OK); | |
1980 } else if (pending_lock_request_) { | |
1981 instance->OnLockMouseACK(PP_ERROR_INPROGRESS); | |
1982 } else { | |
1983 // The only case left here is | |
1984 // !mouse_locked_ && !pending_lock_request_ && pending_unlock_request_, | |
1985 // which is not possible. | |
1986 NOTREACHED(); | |
1987 instance->OnLockMouseACK(PP_ERROR_FAILED); | |
1988 } | |
1989 } | |
1990 } | 1925 } |
1991 | 1926 |
1992 void PepperPluginDelegateImpl::UnlockMouse( | 1927 void PepperPluginDelegateImpl::UnlockMouse( |
1993 webkit::ppapi::PluginInstance* instance) { | 1928 webkit::ppapi::PluginInstance* instance) { |
1994 DCHECK(instance); | 1929 render_view_->mouse_lock_dispatcher()->UnlockMouse( |
| 1930 GetOrCreateLockTargetAdapter(instance)); |
| 1931 } |
1995 | 1932 |
1996 // If no one is using mouse lock or the user is not |instance|, ignore | 1933 bool PepperPluginDelegateImpl::IsMouseLocked( |
1997 // the unlock request. | 1934 webkit::ppapi::PluginInstance* instance) { |
1998 if (MouseLockedOrPending() && mouse_lock_owner_ == instance) { | 1935 return render_view_->mouse_lock_dispatcher()->IsMouseLockedTo( |
1999 if (mouse_locked_ || pending_lock_request_) { | 1936 GetOrCreateLockTargetAdapter(instance)); |
2000 DCHECK(!mouse_locked_ || !pending_lock_request_); | |
2001 if (!pending_unlock_request_) { | |
2002 pending_unlock_request_ = true; | |
2003 | |
2004 render_view_->Send( | |
2005 new ViewHostMsg_UnlockMouse(render_view_->routing_id())); | |
2006 } | |
2007 } else { | |
2008 // The only case left here is | |
2009 // !mouse_locked_ && !pending_lock_request_ && pending_unlock_request_, | |
2010 // which is not possible. | |
2011 NOTREACHED(); | |
2012 } | |
2013 } | |
2014 } | 1937 } |
2015 | 1938 |
2016 void PepperPluginDelegateImpl::DidChangeCursor( | 1939 void PepperPluginDelegateImpl::DidChangeCursor( |
2017 webkit::ppapi::PluginInstance* instance, | 1940 webkit::ppapi::PluginInstance* instance, |
2018 const WebKit::WebCursorInfo& cursor) { | 1941 const WebKit::WebCursorInfo& cursor) { |
2019 // Update the cursor appearance immediately if the requesting plugin is the | 1942 // Update the cursor appearance immediately if the requesting plugin is the |
2020 // one which receives the last mouse event. Otherwise, the new cursor won't be | 1943 // one which receives the last mouse event. Otherwise, the new cursor won't be |
2021 // picked up until the plugin gets the next input event. That is bad if, e.g., | 1944 // picked up until the plugin gets the next input event. That is bad if, e.g., |
2022 // the plugin would like to set an invisible cursor when there isn't any user | 1945 // the plugin would like to set an invisible cursor when there isn't any user |
2023 // input for a while. | 1946 // input for a while. |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2163 | 2086 |
2164 bool PepperPluginDelegateImpl::CanUseSocketAPIs() { | 2087 bool PepperPluginDelegateImpl::CanUseSocketAPIs() { |
2165 WebView* webview = render_view_->webview(); | 2088 WebView* webview = render_view_->webview(); |
2166 WebFrame* main_frame = webview ? webview->mainFrame() : NULL; | 2089 WebFrame* main_frame = webview ? webview->mainFrame() : NULL; |
2167 GURL url(main_frame ? GURL(main_frame->document().url()) : GURL()); | 2090 GURL url(main_frame ? GURL(main_frame->document().url()) : GURL()); |
2168 if (!url.is_valid()) | 2091 if (!url.is_valid()) |
2169 return false; | 2092 return false; |
2170 | 2093 |
2171 return content::GetContentClient()->renderer()->AllowSocketAPI(url); | 2094 return content::GetContentClient()->renderer()->AllowSocketAPI(url); |
2172 } | 2095 } |
| 2096 |
| 2097 MouseLockDispatcher::LockTarget* |
| 2098 PepperPluginDelegateImpl::GetOrCreateLockTargetAdapter( |
| 2099 webkit::ppapi::PluginInstance* instance) { |
| 2100 MouseLockDispatcher::LockTarget* target = mouse_lock_instances_[instance]; |
| 2101 if (target) |
| 2102 return target; |
| 2103 |
| 2104 return mouse_lock_instances_[instance] = |
| 2105 new PluginInstanceLockTarget(instance); |
| 2106 } |
| 2107 |
| 2108 void PepperPluginDelegateImpl::UnSetAndDeleteLockTargetAdapter( |
| 2109 webkit::ppapi::PluginInstance* instance) { |
| 2110 LockTargetMap::iterator it = mouse_lock_instances_.find(instance); |
| 2111 if (it != mouse_lock_instances_.end()) { |
| 2112 MouseLockDispatcher::LockTarget* target = it->second; |
| 2113 render_view_->mouse_lock_dispatcher()->OnLockTargetDestroyed(target); |
| 2114 delete target; |
| 2115 mouse_lock_instances_.erase(it); |
| 2116 } |
| 2117 } |
OLD | NEW |