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

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: Add callk to super's virtual function 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 // Whether or not the bubble UI should be used. 85 // Whether or not the bubble UI should be used.
69 bool IsBubbleUIEnabled() { 86 bool IsBubbleUIEnabled() {
70 const base::CommandLine& command_line = *CommandLine::ForCurrentProcess(); 87 const base::CommandLine& command_line = *CommandLine::ForCurrentProcess();
71 if (command_line.HasSwitch(switches::kDisableSessionCrashedBubble)) 88 if (command_line.HasSwitch(switches::kDisableSessionCrashedBubble))
72 return false; 89 return false;
73 if (command_line.HasSwitch(switches::kEnableSessionCrashedBubble)) 90 if (command_line.HasSwitch(switches::kEnableSessionCrashedBubble))
74 return true; 91 return true;
75 const std::string group_name = base::FieldTrialList::FindFullName( 92 const std::string group_name = base::FieldTrialList::FindFullName(
76 kEnableBubbleUIFinchName); 93 kEnableBubbleUIFinchName);
77 return group_name == kEnableBubbleUIGroupEnabled; 94 return group_name == kEnableBubbleUIGroupEnabled;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 128 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
112 if (browser->profile()->IsOffTheRecord()) 129 if (browser->profile()->IsOffTheRecord())
113 return; 130 return;
114 131
115 // Observes browser removal event and will be deallocated in ShowForReal. 132 // Observes browser removal event and will be deallocated in ShowForReal.
116 scoped_ptr<BrowserRemovalObserver> browser_observer( 133 scoped_ptr<BrowserRemovalObserver> browser_observer(
117 new BrowserRemovalObserver(browser)); 134 new BrowserRemovalObserver(browser));
118 135
119 // Stats collection only applies to Google Chrome builds. 136 // Stats collection only applies to Google Chrome builds.
120 #if defined(GOOGLE_CHROME_BUILD) 137 #if defined(GOOGLE_CHROME_BUILD)
121 // Schedule a task to run ShouldOfferMetricsReporting() on FILE thread, since 138 // Schedule a task to run GoogleUpdateSettings::GetCollectStatsConsent() on
122 // GoogleUpdateSettings::GetCollectStatsConsent() does IO. Then, call 139 // FILE thread, since it does IO. Then, call
123 // SessionCrashedBubbleView::ShowForReal with the result. 140 // SessionCrashedBubbleView::ShowForReal with the result.
124 content::BrowserThread::PostTaskAndReplyWithResult( 141 content::BrowserThread::PostTaskAndReplyWithResult(
125 content::BrowserThread::FILE, 142 content::BrowserThread::FILE,
126 FROM_HERE, 143 FROM_HERE,
127 base::Bind(&GoogleUpdateSettings::GetCollectStatsConsent), 144 base::Bind(&GoogleUpdateSettings::GetCollectStatsConsent),
128 base::Bind(&SessionCrashedBubbleView::ShowForReal, 145 base::Bind(&SessionCrashedBubbleView::ShowForReal,
129 base::Passed(&browser_observer))); 146 base::Passed(&browser_observer)));
130 #else 147 #else
131 SessionCrashedBubbleView::ShowForReal(browser_observer.Pass(), false); 148 SessionCrashedBubbleView::ShowForReal(browser_observer.Pass(), false);
132 #endif // defined(GOOGLE_CHROME_BUILD) 149 #endif // defined(GOOGLE_CHROME_BUILD)
133 } 150 }
134 151
135 // static 152 // static
136 void SessionCrashedBubbleView::ShowForReal( 153 void SessionCrashedBubbleView::ShowForReal(
137 scoped_ptr<BrowserRemovalObserver> browser_observer, 154 scoped_ptr<BrowserRemovalObserver> browser_observer,
138 bool uma_opted_in_already) { 155 bool uma_opted_in_already) {
139 // Determine whether or not the uma opt-in option should be offered. It is 156 // Determine whether or not the uma opt-in option should be offered. It is
140 // offered only when it is a Google chrome build, user hasn't opted in yet, 157 // offered only when it is a Google chrome build, user hasn't opted in yet,
141 // and the preference is modifiable by the user. 158 // and the preference is modifiable by the user.
142 bool offer_uma_optin = false; 159 bool offer_uma_optin = false;
143 160
144 #if defined(GOOGLE_CHROME_BUILD) 161 #if defined(GOOGLE_CHROME_BUILD)
145 if (!uma_opted_in_already) 162 if (uma_opted_in_already) {
163 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_ALREADY_UMA_OPTIN);
164 } else {
146 offer_uma_optin = g_browser_process->local_state()->FindPreference( 165 offer_uma_optin = g_browser_process->local_state()->FindPreference(
147 prefs::kMetricsReportingEnabled)->IsUserModifiable(); 166 prefs::kMetricsReportingEnabled)->IsUserModifiable();
167 }
148 #endif // defined(GOOGLE_CHROME_BUILD) 168 #endif // defined(GOOGLE_CHROME_BUILD)
149 169
150 Browser* browser = browser_observer->browser(); 170 Browser* browser = browser_observer->browser();
151 171
152 if (!browser) 172 if (!browser) {
173 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_ERROR);
153 return; 174 return;
175 }
154 176
155 views::View* anchor_view = 177 views::View* anchor_view =
156 BrowserView::GetBrowserViewForBrowser(browser)->toolbar()->app_menu(); 178 BrowserView::GetBrowserViewForBrowser(browser)->toolbar()->app_menu();
157 content::WebContents* web_contents = 179 content::WebContents* web_contents =
158 browser->tab_strip_model()->GetActiveWebContents(); 180 browser->tab_strip_model()->GetActiveWebContents();
159 181
160 if (!web_contents) 182 if (!web_contents) {
183 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_ERROR);
161 return; 184 return;
185 }
162 186
163 SessionCrashedBubbleView* crash_bubble = 187 SessionCrashedBubbleView* crash_bubble =
164 new SessionCrashedBubbleView(anchor_view, browser, web_contents, 188 new SessionCrashedBubbleView(anchor_view, browser, web_contents,
165 offer_uma_optin); 189 offer_uma_optin);
166 views::BubbleDelegateView::CreateBubble(crash_bubble)->Show(); 190 views::BubbleDelegateView::CreateBubble(crash_bubble)->Show();
191 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_SHOWN);
167 } 192 }
168 193
169 SessionCrashedBubbleView::SessionCrashedBubbleView( 194 SessionCrashedBubbleView::SessionCrashedBubbleView(
170 views::View* anchor_view, 195 views::View* anchor_view,
171 Browser* browser, 196 Browser* browser,
172 content::WebContents* web_contents, 197 content::WebContents* web_contents,
173 bool offer_uma_optin) 198 bool offer_uma_optin)
174 : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_RIGHT), 199 : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_RIGHT),
175 content::WebContentsObserver(web_contents), 200 content::WebContentsObserver(web_contents),
176 browser_(browser), 201 browser_(browser),
177 web_contents_(web_contents), 202 web_contents_(web_contents),
178 restore_button_(NULL), 203 restore_button_(NULL),
179 uma_option_(NULL), 204 uma_option_(NULL),
180 offer_uma_optin_(offer_uma_optin), 205 offer_uma_optin_(offer_uma_optin),
181 started_navigation_(false) { 206 started_navigation_(false),
207 restored_(false) {
182 set_close_on_deactivate(false); 208 set_close_on_deactivate(false);
183 registrar_.Add( 209 registrar_.Add(
184 this, 210 this,
185 chrome::NOTIFICATION_TAB_CLOSING, 211 chrome::NOTIFICATION_TAB_CLOSING,
186 content::Source<content::NavigationController>(&( 212 content::Source<content::NavigationController>(&(
187 web_contents->GetController()))); 213 web_contents->GetController())));
188 browser->tab_strip_model()->AddObserver(this); 214 browser->tab_strip_model()->AddObserver(this);
189 } 215 }
190 216
191 SessionCrashedBubbleView::~SessionCrashedBubbleView() { 217 SessionCrashedBubbleView::~SessionCrashedBubbleView() {
192 browser_->tab_strip_model()->RemoveObserver(this); 218 browser_->tab_strip_model()->RemoveObserver(this);
193 } 219 }
194 220
195 views::View* SessionCrashedBubbleView::GetInitiallyFocusedView() { 221 views::View* SessionCrashedBubbleView::GetInitiallyFocusedView() {
196 return restore_button_; 222 return restore_button_;
197 } 223 }
198 224
199 base::string16 SessionCrashedBubbleView::GetWindowTitle() const { 225 base::string16 SessionCrashedBubbleView::GetWindowTitle() const {
200 return l10n_util::GetStringUTF16(IDS_SESSION_CRASHED_BUBBLE_TITLE); 226 return l10n_util::GetStringUTF16(IDS_SESSION_CRASHED_BUBBLE_TITLE);
201 } 227 }
202 228
203 bool SessionCrashedBubbleView::ShouldShowWindowTitle() const { 229 bool SessionCrashedBubbleView::ShouldShowWindowTitle() const {
204 return true; 230 return true;
205 } 231 }
206 232
207 bool SessionCrashedBubbleView::ShouldShowCloseButton() const { 233 bool SessionCrashedBubbleView::ShouldShowCloseButton() const {
208 return true; 234 return true;
209 } 235 }
210 236
237 void SessionCrashedBubbleView::OnWidgetDestroying(views::Widget* widget) {
238 if (!restored_)
239 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_IGNORED);
240 BubbleDelegateView::OnWidgetDestroying(widget);
241 }
242
211 void SessionCrashedBubbleView::Init() { 243 void SessionCrashedBubbleView::Init() {
212 // Description text label. 244 // Description text label.
213 views::Label* text_label = new views::Label( 245 views::Label* text_label = new views::Label(
214 l10n_util::GetStringUTF16(IDS_SESSION_CRASHED_VIEW_MESSAGE)); 246 l10n_util::GetStringUTF16(IDS_SESSION_CRASHED_VIEW_MESSAGE));
215 text_label->SetMultiLine(true); 247 text_label->SetMultiLine(true);
216 text_label->SetLineHeight(20); 248 text_label->SetLineHeight(20);
217 text_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); 249 text_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
218 text_label->SizeToFit(kWidthOfDescriptionText); 250 text_label->SizeToFit(kWidthOfDescriptionText);
219 251
220 // Restore button. 252 // Restore button.
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 layout->AddView(new views::Separator(views::Separator::HORIZONTAL)); 352 layout->AddView(new views::Separator(views::Separator::HORIZONTAL));
321 layout->StartRow(0, kReportColumnSetId); 353 layout->StartRow(0, kReportColumnSetId);
322 layout->AddView(uma_option_); 354 layout->AddView(uma_option_);
323 layout->AddView(uma_label); 355 layout->AddView(uma_label);
324 } 356 }
325 357
326 void SessionCrashedBubbleView::ButtonPressed(views::Button* sender, 358 void SessionCrashedBubbleView::ButtonPressed(views::Button* sender,
327 const ui::Event& event) { 359 const ui::Event& event) {
328 DCHECK_EQ(sender, restore_button_); 360 DCHECK_EQ(sender, restore_button_);
329 RestorePreviousSession(sender); 361 RestorePreviousSession(sender);
362 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_RESTORED);
363 restored_ = true;
msw 2014/07/10 19:58:37 nit: you should probably record the histogram valu
yao 2014/07/10 20:19:12 Done.
330 } 364 }
331 365
332 void SessionCrashedBubbleView::StyledLabelLinkClicked(const gfx::Range& range, 366 void SessionCrashedBubbleView::StyledLabelLinkClicked(const gfx::Range& range,
333 int event_flags) { 367 int event_flags) {
334 browser_->OpenURL(content::OpenURLParams( 368 browser_->OpenURL(content::OpenURLParams(
335 GURL("https://support.google.com/chrome/answer/96817"), 369 GURL("https://support.google.com/chrome/answer/96817"),
336 content::Referrer(), 370 content::Referrer(),
337 NEW_FOREGROUND_TAB, 371 NEW_FOREGROUND_TAB,
338 content::PAGE_TRANSITION_LINK, 372 content::PAGE_TRANSITION_LINK,
339 false)); 373 false));
374 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_HELP);
340 } 375 }
341 376
342 void SessionCrashedBubbleView::DidStartNavigationToPendingEntry( 377 void SessionCrashedBubbleView::DidStartNavigationToPendingEntry(
343 const GURL& url, 378 const GURL& url,
344 content::NavigationController::ReloadType reload_type) { 379 content::NavigationController::ReloadType reload_type) {
345 started_navigation_ = true; 380 started_navigation_ = true;
346 } 381 }
347 382
348 void SessionCrashedBubbleView::DidFinishLoad( 383 void SessionCrashedBubbleView::DidFinishLoad(
349 int64 frame_id, 384 int64 frame_id,
350 const GURL& validated_url, 385 const GURL& validated_url,
351 bool is_main_frame, 386 bool is_main_frame,
352 content::RenderViewHost* render_view_host) { 387 content::RenderViewHost* render_view_host) {
353 if (started_navigation_) 388 if (started_navigation_)
354 CloseBubble(); 389 CloseBubble();
355 } 390 }
msw 2014/07/10 19:58:37 nit: revert this (indent was correct).
yao 2014/07/10 20:19:12 Done.
356 391
357 void SessionCrashedBubbleView::WasShown() { 392 void SessionCrashedBubbleView::WasShown() {
358 GetWidget()->Show(); 393 GetWidget()->Show();
359 } 394 }
360 395
361 void SessionCrashedBubbleView::WasHidden() { 396 void SessionCrashedBubbleView::WasHidden() {
362 GetWidget()->Hide(); 397 GetWidget()->Hide();
363 } 398 }
364 399
365 void SessionCrashedBubbleView::Observe( 400 void SessionCrashedBubbleView::Observe(
(...skipping 14 matching lines...) Expand all
380 SessionRestore::RestoreSessionAfterCrash(browser_); 415 SessionRestore::RestoreSessionAfterCrash(browser_);
381 416
382 // Record user's choice for opting in to UMA. 417 // Record user's choice for opting in to UMA.
383 // There's no opting-out choice in the crash restore bubble. 418 // There's no opting-out choice in the crash restore bubble.
384 if (uma_option_ && uma_option_->checked()) { 419 if (uma_option_ && uma_option_->checked()) {
385 // TODO: Clean up function ResolveMetricsReportingEnabled so that user pref 420 // TODO: Clean up function ResolveMetricsReportingEnabled so that user pref
386 // is stored automatically. 421 // is stored automatically.
387 OptionsUtil::ResolveMetricsReportingEnabled(true); 422 OptionsUtil::ResolveMetricsReportingEnabled(true);
388 g_browser_process->local_state()->SetBoolean( 423 g_browser_process->local_state()->SetBoolean(
389 prefs::kMetricsReportingEnabled, true); 424 prefs::kMetricsReportingEnabled, true);
425 RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_UMA_OPTIN);
390 } 426 }
391 CloseBubble(); 427 CloseBubble();
392 } 428 }
393 429
394 void SessionCrashedBubbleView::CloseBubble() { 430 void SessionCrashedBubbleView::CloseBubble() {
395 GetWidget()->Close(); 431 GetWidget()->Close();
396 } 432 }
397 433
398 bool ShowSessionCrashedBubble(Browser* browser) { 434 bool ShowSessionCrashedBubble(Browser* browser) {
399 if (IsBubbleUIEnabled()) { 435 if (IsBubbleUIEnabled()) {
400 SessionCrashedBubbleView::Show(browser); 436 SessionCrashedBubbleView::Show(browser);
401 return true; 437 return true;
402 } 438 }
403 return false; 439 return false;
404 } 440 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/session_crashed_bubble_view.h ('k') | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698