mirror of
				https://bitbucket.org/chromiumembedded/cef
				synced 2025-06-05 21:39:12 +02:00 
			
		
		
		
	CTRL + left click on a link in a PDF document should call OnOpenURLFromTab (issue #1737)
This commit is contained in:
		| @@ -639,13 +639,13 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::GetBrowserForView( | ||||
|     return GetBrowserForHost(render_view_host); | ||||
|   } else { | ||||
|     // Use the thread-safe approach. | ||||
|     bool is_guest_view = false; | ||||
|     scoped_refptr<CefBrowserInfo> info = | ||||
|         CefContentBrowserClient::Get()->GetBrowserInfoForView( | ||||
|             render_process_id, | ||||
|             render_routing_id); | ||||
|     if (info.get()) { | ||||
|             render_process_id, render_routing_id, &is_guest_view); | ||||
|     if (info.get() && !is_guest_view) { | ||||
|       CefRefPtr<CefBrowserHostImpl> browser = info->browser(); | ||||
|       if (!browser.get() && !info->is_mime_handler_view()) { | ||||
|       if (!browser.get()) { | ||||
|         LOG(WARNING) << "Found browser id " << info->browser_id() << | ||||
|                         " but no browser object matching view process id " << | ||||
|                         render_process_id << " and routing id " << | ||||
| @@ -672,13 +672,13 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::GetBrowserForFrame( | ||||
|     return GetBrowserForHost(render_frame_host); | ||||
|   } else { | ||||
|     // Use the thread-safe approach. | ||||
|     bool is_guest_view = false; | ||||
|     scoped_refptr<CefBrowserInfo> info = | ||||
|         CefContentBrowserClient::Get()->GetBrowserInfoForFrame( | ||||
|             render_process_id, | ||||
|             render_routing_id); | ||||
|     if (info.get()) { | ||||
|             render_process_id, render_routing_id, &is_guest_view); | ||||
|     if (info.get() && !is_guest_view) { | ||||
|       CefRefPtr<CefBrowserHostImpl> browser = info->browser(); | ||||
|       if (!browser.get() && !info->is_mime_handler_view()) { | ||||
|       if (!browser.get()) { | ||||
|         LOG(WARNING) << "Found browser id " << info->browser_id() << | ||||
|                         " but no browser object matching frame process id " << | ||||
|                         render_process_id << " and routing id " << | ||||
| @@ -2230,6 +2230,8 @@ void CefBrowserHostImpl::DragSourceEndedAt( | ||||
| // content::WebContentsDelegate methods. | ||||
| // ----------------------------------------------------------------------------- | ||||
|  | ||||
| // |source| may be NULL if the navigation originates from a guest view via | ||||
| // CefContentBrowserClient::CanCreateWindow. | ||||
| content::WebContents* CefBrowserHostImpl::OpenURLFromTab( | ||||
|     content::WebContents* source, | ||||
|     const content::OpenURLParams& params) { | ||||
| @@ -2494,12 +2496,17 @@ void CefBrowserHostImpl::WebContentsCreated( | ||||
|   content::RenderFrameHost* main_frame_host = new_contents->GetMainFrame(); | ||||
|  | ||||
|   CefWindowHandle opener = kNullWindowHandle; | ||||
|   bool is_guest_view = false; | ||||
|   scoped_refptr<CefBrowserInfo> info = | ||||
|       CefContentBrowserClient::Get()->GetOrCreateBrowserInfo( | ||||
|           view_host->GetProcess()->GetID(), | ||||
|           view_host->GetRoutingID(), | ||||
|           main_frame_host->GetProcess()->GetID(), | ||||
|           main_frame_host->GetRoutingID()); | ||||
|           main_frame_host->GetRoutingID(), | ||||
|           &is_guest_view); | ||||
|  | ||||
|   // A CefBrowser should never be created for a guest view WebContents. | ||||
|   CHECK(!is_guest_view); | ||||
|  | ||||
|   if (source_contents) { | ||||
|     DCHECK(info->is_popup()); | ||||
| @@ -2654,20 +2661,22 @@ bool CefBrowserHostImpl::CheckMediaAccessPermission( | ||||
|  | ||||
| void CefBrowserHostImpl::RenderFrameCreated( | ||||
|     content::RenderFrameHost* render_frame_host) { | ||||
|   browser_info_->add_render_frame_id(render_frame_host->GetProcess()->GetID(), | ||||
|   browser_info_->render_id_manager()->add_render_frame_id( | ||||
|       render_frame_host->GetProcess()->GetID(), | ||||
|       render_frame_host->GetRoutingID()); | ||||
| } | ||||
|  | ||||
| void CefBrowserHostImpl::RenderFrameDeleted( | ||||
|     content::RenderFrameHost* render_frame_host) { | ||||
|   browser_info_->remove_render_frame_id( | ||||
|   browser_info_->render_id_manager()->remove_render_frame_id( | ||||
|       render_frame_host->GetProcess()->GetID(), | ||||
|       render_frame_host->GetRoutingID()); | ||||
| } | ||||
|  | ||||
| void CefBrowserHostImpl::RenderViewCreated( | ||||
|     content::RenderViewHost* render_view_host) { | ||||
|   browser_info_->add_render_view_id(render_view_host->GetProcess()->GetID(), | ||||
|   browser_info_->render_id_manager()->add_render_view_id( | ||||
|       render_view_host->GetProcess()->GetID(), | ||||
|       render_view_host->GetRoutingID()); | ||||
|  | ||||
|   // May be already registered if the renderer crashed previously. | ||||
| @@ -2681,7 +2690,8 @@ void CefBrowserHostImpl::RenderViewCreated( | ||||
|  | ||||
| void CefBrowserHostImpl::RenderViewDeleted( | ||||
|     content::RenderViewHost* render_view_host) { | ||||
|   browser_info_->remove_render_view_id(render_view_host->GetProcess()->GetID(), | ||||
|   browser_info_->render_id_manager()->remove_render_view_id( | ||||
|       render_view_host->GetProcess()->GetID(), | ||||
|       render_view_host->GetRoutingID()); | ||||
|  | ||||
|   if (registrar_->IsRegistered( | ||||
|   | ||||
| @@ -15,6 +15,7 @@ | ||||
| #include "include/cef_browser.h" | ||||
| #include "include/cef_client.h" | ||||
| #include "include/cef_frame.h" | ||||
| #include "libcef/browser/browser_info.h" | ||||
| #include "libcef/browser/frame_host_impl.h" | ||||
| #include "libcef/browser/javascript_dialog_manager.h" | ||||
| #include "libcef/browser/menu_creator.h" | ||||
| @@ -303,6 +304,7 @@ class CefBrowserHostImpl : public CefBrowserHost, | ||||
|   // Thread safe accessors. | ||||
|   const CefBrowserSettings& settings() const { return settings_; } | ||||
|   CefRefPtr<CefClient> client() const { return client_; } | ||||
|   scoped_refptr<CefBrowserInfo> browser_info() const { return browser_info_; } | ||||
|   int browser_id() const; | ||||
|  | ||||
| #if defined(USE_AURA) | ||||
|   | ||||
| @@ -3,78 +3,59 @@ | ||||
| // be found in the LICENSE file. | ||||
|  | ||||
| #include "libcef/browser/browser_info.h" | ||||
|  | ||||
| #include "libcef/browser/browser_host_impl.h" | ||||
|  | ||||
| #include "ipc/ipc_message.h" | ||||
|  | ||||
| CefBrowserInfo::CefBrowserInfo(int browser_id, bool is_popup) | ||||
|     : browser_id_(browser_id), | ||||
|       is_popup_(is_popup), | ||||
|       is_windowless_(false), | ||||
|       is_mime_handler_view_(false) { | ||||
|   DCHECK_GT(browser_id, 0); | ||||
| // CefBrowserInfo::RenderIDManager | ||||
|  | ||||
| CefBrowserInfo::RenderIDManager::RenderIDManager(base::Lock* lock) | ||||
|   : lock_(lock) { | ||||
|   DCHECK(lock); | ||||
| } | ||||
|  | ||||
| CefBrowserInfo::~CefBrowserInfo() { | ||||
| } | ||||
|  | ||||
| void CefBrowserInfo::set_windowless(bool windowless) { | ||||
|   is_windowless_ = windowless; | ||||
| } | ||||
|  | ||||
| void CefBrowserInfo::set_mime_handler_view(bool mime_handler_view) { | ||||
|   is_mime_handler_view_ = mime_handler_view; | ||||
| } | ||||
|  | ||||
| void CefBrowserInfo::add_render_view_id( | ||||
| void CefBrowserInfo::RenderIDManager::add_render_view_id( | ||||
|     int render_process_id, int render_routing_id) { | ||||
|   add_render_id(&render_view_id_set_, render_process_id, render_routing_id); | ||||
| } | ||||
|  | ||||
| void CefBrowserInfo::add_render_frame_id( | ||||
| void CefBrowserInfo::RenderIDManager::add_render_frame_id( | ||||
|     int render_process_id, int render_routing_id) { | ||||
|   add_render_id(&render_frame_id_set_, render_process_id, render_routing_id); | ||||
| } | ||||
|  | ||||
| void CefBrowserInfo::remove_render_view_id( | ||||
| void CefBrowserInfo::RenderIDManager::remove_render_view_id( | ||||
|     int render_process_id, int render_routing_id) { | ||||
|   remove_render_id(&render_view_id_set_, render_process_id, render_routing_id); | ||||
| } | ||||
|  | ||||
| void CefBrowserInfo::remove_render_frame_id( | ||||
| void CefBrowserInfo::RenderIDManager::remove_render_frame_id( | ||||
|     int render_process_id, int render_routing_id) { | ||||
|   remove_render_id(&render_frame_id_set_, render_process_id, render_routing_id); | ||||
| } | ||||
|  | ||||
| bool CefBrowserInfo::is_render_view_id_match( | ||||
| bool CefBrowserInfo::RenderIDManager::is_render_view_id_match( | ||||
|     int render_process_id, int render_routing_id) { | ||||
|   return is_render_id_match(&render_view_id_set_, | ||||
|                             render_process_id, | ||||
|                             render_routing_id); | ||||
| } | ||||
|  | ||||
| bool CefBrowserInfo::is_render_frame_id_match( | ||||
| bool CefBrowserInfo::RenderIDManager::is_render_frame_id_match( | ||||
|     int render_process_id, int render_routing_id) { | ||||
|   return is_render_id_match(&render_frame_id_set_, | ||||
|                             render_process_id, | ||||
|                             render_routing_id); | ||||
| } | ||||
|  | ||||
| CefRefPtr<CefBrowserHostImpl> CefBrowserInfo::browser() { | ||||
|   base::AutoLock lock_scope(lock_); | ||||
|   return browser_; | ||||
| } | ||||
|  | ||||
| void CefBrowserInfo::set_browser(CefRefPtr<CefBrowserHostImpl> browser) { | ||||
|   base::AutoLock lock_scope(lock_); | ||||
|   browser_ = browser; | ||||
| } | ||||
|  | ||||
| void CefBrowserInfo::add_render_id(RenderIdSet* id_set, | ||||
| void CefBrowserInfo::RenderIDManager::add_render_id(RenderIdSet* id_set, | ||||
|                                                     int render_process_id, | ||||
|                                                     int render_routing_id) { | ||||
|   DCHECK_GT(render_process_id, 0); | ||||
|   DCHECK_GT(render_routing_id, 0); | ||||
|  | ||||
|   base::AutoLock lock_scope(lock_); | ||||
|   base::AutoLock lock_scope(*lock_); | ||||
|  | ||||
|   if (!id_set->empty()) { | ||||
|     RenderIdSet::const_iterator it = | ||||
| @@ -86,13 +67,13 @@ void CefBrowserInfo::add_render_id(RenderIdSet* id_set, | ||||
|   id_set->insert(std::make_pair(render_process_id, render_routing_id)); | ||||
| } | ||||
|  | ||||
| void CefBrowserInfo::remove_render_id(RenderIdSet* id_set, | ||||
| void CefBrowserInfo::RenderIDManager::remove_render_id(RenderIdSet* id_set, | ||||
|                                                        int render_process_id, | ||||
|                                                        int render_routing_id) { | ||||
|   DCHECK_GT(render_process_id, 0); | ||||
|   DCHECK_GT(render_routing_id, 0); | ||||
|  | ||||
|   base::AutoLock lock_scope(lock_); | ||||
|   base::AutoLock lock_scope(*lock_); | ||||
|  | ||||
|   DCHECK(!id_set->empty()); | ||||
|   if (id_set->empty()) | ||||
| @@ -103,10 +84,11 @@ void CefBrowserInfo::remove_render_id(RenderIdSet* id_set, | ||||
|   DCHECK(erased); | ||||
| } | ||||
|  | ||||
| bool CefBrowserInfo::is_render_id_match(const RenderIdSet* id_set, | ||||
| bool CefBrowserInfo::RenderIDManager::is_render_id_match( | ||||
|     const RenderIdSet* id_set, | ||||
|     int render_process_id, | ||||
|     int render_routing_id) { | ||||
|   base::AutoLock lock_scope(lock_); | ||||
|   base::AutoLock lock_scope(*lock_); | ||||
|  | ||||
|   if (id_set->empty()) | ||||
|     return false; | ||||
| @@ -115,3 +97,32 @@ bool CefBrowserInfo::is_render_id_match(const RenderIdSet* id_set, | ||||
|       id_set->find(std::make_pair(render_process_id, render_routing_id)); | ||||
|   return (it != id_set->end()); | ||||
| } | ||||
|  | ||||
|  | ||||
| // CefBrowserInfo | ||||
|  | ||||
| CefBrowserInfo::CefBrowserInfo(int browser_id, bool is_popup) | ||||
|     : browser_id_(browser_id), | ||||
|       is_popup_(is_popup), | ||||
|       is_windowless_(false), | ||||
|       render_id_manager_(&lock_), | ||||
|       guest_render_id_manager_(&lock_) { | ||||
|   DCHECK_GT(browser_id, 0); | ||||
| } | ||||
|  | ||||
| CefBrowserInfo::~CefBrowserInfo() { | ||||
| } | ||||
|  | ||||
| void CefBrowserInfo::set_windowless(bool windowless) { | ||||
|   is_windowless_ = windowless; | ||||
| } | ||||
|  | ||||
| CefRefPtr<CefBrowserHostImpl> CefBrowserInfo::browser() { | ||||
|   base::AutoLock lock_scope(lock_); | ||||
|   return browser_; | ||||
| } | ||||
|  | ||||
| void CefBrowserInfo::set_browser(CefRefPtr<CefBrowserHostImpl> browser) { | ||||
|   base::AutoLock lock_scope(lock_); | ||||
|   browser_ = browser; | ||||
| } | ||||
|   | ||||
| @@ -8,8 +8,12 @@ | ||||
|  | ||||
| #include <set> | ||||
|  | ||||
| #include "libcef/browser/browser_host_impl.h" | ||||
| #include "include/internal/cef_ptr.h" | ||||
|  | ||||
| #include "base/memory/ref_counted.h" | ||||
| #include "base/synchronization/lock.h" | ||||
|  | ||||
| class CefBrowserHostImpl; | ||||
|  | ||||
| // CefBrowserInfo is used to associate a browser ID and render view/process | ||||
| // IDs with a particular CefBrowserHostImpl. Render view/process IDs may change | ||||
| @@ -19,15 +23,9 @@ | ||||
| // be created directly. | ||||
| class CefBrowserInfo : public base::RefCountedThreadSafe<CefBrowserInfo> { | ||||
|  public: | ||||
|   CefBrowserInfo(int browser_id, bool is_popup); | ||||
|  | ||||
|   int browser_id() const { return browser_id_; }; | ||||
|   bool is_popup() const { return is_popup_; } | ||||
|   bool is_windowless() const { return is_windowless_; } | ||||
|   bool is_mime_handler_view() const { return is_mime_handler_view_; } | ||||
|  | ||||
|   void set_windowless(bool windowless); | ||||
|   void set_mime_handler_view(bool mime_handler_view); | ||||
|   class RenderIDManager { | ||||
|    public: | ||||
|     explicit RenderIDManager(base::Lock* lock); | ||||
|  | ||||
|     // Adds an ID pair if it doesn't already exist. | ||||
|     void add_render_view_id(int render_process_id, int render_routing_id); | ||||
| @@ -41,14 +39,7 @@ class CefBrowserInfo : public base::RefCountedThreadSafe<CefBrowserInfo> { | ||||
|     bool is_render_view_id_match(int render_process_id, int render_routing_id); | ||||
|     bool is_render_frame_id_match(int render_process_id, int render_routing_id); | ||||
|  | ||||
|   CefRefPtr<CefBrowserHostImpl> browser(); | ||||
|   void set_browser(CefRefPtr<CefBrowserHostImpl> browser); | ||||
|  | ||||
|    private: | ||||
|   friend class base::RefCountedThreadSafe<CefBrowserInfo>; | ||||
|  | ||||
|   ~CefBrowserInfo(); | ||||
|  | ||||
|     typedef std::set<std::pair<int, int> > RenderIdSet; | ||||
|  | ||||
|     void add_render_id(RenderIdSet* id_set, | ||||
| @@ -61,12 +52,7 @@ class CefBrowserInfo : public base::RefCountedThreadSafe<CefBrowserInfo> { | ||||
|                             int render_process_id, | ||||
|                             int render_routing_id); | ||||
|  | ||||
|   int browser_id_; | ||||
|   bool is_popup_; | ||||
|   bool is_windowless_; | ||||
|   bool is_mime_handler_view_; | ||||
|  | ||||
|   base::Lock lock_; | ||||
|     base::Lock* lock_; | ||||
|  | ||||
|     // The below members must be protected by |lock_|. | ||||
|  | ||||
| @@ -74,13 +60,52 @@ class CefBrowserInfo : public base::RefCountedThreadSafe<CefBrowserInfo> { | ||||
|     // necessary for the following reasons: | ||||
|     // 1. When navigating cross-origin the new (pending) RenderViewHost will be | ||||
|     //    created before the old (current) RenderViewHost is destroyed. | ||||
|   // 2. When canceling and asynchronously continuing navigation of the same URL | ||||
|   //    a new RenderViewHost may be created for the first (canceled) navigation | ||||
|   //    and then destroyed as a result of the second (allowed) navigation. | ||||
|     // 2. When canceling and asynchronously continuing navigation of the same | ||||
|     //    URL a new RenderViewHost may be created for the first (canceled) | ||||
|     //    navigation and then destroyed as a result of the second (allowed) | ||||
|     //    navigation. | ||||
|     // 3. Out-of-process iframes have their own render IDs which must also be | ||||
|     //    associated with the host browser. | ||||
|     RenderIdSet render_view_id_set_; | ||||
|     RenderIdSet render_frame_id_set_; | ||||
|   }; | ||||
|  | ||||
|   CefBrowserInfo(int browser_id, bool is_popup); | ||||
|  | ||||
|   int browser_id() const { return browser_id_; }; | ||||
|   bool is_popup() const { return is_popup_; } | ||||
|   bool is_windowless() const { return is_windowless_; } | ||||
|  | ||||
|   void set_windowless(bool windowless); | ||||
|  | ||||
|   // Returns the render ID manager for this browser. | ||||
|   RenderIDManager* render_id_manager() { | ||||
|     return &render_id_manager_; | ||||
|   } | ||||
|  | ||||
|   // Returns the render ID manager for guest views owned by this browser. | ||||
|   RenderIDManager* guest_render_id_manager() { | ||||
|     return &guest_render_id_manager_; | ||||
|   } | ||||
|  | ||||
|   CefRefPtr<CefBrowserHostImpl> browser(); | ||||
|   void set_browser(CefRefPtr<CefBrowserHostImpl> browser); | ||||
|  | ||||
|  private: | ||||
|   friend class base::RefCountedThreadSafe<CefBrowserInfo>; | ||||
|  | ||||
|   ~CefBrowserInfo(); | ||||
|  | ||||
|   int browser_id_; | ||||
|   bool is_popup_; | ||||
|   bool is_windowless_; | ||||
|  | ||||
|   base::Lock lock_; | ||||
|  | ||||
|   // The below members must be protected by |lock_|. | ||||
|  | ||||
|   RenderIDManager render_id_manager_; | ||||
|   RenderIDManager guest_render_id_manager_; | ||||
|  | ||||
|   // May be NULL if the browser has not yet been created or if the browser has | ||||
|   // been destroyed. | ||||
|   | ||||
| @@ -97,11 +97,11 @@ void CefBrowserMessageFilter::OnGetNewBrowserInfo( | ||||
|           host_->GetID(), | ||||
|           render_view_routing_id, | ||||
|           host_->GetID(), | ||||
|           render_frame_routing_id); | ||||
|           render_frame_routing_id, | ||||
|           ¶ms->is_guest_view); | ||||
|   params->browser_id = info->browser_id(); | ||||
|   params->is_popup = info->is_popup(); | ||||
|   params->is_windowless = info->is_windowless(); | ||||
|   params->is_mime_handler_view = info->is_mime_handler_view(); | ||||
| } | ||||
|  | ||||
| void CefBrowserMessageFilter::OnCreateWindow( | ||||
|   | ||||
| @@ -399,24 +399,37 @@ scoped_refptr<CefBrowserInfo> | ||||
|         int render_view_process_id, | ||||
|         int render_view_routing_id, | ||||
|         int render_frame_process_id, | ||||
|         int render_frame_routing_id) { | ||||
|         int render_frame_routing_id, | ||||
|         bool* is_guest_view) { | ||||
|   base::AutoLock lock_scope(browser_info_lock_); | ||||
|  | ||||
|   if (is_guest_view) | ||||
|     *is_guest_view = false; | ||||
|  | ||||
|   BrowserInfoList::const_iterator it = browser_info_list_.begin(); | ||||
|   for (; it != browser_info_list_.end(); ++it) { | ||||
|     const scoped_refptr<CefBrowserInfo>& browser_info = *it; | ||||
|     if (browser_info->is_render_view_id_match(render_view_process_id, | ||||
|                                               render_view_routing_id)) { | ||||
|     if (browser_info->render_id_manager()->is_render_view_id_match( | ||||
|             render_view_process_id, render_view_routing_id)) { | ||||
|       // Make sure the frame id is also registered. | ||||
|       browser_info->add_render_frame_id(render_frame_process_id, | ||||
|                                         render_frame_routing_id); | ||||
|       browser_info->render_id_manager()->add_render_frame_id( | ||||
|           render_frame_process_id, render_frame_routing_id); | ||||
|       return browser_info; | ||||
|     } else if (browser_info->is_render_frame_id_match( | ||||
|                   render_frame_process_id, | ||||
|                   render_frame_routing_id)) { | ||||
|     } | ||||
|     if (browser_info->render_id_manager()->is_render_frame_id_match( | ||||
|             render_frame_process_id, render_frame_routing_id)) { | ||||
|       // Make sure the view id is also registered. | ||||
|       browser_info->add_render_view_id(render_view_process_id, | ||||
|                                        render_view_routing_id); | ||||
|       browser_info->render_id_manager()->add_render_view_id( | ||||
|           render_view_process_id, render_view_routing_id); | ||||
|       return browser_info; | ||||
|     } | ||||
|     if (extensions::ExtensionsEnabled() && | ||||
|         (browser_info->guest_render_id_manager()->is_render_view_id_match( | ||||
|              render_view_process_id, render_view_routing_id) || | ||||
|          browser_info->guest_render_id_manager()->is_render_frame_id_match( | ||||
|              render_frame_process_id, render_frame_routing_id))) { | ||||
|       if (is_guest_view) | ||||
|         *is_guest_view = true; | ||||
|       return browser_info; | ||||
|     } | ||||
|   } | ||||
| @@ -424,10 +437,10 @@ scoped_refptr<CefBrowserInfo> | ||||
|   // Must be a popup if it hasn't already been created. | ||||
|   scoped_refptr<CefBrowserInfo> browser_info = | ||||
|       new CefBrowserInfo(++next_browser_id_, true); | ||||
|   browser_info->add_render_view_id(render_view_process_id, | ||||
|                                    render_view_routing_id); | ||||
|   browser_info->add_render_frame_id(render_frame_process_id, | ||||
|                                     render_frame_routing_id); | ||||
|   browser_info->render_id_manager()->add_render_view_id( | ||||
|       render_view_process_id, render_view_routing_id); | ||||
|   browser_info->render_id_manager()->add_render_frame_id( | ||||
|       render_frame_process_id, render_frame_routing_id); | ||||
|   browser_info_list_.push_back(browser_info); | ||||
|   return browser_info; | ||||
| } | ||||
| @@ -482,16 +495,28 @@ void CefContentBrowserClient::DestroyAllBrowsers() { | ||||
| } | ||||
|  | ||||
| scoped_refptr<CefBrowserInfo> CefContentBrowserClient::GetBrowserInfoForView( | ||||
|     int render_process_id, int render_routing_id) { | ||||
|     int render_process_id, | ||||
|     int render_routing_id, | ||||
|     bool* is_guest_view) { | ||||
|   base::AutoLock lock_scope(browser_info_lock_); | ||||
|  | ||||
|   if (is_guest_view) | ||||
|     *is_guest_view = false; | ||||
|  | ||||
|   BrowserInfoList::const_iterator it = browser_info_list_.begin(); | ||||
|   for (; it != browser_info_list_.end(); ++it) { | ||||
|     const scoped_refptr<CefBrowserInfo>& browser_info = *it; | ||||
|     if (browser_info->is_render_view_id_match( | ||||
|     if (browser_info->render_id_manager()->is_render_view_id_match( | ||||
|           render_process_id, render_routing_id)) { | ||||
|       return browser_info; | ||||
|     } | ||||
|     if (extensions::ExtensionsEnabled() && | ||||
|         browser_info->guest_render_id_manager()->is_render_view_id_match( | ||||
|             render_process_id, render_routing_id)) { | ||||
|       if (is_guest_view) | ||||
|         *is_guest_view = true; | ||||
|       return browser_info; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   LOG(WARNING) << "No browser info matching view process id " << | ||||
| @@ -501,16 +526,28 @@ scoped_refptr<CefBrowserInfo> CefContentBrowserClient::GetBrowserInfoForView( | ||||
| } | ||||
|  | ||||
| scoped_refptr<CefBrowserInfo> CefContentBrowserClient::GetBrowserInfoForFrame( | ||||
|     int render_process_id, int render_routing_id) { | ||||
|     int render_process_id, | ||||
|     int render_routing_id, | ||||
|     bool* is_guest_view) { | ||||
|   base::AutoLock lock_scope(browser_info_lock_); | ||||
|  | ||||
|   if (is_guest_view) | ||||
|     *is_guest_view = false; | ||||
|  | ||||
|   BrowserInfoList::const_iterator it = browser_info_list_.begin(); | ||||
|   for (; it != browser_info_list_.end(); ++it) { | ||||
|     const scoped_refptr<CefBrowserInfo>& browser_info = *it; | ||||
|     if (browser_info->is_render_frame_id_match( | ||||
|     if (browser_info->render_id_manager()->is_render_frame_id_match( | ||||
|             render_process_id, render_routing_id)) { | ||||
|       return browser_info; | ||||
|     } | ||||
|     if (extensions::ExtensionsEnabled() && | ||||
|         browser_info->guest_render_id_manager()->is_render_frame_id_match( | ||||
|             render_process_id, render_routing_id)) { | ||||
|       if (is_guest_view) | ||||
|         *is_guest_view = true; | ||||
|       return browser_info; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   LOG(WARNING) << "No browser info matching frame process id " << | ||||
| @@ -846,12 +883,36 @@ bool CefContentBrowserClient::CanCreateWindow( | ||||
|   if (last_create_window_params_.opener_process_id == MSG_ROUTING_NONE) | ||||
|     return false; | ||||
|  | ||||
|   bool is_guest_view = false; | ||||
|   CefRefPtr<CefBrowserHostImpl> browser = | ||||
|       CefBrowserHostImpl::GetBrowserForView( | ||||
|       extensions::GetOwnerBrowserForView( | ||||
|           last_create_window_params_.opener_process_id, | ||||
|           last_create_window_params_.opener_view_id); | ||||
|   if (!browser.get()) | ||||
|           last_create_window_params_.opener_view_id, | ||||
|           &is_guest_view); | ||||
|   DCHECK(browser.get()); | ||||
|   if (!browser.get()) { | ||||
|     // Cancel the popup. | ||||
|     last_create_window_params_.opener_process_id = MSG_ROUTING_NONE; | ||||
|     return false; | ||||
|   } | ||||
|  | ||||
|   if (is_guest_view) { | ||||
|     content::OpenURLParams params(target_url, | ||||
|                                   referrer, | ||||
|                                   disposition, | ||||
|                                   ui::PAGE_TRANSITION_LINK, | ||||
|                                   true); | ||||
|     params.user_gesture = user_gesture; | ||||
|  | ||||
|     // Pass navigation to the owner browser. | ||||
|     CEF_POST_TASK(CEF_UIT, | ||||
|         base::Bind(base::IgnoreResult(&CefBrowserHostImpl::OpenURLFromTab), | ||||
|                    browser.get(), nullptr, params)); | ||||
|  | ||||
|     // Cancel the popup. | ||||
|     last_create_window_params_.opener_process_id = MSG_ROUTING_NONE; | ||||
|     return false; | ||||
|   } | ||||
|  | ||||
|   CefRefPtr<CefClient> client = browser->GetClient(); | ||||
|   bool allow = true; | ||||
| @@ -930,7 +991,7 @@ void CefContentBrowserClient::OverrideWebkitPrefs( | ||||
|       base::CommandLine::ForCurrentProcess(); | ||||
|  | ||||
|   CefRefPtr<CefBrowserHostImpl> browser = | ||||
|       extensions::GetOwnerBrowserForHost(rvh); | ||||
|       extensions::GetOwnerBrowserForHost(rvh, NULL); | ||||
|   if (browser.get()) { | ||||
|     // Populate WebPreferences based on CefBrowserSettings. | ||||
|     BrowserToWebSettings(browser->settings(), *prefs); | ||||
|   | ||||
| @@ -51,23 +51,30 @@ class CefContentBrowserClient : public content::ContentBrowserClient { | ||||
|   // to CefBrowserHostImpl::ShouldCreateWebContents on the UI thread. To resolve | ||||
|   // this race CefBrowserInfo may be created when requested for the first time | ||||
|   // and before the associated CefBrowserHostImpl is created. | ||||
|   // |is_guest_view| will be set to true if the IDs match a guest view | ||||
|   // associated with the returned browser info instead of the browser itself. | ||||
|   scoped_refptr<CefBrowserInfo> CreateBrowserInfo(bool is_popup); | ||||
|   scoped_refptr<CefBrowserInfo> GetOrCreateBrowserInfo( | ||||
|       int render_view_process_id, | ||||
|       int render_view_routing_id, | ||||
|       int render_frame_process_id, | ||||
|       int render_frame_routing_id); | ||||
|       int render_frame_routing_id, | ||||
|       bool* is_guest_view); | ||||
|   void RemoveBrowserInfo(scoped_refptr<CefBrowserInfo> browser_info); | ||||
|   void DestroyAllBrowsers(); | ||||
|  | ||||
|   // Retrieves the CefBrowserInfo matching the specified IDs or an empty | ||||
|   // pointer if no match is found. It is allowed to add new callers of this | ||||
|   // method but consider using CefBrowserHostImpl::GetBrowserFor[View|Frame]() | ||||
|   // instead. | ||||
|   // or extensions::GetOwnerBrowserForView() instead. | ||||
|   // |is_guest_view| will be set to true if the IDs match a guest view | ||||
|   // associated with the returned browser info instead of the browser itself. | ||||
|   scoped_refptr<CefBrowserInfo> GetBrowserInfoForView(int render_process_id, | ||||
|                                                       int render_routing_id); | ||||
|                                                       int render_routing_id, | ||||
|                                                       bool* is_guest_view); | ||||
|   scoped_refptr<CefBrowserInfo> GetBrowserInfoForFrame(int render_process_id, | ||||
|                                                        int render_routing_id); | ||||
|                                                        int render_routing_id, | ||||
|                                                        bool* is_guest_view); | ||||
|  | ||||
|   // ContentBrowserClient implementation. | ||||
|   content::BrowserMainParts* CreateBrowserMainParts( | ||||
|   | ||||
| @@ -4,6 +4,8 @@ | ||||
|  | ||||
| #include "libcef/browser/extensions/browser_extensions_util.h" | ||||
|  | ||||
| #include "libcef/browser/content_browser_client.h" | ||||
| #include "libcef/browser/thread_util.h" | ||||
| #include "libcef/common/extensions/extensions_util.h" | ||||
|  | ||||
| #include "content/browser/browser_plugin/browser_plugin_embedder.h" | ||||
| @@ -58,24 +60,51 @@ content::WebContents* GetOwnerForGuestContents(content::WebContents* guest) { | ||||
| } | ||||
|  | ||||
| CefRefPtr<CefBrowserHostImpl> GetOwnerBrowserForView(int render_process_id, | ||||
|                                                      int render_routing_id) { | ||||
|                                                      int render_routing_id, | ||||
|                                                      bool* is_guest_view) { | ||||
|   if (CEF_CURRENTLY_ON_UIT()) { | ||||
|     // Use the non-thread-safe but potentially faster approach. | ||||
|     content::RenderViewHost* host = | ||||
|         content::RenderViewHost::FromID(render_process_id, render_routing_id); | ||||
|     if (host) | ||||
|     return GetOwnerBrowserForHost(host); | ||||
|       return GetOwnerBrowserForHost(host, is_guest_view); | ||||
|     return NULL; | ||||
|   } else { | ||||
|     // Use the thread-safe approach. | ||||
|     scoped_refptr<CefBrowserInfo> info = | ||||
|         CefContentBrowserClient::Get()->GetBrowserInfoForView( | ||||
|             render_process_id, render_routing_id, is_guest_view); | ||||
|     if (info.get()) { | ||||
|       CefRefPtr<CefBrowserHostImpl> browser = info->browser(); | ||||
|       if (!browser.get()) { | ||||
|         LOG(WARNING) << "Found browser id " << info->browser_id() << | ||||
|                         " but no browser object matching view process id " << | ||||
|                         render_process_id << " and routing id " << | ||||
|                         render_routing_id; | ||||
|       } | ||||
|       return browser; | ||||
|     } | ||||
|     return NULL; | ||||
|   } | ||||
| } | ||||
|  | ||||
| CefRefPtr<CefBrowserHostImpl> GetOwnerBrowserForHost( | ||||
|     content::RenderViewHost* host) { | ||||
|     content::RenderViewHost* host, | ||||
|     bool* is_guest_view) { | ||||
|   if (is_guest_view) | ||||
|     *is_guest_view = false; | ||||
|  | ||||
|   CefRefPtr<CefBrowserHostImpl> browser = | ||||
|       CefBrowserHostImpl::GetBrowserForHost(host); | ||||
|   if (!browser.get() && ExtensionsEnabled()) { | ||||
|     // Retrieve the owner browser, if any. | ||||
|     content::WebContents* owner = GetOwnerForGuestContents( | ||||
|         content::WebContents::FromRenderViewHost(host)); | ||||
|     if (owner) | ||||
|     if (owner) { | ||||
|       browser = CefBrowserHostImpl::GetBrowserForContents(owner); | ||||
|       if (browser.get() && is_guest_view) | ||||
|         *is_guest_view = true; | ||||
|     } | ||||
|   } | ||||
|   return browser; | ||||
| } | ||||
|   | ||||
| @@ -28,13 +28,19 @@ void GetAllGuestsForOwnerContents(content::WebContents* owner, | ||||
| content::WebContents* GetOwnerForGuestContents(content::WebContents* guest); | ||||
|  | ||||
| // Returns the CefBrowserHostImpl that owns the host identified by the specified | ||||
| // view routing IDs, if any. | ||||
| // view routing IDs, if any. |is_guest_view| will be set to true if the IDs | ||||
| // match a guest view associated with the returned browser instead of the | ||||
| // browser itself. | ||||
| CefRefPtr<CefBrowserHostImpl> GetOwnerBrowserForView(int render_process_id, | ||||
|                                                      int render_routing_id); | ||||
|                                                      int render_routing_id, | ||||
|                                                      bool* is_guest_view); | ||||
|  | ||||
| // Returns the CefBrowserHostImpl that owns the specified |host|, if any. | ||||
| // |is_guest_view| will be set to true if the host matches a guest view | ||||
| // associated with the returned browser instead of the browser itself. | ||||
| CefRefPtr<CefBrowserHostImpl> GetOwnerBrowserForHost( | ||||
|     content::RenderViewHost* host); | ||||
|     content::RenderViewHost* host, | ||||
|     bool* is_guest_view); | ||||
|  | ||||
| }  // namespace extensions | ||||
|  | ||||
|   | ||||
| @@ -55,18 +55,20 @@ bool CefMimeHandlerViewGuestDelegate::OnGuestAttached( | ||||
|   content::WebContents* web_contents = guest_->web_contents(); | ||||
|   DCHECK(web_contents); | ||||
|  | ||||
|   // Associate state information with the new WebContents. | ||||
|   content::RenderViewHost* view_host = web_contents->GetRenderViewHost(); | ||||
|   content::RenderFrameHost* main_frame_host = web_contents->GetMainFrame(); | ||||
|   scoped_refptr<CefBrowserInfo> info = | ||||
|       CefContentBrowserClient::Get()->GetOrCreateBrowserInfo( | ||||
|           view_host->GetProcess()->GetID(), | ||||
|           view_host->GetRoutingID(), | ||||
|           main_frame_host->GetProcess()->GetID(), | ||||
|           main_frame_host->GetRoutingID()); | ||||
|   info->set_mime_handler_view(true); | ||||
|  | ||||
|   CefRefPtr<CefBrowserHostImpl> owner_browser = GetOwnerBrowser(guest_); | ||||
|  | ||||
|   // Associate guest state information with the owner browser. | ||||
|   scoped_refptr<CefBrowserInfo> info = owner_browser->browser_info(); | ||||
|   info->guest_render_id_manager()->add_render_view_id( | ||||
|       view_host->GetProcess()->GetID(), | ||||
|       view_host->GetRoutingID()); | ||||
|   info->guest_render_id_manager()->add_render_frame_id( | ||||
|       main_frame_host->GetProcess()->GetID(), | ||||
|       main_frame_host->GetRoutingID()); | ||||
|  | ||||
|   if (owner_browser->IsWindowless()) { | ||||
|     // Use the OSR view instead of the default WebContentsViewGuest. | ||||
|     content::WebContentsImpl* web_contents_impl = | ||||
| @@ -85,8 +87,25 @@ bool CefMimeHandlerViewGuestDelegate::OnGuestAttached( | ||||
| bool CefMimeHandlerViewGuestDelegate::OnGuestDetached( | ||||
|     content::WebContentsView* guest_view, | ||||
|     content::WebContentsView* parent_view) { | ||||
|   content::WebContents* web_contents = guest_->web_contents(); | ||||
|   DCHECK(web_contents); | ||||
|  | ||||
|   content::RenderViewHost* view_host = web_contents->GetRenderViewHost(); | ||||
|   content::RenderFrameHost* main_frame_host = web_contents->GetMainFrame(); | ||||
|  | ||||
|   CefRefPtr<CefBrowserHostImpl> owner_browser = GetOwnerBrowser(guest_); | ||||
|  | ||||
|   // Disassociate guest state information with the owner browser. | ||||
|   scoped_refptr<CefBrowserInfo> info = owner_browser->browser_info(); | ||||
|   info->guest_render_id_manager()->remove_render_view_id( | ||||
|       view_host->GetProcess()->GetID(), | ||||
|       view_host->GetRoutingID()); | ||||
|   info->guest_render_id_manager()->remove_render_frame_id( | ||||
|       main_frame_host->GetProcess()->GetID(), | ||||
|       main_frame_host->GetRoutingID()); | ||||
|  | ||||
|   // Do nothing when the browser is windowless. | ||||
|   return GetOwnerBrowser(guest_)->IsWindowless(); | ||||
|   return owner_browser->IsWindowless(); | ||||
| } | ||||
|  | ||||
| bool CefMimeHandlerViewGuestDelegate::CreateViewForWidget( | ||||
|   | ||||
| @@ -160,7 +160,9 @@ void CefPrintDialogLinux::OnPrintStart(int render_process_id, | ||||
|     return; | ||||
|  | ||||
|   CefRefPtr<CefBrowserHostImpl> browser = | ||||
|       extensions::GetOwnerBrowserForView(render_process_id, render_routing_id); | ||||
|       extensions::GetOwnerBrowserForView(render_process_id, | ||||
|                                          render_routing_id, | ||||
|                                          NULL); | ||||
|   if (browser.get()) | ||||
|     handler->OnPrintStart(browser.get()); | ||||
| } | ||||
|   | ||||
| @@ -202,7 +202,7 @@ IPC_STRUCT_BEGIN(CefProcessHostMsg_GetNewBrowserInfo_Params) | ||||
|   IPC_STRUCT_MEMBER(int, browser_id) | ||||
|   IPC_STRUCT_MEMBER(bool, is_popup) | ||||
|   IPC_STRUCT_MEMBER(bool, is_windowless) | ||||
|   IPC_STRUCT_MEMBER(bool, is_mime_handler_view) | ||||
|   IPC_STRUCT_MEMBER(bool, is_guest_view) | ||||
| IPC_STRUCT_END() | ||||
|  | ||||
| // Retrieve information about a newly created browser. | ||||
|   | ||||
| @@ -1009,8 +1009,8 @@ void CefContentRendererClient::BrowserCreated( | ||||
|           ¶ms)); | ||||
|   DCHECK_GT(params.browser_id, 0); | ||||
|  | ||||
|   if (params.is_mime_handler_view) { | ||||
|     // Don't create a CefBrowser for mime handler views. | ||||
|   if (params.is_guest_view) { | ||||
|     // Don't create a CefBrowser for guest views. | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -459,7 +459,8 @@ bool ClientHandler::OnOpenURLFromTab( | ||||
|     const CefString& target_url, | ||||
|     CefRequestHandler::WindowOpenDisposition target_disposition, | ||||
|     bool user_gesture) { | ||||
|   if (user_gesture && target_disposition == WOD_NEW_BACKGROUND_TAB) { | ||||
|   if (target_disposition == WOD_NEW_BACKGROUND_TAB || | ||||
|       target_disposition == WOD_NEW_FOREGROUND_TAB) { | ||||
|     // Handle middle-click and ctrl + left-click by opening the URL in a new | ||||
|     // browser window. | ||||
|     MainContext::Get()->GetRootWindowManager()->CreateRootWindow( | ||||
|   | ||||
		Reference in New Issue
	
	Block a user