diff options
author | vadimt@chromium.org <vadimt@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-07 22:44:40 +0000 |
---|---|---|
committer | vadimt@chromium.org <vadimt@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-07 22:44:40 +0000 |
commit | 6ee43a78f54a4a8b9562ee88bbcc4f9587a339bd (patch) | |
tree | f884daa6336c918453da14b51d87021c035829d9 | |
parent | b761c6337d1c13708dac77c7a9586e7565cdcb1f (diff) | |
download | chromium_src-6ee43a78f54a4a8b9562ee88bbcc4f9587a339bd.zip chromium_src-6ee43a78f54a4a8b9562ee88bbcc4f9587a339bd.tar.gz chromium_src-6ee43a78f54a4a8b9562ee88bbcc4f9587a339bd.tar.bz2 |
Creating a skeleton for Google Now for Chrome implementation.
The CL creates the top-level structure for showing Google Now cards in Chrome via Chrome Notifications.
The implementation lives behind -enable-google-now-integration flag.
BUG=164227
Review URL: https://chromiumcodereview.appspot.com/11412291
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@171868 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | build/common.gypi | 9 | ||||
-rw-r--r-- | chrome/browser/chrome_browser_main.cc | 12 | ||||
-rw-r--r-- | chrome/browser/ui/google_now/google_now_service.cc | 121 | ||||
-rw-r--r-- | chrome/browser/ui/google_now/google_now_service.h | 76 | ||||
-rw-r--r-- | chrome/browser/ui/google_now/google_now_service_factory.cc | 36 | ||||
-rw-r--r-- | chrome/browser/ui/google_now/google_now_service_factory.h | 32 | ||||
-rw-r--r-- | chrome/chrome_browser_ui.gypi | 12 | ||||
-rw-r--r-- | chrome/common/chrome_switches.cc | 3 | ||||
-rw-r--r-- | chrome/common/chrome_switches.h | 1 |
9 files changed, 302 insertions, 0 deletions
diff --git a/build/common.gypi b/build/common.gypi index 31bf1c4..f24dadde 100644 --- a/build/common.gypi +++ b/build/common.gypi @@ -299,6 +299,9 @@ # Enable browser automation. 'enable_automation%': 1, + # Enable Google Now. + 'enable_google_now%': 1, + # Enable language detection. 'enable_language_detection%': 1, @@ -480,6 +483,7 @@ ['OS=="android"', { 'enable_extensions%': 0, + 'enable_google_now%': 0, 'enable_language_detection%': 0, 'enable_printing%': 0, 'enable_themes%': 0, @@ -493,6 +497,7 @@ 'disable_ftp_support%': 1, 'enable_automation%': 0, 'enable_extensions%': 0, + 'enable_google_now%': 0, 'enable_language_detection%': 0, 'enable_printing%': 0, 'enable_session_service%': 0, @@ -691,6 +696,7 @@ 'test_isolation_outdir%': '<(test_isolation_outdir)', 'enable_automation%': '<(enable_automation)', 'enable_printing%': '<(enable_printing)', + 'enable_google_now%': '<(enable_google_now)', 'enable_language_detection%': '<(enable_language_detection)', 'enable_captive_portal_detection%': '<(enable_captive_portal_detection)', 'disable_ftp_support%': '<(disable_ftp_support)', @@ -1888,6 +1894,9 @@ ['enable_automation==1', { 'defines': ['ENABLE_AUTOMATION=1'], }], + ['enable_google_now==1', { + 'defines': ['ENABLE_GOOGLE_NOW=1'], + }], ['enable_language_detection==1', { 'defines': ['ENABLE_LANGUAGE_DETECTION=1'], }], diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index c5c1948..8f79b48 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc @@ -169,6 +169,10 @@ #include "policy/policy_constants.h" #endif +#if defined(ENABLE_GOOGLE_NOW) +#include "chrome/browser/ui/google_now/google_now_service_factory.h" +#endif + #if defined(ENABLE_LANGUAGE_DETECTION) #include "chrome/browser/language_usage_metrics.h" #endif @@ -907,6 +911,14 @@ void ChromeBrowserMainParts::PostBrowserStart() { RunPageCycler(); #endif + // Create the instance of the Google Now service. +#if defined(ENABLE_GOOGLE_NOW) + if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableGoogleNowIntegration)) { + GoogleNowServiceFactory::GetForProfile(profile_); + } +#endif + for (size_t i = 0; i < chrome_extra_parts_.size(); ++i) chrome_extra_parts_[i]->PostBrowserStart(); #if !defined(OS_ANDROID) diff --git a/chrome/browser/ui/google_now/google_now_service.cc b/chrome/browser/ui/google_now/google_now_service.cc new file mode 100644 index 0000000..b23c58b --- /dev/null +++ b/chrome/browser/ui/google_now/google_now_service.cc @@ -0,0 +1,121 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/google_now/google_now_service.h" + +#include "content/public/common/geoposition.h" + +using base::TimeDelta; +using content::Geoposition; +using net::URLRequest; + +namespace { +// Period for polling for Google Now cards to use when the period from the +// server is not available. +// TODO(vadimt): Figure out the value. +// TODO(vadimt): Figure out the consequences for LBS. +// TODO(vadimt): Consider triggers other than the timer for refreshing the +// position, such as waking from sleep. +const int kDefaultPollingPeriodMs = 300000; // 5 minutes +} // namespace + +struct GoogleNowService::ServerResponse { + // TODO(vadimt): Populate this structure with real fields. + TimeDelta next_request_delay; +}; + +GoogleNowService::GoogleNowService(Profile* profile) + : profile_(profile) { + DCHECK(profile_); +} + +GoogleNowService::~GoogleNowService() { +} + +void GoogleNowService::Init() { + // If Google Now integration is enabled for the profile, start the first cards + // update. + if (IsGoogleNowEnabled()) + UpdateCards(); +} + +bool GoogleNowService::IsGoogleNowEnabled() const { + // TODO(vadimt): Return a value indicating whether Google Now integration is + // enabled for 'profile_'. + // TODO(vadimt): Process enabling and disabling Google Now integration while + // the service is running. + return true; +} + +void GoogleNowService::UpdateCards() { + // Start obtaining geolocation for the server's request. + StartObtainingGeolocation(); +} + +void GoogleNowService::StartWaitingForNextUpdate(TimeDelta delay) { + DCHECK(!next_update_timer_.IsRunning()); + + next_update_timer_.Start(FROM_HERE, delay, + this, &GoogleNowService::OnWaitingForNextUpdateEnds); +} + +void GoogleNowService::OnWaitingForNextUpdateEnds() { + DCHECK(IsGoogleNowEnabled()); + DCHECK(!next_update_timer_.IsRunning()); + + UpdateCards(); +} + +void GoogleNowService::StartObtainingGeolocation() { + // TODO(vadimt): Implement via making a geolocation request. + OnLocationObtained(Geoposition()); +} + +void GoogleNowService::OnLocationObtained(const Geoposition& position) { + DCHECK(IsGoogleNowEnabled()); + DCHECK(!next_update_timer_.IsRunning()); + + StartServerRequest(position); +} + +void GoogleNowService::StartServerRequest( + const content::Geoposition& position) { + // TODO(vadimt): Implement via making URLRequest to the server. + OnServerRequestCompleted(NULL, 0); +} + +void GoogleNowService::OnServerRequestCompleted(URLRequest* request, + int num_bytes) { + DCHECK(IsGoogleNowEnabled()); + DCHECK(!next_update_timer_.IsRunning()); + + ServerResponse server_response; + // TODO(vadimt): Check request's status. + if (ParseServerResponse(request, num_bytes, &server_response)) { + ShowNotifications(server_response); + // Once the cards are shown, schedule next cards update after the delay + // suggested by the server. + StartWaitingForNextUpdate(server_response.next_request_delay); + } else { + // If the server response is bad, schedule next cards update after the + // default delay. + // TODO(vadimt): Consider exponential backoff with randomized jitter. + StartWaitingForNextUpdate( + TimeDelta::FromMilliseconds(kDefaultPollingPeriodMs)); + } +} + +bool GoogleNowService::ParseServerResponse(const URLRequest* request, + int num_bytes, + ServerResponse* server_response) { + // TODO(vadimt): Do real parsing. + server_response->next_request_delay = + TimeDelta::FromMilliseconds(kDefaultPollingPeriodMs); + return true; +} + +void GoogleNowService::ShowNotifications( + const ServerResponse& server_response) { + // TODO(vadimt): Implement using Chrome Notifications. +} diff --git a/chrome/browser/ui/google_now/google_now_service.h b/chrome/browser/ui/google_now/google_now_service.h new file mode 100644 index 0000000..eb6459a --- /dev/null +++ b/chrome/browser/ui/google_now/google_now_service.h @@ -0,0 +1,76 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_GOOGLE_NOW_GOOGLE_NOW_SERVICE_H_ +#define CHROME_BROWSER_UI_GOOGLE_NOW_GOOGLE_NOW_SERVICE_H_ + +#include "base/timer.h" +#include "chrome/browser/profiles/profile_keyed_service.h" + +class Profile; + +namespace base { +class TimeDelta; +} + +namespace content { +struct Geoposition; +} + +namespace net { +class URLRequest; +} + +// The Google Now service gets Google Now cards from the server and shows them +// as Chrome notifications. +// The service performs periodic updating of Google Now cards. +// Each updating of the cards consists of 3 steps: +// 1. Obtaining the location of the machine (asynchronous); +// 2. Making a server request (asynchronous); +// 3. Showing the cards as notifications. +class GoogleNowService : public ProfileKeyedService { + public: + // Must call Init after construction. + explicit GoogleNowService(Profile* profile); + virtual ~GoogleNowService(); + void Init(); + + private: + // Parsed response from the server. + struct ServerResponse; + + // Returns true if Google Now integration is enabled for the profile. + bool IsGoogleNowEnabled() const; + // Gets new cards from the server and shows them as notifications. + void UpdateCards(); + + // Schedules next cards update after the specified delay. + void StartWaitingForNextUpdate(base::TimeDelta delay); + void OnWaitingForNextUpdateEnds(); + + // Starts obtaining location of the machine. + void StartObtainingGeolocation(); + void OnLocationObtained(const content::Geoposition& position); + + // Starts downloading cards from the server. + void StartServerRequest(const content::Geoposition& position); + void OnServerRequestCompleted(net::URLRequest* request, int num_bytes); + + // Parses server response. Returns true if the parsing was successful. + static bool ParseServerResponse(const net::URLRequest* request, + int num_bytes, + ServerResponse* server_response); + + // Shows Google Now cards as notifications. + void ShowNotifications(const ServerResponse& server_response); + + // The profile. + Profile* const profile_; + // Timer to schedule next cards update. + base::OneShotTimer<GoogleNowService> next_update_timer_; + + DISALLOW_COPY_AND_ASSIGN(GoogleNowService); +}; + +#endif // CHROME_BROWSER_UI_GOOGLE_NOW_GOOGLE_NOW_SERVICE_H_ diff --git a/chrome/browser/ui/google_now/google_now_service_factory.cc b/chrome/browser/ui/google_now/google_now_service_factory.cc new file mode 100644 index 0000000..3b6747c --- /dev/null +++ b/chrome/browser/ui/google_now/google_now_service_factory.cc @@ -0,0 +1,36 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/google_now/google_now_service_factory.h" + +#include "base/memory/singleton.h" +#include "chrome/browser/profiles/profile_dependency_manager.h" +#include "chrome/browser/ui/google_now/google_now_service.h" + +// static +GoogleNowService* GoogleNowServiceFactory::GetForProfile(Profile* profile) { + return static_cast<GoogleNowService*>( + GetInstance()->GetServiceForProfile(profile, true)); +} + +// static +GoogleNowServiceFactory* GoogleNowServiceFactory::GetInstance() { + return Singleton<GoogleNowServiceFactory>::get(); +} + +GoogleNowServiceFactory::GoogleNowServiceFactory() + : ProfileKeyedServiceFactory( + "GoogleNowService", ProfileDependencyManager::GetInstance()) { +} + +bool GoogleNowServiceFactory::ServiceIsCreatedWithProfile() const { + return true; +} + +ProfileKeyedService* +GoogleNowServiceFactory::BuildServiceInstanceFor(Profile* profile) const { + GoogleNowService* const google_now_service = new GoogleNowService(profile); + google_now_service->Init(); + return google_now_service; +} diff --git a/chrome/browser/ui/google_now/google_now_service_factory.h b/chrome/browser/ui/google_now/google_now_service_factory.h new file mode 100644 index 0000000..e241b66 --- /dev/null +++ b/chrome/browser/ui/google_now/google_now_service_factory.h @@ -0,0 +1,32 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_GOOGLE_NOW_GOOGLE_NOW_SERVICE_FACTORY_H_ +#define CHROME_BROWSER_UI_GOOGLE_NOW_GOOGLE_NOW_SERVICE_FACTORY_H_ + +#include "chrome/browser/profiles/profile_keyed_service_factory.h" + +class GoogleNowService; +class Profile; +template<typename Type> struct DefaultSingletonTraits; + +// Singleton that owns all GoogleNowService and associates them with +// Profiles. +class GoogleNowServiceFactory : public ProfileKeyedServiceFactory { + public: + static GoogleNowService* GetForProfile(Profile* profile); + static GoogleNowServiceFactory* GetInstance(); + + private: + friend struct DefaultSingletonTraits<GoogleNowServiceFactory>; + + GoogleNowServiceFactory(); + + // ProfileKeyedServiceFactory: + virtual bool ServiceIsCreatedWithProfile() const OVERRIDE; + virtual ProfileKeyedService* BuildServiceInstanceFor( + Profile* profile) const OVERRIDE; +}; + +#endif // CHROME_BROWSER_UI_GOOGLE_NOW_GOOGLE_NOW_SERVICE_FACTORY_H_ diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi index 1b4686d..dedd3ca 100644 --- a/chrome/chrome_browser_ui.gypi +++ b/chrome/chrome_browser_ui.gypi @@ -834,6 +834,10 @@ 'browser/ui/global_error/global_error_service.h', 'browser/ui/global_error/global_error_service_factory.cc', 'browser/ui/global_error/global_error_service_factory.h', + 'browser/ui/google_now/google_now_service.cc', + 'browser/ui/google_now/google_now_service.h', + 'browser/ui/google_now/google_now_service_factory.cc', + 'browser/ui/google_now/google_now_service_factory.h', 'browser/ui/gtk/accelerators_gtk.cc', 'browser/ui/gtk/accelerators_gtk.h', 'browser/ui/gtk/action_box_button_gtk.cc', @@ -2194,6 +2198,14 @@ 'browser/ui/views/sync/one_click_signin_bubble_view.h', ] }], + ['enable_google_now==0', { + 'sources!': [ + 'browser/ui/google_now/google_now_service.cc', + 'browser/ui/google_now/google_now_service.h', + 'browser/ui/google_now/google_now_service_factory.cc', + 'browser/ui/google_now/google_now_service_factory.h', + ], + }], ['enable_task_manager==0', { 'sources/': [ ['exclude', '^browser/ui/webui/task_manager/'], diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 019a400..096926b 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -533,6 +533,9 @@ const char kEnableChromeStyleDialogs[] = "enable-chrome-style-dialogs"; // for example page cycler and layout tests. See bug 1157243. const char kEnableFileCookies[] = "enable-file-cookies"; +// Enables Google Now integration. +const char kEnableGoogleNowIntegration[] = "enable-google-now-integration"; + // Enable HTTP pipelining. Attempt to pipeline HTTP connections. Heuristics will // try to figure out if pipelining can be used for a given host and request. // Without this flag, pipelining will never be used. diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 82c5c88..1a6dce4 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -152,6 +152,7 @@ extern const char kEnableExtensionActivityLogging[]; extern const char kEnableExtensionActivityUI[]; extern const char kEnableExtensionTimelineApi[]; extern const char kEnableFileCookies[]; +extern const char kEnableGoogleNowIntegration[]; extern const char kEnableHttpPipelining[]; extern const char kEnableInstantExtendedAPI[]; extern const char kEnableInteractiveAutocomplete[]; |