Home | History | Annotate | Download | only in lib
      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