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

Side by Side Diff: chrome/browser/ui/app_list/start_page_service.cc

Issue 871193006: Add a static Google Doodle to the experimental app list start page. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@remove_xiyuan_start_page
Patch Set: Created 5 years, 10 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
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/ui/app_list/start_page_service.h" 5 #include "chrome/browser/ui/app_list/start_page_service.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/json/json_string_value_serializer.h"
11 #include "base/memory/singleton.h" 12 #include "base/memory/singleton.h"
12 #include "base/metrics/user_metrics.h" 13 #include "base/metrics/user_metrics.h"
13 #include "base/prefs/pref_service.h" 14 #include "base/prefs/pref_service.h"
14 #include "chrome/browser/browser_process.h" 15 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/chrome_notification_types.h" 16 #include "chrome/browser/chrome_notification_types.h"
17 #include "chrome/browser/google/google_profile_helper.h"
16 #include "chrome/browser/media/media_stream_infobar_delegate.h" 18 #include "chrome/browser/media/media_stream_infobar_delegate.h"
17 #include "chrome/browser/profiles/profile.h" 19 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/search/hotword_service.h" 20 #include "chrome/browser/search/hotword_service.h"
19 #include "chrome/browser/search/hotword_service_factory.h" 21 #include "chrome/browser/search/hotword_service_factory.h"
20 #include "chrome/browser/ui/app_list/speech_auth_helper.h" 22 #include "chrome/browser/ui/app_list/speech_auth_helper.h"
21 #include "chrome/browser/ui/app_list/speech_recognizer.h" 23 #include "chrome/browser/ui/app_list/speech_recognizer.h"
22 #include "chrome/browser/ui/app_list/start_page_observer.h" 24 #include "chrome/browser/ui/app_list/start_page_observer.h"
23 #include "chrome/browser/ui/app_list/start_page_service_factory.h" 25 #include "chrome/browser/ui/app_list/start_page_service_factory.h"
24 #include "chrome/common/chrome_switches.h" 26 #include "chrome/common/chrome_switches.h"
25 #include "chrome/common/pref_names.h" 27 #include "chrome/common/pref_names.h"
26 #include "chrome/common/url_constants.h" 28 #include "chrome/common/url_constants.h"
29 #include "components/google/core/browser/google_util.h"
27 #include "components/ui/zoom/zoom_controller.h" 30 #include "components/ui/zoom/zoom_controller.h"
28 #include "content/public/browser/browser_thread.h" 31 #include "content/public/browser/browser_thread.h"
29 #include "content/public/browser/notification_details.h" 32 #include "content/public/browser/notification_details.h"
30 #include "content/public/browser/notification_observer.h" 33 #include "content/public/browser/notification_observer.h"
31 #include "content/public/browser/notification_registrar.h" 34 #include "content/public/browser/notification_registrar.h"
32 #include "content/public/browser/notification_service.h" 35 #include "content/public/browser/notification_service.h"
33 #include "content/public/browser/notification_source.h" 36 #include "content/public/browser/notification_source.h"
34 #include "content/public/browser/speech_recognition_session_preamble.h" 37 #include "content/public/browser/speech_recognition_session_preamble.h"
35 #include "content/public/browser/web_contents.h" 38 #include "content/public/browser/web_contents.h"
36 #include "content/public/browser/web_contents_delegate.h" 39 #include "content/public/browser/web_contents_delegate.h"
37 #include "extensions/browser/extension_system_provider.h" 40 #include "extensions/browser/extension_system_provider.h"
38 #include "extensions/browser/extensions_browser_client.h" 41 #include "extensions/browser/extensions_browser_client.h"
39 #include "extensions/common/extension.h" 42 #include "extensions/common/extension.h"
43 #include "net/base/load_flags.h"
40 #include "net/base/network_change_notifier.h" 44 #include "net/base/network_change_notifier.h"
45 #include "net/url_request/url_fetcher.h"
41 #include "ui/app_list/app_list_switches.h" 46 #include "ui/app_list/app_list_switches.h"
42 47
43 #if defined(OS_CHROMEOS) 48 #if defined(OS_CHROMEOS)
44 #include "chromeos/audio/cras_audio_handler.h" 49 #include "chromeos/audio/cras_audio_handler.h"
45 #endif 50 #endif
46 51
47 using base::RecordAction; 52 using base::RecordAction;
48 using base::UserMetricsAction; 53 using base::UserMetricsAction;
49 54
50 namespace app_list { 55 namespace app_list {
51 56
52 namespace { 57 namespace {
53 58
59 // Path to google.com's doodle JSON.
60 const char kDoodleJsonPath[] = "async/ddljson";
61
62 // Delay between checking for a new doodle when no doodle is found.
63 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.
64
54 bool InSpeechRecognition(SpeechRecognitionState state) { 65 bool InSpeechRecognition(SpeechRecognitionState state) {
55 return state == SPEECH_RECOGNITION_RECOGNIZING || 66 return state == SPEECH_RECOGNITION_RECOGNIZING ||
56 state == SPEECH_RECOGNITION_IN_SPEECH; 67 state == SPEECH_RECOGNITION_IN_SPEECH;
57 } 68 }
58 69
70 GURL GetGoogleBaseURL(Profile* profile) {
71 GURL base_url(google_util::CommandLineGoogleBaseURL());
72 if (!base_url.is_valid())
73 base_url = google_profile_helper::GetGoogleHomePageURL(profile);
74
75 return base_url;
76 }
77
59 } // namespace 78 } // namespace
60 79
61 class StartPageService::ProfileDestroyObserver 80 class StartPageService::ProfileDestroyObserver
62 : public content::NotificationObserver { 81 : public content::NotificationObserver {
63 public: 82 public:
64 explicit ProfileDestroyObserver(StartPageService* service) 83 explicit ProfileDestroyObserver(StartPageService* service)
65 : service_(service) { 84 : service_(service) {
66 registrar_.Add(this, 85 registrar_.Add(this,
67 chrome::NOTIFICATION_PROFILE_DESTROYED, 86 chrome::NOTIFICATION_PROFILE_DESTROYED,
68 content::Source<Profile>(service_->profile())); 87 content::Source<Profile>(service_->profile()));
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 void StartPageService::WebUILoaded() { 484 void StartPageService::WebUILoaded() {
466 // There's a race condition between the WebUI loading, and calling its JS 485 // There's a race condition between the WebUI loading, and calling its JS
467 // functions. Specifically, calling LoadContents() doesn't mean that the page 486 // functions. Specifically, calling LoadContents() doesn't mean that the page
468 // has loaded, but several code paths make this assumption. This function 487 // has loaded, but several code paths make this assumption. This function
469 // allows us to defer calling JS functions until after the page has finished 488 // allows us to defer calling JS functions until after the page has finished
470 // loading. 489 // loading.
471 webui_finished_loading_ = true; 490 webui_finished_loading_ = true;
472 for (const auto& cb : pending_webui_callbacks_) 491 for (const auto& cb : pending_webui_callbacks_)
473 cb.Run(); 492 cb.Run();
474 pending_webui_callbacks_.clear(); 493 pending_webui_callbacks_.clear();
494
495 FetchDoodleJson();
475 } 496 }
476 497
477 void StartPageService::LoadContents() { 498 void StartPageService::LoadContents() {
478 contents_.reset(content::WebContents::Create( 499 contents_.reset(content::WebContents::Create(
479 content::WebContents::CreateParams(profile_))); 500 content::WebContents::CreateParams(profile_)));
480 contents_delegate_.reset(new StartPageWebContentsDelegate()); 501 contents_delegate_.reset(new StartPageWebContentsDelegate());
481 contents_->SetDelegate(contents_delegate_.get()); 502 contents_->SetDelegate(contents_delegate_.get());
482 503
483 // The ZoomController needs to be created before the web contents is observed 504 // The ZoomController needs to be created before the web contents is observed
484 // by this object. Otherwise it will react to DidNavigateMainFrame after this 505 // by this object. Otherwise it will react to DidNavigateMainFrame after this
485 // object does, resetting the zoom mode in the process. 506 // object does, resetting the zoom mode in the process.
486 ui_zoom::ZoomController::CreateForWebContents(contents_.get()); 507 ui_zoom::ZoomController::CreateForWebContents(contents_.get());
487 Observe(contents_.get()); 508 Observe(contents_.get());
488 509
489 contents_->GetController().LoadURL( 510 contents_->GetController().LoadURL(
490 GURL(chrome::kChromeUIAppListStartPageURL), 511 GURL(chrome::kChromeUIAppListStartPageURL),
491 content::Referrer(), 512 content::Referrer(),
492 ui::PAGE_TRANSITION_AUTO_TOPLEVEL, 513 ui::PAGE_TRANSITION_AUTO_TOPLEVEL,
493 std::string()); 514 std::string());
494 } 515 }
495 516
496 void StartPageService::UnloadContents() { 517 void StartPageService::UnloadContents() {
497 contents_.reset(); 518 contents_.reset();
498 webui_finished_loading_ = false; 519 webui_finished_loading_ = false;
499 } 520 }
500 521
522 void StartPageService::FetchDoodleJson() {
523 // SetPathStr() requires its argument to stay in scope as long as
524 // |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
525 std::string path = kDoodleJsonPath;
526 GURL::Replacements replacements;
527 replacements.SetPathStr(path);
528
529 GURL doodle_url = GetGoogleBaseURL(profile_).ReplaceComponents(replacements);
530 doodle_fetcher_.reset(
531 net::URLFetcher::Create(0, doodle_url, net::URLFetcher::GET, this));
532 doodle_fetcher_->SetRequestContext(profile_->GetRequestContext());
533 doodle_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES);
534 doodle_fetcher_->Start();
535 }
536
537 void StartPageService::OnURLFetchComplete(const net::URLFetcher* source) {
538 std::string json_data;
539 source->GetResponseAsString(&json_data);
540
541 // Remove XSSI guard for JSON parsing.
542 size_t json_start_index = json_data.find("{");
543 if (json_start_index != std::string::npos)
544 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.
545
546 JSONStringValueSerializer deserializer(json_data);
547 deserializer.set_allow_trailing_comma(true);
548 int error_code = 0;
549 scoped_ptr<base::Value> doodle_json(
550 deserializer.Deserialize(&error_code, NULL));
Matt Giuca 2015/01/29 08:00:53 nullptrs (everywhere)
calamity 2015/01/30 05:09:14 Done.
551
552 int recheck_delay_ms = kDefaultDoodleRecheckDelayMs;
553
554 if (error_code == 0) {
555 base::DictionaryValue* doodle_dictionary = NULL;
556 // Use the supplied TTL as the recheck delay if available.
557 if (doodle_json->GetAsDictionary(&doodle_dictionary)) {
558 doodle_dictionary->GetInteger("ddljson.time_to_live_ms",
559 &recheck_delay_ms);
560 }
561
562 contents_->GetWebUI()->CallJavascriptFunction(
563 "appList.startPage.onAppListDoodleUpdated", *doodle_json,
564 base::StringValue(GetGoogleBaseURL(profile_).spec()));
565 }
566
567 // Check for a new doodle.
568 content::BrowserThread::PostDelayedTask(
569 content::BrowserThread::UI, FROM_HERE,
570 base::Bind(&StartPageService::FetchDoodleJson,
571 weak_factory_.GetWeakPtr()),
572 base::TimeDelta::FromMilliseconds(recheck_delay_ms));
573 }
574
501 } // namespace app_list 575 } // namespace app_list
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698