Chromium Code Reviews| Index: chrome/browser/ui/app_list/start_page_service.cc |
| diff --git a/chrome/browser/ui/app_list/start_page_service.cc b/chrome/browser/ui/app_list/start_page_service.cc |
| index e08d8ef3dc09362871d901161c94110e1ca2b8b0..ba13f83340957e1ec1d6300c8014a1dc9b321e2d 100644 |
| --- a/chrome/browser/ui/app_list/start_page_service.cc |
| +++ b/chrome/browser/ui/app_list/start_page_service.cc |
| @@ -8,11 +8,13 @@ |
| #include "base/bind.h" |
| #include "base/command_line.h" |
| +#include "base/json/json_string_value_serializer.h" |
| #include "base/memory/singleton.h" |
| #include "base/metrics/user_metrics.h" |
| #include "base/prefs/pref_service.h" |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/browser/chrome_notification_types.h" |
| +#include "chrome/browser/google/google_profile_helper.h" |
| #include "chrome/browser/media/media_stream_infobar_delegate.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/search/hotword_service.h" |
| @@ -24,6 +26,7 @@ |
| #include "chrome/common/chrome_switches.h" |
| #include "chrome/common/pref_names.h" |
| #include "chrome/common/url_constants.h" |
| +#include "components/google/core/browser/google_util.h" |
| #include "components/ui/zoom/zoom_controller.h" |
| #include "content/public/browser/browser_thread.h" |
| #include "content/public/browser/notification_details.h" |
| @@ -37,7 +40,9 @@ |
| #include "extensions/browser/extension_system_provider.h" |
| #include "extensions/browser/extensions_browser_client.h" |
| #include "extensions/common/extension.h" |
| +#include "net/base/load_flags.h" |
| #include "net/base/network_change_notifier.h" |
| +#include "net/url_request/url_fetcher.h" |
| #include "ui/app_list/app_list_switches.h" |
| #if defined(OS_CHROMEOS) |
| @@ -51,11 +56,25 @@ namespace app_list { |
| namespace { |
| +// Path to google.com's doodle JSON. |
| +const char kDoodleJsonPath[] = "async/ddljson"; |
| + |
| +// Delay between checking for a new doodle when no doodle is found. |
| +const int kDefaultDoodleRecheckDelayMs = 30 * 60 * 1000; // 30 minutes. |
|
Matt Giuca
2015/01/29 08:00:53
Not a fan of these hard-coded constants (even if t
calamity
2015/01/30 05:09:14
Done.
|
| + |
| bool InSpeechRecognition(SpeechRecognitionState state) { |
| return state == SPEECH_RECOGNITION_RECOGNIZING || |
| state == SPEECH_RECOGNITION_IN_SPEECH; |
| } |
| +GURL GetGoogleBaseURL(Profile* profile) { |
| + GURL base_url(google_util::CommandLineGoogleBaseURL()); |
| + if (!base_url.is_valid()) |
| + base_url = google_profile_helper::GetGoogleHomePageURL(profile); |
| + |
| + return base_url; |
| +} |
| + |
| } // namespace |
| class StartPageService::ProfileDestroyObserver |
| @@ -472,6 +491,8 @@ void StartPageService::WebUILoaded() { |
| for (const auto& cb : pending_webui_callbacks_) |
| cb.Run(); |
| pending_webui_callbacks_.clear(); |
| + |
| + FetchDoodleJson(); |
| } |
| void StartPageService::LoadContents() { |
| @@ -498,4 +519,57 @@ void StartPageService::UnloadContents() { |
| webui_finished_loading_ = false; |
| } |
| +void StartPageService::FetchDoodleJson() { |
| + // SetPathStr() requires its argument to stay in scope as long as |
| + // |replacements| is, so a std::string is needed, instead of a char*. |
|
Matt Giuca
2015/01/29 08:00:53
But kDoodleJsonPath has global lifetime and thus s
calamity
2015/01/30 05:09:14
const char[] != std::string. The autoconverted str
Matt Giuca
2015/02/02 06:23:14
Acknowledged.
(Lol... it's funny that GURL::Repla
|
| + std::string path = kDoodleJsonPath; |
| + GURL::Replacements replacements; |
| + replacements.SetPathStr(path); |
| + |
| + GURL doodle_url = GetGoogleBaseURL(profile_).ReplaceComponents(replacements); |
| + doodle_fetcher_.reset( |
| + net::URLFetcher::Create(0, doodle_url, net::URLFetcher::GET, this)); |
| + doodle_fetcher_->SetRequestContext(profile_->GetRequestContext()); |
| + doodle_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES); |
| + doodle_fetcher_->Start(); |
| +} |
| + |
| +void StartPageService::OnURLFetchComplete(const net::URLFetcher* source) { |
| + std::string json_data; |
| + source->GetResponseAsString(&json_data); |
| + |
| + // Remove XSSI guard for JSON parsing. |
| + size_t json_start_index = json_data.find("{"); |
| + if (json_start_index != std::string::npos) |
| + json_data.erase(0, json_start_index); |
|
Matt Giuca
2015/01/29 08:00:53
I think the preferred strategy these days is to us
calamity
2015/01/30 05:09:14
As discussed, this is more complicated that it's w
Matt Giuca
2015/02/02 06:23:14
Acknowledged.
|
| + |
| + JSONStringValueSerializer deserializer(json_data); |
| + deserializer.set_allow_trailing_comma(true); |
| + int error_code = 0; |
| + scoped_ptr<base::Value> doodle_json( |
| + deserializer.Deserialize(&error_code, NULL)); |
|
Matt Giuca
2015/01/29 08:00:53
nullptrs (everywhere)
calamity
2015/01/30 05:09:14
Done.
|
| + |
| + int recheck_delay_ms = kDefaultDoodleRecheckDelayMs; |
| + |
| + if (error_code == 0) { |
| + base::DictionaryValue* doodle_dictionary = NULL; |
| + // Use the supplied TTL as the recheck delay if available. |
| + if (doodle_json->GetAsDictionary(&doodle_dictionary)) { |
| + doodle_dictionary->GetInteger("ddljson.time_to_live_ms", |
| + &recheck_delay_ms); |
| + } |
| + |
| + contents_->GetWebUI()->CallJavascriptFunction( |
| + "appList.startPage.onAppListDoodleUpdated", *doodle_json, |
| + base::StringValue(GetGoogleBaseURL(profile_).spec())); |
| + } |
| + |
| + // Check for a new doodle. |
| + content::BrowserThread::PostDelayedTask( |
| + content::BrowserThread::UI, FROM_HERE, |
| + base::Bind(&StartPageService::FetchDoodleJson, |
| + weak_factory_.GetWeakPtr()), |
| + base::TimeDelta::FromMilliseconds(recheck_delay_ms)); |
| +} |
| + |
| } // namespace app_list |