OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/chromeos/arc/arc_navigation_throttle.h" | 5 #include "chrome/browser/chromeos/arc/arc_navigation_throttle.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 if (!handlers[i]->is_preferred) | 166 if (!handlers[i]->is_preferred) |
167 continue; | 167 continue; |
168 if (ArcIntentHelperBridge::IsIntentHelperPackage( | 168 if (ArcIntentHelperBridge::IsIntentHelperPackage( |
169 handlers[i]->package_name)) { | 169 handlers[i]->package_name)) { |
170 // If Chrome browser was selected as the preferred app, we should't | 170 // If Chrome browser was selected as the preferred app, we should't |
171 // create a throttle. | 171 // create a throttle. |
172 DVLOG(1) | 172 DVLOG(1) |
173 << "Chrome browser is selected as the preferred app for this URL: " | 173 << "Chrome browser is selected as the preferred app for this URL: " |
174 << navigation_handle()->GetURL().spec(); | 174 << navigation_handle()->GetURL().spec(); |
175 } | 175 } |
176 std::string package_name = handlers[i]->package_name; | 176 OnIntentPickerClosed(std::move(handlers), i, |
177 OnIntentPickerClosed(std::move(handlers), package_name, | |
178 CloseReason::PREFERRED_ACTIVITY_FOUND); | 177 CloseReason::PREFERRED_ACTIVITY_FOUND); |
179 return; | 178 return; |
180 } | 179 } |
181 | 180 |
182 // Swap Chrome app with any app in row |kMaxAppResults-1| iff its index is | 181 // Swap Chrome app with any app in row |kMaxAppResults-1| iff its index is |
183 // bigger, thus ensuring the user can always see Chrome without scrolling. | 182 // bigger, thus ensuring the user can always see Chrome without scrolling. |
184 size_t chrome_app_index = 0; | 183 size_t chrome_app_index = 0; |
185 for (size_t i = 0; i < handlers.size(); ++i) { | 184 for (size_t i = 0; i < handlers.size(); ++i) { |
186 if (ArcIntentHelperBridge::IsIntentHelperPackage( | 185 if (ArcIntentHelperBridge::IsIntentHelperPackage( |
187 handlers[i]->package_name)) { | 186 handlers[i]->package_name)) { |
(...skipping 18 matching lines...) Expand all Loading... |
206 icon_loader->GetActivityIcons( | 205 icon_loader->GetActivityIcons( |
207 activities, | 206 activities, |
208 base::Bind(&ArcNavigationThrottle::OnAppIconsReceived, | 207 base::Bind(&ArcNavigationThrottle::OnAppIconsReceived, |
209 weak_ptr_factory_.GetWeakPtr(), base::Passed(&handlers))); | 208 weak_ptr_factory_.GetWeakPtr(), base::Passed(&handlers))); |
210 } | 209 } |
211 | 210 |
212 void ArcNavigationThrottle::OnAppIconsReceived( | 211 void ArcNavigationThrottle::OnAppIconsReceived( |
213 mojo::Array<mojom::IntentHandlerInfoPtr> handlers, | 212 mojo::Array<mojom::IntentHandlerInfoPtr> handlers, |
214 std::unique_ptr<ActivityIconLoader::ActivityToIconsMap> icons) { | 213 std::unique_ptr<ActivityIconLoader::ActivityToIconsMap> icons) { |
215 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 214 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
216 std::vector<AppInfo> app_info; | 215 std::vector<NameAndIcon> app_info; |
217 | 216 |
218 for (const auto& handler : handlers) { | 217 for (const auto& handler : handlers) { |
219 gfx::Image icon; | 218 gfx::Image icon; |
220 const ActivityIconLoader::ActivityName activity(handler->package_name, | 219 const ActivityIconLoader::ActivityName activity(handler->package_name, |
221 handler->activity_name); | 220 handler->activity_name); |
222 const auto it = icons->find(activity); | 221 const auto it = icons->find(activity); |
223 | 222 |
224 app_info.emplace_back( | 223 app_info.emplace_back( |
225 AppInfo(it != icons->end() ? it->second.icon20 : gfx::Image(), | 224 handler->name, it != icons->end() ? it->second.icon20 : gfx::Image()); |
226 handler->package_name, handler->name)); | |
227 } | 225 } |
228 | 226 |
229 show_intent_picker_callback_.Run( | 227 show_intent_picker_callback_.Run( |
230 navigation_handle()->GetWebContents(), app_info, | 228 navigation_handle()->GetWebContents(), app_info, |
231 base::Bind(&ArcNavigationThrottle::OnIntentPickerClosed, | 229 base::Bind(&ArcNavigationThrottle::OnIntentPickerClosed, |
232 weak_ptr_factory_.GetWeakPtr(), base::Passed(&handlers))); | 230 weak_ptr_factory_.GetWeakPtr(), base::Passed(&handlers))); |
233 } | 231 } |
234 | 232 |
235 void ArcNavigationThrottle::OnIntentPickerClosed( | 233 void ArcNavigationThrottle::OnIntentPickerClosed( |
236 mojo::Array<mojom::IntentHandlerInfoPtr> handlers, | 234 mojo::Array<mojom::IntentHandlerInfoPtr> handlers, |
237 std::string selected_app_package, | 235 size_t selected_app_index, |
238 CloseReason close_reason) { | 236 CloseReason close_reason) { |
239 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 237 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
240 const GURL& url = navigation_handle()->GetURL(); | 238 const GURL& url = navigation_handle()->GetURL(); |
241 content::NavigationHandle* handle = navigation_handle(); | 239 content::NavigationHandle* handle = navigation_handle(); |
| 240 |
242 previous_user_action_ = close_reason; | 241 previous_user_action_ = close_reason; |
243 | 242 |
244 // Make sure that the instance at least supports HandleUrl. | 243 // Make sure that the instance at least supports HandleUrl. |
245 auto* instance = ArcIntentHelperBridge::GetIntentHelperInstance( | 244 auto* instance = ArcIntentHelperBridge::GetIntentHelperInstance( |
246 "HandleUrl", kMinVersionForHandleUrl); | 245 "HandleUrl", kMinVersionForHandleUrl); |
247 size_t selected_app_index = handlers.size(); | 246 if (!instance || selected_app_index >= handlers.size()) |
248 if (!instance) { | |
249 close_reason = CloseReason::ERROR; | 247 close_reason = CloseReason::ERROR; |
250 } else if (close_reason == CloseReason::JUST_ONCE_PRESSED || | |
251 close_reason == CloseReason::ALWAYS_PRESSED || | |
252 close_reason == CloseReason::PREFERRED_ACTIVITY_FOUND) { | |
253 // Since we are selecting an app by its package name, we need to locate it | |
254 // on the |handlers| structure before sending the IPC to ARC. | |
255 for (size_t i = 0; i < handlers.size(); ++i) { | |
256 if (handlers[i]->package_name == selected_app_package) { | |
257 selected_app_index = i; | |
258 break; | |
259 } | |
260 } | |
261 | |
262 if (selected_app_index == handlers.size()) | |
263 close_reason = CloseReason::ERROR; | |
264 } | |
265 | 248 |
266 switch (close_reason) { | 249 switch (close_reason) { |
267 case CloseReason::ERROR: | 250 case CloseReason::ERROR: |
268 case CloseReason::DIALOG_DEACTIVATED: { | 251 case CloseReason::DIALOG_DEACTIVATED: { |
269 // If the user fails to select an option from the list, or the UI returned | 252 // If the user fails to select an option from the list, or the UI returned |
270 // an error or if |selected_app_index| is not a valid index, then resume | 253 // an error or if |selected_app_index| is not a valid index, then resume |
271 // the navigation in Chrome. | 254 // the navigation in Chrome. |
272 DVLOG(1) << "User didn't select a valid option, resuming navigation."; | 255 DVLOG(1) << "User didn't select a valid option, resuming navigation."; |
273 handle->Resume(); | 256 handle->Resume(); |
274 break; | 257 break; |
275 } | 258 } |
276 case CloseReason::ALWAYS_PRESSED: { | 259 case CloseReason::ALWAYS_PRESSED: { |
277 // Call AddPreferredPackage if it is supported. Reusing the same | 260 // Call AddPreferredPackage if it is supported. Reusing the same |
278 // |instance| is okay. | 261 // |instance| is okay. |
279 if (ArcIntentHelperBridge::GetIntentHelperInstance( | 262 if (ArcIntentHelperBridge::GetIntentHelperInstance( |
280 "AddPreferredPackage", kMinVersionForAddPreferredPackage)) { | 263 "AddPreferredPackage", kMinVersionForAddPreferredPackage)) { |
281 instance->AddPreferredPackage( | 264 instance->AddPreferredPackage( |
282 handlers[selected_app_index]->package_name); | 265 handlers[selected_app_index]->package_name); |
283 } | 266 } |
284 // fall through. | 267 // fall through. |
285 } | 268 } |
286 case CloseReason::JUST_ONCE_PRESSED: | 269 case CloseReason::JUST_ONCE_PRESSED: |
287 case CloseReason::PREFERRED_ACTIVITY_FOUND: { | 270 case CloseReason::PREFERRED_ACTIVITY_FOUND: { |
288 if (ArcIntentHelperBridge::IsIntentHelperPackage( | 271 if (ArcIntentHelperBridge::IsIntentHelperPackage( |
289 handlers[selected_app_index]->package_name)) { | 272 handlers[selected_app_index]->package_name)) { |
290 handle->Resume(); | 273 handle->Resume(); |
291 } else { | 274 } else { |
292 instance->HandleUrl(url.spec(), selected_app_package); | 275 instance->HandleUrl(url.spec(), |
| 276 handlers[selected_app_index]->package_name); |
293 handle->CancelDeferredNavigation( | 277 handle->CancelDeferredNavigation( |
294 content::NavigationThrottle::CANCEL_AND_IGNORE); | 278 content::NavigationThrottle::CANCEL_AND_IGNORE); |
295 if (handle->GetWebContents()->GetController().IsInitialNavigation()) | 279 if (handle->GetWebContents()->GetController().IsInitialNavigation()) |
296 handle->GetWebContents()->Close(); | 280 handle->GetWebContents()->Close(); |
297 } | 281 } |
298 break; | 282 break; |
299 } | 283 } |
300 case CloseReason::INVALID: { | 284 case CloseReason::INVALID: { |
301 NOTREACHED(); | 285 NOTREACHED(); |
302 return; | 286 return; |
303 } | 287 } |
304 } | 288 } |
305 | 289 |
306 UMA_HISTOGRAM_ENUMERATION("Arc.IntentHandlerAction", | 290 UMA_HISTOGRAM_ENUMERATION("Arc.IntentHandlerAction", |
307 static_cast<int>(close_reason), | 291 static_cast<int>(close_reason), |
308 static_cast<int>(CloseReason::SIZE)); | 292 static_cast<int>(CloseReason::SIZE)); |
309 } | 293 } |
310 | 294 |
311 // static | 295 // static |
312 bool ArcNavigationThrottle::ShouldOverrideUrlLoadingForTesting( | 296 bool ArcNavigationThrottle::ShouldOverrideUrlLoadingForTesting( |
313 const GURL& previous_url, | 297 const GURL& previous_url, |
314 const GURL& current_url) { | 298 const GURL& current_url) { |
315 return ShouldOverrideUrlLoading(previous_url, current_url); | 299 return ShouldOverrideUrlLoading(previous_url, current_url); |
316 } | 300 } |
317 | 301 |
318 } // namespace arc | 302 } // namespace arc |
OLD | NEW |