summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/ui/webui/ntp/new_tab_page_handler.cc13
-rw-r--r--chrome/browser/web_resource/notification_promo.cc129
-rw-r--r--chrome/browser/web_resource/notification_promo.h47
-rw-r--r--chrome/browser/web_resource/promo_resource_service.cc19
-rw-r--r--chrome/browser/web_resource/promo_resource_service.h18
-rw-r--r--chrome/browser/web_resource/promo_resource_service_unittest.cc159
-rw-r--r--chrome/common/pref_names.cc6
-rw-r--r--chrome/common/pref_names.h2
8 files changed, 317 insertions, 76 deletions
diff --git a/chrome/browser/ui/webui/ntp/new_tab_page_handler.cc b/chrome/browser/ui/webui/ntp/new_tab_page_handler.cc
index 62b94cd..d3e4a6e 100644
--- a/chrome/browser/ui/webui/ntp/new_tab_page_handler.cc
+++ b/chrome/browser/ui/webui/ntp/new_tab_page_handler.cc
@@ -6,6 +6,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "base/memory/scoped_ptr.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "chrome/browser/browser_process.h"
@@ -66,16 +67,16 @@ void NewTabPageHandler::RegisterMessages() {
}
void NewTabPageHandler::HandleCloseNotificationPromo(const ListValue* args) {
- NotificationPromo notification_promo(
- Profile::FromWebUI(web_ui())->GetPrefs(), NULL);
- notification_promo.HandleClosed();
+ scoped_refptr<NotificationPromo> notification_promo =
+ NotificationPromo::Create(Profile::FromWebUI(web_ui()), NULL);
+ notification_promo->HandleClosed();
Notify(chrome::NOTIFICATION_PROMO_RESOURCE_STATE_CHANGED);
}
void NewTabPageHandler::HandleNotificationPromoViewed(const ListValue* args) {
- NotificationPromo notification_promo(
- Profile::FromWebUI(web_ui_)->GetPrefs(), NULL);
- if (notification_promo.HandleViewed())
+ scoped_refptr<NotificationPromo> notification_promo =
+ NotificationPromo::Create(Profile::FromWebUI(web_ui_), NULL);
+ if (notification_promo->HandleViewed())
Notify(chrome::NOTIFICATION_PROMO_RESOURCE_STATE_CHANGED);
}
diff --git a/chrome/browser/web_resource/notification_promo.cc b/chrome/browser/web_resource/notification_promo.cc
index 9f4a025..a977dcc 100644
--- a/chrome/browser/web_resource/notification_promo.cc
+++ b/chrome/browser/web_resource/notification_promo.cc
@@ -4,13 +4,19 @@
#include "chrome/browser/web_resource/notification_promo.h"
+#include "base/bind.h"
#include "base/rand_util.h"
#include "base/string_number_conversions.h"
+#include "base/string_split.h"
#include "base/time.h"
#include "base/values.h"
#include "chrome/browser/prefs/pref_service.h"
+#include "chrome/browser/profiles/profile_impl.h"
#include "chrome/browser/web_resource/promo_resource_service.h"
#include "chrome/common/pref_names.h"
+#include "googleurl/src/gurl.h"
+#include "net/base/cookie_store.h"
+#include "net/url_request/url_request_context.h"
namespace {
@@ -33,6 +39,10 @@ static const char kTextProperty[] = "tooltip";
static const char kTimeProperty[] = "inproduct";
static const char kParamsProperty[] = "question";
+static const char kGPlusDomainUrl[] = "http://plus.google.com/";
+static const char kGPlusDomainSecureCookieId[] = "SID=";
+static const char kSplitStringToken = ';';
+
// Time getters.
double GetTimeFromDict(const DictionaryValue* dict) {
std::string time_str;
@@ -52,9 +62,10 @@ double GetTimeFromPrefs(PrefService* prefs, const char* pref) {
} // namespace
-NotificationPromo::NotificationPromo(PrefService* prefs, Delegate* delegate)
- : prefs_(prefs),
+NotificationPromo::NotificationPromo(Profile* profile, Delegate* delegate)
+ : profile_(profile),
delegate_(delegate),
+ prefs_(profile_->GetPrefs()),
start_(0.0),
end_(0.0),
build_(PromoResourceService::NO_BUILD),
@@ -62,14 +73,20 @@ NotificationPromo::NotificationPromo(PrefService* prefs, Delegate* delegate)
max_group_(0),
max_views_(0),
platform_(PLATFORM_NONE),
+ feature_mask_(NO_FEATURE),
group_(0),
views_(0),
text_(),
- closed_(false) {
- DCHECK(prefs);
+ closed_(false),
+ gplus_(false) {
+ DCHECK(profile);
+ DCHECK(prefs_);
}
-void NotificationPromo::InitFromJson(const DictionaryValue& json) {
+NotificationPromo::~NotificationPromo() {}
+
+void NotificationPromo::InitFromJson(const DictionaryValue& json,
+ bool do_cookie_check) {
DictionaryValue* dict;
if (json.GetDictionary(kHeaderProperty, &dict)) {
ListValue* answers;
@@ -82,8 +99,45 @@ void NotificationPromo::InitFromJson(const DictionaryValue& json) {
}
}
}
+ if (do_cookie_check) {
+ scoped_refptr<net::URLRequestContextGetter> getter(
+ profile_->GetRequestContext());
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
+ base::Bind(&NotificationPromo::GetCookies, this, getter));
+ } else {
+ CheckForNewNotification(false);
+ }
+}
+
+// static
+bool NotificationPromo::CheckForGPlusCookie(const std::string& cookies) {
+ std::vector<std::string> cookie_list;
+ base::SplitString(cookies, kSplitStringToken, &cookie_list);
+ for (std::vector<std::string>::const_iterator current = cookie_list.begin();
+ current != cookie_list.end();
+ ++current) {
+ if ((*current).find(kGPlusDomainSecureCookieId) == 0) {
+ return true;
+ }
+ }
+ return false;
+}
- CheckForNewNotification();
+void NotificationPromo::GetCookiesCallback(const std::string& cookies) {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+ bool found_cookie = NotificationPromo::CheckForGPlusCookie(cookies);
+ content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
+ base::Bind(&NotificationPromo::CheckForNewNotification, this,
+ found_cookie));
+}
+
+void NotificationPromo::GetCookies(
+ scoped_refptr<net::URLRequestContextGetter> getter) {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+ getter->GetURLRequestContext()->cookie_store()->
+ GetCookiesWithOptionsAsync(
+ GURL(kGPlusDomainUrl), net::CookieOptions(),
+ base::Bind(&NotificationPromo::GetCookiesCallback, this));
}
void NotificationPromo::Parse(const DictionaryValue* dict) {
@@ -112,6 +166,7 @@ void NotificationPromo::ParseParams(const DictionaryValue* dict) {
max_group_ = GetNextQuestionValue(question, &index, &err);
max_views_ = GetNextQuestionValue(question, &index, &err);
platform_ = GetNextQuestionValue(question, &index, &err);
+ feature_mask_ = GetNextQuestionValue(question, &index, &err);
if (err ||
OutOfBounds(build_, PromoResourceService::NO_BUILD,
@@ -126,32 +181,48 @@ void NotificationPromo::ParseParams(const DictionaryValue* dict) {
", time_slice=" << time_slice_ <<
", max_group=" << max_group_ <<
", max_views=" << max_views_ <<
- ", platform_=" << platform_;
+ ", platform_=" << platform_ <<
+ ", feature_mask=" << feature_mask_;
build_ = PromoResourceService::NO_BUILD;
time_slice_ = 0;
max_group_ = 0;
max_views_ = 0;
platform_ = PLATFORM_NONE;
+ feature_mask_ = 0;
}
}
-void NotificationPromo::CheckForNewNotification() {
+void NotificationPromo::CheckForNewNotification(bool found_cookie) {
+ double start = 0.0;
+ double end = 0.0;
+ bool new_notification = false;
+
+ gplus_ = found_cookie;
const double old_start = GetTimeFromPrefs(prefs_, prefs::kNTPPromoStart);
const double old_end = GetTimeFromPrefs(prefs_, prefs::kNTPPromoEnd);
- const bool has_platform = prefs_->HasPrefPath(prefs::kNTPPromoPlatform);
-
+ const bool old_gplus = prefs_->GetBoolean(prefs::kNTPPromoIsLoggedInToPlus);
+ const bool has_feature_mask =
+ prefs_->HasPrefPath(prefs::kNTPPromoFeatureMask);
// Trigger a new notification if the times have changed, or if
- // we previously never wrote out a platform preference. This handles
- // the case where we update to a new client in the middle of a promo.
- if (old_start != start_ || old_end != end_ || !has_platform)
+ // we previously never wrote out a feature_mask, or if the user's gplus
+ // cookies have changed.
+ if (old_start != start_ || old_end != end_ || old_gplus != gplus_ ||
+ !has_feature_mask) {
OnNewNotification();
+ start = StartTimeWithOffset();
+ end = end_;
+ new_notification = true;
+ }
+ if (delegate_) {
+ // If no change needed, call delegate with default values (this
+ // is for testing purposes).
+ delegate_->OnNotificationParsed(start, end, new_notification);
+ }
}
void NotificationPromo::OnNewNotification() {
group_ = NewGroup();
WritePrefs();
- if (delegate_)
- delegate_->OnNewNotification(StartTimeWithOffset(), end_);
}
// static
@@ -196,8 +267,19 @@ void NotificationPromo::RegisterUserPrefs(PrefService* prefs) {
prefs->RegisterBooleanPref(prefs::kNTPPromoClosed,
false,
PrefService::UNSYNCABLE_PREF);
+ prefs->RegisterBooleanPref(prefs::kNTPPromoIsLoggedInToPlus,
+ false,
+ PrefService::UNSYNCABLE_PREF);
+ prefs->RegisterIntegerPref(prefs::kNTPPromoFeatureMask,
+ 0,
+ PrefService::UNSYNCABLE_PREF);
}
+// static
+NotificationPromo* NotificationPromo::Create(Profile *profile,
+ NotificationPromo::Delegate * delegate) {
+ return new NotificationPromo(profile, delegate);
+}
void NotificationPromo::WritePrefs() {
prefs_->SetDouble(prefs::kNTPPromoStart, start_);
@@ -213,6 +295,8 @@ void NotificationPromo::WritePrefs() {
prefs_->SetInteger(prefs::kNTPPromoGroup, group_);
prefs_->SetInteger(prefs::kNTPPromoViews, views_);
prefs_->SetBoolean(prefs::kNTPPromoClosed, closed_);
+ prefs_->SetBoolean(prefs::kNTPPromoIsLoggedInToPlus, gplus_);
+ prefs_->SetInteger(prefs::kNTPPromoFeatureMask, feature_mask_);
}
void NotificationPromo::InitFromPrefs() {
@@ -227,6 +311,12 @@ void NotificationPromo::InitFromPrefs() {
group_ = prefs_->GetInteger(prefs::kNTPPromoGroup);
views_ = prefs_->GetInteger(prefs::kNTPPromoViews);
closed_ = prefs_->GetBoolean(prefs::kNTPPromoClosed);
+
+ if (prefs_->HasPrefPath(prefs::kNTPPromoIsLoggedInToPlus))
+ gplus_ = prefs_->GetBoolean(prefs::kNTPPromoIsLoggedInToPlus);
+
+ if (prefs_->HasPrefPath(prefs::kNTPPromoFeatureMask))
+ feature_mask_ = prefs_->GetInteger(prefs::kNTPPromoFeatureMask);
}
bool NotificationPromo::CanShow() const {
@@ -237,7 +327,8 @@ bool NotificationPromo::CanShow() const {
IsPlatformAllowed(platform_) &&
IsBuildAllowed(build_) &&
base::Time::FromDoubleT(StartTimeWithOffset()) < base::Time::Now() &&
- base::Time::FromDoubleT(end_) > base::Time::Now();
+ base::Time::FromDoubleT(end_) > base::Time::Now() &&
+ (!(feature_mask_ & NotificationPromo::FEATURE_GPLUS) || gplus_);
}
void NotificationPromo::HandleClosed() {
@@ -282,7 +373,7 @@ int NotificationPromo::CurrentPlatform() {
#elif defined(OS_LINUX)
return PLATFORM_LINUX;
#else
- return PLATFORM_NONE;
+ return PLATFORM_NONE;
#endif
}
@@ -322,5 +413,7 @@ bool NotificationPromo::operator==(const NotificationPromo& other) const {
group_ == other.group_ &&
views_ == other.views_ &&
text_ == other.text_ &&
- closed_ == other.closed_;
+ closed_ == other.closed_ &&
+ gplus_ == other.gplus_ &&
+ feature_mask_ == other.feature_mask_;
}
diff --git a/chrome/browser/web_resource/notification_promo.h b/chrome/browser/web_resource/notification_promo.h
index 98bfa06..7f2aa58 100644
--- a/chrome/browser/web_resource/notification_promo.h
+++ b/chrome/browser/web_resource/notification_promo.h
@@ -10,30 +10,40 @@
#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
namespace base {
class DictionaryValue;
}
+namespace net {
+ class URLRequestContextGetter;
+}
+
class PrefService;
+class Profile;
// Helper class for PromoResourceService that parses promo notification info
// from json or prefs.
-class NotificationPromo {
+class NotificationPromo
+ : public base::RefCountedThreadSafe<NotificationPromo> {
public:
class Delegate {
public:
virtual ~Delegate() {}
- virtual void OnNewNotification(double start, double end) = 0;
+ virtual void OnNotificationParsed(double start, double end,
+ bool new_notification) = 0;
// For testing.
virtual bool IsBuildAllowed(int builds_targeted) const { return false; }
virtual int CurrentPlatform() const { return PLATFORM_NONE; }
};
- explicit NotificationPromo(PrefService* prefs, Delegate* delegate);
+ // Static factory for creating new notification promos.
+ static NotificationPromo* Create(Profile* profile, Delegate* delegate);
// Initialize from json/prefs.
- void InitFromJson(const base::DictionaryValue& json);
+ void InitFromJson(const base::DictionaryValue& json, bool do_cookie_check);
void InitFromPrefs();
// Can this promo be shown?
@@ -51,6 +61,10 @@ class NotificationPromo {
static void RegisterUserPrefs(PrefService* prefs);
private:
+ friend class base::RefCountedThreadSafe<NotificationPromo>;
+ NotificationPromo(Profile* profile, Delegate* delegate);
+ virtual ~NotificationPromo();
+
// For testing.
friend class NotificationPromoTestDelegate;
FRIEND_TEST_ALL_PREFIXES(PromoResourceServiceTest, GetNextQuestionValueTest);
@@ -65,6 +79,12 @@ class NotificationPromo {
PLATFORM_ALL = (1 << 4) -1,
};
+ // Flags for feature_mask_.
+ enum Feature {
+ NO_FEATURE = 0,
+ FEATURE_GPLUS = 1,
+ };
+
// Users are randomly assigned to one of kMaxGroupSize + 1 buckets, in order
// to be able to roll out promos slowly, or display different promos to
// different groups.
@@ -75,16 +95,26 @@ class NotificationPromo {
void Parse(const base::DictionaryValue* dict);
// Set promo notification params from a question string, which is of the form
- // <build_type>:<time_slice>:<max_group>:<max_views>
+ // <build_type>:<time_slice>:<max_group>:<max_views>:<platform>:<feature_mask>
void ParseParams(const base::DictionaryValue* dict);
// Check if this promo notification is new based on start/end times,
// and trigger events accordingly.
- void CheckForNewNotification();
+ void CheckForNewNotification(bool found_cookie);
// Actions on receiving a new promo notification.
void OnNewNotification();
+ // Async method to get cookies from GPlus url. Used to check if user is
+ // logged in to GPlus.
+ void GetCookies(scoped_refptr<net::URLRequestContextGetter> getter);
+
+ // Callback for GetCookies.
+ void GetCookiesCallback(const std::string& cookies);
+
+ // Parse cookies in search of a SID= value.
+ static bool CheckForGPlusCookie(const std::string& cookies);
+
// Create a new promo notification group.
static int NewGroup();
@@ -110,8 +140,9 @@ class NotificationPromo {
// For testing.
bool operator==(const NotificationPromo& other) const;
- PrefService* prefs_;
+ Profile* profile_;
Delegate* delegate_;
+ PrefService* prefs_;
double start_;
double end_;
@@ -121,11 +152,13 @@ class NotificationPromo {
int max_group_;
int max_views_;
int platform_;
+ int feature_mask_;
int group_;
int views_;
std::string text_;
bool closed_;
+ bool gplus_;
DISALLOW_COPY_AND_ASSIGN(NotificationPromo);
};
diff --git a/chrome/browser/web_resource/promo_resource_service.cc b/chrome/browser/web_resource/promo_resource_service.cc
index 8bac134..86e905c 100644
--- a/chrome/browser/web_resource/promo_resource_service.cc
+++ b/chrome/browser/web_resource/promo_resource_service.cc
@@ -157,8 +157,11 @@ void PromoResourceService::Unpack(const DictionaryValue& parsed_json) {
UnpackNTPSignInPromoSignal(parsed_json);
}
-void PromoResourceService::OnNewNotification(double start, double end) {
- ScheduleNotification(start, end);
+void PromoResourceService::OnNotificationParsed(double start, double end,
+ bool new_notification) {
+ if (new_notification) {
+ ScheduleNotification(start, end);
+ }
}
void PromoResourceService::ScheduleNotification(double promo_start,
@@ -215,14 +218,16 @@ std::string PromoResourceService::GetPromoLocale() {
void PromoResourceService::UnpackNotificationSignal(
const DictionaryValue& parsed_json) {
- NotificationPromo notification_promo(prefs_, this);
- notification_promo.InitFromJson(parsed_json);
+ scoped_refptr<NotificationPromo> notification_promo =
+ NotificationPromo::Create(profile_, this);
+ notification_promo->InitFromJson(parsed_json, false);
}
bool PromoResourceService::CanShowNotificationPromo(Profile* profile) {
- NotificationPromo notification_promo(profile->GetPrefs(), NULL);
- notification_promo.InitFromPrefs();
- return notification_promo.CanShow();
+ scoped_refptr<NotificationPromo> notification_promo =
+ NotificationPromo::Create(profile, NULL);
+ notification_promo->InitFromPrefs();
+ return notification_promo->CanShow();
}
void PromoResourceService::UnpackWebStoreSignal(
diff --git a/chrome/browser/web_resource/promo_resource_service.h b/chrome/browser/web_resource/promo_resource_service.h
index c211ff6..67f1060 100644
--- a/chrome/browser/web_resource/promo_resource_service.h
+++ b/chrome/browser/web_resource/promo_resource_service.h
@@ -113,7 +113,7 @@ class PromoResourceService
// {
// "answer_id": "1067976",
// "name": "promo_start",
- // "question": "1:24:10:20:7",
+ // "question": "1:24:10:20:7:0",
// "tooltip":
// "Click \u003ca href=http://www.google.com\u003ehere\u003c/a\u003e!",
// "inproduct": "10/8/09 12:00",
@@ -141,12 +141,15 @@ class PromoResourceService
// field. The "question" field gives the type of builds that should be shown
// this promo (see the BuildType enum in web_resource_service.cc), the
// number of hours that each promo group should see it, the maximum promo
- // group that should see it, the maximum number of views of the promo, and
- // the platforms that this promo is suitable for, separated by ":".
- // For example, "7:24:5:10:7" would indicate that all groups with ids less
+ // group that should see it, the maximum number of views of the promo,the
+ // platforms that this promo is suitable for, and a mask of features which
+ // must be present in order for the promo to be shown (0 => no feaures needed
+ // 1 => user must be logged in to gplus), separated by ":".
+ // For example, "7:24:5:10:7:0" would indicate that all groups with ids less
// than 5, and with dev, beta and stable builds on Windows, Mac and Linux,
- // should see the promo a maximum of 10 times. The groups ramp up so one
- // additional group sees the promo every 24 hours.
+ // should see the promo a maximum of 10 times, the promo is suitable for Mac
+ // Linux and Windows platforms, and no features are required to show it. The
+ // groups ramp up so one additional group sees the promo every 24 hours.
//
void UnpackNotificationSignal(const base::DictionaryValue& parsed_json);
@@ -227,7 +230,8 @@ class PromoResourceService
void UnpackNTPSignInPromoSignal(const base::DictionaryValue& parsed_json);
// NotificationPromo::Delegate override.
- virtual void OnNewNotification(double start, double end) OVERRIDE;
+ virtual void OnNotificationParsed(double start, double end,
+ bool new_notification) OVERRIDE;
// The profile this service belongs to.
Profile* profile_;
diff --git a/chrome/browser/web_resource/promo_resource_service_unittest.cc b/chrome/browser/web_resource/promo_resource_service_unittest.cc
index 8a522b1..be7508e 100644
--- a/chrome/browser/web_resource/promo_resource_service_unittest.cc
+++ b/chrome/browser/web_resource/promo_resource_service_unittest.cc
@@ -103,9 +103,9 @@ class NTPSignInPromoTest : public PromoResourceServiceTest,
" }"
"}";
- scoped_ptr<DictionaryValue> test_json(static_cast<DictionaryValue*>(
+ scoped_ptr<DictionaryValue> test_json(static_cast<DictionaryValue*>(
base::JSONReader::Read(json_header + question + json_footer, false)));
- web_resource_service_->UnpackNTPSignInPromoSignal(*(test_json.get()));
+ web_resource_service_->UnpackNTPSignInPromoSignal(*(test_json.get()));
}
private:
@@ -194,10 +194,12 @@ TEST_F(PromoResourceServiceTest, UnpackLogoSignal) {
class NotificationPromoTestDelegate : public NotificationPromo::Delegate {
public:
- explicit NotificationPromoTestDelegate(PrefService* prefs)
- : prefs_(prefs),
+ explicit NotificationPromoTestDelegate(Profile* profile)
+ : profile_(profile),
+ prefs_(profile->GetPrefs()),
notification_promo_(NULL),
received_notification_(false),
+ should_receive_notification_(false),
build_targeted_(true),
start_(0.0),
end_(0.0),
@@ -206,8 +208,10 @@ class NotificationPromoTestDelegate : public NotificationPromo::Delegate {
max_group_(0),
max_views_(0),
platform_(NotificationPromo::PLATFORM_NONE),
+ feature_mask_(0),
text_(),
closed_(false),
+ gplus_(false),
current_platform_(NotificationPromo::CurrentPlatform()) {
}
@@ -216,7 +220,8 @@ class NotificationPromoTestDelegate : public NotificationPromo::Delegate {
double start, double end,
int build, int time_slice,
int max_group, int max_views, int platform,
- const std::string& text, bool closed) {
+ int feature_mask, const std::string& text, bool closed,
+ bool gplus) {
notification_promo_ = notification_promo;
test_json_.reset(static_cast<DictionaryValue*>(
@@ -233,16 +238,23 @@ class NotificationPromoTestDelegate : public NotificationPromo::Delegate {
text_ = text;
closed_ = closed;
+ gplus_ = gplus;
+ feature_mask_ = feature_mask;
received_notification_ = false;
}
// NotificationPromo::Delegate implementation.
- virtual void OnNewNotification(double start, double end) {
- EXPECT_EQ(CalcStart(), start);
- EXPECT_EQ(notification_promo_->StartTimeWithOffset(), start);
- EXPECT_EQ(notification_promo_->end_, end);
- received_notification_ = true;
+ virtual void OnNotificationParsed(double start, double end,
+ bool new_notification) {
+ if (should_receive_notification_) {
+ EXPECT_EQ(CalcStart(), start);
+ EXPECT_EQ(notification_promo_->StartTimeWithOffset(), start);
+ EXPECT_EQ(notification_promo_->end_, end);
+ }
+
+ received_notification_ = new_notification;
+ EXPECT_TRUE(received_notification_ == should_receive_notification_);
}
virtual bool IsBuildAllowed(int builds_targeted) const {
@@ -263,8 +275,9 @@ class NotificationPromoTestDelegate : public NotificationPromo::Delegate {
}
void InitPromoFromJson(bool should_receive_notification) {
+ should_receive_notification_ = should_receive_notification;
received_notification_ = false;
- notification_promo_->InitFromJson(TestJson());
+ notification_promo_->InitFromJson(TestJson(), false);
EXPECT_TRUE(received_notification_ == should_receive_notification);
// Test the fields.
@@ -272,6 +285,56 @@ class NotificationPromoTestDelegate : public NotificationPromo::Delegate {
TestPrefs();
}
+ void TestCookie(const std::string& cookies,
+ bool should_receive_notification, bool should_find_cookie) {
+ gplus_ = should_find_cookie;
+ should_receive_notification_ = should_receive_notification;
+ received_notification_ = false;
+
+ bool found_cookie = NotificationPromo::CheckForGPlusCookie(cookies);
+ EXPECT_TRUE(found_cookie == should_find_cookie);
+
+ notification_promo_->CheckForNewNotification(found_cookie);
+ EXPECT_TRUE(received_notification_ == should_receive_notification);
+
+ // Test the fields.
+ EXPECT_EQ(notification_promo_->gplus_, gplus_);
+ EXPECT_EQ(notification_promo_->feature_mask_, feature_mask_);
+ // Test the prefs.
+ EXPECT_EQ(prefs_->GetBoolean(prefs::kNTPPromoIsLoggedInToPlus), gplus_);
+ EXPECT_EQ(prefs_->GetInteger(prefs::kNTPPromoFeatureMask), feature_mask_);
+
+ // Set group_ manually to a passing group.
+ notification_promo_->group_ = max_group_ - 1;
+ // Assumes feature_mask = GPLUS_FEATURE, so whether or not the promo is
+ // is shown depends only on the value of gplus_.
+ EXPECT_TRUE(notification_promo_->CanShow() == gplus_);
+ }
+
+ void TestGPlus() {
+ feature_mask_ = NotificationPromo::FEATURE_GPLUS;
+ notification_promo_->feature_mask_ = NotificationPromo::FEATURE_GPLUS;
+ // Force a notification when gplus_ is found to be false.
+ notification_promo_->prefs_->
+ SetBoolean(prefs::kNTPPromoIsLoggedInToPlus, true);
+
+ TestCookie("WRONG=123456;", true, false);
+ // Should not trigger notification on second call.
+ TestCookie("WRONG=123456;", false, false);
+
+ TestCookie("SID=123456;", true, true);
+ // Should not trigger notification on second call.
+ TestCookie("SID=123456;", false, true);
+
+ // Reset the notification_promo to its original state.
+ feature_mask_ = NotificationPromo::NO_FEATURE;
+ notification_promo_->feature_mask_ = NotificationPromo::NO_FEATURE;
+ gplus_ = false;
+ notification_promo_->prefs_->
+ SetBoolean(prefs::kNTPPromoIsLoggedInToPlus, false);
+ notification_promo_->gplus_ = false;
+ }
+
void TestNotification() {
// Check values.
EXPECT_EQ(notification_promo_->start_, start_);
@@ -283,6 +346,8 @@ class NotificationPromoTestDelegate : public NotificationPromo::Delegate {
EXPECT_EQ(notification_promo_->platform_, platform_);
EXPECT_EQ(notification_promo_->text_, text_);
EXPECT_EQ(notification_promo_->closed_, closed_);
+ EXPECT_EQ(notification_promo_->gplus_, gplus_);
+ EXPECT_EQ(notification_promo_->feature_mask_, feature_mask_);
// Check group within bounds.
EXPECT_GE(notification_promo_->group_, 0);
@@ -310,14 +375,17 @@ class NotificationPromoTestDelegate : public NotificationPromo::Delegate {
EXPECT_EQ(prefs_->GetInteger(prefs::kNTPPromoViews), 0);
EXPECT_EQ(prefs_->GetString(prefs::kNTPPromoLine), text_);
EXPECT_EQ(prefs_->GetBoolean(prefs::kNTPPromoClosed), closed_);
+ EXPECT_EQ(prefs_->GetBoolean(prefs::kNTPPromoIsLoggedInToPlus), gplus_);
+ EXPECT_EQ(prefs_->GetInteger(prefs::kNTPPromoFeatureMask), feature_mask_);
}
// Create a new NotificationPromo from prefs and compare to current
// notification.
void TestInitFromPrefs() {
- NotificationPromo prefs_notification_promo(prefs_, this);
- prefs_notification_promo.InitFromPrefs();
- const bool is_equal = *notification_promo_ == prefs_notification_promo;
+ scoped_refptr<NotificationPromo> prefs_notification_promo =
+ NotificationPromo::Create(profile_, this);
+ prefs_notification_promo->InitFromPrefs();
+ const bool is_equal = *notification_promo_ == *prefs_notification_promo;
EXPECT_TRUE(is_equal);
}
@@ -515,10 +583,33 @@ class NotificationPromoTestDelegate : public NotificationPromo::Delegate {
EXPECT_TRUE(notification_promo_->CanShow());
}
+ void TestFeatureMask() {
+ // No gplus cookie, feature mask in use.
+ notification_promo_->gplus_ = false;
+ notification_promo_->feature_mask_ = NotificationPromo::FEATURE_GPLUS;
+ EXPECT_FALSE(notification_promo_->CanShow());
+
+ // Gplus cookie, feature mask in use.
+ notification_promo_->gplus_ = true;
+ notification_promo_->feature_mask_ = NotificationPromo::FEATURE_GPLUS;
+ EXPECT_TRUE(notification_promo_->CanShow());
+
+ // If no feature mask, gplus_ value is ignored.
+ notification_promo_->gplus_ = true;
+ notification_promo_->feature_mask_ = NotificationPromo::NO_FEATURE;
+ EXPECT_TRUE(notification_promo_->CanShow());
+
+ notification_promo_->gplus_ = false;
+ notification_promo_->feature_mask_ = NotificationPromo::NO_FEATURE;
+ EXPECT_TRUE(notification_promo_->CanShow());
+ }
+
private:
+ Profile* profile_;
PrefService* prefs_;
NotificationPromo* notification_promo_;
bool received_notification_;
+ bool should_receive_notification_;
bool build_targeted_;
scoped_ptr<DictionaryValue> test_json_;
@@ -530,10 +621,12 @@ class NotificationPromoTestDelegate : public NotificationPromo::Delegate {
int max_group_;
int max_views_;
int platform_;
+ int feature_mask_;
std::string text_;
bool closed_;
+ bool gplus_;
int current_platform_;
};
@@ -542,35 +635,36 @@ TEST_F(PromoResourceServiceTest, NotificationPromoTest) {
PrefService* prefs = profile_.GetPrefs();
ASSERT_TRUE(prefs != NULL);
- NotificationPromoTestDelegate delegate(prefs);
- NotificationPromo notification_promo(prefs, &delegate);
+ NotificationPromoTestDelegate delegate(&profile_);
+ scoped_refptr<NotificationPromo> notification_promo =
+ NotificationPromo::Create(&profile_, &delegate);
// Make sure prefs are unset.
delegate.TestPrefs();
// Set up start and end dates and promo line in a Dictionary as if parsed
// from the service.
- delegate.Init(&notification_promo,
+ delegate.Init(notification_promo,
"{ "
" \"topic\": {"
" \"answers\": ["
" {"
" \"name\": \"promo_start\","
- " \"question\": \"3:2:5:10:15\","
+ " \"question\": \"3:2:5:10:15:0\","
" \"tooltip\": \"Eat more pie!\","
" \"inproduct\": \"31/01/10 01:00 GMT\""
" },"
" {"
" \"name\": \"promo_end\","
- " \"inproduct\": \"31/01/12 01:00 GMT\""
+ " \"inproduct\": \"31/01/14 01:00 GMT\""
" }"
" ]"
" }"
"}",
1264899600, // unix epoch for Jan 31 2010 0100 GMT.
- 1327971600, // unix epoch for Jan 31 2012 0100 GMT.
- 3, 2, 5, 10, 15,
- "Eat more pie!", false);
+ 1391130000, // unix epoch for Jan 31 2012 0100 GMT.
+ 3, 2, 5, 10, 15, 0,
+ "Eat more pie!", false, false);
delegate.InitPromoFromJson(true);
@@ -587,7 +681,9 @@ TEST_F(PromoResourceServiceTest, NotificationPromoTest) {
delegate.TestClosed();
delegate.TestText();
delegate.TestTime();
+ delegate.TestFeatureMask();
delegate.TestPlatforms();
+ delegate.TestGPlus();
}
TEST_F(PromoResourceServiceTest, NotificationPromoTestFail) {
@@ -595,18 +691,19 @@ TEST_F(PromoResourceServiceTest, NotificationPromoTestFail) {
PrefService* prefs = profile_.GetPrefs();
ASSERT_TRUE(prefs != NULL);
- NotificationPromoTestDelegate delegate(prefs);
- NotificationPromo notification_promo(prefs, &delegate);
+ NotificationPromoTestDelegate delegate(&profile_);
+ scoped_refptr<NotificationPromo> notification_promo =
+ NotificationPromo::Create(&profile_, &delegate);
// Set up start and end dates and promo line in a Dictionary as if parsed
// from the service.
- delegate.Init(&notification_promo,
+ delegate.Init(notification_promo,
"{ "
" \"topic\": {"
" \"answers\": ["
" {"
" \"name\": \"promo_start\","
- " \"question\": \"12:8:10:20:15\","
+ " \"question\": \"12:8:10:20:15:0\","
" \"tooltip\": \"Happy 3rd Birthday!\","
" \"inproduct\": \"09/15/10 05:00 PDT\""
" },"
@@ -619,8 +716,8 @@ TEST_F(PromoResourceServiceTest, NotificationPromoTestFail) {
"}",
1284552000, // unix epoch for Sep 15 2010 0500 PDT.
1285848000, // unix epoch for Sep 30 2010 0500 PDT.
- 12, 8, 10, 20, 15,
- "Happy 3rd Birthday!", false);
+ 12, 8, 10, 20, 15, 0,
+ "Happy 3rd Birthday!", false, false);
delegate.InitPromoFromJson(true);
@@ -630,12 +727,12 @@ TEST_F(PromoResourceServiceTest, NotificationPromoTestFail) {
delegate.TestInitFromPrefs();
// Should fail because out of time bounds.
- EXPECT_FALSE(notification_promo.CanShow());
+ EXPECT_FALSE(notification_promo->CanShow());
}
TEST_F(PromoResourceServiceTest, GetNextQuestionValueTest) {
- const std::string question("0:-100:2048:0:2a");
- const int question_vec[] = { 0, -100, 2048, 0 };
+ const std::string question("0:-100:2048:0:0:0:2a");
+ const int question_vec[] = { 0, -100, 2048, 0, 0, 0};
size_t index = 0;
bool err = false;
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index ed16321..4a8c209 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -1270,6 +1270,12 @@ const char kNTPPromoResourceCache[] = "ntp.promo_resource_cache";
// Last time of update of promo_resource_cache.
const char kNTPPromoResourceCacheUpdate[] = "ntp.promo_resource_cache_update";
+// Is user logged into G+ (used for G+ extension promo).
+const char kNTPPromoIsLoggedInToPlus[] = "ntp.promo_is_logged_in_to_plus";
+
+// Bit mask used to decide when to show the NTP Promo.
+const char kNTPPromoFeatureMask[] = "ntp.promo_feature_mask";
+
// Serves promo resources for the NTP.
const char kNTPPromoResourceServer[] = "ntp.web_resource_server";
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 5082456..68c3e25 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -454,6 +454,8 @@ extern const char kNTPMostVisitedURLsBlacklist[];
extern const char kNTPMostVisitedPinnedURLs[];
extern const char kNTPPromoResourceCache[];
extern const char kNTPPromoResourceCacheUpdate[];
+extern const char kNTPPromoIsLoggedInToPlus[];
+extern const char kNTPPromoFeatureMask[];
extern const char kNTPPromoResourceServer[];
extern const char kNTPDateResourceServer[];
extern const char kNTPShownBookmarksFolder[];