summaryrefslogtreecommitdiff
path: root/chromium/content/renderer/input/widget_input_handler_impl.cc
blob: dd01e03a9f14347061760cc15e8cec8c6deff1c0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
// Copyright 2017 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 "content/renderer/input/widget_input_handler_impl.h"

#include <utility>

#include "base/bind.h"
#include "base/logging.h"
#include "content/common/input/ime_text_span_conversions.h"
#include "content/common/input_messages.h"
#include "content/renderer/gpu/render_widget_compositor.h"
#include "content/renderer/ime_event_guard.h"
#include "content/renderer/input/widget_input_handler_manager.h"
#include "content/renderer/render_thread_impl.h"
#include "content/renderer/render_widget.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/scheduler/web_main_thread_scheduler.h"
#include "third_party/blink/public/platform/web_coalesced_input_event.h"
#include "third_party/blink/public/platform/web_keyboard_event.h"
#include "third_party/blink/public/web/web_local_frame.h"

namespace content {

namespace {

void RunClosureIfNotSwappedOut(base::WeakPtr<RenderWidget> render_widget,
                               base::OnceClosure closure) {
  // Input messages must not be processed if the RenderWidget is in swapped out
  // or closing state.
  if (!render_widget || render_widget->is_swapped_out() ||
      render_widget->IsClosing()) {
    return;
  }
  std::move(closure).Run();
}

}  // namespace

WidgetInputHandlerImpl::WidgetInputHandlerImpl(
    scoped_refptr<WidgetInputHandlerManager> manager,
    scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner,
    scoped_refptr<MainThreadEventQueue> input_event_queue,
    base::WeakPtr<RenderWidget> render_widget)
    : main_thread_task_runner_(main_thread_task_runner),
      input_handler_manager_(manager),
      input_event_queue_(input_event_queue),
      render_widget_(render_widget),
      binding_(this),
      associated_binding_(this) {}

WidgetInputHandlerImpl::~WidgetInputHandlerImpl() {}

void WidgetInputHandlerImpl::SetAssociatedBinding(
    mojom::WidgetInputHandlerAssociatedRequest request) {
  associated_binding_.Bind(std::move(request));
  associated_binding_.set_connection_error_handler(
      base::BindOnce(&WidgetInputHandlerImpl::Release, base::Unretained(this)));
}

void WidgetInputHandlerImpl::SetBinding(
    mojom::WidgetInputHandlerRequest request) {
  binding_.Bind(std::move(request));
  binding_.set_connection_error_handler(
      base::BindOnce(&WidgetInputHandlerImpl::Release, base::Unretained(this)));
}

void WidgetInputHandlerImpl::SetFocus(bool focused) {
  RunOnMainThread(
      base::BindOnce(&RenderWidget::OnSetFocus, render_widget_, focused));
}

void WidgetInputHandlerImpl::MouseCaptureLost() {
  RunOnMainThread(
      base::BindOnce(&RenderWidget::OnMouseCaptureLost, render_widget_));
}

void WidgetInputHandlerImpl::SetEditCommandsForNextKeyEvent(
    const std::vector<EditCommand>& commands) {
  RunOnMainThread(
      base::BindOnce(&RenderWidget::OnSetEditCommandsForNextKeyEvent,
                     render_widget_, commands));
}

void WidgetInputHandlerImpl::CursorVisibilityChanged(bool visible) {
  RunOnMainThread(base::BindOnce(&RenderWidget::OnCursorVisibilityChange,
                                 render_widget_, visible));
}

void WidgetInputHandlerImpl::ImeSetComposition(
    const base::string16& text,
    const std::vector<ui::ImeTextSpan>& ime_text_spans,
    const gfx::Range& range,
    int32_t start,
    int32_t end) {
  RunOnMainThread(
      base::BindOnce(&RenderWidget::OnImeSetComposition, render_widget_, text,
                     ConvertUiImeTextSpansToBlinkImeTextSpans(ime_text_spans),
                     range, start, end));
}

void WidgetInputHandlerImpl::ImeCommitText(
    const base::string16& text,
    const std::vector<ui::ImeTextSpan>& ime_text_spans,
    const gfx::Range& range,
    int32_t relative_cursor_position) {
  RunOnMainThread(
      base::BindOnce(&RenderWidget::OnImeCommitText, render_widget_, text,
                     ConvertUiImeTextSpansToBlinkImeTextSpans(ime_text_spans),
                     range, relative_cursor_position));
}

void WidgetInputHandlerImpl::ImeFinishComposingText(bool keep_selection) {
  RunOnMainThread(base::BindOnce(&RenderWidget::OnImeFinishComposingText,
                                 render_widget_, keep_selection));
}

void WidgetInputHandlerImpl::RequestTextInputStateUpdate() {
  RunOnMainThread(base::BindOnce(&RenderWidget::OnRequestTextInputStateUpdate,
                                 render_widget_));
}

void WidgetInputHandlerImpl::RequestCompositionUpdates(bool immediate_request,
                                                       bool monitor_request) {
  RunOnMainThread(base::BindOnce(&RenderWidget::OnRequestCompositionUpdates,
                                 render_widget_, immediate_request,
                                 monitor_request));
}

void WidgetInputHandlerImpl::DispatchEvent(
    std::unique_ptr<content::InputEvent> event,
    DispatchEventCallback callback) {
  TRACE_EVENT0("input", "WidgetInputHandlerImpl::DispatchEvent");
  input_handler_manager_->DispatchEvent(std::move(event), std::move(callback));
}

void WidgetInputHandlerImpl::DispatchNonBlockingEvent(
    std::unique_ptr<content::InputEvent> event) {
  TRACE_EVENT0("input", "WidgetInputHandlerImpl::DispatchNonBlockingEvent");
  input_handler_manager_->DispatchEvent(std::move(event),
                                        DispatchEventCallback());
}

void WidgetInputHandlerImpl::AttachSynchronousCompositor(
    mojom::SynchronousCompositorControlHostPtr control_host,
    mojom::SynchronousCompositorHostAssociatedPtrInfo host,
    mojom::SynchronousCompositorAssociatedRequest compositor_request) {
  input_handler_manager_->AttachSynchronousCompositor(
      std::move(control_host), std::move(host), std::move(compositor_request));
}

void WidgetInputHandlerImpl::RunOnMainThread(base::OnceClosure closure) {
  if (input_event_queue_) {
    input_event_queue_->QueueClosure(base::BindOnce(
        &RunClosureIfNotSwappedOut, render_widget_, std::move(closure)));
  } else {
    RunClosureIfNotSwappedOut(render_widget_, std::move(closure));
  }
}

void WidgetInputHandlerImpl::Release() {
  if (!main_thread_task_runner_->BelongsToCurrentThread()) {
    // Close the binding on the compositor thread first before telling the main
    // thread to delete this object.
    associated_binding_.Close();
    binding_.Close();
    main_thread_task_runner_->PostTask(
        FROM_HERE, base::BindOnce(&WidgetInputHandlerImpl::Release,
                                  base::Unretained(this)));
    return;
  }
  delete this;
}

}  // namespace content