diff options
author | pathorn@chromium.org <pathorn@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-16 18:25:29 +0000 |
---|---|---|
committer | pathorn@chromium.org <pathorn@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-16 18:25:29 +0000 |
commit | a3cd502bb5891548171a4bb17fe1ce351cd45ba7 (patch) | |
tree | 4a2b3ce80d07f2f248775f56cad8f6649fb66431 /chrome/browser/automation | |
parent | 4eb4799f5889c414331aca32a4f0595a36ab8765 (diff) | |
download | chromium_src-a3cd502bb5891548171a4bb17fe1ce351cd45ba7.zip chromium_src-a3cd502bb5891548171a4bb17fe1ce351cd45ba7.tar.gz chromium_src-a3cd502bb5891548171a4bb17fe1ce351cd45ba7.tar.bz2 |
Measure loading time of several tabs.
This is a new set of JSON automation calls which return the individual load times for each tab opened at startup.
BUG=44129
TEST=none
Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=49862
Review URL: http://codereview.chromium.org/2559001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@49981 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/automation')
4 files changed, 93 insertions, 5 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc index 2ed4d53..3dccaaa 100644 --- a/chrome/browser/automation/automation_provider.cc +++ b/chrome/browser/automation/automation_provider.cc @@ -2077,6 +2077,22 @@ void AutomationProvider::OmniboxAcceptInput(Browser* browser, browser->window()->GetLocationBar()->AcceptInput(); } +// Sample json input: { "command": "GetInitialLoadTimes" } +// Refer to InitialLoadObserver::GetTimingInformation() for sample output. +void AutomationProvider::GetInitialLoadTimes( + Browser*, + DictionaryValue*, + IPC::Message* reply_message) { + scoped_ptr<DictionaryValue> return_value( + initial_load_observer_->GetTimingInformation()); + + std::string json_return; + base::JSONWriter::Write(return_value.get(), false, &json_return); + AutomationMsg_SendJSONRequest::WriteReplyParams( + reply_message, json_return, true); + Send(reply_message); +} + // Sample json input: { "command": "GetPluginsInfo" } // Refer chrome/test/pyautolib/plugins_info.py for sample json output. void AutomationProvider::GetPluginsInfo(Browser* browser, @@ -2239,6 +2255,8 @@ void AutomationProvider::SendJSONRequest(int handle, handler_map["WaitForAllDownloadsToComplete"] = &AutomationProvider::WaitForDownloadsToComplete; + handler_map["GetInitialLoadTimes"] = &AutomationProvider::GetInitialLoadTimes; + if (error_string.empty()) { if (handler_map.find(std::string(command)) != handler_map.end()) { (this->*handler_map[command])(browser, dict_value, reply_message); diff --git a/chrome/browser/automation/automation_provider.h b/chrome/browser/automation/automation_provider.h index bd37a4b..b644dd4 100644 --- a/chrome/browser/automation/automation_provider.h +++ b/chrome/browser/automation/automation_provider.h @@ -50,6 +50,7 @@ class ExtensionTestResultNotificationObserver; class ExternalTabContainer; class LoginHandler; class MetricEventDurationObserver; +class InitialLoadObserver; class NavigationControllerRestoredObserver; struct AutocompleteMatchData; @@ -376,6 +377,15 @@ class AutomationProvider : public base::RefCounted<AutomationProvider>, DictionaryValue* args, IPC::Message* reply_message); + // Return load times of initial tabs. + // Uses the JSON interface for input/output. + // Only includes tabs from command line arguments or session restore. + // See declaration of InitialLoadObserver in automation_provider_observers.h + // for example response. + void GetInitialLoadTimes(Browser* browser, + DictionaryValue* args, + IPC::Message* reply_message); + // Get info about plugins. // Uses the JSON interface for input/output. void GetPluginsInfo(Browser* browser, @@ -770,7 +780,7 @@ class AutomationProvider : public base::RefCounted<AutomationProvider>, typedef std::map<int, ExtensionPortContainer*> PortContainerMap; scoped_ptr<IPC::ChannelProxy> channel_; - scoped_ptr<NotificationObserver> initial_load_observer_; + scoped_ptr<InitialLoadObserver> initial_load_observer_; scoped_ptr<NotificationObserver> new_tab_ui_load_observer_; scoped_ptr<NotificationObserver> find_in_page_observer_; scoped_ptr<NotificationObserver> dom_operation_observer_; diff --git a/chrome/browser/automation/automation_provider_observers.cc b/chrome/browser/automation/automation_provider_observers.cc index cdb5de8..8b09fe5 100644 --- a/chrome/browser/automation/automation_provider_observers.cc +++ b/chrome/browser/automation/automation_provider_observers.cc @@ -28,10 +28,31 @@ #include "chrome/browser/chromeos/login/authentication_notification_details.h" #endif +// Holds onto start and stop timestamps for a particular tab +class InitialLoadObserver::TabTime { + public: + explicit TabTime(base::TimeTicks started) + : load_start_time_(started) { + } + void set_stop_time(base::TimeTicks stopped) { + load_stop_time_ = stopped; + } + base::TimeTicks stop_time() const { + return load_stop_time_; + } + base::TimeTicks start_time() const { + return load_start_time_; + } + private: + base::TimeTicks load_start_time_; + base::TimeTicks load_stop_time_; +}; + InitialLoadObserver::InitialLoadObserver(size_t tab_count, AutomationProvider* automation) : automation_(automation), - outstanding_tab_count_(tab_count) { + outstanding_tab_count_(tab_count), + init_time_(base::TimeTicks::Now()) { if (outstanding_tab_count_ > 0) { registrar_.Add(this, NotificationType::LOAD_START, NotificationService::AllSources()); @@ -48,11 +69,16 @@ void InitialLoadObserver::Observe(NotificationType type, const NotificationDetails& details) { if (type == NotificationType::LOAD_START) { if (outstanding_tab_count_ > loading_tabs_.size()) - loading_tabs_.insert(source.map_key()); + loading_tabs_.insert(TabTimeMap::value_type( + source.map_key(), + TabTime(base::TimeTicks::Now()))); } else if (type == NotificationType::LOAD_STOP) { if (outstanding_tab_count_ > finished_tabs_.size()) { - if (loading_tabs_.find(source.map_key()) != loading_tabs_.end()) + TabTimeMap::iterator iter = loading_tabs_.find(source.map_key()); + if (iter != loading_tabs_.end()) { finished_tabs_.insert(source.map_key()); + iter->second.set_stop_time(base::TimeTicks::Now()); + } if (outstanding_tab_count_ == finished_tabs_.size()) ConditionMet(); } @@ -61,6 +87,28 @@ void InitialLoadObserver::Observe(NotificationType type, } } +DictionaryValue* InitialLoadObserver::GetTimingInformation() const { + ListValue* items = new ListValue; + for (TabTimeMap::const_iterator it = loading_tabs_.begin(); + it != loading_tabs_.end(); + ++it) { + DictionaryValue* item = new DictionaryValue; + base::TimeDelta delta_start = it->second.start_time() - init_time_; + + item->SetReal(L"load_start_ms", delta_start.InMillisecondsF()); + if (it->second.stop_time().is_null()) { + item->Set(L"load_stop_ms", Value::CreateNullValue()); + } else { + base::TimeDelta delta_stop = it->second.stop_time() - init_time_; + item->SetReal(L"load_stop_ms", delta_stop.InMillisecondsF()); + } + items->Append(item); + } + DictionaryValue* return_value = new DictionaryValue; + return_value->Set(L"tabs", items); + return return_value; +} + void InitialLoadObserver::ConditionMet() { registrar_.RemoveAll(); automation_->Send(new AutomationMsg_InitialLoadsComplete(0)); diff --git a/chrome/browser/automation/automation_provider_observers.h b/chrome/browser/automation/automation_provider_observers.h index 6481005..6bf6a26 100644 --- a/chrome/browser/automation/automation_provider_observers.h +++ b/chrome/browser/automation/automation_provider_observers.h @@ -36,7 +36,18 @@ class InitialLoadObserver : public NotificationObserver { const NotificationSource& source, const NotificationDetails& details); + // Caller owns the return value and is responsible for deleting it. + // Example return value: + // {'tabs': [{'start_time_ms': 1, 'stop_time_ms': 2.5}, + // {'start_time_ms': 0.5, 'stop_time_ms': 3}]} + // stop_time_ms values may be null if WaitForInitialLoads has not finished. + // Only includes entries for the |tab_count| tabs we are monitoring. + // There is no defined ordering of the return value. + DictionaryValue* GetTimingInformation() const; + private: + class TabTime; + typedef std::map<uintptr_t, TabTime> TabTimeMap; typedef std::set<uintptr_t> TabSet; void ConditionMet(); @@ -45,7 +56,8 @@ class InitialLoadObserver : public NotificationObserver { AutomationProvider* automation_; size_t outstanding_tab_count_; - TabSet loading_tabs_; + base::TimeTicks init_time_; + TabTimeMap loading_tabs_; TabSet finished_tabs_; DISALLOW_COPY_AND_ASSIGN(InitialLoadObserver); |