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