- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / network_time / navigation_time_helper.cc
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.
4
5 #include "chrome/browser/network_time/navigation_time_helper.h"
6
7 #include "chrome/browser/network_time/network_time_service.h"
8 #include "chrome/browser/network_time/network_time_service_factory.h"
9 #include "content/public/browser/navigation_entry.h"
10 #include "content/public/browser/notification_service.h"
11 #include "content/public/browser/notification_types.h"
12
13 DEFINE_WEB_CONTENTS_USER_DATA_KEY(NavigationTimeHelper);
14
15 NavigationTimeHelper::NavigationTimeHelper()
16     : web_contents_(NULL) {}
17
18 NavigationTimeHelper::NavigationTimeHelper(content::WebContents* web_contents)
19     : web_contents_(web_contents) {
20   registrar_.Add(this, content::NOTIFICATION_NAV_LIST_PRUNED,
21                  content::NotificationService::AllSources());
22 }
23
24 NavigationTimeHelper::~NavigationTimeHelper() {}
25
26 base::Time NavigationTimeHelper::GetNavigationTime(
27     const content::NavigationEntry* entry) {
28   const void* entry_key = entry;
29   base::Time local_time = entry->GetTimestamp();
30
31   NavigationTimeCache::iterator iter = time_cache_.find(entry_key);
32   if (iter == time_cache_.end() || iter->second.local_time != local_time) {
33     // Calculate navigation time for new entry or existing entry that has new
34     // navigation.
35     base::Time navigation_time = GetNetworkTime(local_time);
36
37     if (iter == time_cache_.end()) {
38       time_cache_.insert(std::make_pair(entry_key,
39                                         NavigationTimeInfo(local_time,
40                                                            navigation_time)));
41     } else {
42       iter->second = NavigationTimeInfo(local_time, navigation_time);
43     }
44
45     return navigation_time;
46   } else {
47     // Use the navigation time calculated before for unchanged entry.
48     return iter->second.network_time;
49   }
50 }
51
52 void NavigationTimeHelper::Observe(
53     int type,
54     const content::NotificationSource& source,
55     const content::NotificationDetails& details) {
56   DCHECK_EQ(type, content::NOTIFICATION_NAV_LIST_PRUNED);
57
58   // Drop pruned entries from cache.
59   const content::NavigationController& controller =
60       web_contents_->GetController();
61   NavigationTimeCache new_cache;
62   for (int i = 0; i < controller.GetEntryCount(); ++i) {
63     const void* entry_key = controller.GetEntryAtIndex(i);
64     NavigationTimeCache::const_iterator iter = time_cache_.find(entry_key);
65     if (iter != time_cache_.end()) {
66       new_cache.insert(std::make_pair(entry_key,  iter->second));
67     }
68   }
69   time_cache_.swap(new_cache);
70 }
71
72 base::Time NavigationTimeHelper::GetNetworkTime(base::Time local_time) {
73   Profile* profile =
74       Profile::FromBrowserContext(web_contents_->GetBrowserContext());
75   return NetworkTimeServiceFactory::GetForProfile(profile)->
76       GetNetworkTime(local_time);
77 }