Add ICU message format support
[chromium-blink-merge.git] / ios / net / request_tracker.mm
bloba4cfa5476e481550db23888c013e981630377bbd
1 // Copyright 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.
5 #include "ios/net/request_tracker.h"
7 #include "base/logging.h"
8 #import "ios/net/clients/crn_forwarding_network_client.h"
9 #import "ios/net/clients/crn_forwarding_network_client_factory.h"
11 namespace net {
13 namespace {
15 // Reference to the single instance of the RequestTrackerFactory.
16 RequestTracker::RequestTrackerFactory* g_request_tracker_factory = nullptr;
18 // Array of network client factories that should be added to any new request
19 // tracker.
20 class GlobalNetworkClientFactories {
21  public:
22   static GlobalNetworkClientFactories* GetInstance() {
23     if (!g_global_network_client_factories)
24       g_global_network_client_factories = new GlobalNetworkClientFactories;
25     return g_global_network_client_factories;
26   }
28   // Gets the factories.
29   NSArray* GetFactories() {
30     DCHECK(thread_checker_.CalledOnValidThread());
31     return factories_.get();
32   }
34   // Adds a factory.
35   void AddFactory(CRNForwardingNetworkClientFactory* factory) {
36     DCHECK(thread_checker_.CalledOnValidThread());
37     // TODO(justincohen): Cast indexOfObject to work around Xcode beta bugs.
38     // Revisit in future betas where hopefully these types match again.
39     // crbug.com/498825
40     DCHECK_EQ(NSNotFound,
41               static_cast<NSInteger>([factories_ indexOfObject:factory]));
42     DCHECK(!IsSelectorOverriden(factory, @selector(clientHandlingRequest:)));
43     DCHECK(!IsSelectorOverriden(factory,
44                                 @selector(clientHandlingResponse:request:)));
45     DCHECK(!IsSelectorOverriden(
46                factory, @selector(clientHandlingRedirect:url:response:)));
47     [factories_ addObject:factory];
48   }
50   // Returns true if |factory| re-implements |selector|.
51   // Only used for debugging.
52   bool IsSelectorOverriden(CRNForwardingNetworkClientFactory* factory,
53                            SEL selector) {
54     return
55         [factory methodForSelector:selector] !=
56         [CRNForwardingNetworkClientFactory instanceMethodForSelector:selector];
57   }
59  private:
60   GlobalNetworkClientFactories() : factories_([[NSMutableArray alloc] init]) {}
62   base::scoped_nsobject<NSMutableArray> factories_;
63   base::ThreadChecker thread_checker_;
65   static GlobalNetworkClientFactories* g_global_network_client_factories;
68 GlobalNetworkClientFactories*
69     GlobalNetworkClientFactories::g_global_network_client_factories = nullptr;
71 }  // namespace
73 RequestTracker::RequestTrackerFactory::~RequestTrackerFactory() {
76 // static
77 void RequestTracker::SetRequestTrackerFactory(RequestTrackerFactory* factory) {
78   g_request_tracker_factory = factory;
81 // static
82 bool RequestTracker::GetRequestTracker(NSURLRequest* request,
83                                        base::WeakPtr<RequestTracker>* tracker) {
84   DCHECK(request);
85   DCHECK(tracker);
86   DCHECK(!tracker->get());
87   if (!g_request_tracker_factory) {
88     return true;
89   }
90   return g_request_tracker_factory->GetRequestTracker(request, tracker);
93 void RequestTracker::AddNetworkClientFactory(
94     CRNForwardingNetworkClientFactory* factory) {
95   DCHECK(thread_checker_.CalledOnValidThread());
96   DCHECK([[factory clientClass]
97       isSubclassOfClass:[CRNForwardingNetworkClient class]]);
98   // Sanity check: We don't already have a factory of the type being added.
99   DCHECK([client_factories_ indexOfObjectPassingTest:^BOOL(id obj,
100                                                            NSUInteger idx,
101                                                            BOOL* stop) {
102       return [obj clientClass] == [factory clientClass];
103   }] == NSNotFound);
104   [client_factories_ addObject:factory];
105   if ([factory requiresOrdering]) {
106     [client_factories_ sortUsingSelector:@selector(orderRelativeTo:)];
107   }
110 // static
111 void RequestTracker::AddGlobalNetworkClientFactory(
112     CRNForwardingNetworkClientFactory* factory) {
113   GlobalNetworkClientFactories::GetInstance()->AddFactory(factory);
116 RequestTracker::RequestTracker()
117     : client_factories_([[NSMutableArray alloc] init]),
118       initialized_(false),
119       cache_mode_(CACHE_NORMAL),
120       weak_ptr_factory_(this) {
121   // RequestTracker can be created from the main thread and used from another
122   // thread.
123   thread_checker_.DetachFromThread();
126 RequestTracker::~RequestTracker() {
129 base::WeakPtr<RequestTracker> RequestTracker::GetWeakPtr() {
130   return weak_ptr_factory_.GetWeakPtr();
133 void RequestTracker::InvalidateWeakPtrs() {
134   weak_ptr_factory_.InvalidateWeakPtrs();
137 void RequestTracker::Init() {
138   DCHECK(thread_checker_.CalledOnValidThread());
139   DCHECK(!initialized_);
140   initialized_ = true;
141   for (CRNForwardingNetworkClientFactory* factory in
142            GlobalNetworkClientFactories::GetInstance()->GetFactories()) {
143     AddNetworkClientFactory(factory);
144   }
147 // static
148 NSArray* RequestTracker::GlobalClientsHandlingAnyRequest() {
149   NSMutableArray* applicable_clients = [NSMutableArray array];
150   for (CRNForwardingNetworkClientFactory* factory in
151            GlobalNetworkClientFactories::GetInstance()->GetFactories()) {
152     CRNForwardingNetworkClient* client = [factory clientHandlingAnyRequest];
153     if (client)
154       [applicable_clients addObject:client];
155   }
156   return applicable_clients;
159 NSArray* RequestTracker::ClientsHandlingAnyRequest() {
160   DCHECK(thread_checker_.CalledOnValidThread());
161   DCHECK(initialized_);
162   NSMutableArray* applicable_clients = [NSMutableArray array];
163   for (CRNForwardingNetworkClientFactory* factory in client_factories_.get()) {
164     CRNForwardingNetworkClient* client = [factory clientHandlingAnyRequest];
165     if (client)
166       [applicable_clients addObject:client];
167   }
168   return applicable_clients;
171 NSArray* RequestTracker::ClientsHandlingRequest(const URLRequest& request) {
172   DCHECK(thread_checker_.CalledOnValidThread());
173   DCHECK(initialized_);
174   NSMutableArray* applicable_clients = [NSMutableArray array];
175   for (CRNForwardingNetworkClientFactory* factory in client_factories_.get()) {
176     CRNForwardingNetworkClient* client =
177         [factory clientHandlingRequest:request];
178     if (client)
179       [applicable_clients addObject:client];
180   }
181   return applicable_clients;
184 NSArray* RequestTracker::ClientsHandlingRequestAndResponse(
185     const URLRequest& request,
186     NSURLResponse* response) {
187   DCHECK(thread_checker_.CalledOnValidThread());
188   DCHECK(initialized_);
189   NSMutableArray* applicable_clients = [NSMutableArray array];
190   for (CRNForwardingNetworkClientFactory* factory in client_factories_.get()) {
191     CRNForwardingNetworkClient* client =
192         [factory clientHandlingResponse:response request:request];
193     if (client)
194       [applicable_clients addObject:client];
195   }
196   return applicable_clients;
199 NSArray* RequestTracker::ClientsHandlingRedirect(
200     const URLRequest& request,
201     const GURL& new_url,
202     NSURLResponse* redirect_response) {
203   DCHECK(thread_checker_.CalledOnValidThread());
204   DCHECK(initialized_);
205   NSMutableArray* applicable_clients = [NSMutableArray array];
206   for (CRNForwardingNetworkClientFactory* factory in client_factories_.get()) {
207     CRNForwardingNetworkClient* client =
208         [factory clientHandlingRedirect:request
209                                     url:new_url
210                                response:redirect_response];
211     if (client)
212       [applicable_clients addObject:client];
213   }
214   return applicable_clients;
217 RequestTracker::CacheMode RequestTracker::GetCacheMode() const {
218   DCHECK(thread_checker_.CalledOnValidThread());
219   return cache_mode_;
222 void RequestTracker::SetCacheMode(RequestTracker::CacheMode mode) {
223   DCHECK(thread_checker_.CalledOnValidThread());
224   cache_mode_ = mode;
227 }  // namespace net