Chromium Code Reviews| 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" |
| 11 #include "base/memory/ref_counted.h" | 11 #include "base/memory/ref_counted.h" |
| 12 #include "base/metrics/histogram_macros.h" | 12 #include "base/metrics/histogram_macros.h" |
| 13 #include "components/arc/arc_bridge_service.h" | 13 #include "components/arc/arc_bridge_service.h" |
| 14 #include "components/arc/arc_service_manager.h" | 14 #include "components/arc/arc_service_manager.h" |
| 15 #include "components/arc/intent_helper/arc_intent_helper_bridge.h" | 15 #include "components/arc/intent_helper/arc_intent_helper_bridge.h" |
| 16 #include "components/arc/intent_helper/local_activity_resolver.h" | |
| 16 #include "content/public/browser/browser_thread.h" | 17 #include "content/public/browser/browser_thread.h" |
| 17 #include "content/public/browser/navigation_handle.h" | 18 #include "content/public/browser/navigation_handle.h" |
| 18 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" | 19 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" |
| 19 #include "ui/base/page_transition_types.h" | 20 #include "ui/base/page_transition_types.h" |
| 20 | 21 |
| 21 namespace arc { | 22 namespace arc { |
| 22 | 23 |
| 23 namespace { | 24 namespace { |
| 24 | 25 |
| 25 constexpr int kMinInstanceVersion = 7; | 26 constexpr int kMinInstanceVersion = 7; |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 50 return intent_helper_instance; | 51 return intent_helper_instance; |
| 51 } | 52 } |
| 52 | 53 |
| 53 } // namespace | 54 } // namespace |
| 54 | 55 |
| 55 ArcNavigationThrottle::ArcNavigationThrottle( | 56 ArcNavigationThrottle::ArcNavigationThrottle( |
| 56 content::NavigationHandle* navigation_handle, | 57 content::NavigationHandle* navigation_handle, |
| 57 const ShowDisambigDialogCallback& show_disambig_dialog_cb) | 58 const ShowDisambigDialogCallback& show_disambig_dialog_cb) |
| 58 : content::NavigationThrottle(navigation_handle), | 59 : content::NavigationThrottle(navigation_handle), |
| 59 show_disambig_dialog_callback_(show_disambig_dialog_cb), | 60 show_disambig_dialog_callback_(show_disambig_dialog_cb), |
| 60 weak_ptr_factory_(this) {} | 61 weak_ptr_factory_(this), |
| 62 previous_user_action_(CloseReason::SIZE) {} | |
|
djacobo_
2016/07/28 20:08:01
move before weak_ptr_factory pls.
| |
| 61 | 63 |
| 62 ArcNavigationThrottle::~ArcNavigationThrottle() = default; | 64 ArcNavigationThrottle::~ArcNavigationThrottle() = default; |
| 63 | 65 |
| 64 content::NavigationThrottle::ThrottleCheckResult | 66 content::NavigationThrottle::ThrottleCheckResult |
| 65 ArcNavigationThrottle::WillStartRequest() { | 67 ArcNavigationThrottle::WillStartRequest() { |
| 68 return HandleRequest(); | |
| 69 } | |
| 70 | |
| 71 content::NavigationThrottle::ThrottleCheckResult | |
| 72 ArcNavigationThrottle::WillRedirectRequest() { | |
| 73 switch (previous_user_action_) { | |
| 74 case CloseReason::ERROR: | |
| 75 case CloseReason::DIALOG_DEACTIVATED: | |
| 76 // User dismissed the dialog, or some error occurred before. Don't | |
| 77 // repeatedly pop up the dialog. | |
| 78 return content::NavigationThrottle::PROCEED; | |
| 79 | |
| 80 case CloseReason::ALWAYS_PRESSED: | |
| 81 case CloseReason::JUST_ONCE_PRESSED: | |
| 82 case CloseReason::PREFERRED_ACTIVITY_FOUND: | |
| 83 // Should never get here - if the user selected one of these previously, | |
| 84 // chrome should not see a redirect. | |
| 85 NOTREACHED(); | |
| 86 | |
| 87 case CloseReason::SIZE: | |
| 88 // No disambig has previously been popped up for this - continue. | |
| 89 break; | |
| 90 } | |
| 91 return HandleRequest(); | |
| 92 } | |
| 93 | |
| 94 content::NavigationThrottle::ThrottleCheckResult | |
| 95 ArcNavigationThrottle::HandleRequest() { | |
| 66 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 96 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 67 | 97 |
| 98 const GURL& url = navigation_handle()->GetURL(); | |
| 99 // Mask out any redirect qualifiers - this method handles navigation from | |
| 100 // redirect and non-redirect navigations equivalently. | |
| 68 const ui::PageTransition transition = | 101 const ui::PageTransition transition = |
| 69 navigation_handle()->GetPageTransition(); | 102 ui::PageTransitionFromInt(navigation_handle()->GetPageTransition() & |
| 103 ~ui::PAGE_TRANSITION_IS_REDIRECT_MASK); | |
| 70 | 104 |
| 71 if (!ui::PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_LINK)) { | 105 if (!ui::PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_LINK)) { |
| 72 // If this navigation event wasn't spawned by the user clicking on a link. | 106 // If this navigation event wasn't spawned by the user clicking on a link. |
| 73 return content::NavigationThrottle::PROCEED; | 107 return content::NavigationThrottle::PROCEED; |
| 74 } | 108 } |
| 75 | 109 |
| 76 if (ui::PageTransitionGetQualifier(transition) != 0) { | 110 if (ui::PageTransitionGetQualifier(transition) != 0) { |
| 77 // Qualifiers indicate that this navigation was the result of a click on a | 111 // Qualifiers indicate that this navigation was the result of a click on a |
| 78 // forward/back button, or a redirect, or typing in the URL bar, etc. Don't | 112 // forward/back button, or typing in the URL bar, etc. Don't pass any of |
| 79 // pass any of those types of navigations to the intent helper (see | 113 // those types of navigations to the intent helper (see crbug.com/630072). |
| 80 // crbug.com/630072). | 114 // Note that redirects, which we do pass on, are masked out above. |
| 81 return content::NavigationThrottle::PROCEED; | 115 return content::NavigationThrottle::PROCEED; |
| 82 } | 116 } |
| 83 | 117 |
| 84 if (!ShouldOverrideUrlLoading(navigation_handle())) | 118 if (!ShouldOverrideUrlLoading(navigation_handle())) |
| 85 return content::NavigationThrottle::PROCEED; | 119 return content::NavigationThrottle::PROCEED; |
| 86 | 120 |
| 87 const GURL& url = navigation_handle()->GetURL(); | 121 arc::ArcServiceManager* arc_service_manager = arc::ArcServiceManager::Get(); |
| 122 DCHECK(arc_service_manager); | |
| 123 scoped_refptr<arc::LocalActivityResolver> local_resolver = | |
| 124 arc_service_manager->activity_resolver(); | |
| 125 if (local_resolver->ShouldChromeHandleUrl(url)) { | |
| 126 // If this navigation event doesn't hit an android app. | |
| 127 return content::NavigationThrottle::PROCEED; | |
| 128 } | |
| 129 | |
| 88 mojom::IntentHelperInstance* bridge_instance = GetIntentHelper(); | 130 mojom::IntentHelperInstance* bridge_instance = GetIntentHelper(); |
| 89 if (!bridge_instance) | 131 if (!bridge_instance) |
| 90 return content::NavigationThrottle::PROCEED; | 132 return content::NavigationThrottle::PROCEED; |
| 91 bridge_instance->RequestUrlHandlerList( | 133 bridge_instance->RequestUrlHandlerList( |
| 92 url.spec(), base::Bind(&ArcNavigationThrottle::OnAppCandidatesReceived, | 134 url.spec(), base::Bind(&ArcNavigationThrottle::OnAppCandidatesReceived, |
| 93 weak_ptr_factory_.GetWeakPtr())); | 135 weak_ptr_factory_.GetWeakPtr())); |
| 94 return content::NavigationThrottle::DEFER; | 136 return content::NavigationThrottle::DEFER; |
| 95 } | 137 } |
| 96 | 138 |
| 97 content::NavigationThrottle::ThrottleCheckResult | |
| 98 ArcNavigationThrottle::WillRedirectRequest() { | |
| 99 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | |
| 100 return content::NavigationThrottle::PROCEED; | |
| 101 } | |
| 102 | |
| 103 // We received the array of app candidates to handle this URL (even the Chrome | 139 // We received the array of app candidates to handle this URL (even the Chrome |
| 104 // app is included). | 140 // app is included). |
| 105 void ArcNavigationThrottle::OnAppCandidatesReceived( | 141 void ArcNavigationThrottle::OnAppCandidatesReceived( |
| 106 mojo::Array<mojom::UrlHandlerInfoPtr> handlers) { | 142 mojo::Array<mojom::UrlHandlerInfoPtr> handlers) { |
| 107 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 143 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 108 if (handlers.empty() || | 144 if (handlers.empty() || |
| 109 (handlers.size() == 1 && ArcIntentHelperBridge::IsIntentHelperPackage( | 145 (handlers.size() == 1 && ArcIntentHelperBridge::IsIntentHelperPackage( |
| 110 handlers[0]->package_name))) { | 146 handlers[0]->package_name))) { |
| 111 // This scenario shouldn't be accesed as ArcNavigationThrottle is created | 147 // This scenario shouldn't be accesed as ArcNavigationThrottle is created |
| 112 // iff there are ARC apps which can actually handle the given URL. | 148 // iff there are ARC apps which can actually handle the given URL. |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 187 } | 223 } |
| 188 | 224 |
| 189 void ArcNavigationThrottle::OnDisambigDialogClosed( | 225 void ArcNavigationThrottle::OnDisambigDialogClosed( |
| 190 mojo::Array<mojom::UrlHandlerInfoPtr> handlers, | 226 mojo::Array<mojom::UrlHandlerInfoPtr> handlers, |
| 191 size_t selected_app_index, | 227 size_t selected_app_index, |
| 192 CloseReason close_reason) { | 228 CloseReason close_reason) { |
| 193 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 229 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 194 const GURL& url = navigation_handle()->GetURL(); | 230 const GURL& url = navigation_handle()->GetURL(); |
| 195 content::NavigationHandle* handle = navigation_handle(); | 231 content::NavigationHandle* handle = navigation_handle(); |
| 196 | 232 |
| 233 previous_user_action_ = close_reason; | |
| 234 | |
| 197 mojom::IntentHelperInstance* bridge = GetIntentHelper(); | 235 mojom::IntentHelperInstance* bridge = GetIntentHelper(); |
| 198 if (!bridge || selected_app_index >= handlers.size()) { | 236 if (!bridge || selected_app_index >= handlers.size()) { |
| 199 close_reason = CloseReason::ERROR; | 237 close_reason = CloseReason::ERROR; |
| 200 } | 238 } |
| 201 | 239 |
| 202 switch (close_reason) { | 240 switch (close_reason) { |
| 203 case CloseReason::ERROR: | 241 case CloseReason::ERROR: |
| 204 case CloseReason::DIALOG_DEACTIVATED: { | 242 case CloseReason::DIALOG_DEACTIVATED: { |
| 205 // If the user fails to select an option from the list, or the UI returned | 243 // If the user fails to select an option from the list, or the UI returned |
| 206 // an error or if |selected_app_index| is not a valid index, then resume | 244 // an error or if |selected_app_index| is not a valid index, then resume |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 240 bool ArcNavigationThrottle::ShouldOverrideUrlLoading( | 278 bool ArcNavigationThrottle::ShouldOverrideUrlLoading( |
| 241 content::NavigationHandle* navigation_handle) { | 279 content::NavigationHandle* navigation_handle) { |
| 242 GURL previous_url = navigation_handle->GetReferrer().url; | 280 GURL previous_url = navigation_handle->GetReferrer().url; |
| 243 GURL current_url = navigation_handle->GetURL(); | 281 GURL current_url = navigation_handle->GetURL(); |
| 244 return !net::registry_controlled_domains::SameDomainOrHost( | 282 return !net::registry_controlled_domains::SameDomainOrHost( |
| 245 current_url, previous_url, | 283 current_url, previous_url, |
| 246 net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); | 284 net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); |
| 247 } | 285 } |
| 248 | 286 |
| 249 } // namespace arc | 287 } // namespace arc |
| OLD | NEW |