diff options
author | mferreria@google.com <mferreria@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-11 18:55:55 +0000 |
---|---|---|
committer | mferreria@google.com <mferreria@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-11 18:55:55 +0000 |
commit | b7600274ebef95bd2066bdccf5af173863de4494 (patch) | |
tree | b6b8c4899033ff52c9f4212128e3f1a7962a43dc | |
parent | af2cfa8195b000e3863c4bf8aec224ffd617316d (diff) | |
download | chromium_src-b7600274ebef95bd2066bdccf5af173863de4494.zip chromium_src-b7600274ebef95bd2066bdccf5af173863de4494.tar.gz chromium_src-b7600274ebef95bd2066bdccf5af173863de4494.tar.bz2 |
[invalidations] Added logging to about:invalidations
This patch is a follow-up to issue 144093005.
The patch adds functionality to the about:invalidations page, by logging
some calls made on an InvalidatorService implementer (this patch focuses
on Ticl client). Each InvalidatorService now owns an InvalidatorLogger
object that is used to log onInvalidation and onStatusChange.
The invalidationLogger then pushes the invalidation data to the
InvalidationMessageHandler and from there it is sent to the HTML via JS
where it is processed and shown on the textarea as a log file.
Following patches will include a better visualization for the different
types of invalidations, as well as information on the registrars
listening for them.
BUG=263863
Review URL: https://codereview.chromium.org/147353011
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@250458 0039d316-1c4b-4281-b951-d872f2087c98
26 files changed, 670 insertions, 17 deletions
diff --git a/chrome/browser/extensions/api/push_messaging/push_messaging_invalidation_handler_unittest.cc b/chrome/browser/extensions/api/push_messaging/push_messaging_invalidation_handler_unittest.cc index f868f9c..8efba2e6 100644 --- a/chrome/browser/extensions/api/push_messaging/push_messaging_invalidation_handler_unittest.cc +++ b/chrome/browser/extensions/api/push_messaging/push_messaging_invalidation_handler_unittest.cc @@ -7,6 +7,7 @@ #include "base/basictypes.h" #include "base/memory/scoped_ptr.h" #include "chrome/browser/extensions/api/push_messaging/push_messaging_invalidation_handler_delegate.h" +#include "chrome/browser/invalidation/invalidation_logger.h" #include "chrome/browser/invalidation/invalidation_service.h" #include "google/cacheinvalidation/types.pb.h" #include "sync/notifier/object_id_invalidation_map.h" @@ -34,6 +35,7 @@ class MockInvalidationService : public invalidation::InvalidationService { void(syncer::InvalidationHandler*)); MOCK_CONST_METHOD0(GetInvalidatorState, syncer::InvalidatorState()); MOCK_CONST_METHOD0(GetInvalidatorClientId, std::string()); + MOCK_METHOD0(GetInvalidationLogger, invalidation::InvalidationLogger*()); private: DISALLOW_COPY_AND_ASSIGN(MockInvalidationService); diff --git a/chrome/browser/invalidation/fake_invalidation_service.cc b/chrome/browser/invalidation/fake_invalidation_service.cc index 96f4b55..edaf561 100644 --- a/chrome/browser/invalidation/fake_invalidation_service.cc +++ b/chrome/browser/invalidation/fake_invalidation_service.cc @@ -41,6 +41,10 @@ std::string FakeInvalidationService::GetInvalidatorClientId() const { return client_id_; } +InvalidationLogger* FakeInvalidationService::GetInvalidationLogger() { + return NULL; +} + void FakeInvalidationService::SetInvalidatorState( syncer::InvalidatorState state) { invalidator_registrar_.UpdateInvalidatorState(state); diff --git a/chrome/browser/invalidation/fake_invalidation_service.h b/chrome/browser/invalidation/fake_invalidation_service.h index e176889..7f64225 100644 --- a/chrome/browser/invalidation/fake_invalidation_service.h +++ b/chrome/browser/invalidation/fake_invalidation_service.h @@ -19,6 +19,8 @@ class Invalidation; namespace invalidation { +class InvalidationLogger; + // An InvalidationService that emits invalidations only when // its EmitInvalidationForTest method is called. class FakeInvalidationService : public InvalidationService { @@ -36,6 +38,7 @@ class FakeInvalidationService : public InvalidationService { virtual syncer::InvalidatorState GetInvalidatorState() const OVERRIDE; virtual std::string GetInvalidatorClientId() const OVERRIDE; + virtual InvalidationLogger* GetInvalidationLogger() OVERRIDE; void SetInvalidatorState(syncer::InvalidatorState state); diff --git a/chrome/browser/invalidation/invalidation_logger.cc b/chrome/browser/invalidation/invalidation_logger.cc new file mode 100644 index 0000000..19bdf9d --- /dev/null +++ b/chrome/browser/invalidation/invalidation_logger.cc @@ -0,0 +1,81 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/invalidation/invalidation_logger.h" + +#include "base/memory/scoped_ptr.h" +#include "base/values.h" +#include "chrome/browser/invalidation/invalidation_logger_observer.h" + +namespace syncer { +class ObjectIdInvalidationMap; +} + +namespace invalidation { +class InvalidationLoggerObserver; + +InvalidationLogger::InvalidationLogger() + : last_invalidator_state_(syncer::TRANSIENT_INVALIDATION_ERROR) {} + +InvalidationLogger::~InvalidationLogger() {} + +void InvalidationLogger::OnRegistration(const base::DictionaryValue& details) { + FOR_EACH_OBSERVER( + InvalidationLoggerObserver, observer_list_, OnRegistration(details)); +} + +void InvalidationLogger::OnUnregistration( + const base::DictionaryValue& details) { + FOR_EACH_OBSERVER( + InvalidationLoggerObserver, observer_list_, OnUnregistration(details)); +} + +void InvalidationLogger::OnStateChange( + const syncer::InvalidatorState& newState) { + last_invalidator_state_ = newState; + EmitState(); +} + +void InvalidationLogger::EmitState() { + FOR_EACH_OBSERVER(InvalidationLoggerObserver, + observer_list_, + OnStateChange(last_invalidator_state_)); +} + +void InvalidationLogger::OnUpdateIds(const base::DictionaryValue& details) { + FOR_EACH_OBSERVER( + InvalidationLoggerObserver, observer_list_, OnUpdateIds(details)); +} + +void InvalidationLogger::OnDebugMessage(const base::DictionaryValue& details) { + FOR_EACH_OBSERVER( + InvalidationLoggerObserver, observer_list_, OnDebugMessage(details)); +} + +void InvalidationLogger::OnInvalidation( + const syncer::ObjectIdInvalidationMap& details) { + FOR_EACH_OBSERVER( + InvalidationLoggerObserver, observer_list_, OnInvalidation(details)); +} + +void InvalidationLogger::EmitContent() { + // Here we add content to send to the observers not via real time push + // but on explicit request. + EmitState(); +} + +// Obtain a target object to call whenever we have +// debug messages to display +void InvalidationLogger::RegisterForDebug( + InvalidationLoggerObserver* debug_observer) { + observer_list_.AddObserver(debug_observer); +} + +// Removes the target object to call whenever we have +// debug messages to display +void InvalidationLogger::UnregisterForDebug( + InvalidationLoggerObserver* debug_observer) { + observer_list_.RemoveObserver(debug_observer); +} +} // namespace invalidation diff --git a/chrome/browser/invalidation/invalidation_logger.h b/chrome/browser/invalidation/invalidation_logger.h new file mode 100644 index 0000000..0d80b9a --- /dev/null +++ b/chrome/browser/invalidation/invalidation_logger.h @@ -0,0 +1,51 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_INVALIDATION_INVALIDATION_LOGGER_H_ +#define CHROME_BROWSER_INVALIDATION_INVALIDATION_LOGGER_H_ + +#include "base/memory/scoped_ptr.h" +#include "base/observer_list.h" +#include "sync/notifier/invalidator_state.h" + +namespace base { +class DictionaryValue; +} // namespace base + +namespace syncer { +class ObjectIdInvalidationMap; +} + +namespace invalidation { +class InvalidationLoggerObserver; + +class InvalidationLogger { + public: + // Pass through to any registered InvalidationLoggerObservers. + // We will do local logging here too. + void OnRegistration(const base::DictionaryValue& details); + void OnUnregistration(const base::DictionaryValue& details); + void OnStateChange(const syncer::InvalidatorState& newState); + void OnUpdateIds(const base::DictionaryValue& details); + void OnDebugMessage(const base::DictionaryValue& details); + void OnInvalidation(const syncer::ObjectIdInvalidationMap& details); + + void EmitContent(); + + InvalidationLogger(); + ~InvalidationLogger(); + + void RegisterForDebug(InvalidationLoggerObserver* debug_observer); + void UnregisterForDebug(InvalidationLoggerObserver* debug_observer); + + private: + void EmitState(); + // The list of every observer currently listening for notifications. + ObserverList<InvalidationLoggerObserver> observer_list_; + // The last InvalidatorState updated by the InvalidatorService. + syncer::InvalidatorState last_invalidator_state_; +}; + +} // namespace invalidation +#endif // CHROME_BROWSER_INVALIDATION_INVALIDATION_LOGGER_H_ diff --git a/chrome/browser/invalidation/invalidation_logger_observer.h b/chrome/browser/invalidation/invalidation_logger_observer.h new file mode 100644 index 0000000..6bd102e --- /dev/null +++ b/chrome/browser/invalidation/invalidation_logger_observer.h @@ -0,0 +1,42 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_INVALIDATION_INVALIDATION_LOGGER_OBSERVER_H_ +#define CHROME_BROWSER_INVALIDATION_INVALIDATION_LOGGER_OBSERVER_H_ + +#include "base/memory/scoped_ptr.h" +#include "sync/notifier/invalidator_state.h" +#include "sync/notifier/object_id_invalidation_map.h" + +namespace base { +class DictionaryValue; +} // namespace base + +namespace syncer { +class ObjectIdInvalidationMap; +} // namespace syncer + +namespace invalidation { +// This class provides the possibilty to register as an observer for the +// InvalidationLogger notifications whenever an InvalidatorService changes +// its internal state. +// (i.e. A new registration, a new invalidation, a TICL/GCM state change) + +class InvalidationLoggerObserver { + public: + virtual void OnRegistration(const base::DictionaryValue& details) = 0; + virtual void OnUnregistration(const base::DictionaryValue& details) = 0; + virtual void OnStateChange(const syncer::InvalidatorState& newState) = 0; + virtual void OnUpdateIds(const base::DictionaryValue& details) = 0; + virtual void OnDebugMessage(const base::DictionaryValue& details) = 0; + virtual void OnInvalidation( + const syncer::ObjectIdInvalidationMap& details) = 0; + + protected: + virtual ~InvalidationLoggerObserver() {} +}; + +} // namespace invalidation + +#endif // CHROME_BROWSER_INVALIDATION_INVALIDATION_LOGGER_OBSERVER_H_ diff --git a/chrome/browser/invalidation/invalidation_logger_unittest.cc b/chrome/browser/invalidation/invalidation_logger_unittest.cc new file mode 100644 index 0000000..30a3c4d --- /dev/null +++ b/chrome/browser/invalidation/invalidation_logger_unittest.cc @@ -0,0 +1,134 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/invalidation/invalidation_logger.h" +#include "chrome/browser/invalidation/invalidation_logger_observer.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace invalidation { + +class InvalidationLoggerTest : public testing::Test { + public: + InvalidationLoggerTest() {} +}; + +class InvalidationLoggerObserverTest : public InvalidationLoggerObserver { + public: + InvalidationLoggerObserverTest() { resetStates(); } + + void resetStates() { + registrationReceived = false; + unregistrationReceived = false; + stateReceived = false; + updateIdReceived = false; + debugMessageReceived = false; + invalidationReceived = false; + } + + virtual void OnRegistration(const base::DictionaryValue& details) OVERRIDE { + registrationReceived = true; + } + + virtual void OnUnregistration(const base::DictionaryValue& details) OVERRIDE { + unregistrationReceived = true; + } + + virtual void OnStateChange(const syncer::InvalidatorState& newState) + OVERRIDE { + stateReceived = true; + } + + virtual void OnUpdateIds(const base::DictionaryValue& details) OVERRIDE { + updateIdReceived = true; + } + + virtual void OnDebugMessage(const base::DictionaryValue& details) OVERRIDE { + debugMessageReceived = true; + } + + virtual void OnInvalidation( + const syncer::ObjectIdInvalidationMap& newInvalidations) OVERRIDE { + invalidationReceived = true; + } + + bool registrationReceived; + bool unregistrationReceived; + bool stateReceived; + bool updateIdReceived; + bool debugMessageReceived; + bool invalidationReceived; +}; + +// Test that the callbacks are actually being called when observers are +// registered and don't produce any other callback in the meantime. +TEST_F(InvalidationLoggerTest, TestCallbacks) { + InvalidationLogger log; + InvalidationLoggerObserverTest observerTest; + + log.RegisterForDebug(&observerTest); + log.OnStateChange(syncer::INVALIDATIONS_ENABLED); + EXPECT_TRUE(observerTest.stateReceived); + EXPECT_FALSE(observerTest.updateIdReceived); + EXPECT_FALSE(observerTest.registrationReceived); + EXPECT_FALSE(observerTest.invalidationReceived); + EXPECT_FALSE(observerTest.unregistrationReceived); + EXPECT_FALSE(observerTest.debugMessageReceived); + + observerTest.resetStates(); + + log.OnInvalidation(syncer::ObjectIdInvalidationMap()); + EXPECT_TRUE(observerTest.invalidationReceived); + EXPECT_FALSE(observerTest.stateReceived); + EXPECT_FALSE(observerTest.updateIdReceived); + EXPECT_FALSE(observerTest.registrationReceived); + EXPECT_FALSE(observerTest.unregistrationReceived); + EXPECT_FALSE(observerTest.debugMessageReceived); + + log.UnregisterForDebug(&observerTest); +} + +// Test that after registering an observer and then unregistering it +// no callbacks regarding that observer are called. +// (i.e. the observer is cleanly removed) +TEST_F(InvalidationLoggerTest, TestReleaseOfObserver) { + InvalidationLogger log; + InvalidationLoggerObserverTest observerTest; + + log.RegisterForDebug(&observerTest); + log.UnregisterForDebug(&observerTest); + + log.OnInvalidation(syncer::ObjectIdInvalidationMap()); + log.OnStateChange(syncer::INVALIDATIONS_ENABLED); + log.OnRegistration(base::DictionaryValue()); + log.OnUnregistration(base::DictionaryValue()); + log.OnDebugMessage(base::DictionaryValue()); + log.OnUpdateIds(base::DictionaryValue()); + EXPECT_FALSE(observerTest.registrationReceived); + EXPECT_FALSE(observerTest.unregistrationReceived); + EXPECT_FALSE(observerTest.updateIdReceived); + EXPECT_FALSE(observerTest.invalidationReceived); + EXPECT_FALSE(observerTest.stateReceived); + EXPECT_FALSE(observerTest.debugMessageReceived); +} + +// Test the EmitContet in InvalidationLogger is actually +// sending (only) state notifications. +TEST_F(InvalidationLoggerTest, TestEmitContent) { + InvalidationLogger log; + InvalidationLoggerObserverTest observerTest; + + log.RegisterForDebug(&observerTest); + EXPECT_FALSE(observerTest.stateReceived); + log.EmitContent(); + + EXPECT_TRUE(observerTest.stateReceived); + EXPECT_FALSE(observerTest.registrationReceived); + EXPECT_FALSE(observerTest.unregistrationReceived); + EXPECT_FALSE(observerTest.updateIdReceived); + EXPECT_FALSE(observerTest.invalidationReceived); + EXPECT_FALSE(observerTest.debugMessageReceived); + log.UnregisterForDebug(&observerTest); +} +} // namespace invalidation diff --git a/chrome/browser/invalidation/invalidation_service.h b/chrome/browser/invalidation/invalidation_service.h index 33b09f3..48b7274 100644 --- a/chrome/browser/invalidation/invalidation_service.h +++ b/chrome/browser/invalidation/invalidation_service.h @@ -14,6 +14,7 @@ class InvalidationHandler; } // namespace syncer namespace invalidation { +class InvalidationLogger; // Interface for classes that handle invalidation registrations and send out // invalidations to register handlers. @@ -99,6 +100,9 @@ class InvalidationService : public BrowserContextKeyedService { // prevent the receipt of notifications of our own changes. virtual std::string GetInvalidatorClientId() const = 0; + // Return the logger used to debug invalidations + virtual InvalidationLogger* GetInvalidationLogger() = 0; + protected: virtual ~InvalidationService() { } }; diff --git a/chrome/browser/invalidation/invalidation_service_android.cc b/chrome/browser/invalidation/invalidation_service_android.cc index ad30aaa..e37091b 100644 --- a/chrome/browser/invalidation/invalidation_service_android.cc +++ b/chrome/browser/invalidation/invalidation_service_android.cc @@ -56,6 +56,10 @@ std::string InvalidationServiceAndroid::GetInvalidatorClientId() const { return invalidation_controller_->GetInvalidatorClientId(); } +InvalidationLogger* InvalidationServiceAndroid::GetInvalidationLogger() { + return NULL; +} + void InvalidationServiceAndroid::Observe( int type, const content::NotificationSource& source, diff --git a/chrome/browser/invalidation/invalidation_service_android.h b/chrome/browser/invalidation/invalidation_service_android.h index 36b3315..af77045 100644 --- a/chrome/browser/invalidation/invalidation_service_android.h +++ b/chrome/browser/invalidation/invalidation_service_android.h @@ -18,7 +18,7 @@ class Profile; namespace invalidation { - +class InvalidationLogger; class InvalidationControllerAndroid; // This InvalidationService is used to deliver invalidations on Android. The @@ -50,6 +50,7 @@ class InvalidationServiceAndroid syncer::InvalidationHandler* handler) OVERRIDE; virtual syncer::InvalidatorState GetInvalidatorState() const OVERRIDE; virtual std::string GetInvalidatorClientId() const OVERRIDE; + virtual InvalidationLogger* GetInvalidationLogger() OVERRIDE; // content::NotificationObserver implementation. virtual void Observe(int type, diff --git a/chrome/browser/invalidation/p2p_invalidation_service.cc b/chrome/browser/invalidation/p2p_invalidation_service.cc index 1eda06e..e38c3c1 100644 --- a/chrome/browser/invalidation/p2p_invalidation_service.cc +++ b/chrome/browser/invalidation/p2p_invalidation_service.cc @@ -70,4 +70,8 @@ std::string P2PInvalidationService::GetInvalidatorClientId() const { return invalidator_id_; } +InvalidationLogger* P2PInvalidationService::GetInvalidationLogger() { + return NULL; +} + } // namespace invalidation diff --git a/chrome/browser/invalidation/p2p_invalidation_service.h b/chrome/browser/invalidation/p2p_invalidation_service.h index 9e6c023..d4dfdbf 100644 --- a/chrome/browser/invalidation/p2p_invalidation_service.h +++ b/chrome/browser/invalidation/p2p_invalidation_service.h @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "base/threading/non_thread_safe.h" +#include "chrome/browser/invalidation/invalidation_logger.h" #include "chrome/browser/invalidation/invalidation_service.h" #include "components/browser_context_keyed_service/browser_context_keyed_service.h" @@ -41,6 +42,7 @@ class P2PInvalidationService syncer::InvalidationHandler* handler) OVERRIDE; virtual syncer::InvalidatorState GetInvalidatorState() const OVERRIDE; virtual std::string GetInvalidatorClientId() const OVERRIDE; + virtual InvalidationLogger* GetInvalidationLogger() OVERRIDE; void UpdateCredentials(const std::string& username, const std::string& password); diff --git a/chrome/browser/invalidation/ticl_invalidation_service.cc b/chrome/browser/invalidation/ticl_invalidation_service.cc index e76db5b..c30e689 100644 --- a/chrome/browser/invalidation/ticl_invalidation_service.cc +++ b/chrome/browser/invalidation/ticl_invalidation_service.cc @@ -8,6 +8,7 @@ #include "base/metrics/histogram.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/invalidation/gcm_network_channel_delegate_impl.h" +#include "chrome/browser/invalidation/invalidation_logger.h" #include "chrome/browser/invalidation/invalidation_service_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/about_signin_internals.h" @@ -18,9 +19,11 @@ #include "content/public/browser/notification_service.h" #include "google_apis/gaia/gaia_constants.h" #include "sync/notifier/gcm_network_channel_delegate.h" +#include "sync/notifier/invalidation_util.h" #include "sync/notifier/invalidator.h" #include "sync/notifier/invalidator_state.h" #include "sync/notifier/non_blocking_invalidator.h" +#include "sync/notifier/object_id_invalidation_map.h" static const char* kOAuth2Scopes[] = { GaiaConstants::kGoogleTalkOAuth2Scope @@ -65,8 +68,8 @@ TiclInvalidationService::TiclInvalidationService( signin_manager_(signin), oauth2_token_service_(oauth2_token_service), invalidator_registrar_(new syncer::InvalidatorRegistrar()), - request_access_token_backoff_(&kRequestAccessTokenBackoffPolicy) { -} + request_access_token_backoff_(&kRequestAccessTokenBackoffPolicy), + logger_() {} TiclInvalidationService::~TiclInvalidationService() { DCHECK(CalledOnValidThread()); @@ -153,6 +156,10 @@ std::string TiclInvalidationService::GetInvalidatorClientId() const { return invalidator_storage_->GetInvalidatorClientId(); } +InvalidationLogger* TiclInvalidationService::GetInvalidationLogger() { + return &logger_; +} + void TiclInvalidationService::Observe( int type, const content::NotificationSource& source, @@ -266,11 +273,14 @@ void TiclInvalidationService::OnInvalidatorStateChange( } else { invalidator_registrar_->UpdateInvalidatorState(state); } + logger_.OnStateChange(state); } void TiclInvalidationService::OnIncomingInvalidation( const syncer::ObjectIdInvalidationMap& invalidation_map) { invalidator_registrar_->DispatchInvalidationsToHandlers(invalidation_map); + + logger_.OnInvalidation(invalidation_map); } void TiclInvalidationService::Shutdown() { diff --git a/chrome/browser/invalidation/ticl_invalidation_service.h b/chrome/browser/invalidation/ticl_invalidation_service.h index d5323af..cdbd0a6 100644 --- a/chrome/browser/invalidation/ticl_invalidation_service.h +++ b/chrome/browser/invalidation/ticl_invalidation_service.h @@ -8,6 +8,7 @@ #include "base/memory/scoped_ptr.h" #include "base/threading/non_thread_safe.h" #include "base/timer/timer.h" +#include "chrome/browser/invalidation/invalidation_logger.h" #include "chrome/browser/invalidation/invalidation_service.h" #include "chrome/browser/invalidation/invalidator_storage.h" #include "chrome/browser/signin/profile_oauth2_token_service.h" @@ -56,6 +57,7 @@ class TiclInvalidationService syncer::InvalidationHandler* handler) OVERRIDE; virtual syncer::InvalidatorState GetInvalidatorState() const OVERRIDE; virtual std::string GetInvalidatorClientId() const OVERRIDE; + virtual InvalidationLogger* GetInvalidationLogger() OVERRIDE; // content::NotificationObserver implementation. virtual void Observe(int type, @@ -126,6 +128,10 @@ class TiclInvalidationService base::OneShotTimer<TiclInvalidationService> request_access_token_retry_timer_; net::BackoffEntry request_access_token_backoff_; + // The invalidation logger object we use to record state changes + // and invalidations. + InvalidationLogger logger_; + DISALLOW_COPY_AND_ASSIGN(TiclInvalidationService); }; diff --git a/chrome/browser/resources/about_invalidations.css b/chrome/browser/resources/about_invalidations.css index eb3e290..e71c941 100644 --- a/chrome/browser/resources/about_invalidations.css +++ b/chrome/browser/resources/about_invalidations.css @@ -3,6 +3,22 @@ * found in the LICENSE file. */ -/* - * TODO(mferreria): Implement this CSS. See http://crbug.com/263863 - */ +body { + font-family: Ubuntu, Arial, sans-serif; + font-size: 80%; +} + +#invalidations-info p { + color: rgb(74, 142, 230); + font-size: 100%; + font-weight: bold; + margin-bottom: 0; +} + +#invalidations-info .section { + display: inline-block; + margin-left: auto; + margin-right: auto; + width: 100%; +} + diff --git a/chrome/browser/resources/about_invalidations.html b/chrome/browser/resources/about_invalidations.html index 7b1b71b..d7dd623 100644 --- a/chrome/browser/resources/about_invalidations.html +++ b/chrome/browser/resources/about_invalidations.html @@ -1,17 +1,29 @@ +<!DOCTYPE HTML> <html> <head> + <meta charset="utf-8"> <title>Invalidations</title> <script src="chrome://resources/js/cr.js"></script> <script src="chrome://resources/js/parse_html_subset.js"></script> <script src="chrome://resources/js/util.js"></script> <script src="chrome://invalidations/about_invalidations.js"></script> - <link rel="stylesheet" type="text/css" href="about_invalidations.css"> + <link rel="stylesheet" href="about_invalidations.css"> </head> - <body> - <h1>Invalidations Debug Information - <button id='refresh-invalidation-data'>Refresh</button></h1> + <h1>Invalidations Debug Information</h1> + <div id="invalidations-info"> + <div id="states" class="section"> + <label> + <p>Invalidation service state:</p><span id="invalidations-state"></span> + </label> + </div> + <div class="section"> + <label> + <p>Invalidations Log:</p> + <textarea + id="invalidations-log" rows="10" cols="120" readonly></textarea> + </label> + </div> + </div> </body> - - </html> diff --git a/chrome/browser/resources/about_invalidations.js b/chrome/browser/resources/about_invalidations.js index 0a73626..db58dc9 100644 --- a/chrome/browser/resources/about_invalidations.js +++ b/chrome/browser/resources/about_invalidations.js @@ -1,8 +1,77 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. +// Copyright (c) 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +cr.define('chrome.invalidations', function() { -// TODO(mferreria): Implement in this JS the ability to get from the C++ Layer -// the invalidations history and display them as they come. -// See http://crbug.com/263863 + function quote(str) { + return '\"' + str + '\"'; + } + + function nowTimeString() { + return '[' + new Date().getTime() + '] '; + } + + /** + * Appends a string to a textarea log. + * + * @param {string} logMessage The string to be appended. + */ + function appendToLog(logMessage) { + var invalidationsLog = $('invalidations-log'); + invalidationsLog.value += logMessage + '\n'; + } + + /** + * Shows the current state of the InvalidatorService + * + * @param {string} newState The string to be displayed and logged. + */ + function updateState(newState) { + var logMessage = nowTimeString() + + 'Invalidations service state changed to ' + quote(newState); + + appendToLog(logMessage); + $('invalidations-state').textContent = newState; + currentInvalidationState = newState; + } + + /** + * Adds to the log the latest invalidations received + * + * @param {Array of Object} allInvalidations The array of ObjectId + * that contains the invalidations received by the InvalidatorService + */ + function logInvalidations(allInvalidations) { + for (var i = 0; i < allInvalidations.length; i++) { + var inv = allInvalidations[i]; + if (inv.hasOwnProperty('objectId')) { + var logMessage = nowTimeString() + + 'Received Invalidation with type ' + + quote(inv.objectId.name) + + ' version ' + + quote((inv.isUnknownVersion ? 'Unknown' : inv.version)) + + ' with payload ' + + quote(inv.payload); + + appendToLog(logMessage); + } + } + } + + /** + * Function that notifies the Invalidator Logger that the UI is + * ready to receive real-time notifications. + */ + function onLoadWork() { + chrome.send('doneLoading'); + } + + return { + updateState: updateState, + logInvalidations: logInvalidations, + onLoadWork: onLoadWork + }; +}); + +document.addEventListener('DOMContentLoaded', chrome.invalidations.onLoadWork); diff --git a/chrome/browser/ui/webui/invalidations_message_handler.cc b/chrome/browser/ui/webui/invalidations_message_handler.cc new file mode 100644 index 0000000..6a55ec5 --- /dev/null +++ b/chrome/browser/ui/webui/invalidations_message_handler.cc @@ -0,0 +1,81 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/webui/invalidations_message_handler.h" + +#include "base/bind.h" +#include "chrome/browser/invalidation/invalidation_logger.h" +#include "chrome/browser/invalidation/invalidation_service.h" +#include "chrome/browser/invalidation/invalidation_service_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "content/public/browser/web_ui.h" + +namespace invalidation { +class InvalidationLogger; +} // namespace invalidation + +namespace syncer { +class ObjectIdInvalidationMap; +} // namespace syncer + +InvalidationsMessageHandler::InvalidationsMessageHandler() + : logger_(NULL), isRegistered(false) {} + +InvalidationsMessageHandler::~InvalidationsMessageHandler() { + if (logger_) + logger_->UnregisterForDebug(this); +} + +void InvalidationsMessageHandler::RegisterMessages() { + web_ui()->RegisterMessageCallback( + "doneLoading", + base::Bind(&InvalidationsMessageHandler::UIReady, + base::Unretained(this))); +} + +void InvalidationsMessageHandler::UIReady(const base::ListValue* args) { + Profile* profile = Profile::FromWebUI(web_ui()); + if (!isRegistered && profile) { + invalidation::InvalidationService* invalidation_service = + invalidation::InvalidationServiceFactory::GetForProfile(profile); + if (invalidation_service) + logger_ = invalidation_service->GetInvalidationLogger(); + if (logger_) { + logger_->RegisterForDebug(this); + isRegistered = true; + } + } + UpdateContent(args); +} + +void InvalidationsMessageHandler::UpdateContent(const base::ListValue* args) { + if (logger_) + logger_->EmitContent(); +} + +void InvalidationsMessageHandler::OnUnregistration( + const base::DictionaryValue& newRegistrationState) {} + +void InvalidationsMessageHandler::OnRegistration( + const base::DictionaryValue& newRegistrationState) {} + +void InvalidationsMessageHandler::OnStateChange( + const syncer::InvalidatorState& newState) { + std::string state(syncer::InvalidatorStateToString(newState)); + web_ui()->CallJavascriptFunction("chrome.invalidations.updateState", + base::StringValue(state)); +} + +void InvalidationsMessageHandler::OnUpdateIds( + const base::DictionaryValue& newIds) {} + +void InvalidationsMessageHandler::OnDebugMessage( + const base::DictionaryValue& details) {} + +void InvalidationsMessageHandler::OnInvalidation( + const syncer::ObjectIdInvalidationMap& newInvalidations) { + scoped_ptr<base::ListValue> invalidationsList = newInvalidations.ToValue(); + web_ui()->CallJavascriptFunction("chrome.invalidations.logInvalidations", + *invalidationsList); +} diff --git a/chrome/browser/ui/webui/invalidations_message_handler.h b/chrome/browser/ui/webui/invalidations_message_handler.h new file mode 100644 index 0000000..41d6073 --- /dev/null +++ b/chrome/browser/ui/webui/invalidations_message_handler.h @@ -0,0 +1,53 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_WEBUI_INVALIDATIONS_MESSAGE_HANDLER_H_ +#define CHROME_BROWSER_UI_WEBUI_INVALIDATIONS_MESSAGE_HANDLER_H_ + +#include "base/compiler_specific.h" +#include "base/memory/scoped_ptr.h" +#include "base/values.h" +#include "chrome/browser/invalidation/invalidation_logger_observer.h" +#include "content/public/browser/web_ui_message_handler.h" + +class Profile; + +namespace invalidation { +class InvalidationLogger; +} // namespace invalidation + +// The implementation for the chrome://invalidations page. +class InvalidationsMessageHandler + : public content::WebUIMessageHandler, + public invalidation::InvalidationLoggerObserver { + public: + InvalidationsMessageHandler(); + virtual ~InvalidationsMessageHandler(); + + // Implementation of InvalidationLoggerObserver + virtual void OnRegistration(const base::DictionaryValue& details) OVERRIDE; + virtual void OnUnregistration(const base::DictionaryValue& details) OVERRIDE; + virtual void OnStateChange(const syncer::InvalidatorState& newState) OVERRIDE; + virtual void OnUpdateIds(const base::DictionaryValue& details) OVERRIDE; + virtual void OnDebugMessage(const base::DictionaryValue& details) OVERRIDE; + virtual void OnInvalidation( + const syncer::ObjectIdInvalidationMap& newInvalidations) OVERRIDE; + + // Implementation of WebUIMessageHandler + virtual void RegisterMessages() OVERRIDE; + + void UpdateContent(const base::ListValue* args); + void UIReady(const base::ListValue* args); + + private: + // The pointer to the internal InvalidatorService InvalidationLogger. + // Used to get the information necessary to display to the JS and to + // register ourselves as Observers for any notifications. + invalidation::InvalidationLogger* logger_; + // Check to see if we are already registered as an observer + bool isRegistered; + DISALLOW_COPY_AND_ASSIGN(InvalidationsMessageHandler); +}; + +#endif // CHROME_BROWSER_UI_WEBUI_INVALIDATIONS_MESSAGE_HANDLER_H_ diff --git a/chrome/browser/ui/webui/invalidations_ui.cc b/chrome/browser/ui/webui/invalidations_ui.cc index b2e8fba..c18e9fb 100644 --- a/chrome/browser/ui/webui/invalidations_ui.cc +++ b/chrome/browser/ui/webui/invalidations_ui.cc @@ -5,9 +5,11 @@ #include "chrome/browser/ui/webui/invalidations_ui.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/webui/invalidations_message_handler.h" #include "chrome/common/url_constants.h" #include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_data_source.h" +#include "content/public/browser/web_ui_message_handler.h" #include "grit/invalidations_resources.h" content::WebUIDataSource* CreateInvalidationsHTMLSource() { @@ -25,7 +27,12 @@ InvalidationsUI::InvalidationsUI(content::WebUI* web_ui) Profile* profile = Profile::FromWebUI(web_ui); if (profile) { content::WebUIDataSource::Add(profile, CreateInvalidationsHTMLSource()); + InvalidationsMessageHandler* message_handler = + new InvalidationsMessageHandler(); + // The MessageHandler of web_ui takes ownership of the object + web_ui->AddMessageHandler(message_handler); } } InvalidationsUI::~InvalidationsUI() { } + diff --git a/chrome/browser/ui/webui/invalidations_ui.h b/chrome/browser/ui/webui/invalidations_ui.h index fbbbf60..013d3e3 100644 --- a/chrome/browser/ui/webui/invalidations_ui.h +++ b/chrome/browser/ui/webui/invalidations_ui.h @@ -6,7 +6,6 @@ #define CHROME_BROWSER_UI_WEBUI_INVALIDATIONS_UI_H_ #include "base/basictypes.h" -#include "base/compiler_specific.h" #include "content/public/browser/web_ui_controller.h" // The implementation for the chrome://invalidations page. diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 7fd948e..3ab5c03 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -950,6 +950,8 @@ 'browser/internal_auth.h', 'browser/intranet_redirect_detector.cc', 'browser/intranet_redirect_detector.h', + 'browser/invalidation/invalidation_logger.cc', + 'browser/invalidation/invalidation_logger.h', 'browser/invalidation/fake_invalidation_service.cc', 'browser/invalidation/fake_invalidation_service.h', 'browser/invalidation/gcm_network_channel_delegate_impl.cc', diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi index 5bc1d3d..17f22fe 100644 --- a/chrome/chrome_browser_ui.gypi +++ b/chrome/chrome_browser_ui.gypi @@ -2387,6 +2387,8 @@ 'browser/ui/webui/instant_ui.h', 'browser/ui/webui/invalidations_ui.cc', 'browser/ui/webui/invalidations_ui.h', + 'browser/ui/webui/invalidations_message_handler.cc', + 'browser/ui/webui/invalidations_message_handler.h', 'browser/ui/webui/media/webrtc_logs_ui.cc', 'browser/ui/webui/media/webrtc_logs_ui.h', 'browser/ui/webui/memory_internals/memory_internals_handler.cc', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 6c2dc01..c84766e 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1600,6 +1600,7 @@ 'test/base/test_chrome_web_ui_controller_factory.h', 'test/base/test_chrome_web_ui_controller_factory_browsertest.cc', 'test/data/chromeos/oobe_webui_browsertest.js', + 'test/data/webui/about_invalidations_browsertest.js', 'test/data/webui/accessibility_audit_browsertest.js', 'test/data/webui/assertions.js', 'test/data/webui/async_gen.cc', diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index 9c83d3e..104e2e8 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi @@ -1015,6 +1015,7 @@ 'browser/install_verification/win/module_verification_test.cc', 'browser/install_verification/win/module_verification_test.h', 'browser/invalidation/gcm_network_channel_delegate_impl_unittest.cc', + 'browser/invalidation/invalidation_logger_unittest.cc', 'browser/invalidation/invalidation_service_android_unittest.cc', 'browser/invalidation/invalidation_service_test_template.cc', 'browser/invalidation/invalidation_service_test_template.h', diff --git a/chrome/test/data/webui/about_invalidations_browsertest.js b/chrome/test/data/webui/about_invalidations_browsertest.js new file mode 100644 index 0000000..694e488 --- /dev/null +++ b/chrome/test/data/webui/about_invalidations_browsertest.js @@ -0,0 +1,62 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * TestFixture for Invalidations WebUI testing. + * @extends {testing.Test} + * @constructor + **/ +function InvalidationsWebUITest() {} + +InvalidationsWebUITest.prototype = { + __proto__: testing.Test.prototype, + + /** + * Browse to the Invalidations page. + **/ + browsePreload: 'chrome://invalidations', + runAccessibilityChecks: false, + accessibilityIssuesAreErrors: false, +}; + +// Test that registering an invalidations appears properly on the textarea. +TEST_F('InvalidationsWebUITest', 'testRegisteringNewInvalidation', function() { + var invalidationsLog = $('invalidations-log'); + var invalidation = [{ + isUnknownVersion: 'true', + objectId: {name: 'EXTENSIONS', source: 1004} + }]; + invalidationsLog.value = ''; + chrome.invalidations.logInvalidations(invalidation); + var isContained = + invalidationsLog.value.indexOf( + 'Received Invalidation with type ' + + '"EXTENSIONS" version "Unknown" with payload "undefined"') != -1; + expectTrue(isContained, 'Actual log is:' + invalidationsLog.value); + +}); + +// Test that changing the Invalidations Service state appears both in the +// span and in the textarea. +TEST_F('InvalidationsWebUITest', 'testChangingInvalidationsState', function() { + var invalidationsState = $('invalidations-state'); + var invalidationsLog = $('invalidations-log'); + var newState = 'INVALIDATIONS_ENABLED'; + var newNewState = 'TRANSIENT_INVALIDATION_ERROR'; + + chrome.invalidations.updateState(newState); + expectEquals(invalidationsState.textContent, + 'INVALIDATIONS_ENABLED', + 'could not change the invalidations text'); + invalidationsLog.value = ''; + chrome.invalidations.updateState(newNewState); + expectEquals(invalidationsState.textContent, + 'TRANSIENT_INVALIDATION_ERROR'); + var isContained = + invalidationsLog.value.indexOf( + 'Invalidations service state changed to '+ + '"TRANSIENT_INVALIDATION_ERROR"') != -1; + expectTrue(isContained, 'Actual log is:' + invalidationsLog.value); +}); + |