Upstream version 8.37.180.0
[platform/framework/web/crosswalk.git] / src / sync / tools / sync_listen_notifications.cc
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.
4
5 #include <cstddef>
6 #include <cstdio>
7 #include <string>
8
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/non_blocking_invalidator.h"
19 #include "jingle/notifier/base/notification_method.h"
20 #include "jingle/notifier/base/notifier_options.h"
21 #include "net/base/host_port_pair.h"
22 #include "net/base/network_change_notifier.h"
23 #include "net/dns/host_resolver.h"
24 #include "net/http/transport_security_state.h"
25 #include "net/url_request/url_request_test_util.h"
26 #include "sync/internal_api/public/base/model_type.h"
27 #include "sync/notifier/invalidation_handler.h"
28 #include "sync/notifier/invalidation_state_tracker.h"
29 #include "sync/notifier/invalidation_util.h"
30 #include "sync/notifier/invalidator.h"
31 #include "sync/notifier/object_id_invalidation_map.h"
32 #include "sync/tools/null_invalidation_state_tracker.h"
33
34 #if defined(OS_MACOSX)
35 #include "base/mac/scoped_nsautorelease_pool.h"
36 #endif
37
38 // This is a simple utility that initializes a sync notifier and
39 // listens to any received notifications.
40
41 namespace syncer {
42 namespace {
43
44 const char kEmailSwitch[] = "email";
45 const char kTokenSwitch[] = "token";
46 const char kHostPortSwitch[] = "host-port";
47 const char kTrySslTcpFirstSwitch[] = "try-ssltcp-first";
48 const char kAllowInsecureConnectionSwitch[] = "allow-insecure-connection";
49
50 // Class to print received notifications events.
51 class NotificationPrinter : public InvalidationHandler {
52  public:
53   NotificationPrinter() {}
54   virtual ~NotificationPrinter() {}
55
56   virtual void OnInvalidatorStateChange(InvalidatorState state) OVERRIDE {
57     LOG(INFO) << "Invalidator state changed to "
58               << InvalidatorStateToString(state);
59   }
60
61   virtual void OnIncomingInvalidation(
62       const ObjectIdInvalidationMap& invalidation_map) OVERRIDE {
63     ObjectIdSet ids = invalidation_map.GetObjectIds();
64     for (ObjectIdSet::const_iterator it = ids.begin(); it != ids.end(); ++it) {
65       LOG(INFO) << "Remote invalidation: "
66                 << invalidation_map.ToString();
67     }
68   }
69
70   virtual std::string GetOwnerName() const OVERRIDE {
71     return "NotificationPrinter";
72   }
73
74  private:
75   DISALLOW_COPY_AND_ASSIGN(NotificationPrinter);
76 };
77
78 // Needed to use a real host resolver.
79 class MyTestURLRequestContext : public net::TestURLRequestContext {
80  public:
81   MyTestURLRequestContext() : TestURLRequestContext(true) {
82     context_storage_.set_host_resolver(
83         net::HostResolver::CreateDefaultResolver(NULL));
84     context_storage_.set_transport_security_state(
85         new net::TransportSecurityState());
86     Init();
87   }
88
89   virtual ~MyTestURLRequestContext() {}
90 };
91
92 class MyTestURLRequestContextGetter : public net::TestURLRequestContextGetter {
93  public:
94   explicit MyTestURLRequestContextGetter(
95       const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy)
96       : TestURLRequestContextGetter(io_message_loop_proxy) {}
97
98   virtual net::TestURLRequestContext* GetURLRequestContext() OVERRIDE {
99     // Construct |context_| lazily so it gets constructed on the right
100     // thread (the IO thread).
101     if (!context_)
102       context_.reset(new MyTestURLRequestContext());
103     return context_.get();
104   }
105
106  private:
107   virtual ~MyTestURLRequestContextGetter() {}
108
109   scoped_ptr<MyTestURLRequestContext> context_;
110 };
111
112 notifier::NotifierOptions ParseNotifierOptions(
113     const CommandLine& command_line,
114     const scoped_refptr<net::URLRequestContextGetter>&
115         request_context_getter) {
116   notifier::NotifierOptions notifier_options;
117   notifier_options.request_context_getter = request_context_getter;
118
119   if (command_line.HasSwitch(kHostPortSwitch)) {
120     notifier_options.xmpp_host_port =
121         net::HostPortPair::FromString(
122             command_line.GetSwitchValueASCII(kHostPortSwitch));
123     LOG(INFO) << "Using " << notifier_options.xmpp_host_port.ToString()
124               << " for test sync notification server.";
125   }
126
127   notifier_options.try_ssltcp_first =
128       command_line.HasSwitch(kTrySslTcpFirstSwitch);
129   LOG_IF(INFO, notifier_options.try_ssltcp_first)
130       << "Trying SSL/TCP port before XMPP port for notifications.";
131
132   notifier_options.allow_insecure_connection =
133       command_line.HasSwitch(kAllowInsecureConnectionSwitch);
134   LOG_IF(INFO, notifier_options.allow_insecure_connection)
135       << "Allowing insecure XMPP connections.";
136
137   return notifier_options;
138 }
139
140 int SyncListenNotificationsMain(int argc, char* argv[]) {
141   using namespace syncer;
142 #if defined(OS_MACOSX)
143   base::mac::ScopedNSAutoreleasePool pool;
144 #endif
145   base::AtExitManager exit_manager;
146   CommandLine::Init(argc, argv);
147   logging::LoggingSettings settings;
148   settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
149   logging::InitLogging(settings);
150
151   base::MessageLoop ui_loop;
152   base::Thread io_thread("IO thread");
153   base::Thread::Options options;
154   options.message_loop_type = base::MessageLoop::TYPE_IO;
155   io_thread.StartWithOptions(options);
156
157   // Parse command line.
158   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
159   std::string email = command_line.GetSwitchValueASCII(kEmailSwitch);
160   std::string token = command_line.GetSwitchValueASCII(kTokenSwitch);
161   // TODO(akalin): Write a wrapper script that gets a token for an
162   // email and password and passes that in to this utility.
163   if (email.empty() || token.empty()) {
164     std::printf("Usage: %s --%s=foo@bar.com --%s=token\n"
165                 "[--%s=host:port] [--%s] [--%s]\n"
166                 "Run chrome and set a breakpoint on\n"
167                 "syncer::SyncManagerImpl::UpdateCredentials() "
168                 "after logging into\n"
169                 "sync to get the token to pass into this utility.\n",
170                 argv[0],
171                 kEmailSwitch, kTokenSwitch, kHostPortSwitch,
172                 kTrySslTcpFirstSwitch, kAllowInsecureConnectionSwitch);
173     return -1;
174   }
175
176   // Set up objects that monitor the network.
177   scoped_ptr<net::NetworkChangeNotifier> network_change_notifier(
178       net::NetworkChangeNotifier::Create());
179
180   const notifier::NotifierOptions& notifier_options =
181       ParseNotifierOptions(
182           command_line,
183           new MyTestURLRequestContextGetter(io_thread.message_loop_proxy()));
184   syncer::NetworkChannelCreator network_channel_creator =
185       syncer::NonBlockingInvalidator::MakePushClientChannelCreator(
186           notifier_options);
187   const char kClientInfo[] = "sync_listen_notifications";
188   NullInvalidationStateTracker null_invalidation_state_tracker;
189   scoped_ptr<Invalidator> invalidator(
190       new NonBlockingInvalidator(
191           network_channel_creator,
192           base::RandBytesAsString(8),
193           null_invalidation_state_tracker.GetSavedInvalidations(),
194           null_invalidation_state_tracker.GetBootstrapData(),
195           &null_invalidation_state_tracker,
196           kClientInfo,
197           notifier_options.request_context_getter));
198
199   NotificationPrinter notification_printer;
200
201   invalidator->UpdateCredentials(email, token);
202
203   // Listen for notifications for all known types.
204   invalidator->RegisterHandler(&notification_printer);
205   invalidator->UpdateRegisteredIds(
206       &notification_printer, ModelTypeSetToObjectIdSet(ModelTypeSet::All()));
207
208   ui_loop.Run();
209
210   invalidator->UnregisterHandler(&notification_printer);
211   io_thread.Stop();
212   return 0;
213 }
214
215 }  // namespace
216 }  // namespace syncer
217
218 int main(int argc, char* argv[]) {
219   return syncer::SyncListenNotificationsMain(argc, argv);
220 }