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" |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 if (!handlers[i]->is_preferred) | 166 if (!handlers[i]->is_preferred) |
167 continue; | 167 continue; |
168 if (ArcIntentHelperBridge::IsIntentHelperPackage( | 168 if (ArcIntentHelperBridge::IsIntentHelperPackage( |
169 handlers[i]->package_name)) { | 169 handlers[i]->package_name)) { |
170 // If Chrome browser was selected as the preferred app, we should't | 170 // If Chrome browser was selected as the preferred app, we should't |
171 // create a throttle. | 171 // create a throttle. |
172 DVLOG(1) | 172 DVLOG(1) |
173 << "Chrome browser is selected as the preferred app for this URL: " | 173 << "Chrome browser is selected as the preferred app for this URL: " |
174 << navigation_handle()->GetURL().spec(); | 174 << navigation_handle()->GetURL().spec(); |
175 } | 175 } |
176 OnIntentPickerClosed(std::move(handlers), i, | 176 std::string package_name = handlers[i]->package_name; |
| 177 OnIntentPickerClosed(std::move(handlers), package_name, |
177 CloseReason::PREFERRED_ACTIVITY_FOUND); | 178 CloseReason::PREFERRED_ACTIVITY_FOUND); |
178 return; | 179 return; |
179 } | 180 } |
180 | 181 |
181 // Swap Chrome app with any app in row |kMaxAppResults-1| iff its index is | 182 // Swap Chrome app with any app in row |kMaxAppResults-1| iff its index is |
182 // bigger, thus ensuring the user can always see Chrome without scrolling. | 183 // bigger, thus ensuring the user can always see Chrome without scrolling. |
183 size_t chrome_app_index = 0; | 184 size_t chrome_app_index = 0; |
184 for (size_t i = 0; i < handlers.size(); ++i) { | 185 for (size_t i = 0; i < handlers.size(); ++i) { |
185 if (ArcIntentHelperBridge::IsIntentHelperPackage( | 186 if (ArcIntentHelperBridge::IsIntentHelperPackage( |
186 handlers[i]->package_name)) { | 187 handlers[i]->package_name)) { |
(...skipping 18 matching lines...) Expand all Loading... |
205 icon_loader->GetActivityIcons( | 206 icon_loader->GetActivityIcons( |
206 activities, | 207 activities, |
207 base::Bind(&ArcNavigationThrottle::OnAppIconsReceived, | 208 base::Bind(&ArcNavigationThrottle::OnAppIconsReceived, |
208 weak_ptr_factory_.GetWeakPtr(), base::Passed(&handlers))); | 209 weak_ptr_factory_.GetWeakPtr(), base::Passed(&handlers))); |
209 } | 210 } |
210 | 211 |
211 void ArcNavigationThrottle::OnAppIconsReceived( | 212 void ArcNavigationThrottle::OnAppIconsReceived( |
212 mojo::Array<mojom::IntentHandlerInfoPtr> handlers, | 213 mojo::Array<mojom::IntentHandlerInfoPtr> handlers, |
213 std::unique_ptr<ActivityIconLoader::ActivityToIconsMap> icons) { | 214 std::unique_ptr<ActivityIconLoader::ActivityToIconsMap> icons) { |
214 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 215 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
215 std::vector<NameAndIcon> app_info; | 216 std::vector<AppInfo> app_info; |
216 | 217 |
217 for (const auto& handler : handlers) { | 218 for (const auto& handler : handlers) { |
218 gfx::Image icon; | 219 gfx::Image icon; |
219 const ActivityIconLoader::ActivityName activity(handler->package_name, | 220 const ActivityIconLoader::ActivityName activity(handler->package_name, |
220 handler->activity_name); | 221 handler->activity_name); |
221 const auto it = icons->find(activity); | 222 const auto it = icons->find(activity); |
222 | 223 |
223 app_info.emplace_back( | 224 app_info.emplace_back( |
224 handler->name, it != icons->end() ? it->second.icon20 : gfx::Image()); | 225 AppInfo(it != icons->end() ? it->second.icon20 : gfx::Image(), |
| 226 handler->package_name, handler->name)); |
225 } | 227 } |
226 | 228 |
227 show_intent_picker_callback_.Run( | 229 show_intent_picker_callback_.Run( |
228 navigation_handle()->GetWebContents(), app_info, | 230 navigation_handle()->GetWebContents(), app_info, |
229 base::Bind(&ArcNavigationThrottle::OnIntentPickerClosed, | 231 base::Bind(&ArcNavigationThrottle::OnIntentPickerClosed, |
230 weak_ptr_factory_.GetWeakPtr(), base::Passed(&handlers))); | 232 weak_ptr_factory_.GetWeakPtr(), base::Passed(&handlers))); |
231 } | 233 } |
232 | 234 |
233 void ArcNavigationThrottle::OnIntentPickerClosed( | 235 void ArcNavigationThrottle::OnIntentPickerClosed( |
234 mojo::Array<mojom::IntentHandlerInfoPtr> handlers, | 236 mojo::Array<mojom::IntentHandlerInfoPtr> handlers, |
235 size_t selected_app_index, | 237 std::string selected_app_package, |
236 CloseReason close_reason) { | 238 CloseReason close_reason) { |
237 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 239 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
238 const GURL& url = navigation_handle()->GetURL(); | 240 const GURL& url = navigation_handle()->GetURL(); |
239 content::NavigationHandle* handle = navigation_handle(); | 241 content::NavigationHandle* handle = navigation_handle(); |
240 | |
241 previous_user_action_ = close_reason; | 242 previous_user_action_ = close_reason; |
242 | 243 |
243 // Make sure that the instance at least supports HandleUrl. | 244 // Make sure that the instance at least supports HandleUrl. |
244 auto* instance = ArcIntentHelperBridge::GetIntentHelperInstance( | 245 auto* instance = ArcIntentHelperBridge::GetIntentHelperInstance( |
245 "HandleUrl", kMinVersionForHandleUrl); | 246 "HandleUrl", kMinVersionForHandleUrl); |
246 if (!instance || selected_app_index >= handlers.size()) | 247 size_t selected_app_index = handlers.size(); |
| 248 if (!instance) { |
247 close_reason = CloseReason::ERROR; | 249 close_reason = CloseReason::ERROR; |
| 250 } else if (close_reason == CloseReason::JUST_ONCE_PRESSED || |
| 251 close_reason == CloseReason::ALWAYS_PRESSED || |
| 252 close_reason == CloseReason::PREFERRED_ACTIVITY_FOUND) { |
| 253 // Since we are selecting an app by its package name, we need to locate it |
| 254 // on the |handlers| structure before sending the IPC to ARC. |
| 255 for (size_t i = 0; i < handlers.size(); ++i) { |
| 256 if (handlers[i]->package_name == selected_app_package) { |
| 257 selected_app_index = i; |
| 258 break; |
| 259 } |
| 260 } |
| 261 |
| 262 if (selected_app_index == handlers.size()) |
| 263 close_reason = CloseReason::ERROR; |
| 264 } |
248 | 265 |
249 switch (close_reason) { | 266 switch (close_reason) { |
250 case CloseReason::ERROR: | 267 case CloseReason::ERROR: |
251 case CloseReason::DIALOG_DEACTIVATED: { | 268 case CloseReason::DIALOG_DEACTIVATED: { |
252 // If the user fails to select an option from the list, or the UI returned | 269 // If the user fails to select an option from the list, or the UI returned |
253 // an error or if |selected_app_index| is not a valid index, then resume | 270 // an error or if |selected_app_index| is not a valid index, then resume |
254 // the navigation in Chrome. | 271 // the navigation in Chrome. |
255 DVLOG(1) << "User didn't select a valid option, resuming navigation."; | 272 DVLOG(1) << "User didn't select a valid option, resuming navigation."; |
256 handle->Resume(); | 273 handle->Resume(); |
257 break; | 274 break; |
258 } | 275 } |
259 case CloseReason::ALWAYS_PRESSED: { | 276 case CloseReason::ALWAYS_PRESSED: { |
260 // Call AddPreferredPackage if it is supported. Reusing the same | 277 // Call AddPreferredPackage if it is supported. Reusing the same |
261 // |instance| is okay. | 278 // |instance| is okay. |
262 if (ArcIntentHelperBridge::GetIntentHelperInstance( | 279 if (ArcIntentHelperBridge::GetIntentHelperInstance( |
263 "AddPreferredPackage", kMinVersionForAddPreferredPackage)) { | 280 "AddPreferredPackage", kMinVersionForAddPreferredPackage)) { |
264 instance->AddPreferredPackage( | 281 instance->AddPreferredPackage( |
265 handlers[selected_app_index]->package_name); | 282 handlers[selected_app_index]->package_name); |
266 } | 283 } |
267 // fall through. | 284 // fall through. |
268 } | 285 } |
269 case CloseReason::JUST_ONCE_PRESSED: | 286 case CloseReason::JUST_ONCE_PRESSED: |
270 case CloseReason::PREFERRED_ACTIVITY_FOUND: { | 287 case CloseReason::PREFERRED_ACTIVITY_FOUND: { |
271 if (ArcIntentHelperBridge::IsIntentHelperPackage( | 288 if (ArcIntentHelperBridge::IsIntentHelperPackage( |
272 handlers[selected_app_index]->package_name)) { | 289 handlers[selected_app_index]->package_name)) { |
273 handle->Resume(); | 290 handle->Resume(); |
274 } else { | 291 } else { |
275 instance->HandleUrl(url.spec(), | 292 instance->HandleUrl(url.spec(), selected_app_package); |
276 handlers[selected_app_index]->package_name); | |
277 handle->CancelDeferredNavigation( | 293 handle->CancelDeferredNavigation( |
278 content::NavigationThrottle::CANCEL_AND_IGNORE); | 294 content::NavigationThrottle::CANCEL_AND_IGNORE); |
279 if (handle->GetWebContents()->GetController().IsInitialNavigation()) | 295 if (handle->GetWebContents()->GetController().IsInitialNavigation()) |
280 handle->GetWebContents()->Close(); | 296 handle->GetWebContents()->Close(); |
281 } | 297 } |
282 break; | 298 break; |
283 } | 299 } |
284 case CloseReason::INVALID: { | 300 case CloseReason::INVALID: { |
285 NOTREACHED(); | 301 NOTREACHED(); |
286 return; | 302 return; |
287 } | 303 } |
288 } | 304 } |
289 | 305 |
290 UMA_HISTOGRAM_ENUMERATION("Arc.IntentHandlerAction", | 306 UMA_HISTOGRAM_ENUMERATION("Arc.IntentHandlerAction", |
291 static_cast<int>(close_reason), | 307 static_cast<int>(close_reason), |
292 static_cast<int>(CloseReason::SIZE)); | 308 static_cast<int>(CloseReason::SIZE)); |
293 } | 309 } |
294 | 310 |
295 // static | 311 // static |
296 bool ArcNavigationThrottle::ShouldOverrideUrlLoadingForTesting( | 312 bool ArcNavigationThrottle::ShouldOverrideUrlLoadingForTesting( |
297 const GURL& previous_url, | 313 const GURL& previous_url, |
298 const GURL& current_url) { | 314 const GURL& current_url) { |
299 return ShouldOverrideUrlLoading(previous_url, current_url); | 315 return ShouldOverrideUrlLoading(previous_url, current_url); |
300 } | 316 } |
301 | 317 |
302 } // namespace arc | 318 } // namespace arc |
OLD | NEW |