| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 // Description of the life cycle of a instance of MetricsService. | 6 // Description of the life cycle of a instance of MetricsService. |
| 7 // | 7 // |
| 8 // OVERVIEW | 8 // OVERVIEW |
| 9 // | 9 // |
| 10 // A MetricsService instance is created at ChromeFrame startup in | 10 // A MetricsService instance is created at ChromeFrame startup in |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 // | 37 // |
| 38 //----------------------------------------------------------------------------- | 38 //----------------------------------------------------------------------------- |
| 39 | 39 |
| 40 #include "chrome_frame/metrics_service.h" | 40 #include "chrome_frame/metrics_service.h" |
| 41 | 41 |
| 42 #include <atlbase.h> | 42 #include <atlbase.h> |
| 43 #include <atlwin.h> | 43 #include <atlwin.h> |
| 44 #include <objbase.h> | 44 #include <objbase.h> |
| 45 #include <windows.h> | 45 #include <windows.h> |
| 46 | 46 |
| 47 #include <vector> | |
| 48 | |
| 49 #if defined(USE_SYSTEM_LIBBZ2) | 47 #if defined(USE_SYSTEM_LIBBZ2) |
| 50 #include <bzlib.h> | 48 #include <bzlib.h> |
| 51 #else | 49 #else |
| 52 #include "third_party/bzip2/bzlib.h" | 50 #include "third_party/bzip2/bzlib.h" |
| 53 #endif | 51 #endif |
| 54 | 52 |
| 55 #include "base/file_version_info.h" | |
| 56 #include "base/string_split.h" | |
| 57 #include "base/string_util.h" | 53 #include "base/string_util.h" |
| 58 #include "base/stringprintf.h" | 54 #include "base/stringprintf.h" |
| 59 #include "base/synchronization/lock.h" | 55 #include "base/synchronization/lock.h" |
| 60 #include "base/string_number_conversions.h" | 56 #include "base/string_number_conversions.h" |
| 61 #include "base/threading/thread.h" | |
| 62 #include "base/utf_string_conversions.h" | 57 #include "base/utf_string_conversions.h" |
| 58 #include "base/win/scoped_comptr.h" |
| 63 #include "chrome/common/chrome_version_info.h" | 59 #include "chrome/common/chrome_version_info.h" |
| 64 #include "chrome/common/net/url_fetcher.h" | |
| 65 #include "chrome/installer/util/browser_distribution.h" | 60 #include "chrome/installer/util/browser_distribution.h" |
| 66 #include "chrome/installer/util/chrome_frame_distribution.h" | |
| 67 #include "chrome/installer/util/google_update_settings.h" | 61 #include "chrome/installer/util/google_update_settings.h" |
| 68 #include "chrome_frame/bind_status_callback_impl.h" | 62 #include "chrome_frame/bind_status_callback_impl.h" |
| 69 #include "chrome_frame/chrome_frame_delegate.h" | |
| 70 #include "chrome_frame/crash_reporting/crash_metrics.h" | 63 #include "chrome_frame/crash_reporting/crash_metrics.h" |
| 71 #include "chrome_frame/html_utils.h" | 64 #include "chrome_frame/html_utils.h" |
| 72 #include "chrome_frame/http_negotiate.h" | |
| 73 #include "chrome_frame/utils.h" | 65 #include "chrome_frame/utils.h" |
| 74 #include "net/base/capturing_net_log.h" | |
| 75 #include "net/base/cert_verifier.h" | |
| 76 #include "net/base/host_resolver.h" | |
| 77 #include "net/base/ssl_config_service_defaults.h" | |
| 78 #include "net/base/upload_data.h" | |
| 79 #include "net/http/http_auth_handler_factory.h" | |
| 80 #include "net/http/http_cache.h" | |
| 81 #include "net/http/http_network_session.h" | |
| 82 #include "net/url_request/url_request_context.h" | |
| 83 #include "net/url_request/url_request_context_getter.h" | |
| 84 #include "net/url_request/url_request_status.h" | |
| 85 | 66 |
| 86 using base::Time; | 67 using base::Time; |
| 87 using base::TimeDelta; | 68 using base::TimeDelta; |
| 69 using base::win::ScopedComPtr; |
| 88 | 70 |
| 89 static const char kMetricsType[] = "application/vnd.mozilla.metrics.bz2"; | 71 static const char kMetricsType[] = "application/vnd.mozilla.metrics.bz2"; |
| 90 | 72 |
| 91 // The first UMA upload occurs after this interval. | 73 // The first UMA upload occurs after this interval. |
| 92 static const int kInitialUMAUploadTimeoutMilliSeconds = 30000; | 74 static const int kInitialUMAUploadTimeoutMilliSeconds = 30000; |
| 93 | 75 |
| 94 // Default to one UMA upload per 10 mins. | 76 // Default to one UMA upload per 10 mins. |
| 95 static const int kMinMilliSecondsPerUMAUpload = 600000; | 77 static const int kMinMilliSecondsPerUMAUpload = 600000; |
| 96 | 78 |
| 97 base::LazyInstance<MetricsService> | 79 base::LazyInstance<base::ThreadLocalPointer<MetricsService> > |
| 98 g_metrics_instance_(base::LINKER_INITIALIZED); | 80 MetricsService::g_metrics_instance_(base::LINKER_INITIALIZED); |
| 99 | 81 |
| 100 base::Lock MetricsService::metrics_service_lock_; | 82 base::Lock MetricsService::metrics_service_lock_; |
| 101 | 83 |
| 102 // Traits to create an instance of the ChromeFrame upload thread. | |
| 103 struct UploadThreadInstanceTraits | |
| 104 : public base::LeakyLazyInstanceTraits<base::Thread> { | |
| 105 static base::Thread* New(void* instance) { | |
| 106 // Use placement new to initialize our instance in our preallocated space. | |
| 107 // The parenthesis is very important here to force POD type initialization. | |
| 108 base::Thread* upload_thread = | |
| 109 new(instance) base::Thread("ChromeFrameUploadThread"); | |
| 110 base::Thread::Options options; | |
| 111 options.message_loop_type = MessageLoop::TYPE_IO; | |
| 112 bool ret = upload_thread->StartWithOptions(options); | |
| 113 if (!ret) { | |
| 114 NOTREACHED() << "Failed to start upload thread"; | |
| 115 } | |
| 116 return upload_thread; | |
| 117 } | |
| 118 }; | |
| 119 | |
| 120 // ChromeFrame UMA uploads occur on this thread. This thread is started on the | |
| 121 // IE UI thread. This thread needs to be stopped on the same thread it was | |
| 122 // started on. We don't have a good way of achieving this at this point. This | |
| 123 // thread object is currently leaked. | |
| 124 // TODO(ananta) | |
| 125 // TODO(vitalybuka@chromium.org) : Fix this by using MetricsService::Stop() in | |
| 126 // appropriate location. | |
| 127 base::LazyInstance<base::Thread, UploadThreadInstanceTraits> | |
| 128 g_metrics_upload_thread_(base::LINKER_INITIALIZED); | |
| 129 | |
| 130 base::Lock g_metrics_service_lock; | |
| 131 | |
| 132 extern base::LazyInstance<base::StatisticsRecorder> g_statistics_recorder_; | 84 extern base::LazyInstance<base::StatisticsRecorder> g_statistics_recorder_; |
| 133 | 85 |
| 134 // This class provides HTTP request context information for metrics upload | |
| 135 // requests initiated by ChromeFrame. | |
| 136 class ChromeFrameUploadRequestContext : public net::URLRequestContext { | |
| 137 public: | |
| 138 explicit ChromeFrameUploadRequestContext(MessageLoop* io_loop) | |
| 139 : io_loop_(io_loop) { | |
| 140 Initialize(); | |
| 141 } | |
| 142 | |
| 143 ~ChromeFrameUploadRequestContext() { | |
| 144 DVLOG(1) << __FUNCTION__; | |
| 145 delete http_transaction_factory(); | |
| 146 delete http_auth_handler_factory(); | |
| 147 delete cert_verifier(); | |
| 148 delete host_resolver(); | |
| 149 } | |
| 150 | |
| 151 void Initialize() { | |
| 152 user_agent_ = http_utils::GetDefaultUserAgent(); | |
| 153 user_agent_ = http_utils::AddChromeFrameToUserAgentValue( | |
| 154 user_agent_); | |
| 155 | |
| 156 set_host_resolver( | |
| 157 net::CreateSystemHostResolver(net::HostResolver::kDefaultParallelism, | |
| 158 NULL, NULL)); | |
| 159 set_cert_verifier(new net::CertVerifier); | |
| 160 net::ProxyConfigService* proxy_config_service = | |
| 161 net::ProxyService::CreateSystemProxyConfigService(NULL, NULL); | |
| 162 DCHECK(proxy_config_service); | |
| 163 | |
| 164 set_proxy_service(net::ProxyService::CreateUsingSystemProxyResolver( | |
| 165 proxy_config_service, 0, NULL)); | |
| 166 DCHECK(proxy_service()); | |
| 167 | |
| 168 set_ssl_config_service(new net::SSLConfigServiceDefaults); | |
| 169 | |
| 170 url_security_manager_.reset( | |
| 171 net::URLSecurityManager::Create(NULL, NULL)); | |
| 172 | |
| 173 std::string csv_auth_schemes = "basic,digest,ntlm,negotiate"; | |
| 174 std::vector<std::string> supported_schemes; | |
| 175 base::SplitString(csv_auth_schemes, ',', &supported_schemes); | |
| 176 | |
| 177 set_http_auth_handler_factory(net::HttpAuthHandlerRegistryFactory::Create( | |
| 178 supported_schemes, url_security_manager_.get(), host_resolver(), | |
| 179 std::string(), false, false)); | |
| 180 | |
| 181 net::HttpNetworkSession::Params session_params; | |
| 182 session_params.host_resolver = host_resolver(); | |
| 183 session_params.cert_verifier = cert_verifier(); | |
| 184 session_params.proxy_service = proxy_service(); | |
| 185 session_params.http_auth_handler_factory = | |
| 186 http_auth_handler_factory(); | |
| 187 session_params.ssl_config_service = ssl_config_service(); | |
| 188 scoped_refptr<net::HttpNetworkSession> network_session = | |
| 189 new net::HttpNetworkSession(session_params); | |
| 190 | |
| 191 set_http_transaction_factory(new net::HttpCache( | |
| 192 network_session, | |
| 193 net::HttpCache::DefaultBackend::InMemory(0))); | |
| 194 } | |
| 195 | |
| 196 virtual const std::string& GetUserAgent(const GURL& url) const { | |
| 197 return user_agent_; | |
| 198 } | |
| 199 | |
| 200 private: | |
| 201 std::string user_agent_; | |
| 202 MessageLoop* io_loop_; | |
| 203 scoped_ptr<net::URLSecurityManager> url_security_manager_; | |
| 204 }; | |
| 205 | |
| 206 // This class provides an interface to retrieve the URL request context for | |
| 207 // metrics HTTP upload requests initiated by ChromeFrame. | |
| 208 class ChromeFrameUploadRequestContextGetter | |
| 209 : public net::URLRequestContextGetter { | |
| 210 public: | |
| 211 explicit ChromeFrameUploadRequestContextGetter(MessageLoop* io_loop) | |
| 212 : io_loop_(io_loop) {} | |
| 213 | |
| 214 virtual net::URLRequestContext* GetURLRequestContext() { | |
| 215 if (!context_) | |
| 216 context_ = new ChromeFrameUploadRequestContext(io_loop_); | |
| 217 return context_; | |
| 218 } | |
| 219 | |
| 220 virtual scoped_refptr<base::MessageLoopProxy> GetIOMessageLoopProxy() const { | |
| 221 if (!io_message_loop_proxy_.get()) { | |
| 222 io_message_loop_proxy_ = base::MessageLoopProxy::CreateForCurrentThread(); | |
| 223 } | |
| 224 return io_message_loop_proxy_; | |
| 225 } | |
| 226 | |
| 227 private: | |
| 228 ~ChromeFrameUploadRequestContextGetter() { | |
| 229 DVLOG(1) << __FUNCTION__; | |
| 230 } | |
| 231 | |
| 232 scoped_refptr<net::URLRequestContext> context_; | |
| 233 mutable scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; | |
| 234 MessageLoop* io_loop_; | |
| 235 }; | |
| 236 | |
| 237 // This class provides functionality to upload the ChromeFrame UMA data to the | 86 // This class provides functionality to upload the ChromeFrame UMA data to the |
| 238 // server. An instance of this class is created whenever we have data to be | 87 // server. An instance of this class is created whenever we have data to be |
| 239 // uploaded to the server. | 88 // uploaded to the server. |
| 240 class ChromeFrameMetricsDataUploader | 89 class ChromeFrameMetricsDataUploader : public BSCBImpl { |
| 241 : public URLFetcher::Delegate, | |
| 242 public base::RefCountedThreadSafe<ChromeFrameMetricsDataUploader>, | |
| 243 public CWindowImpl<ChromeFrameMetricsDataUploader>, | |
| 244 public TaskMarshallerThroughWindowsMessages< | |
| 245 ChromeFrameMetricsDataUploader> { | |
| 246 public: | 90 public: |
| 247 BEGIN_MSG_MAP(ChromeFrameMetricsDataUploader) | |
| 248 CHAIN_MSG_MAP( | |
| 249 TaskMarshallerThroughWindowsMessages<ChromeFrameMetricsDataUploader>) | |
| 250 END_MSG_MAP() | |
| 251 | |
| 252 ChromeFrameMetricsDataUploader() | 91 ChromeFrameMetricsDataUploader() |
| 253 : fetcher_(NULL) { | 92 : cache_stream_(NULL), |
| 93 upload_data_size_(0) { |
| 254 DVLOG(1) << __FUNCTION__; | 94 DVLOG(1) << __FUNCTION__; |
| 255 creator_thread_id_ = base::PlatformThread::CurrentId(); | |
| 256 } | 95 } |
| 257 | 96 |
| 258 ~ChromeFrameMetricsDataUploader() { | 97 ~ChromeFrameMetricsDataUploader() { |
| 259 DVLOG(1) << __FUNCTION__; | 98 DVLOG(1) << __FUNCTION__; |
| 260 DCHECK(creator_thread_id_ == base::PlatformThread::CurrentId()); | |
| 261 } | |
| 262 | |
| 263 virtual void OnFinalMessage(HWND wnd) { | |
| 264 Release(); | |
| 265 } | |
| 266 | |
| 267 bool Initialize() { | |
| 268 bool ret = false; | |
| 269 | |
| 270 if (!Create(NULL, NULL, NULL, WS_OVERLAPPEDWINDOW)) { | |
| 271 NOTREACHED() << "Failed to create window"; | |
| 272 return ret; | |
| 273 } | |
| 274 DCHECK(IsWindow()); | |
| 275 | |
| 276 if (!g_metrics_upload_thread_.Get().IsRunning()) { | |
| 277 NOTREACHED() << "Upload thread is not running"; | |
| 278 return ret; | |
| 279 } | |
| 280 | |
| 281 ret = true; | |
| 282 // Grab a reference to the current instance which ensures that it stays | |
| 283 // around until the HTTP request initiated below completes. | |
| 284 // Corresponding Release is in OnFinalMessage. | |
| 285 AddRef(); | |
| 286 return ret; | |
| 287 } | |
| 288 | |
| 289 bool Uninitialize() { | |
| 290 DestroyWindow(); | |
| 291 return true; | |
| 292 } | 99 } |
| 293 | 100 |
| 294 static HRESULT ChromeFrameMetricsDataUploader::UploadDataHelper( | 101 static HRESULT ChromeFrameMetricsDataUploader::UploadDataHelper( |
| 295 const std::string& upload_data) { | 102 const std::string& upload_data) { |
| 296 scoped_refptr<ChromeFrameMetricsDataUploader> data_uploader = | 103 CComObject<ChromeFrameMetricsDataUploader>* data_uploader = NULL; |
| 297 new ChromeFrameMetricsDataUploader(); | 104 CComObject<ChromeFrameMetricsDataUploader>::CreateInstance(&data_uploader); |
| 105 DCHECK(data_uploader != NULL); |
| 298 | 106 |
| 299 if (!data_uploader->Initialize()) { | 107 data_uploader->AddRef(); |
| 300 NOTREACHED() << "Failed to initialize ChromeFrameMetricsDataUploader"; | 108 HRESULT hr = data_uploader->UploadData(upload_data); |
| 301 return E_FAIL; | 109 if (FAILED(hr)) { |
| 110 DLOG(ERROR) << "Failed to initialize ChromeFrame UMA data uploader: Err" |
| 111 << hr; |
| 112 } |
| 113 data_uploader->Release(); |
| 114 return hr; |
| 115 } |
| 116 |
| 117 HRESULT UploadData(const std::string& upload_data) { |
| 118 if (upload_data.empty()) { |
| 119 NOTREACHED() << "Invalid upload data"; |
| 120 return E_INVALIDARG; |
| 302 } | 121 } |
| 303 | 122 |
| 304 MessageLoop* io_loop = g_metrics_upload_thread_.Get().message_loop(); | 123 DCHECK(cache_stream_.get() == NULL); |
| 305 if (!io_loop) { | 124 |
| 306 NOTREACHED() << "Failed to initialize ChromeFrame UMA upload thread"; | 125 upload_data_size_ = upload_data.size() + 1; |
| 307 return E_FAIL; | 126 |
| 127 HRESULT hr = CreateStreamOnHGlobal(NULL, TRUE, cache_stream_.Receive()); |
| 128 if (FAILED(hr)) { |
| 129 NOTREACHED() << "Failed to create stream. Error:" |
| 130 << hr; |
| 131 return hr; |
| 308 } | 132 } |
| 309 | 133 |
| 310 io_loop->PostTask( | 134 DCHECK(cache_stream_.get()); |
| 311 FROM_HERE, | 135 |
| 312 NewRunnableMethod(data_uploader.get(), | 136 unsigned long written = 0; |
| 313 &ChromeFrameMetricsDataUploader::UploadData, | 137 cache_stream_->Write(upload_data.c_str(), upload_data_size_, &written); |
| 314 upload_data, io_loop)); | 138 DCHECK(written == upload_data_size_); |
| 315 return S_OK; | 139 |
| 140 RewindStream(cache_stream_); |
| 141 |
| 142 BrowserDistribution* dist = BrowserDistribution::GetSpecificDistribution( |
| 143 BrowserDistribution::CHROME_FRAME); |
| 144 server_url_ = dist->GetStatsServerURL(); |
| 145 DCHECK(!server_url_.empty()); |
| 146 |
| 147 hr = CreateURLMoniker(NULL, server_url_.c_str(), |
| 148 upload_moniker_.Receive()); |
| 149 if (FAILED(hr)) { |
| 150 DLOG(ERROR) << "Failed to create url moniker for url:" |
| 151 << server_url_.c_str() |
| 152 << " Error:" |
| 153 << hr; |
| 154 } else { |
| 155 ScopedComPtr<IBindCtx> context; |
| 156 hr = CreateAsyncBindCtx(0, this, NULL, context.Receive()); |
| 157 DCHECK(SUCCEEDED(hr)); |
| 158 DCHECK(context); |
| 159 |
| 160 ScopedComPtr<IStream> stream; |
| 161 hr = upload_moniker_->BindToStorage( |
| 162 context, NULL, IID_IStream, |
| 163 reinterpret_cast<void**>(stream.Receive())); |
| 164 if (FAILED(hr)) { |
| 165 NOTREACHED(); |
| 166 DLOG(ERROR) << "Failed to bind to upload data moniker. Error:" |
| 167 << hr; |
| 168 } |
| 169 } |
| 170 return hr; |
| 316 } | 171 } |
| 317 | 172 |
| 318 void UploadData(const std::string& upload_data, MessageLoop* message_loop) { | 173 STDMETHOD(BeginningTransaction)(LPCWSTR url, LPCWSTR headers, DWORD reserved, |
| 319 DCHECK(fetcher_ == NULL); | 174 LPWSTR* additional_headers) { |
| 320 DCHECK(message_loop != NULL); | 175 std::string new_headers; |
| 176 new_headers = |
| 177 StringPrintf("Content-Length: %s\r\n" |
| 178 "Content-Type: %s\r\n" |
| 179 "%s\r\n", |
| 180 base::Int64ToString(upload_data_size_).c_str(), |
| 181 kMetricsType, |
| 182 http_utils::GetDefaultUserAgentHeaderWithCFTag()); |
| 321 | 183 |
| 322 BrowserDistribution* dist = ChromeFrameDistribution::GetDistribution(); | 184 *additional_headers = reinterpret_cast<wchar_t*>( |
| 323 DCHECK(dist != NULL); | 185 CoTaskMemAlloc((new_headers.size() + 1) * sizeof(wchar_t))); |
| 324 | 186 |
| 325 fetcher_ = new URLFetcher(GURL(WideToUTF8(dist->GetStatsServerURL())), | 187 lstrcpynW(*additional_headers, ASCIIToWide(new_headers).c_str(), |
| 326 URLFetcher::POST, this); | 188 new_headers.size()); |
| 327 | 189 |
| 328 fetcher_->set_request_context(new ChromeFrameUploadRequestContextGetter( | 190 return BSCBImpl::BeginningTransaction(url, headers, reserved, |
| 329 message_loop)); | 191 additional_headers); |
| 330 fetcher_->set_upload_data(kMetricsType, upload_data); | |
| 331 fetcher_->Start(); | |
| 332 } | 192 } |
| 333 | 193 |
| 334 // URLFetcher::Delegate | 194 STDMETHOD(GetBindInfo)(DWORD* bind_flags, BINDINFO* bind_info) { |
| 335 virtual void OnURLFetchComplete(const URLFetcher* source, | 195 if ((bind_info == NULL) || (bind_info->cbSize == 0) || |
| 336 const GURL& url, | 196 (bind_flags == NULL)) |
| 337 const net::URLRequestStatus& status, | 197 return E_INVALIDARG; |
| 338 int response_code, | |
| 339 const ResponseCookies& cookies, | |
| 340 const std::string& data) { | |
| 341 DVLOG(1) << __FUNCTION__ << base::StringPrintf( | |
| 342 ": url : %hs, status:%d, response code: %d\n", url.spec().c_str(), | |
| 343 status.status(), response_code); | |
| 344 delete fetcher_; | |
| 345 fetcher_ = NULL; | |
| 346 | 198 |
| 347 PostTask(FROM_HERE, | 199 *bind_flags = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA; |
| 348 NewRunnableMethod(this, | 200 // Bypass caching proxies on POSTs and PUTs and avoid writing responses to |
| 349 &ChromeFrameMetricsDataUploader::Uninitialize)); | 201 // these requests to the browser's cache |
| 202 *bind_flags |= BINDF_GETNEWESTVERSION | BINDF_PRAGMA_NO_CACHE; |
| 203 |
| 204 DCHECK(cache_stream_.get()); |
| 205 |
| 206 // Initialize the STGMEDIUM. |
| 207 memset(&bind_info->stgmedData, 0, sizeof(STGMEDIUM)); |
| 208 bind_info->grfBindInfoF = 0; |
| 209 bind_info->szCustomVerb = NULL; |
| 210 bind_info->dwBindVerb = BINDVERB_POST; |
| 211 bind_info->stgmedData.tymed = TYMED_ISTREAM; |
| 212 bind_info->stgmedData.pstm = cache_stream_.get(); |
| 213 bind_info->stgmedData.pstm->AddRef(); |
| 214 return BSCBImpl::GetBindInfo(bind_flags, bind_info); |
| 215 } |
| 216 |
| 217 STDMETHOD(OnResponse)(DWORD response_code, LPCWSTR response_headers, |
| 218 LPCWSTR request_headers, LPWSTR* additional_headers) { |
| 219 DVLOG(1) << __FUNCTION__ << " headers: \n" << response_headers; |
| 220 return BSCBImpl::OnResponse(response_code, response_headers, |
| 221 request_headers, additional_headers); |
| 350 } | 222 } |
| 351 | 223 |
| 352 private: | 224 private: |
| 353 URLFetcher* fetcher_; | 225 std::wstring server_url_; |
| 354 base::PlatformThreadId creator_thread_id_; | 226 size_t upload_data_size_; |
| 227 ScopedComPtr<IStream> cache_stream_; |
| 228 ScopedComPtr<IMoniker> upload_moniker_; |
| 355 }; | 229 }; |
| 356 | 230 |
| 357 MetricsService* MetricsService::GetInstance() { | 231 MetricsService* MetricsService::GetInstance() { |
| 358 base::AutoLock lock(g_metrics_service_lock); | 232 if (g_metrics_instance_.Pointer()->Get()) |
| 359 return &g_metrics_instance_.Get(); | 233 return g_metrics_instance_.Pointer()->Get(); |
| 234 |
| 235 g_metrics_instance_.Pointer()->Set(new MetricsService); |
| 236 return g_metrics_instance_.Pointer()->Get(); |
| 360 } | 237 } |
| 361 | 238 |
| 362 MetricsService::MetricsService() | 239 MetricsService::MetricsService() |
| 363 : recording_active_(false), | 240 : recording_active_(false), |
| 364 reporting_active_(false), | 241 reporting_active_(false), |
| 365 user_permits_upload_(false), | 242 user_permits_upload_(false), |
| 366 state_(INITIALIZED), | 243 state_(INITIALIZED), |
| 367 thread_(NULL), | 244 thread_(NULL), |
| 368 initial_uma_upload_(true), | 245 initial_uma_upload_(true), |
| 369 transmission_timer_id_(0) { | 246 transmission_timer_id_(0) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 386 | 263 |
| 387 thread_ = base::PlatformThread::CurrentId(); | 264 thread_ = base::PlatformThread::CurrentId(); |
| 388 | 265 |
| 389 user_permits_upload_ = GoogleUpdateSettings::GetCollectStatsConsent(); | 266 user_permits_upload_ = GoogleUpdateSettings::GetCollectStatsConsent(); |
| 390 // Update session ID | 267 // Update session ID |
| 391 session_id_ = CrashMetricsReporter::GetInstance()->IncrementMetric( | 268 session_id_ = CrashMetricsReporter::GetInstance()->IncrementMetric( |
| 392 CrashMetricsReporter::SESSION_ID); | 269 CrashMetricsReporter::SESSION_ID); |
| 393 | 270 |
| 394 // Ensure that an instance of the StatisticsRecorder object is created. | 271 // Ensure that an instance of the StatisticsRecorder object is created. |
| 395 g_statistics_recorder_.Get(); | 272 g_statistics_recorder_.Get(); |
| 396 | |
| 397 if (user_permits_upload_) { | |
| 398 // Ensure that an instance of the metrics upload thread is created. | |
| 399 g_metrics_upload_thread_.Get(); | |
| 400 } | |
| 401 | |
| 402 CrashMetricsReporter::GetInstance()->set_active(true); | 273 CrashMetricsReporter::GetInstance()->set_active(true); |
| 403 } | 274 } |
| 404 | 275 |
| 405 // static | 276 // static |
| 406 void MetricsService::Start() { | 277 void MetricsService::Start() { |
| 407 base::AutoLock lock(metrics_service_lock_); | 278 base::AutoLock lock(metrics_service_lock_); |
| 408 | 279 |
| 409 if (GetInstance()->state_ == ACTIVE) | 280 if (GetInstance()->state_ == ACTIVE) |
| 410 return; | 281 return; |
| 411 | 282 |
| 412 GetInstance()->InitializeMetricsState(); | 283 GetInstance()->InitializeMetricsState(); |
| 413 GetInstance()->SetRecording(true); | 284 GetInstance()->SetRecording(true); |
| 414 GetInstance()->SetReporting(true); | 285 GetInstance()->SetReporting(true); |
| 415 } | 286 } |
| 416 | 287 |
| 417 // static | 288 // static |
| 418 void MetricsService::Stop() { | 289 void MetricsService::Stop() { |
| 419 { | 290 base::AutoLock lock(metrics_service_lock_); |
| 420 base::AutoLock lock(metrics_service_lock_); | |
| 421 | 291 |
| 422 GetInstance()->SetReporting(false); | 292 GetInstance()->SetReporting(false); |
| 423 GetInstance()->SetRecording(false); | 293 GetInstance()->SetRecording(false); |
| 424 } | |
| 425 | |
| 426 if (GetInstance()->user_permits_upload_) | |
| 427 g_metrics_upload_thread_.Get().Stop(); | |
| 428 } | 294 } |
| 429 | 295 |
| 430 void MetricsService::SetRecording(bool enabled) { | 296 void MetricsService::SetRecording(bool enabled) { |
| 297 DCHECK_EQ(thread_, base::PlatformThread::CurrentId()); |
| 431 if (enabled == recording_active_) | 298 if (enabled == recording_active_) |
| 432 return; | 299 return; |
| 433 | 300 |
| 434 if (enabled) { | 301 if (enabled) { |
| 435 if (client_id_.empty()) { | 302 if (client_id_.empty()) { |
| 436 client_id_ = GenerateClientID(); | 303 client_id_ = GenerateClientID(); |
| 437 // Save client id somewhere. | 304 // Save client id somewhere. |
| 438 } | 305 } |
| 439 StartRecording(); | 306 StartRecording(); |
| 440 | 307 |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 616 version += "-F"; | 483 version += "-F"; |
| 617 if (!version_info.IsOfficialBuild()) | 484 if (!version_info.IsOfficialBuild()) |
| 618 version.append("-devel"); | 485 version.append("-devel"); |
| 619 return version; | 486 return version; |
| 620 } else { | 487 } else { |
| 621 NOTREACHED() << "Unable to retrieve version string."; | 488 NOTREACHED() << "Unable to retrieve version string."; |
| 622 } | 489 } |
| 623 | 490 |
| 624 return std::string(); | 491 return std::string(); |
| 625 } | 492 } |
| OLD | NEW |