1// Copyright 2014 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 "chrome/browser/ui/webui/invalidations_message_handler.h"
6
7#include "base/bind.h"
8#include "chrome/browser/invalidation/profile_invalidation_provider_factory.h"
9#include "chrome/browser/profiles/profile.h"
10#include "components/invalidation/invalidation_handler.h"
11#include "components/invalidation/invalidation_logger.h"
12#include "components/invalidation/invalidation_service.h"
13#include "components/invalidation/profile_invalidation_provider.h"
14#include "content/public/browser/web_ui.h"
15
16namespace invalidation {
17class InvalidationLogger;
18}  // namespace invalidation
19
20namespace syncer {
21class ObjectIdInvalidationMap;
22}  // namespace syncer
23
24InvalidationsMessageHandler::InvalidationsMessageHandler()
25    : logger_(NULL), weak_ptr_factory_(this) {}
26
27InvalidationsMessageHandler::~InvalidationsMessageHandler() {
28  if (logger_)
29    logger_->UnregisterObserver(this);
30}
31
32void InvalidationsMessageHandler::RegisterMessages() {
33  web_ui()->RegisterMessageCallback(
34      "doneLoading",
35      base::Bind(&InvalidationsMessageHandler::UIReady,
36                 base::Unretained(this)));
37  web_ui()->RegisterMessageCallback(
38      "requestDetailedStatus",
39      base::Bind(&InvalidationsMessageHandler::HandleRequestDetailedStatus,
40                 base::Unretained(this)));
41}
42
43void InvalidationsMessageHandler::UIReady(const base::ListValue* args) {
44  invalidation::ProfileInvalidationProvider* invalidation_provider =
45      invalidation::ProfileInvalidationProviderFactory::GetForProfile(
46          Profile::FromWebUI(web_ui()));
47  if (invalidation_provider) {
48    logger_ = invalidation_provider->GetInvalidationService()->
49        GetInvalidationLogger();
50  }
51  if (logger_ && !logger_->IsObserverRegistered(this))
52    logger_->RegisterObserver(this);
53  UpdateContent(args);
54}
55
56void InvalidationsMessageHandler::HandleRequestDetailedStatus(
57    const base::ListValue* args) {
58  invalidation::ProfileInvalidationProvider* invalidation_provider =
59      invalidation::ProfileInvalidationProviderFactory::GetForProfile(
60          Profile::FromWebUI(web_ui()));
61  if (invalidation_provider) {
62    invalidation_provider->GetInvalidationService()->RequestDetailedStatus(
63        base::Bind(&InvalidationsMessageHandler::OnDetailedStatus,
64                   weak_ptr_factory_.GetWeakPtr()));
65  }
66}
67
68void InvalidationsMessageHandler::UpdateContent(const base::ListValue* args) {
69  if (logger_)
70    logger_->EmitContent();
71}
72
73void InvalidationsMessageHandler::OnRegistrationChange(
74    const std::multiset<std::string>& registered_handlers) {
75  base::ListValue list_of_handlers;
76  for (std::multiset<std::string>::const_iterator it =
77       registered_handlers.begin();
78       it != registered_handlers.end(); ++it) {
79    list_of_handlers.Append(new base::StringValue(*it));
80  }
81  web_ui()->CallJavascriptFunction("chrome.invalidations.updateHandlers",
82                                   list_of_handlers);
83}
84
85void InvalidationsMessageHandler::OnStateChange(
86    const syncer::InvalidatorState& new_state,
87    const base::Time& last_changed_timestamp) {
88  std::string state(syncer::InvalidatorStateToString(new_state));
89  web_ui()->CallJavascriptFunction(
90      "chrome.invalidations.updateInvalidatorState", base::StringValue(state),
91      base::FundamentalValue(last_changed_timestamp.ToJsTime()));
92}
93
94void InvalidationsMessageHandler::OnUpdateIds(
95    const std::string& handler_name,
96    const syncer::ObjectIdCountMap& ids) {
97  base::ListValue list_of_objects;
98  for (syncer::ObjectIdCountMap::const_iterator it = ids.begin();
99       it != ids.end();
100       ++it) {
101    scoped_ptr<base::DictionaryValue> dic(new base::DictionaryValue());
102    dic->SetString("name", (it->first).name());
103    dic->SetInteger("source", (it->first).source());
104    dic->SetInteger("totalCount", it->second);
105    list_of_objects.Append(dic.release());
106  }
107  web_ui()->CallJavascriptFunction("chrome.invalidations.updateIds",
108                                   base::StringValue(handler_name),
109                                   list_of_objects);
110}
111void InvalidationsMessageHandler::OnDebugMessage(
112    const base::DictionaryValue& details) {}
113
114void InvalidationsMessageHandler::OnInvalidation(
115    const syncer::ObjectIdInvalidationMap& new_invalidations) {
116  scoped_ptr<base::ListValue> invalidations_list = new_invalidations.ToValue();
117  web_ui()->CallJavascriptFunction("chrome.invalidations.logInvalidations",
118                                   *invalidations_list);
119}
120
121void InvalidationsMessageHandler::OnDetailedStatus(
122    const base::DictionaryValue& network_details) {
123  web_ui()->CallJavascriptFunction("chrome.invalidations.updateDetailedStatus",
124                                   network_details);
125}
126