| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef CHROME_BROWSER_WEB_RESOURCE_PROMO_RESOURCE_SERVICE_H_ | 5 #ifndef CHROME_BROWSER_WEB_RESOURCE_PROMO_RESOURCE_SERVICE_H_ |
| 6 #define CHROME_BROWSER_WEB_RESOURCE_PROMO_RESOURCE_SERVICE_H_ | 6 #define CHROME_BROWSER_WEB_RESOURCE_PROMO_RESOURCE_SERVICE_H_ |
| 7 #pragma once | 7 #pragma once |
| 8 | 8 |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| 11 #include "chrome/browser/web_resource/promo_notification.h" |
| 11 #include "chrome/browser/web_resource/web_resource_service.h" | 12 #include "chrome/browser/web_resource/web_resource_service.h" |
| 12 #include "chrome/common/chrome_version_info.h" | 13 #include "chrome/common/chrome_version_info.h" |
| 13 | 14 |
| 14 namespace base { | 15 namespace base { |
| 15 class DictionaryValue; | 16 class DictionaryValue; |
| 16 } | 17 } |
| 17 | 18 |
| 18 class AppsPromoLogoFetcher; | 19 class AppsPromoLogoFetcher; |
| 19 class PrefService; | 20 class PrefService; |
| 20 class Profile; | 21 class Profile; |
| 21 // A PromoResourceService fetches data from a web resource server to be used to | 22 // A PromoResourceService fetches data from a web resource server to be used to |
| 22 // dynamically change the appearance of the New Tab Page. For example, it has | 23 // dynamically change the appearance of the New Tab Page. For example, it has |
| 23 // been used to fetch "tips" to be displayed on the NTP, or to display | 24 // been used to fetch "tips" to be displayed on the NTP, or to display |
| 24 // promotional messages to certain groups of Chrome users. | 25 // promotional messages to certain groups of Chrome users. |
| 25 // | 26 // |
| 26 // TODO(mirandac): Arrange for a server to be set up specifically for promo | 27 // TODO(mirandac): Arrange for a server to be set up specifically for promo |
| 27 // messages, which have until now been piggybacked onto the old tips server | 28 // messages, which have until now been piggybacked onto the old tips server |
| 28 // structure. (see http://crbug.com/70634 for details.) | 29 // structure. (see http://crbug.com/70634 for details.) |
| 29 class PromoResourceService | 30 class PromoResourceService |
| 30 : public WebResourceService { | 31 : public WebResourceService, |
| 32 public PromoNotification::Delegate { |
| 31 public: | 33 public: |
| 34 // Identifies types of Chrome builds for promo targeting. |
| 35 enum BuildType { |
| 36 NO_BUILD = 0, |
| 37 DEV_BUILD = 1, |
| 38 BETA_BUILD = 1 << 1, |
| 39 STABLE_BUILD = 1 << 2, |
| 40 CANARY_BUILD = 1 << 3, |
| 41 ALL_BUILDS = (1 << 4) - 1, |
| 42 }; |
| 43 |
| 32 // Checks for conditions to show promo: start/end times, channel, etc. | 44 // Checks for conditions to show promo: start/end times, channel, etc. |
| 33 static bool CanShowNotificationPromo(Profile* profile); | 45 static bool CanShowNotificationPromo(Profile* profile); |
| 34 | 46 |
| 35 static void RegisterPrefs(PrefService* local_state); | 47 static void RegisterPrefs(PrefService* local_state); |
| 36 | 48 |
| 37 static void RegisterUserPrefs(PrefService* prefs); | 49 static void RegisterUserPrefs(PrefService* prefs); |
| 38 | 50 |
| 39 explicit PromoResourceService(Profile* profile); | 51 explicit PromoResourceService(Profile* profile); |
| 40 | 52 |
| 53 static chrome::VersionInfo::Channel GetChannel(); |
| 54 static bool IsBuildTargeted(chrome::VersionInfo::Channel, int builds_allowed); |
| 55 |
| 41 // Default server of dynamically loaded NTP HTML elements. | 56 // Default server of dynamically loaded NTP HTML elements. |
| 42 static const char* kDefaultPromoResourceServer; | 57 static const char* kDefaultPromoResourceServer; |
| 43 | 58 |
| 44 private: | 59 private: |
| 45 FRIEND_TEST_ALL_PREFIXES(PromoResourceServiceTest, IsBuildTargeted); | 60 FRIEND_TEST_ALL_PREFIXES(PromoResourceServiceTest, IsBuildTargetedTest); |
| 46 FRIEND_TEST_ALL_PREFIXES(PromoResourceServiceTest, UnpackLogoSignal); | 61 FRIEND_TEST_ALL_PREFIXES(PromoResourceServiceTest, UnpackLogoSignal); |
| 47 FRIEND_TEST_ALL_PREFIXES(PromoResourceServiceTest, UnpackNotificationSignal); | |
| 48 FRIEND_TEST_ALL_PREFIXES(PromoResourceServiceTest, UnpackWebStoreSignal); | 62 FRIEND_TEST_ALL_PREFIXES(PromoResourceServiceTest, UnpackWebStoreSignal); |
| 49 FRIEND_TEST_ALL_PREFIXES( | 63 FRIEND_TEST_ALL_PREFIXES( |
| 50 PromoResourceServiceTest, UnpackPartialWebStoreSignal); | 64 PromoResourceServiceTest, UnpackPartialWebStoreSignal); |
| 51 FRIEND_TEST_ALL_PREFIXES( | 65 FRIEND_TEST_ALL_PREFIXES( |
| 52 PromoResourceServiceTest, UnpackWebStoreSignalHttpsLogo); | 66 PromoResourceServiceTest, UnpackWebStoreSignalHttpsLogo); |
| 53 FRIEND_TEST_ALL_PREFIXES( | 67 FRIEND_TEST_ALL_PREFIXES( |
| 54 PromoResourceServiceTest, UnpackWebStoreSignalHttpsLogoError); | 68 PromoResourceServiceTest, UnpackWebStoreSignalHttpsLogoError); |
| 55 FRIEND_TEST_ALL_PREFIXES( | 69 FRIEND_TEST_ALL_PREFIXES( |
| 56 PromoResourceServiceTest, UnpackWebStoreSignalHttpLogo); | 70 PromoResourceServiceTest, UnpackWebStoreSignalHttpLogo); |
| 57 | 71 |
| 58 // Identifies types of Chrome builds for promo targeting. | |
| 59 enum BuildType { | |
| 60 NO_BUILD = 0, | |
| 61 DEV_BUILD = 1, | |
| 62 BETA_BUILD = 1 << 1, | |
| 63 STABLE_BUILD = 1 << 2, | |
| 64 CANARY_BUILD = 1 << 3, | |
| 65 ALL_BUILDS = (1 << 4) - 1, | |
| 66 }; | |
| 67 | |
| 68 virtual ~PromoResourceService(); | 72 virtual ~PromoResourceService(); |
| 69 | 73 |
| 70 int GetPromoServiceVersion(); | 74 int GetPromoServiceVersion(); |
| 71 | 75 |
| 72 // Gets the locale of the last promos fetched from the server. This is saved | 76 // Gets the locale of the last promos fetched from the server. This is saved |
| 73 // so we can fetch new data if the locale changes. | 77 // so we can fetch new data if the locale changes. |
| 74 std::string GetPromoLocale(); | 78 std::string GetPromoLocale(); |
| 75 | 79 |
| 76 void Init(); | 80 void Init(); |
| 77 | 81 |
| 78 static bool IsBuildTargeted(chrome::VersionInfo::Channel channel, | |
| 79 int builds_targeted); | |
| 80 | |
| 81 // Returns true if |builds_targeted| includes the release channel Chrome | 82 // Returns true if |builds_targeted| includes the release channel Chrome |
| 82 // belongs to. For testing purposes, you can override the current channel | 83 // belongs to. For testing purposes, you can override the current channel |
| 83 // with set_channel. | 84 // with set_channel. |
| 84 bool IsThisBuildTargeted(int builds_targeted); | 85 bool IsBuildTargeted(int builds_targeted); |
| 85 | 86 |
| 86 // Schedule a notification that a web resource is either going to become | 87 // Schedule a notification that a web resource is either going to become |
| 87 // available or be no longer valid. | 88 // available or be no longer valid. |
| 88 void ScheduleNotification(double ms_start_time, double ms_end_time); | 89 void ScheduleNotification(double start, double end); |
| 89 | 90 |
| 90 // Schedules the initial notification for when the web resource is going | 91 // Schedules the initial notification for when the web resource is going |
| 91 // to become available or no longer valid. This performs a few additional | 92 // to become available or no longer valid. This performs a few additional |
| 92 // checks than ScheduleNotification, namely it schedules updates immediately | 93 // checks than ScheduleNotification, namely it schedules updates immediately |
| 93 // if the promo service or Chrome locale has changed. | 94 // if the promo service or Chrome locale has changed. |
| 94 void ScheduleNotificationOnInit(); | 95 void ScheduleNotificationOnInit(); |
| 95 | 96 |
| 96 // Overrides the current Chrome release channel for testing purposes. | 97 // Overrides the current Chrome release channel for testing purposes. |
| 97 void set_channel(chrome::VersionInfo::Channel channel) { channel_ = channel; } | 98 void set_channel(chrome::VersionInfo::Channel channel) { channel_ = channel; } |
| 98 | 99 |
| 99 virtual void Unpack(const base::DictionaryValue& parsed_json); | 100 // WebResourceService override. |
| 101 virtual void Unpack(const base::DictionaryValue& parsed_json) OVERRIDE; |
| 100 | 102 |
| 101 // Unpack the web resource as a custom promo signal. Expects a start and end | 103 // Unpack the web resource as a custom notification signal. Expects a start |
| 102 // signal, with the promo to be shown in the tooltip of the start signal | 104 // and end signal, with the promo to be shown in the tooltip of the start |
| 103 // field. Delivery will be in json in the form of: | 105 // signal field. Delivery will be in json in the form of: |
| 104 // { | 106 // { |
| 105 // "topic": { | 107 // "topic": { |
| 106 // "answers": [ | 108 // "answers": [ |
| 107 // { | 109 // { |
| 108 // "answer_id": "1067976", | 110 // "answer_id": "1067976", |
| 109 // "name": "promo_start", | 111 // "name": "promo_start", |
| 110 // "question": "1:24:10", | 112 // "question": "1:24:10:10", |
| 111 // "tooltip": | 113 // "tooltip": |
| 112 // "Click \u003ca href=http://www.google.com\u003ehere\u003c/a\u003e!", | 114 // "Click \u003ca href=http://www.google.com\u003ehere\u003c/a\u003e!", |
| 113 // "inproduct": "10/8/09 12:00", | 115 // "inproduct": "10/8/09 12:00", |
| 114 // "inproduct_target": null | 116 // "inproduct_target": null |
| 115 // }, | 117 // }, |
| 116 // { | 118 // { |
| 117 // "answer_id": "1067976", | 119 // "answer_id": "1067976", |
| 118 // "name": "promo_end", | 120 // "name": "promo_end", |
| 119 // "question": "", | 121 // "question": "", |
| 120 // "tooltip": "", | 122 // "tooltip": "", |
| 121 // "inproduct": "10/8/11 12:00", | 123 // "inproduct": "10/8/11 12:00", |
| 122 // "inproduct_target": null | 124 // "inproduct_target": null |
| 123 // }, | 125 // }, |
| 124 // ... | 126 // ... |
| 125 // ] | 127 // ] |
| 126 // } | 128 // } |
| 127 // } | 129 // } |
| 128 // | 130 // |
| 129 // Because the promo signal data is piggybacked onto the tip server, the | 131 // Because the promo signal data is piggybacked onto the tip server, the |
| 130 // values don't exactly correspond with the field names: | 132 // values don't exactly correspond with the field names: |
| 131 // | 133 // |
| 132 // For "promo_start" or "promo_end", the date to start or stop showing the | 134 // For "promo_start" or "promo_end", the date to start or stop showing the |
| 133 // promotional line is given by the "inproduct" line. | 135 // promotional line is given by the "inproduct" line. |
| 134 // For "promo_start", the promotional line itself is given in the "tooltip" | 136 // For "promo_start", the promotional line itself is given in the "tooltip" |
| 135 // field. The "question" field gives the type of builds that should be shown | 137 // field. The "question" field gives the type of builds that should be shown |
| 136 // this promo (see the BuildType enum in web_resource_service.cc), the | 138 // this promo (see the BuildType enum in web_resource_service.cc), the |
| 137 // number of hours that each promo group should see it, and the maximum promo | 139 // number of hours that each promo group should see it, and the maximum promo |
| 138 // group that should see it, separated by ":". | 140 // group that should see it, separated by ":". |
| 139 // For example, "7:24:5" would indicate that all groups with ids less than 5, | 141 // For example, "7:24:5:10" would indicate that all groups with ids less than |
| 140 // and with dev, beta and stable builds, should see the promo. The groups | 142 // 5, and with dev, beta and stable builds, should see the promo a maximum of |
| 141 // ramp up so 1 additional group sees the promo every 24 hours. | 143 // 10 times. The groups ramp up so 1 additional group sees the promo every |
| 144 // 24 hours. |
| 142 // | 145 // |
| 143 void UnpackNotificationSignal(const base::DictionaryValue& parsed_json); | 146 void UnpackNotificationSignal(const base::DictionaryValue& parsed_json); |
| 144 | 147 |
| 145 // Unpack the promo resource as a custom logo signal. Expects a start and end | 148 // Unpack the promo resource as a custom logo signal. Expects a start and end |
| 146 // signal. Delivery will be in json in the form of: | 149 // signal. Delivery will be in json in the form of: |
| 147 // { | 150 // { |
| 148 // "topic": { | 151 // "topic": { |
| 149 // "answers": [ | 152 // "answers": [ |
| 150 // { | 153 // { |
| 151 // "answer_id": "107366", | 154 // "answer_id": "107366", |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 // name: starts with "webstore_promo" to identify the signal. The second | 198 // name: starts with "webstore_promo" to identify the signal. The second |
| 196 // part contains the release channels targeted (bitwise or of | 199 // part contains the release channels targeted (bitwise or of |
| 197 // BuildTypes). The third part specifies what users should maximize | 200 // BuildTypes). The third part specifies what users should maximize |
| 198 // the apps section of the NTP when first loading the promo (bitwise | 201 // the apps section of the NTP when first loading the promo (bitwise |
| 199 // or of AppsPromo::UserGroup). The forth part is optional and | 202 // or of AppsPromo::UserGroup). The forth part is optional and |
| 200 // specifies the URL of the logo image. If left out, the default | 203 // specifies the URL of the logo image. If left out, the default |
| 201 // webstore logo will be used. The logo can be an HTTPS or DATA URL. | 204 // webstore logo will be used. The logo can be an HTTPS or DATA URL. |
| 202 // answer_id: the promo's id | 205 // answer_id: the promo's id |
| 203 void UnpackWebStoreSignal(const base::DictionaryValue& parsed_json); | 206 void UnpackWebStoreSignal(const base::DictionaryValue& parsed_json); |
| 204 | 207 |
| 205 // Parse the answers array element. | 208 // PromoNotification::Delegate override. |
| 206 void ParseNotification(base::DictionaryValue* a_dic, | 209 virtual void OnNewNotification(double start, double end) OVERRIDE; |
| 207 std::string* promo_start_string, | |
| 208 std::string* promo_end_string); | |
| 209 | |
| 210 // Set notification promo params from a question string, which is of the form | |
| 211 // <build_type>:<time_slice>:<max_group>. | |
| 212 void SetNotificationParams(base::DictionaryValue* a_dic); | |
| 213 | |
| 214 // Extract the notification promo text from the tooltip string. | |
| 215 void SetNotificationLine(base::DictionaryValue* a_dic); | |
| 216 | |
| 217 // Check if this notification promo is new based on start/end times, | |
| 218 // and trigger events accordingly. | |
| 219 void CheckForNewNotification(const std::string& promo_start_string, | |
| 220 const std::string& promo_end_string); | |
| 221 | |
| 222 // Calculate the notification promo times, taking into account our group, and | |
| 223 // the group time slice. | |
| 224 void ParseNewNotificationTimes(const std::string& promo_start_string, | |
| 225 const std::string& promo_end_string, | |
| 226 double* promo_start, | |
| 227 double* promo_end); | |
| 228 | |
| 229 // Calculates notification promo start time with group-based time slice | |
| 230 // offset. | |
| 231 static double GetNotificationStartTime(PrefService* prefs); | |
| 232 | |
| 233 // Create a new notification promo group. | |
| 234 int ResetNotificationGroup(); | |
| 235 | |
| 236 // Get saved notification promo times. | |
| 237 void GetCurrentNotificationTimes(double* old_promo_start, | |
| 238 double* old_promo_end); | |
| 239 | |
| 240 // Actions on receiving a new notification promo. | |
| 241 void OnNewNotification(double promo_start, double promo_end); | |
| 242 | 210 |
| 243 // The profile this service belongs to. | 211 // The profile this service belongs to. |
| 244 Profile* profile_; | 212 Profile* profile_; |
| 245 | 213 |
| 246 // Overrides the current Chrome release channel for testing purposes. | 214 // Overrides the current Chrome release channel for testing purposes. |
| 247 chrome::VersionInfo::Channel channel_; | 215 chrome::VersionInfo::Channel channel_; |
| 248 | 216 |
| 249 // A helper that downloads the promo logo. | 217 // A helper that downloads the promo logo. |
| 250 scoped_ptr<AppsPromoLogoFetcher> apps_promo_logo_fetcher_; | 218 scoped_ptr<AppsPromoLogoFetcher> apps_promo_logo_fetcher_; |
| 251 | 219 |
| 252 DISALLOW_COPY_AND_ASSIGN(PromoResourceService); | 220 DISALLOW_COPY_AND_ASSIGN(PromoResourceService); |
| 253 }; | 221 }; |
| 254 | 222 |
| 255 #endif // CHROME_BROWSER_WEB_RESOURCE_PROMO_RESOURCE_SERVICE_H_ | 223 #endif // CHROME_BROWSER_WEB_RESOURCE_PROMO_RESOURCE_SERVICE_H_ |
| OLD | NEW |