diff options
author | aruslan@chromium.org <aruslan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-13 01:32:33 +0000 |
---|---|---|
committer | aruslan@chromium.org <aruslan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-13 01:32:33 +0000 |
commit | 448da3b954ac9891a430960dc4deacf39d6e1ff4 (patch) | |
tree | 207b31d189110adf080b961f9813166b2e78820b /chrome/browser/web_resource | |
parent | 59d816b0141785fda252decfcdfb2f35a40da991 (diff) | |
download | chromium_src-448da3b954ac9891a430960dc4deacf39d6e1ff4.zip chromium_src-448da3b954ac9891a430960dc4deacf39d6e1ff4.tar.gz chromium_src-448da3b954ac9891a430960dc4deacf39d6e1ff4.tar.bz2 |
Separate the mobile promo action from the message
To make a non-HTML iOS and Android integration feasible,
the promo action and its args are disembedded from promo message.
A separate mobile payload format is compatible with promotion server.
BUG=b/6801441
TEST=
Review URL: https://chromiumcodereview.appspot.com/10700174
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@146499 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/web_resource')
-rw-r--r-- | chrome/browser/web_resource/notification_promo.cc | 117 | ||||
-rw-r--r-- | chrome/browser/web_resource/notification_promo.h | 7 | ||||
-rw-r--r-- | chrome/browser/web_resource/promo_resource_service_unittest.cc | 119 |
3 files changed, 236 insertions, 7 deletions
diff --git a/chrome/browser/web_resource/notification_promo.cc b/chrome/browser/web_resource/notification_promo.cc index 87fefdf..560436a 100644 --- a/chrome/browser/web_resource/notification_promo.cc +++ b/chrome/browser/web_resource/notification_promo.cc @@ -10,6 +10,7 @@ #include "base/bind.h" #include "base/rand_util.h" #include "base/string_number_conversions.h" +#include "base/string_util.h" #include "base/time.h" #include "base/values.h" #include "chrome/browser/prefs/pref_service.h" @@ -21,6 +22,11 @@ #include "content/public/browser/user_metrics.h" #include "googleurl/src/gurl.h" +#if defined(OS_ANDROID) +#include "base/command_line.h" +#include "chrome/common/chrome_switches.h" +#endif // defined(OS_ANDROID) + using content::UserMetricsAction; namespace { @@ -29,22 +35,32 @@ const int kDefaultGroupSize = 100; const char promo_server_url[] = "https://clients3.google.com/crsignal/client"; +#if defined(OS_ANDROID) +const int kCurrentMobilePayloadFormatVersion = 3; +#endif // defined(OS_ANDROID) + double GetTimeFromPrefs(PrefService* prefs, const char* pref) { return prefs->HasPrefPath(pref) ? prefs->GetDouble(pref) : 0.0; } // Returns a string suitable for the Promo Server URL 'osname' value. -const char* PlatformString() { +std::string PlatformString() { #if defined(OS_WIN) return "win"; #elif defined(OS_IOS) - return "ios"; + // TODO(noyau): add iOS-specific implementation + const bool isTablet = false; + return std::string("ios-") + (isTablet ? "tablet" : "phone"); #elif defined(OS_MACOSX) return "mac"; #elif defined(OS_CHROMEOS) return "chromeos"; #elif defined(OS_LINUX) return "linux"; +#elif defined(OS_ANDROID) + const bool isTablet = + CommandLine::ForCurrentProcess()->HasSwitch(switches::kTabletUi); + return std::string("android-") + (isTablet ? "tablet" : "phone"); #else return "none"; #endif @@ -78,6 +94,9 @@ const char* ChannelString() { NotificationPromo::NotificationPromo(Profile* profile) : profile_(profile), prefs_(profile_->GetPrefs()), +#if defined(OS_ANDROID) + promo_action_args_(new base::ListValue), +#endif // defined(OS_ANDROID) start_(0.0), end_(0.0), num_groups_(kDefaultGroupSize), @@ -99,8 +118,15 @@ NotificationPromo::~NotificationPromo() {} void NotificationPromo::InitFromJson(const DictionaryValue& json) { ListValue* promo_list = NULL; +#if !defined(OS_ANDROID) if (!json.GetList("ntp_notification_promo", &promo_list)) return; +#else + if (!json.GetList("mobile_ntp_sync_promo", &promo_list)) { + LOG(ERROR) << "Malfromed JSON: not a mobile_ntp_sync_promo"; + return; + } +#endif // !defined(OS_ANDROID) // No support for multiple promos yet. Only consider the first one. DictionaryValue* promo = NULL; @@ -108,15 +134,17 @@ void NotificationPromo::InitFromJson(const DictionaryValue& json) { return; // Strings. Assume the first one is the promo text. - DictionaryValue* strings; + DictionaryValue* strings = NULL; if (promo->GetDictionary("strings", &strings)) { +#if !defined(OS_ANDROID) DictionaryValue::Iterator iter(*strings); iter.value().GetAsString(&promo_text_); DVLOG(1) << "promo_text_=" << promo_text_; +#endif // defined(OS_ANDROID) } // Date. - ListValue* date_list; + ListValue* date_list = NULL; if (promo->GetList("date", &date_list)) { DictionaryValue* date; if (date_list->GetDictionary(0, &date)) { @@ -138,7 +166,7 @@ void NotificationPromo::InitFromJson(const DictionaryValue& json) { } // Grouping. - DictionaryValue* grouping; + DictionaryValue* grouping = NULL; if (promo->GetDictionary("grouping", &grouping)) { grouping->GetInteger("buckets", &num_groups_); grouping->GetInteger("segment", &initial_segment_); @@ -154,7 +182,7 @@ void NotificationPromo::InitFromJson(const DictionaryValue& json) { } // Payload. - DictionaryValue* payload; + DictionaryValue* payload = NULL; if (promo->GetDictionary("payload", &payload)) { payload->GetBoolean("gplus_required", &gplus_required_); @@ -164,14 +192,65 @@ void NotificationPromo::InitFromJson(const DictionaryValue& json) { promo->GetInteger("max_views", &max_views_); DVLOG(1) << "max_views_ " << max_views_; +#if defined(OS_ANDROID) + int payload_version = 0; + if (!payload) { + LOG(ERROR) << "Malformed JSON: no payload"; + return; + } + if (!strings) { + LOG(ERROR) << "Malformed JSON: no strings"; + return; + } + if (!payload->GetInteger("payload_format_version", &payload_version) || + payload_version != kCurrentMobilePayloadFormatVersion) { + LOG(ERROR) << "Unsupported promo payload_format_version " << payload_version + << "; expected " << kCurrentMobilePayloadFormatVersion; + return; + } + std::string promo_key_short; + std::string promo_key_long; + if (!payload->GetString("promo_message_short", &promo_key_short) || + !payload->GetString("promo_message_long", &promo_key_long) || + !strings->GetString(promo_key_short, &promo_text_) || + !strings->GetString(promo_key_long, &promo_text_long_)) { + LOG(ERROR) << "Malformed JSON: no promo_message_short or _long"; + return; + } + payload->GetString("promo_action_type", &promo_action_type_); + // We need to be idempotent as the tests call us more than once. + promo_action_args_.reset(new base::ListValue); + ListValue* args; + if (payload->GetList("promo_action_args", &args)) { + // JSON format for args: "promo_action_args" : [ "<arg1>", "<arg2>"... ] + // Every value comes from "strings" dictionary, either directly or not. + // Every arg is either directly a key into "strings" dictionary, + // or a key into "payload" dictionary with the value that is a key into + // "strings" dictionary. + for (std::size_t i = 0; i < args->GetSize(); ++i) { + std::string name, key, value; + if (!args->GetString(i, &name) || + !(strings->GetString(name, &value) || + (payload->GetString(name, &key) && + strings->GetString(key, &value)))) { + LOG(ERROR) << "Malformed JSON: failed to parse promo_action_args"; + return; + } + promo_action_args_->Append(base::Value::CreateStringValue(value)); + } + } +#endif // defined(OS_ANDROID) + CheckForNewNotification(); } void NotificationPromo::CheckForNewNotification() { const double old_start = GetTimeFromPrefs(prefs_, prefs::kNtpPromoStart); const double old_end = GetTimeFromPrefs(prefs_, prefs::kNtpPromoEnd); + const std::string old_promo_text = prefs_->GetString(prefs::kNtpPromoLine); - new_notification_ = old_start != start_ || old_end != end_; + new_notification_ = + old_start != start_ || old_end != end_ || old_promo_text != promo_text_; if (new_notification_) OnNewNotification(); } @@ -187,6 +266,17 @@ void NotificationPromo::RegisterUserPrefs(PrefService* prefs) { prefs->RegisterStringPref(prefs::kNtpPromoLine, std::string(), PrefService::UNSYNCABLE_PREF); +#if defined(OS_ANDROID) + prefs->RegisterStringPref(prefs::kNtpPromoLineLong, + std::string(), + PrefService::UNSYNCABLE_PREF); + prefs->RegisterStringPref(prefs::kNtpPromoActionType, + std::string(), + PrefService::UNSYNCABLE_PREF); + prefs->RegisterListPref(prefs::kNtpPromoActionArgs, + new base::ListValue, + PrefService::UNSYNCABLE_PREF); +#endif // defined(OS_ANDROID) prefs->RegisterDoublePref(prefs::kNtpPromoStart, 0, @@ -242,6 +332,12 @@ void NotificationPromo::RegisterUserPrefs(PrefService* prefs) { void NotificationPromo::WritePrefs() { prefs_->SetString(prefs::kNtpPromoLine, promo_text_); +#if defined(OS_ANDROID) + prefs_->SetString(prefs::kNtpPromoLineLong, promo_text_long_); + prefs_->SetString(prefs::kNtpPromoActionType, promo_action_type_); + DCHECK(promo_action_args_.get() != NULL); + prefs_->Set(prefs::kNtpPromoActionArgs, *promo_action_args_.get()); +#endif // defined(OS_ANDROID) prefs_->SetDouble(prefs::kNtpPromoStart, start_); prefs_->SetDouble(prefs::kNtpPromoEnd, end_); @@ -263,6 +359,13 @@ void NotificationPromo::WritePrefs() { void NotificationPromo::InitFromPrefs() { promo_text_ = prefs_->GetString(prefs::kNtpPromoLine); +#if defined(OS_ANDROID) + promo_text_long_ = prefs_->GetString(prefs::kNtpPromoLineLong); + promo_action_type_ = prefs_->GetString(prefs::kNtpPromoActionType); + const base::ListValue* lv = prefs_->GetList(prefs::kNtpPromoActionArgs); + DCHECK(lv != NULL); + promo_action_args_.reset(lv->DeepCopy()); +#endif // defined(OS_ANDROID) start_ = prefs_->GetDouble(prefs::kNtpPromoStart); end_ = prefs_->GetDouble(prefs::kNtpPromoEnd); diff --git a/chrome/browser/web_resource/notification_promo.h b/chrome/browser/web_resource/notification_promo.h index 50c1f94..d553a6a 100644 --- a/chrome/browser/web_resource/notification_promo.h +++ b/chrome/browser/web_resource/notification_promo.h @@ -10,10 +10,12 @@ #include "base/basictypes.h" #include "base/gtest_prod_util.h" #include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" #include "googleurl/src/gurl.h" namespace base { class DictionaryValue; +class ListValue; } class PrefService; @@ -78,6 +80,11 @@ class NotificationPromo { PrefService* prefs_; std::string promo_text_; +#if defined(OS_ANDROID) + std::string promo_text_long_; + std::string promo_action_type_; + scoped_ptr<base::ListValue> promo_action_args_; +#endif double start_; double end_; diff --git a/chrome/browser/web_resource/promo_resource_service_unittest.cc b/chrome/browser/web_resource/promo_resource_service_unittest.cc index 70a6115..e98514f 100644 --- a/chrome/browser/web_resource/promo_resource_service_unittest.cc +++ b/chrome/browser/web_resource/promo_resource_service_unittest.cc @@ -58,6 +58,12 @@ class NotificationPromoTest { void Init(const std::string& json, const std::string& promo_text, +#if defined(OS_ANDROID) + const std::string& promo_text_long, + const std::string& promo_action_type, + const std::string& promo_action_arg0, + const std::string& promo_action_arg1, +#endif // defined(OS_ANDROID) double start, double end, int num_groups, int initial_segment, int increment, int time_slice, int max_group, int max_views, @@ -71,6 +77,13 @@ class NotificationPromoTest { promo_text_ = promo_text; +#if defined(OS_ANDROID) + promo_text_long_ = promo_text_long; + promo_action_type_ = promo_action_type; + promo_action_args_.push_back(promo_action_arg0); + promo_action_args_.push_back(promo_action_arg1); +#endif // defined(OS_ANDROID) + start_ = start; end_ = end; @@ -102,6 +115,20 @@ class NotificationPromoTest { // Check values. EXPECT_EQ(notification_promo_.promo_text_, promo_text_); +#if defined(OS_ANDROID) + EXPECT_EQ(notification_promo_.promo_text_long_, promo_text_long_); + EXPECT_EQ(notification_promo_.promo_action_type_, promo_action_type_); + EXPECT_TRUE(notification_promo_.promo_action_args_.get() != NULL); + EXPECT_EQ(std::size_t(2), promo_action_args_.size()); + EXPECT_EQ(notification_promo_.promo_action_args_->GetSize(), + promo_action_args_.size()); + for (std::size_t i = 0; i < promo_action_args_.size(); ++i) { + std::string value; + EXPECT_TRUE(notification_promo_.promo_action_args_->GetString(i, &value)); + EXPECT_EQ(value, promo_action_args_[i]); + } +#endif // defined(OS_ANDROID) + EXPECT_EQ(notification_promo_.start_, start_); EXPECT_EQ(notification_promo_.end_, end_); @@ -126,6 +153,19 @@ class NotificationPromoTest { void TestPrefs() { EXPECT_EQ(prefs_->GetString(prefs::kNtpPromoLine), promo_text_); +#if defined(OS_ANDROID) + EXPECT_EQ(prefs_->GetString(prefs::kNtpPromoLineLong), promo_text_long_); + EXPECT_EQ(prefs_->GetString(prefs::kNtpPromoActionType), + promo_action_type_); + const base::ListValue* lv = prefs_->GetList(prefs::kNtpPromoActionArgs); + EXPECT_TRUE(lv != NULL); + EXPECT_EQ(lv->GetSize(), promo_action_args_.size()); + for (std::size_t i = 0; i < lv->GetSize(); ++i) { + std::string value; + EXPECT_TRUE(lv->GetString(i, &value)); + EXPECT_EQ(value, promo_action_args_[i]); + } +#endif // defined(OS_ANDROID) EXPECT_EQ(prefs_->GetDouble(prefs::kNtpPromoStart), start_); EXPECT_EQ(prefs_->GetDouble(prefs::kNtpPromoEnd), end_); @@ -158,6 +198,27 @@ class NotificationPromoTest { prefs_notification_promo.prefs_); EXPECT_EQ(notification_promo_.promo_text_, prefs_notification_promo.promo_text_); +#if defined(OS_ANDROID) + EXPECT_EQ(notification_promo_.promo_text_long_, + prefs_notification_promo.promo_text_long_); + EXPECT_EQ(notification_promo_.promo_action_type_, + prefs_notification_promo.promo_action_type_); + EXPECT_TRUE(prefs_notification_promo.promo_action_args_.get() != NULL); + EXPECT_EQ(notification_promo_.promo_action_args_->GetSize(), + prefs_notification_promo.promo_action_args_->GetSize()); + for (std::size_t i = 0; + i < notification_promo_.promo_action_args_->GetSize(); + ++i) { + std::string promo_value; + std::string prefs_value; + EXPECT_TRUE( + notification_promo_.promo_action_args_->GetString(i, &promo_value)); + EXPECT_TRUE( + prefs_notification_promo.promo_action_args_->GetString( + i, &prefs_value)); + EXPECT_EQ(promo_value, prefs_value); + } +#endif // defined(OS_ANDROID) EXPECT_EQ(notification_promo_.start_, prefs_notification_promo.start_); EXPECT_EQ(notification_promo_.end_, @@ -331,6 +392,11 @@ class NotificationPromoTest { scoped_ptr<DictionaryValue> test_json_; std::string promo_text_; +#if defined(OS_ANDROID) + std::string promo_text_long_; + std::string promo_action_type_; + std::vector<std::string> promo_action_args_; +#endif // defined(OS_ANDROID) double start_; double end_; @@ -360,6 +426,7 @@ TEST_F(PromoResourceServiceTest, NotificationPromoTest) { // Set up start and end dates and promo line in a Dictionary as if parsed // from the service. +#if !defined(OS_ANDROID) promo_test.Init("{" " \"ntp_notification_promo\": [" " {" @@ -397,6 +464,58 @@ TEST_F(PromoResourceServiceTest, NotificationPromoTest) { 1326653485, // unix epoch for 15 Jan 2012 10:50:85 PST. 1357566075, // unix epoch for 7 Jan 2013 5:40:75 PST. 1000, 200, 100, 3600, 400, 30, false); +#else + promo_test.Init( + "{" + " \"mobile_ntp_sync_promo\": [" + " {" + " \"date\":" + " [" + " {" + " \"start\":\"15 Jan 2012 10:50:85 PST\"," + " \"end\":\"7 Jan 2013 5:40:75 PST\"" + " }" + " ]," + " \"strings\":" + " {" + " \"MOBILE_PROMO_CHROME_SHORT_TEXT\":" + " \"Like Chrome? Go http://www.google.com/chrome/\"," + " \"MOBILE_PROMO_CHROME_LONG_TEXT\":" + " \"It\'s simple. Go http://www.google.com/chrome/\"," + " \"MOBILE_PROMO_EMAIL_BODY\":\"This is the body.\"," + " \"XXX_VALUE\":\"XXX value\"" + " }," + " \"grouping\":" + " {" + " \"buckets\":1000," + " \"segment\":200," + " \"increment\":100," + " \"increment_frequency\":3600," + " \"increment_max\":400" + " }," + " \"payload\":" + " {" + " \"payload_format_version\":3," + " \"gplus_required\":false," + " \"promo_message_long\":" + " \"MOBILE_PROMO_CHROME_LONG_TEXT\"," + " \"promo_message_short\":" + " \"MOBILE_PROMO_CHROME_SHORT_TEXT\"," + " \"promo_action_type\":\"ACTION_EMAIL\"," + " \"promo_action_args\":[\"MOBILE_PROMO_EMAIL_BODY\",\"XXX\"]," + " \"XXX\":\"XXX_VALUE\"" + " }," + " \"max_views\":30" + " }" + " ]" + "}", + "Like Chrome? Go http://www.google.com/chrome/", + "It\'s simple. Go http://www.google.com/chrome/", + "ACTION_EMAIL", "This is the body.", "XXX value", + 1326653485, // unix epoch for 15 Jan 2012 10:50:85 PST. + 1357566075, // unix epoch for 7 Jan 2013 5:40:75 PST. + 1000, 200, 100, 3600, 400, 30, false); +#endif // !defined(OS_ANDROID) promo_test.InitPromoFromJson(true); |