Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / ios / chrome / browser / net / metrics_network_client.mm
blob45f041c9f79fef21e8c09ff1175326cdd9ceda7e
1 // Copyright 2013 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 #import "ios/chrome/browser/net/metrics_network_client.h"
7 #import "base/ios/weak_nsobject.h"
8 #include "base/logging.h"
9 #include "base/metrics/sparse_histogram.h"
10 #include "base/strings/sys_string_conversions.h"
11 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h"
12 #import "ios/chrome/browser/net/metrics_network_client_manager.h"
13 #include "ios/web/public/url_util.h"
14 #include "net/base/net_errors.h"
15 #include "net/http/http_response_headers.h"
16 #include "net/url_request/url_request.h"
18 @interface MetricsNetworkClient () {
19   BOOL _histogramUpdated;
20   // Pointer to the load time record for this request. This will be created
21   // and owned by |_manager|, and it will remain valid as long as |_manager| is.
22   PageLoadTimeRecord* _loadTimeRecord;
23   // Pointer to the creating manager, which is owned by a tab. All network
24   // requests for the tab are destroyed before the tab is, so this pointer
25   // will always be valid as long as the owning client is alive.
26   MetricsNetworkClientManager* _manager;
27   // A pointer to the request, kept so it can be referred to later.
28   scoped_refptr<net::HttpResponseHeaders> _nativeHeaders;
30 - (void)updateHistogram:(NSInteger)code;
31 @end
33 @implementation MetricsNetworkClient
35 - (void)updateHistogram:(NSInteger)code {
36   DCHECK(!_histogramUpdated) << "Histogram should not be updated twice.";
37   // The |error| must be in the |net::kErrorDomain|. All those errors are
38   // defined in |net/base/net_error_list.h|, must be negative values that
39   // fits in an |int|. See |net/base/net_errors.h| for more information.
40   DCHECK_LE(code, 0) << "Net error codes should be negative.";
41   DCHECK_GT(code, INT_MIN) << "Net error code should fit in an int.";
42   // On iOS, we cannot distinguish between main frames, images and other
43   // subresources. Consequently, all the codes are aggregated in
44   // |ErrorCodesForMainFrame3|.
45   // The other histograms (such as |ErrorCodesForHTTPSGoogleMainFrame2|,
46   // |ErrorCodesForImages| and |ErrorCodesForSubresources2|) are not filled.
47   UMA_HISTOGRAM_SPARSE_SLOWLY("Net.ErrorCodesForMainFrame3",
48                               static_cast<int>(-code));
49   _histogramUpdated = YES;
52 - (instancetype)initWithManager:(MetricsNetworkClientManager*)manager {
53   if ((self = [super init])) {
54     _manager = manager;
55   }
56   return self;
59 #pragma mark CRNNetworkClientProtocol methods
61 - (void)didCreateNativeRequest:(net::URLRequest*)nativeRequest {
62   [super didCreateNativeRequest:nativeRequest];
63   GURL url = web::GURLByRemovingRefFromGURL(nativeRequest->original_url());
64   _loadTimeRecord =
65       [_manager recordForPageLoad:url time:nativeRequest->creation_time()];
66   _nativeHeaders = nativeRequest->response_headers();
69 - (void)didFailWithNSErrorCode:(NSInteger)nsErrorCode
70                   netErrorCode:(int)netErrorCode {
71   [super didFailWithNSErrorCode:nsErrorCode netErrorCode:netErrorCode];
73   // Ignore NSURLErrorCancelled errors, which are sometimes created to
74   // silently abort loads.
76   if (nsErrorCode != NSURLErrorCancelled) {
77     [self updateHistogram:netErrorCode];
78   }
81 - (void)didFinishLoading {
82   [super didFinishLoading];
83   [self updateHistogram:net::OK];
84   if (!_nativeHeaders)
85     return;
87   if (!_loadTimeRecord)
88     return;
90   [_loadTimeRecord
91       setDataProxyUsed:data_reduction_proxy::HasDataReductionProxyViaHeader(
92                            _nativeHeaders.get(), NULL)];
95 @end