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 "ui/events/platform/platform_event_source.h" 6 7 #include <algorithm> 8 9 #include "base/lazy_instance.h" 10 #include "base/threading/thread_local.h" 11 #include "ui/events/platform/platform_event_dispatcher.h" 12 #include "ui/events/platform/platform_event_observer.h" 13 #include "ui/events/platform/scoped_event_dispatcher.h" 14 15 namespace ui { 16 17 namespace { 18 19 // PlatformEventSource singleton is thread local so that different instances 20 // can be used on different threads (e.g. browser thread should be able to 21 // access PlatformEventSource owned by the UI Service's thread). 22 base::LazyInstance<base::ThreadLocalPointer<PlatformEventSource>>::Leaky 23 lazy_tls_ptr = LAZY_INSTANCE_INITIALIZER; 24 25 } // namespace 26 27 bool PlatformEventSource::ignore_native_platform_events_ = false; 28 PlatformEventSource()29PlatformEventSource::PlatformEventSource() 30 : overridden_dispatcher_(NULL), 31 overridden_dispatcher_restored_(false) { 32 CHECK(!lazy_tls_ptr.Pointer()->Get()) 33 << "Only one platform event source can be created."; 34 lazy_tls_ptr.Pointer()->Set(this); 35 } 36 ~PlatformEventSource()37PlatformEventSource::~PlatformEventSource() { 38 CHECK_EQ(this, lazy_tls_ptr.Pointer()->Get()); 39 lazy_tls_ptr.Pointer()->Set(nullptr); 40 } 41 GetInstance()42PlatformEventSource* PlatformEventSource::GetInstance() { 43 return lazy_tls_ptr.Pointer()->Get(); 44 } 45 ShouldIgnoreNativePlatformEvents()46bool PlatformEventSource::ShouldIgnoreNativePlatformEvents() { 47 return ignore_native_platform_events_; 48 } 49 SetIgnoreNativePlatformEvents(bool ignore_events)50void PlatformEventSource::SetIgnoreNativePlatformEvents(bool ignore_events) { 51 ignore_native_platform_events_ = ignore_events; 52 } 53 AddPlatformEventDispatcher(PlatformEventDispatcher * dispatcher)54void PlatformEventSource::AddPlatformEventDispatcher( 55 PlatformEventDispatcher* dispatcher) { 56 CHECK(dispatcher); 57 dispatchers_.AddObserver(dispatcher); 58 OnDispatcherListChanged(); 59 } 60 RemovePlatformEventDispatcher(PlatformEventDispatcher * dispatcher)61void PlatformEventSource::RemovePlatformEventDispatcher( 62 PlatformEventDispatcher* dispatcher) { 63 dispatchers_.RemoveObserver(dispatcher); 64 OnDispatcherListChanged(); 65 } 66 OverrideDispatcher(PlatformEventDispatcher * dispatcher)67std::unique_ptr<ScopedEventDispatcher> PlatformEventSource::OverrideDispatcher( 68 PlatformEventDispatcher* dispatcher) { 69 CHECK(dispatcher); 70 overridden_dispatcher_restored_ = false; 71 return std::make_unique<ScopedEventDispatcher>(&overridden_dispatcher_, 72 dispatcher); 73 } 74 StopCurrentEventStream()75void PlatformEventSource::StopCurrentEventStream() { 76 } 77 AddPlatformEventObserver(PlatformEventObserver * observer)78void PlatformEventSource::AddPlatformEventObserver( 79 PlatformEventObserver* observer) { 80 CHECK(observer); 81 observers_.AddObserver(observer); 82 } 83 RemovePlatformEventObserver(PlatformEventObserver * observer)84void PlatformEventSource::RemovePlatformEventObserver( 85 PlatformEventObserver* observer) { 86 observers_.RemoveObserver(observer); 87 } 88 DispatchEvent(PlatformEvent platform_event)89uint32_t PlatformEventSource::DispatchEvent(PlatformEvent platform_event) { 90 uint32_t action = POST_DISPATCH_PERFORM_DEFAULT; 91 92 for (PlatformEventObserver& observer : observers_) 93 observer.WillProcessEvent(platform_event); 94 // Give the overridden dispatcher a chance to dispatch the event first. 95 if (overridden_dispatcher_) 96 action = overridden_dispatcher_->DispatchEvent(platform_event); 97 98 if (action & POST_DISPATCH_PERFORM_DEFAULT) { 99 for (PlatformEventDispatcher& dispatcher : dispatchers_) { 100 if (dispatcher.CanDispatchEvent(platform_event)) 101 action = dispatcher.DispatchEvent(platform_event); 102 if (action & POST_DISPATCH_STOP_PROPAGATION) 103 break; 104 } 105 } 106 for (PlatformEventObserver& observer : observers_) 107 observer.DidProcessEvent(platform_event); 108 109 // If an overridden dispatcher has been destroyed, then the platform 110 // event-source should halt dispatching the current stream of events, and wait 111 // until the next message-loop iteration for dispatching events. This lets any 112 // nested message-loop to unwind correctly and any new dispatchers to receive 113 // the correct sequence of events. 114 if (overridden_dispatcher_restored_) 115 StopCurrentEventStream(); 116 117 overridden_dispatcher_restored_ = false; 118 119 return action; 120 } 121 OnDispatcherListChanged()122void PlatformEventSource::OnDispatcherListChanged() { 123 } 124 OnOverriddenDispatcherRestored()125void PlatformEventSource::OnOverriddenDispatcherRestored() { 126 CHECK(overridden_dispatcher_); 127 overridden_dispatcher_restored_ = true; 128 } 129 130 } // namespace ui 131