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

Side by Side Diff: chrome/browser/ui/views/session_crashed_bubble_view.cc

Issue 341823005: Collects stats on how user interacts with the bubble. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Nits Created 6 years, 5 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
OLDNEW
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 <vector> 7 #include <vector>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/metrics/field_trial.h" 12 #include "base/metrics/field_trial.h"
13 #include "base/metrics/histogram.h"
13 #include "base/prefs/pref_service.h" 14 #include "base/prefs/pref_service.h"
14 #include "chrome/browser/browser_process.h" 15 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/chrome_notification_types.h" 16 #include "chrome/browser/chrome_notification_types.h"
16 #include "chrome/browser/sessions/session_restore.h" 17 #include "chrome/browser/sessions/session_restore.h"
17 #include "chrome/browser/ui/browser_list.h" 18 #include "chrome/browser/ui/browser_list.h"
18 #include "chrome/browser/ui/browser_list_observer.h" 19 #include "chrome/browser/ui/browser_list_observer.h"
19 #include "chrome/browser/ui/options/options_util.h" 20 #include "chrome/browser/ui/options/options_util.h"
20 #include "chrome/browser/ui/startup/session_crashed_bubble.h" 21 #include "chrome/browser/ui/startup/session_crashed_bubble.h"
21 #include "chrome/browser/ui/startup/startup_browser_creator_impl.h" 22 #include "chrome/browser/ui/startup/startup_browser_creator_impl.h"
22 #include "chrome/browser/ui/tabs/tab_strip_model.h" 23 #include "chrome/browser/ui/tabs/tab_strip_model.h"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 59
59 // The color of the text and background of the sub panel to offer UMA optin. 60 // The color of the text and background of the sub panel to offer UMA optin.
60 // These values match the BookmarkSyncPromoView colors. 61 // These values match the BookmarkSyncPromoView colors.
61 const SkColor kBackgroundColor = SkColorSetRGB(245, 245, 245); 62 const SkColor kBackgroundColor = SkColorSetRGB(245, 245, 245);
62 const SkColor kTextColor = SkColorSetRGB(102, 102, 102); 63 const SkColor kTextColor = SkColorSetRGB(102, 102, 102);
63 64
64 // The Finch study name and group name that enables session crashed bubble UI. 65 // The Finch study name and group name that enables session crashed bubble UI.
65 const char kEnableBubbleUIFinchName[] = "EnableSessionCrashedBubbleUI"; 66 const char kEnableBubbleUIFinchName[] = "EnableSessionCrashedBubbleUI";
66 const char kEnableBubbleUIGroupEnabled[] = "Enabled"; 67 const char kEnableBubbleUIGroupEnabled[] = "Enabled";
67 68
69 enum SessionCrashedBubbleHistogramValue {
70 SESSION_CRASHED_BUBBLE_SHOWN,
71 SESSION_CRASHED_BUBBLE_ERROR,
72 SESSION_CRASHED_BUBBLE_RESTORED,
73 SESSION_CRASHED_BUBBLE_ALREADY_UMA_OPTIN,
74 SESSION_CRASHED_BUBBLE_UMA_OPTIN,
75 SESSION_CRASHED_BUBBLE_HELP,
76 SESSION_CRASHED_BUBBLE_IGNORED,
77 SESSION_CRASHED_BUBBLE_MAX,
78 };
79
80 void RecordBubbleHistogramValue(SessionCrashedBubbleHistogramValue value) {
81 UMA_HISTOGRAM_ENUMERATION(
82 "SessionCrashed.Bubble", value, SESSION_CRASHED_BUBBLE_MAX);
83 }
84
68 bool ShouldOfferMetricsReporting() { 85 bool ShouldOfferMetricsReporting() {
69 // Stats collection only applies to Google Chrome builds. 86 // Stats collection only applies to Google Chrome builds.
70 #if defined(GOOGLE_CHROME_BUILD) 87 #if defined(GOOGLE_CHROME_BUILD)
71 // Only show metrics reporting option if user didn't already consent to it. 88 // Only show metrics reporting option if user didn't already consent to it.
72 if (GoogleUpdateSettings::GetCollectStatsConsent()) 89 if (GoogleUpdateSettings::GetCollectStatsConsent()) {
90 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_ALREADY_UMA_OPTIN);
73 return false; 91 return false;
92 }
74 return g_browser_process->local_state()->FindPreference( 93 return g_browser_process->local_state()->FindPreference(
75 prefs::kMetricsReportingEnabled)->IsUserModifiable(); 94 prefs::kMetricsReportingEnabled)->IsUserModifiable();
Alexei Svitkine (slow) 2014/07/02 15:07:26 Hmm, I just noticed that this is wrong. Since you'
yao 2014/07/07 17:47:45 CL on the way.
76 #else 95 #else
77 return false; 96 return false;
78 #endif // defined(GOOGLE_CHROME_BUILD) 97 #endif // defined(GOOGLE_CHROME_BUILD)
79 } 98 }
80 99
81 // Whether or not the bubble UI should be used. 100 // Whether or not the bubble UI should be used.
82 bool IsBubbleUIEnabled() { 101 bool IsBubbleUIEnabled() {
83 const base::CommandLine& command_line = *CommandLine::ForCurrentProcess(); 102 const base::CommandLine& command_line = *CommandLine::ForCurrentProcess();
84 if (command_line.HasSwitch(switches::kDisableSessionCrashedBubble)) 103 if (command_line.HasSwitch(switches::kDisableSessionCrashedBubble))
85 return false; 104 return false;
86 if (command_line.HasSwitch(switches::kEnableSessionCrashedBubble)) 105 if (command_line.HasSwitch(switches::kEnableSessionCrashedBubble))
87 return true; 106 return true;
88 const std::string group_name = base::FieldTrialList::FindFullName( 107 const std::string group_name = base::FieldTrialList::FindFullName(
89 kEnableBubbleUIFinchName); 108 kEnableBubbleUIFinchName);
90 return group_name == kEnableBubbleUIGroupEnabled; 109 return group_name == kEnableBubbleUIGroupEnabled;
91 } 110 }
92 111
112 // Will be passed in as a callback function to BubbleFrameView. Before the
113 // bubble is closed (by the close button), collect the usage stats.
114 void BubbleToBeClosed() {
115 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_IGNORED);
116 }
117
93 } // namespace 118 } // namespace
94 119
95 // A helper class that listens to browser removal event. 120 // A helper class that listens to browser removal event.
96 class SessionCrashedBubbleView::BrowserRemovalObserver 121 class SessionCrashedBubbleView::BrowserRemovalObserver
97 : public chrome::BrowserListObserver { 122 : public chrome::BrowserListObserver {
98 public: 123 public:
99 explicit BrowserRemovalObserver(Browser* browser) : browser_(browser) { 124 explicit BrowserRemovalObserver(Browser* browser) : browser_(browser) {
100 DCHECK(browser_); 125 DCHECK(browser_);
101 BrowserList::AddObserver(this); 126 BrowserList::AddObserver(this);
102 } 127 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 base::Bind(&SessionCrashedBubbleView::ShowForReal, 164 base::Bind(&SessionCrashedBubbleView::ShowForReal,
140 base::Passed(&browser_observer))); 165 base::Passed(&browser_observer)));
141 } 166 }
142 167
143 // static 168 // static
144 void SessionCrashedBubbleView::ShowForReal( 169 void SessionCrashedBubbleView::ShowForReal(
145 scoped_ptr<BrowserRemovalObserver> browser_observer, 170 scoped_ptr<BrowserRemovalObserver> browser_observer,
146 bool offer_uma_optin) { 171 bool offer_uma_optin) {
147 Browser* browser = browser_observer->browser(); 172 Browser* browser = browser_observer->browser();
148 173
149 if (!browser) 174 if (!browser) {
175 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_ERROR);
150 return; 176 return;
177 }
151 178
152 views::View* anchor_view = 179 views::View* anchor_view =
153 BrowserView::GetBrowserViewForBrowser(browser)->toolbar()->app_menu(); 180 BrowserView::GetBrowserViewForBrowser(browser)->toolbar()->app_menu();
154 content::WebContents* web_contents = 181 content::WebContents* web_contents =
155 browser->tab_strip_model()->GetActiveWebContents(); 182 browser->tab_strip_model()->GetActiveWebContents();
156 183
157 if (!web_contents) 184 if (!web_contents) {
185 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_ERROR);
158 return; 186 return;
187 }
159 188
160 SessionCrashedBubbleView* crash_bubble = 189 SessionCrashedBubbleView* crash_bubble =
161 new SessionCrashedBubbleView(anchor_view, browser, web_contents, 190 new SessionCrashedBubbleView(anchor_view, browser, web_contents,
162 offer_uma_optin); 191 offer_uma_optin);
163 views::BubbleDelegateView::CreateBubble(crash_bubble)->Show(); 192 views::BubbleDelegateView::CreateBubble(crash_bubble)->Show();
193 views::BubbleFrameView* frame_view = crash_bubble->GetBubbleFrameView();
194 if (frame_view) {
195 frame_view->SetCloseCallback(base::Bind(&BubbleToBeClosed));
196 }
197 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_SHOWN);
164 } 198 }
165 199
166 SessionCrashedBubbleView::SessionCrashedBubbleView( 200 SessionCrashedBubbleView::SessionCrashedBubbleView(
167 views::View* anchor_view, 201 views::View* anchor_view,
168 Browser* browser, 202 Browser* browser,
169 content::WebContents* web_contents, 203 content::WebContents* web_contents,
170 bool offer_uma_optin) 204 bool offer_uma_optin)
171 : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_RIGHT), 205 : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_RIGHT),
172 content::WebContentsObserver(web_contents), 206 content::WebContentsObserver(web_contents),
173 browser_(browser), 207 browser_(browser),
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 layout->AddView(new views::Separator(views::Separator::HORIZONTAL)); 351 layout->AddView(new views::Separator(views::Separator::HORIZONTAL));
318 layout->StartRow(0, kReportColumnSetId); 352 layout->StartRow(0, kReportColumnSetId);
319 layout->AddView(uma_option_); 353 layout->AddView(uma_option_);
320 layout->AddView(uma_label); 354 layout->AddView(uma_label);
321 } 355 }
322 356
323 void SessionCrashedBubbleView::ButtonPressed(views::Button* sender, 357 void SessionCrashedBubbleView::ButtonPressed(views::Button* sender,
324 const ui::Event& event) { 358 const ui::Event& event) {
325 DCHECK_EQ(sender, restore_button_); 359 DCHECK_EQ(sender, restore_button_);
326 RestorePreviousSession(sender); 360 RestorePreviousSession(sender);
361 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_RESTORED);
327 } 362 }
328 363
329 void SessionCrashedBubbleView::StyledLabelLinkClicked(const gfx::Range& range, 364 void SessionCrashedBubbleView::StyledLabelLinkClicked(const gfx::Range& range,
330 int event_flags) { 365 int event_flags) {
331 browser_->OpenURL(content::OpenURLParams( 366 browser_->OpenURL(content::OpenURLParams(
332 GURL("https://support.google.com/chrome/answer/96817"), 367 GURL("https://support.google.com/chrome/answer/96817"),
333 content::Referrer(), 368 content::Referrer(),
334 NEW_FOREGROUND_TAB, 369 NEW_FOREGROUND_TAB,
335 content::PAGE_TRANSITION_LINK, 370 content::PAGE_TRANSITION_LINK,
336 false)); 371 false));
372 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_HELP);
337 } 373 }
338 374
339 void SessionCrashedBubbleView::DidStartNavigationToPendingEntry( 375 void SessionCrashedBubbleView::DidStartNavigationToPendingEntry(
340 const GURL& url, 376 const GURL& url,
341 content::NavigationController::ReloadType reload_type) { 377 content::NavigationController::ReloadType reload_type) {
342 started_navigation_ = true; 378 started_navigation_ = true;
343 } 379 }
344 380
345 void SessionCrashedBubbleView::DidFinishLoad( 381 void SessionCrashedBubbleView::DidFinishLoad(
346 int64 frame_id, 382 int64 frame_id,
347 const GURL& validated_url, 383 const GURL& validated_url,
348 bool is_main_frame, 384 bool is_main_frame,
349 content::RenderViewHost* render_view_host) { 385 content::RenderViewHost* render_view_host) {
350 if (started_navigation_) 386 if (started_navigation_) {
387 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_IGNORED);
351 CloseBubble(); 388 CloseBubble();
389 }
352 } 390 }
353 391
354 void SessionCrashedBubbleView::WasShown() { 392 void SessionCrashedBubbleView::WasShown() {
355 GetWidget()->Show(); 393 GetWidget()->Show();
356 } 394 }
357 395
358 void SessionCrashedBubbleView::WasHidden() { 396 void SessionCrashedBubbleView::WasHidden() {
359 GetWidget()->Hide(); 397 GetWidget()->Hide();
360 } 398 }
361 399
362 void SessionCrashedBubbleView::Observe( 400 void SessionCrashedBubbleView::Observe(
363 int type, 401 int type,
364 const content::NotificationSource& source, 402 const content::NotificationSource& source,
365 const content::NotificationDetails& details) { 403 const content::NotificationDetails& details) {
366 if (type == chrome::NOTIFICATION_TAB_CLOSING) 404 if (type == chrome::NOTIFICATION_TAB_CLOSING) {
405 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_IGNORED);
367 CloseBubble(); 406 CloseBubble();
407 }
368 } 408 }
369 409
370 void SessionCrashedBubbleView::TabDetachedAt(content::WebContents* contents, 410 void SessionCrashedBubbleView::TabDetachedAt(content::WebContents* contents,
371 int index) { 411 int index) {
372 if (web_contents_ == contents) 412 if (web_contents_ == contents) {
413 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_IGNORED);
373 CloseBubble(); 414 CloseBubble();
415 }
374 } 416 }
375 417
376 void SessionCrashedBubbleView::RestorePreviousSession(views::Button* sender) { 418 void SessionCrashedBubbleView::RestorePreviousSession(views::Button* sender) {
377 SessionRestore::RestoreSessionAfterCrash(browser_); 419 SessionRestore::RestoreSessionAfterCrash(browser_);
378 420
379 // Record user's choice for opting in to UMA. 421 // Record user's choice for opting in to UMA.
380 // There's no opting-out choice in the crash restore bubble. 422 // There's no opting-out choice in the crash restore bubble.
381 if (uma_option_ && uma_option_->checked()) { 423 if (uma_option_ && uma_option_->checked()) {
382 // TODO: Clean up function ResolveMetricsReportingEnabled so that user pref 424 // TODO: Clean up function ResolveMetricsReportingEnabled so that user pref
383 // is stored automatically. 425 // is stored automatically.
384 OptionsUtil::ResolveMetricsReportingEnabled(true); 426 OptionsUtil::ResolveMetricsReportingEnabled(true);
385 g_browser_process->local_state()->SetBoolean( 427 g_browser_process->local_state()->SetBoolean(
386 prefs::kMetricsReportingEnabled, true); 428 prefs::kMetricsReportingEnabled, true);
429 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_UMA_OPTIN);
387 } 430 }
388 CloseBubble(); 431 CloseBubble();
389 } 432 }
390 433
391 void SessionCrashedBubbleView::CloseBubble() { 434 void SessionCrashedBubbleView::CloseBubble() {
392 GetWidget()->Close(); 435 GetWidget()->Close();
393 } 436 }
394 437
395 bool ShowSessionCrashedBubble(Browser* browser) { 438 bool ShowSessionCrashedBubble(Browser* browser) {
396 if (IsBubbleUIEnabled()) { 439 if (IsBubbleUIEnabled()) {
397 SessionCrashedBubbleView::Show(browser); 440 SessionCrashedBubbleView::Show(browser);
398 return true; 441 return true;
399 } 442 }
400 return false; 443 return false;
401 } 444 }
OLDNEW
« no previous file with comments | « no previous file | tools/metrics/histograms/histograms.xml » ('j') | ui/views/bubble/bubble_frame_view.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698