| 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 |