| Index: net/cert/internal/trust_store_collection.cc | 
| diff --git a/net/cert/internal/trust_store_collection.cc b/net/cert/internal/trust_store_collection.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..d025f380603e135fc0cae8baa9d8f7b58b66cc52 | 
| --- /dev/null | 
| +++ b/net/cert/internal/trust_store_collection.cc | 
| @@ -0,0 +1,112 @@ | 
| +// Copyright 2016 The Chromium Authors. All rights reserved. | 
| +// Use of this source code is governed by a BSD-style license that can be | 
| +// found in the LICENSE file. | 
| + | 
| +#include "net/cert/internal/trust_store_collection.h" | 
| + | 
| +#include "base/bind.h" | 
| +#include "base/callback_helpers.h" | 
| +#include "net/cert/internal/parsed_certificate.h" | 
| + | 
| +namespace net { | 
| + | 
| +namespace { | 
| + | 
| +class CollectionRequest : public TrustStore::Request { | 
| + public: | 
| +  explicit CollectionRequest(const TrustStore::TrustCallback& callback); | 
| +  ~CollectionRequest() override; | 
| + | 
| +  void AddRequest(std::unique_ptr<TrustStore::Request> request); | 
| +  bool has_requests() const { return num_pending_requests_; } | 
| + | 
| +  void OnGotTrust(bool is_trusted); | 
| + | 
| + private: | 
| +  TrustStore::TrustCallback callback_; | 
| + | 
| +  size_t num_pending_requests_ = 0; | 
| +  std::vector<std::unique_ptr<TrustStore::Request>> requests_; | 
| + | 
| +  DISALLOW_COPY_AND_ASSIGN(CollectionRequest); | 
| +}; | 
| + | 
| +CollectionRequest::CollectionRequest(const TrustStore::TrustCallback& callback) | 
| +    : callback_(callback) {} | 
| + | 
| +CollectionRequest::~CollectionRequest() = default; | 
| + | 
| +void CollectionRequest::AddRequest( | 
| +    std::unique_ptr<TrustStore::Request> request) { | 
| +  requests_.push_back(std::move(request)); | 
| +  num_pending_requests_++; | 
| +} | 
| + | 
| +void CollectionRequest::OnGotTrust(bool is_trusted) { | 
| +  DCHECK_GT(num_pending_requests_, 0U); | 
| +  num_pending_requests_--; | 
| + | 
| +  if (is_trusted || num_pending_requests_ == 0U) { | 
| +    // Got a positive trust result, or all the requests completed without a | 
| +    // positive result.  Delete all the Request handles so that any remaining | 
| +    // sub-requests are cancelled. | 
| +    requests_.clear(); | 
| +    num_pending_requests_ = 0; | 
| +    // Run the callback last, since it may delete |this|. | 
| +    base::ResetAndReturn(&callback_).Run(is_trusted); | 
| +    // |this| may be deleted here. | 
| +  } | 
| +} | 
| + | 
| +}  // namespace | 
| + | 
| +TrustStoreCollection::TrustStoreCollection() = default; | 
| +TrustStoreCollection::~TrustStoreCollection() = default; | 
| + | 
| +void TrustStoreCollection::AddStore(TrustStore* store) { | 
| +  stores_.push_back(store); | 
| +  cert_sources_.AddSource(store); | 
| +} | 
| + | 
| +void TrustStoreCollection::IsTrustedCertificate( | 
| +    scoped_refptr<ParsedCertificate> cert, | 
| +    const TrustCallback& callback, | 
| +    bool* out_trusted, | 
| +    std::unique_ptr<TrustStore::Request>* out_req) const { | 
| +  std::unique_ptr<CollectionRequest> collection_req( | 
| +      new CollectionRequest(callback)); | 
| + | 
| +  *out_trusted = false; | 
| +  out_req->reset(); | 
| + | 
| +  for (TrustStore* store : stores_) { | 
| +    std::unique_ptr<TrustStore::Request> req; | 
| +    store->IsTrustedCertificate( | 
| +        cert, base::Bind(&CollectionRequest::OnGotTrust, | 
| +                         base::Unretained(collection_req.get())), | 
| +        out_trusted, &req); | 
| +    if (!req && *out_trusted) { | 
| +      // Got a synchronous trust result. Return immediately. | 
| +      return; | 
| +    } | 
| +    if (req) | 
| +      collection_req->AddRequest(std::move(req)); | 
| +  } | 
| + | 
| +  if (collection_req->has_requests()) | 
| +    *out_req = std::move(collection_req); | 
| +} | 
| + | 
| +void TrustStoreCollection::SyncGetIssuersOf(const ParsedCertificate* cert, | 
| +                                            ParsedCertificateList* issuers) { | 
| +  cert_sources_.SyncGetIssuersOf(std::move(cert), issuers); | 
| +} | 
| + | 
| +void TrustStoreCollection::AsyncGetIssuersOf( | 
| +    scoped_refptr<ParsedCertificate> cert, | 
| +    const IssuerCallback& callback, | 
| +    std::unique_ptr<CertIssuerSource::Request>* out_req) { | 
| +  cert_sources_.AsyncGetIssuersOf(std::move(cert), callback, out_req); | 
| +} | 
| + | 
| +}  // namespace net | 
|  |