Home | History | Annotate | Download | only in tab_contents
      1 // Copyright (c) 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.
      4 
      5 #include "chrome/browser/ui/tab_contents/core_tab_helper.h"
      6 
      7 #include "base/command_line.h"
      8 #include "base/metrics/histogram.h"
      9 #include "chrome/browser/renderer_host/web_cache_manager.h"
     10 #include "chrome/browser/ui/browser.h"
     11 #include "chrome/browser/ui/browser_command_controller.h"
     12 #include "chrome/browser/ui/browser_finder.h"
     13 #include "chrome/common/chrome_switches.h"
     14 #include "content/public/browser/render_process_host.h"
     15 #include "content/public/browser/render_view_host.h"
     16 #include "content/public/browser/web_contents.h"
     17 #include "net/base/load_states.h"
     18 #include "grit/generated_resources.h"
     19 #include "ui/base/l10n/l10n_util.h"
     20 
     21 using content::WebContents;
     22 
     23 DEFINE_WEB_CONTENTS_USER_DATA_KEY(CoreTabHelper);
     24 
     25 CoreTabHelper::CoreTabHelper(WebContents* web_contents)
     26     : content::WebContentsObserver(web_contents),
     27       delegate_(NULL),
     28       content_restrictions_(0) {
     29 }
     30 
     31 CoreTabHelper::~CoreTabHelper() {
     32 }
     33 
     34 string16 CoreTabHelper::GetDefaultTitle() {
     35   return l10n_util::GetStringUTF16(IDS_DEFAULT_TAB_TITLE);
     36 }
     37 
     38 string16 CoreTabHelper::GetStatusText() const {
     39   if (!web_contents()->IsLoading() ||
     40       web_contents()->GetLoadState().state == net::LOAD_STATE_IDLE) {
     41     return string16();
     42   }
     43 
     44   switch (web_contents()->GetLoadState().state) {
     45     case net::LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL:
     46     case net::LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET:
     47       return l10n_util::GetStringUTF16(IDS_LOAD_STATE_WAITING_FOR_SOCKET_SLOT);
     48     case net::LOAD_STATE_WAITING_FOR_DELEGATE:
     49       if (!web_contents()->GetLoadState().param.empty()) {
     50         return l10n_util::GetStringFUTF16(IDS_LOAD_STATE_WAITING_FOR_DELEGATE,
     51                                           web_contents()->GetLoadState().param);
     52       } else {
     53         return l10n_util::GetStringUTF16(
     54             IDS_LOAD_STATE_WAITING_FOR_DELEGATE_GENERIC);
     55       }
     56     case net::LOAD_STATE_WAITING_FOR_CACHE:
     57       return l10n_util::GetStringUTF16(IDS_LOAD_STATE_WAITING_FOR_CACHE);
     58     case net::LOAD_STATE_WAITING_FOR_APPCACHE:
     59       return l10n_util::GetStringUTF16(IDS_LOAD_STATE_WAITING_FOR_APPCACHE);
     60     case net::LOAD_STATE_ESTABLISHING_PROXY_TUNNEL:
     61       return
     62           l10n_util::GetStringUTF16(IDS_LOAD_STATE_ESTABLISHING_PROXY_TUNNEL);
     63     case net::LOAD_STATE_DOWNLOADING_PROXY_SCRIPT:
     64       return l10n_util::GetStringUTF16(IDS_LOAD_STATE_DOWNLOADING_PROXY_SCRIPT);
     65     case net::LOAD_STATE_RESOLVING_PROXY_FOR_URL:
     66       return l10n_util::GetStringUTF16(IDS_LOAD_STATE_RESOLVING_PROXY_FOR_URL);
     67     case net::LOAD_STATE_RESOLVING_HOST_IN_PROXY_SCRIPT:
     68       return l10n_util::GetStringUTF16(
     69           IDS_LOAD_STATE_RESOLVING_HOST_IN_PROXY_SCRIPT);
     70     case net::LOAD_STATE_RESOLVING_HOST:
     71       return l10n_util::GetStringUTF16(IDS_LOAD_STATE_RESOLVING_HOST);
     72     case net::LOAD_STATE_CONNECTING:
     73       return l10n_util::GetStringUTF16(IDS_LOAD_STATE_CONNECTING);
     74     case net::LOAD_STATE_SSL_HANDSHAKE:
     75       return l10n_util::GetStringUTF16(IDS_LOAD_STATE_SSL_HANDSHAKE);
     76     case net::LOAD_STATE_SENDING_REQUEST:
     77       if (web_contents()->GetUploadSize()) {
     78         return l10n_util::GetStringFUTF16Int(
     79             IDS_LOAD_STATE_SENDING_REQUEST_WITH_PROGRESS,
     80             static_cast<int>((100 * web_contents()->GetUploadPosition()) /
     81                 web_contents()->GetUploadSize()));
     82       } else {
     83         return l10n_util::GetStringUTF16(IDS_LOAD_STATE_SENDING_REQUEST);
     84       }
     85     case net::LOAD_STATE_WAITING_FOR_RESPONSE:
     86       return l10n_util::GetStringFUTF16(IDS_LOAD_STATE_WAITING_FOR_RESPONSE,
     87                                         web_contents()->GetLoadStateHost());
     88     // Ignore net::LOAD_STATE_READING_RESPONSE and net::LOAD_STATE_IDLE
     89     case net::LOAD_STATE_IDLE:
     90     case net::LOAD_STATE_READING_RESPONSE:
     91       break;
     92   }
     93 
     94   return string16();
     95 }
     96 
     97 void CoreTabHelper::OnCloseStarted() {
     98   if (close_start_time_.is_null())
     99     close_start_time_ = base::TimeTicks::Now();
    100 }
    101 
    102 void CoreTabHelper::OnCloseCanceled() {
    103   close_start_time_ = base::TimeTicks();
    104   before_unload_end_time_ = base::TimeTicks();
    105   unload_detached_start_time_ = base::TimeTicks();
    106 }
    107 
    108 void CoreTabHelper::OnUnloadStarted() {
    109   before_unload_end_time_ = base::TimeTicks::Now();
    110 }
    111 
    112 void CoreTabHelper::OnUnloadDetachedStarted() {
    113   if (unload_detached_start_time_.is_null())
    114     unload_detached_start_time_ = base::TimeTicks::Now();
    115 }
    116 
    117 void CoreTabHelper::UpdateContentRestrictions(int content_restrictions) {
    118   content_restrictions_ = content_restrictions;
    119 #if !defined(OS_ANDROID)
    120   Browser* browser = chrome::FindBrowserWithWebContents(web_contents());
    121   if (!browser)
    122     return;
    123 
    124   browser->command_controller()->ContentRestrictionsChanged();
    125 #endif
    126 }
    127 
    128 ////////////////////////////////////////////////////////////////////////////////
    129 // WebContentsObserver overrides
    130 
    131 void CoreTabHelper::DidStartLoading(content::RenderViewHost* render_view_host) {
    132   UpdateContentRestrictions(0);
    133 }
    134 
    135 void CoreTabHelper::WasShown() {
    136   WebCacheManager::GetInstance()->ObserveActivity(
    137       web_contents()->GetRenderProcessHost()->GetID());
    138 }
    139 
    140 void CoreTabHelper::WebContentsDestroyed(WebContents* web_contents) {
    141   // OnCloseStarted isn't called in unit tests.
    142   if (!close_start_time_.is_null()) {
    143     bool fast_tab_close_enabled = CommandLine::ForCurrentProcess()->HasSwitch(
    144         switches::kEnableFastUnload);
    145 
    146     if (fast_tab_close_enabled) {
    147       base::TimeTicks now = base::TimeTicks::Now();
    148       base::TimeDelta close_time = now - close_start_time_;
    149       UMA_HISTOGRAM_TIMES("Tab.Close", close_time);
    150 
    151       base::TimeTicks unload_start_time = close_start_time_;
    152       base::TimeTicks unload_end_time = now;
    153       if (!before_unload_end_time_.is_null())
    154         unload_start_time = before_unload_end_time_;
    155       if (!unload_detached_start_time_.is_null())
    156         unload_end_time = unload_detached_start_time_;
    157       base::TimeDelta unload_time = unload_end_time - unload_start_time;
    158       UMA_HISTOGRAM_TIMES("Tab.Close.UnloadTime", unload_time);
    159     } else {
    160       base::TimeTicks now = base::TimeTicks::Now();
    161       base::TimeTicks unload_start_time = close_start_time_;
    162       if (!before_unload_end_time_.is_null())
    163         unload_start_time = before_unload_end_time_;
    164       UMA_HISTOGRAM_TIMES("Tab.Close", now - close_start_time_);
    165       UMA_HISTOGRAM_TIMES("Tab.Close.UnloadTime", now - unload_start_time);
    166     }
    167   }
    168 
    169 }
    170 
    171 void CoreTabHelper::BeforeUnloadFired(const base::TimeTicks& proceed_time) {
    172   before_unload_end_time_ = proceed_time;
    173 }
    174 
    175 void CoreTabHelper::BeforeUnloadDialogCancelled() {
    176   OnCloseCanceled();
    177 }
    178