Merge "FrameRateCategory::NoPreference votes Min" into main
diff --git a/include/input/TraceTools.h b/include/input/TraceTools.h
index 70b23c5..81fc7af 100644
--- a/include/input/TraceTools.h
+++ b/include/input/TraceTools.h
@@ -19,7 +19,11 @@
#include <utils/Trace.h>
#include <optional>
-#define ATRACE_NAME_IF(condition, messageProvider) \
- const auto _trace_token = condition \
- ? std::make_optional<android::ScopedTrace>(ATRACE_TAG, messageProvider().c_str()) \
+// A macro for tracing when the given condition is true.
+// This macro relies on the fact that only one branch of the ternary operator is evaluated. That
+// means if `message` is an expression that evaluates to a std::string value, the value will
+// not be computed unless the condition is true.
+#define ATRACE_NAME_IF(condition, message) \
+ const auto _trace_token = condition \
+ ? std::make_optional<android::ScopedTrace>(ATRACE_TAG, (message).c_str()) \
: std::nullopt
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index 2cf5123..8c36058 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -267,8 +267,8 @@
layer_state_t::eBackgroundBlurRadiusChanged | layer_state_t::eBlurRegionsChanged |
layer_state_t::eColorTransformChanged | layer_state_t::eCornerRadiusChanged |
layer_state_t::eFlagsChanged | layer_state_t::eTrustedOverlayChanged |
- layer_state_t::eFrameRateChanged | layer_state_t::eFrameRateSelectionPriority |
- layer_state_t::eFixedTransformHintChanged;
+ layer_state_t::eFrameRateChanged | layer_state_t::eFrameRateCategoryChanged |
+ layer_state_t::eFrameRateSelectionPriority | layer_state_t::eFixedTransformHintChanged;
// Changes affecting data sent to input.
static constexpr uint64_t INPUT_CHANGES = layer_state_t::eInputInfoChanged |
diff --git a/libs/input/Android.bp b/libs/input/Android.bp
index 8656b26..36a01d3 100644
--- a/libs/input/Android.bp
+++ b/libs/input/Android.bp
@@ -33,6 +33,21 @@
],
}
+/////////////////////////////////////////////////
+// flags
+/////////////////////////////////////////////////
+aconfig_declarations {
+ name: "aconfig_input_flags",
+ package: "com.android.input.flags",
+ srcs: ["input_flags.aconfig"],
+}
+
+cc_aconfig_library {
+ name: "aconfig_input_flags_c_lib",
+ aconfig_declarations: "aconfig_input_flags",
+ host_supported: true,
+}
+
aidl_interface {
name: "inputconstants",
host_supported: true,
@@ -176,6 +191,7 @@
"libtinyxml2",
"libutils",
"libvintf",
+ "server_configurable_flags",
],
ldflags: [
@@ -196,6 +212,7 @@
],
whole_static_libs: [
+ "aconfig_input_flags_c_lib",
"libinput_rust_ffi",
],
diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp
index 5fec1a9..1f14396 100644
--- a/libs/input/InputTransport.cpp
+++ b/libs/input/InputTransport.cpp
@@ -23,9 +23,12 @@
#include <log/log.h>
#include <utils/Trace.h>
+#include <com_android_input_flags.h>
#include <input/InputTransport.h>
#include <input/TraceTools.h>
+namespace input_flags = com::android::input::flags;
+
namespace {
/**
@@ -139,7 +142,8 @@
* Enable this via "adb shell setprop log.tag.InputTransportVerifyEvents DEBUG"
*/
static bool verifyEvents() {
- return __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "VerifyEvents", ANDROID_LOG_INFO);
+ return input_flags::enable_outbound_event_verification() ||
+ __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "VerifyEvents", ANDROID_LOG_INFO);
}
template<typename T>
@@ -433,10 +437,10 @@
}
status_t InputChannel::sendMessage(const InputMessage* msg) {
- ATRACE_NAME_IF(ATRACE_ENABLED(), [&]() {
- return StringPrintf("sendMessage(inputChannel=%s, seq=0x%" PRIx32 ", type=0x%" PRIx32 ")",
- mName.c_str(), msg->header.seq, msg->header.type);
- });
+ ATRACE_NAME_IF(ATRACE_ENABLED(),
+ StringPrintf("sendMessage(inputChannel=%s, seq=0x%" PRIx32 ", type=0x%" PRIx32
+ ")",
+ mName.c_str(), msg->header.seq, msg->header.type));
const size_t msgLength = msg->size();
InputMessage cleanMsg;
msg->getSanitizedCopy(&cleanMsg);
@@ -472,9 +476,8 @@
}
status_t InputChannel::receiveMessage(InputMessage* msg) {
- ATRACE_NAME_IF(ATRACE_ENABLED(), [&]() {
- return StringPrintf("receiveMessage(inputChannel=%s)", mName.c_str());
- });
+ ATRACE_NAME_IF(ATRACE_ENABLED(),
+ StringPrintf("receiveMessage(inputChannel=%s)", mName.c_str()));
ssize_t nRead;
do {
nRead = ::recv(getFd(), msg, sizeof(InputMessage), MSG_DONTWAIT);
@@ -580,11 +583,10 @@
int32_t flags, int32_t keyCode, int32_t scanCode,
int32_t metaState, int32_t repeatCount, nsecs_t downTime,
nsecs_t eventTime) {
- ATRACE_NAME_IF(ATRACE_ENABLED(), [&]() {
- return StringPrintf("publishKeyEvent(inputChannel=%s, action=%s, keyCode=%s)",
- mChannel->getName().c_str(), KeyEvent::actionToString(action),
- KeyEvent::getLabel(keyCode));
- });
+ ATRACE_NAME_IF(ATRACE_ENABLED(),
+ StringPrintf("publishKeyEvent(inputChannel=%s, action=%s, keyCode=%s)",
+ mChannel->getName().c_str(), KeyEvent::actionToString(action),
+ KeyEvent::getLabel(keyCode)));
ALOGD_IF(debugTransportPublisher(),
"channel '%s' publisher ~ %s: seq=%u, id=%d, deviceId=%d, source=%s, "
"action=%s, flags=0x%x, keyCode=%s, scanCode=%d, metaState=0x%x, repeatCount=%d,"
@@ -626,11 +628,10 @@
const ui::Transform& rawTransform, nsecs_t downTime, nsecs_t eventTime,
uint32_t pointerCount, const PointerProperties* pointerProperties,
const PointerCoords* pointerCoords) {
- ATRACE_NAME_IF(ATRACE_ENABLED(), [&]() {
- return StringPrintf("publishMotionEvent(inputChannel=%s, action=%s)",
- mChannel->getName().c_str(),
- MotionEvent::actionToString(action).c_str());
- });
+ ATRACE_NAME_IF(ATRACE_ENABLED(),
+ StringPrintf("publishMotionEvent(inputChannel=%s, action=%s)",
+ mChannel->getName().c_str(),
+ MotionEvent::actionToString(action).c_str()));
if (verifyEvents()) {
Result<void> result =
mInputVerifier.processMovement(deviceId, action, pointerCount, pointerProperties,
@@ -709,10 +710,9 @@
}
status_t InputPublisher::publishFocusEvent(uint32_t seq, int32_t eventId, bool hasFocus) {
- ATRACE_NAME_IF(ATRACE_ENABLED(), [&]() {
- return StringPrintf("publishFocusEvent(inputChannel=%s, hasFocus=%s)",
- mChannel->getName().c_str(), toString(hasFocus));
- });
+ ATRACE_NAME_IF(ATRACE_ENABLED(),
+ StringPrintf("publishFocusEvent(inputChannel=%s, hasFocus=%s)",
+ mChannel->getName().c_str(), toString(hasFocus)));
ALOGD_IF(debugTransportPublisher(), "channel '%s' publisher ~ %s: seq=%u, id=%d, hasFocus=%s",
mChannel->getName().c_str(), __func__, seq, eventId, toString(hasFocus));
@@ -726,10 +726,9 @@
status_t InputPublisher::publishCaptureEvent(uint32_t seq, int32_t eventId,
bool pointerCaptureEnabled) {
- ATRACE_NAME_IF(ATRACE_ENABLED(), [&]() {
- return StringPrintf("publishCaptureEvent(inputChannel=%s, pointerCaptureEnabled=%s)",
- mChannel->getName().c_str(), toString(pointerCaptureEnabled));
- });
+ ATRACE_NAME_IF(ATRACE_ENABLED(),
+ StringPrintf("publishCaptureEvent(inputChannel=%s, pointerCaptureEnabled=%s)",
+ mChannel->getName().c_str(), toString(pointerCaptureEnabled)));
ALOGD_IF(debugTransportPublisher(),
"channel '%s' publisher ~ %s: seq=%u, id=%d, pointerCaptureEnabled=%s",
mChannel->getName().c_str(), __func__, seq, eventId, toString(pointerCaptureEnabled));
@@ -744,10 +743,9 @@
status_t InputPublisher::publishDragEvent(uint32_t seq, int32_t eventId, float x, float y,
bool isExiting) {
- ATRACE_NAME_IF(ATRACE_ENABLED(), [&]() {
- return StringPrintf("publishDragEvent(inputChannel=%s, x=%f, y=%f, isExiting=%s)",
- mChannel->getName().c_str(), x, y, toString(isExiting));
- });
+ ATRACE_NAME_IF(ATRACE_ENABLED(),
+ StringPrintf("publishDragEvent(inputChannel=%s, x=%f, y=%f, isExiting=%s)",
+ mChannel->getName().c_str(), x, y, toString(isExiting)));
ALOGD_IF(debugTransportPublisher(),
"channel '%s' publisher ~ %s: seq=%u, id=%d, x=%f, y=%f, isExiting=%s",
mChannel->getName().c_str(), __func__, seq, eventId, x, y, toString(isExiting));
@@ -763,10 +761,9 @@
}
status_t InputPublisher::publishTouchModeEvent(uint32_t seq, int32_t eventId, bool isInTouchMode) {
- ATRACE_NAME_IF(ATRACE_ENABLED(), [&]() {
- return StringPrintf("publishTouchModeEvent(inputChannel=%s, isInTouchMode=%s)",
- mChannel->getName().c_str(), toString(isInTouchMode));
- });
+ ATRACE_NAME_IF(ATRACE_ENABLED(),
+ StringPrintf("publishTouchModeEvent(inputChannel=%s, isInTouchMode=%s)",
+ mChannel->getName().c_str(), toString(isInTouchMode)));
ALOGD_IF(debugTransportPublisher(),
"channel '%s' publisher ~ %s: seq=%u, id=%d, isInTouchMode=%s",
mChannel->getName().c_str(), __func__, seq, eventId, toString(isInTouchMode));
diff --git a/libs/input/input_flags.aconfig b/libs/input/input_flags.aconfig
new file mode 100644
index 0000000..1f29a00
--- /dev/null
+++ b/libs/input/input_flags.aconfig
@@ -0,0 +1,15 @@
+package: "com.android.input.flags"
+
+flag {
+ name: "enable_outbound_event_verification"
+ namespace: "input"
+ description: "Set to true to enable crashing whenever bad outbound events are detected inside InputTransport"
+ bug: "271455682"
+}
+
+flag {
+ name: "enable_inbound_event_verification"
+ namespace: "input"
+ description: "Set to true to enable crashing whenever bad inbound events are going into InputDispatcher"
+ bug: "271455682"
+}
diff --git a/libs/input/tests/Android.bp b/libs/input/tests/Android.bp
index e7224ff..138898f 100644
--- a/libs/input/tests/Android.bp
+++ b/libs/input/tests/Android.bp
@@ -62,6 +62,7 @@
"libtinyxml2",
"libutils",
"libvintf",
+ "server_configurable_flags",
],
data: [
"data/*",
diff --git a/services/inputflinger/InputListener.cpp b/services/inputflinger/InputListener.cpp
index d319d6d..1f17c16 100644
--- a/services/inputflinger/InputListener.cpp
+++ b/services/inputflinger/InputListener.cpp
@@ -114,73 +114,64 @@
void TracedInputListener::notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) {
constexpr static auto& fnName = __func__;
- ATRACE_NAME_IF(ATRACE_ENABLED(), [&]() {
- return StringPrintf("%s::%s(id=0x%" PRIx32 ")", mName, fnName, args.id);
- });
+ ATRACE_NAME_IF(ATRACE_ENABLED(),
+ StringPrintf("%s::%s(id=0x%" PRIx32 ")", mName, fnName, args.id));
mInnerListener.notify(args);
}
void TracedInputListener::notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) {
constexpr static auto& fnName = __func__;
- ATRACE_NAME_IF(ATRACE_ENABLED(), [&]() {
- return StringPrintf("%s::%s(id=0x%" PRIx32 ")", mName, fnName, args.id);
- });
+ ATRACE_NAME_IF(ATRACE_ENABLED(),
+ StringPrintf("%s::%s(id=0x%" PRIx32 ")", mName, fnName, args.id));
mInnerListener.notify(args);
}
void TracedInputListener::notifyKey(const NotifyKeyArgs& args) {
constexpr static auto& fnName = __func__;
- ATRACE_NAME_IF(ATRACE_ENABLED(), [&]() {
- return StringPrintf("%s::%s(id=0x%" PRIx32 ")", mName, fnName, args.id);
- });
+ ATRACE_NAME_IF(ATRACE_ENABLED(),
+ StringPrintf("%s::%s(id=0x%" PRIx32 ")", mName, fnName, args.id));
mInnerListener.notify(args);
}
void TracedInputListener::notifyMotion(const NotifyMotionArgs& args) {
constexpr static auto& fnName = __func__;
- ATRACE_NAME_IF(ATRACE_ENABLED(), [&]() {
- return StringPrintf("%s::%s(id=0x%" PRIx32 ")", mName, fnName, args.id);
- });
+ ATRACE_NAME_IF(ATRACE_ENABLED(),
+ StringPrintf("%s::%s(id=0x%" PRIx32 ")", mName, fnName, args.id));
mInnerListener.notify(args);
}
void TracedInputListener::notifySwitch(const NotifySwitchArgs& args) {
constexpr static auto& fnName = __func__;
- ATRACE_NAME_IF(ATRACE_ENABLED(), [&]() {
- return StringPrintf("%s::%s(id=0x%" PRIx32 ")", mName, fnName, args.id);
- });
+ ATRACE_NAME_IF(ATRACE_ENABLED(),
+ StringPrintf("%s::%s(id=0x%" PRIx32 ")", mName, fnName, args.id));
mInnerListener.notify(args);
}
void TracedInputListener::notifySensor(const NotifySensorArgs& args) {
constexpr static auto& fnName = __func__;
- ATRACE_NAME_IF(ATRACE_ENABLED(), [&]() {
- return StringPrintf("%s::%s(id=0x%" PRIx32 ")", mName, fnName, args.id);
- });
+ ATRACE_NAME_IF(ATRACE_ENABLED(),
+ StringPrintf("%s::%s(id=0x%" PRIx32 ")", mName, fnName, args.id));
mInnerListener.notify(args);
}
void TracedInputListener::notifyVibratorState(const NotifyVibratorStateArgs& args) {
constexpr static auto& fnName = __func__;
- ATRACE_NAME_IF(ATRACE_ENABLED(), [&]() {
- return StringPrintf("%s::%s(id=0x%" PRIx32 ")", mName, fnName, args.id);
- });
+ ATRACE_NAME_IF(ATRACE_ENABLED(),
+ StringPrintf("%s::%s(id=0x%" PRIx32 ")", mName, fnName, args.id));
mInnerListener.notify(args);
}
void TracedInputListener::notifyDeviceReset(const NotifyDeviceResetArgs& args) {
constexpr static auto& fnName = __func__;
- ATRACE_NAME_IF(ATRACE_ENABLED(), [&]() {
- return StringPrintf("%s::%s(id=0x%" PRIx32 ")", mName, fnName, args.id);
- });
+ ATRACE_NAME_IF(ATRACE_ENABLED(),
+ StringPrintf("%s::%s(id=0x%" PRIx32 ")", mName, fnName, args.id));
mInnerListener.notify(args);
}
void TracedInputListener::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs& args) {
constexpr static auto& fnName = __func__;
- ATRACE_NAME_IF(ATRACE_ENABLED(), [&]() {
- return StringPrintf("%s::%s(id=0x%" PRIx32 ")", mName, fnName, args.id);
- });
+ ATRACE_NAME_IF(ATRACE_ENABLED(),
+ StringPrintf("%s::%s(id=0x%" PRIx32 ")", mName, fnName, args.id));
mInnerListener.notify(args);
}
diff --git a/services/inputflinger/dispatcher/DebugConfig.h b/services/inputflinger/dispatcher/DebugConfig.h
index 7a41d68..c7d98ab 100644
--- a/services/inputflinger/dispatcher/DebugConfig.h
+++ b/services/inputflinger/dispatcher/DebugConfig.h
@@ -19,6 +19,9 @@
#define LOG_TAG "InputDispatcher"
#include <android-base/logging.h>
+#include <com_android_input_flags.h>
+
+namespace input_flags = com::android::input::flags;
namespace android::inputdispatcher {
@@ -102,7 +105,7 @@
* Crash if a bad stream from InputListener is detected.
* Enable this via "adb shell setprop log.tag.InputDispatcherVerifyEvents DEBUG" (requires restart)
*/
-const bool DEBUG_VERIFY_EVENTS =
+const bool DEBUG_VERIFY_EVENTS = input_flags::enable_inbound_event_verification() ||
android::base::ShouldLog(android::base::LogSeverity::DEBUG, LOG_TAG "VerifyEvents");
} // namespace android::inputdispatcher
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 8b7a99b..d98641e 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -3183,10 +3183,9 @@
const std::shared_ptr<Connection>& connection,
std::shared_ptr<EventEntry> eventEntry,
const InputTarget& inputTarget) {
- ATRACE_NAME_IF(ATRACE_ENABLED(), [&]() {
- return StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
- connection->getInputChannelName().c_str(), eventEntry->id);
- });
+ ATRACE_NAME_IF(ATRACE_ENABLED(),
+ StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
+ connection->getInputChannelName().c_str(), eventEntry->id));
if (DEBUG_DISPATCH_CYCLE) {
ALOGD("channel '%s' ~ prepareDispatchCycle - flags=%s, "
"globalScaleFactor=%f, pointerIds=%s %s",
@@ -3251,10 +3250,9 @@
const std::shared_ptr<Connection>& connection,
std::shared_ptr<EventEntry> eventEntry,
const InputTarget& inputTarget) {
- ATRACE_NAME_IF(ATRACE_ENABLED(), [&]() {
- return StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
- connection->getInputChannelName().c_str(), eventEntry->id);
- });
+ ATRACE_NAME_IF(ATRACE_ENABLED(),
+ StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
+ connection->getInputChannelName().c_str(), eventEntry->id));
LOG_ALWAYS_FATAL_IF(!inputTarget.flags.any(InputTarget::DISPATCH_MASK),
"No dispatch flags are set for %s", eventEntry->getDescription().c_str());
@@ -3570,10 +3568,9 @@
void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
const std::shared_ptr<Connection>& connection) {
- ATRACE_NAME_IF(ATRACE_ENABLED(), [&]() {
- return StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
- connection->getInputChannelName().c_str());
- });
+ ATRACE_NAME_IF(ATRACE_ENABLED(),
+ StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
+ connection->getInputChannelName().c_str()));
if (DEBUG_DISPATCH_CYCLE) {
ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
}
@@ -4147,10 +4144,10 @@
}
int32_t newId = mIdGenerator.nextId();
- ATRACE_NAME_IF(ATRACE_ENABLED(), [&]() {
- return StringPrintf("Split MotionEvent(id=0x%" PRIx32 ") to MotionEvent(id=0x%" PRIx32 ").",
- originalMotionEntry.id, newId);
- });
+ ATRACE_NAME_IF(ATRACE_ENABLED(),
+ StringPrintf("Split MotionEvent(id=0x%" PRIx32 ") to MotionEvent(id=0x%" PRIx32
+ ").",
+ originalMotionEntry.id, newId));
std::unique_ptr<MotionEntry> splitMotionEntry =
std::make_unique<MotionEntry>(newId, originalMotionEntry.eventTime,
originalMotionEntry.deviceId, originalMotionEntry.source,
diff --git a/services/inputflinger/dispatcher/LatencyAggregator.cpp b/services/inputflinger/dispatcher/LatencyAggregator.cpp
index 96d78c3..e09d97a 100644
--- a/services/inputflinger/dispatcher/LatencyAggregator.cpp
+++ b/services/inputflinger/dispatcher/LatencyAggregator.cpp
@@ -126,6 +126,7 @@
}
void LatencyAggregator::processStatistics(const InputEventTimeline& timeline) {
+ std::scoped_lock lock(mLock);
// Before we do any processing, check that we have not yet exceeded MAX_SIZE
if (mNumSketchEventsProcessed >= MAX_EVENTS_FOR_STATISTICS) {
return;
@@ -167,6 +168,7 @@
}
AStatsManager_PullAtomCallbackReturn LatencyAggregator::pullData(AStatsEventList* data) {
+ std::scoped_lock lock(mLock);
std::array<std::unique_ptr<SafeBytesField>, SketchIndex::SIZE> serializedDownData;
std::array<std::unique_ptr<SafeBytesField>, SketchIndex::SIZE> serializedMoveData;
for (size_t i = 0; i < SketchIndex::SIZE; i++) {
@@ -257,6 +259,7 @@
}
std::string LatencyAggregator::dump(const char* prefix) const {
+ std::scoped_lock lock(mLock);
std::string sketchDump = StringPrintf("%s Sketches:\n", prefix);
for (size_t i = 0; i < SketchIndex::SIZE; i++) {
const int64_t numDown = mDownSketches[i]->num_values();
diff --git a/services/inputflinger/dispatcher/LatencyAggregator.h b/services/inputflinger/dispatcher/LatencyAggregator.h
index 60b6813..d6d1686 100644
--- a/services/inputflinger/dispatcher/LatencyAggregator.h
+++ b/services/inputflinger/dispatcher/LatencyAggregator.h
@@ -16,6 +16,7 @@
#pragma once
+#include <android-base/thread_annotations.h>
#include <kll.h>
#include <statslog.h>
#include <utils/Timers.h>
@@ -61,10 +62,13 @@
~LatencyAggregator();
private:
+ // Binder call -- called on a binder thread. This is different from the thread where the rest of
+ // the public API is called.
static AStatsManager_PullAtomCallbackReturn pullAtomCallback(int32_t atom_tag,
AStatsEventList* data,
void* cookie);
AStatsManager_PullAtomCallbackReturn pullData(AStatsEventList* data);
+
// ---------- Slow event handling ----------
void processSlowEvent(const InputEventTimeline& timeline);
nsecs_t mLastSlowEventTime = 0;
@@ -74,14 +78,17 @@
size_t mNumEventsSinceLastSlowEventReport = 0;
// ---------- Statistics handling ----------
+ // Statistics is pulled rather than pushed. It's pulled on a binder thread, and therefore will
+ // be accessed by two different threads. The lock is needed to protect the pulled data.
+ mutable std::mutex mLock;
void processStatistics(const InputEventTimeline& timeline);
// Sketches
std::array<std::unique_ptr<dist_proc::aggregation::KllQuantile>, SketchIndex::SIZE>
- mDownSketches;
+ mDownSketches GUARDED_BY(mLock);
std::array<std::unique_ptr<dist_proc::aggregation::KllQuantile>, SketchIndex::SIZE>
- mMoveSketches;
+ mMoveSketches GUARDED_BY(mLock);
// How many events have been processed so far
- size_t mNumSketchEventsProcessed = 0;
+ size_t mNumSketchEventsProcessed GUARDED_BY(mLock) = 0;
};
} // namespace android::inputdispatcher
diff --git a/services/sensorservice/aidl/SensorManager.cpp b/services/sensorservice/aidl/SensorManager.cpp
index 08e00b4..2b6ea7c 100644
--- a/services/sensorservice/aidl/SensorManager.cpp
+++ b/services/sensorservice/aidl/SensorManager.cpp
@@ -196,6 +196,11 @@
sp<Looper> SensorManagerAidl::getLooper() {
std::lock_guard<std::mutex> lock(mThreadMutex);
+ if (!mJavaVm) {
+ LOG(ERROR) << "No Java VM. This must be running in a test or fuzzer.";
+ return mLooper;
+ }
+
if (!mPollThread.joinable()) {
// if thread not initialized, start thread
mStopThread = false;
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index 1718e0b..71c75f9 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -7,6 +7,17 @@
default_applicable_licenses: ["frameworks_native_license"],
}
+aconfig_declarations {
+ name: "surfaceflinger_flags",
+ package: "com.android.graphics.surfaceflinger.flags",
+ srcs: ["surfaceflinger_flags.aconfig"],
+}
+
+cc_aconfig_library {
+ name: "libsurfaceflingerflags",
+ aconfig_declarations: "surfaceflinger_flags",
+}
+
cc_defaults {
name: "surfaceflinger_defaults",
cflags: [
@@ -20,6 +31,9 @@
"-Wconversion",
"-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION",
],
+ static_libs: [
+ "libsurfaceflingerflags",
+ ],
}
cc_defaults {
@@ -84,6 +98,7 @@
"libshaders",
"libtimestats",
"libtonemap",
+ "libsurfaceflingerflags",
],
header_libs: [
"android.hardware.graphics.composer@2.1-command-buffer",
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 38dc435..517dc96 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -161,6 +161,8 @@
#include <aidl/android/hardware/graphics/composer3/DisplayCapability.h>
#include <aidl/android/hardware/graphics/composer3/RenderIntent.h>
+#include <com_android_graphics_surfaceflinger_flags.h>
+
#undef NO_THREAD_SAFETY_ANALYSIS
#define NO_THREAD_SAFETY_ANALYSIS \
_Pragma("GCC error \"Prefer <ftl/fake_guard.h> or MutexUtils.h helpers.\"")
@@ -170,6 +172,7 @@
#define DOES_CONTAIN_BORDER false
namespace android {
+using namespace com::android::graphics::surfaceflinger;
using namespace std::chrono_literals;
using namespace std::string_literals;
@@ -490,6 +493,10 @@
base::GetBoolProperty("persist.debug.sf.enable_layer_lifecycle_manager"s, true);
mLegacyFrontEndEnabled = !mLayerLifecycleManagerEnabled ||
base::GetBoolProperty("persist.debug.sf.enable_legacy_frontend"s, false);
+
+ // Trunk-Stable flags
+ mMiscFlagValue = flags::misc1();
+ mConnectedDisplayFlagValue = flags::connected_display();
}
LatchUnsignaledConfig SurfaceFlinger::getLatchUnsignaledConfig() {
@@ -731,6 +738,8 @@
enableRefreshRateOverlay(true);
}
}));
+
+ LOG_ALWAYS_FATAL_IF(flags::misc1() != mMiscFlagValue, "misc1 flag is not boot stable!");
}
static std::optional<renderengine::RenderEngine::RenderEngineType>
@@ -5912,6 +5921,7 @@
}
}
}
+
write(fd, result.c_str(), result.size());
return NO_ERROR;
}
@@ -6333,6 +6343,10 @@
result.append("SurfaceFlinger global state:\n");
colorizer.reset(result);
+ StringAppendF(&result, "MiscFlagValue: %s\n", mMiscFlagValue ? "true" : "false");
+ StringAppendF(&result, "ConnectedDisplayFlagValue: %s\n",
+ mConnectedDisplayFlagValue ? "true" : "false");
+
getRenderEngine().dump(result);
result.append("ClientCache state:\n");
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index dc4e7cf..59b1172 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -1450,6 +1450,10 @@
void sfdo_setDebugFlash(int delay);
void sfdo_scheduleComposite();
void sfdo_scheduleCommit();
+
+ // Trunk-Stable flags
+ bool mMiscFlagValue;
+ bool mConnectedDisplayFlagValue;
};
class SurfaceComposerAIDL : public gui::BnSurfaceComposer {
diff --git a/services/surfaceflinger/surfaceflinger_flags.aconfig b/services/surfaceflinger/surfaceflinger_flags.aconfig
new file mode 100644
index 0000000..f47ed45
--- /dev/null
+++ b/services/surfaceflinger/surfaceflinger_flags.aconfig
@@ -0,0 +1,17 @@
+package: "com.android.graphics.surfaceflinger.flags"
+
+flag {
+ name: "misc1"
+ namespace: "core_graphics"
+ description: "This flag controls minor miscellaneous SurfaceFlinger changes"
+ bug: "297389311"
+ is_fixed_read_only: true
+}
+
+flag {
+ name: "connected_display"
+ namespace: "core_graphics"
+ description: "Controls SurfaceFlinger support for Connected Displays"
+ bug: "278199093"
+ is_fixed_read_only: true
+}
diff --git a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
index 72ed4c8..2353480 100644
--- a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
@@ -667,6 +667,8 @@
scheduler::LayerInfo::FrameRateCompatibility::Default);
EXPECT_EQ(getSnapshot({.id = 122})->frameRate.category, FrameRateCategory::Normal);
EXPECT_TRUE(getSnapshot({.id = 122})->changes.test(RequestedLayerState::Changes::FrameRate));
+ EXPECT_TRUE(
+ getSnapshot({.id = 122})->changes.test(RequestedLayerState::Changes::AffectsChildren));
EXPECT_FALSE(getSnapshot({.id = 1221})->frameRate.vote.rate.isValid());
EXPECT_TRUE(getSnapshot({.id = 1221})->frameRate.isValid());
@@ -674,6 +676,8 @@
scheduler::LayerInfo::FrameRateCompatibility::Default);
EXPECT_EQ(getSnapshot({.id = 1221})->frameRate.category, FrameRateCategory::Normal);
EXPECT_TRUE(getSnapshot({.id = 1221})->changes.test(RequestedLayerState::Changes::FrameRate));
+ EXPECT_TRUE(
+ getSnapshot({.id = 1221})->changes.test(RequestedLayerState::Changes::AffectsChildren));
// reparent and verify the child does NOT get the new parent's framerate because it already has
// the frame rate category specified.