1effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// found in the LICENSE file. 4effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 5effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "ui/events/platform/platform_event_source.h" 6effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 7effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include <algorithm> 8effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 9effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/message_loop/message_loop.h" 10effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "ui/events/platform/platform_event_dispatcher.h" 11effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "ui/events/platform/platform_event_observer.h" 12effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "ui/events/platform/scoped_event_dispatcher.h" 13effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 14effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochnamespace ui { 15effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 16effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// static 17effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochPlatformEventSource* PlatformEventSource::instance_ = NULL; 18effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 19effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochPlatformEventSource::PlatformEventSource() 20effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch : overridden_dispatcher_(NULL), 21effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch overridden_dispatcher_restored_(false) { 22effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch CHECK(!instance_) << "Only one platform event source can be created."; 23effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch instance_ = this; 24effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 25effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 26effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochPlatformEventSource::~PlatformEventSource() { 27effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch CHECK_EQ(this, instance_); 28effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch instance_ = NULL; 29effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 30effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 31effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochPlatformEventSource* PlatformEventSource::GetInstance() { return instance_; } 32effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 33effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid PlatformEventSource::AddPlatformEventDispatcher( 34effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch PlatformEventDispatcher* dispatcher) { 35effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch CHECK(dispatcher); 360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch dispatchers_.AddObserver(dispatcher); 375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu OnDispatcherListChanged(); 38effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 39effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 40effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid PlatformEventSource::RemovePlatformEventDispatcher( 41effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch PlatformEventDispatcher* dispatcher) { 420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch dispatchers_.RemoveObserver(dispatcher); 435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu OnDispatcherListChanged(); 44effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 45effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 46effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochscoped_ptr<ScopedEventDispatcher> PlatformEventSource::OverrideDispatcher( 47effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch PlatformEventDispatcher* dispatcher) { 48effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch CHECK(dispatcher); 49effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch overridden_dispatcher_restored_ = false; 50effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return make_scoped_ptr( 51effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch new ScopedEventDispatcher(&overridden_dispatcher_, dispatcher)); 52effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 53effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 54effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid PlatformEventSource::AddPlatformEventObserver( 55effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch PlatformEventObserver* observer) { 56effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch CHECK(observer); 57effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch observers_.AddObserver(observer); 58effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 59effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 60effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid PlatformEventSource::RemovePlatformEventObserver( 61effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch PlatformEventObserver* observer) { 62effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch observers_.RemoveObserver(observer); 63effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 64effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 65effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochuint32_t PlatformEventSource::DispatchEvent(PlatformEvent platform_event) { 66effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch uint32_t action = POST_DISPATCH_PERFORM_DEFAULT; 67effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 68c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch FOR_EACH_OBSERVER(PlatformEventObserver, observers_, 69c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch WillProcessEvent(platform_event)); 70c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Give the overridden dispatcher a chance to dispatch the event first. 71c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (overridden_dispatcher_) 72c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch action = overridden_dispatcher_->DispatchEvent(platform_event); 73c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if ((action & POST_DISPATCH_PERFORM_DEFAULT) && 750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch dispatchers_.might_have_observers()) { 760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ObserverList<PlatformEventDispatcher>::Iterator iter(dispatchers_); 770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch while (PlatformEventDispatcher* dispatcher = iter.GetNext()) { 78c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (dispatcher->CanDispatchEvent(platform_event)) 79c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch action = dispatcher->DispatchEvent(platform_event); 80c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (action & POST_DISPATCH_STOP_PROPAGATION) 81c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch break; 82effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 83effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 84c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch FOR_EACH_OBSERVER(PlatformEventObserver, observers_, 85c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DidProcessEvent(platform_event)); 86effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 87effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // If an overridden dispatcher has been destroyed, then the platform 88effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // event-source should halt dispatching the current stream of events, and wait 89effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // until the next message-loop iteration for dispatching events. This lets any 90effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // nested message-loop to unwind correctly and any new dispatchers to receive 91effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // the correct sequence of events. 92effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (overridden_dispatcher_restored_) 93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) StopCurrentEventStream(); 94effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 95effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch overridden_dispatcher_restored_ = false; 96effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 97effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return action; 98effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 99effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PlatformEventSource::StopCurrentEventStream() { 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid PlatformEventSource::OnDispatcherListChanged() { 1045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 1055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 106effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid PlatformEventSource::OnOverriddenDispatcherRestored() { 107effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch CHECK(overridden_dispatcher_); 108effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch overridden_dispatcher_restored_ = true; 109effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 110effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 111effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} // namespace ui 112