1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// found in the LICENSE file. 4a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// 5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// A standalone tool for testing MCS connections and the MCS client on their 6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// own. 7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 8a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <cstddef> 9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <cstdio> 10a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <string> 11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/at_exit.h" 13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/command_line.h" 14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/compiler_specific.h" 15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/logging.h" 16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/memory/ref_counted.h" 17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/message_loop/message_loop.h" 19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/run_loop.h" 20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/strings/string_number_conversions.h" 21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/threading/thread.h" 22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/threading/worker_pool.h" 23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/values.h" 24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/gcm/base/mcs_message.h" 25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/gcm/base/mcs_util.h" 26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/gcm/engine/connection_factory_impl.h" 27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/gcm/engine/mcs_client.h" 28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "net/base/host_mapping_rules.h" 29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "net/base/net_log_logger.h" 30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "net/cert/cert_verifier.h" 31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "net/dns/host_resolver.h" 32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "net/http/http_auth_handler_factory.h" 33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "net/http/http_network_session.h" 34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "net/http/http_server_properties_impl.h" 35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "net/http/transport_security_state.h" 36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "net/socket/client_socket_factory.h" 37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "net/socket/ssl_client_socket.h" 38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "net/ssl/default_server_bound_cert_store.h" 39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "net/ssl/server_bound_cert_service.h" 40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "net/url_request/url_request_test_util.h" 41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#if defined(OS_MACOSX) 43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/mac/scoped_nsautorelease_pool.h" 44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif 45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// This is a simple utility that initializes an mcs client and 47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// prints out any events. 48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace gcm { 49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace { 50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// The default server to communicate with. 52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const char kMCSServerHost[] = "mtalk.google.com"; 53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const uint16 kMCSServerPort = 5228; 54a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Command line switches. 56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const char kRMQFileName[] = "rmq_file"; 57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const char kAndroidIdSwitch[] = "android_id"; 58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const char kSecretSwitch[] = "secret"; 59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const char kLogFileSwitch[] = "log-file"; 60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const char kIgnoreCertSwitch[] = "ignore-certs"; 61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const char kServerHostSwitch[] = "host"; 62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const char kServerPortSwitch[] = "port"; 63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MessageReceivedCallback(const MCSMessage& message) { 65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) LOG(INFO) << "Received message with id " 66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) << GetPersistentId(message.GetProtobuf()) << " and tag " 67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) << static_cast<int>(message.tag()); 68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (message.tag() == kDataMessageStanzaTag) { 70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const mcs_proto::DataMessageStanza& data_message = 71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) reinterpret_cast<const mcs_proto::DataMessageStanza&>( 72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) message.GetProtobuf()); 73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DVLOG(1) << " to: " << data_message.to(); 74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DVLOG(1) << " from: " << data_message.from(); 75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DVLOG(1) << " category: " << data_message.category(); 76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DVLOG(1) << " sent: " << data_message.sent(); 77a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (int i = 0; i < data_message.app_data_size(); ++i) { 78a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DVLOG(1) << " App data " << i << " " 79a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) << data_message.app_data(i).key() << " : " 80a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) << data_message.app_data(i).value(); 81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 84a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MessageSentCallback(const std::string& local_id) { 86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) LOG(INFO) << "Message sent. Status: " << local_id; 87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Needed to use a real host resolver. 90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class MyTestURLRequestContext : public net::TestURLRequestContext { 91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public: 92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) MyTestURLRequestContext() : TestURLRequestContext(true) { 93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) context_storage_.set_host_resolver( 94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) net::HostResolver::CreateDefaultResolver(NULL)); 95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) context_storage_.set_transport_security_state( 96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) new net::TransportSecurityState()); 97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Init(); 98a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 99a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual ~MyTestURLRequestContext() {} 101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}; 102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class MyTestURLRequestContextGetter : public net::TestURLRequestContextGetter { 104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public: 105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) explicit MyTestURLRequestContextGetter( 106a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy) 107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : TestURLRequestContextGetter(io_message_loop_proxy) {} 108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual net::TestURLRequestContext* GetURLRequestContext() OVERRIDE { 110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Construct |context_| lazily so it gets constructed on the right 111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // thread (the IO thread). 112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!context_) 113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) context_.reset(new MyTestURLRequestContext()); 114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return context_.get(); 115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) private: 118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual ~MyTestURLRequestContextGetter() {} 119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<MyTestURLRequestContext> context_; 121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}; 122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// A net log that logs all events by default. 124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class MyTestNetLog : public net::NetLog { 125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public: 126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) MyTestNetLog() { 127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SetBaseLogLevel(LOG_ALL); 128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual ~MyTestNetLog() {} 130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}; 131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 132a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// A cert verifier that access all certificates. 133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class MyTestCertVerifier : public net::CertVerifier { 134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public: 135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) MyTestCertVerifier() {} 136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual ~MyTestCertVerifier() {} 137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual int Verify(net::X509Certificate* cert, 139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string& hostname, 140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int flags, 141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) net::CRLSet* crl_set, 142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) net::CertVerifyResult* verify_result, 143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const net::CompletionCallback& callback, 144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) RequestHandle* out_req, 145a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const net::BoundNetLog& net_log) OVERRIDE { 146a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return net::OK; 147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual void CancelRequest(RequestHandle req) OVERRIDE { 150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Do nothing. 151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 152a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}; 153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class MCSProbe { 155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public: 156a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) MCSProbe( 157a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const CommandLine& command_line, 158a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_refptr<net::URLRequestContextGetter> url_request_context_getter); 159a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ~MCSProbe(); 160a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 161a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void Start(); 162a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 163a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint64 android_id() const { return android_id_; } 164a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint64 secret() const { return secret_; } 165a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 166a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) private: 167a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void InitializeNetworkState(); 168a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void BuildNetworkSession(); 169a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 170a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void InitializationCallback(bool success, 171a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint64 restored_android_id, 172a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint64 restored_security_token); 173a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CommandLine command_line_; 175a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 176a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::FilePath rmq_path_; 177a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint64 android_id_; 178a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint64 secret_; 179a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::string server_host_; 180a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int server_port_; 181a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 182a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Network state. 183a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_; 184a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) MyTestNetLog net_log_; 185a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<net::NetLogLogger> logger_; 186a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<base::Value> net_constants_; 187a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<net::HostResolver> host_resolver_; 188a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<net::CertVerifier> cert_verifier_; 189a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<net::ServerBoundCertService> system_server_bound_cert_service_; 190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<net::TransportSecurityState> transport_security_state_; 191a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<net::URLSecurityManager> url_security_manager_; 192a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<net::HttpAuthHandlerFactory> http_auth_handler_factory_; 193a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<net::HttpServerPropertiesImpl> http_server_properties_; 194a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<net::HostMappingRules> host_mapping_rules_; 195a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_refptr<net::HttpNetworkSession> network_session_; 196a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<net::ProxyService> proxy_service_; 197a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 198a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<MCSClient> mcs_client_; 199a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 200a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<ConnectionFactoryImpl> connection_factory_; 201a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 202a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Thread file_thread_; 203a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 204a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<base::RunLoop> run_loop_; 205a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}; 206a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 207a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)MCSProbe::MCSProbe( 208a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const CommandLine& command_line, 209a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_refptr<net::URLRequestContextGetter> url_request_context_getter) 210a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : command_line_(command_line), 211a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) rmq_path_(base::FilePath(FILE_PATH_LITERAL("gcm_rmq_store"))), 212a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) android_id_(0), 213a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) secret_(0), 214a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) server_port_(0), 215a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) url_request_context_getter_(url_request_context_getter), 216a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) file_thread_("FileThread") { 217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (command_line.HasSwitch(kRMQFileName)) { 218a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) rmq_path_ = command_line.GetSwitchValuePath(kRMQFileName); 219a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (command_line.HasSwitch(kAndroidIdSwitch)) { 221a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::StringToUint64(command_line.GetSwitchValueASCII(kAndroidIdSwitch), 222a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) &android_id_); 223a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 224a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (command_line.HasSwitch(kSecretSwitch)) { 225a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::StringToUint64(command_line.GetSwitchValueASCII(kSecretSwitch), 226a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) &secret_); 227a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 228a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) server_host_ = kMCSServerHost; 229a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (command_line.HasSwitch(kServerHostSwitch)) { 230a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) server_host_ = command_line.GetSwitchValueASCII(kServerHostSwitch); 231a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 232a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) server_port_ = kMCSServerPort; 233a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (command_line.HasSwitch(kServerPortSwitch)) { 234a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::StringToInt(command_line.GetSwitchValueASCII(kServerPortSwitch), 235a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) &server_port_); 236a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 237a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 238a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 239a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)MCSProbe::~MCSProbe() { 240a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) file_thread_.Stop(); 241a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 243a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MCSProbe::Start() { 244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) file_thread_.Start(); 245a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) InitializeNetworkState(); 246a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) BuildNetworkSession(); 247a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) connection_factory_.reset( 248a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) new ConnectionFactoryImpl(GURL("https://" + net::HostPortPair( 249a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) server_host_, server_port_).ToString()), 250a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) network_session_, 251a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) &net_log_)); 252a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) mcs_client_.reset(new MCSClient(rmq_path_, 253a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) connection_factory_.get(), 254a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) file_thread_.message_loop_proxy())); 255a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) run_loop_.reset(new base::RunLoop()); 256a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) mcs_client_->Initialize(base::Bind(&MCSProbe::InitializationCallback, 257a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Unretained(this)), 258a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Bind(&MessageReceivedCallback), 259a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Bind(&MessageSentCallback)); 260a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) run_loop_->Run(); 261a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 262a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 263a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MCSProbe::InitializeNetworkState() { 264a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) FILE* log_file = NULL; 265a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (command_line_.HasSwitch(kLogFileSwitch)) { 266a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::FilePath log_path = command_line_.GetSwitchValuePath(kLogFileSwitch); 267a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#if defined(OS_WIN) 268a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) log_file = _wfopen(log_path.value().c_str(), L"w"); 269a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#elif defined(OS_POSIX) 270a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) log_file = fopen(log_path.value().c_str(), "w"); 271a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif 272a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 273a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) net_constants_.reset(net::NetLogLogger::GetConstants()); 274a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (log_file != NULL) { 275a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) logger_.reset(new net::NetLogLogger(log_file, *net_constants_)); 276a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) logger_->StartObserving(&net_log_); 277a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 278a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 279a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) host_resolver_ = net::HostResolver::CreateDefaultResolver(&net_log_); 280a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 281a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (command_line_.HasSwitch(kIgnoreCertSwitch)) { 282a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cert_verifier_.reset(new MyTestCertVerifier()); 283a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } else { 284a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cert_verifier_.reset(net::CertVerifier::CreateDefault()); 285a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 286a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) system_server_bound_cert_service_.reset( 287a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) new net::ServerBoundCertService( 288a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) new net::DefaultServerBoundCertStore(NULL), 289a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::WorkerPool::GetTaskRunner(true))); 290a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 291a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) transport_security_state_.reset(new net::TransportSecurityState()); 292a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) url_security_manager_.reset(net::URLSecurityManager::Create(NULL, NULL)); 293a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) http_auth_handler_factory_.reset( 294a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) net::HttpAuthHandlerRegistryFactory::Create( 295a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::vector<std::string>(1, "basic"), 296a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) url_security_manager_.get(), 297a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) host_resolver_.get(), 298a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::string(), 299a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) false, 300a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) false)); 301a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) http_server_properties_.reset(new net::HttpServerPropertiesImpl()); 302a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) host_mapping_rules_.reset(new net::HostMappingRules()); 303a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) proxy_service_.reset(net::ProxyService::CreateDirectWithNetLog(&net_log_)); 304a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 305a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 306a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MCSProbe::BuildNetworkSession() { 307a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) net::HttpNetworkSession::Params session_params; 308a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) session_params.host_resolver = host_resolver_.get(); 309a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) session_params.cert_verifier = cert_verifier_.get(); 310a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) session_params.server_bound_cert_service = 311a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) system_server_bound_cert_service_.get(); 312a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) session_params.transport_security_state = transport_security_state_.get(); 313a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) session_params.ssl_config_service = new net::SSLConfigServiceDefaults(); 314a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) session_params.http_auth_handler_factory = http_auth_handler_factory_.get(); 315a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) session_params.http_server_properties = 316a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) http_server_properties_->GetWeakPtr(); 317a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) session_params.network_delegate = NULL; // TODO(zea): implement? 318a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) session_params.host_mapping_rules = host_mapping_rules_.get(); 319a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) session_params.ignore_certificate_errors = true; 320a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) session_params.http_pipelining_enabled = false; 321a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) session_params.testing_fixed_http_port = 0; 322a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) session_params.testing_fixed_https_port = 0; 323a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) session_params.net_log = &net_log_; 324a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) session_params.proxy_service = proxy_service_.get(); 325a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 326a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) network_session_ = new net::HttpNetworkSession(session_params); 327a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 328a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 329a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MCSProbe::InitializationCallback(bool success, 330a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint64 restored_android_id, 331a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint64 restored_security_token) { 332a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) LOG(INFO) << "Initialization " << (success ? "success!" : "failure!"); 333a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (restored_android_id && restored_security_token) { 334a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) android_id_ = restored_android_id; 335a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) secret_ = restored_security_token; 336a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 337a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (success) 338a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) mcs_client_->Login(android_id_, secret_); 339a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 340a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 341a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)int MCSProbeMain(int argc, char* argv[]) { 342a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::AtExitManager exit_manager; 343a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 344a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CommandLine::Init(argc, argv); 345a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) logging::LoggingSettings settings; 346a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG; 347a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) logging::InitLogging(settings); 348a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 349a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::MessageLoopForIO message_loop; 350a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 351a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // For check-in and creating registration ids. 352a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const scoped_refptr<MyTestURLRequestContextGetter> context_getter = 353a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) new MyTestURLRequestContextGetter( 354a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::MessageLoop::current()->message_loop_proxy()); 355a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 356a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 357a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 358a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) MCSProbe mcs_probe(command_line, context_getter); 359a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) mcs_probe.Start(); 360a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 361a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::RunLoop run_loop; 362a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) run_loop.Run(); 363a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 364a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return 0; 365a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 366a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 367a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} // namespace 368a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} // namespace gcm 369a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 370a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)int main(int argc, char* argv[]) { 371a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return gcm::MCSProbeMain(argc, argv); 372a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 373