Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(78)

Unified Diff: ios/chrome/browser/ui/ntp/notification_promo_whats_new.mm

Issue 2589803002: Upstream Chrome on iOS source code [6/11]. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ios/chrome/browser/ui/ntp/notification_promo_whats_new.mm
diff --git a/ios/chrome/browser/ui/ntp/notification_promo_whats_new.mm b/ios/chrome/browser/ui/ntp/notification_promo_whats_new.mm
new file mode 100644
index 0000000000000000000000000000000000000000..2828c7980836750a96a8152376c65ca1a471eb29
--- /dev/null
+++ b/ios/chrome/browser/ui/ntp/notification_promo_whats_new.mm
@@ -0,0 +1,287 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/ui/ntp/notification_promo_whats_new.h"
+
+#include <stdint.h>
+#include <algorithm>
+#include <memory>
+#include <vector>
+
+#include "base/json/json_reader.h"
+#include "base/metrics/field_trial.h"
+#include "base/metrics/user_metrics.h"
+#include "base/metrics/user_metrics_action.h"
+#include "base/strings/string_util.h"
+#include "base/time/time.h"
+#include "base/values.h"
+#include "components/metrics/metrics_pref_names.h"
+#include "components/prefs/pref_service.h"
+#include "ios/chrome/browser/experimental_flags.h"
+#include "ios/chrome/browser/notification_promo.h"
+#include "ios/chrome/browser/pref_names.h"
+#include "ios/chrome/browser/ui/commands/ios_command_ids.h"
+#include "ios/chrome/grit/ios_chromium_strings.h"
+#include "ios/chrome/grit/ios_strings.h"
+#include "ui/base/l10n/l10n_util.h"
+
+namespace {
+
+struct PromoStringToIdsMapEntry {
+ const char* promo_text_str;
+ int message_id;
+};
+
+// A mapping from a string to a l10n message id.
+const PromoStringToIdsMapEntry kPromoStringToIdsMap[] = {
+ {"IDS_IOS_APP_RATING_PROMO_STRING", IDS_IOS_APP_RATING_PROMO_STRING},
+ {"IDS_IOS_MOVE_TO_DOCK_FASTER_ACCESS", IDS_IOS_MOVE_TO_DOCK_FASTER_ACCESS},
+ {"IDS_IOS_MOVE_TO_DOCK_LOVE_CHROME", IDS_IOS_MOVE_TO_DOCK_LOVE_CHROME},
+ {"IDS_IOS_MOVE_TO_DOCK_TIP", IDS_IOS_MOVE_TO_DOCK_TIP},
+};
+
+// Returns a localized version of |promo_text| if it has an entry in the
+// |kPromoStringToIdsMap|. If there is no entry, |promo_text| is returned.
+std::string GetLocalizedPromoText(const std::string& promo_text) {
+ for (size_t i = 0; i < arraysize(kPromoStringToIdsMap); ++i) {
+ if (kPromoStringToIdsMap[i].promo_text_str == promo_text)
+ return l10n_util::GetStringUTF8(kPromoStringToIdsMap[i].message_id);
+ }
+ return promo_text;
+}
+
+} // namespace
+
+NotificationPromoWhatsNew::NotificationPromoWhatsNew(PrefService* local_state)
+ : local_state_(local_state),
+ valid_(false),
+ notification_promo_(local_state_) {}
+
+NotificationPromoWhatsNew::~NotificationPromoWhatsNew() {}
+
+bool NotificationPromoWhatsNew::Init() {
+ notification_promo_.InitFromVariations();
+
+ // Force enable a particular promo if experimental flag is set.
+ experimental_flags::WhatsNewPromoStatus forceEnabled =
+ experimental_flags::GetWhatsNewPromoStatus();
+ if (forceEnabled != experimental_flags::WHATS_NEW_DEFAULT) {
+ switch (forceEnabled) {
+ case experimental_flags::WHATS_NEW_APP_RATING:
+ InjectFakePromo("1", "IDS_IOS_APP_RATING_PROMO_STRING",
+ "chrome_command", "ratethisapp", "", "RateThisAppPromo",
+ "logo");
+ break;
+ case experimental_flags::WHATS_NEW_MOVE_TO_DOCK_FASTER:
+ InjectFakePromo("2", "IDS_IOS_MOVE_TO_DOCK_FASTER_ACCESS", "url", "",
+ "https://support.google.com/chrome/?p=iphone_dock",
+ "MoveToDockFasterAccessPromo",
+ "logoWithRoundedRectangle");
+ break;
+ case experimental_flags::WHATS_NEW_MOVE_TO_DOCK_LOVE:
+ InjectFakePromo("3", "IDS_IOS_MOVE_TO_DOCK_LOVE_CHROME", "url", "",
+ "https://support.google.com/chrome/?p=iphone_dock",
+ "MoveToDockLovePromo", "logoWithRoundedRectangle");
+ break;
+ case experimental_flags::WHATS_NEW_MOVE_TO_DOCK_TIP:
+ InjectFakePromo("4", "IDS_IOS_MOVE_TO_DOCK_TIP", "url", "",
+ "https://support.google.com/chrome/?p=iphone_dock",
+ "MoveToDockTipPromo", "logoWithRoundedRectangle");
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+ }
+
+ notification_promo_.InitFromPrefs(
+ ios::NotificationPromo::MOBILE_NTP_WHATS_NEW_PROMO);
+ return InitFromNotificationPromo();
+}
+
+bool NotificationPromoWhatsNew::ClearAndInitFromJson(
+ const base::DictionaryValue& json) {
+ // This clears away old promos.
+ notification_promo_.MigrateUserPrefs(local_state_);
+
+ notification_promo_.InitFromJson(
+ json, ios::NotificationPromo::MOBILE_NTP_WHATS_NEW_PROMO);
+ return InitFromNotificationPromo();
+}
+
+bool NotificationPromoWhatsNew::CanShow() const {
+ if (!valid_ || !notification_promo_.CanShow()) {
+ return false;
+ }
+
+ // Check optional restrictions.
+
+ if (seconds_since_install_ > 0) {
+ // Do not show the promo if the app's installation did not occur more than
+ // |seconds_since_install_| seconds ago.
+ int64_t install_date = local_state_->GetInt64(metrics::prefs::kInstallDate);
+ const base::Time first_view_time =
+ base::Time::FromTimeT(install_date) +
+ base::TimeDelta::FromSeconds(seconds_since_install_);
+ if (first_view_time > base::Time::Now()) {
+ return false;
+ }
+ }
+
+ if (max_seconds_since_install_ > 0) {
+ // Do not show the promo if the app's installation occurred more than
+ // |max_seconds_since_install_| seconds ago.
+ int64_t install_date = local_state_->GetInt64(metrics::prefs::kInstallDate);
+ const base::Time last_view_time =
+ base::Time::FromTimeT(install_date) +
+ base::TimeDelta::FromSeconds(max_seconds_since_install_);
+ if (last_view_time < base::Time::Now()) {
+ return false;
+ }
+ }
+
+ if (promo_name_ == "WKWVGotFasterPromo") {
+ // Promo is not relevant anymore: It was shown during the migration to the
+ // WKWebview.
+ return false;
+ }
+
+ return true;
+}
+
+void NotificationPromoWhatsNew::HandleViewed() {
+ // TODO(justincohen): metrics actions names should be inlined. Since
+ // metric_name_ is retrieved from a server, it's not possible to know at build
+ // time the values. We should investigate to find a solution. In the meantime,
+ // metrics will be reported hashed.
+ // http://crbug.com/437500
+ std::string metric = std::string("WhatsNewPromoViewed_") + metric_name_;
+ base::RecordAction(base::UserMetricsAction(metric.c_str()));
+ base::RecordAction(base::UserMetricsAction("NTPPromoShown"));
+ notification_promo_.HandleViewed();
+}
+
+void NotificationPromoWhatsNew::HandleClosed() {
+ // TODO(justincohen): metrics actions names should be inlined. Since
+ // metric_name_ is retrieved from a server, it's not possible to know at build
+ // time the values. We should investigate to find a solution. In the meantime,
+ // metrics will be reported hashed.
+ // http://crbug.com/437500
+ std::string metric = std::string("WhatsNewPromoClosed_") + metric_name_;
+ base::RecordAction(base::UserMetricsAction(metric.c_str()));
+ base::RecordAction(base::UserMetricsAction("NTPPromoClosed"));
+ notification_promo_.HandleClosed();
+}
+
+bool NotificationPromoWhatsNew::IsURLPromo() const {
+ return promo_type_ == "url";
+}
+
+bool NotificationPromoWhatsNew::IsChromeCommand() const {
+ return promo_type_ == "chrome_command";
+}
+
+WhatsNewIcon NotificationPromoWhatsNew::ParseIconName(
+ const std::string& icon_name) {
+ if (icon_name == "logo") {
+ return WHATS_NEW_LOGO;
+ } else if (icon_name == "logoWithRoundedRectangle") {
+ return WHATS_NEW_LOGO_ROUNDED_RECTANGLE;
+ }
+ return WHATS_NEW_INFO;
+}
+
+bool NotificationPromoWhatsNew::InitFromNotificationPromo() {
+ valid_ = false;
+
+ notification_promo_.promo_payload()->GetString("promo_type", &promo_type_);
+ notification_promo_.promo_payload()->GetString("metric_name", &metric_name_);
+ promo_text_ = GetLocalizedPromoText(notification_promo_.promo_text());
+
+ if (IsURLPromo()) {
+ std::string url_text;
+ notification_promo_.promo_payload()->GetString("url", &url_text);
+ url_ = GURL(url_text);
+ if (url_.is_empty() || !url_.is_valid()) {
+ valid_ = false;
+ return valid_;
+ }
+ }
+
+ if (IsChromeCommand()) {
+ std::string command;
+ notification_promo_.promo_payload()->GetString("command", &command);
+ if (command == "bookmark") {
+ command_id_ = IDC_SHOW_BOOKMARK_MANAGER;
+ } else if (command == "ratethisapp") {
+ command_id_ = IDC_RATE_THIS_APP;
+ } else {
+ valid_ = false;
+ return valid_;
+ }
+ }
+
+ valid_ =
+ !metric_name_.empty() && !promo_type_.empty() && !promo_text_.empty();
+
+ notification_promo_.promo_payload()->GetString("promo_name", &promo_name_);
+ std::string icon_name;
+ notification_promo_.promo_payload()->GetString("icon", &icon_name);
+ icon_ = ParseIconName(icon_name);
+
+ // Optional values don't need validation.
+ seconds_since_install_ = 0;
+ notification_promo_.promo_payload()->GetInteger("seconds_since_install",
+ &seconds_since_install_);
+ max_seconds_since_install_ = 0;
+ notification_promo_.promo_payload()->GetInteger("max_seconds_since_install",
+ &max_seconds_since_install_);
+ return valid_;
+}
+
+void NotificationPromoWhatsNew::InjectFakePromo(const std::string& promo_id,
+ const std::string& promo_text,
+ const std::string& promo_type,
+ const std::string& command,
+ const std::string& url,
+ const std::string& metric_name,
+ const std::string& icon) {
+ // Build vector to fill in json string with given parameters.
+ std::vector<std::string> replacements;
+ replacements.push_back(promo_text);
+ replacements.push_back(promo_type);
+ replacements.push_back(metric_name);
+ replacements.push_back(command);
+ replacements.push_back(url);
+ replacements.push_back(icon);
+ replacements.push_back(promo_id);
+
+ std::string promo_json =
+ "{"
+ " \"start\":\"1 Jan 1999 0:26:06 GMT\","
+ " \"end\":\"1 Jan 2199 0:26:06 GMT\","
+ " \"promo_text\":\"$1\","
+ " \"max_views\":20,"
+ " \"payload\":"
+ " {"
+ " \"promo_type\":\"$2\","
+ " \"metric_name\":\"$3\","
+ " \"command\":\"$4\","
+ " \"url\":\"$5\","
+ " \"icon\":\"$6\""
+ " },"
+ " \"max_seconds\":259200,"
+ " \"promo_id\":$7"
+ "}";
+ std::string promo_json_filled_in =
+ base::ReplaceStringPlaceholders(promo_json, replacements, NULL);
+
+ std::unique_ptr<base::Value> value(
+ base::JSONReader::Read(promo_json_filled_in));
+ base::DictionaryValue* dict = NULL;
+ if (value->GetAsDictionary(&dict)) {
+ notification_promo_.InitFromJson(
+ *dict, ios::NotificationPromo::MOBILE_NTP_WHATS_NEW_PROMO);
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698