| 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 "chrome/browser/chromeos/arc/page_transition_util.h" | 13 #include "chrome/browser/chromeos/arc/page_transition_util.h" |
| 14 #include "components/arc/arc_bridge_service.h" | 14 #include "components/arc/arc_bridge_service.h" |
| 15 #include "components/arc/arc_service_manager.h" | 15 #include "components/arc/arc_service_manager.h" |
| 16 #include "components/arc/intent_helper/arc_intent_helper_bridge.h" | 16 #include "components/arc/intent_helper/arc_intent_helper_bridge.h" |
| 17 #include "components/arc/intent_helper/local_activity_resolver.h" | 17 #include "components/arc/intent_helper/local_activity_resolver.h" |
| 18 #include "content/public/browser/browser_thread.h" | 18 #include "content/public/browser/browser_thread.h" |
| 19 #include "content/public/browser/navigation_controller.h" | 19 #include "content/public/browser/navigation_controller.h" |
| 20 #include "content/public/browser/navigation_handle.h" | 20 #include "content/public/browser/navigation_handle.h" |
| 21 #include "content/public/browser/web_contents.h" | 21 #include "content/public/browser/web_contents.h" |
| 22 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" | 22 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" |
| 23 #include "ui/base/page_transition_types.h" | 23 #include "ui/base/page_transition_types.h" |
| 24 #include "url/gurl.h" | 24 #include "url/gurl.h" |
| 25 | 25 |
| 26 namespace arc { | 26 namespace arc { |
| 27 | 27 |
| 28 namespace { | 28 namespace { |
| 29 | 29 |
| 30 constexpr int kMinInstanceVersion = 7; | 30 constexpr uint32_t kMinVersionForHandleUrl = 2; |
| 31 constexpr uint32_t kMinVersionForRequestUrlHandlerList = 2; |
| 32 constexpr uint32_t kMinVersionForAddPreferredPackage = 7; |
| 31 | 33 |
| 32 scoped_refptr<ActivityIconLoader> GetIconLoader() { | 34 scoped_refptr<ActivityIconLoader> GetIconLoader() { |
| 33 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 35 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 34 ArcServiceManager* arc_service_manager = ArcServiceManager::Get(); | 36 ArcServiceManager* arc_service_manager = ArcServiceManager::Get(); |
| 35 return arc_service_manager ? arc_service_manager->icon_loader() : nullptr; | 37 return arc_service_manager ? arc_service_manager->icon_loader() : nullptr; |
| 36 } | 38 } |
| 37 | 39 |
| 38 // Compares the host name of the referrer and target URL to decide whether | 40 // Compares the host name of the referrer and target URL to decide whether |
| 39 // the navigation needs to be overriden. | 41 // the navigation needs to be overriden. |
| 40 bool ShouldOverrideUrlLoading(const GURL& previous_url, | 42 bool ShouldOverrideUrlLoading(const GURL& previous_url, |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 104 const GURL& url = navigation_handle()->GetURL(); | 106 const GURL& url = navigation_handle()->GetURL(); |
| 105 | 107 |
| 106 if (ShouldIgnoreNavigation(navigation_handle()->GetPageTransition())) | 108 if (ShouldIgnoreNavigation(navigation_handle()->GetPageTransition())) |
| 107 return content::NavigationThrottle::PROCEED; | 109 return content::NavigationThrottle::PROCEED; |
| 108 | 110 |
| 109 const GURL previous_url = navigation_handle()->GetReferrer().url; | 111 const GURL previous_url = navigation_handle()->GetReferrer().url; |
| 110 const GURL current_url = navigation_handle()->GetURL(); | 112 const GURL current_url = navigation_handle()->GetURL(); |
| 111 if (!ShouldOverrideUrlLoading(previous_url, current_url)) | 113 if (!ShouldOverrideUrlLoading(previous_url, current_url)) |
| 112 return content::NavigationThrottle::PROCEED; | 114 return content::NavigationThrottle::PROCEED; |
| 113 | 115 |
| 114 arc::ArcServiceManager* arc_service_manager = arc::ArcServiceManager::Get(); | 116 ArcServiceManager* arc_service_manager = ArcServiceManager::Get(); |
| 115 DCHECK(arc_service_manager); | 117 DCHECK(arc_service_manager); |
| 116 scoped_refptr<arc::LocalActivityResolver> local_resolver = | 118 scoped_refptr<LocalActivityResolver> local_resolver = |
| 117 arc_service_manager->activity_resolver(); | 119 arc_service_manager->activity_resolver(); |
| 118 if (local_resolver->ShouldChromeHandleUrl(url)) { | 120 if (local_resolver->ShouldChromeHandleUrl(url)) { |
| 119 // Allow navigation to proceed if there isn't an android app that handles | 121 // Allow navigation to proceed if there isn't an android app that handles |
| 120 // the given URL. | 122 // the given URL. |
| 121 return content::NavigationThrottle::PROCEED; | 123 return content::NavigationThrottle::PROCEED; |
| 122 } | 124 } |
| 123 | 125 |
| 124 mojom::IntentHelperInstance* bridge_instance = | 126 auto* instance = ArcIntentHelperBridge::GetIntentHelperInstance( |
| 125 arc::ArcIntentHelperBridge::GetIntentHelperInstance(kMinInstanceVersion); | 127 "RequestUrlHandlerList", kMinVersionForRequestUrlHandlerList); |
| 126 if (!bridge_instance) | 128 if (!instance) |
| 127 return content::NavigationThrottle::PROCEED; | 129 return content::NavigationThrottle::PROCEED; |
| 128 bridge_instance->RequestUrlHandlerList( | 130 instance->RequestUrlHandlerList( |
| 129 url.spec(), base::Bind(&ArcNavigationThrottle::OnAppCandidatesReceived, | 131 url.spec(), base::Bind(&ArcNavigationThrottle::OnAppCandidatesReceived, |
| 130 weak_ptr_factory_.GetWeakPtr())); | 132 weak_ptr_factory_.GetWeakPtr())); |
| 131 return content::NavigationThrottle::DEFER; | 133 return content::NavigationThrottle::DEFER; |
| 132 } | 134 } |
| 133 | 135 |
| 134 // We received the array of app candidates to handle this URL (even the Chrome | 136 // We received the array of app candidates to handle this URL (even the Chrome |
| 135 // app is included). | 137 // app is included). |
| 136 void ArcNavigationThrottle::OnAppCandidatesReceived( | 138 void ArcNavigationThrottle::OnAppCandidatesReceived( |
| 137 mojo::Array<mojom::UrlHandlerInfoPtr> handlers) { | 139 mojo::Array<mojom::UrlHandlerInfoPtr> handlers) { |
| 138 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 140 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 void ArcNavigationThrottle::OnIntentPickerClosed( | 222 void ArcNavigationThrottle::OnIntentPickerClosed( |
| 221 mojo::Array<mojom::UrlHandlerInfoPtr> handlers, | 223 mojo::Array<mojom::UrlHandlerInfoPtr> handlers, |
| 222 size_t selected_app_index, | 224 size_t selected_app_index, |
| 223 CloseReason close_reason) { | 225 CloseReason close_reason) { |
| 224 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 226 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 225 const GURL& url = navigation_handle()->GetURL(); | 227 const GURL& url = navigation_handle()->GetURL(); |
| 226 content::NavigationHandle* handle = navigation_handle(); | 228 content::NavigationHandle* handle = navigation_handle(); |
| 227 | 229 |
| 228 previous_user_action_ = close_reason; | 230 previous_user_action_ = close_reason; |
| 229 | 231 |
| 230 mojom::IntentHelperInstance* bridge = | 232 // Make sure that the instance at least supports HandleUrl. |
| 231 arc::ArcIntentHelperBridge::GetIntentHelperInstance(kMinInstanceVersion); | 233 auto* instance = ArcIntentHelperBridge::GetIntentHelperInstance( |
| 232 if (!bridge || selected_app_index >= handlers.size()) { | 234 "HandleUrl", kMinVersionForHandleUrl); |
| 235 if (!instance || selected_app_index >= handlers.size()) |
| 233 close_reason = CloseReason::ERROR; | 236 close_reason = CloseReason::ERROR; |
| 234 } | |
| 235 | 237 |
| 236 switch (close_reason) { | 238 switch (close_reason) { |
| 237 case CloseReason::ERROR: | 239 case CloseReason::ERROR: |
| 238 case CloseReason::DIALOG_DEACTIVATED: { | 240 case CloseReason::DIALOG_DEACTIVATED: { |
| 239 // If the user fails to select an option from the list, or the UI returned | 241 // If the user fails to select an option from the list, or the UI returned |
| 240 // an error or if |selected_app_index| is not a valid index, then resume | 242 // an error or if |selected_app_index| is not a valid index, then resume |
| 241 // the navigation in Chrome. | 243 // the navigation in Chrome. |
| 242 DVLOG(1) << "User didn't select a valid option, resuming navigation."; | 244 DVLOG(1) << "User didn't select a valid option, resuming navigation."; |
| 243 handle->Resume(); | 245 handle->Resume(); |
| 244 break; | 246 break; |
| 245 } | 247 } |
| 246 case CloseReason::ALWAYS_PRESSED: { | 248 case CloseReason::ALWAYS_PRESSED: { |
| 247 bridge->AddPreferredPackage(handlers[selected_app_index]->package_name); | 249 // Call AddPreferredPackage if it is supported. |
| 250 if (ArcIntentHelperBridge::GetIntentHelperInstance( |
| 251 "AddPreferredPackage", kMinVersionForAddPreferredPackage)) { |
| 252 instance->AddPreferredPackage( |
| 253 handlers[selected_app_index]->package_name); |
| 254 } |
| 248 // fall through. | 255 // fall through. |
| 249 } | 256 } |
| 250 case CloseReason::JUST_ONCE_PRESSED: | 257 case CloseReason::JUST_ONCE_PRESSED: |
| 251 case CloseReason::PREFERRED_ACTIVITY_FOUND: { | 258 case CloseReason::PREFERRED_ACTIVITY_FOUND: { |
| 252 if (ArcIntentHelperBridge::IsIntentHelperPackage( | 259 if (ArcIntentHelperBridge::IsIntentHelperPackage( |
| 253 handlers[selected_app_index]->package_name)) { | 260 handlers[selected_app_index]->package_name)) { |
| 254 handle->Resume(); | 261 handle->Resume(); |
| 255 } else { | 262 } else { |
| 256 bridge->HandleUrl(url.spec(), | 263 instance->HandleUrl(url.spec(), |
| 257 handlers[selected_app_index]->package_name); | 264 handlers[selected_app_index]->package_name); |
| 258 handle->CancelDeferredNavigation( | 265 handle->CancelDeferredNavigation( |
| 259 content::NavigationThrottle::CANCEL_AND_IGNORE); | 266 content::NavigationThrottle::CANCEL_AND_IGNORE); |
| 260 if (handle->GetWebContents()->GetController().IsInitialNavigation()) | 267 if (handle->GetWebContents()->GetController().IsInitialNavigation()) |
| 261 handle->GetWebContents()->Close(); | 268 handle->GetWebContents()->Close(); |
| 262 } | 269 } |
| 263 break; | 270 break; |
| 264 } | 271 } |
| 265 case CloseReason::INVALID: { | 272 case CloseReason::INVALID: { |
| 266 NOTREACHED(); | 273 NOTREACHED(); |
| 267 return; | 274 return; |
| 268 } | 275 } |
| 269 } | 276 } |
| 270 | 277 |
| 271 UMA_HISTOGRAM_ENUMERATION("Arc.IntentHandlerAction", | 278 UMA_HISTOGRAM_ENUMERATION("Arc.IntentHandlerAction", |
| 272 static_cast<int>(close_reason), | 279 static_cast<int>(close_reason), |
| 273 static_cast<int>(CloseReason::SIZE)); | 280 static_cast<int>(CloseReason::SIZE)); |
| 274 } | 281 } |
| 275 | 282 |
| 276 // static | 283 // static |
| 277 bool ArcNavigationThrottle::ShouldOverrideUrlLoadingForTesting( | 284 bool ArcNavigationThrottle::ShouldOverrideUrlLoadingForTesting( |
| 278 const GURL& previous_url, | 285 const GURL& previous_url, |
| 279 const GURL& current_url) { | 286 const GURL& current_url) { |
| 280 return ShouldOverrideUrlLoading(previous_url, current_url); | 287 return ShouldOverrideUrlLoading(previous_url, current_url); |
| 281 } | 288 } |
| 282 | 289 |
| 283 } // namespace arc | 290 } // namespace arc |
| OLD | NEW |