summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvadimt@chromium.org <vadimt@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-07 22:44:40 +0000
committervadimt@chromium.org <vadimt@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-07 22:44:40 +0000
commit6ee43a78f54a4a8b9562ee88bbcc4f9587a339bd (patch)
treef884daa6336c918453da14b51d87021c035829d9
parentb761c6337d1c13708dac77c7a9586e7565cdcb1f (diff)
downloadchromium_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.gypi9
-rw-r--r--chrome/browser/chrome_browser_main.cc12
-rw-r--r--chrome/browser/ui/google_now/google_now_service.cc121
-rw-r--r--chrome/browser/ui/google_now/google_now_service.h76
-rw-r--r--chrome/browser/ui/google_now/google_now_service_factory.cc36
-rw-r--r--chrome/browser/ui/google_now/google_now_service_factory.h32
-rw-r--r--chrome/chrome_browser_ui.gypi12
-rw-r--r--chrome/common/chrome_switches.cc3
-rw-r--r--chrome/common/chrome_switches.h1
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[];