Commit e4f716e3 authored by Vitalii Iarko's avatar Vitalii Iarko Committed by Commit Bot

[NTP::Push] Periodically check token validity and resubscribe if not.

GCM token may become invalid (it is stored on disk and may be corrupted).
Therefore, this CL adds a periodical check (at least 24 hours, without waking
up) of the current token validity. If it is invalid, then a new token is
retrieved and used to resubscribe to our server.

Bug: 742240
Change-Id: I27d873049c6dbc7ff8c3ad0471cf20ca7f754d53
Reviewed-on: https://chromium-review.googlesource.com/574232Reviewed-by: default avatarBernhard Bauer <bauerb@chromium.org>
Reviewed-by: default avatarMarc Treib <treib@chromium.org>
Commit-Queue: vitaliii <vitaliii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#491956}
parent 4d538b1b
......@@ -14,6 +14,8 @@
#include "base/sequenced_task_runner.h"
#include "base/task_scheduler/post_task.h"
#include "base/time/default_clock.h"
#include "base/timer/timer.h"
#include "build/build_config.h"
#include "chrome/browser/bookmarks/bookmark_model_factory.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/favicon/large_icon_service_factory.h"
......@@ -40,10 +42,6 @@
#include "components/keyed_service/core/service_access_type.h"
#include "components/language/core/browser/url_language_histogram.h"
#include "components/ntp_snippets/bookmarks/bookmark_suggestions_provider.h"
#include "components/ntp_snippets/breaking_news/breaking_news_gcm_app_handler.h"
#include "components/ntp_snippets/breaking_news/breaking_news_suggestions_provider.h"
#include "components/ntp_snippets/breaking_news/subscription_manager.h"
#include "components/ntp_snippets/breaking_news/subscription_manager_impl.h"
#include "components/ntp_snippets/category_rankers/category_ranker.h"
#include "components/ntp_snippets/content_suggestions_service.h"
#include "components/ntp_snippets/contextual_suggestions_source.h"
......@@ -79,6 +77,10 @@
#include "chrome/browser/download/download_core_service_factory.h"
#include "chrome/browser/download/download_history.h"
#include "chrome/browser/ntp_snippets/download_suggestions_provider.h"
#include "components/ntp_snippets/breaking_news/breaking_news_gcm_app_handler.h"
#include "components/ntp_snippets/breaking_news/breaking_news_suggestions_provider.h"
#include "components/ntp_snippets/breaking_news/subscription_manager.h"
#include "components/ntp_snippets/breaking_news/subscription_manager_impl.h"
#include "components/ntp_snippets/physical_web_pages/physical_web_page_suggestions_provider.h"
#include "components/physical_web/data_source/physical_web_data_source.h"
#endif
......@@ -103,16 +105,12 @@ using history::HistoryService;
using image_fetcher::ImageFetcherImpl;
using language::UrlLanguageHistogram;
using ntp_snippets::BookmarkSuggestionsProvider;
using ntp_snippets::BreakingNewsGCMAppHandler;
using ntp_snippets::BreakingNewsSuggestionsProvider;
using ntp_snippets::CategoryRanker;
using ntp_snippets::ContentSuggestionsService;
using ntp_snippets::ContextualSuggestionsFetcherImpl;
using ntp_snippets::ContextualSuggestionsSource;
using ntp_snippets::ForeignSessionsSuggestionsProvider;
using ntp_snippets::GetFetchEndpoint;
using ntp_snippets::GetPushUpdatesSubscriptionEndpoint;
using ntp_snippets::GetPushUpdatesUnsubscriptionEndpoint;
using ntp_snippets::PersistentScheduler;
using ntp_snippets::PrefetchedPagesTracker;
using ntp_snippets::RemoteSuggestionsDatabase;
......@@ -120,7 +118,6 @@ using ntp_snippets::RemoteSuggestionsFetcherImpl;
using ntp_snippets::RemoteSuggestionsProviderImpl;
using ntp_snippets::RemoteSuggestionsSchedulerImpl;
using ntp_snippets::RemoteSuggestionsStatusService;
using ntp_snippets::SubscriptionManagerImpl;
using ntp_snippets::TabDelegateSyncAdapter;
using ntp_snippets::UserClassifier;
using suggestions::ImageDecoderImpl;
......@@ -128,7 +125,12 @@ using syncer::SyncService;
#if defined(OS_ANDROID)
using content::DownloadManager;
using ntp_snippets::BreakingNewsGCMAppHandler;
using ntp_snippets::BreakingNewsSuggestionsProvider;
using ntp_snippets::GetPushUpdatesSubscriptionEndpoint;
using ntp_snippets::GetPushUpdatesUnsubscriptionEndpoint;
using ntp_snippets::PhysicalWebPageSuggestionsProvider;
using ntp_snippets::SubscriptionManagerImpl;
using physical_web::PhysicalWebDataSource;
#endif // OS_ANDROID
......@@ -428,10 +430,20 @@ void RegisterForeignSessionsProviderIfEnabled(
service->RegisterProvider(std::move(provider));
}
void SubscribeForGCMPushUpdates(
#if defined(OS_ANDROID)
bool IsGCMPushUpdatesEnabled() {
return base::FeatureList::IsEnabled(ntp_snippets::kBreakingNewsPushFeature);
}
void SubscribeForGCMPushUpdatesIfEnabled(
PrefService* pref_service,
ContentSuggestionsService* content_suggestions_service,
Profile* profile) {
if (!IsGCMPushUpdatesEnabled()) {
return;
}
// TODO(mamir): Either pass all params from outside or pass only profile and
// create them inside the method, but be consistent.
gcm::GCMDriver* gcm_driver =
......@@ -469,7 +481,9 @@ void SubscribeForGCMPushUpdates(
auto handler = base::MakeUnique<BreakingNewsGCMAppHandler>(
gcm_driver, instance_id_profile_service->driver(), pref_service,
std::move(subscription_manager),
base::Bind(&safe_json::SafeJsonParser::Parse));
base::Bind(&safe_json::SafeJsonParser::Parse),
base::MakeUnique<base::DefaultClock>(),
/*token_validation_timer=*/base::MakeUnique<base::OneShotTimer>());
scoped_refptr<base::SequencedTaskRunner> task_runner =
base::CreateSequencedTaskRunnerWithTraits(
......@@ -487,6 +501,8 @@ void SubscribeForGCMPushUpdates(
content_suggestions_service->RegisterProvider(std::move(provider));
}
#endif // OS_ANDROID
} // namespace
#endif // CONTENT_SUGGESTIONS_ENABLED
......@@ -587,6 +603,7 @@ KeyedService* ContentSuggestionsServiceFactory::BuildServiceInstanceFor(
#if defined(OS_ANDROID)
RegisterDownloadsProviderIfEnabled(service, profile, offline_page_model);
RegisterPhysicalWebPageProviderIfEnabled(service, profile);
SubscribeForGCMPushUpdatesIfEnabled(pref_service, service, profile);
#endif // OS_ANDROID
#if BUILDFLAG(ENABLE_OFFLINE_PAGES)
......@@ -594,9 +611,6 @@ KeyedService* ContentSuggestionsServiceFactory::BuildServiceInstanceFor(
RegisterPrefetchingObserver(service, profile);
#endif
if (base::FeatureList::IsEnabled(ntp_snippets::kBreakingNewsPushFeature)) {
SubscribeForGCMPushUpdates(pref_service, service, profile);
}
return service;
#else
......
......@@ -78,8 +78,6 @@
#include "components/gcm_driver/gcm_channel_status_syncer.h"
#include "components/language/core/browser/url_language_histogram.h"
#include "components/network_time/network_time_tracker.h"
#include "components/ntp_snippets/breaking_news/breaking_news_gcm_app_handler.h"
#include "components/ntp_snippets/breaking_news/subscription_manager_impl.h"
#include "components/ntp_snippets/content_suggestions_service.h"
#include "components/ntp_snippets/remote/remote_suggestions_provider_impl.h"
#include "components/ntp_snippets/remote/remote_suggestions_scheduler_impl.h"
......@@ -173,6 +171,8 @@
#include "chrome/browser/geolocation/geolocation_permission_context_android.h"
#include "chrome/browser/ntp_snippets/download_suggestions_provider.h"
#include "components/cdm/browser/media_drm_storage_impl.h"
#include "components/ntp_snippets/breaking_news/breaking_news_gcm_app_handler.h"
#include "components/ntp_snippets/breaking_news/subscription_manager_impl.h"
#include "components/ntp_snippets/category_rankers/click_based_category_ranker.h"
#include "components/ntp_snippets/offline_pages/recent_tab_suggestions_provider.h"
#include "components/ntp_snippets/physical_web_pages/physical_web_page_suggestions_provider.h"
......@@ -473,14 +473,12 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
MediaStreamDevicesController::RegisterProfilePrefs(registry);
NavigationCorrectionTabObserver::RegisterProfilePrefs(registry);
NotifierStateTracker::RegisterProfilePrefs(registry);
ntp_snippets::BreakingNewsGCMAppHandler::RegisterProfilePrefs(registry);
ntp_snippets::ContentSuggestionsService::RegisterProfilePrefs(registry);
ntp_snippets::ForeignSessionsSuggestionsProvider::RegisterProfilePrefs(
registry);
ntp_snippets::RemoteSuggestionsProviderImpl::RegisterProfilePrefs(registry);
ntp_snippets::RemoteSuggestionsSchedulerImpl::RegisterProfilePrefs(registry);
ntp_snippets::RequestThrottler::RegisterProfilePrefs(registry);
ntp_snippets::SubscriptionManagerImpl::RegisterProfilePrefs(registry);
ntp_snippets::UserClassifier::RegisterProfilePrefs(registry);
ntp_tiles::MostVisitedSites::RegisterProfilePrefs(registry);
password_bubble_experiment::RegisterPrefs(registry);
......@@ -568,10 +566,12 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
cdm::MediaDrmStorageImpl::RegisterProfilePrefs(registry);
ContentSuggestionsNotifierService::RegisterProfilePrefs(registry);
DownloadSuggestionsProvider::RegisterProfilePrefs(registry);
ntp_snippets::BreakingNewsGCMAppHandler::RegisterProfilePrefs(registry);
ntp_snippets::ClickBasedCategoryRanker::RegisterProfilePrefs(registry);
ntp_snippets::PhysicalWebPageSuggestionsProvider::RegisterProfilePrefs(
registry);
ntp_snippets::RecentTabSuggestionsProvider::RegisterProfilePrefs(registry);
ntp_snippets::SubscriptionManagerImpl::RegisterProfilePrefs(registry);
#endif // defined(OS_ANDROID)
#if !defined(OS_ANDROID)
......
......@@ -15,8 +15,6 @@ static_library("ntp_snippets") {
"bookmarks/bookmark_last_visit_utils.h",
"bookmarks/bookmark_suggestions_provider.cc",
"bookmarks/bookmark_suggestions_provider.h",
"breaking_news/breaking_news_gcm_app_handler.cc",
"breaking_news/breaking_news_gcm_app_handler.h",
"breaking_news/breaking_news_listener.h",
"breaking_news/breaking_news_suggestions_provider.cc",
"breaking_news/breaking_news_suggestions_provider.h",
......@@ -112,6 +110,13 @@ static_library("ntp_snippets") {
"user_classifier.h",
]
if (is_android) {
sources += [
"breaking_news/breaking_news_gcm_app_handler.cc",
"breaking_news/breaking_news_gcm_app_handler.h",
]
}
public_deps = [
"//base",
"//components/keyed_service/core",
......@@ -202,6 +207,10 @@ source_set("unit_tests") {
"user_classifier_unittest.cc",
]
if (is_android) {
sources += [ "breaking_news/breaking_news_gcm_app_handler_unittest.cc" ]
}
deps = [
":ntp_snippets",
":test_support",
......@@ -209,6 +218,8 @@ source_set("unit_tests") {
"//base/test:test_support",
"//components/bookmarks/browser",
"//components/bookmarks/test",
"//components/gcm_driver",
"//components/gcm_driver/instance_id",
"//components/image_fetcher/core",
"//components/leveldb_proto:test_support",
"//components/ntp_snippets/remote/proto",
......@@ -229,6 +240,7 @@ source_set("unit_tests") {
"//components/sync_sessions",
"//components/variations:test_support",
"//components/web_resource:web_resource",
"//google_apis/gcm",
"//net:test_support",
"//testing/gtest",
"//third_party/icu/",
......
......@@ -6,16 +6,21 @@
#include "base/json/json_writer.h"
#include "base/strings/string_util.h"
#include "base/task_scheduler/post_task.h"
#include "build/build_config.h"
#include "components/gcm_driver/gcm_driver.h"
#include "components/gcm_driver/gcm_profile_service.h"
#include "components/gcm_driver/instance_id/instance_id.h"
#include "components/gcm_driver/instance_id/instance_id_driver.h"
#include "components/ntp_snippets/pref_names.h"
#include "components/ntp_snippets/time_serialization.h"
using instance_id::InstanceID;
namespace ntp_snippets {
namespace {
const char kBreakingNewsGCMAppID[] = "com.google.breakingnews.gcm";
// The sender ID is used in the registration process.
......@@ -29,49 +34,71 @@ const char kGCMScope[] = "GCM";
// Key of the news json in the data in the pushed breaking news.
const char kPushedNewsKey[] = "payload";
// Lower bound time between two token validations when listening.
const int kTokenValidationPeriodHours = 24;
base::TimeDelta GetTokenValidationPeriod() {
return base::TimeDelta::FromHours(kTokenValidationPeriodHours);
}
} // namespace
BreakingNewsGCMAppHandler::BreakingNewsGCMAppHandler(
gcm::GCMDriver* gcm_driver,
instance_id::InstanceIDDriver* instance_id_driver,
PrefService* pref_service,
std::unique_ptr<SubscriptionManager> subscription_manager,
const ParseJSONCallback& parse_json_callback)
const ParseJSONCallback& parse_json_callback,
std::unique_ptr<base::Clock> clock,
std::unique_ptr<base::OneShotTimer> token_validation_timer)
: gcm_driver_(gcm_driver),
instance_id_driver_(instance_id_driver),
pref_service_(pref_service),
subscription_manager_(std::move(subscription_manager)),
parse_json_callback_(parse_json_callback),
weak_ptr_factory_(this) {}
clock_(std::move(clock)),
token_validation_timer_(std::move(token_validation_timer)),
weak_ptr_factory_(this) {
#if !defined(OS_ANDROID)
#error The BreakingNewsGCMAppHandler should only be used on Android.
#endif // !OS_ANDROID
DCHECK(token_validation_timer_);
DCHECK(!token_validation_timer_->IsRunning());
}
BreakingNewsGCMAppHandler::~BreakingNewsGCMAppHandler() {
StopListening();
if (IsListening()) {
StopListening();
}
}
void BreakingNewsGCMAppHandler::StartListening(
OnNewRemoteSuggestionCallback on_new_remote_suggestion_callback) {
#if !defined(OS_ANDROID)
NOTREACHED()
<< "The BreakingNewsGCMAppHandler should only be used on Android.";
#endif
Subscribe();
DCHECK(!on_new_remote_suggestion_callback.is_null());
on_new_remote_suggestion_callback_ =
std::move(on_new_remote_suggestion_callback);
Subscribe(/*force_token_retrieval=*/false);
gcm_driver_->AddAppHandler(kBreakingNewsGCMAppID, this);
ScheduleNextTokenValidation();
}
void BreakingNewsGCMAppHandler::StopListening() {
DCHECK(IsListening());
token_validation_timer_->Stop();
DCHECK_EQ(gcm_driver_->GetAppHandler(kBreakingNewsGCMAppID), this);
gcm_driver_->RemoveAppHandler(kBreakingNewsGCMAppID);
on_new_remote_suggestion_callback_ = OnNewRemoteSuggestionCallback();
subscription_manager_->Unsubscribe();
}
void BreakingNewsGCMAppHandler::Subscribe() {
// TODO(mamir): This logic should be moved to the SubscriptionManager.
void BreakingNewsGCMAppHandler::Subscribe(bool force_token_retrieval) {
// TODO(mamir): "Whether to subscribe to content suggestions server" logic
// should be moved to the SubscriptionManager.
std::string token =
pref_service_->GetString(prefs::kBreakingNewsGCMSubscriptionTokenCache);
// If a token has been already obtained, subscribe directly at the content
// suggestions server. Otherwise, obtain a GCM token first.
if (!token.empty()) {
if (!token.empty() && !force_token_retrieval) {
if (!subscription_manager_->IsSubscribed() ||
subscription_manager_->NeedsToResubscribe()) {
subscription_manager_->Subscribe(token);
......@@ -82,15 +109,20 @@ void BreakingNewsGCMAppHandler::Subscribe() {
instance_id_driver_->GetInstanceID(kBreakingNewsGCMAppID)
->GetToken(kBreakingNewsGCMSenderId, kGCMScope,
/*options=*/std::map<std::string, std::string>(),
base::Bind(&BreakingNewsGCMAppHandler::DidSubscribe,
base::Bind(&BreakingNewsGCMAppHandler::DidRetrieveToken,
weak_ptr_factory_.GetWeakPtr()));
}
void BreakingNewsGCMAppHandler::DidSubscribe(
void BreakingNewsGCMAppHandler::DidRetrieveToken(
const std::string& subscription_token,
InstanceID::Result result) {
switch (result) {
case InstanceID::SUCCESS:
// The received token is assumed to be valid, therefore, we reschedule
// validation.
pref_service_->SetInt64(prefs::kBreakingNewsGCMLastTokenValidationTime,
SerializeTime(clock_->Now()));
ScheduleNextTokenValidation();
pref_service_->SetString(prefs::kBreakingNewsGCMSubscriptionTokenCache,
subscription_token);
subscription_manager_->Subscribe(subscription_token);
......@@ -109,6 +141,57 @@ void BreakingNewsGCMAppHandler::DidSubscribe(
}
}
void BreakingNewsGCMAppHandler::ResubscribeIfInvalidToken() {
DCHECK(IsListening());
// InstanceIDAndroid::ValidateToken just returns |true| on Android. Instead it
// is ok to retrieve a token, because it is cached.
instance_id_driver_->GetInstanceID(kBreakingNewsGCMAppID)
->GetToken(
kBreakingNewsGCMSenderId, kGCMScope,
/*options=*/std::map<std::string, std::string>(),
base::Bind(&BreakingNewsGCMAppHandler::DidReceiveTokenForValidation,
weak_ptr_factory_.GetWeakPtr()));
}
void BreakingNewsGCMAppHandler::DidReceiveTokenForValidation(
const std::string& new_token,
InstanceID::Result result) {
// TODO(crbug.com/744557): Add a metric to record time from last validation.
// We intentionally reschedule as normal even if we don't get a token.
// TODO(crbug.com/744557): Add a metric to record number of failed token
// retrievals. Consider rescheduling next validation sooner.
pref_service_->SetInt64(prefs::kBreakingNewsGCMLastTokenValidationTime,
SerializeTime(clock_->Now()));
ScheduleNextTokenValidation();
if (result != InstanceID::SUCCESS) {
return;
}
const std::string old_token =
pref_service_->GetString(prefs::kBreakingNewsGCMSubscriptionTokenCache);
if (old_token != new_token) {
// TODO(crbug.com/744557): Add a metric to record time since last validation
// when the token was valid.
subscription_manager_->Resubscribe(new_token);
}
}
void BreakingNewsGCMAppHandler::ScheduleNextTokenValidation() {
DCHECK(IsListening());
const base::Time last_validation_time = DeserializeTime(
pref_service_->GetInt64(prefs::kBreakingNewsGCMLastTokenValidationTime));
// Timer runs the task immediately if delay is <= 0.
token_validation_timer_->Start(
FROM_HERE,
/*delay=*/last_validation_time + GetTokenValidationPeriod() -
clock_->Now(),
base::Bind(&BreakingNewsGCMAppHandler::ResubscribeIfInvalidToken,
weak_ptr_factory_.GetWeakPtr()));
}
void BreakingNewsGCMAppHandler::ShutdownHandler() {}
void BreakingNewsGCMAppHandler::OnStoreReset() {
......@@ -159,7 +242,9 @@ void BreakingNewsGCMAppHandler::OnSendAcknowledged(
void BreakingNewsGCMAppHandler::RegisterProfilePrefs(
PrefRegistrySimple* registry) {
registry->RegisterStringPref(prefs::kBreakingNewsGCMSubscriptionTokenCache,
std::string());
/*default_value=*/std::string());
registry->RegisterInt64Pref(prefs::kBreakingNewsGCMLastTokenValidationTime,
/*default_value=*/0);
}
void BreakingNewsGCMAppHandler::OnJsonSuccess(
......@@ -198,4 +283,8 @@ void BreakingNewsGCMAppHandler::OnJsonError(const std::string& json_str,
<< " when parsing:" << json_str;
}
bool BreakingNewsGCMAppHandler::IsListening() const {
return !on_new_remote_suggestion_callback_.is_null();
}
} // namespace ntp_snippets
......@@ -6,6 +6,8 @@
#define COMPONENTS_NTP_SNIPPETS_BREAKING_NEWS_BREAKING_NEWS_GCM_APP_HANDLER_H_
#include "base/memory/weak_ptr.h"
#include "base/time/clock.h"
#include "base/timer/timer.h"
#include "components/gcm_driver/gcm_app_handler.h"
#include "components/gcm_driver/instance_id/instance_id.h"
#include "components/ntp_snippets/breaking_news/breaking_news_listener.h"
......@@ -25,9 +27,11 @@ class InstanceIDDriver;
namespace ntp_snippets {
// Handler for pushed GCM breaking news. It retrieves a subscription token
// from the GCM server and registers/unregisters itself with the GCM service to
// be called upon received push breaking news.
// Handler for pushed GCM breaking news. It retrieves a subscription token from
// the GCM server and registers/unregisters itself with the GCM service to be
// called upon received push breaking news. When there is a listener, the token
// is periodically validated. The validation may happen during StartListening if
// enough time has passed since the last validation.
class BreakingNewsGCMAppHandler : public BreakingNewsListener,
public gcm::GCMAppHandler {
public:
......@@ -40,12 +44,16 @@ class BreakingNewsGCMAppHandler : public BreakingNewsListener,
const SuccessCallback& success_callback,
const ErrorCallback& error_callback)>;
// When provided, |timer_task_runner| and |timer_tick_clock| are used inside
// internal validation timer (e.g. for testing).
BreakingNewsGCMAppHandler(
gcm::GCMDriver* gcm_driver,
instance_id::InstanceIDDriver* instance_id_driver,
PrefService* pref_service_,
std::unique_ptr<SubscriptionManager> subscription_manager,
const ParseJSONCallback& parse_json_callback);
const ParseJSONCallback& parse_json_callback,
std::unique_ptr<base::Clock> clock,
std::unique_ptr<base::OneShotTimer> token_validation_timer);
// If still listening, calls StopListening()
~BreakingNewsGCMAppHandler() override;
......@@ -69,14 +77,27 @@ class BreakingNewsGCMAppHandler : public BreakingNewsListener,
static void RegisterProfilePrefs(PrefRegistrySimple* registry);
private:
// Retrieves a subscription token that allows the content suggestions server
// to push content via GCM messages. Calling this method multiple times is not
// necessary but does not harm since the same token is returned everytime.
void Subscribe();
// If there is no subscription token or |force_token_retrieval|, retrieves a
// GCM subscription token and subscribes to content suggestions server with
// it. Otherwise, subscribes to content suggestions server with the existing
// token.
void Subscribe(bool force_token_retrieval);
// Called after the subscription is obtained from the GCM server.
void DidSubscribe(const std::string& subscription_token,
instance_id::InstanceID::Result result);
// Called when a subscription token is obtained from the GCM server.
void DidRetrieveToken(const std::string& subscription_token,
instance_id::InstanceID::Result result);
// Called periodically to validate the subscription token (it is stored on
// disk and may become corrupted) and resubscribe with the new token if the
// old one is invalid.
void ResubscribeIfInvalidToken();
// Called when token obtained from the GCM server for its validation.
void DidReceiveTokenForValidation(const std::string& new_token,
instance_id::InstanceID::Result result);
// If the validation is due, it may be scheduled immediately.
void ScheduleNextTokenValidation();
// Called after successfully parsing the received suggestion JSON.
void OnJsonSuccess(std::unique_ptr<base::Value> content);
......@@ -85,16 +106,21 @@ class BreakingNewsGCMAppHandler : public BreakingNewsListener,
// error.
void OnJsonError(const std::string& json_str, const std::string& error);
bool IsListening() const;
gcm::GCMDriver* const gcm_driver_;
instance_id::InstanceIDDriver* const instance_id_driver_;
PrefService* const pref_service_;
const std::unique_ptr<SubscriptionManager> subscription_manager_;
const ParseJSONCallback parse_json_callback_;
std::unique_ptr<base::Clock> clock_;
// Called after every time a new message is received in OnMessage() to notify
// the content provider.
OnNewRemoteSuggestionCallback on_new_remote_suggestion_callback_;
std::unique_ptr<base::OneShotTimer> token_validation_timer_;
base::WeakPtrFactory<BreakingNewsGCMAppHandler> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(BreakingNewsGCMAppHandler);
......
......@@ -90,5 +90,8 @@ const char kBreakingNewsSubscriptionDataIsAuthenticated[] =
const char kBreakingNewsGCMSubscriptionTokenCache[] =
"ntp_suggestions.breaking_news_gcm_subscription_token_cache";
const char kBreakingNewsGCMLastTokenValidationTime[] =
"ntp_suggestions.breaking_news_gcm_last_token_validation_time";
} // namespace prefs
} // namespace ntp_snippets
......@@ -110,6 +110,9 @@ extern const char kBreakingNewsSubscriptionDataIsAuthenticated[];
// with the new one and update kBreakingNewsSubscriptionDataToken.
extern const char kBreakingNewsGCMSubscriptionTokenCache[];
// When the next GCM token validation is scheduled.
extern const char kBreakingNewsGCMLastTokenValidationTime[];
} // namespace prefs
} // namespace ntp_snippets
......
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