Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1877)

Unified Diff: chrome/browser/views/about_network_dialog.cc

Issue 18728: Create a dialog box for the about:network view and kill the tab type.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/views/about_network_dialog.h ('k') | chrome/browser/views/browser_views.vcproj » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/views/about_network_dialog.cc
===================================================================
--- chrome/browser/views/about_network_dialog.cc (revision 0)
+++ chrome/browser/views/about_network_dialog.cc (revision 0)
@@ -0,0 +1,381 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/views/about_network_dialog.h"
+
+#include "base/string_util.h"
+#include "base/thread.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/views/standard_layout.h"
+#include "chrome/views/grid_layout.h"
+#include "chrome/views/text_button.h"
+#include "chrome/views/text_field.h"
+#include "chrome/views/window.h"
+#include "net/url_request/url_request.h"
+#include "net/url_request/url_request_job.h"
+#include "net/url_request/url_request_job_tracker.h"
+
+namespace {
+
+// We don't localize this UI since this is a developer-only feature.
+const wchar_t kStartTrackingLabel[] = L"Start tracking";
+const wchar_t kStopTrackingLabel[] = L"Stop tracking";
+const wchar_t KShowCurrentLabel[] = L"Show Current";
Ben Goodger (Google) 2009/01/23 23:24:24 K?
+const wchar_t kClearLabel[] = L"Clear";
+
+// The singleton dialog box. This is non-NULL when a dialog is active so we
+// know not to create a new one.
+AboutNetworkDialog* active_dialog = NULL;
+
+// 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)");
+}
+
+// JobTracker ------------------------------------------------------------------
+
+// A JobTracker is allocated to monitor network jobs running on the IO
+// thread. This allows the NetworkStatusView to remain single-threaded.
+class JobTracker : public URLRequestJobTracker::JobObserver,
+ public base::RefCountedThreadSafe<JobTracker> {
+ public:
+ JobTracker(AboutNetworkDialog* view);
+ ~JobTracker();
+
+ // Called by the NetworkStatusView on the main application thread.
+ void StartTracking();
+ void StopTracking();
+ void ReportStatus();
+
+ // URLRequestJobTracker::JobObserver methods (called on the IO thread):
+ virtual void OnJobAdded(URLRequestJob* job);
+ virtual void OnJobRemoved(URLRequestJob* job);
+ virtual void OnJobDone(URLRequestJob* job, const URLRequestStatus& status);
+ virtual void OnJobRedirect(URLRequestJob* job, const GURL& location,
+ int status_code);
+ virtual void OnBytesRead(URLRequestJob* job, int byte_count);
+
+ // The JobTracker may be deleted after NetworkStatusView is deleted.
+ void DetachView() { view_ = NULL; }
+
+ private:
+ void InvokeOnIOThread(void (JobTracker::*method)());
+
+ // Called on the IO thread
+ void OnStartTracking();
+ void OnStopTracking();
+ void OnReportStatus();
+ void AppendText(const std::wstring& text);
+
+ // Called on the main thread
+ void OnAppendText(const std::wstring& text);
+
+ AboutNetworkDialog* view_;
+ MessageLoop* view_message_loop_;
+};
+
+// main thread:
+JobTracker::JobTracker(AboutNetworkDialog* view)
+ : view_(view),
+ view_message_loop_(MessageLoop::current()) {
+}
+
+JobTracker::~JobTracker() {
+}
+
+// main thread:
+void JobTracker::InvokeOnIOThread(void (JobTracker::*m)()) {
+ base::Thread* thread = g_browser_process->io_thread();
+ if (!thread)
+ return;
+ thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(this, m));
+}
+
+// main thread:
+void JobTracker::StartTracking() {
+ DCHECK(MessageLoop::current() == view_message_loop_);
+ DCHECK(view_);
+ InvokeOnIOThread(&JobTracker::OnStartTracking);
+}
+
+// main thread:
+void 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 JobTracker::ReportStatus() {
+ DCHECK(MessageLoop::current() == view_message_loop_);
+ InvokeOnIOThread(&JobTracker::OnReportStatus);
+}
+
+// main thread:
+void JobTracker::OnAppendText(const std::wstring& text) {
+ DCHECK(MessageLoop::current() == view_message_loop_);
+ if (view_ && view_->tracking())
+ view_->AppendText(text);
+}
+
+// IO thread:
+void 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 JobTracker::OnStartTracking() {
+ DCHECK(MessageLoop::current() != view_message_loop_);
+ g_url_request_job_tracker.AddObserver(this);
+}
+
+// IO thread:
+void 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 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 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 JobTracker::OnJobRemoved(URLRequestJob* job) {
+ DCHECK(MessageLoop::current() != view_message_loop_);
+}
+
+// IO thread:
+void 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 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 JobTracker::OnBytesRead(URLRequestJob* job, int byte_count) {
+}
+
+// The singleton job tracker associated with the dialog.
+JobTracker* tracker = NULL;
+
+} // namespace
+
+// AboutNetworkDialog ----------------------------------------------------------
+
+AboutNetworkDialog::AboutNetworkDialog() : tracking_(false) {
+ SetupControls();
+ tracker = new JobTracker(this);
+ tracker->AddRef();
+}
+
+AboutNetworkDialog::~AboutNetworkDialog() {
+ active_dialog = NULL;
+ tracker->Release();
+ tracker = NULL;
+}
+
+// static
+void AboutNetworkDialog::RunDialog() {
+ if (!active_dialog) {
+ active_dialog = new AboutNetworkDialog;
+ views::Window::CreateChromeWindow(NULL, gfx::Rect(), active_dialog)->Show();
+ } else {
+ // TOOD(brettw) it would be nice to focus the existing window.
+ }
+}
+
+void AboutNetworkDialog::AppendText(const std::wstring& text) {
+ text_field_->AppendText(text);
+}
+
+void AboutNetworkDialog::SetupControls() {
+ views::GridLayout* layout = CreatePanelGridLayout(this);
+ SetLayoutManager(layout);
+
+ track_toggle_ = new views::TextButton(kStartTrackingLabel);
+ track_toggle_->SetListener(this, 1);
+ show_button_ = new views::TextButton(KShowCurrentLabel);
+ show_button_->SetListener(this, 2);
+ clear_button_ = new views::TextButton(kClearLabel);
+ clear_button_->SetListener(this, 3);
+
+ text_field_ = new views::TextField(static_cast<views::TextField::StyleFlags>(
+ views::TextField::STYLE_MULTILINE));
+ text_field_->SetReadOnly(true);
+
+ // TODO(brettw): We may want to add this in the future. It can't be called
+ // from here, though, since the hwnd for the field hasn't been created yet.
+ //
+ // This raises the maximum number of chars from 32K to some large maximum,
+ // probably 2GB. 32K is not nearly enough for our use-case.
+ //SendMessageW(text_field_->GetNativeComponent(), EM_SETLIMITTEXT, 0, 0);
+
+ static const int first_column_set = 1;
+ views::ColumnSet* column_set = layout->AddColumnSet(first_column_set);
+ column_set->AddColumn(views::GridLayout::CENTER, views::GridLayout::CENTER,
+ 33.33f, views::GridLayout::FIXED, 0, 0);
+ column_set->AddColumn(views::GridLayout::CENTER, views::GridLayout::CENTER,
+ 33.33f, views::GridLayout::FIXED, 0, 0);
+ column_set->AddColumn(views::GridLayout::CENTER, views::GridLayout::CENTER,
+ 33.33f, views::GridLayout::FIXED, 0, 0);
+
+ static const int text_column_set = 2;
+ column_set = layout->AddColumnSet(text_column_set);
+ column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 100.0f,
+ views::GridLayout::FIXED, 0, 0);
+
+ layout->StartRow(0, first_column_set);
+ layout->AddView(track_toggle_);
+ layout->AddView(show_button_);
+ layout->AddView(clear_button_);
+ layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
+ layout->StartRow(1.0f, text_column_set);
+ layout->AddView(text_field_);
+}
+
+gfx::Size AboutNetworkDialog::GetPreferredSize() {
+ return gfx::Size(800, 400);
+}
+
+views::View* AboutNetworkDialog::GetContentsView() {
+ return this;
+}
+
+int AboutNetworkDialog::GetDialogButtons() const {
+ // Don't want OK or Cancel.
+ return 0;
+}
+
+std::wstring AboutNetworkDialog::GetWindowTitle() const {
+ return L"about:network";
+}
+
+void AboutNetworkDialog::Layout() {
+ GetLayoutManager()->Layout(this);
+}
+
+bool AboutNetworkDialog::CanResize() const {
+ return true;
+}
+
+void AboutNetworkDialog::ButtonPressed(views::BaseButton* button) {
+ if (button == track_toggle_) {
+ if (tracking_) {
+ track_toggle_->SetText(kStartTrackingLabel);
+ tracking_ = false;
+ tracker->StopTracking();
+ } else {
+ track_toggle_->SetText(kStopTrackingLabel);
+ tracking_ = true;
+ tracker->StartTracking();
+ }
+ track_toggle_->SchedulePaint();
+ } else if (button == show_button_) {
+ tracker->ReportStatus();
+ } else if (button == clear_button_) {
+ text_field_->SetText(std::wstring());
+ }
+}
« no previous file with comments | « chrome/browser/views/about_network_dialog.h ('k') | chrome/browser/views/browser_views.vcproj » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698