1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifndef CHROME_BROWSER_NET_LOAD_TIMING_OBSERVER_H_
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define CHROME_BROWSER_NET_LOAD_TIMING_OBSERVER_H_
73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/gtest_prod_util.h"
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/hash_tables.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/time.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/net/chrome_net_log.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_log.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/resource_loader_bridge.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
16201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochnamespace net {
173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass URLRequest;
18201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}  // namespace net
19201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstruct ResourceResponse;
213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// LoadTimingObserver watches the NetLog event stream and collects the network
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// timing information.
2421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen//
2521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// LoadTimingObserver lives completely on the IOThread and ignores events from
2621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// other threads.  It is not safe to use from other threads.
2721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenclass LoadTimingObserver : public ChromeNetLog::ThreadSafeObserver {
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  struct URLRequestRecord {
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    URLRequestRecord();
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
32731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    webkit_glue::ResourceLoadTimingInfo timing;
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    uint32 connect_job_id;
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    uint32 socket_log_id;
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool socket_reused;
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    base::TimeTicks base_ticks;
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  struct HTTPStreamJobRecord {
40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    HTTPStreamJobRecord();
41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    uint32 socket_log_id;
43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    bool socket_reused;
44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    base::TimeTicks connect_start;
45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    base::TimeTicks connect_end;
46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    base::TimeTicks dns_start;
47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    base::TimeTicks dns_end;
48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    base::TimeTicks ssl_start;
49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    base::TimeTicks ssl_end;
50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  struct ConnectJobRecord {
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    base::TimeTicks dns_start;
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    base::TimeTicks dns_end;
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  struct SocketRecord {
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    base::TimeTicks ssl_start;
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    base::TimeTicks ssl_end;
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LoadTimingObserver();
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ~LoadTimingObserver();
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  URLRequestRecord* GetURLRequestRecord(uint32 source_id);
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
6721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // ThreadSafeObserver implementation:
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void OnAddEntry(net::NetLog::EventType type,
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          const base::TimeTicks& time,
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          const net::NetLog::Source& source,
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          net::NetLog::EventPhase phase,
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          net::NetLog::EventParameters* params);
733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
74201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  static void PopulateTimingInfo(net::URLRequest* request,
753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                 ResourceResponse* response);
763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FRIEND_TEST_ALL_PREFIXES(LoadTimingObserverTest,
79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                           HTTPStreamJobRecord);
80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FRIEND_TEST_ALL_PREFIXES(LoadTimingObserverTest,
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           ConnectJobRecord);
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FRIEND_TEST_ALL_PREFIXES(LoadTimingObserverTest,
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           SocketRecord);
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void OnAddURLRequestEntry(net::NetLog::EventType type,
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            const base::TimeTicks& time,
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            const net::NetLog::Source& source,
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            net::NetLog::EventPhase phase,
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            net::NetLog::EventParameters* params);
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void OnAddHTTPStreamJobEntry(net::NetLog::EventType type,
92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                               const base::TimeTicks& time,
93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                               const net::NetLog::Source& source,
94ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                               net::NetLog::EventPhase phase,
95ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                               net::NetLog::EventParameters* params);
96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void OnAddConnectJobEntry(net::NetLog::EventType type,
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            const base::TimeTicks& time,
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            const net::NetLog::Source& source,
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            net::NetLog::EventPhase phase,
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            net::NetLog::EventParameters* params);
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void OnAddSocketEntry(net::NetLog::EventType type,
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        const base::TimeTicks& time,
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        const net::NetLog::Source& source,
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        net::NetLog::EventPhase phase,
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        net::NetLog::EventParameters* params);
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  URLRequestRecord* CreateURLRequestRecord(uint32 source_id);
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void DeleteURLRequestRecord(uint32 source_id);
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef base::hash_map<uint32, URLRequestRecord> URLRequestToRecordMap;
113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  typedef base::hash_map<uint32, HTTPStreamJobRecord> HTTPStreamJobToRecordMap;
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef base::hash_map<uint32, ConnectJobRecord> ConnectJobToRecordMap;
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef base::hash_map<uint32, SocketRecord> SocketToRecordMap;
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  URLRequestToRecordMap url_request_to_record_;
117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  HTTPStreamJobToRecordMap http_stream_job_to_record_;
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ConnectJobToRecordMap connect_job_to_record_;
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SocketToRecordMap socket_to_record_;
1203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  uint32 last_connect_job_id_;
1213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ConnectJobRecord last_connect_job_record_;
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(LoadTimingObserver);
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif  // CHROME_BROWSER_NET_LOAD_TIMING_OBSERVER_H_
127