OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/ui/tabs/pinned_tab_service.h" | 5 #include "chrome/browser/ui/tabs/pinned_tab_service.h" |
6 | 6 |
7 #include "chrome/browser/profiles/profile.h" | 7 #include "chrome/browser/profiles/profile.h" |
8 #include "chrome/browser/ui/browser.h" | 8 #include "chrome/browser/ui/browser.h" |
9 #include "chrome/browser/ui/browser_list.h" | 9 #include "chrome/browser/ui/browser_list.h" |
10 #include "chrome/browser/ui/tabs/pinned_tab_codec.h" | 10 #include "chrome/browser/ui/tabs/pinned_tab_codec.h" |
11 #include "chrome/common/chrome_notification_types.h" | 11 #include "chrome/common/chrome_notification_types.h" |
12 #include "content/public/browser/notification_service.h" | 12 #include "content/public/browser/notification_service.h" |
13 | 13 |
14 namespace { | 14 static bool IsLastNormalBrowser(Browser* browser) { |
15 | |
16 bool IsOnlyNormalBrowser(Browser* browser) { | |
17 for (BrowserList::const_iterator i = BrowserList::begin(); | 15 for (BrowserList::const_iterator i = BrowserList::begin(); |
18 i != BrowserList::end(); ++i) { | 16 i != BrowserList::end(); ++i) { |
19 if (*i != browser && (*i)->is_type_tabbed() && | 17 if (*i != browser && (*i)->is_type_tabbed() && |
20 (*i)->profile() == browser->profile()) { | 18 (*i)->profile() == browser->profile()) { |
21 return false; | 19 return false; |
22 } | 20 } |
23 } | 21 } |
24 return true; | 22 return true; |
25 } | 23 } |
26 | 24 |
27 } // namespace | |
28 | |
29 PinnedTabService::PinnedTabService(Profile* profile) | 25 PinnedTabService::PinnedTabService(Profile* profile) |
30 : profile_(profile), | 26 : profile_(profile), |
31 save_pinned_tabs_(true), | 27 got_exiting_(false), |
32 has_normal_browser_(false) { | 28 has_normal_browser_(false) { |
33 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_OPENED, | 29 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_OPENED, |
34 content::NotificationService::AllBrowserContextsAndSources()); | 30 content::NotificationService::AllBrowserContextsAndSources()); |
35 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_CLOSING, | 31 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_CLOSING, |
36 content::NotificationService::AllSources()); | 32 content::NotificationService::AllSources()); |
37 registrar_.Add(this, chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST, | 33 registrar_.Add(this, chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST, |
38 content::NotificationService::AllSources()); | 34 content::NotificationService::AllSources()); |
39 registrar_.Add(this, chrome::NOTIFICATION_TAB_ADDED, | |
40 content::NotificationService::AllSources()); | |
41 } | 35 } |
42 | 36 |
43 void PinnedTabService::Observe(int type, | 37 void PinnedTabService::Observe(int type, |
44 const content::NotificationSource& source, | 38 const content::NotificationSource& source, |
45 const content::NotificationDetails& details) { | 39 const content::NotificationDetails& details) { |
46 // Saving of tabs happens when saving is enabled, and when either the user | 40 if (got_exiting_) |
47 // exits the application or closes the last browser window. | 41 return; |
48 // Saving is disabled when the user exits the application to prevent the | 42 |
49 // pin state of all the open browsers being overwritten by the state of the | |
50 // last browser window to close. | |
51 // Saving is re-enabled when a browser window or tab is opened again. | |
52 // Note, cancelling a shutdown (via onbeforeunload) will not re-enable pinned | |
53 // tab saving immediately, to prevent the following situation: | |
54 // * two windows are open, one with pinned tabs | |
55 // * user exits | |
56 // * pinned tabs are saved | |
57 // * window with pinned tabs is closed | |
58 // * other window blocks close with onbeforeunload | |
59 // * user saves work, etc. then closes the window | |
60 // * pinned tabs are saved, without the window with the pinned tabs, | |
61 // over-writing the correct state. | |
62 // Saving is re-enabled if a new tab or window is opened. | |
63 switch (type) { | 43 switch (type) { |
64 case chrome::NOTIFICATION_BROWSER_OPENED: { | 44 case chrome::NOTIFICATION_BROWSER_OPENED: { |
65 Browser* browser = content::Source<Browser>(source).ptr(); | 45 Browser* browser = content::Source<Browser>(source).ptr(); |
66 if (!has_normal_browser_ && browser->is_type_tabbed() && | 46 if (!has_normal_browser_ && browser->is_type_tabbed() && |
67 browser->profile() == profile_) { | 47 browser->profile() == profile_) { |
68 has_normal_browser_ = true; | 48 has_normal_browser_ = true; |
69 } | 49 } |
70 save_pinned_tabs_ = true; | |
71 break; | |
72 } | |
73 | |
74 case chrome::NOTIFICATION_TAB_ADDED: { | |
75 save_pinned_tabs_ = true; | |
76 break; | 50 break; |
77 } | 51 } |
78 | 52 |
79 case chrome::NOTIFICATION_BROWSER_CLOSING: { | 53 case chrome::NOTIFICATION_BROWSER_CLOSING: { |
80 Browser* browser = content::Source<Browser>(source).ptr(); | 54 Browser* browser = content::Source<Browser>(source).ptr(); |
81 if (has_normal_browser_ && save_pinned_tabs_ && | 55 if (has_normal_browser_ && browser->profile() == profile_) { |
82 browser->profile() == profile_) { | 56 if (*(content::Details<bool>(details)).ptr()) { |
83 if (IsOnlyNormalBrowser(browser)) { | 57 GotExit(); |
| 58 } else if (IsLastNormalBrowser(browser)) { |
84 has_normal_browser_ = false; | 59 has_normal_browser_ = false; |
85 PinnedTabCodec::WritePinnedTabs(profile_); | 60 PinnedTabCodec::WritePinnedTabs(profile_); |
86 } | 61 } |
87 } | 62 } |
88 break; | 63 break; |
89 } | 64 } |
90 | 65 |
91 case chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST: { | 66 case chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST: { |
92 if (has_normal_browser_ && save_pinned_tabs_) { | 67 if (has_normal_browser_) |
93 PinnedTabCodec::WritePinnedTabs(profile_); | 68 GotExit(); |
94 save_pinned_tabs_ = false; | |
95 } | |
96 break; | 69 break; |
97 } | 70 } |
98 | 71 |
99 default: | 72 default: |
100 NOTREACHED(); | 73 NOTREACHED(); |
101 } | 74 } |
102 } | 75 } |
| 76 |
| 77 void PinnedTabService::GotExit() { |
| 78 DCHECK(!got_exiting_); |
| 79 got_exiting_ = true; |
| 80 PinnedTabCodec::WritePinnedTabs(profile_); |
| 81 } |
OLD | NEW |