aw: Add and use DrawGL kModeSync
[chromium-blink-merge.git] / components / search_provider_logos / google_logo_api.cc
blob9a855cbcef6ab63c6d7e6c4f40f45fe41b26e2b8
1 // Copyright 2014 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.
5 #include "components/search_provider_logos/google_logo_api.h"
7 #include "base/base64.h"
8 #include "base/json/json_reader.h"
9 #include "base/memory/ref_counted_memory.h"
10 #include "base/strings/string_util.h"
11 #include "base/values.h"
12 #include "net/base/url_util.h"
14 namespace search_provider_logos {
16 namespace {
17 const char kResponsePreamble[] = ")]}'";
20 GURL GoogleAppendFingerprintToLogoURL(const GURL& logo_url,
21 const std::string& fingerprint) {
22 return net::AppendQueryParameter(logo_url, "async", "es_dfp:" + fingerprint);
25 scoped_ptr<EncodedLogo> GoogleParseLogoResponse(
26 const scoped_ptr<std::string>& response,
27 base::Time response_time) {
28 // Google doodles are sent as JSON with a prefix. Example:
29 // )]}' {"update":{"logo":{
30 // "data": "/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/...",
31 // "mime_type": "image/png",
32 // "fingerprint": "db063e32",
33 // "target": "http://www.google.com.au/search?q=Wilbur+Christiansen",
34 // "alt": "Wilbur Christiansen's Birthday"
35 // "time_to_live": 1389304799
36 // }}}
38 // The response may start with )]}'. Ignore this.
39 base::StringPiece response_sp(*response);
40 if (response_sp.starts_with(kResponsePreamble))
41 response_sp.remove_prefix(strlen(kResponsePreamble));
43 scoped_ptr<base::Value> value(base::JSONReader::Read(response_sp));
44 if (!value.get())
45 return scoped_ptr<EncodedLogo>();
47 // The important data lives inside several nested dictionaries:
48 // {"update": {"logo": { "mime_type": ..., etc } } }
49 const base::DictionaryValue* outer_dict;
50 if (!value->GetAsDictionary(&outer_dict))
51 return scoped_ptr<EncodedLogo>();
52 const base::DictionaryValue* update_dict;
53 if (!outer_dict->GetDictionary("update", &update_dict))
54 return scoped_ptr<EncodedLogo>();
55 const base::DictionaryValue* logo_dict;
56 if (!update_dict->GetDictionary("logo", &logo_dict))
57 return scoped_ptr<EncodedLogo>();
59 scoped_ptr<EncodedLogo> logo(new EncodedLogo());
61 std::string encoded_image_base64;
62 if (logo_dict->GetString("data", &encoded_image_base64)) {
63 // Data is optional, since we may be revalidating a cached logo.
64 base::RefCountedString* encoded_image_string = new base::RefCountedString();
65 if (!base::Base64Decode(encoded_image_base64,
66 &encoded_image_string->data()))
67 return scoped_ptr<EncodedLogo>();
68 logo->encoded_image = encoded_image_string;
69 if (!logo_dict->GetString("mime_type", &logo->metadata.mime_type))
70 return scoped_ptr<EncodedLogo>();
73 // Don't check return values since these fields are optional.
74 logo_dict->GetString("target", &logo->metadata.on_click_url);
75 logo_dict->GetString("fingerprint", &logo->metadata.fingerprint);
76 logo_dict->GetString("alt", &logo->metadata.alt_text);
78 base::TimeDelta time_to_live;
79 int time_to_live_ms;
80 if (logo_dict->GetInteger("time_to_live", &time_to_live_ms)) {
81 time_to_live = base::TimeDelta::FromMilliseconds(
82 std::min(static_cast<int64>(time_to_live_ms), kMaxTimeToLiveMS));
83 logo->metadata.can_show_after_expiration = false;
84 } else {
85 time_to_live = base::TimeDelta::FromMilliseconds(kMaxTimeToLiveMS);
86 logo->metadata.can_show_after_expiration = true;
88 logo->metadata.expiration_time = response_time + time_to_live;
90 return logo.Pass();
93 } // namespace search_provider_logos