startup_app_launcher.cc revision effb81e5f8246d0db0270817048dc992db66e9fb
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/app_mode/startup_app_launcher.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/command_line.h" 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/files/file_path.h" 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/json/json_file_value_serializer.h" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/path_service.h" 11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/values.h" 137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/app_mode/app_session_lifetime.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/chromeos/app_mode/kiosk_diagnosis_runner.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/login/user_manager.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/extension_service.h" 19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/extensions/updater/extension_updater.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/webstore_startup_installer.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/lifetime/application_lifetime.h" 22a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/signin/signin_manager.h" 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/signin/signin_manager_factory.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/extensions/application_launch.h" 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/chrome_paths.h" 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/chrome_switches.h" 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/common/chrome_version_info.h" 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/common/extensions/manifest_url_handler.h" 30effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "components/signin/core/browser/profile_oauth2_token_service.h" 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h" 327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/browser/notification_service.h" 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h" 34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h" 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/manifest_handlers/kiosk_mode_info.h" 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/common/manifest_handlers/offline_enabled_info.h" 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "google_apis/gaia/gaia_auth_consumer.h" 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "google_apis/gaia/gaia_constants.h" 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/base/load_flags.h" 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_fetcher.h" 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_fetcher_delegate.h" 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h" 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_request_status.h" 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "url/gurl.h" 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::BrowserThread; 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using extensions::Extension; 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using extensions::WebstoreStartupInstaller; 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace chromeos { 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kOAuthRefreshToken[] = "refresh_token"; 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kOAuthClientId[] = "client_id"; 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kOAuthClientSecret[] = "client_secret"; 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::FilePath::CharType kOAuthFileName[] = 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FILE_PATH_LITERAL("kiosk_auth"); 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const int kMaxInstallAttempt = 5; 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace 643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)StartupAppLauncher::StartupAppLauncher(Profile* profile, 66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string& app_id, 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool diagnostic_mode, 68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) StartupAppLauncher::Delegate* delegate) 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : profile_(profile), 7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) app_id_(app_id), 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) diagnostic_mode_(diagnostic_mode), 72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) delegate_(delegate), 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) network_ready_handled_(false), 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) install_attempt_(0), 7558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ready_to_launch_(false) { 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(profile_); 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(Extension::IdIsValid(app_id_)); 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)StartupAppLauncher::~StartupAppLauncher() { 8158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // StartupAppLauncher can be deleted at anytime during the launch process 8258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // through a user bailout shortcut. 8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ProfileOAuth2TokenServiceFactory::GetForProfile(profile_) 8458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ->RemoveObserver(this); 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void StartupAppLauncher::Initialize() { 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StartLoadingOAuthFile(); 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void StartupAppLauncher::ContinueWithNetworkReady() { 92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Starts install if it is not started. 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!network_ready_handled_) { 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) network_ready_handled_ = true; 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MaybeInstall(); 96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void StartupAppLauncher::StartLoadingOAuthFile() { 100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) delegate_->OnLoadingOAuthFile(); 1013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) KioskOAuthParams* auth_params = new KioskOAuthParams(); 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) BrowserThread::PostBlockingPoolTaskAndReply( 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&StartupAppLauncher::LoadOAuthFileOnBlockingPool, 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) auth_params), 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&StartupAppLauncher::OnOAuthFileLoaded, 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AsWeakPtr(), 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Owned(auth_params))); 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static. 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void StartupAppLauncher::LoadOAuthFileOnBlockingPool( 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) KioskOAuthParams* auth_params) { 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int error_code = JSONFileValueSerializer::JSON_NO_ERROR; 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string error_msg; 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath user_data_dir; 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CHECK(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)); 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath auth_file = user_data_dir.Append(kOAuthFileName); 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<JSONFileValueSerializer> serializer( 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new JSONFileValueSerializer(user_data_dir.Append(kOAuthFileName))); 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::Value> value( 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) serializer->Deserialize(&error_code, &error_msg)); 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* dict = NULL; 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (error_code != JSONFileValueSerializer::JSON_NO_ERROR || 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !value.get() || !value->GetAsDictionary(&dict)) { 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(WARNING) << "Can't find auth file at " << auth_file.value(); 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dict->GetString(kOAuthRefreshToken, &auth_params->refresh_token); 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dict->GetString(kOAuthClientId, &auth_params->client_id); 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dict->GetString(kOAuthClientSecret, &auth_params->client_secret); 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void StartupAppLauncher::OnOAuthFileLoaded(KioskOAuthParams* auth_params) { 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) auth_params_ = *auth_params; 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Override chrome client_id and secret that will be used for identity 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // API token minting. 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!auth_params_.client_id.empty() && !auth_params_.client_secret.empty()) { 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UserManager::Get()->SetAppModeChromeClientOAuthInfo( 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) auth_params_.client_id, 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) auth_params_.client_secret); 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If we are restarting chrome (i.e. on crash), we need to initialize 147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // OAuth2TokenService as well. 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) InitializeTokenService(); 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 151effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid StartupAppLauncher::RestartLauncher() { 152effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // If the installer is still running in the background, we don't need to 153effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // restart the launch process. We will just wait until it completes and 154effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // lunches the kiosk app. 155effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (installer_ != NULL) { 156effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch LOG(WARNING) << "Installer still running"; 157effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return; 158effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 159effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 160effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch MaybeInitializeNetwork(); 161effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 162effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void StartupAppLauncher::MaybeInitializeNetwork() { 164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) network_ready_handled_ = false; 165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const Extension* extension = extensions::ExtensionSystem::Get(profile_)-> 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension_service()->GetInstalledExtension(app_id_); 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const bool requires_network = !extension || 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) !extensions::OfflineEnabledInfo::IsOfflineEnabled(extension); 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (requires_network) { 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delegate_->InitializeNetwork(); 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Offline enabled app attempts update if network is ready. Otherwise, 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // go directly to launch. 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (delegate_->IsNetworkReady()) 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ContinueWithNetworkReady(); 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnReadyToLaunch(); 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void StartupAppLauncher::InitializeTokenService() { 185a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) delegate_->OnInitializingTokenService(); 1863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 187a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ProfileOAuth2TokenService* profile_token_service = 188a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SigninManagerBase* signin_manager = 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SigninManagerFactory::GetForProfile(profile_); 191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string primary_account_id = 192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) signin_manager->GetAuthenticatedAccountId(); 193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (profile_token_service->RefreshTokenIsAvailable(primary_account_id) || 194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) auth_params_.refresh_token.empty()) { 1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MaybeInitializeNetwork(); 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Pass oauth2 refresh token from the auth file. 198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // TODO(zelidrag): We should probably remove this option after M27. 199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // TODO(fgorski): This can go when we have persistence implemented on PO2TS. 200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Unless the code is no longer needed. 201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // TODO(rogerta): Now that this CL implements token persistence in PO2TS, is 202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // this code still needed? See above two TODOs. 203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // 204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // ProfileOAuth2TokenService triggers either OnRefreshTokenAvailable or 205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // OnRefreshTokensLoaded. Given that we want to handle exactly one event, 206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // whichever comes first, both handlers call RemoveObserver on PO2TS. 207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Handling any of the two events is the only way to resume the execution 208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // and enable Cleanup method to be called, self-invoking a destructor. 209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) profile_token_service->AddObserver(this); 210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) profile_token_service->UpdateCredentials( 212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) primary_account_id, 213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) auth_params_.refresh_token); 214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 217a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void StartupAppLauncher::OnRefreshTokenAvailable( 218a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::string& account_id) { 219a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ProfileOAuth2TokenServiceFactory::GetForProfile(profile_) 220a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ->RemoveObserver(this); 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MaybeInitializeNetwork(); 222a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 223a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 224a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void StartupAppLauncher::OnRefreshTokensLoaded() { 225a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ProfileOAuth2TokenServiceFactory::GetForProfile(profile_) 226a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ->RemoveObserver(this); 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MaybeInitializeNetwork(); 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 23058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void StartupAppLauncher::LaunchApp() { 23158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!ready_to_launch_) { 23258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) NOTREACHED(); 23358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) LOG(ERROR) << "LaunchApp() called but launcher is not initialized."; 23458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 23558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Extension* extension = extensions::ExtensionSystem::Get(profile_)-> 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_service()->GetInstalledExtension(app_id_); 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(extension); 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 24068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!extensions::KioskModeInfo::IsKioskEnabled(extension)) { 241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) OnLaunchFailure(KioskAppLaunchError::NOT_KIOSK_ENABLED); 242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Always open the app in a window. 2464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) OpenApplication(AppLaunchParams(profile_, extension, 247a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) extensions::LAUNCH_CONTAINER_WINDOW, 248a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) NEW_WINDOW)); 249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) InitAppSession(profile_, app_id_); 250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 25158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) UserManager::Get()->SessionStarted(); 25258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content::NotificationService::current()->Notify( 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chrome::NOTIFICATION_KIOSK_APP_LAUNCHED, 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content::NotificationService::AllSources(), 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content::NotificationService::NoDetails()); 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (diagnostic_mode_) 2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) KioskDiagnosisRunner::Run(profile_, app_id_); 26023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 26123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) OnLaunchSuccess(); 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void StartupAppLauncher::OnLaunchSuccess() { 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delegate_->OnLaunchSucceeded(); 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void StartupAppLauncher::OnLaunchFailure(KioskAppLaunchError::Error error) { 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(ERROR) << "App launch failed, error: " << error; 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_NE(KioskAppLaunchError::NONE, error); 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delegate_->OnLaunchFailed(error); 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void StartupAppLauncher::MaybeInstall() { 276a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) delegate_->OnInstallingApp(); 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionService* extension_service = 2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extensions::ExtensionSystem::Get(profile_)->extension_service(); 280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!extension_service->GetInstalledExtension(app_id_)) { 281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BeginInstall(); 282a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 283a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) extensions::ExtensionUpdater::CheckParams check_params; 286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) check_params.ids.push_back(app_id_); 287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) check_params.install_immediately = true; 288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) check_params.callback = 289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&StartupAppLauncher::OnUpdateCheckFinished, AsWeakPtr()); 290a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) extension_service->updater()->CheckNow(check_params); 2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void StartupAppLauncher::OnUpdateCheckFinished() { 2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnReadyToLaunch(); 295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) UpdateAppData(); 2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void StartupAppLauncher::BeginInstall() { 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) installer_ = new WebstoreStartupInstaller( 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) app_id_, 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile_, 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) false, 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&StartupAppLauncher::InstallCallback, AsWeakPtr())); 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) installer_->BeginInstall(); 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StartupAppLauncher::InstallCallback(bool success, 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& error) { 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) installer_ = NULL; 310effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (delegate_->IsShowingNetworkConfigScreen()) { 311effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch LOG(WARNING) << "Showing network config screen"; 312effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return; 313effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 314effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (success) { 31658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Finish initialization after the callback returns. 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // So that the app finishes its installation. 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::PostTask( 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::UI, 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 32158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::Bind(&StartupAppLauncher::OnReadyToLaunch, 32258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) AsWeakPtr())); 323a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 324a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 325a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 326a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG(ERROR) << "App install failed: " << error 327a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << ", for attempt " << install_attempt_; 3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 329a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ++install_attempt_; 330a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (install_attempt_ < kMaxInstallAttempt) { 3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BrowserThread::PostTask( 3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BrowserThread::UI, 3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FROM_HERE, 334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&StartupAppLauncher::MaybeInitializeNetwork, 3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AsWeakPtr())); 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnLaunchFailure(KioskAppLaunchError::UNABLE_TO_INSTALL); 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 34258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void StartupAppLauncher::OnReadyToLaunch() { 34358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ready_to_launch_ = true; 344a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) delegate_->OnReadyToLaunch(); 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void StartupAppLauncher::UpdateAppData() { 3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) KioskAppManager::Get()->ClearAppData(app_id_); 3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) KioskAppManager::Get()->UpdateAppDataFromProfile(app_id_, profile_, NULL); 3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace chromeos 353