summaryrefslogtreecommitdiffstats
path: root/chrome/browser/web_resource
diff options
context:
space:
mode:
authoraruslan@chromium.org <aruslan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-13 01:32:33 +0000
committeraruslan@chromium.org <aruslan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-13 01:32:33 +0000
commit448da3b954ac9891a430960dc4deacf39d6e1ff4 (patch)
tree207b31d189110adf080b961f9813166b2e78820b /chrome/browser/web_resource
parent59d816b0141785fda252decfcdfb2f35a40da991 (diff)
downloadchromium_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.cc117
-rw-r--r--chrome/browser/web_resource/notification_promo.h7
-rw-r--r--chrome/browser/web_resource/promo_resource_service_unittest.cc119
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);