| Index: chrome/browser/instant/instant_service.cc
|
| diff --git a/chrome/browser/instant/instant_service.cc b/chrome/browser/instant/instant_service.cc
|
| index 3c8a6b2ba2c9c93b4ca5f714d27175e4ffca84e8..d23261fd71b9eeedd55d811828dd3e2d344e0d0e 100644
|
| --- a/chrome/browser/instant/instant_service.cc
|
| +++ b/chrome/browser/instant/instant_service.cc
|
| @@ -4,81 +4,282 @@
|
|
|
| #include "chrome/browser/instant/instant_service.h"
|
|
|
| +#include "base/utf_string_conversions.h"
|
| +#include "chrome/browser/history/top_sites.h"
|
| #include "chrome/browser/instant/instant_io_context.h"
|
| +#include "chrome/browser/instant/instant_preloader.h"
|
| #include "chrome/browser/profiles/profile.h"
|
| +#include "chrome/browser/themes/theme_properties.h"
|
| +#include "chrome/browser/themes/theme_service.h"
|
| +#include "chrome/browser/themes/theme_service_factory.h"
|
| +#include "chrome/browser/ui/search/search.h"
|
| #include "chrome/browser/ui/webui/ntp/thumbnail_source.h"
|
| #include "chrome/common/chrome_notification_types.h"
|
| +#include "chrome/common/pref_names.h"
|
| #include "content/public/browser/browser_thread.h"
|
| #include "content/public/browser/notification_service.h"
|
| -#include "content/public/browser/notification_types.h"
|
| #include "content/public/browser/render_process_host.h"
|
| -#include "content/public/browser/url_data_source.h"
|
| +#include "grit/theme_resources.h"
|
| +#include "ui/base/resource/resource_bundle.h"
|
| +#include "ui/gfx/image/image_skia.h"
|
| +#include "ui/gfx/sys_color_change_listener.h"
|
|
|
| -using content::BrowserThread;
|
| +namespace {
|
| +
|
| +const size_t kMaxDebugEvents = 2000;
|
| +
|
| +} // namespace
|
|
|
| InstantService::InstantService(Profile* profile)
|
| - : profile_(profile) {
|
| + : profile_(profile),
|
| + omnibox_font_size_(0),
|
| + omnibox_start_margin_(0),
|
| + instant_pref_enabled_(false),
|
| + instant_enabled_(false) {
|
| // Stub for unit tests.
|
| - if (!BrowserThread::CurrentlyOn(BrowserThread::UI))
|
| + if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI))
|
| return;
|
|
|
| - registrar_.Add(this,
|
| - content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
|
| - content::NotificationService::AllSources());
|
| + notification_registrar_.Add(this,
|
| + content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
|
| + content::NotificationService::AllSources());
|
|
|
| - instant_io_context_ = new InstantIOContext();
|
| + io_context_ = new InstantIOContext();
|
|
|
| - if (profile_ && profile_->GetResourceContext()) {
|
| - BrowserThread::PostTask(
|
| - BrowserThread::IO, FROM_HERE,
|
| + if (profile && profile->GetResourceContext()) {
|
| + content::BrowserThread::PostTask(
|
| + content::BrowserThread::IO, FROM_HERE,
|
| base::Bind(&InstantIOContext::SetUserDataOnIO,
|
| - profile->GetResourceContext(), instant_io_context_));
|
| + profile->GetResourceContext(), io_context_));
|
| }
|
|
|
| content::URLDataSource::Add(profile, new ThumbnailSource(profile));
|
| +
|
| + // In one mode of the InstantExtended experiments, the kInstantExtendedEnabled
|
| + // preference's default value is set to the existing value of kInstantEnabled.
|
| + // Because this requires reading the value of the kInstantEnabled value, we
|
| + // reset the default for kInstantExtendedEnabled here.
|
| + chrome::search::SetInstantExtendedPrefDefault(profile);
|
| +
|
| + pref_change_registrar_.Init(profile->GetPrefs());
|
| + pref_change_registrar_.Add(
|
| + prefs::kInstantEnabled,
|
| + base::Bind(&InstantService::PrefChanged, base::Unretained(this)));
|
| + pref_change_registrar_.Add(
|
| + prefs::kInstantExtendedEnabled,
|
| + base::Bind(&InstantService::PrefChanged, base::Unretained(this)));
|
| + pref_change_registrar_.Add(
|
| + prefs::kSearchSuggestEnabled,
|
| + base::Bind(&InstantService::PrefChanged, base::Unretained(this)));
|
| + PrefChanged(std::string());
|
| +
|
| + ThemeService* theme_service = ThemeServiceFactory::GetForProfile(profile);
|
| + notification_registrar_.Add(this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
|
| + content::Source<ThemeService>(theme_service));
|
| + ParseTheme(theme_service);
|
| +
|
| + history::TopSites* top_sites = profile->GetTopSites();
|
| + notification_registrar_.Add(this, chrome::NOTIFICATION_TOP_SITES_CHANGED,
|
| + content::Source<history::TopSites>(top_sites));
|
| + RequestMostVisitedItems(top_sites);
|
| +
|
| +// TODO(sail): Remove this once the Mac omnibox font size is updated.
|
| +#if defined(OS_MACOSX)
|
| + ui::ResourceBundle::FontStyle font_style = ui::ResourceBundle::BaseFont;
|
| +#else
|
| + ui::ResourceBundle::FontStyle font_style = ui::ResourceBundle::MediumFont;
|
| +#endif // defined(OS_MACOSX)
|
| + const gfx::Font& omnibox_font =
|
| + ui::ResourceBundle::GetSharedInstance().GetFont(font_style);
|
| + omnibox_font_name_ = UTF8ToUTF16(omnibox_font.GetFontName());
|
| + omnibox_font_size_ = omnibox_font.GetFontSize();
|
| }
|
|
|
| InstantService::~InstantService() {
|
| }
|
|
|
| -void InstantService::AddInstantProcess(int process_id) {
|
| - process_ids_.insert(process_id);
|
| +void InstantService::LogDebugEvent(const std::string& message) {
|
| + DVLOG(1) << message;
|
| + debug_events_.push_front(std::make_pair(base::Time::Now().ToInternalValue(),
|
| + message));
|
| + if (debug_events_.size() > kMaxDebugEvents)
|
| + debug_events_.pop_back();
|
| +}
|
|
|
| - if (instant_io_context_) {
|
| - BrowserThread::PostTask(
|
| - BrowserThread::IO, FROM_HERE,
|
| - base::Bind(&InstantIOContext::AddInstantProcessOnIO,
|
| - instant_io_context_, process_id));
|
| - }
|
| +void InstantService::ClearDebugEvents() {
|
| + debug_events_.clear();
|
| +}
|
| +
|
| +void InstantService::AddObserver(InstantServiceObserver* observer) {
|
| + observers_.AddObserver(observer);
|
| +
|
| + // If we just added our first observer, we have our first browser window.
|
| + // Create the InstantPreloader (which will also register as an observer).
|
| + if (observers_.size() == 1)
|
| + preloader_.reset(new InstantPreloader(this));
|
| +}
|
| +
|
| +void InstantService::RemoveObserver(InstantServiceObserver* observer) {
|
| + observers_.RemoveObserver(observer);
|
| +
|
| + // If there's only one observer left, it must be the InstantPreloader. All
|
| + // browser windows have closed, so kill the preloader, to work around
|
| + // http://crbug.com/180810.
|
| + if (observers_.size() == 1)
|
| + preloader_.reset();
|
| }
|
|
|
| bool InstantService::IsInstantProcess(int process_id) const {
|
| return process_ids_.find(process_id) != process_ids_.end();
|
| }
|
|
|
| -void InstantService::Shutdown() {
|
| - process_ids_.clear();
|
| +void InstantService::AddInstantProcess(int process_id) {
|
| + process_ids_.insert(process_id);
|
| +
|
| + if (io_context_) {
|
| + content::BrowserThread::PostTask(
|
| + content::BrowserThread::IO, FROM_HERE,
|
| + base::Bind(&InstantIOContext::AddInstantProcessOnIO,
|
| + io_context_, process_id));
|
| + }
|
| +}
|
| +
|
| +void InstantService::RemoveInstantProcess(int process_id) {
|
| + process_ids_.erase(process_id);
|
|
|
| - if (instant_io_context_) {
|
| - BrowserThread::PostTask(
|
| - BrowserThread::IO, FROM_HERE,
|
| - base::Bind(&InstantIOContext::ClearInstantProcessesOnIO,
|
| - instant_io_context_));
|
| + if (io_context_) {
|
| + content::BrowserThread::PostTask(
|
| + content::BrowserThread::IO, FROM_HERE,
|
| + base::Bind(&InstantIOContext::RemoveInstantProcessOnIO,
|
| + io_context_, process_id));
|
| }
|
| - instant_io_context_ = NULL;
|
| +}
|
| +
|
| +void InstantService::InstantSupportDetermined() {
|
| + content::NotificationService::current()->Notify(
|
| + chrome::NOTIFICATION_INSTANT_SUPPORT_DETERMINED,
|
| + content::NotificationService::AllSources(),
|
| + content::NotificationService::NoDetails());
|
| }
|
|
|
| void InstantService::Observe(int type,
|
| const content::NotificationSource& source,
|
| const content::NotificationDetails& details) {
|
| - DCHECK_EQ(type, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED);
|
| - int process_id = content::Source<content::RenderProcessHost>(source)->GetID();
|
| - process_ids_.erase(process_id);
|
| + switch (type) {
|
| + case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED:
|
| + RemoveInstantProcess(
|
| + content::Source<content::RenderProcessHost>(source)->GetID());
|
| + break;
|
|
|
| - if (instant_io_context_) {
|
| - BrowserThread::PostTask(
|
| - BrowserThread::IO, FROM_HERE,
|
| - base::Bind(&InstantIOContext::RemoveInstantProcessOnIO,
|
| - instant_io_context_, process_id));
|
| + case chrome::NOTIFICATION_BROWSER_THEME_CHANGED:
|
| + ParseTheme(content::Source<ThemeService>(source).ptr());
|
| + break;
|
| +
|
| + case chrome::NOTIFICATION_TOP_SITES_CHANGED:
|
| + RequestMostVisitedItems(content::Source<history::TopSites>(source).ptr());
|
| + break;
|
| +
|
| + default:
|
| + NOTREACHED();
|
| + break;
|
| + }
|
| +}
|
| +
|
| +void InstantService::PrefChanged(const std::string& pref_name) {
|
| + if (pref_name == prefs::kInstantEnabled)
|
| + chrome::search::SetInstantExtendedPrefDefault(profile_);
|
| +
|
| + bool instant_pref_enabled = chrome::search::IsInstantPrefEnabled(profile_);
|
| + bool instant_enabled = chrome::search::IsInstantEnabled(profile_);
|
| + if (instant_pref_enabled_ == instant_pref_enabled &&
|
| + instant_enabled_ == instant_enabled)
|
| + return;
|
| +
|
| + instant_pref_enabled_ = instant_pref_enabled;
|
| + instant_enabled_ = instant_enabled;
|
| + FOR_EACH_OBSERVER(InstantServiceObserver, observers_, InstantStatusChanged());
|
| +}
|
| +
|
| +void InstantService::ParseTheme(ThemeService* theme_service) {
|
| + theme_info_ = ThemeBackgroundInfo();
|
| +
|
| + // Set theme background color.
|
| + SkColor background_color =
|
| + theme_service->GetColor(ThemeProperties::COLOR_NTP_BACKGROUND);
|
| + if (gfx::IsInvertedColorScheme())
|
| + background_color = color_utils::InvertColor(background_color);
|
| + theme_info_.color_r = SkColorGetR(background_color);
|
| + theme_info_.color_g = SkColorGetG(background_color);
|
| + theme_info_.color_b = SkColorGetB(background_color);
|
| + theme_info_.color_a = SkColorGetA(background_color);
|
| +
|
| + if (!theme_service->HasCustomImage(IDR_THEME_NTP_BACKGROUND))
|
| + return;
|
| +
|
| + // Set theme id for theme background image url.
|
| + theme_info_.theme_id = UTF8ToUTF16(theme_service->GetThemeID());
|
| +
|
| + // Set theme background image horizontal alignment.
|
| + int alignment = 0;
|
| + theme_service->GetDisplayProperty(ThemeProperties::NTP_BACKGROUND_ALIGNMENT,
|
| + &alignment);
|
| + if (alignment & ThemeProperties::ALIGN_LEFT) {
|
| + theme_info_.image_horizontal_alignment = THEME_BKGRND_IMAGE_ALIGN_LEFT;
|
| + } else if (alignment & ThemeProperties::ALIGN_RIGHT) {
|
| + theme_info_.image_horizontal_alignment = THEME_BKGRND_IMAGE_ALIGN_RIGHT;
|
| + } else { // ALIGN_CENTER
|
| + theme_info_.image_horizontal_alignment = THEME_BKGRND_IMAGE_ALIGN_CENTER;
|
| + }
|
| +
|
| + // Set theme background image vertical alignment.
|
| + if (alignment & ThemeProperties::ALIGN_TOP) {
|
| + theme_info_.image_vertical_alignment = THEME_BKGRND_IMAGE_ALIGN_TOP;
|
| + } else if (alignment & ThemeProperties::ALIGN_BOTTOM) {
|
| + theme_info_.image_vertical_alignment = THEME_BKGRND_IMAGE_ALIGN_BOTTOM;
|
| + } else { // ALIGN_CENTER
|
| + theme_info_.image_vertical_alignment = THEME_BKGRND_IMAGE_ALIGN_CENTER;
|
| + }
|
| +
|
| + // Set theme background image tiling.
|
| + int tiling = 0;
|
| + theme_service->GetDisplayProperty(ThemeProperties::NTP_BACKGROUND_TILING,
|
| + &tiling);
|
| + switch (tiling) {
|
| + case ThemeProperties::NO_REPEAT:
|
| + theme_info_.image_tiling = THEME_BKGRND_IMAGE_NO_REPEAT;
|
| + break;
|
| + case ThemeProperties::REPEAT_X:
|
| + theme_info_.image_tiling = THEME_BKGRND_IMAGE_REPEAT_X;
|
| + break;
|
| + case ThemeProperties::REPEAT_Y:
|
| + theme_info_.image_tiling = THEME_BKGRND_IMAGE_REPEAT_Y;
|
| + break;
|
| + case ThemeProperties::REPEAT:
|
| + theme_info_.image_tiling = THEME_BKGRND_IMAGE_REPEAT;
|
| + break;
|
| }
|
| +
|
| + // Set theme background image height.
|
| + gfx::ImageSkia* image = theme_service->GetImageSkiaNamed(
|
| + IDR_THEME_NTP_BACKGROUND);
|
| + DCHECK(image);
|
| + theme_info_.image_height = image->height();
|
| +
|
| + FOR_EACH_OBSERVER(InstantServiceObserver, observers_, ThemeInfoChanged());
|
| +}
|
| +
|
| +void InstantService::RequestMostVisitedItems(history::TopSites* top_sites) {
|
| + top_sites->GetMostVisitedURLs(
|
| + base::Bind(&InstantService::MostVisitedItemsReceived,
|
| + base::Unretained(this)));
|
| +}
|
| +
|
| +void InstantService::MostVisitedItemsReceived(
|
| + const history::MostVisitedURLList& data) {
|
| + most_visited_items_.clear();
|
| + for (size_t i = 0; i < data.size(); ++i)
|
| + most_visited_items_.push_back(MostVisitedItem(data[i].url, data[i].title));
|
| +
|
| + FOR_EACH_OBSERVER(InstantServiceObserver, observers_,
|
| + MostVisitedItemsChanged());
|
| }
|
|
|