Home | History | Annotate | Download | only in network_time
      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 }
     78