diff options
author | caitkp@chromium.org <caitkp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-30 15:10:20 +0000 |
---|---|---|
committer | caitkp@chromium.org <caitkp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-30 15:10:20 +0000 |
commit | 34efc42324c0d7979bbea488e64e742c22c24a1c (patch) | |
tree | 9c9cfbcd7f7a402f7c2d646d1b9bb7b552ef5856 | |
parent | c4e075ca89bd18129b09b60cc331d9e0b231ac79 (diff) | |
download | chromium_src-34efc42324c0d7979bbea488e64e742c22c24a1c.zip chromium_src-34efc42324c0d7979bbea488e64e742c22c24a1c.tar.gz chromium_src-34efc42324c0d7979bbea488e64e742c22c24a1c.tar.bz2 |
Only show G+ promo for users logged into G+
Review URL: http://codereview.chromium.org/8520009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@112225 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/ui/webui/ntp/new_tab_page_handler.cc | 13 | ||||
-rw-r--r-- | chrome/browser/web_resource/notification_promo.cc | 129 | ||||
-rw-r--r-- | chrome/browser/web_resource/notification_promo.h | 47 | ||||
-rw-r--r-- | chrome/browser/web_resource/promo_resource_service.cc | 19 | ||||
-rw-r--r-- | chrome/browser/web_resource/promo_resource_service.h | 18 | ||||
-rw-r--r-- | chrome/browser/web_resource/promo_resource_service_unittest.cc | 159 | ||||
-rw-r--r-- | chrome/common/pref_names.cc | 6 | ||||
-rw-r--r-- | chrome/common/pref_names.h | 2 |
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(¬ification_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(¬ification_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[]; |