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

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

Issue 141803014: Merge 244632 "kiosk: Do update check during launch." (Closed) Base URL: svn://svn.chromium.org/chrome/branches/1700/src/
Patch Set: Created 6 years, 11 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
« no previous file with comments | « chrome/browser/chromeos/app_mode/startup_app_launcher.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/files/file_path.h" 8 #include "base/files/file_path.h"
9 #include "base/json/json_file_value_serializer.h" 9 #include "base/json/json_file_value_serializer.h"
10 #include "base/path_service.h" 10 #include "base/path_service.h"
11 #include "base/time/time.h" 11 #include "base/time/time.h"
12 #include "base/values.h" 12 #include "base/values.h"
13 #include "chrome/browser/chrome_notification_types.h" 13 #include "chrome/browser/chrome_notification_types.h"
14 #include "chrome/browser/chromeos/app_mode/app_session_lifetime.h" 14 #include "chrome/browser/chromeos/app_mode/app_session_lifetime.h"
15 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" 15 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
16 #include "chrome/browser/chromeos/login/user_manager.h" 16 #include "chrome/browser/chromeos/login/user_manager.h"
17 #include "chrome/browser/extensions/extension_service.h" 17 #include "chrome/browser/extensions/extension_service.h"
18 #include "chrome/browser/extensions/extension_system.h" 18 #include "chrome/browser/extensions/extension_system.h"
19 #include "chrome/browser/extensions/updater/manifest_fetch_data.h"
20 #include "chrome/browser/extensions/updater/safe_manifest_parser.h"
19 #include "chrome/browser/extensions/webstore_startup_installer.h" 21 #include "chrome/browser/extensions/webstore_startup_installer.h"
20 #include "chrome/browser/lifetime/application_lifetime.h" 22 #include "chrome/browser/lifetime/application_lifetime.h"
21 #include "chrome/browser/signin/profile_oauth2_token_service.h" 23 #include "chrome/browser/signin/profile_oauth2_token_service.h"
22 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" 24 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
23 #include "chrome/browser/signin/token_service.h" 25 #include "chrome/browser/signin/token_service.h"
24 #include "chrome/browser/signin/token_service_factory.h" 26 #include "chrome/browser/signin/token_service_factory.h"
25 #include "chrome/browser/ui/extensions/application_launch.h" 27 #include "chrome/browser/ui/extensions/application_launch.h"
26 #include "chrome/common/chrome_paths.h" 28 #include "chrome/common/chrome_paths.h"
27 #include "chrome/common/chrome_switches.h" 29 #include "chrome/common/chrome_switches.h"
28 #include "chrome/common/extensions/extension.h" 30 #include "chrome/common/extensions/extension.h"
29 #include "chrome/common/extensions/manifest_handlers/kiosk_mode_info.h" 31 #include "chrome/common/extensions/manifest_handlers/kiosk_mode_info.h"
32 #include "chrome/common/chrome_version_info.h"
33 #include "chrome/common/extensions/manifest_url_handler.h"
30 #include "content/public/browser/browser_thread.h" 34 #include "content/public/browser/browser_thread.h"
31 #include "content/public/browser/notification_service.h" 35 #include "content/public/browser/notification_service.h"
32 #include "google_apis/gaia/gaia_auth_consumer.h" 36 #include "google_apis/gaia/gaia_auth_consumer.h"
33 #include "google_apis/gaia/gaia_constants.h" 37 #include "google_apis/gaia/gaia_constants.h"
38 #include "net/base/load_flags.h"
39 #include "net/url_request/url_fetcher.h"
40 #include "net/url_request/url_fetcher_delegate.h"
41 #include "net/url_request/url_request_context_getter.h"
42 #include "net/url_request/url_request_status.h"
43 #include "url/gurl.h"
34 44
35 using content::BrowserThread; 45 using content::BrowserThread;
36 using extensions::Extension; 46 using extensions::Extension;
37 using extensions::WebstoreStartupInstaller; 47 using extensions::WebstoreStartupInstaller;
38 48
39 namespace chromeos { 49 namespace chromeos {
40 50
41 namespace { 51 namespace {
42 52
43 const char kOAuthRefreshToken[] = "refresh_token"; 53 const char kOAuthRefreshToken[] = "refresh_token";
44 const char kOAuthClientId[] = "client_id"; 54 const char kOAuthClientId[] = "client_id";
45 const char kOAuthClientSecret[] = "client_secret"; 55 const char kOAuthClientSecret[] = "client_secret";
46 56
47 const base::FilePath::CharType kOAuthFileName[] = 57 const base::FilePath::CharType kOAuthFileName[] =
48 FILE_PATH_LITERAL("kiosk_auth"); 58 FILE_PATH_LITERAL("kiosk_auth");
49 59
50 bool IsAppInstalled(Profile* profile, const std::string& app_id) {
51 return extensions::ExtensionSystem::Get(profile)->extension_service()->
52 GetInstalledExtension(app_id);
53 }
54
55 } // namespace 60 } // namespace
56 61
62 class StartupAppLauncher::AppUpdateChecker
63 : public base::SupportsWeakPtr<AppUpdateChecker>,
64 public net::URLFetcherDelegate {
65 public:
66 explicit AppUpdateChecker(StartupAppLauncher* launcher)
67 : launcher_(launcher),
68 profile_(launcher->profile_),
69 app_id_(launcher->app_id_) {}
70 virtual ~AppUpdateChecker() {}
71
72 void Start() {
73 const Extension* app = GetInstalledApp();
74 if (!app) {
75 launcher_->OnUpdateCheckNotInstalled();
76 return;
77 }
78
79 GURL update_url = extensions::ManifestURL::GetUpdateURL(app);
80 if (update_url.is_empty())
81 update_url = extension_urls::GetWebstoreUpdateUrl();
82 if (!update_url.is_valid()) {
83 launcher_->OnUpdateCheckNoUpdate();
84 return;
85 }
86
87 manifest_fetch_data_.reset(
88 new extensions::ManifestFetchData(update_url, 0));
89 manifest_fetch_data_->AddExtension(
90 app_id_, app->version()->GetString(), NULL, "", "");
91
92 manifest_fetcher_.reset(net::URLFetcher::Create(
93 manifest_fetch_data_->full_url(), net::URLFetcher::GET, this));
94 manifest_fetcher_->SetRequestContext(profile_->GetRequestContext());
95 manifest_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
96 net::LOAD_DO_NOT_SAVE_COOKIES |
97 net::LOAD_DISABLE_CACHE);
98 manifest_fetcher_->SetAutomaticallyRetryOnNetworkChanges(3);
99 manifest_fetcher_->Start();
100 }
101
102 private:
103 const Extension* GetInstalledApp() {
104 ExtensionService* extension_service =
105 extensions::ExtensionSystem::Get(profile_)->extension_service();
106 return extension_service->GetInstalledExtension(app_id_);
107 }
108
109 void HandleManifestResults(const extensions::ManifestFetchData& fetch_data,
110 const UpdateManifest::Results* results) {
111 if (!results || results->list.empty()) {
112 launcher_->OnUpdateCheckNoUpdate();
113 return;
114 }
115
116 DCHECK_EQ(1u, results->list.size());
117
118 const UpdateManifest::Result& update = results->list[0];
119
120 if (update.browser_min_version.length() > 0) {
121 Version browser_version;
122 chrome::VersionInfo version_info;
123 if (version_info.is_valid())
124 browser_version = Version(version_info.Version());
125
126 Version browser_min_version(update.browser_min_version);
127 if (browser_version.IsValid() &&
128 browser_min_version.IsValid() &&
129 browser_min_version.CompareTo(browser_version) > 0) {
130 launcher_->OnUpdateCheckNoUpdate();
131 return;
132 }
133 }
134
135 const Version& existing_version = *GetInstalledApp()->version();
136 Version update_version(update.version);
137 if (existing_version.IsValid() &&
138 update_version.IsValid() &&
139 update_version.CompareTo(existing_version) <= 0) {
140 launcher_->OnUpdateCheckNoUpdate();
141 return;
142 }
143
144 launcher_->OnUpdateCheckUpdateAvailable();
145 }
146
147 // net::URLFetcherDelegate implementation.
148 virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE {
149 DCHECK_EQ(source, manifest_fetcher_.get());
150
151 if (source->GetStatus().status() != net::URLRequestStatus::SUCCESS ||
152 source->GetResponseCode() != 200) {
153 launcher_->OnUpdateCheckNoUpdate();
154 return;
155 }
156
157 std::string data;
158 source->GetResponseAsString(&data);
159 scoped_refptr<extensions::SafeManifestParser> safe_parser(
160 new extensions::SafeManifestParser(
161 data,
162 manifest_fetch_data_.release(),
163 base::Bind(&AppUpdateChecker::HandleManifestResults,
164 AsWeakPtr())));
165 safe_parser->Start();
166 }
167
168 StartupAppLauncher* launcher_;
169 Profile* profile_;
170 const std::string app_id_;
171
172 scoped_ptr<extensions::ManifestFetchData> manifest_fetch_data_;
173 scoped_ptr<net::URLFetcher> manifest_fetcher_;
174
175 DISALLOW_COPY_AND_ASSIGN(AppUpdateChecker);
176 };
57 177
58 StartupAppLauncher::StartupAppLauncher(Profile* profile, 178 StartupAppLauncher::StartupAppLauncher(Profile* profile,
59 const std::string& app_id) 179 const std::string& app_id)
60 : profile_(profile), 180 : profile_(profile),
61 app_id_(app_id), 181 app_id_(app_id),
62 ready_to_launch_(false) { 182 ready_to_launch_(false) {
63 DCHECK(profile_); 183 DCHECK(profile_);
64 DCHECK(Extension::IdIsValid(app_id_)); 184 DCHECK(Extension::IdIsValid(app_id_));
65 } 185 }
66 186
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 UserManager::Get()->SessionStarted(); 355 UserManager::Get()->SessionStarted();
236 356
237 content::NotificationService::current()->Notify( 357 content::NotificationService::current()->Notify(
238 chrome::NOTIFICATION_KIOSK_APP_LAUNCHED, 358 chrome::NOTIFICATION_KIOSK_APP_LAUNCHED,
239 content::NotificationService::AllSources(), 359 content::NotificationService::AllSources(),
240 content::NotificationService::NoDetails()); 360 content::NotificationService::NoDetails());
241 361
242 OnLaunchSuccess(); 362 OnLaunchSuccess();
243 } 363 }
244 364
245 void StartupAppLauncher::BeginInstall() { 365 void StartupAppLauncher::MaybeInstall() {
246 FOR_EACH_OBSERVER(Observer, observer_list_, OnInstallingApp()); 366 FOR_EACH_OBSERVER(Observer, observer_list_, OnInstallingApp());
247 367
248 DVLOG(1) << "BeginInstall... connection = " 368 update_checker_.reset(new AppUpdateChecker(this));
249 << net::NetworkChangeNotifier::GetConnectionType(); 369 update_checker_->Start();
370 }
250 371
251 if (IsAppInstalled(profile_, app_id_)) { 372 void StartupAppLauncher::OnUpdateCheckNotInstalled() {
252 OnReadyToLaunch(); 373 BeginInstall();
253 return; 374 }
254 }
255 375
376 void StartupAppLauncher::OnUpdateCheckUpdateAvailable() {
377 // Uninstall to force a re-install.
378 // TODO(xiyuan): Find a better way. Either download CRX and install it
379 // directly or integrate with ExtensionUpdater in someway.
380 ExtensionService* extension_service =
381 extensions::ExtensionSystem::Get(profile_)->extension_service();
382 extension_service->UninstallExtension(app_id_, false, NULL);
383
384 OnUpdateCheckNotInstalled();
385 }
386
387 void StartupAppLauncher::OnUpdateCheckNoUpdate() {
388 OnReadyToLaunch();
389 }
390
391 void StartupAppLauncher::BeginInstall() {
256 installer_ = new WebstoreStartupInstaller( 392 installer_ = new WebstoreStartupInstaller(
257 app_id_, 393 app_id_,
258 profile_, 394 profile_,
259 false, 395 false,
260 base::Bind(&StartupAppLauncher::InstallCallback, AsWeakPtr())); 396 base::Bind(&StartupAppLauncher::InstallCallback, AsWeakPtr()));
261 installer_->BeginInstall(); 397 installer_->BeginInstall();
262 } 398 }
263 399
264 void StartupAppLauncher::InstallCallback(bool success, 400 void StartupAppLauncher::InstallCallback(bool success,
265 const std::string& error) { 401 const std::string& error) {
266 installer_ = NULL; 402 installer_ = NULL;
267 if (success) { 403 if (success) {
268 // Finish initialization after the callback returns. 404 // Finish initialization after the callback returns.
269 // So that the app finishes its installation. 405 // So that the app finishes its installation.
270 BrowserThread::PostTask( 406 BrowserThread::PostTask(
271 BrowserThread::UI, 407 BrowserThread::UI,
272 FROM_HERE, 408 FROM_HERE,
273 base::Bind(&StartupAppLauncher::OnReadyToLaunch, 409 base::Bind(&StartupAppLauncher::OnReadyToLaunch,
274 AsWeakPtr())); 410 AsWeakPtr()));
411
412 // Schedule app data update after installation.
413 BrowserThread::PostTask(
414 BrowserThread::UI,
415 FROM_HERE,
416 base::Bind(&StartupAppLauncher::UpdateAppData,
417 AsWeakPtr()));
275 return; 418 return;
276 } 419 }
277 420
278 LOG(ERROR) << "App install failed: " << error; 421 LOG(ERROR) << "App install failed: " << error;
279 OnLaunchFailure(KioskAppLaunchError::UNABLE_TO_INSTALL); 422 OnLaunchFailure(KioskAppLaunchError::UNABLE_TO_INSTALL);
280 } 423 }
281 424
282 void StartupAppLauncher::OnReadyToLaunch() { 425 void StartupAppLauncher::OnReadyToLaunch() {
283 ready_to_launch_ = true; 426 ready_to_launch_ = true;
284 FOR_EACH_OBSERVER(Observer, observer_list_, OnReadyToLaunch()); 427 FOR_EACH_OBSERVER(Observer, observer_list_, OnReadyToLaunch());
285 } 428 }
286 429
287 void StartupAppLauncher::OnNetworkChanged( 430 void StartupAppLauncher::OnNetworkChanged(
288 net::NetworkChangeNotifier::ConnectionType type) { 431 net::NetworkChangeNotifier::ConnectionType type) {
289 DVLOG(1) << "OnNetworkChanged... connection = " 432 DVLOG(1) << "OnNetworkChanged... connection = "
290 << net::NetworkChangeNotifier::GetConnectionType(); 433 << net::NetworkChangeNotifier::GetConnectionType();
291 if (!net::NetworkChangeNotifier::IsOffline()) { 434 if (!net::NetworkChangeNotifier::IsOffline()) {
292 DVLOG(1) << "Network up and running!"; 435 DVLOG(1) << "Network up and running!";
293 net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this); 436 net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
294 437
295 BeginInstall(); 438 MaybeInstall();
296 } else { 439 } else {
297 DVLOG(1) << "Network not running yet!"; 440 DVLOG(1) << "Network not running yet!";
298 } 441 }
299 } 442 }
300 443
444 void StartupAppLauncher::UpdateAppData() {
445 KioskAppManager::Get()->ClearAppData(app_id_);
446 KioskAppManager::Get()->UpdateAppDataFromProfile(app_id_, profile_, NULL);
447 }
448
301 } // namespace chromeos 449 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/app_mode/startup_app_launcher.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698