Home | History | Annotate | Download | only in webapps
      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 &params) {
     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