diff options
author | pavely@chromium.org <pavely@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-22 18:36:20 +0000 |
---|---|---|
committer | pavely@chromium.org <pavely@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-22 18:36:20 +0000 |
commit | df006cbc99fb695e25b0d494279a8c16e39bcca9 (patch) | |
tree | a331c547a865697f2cfa93ca957ff2b16201ff46 | |
parent | a077ab834eba15dd0aea87a0fd9112b9b8b8a676 (diff) | |
download | chromium_src-df006cbc99fb695e25b0d494279a8c16e39bcca9.zip chromium_src-df006cbc99fb695e25b0d494279a8c16e39bcca9.tar.gz chromium_src-df006cbc99fb695e25b0d494279a8c16e39bcca9.tar.bz2 |
Client-to-server messages in GCMNetworkChannel
This change implements sending client-to-server messages in
GCMNetworkChannel. Implementation mimics what android implementation is
doing. To send message to server GCMNetworkChannel needs GCM
registration Id and access token. Registration Id is requested during
initialization and doesn’t change through process lifetime. Access token
is requested for every message. Errors are not handled,
cacheinvalidations will retry sending message if it doesn’t see
confirmation from server that the message was received. The only handled
error is HTTP_UNAUTHORIZED from tango server since access token needs to
be invalidated in this case.
Actual work of requesting registration id and access token is delegated
to GCMNetworkChannelDelegate interface. Implementation of this interface
will live in chrome/browser/invalidation directory and will use
GCMProfileService for registration and ProfileOAuth2TokenService for
token functions.
There are two things that are still not implemented:
- Register error handling: will need to implement retry.
- Building url for tango endpoint: this involves preparing and base64
encoding NetworkEndpointId protobuf from cacheinvalidations library.
Will address both in next CL.
BUG=325020
Review URL: https://codereview.chromium.org/140513002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@246377 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/invalidation/ticl_invalidation_service.cc | 8 | ||||
-rw-r--r-- | sync/notifier/DEPS | 4 | ||||
-rw-r--r-- | sync/notifier/gcm_network_channel.cc | 110 | ||||
-rw-r--r-- | sync/notifier/gcm_network_channel.h | 45 | ||||
-rw-r--r-- | sync/notifier/gcm_network_channel_delegate.h | 46 | ||||
-rw-r--r-- | sync/notifier/gcm_network_channel_unittest.cc | 226 | ||||
-rw-r--r-- | sync/notifier/non_blocking_invalidator.cc | 10 | ||||
-rw-r--r-- | sync/notifier/non_blocking_invalidator.h | 5 | ||||
-rw-r--r-- | sync/notifier/sync_system_resources.cc | 8 | ||||
-rw-r--r-- | sync/notifier/sync_system_resources.h | 6 | ||||
-rw-r--r-- | sync/sync_notifier.gypi | 1 | ||||
-rw-r--r-- | sync/sync_tests.gypi | 2 |
12 files changed, 448 insertions, 23 deletions
diff --git a/chrome/browser/invalidation/ticl_invalidation_service.cc b/chrome/browser/invalidation/ticl_invalidation_service.cc index c32714d..6f2b561 100644 --- a/chrome/browser/invalidation/ticl_invalidation_service.cc +++ b/chrome/browser/invalidation/ticl_invalidation_service.cc @@ -16,6 +16,7 @@ #include "chrome/browser/signin/signin_manager.h" #include "content/public/browser/notification_service.h" #include "google_apis/gaia/gaia_constants.h" +#include "sync/notifier/gcm_network_channel_delegate.h" #include "sync/notifier/invalidator.h" #include "sync/notifier/invalidator_state.h" #include "sync/notifier/non_blocking_invalidator.h" @@ -342,8 +343,13 @@ void TiclInvalidationService::StartInvalidator( break; } case GCM_NETWORK_CHANNEL: { + // TODO(pavely): Pass NULL pointer for now. When GCMNetworkChannelDelegate + // is implemented it will be instantiated and passed here. + scoped_ptr<syncer::GCMNetworkChannelDelegate> delegate; network_channel_creator = - syncer::NonBlockingInvalidator::MakeGCMNetworkChannelCreator(); + syncer::NonBlockingInvalidator::MakeGCMNetworkChannelCreator( + profile_->GetRequestContext(), + delegate.Pass()); break; } default: { diff --git a/sync/notifier/DEPS b/sync/notifier/DEPS index e02d522..4469705 100644 --- a/sync/notifier/DEPS +++ b/sync/notifier/DEPS @@ -3,8 +3,8 @@ include_rules = [ "+jingle/notifier", "+net/base/backoff_entry.h", "+net/base/mock_host_resolver.h", - "+net/url_request/url_request_context.h", - "+net/url_request/url_request_test_util.h", + "+net/http/http_status_code.h", + "+net/url_request", "+sync/base", "+sync/internal_api/public/base", diff --git a/sync/notifier/gcm_network_channel.cc b/sync/notifier/gcm_network_channel.cc index 41f288c..2e75472 100644 --- a/sync/notifier/gcm_network_channel.cc +++ b/sync/notifier/gcm_network_channel.cc @@ -2,21 +2,127 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "google_apis/gaia/google_service_auth_error.h" +#include "net/http/http_status_code.h" +#include "net/url_request/url_fetcher.h" +#include "net/url_request/url_request_status.h" #include "sync/notifier/gcm_network_channel.h" +#include "sync/notifier/gcm_network_channel_delegate.h" namespace syncer { -GCMNetworkChannel::GCMNetworkChannel() { +GCMNetworkChannel::GCMNetworkChannel( + scoped_refptr<net::URLRequestContextGetter> request_context_getter, + scoped_ptr<GCMNetworkChannelDelegate> delegate) + : request_context_getter_(request_context_getter), + delegate_(delegate.Pass()), + weak_factory_(this) { + delegate_->Register(base::Bind(&GCMNetworkChannel::OnRegisterComplete, + weak_factory_.GetWeakPtr())); } GCMNetworkChannel::~GCMNetworkChannel() { } +void GCMNetworkChannel::UpdateCredentials( + const std::string& email, + const std::string& token) { + // Do nothing. We get access token by requesting it for every message. +} + +void GCMNetworkChannel::OnRegisterComplete( + const std::string& registration_id, + gcm::GCMClient::Result result) { + DCHECK(CalledOnValidThread()); + if (result == gcm::GCMClient::SUCCESS) { + DCHECK(!registration_id.empty()); + DVLOG(2) << "Got registration_id"; + registration_id_ = registration_id; + if (!encoded_message_.empty()) + RequestAccessToken(); + } else { + DVLOG(2) << "Register failed"; + // TODO(pavely): crbug.com/335670: Implement exponential backoff retry. + } +} + void GCMNetworkChannel::SendEncodedMessage(const std::string& encoded_message) { + DCHECK(CalledOnValidThread()); + DCHECK(!encoded_message.empty()); + DVLOG(2) << "SendEncodedMessage"; + encoded_message_ = encoded_message; + + if (!registration_id_.empty()) { + RequestAccessToken(); + } +} + +void GCMNetworkChannel::RequestAccessToken() { + DCHECK(CalledOnValidThread()); + delegate_->RequestToken(base::Bind(&GCMNetworkChannel::OnGetTokenComplete, + weak_factory_.GetWeakPtr())); } -void GCMNetworkChannel::UpdateCredentials(const std::string& email, +void GCMNetworkChannel::OnGetTokenComplete( + const GoogleServiceAuthError& error, const std::string& token) { + DCHECK(CalledOnValidThread()); + if (encoded_message_.empty()) { + // Nothing to do. + return; + } + + if (error.state() != GoogleServiceAuthError::NONE) { + // Requesting access token failed. Persistent errors will be reported by + // token service. Just drop this request, cacheinvalidations will retry + // sending message and at that time we'll retry requesting access token. + DVLOG(1) << "RequestAccessToken failed: " << error.ToString(); + return; + } + DCHECK(!token.empty()); + // Save access token in case POST fails and we need to invalidate it. + access_token_ = token; + + DVLOG(2) << "Got access token, sending message"; + + fetcher_.reset(net::URLFetcher::Create(BuildUrl(), net::URLFetcher::POST, + this)); + fetcher_->SetRequestContext(request_context_getter_); + const std::string auth_header("Authorization: Bearer " + access_token_); + fetcher_->AddExtraRequestHeader(auth_header); + fetcher_->SetUploadData("application/x-protobuffer", encoded_message_); + fetcher_->Start(); + // Clear message to prevent accidentally resending it in the future. + encoded_message_.clear(); +} + +void GCMNetworkChannel::OnURLFetchComplete(const net::URLFetcher* source) { + DCHECK(CalledOnValidThread()); + DCHECK_EQ(fetcher_, source); + // Free fetcher at the end of function. + scoped_ptr<net::URLFetcher> fetcher = fetcher_.Pass(); + + net::URLRequestStatus status = fetcher->GetStatus(); + if (!status.is_success()) { + DVLOG(1) << "URLFetcher failure"; + return; + } + + if (fetcher->GetResponseCode() == net::HTTP_UNAUTHORIZED) { + DVLOG(1) << "URLFetcher failure: HTTP_UNAUTHORIZED"; + delegate_->InvalidateToken(access_token_); + return; + } + DVLOG(2) << "URLFetcher success"; +} + +GURL GCMNetworkChannel::BuildUrl() { + DCHECK(!registration_id_.empty()); + // Prepare NetworkEndpointId using registration_id + // Serialize NetworkEndpointId into byte array and base64 encode. + // Format url using encoded NetworkEndpointId. + // TODO(pavely): implement all of the above. + return GURL("http://invalid.url.com"); } } // namespace syncer diff --git a/sync/notifier/gcm_network_channel.h b/sync/notifier/gcm_network_channel.h index b7d97fb..b8bd0a4 100644 --- a/sync/notifier/gcm_network_channel.h +++ b/sync/notifier/gcm_network_channel.h @@ -10,26 +10,65 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" +#include "base/threading/non_thread_safe.h" +#include "net/url_request/url_fetcher_delegate.h" #include "sync/base/sync_export.h" +#include "sync/notifier/gcm_network_channel_delegate.h" #include "sync/notifier/sync_system_resources.h" +#include "url/gurl.h" + +class GoogleServiceAuthError; namespace syncer { // GCMNetworkChannel is an implementation of SyncNetworkChannel that routes // messages through GCMProfileService. class SYNC_EXPORT_PRIVATE GCMNetworkChannel - : public SyncNetworkChannel { + : public SyncNetworkChannel, + public net::URLFetcherDelegate, + public base::NonThreadSafe { public: - explicit GCMNetworkChannel(); + GCMNetworkChannel( + scoped_refptr<net::URLRequestContextGetter> request_context_getter, + scoped_ptr<GCMNetworkChannelDelegate> delegate); virtual ~GCMNetworkChannel(); // SyncNetworkChannel implementation. virtual void SendEncodedMessage(const std::string& encoded_message) OVERRIDE; virtual void UpdateCredentials(const std::string& email, - const std::string& token) OVERRIDE; + const std::string& token) OVERRIDE; + + // URLFetcherDelegate implementation. + virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; private: + void OnRegisterComplete(const std::string& registration_id, + gcm::GCMClient::Result result); + void RequestAccessToken(); + void OnGetTokenComplete(const GoogleServiceAuthError& error, + const std::string& token); + GURL BuildUrl(); + + scoped_refptr<net::URLRequestContextGetter> request_context_getter_; + scoped_ptr<GCMNetworkChannelDelegate> delegate_; + + // Message is saved until all conditions are met: there is valid + // registration_id and access_token. + std::string encoded_message_; + + // Access token is saved because in case of auth failure from server we need + // to invalidate it. + std::string access_token_; + + // GCM registration_id is requested one at startup and never refreshed until + // next restart. + std::string registration_id_; + + scoped_ptr<net::URLFetcher> fetcher_; + + base::WeakPtrFactory<GCMNetworkChannel> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(GCMNetworkChannel); }; diff --git a/sync/notifier/gcm_network_channel_delegate.h b/sync/notifier/gcm_network_channel_delegate.h new file mode 100644 index 0000000..30c91f7 --- /dev/null +++ b/sync/notifier/gcm_network_channel_delegate.h @@ -0,0 +1,46 @@ +// Copyright 2014 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 SYNC_NOTIFIER_GCM_NETWORK_CHANNEL_DELEGATE_H_ +#define SYNC_NOTIFIER_GCM_NETWORK_CHANNEL_DELEGATE_H_ + +#include <string> + +#include "base/callback.h" +#include "google_apis/gcm/gcm_client.h" + +class GoogleServiceAuthError; + +namespace syncer { + +// Delegate for GCMNetworkChannel. +// GCMNetworkChannel needs Register to register with GCM client and obtain gcm +// registration id. This id is used for building URL to cache invalidation +// endpoint. +// It needs RequestToken and InvalidateToken to get access token to include it +// in HTTP message to server. +// GCMNetworkChannel lives on IO thread therefore calls will be made on IO +// thread and callbacks should be invoked there as well. +class GCMNetworkChannelDelegate { + public: + typedef base::Callback<void(const GoogleServiceAuthError& error, + const std::string& token)> RequestTokenCallback; + typedef base::Callback<void(const std::string& registration_id, + gcm::GCMClient::Result result)> RegisterCallback; + + virtual ~GCMNetworkChannelDelegate() {} + + // Request access token. Callback should be called either with access token or + // error code. + virtual void RequestToken(RequestTokenCallback callback) = 0; + // Invalidate access token that was rejected by server. + virtual void InvalidateToken(const std::string& token) = 0; + + // Register with GCMProfileService. Callback should be called with either + // registration id or error code. + virtual void Register(RegisterCallback callback) = 0; +}; +} // namespace syncer + +#endif // SYNC_NOTIFIER_GCM_NETWORK_CHANNEL_DELEGATE_H_ diff --git a/sync/notifier/gcm_network_channel_unittest.cc b/sync/notifier/gcm_network_channel_unittest.cc index 8656385..20a939d 100644 --- a/sync/notifier/gcm_network_channel_unittest.cc +++ b/sync/notifier/gcm_network_channel_unittest.cc @@ -2,28 +2,67 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/run_loop.h" +#include "google_apis/gaia/google_service_auth_error.h" +#include "net/url_request/test_url_fetcher_factory.h" +#include "net/url_request/url_request_test_util.h" #include "sync/notifier/gcm_network_channel.h" - -#include "base/compiler_specific.h" #include "testing/gtest/include/gtest/gtest.h" namespace syncer { namespace { +class TestGCMNetworkChannelDelegate : public GCMNetworkChannelDelegate { + public: + virtual void RequestToken(RequestTokenCallback callback) OVERRIDE { + request_token_callback = callback; + } + + virtual void InvalidateToken(const std::string& token) OVERRIDE { + invalidated_token = token; + } + + virtual void Register(RegisterCallback callback) OVERRIDE { + register_callback = callback; + } + + RequestTokenCallback request_token_callback; + std::string invalidated_token; + RegisterCallback register_callback; +}; + class GCMNetworkChannelTest : public ::testing::Test, public SyncNetworkChannel::Observer { protected: GCMNetworkChannelTest() - : gcm_network_channel_() { - gcm_network_channel_.AddObserver(this); - gcm_network_channel_.SetMessageReceiver( + : delegate_(NULL), + url_fetchers_created_count_(0) { + } + + virtual ~GCMNetworkChannelTest() { + } + + virtual void SetUp() { + request_context_getter_ = new net::TestURLRequestContextGetter( + base::MessageLoopProxy::current()); + // Ownership of delegate goes to GCNMentworkChannel but test needs pointer + // to it. + delegate_ = new TestGCMNetworkChannelDelegate(); + scoped_ptr<GCMNetworkChannelDelegate> delegate(delegate_); + gcm_network_channel_.reset(new GCMNetworkChannel(request_context_getter_, + delegate.Pass())); + gcm_network_channel_->AddObserver(this); + gcm_network_channel_->SetMessageReceiver( invalidation::NewPermanentCallback( this, &GCMNetworkChannelTest::OnIncomingMessage)); + url_fetcher_factory_.reset(new net::FakeURLFetcherFactory(NULL, + base::Bind(&GCMNetworkChannelTest::CreateURLFetcher, + base::Unretained(this)))); } - virtual ~GCMNetworkChannelTest() { - gcm_network_channel_.RemoveObserver(this); + virtual void TearDown() { + gcm_network_channel_->RemoveObserver(this); } virtual void OnNetworkChannelStateChanged( @@ -33,8 +72,179 @@ class GCMNetworkChannelTest void OnIncomingMessage(std::string incoming_message) { } - GCMNetworkChannel gcm_network_channel_; + GCMNetworkChannel* network_channel() { + return gcm_network_channel_.get(); + } + + TestGCMNetworkChannelDelegate* delegate() { + return delegate_; + } + + int url_fetchers_created_count() { + return url_fetchers_created_count_; + } + + net::FakeURLFetcherFactory* url_fetcher_factory() { + return url_fetcher_factory_.get(); + } + + scoped_ptr<net::FakeURLFetcher> CreateURLFetcher( + const GURL& url, + net::URLFetcherDelegate* delegate, + const std::string& response_data, + net::HttpStatusCode response_code, + net::URLRequestStatus::Status status) { + url_fetchers_created_count_++; + return scoped_ptr<net::FakeURLFetcher>(new net::FakeURLFetcher( + url, delegate, response_data, response_code, status)); + } + + private: + base::MessageLoop message_loop_; + TestGCMNetworkChannelDelegate* delegate_; + scoped_ptr<GCMNetworkChannel> gcm_network_channel_; + scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_; + scoped_ptr<net::FakeURLFetcherFactory> url_fetcher_factory_; + int url_fetchers_created_count_; }; +TEST_F(GCMNetworkChannelTest, HappyCase) { + GURL url("http://invalid.url.com"); + url_fetcher_factory()->SetFakeResponse(url, std::string(), net::HTTP_OK, + net::URLRequestStatus::SUCCESS); + + // After construction GCMNetworkChannel should have called Register. + EXPECT_FALSE(delegate()->register_callback.is_null()); + // Return valid registration id. + delegate()->register_callback.Run("registration.id", gcm::GCMClient::SUCCESS); + + network_channel()->SendMessage("abra.cadabra"); + // SendMessage should have triggered RequestToken. No HTTP request should be + // started yet. + EXPECT_FALSE(delegate()->request_token_callback.is_null()); + EXPECT_EQ(url_fetchers_created_count(), 0); + // Return valid access token. This should trigger HTTP request. + delegate()->request_token_callback.Run( + GoogleServiceAuthError::AuthErrorNone(), "access.token"); + { + base::RunLoop run_loop; + run_loop.RunUntilIdle(); + } + EXPECT_EQ(url_fetchers_created_count(), 1); + + // Return another access token. Message should be cleared by now and shouldn't + // be sent. + delegate()->request_token_callback.Run( + GoogleServiceAuthError::AuthErrorNone(), "access.token2"); + { + base::RunLoop run_loop; + run_loop.RunUntilIdle(); + } + EXPECT_EQ(url_fetchers_created_count(), 1); +} + +TEST_F(GCMNetworkChannelTest, FailedRegister) { + // After construction GCMNetworkChannel should have called Register. + EXPECT_FALSE(delegate()->register_callback.is_null()); + // Return error from Register call. + delegate()->register_callback.Run("", gcm::GCMClient::SERVER_ERROR); + + network_channel()->SendMessage("abra.cadabra"); + // SendMessage shouldn't trigger RequestToken. + EXPECT_TRUE(delegate()->request_token_callback.is_null()); + EXPECT_EQ(url_fetchers_created_count(), 0); +} + +TEST_F(GCMNetworkChannelTest, RegisterFinishesAfterSendMessage) { + GURL url("http://invalid.url.com"); + url_fetcher_factory()->SetFakeResponse(url, "", net::HTTP_OK, + net::URLRequestStatus::SUCCESS); + + // After construction GCMNetworkChannel should have called Register. + EXPECT_FALSE(delegate()->register_callback.is_null()); + + network_channel()->SendMessage("abra.cadabra"); + // SendMessage shouldn't trigger RequestToken. + EXPECT_TRUE(delegate()->request_token_callback.is_null()); + EXPECT_EQ(url_fetchers_created_count(), 0); + + // Return valid registration id. + delegate()->register_callback.Run("registration.id", gcm::GCMClient::SUCCESS); + + EXPECT_FALSE(delegate()->request_token_callback.is_null()); + EXPECT_EQ(url_fetchers_created_count(), 0); + // Return valid access token. This should trigger HTTP request. + delegate()->request_token_callback.Run( + GoogleServiceAuthError::AuthErrorNone(), "access.token"); + { + base::RunLoop run_loop; + run_loop.RunUntilIdle(); + } + EXPECT_EQ(url_fetchers_created_count(), 1); +} + +TEST_F(GCMNetworkChannelTest, RequestTokenFailure) { + // After construction GCMNetworkChannel should have called Register. + EXPECT_FALSE(delegate()->register_callback.is_null()); + // Return valid registration id. + delegate()->register_callback.Run("registration.id", gcm::GCMClient::SUCCESS); + + network_channel()->SendMessage("abra.cadabra"); + // SendMessage should have triggered RequestToken. No HTTP request should be + // started yet. + EXPECT_FALSE(delegate()->request_token_callback.is_null()); + EXPECT_EQ(url_fetchers_created_count(), 0); + // RequestToken returns failure. + delegate()->request_token_callback.Run( + GoogleServiceAuthError::FromConnectionError(1), ""); + + // Should be no HTTP requests. + EXPECT_EQ(url_fetchers_created_count(), 0); +} + +TEST_F(GCMNetworkChannelTest, AuthErrorFromServer) { + // Setup fake response to return AUTH_ERROR. + GURL url("http://invalid.url.com"); + url_fetcher_factory()->SetFakeResponse(url, "", net::HTTP_UNAUTHORIZED, + net::URLRequestStatus::SUCCESS); + + // After construction GCMNetworkChannel should have called Register. + EXPECT_FALSE(delegate()->register_callback.is_null()); + // Return valid registration id. + delegate()->register_callback.Run("registration.id", gcm::GCMClient::SUCCESS); + + network_channel()->SendMessage("abra.cadabra"); + // SendMessage should have triggered RequestToken. No HTTP request should be + // started yet. + EXPECT_FALSE(delegate()->request_token_callback.is_null()); + EXPECT_EQ(url_fetchers_created_count(), 0); + // Return valid access token. This should trigger HTTP request. + delegate()->request_token_callback.Run( + GoogleServiceAuthError::AuthErrorNone(), "access.token"); + { + base::RunLoop run_loop; + run_loop.RunUntilIdle(); + } + EXPECT_EQ(url_fetchers_created_count(), 1); + EXPECT_EQ(delegate()->invalidated_token, "access.token"); +} + +// Following two tests are to check for memory leaks/crashes when Register and +// RequestToken don't complete by the teardown. +TEST_F(GCMNetworkChannelTest, RegisterNeverCompletes) { + network_channel()->SendMessage("abra.cadabra"); + // Register should be called by now. Let's not complete and see what happens. + EXPECT_FALSE(delegate()->register_callback.is_null()); +} + +TEST_F(GCMNetworkChannelTest, RequestTokenNeverCompletes) { + network_channel()->SendMessage("abra.cadabra"); + // Return valid registration id. + delegate()->register_callback.Run("registration.id", gcm::GCMClient::SUCCESS); + // RequestToken should be called by now. Let's not complete and see what + // happens. + EXPECT_FALSE(delegate()->request_token_callback.is_null()); +} + } // namespace } // namespace syncer diff --git a/sync/notifier/non_blocking_invalidator.cc b/sync/notifier/non_blocking_invalidator.cc index 5ec1758..1b90a97 100644 --- a/sync/notifier/non_blocking_invalidator.cc +++ b/sync/notifier/non_blocking_invalidator.cc @@ -13,6 +13,7 @@ #include "base/thread_task_runner_handle.h" #include "base/threading/thread.h" #include "jingle/notifier/listener/push_client.h" +#include "sync/notifier/gcm_network_channel_delegate.h" #include "sync/notifier/invalidation_notifier.h" #include "sync/notifier/object_id_invalidation_map.h" #include "sync/notifier/sync_system_resources.h" @@ -247,9 +248,12 @@ NetworkChannelCreator notifier_options); } -NetworkChannelCreator - NonBlockingInvalidator::MakeGCMNetworkChannelCreator() { - return base::Bind(SyncNetworkChannel::CreateGCMNetworkChannel); +NetworkChannelCreator NonBlockingInvalidator::MakeGCMNetworkChannelCreator( + scoped_refptr<net::URLRequestContextGetter> request_context_getter, + scoped_ptr<GCMNetworkChannelDelegate> delegate) { + return base::Bind(&SyncNetworkChannel::CreateGCMNetworkChannel, + request_context_getter, + base::Passed(&delegate)); } } // namespace syncer diff --git a/sync/notifier/non_blocking_invalidator.h b/sync/notifier/non_blocking_invalidator.h index 7de6d95..1b2e072 100644 --- a/sync/notifier/non_blocking_invalidator.h +++ b/sync/notifier/non_blocking_invalidator.h @@ -29,6 +29,7 @@ class SingleThreadTaskRunner; namespace syncer { class SyncNetworkChannel; +class GCMNetworkChannelDelegate; // Callback type for function that creates SyncNetworkChannel. This function // gets passed into NonBlockingInvalidator constructor. @@ -74,7 +75,9 @@ class SYNC_EXPORT_PRIVATE NonBlockingInvalidator // channel implementation to client of invalidator. static NetworkChannelCreator MakePushClientChannelCreator( const notifier::NotifierOptions& notifier_options); - static NetworkChannelCreator MakeGCMNetworkChannelCreator(); + static NetworkChannelCreator MakeGCMNetworkChannelCreator( + scoped_refptr<net::URLRequestContextGetter> request_context_getter, + scoped_ptr<GCMNetworkChannelDelegate> delegate); private: struct InitializeOptions; class Core; diff --git a/sync/notifier/sync_system_resources.cc b/sync/notifier/sync_system_resources.cc index c9ca212..dd783da 100644 --- a/sync/notifier/sync_system_resources.cc +++ b/sync/notifier/sync_system_resources.cc @@ -19,6 +19,7 @@ #include "google/cacheinvalidation/include/types.h" #include "jingle/notifier/listener/push_client.h" #include "sync/notifier/gcm_network_channel.h" +#include "sync/notifier/gcm_network_channel_delegate.h" #include "sync/notifier/invalidation_util.h" #include "sync/notifier/push_client_channel.h" @@ -179,8 +180,11 @@ scoped_ptr<SyncNetworkChannel> SyncNetworkChannel::CreatePushClientChannel( new PushClientChannel(push_client.Pass())); } -scoped_ptr<SyncNetworkChannel> SyncNetworkChannel::CreateGCMNetworkChannel() { - return scoped_ptr<SyncNetworkChannel>(new GCMNetworkChannel()); +scoped_ptr<SyncNetworkChannel> SyncNetworkChannel::CreateGCMNetworkChannel( + scoped_refptr<net::URLRequestContextGetter> request_context_getter, + scoped_ptr<GCMNetworkChannelDelegate> delegate) { + return scoped_ptr<SyncNetworkChannel>(new GCMNetworkChannel( + request_context_getter, delegate.Pass())); } const std::string& SyncNetworkChannel::GetServiceContextForTest() const { diff --git a/sync/notifier/sync_system_resources.h b/sync/notifier/sync_system_resources.h index 22fcb96..14711dd 100644 --- a/sync/notifier/sync_system_resources.h +++ b/sync/notifier/sync_system_resources.h @@ -26,6 +26,8 @@ namespace syncer { +class GCMNetworkChannelDelegate; + class SyncLogger : public invalidation::Logger { public: SyncLogger(); @@ -123,7 +125,9 @@ class SYNC_EXPORT_PRIVATE SyncNetworkChannel // specific parameters. static scoped_ptr<SyncNetworkChannel> CreatePushClientChannel( const notifier::NotifierOptions& notifier_options); - static scoped_ptr<SyncNetworkChannel> CreateGCMNetworkChannel(); + static scoped_ptr<SyncNetworkChannel> CreateGCMNetworkChannel( + scoped_refptr<net::URLRequestContextGetter> request_context_getter, + scoped_ptr<GCMNetworkChannelDelegate> delegate); const std::string& GetServiceContextForTest() const; diff --git a/sync/sync_notifier.gypi b/sync/sync_notifier.gypi index 930bb09..f8e9d5c 100644 --- a/sync/sync_notifier.gypi +++ b/sync/sync_notifier.gypi @@ -50,6 +50,7 @@ 'sources': [ 'notifier/gcm_network_channel.cc', 'notifier/gcm_network_channel.h', + 'notifier/gcm_network_channel_delegate.h', 'notifier/invalidation_notifier.cc', 'notifier/invalidation_notifier.h', 'notifier/non_blocking_invalidator.cc', diff --git a/sync/sync_tests.gypi b/sync/sync_tests.gypi index f4729c6..1adbf1c 100644 --- a/sync/sync_tests.gypi +++ b/sync/sync_tests.gypi @@ -313,6 +313,7 @@ 'suppress_wildcard': 1, 'dependencies': [ '../base/base.gyp:base', + '../google_apis/google_apis.gyp:google_apis', '../jingle/jingle.gyp:notifier_test_util', '../net/net.gyp:net_test_support', '../testing/gmock.gyp:gmock', @@ -326,6 +327,7 @@ # happens in the dependents. 'export_dependent_settings': [ '../base/base.gyp:base', + '../google_apis/google_apis.gyp:google_apis', '../jingle/jingle.gyp:notifier_test_util', '../net/net.gyp:net_test_support', '../testing/gmock.gyp:gmock', |