summaryrefslogtreecommitdiffstats
path: root/chrome/browser/network_status_view.cc
diff options
context:
space:
mode:
authorinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 23:55:29 +0000
committerinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 23:55:29 +0000
commit09911bf300f1a419907a9412154760efd0b7abc3 (patch)
treef131325fb4e2ad12c6d3504ab75b16dd92facfed /chrome/browser/network_status_view.cc
parent586acc5fe142f498261f52c66862fa417c3d52d2 (diff)
downloadchromium_src-09911bf300f1a419907a9412154760efd0b7abc3.zip
chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.gz
chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.bz2
Add chrome to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/network_status_view.cc')
-rw-r--r--chrome/browser/network_status_view.cc509
1 files changed, 509 insertions, 0 deletions
diff --git a/chrome/browser/network_status_view.cc b/chrome/browser/network_status_view.cc
new file mode 100644
index 0000000..a05a01b
--- /dev/null
+++ b/chrome/browser/network_status_view.cc
@@ -0,0 +1,509 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <stdio.h>
+
+#include "chrome/browser/network_status_view.h"
+
+#include "base/string_util.h"
+#include "base/thread.h"
+#include "chrome/browser/browser.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/navigation_profiler.h"
+#include "chrome/browser/navigation_performance_viewer.h"
+#include "chrome/browser/page_load_tracker.h"
+#include "chrome/browser/tab_contents_delegate.h"
+#include "chrome/views/hwnd_view_container.h"
+#include "net/url_request/url_request.h"
+#include "net/url_request/url_request_job.h"
+
+namespace {
+const wchar_t kTitleMsg[] = L"Network Status";
+const wchar_t kStartTrackingMsg[] = L"Start I/O Tracking";
+const wchar_t kStopTrackingMsg[] = L"Stop I/O Tracking";
+
+const wchar_t kStartProfilingMsg[] = L"Start Profiling";
+const wchar_t kStopProfilingMsg[] = L"Stop Profiling";
+
+const wchar_t kShowIOStatusMsg[] = L"Show Current I/O Status";
+const wchar_t kShowPerformanceMsg[] = L"Show Performance";
+const wchar_t kRefreshPerformanceMsg[] = L"Refresh Performance";
+const wchar_t kClearOutputMsg[] = L"Clear Output";
+
+// Returns a string representing the URL, handling the case where the spec
+// is invalid.
+std::wstring StringForURL(const GURL& url) {
+ if (url.is_valid())
+ return UTF8ToWide(url.spec());
+ return UTF8ToWide(url.possibly_invalid_spec()) + L" (invalid)";
+}
+
+std::wstring URLForJob(URLRequestJob* job) {
+ URLRequest* request = job->request();
+ if (request)
+ return StringForURL(request->url());
+ return std::wstring(L"(orphaned)");
+}
+
+} // namespace
+
+NetworkStatusView::NetworkStatusView()
+ : StatusView(TAB_CONTENTS_NETWORK_STATUS_VIEW) {
+ tracker_ = new JobTracker(this);
+}
+
+NetworkStatusView::~NetworkStatusView() {
+ if (monospaced_font_)
+ DeleteObject(monospaced_font_);
+
+ if (is_tracking_) {
+ tracker_->StopTracking();
+ is_tracking_ = false;
+ }
+
+ if (is_profiling_) {
+ g_navigation_profiler.StopProfiling(profiling_session_id_);
+ is_profiling_ = false;
+ }
+
+ tracker_->DetachView();
+}
+
+const std::wstring NetworkStatusView::GetDefaultTitle() {
+ return kTitleMsg;
+}
+
+void NetworkStatusView::OnCreate(const CRect& rect) {
+ CreateButton(IDC_CONFIG_TRACKING_BUTTON, kStartTrackingMsg);
+ CreateButton(IDC_CURRENT_STATUS_BUTTON, kShowIOStatusMsg);
+ CreateButton(IDC_CONFIG_PROFILING_BUTTON, kStartProfilingMsg);
+ CreateButton(IDC_SHOW_PERFORMANCE_BUTTON, kShowPerformanceMsg);
+ CreateButton(IDC_CLEAR, kClearOutputMsg);
+
+ is_tracking_ = false;
+ is_profiling_ = false;
+
+ // Initialize the text box for network tracking
+ // Don't worry about the size, we'll resize when we get WM_SIZE
+ text_area_.Create(m_hWnd, const_cast<CRect&>(rect), NULL,
+ WS_CHILD | WS_HSCROLL | WS_VSCROLL |
+ ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
+
+ // This raises the maximum number of chars from 32K to some large maximum,
+ // probably 2GB. 32K is not nearly enough for our use-case.
+ text_area_.SendMessageW(EM_SETLIMITTEXT, 0, 0);
+
+ // make a monospaced font for the edit control
+ LOGFONT lf = {0};
+ lf.lfHeight = 16;
+ wcscpy_s(lf.lfFaceName, LF_FACESIZE, L"Courier New");
+ monospaced_font_ = CreateFontIndirect(&lf);
+ text_area_.SetFont(monospaced_font_);
+
+ HideTrackingResults();
+
+ // Initialize the view for performance profiling
+ // Don't worry about the size, we'll resize when we get WM_SIZE
+
+ // List of loaded pages
+ page_list_.Create(m_hWnd, const_cast<CRect&>(rect), NULL,
+ WS_CHILD | WS_HSCROLL | WS_VSCROLL | LBS_STANDARD, 0,
+ IDC_PAGE_LISTBOX);
+
+ // Textual report of page loading
+ page_text_.Create(m_hWnd, const_cast<CRect&>(rect), NULL,
+ WS_CHILD | WS_HSCROLL | WS_VSCROLL |
+ ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
+ page_text_.SetFont(monospaced_font_);
+ // Raise the maximum number of chars from 32K to some large maximum.
+ page_text_.SendMessageW(EM_SETLIMITTEXT, 0, 0);
+
+ // Graphical report of page loading
+ page_load_view_ = new PageLoadView();
+ page_view_container_ = new ChromeViews::HWNDViewContainer;
+ page_view_container_->Init(m_hWnd, gfx::Rect(rect), page_load_view_, false);
+
+ HideProfilingResults();
+}
+
+void NetworkStatusView::OnSize(const CRect& rect) {
+ // re-layout the edit control
+ text_area_.MoveWindow(rect);
+
+ // re-layout the performance view
+ CRect new_rect(rect);
+ int list_width = rect.Width();
+ int list_height = static_cast<int>(rect.Height() / 5);
+ int page_width = rect.Width() / 2;
+ int page_height = static_cast<int>(rect.Height() * 4 / 5);
+
+ new_rect.SetRect(rect.left, rect.top,
+ rect.left + list_width, rect.top + list_height);
+ page_list_.MoveWindow(new_rect);
+
+ new_rect.SetRect(rect.left,
+ rect.top + list_height,
+ rect.left + page_width,
+ rect.top + list_height + page_height);
+ page_text_.MoveWindow(new_rect);
+
+ page_view_container_->MoveWindow(rect.left + page_width + kLayoutPadding,
+ rect.top + list_height,
+ page_width - kLayoutPadding, page_height,
+ TRUE);
+}
+
+void NetworkStatusView::OnConfigTrackingClicked(UINT code, int button_id,
+ HWND hwnd) {
+ if (is_tracking_) {
+ tracker_->StopTracking();
+ is_tracking_ = false;
+
+ SetButtonText(IDC_CONFIG_TRACKING_BUTTON, kStartTrackingMsg);
+ } else {
+ tracker_->StartTracking();
+ is_tracking_ = true;
+
+ ClearTrackingResults();
+ ShowTrackingResults();
+
+ SetButtonText(IDC_CONFIG_TRACKING_BUTTON, kStopTrackingMsg);
+ }
+}
+
+void NetworkStatusView::OnCurrentStatusClicked(UINT code, int button_id,
+ HWND hwnd) {
+ ShowTrackingResults();
+ if (is_tracking_) {
+ tracker_->ReportStatus();
+ }
+}
+
+void NetworkStatusView::OnClearClicked(UINT code, int button_id, HWND hwnd) {
+ ClearTrackingResults();
+ ClearProfilingResults();
+}
+
+void NetworkStatusView::OnConfigProfilingClicked(UINT code, int button_id,
+ HWND hwnd) {
+ if (is_profiling_) {
+ g_navigation_profiler.StopProfiling(profiling_session_id_);
+ is_profiling_ = false;
+
+ HideProfilingResults();
+
+ SetButtonText(IDC_CONFIG_PROFILING_BUTTON, kStartProfilingMsg);
+ } else {
+ profiling_session_id_ = g_navigation_profiler.StartProfiling();
+ is_profiling_ = true;
+
+ HideTrackingResults();
+ ClearProfilingResults();
+
+ performance_viewer_.reset(
+ new NavigationPerformanceViewer(profiling_session_id_));
+
+ ShowProfilingResults();
+
+ SetButtonText(IDC_CONFIG_PROFILING_BUTTON, kStopProfilingMsg);
+ SetButtonText(IDC_SHOW_PERFORMANCE_BUTTON, kShowPerformanceMsg);
+ }
+}
+
+void NetworkStatusView::OnShowPerformanceClicked(UINT code, int button_id,
+ HWND hwnd) {
+ HideTrackingResults();
+ ShowProfilingResults();
+
+ if (!is_profiling_)
+ return;
+
+ int num_pages =
+ g_navigation_profiler.RetrieveVisitedPages(performance_viewer_.get());
+
+ // Refresh display if there are new page profiling results
+ if (num_pages > 0) {
+ // Display the list of page URLs
+ page_list_.ResetContent();
+ int size = performance_viewer_->GetSize();
+ for (int i = 0; i < size; ++i) {
+ PageLoadTracker* page = performance_viewer_->GetPageReference(i);
+ page_list_.InsertString(i, StringForURL(page->url()).c_str());
+ }
+
+ page_list_.SetCurSel(current_page_index_);
+ ReportPagePerformance(current_page_index_);
+
+ SetButtonText(IDC_SHOW_PERFORMANCE_BUTTON, kRefreshPerformanceMsg);
+ }
+}
+
+void NetworkStatusView::OnPageDoubleClicked(UINT code, int command_id,
+ HWND window) {
+ int index = page_list_.GetCurSel();
+ if (index == LB_ERR)
+ return;
+
+ current_page_index_ = index;
+ ReportPagePerformance(current_page_index_);
+}
+
+void NetworkStatusView::AppendText(const std::wstring& text) {
+ text_area_.AppendText(text.c_str());
+}
+
+void NetworkStatusView::HideTrackingResults() {
+ text_area_.ShowWindow(SW_HIDE);
+}
+
+void NetworkStatusView::ShowTrackingResults() {
+ HideProfilingResults();
+ text_area_.ShowWindow(SW_SHOW);
+}
+
+void NetworkStatusView::ClearTrackingResults() {
+ text_area_.SetSelAll();
+ text_area_.Clear();
+}
+
+void NetworkStatusView::HideProfilingResults() {
+ page_list_.ShowWindow(SW_HIDE);
+ page_text_.ShowWindow(SW_HIDE);
+ page_view_container_->ShowWindow(SW_HIDE);
+}
+
+void NetworkStatusView::ShowProfilingResults() {
+ HideTrackingResults();
+ page_list_.ShowWindow(SW_SHOW);
+ page_text_.ShowWindow(SW_SHOW);
+ page_view_container_->ShowWindow(SW_SHOW);
+}
+
+void NetworkStatusView::ClearProfilingResults() {
+ page_list_.ResetContent();
+ current_page_index_ = 0;
+
+ page_text_.SetSelAll();
+ page_text_.Clear();
+
+ page_load_view_->SetPage(NULL);
+ page_view_container_->GetRootView()->SchedulePaint();
+
+ if (performance_viewer_.get())
+ performance_viewer_->Reset();
+}
+
+void NetworkStatusView::ReportPagePerformance(int page_index) {
+ PageLoadTracker* page = performance_viewer_->GetPageReference(page_index);
+
+ page_text_.SetSelAll();
+ page_text_.Clear();
+
+ if (page != NULL) {
+ std::wstring text;
+ page->AppendText(&text);
+ page_text_.AppendText(text.c_str());
+ }
+
+ page_load_view_->SetPage(page);
+ page_view_container_->GetRootView()->SchedulePaint();
+}
+
+//-----------------------------------------------------------------------------
+
+// main thread:
+NetworkStatusView::JobTracker::JobTracker(NetworkStatusView* view)
+ : view_(view),
+ view_message_loop_(MessageLoop::current()) {
+}
+
+// main thread:
+void NetworkStatusView::JobTracker::InvokeOnIOThread(void (JobTracker::*m)()) {
+ Thread* thread = g_browser_process->io_thread();
+ if (!thread)
+ return;
+ thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(this, m));
+}
+
+// main thread:
+void NetworkStatusView::JobTracker::StartTracking() {
+ DCHECK(MessageLoop::current() == view_message_loop_);
+ DCHECK(view_);
+ InvokeOnIOThread(&JobTracker::OnStartTracking);
+}
+
+// main thread:
+void NetworkStatusView::JobTracker::StopTracking() {
+ DCHECK(MessageLoop::current() == view_message_loop_);
+ // The tracker should not be deleted before it is removed from observer
+ // list.
+ AddRef();
+ InvokeOnIOThread(&JobTracker::OnStopTracking);
+}
+
+// main thread:
+void NetworkStatusView::JobTracker::ReportStatus() {
+ DCHECK(MessageLoop::current() == view_message_loop_);
+ InvokeOnIOThread(&JobTracker::OnReportStatus);
+}
+
+// main thread:
+void NetworkStatusView::JobTracker::OnAppendText(const std::wstring& text) {
+ DCHECK(MessageLoop::current() == view_message_loop_);
+ if (view_ && view_->is_tracking_)
+ view_->AppendText(text);
+}
+
+// IO thread:
+void NetworkStatusView::JobTracker::AppendText(const std::wstring& text) {
+ DCHECK(MessageLoop::current() != view_message_loop_);
+ view_message_loop_->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &JobTracker::OnAppendText, text));
+}
+
+// IO thread:
+void NetworkStatusView::JobTracker::OnStartTracking() {
+ DCHECK(MessageLoop::current() != view_message_loop_);
+ g_url_request_job_tracker.AddObserver(this);
+}
+
+// IO thread:
+void NetworkStatusView::JobTracker::OnStopTracking() {
+ DCHECK(MessageLoop::current() != view_message_loop_);
+ g_url_request_job_tracker.RemoveObserver(this);
+ // Balance the AddRef() in StopTracking() called in main thread.
+ Release();
+}
+
+// IO thread:
+void NetworkStatusView::JobTracker::OnReportStatus() {
+ DCHECK(MessageLoop::current() != view_message_loop_);
+
+ std::wstring text(L"\r\n===== Active Job Summary =====\r\n");
+
+ URLRequestJobTracker::JobIterator begin_job =
+ g_url_request_job_tracker.begin();
+ URLRequestJobTracker::JobIterator end_job = g_url_request_job_tracker.end();
+ int orphaned_count = 0;
+ int regular_count = 0;
+ for (URLRequestJobTracker::JobIterator cur = begin_job;
+ cur != end_job; ++cur) {
+ URLRequestJob* job = (*cur);
+ URLRequest* request = job->request();
+ if (!request) {
+ orphaned_count++;
+ continue;
+ }
+
+ regular_count++;
+
+ // active state
+ if (job->is_done())
+ text.append(L" Done: ");
+ else
+ text.append(L" Active: ");
+
+ // URL
+ text.append(StringForURL(request->url()));
+ text.append(L"\r\n");
+ }
+
+ if (regular_count == 0)
+ text.append(L" (No active jobs)\r\n");
+
+ if (orphaned_count) {
+ wchar_t buf[64];
+ swprintf(buf, arraysize(buf), L" %d orphaned jobs\r\n", orphaned_count);
+ text.append(buf);
+ }
+
+ text.append(L"=====\r\n\r\n");
+ AppendText(text);
+}
+
+// IO thread:
+void NetworkStatusView::JobTracker::OnJobAdded(URLRequestJob* job) {
+ DCHECK(MessageLoop::current() != view_message_loop_);
+
+ std::wstring text(L"+ New job : ");
+ text.append(URLForJob(job));
+ text.append(L"\r\n");
+ AppendText(text);
+}
+
+// IO thread:
+void NetworkStatusView::JobTracker::OnJobRemoved(URLRequestJob* job) {
+ DCHECK(MessageLoop::current() != view_message_loop_);
+}
+
+// IO thread:
+void NetworkStatusView::JobTracker::OnJobDone(URLRequestJob* job,
+ const URLRequestStatus& status) {
+ DCHECK(MessageLoop::current() != view_message_loop_);
+
+ std::wstring text;
+ if (status.is_success()) {
+ text.assign(L"- Complete: ");
+ } else if (status.status() == URLRequestStatus::CANCELED) {
+ text.assign(L"- Canceled: ");
+ } else if (status.status() == URLRequestStatus::HANDLED_EXTERNALLY) {
+ text.assign(L"- Handled externally: ");
+ } else {
+ wchar_t buf[32];
+ swprintf(buf, arraysize(buf), L"Failed with %d: ", status.os_error());
+ text.assign(buf);
+ }
+
+ text.append(URLForJob(job));
+ text.append(L"\r\n");
+ AppendText(text);
+}
+
+// IO thread:
+void NetworkStatusView::JobTracker::OnJobRedirect(URLRequestJob* job,
+ const GURL& location,
+ int status_code) {
+ DCHECK(MessageLoop::current() != view_message_loop_);
+
+ std::wstring text(L"- Redirect: ");
+ text.append(URLForJob(job));
+ text.append(L"\r\n ");
+
+ wchar_t buf[16];
+ swprintf(buf, arraysize(buf), L"(%d) to: ", status_code);
+ text.append(buf);
+
+ text.append(StringForURL(location));
+ text.append(L"\r\n");
+ AppendText(text);
+}
+
+void NetworkStatusView::JobTracker::OnBytesRead(URLRequestJob* job,
+ int byte_count) {
+}