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