Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / sync / tools / sync_listen_notifications.cc
blob1903f7fc3b308f1e838c6fca6a5d1212bf5819c6
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include <cstddef>
6 #include <cstdio>
7 #include <string>
9 #include "base/at_exit.h"
10 #include "base/command_line.h"
11 #include "base/compiler_specific.h"
12 #include "base/logging.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/message_loop/message_loop.h"
16 #include "base/rand_util.h"
17 #include "base/threading/thread.h"
18 #include "components/invalidation/impl/invalidation_state_tracker.h"
19 #include "components/invalidation/impl/invalidator.h"
20 #include "components/invalidation/impl/non_blocking_invalidator.h"
21 #include "components/invalidation/public/invalidation_handler.h"
22 #include "components/invalidation/public/invalidation_util.h"
23 #include "components/invalidation/public/object_id_invalidation_map.h"
24 #include "components/sync_driver/invalidation_helper.h"
25 #include "jingle/notifier/base/notification_method.h"
26 #include "jingle/notifier/base/notifier_options.h"
27 #include "net/base/host_port_pair.h"
28 #include "net/base/network_change_notifier.h"
29 #include "net/dns/host_resolver.h"
30 #include "net/http/transport_security_state.h"
31 #include "net/url_request/url_request_test_util.h"
32 #include "sync/internal_api/public/base/model_type.h"
33 #include "sync/tools/null_invalidation_state_tracker.h"
35 #if defined(OS_MACOSX)
36 #include "base/mac/scoped_nsautorelease_pool.h"
37 #endif
39 // This is a simple utility that initializes a sync notifier and
40 // listens to any received notifications.
42 namespace syncer {
43 namespace {
45 const char kEmailSwitch[] = "email";
46 const char kTokenSwitch[] = "token";
47 const char kHostPortSwitch[] = "host-port";
48 const char kTrySslTcpFirstSwitch[] = "try-ssltcp-first";
49 const char kAllowInsecureConnectionSwitch[] = "allow-insecure-connection";
51 // Class to print received notifications events.
52 class NotificationPrinter : public InvalidationHandler {
53 public:
54 NotificationPrinter() {}
55 ~NotificationPrinter() override {}
57 void OnInvalidatorStateChange(InvalidatorState state) override {
58 LOG(INFO) << "Invalidator state changed to "
59 << InvalidatorStateToString(state);
62 void OnIncomingInvalidation(
63 const ObjectIdInvalidationMap& invalidation_map) override {
64 ObjectIdSet ids = invalidation_map.GetObjectIds();
65 for (ObjectIdSet::const_iterator it = ids.begin(); it != ids.end(); ++it) {
66 LOG(INFO) << "Remote invalidation: "
67 << invalidation_map.ToString();
71 std::string GetOwnerName() const override { return "NotificationPrinter"; }
73 private:
74 DISALLOW_COPY_AND_ASSIGN(NotificationPrinter);
77 // Needed to use a real host resolver.
78 class MyTestURLRequestContext : public net::TestURLRequestContext {
79 public:
80 MyTestURLRequestContext() : TestURLRequestContext(true) {
81 context_storage_.set_host_resolver(
82 net::HostResolver::CreateDefaultResolver(NULL));
83 context_storage_.set_transport_security_state(
84 make_scoped_ptr(new net::TransportSecurityState()));
85 Init();
88 ~MyTestURLRequestContext() override {}
91 class MyTestURLRequestContextGetter : public net::TestURLRequestContextGetter {
92 public:
93 explicit MyTestURLRequestContextGetter(
94 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
95 : TestURLRequestContextGetter(io_task_runner) {}
97 net::TestURLRequestContext* GetURLRequestContext() override {
98 // Construct |context_| lazily so it gets constructed on the right
99 // thread (the IO thread).
100 if (!context_)
101 context_.reset(new MyTestURLRequestContext());
102 return context_.get();
105 private:
106 ~MyTestURLRequestContextGetter() override {}
108 scoped_ptr<MyTestURLRequestContext> context_;
111 notifier::NotifierOptions ParseNotifierOptions(
112 const base::CommandLine& command_line,
113 const scoped_refptr<net::URLRequestContextGetter>& request_context_getter) {
114 notifier::NotifierOptions notifier_options;
115 notifier_options.request_context_getter = request_context_getter;
117 if (command_line.HasSwitch(kHostPortSwitch)) {
118 notifier_options.xmpp_host_port =
119 net::HostPortPair::FromString(
120 command_line.GetSwitchValueASCII(kHostPortSwitch));
121 LOG(INFO) << "Using " << notifier_options.xmpp_host_port.ToString()
122 << " for test sync notification server.";
125 notifier_options.try_ssltcp_first =
126 command_line.HasSwitch(kTrySslTcpFirstSwitch);
127 LOG_IF(INFO, notifier_options.try_ssltcp_first)
128 << "Trying SSL/TCP port before XMPP port for notifications.";
130 notifier_options.allow_insecure_connection =
131 command_line.HasSwitch(kAllowInsecureConnectionSwitch);
132 LOG_IF(INFO, notifier_options.allow_insecure_connection)
133 << "Allowing insecure XMPP connections.";
135 return notifier_options;
138 int SyncListenNotificationsMain(int argc, char* argv[]) {
139 using namespace syncer;
140 #if defined(OS_MACOSX)
141 base::mac::ScopedNSAutoreleasePool pool;
142 #endif
143 base::AtExitManager exit_manager;
144 base::CommandLine::Init(argc, argv);
145 logging::LoggingSettings settings;
146 settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
147 logging::InitLogging(settings);
149 base::MessageLoop ui_loop;
150 base::Thread io_thread("IO thread");
151 base::Thread::Options options;
152 options.message_loop_type = base::MessageLoop::TYPE_IO;
153 io_thread.StartWithOptions(options);
155 // Parse command line.
156 const base::CommandLine& command_line =
157 *base::CommandLine::ForCurrentProcess();
158 std::string email = command_line.GetSwitchValueASCII(kEmailSwitch);
159 std::string token = command_line.GetSwitchValueASCII(kTokenSwitch);
160 // TODO(akalin): Write a wrapper script that gets a token for an
161 // email and password and passes that in to this utility.
162 if (email.empty() || token.empty()) {
163 std::printf("Usage: %s --%s=foo@bar.com --%s=token\n"
164 "[--%s=host:port] [--%s] [--%s]\n"
165 "Run chrome and set a breakpoint on\n"
166 "syncer::SyncManagerImpl::UpdateCredentials() "
167 "after logging into\n"
168 "sync to get the token to pass into this utility.\n",
169 argv[0],
170 kEmailSwitch, kTokenSwitch, kHostPortSwitch,
171 kTrySslTcpFirstSwitch, kAllowInsecureConnectionSwitch);
172 return -1;
175 // Set up objects that monitor the network.
176 scoped_ptr<net::NetworkChangeNotifier> network_change_notifier(
177 net::NetworkChangeNotifier::Create());
179 const notifier::NotifierOptions& notifier_options =
180 ParseNotifierOptions(
181 command_line,
182 new MyTestURLRequestContextGetter(io_thread.task_runner()));
183 syncer::NetworkChannelCreator network_channel_creator =
184 syncer::NonBlockingInvalidator::MakePushClientChannelCreator(
185 notifier_options);
186 const char kClientInfo[] = "sync_listen_notifications";
187 NullInvalidationStateTracker null_invalidation_state_tracker;
188 scoped_ptr<Invalidator> invalidator(
189 new NonBlockingInvalidator(
190 network_channel_creator,
191 base::RandBytesAsString(8),
192 null_invalidation_state_tracker.GetSavedInvalidations(),
193 null_invalidation_state_tracker.GetBootstrapData(),
194 &null_invalidation_state_tracker,
195 kClientInfo,
196 notifier_options.request_context_getter));
198 NotificationPrinter notification_printer;
200 invalidator->UpdateCredentials(email, token);
202 // Listen for notifications for all known types.
203 invalidator->RegisterHandler(&notification_printer);
204 CHECK(invalidator->UpdateRegisteredIds(
205 &notification_printer, ModelTypeSetToObjectIdSet(ModelTypeSet::All())));
207 ui_loop.Run();
209 invalidator->UnregisterHandler(&notification_printer);
210 io_thread.Stop();
211 return 0;
214 } // namespace
215 } // namespace syncer
217 int main(int argc, char* argv[]) {
218 return syncer::SyncListenNotificationsMain(argc, argv);