1*38e8c45fSAndroid Build Coastguard Worker /* 2*38e8c45fSAndroid Build Coastguard Worker * Copyright (C) 2021 The Android Open Source Project 3*38e8c45fSAndroid Build Coastguard Worker * 4*38e8c45fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*38e8c45fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*38e8c45fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*38e8c45fSAndroid Build Coastguard Worker * 8*38e8c45fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*38e8c45fSAndroid Build Coastguard Worker * 10*38e8c45fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*38e8c45fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*38e8c45fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*38e8c45fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*38e8c45fSAndroid Build Coastguard Worker * limitations under the License. 15*38e8c45fSAndroid Build Coastguard Worker */ 16*38e8c45fSAndroid Build Coastguard Worker 17*38e8c45fSAndroid Build Coastguard Worker #pragma once 18*38e8c45fSAndroid Build Coastguard Worker 19*38e8c45fSAndroid Build Coastguard Worker #include "../InputDeviceMetricsSource.h" 20*38e8c45fSAndroid Build Coastguard Worker 21*38e8c45fSAndroid Build Coastguard Worker #include <binder/IBinder.h> 22*38e8c45fSAndroid Build Coastguard Worker #include <input/Input.h> 23*38e8c45fSAndroid Build Coastguard Worker #include <unordered_map> 24*38e8c45fSAndroid Build Coastguard Worker 25*38e8c45fSAndroid Build Coastguard Worker namespace android { 26*38e8c45fSAndroid Build Coastguard Worker 27*38e8c45fSAndroid Build Coastguard Worker namespace inputdispatcher { 28*38e8c45fSAndroid Build Coastguard Worker 29*38e8c45fSAndroid Build Coastguard Worker /** 30*38e8c45fSAndroid Build Coastguard Worker * Describes the input event timeline for each connection. 31*38e8c45fSAndroid Build Coastguard Worker * An event with the same inputEventId can go to more than 1 connection simultaneously. 32*38e8c45fSAndroid Build Coastguard Worker * For each connection that the input event goes to, there will be a separate ConnectionTimeline 33*38e8c45fSAndroid Build Coastguard Worker * created. 34*38e8c45fSAndroid Build Coastguard Worker * To create a complete ConnectionTimeline, we must receive two calls: 35*38e8c45fSAndroid Build Coastguard Worker * 1) setDispatchTimeline 36*38e8c45fSAndroid Build Coastguard Worker * 2) setGraphicsTimeline 37*38e8c45fSAndroid Build Coastguard Worker * 38*38e8c45fSAndroid Build Coastguard Worker * In a typical scenario, the dispatch timeline is known first. Later, if a frame is produced, the 39*38e8c45fSAndroid Build Coastguard Worker * graphics timeline is available. 40*38e8c45fSAndroid Build Coastguard Worker */ 41*38e8c45fSAndroid Build Coastguard Worker struct ConnectionTimeline { 42*38e8c45fSAndroid Build Coastguard Worker // DispatchTimeline 43*38e8c45fSAndroid Build Coastguard Worker nsecs_t deliveryTime; // time at which the event was sent to the receiver 44*38e8c45fSAndroid Build Coastguard Worker nsecs_t consumeTime; // time at which the receiver read the event 45*38e8c45fSAndroid Build Coastguard Worker nsecs_t finishTime; // time at which the finish event was received 46*38e8c45fSAndroid Build Coastguard Worker // GraphicsTimeline 47*38e8c45fSAndroid Build Coastguard Worker std::array<nsecs_t, GraphicsTimeline::SIZE> graphicsTimeline; 48*38e8c45fSAndroid Build Coastguard Worker 49*38e8c45fSAndroid Build Coastguard Worker ConnectionTimeline(nsecs_t deliveryTime, nsecs_t consumeTime, nsecs_t finishTime); 50*38e8c45fSAndroid Build Coastguard Worker ConnectionTimeline(std::array<nsecs_t, GraphicsTimeline::SIZE> graphicsTimeline); 51*38e8c45fSAndroid Build Coastguard Worker 52*38e8c45fSAndroid Build Coastguard Worker /** 53*38e8c45fSAndroid Build Coastguard Worker * True if all contained timestamps are valid, false otherwise. 54*38e8c45fSAndroid Build Coastguard Worker */ 55*38e8c45fSAndroid Build Coastguard Worker bool isComplete() const; 56*38e8c45fSAndroid Build Coastguard Worker /** 57*38e8c45fSAndroid Build Coastguard Worker * Set the dispatching-related times. Return true if the operation succeeded, false if the 58*38e8c45fSAndroid Build Coastguard Worker * dispatching times have already been set. If this function returns false, it likely indicates 59*38e8c45fSAndroid Build Coastguard Worker * an error from the app side. 60*38e8c45fSAndroid Build Coastguard Worker */ 61*38e8c45fSAndroid Build Coastguard Worker bool setDispatchTimeline(nsecs_t deliveryTime, nsecs_t consumeTime, nsecs_t finishTime); 62*38e8c45fSAndroid Build Coastguard Worker /** 63*38e8c45fSAndroid Build Coastguard Worker * Set the graphics-related times. Return true if the operation succeeded, false if the 64*38e8c45fSAndroid Build Coastguard Worker * graphics times have already been set. If this function returns false, it likely indicates 65*38e8c45fSAndroid Build Coastguard Worker * an error from the app side. 66*38e8c45fSAndroid Build Coastguard Worker */ 67*38e8c45fSAndroid Build Coastguard Worker bool setGraphicsTimeline(std::array<nsecs_t, GraphicsTimeline::SIZE> graphicsTimeline); 68*38e8c45fSAndroid Build Coastguard Worker 69*38e8c45fSAndroid Build Coastguard Worker inline bool operator==(const ConnectionTimeline& rhs) const; 70*38e8c45fSAndroid Build Coastguard Worker inline bool operator!=(const ConnectionTimeline& rhs) const; 71*38e8c45fSAndroid Build Coastguard Worker 72*38e8c45fSAndroid Build Coastguard Worker private: 73*38e8c45fSAndroid Build Coastguard Worker bool mHasDispatchTimeline = false; 74*38e8c45fSAndroid Build Coastguard Worker bool mHasGraphicsTimeline = false; 75*38e8c45fSAndroid Build Coastguard Worker }; 76*38e8c45fSAndroid Build Coastguard Worker 77*38e8c45fSAndroid Build Coastguard Worker enum class InputEventActionType : int32_t { 78*38e8c45fSAndroid Build Coastguard Worker UNKNOWN_INPUT_EVENT = 0, 79*38e8c45fSAndroid Build Coastguard Worker MOTION_ACTION_DOWN = 1, 80*38e8c45fSAndroid Build Coastguard Worker // Motion events for ACTION_MOVE (characterizes scrolling motion) 81*38e8c45fSAndroid Build Coastguard Worker MOTION_ACTION_MOVE = 2, 82*38e8c45fSAndroid Build Coastguard Worker // Motion events for ACTION_UP (when the pointer first goes up) 83*38e8c45fSAndroid Build Coastguard Worker MOTION_ACTION_UP = 3, 84*38e8c45fSAndroid Build Coastguard Worker // Motion events for ACTION_HOVER_MOVE (pointer position on screen changes but pointer is not 85*38e8c45fSAndroid Build Coastguard Worker // down) 86*38e8c45fSAndroid Build Coastguard Worker MOTION_ACTION_HOVER_MOVE = 4, 87*38e8c45fSAndroid Build Coastguard Worker // Motion events for ACTION_SCROLL (moving the mouse wheel) 88*38e8c45fSAndroid Build Coastguard Worker MOTION_ACTION_SCROLL = 5, 89*38e8c45fSAndroid Build Coastguard Worker // Key events for both ACTION_DOWN and ACTION_UP (key press and key release) 90*38e8c45fSAndroid Build Coastguard Worker KEY = 6, 91*38e8c45fSAndroid Build Coastguard Worker 92*38e8c45fSAndroid Build Coastguard Worker ftl_first = UNKNOWN_INPUT_EVENT, 93*38e8c45fSAndroid Build Coastguard Worker ftl_last = KEY, 94*38e8c45fSAndroid Build Coastguard Worker // Used by latency fuzzer 95*38e8c45fSAndroid Build Coastguard Worker kMaxValue = ftl_last 96*38e8c45fSAndroid Build Coastguard Worker 97*38e8c45fSAndroid Build Coastguard Worker }; 98*38e8c45fSAndroid Build Coastguard Worker 99*38e8c45fSAndroid Build Coastguard Worker struct InputEventTimeline { 100*38e8c45fSAndroid Build Coastguard Worker InputEventTimeline(nsecs_t eventTime, nsecs_t readTime, uint16_t vendorId, uint16_t productId, 101*38e8c45fSAndroid Build Coastguard Worker const std::set<InputDeviceUsageSource>& sources, 102*38e8c45fSAndroid Build Coastguard Worker InputEventActionType inputEventActionType); 103*38e8c45fSAndroid Build Coastguard Worker const nsecs_t eventTime; 104*38e8c45fSAndroid Build Coastguard Worker const nsecs_t readTime; 105*38e8c45fSAndroid Build Coastguard Worker const uint16_t vendorId; 106*38e8c45fSAndroid Build Coastguard Worker const uint16_t productId; 107*38e8c45fSAndroid Build Coastguard Worker const std::set<InputDeviceUsageSource> sources; 108*38e8c45fSAndroid Build Coastguard Worker const InputEventActionType inputEventActionType; 109*38e8c45fSAndroid Build Coastguard Worker 110*38e8c45fSAndroid Build Coastguard Worker struct IBinderHash { operatorInputEventTimeline::IBinderHash111*38e8c45fSAndroid Build Coastguard Worker std::size_t operator()(const sp<IBinder>& b) const { 112*38e8c45fSAndroid Build Coastguard Worker return std::hash<IBinder*>{}(b.get()); 113*38e8c45fSAndroid Build Coastguard Worker } 114*38e8c45fSAndroid Build Coastguard Worker }; 115*38e8c45fSAndroid Build Coastguard Worker 116*38e8c45fSAndroid Build Coastguard Worker std::unordered_map<sp<IBinder>, ConnectionTimeline, IBinderHash> connectionTimelines; 117*38e8c45fSAndroid Build Coastguard Worker 118*38e8c45fSAndroid Build Coastguard Worker bool operator==(const InputEventTimeline& rhs) const; 119*38e8c45fSAndroid Build Coastguard Worker }; 120*38e8c45fSAndroid Build Coastguard Worker 121*38e8c45fSAndroid Build Coastguard Worker class InputEventTimelineProcessor { 122*38e8c45fSAndroid Build Coastguard Worker protected: InputEventTimelineProcessor()123*38e8c45fSAndroid Build Coastguard Worker InputEventTimelineProcessor() {} 124*38e8c45fSAndroid Build Coastguard Worker 125*38e8c45fSAndroid Build Coastguard Worker public: ~InputEventTimelineProcessor()126*38e8c45fSAndroid Build Coastguard Worker virtual ~InputEventTimelineProcessor() {} 127*38e8c45fSAndroid Build Coastguard Worker 128*38e8c45fSAndroid Build Coastguard Worker /** 129*38e8c45fSAndroid Build Coastguard Worker * Process the provided timeline 130*38e8c45fSAndroid Build Coastguard Worker */ 131*38e8c45fSAndroid Build Coastguard Worker virtual void processTimeline(const InputEventTimeline& timeline) = 0; 132*38e8c45fSAndroid Build Coastguard Worker 133*38e8c45fSAndroid Build Coastguard Worker /** 134*38e8c45fSAndroid Build Coastguard Worker * Trigger a push for the input event latency statistics 135*38e8c45fSAndroid Build Coastguard Worker */ 136*38e8c45fSAndroid Build Coastguard Worker virtual void pushLatencyStatistics() = 0; 137*38e8c45fSAndroid Build Coastguard Worker 138*38e8c45fSAndroid Build Coastguard Worker virtual std::string dump(const char* prefix) const = 0; 139*38e8c45fSAndroid Build Coastguard Worker }; 140*38e8c45fSAndroid Build Coastguard Worker 141*38e8c45fSAndroid Build Coastguard Worker } // namespace inputdispatcher 142*38e8c45fSAndroid Build Coastguard Worker } // namespace android 143