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
AddPairOnIOThread(int32 process_id,int32 routing_id)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
RemovePairOnIOThread(int32 process_id,int32 routing_id)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
AddPair(content::RenderViewHost * render_view_host)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
RemovePair(content::RenderViewHost * render_view_host)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
SingleTabModeTabHelper(content::WebContents * web_contents)60 SingleTabModeTabHelper::SingleTabModeTabHelper(
61 content::WebContents* web_contents)
62 : content::WebContentsObserver(web_contents),
63 block_all_new_windows_(false) {
64 }
65
~SingleTabModeTabHelper()66 SingleTabModeTabHelper::~SingleTabModeTabHelper() {
67 }
68
RenderViewCreated(content::RenderViewHost * render_view_host)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
RenderViewDeleted(content::RenderViewHost * render_view_host)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
PermanentlyBlockAllNewWindows()83 void SingleTabModeTabHelper::PermanentlyBlockAllNewWindows() {
84 block_all_new_windows_ = true;
85 AddPair(web_contents()->GetRenderViewHost());
86 }
87
IsRegistered(int32 process_id,int32 routing_id)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
HandleOpenUrl(const BlockedWindowParams & params)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