1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <cstdio>
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string>
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/at_exit.h"
9731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/base64.h"
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/command_line.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h"
12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/ref_counted.h"
13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop.h"
15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/sync/notifier/sync_notifier.h"
16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/sync/notifier/sync_notifier_factory.h"
17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/sync/notifier/sync_notifier_observer.h"
18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/sync/syncable/model_type.h"
19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/sync/syncable/model_type_payload_map.h"
20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/test/test_url_request_context_getter.h"
21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/browser/browser_thread.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// This is a simple utility that initializes a sync notifier and
24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// listens to any received notifications.
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Class to print received notifications events.
29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass NotificationPrinter : public sync_notifier::SyncNotifierObserver {
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  NotificationPrinter() {}
32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual ~NotificationPrinter() {}
33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void OnIncomingNotification(
35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      const syncable::ModelTypePayloadMap& type_payloads) {
36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    for (syncable::ModelTypePayloadMap::const_iterator it =
37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen             type_payloads.begin(); it != type_payloads.end(); ++it) {
38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      LOG(INFO) << "Notification: type = "
39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                << syncable::ModelTypeToString(it->first)
40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                << ", payload = " << it->second;
41dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    }
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void OnNotificationStateChange(bool notifications_enabled) {
45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    LOG(INFO) << "Notifications enabled: " << notifications_enabled;
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void StoreState(const std::string& state) {
49731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    std::string base64_state;
50731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CHECK(base::Base64Encode(state, &base64_state));
51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    LOG(INFO) << "Got state to store: " << base64_state;
52731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
53731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DISALLOW_COPY_AND_ASSIGN(NotificationPrinter);
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint main(int argc, char* argv[]) {
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base::AtExitManager exit_manager;
62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<TestURLRequestContextGetter> request_context_getter(
63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      new TestURLRequestContextGetter);
64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  BrowserThread io_thread(BrowserThread::IO);
65ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::Thread::Options options;
66ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  options.message_loop_type = MessageLoop::TYPE_IO;
67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  io_thread.StartWithOptions(options);
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CommandLine::Init(argc, argv);
6972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  logging::InitLogging(
7072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      NULL,
7172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG,
7272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      logging::LOCK_LOG_FILE,
7372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      logging::DELETE_OLD_LOG_FILE,
7472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS);
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Parse command line.
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
78513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  std::string email = command_line.GetSwitchValueASCII("email");
79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::string token = command_line.GetSwitchValueASCII("token");
80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // TODO(akalin): Write a wrapper script that gets a token for an
81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // email and password and passes that in to this utility.
82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (email.empty() || token.empty()) {
83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    std::printf("Usage: %s --email=foo@bar.com --token=token\n\n"
84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                "See sync_notifier_factory.cc for more switches.\n\n"
85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                "Run chrome and set a breakpoint on "
86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                "sync_api::SyncManager::SyncInternal::UpdateCredentials() "
87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                "after logging into sync to get the token to pass into this "
88ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                "utility.\n",
89ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                argv[0]);
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return -1;
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Needed by the SyncNotifier implementations.
94ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  MessageLoop main_loop;
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const char kClientInfo[] = "sync_listen_notifications";
97ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  sync_notifier::SyncNotifierFactory sync_notifier_factory(kClientInfo);
98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_ptr<sync_notifier::SyncNotifier> sync_notifier(
99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      sync_notifier_factory.CreateSyncNotifier(command_line,
100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                               request_context_getter.get()));
101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  NotificationPrinter notification_printer;
102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  sync_notifier->AddObserver(&notification_printer);
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  sync_notifier->UpdateCredentials(email, token);
105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  {
106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Listen for notifications for all known types.
107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    syncable::ModelTypeSet types;
108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    for (int i = syncable::FIRST_REAL_MODEL_TYPE;
109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         i < syncable::MODEL_TYPE_COUNT; ++i) {
110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      types.insert(syncable::ModelTypeFromInt(i));
111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    sync_notifier->UpdateEnabledTypes(types);
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  main_loop.Run();
116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  sync_notifier->RemoveObserver(&notification_printer);
118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  io_thread.Stop();
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return 0;
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
121