OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/sessions/session_restore.h" | 5 #include "chrome/browser/sessions/session_restore.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/callback.h" | 9 #include "base/callback.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 Browser* browser, | 265 Browser* browser, |
266 bool synchronous, | 266 bool synchronous, |
267 bool clobber_existing_window, | 267 bool clobber_existing_window, |
268 bool always_create_tabbed_browser, | 268 bool always_create_tabbed_browser, |
269 const std::vector<GURL>& urls_to_open) | 269 const std::vector<GURL>& urls_to_open) |
270 : profile_(profile), | 270 : profile_(profile), |
271 browser_(browser), | 271 browser_(browser), |
272 synchronous_(synchronous), | 272 synchronous_(synchronous), |
273 clobber_existing_window_(clobber_existing_window), | 273 clobber_existing_window_(clobber_existing_window), |
274 always_create_tabbed_browser_(always_create_tabbed_browser), | 274 always_create_tabbed_browser_(always_create_tabbed_browser), |
275 urls_to_open_(urls_to_open) { | 275 urls_to_open_(urls_to_open), |
| 276 waiting_for_extension_service_(false) { |
276 } | 277 } |
277 | 278 |
278 void Restore() { | 279 void Restore() { |
279 SessionService* session_service = profile_->GetSessionService(); | 280 SessionService* session_service = profile_->GetSessionService(); |
280 DCHECK(session_service); | 281 DCHECK(session_service); |
281 SessionService::SessionCallback* callback = | 282 SessionService::SessionCallback* callback = |
282 NewCallback(this, &SessionRestoreImpl::OnGotSession); | 283 NewCallback(this, &SessionRestoreImpl::OnGotSession); |
283 session_service->GetLastSession(&request_consumer_, callback); | 284 session_service->GetLastSession(&request_consumer_, callback); |
284 | 285 |
285 if (synchronous_) { | 286 if (synchronous_) { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
331 } | 332 } |
332 | 333 |
333 virtual void Observe(NotificationType type, | 334 virtual void Observe(NotificationType type, |
334 const NotificationSource& source, | 335 const NotificationSource& source, |
335 const NotificationDetails& details) { | 336 const NotificationDetails& details) { |
336 switch (type.value) { | 337 switch (type.value) { |
337 case NotificationType::BROWSER_CLOSED: | 338 case NotificationType::BROWSER_CLOSED: |
338 delete this; | 339 delete this; |
339 return; | 340 return; |
340 | 341 |
| 342 case NotificationType::EXTENSIONS_READY: { |
| 343 if (!waiting_for_extension_service_) |
| 344 return; |
| 345 |
| 346 waiting_for_extension_service_ = false; |
| 347 if (synchronous_) { |
| 348 MessageLoop::current()->Quit(); |
| 349 return; |
| 350 } |
| 351 ProcessSessionWindows(&windows_); |
| 352 return; |
| 353 } |
| 354 |
341 default: | 355 default: |
342 NOTREACHED(); | 356 NOTREACHED(); |
343 break; | 357 break; |
344 } | 358 } |
345 } | 359 } |
346 | 360 |
347 private: | 361 private: |
348 // Invoked when done with creating all the tabs/browsers. | 362 // Invoked when done with creating all the tabs/browsers. |
349 // | 363 // |
350 // |created_tabbed_browser| indicates whether a tabbed browser was created, | 364 // |created_tabbed_browser| indicates whether a tabbed browser was created, |
(...skipping 24 matching lines...) Expand all Loading... |
375 // If we're not synchronous we need to delete ourself. | 389 // If we're not synchronous we need to delete ourself. |
376 // NOTE: we must use DeleteLater here as most likely we're in a callback | 390 // NOTE: we must use DeleteLater here as most likely we're in a callback |
377 // from the history service which doesn't deal well with deleting the | 391 // from the history service which doesn't deal well with deleting the |
378 // object it is notifying. | 392 // object it is notifying. |
379 MessageLoop::current()->DeleteSoon(FROM_HERE, this); | 393 MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
380 } | 394 } |
381 } | 395 } |
382 | 396 |
383 void OnGotSession(SessionService::Handle handle, | 397 void OnGotSession(SessionService::Handle handle, |
384 std::vector<SessionWindow*>* windows) { | 398 std::vector<SessionWindow*>* windows) { |
| 399 if (HasExtensionApps(*windows) && profile_->GetExtensionsService() && |
| 400 !profile_->GetExtensionsService()->is_ready()) { |
| 401 // At least one tab is an app tab and the extension service hasn't |
| 402 // finished loading. Wait to continue processing until the extensions |
| 403 // service finishes loading. |
| 404 registrar_.Add(this, NotificationType::EXTENSIONS_READY, |
| 405 Source<Profile>(profile_)); |
| 406 windows_.swap(*windows); |
| 407 waiting_for_extension_service_ = true; |
| 408 return; |
| 409 } |
| 410 |
385 if (synchronous_) { | 411 if (synchronous_) { |
386 // See comment above windows_ as to why we don't process immediately. | 412 // See comment above windows_ as to why we don't process immediately. |
387 windows_.swap(*windows); | 413 windows_.swap(*windows); |
388 MessageLoop::current()->Quit(); | 414 MessageLoop::current()->Quit(); |
389 return; | 415 return; |
390 } | 416 } |
391 | 417 |
392 ProcessSessionWindows(windows); | 418 ProcessSessionWindows(windows); |
393 } | 419 } |
394 | 420 |
| 421 // Returns true if any tab in |windows| has an application extension id. |
| 422 bool HasExtensionApps(const std::vector<SessionWindow*>& windows) { |
| 423 for (std::vector<SessionWindow*>::const_iterator i = windows.begin(); |
| 424 i != windows.end(); ++i) { |
| 425 if (HasExtensionApps((*i)->tabs)) |
| 426 return true; |
| 427 } |
| 428 |
| 429 return false; |
| 430 } |
| 431 |
| 432 // Returns true if any tab in |tabs| has an application extension id. |
| 433 bool HasExtensionApps(const std::vector<SessionTab*>& tabs) { |
| 434 for (std::vector<SessionTab*>::const_iterator i = tabs.begin(); |
| 435 i != tabs.end(); ++i) { |
| 436 if (!(*i)->extension_app_id.empty()) |
| 437 return true; |
| 438 } |
| 439 |
| 440 return false; |
| 441 } |
| 442 |
395 void ProcessSessionWindows(std::vector<SessionWindow*>* windows) { | 443 void ProcessSessionWindows(std::vector<SessionWindow*>* windows) { |
396 if (windows->empty()) { | 444 if (windows->empty()) { |
397 // Restore was unsuccessful. | 445 // Restore was unsuccessful. |
398 FinishedTabCreation(false, false); | 446 FinishedTabCreation(false, false); |
399 return; | 447 return; |
400 } | 448 } |
401 | 449 |
402 tab_loader_.reset(new TabLoader()); | 450 tab_loader_.reset(new TabLoader()); |
403 | 451 |
404 Browser* current_browser = | 452 Browser* current_browser = |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
546 | 594 |
547 // Responsible for loading the tabs. | 595 // Responsible for loading the tabs. |
548 scoped_ptr<TabLoader> tab_loader_; | 596 scoped_ptr<TabLoader> tab_loader_; |
549 | 597 |
550 // When synchronous we run a nested message loop. To avoid creating windows | 598 // When synchronous we run a nested message loop. To avoid creating windows |
551 // from the nested message loop (which can make exiting the nested message | 599 // from the nested message loop (which can make exiting the nested message |
552 // loop take a while) we cache the SessionWindows here and create the actual | 600 // loop take a while) we cache the SessionWindows here and create the actual |
553 // windows when the nested message loop exits. | 601 // windows when the nested message loop exits. |
554 std::vector<SessionWindow*> windows_; | 602 std::vector<SessionWindow*> windows_; |
555 | 603 |
| 604 // If true, indicates at least one tab has an application extension id and |
| 605 // we're waiting for the extension service to finish loading. |
| 606 bool waiting_for_extension_service_; |
| 607 |
556 NotificationRegistrar registrar_; | 608 NotificationRegistrar registrar_; |
557 }; | 609 }; |
558 | 610 |
559 } // namespace | 611 } // namespace |
560 | 612 |
561 // SessionRestore ------------------------------------------------------------- | 613 // SessionRestore ------------------------------------------------------------- |
562 | 614 |
563 static void Restore(Profile* profile, | 615 static void Restore(Profile* profile, |
564 Browser* browser, | 616 Browser* browser, |
565 bool synchronous, | 617 bool synchronous, |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
612 void SessionRestore::RestoreSessionSynchronously( | 664 void SessionRestore::RestoreSessionSynchronously( |
613 Profile* profile, | 665 Profile* profile, |
614 const std::vector<GURL>& urls_to_open) { | 666 const std::vector<GURL>& urls_to_open) { |
615 Restore(profile, NULL, true, false, true, urls_to_open); | 667 Restore(profile, NULL, true, false, true, urls_to_open); |
616 } | 668 } |
617 | 669 |
618 // static | 670 // static |
619 bool SessionRestore::IsRestoring() { | 671 bool SessionRestore::IsRestoring() { |
620 return restoring; | 672 return restoring; |
621 } | 673 } |
OLD | NEW |