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/browser_instant_controller.h" | 5 #include "chrome/browser/ui/browser_instant_controller.h" |
6 | 6 |
7 #include "chrome/browser/browser_shutdown.h" | 7 #include "chrome/browser/browser_shutdown.h" |
8 #include "chrome/browser/extensions/extension_service.h" | 8 #include "chrome/browser/extensions/extension_service.h" |
9 #include "chrome/browser/instant/instant_controller.h" | 9 #include "chrome/browser/instant/instant_controller.h" |
10 #include "chrome/browser/instant/instant_unload_handler.h" | 10 #include "chrome/browser/instant/instant_unload_handler.h" |
11 #include "chrome/browser/profiles/profile.h" | 11 #include "chrome/browser/profiles/profile.h" |
12 #include "chrome/browser/ui/browser.h" | 12 #include "chrome/browser/ui/browser.h" |
13 #include "chrome/browser/ui/browser_tabstrip.h" | 13 #include "chrome/browser/ui/browser_tabstrip.h" |
14 #include "chrome/browser/ui/browser_window.h" | 14 #include "chrome/browser/ui/browser_window.h" |
15 #include "chrome/browser/ui/omnibox/location_bar.h" | 15 #include "chrome/browser/ui/omnibox/location_bar.h" |
16 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 16 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
17 #include "chrome/browser/ui/tab_contents/tab_contents.h" | 17 #include "chrome/browser/ui/tab_contents/tab_contents.h" |
18 #include "chrome/browser/ui/webui/ntp/app_launcher_handler.h" | 18 #include "chrome/browser/ui/webui/ntp/app_launcher_handler.h" |
19 #include "chrome/common/chrome_notification_types.h" | 19 #include "chrome/common/chrome_notification_types.h" |
20 #include "chrome/common/pref_names.h" | 20 #include "chrome/common/pref_names.h" |
21 #include "content/public/browser/notification_service.h" | 21 #include "content/public/browser/notification_service.h" |
22 #include "content/public/browser/notification_source.h" | |
23 #include "content/public/browser/web_contents.h" | 22 #include "content/public/browser/web_contents.h" |
24 | 23 |
25 | |
26 namespace chrome { | 24 namespace chrome { |
27 | 25 |
28 //////////////////////////////////////////////////////////////////////////////// | 26 //////////////////////////////////////////////////////////////////////////////// |
29 // BrowserInstantController, public: | 27 // BrowserInstantController, public: |
30 | 28 |
31 BrowserInstantController::BrowserInstantController(Browser* browser) | 29 BrowserInstantController::BrowserInstantController(Browser* browser) |
32 : browser_(browser) { | 30 : browser_(browser) { |
33 profile_pref_registrar_.Init(browser_->profile()->GetPrefs()); | 31 profile_pref_registrar_.Init(browser_->profile()->GetPrefs()); |
34 profile_pref_registrar_.Add(prefs::kInstantEnabled, this); | 32 profile_pref_registrar_.Add(prefs::kInstantEnabled, this); |
35 CreateInstantIfNecessary(); | 33 ResetInstant(); |
36 browser_->tab_strip_model()->AddObserver(this); | 34 browser_->tab_strip_model()->AddObserver(this); |
37 } | 35 } |
38 | 36 |
39 BrowserInstantController::~BrowserInstantController() { | 37 BrowserInstantController::~BrowserInstantController() { |
40 browser_->tab_strip_model()->RemoveObserver(this); | 38 browser_->tab_strip_model()->RemoveObserver(this); |
41 } | 39 } |
42 | 40 |
43 bool BrowserInstantController::OpenInstant(WindowOpenDisposition disposition) { | 41 bool BrowserInstantController::OpenInstant(WindowOpenDisposition disposition) { |
44 if (!instant() || !instant()->PrepareForCommit() || | 42 // NEW_BACKGROUND_TAB results in leaving the omnibox open, so we don't attempt |
45 disposition == NEW_BACKGROUND_TAB) { | 43 // to use the Instant preview. |
46 // NEW_BACKGROUND_TAB results in leaving the omnibox open, so we don't | 44 if (!instant() || !instant_->IsCurrent() || disposition == NEW_BACKGROUND_TAB) |
47 // attempt to use the instant preview. | |
48 return false; | 45 return false; |
49 } | |
50 | 46 |
51 if (disposition == CURRENT_TAB) { | 47 if (disposition == CURRENT_TAB) { |
52 content::NotificationService::current()->Notify( | 48 content::NotificationService::current()->Notify( |
53 chrome::NOTIFICATION_INSTANT_COMMITTED, | 49 chrome::NOTIFICATION_INSTANT_COMMITTED, |
54 content::Source<TabContents>(instant()->CommitCurrentPreview( | 50 content::Source<TabContents>(instant_->CommitCurrentPreview( |
55 INSTANT_COMMIT_PRESSED_ENTER)), | 51 INSTANT_COMMIT_PRESSED_ENTER)), |
56 content::NotificationService::NoDetails()); | 52 content::NotificationService::NoDetails()); |
57 return true; | 53 return true; |
58 } | 54 } |
| 55 |
59 if (disposition == NEW_FOREGROUND_TAB) { | 56 if (disposition == NEW_FOREGROUND_TAB) { |
60 TabContents* preview_contents = instant()->ReleasePreviewContents( | 57 TabContents* preview = instant_->ReleasePreviewContents( |
61 INSTANT_COMMIT_PRESSED_ENTER, NULL); | 58 INSTANT_COMMIT_PRESSED_ENTER); |
62 // HideInstant is invoked after release so that InstantController is not | 59 preview->web_contents()->GetController().PruneAllButActive(); |
63 // active when HideInstant asks it for its state. | 60 browser_->tab_strip_model()->AddTabContents(preview, -1, |
64 HideInstant(); | 61 instant_->last_transition_type(), TabStripModel::ADD_ACTIVE); |
65 preview_contents->web_contents()->GetController().PruneAllButActive(); | |
66 browser_->tab_strip_model()->AddTabContents( | |
67 preview_contents, | |
68 -1, | |
69 instant()->last_transition_type(), | |
70 TabStripModel::ADD_ACTIVE); | |
71 instant()->CompleteRelease(preview_contents); | |
72 content::NotificationService::current()->Notify( | 62 content::NotificationService::current()->Notify( |
73 chrome::NOTIFICATION_INSTANT_COMMITTED, | 63 chrome::NOTIFICATION_INSTANT_COMMITTED, |
74 content::Source<TabContents>(preview_contents), | 64 content::Source<TabContents>(preview), |
75 content::NotificationService::NoDetails()); | 65 content::NotificationService::NoDetails()); |
76 return true; | 66 return true; |
77 } | 67 } |
| 68 |
78 // The omnibox currently doesn't use other dispositions, so we don't attempt | 69 // The omnibox currently doesn't use other dispositions, so we don't attempt |
79 // to handle them. If you hit this NOTREACHED file a bug and I'll (sky) add | 70 // to handle them. If you hit this NOTREACHED file a bug and I'll (sky) add |
80 // support for the new disposition. | 71 // support for the new disposition. |
81 NOTREACHED(); | 72 NOTREACHED(); |
82 return false; | 73 return false; |
83 } | 74 } |
84 | 75 |
85 //////////////////////////////////////////////////////////////////////////////// | 76 //////////////////////////////////////////////////////////////////////////////// |
86 // BrowserInstantController, InstantControllerDelegate implementation: | 77 // BrowserInstantController, InstantControllerDelegate implementation: |
87 | 78 |
88 void BrowserInstantController::ShowInstant(TabContents* preview_contents) { | 79 void BrowserInstantController::ShowInstant() { |
89 browser_->window()->ShowInstant(preview_contents); | 80 TabContents* preview = instant_->GetPreviewContents(); |
| 81 browser_->window()->ShowInstant(preview); |
90 | 82 |
91 // TODO(beng): investigate if we can avoid this and instead rely on the | 83 content::NotificationService::current()->Notify( |
92 // visibility of the WebContentsView | 84 chrome::NOTIFICATION_INSTANT_CONTROLLER_SHOWN, |
| 85 content::Source<InstantController>(instant()), |
| 86 content::NotificationService::NoDetails()); |
| 87 |
| 88 // TODO(beng): Investigate if we can avoid this and instead rely on the |
| 89 // visibility of the WebContentsView. |
93 chrome::GetActiveWebContents(browser_)->WasHidden(); | 90 chrome::GetActiveWebContents(browser_)->WasHidden(); |
94 preview_contents->web_contents()->WasShown(); | 91 preview->web_contents()->WasShown(); |
95 } | 92 } |
96 | 93 |
97 void BrowserInstantController::HideInstant() { | 94 void BrowserInstantController::HideInstant() { |
98 browser_->window()->HideInstant(); | 95 browser_->window()->HideInstant(); |
| 96 |
| 97 content::NotificationService::current()->Notify( |
| 98 chrome::NOTIFICATION_INSTANT_CONTROLLER_HIDDEN, |
| 99 content::Source<InstantController>(instant()), |
| 100 content::NotificationService::NoDetails()); |
| 101 |
99 if (chrome::GetActiveWebContents(browser_)) | 102 if (chrome::GetActiveWebContents(browser_)) |
100 chrome::GetActiveWebContents(browser_)->WasShown(); | 103 chrome::GetActiveWebContents(browser_)->WasShown(); |
101 if (instant_->GetPreviewContents()) | 104 if (TabContents* preview = instant_->GetPreviewContents()) |
102 instant_->GetPreviewContents()->web_contents()->WasHidden(); | 105 preview->web_contents()->WasHidden(); |
103 } | 106 } |
104 | 107 |
105 void BrowserInstantController::CommitInstant(TabContents* preview_contents) { | 108 void BrowserInstantController::CommitInstant(TabContents* preview) { |
106 TabContents* tab_contents = chrome::GetActiveTabContents(browser_); | 109 TabContents* active_tab = chrome::GetActiveTabContents(browser_); |
107 int index = browser_->tab_strip_model()->GetIndexOfTabContents(tab_contents); | 110 int index = browser_->tab_strip_model()->GetIndexOfTabContents(active_tab); |
108 DCHECK_NE(TabStripModel::kNoTab, index); | 111 DCHECK_NE(TabStripModel::kNoTab, index); |
109 // TabStripModel takes ownership of preview_contents. | 112 // TabStripModel takes ownership of |preview|. |
110 browser_->tab_strip_model()->ReplaceTabContentsAt(index, preview_contents); | 113 browser_->tab_strip_model()->ReplaceTabContentsAt(index, preview); |
111 // InstantUnloadHandler takes ownership of tab_contents. | 114 // InstantUnloadHandler takes ownership of |active_tab|. |
112 instant_unload_handler_->RunUnloadListenersOrDestroy(tab_contents, index); | 115 instant_unload_handler_->RunUnloadListenersOrDestroy(active_tab, index); |
113 | 116 |
114 GURL url = preview_contents->web_contents()->GetURL(); | 117 GURL url = preview->web_contents()->GetURL(); |
115 DCHECK(browser_->profile()->GetExtensionService()); | 118 DCHECK(browser_->profile()->GetExtensionService()); |
116 if (browser_->profile()->GetExtensionService()->IsInstalledApp(url)) { | 119 if (browser_->profile()->GetExtensionService()->IsInstalledApp(url)) { |
117 AppLauncherHandler::RecordAppLaunchType( | 120 AppLauncherHandler::RecordAppLaunchType( |
118 extension_misc::APP_LAUNCH_OMNIBOX_INSTANT); | 121 extension_misc::APP_LAUNCH_OMNIBOX_INSTANT); |
119 } | 122 } |
120 } | 123 } |
121 | 124 |
122 void BrowserInstantController::SetSuggestedText( | 125 void BrowserInstantController::SetSuggestedText( |
123 const string16& text, | 126 const string16& text, |
124 InstantCompleteBehavior behavior) { | 127 InstantCompleteBehavior behavior) { |
125 if (browser_->window()->GetLocationBar()) | 128 if (browser_->window()->GetLocationBar()) |
126 browser_->window()->GetLocationBar()->SetSuggestedText(text, behavior); | 129 browser_->window()->GetLocationBar()->SetSuggestedText(text, behavior); |
127 } | 130 } |
128 | 131 |
129 gfx::Rect BrowserInstantController::GetInstantBounds() { | 132 gfx::Rect BrowserInstantController::GetInstantBounds() { |
130 return browser_->window()->GetInstantBounds(); | 133 return browser_->window()->GetInstantBounds(); |
131 } | 134 } |
132 | 135 |
133 void BrowserInstantController::InstantPreviewFocused() { | 136 void BrowserInstantController::InstantPreviewFocused() { |
134 // NOTE: This is only invoked on aura. | 137 // NOTE: This is only invoked on aura. |
135 browser_->window()->WebContentsFocused( | 138 browser_->window()->WebContentsFocused( |
136 instant_->GetPreviewContents()->web_contents()); | 139 instant_->GetPreviewContents()->web_contents()); |
137 } | 140 } |
138 | 141 |
139 TabContents* BrowserInstantController::GetInstantHostTabContents() const { | 142 TabContents* BrowserInstantController::GetActiveTabContents() const { |
140 return chrome::GetActiveTabContents(browser_); | 143 return chrome::GetActiveTabContents(browser_); |
141 } | 144 } |
142 | 145 |
143 //////////////////////////////////////////////////////////////////////////////// | 146 //////////////////////////////////////////////////////////////////////////////// |
144 // BrowserInstantController, content::NotificationObserver implementation: | 147 // BrowserInstantController, content::NotificationObserver implementation: |
145 | 148 |
146 void BrowserInstantController::Observe( | 149 void BrowserInstantController::Observe( |
147 int type, | 150 int type, |
148 const content::NotificationSource& source, | 151 const content::NotificationSource& source, |
149 const content::NotificationDetails& details) { | 152 const content::NotificationDetails& details) { |
150 DCHECK(type == chrome::NOTIFICATION_PREF_CHANGED); | 153 DCHECK_EQ(chrome::NOTIFICATION_PREF_CHANGED, type); |
151 const std::string& pref_name = | 154 DCHECK_EQ(std::string(prefs::kInstantEnabled), |
152 *content::Details<std::string>(details).ptr(); | 155 *content::Details<std::string>(details).ptr()); |
153 DCHECK(pref_name == prefs::kInstantEnabled); | 156 ResetInstant(); |
154 if (browser_shutdown::ShuttingDownWithoutClosingBrowsers() || | |
155 !InstantController::IsEnabled(browser_->profile())) { | |
156 if (instant()) { | |
157 instant()->DestroyPreviewContents(); | |
158 instant_.reset(); | |
159 instant_unload_handler_.reset(); | |
160 } | |
161 } else { | |
162 CreateInstantIfNecessary(); | |
163 } | |
164 } | 157 } |
165 | 158 |
166 //////////////////////////////////////////////////////////////////////////////// | 159 //////////////////////////////////////////////////////////////////////////////// |
167 // BrowserInstantController, TabStripModelObserver implementation: | 160 // BrowserInstantController, TabStripModelObserver implementation: |
168 | 161 |
169 void BrowserInstantController::TabDeactivated(TabContents* contents) { | 162 void BrowserInstantController::TabDeactivated(TabContents* contents) { |
170 if (instant()) | 163 if (instant()) |
171 instant()->Hide(); | 164 instant_->Hide(); |
172 } | 165 } |
173 | 166 |
174 //////////////////////////////////////////////////////////////////////////////// | 167 //////////////////////////////////////////////////////////////////////////////// |
175 // BrowserInstantController, private: | 168 // BrowserInstantController, private: |
176 | 169 |
177 void BrowserInstantController::CreateInstantIfNecessary() { | 170 void BrowserInstantController::ResetInstant() { |
178 if (browser_->is_type_tabbed() && | 171 if (!browser_shutdown::ShuttingDownWithoutClosingBrowsers() && |
179 InstantController::IsEnabled(browser_->profile()) && | 172 InstantController::IsEnabled(browser_->profile()) && |
180 !browser_->profile()->IsOffTheRecord()) { | 173 browser_->is_type_tabbed() && !browser_->profile()->IsOffTheRecord()) { |
181 instant_.reset(new InstantController(this, InstantController::INSTANT)); | 174 instant_.reset(new InstantController(this, InstantController::INSTANT)); |
182 instant_unload_handler_.reset(new InstantUnloadHandler(browser_)); | 175 instant_unload_handler_.reset(new InstantUnloadHandler(browser_)); |
| 176 } else { |
| 177 instant_.reset(); |
| 178 instant_unload_handler_.reset(); |
183 } | 179 } |
184 } | 180 } |
185 | 181 |
186 } // namespace chrome | 182 } // namespace chrome |
OLD | NEW |