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

Unified Diff: chrome_frame/metrics_service.cc

Issue 6881018: Switch back to using urlmon (from using Chrome's network stack) to upload metrics. This basicall... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome_frame/metrics_service.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome_frame/metrics_service.cc
===================================================================
--- chrome_frame/metrics_service.cc (revision 81938)
+++ chrome_frame/metrics_service.cc (working copy)
@@ -44,47 +44,29 @@
#include <objbase.h>
#include <windows.h>
-#include <vector>
-
#if defined(USE_SYSTEM_LIBBZ2)
#include <bzlib.h>
#else
#include "third_party/bzip2/bzlib.h"
#endif
-#include "base/file_version_info.h"
-#include "base/string_split.h"
#include "base/string_util.h"
#include "base/stringprintf.h"
#include "base/synchronization/lock.h"
#include "base/string_number_conversions.h"
-#include "base/threading/thread.h"
#include "base/utf_string_conversions.h"
+#include "base/win/scoped_comptr.h"
#include "chrome/common/chrome_version_info.h"
-#include "chrome/common/net/url_fetcher.h"
#include "chrome/installer/util/browser_distribution.h"
-#include "chrome/installer/util/chrome_frame_distribution.h"
#include "chrome/installer/util/google_update_settings.h"
#include "chrome_frame/bind_status_callback_impl.h"
-#include "chrome_frame/chrome_frame_delegate.h"
#include "chrome_frame/crash_reporting/crash_metrics.h"
#include "chrome_frame/html_utils.h"
-#include "chrome_frame/http_negotiate.h"
#include "chrome_frame/utils.h"
-#include "net/base/capturing_net_log.h"
-#include "net/base/cert_verifier.h"
-#include "net/base/host_resolver.h"
-#include "net/base/ssl_config_service_defaults.h"
-#include "net/base/upload_data.h"
-#include "net/http/http_auth_handler_factory.h"
-#include "net/http/http_cache.h"
-#include "net/http/http_network_session.h"
-#include "net/url_request/url_request_context.h"
-#include "net/url_request/url_request_context_getter.h"
-#include "net/url_request/url_request_status.h"
using base::Time;
using base::TimeDelta;
+using base::win::ScopedComPtr;
static const char kMetricsType[] = "application/vnd.mozilla.metrics.bz2";
@@ -94,269 +76,164 @@
// Default to one UMA upload per 10 mins.
static const int kMinMilliSecondsPerUMAUpload = 600000;
-base::LazyInstance<MetricsService>
- g_metrics_instance_(base::LINKER_INITIALIZED);
+base::LazyInstance<base::ThreadLocalPointer<MetricsService> >
+ MetricsService::g_metrics_instance_(base::LINKER_INITIALIZED);
base::Lock MetricsService::metrics_service_lock_;
-// Traits to create an instance of the ChromeFrame upload thread.
-struct UploadThreadInstanceTraits
- : public base::LeakyLazyInstanceTraits<base::Thread> {
- static base::Thread* New(void* instance) {
- // Use placement new to initialize our instance in our preallocated space.
- // The parenthesis is very important here to force POD type initialization.
- base::Thread* upload_thread =
- new(instance) base::Thread("ChromeFrameUploadThread");
- base::Thread::Options options;
- options.message_loop_type = MessageLoop::TYPE_IO;
- bool ret = upload_thread->StartWithOptions(options);
- if (!ret) {
- NOTREACHED() << "Failed to start upload thread";
- }
- return upload_thread;
- }
-};
-
-// ChromeFrame UMA uploads occur on this thread. This thread is started on the
-// IE UI thread. This thread needs to be stopped on the same thread it was
-// started on. We don't have a good way of achieving this at this point. This
-// thread object is currently leaked.
-// TODO(ananta)
-// TODO(vitalybuka@chromium.org) : Fix this by using MetricsService::Stop() in
-// appropriate location.
-base::LazyInstance<base::Thread, UploadThreadInstanceTraits>
- g_metrics_upload_thread_(base::LINKER_INITIALIZED);
-
-base::Lock g_metrics_service_lock;
-
extern base::LazyInstance<base::StatisticsRecorder> g_statistics_recorder_;
-// This class provides HTTP request context information for metrics upload
-// requests initiated by ChromeFrame.
-class ChromeFrameUploadRequestContext : public net::URLRequestContext {
+// This class provides functionality to upload the ChromeFrame UMA data to the
+// server. An instance of this class is created whenever we have data to be
+// uploaded to the server.
+class ChromeFrameMetricsDataUploader : public BSCBImpl {
public:
- explicit ChromeFrameUploadRequestContext(MessageLoop* io_loop)
- : io_loop_(io_loop) {
- Initialize();
+ ChromeFrameMetricsDataUploader()
+ : cache_stream_(NULL),
+ upload_data_size_(0) {
+ DVLOG(1) << __FUNCTION__;
}
- ~ChromeFrameUploadRequestContext() {
+ ~ChromeFrameMetricsDataUploader() {
DVLOG(1) << __FUNCTION__;
- delete http_transaction_factory();
- delete http_auth_handler_factory();
- delete cert_verifier();
- delete host_resolver();
}
- void Initialize() {
- user_agent_ = http_utils::GetDefaultUserAgent();
- user_agent_ = http_utils::AddChromeFrameToUserAgentValue(
- user_agent_);
+ static HRESULT ChromeFrameMetricsDataUploader::UploadDataHelper(
+ const std::string& upload_data) {
+ CComObject<ChromeFrameMetricsDataUploader>* data_uploader = NULL;
+ CComObject<ChromeFrameMetricsDataUploader>::CreateInstance(&data_uploader);
+ DCHECK(data_uploader != NULL);
- set_host_resolver(
- net::CreateSystemHostResolver(net::HostResolver::kDefaultParallelism,
- NULL, NULL));
- set_cert_verifier(new net::CertVerifier);
- net::ProxyConfigService* proxy_config_service =
- net::ProxyService::CreateSystemProxyConfigService(NULL, NULL);
- DCHECK(proxy_config_service);
-
- set_proxy_service(net::ProxyService::CreateUsingSystemProxyResolver(
- proxy_config_service, 0, NULL));
- DCHECK(proxy_service());
-
- set_ssl_config_service(new net::SSLConfigServiceDefaults);
-
- url_security_manager_.reset(
- net::URLSecurityManager::Create(NULL, NULL));
-
- std::string csv_auth_schemes = "basic,digest,ntlm,negotiate";
- std::vector<std::string> supported_schemes;
- base::SplitString(csv_auth_schemes, ',', &supported_schemes);
-
- set_http_auth_handler_factory(net::HttpAuthHandlerRegistryFactory::Create(
- supported_schemes, url_security_manager_.get(), host_resolver(),
- std::string(), false, false));
-
- net::HttpNetworkSession::Params session_params;
- session_params.host_resolver = host_resolver();
- session_params.cert_verifier = cert_verifier();
- session_params.proxy_service = proxy_service();
- session_params.http_auth_handler_factory =
- http_auth_handler_factory();
- session_params.ssl_config_service = ssl_config_service();
- scoped_refptr<net::HttpNetworkSession> network_session =
- new net::HttpNetworkSession(session_params);
-
- set_http_transaction_factory(new net::HttpCache(
- network_session,
- net::HttpCache::DefaultBackend::InMemory(0)));
+ data_uploader->AddRef();
+ HRESULT hr = data_uploader->UploadData(upload_data);
+ if (FAILED(hr)) {
+ DLOG(ERROR) << "Failed to initialize ChromeFrame UMA data uploader: Err"
+ << hr;
+ }
+ data_uploader->Release();
+ return hr;
}
- virtual const std::string& GetUserAgent(const GURL& url) const {
- return user_agent_;
- }
+ HRESULT UploadData(const std::string& upload_data) {
+ if (upload_data.empty()) {
+ NOTREACHED() << "Invalid upload data";
+ return E_INVALIDARG;
+ }
- private:
- std::string user_agent_;
- MessageLoop* io_loop_;
- scoped_ptr<net::URLSecurityManager> url_security_manager_;
-};
+ DCHECK(cache_stream_.get() == NULL);
-// This class provides an interface to retrieve the URL request context for
-// metrics HTTP upload requests initiated by ChromeFrame.
-class ChromeFrameUploadRequestContextGetter
- : public net::URLRequestContextGetter {
- public:
- explicit ChromeFrameUploadRequestContextGetter(MessageLoop* io_loop)
- : io_loop_(io_loop) {}
+ upload_data_size_ = upload_data.size() + 1;
- virtual net::URLRequestContext* GetURLRequestContext() {
- if (!context_)
- context_ = new ChromeFrameUploadRequestContext(io_loop_);
- return context_;
- }
-
- virtual scoped_refptr<base::MessageLoopProxy> GetIOMessageLoopProxy() const {
- if (!io_message_loop_proxy_.get()) {
- io_message_loop_proxy_ = base::MessageLoopProxy::CreateForCurrentThread();
+ HRESULT hr = CreateStreamOnHGlobal(NULL, TRUE, cache_stream_.Receive());
+ if (FAILED(hr)) {
+ NOTREACHED() << "Failed to create stream. Error:"
+ << hr;
+ return hr;
}
- return io_message_loop_proxy_;
- }
- private:
- ~ChromeFrameUploadRequestContextGetter() {
- DVLOG(1) << __FUNCTION__;
- }
+ DCHECK(cache_stream_.get());
- scoped_refptr<net::URLRequestContext> context_;
- mutable scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_;
- MessageLoop* io_loop_;
-};
+ unsigned long written = 0;
+ cache_stream_->Write(upload_data.c_str(), upload_data_size_, &written);
+ DCHECK(written == upload_data_size_);
-// This class provides functionality to upload the ChromeFrame UMA data to the
-// server. An instance of this class is created whenever we have data to be
-// uploaded to the server.
-class ChromeFrameMetricsDataUploader
- : public URLFetcher::Delegate,
- public base::RefCountedThreadSafe<ChromeFrameMetricsDataUploader>,
- public CWindowImpl<ChromeFrameMetricsDataUploader>,
- public TaskMarshallerThroughWindowsMessages<
- ChromeFrameMetricsDataUploader> {
- public:
- BEGIN_MSG_MAP(ChromeFrameMetricsDataUploader)
- CHAIN_MSG_MAP(
- TaskMarshallerThroughWindowsMessages<ChromeFrameMetricsDataUploader>)
- END_MSG_MAP()
+ RewindStream(cache_stream_);
- ChromeFrameMetricsDataUploader()
- : fetcher_(NULL) {
- DVLOG(1) << __FUNCTION__;
- creator_thread_id_ = base::PlatformThread::CurrentId();
- }
+ BrowserDistribution* dist = BrowserDistribution::GetSpecificDistribution(
+ BrowserDistribution::CHROME_FRAME);
+ server_url_ = dist->GetStatsServerURL();
+ DCHECK(!server_url_.empty());
- ~ChromeFrameMetricsDataUploader() {
- DVLOG(1) << __FUNCTION__;
- DCHECK(creator_thread_id_ == base::PlatformThread::CurrentId());
- }
+ hr = CreateURLMoniker(NULL, server_url_.c_str(),
+ upload_moniker_.Receive());
+ if (FAILED(hr)) {
+ DLOG(ERROR) << "Failed to create url moniker for url:"
+ << server_url_.c_str()
+ << " Error:"
+ << hr;
+ } else {
+ ScopedComPtr<IBindCtx> context;
+ hr = CreateAsyncBindCtx(0, this, NULL, context.Receive());
+ DCHECK(SUCCEEDED(hr));
+ DCHECK(context);
- virtual void OnFinalMessage(HWND wnd) {
- Release();
- }
-
- bool Initialize() {
- bool ret = false;
-
- if (!Create(NULL, NULL, NULL, WS_OVERLAPPEDWINDOW)) {
- NOTREACHED() << "Failed to create window";
- return ret;
+ ScopedComPtr<IStream> stream;
+ hr = upload_moniker_->BindToStorage(
+ context, NULL, IID_IStream,
+ reinterpret_cast<void**>(stream.Receive()));
+ if (FAILED(hr)) {
+ NOTREACHED();
+ DLOG(ERROR) << "Failed to bind to upload data moniker. Error:"
+ << hr;
+ }
}
- DCHECK(IsWindow());
-
- if (!g_metrics_upload_thread_.Get().IsRunning()) {
- NOTREACHED() << "Upload thread is not running";
- return ret;
- }
-
- ret = true;
- // Grab a reference to the current instance which ensures that it stays
- // around until the HTTP request initiated below completes.
- // Corresponding Release is in OnFinalMessage.
- AddRef();
- return ret;
+ return hr;
}
- bool Uninitialize() {
- DestroyWindow();
- return true;
- }
+ STDMETHOD(BeginningTransaction)(LPCWSTR url, LPCWSTR headers, DWORD reserved,
+ LPWSTR* additional_headers) {
+ std::string new_headers;
+ new_headers =
+ StringPrintf("Content-Length: %s\r\n"
+ "Content-Type: %s\r\n"
+ "%s\r\n",
+ base::Int64ToString(upload_data_size_).c_str(),
+ kMetricsType,
+ http_utils::GetDefaultUserAgentHeaderWithCFTag());
- static HRESULT ChromeFrameMetricsDataUploader::UploadDataHelper(
- const std::string& upload_data) {
- scoped_refptr<ChromeFrameMetricsDataUploader> data_uploader =
- new ChromeFrameMetricsDataUploader();
+ *additional_headers = reinterpret_cast<wchar_t*>(
+ CoTaskMemAlloc((new_headers.size() + 1) * sizeof(wchar_t)));
- if (!data_uploader->Initialize()) {
- NOTREACHED() << "Failed to initialize ChromeFrameMetricsDataUploader";
- return E_FAIL;
- }
+ lstrcpynW(*additional_headers, ASCIIToWide(new_headers).c_str(),
+ new_headers.size());
- MessageLoop* io_loop = g_metrics_upload_thread_.Get().message_loop();
- if (!io_loop) {
- NOTREACHED() << "Failed to initialize ChromeFrame UMA upload thread";
- return E_FAIL;
- }
-
- io_loop->PostTask(
- FROM_HERE,
- NewRunnableMethod(data_uploader.get(),
- &ChromeFrameMetricsDataUploader::UploadData,
- upload_data, io_loop));
- return S_OK;
+ return BSCBImpl::BeginningTransaction(url, headers, reserved,
+ additional_headers);
}
- void UploadData(const std::string& upload_data, MessageLoop* message_loop) {
- DCHECK(fetcher_ == NULL);
- DCHECK(message_loop != NULL);
+ STDMETHOD(GetBindInfo)(DWORD* bind_flags, BINDINFO* bind_info) {
+ if ((bind_info == NULL) || (bind_info->cbSize == 0) ||
+ (bind_flags == NULL))
+ return E_INVALIDARG;
- BrowserDistribution* dist = ChromeFrameDistribution::GetDistribution();
- DCHECK(dist != NULL);
+ *bind_flags = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
+ // Bypass caching proxies on POSTs and PUTs and avoid writing responses to
+ // these requests to the browser's cache
+ *bind_flags |= BINDF_GETNEWESTVERSION | BINDF_PRAGMA_NO_CACHE;
- fetcher_ = new URLFetcher(GURL(WideToUTF8(dist->GetStatsServerURL())),
- URLFetcher::POST, this);
+ DCHECK(cache_stream_.get());
- fetcher_->set_request_context(new ChromeFrameUploadRequestContextGetter(
- message_loop));
- fetcher_->set_upload_data(kMetricsType, upload_data);
- fetcher_->Start();
+ // Initialize the STGMEDIUM.
+ memset(&bind_info->stgmedData, 0, sizeof(STGMEDIUM));
+ bind_info->grfBindInfoF = 0;
+ bind_info->szCustomVerb = NULL;
+ bind_info->dwBindVerb = BINDVERB_POST;
+ bind_info->stgmedData.tymed = TYMED_ISTREAM;
+ bind_info->stgmedData.pstm = cache_stream_.get();
+ bind_info->stgmedData.pstm->AddRef();
+ return BSCBImpl::GetBindInfo(bind_flags, bind_info);
}
- // URLFetcher::Delegate
- virtual void OnURLFetchComplete(const URLFetcher* source,
- const GURL& url,
- const net::URLRequestStatus& status,
- int response_code,
- const ResponseCookies& cookies,
- const std::string& data) {
- DVLOG(1) << __FUNCTION__ << base::StringPrintf(
- ": url : %hs, status:%d, response code: %d\n", url.spec().c_str(),
- status.status(), response_code);
- delete fetcher_;
- fetcher_ = NULL;
-
- PostTask(FROM_HERE,
- NewRunnableMethod(this,
- &ChromeFrameMetricsDataUploader::Uninitialize));
+ STDMETHOD(OnResponse)(DWORD response_code, LPCWSTR response_headers,
+ LPCWSTR request_headers, LPWSTR* additional_headers) {
+ DVLOG(1) << __FUNCTION__ << " headers: \n" << response_headers;
+ return BSCBImpl::OnResponse(response_code, response_headers,
+ request_headers, additional_headers);
}
private:
- URLFetcher* fetcher_;
- base::PlatformThreadId creator_thread_id_;
+ std::wstring server_url_;
+ size_t upload_data_size_;
+ ScopedComPtr<IStream> cache_stream_;
+ ScopedComPtr<IMoniker> upload_moniker_;
};
MetricsService* MetricsService::GetInstance() {
- base::AutoLock lock(g_metrics_service_lock);
- return &g_metrics_instance_.Get();
+ if (g_metrics_instance_.Pointer()->Get())
+ return g_metrics_instance_.Pointer()->Get();
+
+ g_metrics_instance_.Pointer()->Set(new MetricsService);
+ return g_metrics_instance_.Pointer()->Get();
}
MetricsService::MetricsService()
@@ -393,12 +270,6 @@
// Ensure that an instance of the StatisticsRecorder object is created.
g_statistics_recorder_.Get();
-
- if (user_permits_upload_) {
- // Ensure that an instance of the metrics upload thread is created.
- g_metrics_upload_thread_.Get();
- }
-
CrashMetricsReporter::GetInstance()->set_active(true);
}
@@ -416,18 +287,14 @@
// static
void MetricsService::Stop() {
- {
- base::AutoLock lock(metrics_service_lock_);
+ base::AutoLock lock(metrics_service_lock_);
- GetInstance()->SetReporting(false);
- GetInstance()->SetRecording(false);
- }
-
- if (GetInstance()->user_permits_upload_)
- g_metrics_upload_thread_.Get().Stop();
+ GetInstance()->SetReporting(false);
+ GetInstance()->SetRecording(false);
}
void MetricsService::SetRecording(bool enabled) {
+ DCHECK_EQ(thread_, base::PlatformThread::CurrentId());
if (enabled == recording_active_)
return;
« 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