upgrade velocity to android14

This commit is contained in:
侯歌 2024-05-08 17:20:36 +08:00
parent e8d128468a
commit 4dbc0eaf13
12 changed files with 1033 additions and 773 deletions

View File

@ -6,30 +6,29 @@ namespace uidemo1{
namespace R{
namespace id{
static constexpr int tick = 0x00002710 ;/*10000*/
static constexpr int idno = 0x00002711 ;/*10001*/
static constexpr int filename = 0x00002712 ;/*10002*/
static constexpr int filesize = 0x00002713 ;/*10003*/
static constexpr int icon = 0x00002714 ;/*10004*/
static constexpr int address = 0x00002715 ;/*10005*/
static constexpr int BtnGo = 0x00002716 ;/*10006*/
static constexpr int TextUrl = 0x00002717 ;/*10007*/
static constexpr int WebView01 = 0x00002718 ;/*10008*/
static constexpr int editText1 = 0x00002719 ;/*10009*/
static constexpr int editText2 = 0x0000271A ;/*10010*/
static constexpr int textcontainer = 0x0000271B ;/*10011*/
static constexpr int button1 = 0x0000271C ;/*10012*/
static constexpr int textview1 = 0x0000271D ;/*10013*/
static constexpr int light = 0x0000271E ;/*10014*/
static constexpr int tv1 = 0x0000271F ;/*10015*/
static constexpr int et1 = 0x00002720 ;/*10016*/
static constexpr int tv2 = 0x00002721 ;/*10017*/
static constexpr int et2 = 0x00002722 ;/*10018*/
static constexpr int btnadd = 0x00002723 ;/*10019*/
static constexpr int table = 0x00002724 ;/*10020*/
static constexpr int exitbutton = 0x00002725 ;/*10021*/
static constexpr int tablayout = 0x00002726 ;/*10022*/
static constexpr int viewpager = 0x00002727 ;/*10023*/
static constexpr int idno = 0x00002710 ;/*10000*/
static constexpr int filename = 0x00002711 ;/*10001*/
static constexpr int filesize = 0x00002712 ;/*10002*/
static constexpr int icon = 0x00002713 ;/*10003*/
static constexpr int address = 0x00002714 ;/*10004*/
static constexpr int BtnGo = 0x00002715 ;/*10005*/
static constexpr int TextUrl = 0x00002716 ;/*10006*/
static constexpr int WebView01 = 0x00002717 ;/*10007*/
static constexpr int editText1 = 0x00002718 ;/*10008*/
static constexpr int editText2 = 0x00002719 ;/*10009*/
static constexpr int textcontainer = 0x0000271A ;/*10010*/
static constexpr int button1 = 0x0000271B ;/*10011*/
static constexpr int textview1 = 0x0000271C ;/*10012*/
static constexpr int light = 0x0000271D ;/*10013*/
static constexpr int tv1 = 0x0000271E ;/*10014*/
static constexpr int et1 = 0x0000271F ;/*10015*/
static constexpr int tv2 = 0x00002720 ;/*10016*/
static constexpr int et2 = 0x00002721 ;/*10017*/
static constexpr int btnadd = 0x00002722 ;/*10018*/
static constexpr int table = 0x00002723 ;/*10019*/
static constexpr int exitbutton = 0x00002724 ;/*10020*/
static constexpr int tablayout = 0x00002725 ;/*10021*/
static constexpr int viewpager = 0x00002726 ;/*10022*/
};/*namespace id*/
namespace strings{

View File

@ -1,28 +1,27 @@
<?xml version="1.0" encoding="utf-8"?><!--Generated by CDdroid's machine,Do not edit !!!-->
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<id name="tick">0x00002710</id>
<id name="idno">0x00002711</id>
<id name="filename">0x00002712</id>
<id name="filesize">0x00002713</id>
<id name="icon">0x00002714</id>
<id name="address">0x00002715</id>
<id name="BtnGo">0x00002716</id>
<id name="TextUrl">0x00002717</id>
<id name="WebView01">0x00002718</id>
<id name="editText1">0x00002719</id>
<id name="editText2">0x0000271a</id>
<id name="textcontainer">0x0000271b</id>
<id name="button1">0x0000271c</id>
<id name="textview1">0x0000271d</id>
<id name="light">0x0000271e</id>
<id name="tv1">0x0000271f</id>
<id name="et1">0x00002720</id>
<id name="tv2">0x00002721</id>
<id name="et2">0x00002722</id>
<id name="btnadd">0x00002723</id>
<id name="table">0x00002724</id>
<id name="exitbutton">0x00002725</id>
<id name="tablayout">0x00002726</id>
<id name="viewpager">0x00002727</id>
<id name="idno">0x00002710</id>
<id name="filename">0x00002711</id>
<id name="filesize">0x00002712</id>
<id name="icon">0x00002713</id>
<id name="address">0x00002714</id>
<id name="BtnGo">0x00002715</id>
<id name="TextUrl">0x00002716</id>
<id name="WebView01">0x00002717</id>
<id name="editText1">0x00002718</id>
<id name="editText2">0x00002719</id>
<id name="textcontainer">0x0000271a</id>
<id name="button1">0x0000271b</id>
<id name="textview1">0x0000271c</id>
<id name="light">0x0000271d</id>
<id name="tv1">0x0000271e</id>
<id name="et1">0x0000271f</id>
<id name="tv2">0x00002720</id>
<id name="et2">0x00002721</id>
<id name="btnadd">0x00002722</id>
<id name="table">0x00002723</id>
<id name="exitbutton">0x00002724</id>
<id name="tablayout">0x00002725</id>
<id name="viewpager">0x00002726</id>
</resources>

View File

@ -19,21 +19,22 @@ public:
template<typename T>
class SimplePool:public Pool<T>{
private:
int maxPoolSize;
int mPoolSize;
std::vector<T*> mPool;
public:
SimplePool(int maxPoolSize) {
this->maxPoolSize = maxPoolSize;
for(int i=0;i<maxPoolSize;i++)mPool.push_back(new T());
mPool.resize(maxPoolSize);
mPoolSize = 0;
}
~SimplePool(){
for(int i=0;i<maxPoolSize;i++)delete mPool.at(i);
for(auto elem:mPool)
delete elem;
mPool.clear();
}
T* acquire() {
if (!mPool.empty()) {
T* instance = (T*) mPool.back();
mPool.pop_back();
if (mPoolSize>0) {
T* instance = (T*) mPool[mPoolSize-1];
mPool[--mPoolSize] = nullptr;
return instance;
}
return nullptr;
@ -42,15 +43,15 @@ public:
if (isInPool(instance)) {
throw "Already in the pool!";
}
if (maxPoolSize > mPool.size()) {
mPool.push_back(instance);
if (mPoolSize < mPool.size()) {
mPool[mPoolSize++] = instance;
return true;
}
return false;
}
private:
bool isInPool(T* instance) {
for (int i = 0; i < mPool.size(); i++) {
bool isInPool(T* instance) {
for (int i = 0; i < mPoolSize; i++) {
if (mPool[i] == instance) {
return true;
}
@ -64,7 +65,7 @@ public:
private:
std::mutex mutex;
public:
SynchronizedPool(int maxPoolSize):SimplePool<T>(maxPoolSize){
SynchronizedPool(int maxPoolSize):SimplePool<T>(maxPoolSize){
}
T acquire() {

View File

@ -83,6 +83,7 @@ bool PointerCoords::operator==(const PointerCoords& other) const {
return false;
}
}
if(isResampled != other.isResampled)return false;
return true;
}
@ -300,7 +301,7 @@ MotionEvent*MotionEvent::split(int idBits){
const int historyPos = h == historySize ? HISTORY_CURRENT : h;
for (int i = 0; i < newPointerCount; i++) {
//getPointerCoords(map[i], historyPos, &pc[i]);
getHistoricalRawPointerCoords(map[i], historyPos, pc[i]);
pc[i] = getHistoricalRawPointerCoords(map[i], historyPos);
}
const long eventTimeNanos = getHistoricalEventTime(historyPos);
if (h == 0) {
@ -362,7 +363,7 @@ int MotionEvent::getPointerIdBits()const{
}
float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
return getRawPointerCoords(pointerIndex).getAxisValue(axis);
return getHistoricalRawAxisValue(axis,pointerIndex,getHistorySize());
}
float MotionEvent::getAxisValue(int axis)const {
@ -370,7 +371,7 @@ float MotionEvent::getAxisValue(int axis)const {
}
float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
const float value = getRawPointerCoords(pointerIndex).getAxisValue(axis);
const float value = getHistoricalAxisValue(axis,pointerIndex,getHistorySize());
switch (axis) {
case AXIS_X://AMOTION_EVENT_AXIS_X:
return value + mXOffset;
@ -384,8 +385,6 @@ nsecs_t MotionEvent::getHistoricalEventTime(size_t historyPos) const{
if(historyPos==HISTORY_CURRENT){
return getEventTime();
}else{
const size_t historySize = getHistorySize();
if((historyPos<0)||(historyPos>=historySize))return 0;
return mSampleEventTimes[historyPos];
}
}
@ -394,8 +393,6 @@ nsecs_t MotionEvent::getHistoricalEventTimeNanos(size_t historyPos) const{
if(historyPos==HISTORY_CURRENT){
return getEventTimeNanos();
}else{
const size_t historySize = getHistorySize();
if((historyPos<0)||(historyPos>=historySize))return 0;
return mSampleEventTimes[historyPos]*NS_PER_MS;
}
}
@ -427,6 +424,10 @@ bool MotionEvent::isTouchEvent(int32_t source, int32_t action){
return false;
}
bool MotionEvent::isResampled(size_t pointerIndex, size_t historicalIndex) const {
return getHistoricalRawPointerCoords(pointerIndex, historicalIndex).isResampled;
}
bool MotionEvent::isTouchEvent()const{
return isTouchEvent(mSource, mAction);
}
@ -562,22 +563,21 @@ void MotionEvent::transform(const Cairo::Matrix& matrix){
transform(f9);
}
void MotionEvent::getHistoricalRawPointerCoords(
size_t pointerIndex, size_t historicalIndex,PointerCoords&out) const {
const PointerCoords& MotionEvent::getHistoricalRawPointerCoords(
size_t pointerIndex, size_t historicalIndex) const {
const size_t pointerCount = getPointerCount();
if(pointerIndex<0||pointerIndex>=pointerCount)return;
if(pointerIndex<0||pointerIndex>=pointerCount)throw "outof Range";
if(historicalIndex==HISTORY_CURRENT){
out = mSamplePointerCoords[pointerIndex];
return mSamplePointerCoords[pointerIndex];
}else{
out = mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
const size_t position = historicalIndex * getPointerCount() + pointerIndex;
return mSamplePointerCoords[position];
}
}
float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
size_t historicalIndex) const {
PointerCoords pc;
getHistoricalRawPointerCoords(pointerIndex,historicalIndex,pc);
return pc.getAxisValue(axis);
return getHistoricalRawPointerCoords(pointerIndex,historicalIndex).getAxisValue(axis);
}
float MotionEvent::getHistoricalRawX(size_t pointerIndex, size_t historicalIndex) const {
@ -587,15 +587,22 @@ float MotionEvent::getHistoricalRawX(size_t pointerIndex, size_t historicalIndex
float MotionEvent::getHistoricalRawY(size_t pointerIndex, size_t historicalIndex) const {
return getHistoricalRawAxisValue(AXIS_Y, pointerIndex, historicalIndex);
}
const PointerCoords& MotionEvent::getPointerCoords(int pointerIndex)const{
return getHistoricalRawPointerCoords(pointerIndex,HISTORY_CURRENT);
}
const PointerCoords& MotionEvent::getHistoricalPointerCoords(size_t pointerIndex, size_t historicalIndex) const{
return getHistoricalRawPointerCoords(pointerIndex,historicalIndex);
}
float MotionEvent::getHistoricalAxisValue(int axis,size_t pointerIndex,size_t historicalIndex)const{
PointerCoords pc;
getHistoricalRawPointerCoords(pointerIndex,historicalIndex,pc);
return pc.getAxisValue(axis);
return getHistoricalRawPointerCoords(pointerIndex,historicalIndex).getAxisValue(axis);
}
float MotionEvent::getHistoricalX(size_t pointerIndex, size_t historicalIndex) const{
return getHistoricalRawAxisValue(AXIS_X, pointerIndex, historicalIndex);
}
float MotionEvent::getHistoricalY(size_t pointerIndex, size_t historicalIndex) const{
return getHistoricalRawAxisValue(AXIS_Y, pointerIndex, historicalIndex);
}

View File

@ -10,13 +10,14 @@ struct PointerCoords {
// Bitfield of axes that are present in this structure.
uint64_t bits __attribute__((aligned(8)));
bool isResampled;
// Values of axes that are stored in this structure packed in order by axis id
// for each axis that is present in the structure according to 'bits'.
float values[MAX_AXES];
inline void clear() {
BitSet64::clear(bits);
isResampled = false;
}
bool isEmpty() const {
@ -245,22 +246,20 @@ public:
nsecs_t getHistoricalEventTime(size_t historicalIndex) const;
nsecs_t getHistoricalEventTimeNanos(size_t historicalIndex) const;
private:
////////////////////////////////// Raw AXIS Properties ///////////////////////////////////
const PointerCoords& getRawPointerCoords(size_t pointerIndex) const;
void getHistoricalRawPointerCoords(size_t pointerIndex, size_t historicalIndex,PointerCoords& outPointerCoords) const;
const PointerCoords& getHistoricalRawPointerCoords(size_t pointerIndex, size_t historicalIndex) const;
float getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,size_t historicalIndex) const;
float getHistoricalRawX(size_t pointerIndex, size_t historicalIndex) const;
float getHistoricalRawY(size_t pointerIndex, size_t historicalIndex) const;
float getRawAxisValue(int32_t axis, size_t pointerIndex) const;
inline float getRawX(size_t pointerIndex) const { return getRawAxisValue(AXIS_X, pointerIndex); }
inline float getRawY(size_t pointerIndex) const { return getRawAxisValue(AXIS_Y, pointerIndex); }
public:
/////////////////////// AXIS Properties has been transformed //////////////////////////////
void getPointerCoords(int pointerIndex, PointerCoords& outPointerCoords)const{
getHistoricalRawPointerCoords(pointerIndex,HISTORY_CURRENT,outPointerCoords);
}
void getHistoricalPointerCoords(size_t pointerIndex, size_t historicalIndex,PointerCoords& outPointerCoords) const;
const PointerCoords& getPointerCoords(int pointerIndex)const;
const PointerCoords& getHistoricalPointerCoords(size_t pointerIndex, size_t historicalIndex) const;
float getHistoricalAxisValue(int axis, size_t pointerIndex,size_t historicalIndex) const;
float getHistoricalX(size_t pointerIndex, size_t historicalIndex) const;
float getHistoricalY(size_t pointerIndex, size_t historicalIndex) const;
@ -312,6 +311,7 @@ public:
inline float getOrientation(size_t pointerIndex) const {
return getAxisValue(AXIS_ORIENTATION, pointerIndex);
}
bool isResampled(size_t pointerIndex, size_t historicalIndex) const;
ssize_t findPointerIndex(int32_t pointerId) const;
inline bool isTargetAccessibilityFocus()const{
return (mFlags & FLAG_TARGET_ACCESSIBILITY_FOCUS) != 0;

File diff suppressed because it is too large Load Diff

View File

@ -1,140 +1,199 @@
#ifndef __VELOCITY_TRACKER_H__
#define __VELOCITY_TRACKER_H__
#include <map>
#include <array>
#include <memory>
#include <core/pools.h>
#include <view/motionevent.h>
namespace cdroid{
typedef int64_t nsecs_t;
class VelocityTrackerStrategy;
class VelocityTrackerImpl;
#define MAX_POINTERS 16
#define MAX_POINTER_ID 31
#define ACTIVE_POINTER_ID -1
////////////VelocityTracker.java///////////////////////////
//frameworks/base/core/jni/android_view_VelocityTracker.cpp
class VelocityTracker{
public:
/**
* Use the default Velocity Tracker Strategy. Different axes may use different default
* strategies.
*/
static constexpr int VELOCITY_TRACKER_STRATEGY_DEFAULT = -1;
/**
* Velocity Tracker Strategy: Impulse.
* Physical model of pushing an object. Quality: VERY GOOD.
* Works with duplicate coordinates, unclean finger liftoff.
*/
static constexpr int VELOCITY_TRACKER_STRATEGY_IMPULSE = 0;
/**
* Velocity Tracker Strategy: LSQ1.
* 1st order least squares. Quality: POOR.
* Frequently underfits the touch data especially when the finger accelerates
* or changes direction. Often underestimates velocity. The direction
* is overly influenced by historical touch points.
*/
static constexpr int VELOCITY_TRACKER_STRATEGY_LSQ1 = 1;
/**
* Velocity Tracker Strategy: LSQ2.
* 2nd order least squares. Quality: VERY GOOD.
* Pretty much ideal, but can be confused by certain kinds of touch data,
* particularly if the panel has a tendency to generate delayed,
* duplicate or jittery touch coordinates when the finger is released.
*/
static constexpr int VELOCITY_TRACKER_STRATEGY_LSQ2 = 2;
/**
* Velocity Tracker Strategy: LSQ3.
* 3rd order least squares. Quality: UNUSABLE.
* Frequently overfits the touch data yielding wildly divergent estimates
* of the velocity when the finger is released.
*/
static constexpr int VELOCITY_TRACKER_STRATEGY_LSQ3 = 3;
/**
* Velocity Tracker Strategy: WLSQ2_DELTA.
* 2nd order weighted least squares, delta weighting. Quality: EXPERIMENTAL
*/
static constexpr int VELOCITY_TRACKER_STRATEGY_WLSQ2_DELTA = 4;
/**
* Velocity Tracker Strategy: WLSQ2_CENTRAL.
* 2nd order weighted least squares, central weighting. Quality: EXPERIMENTALe
*/
static constexpr int VELOCITY_TRACKER_STRATEGY_WLSQ2_CENTRAL = 5;
/**
* Velocity Tracker Strategy: WLSQ2_RECENT.
* 2nd order weighted least squares, recent weighting. Quality: EXPERIMENTAL
*/
static constexpr int VELOCITY_TRACKER_STRATEGY_WLSQ2_RECENT = 6;
/**
* Velocity Tracker Strategy: INT1.
* 1st order integrating filter. Quality: GOOD.
* Not as good as 'lsq2' because it cannot estimate acceleration but it is
* more tolerant of errors. Like 'lsq1', this strategy tends to underestimate
* the velocity of a fling but this strategy tends to respond to changes in
* direction more quickly and accurately.
*/
static constexpr int VELOCITY_TRACKER_STRATEGY_INT1 = 7;
/**
* Velocity Tracker Strategy: INT2.
* 2nd order integrating filter. Quality: EXPERIMENTAL.
* For comparison purposes only. Unlike 'int1' this strategy can compensate
* for acceleration but it typically overestimates the effect.
*/
static constexpr int VELOCITY_TRACKER_STRATEGY_INT2 = 8;
/**
* Velocity Tracker Strategy: Legacy.
* Legacy velocity tracker algorithm. Quality: POOR.
* For comparison purposes only. This algorithm is strongly influenced by
* old data points, consistently underestimates velocity and takes a very long
* time to adjust to changes in direction.
*/
static constexpr int VELOCITY_TRACKER_STRATEGY_LEGACY = 9;
public:
class VelocityTrackerState;
struct Estimator;
struct ComputedVelocity;
private:
struct Velocity {
float vx, vy;
};
class VelocityTrackerImpl* mVelocityTracker;
int32_t mActivePointerId;
BitSet32 mCalculatedIdBits;
Velocity mCalculatedVelocity[MAX_POINTERS];
int mStrategy;
VelocityTrackerState*mTrackerState;
static std::map<const std::string,int>STRATEGIES;
static int toStrategyId(const char*);
static Pools::SimplePool<VelocityTracker>sPool;
public:
struct Position {
float x, y;
};
struct Estimator {
static constexpr size_t MAX_DEGREE = 4;
// Estimator time base.
nsecs_t time;
// Polynomial coefficients describing motion in X and Y.
float xCoeff[MAX_DEGREE + 1], yCoeff[MAX_DEGREE + 1];
// Polynomial degree (number of coefficients), or zero if no information is
// available.
uint32_t degree;
// Confidence (coefficient of determination), between 0 (no fit) and 1 (perfect fit).
float confidence;
inline void clear() {
time = 0;
degree = 0;
confidence = 0;
for (size_t i = 0; i <= MAX_DEGREE; i++) {
xCoeff[i] = 0;
yCoeff[i] = 0;
}
}
};
public:
VelocityTracker();
explicit VelocityTracker(const char* strategy);
friend Pools::SimplePool<VelocityTracker>;
VelocityTracker(int strategy=0);
~VelocityTracker();
public:
static VelocityTracker*obtain();
static VelocityTracker*obtain(const char*);
static VelocityTracker*obtain(int strategy);
void recycle();
void clear();
void addMovement(const MotionEvent& event);
void computeCurrentVelocity(int32_t units);
void computeCurrentVelocity(int32_t units, float maxVelocity);
void getVelocity(int32_t id, float* outVx, float* outVy);
bool getEstimator(int32_t id, Estimator* outEstimator);
void computeCurrentVelocity(int units);
void computeCurrentVelocity(int units,float maxVelocity);
float getXVelocity();
float getXVelocity(int);
float getYVelocity();
float getYVelocity(int);
static VelocityTracker*obtain();
static VelocityTracker*obtain(const char*name);
void recycle();
float getXVelocity(int pointerId);
float getYVelocity(int pointerId);
float getAxisVelocity(int axis);
float getAxisVelocity(int axis,int pointerId);
};
struct VelocityTracker::Estimator {
static constexpr size_t MAX_DEGREE = 4;
// Estimator time base.
nsecs_t time;
// Polynomial coefficients describing motion.
float coeff[MAX_DEGREE + 1];
// Polynomial degree (number of coefficients), or zero if no information is
// available.
uint32_t degree;
// Confidence (coefficient of determination), between 0 (no fit) and 1 (perfect fit).
float confidence;
Estimator();
void clear();
};
/*Contains all available velocity data from a VelocityTracker.*/
struct VelocityTracker::ComputedVelocity {
bool getVelocity(int32_t axis, int32_t id,float&outVelocity) const;
inline void addVelocity(int32_t axis, int32_t id, float velocity) {
mVelocities[axis][id] = velocity;
}
private:
std::map<int32_t /*axis*/, std::map<int32_t /*pointerId*/, float /*velocity*/>> mVelocities;
};
class VelocityTracker::VelocityTrackerState {
public:
explicit VelocityTrackerState(int strategy);
~VelocityTrackerState();
void clear();
void addMovement(const MotionEvent& event);
// TODO(b/32830165): consider supporting an overload that supports computing velocity only for
// a subset of the supported axes.
void computeCurrentVelocity(int32_t units, float maxVelocity);
float getVelocity(int32_t axis, int32_t id);
private:
VelocityTrackerImpl *mVelocityTracker;
VelocityTracker::ComputedVelocity mComputedVelocity;
};
///////////////////////////////////////////////////////////////////////////////////////////////
class VelocityTrackerStrategy {
protected:
VelocityTrackerStrategy() { }
public:
virtual ~VelocityTrackerStrategy() { }
virtual void clear() = 0;
virtual void clearPointers(BitSet32 idBits) = 0;
virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
const VelocityTracker::Position* positions) = 0;
virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const = 0;
};
class IntegratingVelocityTrackerStrategy : public VelocityTrackerStrategy {
public:
// Degree must be 1 or 2.
IntegratingVelocityTrackerStrategy(uint32_t degree);
~IntegratingVelocityTrackerStrategy();
virtual void clear();
virtual void clearPointers(BitSet32 idBits);
virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
const VelocityTracker::Position* positions);
virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const;
private:
// Current state estimate for a particular pointer.
struct State {
nsecs_t updateTime;
uint32_t degree;
float xpos, xvel, xaccel;
float ypos, yvel, yaccel;
};
const uint32_t mDegree;
BitSet32 mPointerIdBits;
State mPointerState[MAX_POINTER_ID + 1];
void initState(State& state, nsecs_t eventTime, float xpos, float ypos) const;
void updateState(State& state, nsecs_t eventTime, float xpos, float ypos) const;
void populateEstimator(const State& state, VelocityTracker::Estimator* outEstimator) const;
virtual void clearPointer(int32_t pointerId) = 0;
virtual void addMovement(nsecs_t eventTime, int32_t pointerId,float positions) = 0;
virtual bool getEstimator(int32_t pointerId, VelocityTracker::Estimator* outEstimator) const = 0;
};
class LeastSquaresVelocityTrackerStrategy : public VelocityTrackerStrategy {
public:
enum Weighting {
// No weights applied. All data points are equally reliable.
WEIGHTING_NONE,
NONE,
// Weight by time delta. Data points clustered together are weighted less.
WEIGHTING_DELTA,
DELTA,
// Weight such that points within a certain horizon are weighed more than those
// outside of that horizon.
WEIGHTING_CENTRAL,
CENTRAL,
// Weight such that points older than a certain amount are weighed less.
WEIGHTING_RECENT,
RECENT,
};
// Degree must be no greater than Estimator::MAX_DEGREE.
LeastSquaresVelocityTrackerStrategy(uint32_t degree, Weighting weighting = WEIGHTING_NONE);
LeastSquaresVelocityTrackerStrategy(uint32_t degree, Weighting weighting = NONE);
virtual ~LeastSquaresVelocityTrackerStrategy();
virtual void clear();
virtual void clearPointers(BitSet32 idBits);
virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
const VelocityTracker::Position* positions);
virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const;
void clearPointer(int32_t pointerId)override;
void addMovement(nsecs_t eventTime, int32_t pointerId,float positions) override;
bool getEstimator(int32_t pointerId, VelocityTracker::Estimator* outEstimator) const override;
private:
// Sample horizon.
// We don't use too much history by default since we want to react to quick
@ -144,32 +203,81 @@ private:
static const uint32_t HISTORY_SIZE = 20;
struct Movement {
nsecs_t eventTime;
BitSet32 idBits;
VelocityTracker::Position positions[MAX_POINTERS];
inline const VelocityTracker::Position& getPosition(uint32_t id) const {
return positions[idBits.getIndexOfBit(id)];
}
float position ;
};
float chooseWeight(uint32_t index) const;
float chooseWeight(int32_t pointerId,uint32_t index) const;
const uint32_t mDegree;
const Weighting mWeighting;
uint32_t mIndex;
Movement mMovements[HISTORY_SIZE];
std::map<int32_t/*pointerId*/,size_t/*position inArray*/> mIndex;
std::map<int32_t/*pointerId*/,std::array<Movement,HISTORY_SIZE>>mMovements;
};
class IntegratingVelocityTrackerStrategy : public VelocityTrackerStrategy {
public:
// Degree must be 1 or 2.
IntegratingVelocityTrackerStrategy(uint32_t degree);
~IntegratingVelocityTrackerStrategy();
void clearPointer(int32_t pointerId) override;
void addMovement(nsecs_t eventTime, int32_t pointerId,float positions) override;
bool getEstimator(int32_t pointerId, VelocityTracker::Estimator* outEstimator) const override;
private:
// Current state estimate for a particular pointer.
struct State {
nsecs_t updateTime;
uint32_t degree;
float pos, vel, accel;
};
const uint32_t mDegree;
BitSet32 mPointerIdBits;
State mPointerState[MAX_POINTER_ID + 1];
void initState(State& state, nsecs_t eventTime, float pos) const;
void updateState(State& state, nsecs_t eventTime, float pos) const;
void populateEstimator(const State& state, VelocityTracker::Estimator* outEstimator) const;
};
/*
* Velocity tracker strategy used prior to ICS.
*/
class LegacyVelocityTrackerStrategy : public VelocityTrackerStrategy {
public:
LegacyVelocityTrackerStrategy();
~LegacyVelocityTrackerStrategy() override;
void clearPointer(int32_t pointerId) override;
void addMovement(nsecs_t eventTime, int32_t pointerId, float position) override;
bool getEstimator(int32_t pointerId,VelocityTracker::Estimator*) const override;
private:
// Oldest sample to consider when calculating the velocity.
static const nsecs_t HORIZON = 200 * 1000000; // 100 ms
// Number of samples to keep.
static const uint32_t HISTORY_SIZE = 20;
// The minimum duration between samples when estimating velocity.
static const nsecs_t MIN_DURATION = 10 * 1000000; // 10 ms
struct Movement {
nsecs_t eventTime;
float position;
};
std::map<int32_t /*pointerId*/, size_t /*positionInArray*/> mIndex;
std::map<int32_t /*pointerId*/, std::array<Movement, HISTORY_SIZE>> mMovements;
};
class ImpulseVelocityTrackerStrategy : public VelocityTrackerStrategy {
public:
ImpulseVelocityTrackerStrategy();
ImpulseVelocityTrackerStrategy(bool deltaValues);
virtual ~ImpulseVelocityTrackerStrategy();
virtual void clear();
virtual void clearPointers(BitSet32 idBits);
virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
const VelocityTracker::Position* positions);
virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const;
void clearPointer(int32_t pointerId) override;
void addMovement(nsecs_t eventTime, int32_t pointer,float positions) override;
bool getEstimator(int32_t pointerId, VelocityTracker::Estimator* outEstimator) const override;
private:
// Sample horizon.
// We don't use too much history by default since we want to react to quick
@ -181,16 +289,11 @@ private:
struct Movement {
nsecs_t eventTime;
BitSet32 idBits;
VelocityTracker::Position positions[MAX_POINTERS];
inline const VelocityTracker::Position& getPosition(uint32_t id) const {
return positions[idBits.getIndexOfBit(id)];
}
float position;
};
size_t mIndex;
Movement mMovements[HISTORY_SIZE];
const bool mDeltaValues;
std::map<int32_t /*pointerId*/, size_t /*positionInArray*/> mIndex;
std::map<int32_t /*pointerId*/, std::array<Movement, HISTORY_SIZE>> mMovements;
};
}
#endif

View File

@ -24,14 +24,18 @@ static void* X11EventProc(void*p);
static GFXRect screenMargin= {0}; //{60,0,60,0};
#define SENDKEY(k,down) {InjectKey(EV_KEY,k,down);}
#if 1
#define SENDMOUSE(time,x,y) {\
#if 0
#define SENDMOUSE(time,x,y) {\
InjectABS(time,EV_ABS,ABS_MT_TRACKING_ID,12);\
InjectABS(time,EV_ABS,ABS_MT_POSITION_X,x);\
InjectABS(time,EV_ABS,ABS_MT_POSITION_Y,y);\
InjectABS(time,EV_ABS,SYN_MT_REPORT,0);\
InjectABS(time,EV_SYN,SYN_REPORT,0);}
#else
#define SENDMOUSE(time,x,y) {\
InjectABS(time,EV_ABS,ABS_X,x);\
InjectABS(time,EV_ABS,ABS_Y,y);\
InjectABS(time,EV_SYN,SYN_REPORT,0);}
#else
#define SENDMOUSE(time,x,y) {InjectREL(time,EV_REL,0,x);\
InjectREL(time,EV_REL,1,y);InjectREL(time,EV_SYN,SYN_REPORT,0);}
#endif
static void InjectKey(int type,int code,int value) {
INPUTEVENT i= {0};

View File

@ -129,7 +129,7 @@ INT InputGetDeviceInfo(int device,INPUTDEVICEINFO*devinfo) {
strcpy(devinfo->name,"Touch-Inject");
devinfo->vendor = INJECTDEV_TOUCH>>16;
devinfo->product= INJECTDEV_TOUCH&0xFF;
#if 1
#if 0//case to make injectdevice as single touch
SET_BIT(devinfo->keyBitMask,BTN_TOUCH);
SET_BIT(devinfo->absBitMask,ABS_X);
SET_BIT(devinfo->absBitMask,ABS_Y);

View File

@ -67,8 +67,8 @@ public:
#ifndef DEBUG
#define LOGV(...)
#define LOGD(...)
#define LOGV_IF(x,...)
#define LOGD(...)
#define LOGD_IF(x,...)
#define LOG_DUMP(tag,data,len)
#else

View File

@ -17,7 +17,7 @@ typedef struct{
void*userdata;
GFXRect viewPort;
}MP_PLAYER;
#if 0
static timer_t timerid=0;
static void timer_handler(int signum/*,siginfo_t*, void**/) {
@ -58,7 +58,7 @@ static timer_t initTimer(){
}
return timerid;
}
#endif
HANDLE MPOpen(const char*fname){
MP_PLAYER *mp=(MP_PLAYER*)malloc(sizeof(MP_PLAYER));
memset(mp,0,sizeof(MP_PLAYER));

View File

@ -17,11 +17,11 @@ class VELOCITY:public testing::Test{
TEST_F(VELOCITY,test1){
VelocityTracker*vc =VelocityTracker::obtain();
nsecs_t etime = SystemClock::uptimeMillis();
for(int i=0,y=0;i<10;i++){
MotionEvent*e=MotionEvent::obtain(etime,etime,MotionEvent::ACTION_MOVE,0,y,0);
for(int i=0,x=0,y=0;i<10;i++){
MotionEvent*e=MotionEvent::obtain(etime,etime,MotionEvent::ACTION_MOVE,x,y,0);
vc->addMovement(*e);
etime+=10;
y+=10;
y+=10;x+=6;
}
vc->computeCurrentVelocity(1000,8000.0f);
int velocity=vc->getYVelocity(0);