| 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> |
| 11 | 11 |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/bind_helpers.h" | 13 #include "base/bind_helpers.h" |
| 14 #include "base/macros.h" | 14 #include "base/macros.h" |
| 15 #include "base/metrics/histogram_macros.h" | 15 #include "base/metrics/histogram_macros.h" |
| 16 #include "build/build_config.h" | 16 #include "build/build_config.h" |
| 17 #include "chrome/browser/metrics/metrics_reporting_state.h" | 17 #include "chrome/browser/metrics/metrics_reporting_state.h" |
| 18 #include "chrome/browser/prefs/session_startup_pref.h" |
| 18 #include "chrome/browser/sessions/session_restore.h" | 19 #include "chrome/browser/sessions/session_restore.h" |
| 19 #include "chrome/browser/ui/browser_list.h" | 20 #include "chrome/browser/ui/browser_list.h" |
| 20 #include "chrome/browser/ui/browser_list_observer.h" | 21 #include "chrome/browser/ui/browser_list_observer.h" |
| 21 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 22 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 22 #include "chrome/browser/ui/views/frame/browser_view.h" | 23 #include "chrome/browser/ui/views/frame/browser_view.h" |
| 23 #include "chrome/browser/ui/views/toolbar/app_menu_button.h" | 24 #include "chrome/browser/ui/views/toolbar/app_menu_button.h" |
| 24 #include "chrome/browser/ui/views/toolbar/toolbar_view.h" | 25 #include "chrome/browser/ui/views/toolbar/toolbar_view.h" |
| 25 #include "chrome/grit/chromium_strings.h" | 26 #include "chrome/grit/chromium_strings.h" |
| 26 #include "chrome/grit/generated_resources.h" | 27 #include "chrome/grit/generated_resources.h" |
| 27 #include "chrome/installer/util/google_update_settings.h" | 28 #include "chrome/installer/util/google_update_settings.h" |
| (...skipping 26 matching lines...) Expand all Loading... |
| 54 | 55 |
| 55 enum SessionCrashedBubbleHistogramValue { | 56 enum SessionCrashedBubbleHistogramValue { |
| 56 SESSION_CRASHED_BUBBLE_SHOWN, | 57 SESSION_CRASHED_BUBBLE_SHOWN, |
| 57 SESSION_CRASHED_BUBBLE_ERROR, | 58 SESSION_CRASHED_BUBBLE_ERROR, |
| 58 SESSION_CRASHED_BUBBLE_RESTORED, | 59 SESSION_CRASHED_BUBBLE_RESTORED, |
| 59 SESSION_CRASHED_BUBBLE_ALREADY_UMA_OPTIN, | 60 SESSION_CRASHED_BUBBLE_ALREADY_UMA_OPTIN, |
| 60 SESSION_CRASHED_BUBBLE_UMA_OPTIN, | 61 SESSION_CRASHED_BUBBLE_UMA_OPTIN, |
| 61 SESSION_CRASHED_BUBBLE_HELP, | 62 SESSION_CRASHED_BUBBLE_HELP, |
| 62 SESSION_CRASHED_BUBBLE_IGNORED, | 63 SESSION_CRASHED_BUBBLE_IGNORED, |
| 63 SESSION_CRASHED_BUBBLE_OPTIN_BAR_SHOWN, | 64 SESSION_CRASHED_BUBBLE_OPTIN_BAR_SHOWN, |
| 65 SESSION_CRASHED_BUBBLE_STARTUP_PAGES, |
| 64 SESSION_CRASHED_BUBBLE_MAX, | 66 SESSION_CRASHED_BUBBLE_MAX, |
| 65 }; | 67 }; |
| 66 | 68 |
| 67 void RecordBubbleHistogramValue(SessionCrashedBubbleHistogramValue value) { | 69 void RecordBubbleHistogramValue(SessionCrashedBubbleHistogramValue value) { |
| 68 UMA_HISTOGRAM_ENUMERATION( | 70 UMA_HISTOGRAM_ENUMERATION( |
| 69 "SessionCrashed.Bubble", value, SESSION_CRASHED_BUBBLE_MAX); | 71 "SessionCrashed.Bubble", value, SESSION_CRASHED_BUBBLE_MAX); |
| 70 } | 72 } |
| 71 | 73 |
| 72 // Whether or not the bubble UI should be used. | 74 // Whether or not the bubble UI should be used. |
| 73 // TODO(crbug.com/653966): Enable this on all desktop platforms. | 75 // TODO(crbug.com/653966): Enable this on all desktop platforms. |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 167 ->app_menu_button(); | 169 ->app_menu_button(); |
| 168 SessionCrashedBubbleView* crash_bubble = | 170 SessionCrashedBubbleView* crash_bubble = |
| 169 new SessionCrashedBubbleView(anchor_view, browser, offer_uma_optin); | 171 new SessionCrashedBubbleView(anchor_view, browser, offer_uma_optin); |
| 170 views::BubbleDialogDelegateView::CreateBubble(crash_bubble)->Show(); | 172 views::BubbleDialogDelegateView::CreateBubble(crash_bubble)->Show(); |
| 171 | 173 |
| 172 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_SHOWN); | 174 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_SHOWN); |
| 173 if (uma_opted_in_already) | 175 if (uma_opted_in_already) |
| 174 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_ALREADY_UMA_OPTIN); | 176 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_ALREADY_UMA_OPTIN); |
| 175 } | 177 } |
| 176 | 178 |
| 177 SessionCrashedBubbleView::SessionCrashedBubbleView( | 179 SessionCrashedBubbleView::SessionCrashedBubbleView(views::View* anchor_view, |
| 178 views::View* anchor_view, | 180 Browser* browser, |
| 179 Browser* browser, | 181 bool offer_uma_optin) |
| 180 bool offer_uma_optin) | |
| 181 : BubbleDialogDelegateView(anchor_view, views::BubbleBorder::TOP_RIGHT), | 182 : BubbleDialogDelegateView(anchor_view, views::BubbleBorder::TOP_RIGHT), |
| 182 browser_(browser), | 183 browser_(browser), |
| 183 uma_option_(NULL), | 184 uma_option_(NULL), |
| 184 offer_uma_optin_(offer_uma_optin), | 185 offer_uma_optin_(offer_uma_optin), |
| 185 restored_(false) { | 186 ignored_(true) { |
| 186 set_close_on_deactivate(false); | 187 set_close_on_deactivate(false); |
| 187 } | 188 } |
| 188 | 189 |
| 189 SessionCrashedBubbleView::~SessionCrashedBubbleView() { | 190 SessionCrashedBubbleView::~SessionCrashedBubbleView() { |
| 190 } | 191 } |
| 191 | 192 |
| 192 base::string16 SessionCrashedBubbleView::GetWindowTitle() const { | 193 base::string16 SessionCrashedBubbleView::GetWindowTitle() const { |
| 193 return l10n_util::GetStringUTF16(IDS_SESSION_CRASHED_BUBBLE_TITLE); | 194 return l10n_util::GetStringUTF16(IDS_SESSION_CRASHED_BUBBLE_TITLE); |
| 194 } | 195 } |
| 195 | 196 |
| 196 bool SessionCrashedBubbleView::ShouldShowWindowTitle() const { | 197 bool SessionCrashedBubbleView::ShouldShowWindowTitle() const { |
| 197 return true; | 198 return true; |
| 198 } | 199 } |
| 199 | 200 |
| 200 bool SessionCrashedBubbleView::ShouldShowCloseButton() const { | 201 bool SessionCrashedBubbleView::ShouldShowCloseButton() const { |
| 201 return true; | 202 return true; |
| 202 } | 203 } |
| 203 | 204 |
| 204 void SessionCrashedBubbleView::OnWidgetDestroying(views::Widget* widget) { | 205 void SessionCrashedBubbleView::OnWidgetDestroying(views::Widget* widget) { |
| 205 if (!restored_) | 206 if (ignored_) |
| 206 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_IGNORED); | 207 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_IGNORED); |
| 207 BubbleDialogDelegateView::OnWidgetDestroying(widget); | 208 BubbleDialogDelegateView::OnWidgetDestroying(widget); |
| 208 } | 209 } |
| 209 | 210 |
| 210 void SessionCrashedBubbleView::Init() { | 211 void SessionCrashedBubbleView::Init() { |
| 211 SetLayoutManager(new views::FillLayout()); | 212 SetLayoutManager(new views::FillLayout()); |
| 212 | 213 |
| 213 // Description text label. | 214 // Description text label. |
| 214 views::Label* text_label = new views::Label( | 215 views::Label* text_label = new views::Label( |
| 215 l10n_util::GetStringUTF16(IDS_SESSION_CRASHED_VIEW_MESSAGE)); | 216 l10n_util::GetStringUTF16(IDS_SESSION_CRASHED_VIEW_MESSAGE)); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 uma_layout->AddView(uma_label); | 277 uma_layout->AddView(uma_label); |
| 277 | 278 |
| 278 return uma_view; | 279 return uma_view; |
| 279 } | 280 } |
| 280 | 281 |
| 281 bool SessionCrashedBubbleView::Accept() { | 282 bool SessionCrashedBubbleView::Accept() { |
| 282 RestorePreviousSession(); | 283 RestorePreviousSession(); |
| 283 return true; | 284 return true; |
| 284 } | 285 } |
| 285 | 286 |
| 287 // The cancel button is used as an option to open the startup pages instead of |
| 288 // restoring the previous session. |
| 289 bool SessionCrashedBubbleView::Cancel() { |
| 290 OpenStartupPages(); |
| 291 return true; |
| 292 } |
| 293 |
| 286 bool SessionCrashedBubbleView::Close() { | 294 bool SessionCrashedBubbleView::Close() { |
| 287 // Don't default to Accept() just because that's the only choice. Instead, do | 295 // Don't default to Accept() just because that's the only choice. Instead, do |
| 288 // nothing. | 296 // nothing. |
| 289 return true; | 297 return true; |
| 290 } | 298 } |
| 291 | 299 |
| 292 int SessionCrashedBubbleView::GetDialogButtons() const { | 300 int SessionCrashedBubbleView::GetDialogButtons() const { |
| 293 return ui::DIALOG_BUTTON_OK; | 301 int buttons = ui::DIALOG_BUTTON_OK; |
| 302 // Offer the option to open the startup pages using the cancel button, but |
| 303 // only when the user has selected the URLS option, and set at least one url. |
| 304 SessionStartupPref session_startup_pref = |
| 305 SessionStartupPref::GetStartupPref(browser_->profile()); |
| 306 if (session_startup_pref.type == SessionStartupPref::URLS && |
| 307 !session_startup_pref.urls.empty()) { |
| 308 buttons |= ui::DIALOG_BUTTON_CANCEL; |
| 309 } |
| 310 return buttons; |
| 294 } | 311 } |
| 295 | 312 |
| 296 base::string16 SessionCrashedBubbleView::GetDialogButtonLabel( | 313 base::string16 SessionCrashedBubbleView::GetDialogButtonLabel( |
| 297 ui::DialogButton button) const { | 314 ui::DialogButton button) const { |
| 298 return l10n_util::GetStringUTF16(IDS_SESSION_CRASHED_VIEW_RESTORE_BUTTON); | 315 if (button == ui::DIALOG_BUTTON_OK) |
| 316 return l10n_util::GetStringUTF16(IDS_SESSION_CRASHED_VIEW_RESTORE_BUTTON); |
| 317 DCHECK_EQ(ui::DIALOG_BUTTON_CANCEL, button); |
| 318 return l10n_util::GetStringUTF16( |
| 319 IDS_SESSION_CRASHED_VIEW_STARTUP_PAGES_BUTTON); |
| 299 } | 320 } |
| 300 | 321 |
| 301 void SessionCrashedBubbleView::StyledLabelLinkClicked(views::StyledLabel* label, | 322 void SessionCrashedBubbleView::StyledLabelLinkClicked(views::StyledLabel* label, |
| 302 const gfx::Range& range, | 323 const gfx::Range& range, |
| 303 int event_flags) { | 324 int event_flags) { |
| 304 browser_->OpenURL(content::OpenURLParams( | 325 browser_->OpenURL(content::OpenURLParams( |
| 305 GURL("https://support.google.com/chrome/answer/96817"), | 326 GURL("https://support.google.com/chrome/answer/96817"), |
| 306 content::Referrer(), WindowOpenDisposition::NEW_FOREGROUND_TAB, | 327 content::Referrer(), WindowOpenDisposition::NEW_FOREGROUND_TAB, |
| 307 ui::PAGE_TRANSITION_LINK, false)); | 328 ui::PAGE_TRANSITION_LINK, false)); |
| 308 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_HELP); | 329 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_HELP); |
| 309 } | 330 } |
| 310 | 331 |
| 311 void SessionCrashedBubbleView::RestorePreviousSession() { | 332 void SessionCrashedBubbleView::RestorePreviousSession() { |
| 333 ignored_ = false; |
| 334 MaybeEnableUMA(); |
| 335 CloseBubble(); |
| 336 |
| 337 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_RESTORED); |
| 338 // Restoring tabs has side effects, so it's preferable to do it after the |
| 339 // bubble was closed. |
| 312 SessionRestore::RestoreSessionAfterCrash(browser_); | 340 SessionRestore::RestoreSessionAfterCrash(browser_); |
| 313 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_RESTORED); | 341 } |
| 314 restored_ = true; | |
| 315 | 342 |
| 343 void SessionCrashedBubbleView::OpenStartupPages() { |
| 344 ignored_ = false; |
| 345 MaybeEnableUMA(); |
| 346 CloseBubble(); |
| 347 |
| 348 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_STARTUP_PAGES); |
| 349 // Opening tabs has side effects, so it's preferable to do it after the bubble |
| 350 // was closed. |
| 351 SessionRestore::OpenStartupPagesAfterCrash(browser_); |
| 352 } |
| 353 |
| 354 void SessionCrashedBubbleView::MaybeEnableUMA() { |
| 316 // Record user's choice for opt-in in to UMA. | 355 // Record user's choice for opt-in in to UMA. |
| 317 // There's no opt-out choice in the crash restore bubble. | 356 // There's no opt-out choice in the crash restore bubble. |
| 318 if (uma_option_ && uma_option_->checked()) { | 357 if (uma_option_ && uma_option_->checked()) { |
| 319 ChangeMetricsReportingState(true); | 358 ChangeMetricsReportingState(true); |
| 320 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_UMA_OPTIN); | 359 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_UMA_OPTIN); |
| 321 } | 360 } |
| 361 } |
| 362 |
| 363 void SessionCrashedBubbleView::CloseBubble() { |
| 322 GetWidget()->Close(); | 364 GetWidget()->Close(); |
| 323 } | 365 } |
| OLD | NEW |