OLD | NEW |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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/app_list/search_answer_web_contents_delegate.h" | 5 #include "chrome/browser/ui/app_list/search/answer_card_search_provider.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/metrics/histogram_macros.h" | 8 #include "base/metrics/histogram_macros.h" |
9 #include "base/metrics/user_metrics.h" | 9 #include "base/metrics/user_metrics.h" |
10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
11 #include "chrome/browser/profiles/profile.h" | 11 #include "chrome/browser/profiles/profile.h" |
12 #include "chrome/browser/ui/browser_navigator.h" | 12 #include "chrome/browser/ui/browser_navigator.h" |
13 #include "chrome/browser/ui/browser_navigator_params.h" | 13 #include "chrome/browser/ui/browser_navigator_params.h" |
14 #include "content/public/browser/navigation_handle.h" | 14 #include "content/public/browser/navigation_handle.h" |
15 #include "content/public/browser/render_view_host.h" | 15 #include "content/public/browser/render_view_host.h" |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 params.disposition = ui::DispositionFromEventFlags(event_flags); | 97 params.disposition = ui::DispositionFromEventFlags(event_flags); |
98 chrome::Navigate(¶ms); | 98 chrome::Navigate(¶ms); |
99 } | 99 } |
100 | 100 |
101 private: | 101 private: |
102 Profile* const profile_; | 102 Profile* const profile_; |
103 }; | 103 }; |
104 | 104 |
105 } // namespace | 105 } // namespace |
106 | 106 |
107 SearchAnswerWebContentsDelegate::SearchAnswerWebContentsDelegate( | 107 AnswerCardSearchProvider::AnswerCardSearchProvider( |
108 Profile* profile, | 108 Profile* profile, |
109 app_list::AppListModel* model) | 109 app_list::AppListModel* model) |
110 : profile_(profile), | 110 : profile_(profile), |
111 model_(model), | 111 model_(model), |
112 web_view_(base::MakeUnique<SearchAnswerWebView>(profile)), | 112 web_view_(base::MakeUnique<SearchAnswerWebView>(profile)), |
113 web_contents_( | 113 web_contents_( |
114 content::WebContents::Create(content::WebContents::CreateParams( | 114 content::WebContents::Create(content::WebContents::CreateParams( |
115 profile, | 115 profile, |
116 content::SiteInstance::Create(profile)))), | 116 content::SiteInstance::Create(profile)))), |
117 answer_server_url_(features::AnswerServerUrl()) { | 117 answer_server_url_(features::AnswerServerUrl()) { |
118 content::RendererPreferences* renderer_prefs = | 118 content::RendererPreferences* renderer_prefs = |
119 web_contents_->GetMutableRendererPrefs(); | 119 web_contents_->GetMutableRendererPrefs(); |
120 renderer_prefs->can_accept_load_drops = false; | 120 renderer_prefs->can_accept_load_drops = false; |
121 // We need the OpenURLFromTab() to get called. | 121 // We need the OpenURLFromTab() to get called. |
122 renderer_prefs->browser_handles_all_top_level_requests = true; | 122 renderer_prefs->browser_handles_all_top_level_requests = true; |
123 web_contents_->GetRenderViewHost()->SyncRendererPrefs(); | 123 web_contents_->GetRenderViewHost()->SyncRendererPrefs(); |
124 | 124 |
125 Observe(web_contents_.get()); | 125 Observe(web_contents_.get()); |
126 web_contents_->SetDelegate(this); | 126 web_contents_->SetDelegate(this); |
127 web_view_->set_owned_by_client(); | 127 web_view_->set_owned_by_client(); |
128 web_view_->SetWebContents(web_contents_.get()); | 128 web_view_->SetWebContents(web_contents_.get()); |
129 | 129 |
130 // Make the webview transparent since it's going to be shown on top of a | 130 // Make the webview transparent since it's going to be shown on top of a |
131 // highlightable button. | 131 // highlightable button. |
132 views::WebContentsSetBackgroundColor::CreateForWebContentsWithColor( | 132 views::WebContentsSetBackgroundColor::CreateForWebContentsWithColor( |
133 web_contents_.get(), SK_ColorTRANSPARENT); | 133 web_contents_.get(), SK_ColorTRANSPARENT); |
134 } | 134 } |
135 | 135 |
136 SearchAnswerWebContentsDelegate::~SearchAnswerWebContentsDelegate() { | 136 AnswerCardSearchProvider::~AnswerCardSearchProvider() { |
137 RecordReceivedAnswerFinalResult(); | 137 RecordReceivedAnswerFinalResult(); |
138 } | 138 } |
139 | 139 |
140 views::View* SearchAnswerWebContentsDelegate::web_view() { | 140 views::View* AnswerCardSearchProvider::web_view() { |
141 return web_view_.get(); | 141 return web_view_.get(); |
142 } | 142 } |
143 | 143 |
144 void SearchAnswerWebContentsDelegate::Start(bool is_voice_query, | 144 void AnswerCardSearchProvider::Start(bool is_voice_query, |
145 const base::string16& query) { | 145 const base::string16& query) { |
146 RecordReceivedAnswerFinalResult(); | 146 RecordReceivedAnswerFinalResult(); |
147 // Reset the state. | 147 // Reset the state. |
148 received_answer_ = false; | 148 received_answer_ = false; |
149 OnResultAvailable(false); | 149 OnResultAvailable(false); |
150 current_request_url_ = GURL(); | 150 current_request_url_ = GURL(); |
151 server_request_start_time_ = answer_loaded_time_ = base::TimeTicks(); | 151 server_request_start_time_ = answer_loaded_time_ = base::TimeTicks(); |
152 | 152 |
153 if (is_voice_query) { | 153 if (is_voice_query) { |
154 // No need to send a server request and show a card because launcher | 154 // No need to send a server request and show a card because launcher |
155 // automatically closes upon voice queries. | 155 // automatically closes upon voice queries. |
(...skipping 19 matching lines...) Expand all Loading... |
175 current_request_url_); | 175 current_request_url_); |
176 load_params.transition_type = ui::PAGE_TRANSITION_AUTO_TOPLEVEL; | 176 load_params.transition_type = ui::PAGE_TRANSITION_AUTO_TOPLEVEL; |
177 load_params.should_clear_history_list = true; | 177 load_params.should_clear_history_list = true; |
178 web_contents_->GetController().LoadURLWithParams(load_params); | 178 web_contents_->GetController().LoadURLWithParams(load_params); |
179 server_request_start_time_ = base::TimeTicks::Now(); | 179 server_request_start_time_ = base::TimeTicks::Now(); |
180 | 180 |
181 // We are going to call WebContents::GetPreferredSize(). | 181 // We are going to call WebContents::GetPreferredSize(). |
182 web_contents_->GetRenderViewHost()->EnablePreferredSizeMode(); | 182 web_contents_->GetRenderViewHost()->EnablePreferredSizeMode(); |
183 } | 183 } |
184 | 184 |
185 void SearchAnswerWebContentsDelegate::UpdatePreferredSize( | 185 void AnswerCardSearchProvider::UpdatePreferredSize( |
186 content::WebContents* web_contents, | 186 content::WebContents* web_contents, |
187 const gfx::Size& pref_size) { | 187 const gfx::Size& pref_size) { |
188 OnResultAvailable(received_answer_ && IsCardSizeOk() && | 188 OnResultAvailable(received_answer_ && IsCardSizeOk() && |
189 !web_contents_->IsLoading()); | 189 !web_contents_->IsLoading()); |
190 web_view_->SetPreferredSize(pref_size); | 190 web_view_->SetPreferredSize(pref_size); |
191 if (!answer_loaded_time_.is_null()) { | 191 if (!answer_loaded_time_.is_null()) { |
192 UMA_HISTOGRAM_TIMES("SearchAnswer.ResizeAfterLoadTime", | 192 UMA_HISTOGRAM_TIMES("SearchAnswer.ResizeAfterLoadTime", |
193 base::TimeTicks::Now() - answer_loaded_time_); | 193 base::TimeTicks::Now() - answer_loaded_time_); |
194 } | 194 } |
195 } | 195 } |
196 | 196 |
197 content::WebContents* SearchAnswerWebContentsDelegate::OpenURLFromTab( | 197 content::WebContents* AnswerCardSearchProvider::OpenURLFromTab( |
198 content::WebContents* source, | 198 content::WebContents* source, |
199 const content::OpenURLParams& params) { | 199 const content::OpenURLParams& params) { |
200 if (!params.user_gesture) | 200 if (!params.user_gesture) |
201 return WebContentsDelegate::OpenURLFromTab(source, params); | 201 return WebContentsDelegate::OpenURLFromTab(source, params); |
202 | 202 |
203 // Open the user-clicked link in the browser taking into account the requested | 203 // Open the user-clicked link in the browser taking into account the requested |
204 // disposition. | 204 // disposition. |
205 chrome::NavigateParams new_tab_params(profile_, params.url, | 205 chrome::NavigateParams new_tab_params(profile_, params.url, |
206 params.transition); | 206 params.transition); |
207 | 207 |
208 new_tab_params.disposition = params.disposition; | 208 new_tab_params.disposition = params.disposition; |
209 | 209 |
210 if (params.disposition == WindowOpenDisposition::NEW_BACKGROUND_TAB) { | 210 if (params.disposition == WindowOpenDisposition::NEW_BACKGROUND_TAB) { |
211 // When the user asks to open a link as a background tab, we show an | 211 // When the user asks to open a link as a background tab, we show an |
212 // activated window with the new activated tab after the user closes the | 212 // activated window with the new activated tab after the user closes the |
213 // launcher. So it's "background" relative to the launcher itself. | 213 // launcher. So it's "background" relative to the launcher itself. |
214 new_tab_params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; | 214 new_tab_params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; |
215 new_tab_params.window_action = chrome::NavigateParams::SHOW_WINDOW_INACTIVE; | 215 new_tab_params.window_action = chrome::NavigateParams::SHOW_WINDOW_INACTIVE; |
216 } | 216 } |
217 | 217 |
218 chrome::Navigate(&new_tab_params); | 218 chrome::Navigate(&new_tab_params); |
219 | 219 |
220 base::RecordAction(base::UserMetricsAction("SearchAnswer_OpenedUrl")); | 220 base::RecordAction(base::UserMetricsAction("SearchAnswer_OpenedUrl")); |
221 | 221 |
222 return new_tab_params.target_contents; | 222 return new_tab_params.target_contents; |
223 } | 223 } |
224 | 224 |
225 bool SearchAnswerWebContentsDelegate::HandleContextMenu( | 225 bool AnswerCardSearchProvider::HandleContextMenu( |
226 const content::ContextMenuParams& params) { | 226 const content::ContextMenuParams& params) { |
227 // Disable showing the menu. | 227 // Disable showing the menu. |
228 return true; | 228 return true; |
229 } | 229 } |
230 | 230 |
231 void SearchAnswerWebContentsDelegate::DidFinishNavigation( | 231 void AnswerCardSearchProvider::DidFinishNavigation( |
232 content::NavigationHandle* navigation_handle) { | 232 content::NavigationHandle* navigation_handle) { |
233 if (navigation_handle->GetURL() != current_request_url_) { | 233 if (navigation_handle->GetURL() != current_request_url_) { |
234 RecordRequestResult( | 234 RecordRequestResult( |
235 SearchAnswerRequestResult::REQUEST_RESULT_ANOTHER_REQUEST_STARTED); | 235 SearchAnswerRequestResult::REQUEST_RESULT_ANOTHER_REQUEST_STARTED); |
236 return; | 236 return; |
237 } | 237 } |
238 | 238 |
239 if (!navigation_handle->HasCommitted() || navigation_handle->IsErrorPage() || | 239 if (!navigation_handle->HasCommitted() || navigation_handle->IsErrorPage() || |
240 !navigation_handle->IsInMainFrame()) { | 240 !navigation_handle->IsInMainFrame()) { |
241 RecordRequestResult( | 241 RecordRequestResult( |
(...skipping 13 matching lines...) Expand all Loading... |
255 return; | 255 return; |
256 // SearchResult requires a non-empty id. This "url" will never be opened. | 256 // SearchResult requires a non-empty id. This "url" will never be opened. |
257 result_url_ = "some string"; | 257 result_url_ = "some string"; |
258 } | 258 } |
259 | 259 |
260 received_answer_ = true; | 260 received_answer_ = true; |
261 UMA_HISTOGRAM_TIMES("SearchAnswer.NavigationTime", | 261 UMA_HISTOGRAM_TIMES("SearchAnswer.NavigationTime", |
262 base::TimeTicks::Now() - server_request_start_time_); | 262 base::TimeTicks::Now() - server_request_start_time_); |
263 } | 263 } |
264 | 264 |
265 void SearchAnswerWebContentsDelegate::DidStopLoading() { | 265 void AnswerCardSearchProvider::DidStopLoading() { |
266 if (!received_answer_) | 266 if (!received_answer_) |
267 return; | 267 return; |
268 | 268 |
269 if (IsCardSizeOk()) | 269 if (IsCardSizeOk()) |
270 OnResultAvailable(true); | 270 OnResultAvailable(true); |
271 answer_loaded_time_ = base::TimeTicks::Now(); | 271 answer_loaded_time_ = base::TimeTicks::Now(); |
272 UMA_HISTOGRAM_TIMES("SearchAnswer.LoadingTime", | 272 UMA_HISTOGRAM_TIMES("SearchAnswer.LoadingTime", |
273 answer_loaded_time_ - server_request_start_time_); | 273 answer_loaded_time_ - server_request_start_time_); |
274 base::RecordAction(base::UserMetricsAction("SearchAnswer_StoppedLoading")); | 274 base::RecordAction(base::UserMetricsAction("SearchAnswer_StoppedLoading")); |
275 } | 275 } |
276 | 276 |
277 void SearchAnswerWebContentsDelegate::DidGetUserInteraction( | 277 void AnswerCardSearchProvider::DidGetUserInteraction( |
278 const blink::WebInputEvent::Type type) { | 278 const blink::WebInputEvent::Type type) { |
279 base::RecordAction(base::UserMetricsAction("SearchAnswer_UserInteraction")); | 279 base::RecordAction(base::UserMetricsAction("SearchAnswer_UserInteraction")); |
280 } | 280 } |
281 | 281 |
282 bool SearchAnswerWebContentsDelegate::IsCardSizeOk() const { | 282 bool AnswerCardSearchProvider::IsCardSizeOk() const { |
283 if (features::IsAnswerCardDarkRunEnabled()) | 283 if (features::IsAnswerCardDarkRunEnabled()) |
284 return true; | 284 return true; |
285 | 285 |
286 const gfx::Size size = web_contents_->GetPreferredSize(); | 286 const gfx::Size size = web_contents_->GetPreferredSize(); |
287 return size.width() <= features::AnswerCardMaxWidth() && | 287 return size.width() <= features::AnswerCardMaxWidth() && |
288 size.height() <= features::AnswerCardMaxHeight(); | 288 size.height() <= features::AnswerCardMaxHeight(); |
289 } | 289 } |
290 | 290 |
291 void SearchAnswerWebContentsDelegate::RecordReceivedAnswerFinalResult() { | 291 void AnswerCardSearchProvider::RecordReceivedAnswerFinalResult() { |
292 // Recording whether a server response with an answer contains a card of a | 292 // Recording whether a server response with an answer contains a card of a |
293 // fitting size, or a too large one. Cannot do this in DidStopLoading() or | 293 // fitting size, or a too large one. Cannot do this in DidStopLoading() or |
294 // UpdatePreferredSize() because this may be followed by a resizing with | 294 // UpdatePreferredSize() because this may be followed by a resizing with |
295 // different dimensions, so this method gets called when card's life ends. | 295 // different dimensions, so this method gets called when card's life ends. |
296 if (!received_answer_) | 296 if (!received_answer_) |
297 return; | 297 return; |
298 | 298 |
299 RecordRequestResult( | 299 RecordRequestResult( |
300 IsCardSizeOk() ? SearchAnswerRequestResult::REQUEST_RESULT_RECEIVED_ANSWER | 300 IsCardSizeOk() ? SearchAnswerRequestResult::REQUEST_RESULT_RECEIVED_ANSWER |
301 : SearchAnswerRequestResult:: | 301 : SearchAnswerRequestResult:: |
302 REQUEST_RESULT_RECEIVED_ANSWER_TOO_LARGE); | 302 REQUEST_RESULT_RECEIVED_ANSWER_TOO_LARGE); |
303 } | 303 } |
304 | 304 |
305 void SearchAnswerWebContentsDelegate::OnResultAvailable(bool is_available) { | 305 void AnswerCardSearchProvider::OnResultAvailable(bool is_available) { |
306 SearchProvider::Results results; | 306 SearchProvider::Results results; |
307 if (is_available) { | 307 if (is_available) { |
308 results.reserve(1); | 308 results.reserve(1); |
309 results.emplace_back(base::MakeUnique<SearchAnswerResult>( | 309 results.emplace_back(base::MakeUnique<SearchAnswerResult>( |
310 profile_, result_url_, web_view_.get())); | 310 profile_, result_url_, web_view_.get())); |
311 } | 311 } |
312 SwapResults(&results); | 312 SwapResults(&results); |
313 } | 313 } |
314 | 314 |
315 bool SearchAnswerWebContentsDelegate::ParseResponseHeaders( | 315 bool AnswerCardSearchProvider::ParseResponseHeaders( |
316 const net::HttpResponseHeaders* headers) { | 316 const net::HttpResponseHeaders* headers) { |
317 if (!headers || headers->response_code() != net::HTTP_OK) | 317 if (!headers || headers->response_code() != net::HTTP_OK) |
318 return false; | 318 return false; |
319 if (!headers->HasHeaderValue("SearchAnswer-HasResult", "true")) | 319 if (!headers->HasHeaderValue("SearchAnswer-HasResult", "true")) |
320 return false; | 320 return false; |
321 if (!headers->GetNormalizedHeader("SearchAnswer-OpenResultUrl", &result_url_)) | 321 if (!headers->GetNormalizedHeader("SearchAnswer-OpenResultUrl", &result_url_)) |
322 return false; | 322 return false; |
323 return true; | 323 return true; |
324 } | 324 } |
325 | 325 |
326 } // namespace app_list | 326 } // namespace app_list |
OLD | NEW |