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