15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/web_resource/notification_promo.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cmath> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_registry_simple.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/rand_util.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/sys_info.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread_restrictions.h" 18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/browser_process.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/web_resource/promo_resource_service.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_version_info.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/pref_registry/pref_registry_syncable.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/user_metrics.h" 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/url_util.h" 27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/base/device_form_factor.h" 28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::UserMetricsAction; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kDefaultGroupSize = 100; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char promo_server_url[] = "https://clients3.google.com/crsignal/client"; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The name of the preference that stores the promotion object. 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPrefPromoObject[] = "promo"; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Keys in the kPrefPromoObject dictionary; used only here. 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPrefPromoText[] = "text"; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPrefPromoPayload[] = "payload"; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPrefPromoStart[] = "start"; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPrefPromoEnd[] = "end"; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPrefPromoNumGroups[] = "num_groups"; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPrefPromoSegment[] = "segment"; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPrefPromoIncrement[] = "increment"; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPrefPromoIncrementFrequency[] = "increment_frequency"; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPrefPromoIncrementMax[] = "increment_max"; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPrefPromoMaxViews[] = "max_views"; 525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kPrefPromoMaxSeconds[] = "max_seconds"; 535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kPrefPromoFirstViewTime[] = "first_view_time"; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPrefPromoGroup[] = "group"; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPrefPromoViews[] = "views"; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPrefPromoClosed[] = "closed"; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns a string suitable for the Promo Server URL 'osname' value. 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string PlatformString() { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "win"; 62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#elif defined(OS_ANDROID) 63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ui::DeviceFormFactor form_factor = ui::GetDeviceFormFactor(); 64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return std::string("android-") + 65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) (form_factor == ui::DEVICE_FORM_FACTOR_TABLET ? "tablet" : "phone"); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_IOS) 67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ui::DeviceFormFactor form_factor = ui::GetDeviceFormFactor(); 68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return std::string("ios-") + 69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) (form_factor == ui::DEVICE_FORM_FACTOR_TABLET ? "tablet" : "phone"); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "mac"; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_CHROMEOS) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "chromeos"; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_LINUX) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "linux"; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "none"; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns a string suitable for the Promo Server URL 'dist' value. 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* ChannelString() { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined (OS_WIN) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // GetChannel hits the registry on Windows. See http://crbug.com/70898. 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(achuith): Move NotificationPromo::PromoServerURL to the blocking pool. 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ThreadRestrictions::ScopedAllowIO allow_io; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const chrome::VersionInfo::Channel channel = 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::VersionInfo::GetChannel(); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (channel) { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case chrome::VersionInfo::CHANNEL_CANARY: 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "canary"; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case chrome::VersionInfo::CHANNEL_DEV: 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "dev"; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case chrome::VersionInfo::CHANNEL_BETA: 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "beta"; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case chrome::VersionInfo::CHANNEL_STABLE: 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "stable"; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "none"; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct PromoMapEntry { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotificationPromo::PromoType promo_type; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* promo_type_str; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const PromoMapEntry kPromoMap[] = { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { NotificationPromo::NO_PROMO, "" }, 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { NotificationPromo::NTP_NOTIFICATION_PROMO, "ntp_notification_promo" }, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { NotificationPromo::NTP_BUBBLE_PROMO, "ntp_bubble_promo" }, 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { NotificationPromo::MOBILE_NTP_SYNC_PROMO, "mobile_ntp_sync_promo" }, 114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch { NotificationPromo::MOBILE_NTP_WHATS_NEW_PROMO, 115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "mobile_ntp_whats_new_promo" }, 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Convert PromoType to appropriate string. 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* PromoTypeToString(NotificationPromo::PromoType promo_type) { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < arraysize(kPromoMap); ++i) { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (kPromoMap[i].promo_type == promo_type) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kPromoMap[i].promo_type_str; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ""; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Deep-copies a node, replacing any "value" that is a key 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// into "strings" dictionary with its value from "strings". 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// E.g. for 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// {promo_action_args:['MSG_SHORT']} + strings:{MSG_SHORT:'yes'} 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// it will return 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// {promo_action_args:['yes']} 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |node| - a value to be deep copied and resolved. 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |strings| - a dictionary of strings to be used for resolution. 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns a _new_ object that is a deep copy with replacements. 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(aruslan): http://crbug.com/144320 Consider moving it to values.cc/h. 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Value* DeepCopyAndResolveStrings( 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Value* node, 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::DictionaryValue* strings) { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (node->GetType()) { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case base::Value::TYPE_LIST: { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::ListValue* list = static_cast<const base::ListValue*>(node); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ListValue* copy = new base::ListValue; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (base::ListValue::const_iterator it = list->begin(); 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != list->end(); 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++it) { 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Value* child_copy = DeepCopyAndResolveStrings(*it, strings); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) copy->Append(child_copy); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return copy; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case base::Value::TYPE_DICTIONARY: { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::DictionaryValue* dict = 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<const base::DictionaryValue*>(node); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::DictionaryValue* copy = new base::DictionaryValue; 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (base::DictionaryValue::Iterator it(*dict); 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !it.IsAtEnd(); 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it.Advance()) { 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Value* child_copy = DeepCopyAndResolveStrings(&it.value(), 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) strings); 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) copy->SetWithoutPathExpansion(it.key(), child_copy); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return copy; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case base::Value::TYPE_STRING: { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string value; 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool rv = node->GetAsString(&value); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(rv); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string actual_value; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!strings || !strings->GetString(value, &actual_value)) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) actual_value = value; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new base::StringValue(actual_value); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For everything else, just make a copy. 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return node->DeepCopy(); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppendQueryParameter(GURL* url, 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& param, 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& value) { 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *url = net::AppendQueryParameter(*url, param, value); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)NotificationPromo::NotificationPromo() 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : prefs_(g_browser_process->local_state()), 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) promo_type_(NO_PROMO), 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) promo_payload_(new base::DictionaryValue()), 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_(0.0), 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end_(0.0), 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_groups_(kDefaultGroupSize), 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initial_segment_(0), 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) increment_(1), 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_slice_(0), 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_group_(0), 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_views_(0), 2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) max_seconds_(0), 2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) first_view_time_(0), 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) group_(0), 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views_(0), 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) closed_(false), 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_notification_(false) { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(prefs_); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NotificationPromo::~NotificationPromo() {} 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void NotificationPromo::InitFromJson(const base::DictionaryValue& json, 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PromoType promo_type) { 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) promo_type_ = promo_type; 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::ListValue* promo_list = NULL; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "InitFromJson " << PromoTypeToString(promo_type_); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!json.GetList(PromoTypeToString(promo_type_), &promo_list)) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No support for multiple promos yet. Only consider the first one. 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::DictionaryValue* promo = NULL; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!promo_list->GetDictionary(0, &promo)) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Date. 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::ListValue* date_list = NULL; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (promo->GetList("date", &date_list)) { 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::DictionaryValue* date; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (date_list->GetDictionary(0, &date)) { 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string time_str; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time time; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (date->GetString("start", &time_str) && 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time::FromString(time_str.c_str(), &time)) { 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_ = time.ToDoubleT(); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "start str=" << time_str 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ", start_="<< base::DoubleToString(start_); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (date->GetString("end", &time_str) && 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time::FromString(time_str.c_str(), &time)) { 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end_ = time.ToDoubleT(); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "end str =" << time_str 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ", end_=" << base::DoubleToString(end_); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Grouping. 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::DictionaryValue* grouping = NULL; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (promo->GetDictionary("grouping", &grouping)) { 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) grouping->GetInteger("buckets", &num_groups_); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) grouping->GetInteger("segment", &initial_segment_); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) grouping->GetInteger("increment", &increment_); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) grouping->GetInteger("increment_frequency", &time_slice_); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) grouping->GetInteger("increment_max", &max_group_); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "num_groups_ = " << num_groups_ 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ", initial_segment_ = " << initial_segment_ 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ", increment_ = " << increment_ 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ", time_slice_ = " << time_slice_ 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ", max_group_ = " << max_group_; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Strings. 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::DictionaryValue* strings = NULL; 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) promo->GetDictionary("strings", &strings); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Payload. 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::DictionaryValue* payload = NULL; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (promo->GetDictionary("payload", &payload)) { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Value* ppcopy = DeepCopyAndResolveStrings(payload, strings); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ppcopy && ppcopy->IsType(base::Value::TYPE_DICTIONARY)); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) promo_payload_.reset(static_cast<base::DictionaryValue*>(ppcopy)); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!promo_payload_->GetString("promo_message_short", &promo_text_) && 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strings) { 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For compatibility with the legacy desktop version, 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if no |payload.promo_message_short| is specified, 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the first string in |strings| is used. 2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue::Iterator iter(*strings); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter.value().GetAsString(&promo_text_); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "promo_text_=" << promo_text_; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) promo->GetInteger("max_views", &max_views_); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "max_views_ " << max_views_; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) promo->GetInteger("max_seconds", &max_seconds_); 2925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DVLOG(1) << "max_seconds_ " << max_seconds_; 2935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckForNewNotification(); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NotificationPromo::CheckForNewNotification() { 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NotificationPromo old_promo; 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old_promo.InitFromPrefs(promo_type_); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const double old_start = old_promo.start_; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const double old_end = old_promo.end_; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string old_promo_text = old_promo.promo_text_; 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_notification_ = 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old_start != start_ || old_end != end_ || old_promo_text != promo_text_; 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (new_notification_) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnNewNotification(); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NotificationPromo::OnNewNotification() { 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "OnNewNotification"; 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a new promo group. 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) group_ = base::RandInt(0, num_groups_ - 1); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WritePrefs(); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NotificationPromo::RegisterPrefs(PrefRegistrySimple* registry) { 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) registry->RegisterDictionaryPref(kPrefPromoObject); 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 3237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid NotificationPromo::RegisterProfilePrefs( 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) user_prefs::PrefRegistrySyncable* registry) { 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(dbeam): Registered only for migration. Remove in M28 when 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // we're reasonably sure all prefs are gone. 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // http://crbug.com/168887 328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) registry->RegisterDictionaryPref( 329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kPrefPromoObject, user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NotificationPromo::MigrateUserPrefs(PrefService* user_prefs) { 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) user_prefs->ClearPref(kPrefPromoObject); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NotificationPromo::WritePrefs() { 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::DictionaryValue* ntp_promo = new base::DictionaryValue; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ntp_promo->SetString(kPrefPromoText, promo_text_); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ntp_promo->Set(kPrefPromoPayload, promo_payload_->DeepCopy()); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ntp_promo->SetDouble(kPrefPromoStart, start_); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ntp_promo->SetDouble(kPrefPromoEnd, end_); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ntp_promo->SetInteger(kPrefPromoNumGroups, num_groups_); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ntp_promo->SetInteger(kPrefPromoSegment, initial_segment_); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ntp_promo->SetInteger(kPrefPromoIncrement, increment_); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ntp_promo->SetInteger(kPrefPromoIncrementFrequency, time_slice_); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ntp_promo->SetInteger(kPrefPromoIncrementMax, max_group_); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ntp_promo->SetInteger(kPrefPromoMaxViews, max_views_); 3515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ntp_promo->SetInteger(kPrefPromoMaxSeconds, max_seconds_); 3525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ntp_promo->SetDouble(kPrefPromoFirstViewTime, first_view_time_); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ntp_promo->SetInteger(kPrefPromoGroup, group_); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ntp_promo->SetInteger(kPrefPromoViews, views_); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ntp_promo->SetBoolean(kPrefPromoClosed, closed_); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ListValue* promo_list = new base::ListValue; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) promo_list->Set(0, ntp_promo); // Only support 1 promo for now. 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::DictionaryValue promo_dict; 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) promo_dict.MergeDictionary(prefs_->GetDictionary(kPrefPromoObject)); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) promo_dict.Set(PromoTypeToString(promo_type_), promo_list); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefs_->Set(kPrefPromoObject, promo_dict); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "WritePrefs " << promo_dict; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NotificationPromo::InitFromPrefs(PromoType promo_type) { 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) promo_type_ = promo_type; 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::DictionaryValue* promo_dict = 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefs_->GetDictionary(kPrefPromoObject); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!promo_dict) 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::ListValue* promo_list = NULL; 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) promo_dict->GetList(PromoTypeToString(promo_type_), &promo_list); 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!promo_list) 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::DictionaryValue* ntp_promo = NULL; 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) promo_list->GetDictionary(0, &ntp_promo); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ntp_promo) 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ntp_promo->GetString(kPrefPromoText, &promo_text_); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::DictionaryValue* promo_payload = NULL; 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ntp_promo->GetDictionary(kPrefPromoPayload, &promo_payload)) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) promo_payload_.reset(promo_payload->DeepCopy()); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ntp_promo->GetDouble(kPrefPromoStart, &start_); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ntp_promo->GetDouble(kPrefPromoEnd, &end_); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ntp_promo->GetInteger(kPrefPromoNumGroups, &num_groups_); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ntp_promo->GetInteger(kPrefPromoSegment, &initial_segment_); 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ntp_promo->GetInteger(kPrefPromoIncrement, &increment_); 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ntp_promo->GetInteger(kPrefPromoIncrementFrequency, &time_slice_); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ntp_promo->GetInteger(kPrefPromoIncrementMax, &max_group_); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ntp_promo->GetInteger(kPrefPromoMaxViews, &max_views_); 4005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ntp_promo->GetInteger(kPrefPromoMaxSeconds, &max_seconds_); 4015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ntp_promo->GetDouble(kPrefPromoFirstViewTime, &first_view_time_); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ntp_promo->GetInteger(kPrefPromoGroup, &group_); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ntp_promo->GetInteger(kPrefPromoViews, &views_); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ntp_promo->GetBoolean(kPrefPromoClosed, &closed_); 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool NotificationPromo::CheckAppLauncher() const { 4094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if !defined(ENABLE_APP_LIST) 410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#else 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_app_launcher_promo = false; 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!promo_payload_->GetBoolean("is_app_launcher_promo", 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &is_app_launcher_promo)) 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return !is_app_launcher_promo || 4174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) !prefs_->GetBoolean(prefs::kAppLauncherIsEnabled); 4184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif // !defined(ENABLE_APP_LIST) 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NotificationPromo::CanShow() const { 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !closed_ && 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !promo_text_.empty() && 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !ExceedsMaxGroup() && 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !ExceedsMaxViews() && 4265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) !ExceedsMaxSeconds() && 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckAppLauncher() && 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time::FromDoubleT(StartTimeForGroup()) < base::Time::Now() && 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Time::FromDoubleT(EndTime()) > base::Time::Now(); 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NotificationPromo::HandleClosed(PromoType promo_type) { 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RecordAction(UserMetricsAction("NTPPromoClosed")); 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NotificationPromo promo; 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) promo.InitFromPrefs(promo_type); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!promo.closed_) { 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) promo.closed_ = true; 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) promo.WritePrefs(); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool NotificationPromo::HandleViewed(PromoType promo_type) { 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RecordAction(UserMetricsAction("NTPPromoShown")); 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NotificationPromo promo; 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) promo.InitFromPrefs(promo_type); 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++promo.views_; 4495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (promo.first_view_time_ == 0) { 4505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) promo.first_view_time_ = base::Time::Now().ToDoubleT(); 4515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) promo.WritePrefs(); 4535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return promo.ExceedsMaxViews() || promo.ExceedsMaxSeconds(); 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NotificationPromo::ExceedsMaxGroup() const { 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (max_group_ == 0) ? false : group_ >= max_group_; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NotificationPromo::ExceedsMaxViews() const { 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (max_views_ == 0) ? false : views_ >= max_views_; 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool NotificationPromo::ExceedsMaxSeconds() const { 4655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (max_seconds_ == 0 || first_view_time_ == 0) 4665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 4675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const base::Time last_view_time = base::Time::FromDoubleT(first_view_time_) + 4695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::TimeDelta::FromSeconds(max_seconds_); 4705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return last_view_time < base::Time::Now(); 4715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 4725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GURL NotificationPromo::PromoServerURL() { 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url(promo_server_url); 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendQueryParameter(&url, "dist", ChannelString()); 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendQueryParameter(&url, "osname", PlatformString()); 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendQueryParameter(&url, "branding", chrome::VersionInfo().Version()); 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendQueryParameter(&url, "osver", base::SysInfo::OperatingSystemVersion()); 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "PromoServerURL=" << url.spec(); 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that locale param is added by WebResourceService. 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return url; 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)double NotificationPromo::StartTimeForGroup() const { 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (group_ < initial_segment_) 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return start_; 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return start_ + 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::ceil(static_cast<float>(group_ - initial_segment_ + 1) / increment_) 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * time_slice_; 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)double NotificationPromo::EndTime() const { 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return end_; 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 496