1 // Copyright (c) 2012 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 // A library to manage RLZ information for access-points shared 6 // across different client applications. 7 // 8 // All functions return true on success and false on error. 9 // This implemenation is thread safe. 10 11 12 #ifndef RLZ_LIB_RLZ_LIB_H_ 13 #define RLZ_LIB_RLZ_LIB_H_ 14 15 #include <stdio.h> 16 #include <string> 17 18 #include "build/build_config.h" 19 20 #include "rlz/lib/rlz_enums.h" 21 22 #if defined(OS_WIN) 23 #define RLZ_LIB_API __cdecl 24 #else 25 #define RLZ_LIB_API 26 #endif 27 28 // Define one of 29 // + RLZ_NETWORK_IMPLEMENTATION_WIN_INET: Uses win inet to send financial pings. 30 // + RLZ_NETWORK_IMPLEMENTATION_CHROME_NET: Uses chrome's network stack to send 31 // financial pings. rlz_lib::SetURLRequestContext() must be called before 32 // any calls to SendFinancialPing(). 33 #if defined(RLZ_NETWORK_IMPLEMENTATION_WIN_INET) && \ 34 defined(RLZ_NETWORK_IMPLEMENTATION_CHROME_NET) 35 #error Exactly one of RLZ_NETWORK_IMPLEMENTATION_WIN_INET and \ 36 RLZ_NETWORK_IMPLEMENTATION_CHROME_NET should be defined. 37 #endif 38 #if !defined(RLZ_NETWORK_IMPLEMENTATION_WIN_INET) && \ 39 !defined(RLZ_NETWORK_IMPLEMENTATION_CHROME_NET) 40 #if defined(OS_WIN) 41 #define RLZ_NETWORK_IMPLEMENTATION_WIN_INET 42 #else 43 #define RLZ_NETWORK_IMPLEMENTATION_CHROME_NET 44 #endif 45 #endif 46 47 #if defined(RLZ_NETWORK_IMPLEMENTATION_CHROME_NET) 48 namespace net { 49 class URLRequestContextGetter; 50 } // namespace net 51 #endif 52 53 namespace rlz_lib { 54 55 class ScopedRlzValueStoreLock; 56 57 // The maximum length of an access points RLZ in bytes. 58 const size_t kMaxRlzLength = 64; 59 // The maximum length of an access points RLZ in bytes. 60 const size_t kMaxDccLength = 128; 61 // The maximum length of a CGI string in bytes. 62 const size_t kMaxCgiLength = 2048; 63 // The maximum length of a ping response we will parse in bytes. If the response 64 // is bigger, please break it up into separate calls. 65 const size_t kMaxPingResponseLength = 0x4000; // 16K 66 67 #if defined(RLZ_NETWORK_IMPLEMENTATION_CHROME_NET) 68 // Set the URLRequestContextGetter used by SendFinancialPing(). The IO message 69 // loop returned by this context will be used for the IO done by 70 // SendFinancialPing(). 71 bool RLZ_LIB_API SetURLRequestContext(net::URLRequestContextGetter* context); 72 #endif 73 74 // RLZ storage functions. 75 76 // Get all the events reported by this product as a CGI string to append to 77 // the daily ping. 78 // Access: HKCU read. 79 bool RLZ_LIB_API GetProductEventsAsCgi(Product product, char* unescaped_cgi, 80 size_t unescaped_cgi_size); 81 82 // Records an RLZ event. 83 // Some events can be product-independent (e.g: First search from home page), 84 // and some can be access point independent (e.g. Pack installed). However, 85 // product independent events must still include the product which cares about 86 // that information being reported. 87 // Access: HKCU write. 88 bool RLZ_LIB_API RecordProductEvent(Product product, AccessPoint point, 89 Event event_id); 90 91 // Clear an event reported by this product. This should be called after a 92 // successful ping to the RLZ server. 93 // Access: HKCU write. 94 bool RLZ_LIB_API ClearProductEvent(Product product, AccessPoint point, 95 Event event_id); 96 97 // Clear all reported events and recorded stateful events of this product. 98 // This should be called on complete uninstallation of the product. 99 // Access: HKCU write. 100 bool RLZ_LIB_API ClearAllProductEvents(Product product); 101 102 // Clears all product-specifc state from the RLZ registry. 103 // Should be called during product uninstallation. 104 // This removes outstanding product events, product financial ping times, 105 // the product RLS argument (if any), and any RLZ's for access points being 106 // uninstalled with the product. 107 // access_points is an array terminated with NO_ACCESS_POINT. 108 // IMPORTANT: These are the access_points the product is removing as part 109 // of the uninstallation, not necessarily all the access points passed to 110 // SendFinancialPing() and GetPingParams(). 111 // access_points can be NULL if no points are being uninstalled. 112 // No return value - this is best effort. Will assert in debug mode on 113 // failed attempts. 114 // Access: HKCU write. 115 void RLZ_LIB_API ClearProductState(Product product, 116 const AccessPoint* access_points); 117 118 // Get the RLZ value of the access point. If the access point is not Google, the 119 // RLZ will be the empty string and the function will return false. 120 // Access: HKCU read. 121 bool RLZ_LIB_API GetAccessPointRlz(AccessPoint point, char* rlz, 122 size_t rlz_size); 123 124 // Set the RLZ for the access-point. Fails and asserts if called when the access 125 // point is not set to Google. 126 // new_rlz should come from a server-response. Client applications should not 127 // create their own RLZ values. 128 // Access: HKCU write. 129 bool RLZ_LIB_API SetAccessPointRlz(AccessPoint point, const char* new_rlz); 130 131 // Financial Server pinging functions. 132 // These functions deal with pinging the RLZ financial server and parsing and 133 // acting upon the response. Clients should SendFinancialPing() to avoid needing 134 // these functions. However, these functions allow clients to split the various 135 // parts of the pinging process up as needed (to avoid firewalls, etc). 136 137 // Forms the HTTP request to send to the RLZ financial server. 138 // 139 // product : The product to ping for. 140 // access_points : The access points this product affects. Array must be 141 // terminated with NO_ACCESS_POINT. 142 // product_signature : The signature sent with daily pings (e.g. swg, ietb) 143 // product_brand : The brand of the pinging product, if any. 144 // product_id : The product-specific installation ID (can be NULL). 145 // product_lang : The language for the product (used to determine cohort). 146 // exclude_machine_id : Whether the Machine ID should be explicitly excluded 147 // based on the products privacy policy. 148 // request : The buffer where the function returns the HTTP request. 149 // request_buffer_size: The size of the request buffer in bytes. The buffer 150 // size (kMaxCgiLength+1) is guaranteed to be enough. 151 // 152 // Access: HKCU read. 153 bool RLZ_LIB_API FormFinancialPingRequest(Product product, 154 const AccessPoint* access_points, 155 const char* product_signature, 156 const char* product_brand, 157 const char* product_id, 158 const char* product_lang, 159 bool exclude_machine_id, 160 char* request, 161 size_t request_buffer_size); 162 163 // Pings the financial server and returns the HTTP response. This will fail 164 // if it is too early to ping the server since the last ping. 165 // 166 // If RLZ_NETWORK_IMPLEMENTATION_CHROME_NET is set, SetURLRequestContext() needs 167 // to be called before calling this function. 168 // 169 // product : The product to ping for. 170 // request : The HTTP request (for example, returned by 171 // FormFinancialPingRequest). 172 // response : The buffer in which the HTTP response is returned. 173 // response_buffer_size : The size of the response buffer in bytes. The buffer 174 // size (kMaxPingResponseLength+1) is enough for all 175 // legitimate server responses (any response that is 176 // bigger should be considered the same way as a general 177 // network problem). 178 // 179 // Access: HKCU read. 180 bool RLZ_LIB_API PingFinancialServer(Product product, 181 const char* request, 182 char* response, 183 size_t response_buffer_size); 184 185 // Checks if a ping response is valid - ie. it has a checksum line which 186 // is the CRC-32 checksum of the message uptil the checksum. If 187 // checksum_idx is not NULL, it will get the index of the checksum, i.e. - 188 // the effective end of the message. 189 // Access: No restrictions. 190 bool RLZ_LIB_API IsPingResponseValid(const char* response, 191 int* checksum_idx); 192 193 194 // Complex helpers built on top of other functions. 195 196 // Parses the responses from the financial server and updates product state 197 // and access point RLZ's in registry. Like ParsePingResponse(), but also 198 // updates the last ping time. 199 // Access: HKCU write. 200 bool RLZ_LIB_API ParseFinancialPingResponse(Product product, 201 const char* response); 202 203 // Send the ping with RLZs and events to the PSO server. 204 // This ping method should be called daily. (More frequent calls will fail). 205 // Also, if there are no events, the call will succeed only once a week. 206 // 207 // If RLZ_NETWORK_IMPLEMENTATION_CHROME_NET is set, SetURLRequestContext() needs 208 // to be called before calling this function. 209 // 210 // product : The product to ping for. 211 // access_points : The access points this product affects. Array must be 212 // terminated with NO_ACCESS_POINT. 213 // product_signature : The signature sent with daily pings (e.g. swg, ietb) 214 // product_brand : The brand of the pinging product, if any. 215 // product_id : The product-specific installation ID (can be NULL). 216 // product_lang : The language for the product (used to determine cohort). 217 // exclude_machine_id : Whether the Machine ID should be explicitly excluded 218 // based on the products privacy policy. 219 // 220 // Returns true on successful ping and response, false otherwise. 221 // Access: HKCU write. 222 bool RLZ_LIB_API SendFinancialPing(Product product, 223 const AccessPoint* access_points, 224 const char* product_signature, 225 const char* product_brand, 226 const char* product_id, 227 const char* product_lang, 228 bool exclude_machine_id); 229 230 // An alternate implementations of SendFinancialPing with the same behavior, 231 // except the caller can optionally choose to skip the timing check. 232 bool RLZ_LIB_API SendFinancialPing(Product product, 233 const AccessPoint* access_points, 234 const char* product_signature, 235 const char* product_brand, 236 const char* product_id, 237 const char* product_lang, 238 bool exclude_machine_id, 239 const bool skip_time_check); 240 241 // Parses RLZ related ping response information from the server. 242 // Updates stored RLZ values and clears stored events accordingly. 243 // Access: HKCU write. 244 bool RLZ_LIB_API ParsePingResponse(Product product, const char* response); 245 246 247 // Copies the events associated with the product and the RLZ's for each access 248 // point in access_points into cgi. This string can be directly appended 249 // to a ping (will need an & if not first paramter). 250 // access_points must be an array of AccessPoints terminated with 251 // NO_ACCESS_POINT. 252 // Access: HKCU read. 253 bool RLZ_LIB_API GetPingParams(Product product, 254 const AccessPoint* access_points, 255 char* unescaped_cgi, size_t unescaped_cgi_size); 256 257 #if defined(OS_WIN) 258 // OEM Deal confirmation storage functions. OEM Deals are windows-only. 259 260 // Makes the OEM Deal Confirmation code writable by all users on the machine. 261 // This should be called before calling SetMachineDealCode from a non-admin 262 // account. 263 // Access: HKLM write. 264 bool RLZ_LIB_API CreateMachineState(void); 265 266 // Set the OEM Deal Confirmation Code (DCC). This information is used for RLZ 267 // initalization. 268 // Access: HKLM write, or 269 // HKCU read if rlz_lib::CreateMachineState() has been sucessfully called. 270 bool RLZ_LIB_API SetMachineDealCode(const char* dcc); 271 272 // Get the DCC cgi argument string to append to a daily ping. 273 // Should be used only by OEM deal trackers. Applications should use the 274 // GetMachineDealCode method which has an AccessPoint paramter. 275 // Access: HKLM read. 276 bool RLZ_LIB_API GetMachineDealCodeAsCgi(char* cgi, size_t cgi_size); 277 278 // Get the DCC value stored in registry. 279 // Should be used only by OEM deal trackers. Applications should use the 280 // GetMachineDealCode method which has an AccessPoint paramter. 281 // Access: HKLM read. 282 bool RLZ_LIB_API GetMachineDealCode(char* dcc, size_t dcc_size); 283 284 // Parses a ping response, checks if it is valid and sets the machine DCC 285 // from the response. The ping must also contain the current DCC value in 286 // order to be considered valid. 287 // Access: HKLM write; 288 // HKCU write if CreateMachineState() has been successfully called. 289 bool RLZ_LIB_API SetMachineDealCodeFromPingResponse(const char* response); 290 291 #endif 292 293 // Segment RLZ persistence based on branding information. 294 // All information for a given product is persisted under keys with the either 295 // product's name or its access point's name. This assumes that only 296 // one instance of the product is installed on the machine, and that only one 297 // product brand is associated with it. 298 // 299 // In some cases, a given product may be using supplementary brands. The RLZ 300 // information must be kept separately for each of these brands. To achieve 301 // this segmentation, scope all RLZ library calls that deal with supplementary 302 // brands within the lifetime of an rlz_lib::ProductBranding instance. 303 // 304 // For example, to record events for a supplementary brand, do the following: 305 // 306 // { 307 // rlz_lib::SupplementaryBranding branding("AAAA"); 308 // // This call to RecordProductEvent is scoped to the AAAA brand. 309 // rlz_lib::RecordProductEvent(rlz_lib::DESKTOP, rlz_lib::GD_DESKBAND, 310 // rlz_lib::INSTALL); 311 // } 312 // 313 // // This call to RecordProductEvent is not scoped to any supplementary brand. 314 // rlz_lib::RecordProductEvent(rlz_lib::DESKTOP, rlz_lib::GD_DESKBAND, 315 // rlz_lib::INSTALL); 316 // 317 // In particular, this affects the recording of stateful events and the sending 318 // of financial pings. In the former case, a stateful event recorded while 319 // scoped to a supplementary brand will be recorded again when scoped to a 320 // different supplementary brand (or not scoped at all). In the latter case, 321 // the time skip check is specific to each supplementary brand. 322 class SupplementaryBranding { 323 public: 324 SupplementaryBranding(const char* brand); 325 ~SupplementaryBranding(); 326 327 static const std::string& GetBrand(); 328 329 private: 330 ScopedRlzValueStoreLock* lock_; 331 }; 332 333 } // namespace rlz_lib 334 335 #endif // RLZ_LIB_RLZ_LIB_H_ 336