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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2009 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/views/about_network_dialog.h"
6
7 #include "base/string_util.h"
8 #include "base/thread.h"
9 #include "chrome/browser/browser_process.h"
10 #include "chrome/browser/views/standard_layout.h"
11 #include "chrome/views/grid_layout.h"
12 #include "chrome/views/text_button.h"
13 #include "chrome/views/text_field.h"
14 #include "chrome/views/window.h"
15 #include "net/url_request/url_request.h"
16 #include "net/url_request/url_request_job.h"
17 #include "net/url_request/url_request_job_tracker.h"
18
19 namespace {
20
21 // We don't localize this UI since this is a developer-only feature.
22 const wchar_t kStartTrackingLabel[] = L"Start tracking";
23 const wchar_t kStopTrackingLabel[] = L"Stop tracking";
24 const wchar_t KShowCurrentLabel[] = L"Show Current";
Ben Goodger (Google) 2009/01/23 23:24:24 K?
25 const wchar_t kClearLabel[] = L"Clear";
26
27 // The singleton dialog box. This is non-NULL when a dialog is active so we
28 // know not to create a new one.
29 AboutNetworkDialog* active_dialog = NULL;
30
31 // Returns a string representing the URL, handling the case where the spec
32 // is invalid.
33 std::wstring StringForURL(const GURL& url) {
34 if (url.is_valid())
35 return UTF8ToWide(url.spec());
36 return UTF8ToWide(url.possibly_invalid_spec()) + L" (invalid)";
37 }
38
39 std::wstring URLForJob(URLRequestJob* job) {
40 URLRequest* request = job->request();
41 if (request)
42 return StringForURL(request->url());
43 return std::wstring(L"(orphaned)");
44 }
45
46 // JobTracker ------------------------------------------------------------------
47
48 // A JobTracker is allocated to monitor network jobs running on the IO
49 // thread. This allows the NetworkStatusView to remain single-threaded.
50 class JobTracker : public URLRequestJobTracker::JobObserver,
51 public base::RefCountedThreadSafe<JobTracker> {
52 public:
53 JobTracker(AboutNetworkDialog* view);
54 ~JobTracker();
55
56 // Called by the NetworkStatusView on the main application thread.
57 void StartTracking();
58 void StopTracking();
59 void ReportStatus();
60
61 // URLRequestJobTracker::JobObserver methods (called on the IO thread):
62 virtual void OnJobAdded(URLRequestJob* job);
63 virtual void OnJobRemoved(URLRequestJob* job);
64 virtual void OnJobDone(URLRequestJob* job, const URLRequestStatus& status);
65 virtual void OnJobRedirect(URLRequestJob* job, const GURL& location,
66 int status_code);
67 virtual void OnBytesRead(URLRequestJob* job, int byte_count);
68
69 // The JobTracker may be deleted after NetworkStatusView is deleted.
70 void DetachView() { view_ = NULL; }
71
72 private:
73 void InvokeOnIOThread(void (JobTracker::*method)());
74
75 // Called on the IO thread
76 void OnStartTracking();
77 void OnStopTracking();
78 void OnReportStatus();
79 void AppendText(const std::wstring& text);
80
81 // Called on the main thread
82 void OnAppendText(const std::wstring& text);
83
84 AboutNetworkDialog* view_;
85 MessageLoop* view_message_loop_;
86 };
87
88 // main thread:
89 JobTracker::JobTracker(AboutNetworkDialog* view)
90 : view_(view),
91 view_message_loop_(MessageLoop::current()) {
92 }
93
94 JobTracker::~JobTracker() {
95 }
96
97 // main thread:
98 void JobTracker::InvokeOnIOThread(void (JobTracker::*m)()) {
99 base::Thread* thread = g_browser_process->io_thread();
100 if (!thread)
101 return;
102 thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(this, m));
103 }
104
105 // main thread:
106 void JobTracker::StartTracking() {
107 DCHECK(MessageLoop::current() == view_message_loop_);
108 DCHECK(view_);
109 InvokeOnIOThread(&JobTracker::OnStartTracking);
110 }
111
112 // main thread:
113 void JobTracker::StopTracking() {
114 DCHECK(MessageLoop::current() == view_message_loop_);
115 // The tracker should not be deleted before it is removed from observer
116 // list.
117 AddRef();
118 InvokeOnIOThread(&JobTracker::OnStopTracking);
119 }
120
121 // main thread:
122 void JobTracker::ReportStatus() {
123 DCHECK(MessageLoop::current() == view_message_loop_);
124 InvokeOnIOThread(&JobTracker::OnReportStatus);
125 }
126
127 // main thread:
128 void JobTracker::OnAppendText(const std::wstring& text) {
129 DCHECK(MessageLoop::current() == view_message_loop_);
130 if (view_ && view_->tracking())
131 view_->AppendText(text);
132 }
133
134 // IO thread:
135 void JobTracker::AppendText(const std::wstring& text) {
136 DCHECK(MessageLoop::current() != view_message_loop_);
137 view_message_loop_->PostTask(FROM_HERE, NewRunnableMethod(
138 this, &JobTracker::OnAppendText, text));
139 }
140
141 // IO thread:
142 void JobTracker::OnStartTracking() {
143 DCHECK(MessageLoop::current() != view_message_loop_);
144 g_url_request_job_tracker.AddObserver(this);
145 }
146
147 // IO thread:
148 void JobTracker::OnStopTracking() {
149 DCHECK(MessageLoop::current() != view_message_loop_);
150 g_url_request_job_tracker.RemoveObserver(this);
151 // Balance the AddRef() in StopTracking() called in main thread.
152 Release();
153 }
154
155 // IO thread:
156 void JobTracker::OnReportStatus() {
157 DCHECK(MessageLoop::current() != view_message_loop_);
158
159 std::wstring text(L"\r\n===== Active Job Summary =====\r\n");
160
161 URLRequestJobTracker::JobIterator begin_job =
162 g_url_request_job_tracker.begin();
163 URLRequestJobTracker::JobIterator end_job = g_url_request_job_tracker.end();
164 int orphaned_count = 0;
165 int regular_count = 0;
166 for (URLRequestJobTracker::JobIterator cur = begin_job;
167 cur != end_job; ++cur) {
168 URLRequestJob* job = (*cur);
169 URLRequest* request = job->request();
170 if (!request) {
171 orphaned_count++;
172 continue;
173 }
174
175 regular_count++;
176
177 // active state
178 if (job->is_done())
179 text.append(L" Done: ");
180 else
181 text.append(L" Active: ");
182
183 // URL
184 text.append(StringForURL(request->url()));
185 text.append(L"\r\n");
186 }
187
188 if (regular_count == 0)
189 text.append(L" (No active jobs)\r\n");
190
191 if (orphaned_count) {
192 wchar_t buf[64];
193 swprintf(buf, arraysize(buf), L" %d orphaned jobs\r\n", orphaned_count);
194 text.append(buf);
195 }
196
197 text.append(L"=====\r\n\r\n");
198 AppendText(text);
199 }
200
201 // IO thread:
202 void JobTracker::OnJobAdded(URLRequestJob* job) {
203 DCHECK(MessageLoop::current() != view_message_loop_);
204
205 std::wstring text(L"+ New job : ");
206 text.append(URLForJob(job));
207 text.append(L"\r\n");
208 AppendText(text);
209 }
210
211 // IO thread:
212 void JobTracker::OnJobRemoved(URLRequestJob* job) {
213 DCHECK(MessageLoop::current() != view_message_loop_);
214 }
215
216 // IO thread:
217 void JobTracker::OnJobDone(URLRequestJob* job,
218 const URLRequestStatus& status) {
219 DCHECK(MessageLoop::current() != view_message_loop_);
220
221 std::wstring text;
222 if (status.is_success()) {
223 text.assign(L"- Complete: ");
224 } else if (status.status() == URLRequestStatus::CANCELED) {
225 text.assign(L"- Canceled: ");
226 } else if (status.status() == URLRequestStatus::HANDLED_EXTERNALLY) {
227 text.assign(L"- Handled externally: ");
228 } else {
229 wchar_t buf[32];
230 swprintf(buf, arraysize(buf), L"Failed with %d: ", status.os_error());
231 text.assign(buf);
232 }
233
234 text.append(URLForJob(job));
235 text.append(L"\r\n");
236 AppendText(text);
237 }
238
239 // IO thread:
240 void JobTracker::OnJobRedirect(URLRequestJob* job,
241 const GURL& location,
242 int status_code) {
243 DCHECK(MessageLoop::current() != view_message_loop_);
244
245 std::wstring text(L"- Redirect: ");
246 text.append(URLForJob(job));
247 text.append(L"\r\n ");
248
249 wchar_t buf[16];
250 swprintf(buf, arraysize(buf), L"(%d) to: ", status_code);
251 text.append(buf);
252
253 text.append(StringForURL(location));
254 text.append(L"\r\n");
255 AppendText(text);
256 }
257
258 void JobTracker::OnBytesRead(URLRequestJob* job, int byte_count) {
259 }
260
261 // The singleton job tracker associated with the dialog.
262 JobTracker* tracker = NULL;
263
264 } // namespace
265
266 // AboutNetworkDialog ----------------------------------------------------------
267
268 AboutNetworkDialog::AboutNetworkDialog() : tracking_(false) {
269 SetupControls();
270 tracker = new JobTracker(this);
271 tracker->AddRef();
272 }
273
274 AboutNetworkDialog::~AboutNetworkDialog() {
275 active_dialog = NULL;
276 tracker->Release();
277 tracker = NULL;
278 }
279
280 // static
281 void AboutNetworkDialog::RunDialog() {
282 if (!active_dialog) {
283 active_dialog = new AboutNetworkDialog;
284 views::Window::CreateChromeWindow(NULL, gfx::Rect(), active_dialog)->Show();
285 } else {
286 // TOOD(brettw) it would be nice to focus the existing window.
287 }
288 }
289
290 void AboutNetworkDialog::AppendText(const std::wstring& text) {
291 text_field_->AppendText(text);
292 }
293
294 void AboutNetworkDialog::SetupControls() {
295 views::GridLayout* layout = CreatePanelGridLayout(this);
296 SetLayoutManager(layout);
297
298 track_toggle_ = new views::TextButton(kStartTrackingLabel);
299 track_toggle_->SetListener(this, 1);
300 show_button_ = new views::TextButton(KShowCurrentLabel);
301 show_button_->SetListener(this, 2);
302 clear_button_ = new views::TextButton(kClearLabel);
303 clear_button_->SetListener(this, 3);
304
305 text_field_ = new views::TextField(static_cast<views::TextField::StyleFlags>(
306 views::TextField::STYLE_MULTILINE));
307 text_field_->SetReadOnly(true);
308
309 // TODO(brettw): We may want to add this in the future. It can't be called
310 // from here, though, since the hwnd for the field hasn't been created yet.
311 //
312 // This raises the maximum number of chars from 32K to some large maximum,
313 // probably 2GB. 32K is not nearly enough for our use-case.
314 //SendMessageW(text_field_->GetNativeComponent(), EM_SETLIMITTEXT, 0, 0);
315
316 static const int first_column_set = 1;
317 views::ColumnSet* column_set = layout->AddColumnSet(first_column_set);
318 column_set->AddColumn(views::GridLayout::CENTER, views::GridLayout::CENTER,
319 33.33f, views::GridLayout::FIXED, 0, 0);
320 column_set->AddColumn(views::GridLayout::CENTER, views::GridLayout::CENTER,
321 33.33f, views::GridLayout::FIXED, 0, 0);
322 column_set->AddColumn(views::GridLayout::CENTER, views::GridLayout::CENTER,
323 33.33f, views::GridLayout::FIXED, 0, 0);
324
325 static const int text_column_set = 2;
326 column_set = layout->AddColumnSet(text_column_set);
327 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 100.0f ,
328 views::GridLayout::FIXED, 0, 0);
329
330 layout->StartRow(0, first_column_set);
331 layout->AddView(track_toggle_);
332 layout->AddView(show_button_);
333 layout->AddView(clear_button_);
334 layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
335 layout->StartRow(1.0f, text_column_set);
336 layout->AddView(text_field_);
337 }
338
339 gfx::Size AboutNetworkDialog::GetPreferredSize() {
340 return gfx::Size(800, 400);
341 }
342
343 views::View* AboutNetworkDialog::GetContentsView() {
344 return this;
345 }
346
347 int AboutNetworkDialog::GetDialogButtons() const {
348 // Don't want OK or Cancel.
349 return 0;
350 }
351
352 std::wstring AboutNetworkDialog::GetWindowTitle() const {
353 return L"about:network";
354 }
355
356 void AboutNetworkDialog::Layout() {
357 GetLayoutManager()->Layout(this);
358 }
359
360 bool AboutNetworkDialog::CanResize() const {
361 return true;
362 }
363
364 void AboutNetworkDialog::ButtonPressed(views::BaseButton* button) {
365 if (button == track_toggle_) {
366 if (tracking_) {
367 track_toggle_->SetText(kStartTrackingLabel);
368 tracking_ = false;
369 tracker->StopTracking();
370 } else {
371 track_toggle_->SetText(kStopTrackingLabel);
372 tracking_ = true;
373 tracker->StartTracking();
374 }
375 track_toggle_->SchedulePaint();
376 } else if (button == show_button_) {
377 tracker->ReportStatus();
378 } else if (button == clear_button_) {
379 text_field_->SetText(std::wstring());
380 }
381 }
OLDNEW
« 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