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

Side by Side Diff: chrome_frame/metrics_service.cc

Issue 3396005: Fixes for a couple of ChromeFrame crashes seen in the latest dev channel buil... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 3 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_frame/metrics_service.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 5
6 //------------------------------------------------------------------------------ 6 //------------------------------------------------------------------------------
7 // Description of the life cycle of a instance of MetricsService. 7 // Description of the life cycle of a instance of MetricsService.
8 // 8 //
9 // OVERVIEW 9 // OVERVIEW
10 // 10 //
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 #include <windows.h> 45 #include <windows.h>
46 #include <objbase.h> 46 #include <objbase.h>
47 47
48 #if defined(USE_SYSTEM_LIBBZ2) 48 #if defined(USE_SYSTEM_LIBBZ2)
49 #include <bzlib.h> 49 #include <bzlib.h>
50 #else 50 #else
51 #include "third_party/bzip2/bzlib.h" 51 #include "third_party/bzip2/bzlib.h"
52 #endif 52 #endif
53 53
54 #include "base/file_version_info.h" 54 #include "base/file_version_info.h"
55 #include "base/lock.h"
55 #include "base/string_util.h" 56 #include "base/string_util.h"
56 #include "base/thread.h" 57 #include "base/thread.h"
57 #include "base/string_number_conversions.h" 58 #include "base/string_number_conversions.h"
58 #include "base/utf_string_conversions.h" 59 #include "base/utf_string_conversions.h"
59 #include "chrome/common/chrome_version_info.h" 60 #include "chrome/common/chrome_version_info.h"
60 #include "chrome/common/net/url_fetcher.h" 61 #include "chrome/common/net/url_fetcher.h"
61 #include "chrome/common/net/url_fetcher_protect.h" 62 #include "chrome/common/net/url_fetcher_protect.h"
62 #include "chrome/common/net/url_request_context_getter.h" 63 #include "chrome/common/net/url_request_context_getter.h"
63 #include "chrome/installer/util/browser_distribution.h" 64 #include "chrome/installer/util/browser_distribution.h"
64 #include "chrome/installer/util/chrome_frame_distribution.h" 65 #include "chrome/installer/util/chrome_frame_distribution.h"
(...skipping 18 matching lines...) Expand all
83 using base::TimeDelta; 84 using base::TimeDelta;
84 85
85 static const char kMetricsType[] = "application/vnd.mozilla.metrics.bz2"; 86 static const char kMetricsType[] = "application/vnd.mozilla.metrics.bz2";
86 87
87 // The first UMA upload occurs after this interval. 88 // The first UMA upload occurs after this interval.
88 static const int kInitialUMAUploadTimeoutMilliSeconds = 30000; 89 static const int kInitialUMAUploadTimeoutMilliSeconds = 30000;
89 90
90 // Default to one UMA upload per 10 mins. 91 // Default to one UMA upload per 10 mins.
91 static const int kMinMilliSecondsPerUMAUpload = 600000; 92 static const int kMinMilliSecondsPerUMAUpload = 600000;
92 93
93 base::LazyInstance<base::ThreadLocalPointer<MetricsService> > 94 base::LazyInstance<MetricsService>
94 MetricsService::g_metrics_instance_(base::LINKER_INITIALIZED); 95 g_metrics_instance_(base::LINKER_INITIALIZED);
96
97 // Traits to create an instance of the ChromeFrame upload thread.
98 struct UploadThreadInstanceTraits
99 : public base::DefaultLazyInstanceTraits<base::Thread> {
100 static base::Thread* New(void* instance) {
101 // Use placement new to initialize our instance in our preallocated space.
102 // The parenthesis is very important here to force POD type initialization.
103 base::Thread* upload_thread =
104 new (instance) base::Thread("ChromeFrameUploadThread");
105 base::Thread::Options options;
106 options.message_loop_type = MessageLoop::TYPE_IO;
107 bool ret = upload_thread->StartWithOptions(options);
108 if (!ret) {
109 NOTREACHED() << "Failed to start upload thread";
110 }
111 return upload_thread;
112 }
113 };
114
115 // ChromeFrame UMA uploads occur on this thread. This thread is started on the
116 // IE UI thread. This thread needs to be stopped on the same thread it was
117 // started on. We don't have a good way of achieving this at this point. This
118 // thread object is currently leaked.
119 // TODO(ananta)
120 // Fix this.
121 base::LazyInstance<base::Thread, UploadThreadInstanceTraits>
122 g_metrics_upload_thread_(base::LINKER_INITIALIZED);
123
124 Lock g_metrics_service_lock;
95 125
96 extern base::LazyInstance<StatisticsRecorder> g_statistics_recorder_; 126 extern base::LazyInstance<StatisticsRecorder> g_statistics_recorder_;
97 127
98 // This class provides HTTP request context information for metrics upload 128 // This class provides HTTP request context information for metrics upload
99 // requests initiated by ChromeFrame. 129 // requests initiated by ChromeFrame.
100 class ChromeFrameUploadRequestContext : public URLRequestContext { 130 class ChromeFrameUploadRequestContext : public URLRequestContext {
101 public: 131 public:
102 ChromeFrameUploadRequestContext(MessageLoop* io_loop) 132 ChromeFrameUploadRequestContext(MessageLoop* io_loop)
103 : io_loop_(io_loop) { 133 : io_loop_(io_loop) {
104 Initialize(); 134 Initialize();
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 public CWindowImpl<ChromeFrameMetricsDataUploader>, 232 public CWindowImpl<ChromeFrameMetricsDataUploader>,
203 public TaskMarshallerThroughWindowsMessages< 233 public TaskMarshallerThroughWindowsMessages<
204 ChromeFrameMetricsDataUploader> { 234 ChromeFrameMetricsDataUploader> {
205 public: 235 public:
206 BEGIN_MSG_MAP(ChromeFrameMetricsDataUploader) 236 BEGIN_MSG_MAP(ChromeFrameMetricsDataUploader)
207 CHAIN_MSG_MAP( 237 CHAIN_MSG_MAP(
208 TaskMarshallerThroughWindowsMessages<ChromeFrameMetricsDataUploader>) 238 TaskMarshallerThroughWindowsMessages<ChromeFrameMetricsDataUploader>)
209 END_MSG_MAP() 239 END_MSG_MAP()
210 240
211 ChromeFrameMetricsDataUploader() 241 ChromeFrameMetricsDataUploader()
212 : fetcher_(NULL), 242 : fetcher_(NULL) {
213 upload_thread_("ChromeFrameMetricsUploadThread") {
214 DLOG(INFO) << __FUNCTION__; 243 DLOG(INFO) << __FUNCTION__;
215 creator_thread_id_ = PlatformThread::CurrentId(); 244 creator_thread_id_ = PlatformThread::CurrentId();
216 } 245 }
217 246
218 ~ChromeFrameMetricsDataUploader() { 247 ~ChromeFrameMetricsDataUploader() {
219 DLOG(INFO) << __FUNCTION__; 248 DLOG(INFO) << __FUNCTION__;
220 DCHECK(creator_thread_id_ == PlatformThread::CurrentId()); 249 DCHECK(creator_thread_id_ == PlatformThread::CurrentId());
221 } 250 }
222 251
223 virtual void OnFinalMessage(HWND wnd) { 252 virtual void OnFinalMessage(HWND wnd) {
224 Release(); 253 Release();
225 } 254 }
226 255
227 bool Initialize() { 256 bool Initialize() {
257 bool ret = false;
258
228 if (!Create(NULL, NULL, NULL, WS_OVERLAPPEDWINDOW)) { 259 if (!Create(NULL, NULL, NULL, WS_OVERLAPPEDWINDOW)) {
229 NOTREACHED() << "Failed to create window"; 260 NOTREACHED() << "Failed to create window";
230 return false; 261 return ret;
231 } 262 }
232 DCHECK(IsWindow()); 263 DCHECK(IsWindow());
233 264
265 if (!g_metrics_upload_thread_.Get().IsRunning()) {
266 NOTREACHED() << "Upload thread is not running";
267 return ret;
268 }
269
270 ret = true;
234 // Grab a reference to the current instance which ensures that it stays 271 // Grab a reference to the current instance which ensures that it stays
235 // around until the HTTP request initiated below completes. 272 // around until the HTTP request initiated below completes.
236 // Corresponding Release is in OnFinalMessage. 273 // Corresponding Release is in OnFinalMessage.
237 AddRef(); 274 AddRef();
238 275 return ret;
239 base::Thread::Options options;
240 options.message_loop_type = MessageLoop::TYPE_IO;
241 return upload_thread_.StartWithOptions(options);
242 } 276 }
243 277
244 bool Uninitialize() { 278 bool Uninitialize() {
245 DestroyWindow(); 279 DestroyWindow();
246 return true; 280 return true;
247 } 281 }
248 282
249 static HRESULT ChromeFrameMetricsDataUploader::UploadDataHelper( 283 static HRESULT ChromeFrameMetricsDataUploader::UploadDataHelper(
250 const std::string& upload_data) { 284 const std::string& upload_data) {
251 scoped_refptr<ChromeFrameMetricsDataUploader> data_uploader = 285 scoped_refptr<ChromeFrameMetricsDataUploader> data_uploader =
252 new ChromeFrameMetricsDataUploader(); 286 new ChromeFrameMetricsDataUploader();
253 287
254 data_uploader->Initialize(); 288 if (!data_uploader->Initialize()) {
255 DCHECK(data_uploader->upload_thread_.message_loop()); 289 NOTREACHED() << "Failed to initialize ChromeFrameMetricsDataUploader";
290 return E_FAIL;
291 }
256 292
257 data_uploader->upload_thread_.message_loop()->PostTask(FROM_HERE, 293 MessageLoop* io_loop = g_metrics_upload_thread_.Get().message_loop();
294 if (!io_loop) {
295 NOTREACHED() << "Failed to initialize ChromeFrame UMA upload thread";
296 return E_FAIL;
297 }
298
299 io_loop->PostTask(
300 FROM_HERE,
258 NewRunnableMethod(data_uploader.get(), 301 NewRunnableMethod(data_uploader.get(),
259 &ChromeFrameMetricsDataUploader::UploadData, 302 &ChromeFrameMetricsDataUploader::UploadData,
260 upload_data)); 303 upload_data, io_loop));
261 return S_OK; 304 return S_OK;
262 } 305 }
263 306
264 void UploadData(const std::string& upload_data) { 307 void UploadData(const std::string& upload_data, MessageLoop* message_loop) {
265 DCHECK(fetcher_ == NULL); 308 DCHECK(fetcher_ == NULL);
309 DCHECK(message_loop != NULL);
266 310
267 BrowserDistribution* dist = ChromeFrameDistribution::GetDistribution(); 311 BrowserDistribution* dist = ChromeFrameDistribution::GetDistribution();
268 DCHECK(dist != NULL); 312 DCHECK(dist != NULL);
269 313
270 fetcher_ = new URLFetcher(GURL(WideToUTF8(dist->GetStatsServerURL())), 314 fetcher_ = new URLFetcher(GURL(WideToUTF8(dist->GetStatsServerURL())),
271 URLFetcher::POST, this); 315 URLFetcher::POST, this);
272 316
273 fetcher_->set_request_context(new ChromeFrameUploadRequestContextGetter( 317 fetcher_->set_request_context(new ChromeFrameUploadRequestContextGetter(
274 upload_thread_.message_loop())); 318 message_loop));
275 fetcher_->set_upload_data(kMetricsType, upload_data); 319 fetcher_->set_upload_data(kMetricsType, upload_data);
276 fetcher_->Start(); 320 fetcher_->Start();
277 } 321 }
278 322
279 // URLFetcher::Delegate 323 // URLFetcher::Delegate
280 virtual void OnURLFetchComplete(const URLFetcher* source, 324 virtual void OnURLFetchComplete(const URLFetcher* source,
281 const GURL& url, 325 const GURL& url,
282 const URLRequestStatus& status, 326 const URLRequestStatus& status,
283 int response_code, 327 int response_code,
284 const ResponseCookies& cookies, 328 const ResponseCookies& cookies,
285 const std::string& data) { 329 const std::string& data) {
286 DLOG(INFO) << __FUNCTION__ 330 DLOG(INFO) << __FUNCTION__
287 << StringPrintf(": url : %hs, status:%d, response code: %d\n", 331 << StringPrintf(": url : %hs, status:%d, response code: %d\n",
288 url.spec().c_str(), status.status(), 332 url.spec().c_str(), status.status(),
289 response_code); 333 response_code);
290 delete fetcher_; 334 delete fetcher_;
291 fetcher_ = NULL; 335 fetcher_ = NULL;
292 336
293 PostTask(FROM_HERE, 337 PostTask(FROM_HERE,
294 NewRunnableMethod(this, 338 NewRunnableMethod(this,
295 &ChromeFrameMetricsDataUploader::Uninitialize)); 339 &ChromeFrameMetricsDataUploader::Uninitialize));
296 } 340 }
297 341
298 private: 342 private:
299 base::Thread upload_thread_;
300 URLFetcher* fetcher_; 343 URLFetcher* fetcher_;
301 PlatformThreadId creator_thread_id_; 344 PlatformThreadId creator_thread_id_;
302 }; 345 };
303 346
304 MetricsService* MetricsService::GetInstance() { 347 MetricsService* MetricsService::GetInstance() {
305 if (g_metrics_instance_.Pointer()->Get()) 348 AutoLock lock(g_metrics_service_lock);
306 return g_metrics_instance_.Pointer()->Get(); 349 return &g_metrics_instance_.Get();
307
308 g_metrics_instance_.Pointer()->Set(new MetricsService);
309 return g_metrics_instance_.Pointer()->Get();
310 } 350 }
311 351
312 MetricsService::MetricsService() 352 MetricsService::MetricsService()
313 : recording_active_(false), 353 : recording_active_(false),
314 reporting_active_(false), 354 reporting_active_(false),
315 user_permits_upload_(false), 355 user_permits_upload_(false),
316 state_(INITIALIZED), 356 state_(INITIALIZED),
317 thread_(NULL), 357 thread_(NULL),
318 initial_uma_upload_(true), 358 initial_uma_upload_(true),
319 transmission_timer_id_(0) { 359 transmission_timer_id_(0) {
(...skipping 16 matching lines...) Expand all
336 376
337 thread_ = PlatformThread::CurrentId(); 377 thread_ = PlatformThread::CurrentId();
338 378
339 user_permits_upload_ = GoogleUpdateSettings::GetCollectStatsConsent(); 379 user_permits_upload_ = GoogleUpdateSettings::GetCollectStatsConsent();
340 // Update session ID 380 // Update session ID
341 session_id_ = CrashMetricsReporter::GetInstance()->IncrementMetric( 381 session_id_ = CrashMetricsReporter::GetInstance()->IncrementMetric(
342 CrashMetricsReporter::SESSION_ID); 382 CrashMetricsReporter::SESSION_ID);
343 383
344 // Ensure that an instance of the StatisticsRecorder object is created. 384 // Ensure that an instance of the StatisticsRecorder object is created.
345 g_statistics_recorder_.Get(); 385 g_statistics_recorder_.Get();
386
387 if (user_permits_upload_) {
388 // Ensure that an instance of the metrics upload thread is created.
389 g_metrics_upload_thread_.Get();
390 }
391
346 CrashMetricsReporter::GetInstance()->set_active(true); 392 CrashMetricsReporter::GetInstance()->set_active(true);
347 } 393 }
348 394
349 // static 395 // static
350 void MetricsService::Start() { 396 void MetricsService::Start() {
351 if (GetInstance()->state_ == ACTIVE) 397 if (GetInstance()->state_ == ACTIVE)
352 return; 398 return;
353 399
354 GetInstance()->InitializeMetricsState(); 400 GetInstance()->InitializeMetricsState();
355 GetInstance()->SetRecording(true); 401 GetInstance()->SetRecording(true);
356 GetInstance()->SetReporting(true); 402 GetInstance()->SetReporting(true);
357 } 403 }
358 404
359 // static 405 // static
360 void MetricsService::Stop() { 406 void MetricsService::Stop() {
361 GetInstance()->SetReporting(false); 407 GetInstance()->SetReporting(false);
362 GetInstance()->SetRecording(false); 408 GetInstance()->SetRecording(false);
363 } 409 }
364 410
365 void MetricsService::SetRecording(bool enabled) { 411 void MetricsService::SetRecording(bool enabled) {
366 DCHECK_EQ(thread_, PlatformThread::CurrentId());
367 if (enabled == recording_active_) 412 if (enabled == recording_active_)
368 return; 413 return;
369 414
370 if (enabled) { 415 if (enabled) {
371 if (client_id_.empty()) { 416 if (client_id_.empty()) {
372 client_id_ = GenerateClientID(); 417 client_id_ = GenerateClientID();
373 // Save client id somewhere. 418 // Save client id somewhere.
374 } 419 }
375 StartRecording(); 420 StartRecording();
376 421
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 version += "-F"; 595 version += "-F";
551 if (!version_info.IsOfficialBuild()) 596 if (!version_info.IsOfficialBuild())
552 version.append("-devel"); 597 version.append("-devel");
553 return version; 598 return version;
554 } else { 599 } else {
555 NOTREACHED() << "Unable to retrieve version string."; 600 NOTREACHED() << "Unable to retrieve version string.";
556 } 601 }
557 602
558 return std::string(); 603 return std::string();
559 } 604 }
OLDNEW
« no previous file with comments | « chrome_frame/metrics_service.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698