1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/android/webapps/single_tab_mode_tab_helper.h" 6 7 #include "base/lazy_instance.h" 8 #include "chrome/browser/android/tab_android.h" 9 #include "content/public/browser/browser_thread.h" 10 #include "content/public/browser/render_process_host.h" 11 #include "content/public/browser/render_view_host.h" 12 #include "content/public/browser/web_contents.h" 13 14 DEFINE_WEB_CONTENTS_USER_DATA_KEY(SingleTabModeTabHelper); 15 16 namespace { 17 18 typedef std::pair<int32, int32> RenderWidgetHostID; 19 typedef std::set<RenderWidgetHostID> SingleTabIDSet; 20 base::LazyInstance<SingleTabIDSet> g_blocked_ids = LAZY_INSTANCE_INITIALIZER; 21 22 void AddPairOnIOThread(int32 process_id, int32 routing_id) { 23 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 24 RenderWidgetHostID single_tab_pair(process_id, routing_id); 25 g_blocked_ids.Get().insert(single_tab_pair); 26 } 27 28 void RemovePairOnIOThread(int32 process_id, int32 routing_id) { 29 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 30 RenderWidgetHostID single_tab_pair(process_id, routing_id); 31 SingleTabIDSet::iterator itr = g_blocked_ids.Get().find(single_tab_pair); 32 DCHECK(itr != g_blocked_ids.Get().end()); 33 g_blocked_ids.Get().erase(itr); 34 } 35 36 void AddPair(content::RenderViewHost* render_view_host) { 37 if (!render_view_host) 38 return; 39 40 int32 process_id = render_view_host->GetProcess()->GetID(); 41 int32 routing_id = render_view_host->GetRoutingID(); 42 content::BrowserThread::PostTask( 43 content::BrowserThread::IO, FROM_HERE, 44 base::Bind(&AddPairOnIOThread, process_id, routing_id)); 45 } 46 47 void RemovePair(content::RenderViewHost* render_view_host) { 48 if (!render_view_host) 49 return; 50 51 int32 process_id = render_view_host->GetProcess()->GetID(); 52 int32 routing_id = render_view_host->GetRoutingID(); 53 content::BrowserThread::PostTask( 54 content::BrowserThread::IO, FROM_HERE, 55 base::Bind(&RemovePairOnIOThread, process_id, routing_id)); 56 } 57 58 } // namespace 59 60 SingleTabModeTabHelper::SingleTabModeTabHelper( 61 content::WebContents* web_contents) 62 : content::WebContentsObserver(web_contents), 63 block_all_new_windows_(false) { 64 } 65 66 SingleTabModeTabHelper::~SingleTabModeTabHelper() { 67 } 68 69 void SingleTabModeTabHelper::RenderViewCreated( 70 content::RenderViewHost* render_view_host) { 71 if (!block_all_new_windows_) 72 return; 73 AddPair(render_view_host); 74 } 75 76 void SingleTabModeTabHelper::RenderViewDeleted( 77 content::RenderViewHost* render_view_host) { 78 if (!block_all_new_windows_) 79 return; 80 RemovePair(render_view_host); 81 } 82 83 void SingleTabModeTabHelper::PermanentlyBlockAllNewWindows() { 84 block_all_new_windows_ = true; 85 AddPair(web_contents()->GetRenderViewHost()); 86 } 87 88 bool SingleTabModeTabHelper::IsRegistered(int32 process_id, 89 int32 routing_id) { 90 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 91 RenderWidgetHostID single_tab_pair(process_id, routing_id); 92 SingleTabIDSet::iterator itr = g_blocked_ids.Get().find(single_tab_pair); 93 return itr != g_blocked_ids.Get().end(); 94 } 95 96 void SingleTabModeTabHelper::HandleOpenUrl(const BlockedWindowParams ¶ms) { 97 TabAndroid* tab = TabAndroid::FromWebContents(web_contents()); 98 if (!tab) 99 return; 100 101 chrome::NavigateParams nav_params = 102 params.CreateNavigateParams(web_contents()); 103 tab->HandlePopupNavigation(&nav_params); 104 } 105