| 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" |
| 11 #include "base/memory/ref_counted.h" | 11 #include "base/memory/ref_counted.h" |
| 12 #include "chrome/browser/chromeos/arc/intent_helper/arc_navigation_throttle.h" | 12 #include "chrome/browser/chromeos/arc/intent_helper/arc_navigation_throttle.h" |
| 13 #include "chrome/browser/chromeos/external_protocol_dialog.h" | 13 #include "chrome/browser/chromeos/external_protocol_dialog.h" |
| 14 #include "chrome/browser/tab_contents/tab_util.h" | 14 #include "chrome/browser/tab_contents/tab_util.h" |
| 15 #include "chrome/browser/ui/browser_dialogs.h" | 15 #include "chrome/browser/ui/browser_dialogs.h" |
| 16 #include "components/arc/arc_bridge_service.h" | 16 #include "components/arc/arc_bridge_service.h" |
| 17 #include "components/arc/arc_service_manager.h" | 17 #include "components/arc/arc_service_manager.h" |
| 18 #include "components/arc/intent_helper/activity_icon_loader.h" | |
| 19 #include "components/arc/intent_helper/arc_intent_helper_bridge.h" | 18 #include "components/arc/intent_helper/arc_intent_helper_bridge.h" |
| 20 #include "components/arc/intent_helper/page_transition_util.h" | 19 #include "components/arc/intent_helper/page_transition_util.h" |
| 21 #include "content/public/browser/browser_context.h" | 20 #include "content/public/browser/browser_context.h" |
| 22 #include "content/public/browser/browser_thread.h" | 21 #include "content/public/browser/browser_thread.h" |
| 23 #include "content/public/browser/page_navigator.h" | 22 #include "content/public/browser/page_navigator.h" |
| 24 #include "content/public/browser/web_contents.h" | 23 #include "content/public/browser/web_contents.h" |
| 25 #include "content/public/common/referrer.h" | 24 #include "content/public/common/referrer.h" |
| 26 #include "ui/base/page_transition_types.h" | 25 #include "ui/base/page_transition_types.h" |
| 27 #include "ui/base/window_open_disposition.h" | 26 #include "ui/base/window_open_disposition.h" |
| 28 #include "ui/gfx/image/image.h" | 27 #include "ui/gfx/image/image.h" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 41 | 40 |
| 42 // Shows the Chrome OS' original external protocol dialog as a fallback. | 41 // Shows the Chrome OS' original external protocol dialog as a fallback. |
| 43 void ShowFallbackExternalProtocolDialog(int render_process_host_id, | 42 void ShowFallbackExternalProtocolDialog(int render_process_host_id, |
| 44 int routing_id, | 43 int routing_id, |
| 45 const GURL& url) { | 44 const GURL& url) { |
| 46 WebContents* web_contents = | 45 WebContents* web_contents = |
| 47 tab_util::GetWebContentsByID(render_process_host_id, routing_id); | 46 tab_util::GetWebContentsByID(render_process_host_id, routing_id); |
| 48 new ExternalProtocolDialog(web_contents, url); | 47 new ExternalProtocolDialog(web_contents, url); |
| 49 } | 48 } |
| 50 | 49 |
| 51 scoped_refptr<ActivityIconLoader> GetIconLoader() { | |
| 52 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | |
| 53 ArcServiceManager* arc_service_manager = ArcServiceManager::Get(); | |
| 54 return arc_service_manager ? arc_service_manager->icon_loader() : nullptr; | |
| 55 } | |
| 56 | |
| 57 void CloseTabIfNeeded(int render_process_host_id, int routing_id) { | 50 void CloseTabIfNeeded(int render_process_host_id, int routing_id) { |
| 58 WebContents* web_contents = | 51 WebContents* web_contents = |
| 59 tab_util::GetWebContentsByID(render_process_host_id, routing_id); | 52 tab_util::GetWebContentsByID(render_process_host_id, routing_id); |
| 60 if (web_contents && web_contents->GetController().IsInitialNavigation()) | 53 if (web_contents && web_contents->GetController().IsInitialNavigation()) |
| 61 web_contents->Close(); | 54 web_contents->Close(); |
| 62 } | 55 } |
| 63 | 56 |
| 64 // Shows |url| in the current tab. | 57 // Shows |url| in the current tab. |
| 65 void OpenUrlInChrome(int render_process_host_id, | 58 void OpenUrlInChrome(int render_process_host_id, |
| 66 int routing_id, | 59 int routing_id, |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 325 close_reason); | 318 close_reason); |
| 326 ArcNavigationThrottle::RecordUma(close_reason, platform); | 319 ArcNavigationThrottle::RecordUma(close_reason, platform); |
| 327 } | 320 } |
| 328 | 321 |
| 329 // Called when ARC returned activity icons for the |handlers|. | 322 // Called when ARC returned activity icons for the |handlers|. |
| 330 void OnAppIconsReceived( | 323 void OnAppIconsReceived( |
| 331 int render_process_host_id, | 324 int render_process_host_id, |
| 332 int routing_id, | 325 int routing_id, |
| 333 const GURL& url, | 326 const GURL& url, |
| 334 std::vector<mojom::IntentHandlerInfoPtr> handlers, | 327 std::vector<mojom::IntentHandlerInfoPtr> handlers, |
| 335 std::unique_ptr<ActivityIconLoader::ActivityToIconsMap> icons) { | 328 std::unique_ptr<ArcIntentHelperBridge::ActivityToIconsMap> icons) { |
| 336 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 329 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 337 | 330 |
| 338 using AppInfo = ArcNavigationThrottle::AppInfo; | 331 using AppInfo = ArcNavigationThrottle::AppInfo; |
| 339 std::vector<AppInfo> app_info; | 332 std::vector<AppInfo> app_info; |
| 340 | 333 |
| 341 for (const auto& handler : handlers) { | 334 for (const auto& handler : handlers) { |
| 342 const ActivityIconLoader::ActivityName activity(handler->package_name, | 335 const ArcIntentHelperBridge::ActivityName activity(handler->package_name, |
| 343 handler->activity_name); | 336 handler->activity_name); |
| 344 const auto it = icons->find(activity); | 337 const auto it = icons->find(activity); |
| 345 app_info.emplace_back( | 338 app_info.emplace_back( |
| 346 AppInfo(it != icons->end() ? it->second.icon20 : gfx::Image(), | 339 AppInfo(it != icons->end() ? it->second.icon20 : gfx::Image(), |
| 347 handler->package_name, handler->name)); | 340 handler->package_name, handler->name)); |
| 348 } | 341 } |
| 349 | 342 |
| 350 auto show_bubble_cb = base::Bind(ShowIntentPickerBubble()); | 343 auto show_bubble_cb = base::Bind(ShowIntentPickerBubble()); |
| 351 WebContents* web_contents = | 344 WebContents* web_contents = |
| 352 tab_util::GetWebContentsByID(render_process_host_id, routing_id); | 345 tab_util::GetWebContentsByID(render_process_host_id, routing_id); |
| 353 show_bubble_cb.Run(web_contents, app_info, | 346 show_bubble_cb.Run(web_contents, app_info, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 365 | 358 |
| 366 auto* arc_service_manager = ArcServiceManager::Get(); | 359 auto* arc_service_manager = ArcServiceManager::Get(); |
| 367 if (!arc_service_manager) { | 360 if (!arc_service_manager) { |
| 368 // ARC is not running anymore. Show the Chrome OS dialog. | 361 // ARC is not running anymore. Show the Chrome OS dialog. |
| 369 ShowFallbackExternalProtocolDialog(render_process_host_id, routing_id, url); | 362 ShowFallbackExternalProtocolDialog(render_process_host_id, routing_id, url); |
| 370 return; | 363 return; |
| 371 } | 364 } |
| 372 | 365 |
| 373 auto* instance = ARC_GET_INSTANCE_FOR_METHOD( | 366 auto* instance = ARC_GET_INSTANCE_FOR_METHOD( |
| 374 arc_service_manager->arc_bridge_service()->intent_helper(), HandleUrl); | 367 arc_service_manager->arc_bridge_service()->intent_helper(), HandleUrl); |
| 375 scoped_refptr<ActivityIconLoader> icon_loader = GetIconLoader(); | 368 auto* intent_helper_bridge = |
| 376 | 369 ArcServiceManager::GetGlobalService<ArcIntentHelperBridge>(); |
| 377 if (!instance || !icon_loader) { | 370 if (!instance || !intent_helper_bridge) { |
| 378 // ARC is not running anymore. Show the Chrome OS dialog. | 371 // ARC is not running anymore. Show the Chrome OS dialog. |
| 379 ShowFallbackExternalProtocolDialog(render_process_host_id, routing_id, url); | 372 ShowFallbackExternalProtocolDialog(render_process_host_id, routing_id, url); |
| 380 return; | 373 return; |
| 381 } | 374 } |
| 382 | 375 |
| 383 // Check if the |url| should be handled right away without showing the UI. | 376 // Check if the |url| should be handled right away without showing the UI. |
| 384 GetActionResult result; | 377 GetActionResult result; |
| 385 if (HandleUrl(render_process_host_id, routing_id, url, always_ask_user, | 378 if (HandleUrl(render_process_host_id, routing_id, url, always_ask_user, |
| 386 handlers, handlers.size(), &result)) { | 379 handlers, handlers.size(), &result)) { |
| 387 if (result == GetActionResult::HANDLE_URL_IN_ARC) { | 380 if (result == GetActionResult::HANDLE_URL_IN_ARC) { |
| 388 ArcNavigationThrottle::RecordUma( | 381 ArcNavigationThrottle::RecordUma( |
| 389 ArcNavigationThrottle::CloseReason::PREFERRED_ACTIVITY_FOUND, | 382 ArcNavigationThrottle::CloseReason::PREFERRED_ACTIVITY_FOUND, |
| 390 ArcNavigationThrottle::Platform::ARC); | 383 ArcNavigationThrottle::Platform::ARC); |
| 391 } | 384 } |
| 392 return; // the |url| has been handled. | 385 return; // the |url| has been handled. |
| 393 } | 386 } |
| 394 | 387 |
| 395 // Otherwise, retrieve icons of the activities. First, swap |handler| elements | 388 // Otherwise, retrieve icons of the activities. First, swap |handler| elements |
| 396 // to ensure Chrome is visible in the UI by default. Since this function is | 389 // to ensure Chrome is visible in the UI by default. Since this function is |
| 397 // for handling external protocols, Chrome is rarely in the list, but if the | 390 // for handling external protocols, Chrome is rarely in the list, but if the |
| 398 // |url| is intent: with fallback or geo:, for example, it may be. | 391 // |url| is intent: with fallback or geo:, for example, it may be. |
| 399 std::pair<size_t, size_t> indices; | 392 std::pair<size_t, size_t> indices; |
| 400 if (ArcNavigationThrottle::IsSwapElementsNeeded(handlers, &indices)) | 393 if (ArcNavigationThrottle::IsSwapElementsNeeded(handlers, &indices)) |
| 401 std::swap(handlers[indices.first], handlers[indices.second]); | 394 std::swap(handlers[indices.first], handlers[indices.second]); |
| 402 | 395 |
| 403 // Then request the icons. | 396 // Then request the icons. |
| 404 std::vector<ActivityIconLoader::ActivityName> activities; | 397 std::vector<ArcIntentHelperBridge::ActivityName> activities; |
| 405 for (const auto& handler : handlers) { | 398 for (const auto& handler : handlers) { |
| 406 activities.emplace_back(handler->package_name, handler->activity_name); | 399 activities.emplace_back(handler->package_name, handler->activity_name); |
| 407 } | 400 } |
| 408 icon_loader->GetActivityIcons( | 401 intent_helper_bridge->GetActivityIcons( |
| 409 activities, base::Bind(OnAppIconsReceived, render_process_host_id, | 402 activities, base::Bind(OnAppIconsReceived, render_process_host_id, |
| 410 routing_id, url, base::Passed(&handlers))); | 403 routing_id, url, base::Passed(&handlers))); |
| 411 } | 404 } |
| 412 | 405 |
| 413 // Returns true if the |url| is safe to be forwarded to ARC without showing the | 406 // Returns true if the |url| is safe to be forwarded to ARC without showing the |
| 414 // disambig dialog when there is a preferred app on ARC for the |url|. Note that | 407 // disambig dialog when there is a preferred app on ARC for the |url|. Note that |
| 415 // this function almost always returns true (i.e. "safe") except for very rare | 408 // this function almost always returns true (i.e. "safe") except for very rare |
| 416 // situations mentioned below. | 409 // situations mentioned below. |
| 417 // TODO(yusukes|djacobo): Find a better way to detect a request loop and remove | 410 // TODO(yusukes|djacobo): Find a better way to detect a request loop and remove |
| 418 // these heuristics. | 411 // these heuristics. |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 514 bool IsSafeToRedirectToArcWithoutUserConfirmationForTesting( | 507 bool IsSafeToRedirectToArcWithoutUserConfirmationForTesting( |
| 515 const GURL& url, | 508 const GURL& url, |
| 516 ui::PageTransition page_transition, | 509 ui::PageTransition page_transition, |
| 517 const GURL& last_url, | 510 const GURL& last_url, |
| 518 ui::PageTransition last_page_transition) { | 511 ui::PageTransition last_page_transition) { |
| 519 return IsSafeToRedirectToArcWithoutUserConfirmation( | 512 return IsSafeToRedirectToArcWithoutUserConfirmation( |
| 520 url, page_transition, last_url, last_page_transition); | 513 url, page_transition, last_url, last_page_transition); |
| 521 } | 514 } |
| 522 | 515 |
| 523 } // namespace arc | 516 } // namespace arc |
| OLD | NEW |