Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit df79be8a authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 12477291 from 9a43d3f7 to 25Q1-release

Change-Id: Id03d9d8792f55fb7b56134d20b5ac8b75c5fd847
parents c364f9df 9a43d3f7
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
@@ -99,6 +99,17 @@ private:
     */
    RingBuffer<Sample> mLatestSamples{/*capacity=*/2};

    /**
     * Latest sample in mLatestSamples after resampling motion event. Used to compare if a pointer
     * does not move between samples.
     */
    std::optional<Sample> mLastRealSample;

    /**
     * Latest prediction. Used to overwrite motion event samples if a set of conditions is met.
     */
    std::optional<Sample> mPreviousPrediction;

    /**
     * Adds up to mLatestSamples.capacity() of motionEvent's latest samples to mLatestSamples. If
     * motionEvent has fewer samples than mLatestSamples.capacity(), then the available samples are
@@ -144,6 +155,23 @@ private:
     */
    std::optional<Sample> attemptExtrapolation(std::chrono::nanoseconds resampleTime) const;

    /**
     * Iterates through motion event samples, and calls overwriteStillPointers on each sample.
     */
    void overwriteMotionEventSamples(MotionEvent& motionEvent) const;

    /**
     * Overwrites with resampled data the pointer coordinates that did not move between motion event
     * samples, that is, both x and y values are identical to mLastRealSample.
     */
    void overwriteStillPointers(MotionEvent& motionEvent, size_t sampleIndex) const;

    /**
     * Overwrites the pointer coordinates of a sample with event time older than
     * that of mPreviousPrediction.
     */
    void overwriteOldPointers(MotionEvent& motionEvent, size_t sampleIndex) const;

    inline static void addSampleToMotionEvent(const Sample& sample, MotionEvent& motionEvent);
};
} // namespace android
+3 −5
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@
#include <android/binder_auto_utils.h>
#include <android/binder_ibinder.h>

#if defined(__ANDROID_VENDOR__)
#if defined(__ANDROID_VENDOR_API__)
#include <android/llndk-versioning.h>
#elif !defined(API_LEVEL_AT_LEAST)
#if defined(__BIONIC__)
@@ -39,7 +39,7 @@
#else
#define API_LEVEL_AT_LEAST(sdk_api_level, vendor_api_level) (true)
#endif  // __BIONIC__
#endif  // __ANDROID_VENDOR__
#endif  // __ANDROID_VENDOR_API__

#if __has_include(<android/binder_shell.h>)
#include <android/binder_shell.h>
@@ -297,9 +297,7 @@ AIBinder_Class* ICInterface::defineClass(const char* interfaceDescriptor,
    }
#endif

// TODO(b/368559337): fix versioning on product partition
#if !defined(__ANDROID_PRODUCT__) && \
        (defined(__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__) || __ANDROID_API__ >= 36)
#if defined(__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__) || __ANDROID_API__ >= 36
    if API_LEVEL_AT_LEAST (36, 202504) {
        if (codeToFunction != nullptr) {
            AIBinder_Class_setTransactionCodeToFunctionNameMap(clazz, codeToFunction,
+3 −3
Original line number Diff line number Diff line
@@ -22,8 +22,8 @@
#include <set>
#include <sstream>

// Include llndk-versioning.h only for vendor build as it is not available for NDK headers.
#if defined(__ANDROID_VENDOR__)
// Include llndk-versioning.h only for non-system build as it is not available for NDK headers.
#if defined(__ANDROID_VENDOR_API__)
#include <android/llndk-versioning.h>
#elif !defined(API_LEVEL_AT_LEAST)
#if defined(__BIONIC__)
@@ -32,7 +32,7 @@
#else
#define API_LEVEL_AT_LEAST(sdk_api_level, vendor_api_level) (true)
#endif  // __BIONIC__
#endif  // __ANDROID_VENDOR__
#endif  // __ANDROID_VENDOR_API__

namespace aidl::android::os {

+8 −0
Original line number Diff line number Diff line
@@ -108,6 +108,14 @@ flag {
  is_fixed_read_only: true
} # wb_libcameraservice

flag {
  name: "wb_unlimited_slots"
  namespace: "core_graphics"
  description: "Adds APIs and updates the implementation of bufferqueues to have a user-defined slot count."
  bug: "341359814"
  is_fixed_read_only: true
} # wb_unlimited_slots

flag {
  name: "bq_producer_throttles_only_async_mode"
  namespace: "core_graphics"
+82 −9
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@

#include <algorithm>
#include <chrono>
#include <ostream>

#include <android-base/logging.h>
#include <android-base/properties.h>
@@ -26,10 +27,7 @@
#include <input/Resampler.h>
#include <utils/Timers.h>

using std::chrono::nanoseconds;

namespace android {

namespace {

const bool IS_DEBUGGABLE_BUILD =
@@ -49,6 +47,8 @@ bool debugResampling() {
    return __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "Resampling", ANDROID_LOG_INFO);
}

using std::chrono::nanoseconds;

constexpr std::chrono::milliseconds RESAMPLE_LATENCY{5};

constexpr std::chrono::milliseconds RESAMPLE_MIN_DELTA{2};
@@ -75,6 +75,31 @@ PointerCoords calculateResampledCoords(const PointerCoords& a, const PointerCoor
    resampledCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, lerp(a.getY(), b.getY(), alpha));
    return resampledCoords;
}

bool equalXY(const PointerCoords& a, const PointerCoords& b) {
    return (a.getX() == b.getX()) && (a.getY() == b.getY());
}

void setMotionEventPointerCoords(MotionEvent& motionEvent, size_t sampleIndex, size_t pointerIndex,
                                 const PointerCoords& pointerCoords) {
    // Ideally, we should not cast away const. In this particular case, it's safe to cast away const
    // and dereference getHistoricalRawPointerCoords returned pointer because motionEvent is a
    // nonconst reference to a MotionEvent object, so mutating the object should not be undefined
    // behavior; moreover, the invoked method guarantees to return a valid pointer. Otherwise, it
    // fatally logs. Alternatively, we could've created a new MotionEvent from scratch, but this
    // approach is simpler and more efficient.
    PointerCoords& motionEventCoords = const_cast<PointerCoords&>(
            *(motionEvent.getHistoricalRawPointerCoords(pointerIndex, sampleIndex)));
    motionEventCoords.setAxisValue(AMOTION_EVENT_AXIS_X, pointerCoords.getX());
    motionEventCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, pointerCoords.getY());
    motionEventCoords.isResampled = pointerCoords.isResampled;
}

std::ostream& operator<<(std::ostream& os, const PointerCoords& pointerCoords) {
    os << "(" << pointerCoords.getX() << ", " << pointerCoords.getY() << ")";
    return os;
}

} // namespace

void LegacyResampler::updateLatestSamples(const MotionEvent& motionEvent) {
@@ -85,12 +110,9 @@ void LegacyResampler::updateLatestSamples(const MotionEvent& motionEvent) {
        std::vector<Pointer> pointers;
        const size_t numPointers = motionEvent.getPointerCount();
        for (size_t pointerIndex = 0; pointerIndex < numPointers; ++pointerIndex) {
            // getSamplePointerCoords is the vector representation of a getHistorySize by
            // getPointerCount matrix.
            const PointerCoords& pointerCoords =
                    motionEvent.getSamplePointerCoords()[sampleIndex * numPointers + pointerIndex];
            pointers.push_back(
                    Pointer{*motionEvent.getPointerProperties(pointerIndex), pointerCoords});
            pointers.push_back(Pointer{*(motionEvent.getPointerProperties(pointerIndex)),
                                       *(motionEvent.getHistoricalRawPointerCoords(pointerIndex,
                                                                                   sampleIndex))});
        }
        mLatestSamples.pushBack(
                Sample{nanoseconds{motionEvent.getHistoricalEventTime(sampleIndex)}, pointers});
@@ -245,6 +267,47 @@ nanoseconds LegacyResampler::getResampleLatency() const {
    return RESAMPLE_LATENCY;
}

void LegacyResampler::overwriteMotionEventSamples(MotionEvent& motionEvent) const {
    const size_t numSamples = motionEvent.getHistorySize() + 1;
    for (size_t sampleIndex = 0; sampleIndex < numSamples; ++sampleIndex) {
        overwriteStillPointers(motionEvent, sampleIndex);
        overwriteOldPointers(motionEvent, sampleIndex);
    }
}

void LegacyResampler::overwriteStillPointers(MotionEvent& motionEvent, size_t sampleIndex) const {
    for (size_t pointerIndex = 0; pointerIndex < motionEvent.getPointerCount(); ++pointerIndex) {
        const PointerCoords& pointerCoords =
                *(motionEvent.getHistoricalRawPointerCoords(pointerIndex, sampleIndex));
        if (equalXY(mLastRealSample->pointers[pointerIndex].coords, pointerCoords)) {
            LOG_IF(INFO, debugResampling())
                    << "Pointer ID: " << motionEvent.getPointerId(pointerIndex)
                    << " did not move. Overwriting its coordinates from " << pointerCoords << " to "
                    << mLastRealSample->pointers[pointerIndex].coords;
            setMotionEventPointerCoords(motionEvent, sampleIndex, pointerIndex,
                                        mPreviousPrediction->pointers[pointerIndex].coords);
        }
    }
}

void LegacyResampler::overwriteOldPointers(MotionEvent& motionEvent, size_t sampleIndex) const {
    if (!mPreviousPrediction.has_value()) {
        return;
    }
    if (nanoseconds{motionEvent.getHistoricalEventTime(sampleIndex)} <
        mPreviousPrediction->eventTime) {
        LOG_IF(INFO, debugResampling())
                << "Motion event sample older than predicted sample. Overwriting event time from "
                << motionEvent.getHistoricalEventTime(sampleIndex) << "ns to "
                << mPreviousPrediction->eventTime.count() << "ns.";
        for (size_t pointerIndex = 0; pointerIndex < motionEvent.getPointerCount();
             ++pointerIndex) {
            setMotionEventPointerCoords(motionEvent, sampleIndex, pointerIndex,
                                        mPreviousPrediction->pointers[pointerIndex].coords);
        }
    }
}

void LegacyResampler::resampleMotionEvent(nanoseconds frameTime, MotionEvent& motionEvent,
                                          const InputMessage* futureSample) {
    const nanoseconds resampleTime = frameTime - RESAMPLE_LATENCY;
@@ -261,6 +324,16 @@ void LegacyResampler::resampleMotionEvent(nanoseconds frameTime, MotionEvent& mo
            : (attemptExtrapolation(resampleTime));
    if (sample.has_value()) {
        addSampleToMotionEvent(*sample, motionEvent);
        if (mPreviousPrediction.has_value()) {
            overwriteMotionEventSamples(motionEvent);
        }
        // mPreviousPrediction is only updated whenever extrapolation occurs because extrapolation
        // is about predicting upcoming scenarios.
        if (futureSample == nullptr) {
            mPreviousPrediction = sample;
        }
    }
    mLastRealSample = *(mLatestSamples.end() - 1);
}

} // namespace android
Loading