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_
|