startup_app_launcher.cc revision 6e8cce623b6e4fe0c9e4af605d675dd9d0338c38
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"
17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/chromeos/login/session/user_session_manager.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/extensions/install_tracker.h"
20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/extensions/install_tracker_factory.h"
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/extensions/updater/extension_updater.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/lifetime/application_lifetime.h"
23a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/signin/profile_oauth2_token_service_factory.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"
31e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "components/signin/core/browser/signin_manager.h"
326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "components/user_manager/user_manager.h"
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/browser/notification_service.h"
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h"
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/manifest_handlers/kiosk_mode_info.h"
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/common/manifest_handlers/offline_enabled_info.h"
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "google_apis/gaia/gaia_auth_consumer.h"
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "google_apis/gaia/gaia_constants.h"
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/base/load_flags.h"
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_fetcher.h"
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_fetcher_delegate.h"
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_request_status.h"
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "url/gurl.h"
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::BrowserThread;
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using extensions::Extension;
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace chromeos {
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kOAuthRefreshToken[] = "refresh_token";
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kOAuthClientId[] = "client_id";
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kOAuthClientSecret[] = "client_secret";
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::FilePath::CharType kOAuthFileName[] =
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    FILE_PATH_LITERAL("kiosk_auth");
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst int kMaxLaunchAttempt = 5;
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace
653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)StartupAppLauncher::StartupAppLauncher(Profile* profile,
67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                       const std::string& app_id,
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       bool diagnostic_mode,
69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                       StartupAppLauncher::Delegate* delegate)
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : profile_(profile),
7158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      app_id_(app_id),
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      diagnostic_mode_(diagnostic_mode),
73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      delegate_(delegate),
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      network_ready_handled_(false),
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      launch_attempt_(0),
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ready_to_launch_(false),
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      wait_for_crx_update_(false) {
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(profile_);
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(Extension::IdIsValid(app_id_));
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  KioskAppManager::Get()->AddObserver(this);
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)StartupAppLauncher::~StartupAppLauncher() {
84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  KioskAppManager::Get()->RemoveObserver(this);
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
8658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // StartupAppLauncher can be deleted at anytime during the launch process
8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // through a user bailout shortcut.
8858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)
8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      ->RemoveObserver(this);
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void StartupAppLauncher::Initialize() {
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  StartLoadingOAuthFile();
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void StartupAppLauncher::ContinueWithNetworkReady() {
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!network_ready_handled_) {
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    network_ready_handled_ = true;
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // The network might not be ready when KioskAppManager tries to update
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // external cache initially. Update the external cache now that the network
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // is ready for sure.
102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    wait_for_crx_update_ = true;
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    KioskAppManager::Get()->UpdateExternalCache();
104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void StartupAppLauncher::StartLoadingOAuthFile() {
108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  delegate_->OnLoadingOAuthFile();
1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  KioskOAuthParams* auth_params = new KioskOAuthParams();
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BrowserThread::PostBlockingPoolTaskAndReply(
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FROM_HERE,
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&StartupAppLauncher::LoadOAuthFileOnBlockingPool,
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 auth_params),
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&StartupAppLauncher::OnOAuthFileLoaded,
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 AsWeakPtr(),
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Owned(auth_params)));
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static.
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void StartupAppLauncher::LoadOAuthFileOnBlockingPool(
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    KioskOAuthParams* auth_params) {
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int error_code = JSONFileValueSerializer::JSON_NO_ERROR;
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error_msg;
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::FilePath user_data_dir;
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir));
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::FilePath auth_file = user_data_dir.Append(kOAuthFileName);
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<JSONFileValueSerializer> serializer(
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new JSONFileValueSerializer(user_data_dir.Append(kOAuthFileName)));
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::Value> value(
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      serializer->Deserialize(&error_code, &error_msg));
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::DictionaryValue* dict = NULL;
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (error_code != JSONFileValueSerializer::JSON_NO_ERROR ||
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      !value.get() || !value->GetAsDictionary(&dict)) {
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    LOG(WARNING) << "Can't find auth file at " << auth_file.value();
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  dict->GetString(kOAuthRefreshToken, &auth_params->refresh_token);
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  dict->GetString(kOAuthClientId, &auth_params->client_id);
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  dict->GetString(kOAuthClientSecret, &auth_params->client_secret);
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void StartupAppLauncher::OnOAuthFileLoaded(KioskOAuthParams* auth_params) {
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  auth_params_ = *auth_params;
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Override chrome client_id and secret that will be used for identity
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // API token minting.
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!auth_params_.client_id.empty() && !auth_params_.client_secret.empty()) {
149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    UserSessionManager::GetInstance()->SetAppModeChromeClientOAuthInfo(
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            auth_params_.client_id,
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            auth_params_.client_secret);
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // If we are restarting chrome (i.e. on crash), we need to initialize
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // OAuth2TokenService as well.
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  InitializeTokenService();
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
159effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid StartupAppLauncher::RestartLauncher() {
160effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // If the installer is still running in the background, we don't need to
161effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // restart the launch process. We will just wait until it completes and
162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // launches the kiosk app.
163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (extensions::ExtensionSystem::Get(profile_)
164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          ->extension_service()
165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          ->pending_extension_manager()
166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          ->IsIdPending(app_id_)) {
167effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    LOG(WARNING) << "Installer still running";
168effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return;
169effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
170effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
171effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MaybeInitializeNetwork();
172effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
173effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void StartupAppLauncher::MaybeInitializeNetwork() {
175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  network_ready_handled_ = false;
176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const Extension* extension = extensions::ExtensionSystem::Get(profile_)->
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extension_service()->GetInstalledExtension(app_id_);
179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool crx_cached = KioskAppManager::Get()->HasCachedCrx(app_id_);
180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const bool requires_network =
181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      (!extension && !crx_cached) ||
182116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      (extension &&
183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       !extensions::OfflineEnabledInfo::IsOfflineEnabled(extension));
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (requires_network) {
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    delegate_->InitializeNetwork();
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
190116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Update the offline enabled crx cache if the network is ready;
191116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // or just install the app.
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (delegate_->IsNetworkReady())
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ContinueWithNetworkReady();
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  else
195116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    BeginInstall();
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void StartupAppLauncher::InitializeTokenService() {
199a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  delegate_->OnInitializingTokenService();
2003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
201a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ProfileOAuth2TokenService* profile_token_service =
202a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SigninManagerBase* signin_manager =
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      SigninManagerFactory::GetForProfile(profile_);
205a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const std::string primary_account_id =
206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      signin_manager->GetAuthenticatedAccountId();
207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (profile_token_service->RefreshTokenIsAvailable(primary_account_id) ||
208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      auth_params_.refresh_token.empty()) {
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MaybeInitializeNetwork();
210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Pass oauth2 refresh token from the auth file.
212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // TODO(zelidrag): We should probably remove this option after M27.
213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // TODO(fgorski): This can go when we have persistence implemented on PO2TS.
214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Unless the code is no longer needed.
215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // TODO(rogerta): Now that this CL implements token persistence in PO2TS, is
216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // this code still needed?  See above two TODOs.
217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    //
218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // ProfileOAuth2TokenService triggers either OnRefreshTokenAvailable or
219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // OnRefreshTokensLoaded. Given that we want to handle exactly one event,
220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // whichever comes first, both handlers call RemoveObserver on PO2TS.
221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Handling any of the two events is the only way to resume the execution
222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // and enable Cleanup method to be called, self-invoking a destructor.
223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    profile_token_service->AddObserver(this);
224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    profile_token_service->UpdateCredentials(
226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        primary_account_id,
227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        auth_params_.refresh_token);
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
231a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void StartupAppLauncher::OnRefreshTokenAvailable(
232a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const std::string& account_id) {
233a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)
234a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      ->RemoveObserver(this);
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MaybeInitializeNetwork();
236a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
237a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
238a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void StartupAppLauncher::OnRefreshTokensLoaded() {
239a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)
240a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      ->RemoveObserver(this);
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MaybeInitializeNetwork();
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
244116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid StartupAppLauncher::MaybeLaunchApp() {
245116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Check if the app is offline enabled.
246116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const Extension* extension = extensions::ExtensionSystem::Get(profile_)
247116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   ->extension_service()
248116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   ->GetInstalledExtension(app_id_);
249116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(extension);
250116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const bool offline_enabled =
251116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      extensions::OfflineEnabledInfo::IsOfflineEnabled(extension);
252116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (offline_enabled || delegate_->IsNetworkReady()) {
253116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    BrowserThread::PostTask(
254116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        BrowserThread::UI,
255116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        FROM_HERE,
256116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        base::Bind(&StartupAppLauncher::OnReadyToLaunch, AsWeakPtr()));
257116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  } else {
258116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ++launch_attempt_;
259116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (launch_attempt_ < kMaxLaunchAttempt) {
260116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      BrowserThread::PostTask(
261116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          BrowserThread::UI,
262116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          FROM_HERE,
263116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          base::Bind(&StartupAppLauncher::MaybeInitializeNetwork, AsWeakPtr()));
264116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return;
265116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
266116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    OnLaunchFailure(KioskAppLaunchError::UNABLE_TO_LAUNCH);
267116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
268116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
269116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
270116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid StartupAppLauncher::OnFinishCrxInstall(const std::string& extension_id,
271116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                            bool success) {
272116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (extension_id != app_id_)
273116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
274116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
275116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  extensions::InstallTracker* tracker =
2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      extensions::InstallTrackerFactory::GetForBrowserContext(profile_);
277116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  tracker->RemoveObserver(this);
278116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (delegate_->IsShowingNetworkConfigScreen()) {
279116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    LOG(WARNING) << "Showing network config screen";
280116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
281116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
282116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
283116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (success) {
284116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    MaybeLaunchApp();
285116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
286116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
287116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
288116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  LOG(ERROR) << "Failed to install the kiosk application app_id: "
289116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             << extension_id;
290116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  OnLaunchFailure(KioskAppLaunchError::UNABLE_TO_INSTALL);
291116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
292116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
293116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid StartupAppLauncher::OnKioskExtensionLoadedInCache(
294116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const std::string& app_id) {
295116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  OnKioskAppDataLoadStatusChanged(app_id);
296116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
297116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
298116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid StartupAppLauncher::OnKioskExtensionDownloadFailed(
299116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const std::string& app_id) {
300116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  OnKioskAppDataLoadStatusChanged(app_id);
301116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
302116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
303116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid StartupAppLauncher::OnKioskAppDataLoadStatusChanged(
304116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const std::string& app_id) {
305116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (app_id != app_id_ || !wait_for_crx_update_)
306116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
307116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
308116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  wait_for_crx_update_ = false;
309116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (KioskAppManager::Get()->HasCachedCrx(app_id_))
310116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    BeginInstall();
311116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  else
312116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    OnLaunchFailure(KioskAppLaunchError::UNABLE_TO_DOWNLOAD);
313116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
314116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
31558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void StartupAppLauncher::LaunchApp() {
31658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!ready_to_launch_) {
31758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    NOTREACHED();
31858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    LOG(ERROR) << "LaunchApp() called but launcher is not initialized.";
31958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
32058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Extension* extension = extensions::ExtensionSystem::Get(profile_)->
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extension_service()->GetInstalledExtension(app_id_);
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(extension);
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!extensions::KioskModeInfo::IsKioskEnabled(extension)) {
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    OnLaunchFailure(KioskAppLaunchError::NOT_KIOSK_ENABLED);
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Always open the app in a window.
3314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  OpenApplication(AppLaunchParams(profile_, extension,
332a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                  extensions::LAUNCH_CONTAINER_WINDOW,
333a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                  NEW_WINDOW));
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  InitAppSession(profile_, app_id_);
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  user_manager::UserManager::Get()->SessionStarted();
33758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  content::NotificationService::current()->Notify(
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      chrome::NOTIFICATION_KIOSK_APP_LAUNCHED,
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      content::NotificationService::AllSources(),
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      content::NotificationService::NoDetails());
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (diagnostic_mode_)
3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    KioskDiagnosisRunner::Run(profile_, app_id_);
34523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
34623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  OnLaunchSuccess();
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void StartupAppLauncher::OnLaunchSuccess() {
3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delegate_->OnLaunchSucceeded();
3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void StartupAppLauncher::OnLaunchFailure(KioskAppLaunchError::Error error) {
3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  LOG(ERROR) << "App launch failed, error: " << error;
3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_NE(KioskAppLaunchError::NONE, error);
3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delegate_->OnLaunchFailed(error);
3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
360a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void StartupAppLauncher::OnUpdateCheckFinished() {
3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  OnReadyToLaunch();
362a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  UpdateAppData();
3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void StartupAppLauncher::BeginInstall() {
366116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  KioskAppManager::Get()->InstallFromCache(app_id_);
367116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (extensions::ExtensionSystem::Get(profile_)
368116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          ->extension_service()
369116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          ->pending_extension_manager()
370116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          ->IsIdPending(app_id_)) {
371116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    delegate_->OnInstallingApp();
372116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Observe the crx installation events.
373116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    extensions::InstallTracker* tracker =
3745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        extensions::InstallTrackerFactory::GetForBrowserContext(profile_);
375116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    tracker->AddObserver(this);
376a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
377a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
378a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
379116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (extensions::ExtensionSystem::Get(profile_)
380116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          ->extension_service()
381116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          ->GetInstalledExtension(app_id_)) {
382116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Launch the app.
383116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    OnReadyToLaunch();
384116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  } else {
385116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // The extension is skipped for installation due to some error.
386116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    OnLaunchFailure(KioskAppLaunchError::UNABLE_TO_INSTALL);
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
39058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void StartupAppLauncher::OnReadyToLaunch() {
39158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ready_to_launch_ = true;
392a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  delegate_->OnReadyToLaunch();
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void StartupAppLauncher::UpdateAppData() {
3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  KioskAppManager::Get()->ClearAppData(app_id_);
3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  KioskAppManager::Get()->UpdateAppDataFromProfile(app_id_, profile_, NULL);
3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}   // namespace chromeos
401