Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(540)

Side by Side Diff: chrome/browser/chromeos/app_mode/startup_app_launcher.cc

Issue 22914008: Refactor kiosk app launch to be part of login screen UI flow. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/chromeos/app_mode/startup_app_launcher.h" 5 #include "chrome/browser/chromeos/app_mode/startup_app_launcher.h"
6 6
7 #include "ash/shell.h"
8 #include "base/command_line.h" 7 #include "base/command_line.h"
9 #include "base/files/file_path.h" 8 #include "base/files/file_path.h"
10 #include "base/json/json_file_value_serializer.h" 9 #include "base/json/json_file_value_serializer.h"
11 #include "base/path_service.h" 10 #include "base/path_service.h"
12 #include "base/time/time.h" 11 #include "base/time/time.h"
13 #include "base/values.h" 12 #include "base/values.h"
14 #include "chrome/browser/chrome_notification_types.h" 13 #include "chrome/browser/chrome_notification_types.h"
15 #include "chrome/browser/chromeos/app_mode/app_session_lifetime.h" 14 #include "chrome/browser/chromeos/app_mode/app_session_lifetime.h"
16 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" 15 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
17 #include "chrome/browser/chromeos/login/user_manager.h" 16 #include "chrome/browser/chromeos/login/user_manager.h"
18 #include "chrome/browser/chromeos/ui/app_launch_view.h"
19 #include "chrome/browser/extensions/extension_service.h" 17 #include "chrome/browser/extensions/extension_service.h"
20 #include "chrome/browser/extensions/extension_system.h" 18 #include "chrome/browser/extensions/extension_system.h"
21 #include "chrome/browser/extensions/webstore_startup_installer.h" 19 #include "chrome/browser/extensions/webstore_startup_installer.h"
22 #include "chrome/browser/lifetime/application_lifetime.h" 20 #include "chrome/browser/lifetime/application_lifetime.h"
23 #include "chrome/browser/signin/profile_oauth2_token_service.h" 21 #include "chrome/browser/signin/profile_oauth2_token_service.h"
24 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" 22 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
25 #include "chrome/browser/signin/token_service.h" 23 #include "chrome/browser/signin/token_service.h"
26 #include "chrome/browser/signin/token_service_factory.h" 24 #include "chrome/browser/signin/token_service_factory.h"
27 #include "chrome/browser/ui/extensions/application_launch.h" 25 #include "chrome/browser/ui/extensions/application_launch.h"
28 #include "chrome/common/chrome_paths.h" 26 #include "chrome/common/chrome_paths.h"
(...skipping 13 matching lines...) Expand all
42 40
43 namespace { 41 namespace {
44 42
45 const char kOAuthRefreshToken[] = "refresh_token"; 43 const char kOAuthRefreshToken[] = "refresh_token";
46 const char kOAuthClientId[] = "client_id"; 44 const char kOAuthClientId[] = "client_id";
47 const char kOAuthClientSecret[] = "client_secret"; 45 const char kOAuthClientSecret[] = "client_secret";
48 46
49 const base::FilePath::CharType kOAuthFileName[] = 47 const base::FilePath::CharType kOAuthFileName[] =
50 FILE_PATH_LITERAL("kiosk_auth"); 48 FILE_PATH_LITERAL("kiosk_auth");
51 49
52 // Application install splash screen minimum show time in milliseconds.
53 const int kAppInstallSplashScreenMinTimeMS = 3000;
54
55 bool IsAppInstalled(Profile* profile, const std::string& app_id) { 50 bool IsAppInstalled(Profile* profile, const std::string& app_id) {
56 return extensions::ExtensionSystem::Get(profile)->extension_service()-> 51 return extensions::ExtensionSystem::Get(profile)->extension_service()->
57 GetInstalledExtension(app_id); 52 GetInstalledExtension(app_id);
58 } 53 }
59 54
60 } // namespace 55 } // namespace
61 56
57
62 StartupAppLauncher::StartupAppLauncher(Profile* profile, 58 StartupAppLauncher::StartupAppLauncher(Profile* profile,
63 const std::string& app_id) 59 const std::string& app_id)
64 : profile_(profile), 60 : profile_(profile),
65 app_id_(app_id), 61 app_id_(app_id) {
66 launch_splash_start_time_(0) {
67 DCHECK(profile_); 62 DCHECK(profile_);
68 DCHECK(Extension::IdIsValid(app_id_)); 63 DCHECK(Extension::IdIsValid(app_id_));
69 DCHECK(ash::Shell::HasInstance());
70 ash::Shell::GetInstance()->AddPreTargetHandler(this);
71 } 64 }
72 65
73 StartupAppLauncher::~StartupAppLauncher() { 66 StartupAppLauncher::~StartupAppLauncher() {
74 DCHECK(ash::Shell::HasInstance());
75 ash::Shell::GetInstance()->RemovePreTargetHandler(this);
76 } 67 }
77 68
78 void StartupAppLauncher::Start() { 69 void StartupAppLauncher::Start() {
79 launch_splash_start_time_ = base::TimeTicks::Now().ToInternalValue();
80 DVLOG(1) << "Starting... connection = " 70 DVLOG(1) << "Starting... connection = "
81 << net::NetworkChangeNotifier::GetConnectionType(); 71 << net::NetworkChangeNotifier::GetConnectionType();
82 chromeos::ShowAppLaunchSplashScreen(app_id_);
83 StartLoadingOAuthFile(); 72 StartLoadingOAuthFile();
84 } 73 }
85 74
75 void StartupAppLauncher::AddObserver(Observer* observer) {
76 observer_list_.AddObserver(observer);
77 }
78
79 void StartupAppLauncher::RemoveObserver(Observer* observer) {
80 observer_list_.RemoveObserver(observer);
81 }
82
86 void StartupAppLauncher::StartLoadingOAuthFile() { 83 void StartupAppLauncher::StartLoadingOAuthFile() {
84 FOR_EACH_OBSERVER(Observer, observer_list_, OnLoadingOAuthFile());
85
87 KioskOAuthParams* auth_params = new KioskOAuthParams(); 86 KioskOAuthParams* auth_params = new KioskOAuthParams();
88 BrowserThread::PostBlockingPoolTaskAndReply( 87 BrowserThread::PostBlockingPoolTaskAndReply(
89 FROM_HERE, 88 FROM_HERE,
90 base::Bind(&StartupAppLauncher::LoadOAuthFileOnBlockingPool, 89 base::Bind(&StartupAppLauncher::LoadOAuthFileOnBlockingPool,
91 auth_params), 90 auth_params),
92 base::Bind(&StartupAppLauncher::OnOAuthFileLoaded, 91 base::Bind(&StartupAppLauncher::OnOAuthFileLoaded,
93 AsWeakPtr(), 92 AsWeakPtr(),
94 base::Owned(auth_params))); 93 base::Owned(auth_params)));
95 } 94 }
96 95
(...skipping 30 matching lines...) Expand all
127 auth_params_.client_id, 126 auth_params_.client_id,
128 auth_params_.client_secret); 127 auth_params_.client_secret);
129 } 128 }
130 129
131 // If we are restarting chrome (i.e. on crash), we need to initialize 130 // If we are restarting chrome (i.e. on crash), we need to initialize
132 // TokenService as well. 131 // TokenService as well.
133 InitializeTokenService(); 132 InitializeTokenService();
134 } 133 }
135 134
136 void StartupAppLauncher::InitializeNetwork() { 135 void StartupAppLauncher::InitializeNetwork() {
137 chromeos::UpdateAppLaunchSplashScreenState( 136 FOR_EACH_OBSERVER(Observer, observer_list_, OnInitializingNetwork());
138 chromeos::APP_LAUNCH_STATE_PREPARING_NETWORK); 137
139 // Set a maximum allowed wait time for network. 138 // Set a maximum allowed wait time for network.
140 const int kMaxNetworkWaitSeconds = 5 * 60; 139 const int kMaxNetworkWaitSeconds = 5 * 60;
141 network_wait_timer_.Start( 140 network_wait_timer_.Start(
142 FROM_HERE, 141 FROM_HERE,
143 base::TimeDelta::FromSeconds(kMaxNetworkWaitSeconds), 142 base::TimeDelta::FromSeconds(kMaxNetworkWaitSeconds),
144 this, &StartupAppLauncher::OnNetworkWaitTimedout); 143 this, &StartupAppLauncher::OnNetworkWaitTimedout);
145 144
146 net::NetworkChangeNotifier::AddNetworkChangeObserver(this); 145 net::NetworkChangeNotifier::AddNetworkChangeObserver(this);
147 OnNetworkChanged(net::NetworkChangeNotifier::GetConnectionType()); 146 OnNetworkChanged(net::NetworkChangeNotifier::GetConnectionType());
148 } 147 }
149 148
150 void StartupAppLauncher::InitializeTokenService() { 149 void StartupAppLauncher::InitializeTokenService() {
151 chromeos::UpdateAppLaunchSplashScreenState( 150 FOR_EACH_OBSERVER(Observer, observer_list_, OnInitializingTokenService());
152 chromeos::APP_LAUNCH_STATE_LOADING_TOKEN_SERVICE); 151
153 ProfileOAuth2TokenService* profile_token_service = 152 ProfileOAuth2TokenService* profile_token_service =
154 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); 153 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
155 if (profile_token_service->RefreshTokenIsAvailable()) { 154 if (profile_token_service->RefreshTokenIsAvailable()) {
156 InitializeNetwork(); 155 InitializeNetwork();
157 return; 156 return;
158 } 157 }
159 158
160 // At the end of this method, the execution will be put on hold until 159 // At the end of this method, the execution will be put on hold until
161 // ProfileOAuth2TokenService triggers either OnRefreshTokenAvailable or 160 // ProfileOAuth2TokenService triggers either OnRefreshTokenAvailable or
162 // OnRefreshTokensLoaded. Given that we want to handle exactly one event, 161 // OnRefreshTokensLoaded. Given that we want to handle exactly one event,
(...skipping 29 matching lines...) Expand all
192 ->RemoveObserver(this); 191 ->RemoveObserver(this);
193 InitializeNetwork(); 192 InitializeNetwork();
194 } 193 }
195 194
196 void StartupAppLauncher::OnRefreshTokensLoaded() { 195 void StartupAppLauncher::OnRefreshTokensLoaded() {
197 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_) 196 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)
198 ->RemoveObserver(this); 197 ->RemoveObserver(this);
199 InitializeNetwork(); 198 InitializeNetwork();
200 } 199 }
201 200
202 void StartupAppLauncher::Cleanup() {
203 chromeos::CloseAppLaunchSplashScreen();
204
205 delete this;
206 }
207
208 void StartupAppLauncher::OnLaunchSuccess() { 201 void StartupAppLauncher::OnLaunchSuccess() {
209 const int64 time_taken_ms = (base::TimeTicks::Now() - 202 FOR_EACH_OBSERVER(Observer, observer_list_, OnLaunchSucceeded());
210 base::TimeTicks::FromInternalValue(launch_splash_start_time_)).
211 InMilliseconds();
212
213 // Enforce that we show app install splash screen for some minimum amount
214 // of time.
215 if (time_taken_ms < kAppInstallSplashScreenMinTimeMS) {
216 BrowserThread::PostDelayedTask(
217 BrowserThread::UI,
218 FROM_HERE,
219 base::Bind(&StartupAppLauncher::OnLaunchSuccess, AsWeakPtr()),
220 base::TimeDelta::FromMilliseconds(
221 kAppInstallSplashScreenMinTimeMS - time_taken_ms));
222 return;
223 }
224
225 Cleanup();
226 } 203 }
227 204
228 void StartupAppLauncher::OnLaunchFailure(KioskAppLaunchError::Error error) { 205 void StartupAppLauncher::OnLaunchFailure(KioskAppLaunchError::Error error) {
206 LOG(ERROR) << "App launch failed";
229 DCHECK_NE(KioskAppLaunchError::NONE, error); 207 DCHECK_NE(KioskAppLaunchError::NONE, error);
230 208
231 // Saves the error and ends the session to go back to login screen. 209 FOR_EACH_OBSERVER(Observer, observer_list_, OnLaunchFailed(error));
232 KioskAppLaunchError::Save(error);
233 chrome::AttemptUserExit();
234
235 Cleanup();
236 } 210 }
237 211
238 void StartupAppLauncher::Launch() { 212 void StartupAppLauncher::Launch() {
239 const Extension* extension = extensions::ExtensionSystem::Get(profile_)-> 213 const Extension* extension = extensions::ExtensionSystem::Get(profile_)->
240 extension_service()->GetInstalledExtension(app_id_); 214 extension_service()->GetInstalledExtension(app_id_);
241 CHECK(extension); 215 CHECK(extension);
242 216
243 if (!extensions::KioskEnabledInfo::IsKioskEnabled(extension)) { 217 if (!extensions::KioskEnabledInfo::IsKioskEnabled(extension)) {
244 OnLaunchFailure(KioskAppLaunchError::NOT_KIOSK_ENABLED); 218 OnLaunchFailure(KioskAppLaunchError::NOT_KIOSK_ENABLED);
245 return; 219 return;
246 } 220 }
247 221
248 // Always open the app in a window. 222 // Always open the app in a window.
249 chrome::OpenApplication(chrome::AppLaunchParams(profile_, 223 chrome::OpenApplication(chrome::AppLaunchParams(profile_,
250 extension, 224 extension,
251 extension_misc::LAUNCH_WINDOW, 225 extension_misc::LAUNCH_WINDOW,
252 NEW_WINDOW)); 226 NEW_WINDOW));
253 InitAppSession(profile_, app_id_); 227 InitAppSession(profile_, app_id_);
254 228
255 content::NotificationService::current()->Notify( 229 content::NotificationService::current()->Notify(
256 chrome::NOTIFICATION_KIOSK_APP_LAUNCHED, 230 chrome::NOTIFICATION_KIOSK_APP_LAUNCHED,
257 content::NotificationService::AllSources(), 231 content::NotificationService::AllSources(),
258 content::NotificationService::NoDetails()); 232 content::NotificationService::NoDetails());
259 233
260 OnLaunchSuccess(); 234 OnLaunchSuccess();
261 } 235 }
262 236
263 void StartupAppLauncher::BeginInstall() { 237 void StartupAppLauncher::BeginInstall() {
238 FOR_EACH_OBSERVER(Observer, observer_list_, OnInstallingApp());
239
264 DVLOG(1) << "BeginInstall... connection = " 240 DVLOG(1) << "BeginInstall... connection = "
265 << net::NetworkChangeNotifier::GetConnectionType(); 241 << net::NetworkChangeNotifier::GetConnectionType();
266 242
267 chromeos::UpdateAppLaunchSplashScreenState(
268 chromeos::APP_LAUNCH_STATE_INSTALLING_APPLICATION);
269
270 if (IsAppInstalled(profile_, app_id_)) { 243 if (IsAppInstalled(profile_, app_id_)) {
271 Launch(); 244 Launch();
272 return; 245 return;
273 } 246 }
274 247
275 installer_ = new WebstoreStartupInstaller( 248 installer_ = new WebstoreStartupInstaller(
276 app_id_, 249 app_id_,
277 profile_, 250 profile_,
278 false, 251 false,
279 base::Bind(&StartupAppLauncher::InstallCallback, AsWeakPtr())); 252 base::Bind(&StartupAppLauncher::InstallCallback, AsWeakPtr()));
280 installer_->BeginInstall(); 253 installer_->BeginInstall();
281 } 254 }
282 255
283 void StartupAppLauncher::InstallCallback(bool success, 256 void StartupAppLauncher::InstallCallback(bool success,
284 const std::string& error) { 257 const std::string& error) {
285 installer_ = NULL; 258 installer_ = NULL;
286 if (success) { 259 if (success) {
287 // Schedules Launch() to be called after the callback returns. 260 // Schedules Launch() to be called after the callback returns.
288 // So that the app finishes its installation. 261 // So that the app finishes its installation.
289 BrowserThread::PostTask( 262 BrowserThread::PostTask(
290 BrowserThread::UI, 263 BrowserThread::UI,
291 FROM_HERE, 264 FROM_HERE,
292 base::Bind(&StartupAppLauncher::Launch, AsWeakPtr())); 265 base::Bind(&StartupAppLauncher::Launch, AsWeakPtr()));
293 return; 266 return;
294 } 267 }
295 268
296 LOG(ERROR) << "Failed to install app with error: " << error; 269 // TODO: revert this.
270 LOG(ERROR) << "Failed to install app with error: " << error << ".";
271 LOG(ERROR) << " " << app_id_;
297 OnLaunchFailure(KioskAppLaunchError::UNABLE_TO_INSTALL); 272 OnLaunchFailure(KioskAppLaunchError::UNABLE_TO_INSTALL);
298 } 273 }
299 274
300 void StartupAppLauncher::OnNetworkWaitTimedout() { 275 void StartupAppLauncher::OnNetworkWaitTimedout() {
301 LOG(WARNING) << "OnNetworkWaitTimedout... connection = " 276 LOG(WARNING) << "OnNetworkWaitTimedout... connection = "
302 << net::NetworkChangeNotifier::GetConnectionType(); 277 << net::NetworkChangeNotifier::GetConnectionType();
278
279 FOR_EACH_OBSERVER(Observer, observer_list_, OnNetworkWaitTimedout());
280
303 // Timeout in waiting for online. Try the install anyway. 281 // Timeout in waiting for online. Try the install anyway.
304 net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this); 282 net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
305 BeginInstall(); 283 BeginInstall();
306 } 284 }
307 285
308 void StartupAppLauncher::OnNetworkChanged( 286 void StartupAppLauncher::OnNetworkChanged(
309 net::NetworkChangeNotifier::ConnectionType type) { 287 net::NetworkChangeNotifier::ConnectionType type) {
310 DVLOG(1) << "OnNetworkChanged... connection = " 288 DVLOG(1) << "OnNetworkChanged... connection = "
311 << net::NetworkChangeNotifier::GetConnectionType(); 289 << net::NetworkChangeNotifier::GetConnectionType();
312 if (!net::NetworkChangeNotifier::IsOffline()) { 290 if (!net::NetworkChangeNotifier::IsOffline()) {
313 DVLOG(1) << "Network up and running!"; 291 DVLOG(1) << "Network up and running!";
314 net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this); 292 net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
315 network_wait_timer_.Stop(); 293 network_wait_timer_.Stop();
316 294
317 BeginInstall(); 295 BeginInstall();
318 } else { 296 } else {
319 DVLOG(1) << "Network not running yet!"; 297 DVLOG(1) << "Network not running yet!";
320 } 298 }
321 } 299 }
322 300
323 void StartupAppLauncher::OnKeyEvent(ui::KeyEvent* event) {
324 if (event->type() != ui::ET_KEY_PRESSED)
325 return;
326
327 if (KioskAppManager::Get()->GetDisableBailoutShortcut())
328 return;
329
330 if (event->key_code() != ui::VKEY_S ||
331 !(event->flags() & ui::EF_CONTROL_DOWN) ||
332 !(event->flags() & ui::EF_ALT_DOWN)) {
333 return;
334 }
335
336 OnLaunchFailure(KioskAppLaunchError::USER_CANCEL);
337 }
338
339 } // namespace chromeos 301 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/app_mode/startup_app_launcher.h ('k') | chrome/browser/chromeos/chrome_browser_main_chromeos.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698