File: input_transfer_handler_android.h

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,811; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (168 lines) | stat: -rw-r--r-- 6,609 bytes parent folder | download | duplicates (4)
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
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_TRANSFER_HANDLER_ANDROID_H_
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_TRANSFER_HANDLER_ANDROID_H_

#include <memory>
#include <optional>

#include "base/android/scoped_java_ref.h"
#include "base/memory/raw_ptr.h"
#include "content/common/content_export.h"
#include "content/public/browser/android/transfer_input_to_viz_result.h"
#include "content/public/browser/render_widget_host.h"
#include "gpu/ipc/common/surface_handle.h"
#include "ui/events/android/motion_event_android.h"

namespace content {

class InputTransferHandlerAndroidClient {
 public:
  virtual gpu::SurfaceHandle GetRootSurfaceHandle() = 0;
  virtual void SendStateOnTouchTransfer(const ui::MotionEvent& event,
                                        bool browser_would_have_handled) = 0;
  virtual bool IsMojoRIRDelegateConnectionSetup() = 0;
};

// The class assumes transfer input to viz is supported, so instantiate only
// when |input::IsTransferInputToVizSupported()| returns true.
// The class is responsible for coordinating with java side InputTransferHandler
// which may end up issuing |WindowManager.transferTouchGesture| Android API
// call. In case of a successful transfer, rest of the touch sequence is
// consumed until a TOUCH_CANCEL is seen. InputTransferHandlerAndroid is owned
// by RenderWidgetHostViewAndroid, instantiated if
// |input::IsTransferInputToVizSupported()| returns true.
class CONTENT_EXPORT InputTransferHandlerAndroid {
 public:
  class JniDelegate {
   public:
    virtual ~JniDelegate() = default;
    virtual int MaybeTransferInputToViz(int surface_id) = 0;
    virtual int TransferInputToViz(int surface_id) = 0;
  };

  explicit InputTransferHandlerAndroid(
      InputTransferHandlerAndroidClient* client);
  virtual ~InputTransferHandlerAndroid();

  // Virtual for testing.
  virtual bool OnTouchEvent(const ui::MotionEventAndroid& event,
                            bool is_ignoring_input_events = false);

  void set_jni_delegate_for_testing(std::unique_ptr<JniDelegate> delegate) {
    jni_delegate_ = std::move(delegate);
  }

  static constexpr const char* kTouchMovesSeenHistogram =
      "Android.InputOnViz.Browser.TouchMovesSeenAfterTransfer";
  static constexpr const char* kEventsAfterTransferHistogram =
      "Android.InputOnViz.Browser.EventsAfterTransfer";
  static constexpr const char* kTransferInputToVizResultHistogram =
      "Android.InputOnViz.Browser.TransferInputToVizResult";
  static constexpr const char* kEventsInDroppedSequenceHistogram =
      "Android.InputOnViz.Browser.NumEventsInDroppedSequence";
  static constexpr const char* kEventTypesInDroppedSequenceHistogram =
      "Android.InputOnViz.Browser.EventTypesInDroppedSequence";
  static constexpr const char* kTouchSequenceDroppedReasonHistogram =
      "Android.InputOnViz.Browser.SequenceDroppedReason";

  bool touch_transferred() {
    return handler_state_ == HandlerState::kConsumeEventsUntilCancel;
  }
  bool FilterRedundantDownEvent(const ui::MotionEvent& event);

  enum class RequestInputBackReason {
    kStartDragAndDropGesture = 0,
    kStartTouchSelectionDragGesture = 1,
    kStartOverscrollGestures = 2,
  };
  void RequestInputBack(RequestInputBackReason reason);

  void OnTouchEnd(base::TimeTicks event_time);

  // Virtual for testing.
  virtual bool IsTouchSequencePotentiallyActiveOnViz() const;

  RenderWidgetHost::InputEventObserver& GetInputObserver() {
    return input_observer_;
  }

 private:
  class InputObserver : public RenderWidgetHost::InputEventObserver {
   public:
    explicit InputObserver(InputTransferHandlerAndroid& transfer_handler);
    ~InputObserver() override;
    // Start RenderWidgetHost::InputEventObserver overrides
    void OnInputEvent(const RenderWidgetHost& host,
                      const blink::WebInputEvent& event) override;
    // End RenderWidgetHost::InputEventObserver overrides

   private:
    const raw_ref<InputTransferHandlerAndroid> transfer_handler_;
  };

  void Reset();
  void OnTouchTransferredSuccessfully(const ui::MotionEventAndroid& event,
                                      bool browser_would_have_handled);

  void EmitTransferResultHistogramAndTraceEvent(
      TransferInputToVizResult result);

  // These values are persisted to logs. Entries should not be renumbered and
  // numeric values should never be reused.
  //
  // LINT.IfChange(InputOnVizSequenceDroppedReason)
  enum class InputOnVizSequenceDroppedReason {
    kActiveSeqOnVizAbnormalDownTime = 0,
    kFailedToTransferPotentialPointer = 1,
    kMaxValue = kFailedToTransferPotentialPointer,
  };
  // LINT.ThenChange(//tools/metrics/histograms/metadata/android/enums.xml:InputOnVizSequenceDroppedReason)

  void OnStartDroppingSequence(const ui::MotionEventAndroid& event,
                               InputOnVizSequenceDroppedReason reason);

  void DropCurrentSequence(const ui::MotionEventAndroid& event);
  void ConsumeEventsUntilCancel(const ui::MotionEventAndroid& event);
  void ConsumeSequence(const ui::MotionEventAndroid& event);

  friend class MockInputTransferHandler;
  InputTransferHandlerAndroid();

  raw_ptr<InputTransferHandlerAndroidClient> client_ = nullptr;
  // Stores the event time of first down event of the most recent touch sequence
  // transferred to VizCompositor. See
  // (https://developer.android.com/reference/android/view/MotionEvent#getDownTime())
  base::TimeTicks cached_transferred_sequence_down_time_ms_;

  int num_events_in_dropped_sequence_ = 0;

  enum class HandlerState {
    // Handler is just passively listening for events in this state.
    kIdle,
    // The sequence is being dropped since a potential pointer sequence failed
    // to transfer.
    kDroppingCurrentSequence,
    // The touch sequence was transferred to Viz and the handler is consuming
    // rest of sequence that might hit Browser.
    kConsumeEventsUntilCancel,
    // Consume current sequence until an action cancel or action up comes in.
    kConsumeSequence,
  } handler_state_ = HandlerState::kIdle;

  bool requested_input_back_ = false;
  std::optional<RequestInputBackReason> requested_input_back_reason_ =
      std::nullopt;
  int touch_moves_seen_after_transfer_ = 0;
  std::unique_ptr<JniDelegate> jni_delegate_ = nullptr;

  base::TimeTicks last_seen_touch_end_ts_;

  InputObserver input_observer_;
};

}  // namespace content

#endif  // CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_TRANSFER_HANDLER_ANDROID_H_