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 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_WEB_RESOURCE_PROMO_RESOURCE_SERVICE_H_ 6 #define CHROME_BROWSER_WEB_RESOURCE_PROMO_RESOURCE_SERVICE_H_ 7 #pragma once 8 9 #include "chrome/browser/web_resource/web_resource_service.h" 10 11 namespace PromoResourceServiceUtil { 12 13 // Certain promotions should only be shown to certain classes of users. This 14 // function will change to reflect each kind of promotion. 15 bool CanShowPromo(Profile* profile); 16 17 } // namespace PromoResourceServiceUtil 18 19 class PrefService; 20 21 // 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 // been used to fetch "tips" to be displayed on the NTP, or to display 24 // promotional messages to certain groups of Chrome users. 25 // 26 // 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 // structure. (see http://crbug.com/70634 for details.) 29 class PromoResourceService 30 : public WebResourceService { 31 public: 32 static bool IsBuildTargeted(const std::string& channel, int builds_targeted); 33 34 static void RegisterPrefs(PrefService* local_state); 35 36 static void RegisterUserPrefs(PrefService* prefs); 37 38 explicit PromoResourceService(Profile* profile); 39 40 // Default server of dynamically loaded NTP HTML elements. 41 static const char* kDefaultPromoResourceServer; 42 43 private: 44 FRIEND_TEST_ALL_PREFIXES(PromoResourceServiceTest, UnpackLogoSignal); 45 FRIEND_TEST_ALL_PREFIXES(PromoResourceServiceTest, UnpackPromoSignal); 46 FRIEND_TEST_ALL_PREFIXES(PromoResourceServiceTest, UnpackWebStoreSignal); 47 48 // Identifies types of Chrome builds for promo targeting. 49 enum BuildType { 50 NO_BUILD = 0, 51 DEV_BUILD = 1, 52 BETA_BUILD = 1 << 1, 53 STABLE_BUILD = 1 << 2, 54 CANARY_BUILD = 1 << 3, 55 }; 56 57 virtual ~PromoResourceService(); 58 59 int GetPromoServiceVersion(); 60 61 // Gets the locale of the last promos fetched from the server. This is saved 62 // so we can fetch new data if the locale changes. 63 std::string GetPromoLocale(); 64 65 void Init(); 66 67 // Returns true if |builds_targeted| includes the release channel Chrome 68 // belongs to. For testing purposes, you can override the current channel 69 // with set_channel. 70 bool IsThisBuildTargeted(int builds_targeted); 71 72 // Schedule a notification that a web resource is either going to become 73 // available or be no longer valid. 74 void ScheduleNotification(double ms_start_time, double ms_end_time); 75 76 // Schedules the initial notification for when the web resource is going 77 // to become available or no longer valid. This performs a few additional 78 // checks than ScheduleNotification, namely it schedules updates immediately 79 // if the promo service or Chrome locale has changed. 80 void ScheduleNotificationOnInit(); 81 82 // Overrides the current Chrome release channel for testing purposes. set_channel(const char * channel)83 void set_channel(const char* channel) { channel_ = channel; } 84 85 virtual void Unpack(const DictionaryValue& parsed_json); 86 87 // Unpack the web resource as a custom promo signal. Expects a start and end 88 // signal, with the promo to be shown in the tooltip of the start signal 89 // field. Delivery will be in json in the form of: 90 // { 91 // "topic": { 92 // "answers": [ 93 // { 94 // "answer_id": "1067976", 95 // "name": "promo_start", 96 // "question": "1:24", 97 // "tooltip": 98 // "Click \u003ca href=http://www.google.com\u003ehere\u003c/a\u003e!", 99 // "inproduct": "10/8/09 12:00", 100 // "inproduct_target": null 101 // }, 102 // { 103 // "answer_id": "1067976", 104 // "name": "promo_end", 105 // "question": "", 106 // "tooltip": "", 107 // "inproduct": "10/8/11 12:00", 108 // "inproduct_target": null 109 // }, 110 // ... 111 // ] 112 // } 113 // } 114 // 115 // Because the promo signal data is piggybacked onto the tip server, the 116 // values don't exactly correspond with the field names: 117 // 118 // For "promo_start" or "promo_end", the date to start or stop showing the 119 // promotional line is given by the "inproduct" line. 120 // For "promo_start", the promotional line itself is given in the "tooltip" 121 // field. The "question" field gives the type of builds that should be shown 122 // this promo (see the BuildType enum in web_resource_service.cc) and the 123 // number of hours that each promo group should see it, separated by ":". 124 // For example, "7:24" would indicate that all builds should see the promo, 125 // and each group should see it for 24 hours. 126 // 127 void UnpackPromoSignal(const DictionaryValue& parsed_json); 128 129 // Unpack the promo resource as a custom logo signal. Expects a start and end 130 // signal. Delivery will be in json in the form of: 131 // { 132 // "topic": { 133 // "answers": [ 134 // { 135 // "answer_id": "107366", 136 // "name": "custom_logo_start", 137 // "question": "", 138 // "tooltip": "", 139 // "inproduct": "10/8/09 12:00", 140 // "inproduct_target": null 141 // }, 142 // { 143 // "answer_id": "107366", 144 // "name": "custom_logo_end", 145 // "question": "", 146 // "tooltip": "", 147 // "inproduct": "10/8/09 12:00", 148 // "inproduct_target": null 149 // }, 150 // ... 151 // ] 152 // } 153 // } 154 // 155 void UnpackLogoSignal(const DictionaryValue& parsed_json); 156 157 // Unpack the web store promo. Expects JSON delivery in the following format: 158 // { 159 // "topic": { 160 // "answers": [ 161 // { 162 // "answer_id": "1143011", 163 // "name": "webstore_promo:15", 164 // "question": "Browse thousands of apps and games for Chrome.", 165 // "inproduct_target": "Visit the Chrome Web Store", 166 // "inproduct": "https://chrome.google.com/webstore?hl=en", 167 // "tooltip": "No thanks, hide this" 168 // }, 169 // ... 170 // ] 171 // } 172 // } 173 // The properties are defined as follows: 174 // inproduct: the release channels targeted (bitwise or of BuildTypes) 175 // question: the promo header text 176 // inproduct_target: the promo button text 177 // inproduct: the promo button link 178 // tooltip: the text for the "hide this" link on the promo 179 // name: starts with "webstore_promo" to identify the signal. the second 180 // part contains the release channels targeted (bitwise or of 181 // BuildTypes) 182 // answer_id: the promo's id 183 void UnpackWebStoreSignal(const DictionaryValue& parsed_json); 184 185 // Gets mutable dictionary attached to user's preferences, so that we 186 // can write resource data back to user's pref file. 187 DictionaryValue* web_resource_cache_; 188 189 // Overrides the current Chrome release channel for testing purposes. 190 const char* channel_; 191 192 DISALLOW_COPY_AND_ASSIGN(PromoResourceService); 193 }; 194 195 #endif // CHROME_BROWSER_WEB_RESOURCE_PROMO_RESOURCE_SERVICE_H_ 196