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) 48namespace net { 49class URLRequestContextGetter; 50} // namespace net 51#endif 52 53namespace rlz_lib { 54 55class ScopedRlzValueStoreLock; 56 57// The maximum length of an access points RLZ in bytes. 58const size_t kMaxRlzLength = 64; 59// The maximum length of an access points RLZ in bytes. 60const size_t kMaxDccLength = 128; 61// The maximum length of a CGI string in bytes. 62const 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. 65const 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(). 71bool 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. 79bool 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. 88bool 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. 94bool 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. 100bool 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. 115void 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. 121bool 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. 129bool 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. 153bool 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. 180bool 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. 190bool 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. 200bool 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. 222bool 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. 232bool 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. 244bool 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. 253bool 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. 264bool 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. 270bool 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. 276bool 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. 282bool 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. 289bool 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. 322class 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