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

Side by Side Diff: chrome/browser/instant/instant_service.cc

Issue 12386019: Instant: Use only one hidden WebContents per profile. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 7 years, 9 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/instant/instant_service.h" 5 #include "chrome/browser/instant/instant_service.h"
6 6
7 #include "base/utf_string_conversions.h"
8 #include "chrome/browser/history/top_sites.h"
7 #include "chrome/browser/instant/instant_io_context.h" 9 #include "chrome/browser/instant/instant_io_context.h"
10 #include "chrome/browser/instant/instant_preloader.h"
11 #include "chrome/browser/instant/search.h"
8 #include "chrome/browser/profiles/profile.h" 12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/themes/theme_properties.h"
14 #include "chrome/browser/themes/theme_service.h"
15 #include "chrome/browser/themes/theme_service_factory.h"
9 #include "chrome/browser/ui/webui/ntp/thumbnail_source.h" 16 #include "chrome/browser/ui/webui/ntp/thumbnail_source.h"
10 #include "chrome/common/chrome_notification_types.h" 17 #include "chrome/common/chrome_notification_types.h"
18 #include "chrome/common/pref_names.h"
11 #include "content/public/browser/browser_thread.h" 19 #include "content/public/browser/browser_thread.h"
12 #include "content/public/browser/notification_service.h" 20 #include "content/public/browser/notification_service.h"
13 #include "content/public/browser/notification_types.h"
14 #include "content/public/browser/render_process_host.h" 21 #include "content/public/browser/render_process_host.h"
15 #include "content/public/browser/url_data_source.h" 22 #include "grit/theme_resources.h"
16 23 #include "ui/base/resource/resource_bundle.h"
17 using content::BrowserThread; 24 #include "ui/gfx/image/image_skia.h"
25 #include "ui/gfx/sys_color_change_listener.h"
26
27 namespace {
28
29 const size_t kMaxDebugEvents = 2000;
30
31 } // namespace
18 32
19 InstantService::InstantService(Profile* profile) 33 InstantService::InstantService(Profile* profile)
20 : profile_(profile) { 34 : profile_(profile),
35 omnibox_font_size_(0),
36 omnibox_start_margin_(0),
37 instant_pref_enabled_(false),
38 instant_enabled_(false) {
21 // Stub for unit tests. 39 // Stub for unit tests.
samarth 2013/03/11 19:03:24 Makes me slightly nervous. How about wrapping this
22 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) 40 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI))
23 return; 41 return;
24 42
25 registrar_.Add(this, 43 notification_registrar_.Add(this,
26 content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, 44 content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
27 content::NotificationService::AllSources()); 45 content::NotificationService::AllSources());
28 46
29 instant_io_context_ = new InstantIOContext(); 47 io_context_ = new InstantIOContext();
30 48
31 if (profile_ && profile_->GetResourceContext()) { 49 if (profile && profile->GetResourceContext()) {
32 BrowserThread::PostTask( 50 content::BrowserThread::PostTask(
33 BrowserThread::IO, FROM_HERE, 51 content::BrowserThread::IO, FROM_HERE,
34 base::Bind(&InstantIOContext::SetUserDataOnIO, 52 base::Bind(&InstantIOContext::SetUserDataOnIO,
35 profile->GetResourceContext(), instant_io_context_)); 53 profile->GetResourceContext(), io_context_));
36 } 54 }
37 55
38 content::URLDataSource::Add(profile, new ThumbnailSource(profile)); 56 content::URLDataSource::Add(profile, new ThumbnailSource(profile));
57
58 // In one mode of the InstantExtended experiments, the kInstantExtendedEnabled
59 // preference's default value is set to the existing value of kInstantEnabled.
60 // Because this requires reading the value of the kInstantEnabled value, we
61 // reset the default for kInstantExtendedEnabled here.
62 chrome::search::SetInstantExtendedPrefDefault(profile);
63
64 pref_change_registrar_.Init(profile->GetPrefs());
65 pref_change_registrar_.Add(
66 prefs::kInstantEnabled,
67 base::Bind(&InstantService::PrefChanged, base::Unretained(this)));
68 pref_change_registrar_.Add(
69 prefs::kInstantExtendedEnabled,
70 base::Bind(&InstantService::PrefChanged, base::Unretained(this)));
71 pref_change_registrar_.Add(
72 prefs::kSearchSuggestEnabled,
73 base::Bind(&InstantService::PrefChanged, base::Unretained(this)));
74 PrefChanged(std::string());
75
76 ThemeService* theme_service = ThemeServiceFactory::GetForProfile(profile);
77 notification_registrar_.Add(this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
78 content::Source<ThemeService>(theme_service));
79 ParseTheme(theme_service);
80
81 history::TopSites* top_sites = profile->GetTopSites();
82 notification_registrar_.Add(this, chrome::NOTIFICATION_TOP_SITES_CHANGED,
83 content::Source<history::TopSites>(top_sites));
84 RequestMostVisitedItems(top_sites);
85
86 // TODO(sail): Remove this once the Mac omnibox font size is updated.
87 #if defined(OS_MACOSX)
88 ui::ResourceBundle::FontStyle font_style = ui::ResourceBundle::BaseFont;
89 #else
90 ui::ResourceBundle::FontStyle font_style = ui::ResourceBundle::MediumFont;
91 #endif // defined(OS_MACOSX)
92 const gfx::Font& omnibox_font =
93 ui::ResourceBundle::GetSharedInstance().GetFont(font_style);
94 omnibox_font_name_ = UTF8ToUTF16(omnibox_font.GetFontName());
95 omnibox_font_size_ = omnibox_font.GetFontSize();
39 } 96 }
40 97
41 InstantService::~InstantService() { 98 InstantService::~InstantService() {
42 } 99 }
43 100
101 void InstantService::LogDebugEvent(const std::string& message) {
102 DVLOG(1) << message;
103 debug_events_.push_front(std::make_pair(base::Time::Now().ToInternalValue(),
104 message));
105 if (debug_events_.size() > kMaxDebugEvents)
106 debug_events_.pop_back();
107 }
108
109 void InstantService::ClearDebugEvents() {
110 debug_events_.clear();
111 }
112
113 void InstantService::AddObserver(InstantServiceObserver* observer) {
114 observers_.AddObserver(observer);
115
116 // If we just added our first observer, we have our first browser window.
samarth 2013/03/11 19:03:24 This seems too subtle and easy to go wrong. I'd pr
117 // Create the InstantPreloader (which will also register as an observer).
118 if (observers_.size() == 1)
119 preloader_.reset(new InstantPreloader(this));
120 }
121
122 void InstantService::RemoveObserver(InstantServiceObserver* observer) {
123 observers_.RemoveObserver(observer);
124
125 // If there's only one observer left, it must be the InstantPreloader. All
samarth 2013/03/11 19:03:24 Again, I'd prefer a more explicit signal if possib
126 // browser windows have closed, so kill the preloader, to work around
127 // http://crbug.com/180810.
128 if (observers_.size() == 1)
129 preloader_.reset();
130 }
131
132 bool InstantService::IsInstantProcess(int process_id) const {
133 return process_ids_.find(process_id) != process_ids_.end();
134 }
135
44 void InstantService::AddInstantProcess(int process_id) { 136 void InstantService::AddInstantProcess(int process_id) {
45 process_ids_.insert(process_id); 137 process_ids_.insert(process_id);
46 138
47 if (instant_io_context_) { 139 if (io_context_) {
48 BrowserThread::PostTask( 140 content::BrowserThread::PostTask(
49 BrowserThread::IO, FROM_HERE, 141 content::BrowserThread::IO, FROM_HERE,
50 base::Bind(&InstantIOContext::AddInstantProcessOnIO, 142 base::Bind(&InstantIOContext::AddInstantProcessOnIO,
51 instant_io_context_, process_id)); 143 io_context_, process_id));
52 } 144 }
53 } 145 }
54 146
55 bool InstantService::IsInstantProcess(int process_id) const { 147 void InstantService::RemoveInstantProcess(int process_id) {
56 return process_ids_.find(process_id) != process_ids_.end(); 148 process_ids_.erase(process_id);
57 } 149
58 150 if (io_context_) {
59 void InstantService::Shutdown() { 151 content::BrowserThread::PostTask(
60 process_ids_.clear(); 152 content::BrowserThread::IO, FROM_HERE,
61 153 base::Bind(&InstantIOContext::RemoveInstantProcessOnIO,
62 if (instant_io_context_) { 154 io_context_, process_id));
63 BrowserThread::PostTask( 155 }
64 BrowserThread::IO, FROM_HERE, 156 }
65 base::Bind(&InstantIOContext::ClearInstantProcessesOnIO, 157
66 instant_io_context_)); 158 void InstantService::InstantSupportDetermined() {
67 } 159 content::NotificationService::current()->Notify(
68 instant_io_context_ = NULL; 160 chrome::NOTIFICATION_INSTANT_SUPPORT_DETERMINED,
161 content::NotificationService::AllSources(),
162 content::NotificationService::NoDetails());
69 } 163 }
70 164
71 void InstantService::Observe(int type, 165 void InstantService::Observe(int type,
72 const content::NotificationSource& source, 166 const content::NotificationSource& source,
73 const content::NotificationDetails& details) { 167 const content::NotificationDetails& details) {
74 DCHECK_EQ(type, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED); 168 switch (type) {
75 int process_id = content::Source<content::RenderProcessHost>(source)->GetID(); 169 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED:
76 process_ids_.erase(process_id); 170 RemoveInstantProcess(
77 171 content::Source<content::RenderProcessHost>(source)->GetID());
78 if (instant_io_context_) { 172 break;
79 BrowserThread::PostTask( 173
80 BrowserThread::IO, FROM_HERE, 174 case chrome::NOTIFICATION_BROWSER_THEME_CHANGED:
81 base::Bind(&InstantIOContext::RemoveInstantProcessOnIO, 175 ParseTheme(content::Source<ThemeService>(source).ptr());
82 instant_io_context_, process_id)); 176 break;
83 } 177
84 } 178 case chrome::NOTIFICATION_TOP_SITES_CHANGED:
179 RequestMostVisitedItems(content::Source<history::TopSites>(source).ptr());
180 break;
181
182 default:
183 NOTREACHED();
184 break;
185 }
186 }
187
188 void InstantService::PrefChanged(const std::string& pref_name) {
189 if (pref_name == prefs::kInstantEnabled)
samarth 2013/03/11 19:03:24 I'm a little confused why you reset some of the pr
190 chrome::search::SetInstantExtendedPrefDefault(profile_);
191
192 bool instant_pref_enabled = chrome::search::IsInstantPrefEnabled(profile_);
193 bool instant_enabled = chrome::search::IsInstantEnabled(profile_);
194 if (instant_pref_enabled_ == instant_pref_enabled &&
195 instant_enabled_ == instant_enabled)
196 return;
197
198 instant_pref_enabled_ = instant_pref_enabled;
199 instant_enabled_ = instant_enabled;
200 FOR_EACH_OBSERVER(InstantServiceObserver, observers_, InstantStatusChanged());
201 }
202
203 void InstantService::ParseTheme(ThemeService* theme_service) {
204 theme_info_ = ThemeBackgroundInfo();
205
206 // Set theme background color.
207 SkColor background_color =
208 theme_service->GetColor(ThemeProperties::COLOR_NTP_BACKGROUND);
209 if (gfx::IsInvertedColorScheme())
210 background_color = color_utils::InvertColor(background_color);
211 theme_info_.color_r = SkColorGetR(background_color);
212 theme_info_.color_g = SkColorGetG(background_color);
213 theme_info_.color_b = SkColorGetB(background_color);
214 theme_info_.color_a = SkColorGetA(background_color);
215
216 if (!theme_service->HasCustomImage(IDR_THEME_NTP_BACKGROUND))
217 return;
218
219 // Set theme id for theme background image url.
220 theme_info_.theme_id = UTF8ToUTF16(theme_service->GetThemeID());
221
222 // Set theme background image horizontal alignment.
223 int alignment = 0;
224 theme_service->GetDisplayProperty(ThemeProperties::NTP_BACKGROUND_ALIGNMENT,
225 &alignment);
226 if (alignment & ThemeProperties::ALIGN_LEFT) {
samarth 2013/03/11 19:03:24 nit: no braces? (not sure if Chromium makes an ex
227 theme_info_.image_horizontal_alignment = THEME_BKGRND_IMAGE_ALIGN_LEFT;
228 } else if (alignment & ThemeProperties::ALIGN_RIGHT) {
229 theme_info_.image_horizontal_alignment = THEME_BKGRND_IMAGE_ALIGN_RIGHT;
230 } else { // ALIGN_CENTER
231 theme_info_.image_horizontal_alignment = THEME_BKGRND_IMAGE_ALIGN_CENTER;
232 }
233
234 // Set theme background image vertical alignment.
235 if (alignment & ThemeProperties::ALIGN_TOP) {
236 theme_info_.image_vertical_alignment = THEME_BKGRND_IMAGE_ALIGN_TOP;
237 } else if (alignment & ThemeProperties::ALIGN_BOTTOM) {
238 theme_info_.image_vertical_alignment = THEME_BKGRND_IMAGE_ALIGN_BOTTOM;
239 } else { // ALIGN_CENTER
240 theme_info_.image_vertical_alignment = THEME_BKGRND_IMAGE_ALIGN_CENTER;
241 }
242
243 // Set theme background image tiling.
244 int tiling = 0;
245 theme_service->GetDisplayProperty(ThemeProperties::NTP_BACKGROUND_TILING,
246 &tiling);
247 switch (tiling) {
248 case ThemeProperties::NO_REPEAT:
249 theme_info_.image_tiling = THEME_BKGRND_IMAGE_NO_REPEAT;
samarth 2013/03/11 19:03:24 Indent looks wrong
250 break;
251 case ThemeProperties::REPEAT_X:
252 theme_info_.image_tiling = THEME_BKGRND_IMAGE_REPEAT_X;
253 break;
254 case ThemeProperties::REPEAT_Y:
255 theme_info_.image_tiling = THEME_BKGRND_IMAGE_REPEAT_Y;
256 break;
257 case ThemeProperties::REPEAT:
258 theme_info_.image_tiling = THEME_BKGRND_IMAGE_REPEAT;
259 break;
260 }
261
262 // Set theme background image height.
263 gfx::ImageSkia* image = theme_service->GetImageSkiaNamed(
264 IDR_THEME_NTP_BACKGROUND);
265 DCHECK(image);
266 theme_info_.image_height = image->height();
267
268 FOR_EACH_OBSERVER(InstantServiceObserver, observers_, ThemeInfoChanged());
269 }
270
271 void InstantService::RequestMostVisitedItems(history::TopSites* top_sites) {
272 top_sites->GetMostVisitedURLs(
273 base::Bind(&InstantService::MostVisitedItemsReceived,
274 base::Unretained(this)));
275 }
276
277 void InstantService::MostVisitedItemsReceived(
278 const history::MostVisitedURLList& data) {
279 most_visited_items_.clear();
280 for (size_t i = 0; i < data.size(); ++i)
281 most_visited_items_.push_back(MostVisitedItem(data[i].url, data[i].title));
282
283 FOR_EACH_OBSERVER(InstantServiceObserver, observers_,
284 MostVisitedItemsChanged());
285 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698