OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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 "chrome/browser/ui/search/search_ipc_router.h" | 5 #include "chrome/browser/ui/search/search_ipc_router.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "chrome/browser/profiles/profile.h" | 9 #include "chrome/browser/profiles/profile.h" |
| 10 #include "chrome/browser/search/instant_service.h" |
| 11 #include "chrome/browser/search/instant_service_factory.h" |
10 #include "chrome/browser/search/search.h" | 12 #include "chrome/browser/search/search.h" |
11 #include "chrome/common/render_messages.h" | 13 #include "chrome/common/render_messages.h" |
12 #include "components/search/search.h" | 14 #include "components/search/search.h" |
13 #include "content/public/browser/navigation_details.h" | 15 #include "content/public/browser/navigation_details.h" |
14 #include "content/public/browser/render_frame_host.h" | 16 #include "content/public/browser/render_frame_host.h" |
15 #include "content/public/browser/render_process_host.h" | 17 #include "content/public/browser/render_process_host.h" |
16 #include "content/public/browser/web_contents.h" | 18 #include "content/public/browser/web_contents.h" |
17 #include "content/public/common/associated_interface_provider.h" | 19 #include "content/public/common/associated_interface_provider.h" |
18 #include "content/public/common/child_process_host.h" | 20 #include "content/public/common/child_process_host.h" |
19 | 21 |
20 namespace { | 22 namespace { |
21 | 23 |
22 bool IsRenderedInInstantProcess(content::WebContents* web_contents) { | 24 bool IsInInstantProcess(content::RenderFrameHost* render_frame) { |
23 // TODO(tibell): Instead of rejecting messages check at connection time if we | 25 content::RenderProcessHost* process_host = render_frame->GetProcess(); |
24 // want to talk to the render frame or not. Later, in an out-of-process iframe | 26 const InstantService* instant_service = InstantServiceFactory::GetForProfile( |
25 // world, the IsRenderedInInstantProcess check will have to be done, as it's | 27 Profile::FromBrowserContext(process_host->GetBrowserContext())); |
26 // based on the RenderView. | 28 if (!instant_service) |
27 Profile* profile = | 29 return false; |
28 Profile::FromBrowserContext(web_contents->GetBrowserContext()); | 30 |
29 return search::IsRenderedInInstantProcess(web_contents, profile); | 31 return instant_service->IsInstantProcess(process_host->GetID()); |
30 } | 32 } |
31 | 33 |
32 class SearchBoxClientFactoryImpl | 34 class SearchBoxClientFactoryImpl |
33 : public SearchIPCRouter::SearchBoxClientFactory { | 35 : public SearchIPCRouter::SearchBoxClientFactory, |
| 36 public chrome::mojom::EmbeddedSearchConnector { |
34 public: | 37 public: |
35 // The |web_contents| must outlive this object. | 38 // |web_contents| and |binding| must outlive this object. |
36 explicit SearchBoxClientFactoryImpl(content::WebContents* web_contents) | 39 SearchBoxClientFactoryImpl( |
37 : web_contents_(web_contents), | 40 content::WebContents* web_contents, |
38 last_connected_rfh_( | 41 mojo::AssociatedBinding<chrome::mojom::Instant>* binding) |
39 std::make_pair(content::ChildProcessHost::kInvalidUniqueID, | 42 : client_binding_(binding), factory_bindings_(web_contents, this) { |
40 MSG_ROUTING_NONE)) {} | 43 DCHECK(web_contents); |
41 chrome::mojom::SearchBox* GetSearchBox() override; | 44 DCHECK(binding); |
| 45 // Before we are connected to a frame we throw away all messages. |
| 46 mojo::GetIsolatedProxy(&search_box_); |
| 47 } |
| 48 |
| 49 chrome::mojom::SearchBox* GetSearchBox() override { |
| 50 return search_box_.get(); |
| 51 } |
42 | 52 |
43 private: | 53 private: |
44 void OnConnectionError(); | 54 void Connect(chrome::mojom::InstantAssociatedRequest request, |
| 55 chrome::mojom::SearchBoxAssociatedPtrInfo client) override; |
45 | 56 |
46 content::WebContents* web_contents_; | 57 // An interface used to push updates to the frame that connected to us. Before |
| 58 // we've been connected to a frame, messages sent on this interface go into |
| 59 // the void. |
47 chrome::mojom::SearchBoxAssociatedPtr search_box_; | 60 chrome::mojom::SearchBoxAssociatedPtr search_box_; |
48 | 61 |
49 // The proccess ID and routing ID of the last connected main frame. May be | 62 // Used to bind incoming interface requests to the implementation, which lives |
50 // (ChildProcessHost::kInvalidUniqueID, MSG_ROUTING_NONE) if we haven't | 63 // in SearchIPCRouter. |
51 // connected yet. | 64 mojo::AssociatedBinding<chrome::mojom::Instant>* client_binding_; |
52 std::pair<int, int> last_connected_rfh_; | 65 |
| 66 // Binding used to listen to connection requests. |
| 67 content::WebContentsFrameBindingSet<chrome::mojom::EmbeddedSearchConnector> |
| 68 factory_bindings_; |
53 | 69 |
54 DISALLOW_COPY_AND_ASSIGN(SearchBoxClientFactoryImpl); | 70 DISALLOW_COPY_AND_ASSIGN(SearchBoxClientFactoryImpl); |
55 }; | 71 }; |
56 | 72 |
57 chrome::mojom::SearchBox* SearchBoxClientFactoryImpl::GetSearchBox() { | 73 void SearchBoxClientFactoryImpl::Connect( |
58 content::RenderFrameHost* frame = web_contents_->GetMainFrame(); | 74 chrome::mojom::InstantAssociatedRequest request, |
59 auto id = std::make_pair(frame->GetProcess()->GetID(), frame->GetRoutingID()); | 75 chrome::mojom::SearchBoxAssociatedPtrInfo client) { |
60 // Avoid reconnecting repeatedly to the same RenderFrameHost for performance | 76 content::RenderFrameHost* frame = factory_bindings_.GetCurrentTargetFrame(); |
61 // reasons. | 77 const bool is_main_frame = frame->GetParent() == nullptr; |
62 if (id != last_connected_rfh_) { | 78 if (!IsInInstantProcess(frame) || !is_main_frame) { |
63 if (IsRenderedInInstantProcess(web_contents_)) { | 79 return; |
64 frame->GetRemoteAssociatedInterfaces()->GetInterface(&search_box_); | |
65 search_box_.set_connection_error_handler( | |
66 base::Bind(&SearchBoxClientFactoryImpl::OnConnectionError, | |
67 base::Unretained(this))); | |
68 } else { | |
69 // Renderer is not an instant process. We'll create a connection that | |
70 // drops all messages. | |
71 mojo::GetIsolatedProxy(&search_box_); | |
72 } | |
73 last_connected_rfh_ = id; | |
74 } | 80 } |
75 return search_box_.get(); | 81 client_binding_->Bind(std::move(request)); |
76 } | 82 search_box_.Bind(std::move(client)); |
77 | |
78 void SearchBoxClientFactoryImpl::OnConnectionError() { | |
79 search_box_.reset(); | |
80 last_connected_rfh_ = std::make_pair( | |
81 content::ChildProcessHost::kInvalidUniqueID, | |
82 MSG_ROUTING_NONE); | |
83 } | 83 } |
84 | 84 |
85 } // namespace | 85 } // namespace |
86 | 86 |
87 SearchIPCRouter::SearchIPCRouter(content::WebContents* web_contents, | 87 SearchIPCRouter::SearchIPCRouter(content::WebContents* web_contents, |
88 Delegate* delegate, | 88 Delegate* delegate, |
89 std::unique_ptr<Policy> policy) | 89 std::unique_ptr<Policy> policy) |
90 : WebContentsObserver(web_contents), | 90 : WebContentsObserver(web_contents), |
91 delegate_(delegate), | 91 delegate_(delegate), |
92 policy_(std::move(policy)), | 92 policy_(std::move(policy)), |
93 commit_counter_(0), | 93 commit_counter_(0), |
94 is_active_tab_(false), | 94 is_active_tab_(false), |
95 bindings_(web_contents, this), | 95 binding_(this), |
96 search_box_client_factory_(new SearchBoxClientFactoryImpl(web_contents)) { | 96 search_box_client_factory_( |
| 97 new SearchBoxClientFactoryImpl(web_contents, &binding_)) { |
97 DCHECK(web_contents); | 98 DCHECK(web_contents); |
98 DCHECK(delegate); | 99 DCHECK(delegate); |
99 DCHECK(policy_.get()); | 100 DCHECK(policy_.get()); |
100 } | 101 } |
101 | 102 |
102 SearchIPCRouter::~SearchIPCRouter() {} | 103 SearchIPCRouter::~SearchIPCRouter() = default; |
103 | 104 |
104 void SearchIPCRouter::OnNavigationEntryCommitted() { | 105 void SearchIPCRouter::OnNavigationEntryCommitted() { |
105 ++commit_counter_; | 106 ++commit_counter_; |
106 search_box()->SetPageSequenceNumber(commit_counter_); | 107 search_box()->SetPageSequenceNumber(commit_counter_); |
107 } | 108 } |
108 | 109 |
109 void SearchIPCRouter::DetermineIfPageSupportsInstant() { | 110 void SearchIPCRouter::DetermineIfPageSupportsInstant() { |
110 search_box()->DetermineIfPageSupportsInstant(); | 111 search_box()->DetermineIfPageSupportsInstant(); |
111 } | 112 } |
112 | 113 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 void SearchIPCRouter::OnTabActivated() { | 177 void SearchIPCRouter::OnTabActivated() { |
177 is_active_tab_ = true; | 178 is_active_tab_ = true; |
178 } | 179 } |
179 | 180 |
180 void SearchIPCRouter::OnTabDeactivated() { | 181 void SearchIPCRouter::OnTabDeactivated() { |
181 is_active_tab_ = false; | 182 is_active_tab_ = false; |
182 } | 183 } |
183 | 184 |
184 void SearchIPCRouter::InstantSupportDetermined(int page_seq_no, | 185 void SearchIPCRouter::InstantSupportDetermined(int page_seq_no, |
185 bool instant_support) { | 186 bool instant_support) { |
186 if (!IsRenderedInInstantProcess(web_contents())) | |
187 return; | |
188 if (page_seq_no != commit_counter_) | 187 if (page_seq_no != commit_counter_) |
189 return; | 188 return; |
190 | 189 |
191 delegate_->OnInstantSupportDetermined(instant_support); | 190 delegate_->OnInstantSupportDetermined(instant_support); |
192 } | 191 } |
193 | 192 |
194 void SearchIPCRouter::FocusOmnibox(int page_seq_no, OmniboxFocusState state) { | 193 void SearchIPCRouter::FocusOmnibox(int page_seq_no, OmniboxFocusState state) { |
195 if (!IsRenderedInInstantProcess(web_contents())) | |
196 return; | |
197 if (page_seq_no != commit_counter_) | 194 if (page_seq_no != commit_counter_) |
198 return; | 195 return; |
199 | 196 |
200 delegate_->OnInstantSupportDetermined(true); | 197 delegate_->OnInstantSupportDetermined(true); |
201 if (!policy_->ShouldProcessFocusOmnibox(is_active_tab_)) | 198 if (!policy_->ShouldProcessFocusOmnibox(is_active_tab_)) |
202 return; | 199 return; |
203 | 200 |
204 delegate_->FocusOmnibox(state); | 201 delegate_->FocusOmnibox(state); |
205 } | 202 } |
206 | 203 |
207 void SearchIPCRouter::DeleteMostVisitedItem(int page_seq_no, const GURL& url) { | 204 void SearchIPCRouter::DeleteMostVisitedItem(int page_seq_no, const GURL& url) { |
208 if (!IsRenderedInInstantProcess(web_contents())) | |
209 return; | |
210 if (page_seq_no != commit_counter_) | 205 if (page_seq_no != commit_counter_) |
211 return; | 206 return; |
212 | 207 |
213 delegate_->OnInstantSupportDetermined(true); | 208 delegate_->OnInstantSupportDetermined(true); |
214 if (!policy_->ShouldProcessDeleteMostVisitedItem()) | 209 if (!policy_->ShouldProcessDeleteMostVisitedItem()) |
215 return; | 210 return; |
216 | 211 |
217 delegate_->OnDeleteMostVisitedItem(url); | 212 delegate_->OnDeleteMostVisitedItem(url); |
218 } | 213 } |
219 | 214 |
220 void SearchIPCRouter::UndoMostVisitedDeletion(int page_seq_no, | 215 void SearchIPCRouter::UndoMostVisitedDeletion(int page_seq_no, |
221 const GURL& url) { | 216 const GURL& url) { |
222 if (!IsRenderedInInstantProcess(web_contents())) | |
223 return; | |
224 if (page_seq_no != commit_counter_) | 217 if (page_seq_no != commit_counter_) |
225 return; | 218 return; |
226 | 219 |
227 delegate_->OnInstantSupportDetermined(true); | 220 delegate_->OnInstantSupportDetermined(true); |
228 if (!policy_->ShouldProcessUndoMostVisitedDeletion()) | 221 if (!policy_->ShouldProcessUndoMostVisitedDeletion()) |
229 return; | 222 return; |
230 | 223 |
231 delegate_->OnUndoMostVisitedDeletion(url); | 224 delegate_->OnUndoMostVisitedDeletion(url); |
232 } | 225 } |
233 | 226 |
234 void SearchIPCRouter::UndoAllMostVisitedDeletions(int page_seq_no) { | 227 void SearchIPCRouter::UndoAllMostVisitedDeletions(int page_seq_no) { |
235 if (!IsRenderedInInstantProcess(web_contents())) | |
236 return; | |
237 if (page_seq_no != commit_counter_) | 228 if (page_seq_no != commit_counter_) |
238 return; | 229 return; |
239 | 230 |
240 delegate_->OnInstantSupportDetermined(true); | 231 delegate_->OnInstantSupportDetermined(true); |
241 if (!policy_->ShouldProcessUndoAllMostVisitedDeletions()) | 232 if (!policy_->ShouldProcessUndoAllMostVisitedDeletions()) |
242 return; | 233 return; |
243 | 234 |
244 delegate_->OnUndoAllMostVisitedDeletions(); | 235 delegate_->OnUndoAllMostVisitedDeletions(); |
245 } | 236 } |
246 | 237 |
247 void SearchIPCRouter::LogEvent(int page_seq_no, | 238 void SearchIPCRouter::LogEvent(int page_seq_no, |
248 NTPLoggingEventType event, | 239 NTPLoggingEventType event, |
249 base::TimeDelta time) { | 240 base::TimeDelta time) { |
250 if (!IsRenderedInInstantProcess(web_contents())) | |
251 return; | |
252 if (page_seq_no != commit_counter_) | 241 if (page_seq_no != commit_counter_) |
253 return; | 242 return; |
254 | 243 |
255 delegate_->OnInstantSupportDetermined(true); | 244 delegate_->OnInstantSupportDetermined(true); |
256 if (!policy_->ShouldProcessLogEvent()) | 245 if (!policy_->ShouldProcessLogEvent()) |
257 return; | 246 return; |
258 | 247 |
259 delegate_->OnLogEvent(event, time); | 248 delegate_->OnLogEvent(event, time); |
260 } | 249 } |
261 | 250 |
262 void SearchIPCRouter::LogMostVisitedImpression( | 251 void SearchIPCRouter::LogMostVisitedImpression( |
263 int page_seq_no, | 252 int page_seq_no, |
264 int position, | 253 int position, |
265 ntp_tiles::NTPTileSource tile_source) { | 254 ntp_tiles::NTPTileSource tile_source) { |
266 if (!IsRenderedInInstantProcess(web_contents())) | |
267 return; | |
268 if (page_seq_no != commit_counter_) | 255 if (page_seq_no != commit_counter_) |
269 return; | 256 return; |
270 | 257 |
271 delegate_->OnInstantSupportDetermined(true); | 258 delegate_->OnInstantSupportDetermined(true); |
272 // Logging impressions is controlled by the same policy as logging events. | 259 // Logging impressions is controlled by the same policy as logging events. |
273 if (!policy_->ShouldProcessLogEvent()) | 260 if (!policy_->ShouldProcessLogEvent()) |
274 return; | 261 return; |
275 | 262 |
276 delegate_->OnLogMostVisitedImpression(position, tile_source); | 263 delegate_->OnLogMostVisitedImpression(position, tile_source); |
277 } | 264 } |
278 | 265 |
279 void SearchIPCRouter::LogMostVisitedNavigation( | 266 void SearchIPCRouter::LogMostVisitedNavigation( |
280 int page_seq_no, | 267 int page_seq_no, |
281 int position, | 268 int position, |
282 ntp_tiles::NTPTileSource tile_source) { | 269 ntp_tiles::NTPTileSource tile_source) { |
283 if (!IsRenderedInInstantProcess(web_contents())) | |
284 return; | |
285 if (page_seq_no != commit_counter_) | 270 if (page_seq_no != commit_counter_) |
286 return; | 271 return; |
287 | 272 |
288 delegate_->OnInstantSupportDetermined(true); | 273 delegate_->OnInstantSupportDetermined(true); |
289 // Logging navigations is controlled by the same policy as logging events. | 274 // Logging navigations is controlled by the same policy as logging events. |
290 if (!policy_->ShouldProcessLogEvent()) | 275 if (!policy_->ShouldProcessLogEvent()) |
291 return; | 276 return; |
292 | 277 |
293 delegate_->OnLogMostVisitedNavigation(position, tile_source); | 278 delegate_->OnLogMostVisitedNavigation(position, tile_source); |
294 } | 279 } |
295 | 280 |
296 void SearchIPCRouter::PasteAndOpenDropdown(int page_seq_no, | 281 void SearchIPCRouter::PasteAndOpenDropdown(int page_seq_no, |
297 const base::string16& text) { | 282 const base::string16& text) { |
298 if (!IsRenderedInInstantProcess(web_contents())) | |
299 return; | |
300 if (page_seq_no != commit_counter_) | 283 if (page_seq_no != commit_counter_) |
301 return; | 284 return; |
302 | 285 |
303 delegate_->OnInstantSupportDetermined(true); | 286 delegate_->OnInstantSupportDetermined(true); |
304 if (!policy_->ShouldProcessPasteIntoOmnibox(is_active_tab_)) | 287 if (!policy_->ShouldProcessPasteIntoOmnibox(is_active_tab_)) |
305 return; | 288 return; |
306 | 289 |
307 delegate_->PasteIntoOmnibox(text); | 290 delegate_->PasteIntoOmnibox(text); |
308 } | 291 } |
309 | 292 |
310 void SearchIPCRouter::ChromeIdentityCheck(int page_seq_no, | 293 void SearchIPCRouter::ChromeIdentityCheck(int page_seq_no, |
311 const base::string16& identity) { | 294 const base::string16& identity) { |
312 if (!IsRenderedInInstantProcess(web_contents())) | |
313 return; | |
314 if (page_seq_no != commit_counter_) | 295 if (page_seq_no != commit_counter_) |
315 return; | 296 return; |
316 | 297 |
317 delegate_->OnInstantSupportDetermined(true); | 298 delegate_->OnInstantSupportDetermined(true); |
318 if (!policy_->ShouldProcessChromeIdentityCheck()) | 299 if (!policy_->ShouldProcessChromeIdentityCheck()) |
319 return; | 300 return; |
320 | 301 |
321 delegate_->OnChromeIdentityCheck(identity); | 302 delegate_->OnChromeIdentityCheck(identity); |
322 } | 303 } |
323 | 304 |
324 void SearchIPCRouter::HistorySyncCheck(int page_seq_no) { | 305 void SearchIPCRouter::HistorySyncCheck(int page_seq_no) { |
325 if (!IsRenderedInInstantProcess(web_contents())) | |
326 return; | |
327 if (page_seq_no != commit_counter_) | 306 if (page_seq_no != commit_counter_) |
328 return; | 307 return; |
329 | 308 |
330 delegate_->OnInstantSupportDetermined(true); | 309 delegate_->OnInstantSupportDetermined(true); |
331 if (!policy_->ShouldProcessHistorySyncCheck()) | 310 if (!policy_->ShouldProcessHistorySyncCheck()) |
332 return; | 311 return; |
333 | 312 |
334 delegate_->OnHistorySyncCheck(); | 313 delegate_->OnHistorySyncCheck(); |
335 } | 314 } |
336 | 315 |
337 void SearchIPCRouter::set_delegate_for_testing(Delegate* delegate) { | 316 void SearchIPCRouter::set_delegate_for_testing(Delegate* delegate) { |
338 DCHECK(delegate); | 317 DCHECK(delegate); |
339 delegate_ = delegate; | 318 delegate_ = delegate; |
340 } | 319 } |
341 | 320 |
342 void SearchIPCRouter::set_policy_for_testing(std::unique_ptr<Policy> policy) { | 321 void SearchIPCRouter::set_policy_for_testing(std::unique_ptr<Policy> policy) { |
343 DCHECK(policy); | 322 DCHECK(policy); |
344 policy_ = std::move(policy); | 323 policy_ = std::move(policy); |
345 } | 324 } |
OLD | NEW |