Commit 74eadb07 authored by Jian Li's avatar Jian Li

[GCM] Start GCMChannelStatusSyncer when GCM is disabled

We need to start GCMChannelStatusSyncer when GCM is disabled in order
to poll the server to find out when it is reenabled.

Also if server returns empty response, we should not treat it as error
and trigger the backoff logic.

BUG=423415
TEST=new tests added

Committed: https://crrev.com/9e9dd3b7798b3500d70941af04b1325ef9a0b544
Cr-Commit-Position: refs/heads/master@{#299518}

R=fgorski@chromium.org

Review URL: https://codereview.chromium.org/653843003

Cr-Commit-Position: refs/heads/master@{#299854}
parent 094e6375
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "chrome/browser/services/gcm/gcm_desktop_utils.h" #include "chrome/browser/services/gcm/gcm_desktop_utils.h"
#include "base/command_line.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/sequenced_task_runner.h" #include "base/sequenced_task_runner.h"
#include "base/threading/sequenced_worker_pool.h" #include "base/threading/sequenced_worker_pool.h"
...@@ -20,6 +21,8 @@ namespace gcm { ...@@ -20,6 +21,8 @@ namespace gcm {
namespace { namespace {
const char kChannelStatusRelativePath[] = "/experimentstatus";
GCMClient::ChromePlatform GetPlatform() { GCMClient::ChromePlatform GetPlatform() {
#if defined(OS_WIN) #if defined(OS_WIN)
return GCMClient::PLATFORM_WIN; return GCMClient::PLATFORM_WIN;
...@@ -72,13 +75,9 @@ GCMClient::ChromeBuildInfo GetChromeBuildInfo() { ...@@ -72,13 +75,9 @@ GCMClient::ChromeBuildInfo GetChromeBuildInfo() {
} }
std::string GetChannelStatusRequestUrl() { std::string GetChannelStatusRequestUrl() {
chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel(); GURL sync_url(
if (channel == chrome::VersionInfo::CHANNEL_STABLE || ProfileSyncService::GetSyncServiceURL(*CommandLine::ForCurrentProcess()));
channel == chrome::VersionInfo::CHANNEL_BETA) { return sync_url.spec() + kChannelStatusRelativePath;
return ProfileSyncService::kSyncServerUrl;
}
return ProfileSyncService::kDevServerUrl;
} }
std::string GetUserAgent() { std::string GetUserAgent() {
......
...@@ -93,15 +93,20 @@ bool GCMChannelStatusRequest::ParseResponse(const net::URLFetcher* source) { ...@@ -93,15 +93,20 @@ bool GCMChannelStatusRequest::ParseResponse(const net::URLFetcher* source) {
} }
std::string response_string; std::string response_string;
if (!source->GetResponseAsString(&response_string) || if (!source->GetResponseAsString(&response_string)) {
response_string.empty()) {
LOG(ERROR) << "GCM channel response failed to be retrieved."; LOG(ERROR) << "GCM channel response failed to be retrieved.";
return false; return false;
} }
// Empty response means to keep the existing values.
if (response_string.empty()) {
callback_.Run(false, false, 0);
return true;
}
sync_pb::ExperimentStatusResponse response_proto; sync_pb::ExperimentStatusResponse response_proto;
if (!response_proto.ParseFromString(response_string)) { if (!response_proto.ParseFromString(response_string)) {
LOG(ERROR) << "GCM channel response failed to be parse as proto."; LOG(ERROR) << "GCM channel response failed to be parsed as proto.";
return false; return false;
} }
...@@ -120,7 +125,7 @@ bool GCMChannelStatusRequest::ParseResponse(const net::URLFetcher* source) { ...@@ -120,7 +125,7 @@ bool GCMChannelStatusRequest::ParseResponse(const net::URLFetcher* source) {
if (poll_interval_seconds < kMinPollIntervalSeconds) if (poll_interval_seconds < kMinPollIntervalSeconds)
poll_interval_seconds = kMinPollIntervalSeconds; poll_interval_seconds = kMinPollIntervalSeconds;
callback_.Run(enabled, poll_interval_seconds); callback_.Run(true, enabled, poll_interval_seconds);
return true; return true;
} }
......
...@@ -26,7 +26,14 @@ namespace gcm { ...@@ -26,7 +26,14 @@ namespace gcm {
class GCMChannelStatusRequest : public net::URLFetcherDelegate { class GCMChannelStatusRequest : public net::URLFetcherDelegate {
public: public:
// Callback completing the channel status request. // Callback completing the channel status request.
typedef base::Callback<void(bool enabled, int poll_interval_seconds)> // |update_received|: use the existing values if it is false which means no
// update is received.
// |enabled|: indicates if GCM is enabled (allowed to run) or not.
// |poll_interval_seconds|: the interval in seconds to start next poll
// request.
typedef base::Callback<void(bool update_received,
bool enabled,
int poll_interval_seconds)>
GCMChannelStatusRequestCallback; GCMChannelStatusRequestCallback;
GCMChannelStatusRequest( GCMChannelStatusRequest(
......
...@@ -29,13 +29,16 @@ class GCMChannelStatusRequestTest : public testing::Test { ...@@ -29,13 +29,16 @@ class GCMChannelStatusRequestTest : public testing::Test {
const std::string& response_body); const std::string& response_body);
void SetResponseProtoData(GCMStatus status, int poll_interval_seconds); void SetResponseProtoData(GCMStatus status, int poll_interval_seconds);
void CompleteFetch(); void CompleteFetch();
void OnRequestCompleted(bool enabled, int poll_interval_seconds); void OnRequestCompleted(bool update_received,
bool enabled,
int poll_interval_seconds);
scoped_ptr<GCMChannelStatusRequest> request_; scoped_ptr<GCMChannelStatusRequest> request_;
base::MessageLoop message_loop_; base::MessageLoop message_loop_;
net::TestURLFetcherFactory url_fetcher_factory_; net::TestURLFetcherFactory url_fetcher_factory_;
scoped_refptr<net::TestURLRequestContextGetter> url_request_context_getter_; scoped_refptr<net::TestURLRequestContextGetter> url_request_context_getter_;
bool request_callback_invoked_; bool request_callback_invoked_;
bool update_received_;
bool enabled_; bool enabled_;
int poll_interval_seconds_; int poll_interval_seconds_;
}; };
...@@ -44,6 +47,7 @@ GCMChannelStatusRequestTest::GCMChannelStatusRequestTest() ...@@ -44,6 +47,7 @@ GCMChannelStatusRequestTest::GCMChannelStatusRequestTest()
: url_request_context_getter_(new net::TestURLRequestContextGetter( : url_request_context_getter_(new net::TestURLRequestContextGetter(
message_loop_.message_loop_proxy())), message_loop_.message_loop_proxy())),
request_callback_invoked_(false), request_callback_invoked_(false),
update_received_(false),
enabled_(true), enabled_(true),
poll_interval_seconds_(0) { poll_interval_seconds_(0) {
} }
...@@ -97,8 +101,9 @@ void GCMChannelStatusRequestTest::CompleteFetch() { ...@@ -97,8 +101,9 @@ void GCMChannelStatusRequestTest::CompleteFetch() {
} }
void GCMChannelStatusRequestTest::OnRequestCompleted( void GCMChannelStatusRequestTest::OnRequestCompleted(
bool enabled, int poll_interval_seconds) { bool update_received, bool enabled, int poll_interval_seconds) {
request_callback_invoked_ = true; request_callback_invoked_ = true;
update_received_ = update_received;
enabled_ = enabled; enabled_ = enabled;
poll_interval_seconds_ = poll_interval_seconds; poll_interval_seconds_ = poll_interval_seconds;
} }
...@@ -116,7 +121,8 @@ TEST_F(GCMChannelStatusRequestTest, ResponseEmpty) { ...@@ -116,7 +121,8 @@ TEST_F(GCMChannelStatusRequestTest, ResponseEmpty) {
SetResponseStatusAndString(net::HTTP_OK, ""); SetResponseStatusAndString(net::HTTP_OK, "");
CompleteFetch(); CompleteFetch();
EXPECT_FALSE(request_callback_invoked_); EXPECT_TRUE(request_callback_invoked_);
EXPECT_FALSE(update_received_);
} }
TEST_F(GCMChannelStatusRequestTest, ResponseNotInProtoFormat) { TEST_F(GCMChannelStatusRequestTest, ResponseNotInProtoFormat) {
...@@ -132,7 +138,8 @@ TEST_F(GCMChannelStatusRequestTest, ResponseEmptyProtoData) { ...@@ -132,7 +138,8 @@ TEST_F(GCMChannelStatusRequestTest, ResponseEmptyProtoData) {
SetResponseProtoData(NOT_SPECIFIED, 0); SetResponseProtoData(NOT_SPECIFIED, 0);
CompleteFetch(); CompleteFetch();
EXPECT_FALSE(request_callback_invoked_); EXPECT_TRUE(request_callback_invoked_);
EXPECT_FALSE(update_received_);
} }
TEST_F(GCMChannelStatusRequestTest, ResponseWithDisabledStatus) { TEST_F(GCMChannelStatusRequestTest, ResponseWithDisabledStatus) {
...@@ -141,6 +148,7 @@ TEST_F(GCMChannelStatusRequestTest, ResponseWithDisabledStatus) { ...@@ -141,6 +148,7 @@ TEST_F(GCMChannelStatusRequestTest, ResponseWithDisabledStatus) {
CompleteFetch(); CompleteFetch();
EXPECT_TRUE(request_callback_invoked_); EXPECT_TRUE(request_callback_invoked_);
EXPECT_TRUE(update_received_);
EXPECT_FALSE(enabled_); EXPECT_FALSE(enabled_);
EXPECT_EQ( EXPECT_EQ(
GCMChannelStatusRequest::default_poll_interval_seconds(), GCMChannelStatusRequest::default_poll_interval_seconds(),
...@@ -153,6 +161,7 @@ TEST_F(GCMChannelStatusRequestTest, ResponseWithEnabledStatus) { ...@@ -153,6 +161,7 @@ TEST_F(GCMChannelStatusRequestTest, ResponseWithEnabledStatus) {
CompleteFetch(); CompleteFetch();
EXPECT_TRUE(request_callback_invoked_); EXPECT_TRUE(request_callback_invoked_);
EXPECT_TRUE(update_received_);
EXPECT_TRUE(enabled_); EXPECT_TRUE(enabled_);
EXPECT_EQ( EXPECT_EQ(
GCMChannelStatusRequest::default_poll_interval_seconds(), GCMChannelStatusRequest::default_poll_interval_seconds(),
...@@ -169,6 +178,7 @@ TEST_F(GCMChannelStatusRequestTest, ResponseWithPollInterval) { ...@@ -169,6 +178,7 @@ TEST_F(GCMChannelStatusRequestTest, ResponseWithPollInterval) {
CompleteFetch(); CompleteFetch();
EXPECT_TRUE(request_callback_invoked_); EXPECT_TRUE(request_callback_invoked_);
EXPECT_TRUE(update_received_);
EXPECT_TRUE(enabled_); EXPECT_TRUE(enabled_);
EXPECT_EQ(poll_interval_seconds, poll_interval_seconds_); EXPECT_EQ(poll_interval_seconds, poll_interval_seconds_);
} }
...@@ -183,6 +193,7 @@ TEST_F(GCMChannelStatusRequestTest, ResponseWithShortPollInterval) { ...@@ -183,6 +193,7 @@ TEST_F(GCMChannelStatusRequestTest, ResponseWithShortPollInterval) {
CompleteFetch(); CompleteFetch();
EXPECT_TRUE(request_callback_invoked_); EXPECT_TRUE(request_callback_invoked_);
EXPECT_TRUE(update_received_);
EXPECT_TRUE(enabled_); EXPECT_TRUE(enabled_);
EXPECT_EQ(GCMChannelStatusRequest::min_poll_interval_seconds(), EXPECT_EQ(GCMChannelStatusRequest::min_poll_interval_seconds(),
poll_interval_seconds_); poll_interval_seconds_);
...@@ -196,6 +207,7 @@ TEST_F(GCMChannelStatusRequestTest, ResponseWithDisabledStatusAndPollInterval) { ...@@ -196,6 +207,7 @@ TEST_F(GCMChannelStatusRequestTest, ResponseWithDisabledStatusAndPollInterval) {
CompleteFetch(); CompleteFetch();
EXPECT_TRUE(request_callback_invoked_); EXPECT_TRUE(request_callback_invoked_);
EXPECT_TRUE(update_received_);
EXPECT_FALSE(enabled_); EXPECT_FALSE(enabled_);
EXPECT_EQ(poll_interval_seconds, poll_interval_seconds_); EXPECT_EQ(poll_interval_seconds, poll_interval_seconds_);
} }
......
...@@ -5,12 +5,14 @@ ...@@ -5,12 +5,14 @@
#include "components/gcm_driver/gcm_channel_status_syncer.h" #include "components/gcm_driver/gcm_channel_status_syncer.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/command_line.h"
#include "base/location.h" #include "base/location.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop.h"
#include "base/prefs/pref_registry_simple.h" #include "base/prefs/pref_registry_simple.h"
#include "base/prefs/pref_service.h" #include "base/prefs/pref_service.h"
#include "base/rand_util.h" #include "base/rand_util.h"
#include "base/strings/string_number_conversions.h"
#include "components/gcm_driver/gcm_channel_status_request.h" #include "components/gcm_driver/gcm_channel_status_request.h"
#include "components/gcm_driver/gcm_driver.h" #include "components/gcm_driver/gcm_driver.h"
#include "components/pref_registry/pref_registry_syncable.h" #include "components/pref_registry/pref_registry_syncable.h"
...@@ -35,8 +37,21 @@ const int kFirstTimeDelaySeconds = 1 * 60; // 1 minute. ...@@ -35,8 +37,21 @@ const int kFirstTimeDelaySeconds = 1 * 60; // 1 minute.
// The fuzzing variation added to the polling delay. // The fuzzing variation added to the polling delay.
const int kGCMChannelRequestTimeJitterSeconds = 15 * 60; // 15 minues. const int kGCMChannelRequestTimeJitterSeconds = 15 * 60; // 15 minues.
// The minimum poll interval that can be overridden to.
const int kMinCustomPollIntervalMinutes = 2;
// Custom poll interval could not be used more than the limit below.
const int kMaxNumberToUseCustomPollInterval = 10;
} // namespace } // namespace
namespace switches {
// Override the default poll interval for testing purpose.
const char kCustomPollIntervalMinutes[] = "gcm-channel-poll-interval";
} // namepsace switches
// static // static
void GCMChannelStatusSyncer::RegisterPrefs(PrefRegistrySimple* registry) { void GCMChannelStatusSyncer::RegisterPrefs(PrefRegistrySimple* registry) {
registry->RegisterBooleanPref(kGCMChannelStatus, true); registry->RegisterBooleanPref(kGCMChannelStatus, true);
...@@ -79,9 +94,11 @@ GCMChannelStatusSyncer::GCMChannelStatusSyncer( ...@@ -79,9 +94,11 @@ GCMChannelStatusSyncer::GCMChannelStatusSyncer(
channel_status_request_url_(channel_status_request_url), channel_status_request_url_(channel_status_request_url),
user_agent_(user_agent), user_agent_(user_agent),
request_context_(request_context), request_context_(request_context),
started_(false),
gcm_enabled_(true), gcm_enabled_(true),
poll_interval_seconds_( poll_interval_seconds_(
GCMChannelStatusRequest::default_poll_interval_seconds()), GCMChannelStatusRequest::default_poll_interval_seconds()),
custom_poll_interval_use_count_(0),
delay_removed_for_testing_(false), delay_removed_for_testing_(false),
weak_ptr_factory_(this) { weak_ptr_factory_(this) {
gcm_enabled_ = prefs_->GetBoolean(kGCMChannelStatus); gcm_enabled_ = prefs_->GetBoolean(kGCMChannelStatus);
...@@ -91,6 +108,19 @@ GCMChannelStatusSyncer::GCMChannelStatusSyncer( ...@@ -91,6 +108,19 @@ GCMChannelStatusSyncer::GCMChannelStatusSyncer(
poll_interval_seconds_ = poll_interval_seconds_ =
GCMChannelStatusRequest::min_poll_interval_seconds(); GCMChannelStatusRequest::min_poll_interval_seconds();
} }
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kCustomPollIntervalMinutes)) {
std::string value(CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
switches::kCustomPollIntervalMinutes));
int minutes = 0;
if (base::StringToInt(value, &minutes)) {
DCHECK_GE(minutes, kMinCustomPollIntervalMinutes);
if (minutes >= kMinCustomPollIntervalMinutes) {
poll_interval_seconds_ = minutes * 60;
custom_poll_interval_use_count_ = kMaxNumberToUseCustomPollInterval;
}
}
}
last_check_time_ = base::Time::FromInternalValue( last_check_time_ = base::Time::FromInternalValue(
prefs_->GetInt64(kGCMChannelLastCheckTime)); prefs_->GetInt64(kGCMChannelLastCheckTime));
} }
...@@ -100,18 +130,21 @@ GCMChannelStatusSyncer::~GCMChannelStatusSyncer() { ...@@ -100,18 +130,21 @@ GCMChannelStatusSyncer::~GCMChannelStatusSyncer() {
void GCMChannelStatusSyncer::EnsureStarted() { void GCMChannelStatusSyncer::EnsureStarted() {
// Bail out if the request is already scheduled or started. // Bail out if the request is already scheduled or started.
if (weak_ptr_factory_.HasWeakPtrs() || request_) if (started_)
return; return;
started_ = true;
ScheduleRequest(); ScheduleRequest();
} }
void GCMChannelStatusSyncer::Stop() { void GCMChannelStatusSyncer::Stop() {
started_ = false;
request_.reset(); request_.reset();
weak_ptr_factory_.InvalidateWeakPtrs(); weak_ptr_factory_.InvalidateWeakPtrs();
} }
void GCMChannelStatusSyncer::OnRequestCompleted(bool enabled, void GCMChannelStatusSyncer::OnRequestCompleted(bool update_received,
bool enabled,
int poll_interval_seconds) { int poll_interval_seconds) {
DCHECK(request_); DCHECK(request_);
request_.reset(); request_.reset();
...@@ -121,23 +154,31 @@ void GCMChannelStatusSyncer::OnRequestCompleted(bool enabled, ...@@ -121,23 +154,31 @@ void GCMChannelStatusSyncer::OnRequestCompleted(bool enabled,
prefs_->SetInt64(kGCMChannelLastCheckTime, prefs_->SetInt64(kGCMChannelLastCheckTime,
last_check_time_.ToInternalValue()); last_check_time_.ToInternalValue());
if (gcm_enabled_ != enabled) { if (update_received) {
gcm_enabled_ = enabled; if (gcm_enabled_ != enabled) {
prefs_->SetBoolean(kGCMChannelStatus, enabled); gcm_enabled_ = enabled;
if (gcm_enabled_) prefs_->SetBoolean(kGCMChannelStatus, enabled);
driver_->Enable(); if (gcm_enabled_)
else driver_->Enable();
driver_->Disable(); else
} driver_->Disable();
}
DCHECK_GE(poll_interval_seconds,
GCMChannelStatusRequest::min_poll_interval_seconds()); // Skip updating poll interval if the custom one is still in effect.
if (poll_interval_seconds_ != poll_interval_seconds) { if (!custom_poll_interval_use_count_) {
poll_interval_seconds_ = poll_interval_seconds; DCHECK_GE(poll_interval_seconds,
prefs_->SetInteger(kGCMChannelPollIntervalSeconds, poll_interval_seconds_); GCMChannelStatusRequest::min_poll_interval_seconds());
if (poll_interval_seconds_ != poll_interval_seconds) {
poll_interval_seconds_ = poll_interval_seconds;
prefs_->SetInteger(kGCMChannelPollIntervalSeconds,
poll_interval_seconds_);
}
}
} }
ScheduleRequest(); // Do not schedule next request if syncer is stopped.
if (started_)
ScheduleRequest();
} }
void GCMChannelStatusSyncer::ScheduleRequest() { void GCMChannelStatusSyncer::ScheduleRequest() {
...@@ -147,6 +188,9 @@ void GCMChannelStatusSyncer::ScheduleRequest() { ...@@ -147,6 +188,9 @@ void GCMChannelStatusSyncer::ScheduleRequest() {
base::Bind(&GCMChannelStatusSyncer::StartRequest, base::Bind(&GCMChannelStatusSyncer::StartRequest,
weak_ptr_factory_.GetWeakPtr()), weak_ptr_factory_.GetWeakPtr()),
current_request_delay_interval_); current_request_delay_interval_);
if (custom_poll_interval_use_count_)
custom_poll_interval_use_count_--;
} }
void GCMChannelStatusSyncer::StartRequest() { void GCMChannelStatusSyncer::StartRequest() {
...@@ -180,7 +224,9 @@ base::TimeDelta GCMChannelStatusSyncer::GetRequestDelayInterval() const { ...@@ -180,7 +224,9 @@ base::TimeDelta GCMChannelStatusSyncer::GetRequestDelayInterval() const {
delay_seconds = kFirstTimeDelaySeconds; delay_seconds = kFirstTimeDelaySeconds;
} else { } else {
// Otherwise, add a fuzzing variation to the delay. // Otherwise, add a fuzzing variation to the delay.
delay_seconds += base::RandInt(0, kGCMChannelRequestTimeJitterSeconds); // The fuzzing variation is off when the custom interval is used.
if (!custom_poll_interval_use_count_)
delay_seconds += base::RandInt(0, kGCMChannelRequestTimeJitterSeconds);
} }
return base::TimeDelta::FromSeconds(delay_seconds); return base::TimeDelta::FromSeconds(delay_seconds);
......
...@@ -59,7 +59,9 @@ class GCMChannelStatusSyncer { ...@@ -59,7 +59,9 @@ class GCMChannelStatusSyncer {
private: private:
// Called when a request is completed. // Called when a request is completed.
void OnRequestCompleted(bool enabled, int poll_interval_seconds); void OnRequestCompleted(bool update_received,
bool enabled,
int poll_interval_seconds);
// Schedules next request to start after appropriate delay. // Schedules next request to start after appropriate delay.
void ScheduleRequest(); void ScheduleRequest();
...@@ -80,10 +82,17 @@ class GCMChannelStatusSyncer { ...@@ -80,10 +82,17 @@ class GCMChannelStatusSyncer {
scoped_refptr<net::URLRequestContextGetter> request_context_; scoped_refptr<net::URLRequestContextGetter> request_context_;
scoped_ptr<GCMChannelStatusRequest> request_; scoped_ptr<GCMChannelStatusRequest> request_;
bool started_;
bool gcm_enabled_; bool gcm_enabled_;
int poll_interval_seconds_; int poll_interval_seconds_;
base::Time last_check_time_; base::Time last_check_time_;
// If non-zero, |poll_interval_seconds_| is overriden by the command line
// options for testing purpose. Each time when the custom poll interval is
// used, this count is subtracted by one. When it reaches zero, the default
// poll interval will be used instead.
int custom_poll_interval_use_count_;
// The flag that indicates if the delay, including fuzzing variation and poll // The flag that indicates if the delay, including fuzzing variation and poll
// interval, is removed for testing purpose. // interval, is removed for testing purpose.
bool delay_removed_for_testing_; bool delay_removed_for_testing_;
......
...@@ -432,6 +432,7 @@ void GCMDriverDesktop::RemoveAppHandler(const std::string& app_id) { ...@@ -432,6 +432,7 @@ void GCMDriverDesktop::RemoveAppHandler(const std::string& app_id) {
// remove the last app handler - account mapper. // remove the last app handler - account mapper.
if (app_handlers().size() == 1) { if (app_handlers().size() == 1) {
Stop(); Stop();
gcm_channel_status_syncer_->Stop();
} }
} }
...@@ -471,8 +472,6 @@ void GCMDriverDesktop::Stop() { ...@@ -471,8 +472,6 @@ void GCMDriverDesktop::Stop() {
if (!gcm_started_) if (!gcm_started_)
return; return;
gcm_channel_status_syncer_->Stop();
account_mapper_->ShutdownHandler(); account_mapper_->ShutdownHandler();
GCMDriver::RemoveAppHandler(kGCMAccountMapperAppId); GCMDriver::RemoveAppHandler(kGCMAccountMapperAppId);
...@@ -650,8 +649,14 @@ GCMClient::Result GCMDriverDesktop::EnsureStarted() { ...@@ -650,8 +649,14 @@ GCMClient::Result GCMDriverDesktop::EnsureStarted() {
if (gcm_started_) if (gcm_started_)
return GCMClient::SUCCESS; return GCMClient::SUCCESS;
if (!gcm_enabled_) if (!gcm_enabled_) {
// Poll for channel status in order to find out when it is re-enabled when
// GCM is currently disabled.
if (GCMDriver::IsAllowedForAllUsers())
gcm_channel_status_syncer_->EnsureStarted();
return GCMClient::GCM_DISABLED; return GCMClient::GCM_DISABLED;
}
// Have any app requested the service? // Have any app requested the service?
if (app_handlers().empty()) if (app_handlers().empty())
......
...@@ -1017,6 +1017,8 @@ GCMChannelStatusSyncerTest::~GCMChannelStatusSyncerTest() { ...@@ -1017,6 +1017,8 @@ GCMChannelStatusSyncerTest::~GCMChannelStatusSyncerTest() {
void GCMChannelStatusSyncerTest::SetUp() { void GCMChannelStatusSyncerTest::SetUp() {
GCMDriverTest::SetUp(); GCMDriverTest::SetUp();
url_fetcher_factory_.set_remove_fetcher_on_delete(true);
// Turn on all-user support. // Turn on all-user support.
ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("GCM", "Enabled")); ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("GCM", "Enabled"));
} }
...@@ -1091,7 +1093,7 @@ TEST_F(GCMChannelStatusSyncerTest, DisableAndEnable) { ...@@ -1091,7 +1093,7 @@ TEST_F(GCMChannelStatusSyncerTest, DisableAndEnable) {
EXPECT_TRUE(driver()->IsStarted()); EXPECT_TRUE(driver()->IsStarted());
} }
TEST_F(GCMChannelStatusSyncerTest, DisableAndRestart) { TEST_F(GCMChannelStatusSyncerTest, DisableRestartAndEnable) {
// Create GCMDriver first. GCM is not started. // Create GCMDriver first. GCM is not started.
CreateDriver(FakeGCMClient::NO_DELAY_START); CreateDriver(FakeGCMClient::NO_DELAY_START);
EXPECT_FALSE(driver()->IsStarted()); EXPECT_FALSE(driver()->IsStarted());
...@@ -1124,6 +1126,9 @@ TEST_F(GCMChannelStatusSyncerTest, DisableAndRestart) { ...@@ -1124,6 +1126,9 @@ TEST_F(GCMChannelStatusSyncerTest, DisableAndRestart) {
ShutdownDriver(); ShutdownDriver();
CreateDriver(FakeGCMClient::NO_DELAY_START); CreateDriver(FakeGCMClient::NO_DELAY_START);
// Remove delay such that the request could be executed immediately.
syncer()->set_delay_removed_for_testing(true);
// GCM is still disabled. // GCM is still disabled.
EXPECT_FALSE(driver()->gcm_enabled()); EXPECT_FALSE(driver()->gcm_enabled());
EXPECT_FALSE(syncer()->gcm_enabled()); EXPECT_FALSE(syncer()->gcm_enabled());
...@@ -1133,6 +1138,15 @@ TEST_F(GCMChannelStatusSyncerTest, DisableAndRestart) { ...@@ -1133,6 +1138,15 @@ TEST_F(GCMChannelStatusSyncerTest, DisableAndRestart) {
EXPECT_FALSE(driver()->gcm_enabled()); EXPECT_FALSE(driver()->gcm_enabled());
EXPECT_FALSE(syncer()->gcm_enabled()); EXPECT_FALSE(syncer()->gcm_enabled());
EXPECT_FALSE(driver()->IsStarted()); EXPECT_FALSE(driver()->IsStarted());
// Wait until the GCM channel status request gets triggered.
PumpUILoop();
// Complete the request that re-enables the GCM.
CompleteGCMChannelStatusRequest(true, 0);
EXPECT_TRUE(driver()->gcm_enabled());
EXPECT_TRUE(syncer()->gcm_enabled());
EXPECT_TRUE(driver()->IsStarted());
} }
TEST_F(GCMChannelStatusSyncerTest, FirstTimePolling) { TEST_F(GCMChannelStatusSyncerTest, FirstTimePolling) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment