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"
3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/crx_file/id_util.h"
31effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "components/signin/core/browser/profile_oauth2_token_service.h"
32e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "components/signin/core/browser/signin_manager.h"
336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "components/user_manager/user_manager.h"
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/browser/notification_service.h"
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h"
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/manifest_handlers/kiosk_mode_info.h"
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/common/manifest_handlers/offline_enabled_info.h"
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "google_apis/gaia/gaia_auth_consumer.h"
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "google_apis/gaia/gaia_constants.h"
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/base/load_flags.h"
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_fetcher.h"
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_fetcher_delegate.h"
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_request_status.h"
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "url/gurl.h"
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::BrowserThread;
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using extensions::Extension;
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace chromeos {
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kOAuthRefreshToken[] = "refresh_token";
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kOAuthClientId[] = "client_id";
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kOAuthClientSecret[] = "client_secret";
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::FilePath::CharType kOAuthFileName[] =
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    FILE_PATH_LITERAL("kiosk_auth");
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst int kMaxLaunchAttempt = 5;
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace
663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)StartupAppLauncher::StartupAppLauncher(Profile* profile,
68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                       const std::string& app_id,
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       bool diagnostic_mode,
70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                       StartupAppLauncher::Delegate* delegate)
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : profile_(profile),
7258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      app_id_(app_id),
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      diagnostic_mode_(diagnostic_mode),
74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      delegate_(delegate),
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      network_ready_handled_(false),
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      launch_attempt_(0),
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ready_to_launch_(false),
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      wait_for_crx_update_(false) {
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(profile_);
8003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(crx_file::id_util::IdIsValid(app_id_));
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  KioskAppManager::Get()->AddObserver(this);
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)StartupAppLauncher::~StartupAppLauncher() {
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  KioskAppManager::Get()->RemoveObserver(this);
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // StartupAppLauncher can be deleted at anytime during the launch process
8858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // through a user bailout shortcut.
8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)
9058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      ->RemoveObserver(this);
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void StartupAppLauncher::Initialize() {
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  StartLoadingOAuthFile();
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void StartupAppLauncher::ContinueWithNetworkReady() {
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!network_ready_handled_) {
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    network_ready_handled_ = true;
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // The network might not be ready when KioskAppManager tries to update
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // external cache initially. Update the external cache now that the network
102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // is ready for sure.
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    wait_for_crx_update_ = true;
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    KioskAppManager::Get()->UpdateExternalCache();
105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void StartupAppLauncher::StartLoadingOAuthFile() {
109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  delegate_->OnLoadingOAuthFile();
1103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  KioskOAuthParams* auth_params = new KioskOAuthParams();
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BrowserThread::PostBlockingPoolTaskAndReply(
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FROM_HERE,
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&StartupAppLauncher::LoadOAuthFileOnBlockingPool,
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 auth_params),
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&StartupAppLauncher::OnOAuthFileLoaded,
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 AsWeakPtr(),
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Owned(auth_params)));
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static.
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void StartupAppLauncher::LoadOAuthFileOnBlockingPool(
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    KioskOAuthParams* auth_params) {
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int error_code = JSONFileValueSerializer::JSON_NO_ERROR;
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error_msg;
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::FilePath user_data_dir;
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir));
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::FilePath auth_file = user_data_dir.Append(kOAuthFileName);
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<JSONFileValueSerializer> serializer(
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new JSONFileValueSerializer(user_data_dir.Append(kOAuthFileName)));
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::Value> value(
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      serializer->Deserialize(&error_code, &error_msg));
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::DictionaryValue* dict = NULL;
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (error_code != JSONFileValueSerializer::JSON_NO_ERROR ||
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      !value.get() || !value->GetAsDictionary(&dict)) {
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    LOG(WARNING) << "Can't find auth file at " << auth_file.value();
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  dict->GetString(kOAuthRefreshToken, &auth_params->refresh_token);
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  dict->GetString(kOAuthClientId, &auth_params->client_id);
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  dict->GetString(kOAuthClientSecret, &auth_params->client_secret);
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void StartupAppLauncher::OnOAuthFileLoaded(KioskOAuthParams* auth_params) {
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  auth_params_ = *auth_params;
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Override chrome client_id and secret that will be used for identity
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // API token minting.
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!auth_params_.client_id.empty() && !auth_params_.client_secret.empty()) {
150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    UserSessionManager::GetInstance()->SetAppModeChromeClientOAuthInfo(
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            auth_params_.client_id,
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            auth_params_.client_secret);
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // If we are restarting chrome (i.e. on crash), we need to initialize
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // OAuth2TokenService as well.
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  InitializeTokenService();
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
160effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid StartupAppLauncher::RestartLauncher() {
161effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // If the installer is still running in the background, we don't need to
162effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // restart the launch process. We will just wait until it completes and
163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // launches the kiosk app.
164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (extensions::ExtensionSystem::Get(profile_)
165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          ->extension_service()
166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          ->pending_extension_manager()
167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          ->IsIdPending(app_id_)) {
168effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    LOG(WARNING) << "Installer still running";
169effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return;
170effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
171effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
172effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MaybeInitializeNetwork();
173effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
174effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void StartupAppLauncher::MaybeInitializeNetwork() {
176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  network_ready_handled_ = false;
177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const Extension* extension = extensions::ExtensionSystem::Get(profile_)->
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extension_service()->GetInstalledExtension(app_id_);
180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool crx_cached = KioskAppManager::Get()->HasCachedCrx(app_id_);
181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const bool requires_network =
182116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      (!extension && !crx_cached) ||
183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      (extension &&
184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       !extensions::OfflineEnabledInfo::IsOfflineEnabled(extension));
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (requires_network) {
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    delegate_->InitializeNetwork();
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
191116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Update the offline enabled crx cache if the network is ready;
192116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // or just install the app.
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (delegate_->IsNetworkReady())
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ContinueWithNetworkReady();
1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  else
196116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    BeginInstall();
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void StartupAppLauncher::InitializeTokenService() {
200a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  delegate_->OnInitializingTokenService();
2013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
202a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ProfileOAuth2TokenService* profile_token_service =
203a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SigninManagerBase* signin_manager =
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      SigninManagerFactory::GetForProfile(profile_);
206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const std::string primary_account_id =
207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      signin_manager->GetAuthenticatedAccountId();
208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (profile_token_service->RefreshTokenIsAvailable(primary_account_id) ||
209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      auth_params_.refresh_token.empty()) {
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MaybeInitializeNetwork();
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Pass oauth2 refresh token from the auth file.
213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // TODO(zelidrag): We should probably remove this option after M27.
214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // TODO(fgorski): This can go when we have persistence implemented on PO2TS.
215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Unless the code is no longer needed.
216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // TODO(rogerta): Now that this CL implements token persistence in PO2TS, is
217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // this code still needed?  See above two TODOs.
218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    //
219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // ProfileOAuth2TokenService triggers either OnRefreshTokenAvailable or
220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // OnRefreshTokensLoaded. Given that we want to handle exactly one event,
221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // whichever comes first, both handlers call RemoveObserver on PO2TS.
222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Handling any of the two events is the only way to resume the execution
223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // and enable Cleanup method to be called, self-invoking a destructor.
224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    profile_token_service->AddObserver(this);
225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    profile_token_service->UpdateCredentials(
227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        primary_account_id,
228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        auth_params_.refresh_token);
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
232a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void StartupAppLauncher::OnRefreshTokenAvailable(
233a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const std::string& account_id) {
234a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)
235a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      ->RemoveObserver(this);
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MaybeInitializeNetwork();
237a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
238a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
239a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void StartupAppLauncher::OnRefreshTokensLoaded() {
240a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)
241a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      ->RemoveObserver(this);
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MaybeInitializeNetwork();
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
245116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid StartupAppLauncher::MaybeLaunchApp() {
246116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Check if the app is offline enabled.
247116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const Extension* extension = extensions::ExtensionSystem::Get(profile_)
248116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   ->extension_service()
249116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   ->GetInstalledExtension(app_id_);
250116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(extension);
251116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const bool offline_enabled =
252116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      extensions::OfflineEnabledInfo::IsOfflineEnabled(extension);
253116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (offline_enabled || delegate_->IsNetworkReady()) {
254116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    BrowserThread::PostTask(
255116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        BrowserThread::UI,
256116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        FROM_HERE,
257116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        base::Bind(&StartupAppLauncher::OnReadyToLaunch, AsWeakPtr()));
258116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  } else {
259116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ++launch_attempt_;
260116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (launch_attempt_ < kMaxLaunchAttempt) {
261116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      BrowserThread::PostTask(
262116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          BrowserThread::UI,
263116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          FROM_HERE,
264116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          base::Bind(&StartupAppLauncher::MaybeInitializeNetwork, AsWeakPtr()));
265116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return;
266116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
267116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    OnLaunchFailure(KioskAppLaunchError::UNABLE_TO_LAUNCH);
268116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
269116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
270116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
271116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid StartupAppLauncher::OnFinishCrxInstall(const std::string& extension_id,
272116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                            bool success) {
273116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (extension_id != app_id_)
274116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
275116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
276116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  extensions::InstallTracker* tracker =
2775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      extensions::InstallTrackerFactory::GetForBrowserContext(profile_);
278116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  tracker->RemoveObserver(this);
279116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (delegate_->IsShowingNetworkConfigScreen()) {
280116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    LOG(WARNING) << "Showing network config screen";
281116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
282116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
283116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
284116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (success) {
285116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    MaybeLaunchApp();
286116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
287116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
288116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
289116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  LOG(ERROR) << "Failed to install the kiosk application app_id: "
290116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             << extension_id;
291116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  OnLaunchFailure(KioskAppLaunchError::UNABLE_TO_INSTALL);
292116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
293116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
294116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid StartupAppLauncher::OnKioskExtensionLoadedInCache(
295116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const std::string& app_id) {
296116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  OnKioskAppDataLoadStatusChanged(app_id);
297116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
298116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
299116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid StartupAppLauncher::OnKioskExtensionDownloadFailed(
300116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const std::string& app_id) {
301116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  OnKioskAppDataLoadStatusChanged(app_id);
302116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
303116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
304116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid StartupAppLauncher::OnKioskAppDataLoadStatusChanged(
305116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const std::string& app_id) {
306116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (app_id != app_id_ || !wait_for_crx_update_)
307116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
308116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
309116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  wait_for_crx_update_ = false;
310116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (KioskAppManager::Get()->HasCachedCrx(app_id_))
311116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    BeginInstall();
312116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  else
313116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    OnLaunchFailure(KioskAppLaunchError::UNABLE_TO_DOWNLOAD);
314116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
315116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
31658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void StartupAppLauncher::LaunchApp() {
31758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!ready_to_launch_) {
31858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    NOTREACHED();
31958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    LOG(ERROR) << "LaunchApp() called but launcher is not initialized.";
32058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
32158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Extension* extension = extensions::ExtensionSystem::Get(profile_)->
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extension_service()->GetInstalledExtension(app_id_);
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(extension);
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!extensions::KioskModeInfo::IsKioskEnabled(extension)) {
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    OnLaunchFailure(KioskAppLaunchError::NOT_KIOSK_ENABLED);
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Always open the app in a window.
3324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  OpenApplication(AppLaunchParams(profile_, extension,
333a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                  extensions::LAUNCH_CONTAINER_WINDOW,
334a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                  NEW_WINDOW));
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  InitAppSession(profile_, app_id_);
336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  user_manager::UserManager::Get()->SessionStarted();
33858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  content::NotificationService::current()->Notify(
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      chrome::NOTIFICATION_KIOSK_APP_LAUNCHED,
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      content::NotificationService::AllSources(),
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      content::NotificationService::NoDetails());
343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (diagnostic_mode_)
3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    KioskDiagnosisRunner::Run(profile_, app_id_);
34623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
34723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  OnLaunchSuccess();
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void StartupAppLauncher::OnLaunchSuccess() {
3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delegate_->OnLaunchSucceeded();
3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void StartupAppLauncher::OnLaunchFailure(KioskAppLaunchError::Error error) {
3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  LOG(ERROR) << "App launch failed, error: " << error;
3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_NE(KioskAppLaunchError::NONE, error);
3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delegate_->OnLaunchFailed(error);
3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
361a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void StartupAppLauncher::OnUpdateCheckFinished() {
3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  OnReadyToLaunch();
363a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  UpdateAppData();
3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void StartupAppLauncher::BeginInstall() {
367116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  KioskAppManager::Get()->InstallFromCache(app_id_);
368116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (extensions::ExtensionSystem::Get(profile_)
369116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          ->extension_service()
370116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          ->pending_extension_manager()
371116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          ->IsIdPending(app_id_)) {
372116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    delegate_->OnInstallingApp();
373116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Observe the crx installation events.
374116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    extensions::InstallTracker* tracker =
3755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        extensions::InstallTrackerFactory::GetForBrowserContext(profile_);
376116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    tracker->AddObserver(this);
377a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
378a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
379a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
380116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (extensions::ExtensionSystem::Get(profile_)
381116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          ->extension_service()
382116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          ->GetInstalledExtension(app_id_)) {
383116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Launch the app.
384116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    OnReadyToLaunch();
385116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  } else {
386116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // The extension is skipped for installation due to some error.
387116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    OnLaunchFailure(KioskAppLaunchError::UNABLE_TO_INSTALL);
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
39158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void StartupAppLauncher::OnReadyToLaunch() {
39258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ready_to_launch_ = true;
393a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  delegate_->OnReadyToLaunch();
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void StartupAppLauncher::UpdateAppData() {
3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  KioskAppManager::Get()->ClearAppData(app_id_);
3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  KioskAppManager::Get()->UpdateAppDataFromProfile(app_id_, profile_, NULL);
3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}   // namespace chromeos
402