Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(108)

Side by Side Diff: components/quirks/quirks_client.cc

Issue 1528963002: Quirks Client for downloading and providing display profiles (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: A few small tweaks Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « components/quirks/quirks_client.h ('k') | components/quirks/quirks_export.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 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 #include "components/quirks/quirks_client.h"
6
7 #include "base/base64.h"
8 #include "base/files/file_util.h"
9 #include "base/json/json_reader.h"
10 #include "base/strings/stringprintf.h"
11 #include "base/task_runner_util.h"
12 #include "components/prefs/scoped_user_pref_update.h"
13 #include "components/quirks/quirks_manager.h"
14 #include "components/version_info/version_info.h"
15 #include "net/base/load_flags.h"
16 #include "net/http/http_status_code.h"
17 #include "net/url_request/url_fetcher.h"
18 #include "net/url_request/url_request_context_getter.h"
19
20 namespace quirks {
21
22 namespace {
23
24 const char kQuirksUrlFormat[] =
25 "https://qa-quirksserver-pa.sandbox.googleapis.com/v2/display/%s/clients"
26 "/chromeos/M%d";
27
28 const net::BackoffEntry::Policy kDefaultBackoffPolicy = {
29 1, // Initial errors before applying backoff
30 10000, // 10 seconds.
31 2, // Factor by which the waiting time will be multiplied.
32 0, // Random fuzzing percentage.
33 1000 * 3600 * 6, // Max wait between requests = 6 hours.
34 -1, // Don't discard entry.
35 true, // Use initial delay after first error.
36 };
37
38 bool WriteIccFile(const base::FilePath file_path, const std::string& data) {
39 int bytes_written = base::WriteFile(file_path, data.data(), data.length());
40 if (bytes_written == -1)
41 LOG(ERROR) << "Write failed: " << file_path.value() << ", err = " << errno;
42 else
43 VLOG(1) << bytes_written << "bytes written to: " << file_path.value();
44
45 return (bytes_written != -1);
46 }
47
48 } // namespace
49
50 ////////////////////////////////////////////////////////////////////////////////
51 // QuirksClient
52
53 QuirksClient::QuirksClient(int64_t product_id,
54 const RequestFinishedCallback& on_request_finished,
55 QuirksManager* manager)
56 : product_id_(product_id),
57 on_request_finished_(on_request_finished),
58 manager_(manager),
59 icc_path_(
60 manager->delegate()->GetDownloadDisplayProfileDirectory().Append(
61 IdToFileName(product_id))),
62 backoff_entry_(&kDefaultBackoffPolicy),
63 weak_ptr_factory_(this) {}
64
65 QuirksClient::~QuirksClient() {}
66
67 void QuirksClient::StartDownload() {
68 DCHECK(thread_checker_.CalledOnValidThread());
69
70 // URL of icc file on Quirks Server.
71 int major_version = atoi(version_info::GetVersionNumber().c_str());
72 std::string url = base::StringPrintf(
73 kQuirksUrlFormat, IdToHexString(product_id_).c_str(), major_version);
74
75 VLOG(2) << "Preparing to download\n " << url << "\nto file "
76 << icc_path_.value();
77
78 url += "?key=";
79 url += manager_->delegate()->GetApiKey();
80
81 url_fetcher_ = manager_->CreateURLFetcher(GURL(url), this);
82 url_fetcher_->SetRequestContext(manager_->url_context_getter());
83 url_fetcher_->SetLoadFlags(net::LOAD_BYPASS_CACHE | net::LOAD_DISABLE_CACHE |
84 net::LOAD_DO_NOT_SAVE_COOKIES |
85 net::LOAD_DO_NOT_SEND_COOKIES |
86 net::LOAD_DO_NOT_SEND_AUTH_DATA);
87 url_fetcher_->Start();
88 }
89
90 void QuirksClient::OnURLFetchComplete(const net::URLFetcher* source) {
91 DCHECK(thread_checker_.CalledOnValidThread());
92 DCHECK_EQ(url_fetcher_.get(), source);
93
94 const int HTTP_INTERNAL_SERVER_ERROR_LAST =
95 net::HTTP_INTERNAL_SERVER_ERROR + 99;
96 const net::URLRequestStatus status = source->GetStatus();
97 const int response_code = source->GetResponseCode();
98 const bool server_error = !status.is_success() ||
99 (response_code >= net::HTTP_INTERNAL_SERVER_ERROR &&
100 response_code <= HTTP_INTERNAL_SERVER_ERROR_LAST);
101
102 VLOG(2) << "QuirksClient::OnURLFetchComplete():"
103 << " status=" << status.status()
104 << ", response_code=" << response_code
105 << ", server_error=" << server_error;
106
107 if (response_code == net::HTTP_NOT_FOUND) {
108 VLOG(1) << IdToFileName(product_id_) << " not found on Quirks server.";
109 Shutdown(false);
110 return;
111 }
112
113 if (server_error) {
114 url_fetcher_.reset();
115 Retry();
116 return;
117 }
118
119 std::string response;
120 url_fetcher_->GetResponseAsString(&response);
121 VLOG(2) << "Quirks server response:\n" << response;
122
123 // Parse response data and write to file on file thread.
124 std::string data;
125 if (!ParseResult(response, &data)) {
126 Shutdown(false);
127 return;
128 }
129
130 base::PostTaskAndReplyWithResult(
131 manager_->blocking_pool(), FROM_HERE,
132 base::Bind(&WriteIccFile, icc_path_, data),
133 base::Bind(&QuirksClient::Shutdown, weak_ptr_factory_.GetWeakPtr()));
134 }
135
136 void QuirksClient::Shutdown(bool success) {
137 DCHECK(thread_checker_.CalledOnValidThread());
138 on_request_finished_.Run(success ? icc_path_ : base::FilePath(), true);
139 manager_->ClientFinished(this);
140 }
141
142 void QuirksClient::Retry() {
143 DCHECK(thread_checker_.CalledOnValidThread());
144 backoff_entry_.InformOfRequest(false);
145 const base::TimeDelta delay = backoff_entry_.GetTimeUntilRelease();
146
147 VLOG(1) << "Schedule next Quirks download attempt in " << delay.InSecondsF()
148 << " seconds (retry = " << backoff_entry_.failure_count() << ").";
149 request_scheduled_.Start(FROM_HERE, delay, this,
150 &QuirksClient::StartDownload);
151 }
152
153 bool QuirksClient::ParseResult(const std::string& result, std::string* data) {
154 std::string data64;
155 const base::DictionaryValue* dict;
156 scoped_ptr<base::Value> json = base::JSONReader::Read(result);
157 if (!json || !json->GetAsDictionary(&dict) ||
158 !dict->GetString("icc", &data64)) {
159 VLOG(1) << "Failed to parse JSON icc data";
160 return false;
161 }
162
163 if (!base::Base64Decode(data64, data)) {
164 VLOG(1) << "Failed to decode Base64 icc data";
165 return false;
166 }
167
168 return true;
169 }
170
171 } // namespace quirks
OLDNEW
« no previous file with comments | « components/quirks/quirks_client.h ('k') | components/quirks/quirks_export.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698