Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(435)

Side by Side Diff: chrome/browser/chromeos/arc/arc_navigation_throttle.cc

Issue 2443313002: Add more tests to arc_navigation_throttle.cc (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 if (!current_url.is_valid() || current_url.is_empty()) { 51 if (!current_url.is_valid() || current_url.is_empty()) {
52 DVLOG(1) << "Unexpected URL: " << current_url << ", opening it in Chrome."; 52 DVLOG(1) << "Unexpected URL: " << current_url << ", opening it in Chrome.";
53 return false; 53 return false;
54 } 54 }
55 55
56 return !net::registry_controlled_domains::SameDomainOrHost( 56 return !net::registry_controlled_domains::SameDomainOrHost(
57 current_url, previous_url, 57 current_url, previous_url,
58 net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); 58 net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
59 } 59 }
60 60
61 // Returns true if |handlers| contain one or more apps.
62 bool IsAppAvailable(const mojo::Array<mojom::IntentHandlerInfoPtr>& handlers) {
63 return !handlers.empty() &&
64 !(handlers.size() == 1 && ArcIntentHelperBridge::IsIntentHelperPackage(
Luis Héctor Chávez 2016/10/24 20:24:34 nit: I think it's clearer after applying de Morgan
Yusuke Sato 2016/10/24 22:27:16 Done. Applied yours and shuffled the order a litt
65 handlers[0]->package_name));
66 }
67
68 // Searches for a preferred app in |handlers| and returns its index. If not
69 // found, returns |handlers.size()|.
70 size_t FindPreferredApp(
71 const mojo::Array<mojom::IntentHandlerInfoPtr>& handlers,
72 const GURL& url_for_logging) {
73 for (size_t i = 0; i < handlers.size(); ++i) {
74 if (!handlers[i]->is_preferred)
75 continue;
76 if (ArcIntentHelperBridge::IsIntentHelperPackage(
77 handlers[i]->package_name)) {
78 // If Chrome browser was selected as the preferred app, we should't
djacobo_ 2016/10/24 20:22:14 nit: shouldn't*
Yusuke Sato 2016/10/24 22:27:16 Done.
79 // create a throttle.
80 DVLOG(1)
81 << "Chrome browser is selected as the preferred app for this URL: "
82 << url_for_logging;
Luis Héctor Chávez 2016/10/24 20:24:34 isn't this missing |.spec()|? Since it's not a tri
Yusuke Sato 2016/10/24 22:27:16 I'm not sure if I understand your concern.. could
Luis Héctor Chávez 2016/10/24 22:59:54 This snippet of code used to log |url_for_logging.
Yusuke Sato 2016/10/24 23:25:17 Let me use url_for_logging (w/o .spec()) for simpl
83 }
84 return i;
85 }
86 return handlers.size(); // not found
87 }
88
89 // Swaps Chrome app with any app in row |kMaxAppResults-1| iff its index is
90 // bigger, thus ensuring the user can always see Chrome without scrolling.
91 // When swap is needed, fills |out_indices| and returns true.
92 bool IsSwapElementsNeeded(
93 const mojo::Array<mojom::IntentHandlerInfoPtr>& handlers,
94 std::pair<size_t, size_t>* out_indices) {
95 size_t chrome_app_index = 0;
96 for (size_t i = 0; i < handlers.size(); ++i) {
97 if (ArcIntentHelperBridge::IsIntentHelperPackage(
Luis Héctor Chávez 2016/10/24 20:24:34 qq: is it possible that the intent helper package
Yusuke Sato 2016/10/24 22:27:16 On production, Chrome always appears actually. It'
98 handlers[i]->package_name)) {
99 chrome_app_index = i;
100 break;
101 }
102 }
103 if (chrome_app_index < ArcNavigationThrottle::kMaxAppResults)
104 return false;
105
106 *out_indices = std::make_pair(ArcNavigationThrottle::kMaxAppResults - 1,
107 chrome_app_index);
108 return true;
109 }
110
61 } // namespace 111 } // namespace
62 112
63 ArcNavigationThrottle::ArcNavigationThrottle( 113 ArcNavigationThrottle::ArcNavigationThrottle(
64 content::NavigationHandle* navigation_handle, 114 content::NavigationHandle* navigation_handle,
65 const ShowIntentPickerCallback& show_intent_picker_cb) 115 const ShowIntentPickerCallback& show_intent_picker_cb)
66 : content::NavigationThrottle(navigation_handle), 116 : content::NavigationThrottle(navigation_handle),
67 show_intent_picker_callback_(show_intent_picker_cb), 117 show_intent_picker_callback_(show_intent_picker_cb),
68 previous_user_action_(CloseReason::INVALID), 118 previous_user_action_(CloseReason::INVALID),
69 weak_ptr_factory_(this) {} 119 weak_ptr_factory_(this) {}
70 120
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 url.spec(), base::Bind(&ArcNavigationThrottle::OnAppCandidatesReceived, 206 url.spec(), base::Bind(&ArcNavigationThrottle::OnAppCandidatesReceived,
157 weak_ptr_factory_.GetWeakPtr())); 207 weak_ptr_factory_.GetWeakPtr()));
158 return content::NavigationThrottle::DEFER; 208 return content::NavigationThrottle::DEFER;
159 } 209 }
160 210
161 // We received the array of app candidates to handle this URL (even the Chrome 211 // We received the array of app candidates to handle this URL (even the Chrome
162 // app is included). 212 // app is included).
163 void ArcNavigationThrottle::OnAppCandidatesReceived( 213 void ArcNavigationThrottle::OnAppCandidatesReceived(
164 mojo::Array<mojom::IntentHandlerInfoPtr> handlers) { 214 mojo::Array<mojom::IntentHandlerInfoPtr> handlers) {
165 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 215 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
166 if (handlers.empty() || 216 if (!IsAppAvailable(handlers)) {
167 (handlers.size() == 1 && ArcIntentHelperBridge::IsIntentHelperPackage(
168 handlers[0]->package_name))) {
169 // This scenario shouldn't be accesed as ArcNavigationThrottle is created 217 // This scenario shouldn't be accesed as ArcNavigationThrottle is created
170 // iff there are ARC apps which can actually handle the given URL. 218 // iff there are ARC apps which can actually handle the given URL.
171 DVLOG(1) << "There are no app candidates for this URL: " 219 DVLOG(1) << "There are no app candidates for this URL: "
172 << navigation_handle()->GetURL().spec(); 220 << navigation_handle()->GetURL().spec();
Yusuke Sato 2016/10/24 23:25:17 Removed this .spec() call too to be consistent wit
173 navigation_handle()->Resume(); 221 navigation_handle()->Resume();
174 return; 222 return;
175 } 223 }
176 224
177 // If one of the apps is marked as preferred, use it right away without 225 // If one of the apps is marked as preferred, use it right away without
178 // showing the UI. 226 // showing the UI.
179 for (size_t i = 0; i < handlers.size(); ++i) { 227 const size_t index =
180 if (!handlers[i]->is_preferred) 228 FindPreferredApp(handlers, navigation_handle()->GetURL());
181 continue; 229 if (index != handlers.size()) {
182 if (ArcIntentHelperBridge::IsIntentHelperPackage( 230 const std::string package_name = handlers[index]->package_name;
183 handlers[i]->package_name)) {
184 // If Chrome browser was selected as the preferred app, we should't
185 // create a throttle.
186 DVLOG(1)
187 << "Chrome browser is selected as the preferred app for this URL: "
188 << navigation_handle()->GetURL().spec();
189 }
190 std::string package_name = handlers[i]->package_name;
191 OnIntentPickerClosed(std::move(handlers), package_name, 231 OnIntentPickerClosed(std::move(handlers), package_name,
192 CloseReason::PREFERRED_ACTIVITY_FOUND); 232 CloseReason::PREFERRED_ACTIVITY_FOUND);
193 return; 233 return;
194 } 234 }
195 235
196 // Swap Chrome app with any app in row |kMaxAppResults-1| iff its index is 236 std::pair<size_t, size_t> indices;
197 // bigger, thus ensuring the user can always see Chrome without scrolling. 237 if (IsSwapElementsNeeded(handlers, &indices))
198 size_t chrome_app_index = 0; 238 std::swap(handlers[indices.first], handlers[indices.second]);
199 for (size_t i = 0; i < handlers.size(); ++i) {
200 if (ArcIntentHelperBridge::IsIntentHelperPackage(
201 handlers[i]->package_name)) {
202 chrome_app_index = i;
203 break;
204 }
205 }
206
207 if (chrome_app_index >= kMaxAppResults)
208 std::swap(handlers[kMaxAppResults - 1], handlers[chrome_app_index]);
209 239
210 scoped_refptr<ActivityIconLoader> icon_loader = GetIconLoader(); 240 scoped_refptr<ActivityIconLoader> icon_loader = GetIconLoader();
211 if (!icon_loader) { 241 if (!icon_loader) {
212 LOG(ERROR) << "Cannot get an instance of ActivityIconLoader"; 242 LOG(ERROR) << "Cannot get an instance of ActivityIconLoader";
213 navigation_handle()->Resume(); 243 navigation_handle()->Resume();
214 return; 244 return;
215 } 245 }
216 std::vector<ActivityIconLoader::ActivityName> activities; 246 std::vector<ActivityIconLoader::ActivityName> activities;
217 for (const auto& handler : handlers) { 247 for (const auto& handler : handlers)
218 activities.emplace_back(handler->package_name, handler->activity_name); 248 activities.emplace_back(handler->package_name, handler->activity_name);
219 }
220 icon_loader->GetActivityIcons( 249 icon_loader->GetActivityIcons(
221 activities, 250 activities,
222 base::Bind(&ArcNavigationThrottle::OnAppIconsReceived, 251 base::Bind(&ArcNavigationThrottle::OnAppIconsReceived,
223 weak_ptr_factory_.GetWeakPtr(), base::Passed(&handlers))); 252 weak_ptr_factory_.GetWeakPtr(), base::Passed(&handlers)));
224 } 253 }
225 254
226 void ArcNavigationThrottle::OnAppIconsReceived( 255 void ArcNavigationThrottle::OnAppIconsReceived(
227 mojo::Array<mojom::IntentHandlerInfoPtr> handlers, 256 mojo::Array<mojom::IntentHandlerInfoPtr> handlers,
228 std::unique_ptr<ActivityIconLoader::ActivityToIconsMap> icons) { 257 std::unique_ptr<ActivityIconLoader::ActivityToIconsMap> icons) {
229 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 258 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
(...skipping 21 matching lines...) Expand all
251 std::string selected_app_package, 280 std::string selected_app_package,
252 CloseReason close_reason) { 281 CloseReason close_reason) {
253 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 282 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
254 const GURL& url = navigation_handle()->GetURL(); 283 const GURL& url = navigation_handle()->GetURL();
255 content::NavigationHandle* handle = navigation_handle(); 284 content::NavigationHandle* handle = navigation_handle();
256 previous_user_action_ = close_reason; 285 previous_user_action_ = close_reason;
257 286
258 // Make sure that the instance at least supports HandleUrl. 287 // Make sure that the instance at least supports HandleUrl.
259 auto* instance = ArcIntentHelperBridge::GetIntentHelperInstance( 288 auto* instance = ArcIntentHelperBridge::GetIntentHelperInstance(
260 "HandleUrl", kMinVersionForHandleUrl); 289 "HandleUrl", kMinVersionForHandleUrl);
261 size_t selected_app_index = handlers.size(); 290 // Since we are selecting an app by its package name, we need to locate it
291 // on the |handlers| structure before sending the IPC to ARC.
292 const size_t selected_app_index = GetAppIndex(handlers, selected_app_package);
262 if (!instance) { 293 if (!instance) {
263 close_reason = CloseReason::ERROR; 294 close_reason = CloseReason::ERROR;
264 } else if (close_reason == CloseReason::JUST_ONCE_PRESSED || 295 } else if (close_reason == CloseReason::JUST_ONCE_PRESSED ||
265 close_reason == CloseReason::ALWAYS_PRESSED || 296 close_reason == CloseReason::ALWAYS_PRESSED ||
266 close_reason == CloseReason::PREFERRED_ACTIVITY_FOUND) { 297 close_reason == CloseReason::PREFERRED_ACTIVITY_FOUND) {
267 // Since we are selecting an app by its package name, we need to locate it
268 // on the |handlers| structure before sending the IPC to ARC.
269 for (size_t i = 0; i < handlers.size(); ++i) {
270 if (handlers[i]->package_name == selected_app_package) {
271 selected_app_index = i;
272 break;
273 }
274 }
275
276 if (selected_app_index == handlers.size()) 298 if (selected_app_index == handlers.size())
277 close_reason = CloseReason::ERROR; 299 close_reason = CloseReason::ERROR;
278 } 300 }
279 301
280 switch (close_reason) { 302 switch (close_reason) {
281 case CloseReason::ERROR: 303 case CloseReason::ERROR:
282 case CloseReason::DIALOG_DEACTIVATED: { 304 case CloseReason::DIALOG_DEACTIVATED: {
283 // If the user fails to select an option from the list, or the UI returned 305 // If the user fails to select an option from the list, or the UI returned
284 // an error or if |selected_app_index| is not a valid index, then resume 306 // an error or if |selected_app_index| is not a valid index, then resume
285 // the navigation in Chrome. 307 // the navigation in Chrome.
(...skipping 30 matching lines...) Expand all
316 return; 338 return;
317 } 339 }
318 } 340 }
319 341
320 UMA_HISTOGRAM_ENUMERATION("Arc.IntentHandlerAction", 342 UMA_HISTOGRAM_ENUMERATION("Arc.IntentHandlerAction",
321 static_cast<int>(close_reason), 343 static_cast<int>(close_reason),
322 static_cast<int>(CloseReason::SIZE)); 344 static_cast<int>(CloseReason::SIZE));
323 } 345 }
324 346
325 // static 347 // static
348 size_t ArcNavigationThrottle::GetAppIndex(
349 const mojo::Array<mojom::IntentHandlerInfoPtr>& handlers,
350 const std::string& selected_app_package) {
351 for (size_t i = 0; i < handlers.size(); ++i) {
352 if (handlers[i]->package_name == selected_app_package)
353 return i;
354 }
355 return handlers.size();
356 }
357
358 // static
326 bool ArcNavigationThrottle::ShouldOverrideUrlLoadingForTesting( 359 bool ArcNavigationThrottle::ShouldOverrideUrlLoadingForTesting(
327 const GURL& previous_url, 360 const GURL& previous_url,
328 const GURL& current_url) { 361 const GURL& current_url) {
329 return ShouldOverrideUrlLoading(previous_url, current_url); 362 return ShouldOverrideUrlLoading(previous_url, current_url);
330 } 363 }
331 364
365 // static
366 bool ArcNavigationThrottle::IsAppAvailableForTesting(
367 const mojo::Array<mojom::IntentHandlerInfoPtr>& handlers) {
368 return IsAppAvailable(handlers);
369 }
370
371 // static
372 size_t ArcNavigationThrottle::FindPreferredAppForTesting(
373 const mojo::Array<mojom::IntentHandlerInfoPtr>& handlers) {
374 return FindPreferredApp(handlers, GURL());
375 }
376
377 // static
378 bool ArcNavigationThrottle::IsSwapElementsNeededForTesting(
379 const mojo::Array<mojom::IntentHandlerInfoPtr>& handlers,
380 std::pair<size_t, size_t>* out_indices) {
381 return IsSwapElementsNeeded(handlers, out_indices);
382 }
383
332 } // namespace arc 384 } // namespace arc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698