OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/views/session_crashed_bubble_view.h" | 5 #include "chrome/browser/ui/views/session_crashed_bubble_view.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <string> | 8 #include <string> |
9 #include <utility> | 9 #include <utility> |
10 #include <vector> | 10 #include <vector> |
(...skipping 28 matching lines...) Expand all Loading... |
39 #include "components/strings/grit/components_chromium_strings.h" | 39 #include "components/strings/grit/components_chromium_strings.h" |
40 #include "components/strings/grit/components_google_chrome_strings.h" | 40 #include "components/strings/grit/components_google_chrome_strings.h" |
41 #include "components/strings/grit/components_strings.h" | 41 #include "components/strings/grit/components_strings.h" |
42 #include "content/public/browser/browser_context.h" | 42 #include "content/public/browser/browser_context.h" |
43 #include "content/public/browser/browser_thread.h" | 43 #include "content/public/browser/browser_thread.h" |
44 #include "content/public/browser/notification_source.h" | 44 #include "content/public/browser/notification_source.h" |
45 #include "content/public/browser/web_contents.h" | 45 #include "content/public/browser/web_contents.h" |
46 #include "ui/base/l10n/l10n_util.h" | 46 #include "ui/base/l10n/l10n_util.h" |
47 #include "ui/views/bubble/bubble_frame_view.h" | 47 #include "ui/views/bubble/bubble_frame_view.h" |
48 #include "ui/views/controls/button/checkbox.h" | 48 #include "ui/views/controls/button/checkbox.h" |
49 #include "ui/views/controls/button/label_button.h" | |
50 #include "ui/views/controls/label.h" | 49 #include "ui/views/controls/label.h" |
51 #include "ui/views/controls/separator.h" | 50 #include "ui/views/controls/separator.h" |
52 #include "ui/views/controls/styled_label.h" | 51 #include "ui/views/controls/styled_label.h" |
| 52 #include "ui/views/layout/fill_layout.h" |
53 #include "ui/views/layout/grid_layout.h" | 53 #include "ui/views/layout/grid_layout.h" |
54 #include "ui/views/layout/layout_constants.h" | 54 #include "ui/views/layout/layout_constants.h" |
55 #include "ui/views/widget/widget.h" | 55 #include "ui/views/widget/widget.h" |
56 | 56 |
57 using views::GridLayout; | 57 using views::GridLayout; |
58 | 58 |
59 namespace { | 59 namespace { |
60 | 60 |
61 // Fixed width of the column holding the description label of the bubble. | 61 // Fixed width of the column holding the description label of the bubble. |
62 const int kWidthOfDescriptionText = 320; | 62 const int kWidthOfDescriptionText = 320; |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 browser->tab_strip_model()->GetActiveWebContents(); | 206 browser->tab_strip_model()->GetActiveWebContents(); |
207 | 207 |
208 if (!web_contents) { | 208 if (!web_contents) { |
209 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_ERROR); | 209 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_ERROR); |
210 return; | 210 return; |
211 } | 211 } |
212 | 212 |
213 SessionCrashedBubbleView* crash_bubble = | 213 SessionCrashedBubbleView* crash_bubble = |
214 new SessionCrashedBubbleView(anchor_view, browser, web_contents, | 214 new SessionCrashedBubbleView(anchor_view, browser, web_contents, |
215 offer_uma_optin); | 215 offer_uma_optin); |
216 views::BubbleDelegateView::CreateBubble(crash_bubble)->Show(); | 216 views::BubbleDialogDelegateView::CreateBubble(crash_bubble)->Show(); |
217 | 217 |
218 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_SHOWN); | 218 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_SHOWN); |
219 if (uma_opted_in_already) | 219 if (uma_opted_in_already) |
220 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_ALREADY_UMA_OPTIN); | 220 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_ALREADY_UMA_OPTIN); |
221 } | 221 } |
222 | 222 |
223 SessionCrashedBubbleView::SessionCrashedBubbleView( | 223 SessionCrashedBubbleView::SessionCrashedBubbleView( |
224 views::View* anchor_view, | 224 views::View* anchor_view, |
225 Browser* browser, | 225 Browser* browser, |
226 content::WebContents* web_contents, | 226 content::WebContents* web_contents, |
227 bool offer_uma_optin) | 227 bool offer_uma_optin) |
228 : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_RIGHT), | 228 : BubbleDialogDelegateView(anchor_view, views::BubbleBorder::TOP_RIGHT), |
229 content::WebContentsObserver(web_contents), | 229 content::WebContentsObserver(web_contents), |
230 browser_(browser), | 230 browser_(browser), |
231 web_contents_(web_contents), | 231 web_contents_(web_contents), |
232 restore_button_(NULL), | |
233 uma_option_(NULL), | 232 uma_option_(NULL), |
234 offer_uma_optin_(offer_uma_optin), | 233 offer_uma_optin_(offer_uma_optin), |
235 started_navigation_(false), | 234 started_navigation_(false), |
236 restored_(false) { | 235 restored_(false) { |
237 set_close_on_deactivate(false); | 236 set_close_on_deactivate(false); |
238 registrar_.Add( | 237 registrar_.Add( |
239 this, | 238 this, |
240 chrome::NOTIFICATION_TAB_CLOSING, | 239 chrome::NOTIFICATION_TAB_CLOSING, |
241 content::Source<content::NavigationController>(&( | 240 content::Source<content::NavigationController>(&( |
242 web_contents->GetController()))); | 241 web_contents->GetController()))); |
243 browser->tab_strip_model()->AddObserver(this); | 242 browser->tab_strip_model()->AddObserver(this); |
244 } | 243 } |
245 | 244 |
246 SessionCrashedBubbleView::~SessionCrashedBubbleView() { | 245 SessionCrashedBubbleView::~SessionCrashedBubbleView() { |
247 browser_->tab_strip_model()->RemoveObserver(this); | 246 browser_->tab_strip_model()->RemoveObserver(this); |
248 } | 247 } |
249 | 248 |
250 views::View* SessionCrashedBubbleView::GetInitiallyFocusedView() { | |
251 return restore_button_; | |
252 } | |
253 | |
254 base::string16 SessionCrashedBubbleView::GetWindowTitle() const { | 249 base::string16 SessionCrashedBubbleView::GetWindowTitle() const { |
255 return l10n_util::GetStringUTF16(IDS_SESSION_CRASHED_BUBBLE_TITLE); | 250 return l10n_util::GetStringUTF16(IDS_SESSION_CRASHED_BUBBLE_TITLE); |
256 } | 251 } |
257 | 252 |
258 bool SessionCrashedBubbleView::ShouldShowWindowTitle() const { | 253 bool SessionCrashedBubbleView::ShouldShowWindowTitle() const { |
259 return true; | 254 return true; |
260 } | 255 } |
261 | 256 |
262 bool SessionCrashedBubbleView::ShouldShowCloseButton() const { | 257 bool SessionCrashedBubbleView::ShouldShowCloseButton() const { |
263 return true; | 258 return true; |
264 } | 259 } |
265 | 260 |
266 void SessionCrashedBubbleView::OnWidgetDestroying(views::Widget* widget) { | 261 void SessionCrashedBubbleView::OnWidgetDestroying(views::Widget* widget) { |
267 if (!restored_) | 262 if (!restored_) |
268 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_IGNORED); | 263 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_IGNORED); |
269 BubbleDelegateView::OnWidgetDestroying(widget); | 264 BubbleDialogDelegateView::OnWidgetDestroying(widget); |
270 } | 265 } |
271 | 266 |
272 void SessionCrashedBubbleView::Init() { | 267 void SessionCrashedBubbleView::Init() { |
| 268 SetLayoutManager(new views::FillLayout()); |
| 269 |
273 // Description text label. | 270 // Description text label. |
274 views::Label* text_label = new views::Label( | 271 views::Label* text_label = new views::Label( |
275 l10n_util::GetStringUTF16(IDS_SESSION_CRASHED_VIEW_MESSAGE)); | 272 l10n_util::GetStringUTF16(IDS_SESSION_CRASHED_VIEW_MESSAGE)); |
276 text_label->SetMultiLine(true); | 273 text_label->SetMultiLine(true); |
277 text_label->SetLineHeight(20); | 274 text_label->SetLineHeight(20); |
278 text_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 275 text_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
279 text_label->SizeToFit(kWidthOfDescriptionText); | 276 text_label->SizeToFit(kWidthOfDescriptionText); |
280 | 277 AddChildView(text_label); |
281 // Restore button. | |
282 restore_button_ = new views::LabelButton( | |
283 this, l10n_util::GetStringUTF16(IDS_SESSION_CRASHED_VIEW_RESTORE_BUTTON)); | |
284 restore_button_->SetStyle(views::Button::STYLE_BUTTON); | |
285 restore_button_->SetIsDefault(true); | |
286 | |
287 GridLayout* layout = new GridLayout(this); | |
288 SetLayoutManager(layout); | |
289 | |
290 // Text row. | |
291 const int kTextColumnSetId = 0; | |
292 views::ColumnSet* cs = layout->AddColumnSet(kTextColumnSetId); | |
293 cs->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, | |
294 GridLayout::FIXED, kWidthOfDescriptionText, 0); | |
295 | |
296 // Restore button row. | |
297 const int kButtonColumnSetId = 1; | |
298 cs = layout->AddColumnSet(kButtonColumnSetId); | |
299 cs->AddColumn(GridLayout::TRAILING, GridLayout::CENTER, 1, | |
300 GridLayout::USE_PREF, 0, 0); | |
301 | |
302 layout->StartRow(0, kTextColumnSetId); | |
303 layout->AddView(text_label); | |
304 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | |
305 | |
306 layout->StartRow(0, kButtonColumnSetId); | |
307 layout->AddView(restore_button_); | |
308 } | 278 } |
309 | 279 |
310 scoped_ptr<views::View> SessionCrashedBubbleView::CreateFootnoteView() { | 280 scoped_ptr<views::View> SessionCrashedBubbleView::CreateFootnoteView() { |
311 if (!offer_uma_optin_) | 281 if (!offer_uma_optin_) |
312 return nullptr; | 282 return nullptr; |
313 | 283 |
314 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_OPTIN_BAR_SHOWN); | 284 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_OPTIN_BAR_SHOWN); |
315 | 285 |
316 // Checkbox for metric reporting setting. | 286 // Checkbox for metric reporting setting. |
317 // Since the text to the right of the checkbox can't be a simple string (needs | 287 // Since the text to the right of the checkbox can't be a simple string (needs |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 cs->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, GridLayout::USE_PREF, 0, | 328 cs->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, GridLayout::USE_PREF, 0, |
359 0); | 329 0); |
360 | 330 |
361 uma_layout->StartRow(0, kReportColumnSetId); | 331 uma_layout->StartRow(0, kReportColumnSetId); |
362 uma_layout->AddView(uma_option_); | 332 uma_layout->AddView(uma_option_); |
363 uma_layout->AddView(uma_label); | 333 uma_layout->AddView(uma_label); |
364 | 334 |
365 return uma_view; | 335 return uma_view; |
366 } | 336 } |
367 | 337 |
368 void SessionCrashedBubbleView::ButtonPressed(views::Button* sender, | 338 bool SessionCrashedBubbleView::Accept(bool window_closing) { |
369 const ui::Event& event) { | 339 // If the window is just closing (no explicit accept), don't restore. |
370 DCHECK_EQ(sender, restore_button_); | 340 if (!window_closing) |
371 RestorePreviousSession(sender); | 341 RestorePreviousSession(); |
| 342 return true; |
| 343 } |
| 344 |
| 345 int SessionCrashedBubbleView::GetDialogButtons() const { |
| 346 return ui::DIALOG_BUTTON_OK; |
| 347 } |
| 348 |
| 349 base::string16 SessionCrashedBubbleView::GetDialogButtonLabel( |
| 350 ui::DialogButton button) const { |
| 351 return l10n_util::GetStringUTF16(IDS_SESSION_CRASHED_VIEW_RESTORE_BUTTON); |
372 } | 352 } |
373 | 353 |
374 void SessionCrashedBubbleView::StyledLabelLinkClicked(views::StyledLabel* label, | 354 void SessionCrashedBubbleView::StyledLabelLinkClicked(views::StyledLabel* label, |
375 const gfx::Range& range, | 355 const gfx::Range& range, |
376 int event_flags) { | 356 int event_flags) { |
377 browser_->OpenURL(content::OpenURLParams( | 357 browser_->OpenURL(content::OpenURLParams( |
378 GURL("https://support.google.com/chrome/answer/96817"), | 358 GURL("https://support.google.com/chrome/answer/96817"), |
379 content::Referrer(), | 359 content::Referrer(), |
380 NEW_FOREGROUND_TAB, | 360 NEW_FOREGROUND_TAB, |
381 ui::PAGE_TRANSITION_LINK, | 361 ui::PAGE_TRANSITION_LINK, |
(...skipping 29 matching lines...) Expand all Loading... |
411 if (type == chrome::NOTIFICATION_TAB_CLOSING) | 391 if (type == chrome::NOTIFICATION_TAB_CLOSING) |
412 CloseBubble(); | 392 CloseBubble(); |
413 } | 393 } |
414 | 394 |
415 void SessionCrashedBubbleView::TabDetachedAt(content::WebContents* contents, | 395 void SessionCrashedBubbleView::TabDetachedAt(content::WebContents* contents, |
416 int index) { | 396 int index) { |
417 if (web_contents_ == contents) | 397 if (web_contents_ == contents) |
418 CloseBubble(); | 398 CloseBubble(); |
419 } | 399 } |
420 | 400 |
421 void SessionCrashedBubbleView::RestorePreviousSession(views::Button* sender) { | 401 void SessionCrashedBubbleView::RestorePreviousSession() { |
422 SessionRestore::RestoreSessionAfterCrash(browser_); | 402 SessionRestore::RestoreSessionAfterCrash(browser_); |
423 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_RESTORED); | 403 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_RESTORED); |
424 restored_ = true; | 404 restored_ = true; |
425 | 405 |
426 // Record user's choice for opt-in in to UMA. | 406 // Record user's choice for opt-in in to UMA. |
427 // There's no opt-out choice in the crash restore bubble. | 407 // There's no opt-out choice in the crash restore bubble. |
428 if (uma_option_ && uma_option_->checked()) { | 408 if (uma_option_ && uma_option_->checked()) { |
429 InitiateMetricsReportingChange(true, OnMetricsReportingCallbackType()); | 409 InitiateMetricsReportingChange(true, OnMetricsReportingCallbackType()); |
430 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_UMA_OPTIN); | 410 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_UMA_OPTIN); |
431 } | 411 } |
432 CloseBubble(); | 412 CloseBubble(); |
433 } | 413 } |
434 | 414 |
435 void SessionCrashedBubbleView::CloseBubble() { | 415 void SessionCrashedBubbleView::CloseBubble() { |
436 GetWidget()->Close(); | 416 GetWidget()->Close(); |
437 } | 417 } |
OLD | NEW |