Merge "Add test to ensure a keyboard with HID usage support is not a stylus" into udc-qpr-dev
diff --git a/include/input/VelocityTracker.h b/include/input/VelocityTracker.h
index da97c3e..4257cb5 100644
--- a/include/input/VelocityTracker.h
+++ b/include/input/VelocityTracker.h
@@ -45,6 +45,7 @@
INT2 = 8,
LEGACY = 9,
MAX = LEGACY,
+ ftl_last = LEGACY,
};
struct Estimator {
@@ -95,8 +96,6 @@
// TODO(b/32830165): support axis-specific strategies.
VelocityTracker(const Strategy strategy = Strategy::DEFAULT);
- ~VelocityTracker();
-
/** Return true if the axis is supported for velocity tracking, false otherwise. */
static bool isAxisSupported(int32_t axis);
diff --git a/libs/input/VelocityTracker.cpp b/libs/input/VelocityTracker.cpp
index 8551e5f..078109a 100644
--- a/libs/input/VelocityTracker.cpp
+++ b/libs/input/VelocityTracker.cpp
@@ -16,7 +16,9 @@
#define LOG_TAG "VelocityTracker"
+#include <android-base/logging.h>
#include <array>
+#include <ftl/enum.h>
#include <inttypes.h>
#include <limits.h>
#include <math.h>
@@ -145,27 +147,19 @@
VelocityTracker::VelocityTracker(const Strategy strategy)
: mLastEventTime(0), mCurrentPointerIdBits(0), mOverrideStrategy(strategy) {}
-VelocityTracker::~VelocityTracker() {
-}
-
bool VelocityTracker::isAxisSupported(int32_t axis) {
return DEFAULT_STRATEGY_BY_AXIS.find(axis) != DEFAULT_STRATEGY_BY_AXIS.end();
}
void VelocityTracker::configureStrategy(int32_t axis) {
const bool isDifferentialAxis = DIFFERENTIAL_AXES.find(axis) != DIFFERENTIAL_AXES.end();
-
- std::unique_ptr<VelocityTrackerStrategy> createdStrategy;
- if (mOverrideStrategy != VelocityTracker::Strategy::DEFAULT) {
- createdStrategy = createStrategy(mOverrideStrategy, /*deltaValues=*/isDifferentialAxis);
+ if (isDifferentialAxis || mOverrideStrategy == VelocityTracker::Strategy::DEFAULT) {
+ // Do not allow overrides of strategies for differential axes, for now.
+ mConfiguredStrategies[axis] = createStrategy(DEFAULT_STRATEGY_BY_AXIS.at(axis),
+ /*deltaValues=*/isDifferentialAxis);
} else {
- createdStrategy = createStrategy(DEFAULT_STRATEGY_BY_AXIS.at(axis),
- /*deltaValues=*/isDifferentialAxis);
+ mConfiguredStrategies[axis] = createStrategy(mOverrideStrategy, /*deltaValues=*/false);
}
-
- LOG_ALWAYS_FATAL_IF(createdStrategy == nullptr,
- "Could not create velocity tracker strategy for axis '%" PRId32 "'!", axis);
- mConfiguredStrategies[axis] = std::move(createdStrategy);
}
std::unique_ptr<VelocityTrackerStrategy> VelocityTracker::createStrategy(
@@ -213,6 +207,9 @@
default:
break;
}
+ LOG(FATAL) << "Invalid strategy: " << ftl::enum_string(strategy)
+ << ", deltaValues = " << deltaValues;
+
return nullptr;
}
diff --git a/libs/input/tests/VelocityTracker_test.cpp b/libs/input/tests/VelocityTracker_test.cpp
index ae72109..73f25cc 100644
--- a/libs/input/tests/VelocityTracker_test.cpp
+++ b/libs/input/tests/VelocityTracker_test.cpp
@@ -282,6 +282,11 @@
const std::vector<std::pair<std::chrono::nanoseconds, float>>& motions,
std::optional<float> targetVelocity) {
checkVelocity(computeVelocity(strategy, motions, AMOTION_EVENT_AXIS_SCROLL), targetVelocity);
+ // The strategy LSQ2 is not compatible with AXIS_SCROLL. In those situations, we should fall
+ // back to a strategy that supports differential axes.
+ checkVelocity(computeVelocity(VelocityTracker::Strategy::LSQ2, motions,
+ AMOTION_EVENT_AXIS_SCROLL),
+ targetVelocity);
}
static void computeAndCheckQuadraticEstimate(const std::vector<PlanarMotionEventEntry>& motions,
diff --git a/services/inputflinger/reader/InputReader.cpp b/services/inputflinger/reader/InputReader.cpp
index 08600b2..7f63355 100644
--- a/services/inputflinger/reader/InputReader.cpp
+++ b/services/inputflinger/reader/InputReader.cpp
@@ -77,7 +77,7 @@
: mContext(this),
mEventHub(eventHub),
mPolicy(policy),
- mQueuedListener(listener),
+ mNextListener(listener),
mGlobalMetaState(AMETA_NONE),
mLedMetaState(AMETA_NONE),
mGeneration(1),
@@ -140,7 +140,7 @@
mReaderIsAliveCondition.notify_all();
if (!events.empty()) {
- notifyArgs += processEventsLocked(events.data(), events.size());
+ mPendingArgs += processEventsLocked(events.data(), events.size());
}
if (mNextTimeout != LLONG_MAX) {
@@ -150,16 +150,18 @@
ALOGD("Timeout expired, latency=%0.3fms", (now - mNextTimeout) * 0.000001f);
}
mNextTimeout = LLONG_MAX;
- notifyArgs += timeoutExpiredLocked(now);
+ mPendingArgs += timeoutExpiredLocked(now);
}
}
if (oldGeneration != mGeneration) {
inputDevicesChanged = true;
inputDevices = getInputDevicesLocked();
- notifyArgs.emplace_back(
+ mPendingArgs.emplace_back(
NotifyInputDevicesChangedArgs{mContext.getNextId(), inputDevices});
}
+
+ std::swap(notifyArgs, mPendingArgs);
} // release lock
// Send out a message that the describes the changed input devices.
@@ -175,8 +177,6 @@
}
}
- notifyAll(std::move(notifyArgs));
-
// Flush queued events out to the listener.
// This must happen outside of the lock because the listener could potentially call
// back into the InputReader's methods, such as getScanCodeState, or become blocked
@@ -184,7 +184,9 @@
// resulting in a deadlock. This situation is actually quite plausible because the
// listener is actually the input dispatcher, which calls into the window manager,
// which occasionally calls into the input reader.
- mQueuedListener.flush();
+ for (const NotifyArgs& args : notifyArgs) {
+ mNextListener.notify(args);
+ }
}
std::list<NotifyArgs> InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
@@ -236,8 +238,8 @@
InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(eventHubId);
std::shared_ptr<InputDevice> device = createDeviceLocked(eventHubId, identifier);
- notifyAll(device->configure(when, mConfig, /*changes=*/{}));
- notifyAll(device->reset(when));
+ mPendingArgs += device->configure(when, mConfig, /*changes=*/{});
+ mPendingArgs += device->reset(when);
if (device->isIgnored()) {
ALOGI("Device added: id=%d, eventHubId=%d, name='%s', descriptor='%s' "
@@ -310,12 +312,10 @@
notifyExternalStylusPresenceChangedLocked();
}
- std::list<NotifyArgs> resetEvents;
if (device->hasEventHubDevices()) {
- resetEvents += device->configure(when, mConfig, /*changes=*/{});
+ mPendingArgs += device->configure(when, mConfig, /*changes=*/{});
}
- resetEvents += device->reset(when);
- notifyAll(std::move(resetEvents));
+ mPendingArgs += device->reset(when);
}
std::shared_ptr<InputDevice> InputReader::createDeviceLocked(
@@ -387,7 +387,7 @@
updateGlobalMetaStateLocked();
// Enqueue configuration changed.
- mQueuedListener.notifyConfigurationChanged({mContext.getNextId(), when});
+ mPendingArgs.emplace_back(NotifyConfigurationChangedArgs{mContext.getNextId(), when});
}
void InputReader::refreshConfigurationLocked(ConfigurationChanges changes) {
@@ -409,7 +409,7 @@
} else {
for (auto& devicePair : mDevices) {
std::shared_ptr<InputDevice>& device = devicePair.second;
- notifyAll(device->configure(now, mConfig, changes));
+ mPendingArgs += device->configure(now, mConfig, changes);
}
}
@@ -419,18 +419,13 @@
"There was no change in the pointer capture state.");
} else {
mCurrentPointerCaptureRequest = mConfig.pointerCaptureRequest;
- mQueuedListener.notifyPointerCaptureChanged(
- {mContext.getNextId(), now, mCurrentPointerCaptureRequest});
+ mPendingArgs.emplace_back(
+ NotifyPointerCaptureChangedArgs{mContext.getNextId(), now,
+ mCurrentPointerCaptureRequest});
}
}
}
-void InputReader::notifyAll(std::list<NotifyArgs>&& argsList) {
- for (const NotifyArgs& args : argsList) {
- mQueuedListener.notify(args);
- }
-}
-
void InputReader::updateGlobalMetaStateLocked() {
mGlobalMetaState = 0;
@@ -690,7 +685,7 @@
InputDevice* device = findInputDeviceLocked(deviceId);
if (device) {
- notifyAll(device->vibrate(sequence, repeat, token));
+ mPendingArgs += device->vibrate(sequence, repeat, token);
}
}
@@ -699,7 +694,7 @@
InputDevice* device = findInputDeviceLocked(deviceId);
if (device) {
- notifyAll(device->cancelVibrate(token));
+ mPendingArgs += device->cancelVibrate(token);
}
}
diff --git a/services/inputflinger/reader/include/InputReader.h b/services/inputflinger/reader/include/InputReader.h
index 01ec7c1..e21715e 100644
--- a/services/inputflinger/reader/include/InputReader.h
+++ b/services/inputflinger/reader/include/InputReader.h
@@ -174,7 +174,14 @@
// in parallel to passing it to the InputReader.
std::shared_ptr<EventHubInterface> mEventHub;
sp<InputReaderPolicyInterface> mPolicy;
- QueuedInputListener mQueuedListener;
+
+ // The next stage that should receive the events generated inside InputReader.
+ InputListenerInterface& mNextListener;
+ // As various events are generated inside InputReader, they are stored inside this list. The
+ // list can only be accessed with the lock, so the events inside it are well-ordered.
+ // Once the reader is done working, these events will be swapped into a temporary storage and
+ // sent to the 'mNextListener' without holding the lock.
+ std::list<NotifyArgs> mPendingArgs GUARDED_BY(mLock);
InputReaderConfiguration mConfig GUARDED_BY(mLock);
@@ -242,8 +249,6 @@
ConfigurationChanges mConfigurationChangesToRefresh GUARDED_BY(mLock);
void refreshConfigurationLocked(ConfigurationChanges changes) REQUIRES(mLock);
- void notifyAll(std::list<NotifyArgs>&& argsList);
-
PointerCaptureRequest mCurrentPointerCaptureRequest GUARDED_BY(mLock);
// state queries
diff --git a/services/surfaceflinger/ScreenCaptureOutput.cpp b/services/surfaceflinger/ScreenCaptureOutput.cpp
index 0103843..ef9b457 100644
--- a/services/surfaceflinger/ScreenCaptureOutput.cpp
+++ b/services/surfaceflinger/ScreenCaptureOutput.cpp
@@ -45,10 +45,9 @@
std::shared_ptr<ScreenCaptureOutput> createScreenCaptureOutput(ScreenCaptureOutputArgs args) {
std::shared_ptr<ScreenCaptureOutput> output = compositionengine::impl::createOutputTemplated<
ScreenCaptureOutput, compositionengine::CompositionEngine, const RenderArea&,
- const compositionengine::Output::ColorProfile&, bool>(args.compositionEngine,
- args.renderArea,
- args.colorProfile,
- args.regionSampling);
+ const compositionengine::Output::ColorProfile&,
+ bool>(args.compositionEngine, args.renderArea, args.colorProfile, args.regionSampling,
+ args.dimInGammaSpaceForEnhancedScreenshots);
output->editState().isSecure = args.renderArea.isSecure();
output->setCompositionEnabled(true);
output->setLayerFilter({args.layerStack});
@@ -81,8 +80,11 @@
ScreenCaptureOutput::ScreenCaptureOutput(
const RenderArea& renderArea, const compositionengine::Output::ColorProfile& colorProfile,
- bool regionSampling)
- : mRenderArea(renderArea), mColorProfile(colorProfile), mRegionSampling(regionSampling) {}
+ bool regionSampling, bool dimInGammaSpaceForEnhancedScreenshots)
+ : mRenderArea(renderArea),
+ mColorProfile(colorProfile),
+ mRegionSampling(regionSampling),
+ mDimInGammaSpaceForEnhancedScreenshots(dimInGammaSpaceForEnhancedScreenshots) {}
void ScreenCaptureOutput::updateColorProfile(const compositionengine::CompositionRefreshArgs&) {
auto& outputState = editState();
@@ -95,6 +97,14 @@
auto clientCompositionDisplay =
compositionengine::impl::Output::generateClientCompositionDisplaySettings();
clientCompositionDisplay.clip = mRenderArea.getSourceCrop();
+
+ auto renderIntent = static_cast<ui::RenderIntent>(clientCompositionDisplay.renderIntent);
+ if (mDimInGammaSpaceForEnhancedScreenshots && renderIntent != ui::RenderIntent::COLORIMETRIC &&
+ renderIntent != ui::RenderIntent::TONE_MAP_COLORIMETRIC) {
+ clientCompositionDisplay.dimmingStage =
+ aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF;
+ }
+
return clientCompositionDisplay;
}
diff --git a/services/surfaceflinger/ScreenCaptureOutput.h b/services/surfaceflinger/ScreenCaptureOutput.h
index 159c2bf..fc095de 100644
--- a/services/surfaceflinger/ScreenCaptureOutput.h
+++ b/services/surfaceflinger/ScreenCaptureOutput.h
@@ -37,6 +37,7 @@
float targetBrightness;
bool regionSampling;
bool treat170mAsSrgb;
+ bool dimInGammaSpaceForEnhancedScreenshots;
};
// ScreenCaptureOutput is used to compose a set of layers into a preallocated buffer.
@@ -47,7 +48,7 @@
public:
ScreenCaptureOutput(const RenderArea& renderArea,
const compositionengine::Output::ColorProfile& colorProfile,
- bool regionSampling);
+ bool regionSampling, bool dimInGammaSpaceForEnhancedScreenshots);
void updateColorProfile(const compositionengine::CompositionRefreshArgs&) override;
@@ -63,6 +64,7 @@
const RenderArea& mRenderArea;
const compositionengine::Output::ColorProfile& mColorProfile;
const bool mRegionSampling;
+ const bool mDimInGammaSpaceForEnhancedScreenshots;
};
std::shared_ptr<ScreenCaptureOutput> createScreenCaptureOutput(ScreenCaptureOutputArgs);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 39ea248..f118d46 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -451,6 +451,9 @@
property_get("debug.sf.treat_170m_as_sRGB", value, "0");
mTreat170mAsSrgb = atoi(value);
+ property_get("debug.sf.dim_in_gamma_in_enhanced_screenshots", value, 0);
+ mDimInGammaSpaceForEnhancedScreenshots = atoi(value);
+
mIgnoreHwcPhysicalDisplayOrientation =
base::GetBoolProperty("debug.sf.ignore_hwc_physical_display_orientation"s, false);
@@ -7480,7 +7483,9 @@
.displayBrightnessNits = displayBrightnessNits,
.targetBrightness = targetBrightness,
.regionSampling = regionSampling,
- .treat170mAsSrgb = mTreat170mAsSrgb});
+ .treat170mAsSrgb = mTreat170mAsSrgb,
+ .dimInGammaSpaceForEnhancedScreenshots =
+ mDimInGammaSpaceForEnhancedScreenshots});
const float colorSaturation = grayscale ? 0 : 1;
compositionengine::CompositionRefreshArgs refreshArgs{
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index e3e72ed..f1989db 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -323,6 +323,11 @@
// on this behavior to increase contrast for some media sources.
bool mTreat170mAsSrgb = false;
+ // If true, then screenshots with an enhanced render intent will dim in gamma space.
+ // The purpose is to ensure that screenshots appear correct during system animations for devices
+ // that require that dimming must occur in gamma space.
+ bool mDimInGammaSpaceForEnhancedScreenshots = false;
+
// Allows to ignore physical orientation provided through hwc API in favour of
// 'ro.surface_flinger.primary_display_orientation'.
// TODO(b/246793311): Clean up a temporary property