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/intent_helper/arc_external_protocol_dialog
.h" | 5 #include "chrome/browser/chromeos/arc/intent_helper/arc_external_protocol_dialog
.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
(...skipping 16 matching lines...) Expand all Loading... |
27 #include "ui/base/window_open_disposition.h" | 27 #include "ui/base/window_open_disposition.h" |
28 #include "ui/gfx/image/image.h" | 28 #include "ui/gfx/image/image.h" |
29 #include "url/gurl.h" | 29 #include "url/gurl.h" |
30 | 30 |
31 using content::WebContents; | 31 using content::WebContents; |
32 | 32 |
33 namespace arc { | 33 namespace arc { |
34 | 34 |
35 namespace { | 35 namespace { |
36 | 36 |
37 constexpr uint32_t kMinVersionForHandleUrl = 2; | |
38 constexpr uint32_t kMinVersionForRequestUrlHandlerList = 2; | |
39 constexpr uint32_t kMinVersionForAddPreferredPackage = 7; | |
40 | |
41 // TODO(yusukes|djacobo): Find a better way to detect a request loop and remove | 37 // TODO(yusukes|djacobo): Find a better way to detect a request loop and remove |
42 // the global variables. | 38 // the global variables. |
43 base::LazyInstance<GURL> g_last_url = LAZY_INSTANCE_INITIALIZER; | 39 base::LazyInstance<GURL> g_last_url = LAZY_INSTANCE_INITIALIZER; |
44 ui::PageTransition g_last_page_transition; | 40 ui::PageTransition g_last_page_transition; |
45 | 41 |
46 // Shows the Chrome OS' original external protocol dialog as a fallback. | 42 // Shows the Chrome OS' original external protocol dialog as a fallback. |
47 void ShowFallbackExternalProtocolDialog(int render_process_host_id, | 43 void ShowFallbackExternalProtocolDialog(int render_process_host_id, |
48 int routing_id, | 44 int routing_id, |
49 const GURL& url) { | 45 const GURL& url) { |
50 WebContents* web_contents = | 46 WebContents* web_contents = |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 // TODO(yusukes): Send a non-empty referrer. | 79 // TODO(yusukes): Send a non-empty referrer. |
84 url, content::Referrer(), WindowOpenDisposition::CURRENT_TAB, | 80 url, content::Referrer(), WindowOpenDisposition::CURRENT_TAB, |
85 page_transition_type, kIsRendererInitiated); | 81 page_transition_type, kIsRendererInitiated); |
86 web_contents->OpenURL(params); | 82 web_contents->OpenURL(params); |
87 } | 83 } |
88 | 84 |
89 // Sends |url| to ARC. | 85 // Sends |url| to ARC. |
90 void HandleUrlInArc(int render_process_host_id, | 86 void HandleUrlInArc(int render_process_host_id, |
91 int routing_id, | 87 int routing_id, |
92 const std::pair<GURL, std::string>& url_and_package) { | 88 const std::pair<GURL, std::string>& url_and_package) { |
93 auto* instance = ArcIntentHelperBridge::GetIntentHelperInstance( | 89 auto* arc_service_manager = ArcServiceManager::Get(); |
94 "HandleUrl", kMinVersionForHandleUrl); | 90 if (!arc_service_manager) |
| 91 return; |
| 92 auto* instance = ARC_GET_INSTANCE_FOR_METHOD( |
| 93 arc_service_manager->arc_bridge_service()->intent_helper(), HandleUrl); |
95 if (!instance) | 94 if (!instance) |
96 return; | 95 return; |
97 | 96 |
98 instance->HandleUrl(url_and_package.first.spec(), url_and_package.second); | 97 instance->HandleUrl(url_and_package.first.spec(), url_and_package.second); |
99 CloseTabIfNeeded(render_process_host_id, routing_id); | 98 CloseTabIfNeeded(render_process_host_id, routing_id); |
100 } | 99 } |
101 | 100 |
102 // A helper function called by GetAction(). | 101 // A helper function called by GetAction(). |
103 GetActionResult GetActionInternal( | 102 GetActionResult GetActionInternal( |
104 const GURL& original_url, | 103 const GURL& original_url, |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 const GURL& url, | 252 const GURL& url, |
254 std::vector<mojom::IntentHandlerInfoPtr> handlers, | 253 std::vector<mojom::IntentHandlerInfoPtr> handlers, |
255 const std::string& selected_app_package, | 254 const std::string& selected_app_package, |
256 ArcNavigationThrottle::CloseReason close_reason) { | 255 ArcNavigationThrottle::CloseReason close_reason) { |
257 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 256 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
258 | 257 |
259 // If the user selected an app to continue the navigation, confirm that the | 258 // If the user selected an app to continue the navigation, confirm that the |
260 // |package_name| matches a valid option and return the index. | 259 // |package_name| matches a valid option and return the index. |
261 const size_t selected_app_index = | 260 const size_t selected_app_index = |
262 ArcNavigationThrottle::GetAppIndex(handlers, selected_app_package); | 261 ArcNavigationThrottle::GetAppIndex(handlers, selected_app_package); |
| 262 |
263 // Make sure that the instance at least supports HandleUrl. | 263 // Make sure that the instance at least supports HandleUrl. |
264 auto* instance = ArcIntentHelperBridge::GetIntentHelperInstance( | 264 auto* arc_service_manager = ArcServiceManager::Get(); |
265 "HandleUrl", kMinVersionForHandleUrl); | 265 mojom::IntentHelperInstance* instance = nullptr; |
| 266 if (arc_service_manager) { |
| 267 instance = ARC_GET_INSTANCE_FOR_METHOD( |
| 268 arc_service_manager->arc_bridge_service()->intent_helper(), HandleUrl); |
| 269 } |
| 270 |
266 if (!instance) { | 271 if (!instance) { |
267 close_reason = ArcNavigationThrottle::CloseReason::ERROR; | 272 close_reason = ArcNavigationThrottle::CloseReason::ERROR; |
268 } else if (close_reason == | 273 } else if (close_reason == |
269 ArcNavigationThrottle::CloseReason::JUST_ONCE_PRESSED || | 274 ArcNavigationThrottle::CloseReason::JUST_ONCE_PRESSED || |
270 close_reason == | 275 close_reason == |
271 ArcNavigationThrottle::CloseReason::ALWAYS_PRESSED) { | 276 ArcNavigationThrottle::CloseReason::ALWAYS_PRESSED) { |
272 if (selected_app_index == handlers.size()) { | 277 if (selected_app_index == handlers.size()) { |
273 close_reason = ArcNavigationThrottle::CloseReason::ERROR; | 278 close_reason = ArcNavigationThrottle::CloseReason::ERROR; |
274 } else { | 279 } else { |
275 // The user has made a selection. Clear g_last_* variables. | 280 // The user has made a selection. Clear g_last_* variables. |
276 g_last_url.Get() = GURL(); | 281 g_last_url.Get() = GURL(); |
277 g_last_page_transition = ui::PageTransition(); | 282 g_last_page_transition = ui::PageTransition(); |
278 } | 283 } |
279 } | 284 } |
280 | 285 |
281 switch (close_reason) { | 286 switch (close_reason) { |
282 case ArcNavigationThrottle::CloseReason::ALWAYS_PRESSED: { | 287 case ArcNavigationThrottle::CloseReason::ALWAYS_PRESSED: { |
283 if (ArcIntentHelperBridge::GetIntentHelperInstance( | 288 DCHECK(arc_service_manager); |
284 "AddPreferredPackage", kMinVersionForAddPreferredPackage)) { | 289 if (ARC_GET_INSTANCE_FOR_METHOD( |
| 290 arc_service_manager->arc_bridge_service()->intent_helper(), |
| 291 AddPreferredPackage)) { |
285 instance->AddPreferredPackage( | 292 instance->AddPreferredPackage( |
286 handlers[selected_app_index]->package_name); | 293 handlers[selected_app_index]->package_name); |
287 } | 294 } |
288 // fall through. | 295 // fall through. |
289 } | 296 } |
290 case ArcNavigationThrottle::CloseReason::JUST_ONCE_PRESSED: { | 297 case ArcNavigationThrottle::CloseReason::JUST_ONCE_PRESSED: { |
291 // Launch the selected app. | 298 // Launch the selected app. |
292 HandleUrl(render_process_host_id, routing_id, url, false, handlers, | 299 HandleUrl(render_process_host_id, routing_id, url, false, handlers, |
293 selected_app_index, nullptr); | 300 selected_app_index, nullptr); |
294 break; | 301 break; |
(...skipping 26 matching lines...) Expand all Loading... |
321 | 328 |
322 // Called when ARC returned activity icons for the |handlers|. | 329 // Called when ARC returned activity icons for the |handlers|. |
323 void OnAppIconsReceived( | 330 void OnAppIconsReceived( |
324 int render_process_host_id, | 331 int render_process_host_id, |
325 int routing_id, | 332 int routing_id, |
326 const GURL& url, | 333 const GURL& url, |
327 std::vector<mojom::IntentHandlerInfoPtr> handlers, | 334 std::vector<mojom::IntentHandlerInfoPtr> handlers, |
328 std::unique_ptr<ActivityIconLoader::ActivityToIconsMap> icons) { | 335 std::unique_ptr<ActivityIconLoader::ActivityToIconsMap> icons) { |
329 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 336 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
330 | 337 |
331 using AppInfo = arc::ArcNavigationThrottle::AppInfo; | 338 using AppInfo = ArcNavigationThrottle::AppInfo; |
332 std::vector<AppInfo> app_info; | 339 std::vector<AppInfo> app_info; |
333 | 340 |
334 for (const auto& handler : handlers) { | 341 for (const auto& handler : handlers) { |
335 const ActivityIconLoader::ActivityName activity(handler->package_name, | 342 const ActivityIconLoader::ActivityName activity(handler->package_name, |
336 handler->activity_name); | 343 handler->activity_name); |
337 const auto it = icons->find(activity); | 344 const auto it = icons->find(activity); |
338 app_info.emplace_back( | 345 app_info.emplace_back( |
339 AppInfo(it != icons->end() ? it->second.icon20 : gfx::Image(), | 346 AppInfo(it != icons->end() ? it->second.icon20 : gfx::Image(), |
340 handler->package_name, handler->name)); | 347 handler->package_name, handler->name)); |
341 } | 348 } |
342 | 349 |
343 auto show_bubble_cb = base::Bind(ShowIntentPickerBubble()); | 350 auto show_bubble_cb = base::Bind(ShowIntentPickerBubble()); |
344 WebContents* web_contents = | 351 WebContents* web_contents = |
345 tab_util::GetWebContentsByID(render_process_host_id, routing_id); | 352 tab_util::GetWebContentsByID(render_process_host_id, routing_id); |
346 show_bubble_cb.Run(web_contents, app_info, | 353 show_bubble_cb.Run(web_contents, app_info, |
347 base::Bind(OnIntentPickerClosed, render_process_host_id, | 354 base::Bind(OnIntentPickerClosed, render_process_host_id, |
348 routing_id, url, base::Passed(&handlers))); | 355 routing_id, url, base::Passed(&handlers))); |
349 } | 356 } |
350 | 357 |
351 // Called when ARC returned a handler list for the |url|. | 358 // Called when ARC returned a handler list for the |url|. |
352 void OnUrlHandlerList(int render_process_host_id, | 359 void OnUrlHandlerList(int render_process_host_id, |
353 int routing_id, | 360 int routing_id, |
354 const GURL& url, | 361 const GURL& url, |
355 bool always_ask_user, | 362 bool always_ask_user, |
356 std::vector<mojom::IntentHandlerInfoPtr> handlers) { | 363 std::vector<mojom::IntentHandlerInfoPtr> handlers) { |
357 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 364 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
358 | 365 |
359 auto* instance = ArcIntentHelperBridge::GetIntentHelperInstance( | 366 auto* arc_service_manager = ArcServiceManager::Get(); |
360 "HandleUrl", kMinVersionForHandleUrl); | 367 if (!arc_service_manager) { |
| 368 // ARC is not running anymore. Show the Chrome OS dialog. |
| 369 ShowFallbackExternalProtocolDialog(render_process_host_id, routing_id, url); |
| 370 return; |
| 371 } |
| 372 |
| 373 auto* instance = ARC_GET_INSTANCE_FOR_METHOD( |
| 374 arc_service_manager->arc_bridge_service()->intent_helper(), HandleUrl); |
361 scoped_refptr<ActivityIconLoader> icon_loader = GetIconLoader(); | 375 scoped_refptr<ActivityIconLoader> icon_loader = GetIconLoader(); |
362 | 376 |
363 if (!instance || !icon_loader) { | 377 if (!instance || !icon_loader) { |
364 // ARC is not running anymore. Show the Chrome OS dialog. | 378 // ARC is not running anymore. Show the Chrome OS dialog. |
365 ShowFallbackExternalProtocolDialog(render_process_host_id, routing_id, url); | 379 ShowFallbackExternalProtocolDialog(render_process_host_id, routing_id, url); |
366 return; | 380 return; |
367 } | 381 } |
368 | 382 |
369 // Check if the |url| should be handled right away without showing the UI. | 383 // Check if the |url| should be handled right away without showing the UI. |
370 GetActionResult result; | 384 GetActionResult result; |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 MaskOutPageTransition(page_transition, ui::PAGE_TRANSITION_FROM_API); | 464 MaskOutPageTransition(page_transition, ui::PAGE_TRANSITION_FROM_API); |
451 | 465 |
452 if (ShouldIgnoreNavigation(masked_page_transition, | 466 if (ShouldIgnoreNavigation(masked_page_transition, |
453 true /* allow_form_submit */, | 467 true /* allow_form_submit */, |
454 true /* allow_client_redirect */)) { | 468 true /* allow_client_redirect */)) { |
455 LOG(WARNING) << "RunArcExternalProtocolDialog: ignoring " << url | 469 LOG(WARNING) << "RunArcExternalProtocolDialog: ignoring " << url |
456 << " with PageTransition=" << masked_page_transition; | 470 << " with PageTransition=" << masked_page_transition; |
457 return false; | 471 return false; |
458 } | 472 } |
459 | 473 |
460 auto* instance = ArcIntentHelperBridge::GetIntentHelperInstance( | 474 auto* arc_service_manager = ArcServiceManager::Get(); |
461 "RequestUrlHandlerList", kMinVersionForRequestUrlHandlerList); | 475 if (!arc_service_manager) |
| 476 return false; // ARC is either not supported or not yet ready. |
| 477 |
| 478 auto* instance = ARC_GET_INSTANCE_FOR_METHOD( |
| 479 arc_service_manager->arc_bridge_service()->intent_helper(), |
| 480 RequestUrlHandlerList); |
462 if (!instance) | 481 if (!instance) |
463 return false; // ARC is either not supported or not yet ready. | 482 return false; // the same. |
464 | 483 |
465 WebContents* web_contents = | 484 WebContents* web_contents = |
466 tab_util::GetWebContentsByID(render_process_host_id, routing_id); | 485 tab_util::GetWebContentsByID(render_process_host_id, routing_id); |
467 if (!web_contents || !web_contents->GetBrowserContext() || | 486 if (!web_contents || !web_contents->GetBrowserContext() || |
468 web_contents->GetBrowserContext()->IsOffTheRecord()) { | 487 web_contents->GetBrowserContext()->IsOffTheRecord()) { |
469 return false; | 488 return false; |
470 } | 489 } |
471 | 490 |
472 // Show ARC version of the dialog, which is IntentPickerBubbleView. To show | 491 // Show ARC version of the dialog, which is IntentPickerBubbleView. To show |
473 // the bubble view, we need to ask ARC for a handler list first. | 492 // the bubble view, we need to ask ARC for a handler list first. |
(...skipping 21 matching lines...) Expand all Loading... |
495 bool IsSafeToRedirectToArcWithoutUserConfirmationForTesting( | 514 bool IsSafeToRedirectToArcWithoutUserConfirmationForTesting( |
496 const GURL& url, | 515 const GURL& url, |
497 ui::PageTransition page_transition, | 516 ui::PageTransition page_transition, |
498 const GURL& last_url, | 517 const GURL& last_url, |
499 ui::PageTransition last_page_transition) { | 518 ui::PageTransition last_page_transition) { |
500 return IsSafeToRedirectToArcWithoutUserConfirmation( | 519 return IsSafeToRedirectToArcWithoutUserConfirmation( |
501 url, page_transition, last_url, last_page_transition); | 520 url, page_transition, last_url, last_page_transition); |
502 } | 521 } |
503 | 522 |
504 } // namespace arc | 523 } // namespace arc |
OLD | NEW |