Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / chromeos / certificate_provider / certificate_requests.cc
blobf24552a292c29e4a4473617fced9f300777491c1
1 // Copyright 2015 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 "chrome/browser/chromeos/certificate_provider/certificate_requests.h"
7 #include <set>
9 #include "base/bind.h"
10 #include "base/callback.h"
11 #include "base/location.h"
12 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/time/time.h"
15 #include "base/timer/timer.h"
17 namespace chromeos {
18 namespace certificate_provider {
20 namespace {
21 const int kGetCertificatesTimeoutInMinutes = 5;
22 } // namespace
24 // Holds state for a single certificate request.
25 struct CertificateRequests::CertificateRequestState {
26 CertificateRequestState() : timeout(false, false) {}
28 ~CertificateRequestState() {}
30 // Extensions that are too slow are eventually dropped from a request.
31 base::Timer timeout;
33 // Extensions that this request is still waiting for.
34 std::set<std::string> pending_extensions;
36 // For every extension that replied to this request, there is one entry from
37 // extension id to the reported certificates.
38 std::map<std::string, CertificateInfoList> extension_to_certificates;
40 // The callback that must be run with the final list of certificates.
41 base::Callback<void(const net::CertificateList&)> callback;
44 CertificateRequests::CertificateRequests() {}
46 CertificateRequests::~CertificateRequests() {}
48 int CertificateRequests::AddRequest(
49 const std::vector<std::string>& extension_ids,
50 const base::Callback<void(const net::CertificateList&)>& callback,
51 const base::Callback<void(int)>& timeout_callback) {
52 scoped_ptr<CertificateRequestState> state(new CertificateRequestState);
53 state->callback = callback;
54 state->pending_extensions.insert(extension_ids.begin(), extension_ids.end());
56 const int request_id = next_free_request_id_++;
57 state->timeout.Start(
58 FROM_HERE, base::TimeDelta::FromMinutes(kGetCertificatesTimeoutInMinutes),
59 base::Bind(timeout_callback, request_id));
61 const auto insert_result = requests_.insert(request_id, state.Pass());
62 DCHECK(insert_result.second) << "request id already in use.";
63 return request_id;
66 bool CertificateRequests::SetCertificates(
67 const std::string& extension_id,
68 int request_id,
69 const CertificateInfoList& certificate_infos,
70 bool* completed) {
71 *completed = false;
72 const auto it = requests_.find(request_id);
73 if (it == requests_.end())
74 return false;
76 CertificateRequestState& state = *it->second;
77 if (state.pending_extensions.erase(extension_id) == 0)
78 return false;
80 state.extension_to_certificates[extension_id] = certificate_infos;
81 *completed = state.pending_extensions.empty();
82 return true;
85 bool CertificateRequests::RemoveRequest(
86 int request_id,
87 std::map<std::string, CertificateInfoList>* certificates,
88 base::Callback<void(const net::CertificateList&)>* callback) {
89 const auto it = requests_.find(request_id);
90 if (it == requests_.end())
91 return false;
93 CertificateRequestState& state = *it->second;
94 *certificates = state.extension_to_certificates;
95 *callback = state.callback;
96 requests_.erase(it);
97 DVLOG(2) << "Completed certificate request " << request_id;
98 return true;
101 std::vector<int> CertificateRequests::DropExtension(
102 const std::string& extension_id) {
103 std::vector<int> completed_requests;
104 for (auto& entry : requests_) {
105 DVLOG(2) << "Remove extension " << extension_id
106 << " from certificate request " << entry.first;
108 CertificateRequestState& state = *entry.second;
109 state.pending_extensions.erase(extension_id);
110 if (state.pending_extensions.empty())
111 completed_requests.push_back(entry.first);
113 return completed_requests;
116 } // namespace certificate_provider
117 } // namespace chromeos