OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/app_mode/startup_app_launcher.h" | 5 #include "chrome/browser/chromeos/app_mode/startup_app_launcher.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
9 #include "base/json/json_file_value_serializer.h" | 9 #include "base/json/json_file_value_serializer.h" |
10 #include "base/path_service.h" | 10 #include "base/path_service.h" |
(...skipping 18 matching lines...) Expand all Loading... |
29 #include "components/crx_file/id_util.h" | 29 #include "components/crx_file/id_util.h" |
30 #include "components/signin/core/browser/profile_oauth2_token_service.h" | 30 #include "components/signin/core/browser/profile_oauth2_token_service.h" |
31 #include "components/signin/core/browser/signin_manager.h" | 31 #include "components/signin/core/browser/signin_manager.h" |
32 #include "components/user_manager/user_manager.h" | 32 #include "components/user_manager/user_manager.h" |
33 #include "content/public/browser/browser_thread.h" | 33 #include "content/public/browser/browser_thread.h" |
34 #include "content/public/browser/notification_service.h" | 34 #include "content/public/browser/notification_service.h" |
35 #include "extensions/browser/extension_system.h" | 35 #include "extensions/browser/extension_system.h" |
36 #include "extensions/common/constants.h" | 36 #include "extensions/common/constants.h" |
37 #include "extensions/common/extension.h" | 37 #include "extensions/common/extension.h" |
38 #include "extensions/common/manifest_handlers/kiosk_mode_info.h" | 38 #include "extensions/common/manifest_handlers/kiosk_mode_info.h" |
| 39 #include "extensions/common/manifest_handlers/kiosk_secondary_apps_info.h" |
39 #include "extensions/common/manifest_handlers/offline_enabled_info.h" | 40 #include "extensions/common/manifest_handlers/offline_enabled_info.h" |
40 #include "extensions/common/manifest_url_handlers.h" | 41 #include "extensions/common/manifest_url_handlers.h" |
41 #include "google_apis/gaia/gaia_auth_consumer.h" | 42 #include "google_apis/gaia/gaia_auth_consumer.h" |
42 #include "google_apis/gaia/gaia_constants.h" | 43 #include "google_apis/gaia/gaia_constants.h" |
43 #include "net/base/load_flags.h" | 44 #include "net/base/load_flags.h" |
44 #include "net/url_request/url_fetcher.h" | 45 #include "net/url_request/url_fetcher.h" |
45 #include "net/url_request/url_fetcher_delegate.h" | 46 #include "net/url_request/url_fetcher_delegate.h" |
46 #include "net/url_request/url_request_context_getter.h" | 47 #include "net/url_request/url_request_context_getter.h" |
47 #include "net/url_request/url_request_status.h" | 48 #include "net/url_request/url_request_status.h" |
48 #include "url/gurl.h" | 49 #include "url/gurl.h" |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 LOG(WARNING) << "Installer still running"; | 172 LOG(WARNING) << "Installer still running"; |
172 return; | 173 return; |
173 } | 174 } |
174 | 175 |
175 MaybeInitializeNetwork(); | 176 MaybeInitializeNetwork(); |
176 } | 177 } |
177 | 178 |
178 void StartupAppLauncher::MaybeInitializeNetwork() { | 179 void StartupAppLauncher::MaybeInitializeNetwork() { |
179 network_ready_handled_ = false; | 180 network_ready_handled_ = false; |
180 | 181 |
181 const Extension* extension = extensions::ExtensionSystem::Get(profile_)-> | 182 const Extension* extension = GetPrimaryAppExtension(); |
182 extension_service()->GetInstalledExtension(app_id_); | |
183 bool crx_cached = KioskAppManager::Get()->HasCachedCrx(app_id_); | 183 bool crx_cached = KioskAppManager::Get()->HasCachedCrx(app_id_); |
184 const bool requires_network = | 184 const bool requires_network = |
185 (!extension && !crx_cached) || | 185 (!extension && !crx_cached) || |
186 (extension && | 186 (extension && |
187 !extensions::OfflineEnabledInfo::IsOfflineEnabled(extension)); | 187 !extensions::OfflineEnabledInfo::IsOfflineEnabled(extension)); |
188 | 188 |
189 if (requires_network) { | 189 if (requires_network) { |
190 delegate_->InitializeNetwork(); | 190 delegate_->InitializeNetwork(); |
191 return; | 191 return; |
192 } | 192 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 } | 240 } |
241 | 241 |
242 void StartupAppLauncher::OnRefreshTokensLoaded() { | 242 void StartupAppLauncher::OnRefreshTokensLoaded() { |
243 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_) | 243 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_) |
244 ->RemoveObserver(this); | 244 ->RemoveObserver(this); |
245 MaybeInitializeNetwork(); | 245 MaybeInitializeNetwork(); |
246 } | 246 } |
247 | 247 |
248 void StartupAppLauncher::MaybeLaunchApp() { | 248 void StartupAppLauncher::MaybeLaunchApp() { |
249 // Check if the app is offline enabled. | 249 // Check if the app is offline enabled. |
250 const Extension* extension = extensions::ExtensionSystem::Get(profile_) | 250 const Extension* extension = GetPrimaryAppExtension(); |
251 ->extension_service() | |
252 ->GetInstalledExtension(app_id_); | |
253 DCHECK(extension); | 251 DCHECK(extension); |
254 const bool offline_enabled = | 252 const bool offline_enabled = |
255 extensions::OfflineEnabledInfo::IsOfflineEnabled(extension); | 253 extensions::OfflineEnabledInfo::IsOfflineEnabled(extension); |
256 if (offline_enabled || delegate_->IsNetworkReady()) { | 254 if (offline_enabled || delegate_->IsNetworkReady()) { |
257 BrowserThread::PostTask( | 255 BrowserThread::PostTask( |
258 BrowserThread::UI, | 256 BrowserThread::UI, |
259 FROM_HERE, | 257 FROM_HERE, |
260 base::Bind(&StartupAppLauncher::OnReadyToLaunch, AsWeakPtr())); | 258 base::Bind(&StartupAppLauncher::OnReadyToLaunch, AsWeakPtr())); |
261 } else { | 259 } else { |
262 ++launch_attempt_; | 260 ++launch_attempt_; |
(...skipping 19 matching lines...) Expand all Loading... |
282 } | 280 } |
283 | 281 |
284 extensions::InstallTracker* tracker = | 282 extensions::InstallTracker* tracker = |
285 extensions::InstallTrackerFactory::GetForBrowserContext(profile_); | 283 extensions::InstallTrackerFactory::GetForBrowserContext(profile_); |
286 tracker->RemoveObserver(this); | 284 tracker->RemoveObserver(this); |
287 if (delegate_->IsShowingNetworkConfigScreen()) { | 285 if (delegate_->IsShowingNetworkConfigScreen()) { |
288 LOG(WARNING) << "Showing network config screen"; | 286 LOG(WARNING) << "Showing network config screen"; |
289 return; | 287 return; |
290 } | 288 } |
291 | 289 |
292 if (success) { | 290 if (extension_id == app_id_) { |
293 MaybeLaunchApp(); | 291 if (success) { |
| 292 MaybeInstallSecondaryApps(); |
| 293 } else { |
| 294 LOG(ERROR) << "Failed to install the kiosk application app_id: " |
| 295 << extension_id; |
| 296 OnLaunchFailure(KioskAppLaunchError::UNABLE_TO_INSTALL); |
| 297 } |
294 return; | 298 return; |
295 } | 299 } |
296 | 300 |
297 LOG(ERROR) << "Failed to install the kiosk application app_id: " | 301 if (AreSecondaryAppsInstalled()) { |
298 << extension_id; | 302 MaybeLaunchApp(); |
299 OnLaunchFailure(KioskAppLaunchError::UNABLE_TO_INSTALL); | 303 } else { |
| 304 LOG(ERROR) << "Failed to install one or more secondary apps."; |
| 305 OnLaunchFailure(KioskAppLaunchError::UNABLE_TO_INSTALL); |
| 306 } |
300 } | 307 } |
301 | 308 |
302 void StartupAppLauncher::OnKioskExtensionLoadedInCache( | 309 void StartupAppLauncher::OnKioskExtensionLoadedInCache( |
303 const std::string& app_id) { | 310 const std::string& app_id) { |
304 OnKioskAppDataLoadStatusChanged(app_id); | 311 OnKioskAppDataLoadStatusChanged(app_id); |
305 } | 312 } |
306 | 313 |
307 void StartupAppLauncher::OnKioskExtensionDownloadFailed( | 314 void StartupAppLauncher::OnKioskExtensionDownloadFailed( |
308 const std::string& app_id) { | 315 const std::string& app_id) { |
309 OnKioskAppDataLoadStatusChanged(app_id); | 316 OnKioskAppDataLoadStatusChanged(app_id); |
310 } | 317 } |
311 | 318 |
312 void StartupAppLauncher::OnKioskAppDataLoadStatusChanged( | 319 void StartupAppLauncher::OnKioskAppDataLoadStatusChanged( |
313 const std::string& app_id) { | 320 const std::string& app_id) { |
314 if (app_id != app_id_ || !wait_for_crx_update_) | 321 if (app_id != app_id_ || !wait_for_crx_update_) |
315 return; | 322 return; |
316 | 323 |
317 wait_for_crx_update_ = false; | 324 wait_for_crx_update_ = false; |
318 if (KioskAppManager::Get()->HasCachedCrx(app_id_)) | 325 if (KioskAppManager::Get()->HasCachedCrx(app_id_)) |
319 BeginInstall(); | 326 BeginInstall(); |
320 else | 327 else |
321 OnLaunchFailure(KioskAppLaunchError::UNABLE_TO_DOWNLOAD); | 328 OnLaunchFailure(KioskAppLaunchError::UNABLE_TO_DOWNLOAD); |
322 } | 329 } |
323 | 330 |
| 331 bool StartupAppLauncher::IsAnySecondaryAppPending() const { |
| 332 DCHECK(HaveSecondaryApps()); |
| 333 const extensions::Extension* extension = GetPrimaryAppExtension(); |
| 334 DCHECK(extension); |
| 335 extensions::KioskSecondaryAppsInfo* info = |
| 336 extensions::KioskSecondaryAppsInfo::Get(extension); |
| 337 for (size_t i = 0; i < info->ids.size(); ++i) { |
| 338 if (extensions::ExtensionSystem::Get(profile_) |
| 339 ->extension_service() |
| 340 ->pending_extension_manager() |
| 341 ->IsIdPending(info->ids[i])) { |
| 342 return true; |
| 343 } |
| 344 } |
| 345 return false; |
| 346 } |
| 347 |
| 348 bool StartupAppLauncher::AreSecondaryAppsInstalled() const { |
| 349 DCHECK(HaveSecondaryApps()); |
| 350 const extensions::Extension* extension = GetPrimaryAppExtension(); |
| 351 DCHECK(extension); |
| 352 extensions::KioskSecondaryAppsInfo* info = |
| 353 extensions::KioskSecondaryAppsInfo::Get(extension); |
| 354 for (size_t i = 0; i < info->ids.size(); ++i) { |
| 355 if (!extensions::ExtensionSystem::Get(profile_) |
| 356 ->extension_service() |
| 357 ->GetInstalledExtension(info->ids[i])) { |
| 358 return false; |
| 359 } |
| 360 } |
| 361 return true; |
| 362 } |
| 363 |
| 364 bool StartupAppLauncher::HaveSecondaryApps() const { |
| 365 const extensions::Extension* extension = GetPrimaryAppExtension(); |
| 366 DCHECK(extension); |
| 367 return extensions::KioskSecondaryAppsInfo::HaveSecondaryApps(extension); |
| 368 } |
| 369 |
| 370 const extensions::Extension* StartupAppLauncher::GetPrimaryAppExtension() |
| 371 const { |
| 372 return extensions::ExtensionSystem::Get(profile_) |
| 373 ->extension_service() |
| 374 ->GetInstalledExtension(app_id_); |
| 375 } |
| 376 |
324 void StartupAppLauncher::LaunchApp() { | 377 void StartupAppLauncher::LaunchApp() { |
325 if (!ready_to_launch_) { | 378 if (!ready_to_launch_) { |
326 NOTREACHED(); | 379 NOTREACHED(); |
327 LOG(ERROR) << "LaunchApp() called but launcher is not initialized."; | 380 LOG(ERROR) << "LaunchApp() called but launcher is not initialized."; |
328 } | 381 } |
329 | 382 |
330 const Extension* extension = extensions::ExtensionSystem::Get(profile_)-> | 383 const Extension* extension = GetPrimaryAppExtension(); |
331 extension_service()->GetInstalledExtension(app_id_); | |
332 CHECK(extension); | 384 CHECK(extension); |
333 | 385 |
334 if (!extensions::KioskModeInfo::IsKioskEnabled(extension)) { | 386 if (!extensions::KioskModeInfo::IsKioskEnabled(extension)) { |
335 OnLaunchFailure(KioskAppLaunchError::NOT_KIOSK_ENABLED); | 387 OnLaunchFailure(KioskAppLaunchError::NOT_KIOSK_ENABLED); |
336 return; | 388 return; |
337 } | 389 } |
338 | 390 |
339 // Always open the app in a window. | 391 // Always open the app in a window. |
340 OpenApplication(AppLaunchParams(profile_, extension, | 392 OpenApplication(AppLaunchParams(profile_, extension, |
341 extensions::LAUNCH_CONTAINER_WINDOW, | 393 extensions::LAUNCH_CONTAINER_WINDOW, |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
373 ->pending_extension_manager() | 425 ->pending_extension_manager() |
374 ->IsIdPending(app_id_)) { | 426 ->IsIdPending(app_id_)) { |
375 delegate_->OnInstallingApp(); | 427 delegate_->OnInstallingApp(); |
376 // Observe the crx installation events. | 428 // Observe the crx installation events. |
377 extensions::InstallTracker* tracker = | 429 extensions::InstallTracker* tracker = |
378 extensions::InstallTrackerFactory::GetForBrowserContext(profile_); | 430 extensions::InstallTrackerFactory::GetForBrowserContext(profile_); |
379 tracker->AddObserver(this); | 431 tracker->AddObserver(this); |
380 return; | 432 return; |
381 } | 433 } |
382 | 434 |
383 if (extensions::ExtensionSystem::Get(profile_) | 435 if (GetPrimaryAppExtension()) { |
384 ->extension_service() | 436 // Install secondary apps. |
385 ->GetInstalledExtension(app_id_)) { | 437 MaybeInstallSecondaryApps(); |
386 // Launch the app. | |
387 OnReadyToLaunch(); | |
388 } else { | 438 } else { |
389 // The extension is skipped for installation due to some error. | 439 // The extension is skipped for installation due to some error. |
390 OnLaunchFailure(KioskAppLaunchError::UNABLE_TO_INSTALL); | 440 OnLaunchFailure(KioskAppLaunchError::UNABLE_TO_INSTALL); |
391 } | 441 } |
392 } | 442 } |
393 | 443 |
| 444 void StartupAppLauncher::MaybeInstallSecondaryApps() { |
| 445 if (!HaveSecondaryApps()) { |
| 446 // Launch the primary app. |
| 447 MaybeLaunchApp(); |
| 448 return; |
| 449 } |
| 450 |
| 451 if (!AreSecondaryAppsInstalled() && !delegate_->IsNetworkReady()) { |
| 452 OnLaunchFailure(KioskAppLaunchError::UNABLE_TO_INSTALL); |
| 453 return; |
| 454 } |
| 455 |
| 456 extensions::KioskSecondaryAppsInfo* info = |
| 457 extensions::KioskSecondaryAppsInfo::Get(GetPrimaryAppExtension()); |
| 458 KioskAppManager::Get()->InstallSecondaryApps(info->ids); |
| 459 if (IsAnySecondaryAppPending()) { |
| 460 delegate_->OnInstallingApp(); |
| 461 // Observe the crx installation events. |
| 462 extensions::InstallTracker* tracker = |
| 463 extensions::InstallTrackerFactory::GetForBrowserContext(profile_); |
| 464 tracker->AddObserver(this); |
| 465 return; |
| 466 } |
| 467 |
| 468 if (AreSecondaryAppsInstalled()) { |
| 469 // Launch the primary app. |
| 470 MaybeLaunchApp(); |
| 471 } else { |
| 472 OnLaunchFailure(KioskAppLaunchError::UNABLE_TO_INSTALL); |
| 473 } |
| 474 } |
| 475 |
394 void StartupAppLauncher::OnReadyToLaunch() { | 476 void StartupAppLauncher::OnReadyToLaunch() { |
395 ready_to_launch_ = true; | 477 ready_to_launch_ = true; |
396 UpdateAppData(); | 478 UpdateAppData(); |
397 delegate_->OnReadyToLaunch(); | 479 delegate_->OnReadyToLaunch(); |
398 } | 480 } |
399 | 481 |
400 void StartupAppLauncher::UpdateAppData() { | 482 void StartupAppLauncher::UpdateAppData() { |
401 KioskAppManager::Get()->ClearAppData(app_id_); | 483 KioskAppManager::Get()->ClearAppData(app_id_); |
402 KioskAppManager::Get()->UpdateAppDataFromProfile(app_id_, profile_, NULL); | 484 KioskAppManager::Get()->UpdateAppDataFromProfile(app_id_, profile_, NULL); |
403 } | 485 } |
404 | 486 |
405 } // namespace chromeos | 487 } // namespace chromeos |
OLD | NEW |