diff options
author | fgorski@chromium.org <fgorski@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-15 20:34:28 +0000 |
---|---|---|
committer | fgorski@chromium.org <fgorski@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-15 20:34:28 +0000 |
commit | e400704fcf1b2b8ff15c73e9d26c8e4df30899ae (patch) | |
tree | da6cfef1239f48b048f1d70859b8be3de59a0923 /google_apis/gcm | |
parent | 1ea4c493152c8b225d397ade32ef1023870293c3 (diff) | |
download | chromium_src-e400704fcf1b2b8ff15c73e9d26c8e4df30899ae.zip chromium_src-e400704fcf1b2b8ff15c73e9d26c8e4df30899ae.tar.gz chromium_src-e400704fcf1b2b8ff15c73e9d26c8e4df30899ae.tar.bz2 |
[GCM] Hooking up unregistration
* Implemetning GCMClientImpl.Unregister, added UnregisterCompleted
* Added OnUnregisterFinished to GCMClient::Delegate - the status is passed as a bool, because we ignore it anyway, and it is simply a hook for testing. Functionality is triggered in response to downstream message and not user's interaction.
* Added a test that consumes the delegate hook.
* I considered removing messages related to APP ID, but decided not to add that functionality to GCM Store, as those messages would be sent to MCS before we realize that the app is uninstalled, and there is no point in writing code that would never really do much.
BUG=284553
Review URL: https://codereview.chromium.org/163953013
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@251593 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'google_apis/gcm')
-rw-r--r-- | google_apis/gcm/gcm_client.h | 6 | ||||
-rw-r--r-- | google_apis/gcm/gcm_client_impl.cc | 39 | ||||
-rw-r--r-- | google_apis/gcm/gcm_client_impl.h | 18 | ||||
-rw-r--r-- | google_apis/gcm/gcm_client_impl_unittest.cc | 33 |
4 files changed, 91 insertions, 5 deletions
diff --git a/google_apis/gcm/gcm_client.h b/google_apis/gcm/gcm_client.h index be3af60..8bb616d 100644 --- a/google_apis/gcm/gcm_client.h +++ b/google_apis/gcm/gcm_client.h @@ -90,6 +90,12 @@ class GCM_EXPORT GCMClient { const std::string& registration_id, Result result) = 0; + // Called when the unregistration completed. + // |app_id|: application ID. + // |success|: indicates whether unregistration request was successful. + virtual void OnUnregisterFinished(const std::string& app_id, + bool success) = 0; + // Called when the message is scheduled to send successfully or an error // occurs. // |app_id|: application ID. diff --git a/google_apis/gcm/gcm_client_impl.cc b/google_apis/gcm/gcm_client_impl.cc index 3100e71..b0160d6 100644 --- a/google_apis/gcm/gcm_client_impl.cc +++ b/google_apis/gcm/gcm_client_impl.cc @@ -18,6 +18,7 @@ #include "google_apis/gcm/engine/gcm_store_impl.h" #include "google_apis/gcm/engine/mcs_client.h" #include "google_apis/gcm/engine/registration_request.h" +#include "google_apis/gcm/engine/unregistration_request.h" #include "google_apis/gcm/protocol/mcs.pb.h" #include "net/http/http_network_session.h" #include "net/url_request/url_request_context.h" @@ -115,6 +116,7 @@ GCMClientImpl::GCMClientImpl() clock_(new base::DefaultClock()), url_request_context_getter_(NULL), pending_registrations_deleter_(&pending_registrations_), + pending_unregistrations_deleter_(&pending_unregistrations_), weak_ptr_factory_(this) { } @@ -305,8 +307,8 @@ void GCMClientImpl::Register(const std::string& app_id, } void GCMClientImpl::OnRegisterCompleted(const std::string& app_id, - RegistrationRequest::Status status, - const std::string& registration_id) { + RegistrationRequest::Status status, + const std::string& registration_id) { DCHECK(delegate_); Result result; @@ -330,6 +332,39 @@ void GCMClientImpl::OnRegisterCompleted(const std::string& app_id, } void GCMClientImpl::Unregister(const std::string& app_id) { + DCHECK_EQ(state_, READY); + if (pending_unregistrations_.count(app_id) == 1) + return; + + UnregistrationRequest::RequestInfo request_info( + device_checkin_info_.android_id, + device_checkin_info_.secret, + app_id); + + UnregistrationRequest* unregistration_request = + new UnregistrationRequest( + request_info, + kDefaultBackoffPolicy, + base::Bind(&GCMClientImpl::OnUnregisterCompleted, + weak_ptr_factory_.GetWeakPtr(), + app_id), + url_request_context_getter_); + pending_unregistrations_[app_id] = unregistration_request; + unregistration_request->Start(); +} + +void GCMClientImpl::OnUnregisterCompleted(const std::string& app_id, + bool status) { + DVLOG(1) << "Unregister completed for app: " << app_id + << " with " << (status ? "success." : "failure."); + delegate_->OnUnregisterFinished(app_id, status); + + PendingUnregistrations::iterator iter = pending_unregistrations_.find(app_id); + if (iter == pending_unregistrations_.end()) + return; + + delete iter->second; + pending_unregistrations_.erase(iter); } void GCMClientImpl::Send(const std::string& app_id, diff --git a/google_apis/gcm/gcm_client_impl.h b/google_apis/gcm/gcm_client_impl.h index 3e59702..40b90f2 100644 --- a/google_apis/gcm/gcm_client_impl.h +++ b/google_apis/gcm/gcm_client_impl.h @@ -35,7 +35,7 @@ namespace gcm { class CheckinRequest; class ConnectionFactory; class GCMClientImplTest; -class RegistrationRequest; +class UnregistrationRequest; // Implements the GCM Client. It is used to coordinate MCS Client (communication // with MCS) and other pieces of GCM infrastructure like Registration and @@ -90,12 +90,18 @@ class GCM_EXPORT GCMClientImpl : public GCMClient { uint64 secret; }; - // Collection of pending registration requests. Keys are app_id, while values + // Collection of pending registration requests. Keys are app IDs, while values // are pending registration requests to obtain a registration ID for // requesting application. typedef std::map<std::string, RegistrationRequest*> PendingRegistrations; + // Collection of pending unregistration requests. Keys are app IDs, while + // values are pending unregistration requests to disable the registration ID + // currently assigned to the application. + typedef std::map<std::string, UnregistrationRequest*> + PendingUnregistrations; + friend class GCMClientImplTest; // Callbacks for the MCSClient. @@ -140,6 +146,9 @@ class GCM_EXPORT GCMClientImpl : public GCMClient { RegistrationRequest::Status status, const std::string& registration_id); + // Completes the unregistration request. + void OnUnregisterCompleted(const std::string& app_id, bool status); + // Handles incoming data message and dispatches it the a relevant user // delegate. void HandleIncomingMessage(const gcm::MCSMessage& message); @@ -192,6 +201,11 @@ class GCM_EXPORT GCMClientImpl : public GCMClient { PendingRegistrations pending_registrations_; STLValueDeleter<PendingRegistrations> pending_registrations_deleter_; + // Currently pending unregistrations. GCMClientImpl owns the + // UnregistrationRequests. + PendingUnregistrations pending_unregistrations_; + STLValueDeleter<PendingUnregistrations> pending_unregistrations_deleter_; + // Factory for creating references in callbacks. base::WeakPtrFactory<GCMClientImpl> weak_ptr_factory_; diff --git a/google_apis/gcm/gcm_client_impl_unittest.cc b/google_apis/gcm/gcm_client_impl_unittest.cc index d5b20dd..e836196 100644 --- a/google_apis/gcm/gcm_client_impl_unittest.cc +++ b/google_apis/gcm/gcm_client_impl_unittest.cc @@ -29,6 +29,7 @@ enum LastEvent { NONE, LOADING_COMPLETED, REGISTRATION_COMPLETED, + UNREGISTRATION_COMPLETED, MESSAGE_SEND_ERROR, MESSAGE_RECEIVED, MESSAGES_DELETED, @@ -37,6 +38,7 @@ enum LastEvent { const uint64 kDeviceAndroidId = 54321; const uint64 kDeviceSecurityToken = 12345; const char kRegistrationResponsePrefix[] = "token="; +const char kUnregistrationResponsePrefix[] = "deleted="; // Helper for building arbitrary data messages. MCSMessage BuildDownstreamMessage( @@ -123,11 +125,14 @@ class GCMClientImplTest : public testing::Test, void ReceiveMessageFromMCS(const MCSMessage& message); void CompleteCheckin(uint64 android_id, uint64 security_token); void CompleteRegistration(const std::string& registration_id); + void CompleteUnregistration(const std::string& app_id); // GCMClient::Delegate overrides (for verification). virtual void OnRegisterFinished(const std::string& app_id, const std::string& registration_id, GCMClient::Result result) OVERRIDE; + virtual void OnUnregisterFinished(const std::string& app_id, + bool success) OVERRIDE; virtual void OnSendFinished(const std::string& app_id, const std::string& message_id, GCMClient::Result result) OVERRIDE {} @@ -250,7 +255,17 @@ void GCMClientImplTest::CompleteRegistration( fetcher->set_response_code(net::HTTP_OK); fetcher->SetResponseString(response); fetcher->delegate()->OnURLFetchComplete(fetcher); - url_fetcher_factory_.RemoveFetcherFromMap(0); +} + +void GCMClientImplTest::CompleteUnregistration( + const std::string& app_id) { + std::string response(kUnregistrationResponsePrefix); + response.append(app_id); + net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0); + ASSERT_TRUE(fetcher); + fetcher->set_response_code(net::HTTP_OK); + fetcher->SetResponseString(response); + fetcher->delegate()->OnURLFetchComplete(fetcher); } void GCMClientImplTest::InitializeGCMClient() { @@ -305,6 +320,13 @@ void GCMClientImplTest::OnRegisterFinished(const std::string& app_id, last_result_ = result; } +void GCMClientImplTest::OnUnregisterFinished(const std::string& app_id, + bool success) { + last_event_ = UNREGISTRATION_COMPLETED; + last_app_id_ = app_id; + last_result_ = success ? GCMClient::SUCCESS : GCMClient::UNKNOWN_ERROR; +} + void GCMClientImplTest::OnMessagesDeleted(const std::string& app_id) { last_event_ = MESSAGES_DELETED; last_app_id_ = app_id; @@ -347,6 +369,15 @@ TEST_F(GCMClientImplTest, RegisterApp) { EXPECT_EQ(GCMClient::SUCCESS, last_result()); } +TEST_F(GCMClientImplTest, UnregisterApp) { + gcm_client()->Unregister("app_id"); + CompleteUnregistration("app_id"); + + EXPECT_EQ(UNREGISTRATION_COMPLETED, last_event()); + EXPECT_EQ("app_id", last_app_id()); + EXPECT_EQ(GCMClient::SUCCESS, last_result()); +} + TEST_F(GCMClientImplTest, DispatchDownstreamMessage) { std::map<std::string, std::string> expected_data; expected_data["message_type"] = "gcm"; |