OLD | NEW |
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/search/instant_service.h" | 5 #include "chrome/browser/search/instant_service.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
11 #include "build/build_config.h" | 11 #include "build/build_config.h" |
12 #include "chrome/browser/history/history_notifications.h" | 12 #include "chrome/browser/history/history_notifications.h" |
13 #include "chrome/browser/history/top_sites.h" | 13 #include "chrome/browser/history/top_sites.h" |
14 #include "chrome/browser/profiles/profile.h" | 14 #include "chrome/browser/profiles/profile.h" |
15 #include "chrome/browser/search/instant_io_context.h" | 15 #include "chrome/browser/search/instant_io_context.h" |
16 #include "chrome/browser/search/instant_service_factory.h" | 16 #include "chrome/browser/search/instant_service_factory.h" |
| 17 #include "chrome/browser/search/instant_service_observer.h" |
17 #include "chrome/browser/search/local_ntp_source.h" | 18 #include "chrome/browser/search/local_ntp_source.h" |
18 #include "chrome/browser/search/most_visited_iframe_source.h" | 19 #include "chrome/browser/search/most_visited_iframe_source.h" |
19 #include "chrome/browser/search/search.h" | 20 #include "chrome/browser/search/search.h" |
20 #include "chrome/browser/search/suggestion_iframe_source.h" | 21 #include "chrome/browser/search/suggestion_iframe_source.h" |
| 22 #include "chrome/browser/themes/theme_properties.h" |
| 23 #include "chrome/browser/themes/theme_service.h" |
| 24 #include "chrome/browser/themes/theme_service_factory.h" |
21 #include "chrome/browser/ui/browser.h" | 25 #include "chrome/browser/ui/browser.h" |
22 #include "chrome/browser/ui/browser_instant_controller.h" | 26 #include "chrome/browser/ui/browser_instant_controller.h" |
23 #include "chrome/browser/ui/browser_list.h" | 27 #include "chrome/browser/ui/browser_list.h" |
24 #include "chrome/browser/ui/host_desktop.h" | 28 #include "chrome/browser/ui/host_desktop.h" |
25 #include "chrome/browser/ui/search/instant_controller.h" | 29 #include "chrome/browser/ui/search/instant_controller.h" |
26 #include "chrome/browser/ui/webui/favicon_source.h" | 30 #include "chrome/browser/ui/webui/favicon_source.h" |
27 #include "chrome/browser/ui/webui/ntp/thumbnail_source.h" | 31 #include "chrome/browser/ui/webui/ntp/thumbnail_source.h" |
28 #include "chrome/browser/ui/webui/theme_source.h" | 32 #include "chrome/browser/ui/webui/theme_source.h" |
29 #include "chrome/common/chrome_notification_types.h" | 33 #include "chrome/common/chrome_notification_types.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 "content/public/browser/notification_types.h" | 36 #include "content/public/browser/notification_types.h" |
33 #include "content/public/browser/render_process_host.h" | 37 #include "content/public/browser/render_process_host.h" |
34 #include "content/public/browser/url_data_source.h" | 38 #include "content/public/browser/url_data_source.h" |
35 #include "googleurl/src/gurl.h" | 39 #include "googleurl/src/gurl.h" |
| 40 #include "grit/theme_resources.h" |
36 #include "net/url_request/url_request.h" | 41 #include "net/url_request/url_request.h" |
| 42 #include "ui/gfx/color_utils.h" |
| 43 #include "ui/gfx/image/image_skia.h" |
| 44 #include "ui/gfx/sys_color_change_listener.h" |
37 | 45 |
38 using content::BrowserThread; | 46 using content::BrowserThread; |
39 | 47 |
40 InstantService::InstantService(Profile* profile) | 48 InstantService::InstantService(Profile* profile) |
41 : profile_(profile), | 49 : profile_(profile), |
42 weak_ptr_factory_(this) { | 50 weak_ptr_factory_(this) { |
43 // Stub for unit tests. | 51 // Stub for unit tests. |
44 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) | 52 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) |
45 return; | 53 return; |
46 | 54 |
(...skipping 11 matching lines...) Expand all Loading... |
58 | 66 |
59 if (profile_ && profile_->GetResourceContext()) { | 67 if (profile_ && profile_->GetResourceContext()) { |
60 BrowserThread::PostTask( | 68 BrowserThread::PostTask( |
61 BrowserThread::IO, FROM_HERE, | 69 BrowserThread::IO, FROM_HERE, |
62 base::Bind(&InstantIOContext::SetUserDataOnIO, | 70 base::Bind(&InstantIOContext::SetUserDataOnIO, |
63 profile->GetResourceContext(), instant_io_context_)); | 71 profile->GetResourceContext(), instant_io_context_)); |
64 } | 72 } |
65 | 73 |
66 // Set up the data sources that Instant uses on the NTP. | 74 // Set up the data sources that Instant uses on the NTP. |
67 #if defined(ENABLE_THEMES) | 75 #if defined(ENABLE_THEMES) |
| 76 // Listen for theme installation. |
| 77 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED, |
| 78 content::Source<ThemeService>( |
| 79 ThemeServiceFactory::GetForProfile(profile_))); |
| 80 |
68 content::URLDataSource::Add(profile, new ThemeSource(profile)); | 81 content::URLDataSource::Add(profile, new ThemeSource(profile)); |
69 #endif | 82 #endif // defined(ENABLE_THEMES) |
| 83 |
70 content::URLDataSource::Add(profile, new ThumbnailSource(profile)); | 84 content::URLDataSource::Add(profile, new ThumbnailSource(profile)); |
71 content::URLDataSource::Add(profile, new FaviconSource( | 85 content::URLDataSource::Add(profile, new FaviconSource( |
72 profile, FaviconSource::FAVICON)); | 86 profile, FaviconSource::FAVICON)); |
73 content::URLDataSource::Add(profile, new LocalNtpSource()); | 87 content::URLDataSource::Add(profile, new LocalNtpSource()); |
74 content::URLDataSource::Add(profile, new SuggestionIframeSource()); | 88 content::URLDataSource::Add(profile, new SuggestionIframeSource()); |
75 content::URLDataSource::Add(profile, new MostVisitedIframeSource()); | 89 content::URLDataSource::Add(profile, new MostVisitedIframeSource()); |
76 } | 90 } |
77 | 91 |
78 InstantService::~InstantService() { | 92 InstantService::~InstantService() { |
79 } | 93 } |
80 | 94 |
81 void InstantService::AddInstantProcess(int process_id) { | 95 void InstantService::AddInstantProcess(int process_id) { |
82 process_ids_.insert(process_id); | 96 process_ids_.insert(process_id); |
83 | 97 |
84 if (instant_io_context_.get()) { | 98 if (instant_io_context_.get()) { |
85 BrowserThread::PostTask(BrowserThread::IO, | 99 BrowserThread::PostTask(BrowserThread::IO, |
86 FROM_HERE, | 100 FROM_HERE, |
87 base::Bind(&InstantIOContext::AddInstantProcessOnIO, | 101 base::Bind(&InstantIOContext::AddInstantProcessOnIO, |
88 instant_io_context_, | 102 instant_io_context_, |
89 process_id)); | 103 process_id)); |
90 } | 104 } |
91 } | 105 } |
92 | 106 |
93 bool InstantService::IsInstantProcess(int process_id) const { | 107 bool InstantService::IsInstantProcess(int process_id) const { |
94 return process_ids_.find(process_id) != process_ids_.end(); | 108 return process_ids_.find(process_id) != process_ids_.end(); |
95 } | 109 } |
96 | 110 |
| 111 void InstantService::AddObserver(InstantServiceObserver* observer) { |
| 112 observers_.AddObserver(observer); |
| 113 } |
| 114 |
| 115 void InstantService::RemoveObserver(InstantServiceObserver* observer) { |
| 116 observers_.RemoveObserver(observer); |
| 117 } |
| 118 |
97 void InstantService::DeleteMostVisitedItem(const GURL& url) { | 119 void InstantService::DeleteMostVisitedItem(const GURL& url) { |
98 history::TopSites* top_sites = profile_->GetTopSites(); | 120 history::TopSites* top_sites = profile_->GetTopSites(); |
99 if (!top_sites) | 121 if (!top_sites) |
100 return; | 122 return; |
101 | 123 |
102 top_sites->AddBlacklistedURL(url); | 124 top_sites->AddBlacklistedURL(url); |
103 } | 125 } |
104 | 126 |
105 void InstantService::UndoMostVisitedDeletion(const GURL& url) { | 127 void InstantService::UndoMostVisitedDeletion(const GURL& url) { |
106 history::TopSites* top_sites = profile_->GetTopSites(); | 128 history::TopSites* top_sites = profile_->GetTopSites(); |
107 if (!top_sites) | 129 if (!top_sites) |
108 return; | 130 return; |
109 | 131 |
110 top_sites->RemoveBlacklistedURL(url); | 132 top_sites->RemoveBlacklistedURL(url); |
111 } | 133 } |
112 | 134 |
113 void InstantService::UndoAllMostVisitedDeletions() { | 135 void InstantService::UndoAllMostVisitedDeletions() { |
114 history::TopSites* top_sites = profile_->GetTopSites(); | 136 history::TopSites* top_sites = profile_->GetTopSites(); |
115 if (!top_sites) | 137 if (!top_sites) |
116 return; | 138 return; |
117 | 139 |
118 top_sites->ClearBlacklistedURLs(); | 140 top_sites->ClearBlacklistedURLs(); |
119 } | 141 } |
120 | 142 |
121 void InstantService::GetCurrentMostVisitedItems( | 143 void InstantService::GetCurrentMostVisitedItems( |
122 std::vector<InstantMostVisitedItem>* items) const { | 144 std::vector<InstantMostVisitedItem>* items) const { |
123 *items = most_visited_items_; | 145 *items = most_visited_items_; |
124 } | 146 } |
125 | 147 |
| 148 void InstantService::UpdateThemeInfo() { |
| 149 // Update theme background info. |
| 150 // Initialize |theme_info| if necessary. |
| 151 if (!theme_info_) |
| 152 OnThemeChanged(ThemeServiceFactory::GetForProfile(profile_)); |
| 153 else |
| 154 OnThemeChanged(NULL); |
| 155 } |
| 156 |
126 void InstantService::Shutdown() { | 157 void InstantService::Shutdown() { |
127 process_ids_.clear(); | 158 process_ids_.clear(); |
128 | 159 |
129 if (instant_io_context_.get()) { | 160 if (instant_io_context_.get()) { |
130 BrowserThread::PostTask( | 161 BrowserThread::PostTask( |
131 BrowserThread::IO, | 162 BrowserThread::IO, |
132 FROM_HERE, | 163 FROM_HERE, |
133 base::Bind(&InstantIOContext::ClearInstantProcessesOnIO, | 164 base::Bind(&InstantIOContext::ClearInstantProcessesOnIO, |
134 instant_io_context_)); | 165 instant_io_context_)); |
135 } | 166 } |
(...skipping 21 matching lines...) Expand all Loading... |
157 } | 188 } |
158 case chrome::NOTIFICATION_TOP_SITES_CHANGED: { | 189 case chrome::NOTIFICATION_TOP_SITES_CHANGED: { |
159 history::TopSites* top_sites = profile_->GetTopSites(); | 190 history::TopSites* top_sites = profile_->GetTopSites(); |
160 if (top_sites) { | 191 if (top_sites) { |
161 top_sites->GetMostVisitedURLs( | 192 top_sites->GetMostVisitedURLs( |
162 base::Bind(&InstantService::OnMostVisitedItemsReceived, | 193 base::Bind(&InstantService::OnMostVisitedItemsReceived, |
163 weak_ptr_factory_.GetWeakPtr())); | 194 weak_ptr_factory_.GetWeakPtr())); |
164 } | 195 } |
165 break; | 196 break; |
166 } | 197 } |
| 198 #if defined(ENABLE_THEMES) |
| 199 case chrome::NOTIFICATION_BROWSER_THEME_CHANGED: { |
| 200 OnThemeChanged(content::Source<ThemeService>(source).ptr()); |
| 201 break; |
| 202 } |
| 203 #endif // defined(ENABLE_THEMES) |
167 default: | 204 default: |
168 NOTREACHED() << "Unexpected notification type in InstantService."; | 205 NOTREACHED() << "Unexpected notification type in InstantService."; |
169 } | 206 } |
170 } | 207 } |
171 | 208 |
172 void InstantService::OnMostVisitedItemsReceived( | 209 void InstantService::OnMostVisitedItemsReceived( |
173 const history::MostVisitedURLList& data) { | 210 const history::MostVisitedURLList& data) { |
174 // Android doesn't use Browser/BrowserList. Do nothing for Android platform. | 211 // Android doesn't use Browser/BrowserList. Do nothing for Android platform. |
175 #if !defined(OS_ANDROID) | 212 #if !defined(OS_ANDROID) |
176 history::MostVisitedURLList reordered_data(data); | 213 history::MostVisitedURLList reordered_data(data); |
(...skipping 24 matching lines...) Expand all Loading... |
201 InstantController* controller = (*it)->instant_controller()->instant(); | 238 InstantController* controller = (*it)->instant_controller()->instant(); |
202 if (!controller) | 239 if (!controller) |
203 continue; | 240 continue; |
204 // TODO(kmadhusu): It would be cleaner to have each InstantController | 241 // TODO(kmadhusu): It would be cleaner to have each InstantController |
205 // register itself as an InstantServiceObserver and push out updates that | 242 // register itself as an InstantServiceObserver and push out updates that |
206 // way. Refer to crbug.com/246355 for more details. | 243 // way. Refer to crbug.com/246355 for more details. |
207 controller->UpdateMostVisitedItems(); | 244 controller->UpdateMostVisitedItems(); |
208 } | 245 } |
209 #endif | 246 #endif |
210 } | 247 } |
| 248 |
| 249 void InstantService::OnThemeChanged(ThemeService* theme_service) { |
| 250 if (!theme_service) { |
| 251 DCHECK(theme_info_.get()); |
| 252 FOR_EACH_OBSERVER(InstantServiceObserver, observers_, |
| 253 ThemeInfoChanged(*theme_info_)); |
| 254 return; |
| 255 } |
| 256 |
| 257 // Get theme information from theme service. |
| 258 theme_info_.reset(new ThemeBackgroundInfo()); |
| 259 |
| 260 // Set theme background color. |
| 261 SkColor background_color = |
| 262 theme_service->GetColor(ThemeProperties::COLOR_NTP_BACKGROUND); |
| 263 if (gfx::IsInvertedColorScheme()) |
| 264 background_color = color_utils::InvertColor(background_color); |
| 265 |
| 266 theme_info_->color_r = SkColorGetR(background_color); |
| 267 theme_info_->color_g = SkColorGetG(background_color); |
| 268 theme_info_->color_b = SkColorGetB(background_color); |
| 269 theme_info_->color_a = SkColorGetA(background_color); |
| 270 |
| 271 if (theme_service->HasCustomImage(IDR_THEME_NTP_BACKGROUND)) { |
| 272 // Set theme id for theme background image url. |
| 273 theme_info_->theme_id = theme_service->GetThemeID(); |
| 274 |
| 275 // Set theme background image horizontal alignment. |
| 276 int alignment = 0; |
| 277 theme_service->GetDisplayProperty( |
| 278 ThemeProperties::NTP_BACKGROUND_ALIGNMENT, &alignment); |
| 279 if (alignment & ThemeProperties::ALIGN_LEFT) |
| 280 theme_info_->image_horizontal_alignment = THEME_BKGRND_IMAGE_ALIGN_LEFT; |
| 281 else if (alignment & ThemeProperties::ALIGN_RIGHT) |
| 282 theme_info_->image_horizontal_alignment = THEME_BKGRND_IMAGE_ALIGN_RIGHT; |
| 283 else |
| 284 theme_info_->image_horizontal_alignment = THEME_BKGRND_IMAGE_ALIGN_CENTER; |
| 285 |
| 286 // Set theme background image vertical alignment. |
| 287 if (alignment & ThemeProperties::ALIGN_TOP) |
| 288 theme_info_->image_vertical_alignment = THEME_BKGRND_IMAGE_ALIGN_TOP; |
| 289 else if (alignment & ThemeProperties::ALIGN_BOTTOM) |
| 290 theme_info_->image_vertical_alignment = THEME_BKGRND_IMAGE_ALIGN_BOTTOM; |
| 291 else |
| 292 theme_info_->image_vertical_alignment = THEME_BKGRND_IMAGE_ALIGN_CENTER; |
| 293 |
| 294 // Set theme backgorund image tiling. |
| 295 int tiling = 0; |
| 296 theme_service->GetDisplayProperty(ThemeProperties::NTP_BACKGROUND_TILING, |
| 297 &tiling); |
| 298 switch (tiling) { |
| 299 case ThemeProperties::NO_REPEAT: |
| 300 theme_info_->image_tiling = THEME_BKGRND_IMAGE_NO_REPEAT; |
| 301 break; |
| 302 case ThemeProperties::REPEAT_X: |
| 303 theme_info_->image_tiling = THEME_BKGRND_IMAGE_REPEAT_X; |
| 304 break; |
| 305 case ThemeProperties::REPEAT_Y: |
| 306 theme_info_->image_tiling = THEME_BKGRND_IMAGE_REPEAT_Y; |
| 307 break; |
| 308 case ThemeProperties::REPEAT: |
| 309 theme_info_->image_tiling = THEME_BKGRND_IMAGE_REPEAT; |
| 310 break; |
| 311 } |
| 312 |
| 313 // Set theme background image height. |
| 314 gfx::ImageSkia* image = theme_service->GetImageSkiaNamed( |
| 315 IDR_THEME_NTP_BACKGROUND); |
| 316 DCHECK(image); |
| 317 theme_info_->image_height = image->height(); |
| 318 |
| 319 theme_info_->has_attribution = |
| 320 theme_service->HasCustomImage(IDR_THEME_NTP_ATTRIBUTION); |
| 321 } |
| 322 |
| 323 FOR_EACH_OBSERVER(InstantServiceObserver, observers_, |
| 324 ThemeInfoChanged(*theme_info_)); |
| 325 } |
OLD | NEW |