Merge changes from topic "main-vulkan13-dev to master"
* changes:
Add Vulkan 1.3 symbols to null_driver
Vulkan: update the loader for vulkan-headers v1.3.203
Add Vulkan version 1.3 to frameworks/native/data/etc
Added a comment deprecating vkjson
Updated the llndk symbol map for Vulkan 1.3
Added Vulkan 1.3 support to vkjson
Change Vulkan API to 1.3
Vulkan: update the loader for vulkan-headers v1.3.197
Added Vulkan 1.2 support to vkjson
Deprecate old VK_* defines
Change Vulkan API to 1.2
diff --git a/cmds/servicemanager/servicemanager.microdroid.rc b/cmds/servicemanager/servicemanager.microdroid.rc
index 8c1a6ed..e01f132 100644
--- a/cmds/servicemanager/servicemanager.microdroid.rc
+++ b/cmds/servicemanager/servicemanager.microdroid.rc
@@ -1,13 +1,8 @@
service servicemanager /system/bin/servicemanager.microdroid
- class core animation
+ class core
user system
group system readproc
critical
onrestart restart apexd
- onrestart restart audioserver
- onrestart restart gatekeeperd
- onrestart class_restart --only-enabled main
- onrestart class_restart --only-enabled hal
- onrestart class_restart --only-enabled early_hal
task_profiles ServiceCapacityLow
shutdown critical
diff --git a/include/android/choreographer.h b/include/android/choreographer.h
index 6f579ca..98f0eec 100644
--- a/include/android/choreographer.h
+++ b/include/android/choreographer.h
@@ -39,6 +39,12 @@
*/
typedef struct AChoreographer AChoreographer;
+
+/**
+ * The identifier of a frame timeline.
+ */
+typedef int64_t AVsyncId;
+
struct AChoreographerFrameCallbackData;
/**
* Opaque type that provides access to an AChoreographerFrameCallbackData object.
@@ -203,7 +209,7 @@
/**
* The vsync ID token used to map Choreographer data.
*/
-int64_t AChoreographerFrameCallbackData_getFrameTimelineVsyncId(
+AVsyncId AChoreographerFrameCallbackData_getFrameTimelineVsyncId(
const AChoreographerFrameCallbackData* data, size_t index) __INTRODUCED_IN(33);
/**
diff --git a/include/android/surface_control.h b/include/android/surface_control.h
index 3a13104..9a36ecb 100644
--- a/include/android/surface_control.h
+++ b/include/android/surface_control.h
@@ -28,6 +28,7 @@
#include <sys/cdefs.h>
+#include <android/choreographer.h>
#include <android/data_space.h>
#include <android/hardware_buffer.h>
#include <android/hdr_metadata.h>
@@ -596,13 +597,23 @@
__INTRODUCED_IN(31);
/**
- * Sets the frame timeline to use.
+ * Sets the frame timeline to use in Surface Flinger.
+ *
+ * A frame timeline should be chosen based on what frame deadline the application
+ * can meet when rendering the frame and the application's desired present time.
+ * By setting a frame timeline, Surface Flinger tries to present the frame at the corresponding
+ * expected present time.
+ *
+ * To receive frame timelines, a callback must be posted to Choreographer using
+ * AChoreographer_postExtendedFrameCallback(). The \a vsnycId can then be extracted from the
+ * callback payload using AChoreographerFrameCallbackData_getFrameTimelineVsyncId().
*
* \param vsyncId The vsync ID received from AChoreographer, setting the frame's present target to
- * the corresponding expected present time and deadline from the frame to be rendered.
+ * the corresponding expected present time and deadline from the frame to be rendered. A stale or
+ * invalid value will be ignored.
*/
void ASurfaceTransaction_setFrameTimeline(ASurfaceTransaction* transaction,
- int64_t vsyncId) __INTRODUCED_IN(33);
+ AVsyncId vsyncId) __INTRODUCED_IN(33);
__END_DECLS
diff --git a/libs/binder/rust/src/binder.rs b/libs/binder/rust/src/binder.rs
index 7895a72..467e51e 100644
--- a/libs/binder/rust/src/binder.rs
+++ b/libs/binder/rust/src/binder.rs
@@ -192,9 +192,6 @@
/// Is this object still alive?
fn is_binder_alive(&self) -> bool;
- /// Send a ping transaction to this object
- fn ping_binder(&mut self) -> Result<()>;
-
/// Indicate that the service intends to receive caller security contexts.
#[cfg(not(android_vndk))]
fn set_requesting_sid(&mut self, enable: bool);
@@ -270,6 +267,9 @@
/// The recipient will no longer be called if this object
/// dies.
fn unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>;
+
+ /// Send a ping transaction to this object
+ fn ping_binder(&mut self) -> Result<()>;
}
/// Opaque reference to the type of a Binder interface.
diff --git a/libs/binder/rust/src/proxy.rs b/libs/binder/rust/src/proxy.rs
index 760d862..12bfde7 100644
--- a/libs/binder/rust/src/proxy.rs
+++ b/libs/binder/rust/src/proxy.rs
@@ -312,17 +312,6 @@
}
}
- fn ping_binder(&mut self) -> Result<()> {
- let status = unsafe {
- // Safety: `SpIBinder` guarantees that `self` always contains a
- // valid pointer to an `AIBinder`.
- //
- // This call does not affect ownership of its pointer parameter.
- sys::AIBinder_ping(self.as_native_mut())
- };
- status_result(status)
- }
-
#[cfg(not(android_vndk))]
fn set_requesting_sid(&mut self, enable: bool) {
unsafe { sys::AIBinder_setRequestingSid(self.as_native_mut(), enable) };
@@ -412,6 +401,17 @@
)
})
}
+
+ fn ping_binder(&mut self) -> Result<()> {
+ let status = unsafe {
+ // Safety: `SpIBinder` guarantees that `self` always contains a
+ // valid pointer to an `AIBinder`.
+ //
+ // This call does not affect ownership of its pointer parameter.
+ sys::AIBinder_ping(self.as_native_mut())
+ };
+ status_result(status)
+ }
}
impl Serialize for SpIBinder {
diff --git a/libs/cputimeinstate/Android.bp b/libs/cputimeinstate/Android.bp
index 1fd2c62..73f9d4d 100644
--- a/libs/cputimeinstate/Android.bp
+++ b/libs/cputimeinstate/Android.bp
@@ -14,6 +14,7 @@
"libbase",
"libbpf_bcc",
"libbpf_android",
+ "libbpf_minimal",
"liblog",
"libnetdutils"
],
@@ -33,6 +34,7 @@
"libbase",
"libbpf_bcc",
"libbpf_android",
+ "libbpf_minimal",
"libtimeinstate",
"libnetdutils",
],
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index 968ace9..b3e6ffa 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -136,7 +136,7 @@
eLayerStackChanged = 0x00000080,
/* unused 0x00000400, */
eShadowRadiusChanged = 0x00000800,
- eLayerCreated = 0x00001000,
+ /* unused 0x00001000, */
eBufferCropChanged = 0x00002000,
eRelativeLayerChanged = 0x00004000,
eReparent = 0x00008000,
diff --git a/libs/input/android/os/IInputConstants.aidl b/libs/input/android/os/IInputConstants.aidl
index 829bbdd..265cbf0 100644
--- a/libs/input/android/os/IInputConstants.aidl
+++ b/libs/input/android/os/IInputConstants.aidl
@@ -95,4 +95,7 @@
*/
INTERCEPTS_STYLUS = 0x00000040,
}
+
+ /* The default pointer acceleration value. */
+ const int DEFAULT_POINTER_ACCELERATION = 3;
}
diff --git a/libs/nativedisplay/AChoreographer.cpp b/libs/nativedisplay/AChoreographer.cpp
index 84daea0..d90ee57 100644
--- a/libs/nativedisplay/AChoreographer.cpp
+++ b/libs/nativedisplay/AChoreographer.cpp
@@ -552,7 +552,7 @@
const AChoreographerFrameCallbackData* data) {
return AChoreographerFrameCallbackData_getPreferredFrameTimelineIndex(data);
}
-int64_t AChoreographerFrameCallbackData_routeGetFrameTimelineVsyncId(
+AVsyncId AChoreographerFrameCallbackData_routeGetFrameTimelineVsyncId(
const AChoreographerFrameCallbackData* data, size_t index) {
return AChoreographerFrameCallbackData_getFrameTimelineVsyncId(data, index);
}
@@ -644,7 +644,7 @@
"Data is only valid in callback");
return frameCallbackData->preferredFrameTimelineIndex;
}
-int64_t AChoreographerFrameCallbackData_getFrameTimelineVsyncId(
+AVsyncId AChoreographerFrameCallbackData_getFrameTimelineVsyncId(
const AChoreographerFrameCallbackData* data, size_t index) {
const ChoreographerFrameCallbackDataImpl* frameCallbackData =
AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(data);
diff --git a/libs/nativedisplay/ADisplay.cpp b/libs/nativedisplay/ADisplay.cpp
index 6288194..76b85d6 100644
--- a/libs/nativedisplay/ADisplay.cpp
+++ b/libs/nativedisplay/ADisplay.cpp
@@ -50,11 +50,6 @@
int32_t height{0};
/**
- * The display density.
- */
- float density{0};
-
- /**
* The refresh rate of the display configuration, in frames per second.
*/
float fps{0.0};
@@ -168,8 +163,8 @@
const ui::DisplayMode& mode = modes[j];
modesPerDisplay[i].emplace_back(
DisplayConfigImpl{static_cast<size_t>(mode.id), mode.resolution.getWidth(),
- mode.resolution.getHeight(), staticInfo.density,
- mode.refreshRate, mode.sfVsyncOffset, mode.appVsyncOffset});
+ mode.resolution.getHeight(), mode.refreshRate,
+ mode.sfVsyncOffset, mode.appVsyncOffset});
}
}
@@ -283,12 +278,6 @@
return NAME_NOT_FOUND;
}
-float ADisplayConfig_getDensity(ADisplayConfig* config) {
- CHECK_NOT_NULL(config);
-
- return reinterpret_cast<DisplayConfigImpl*>(config)->density;
-}
-
int32_t ADisplayConfig_getWidth(ADisplayConfig* config) {
CHECK_NOT_NULL(config);
diff --git a/libs/nativedisplay/include-private/private/android/choreographer.h b/libs/nativedisplay/include-private/private/android/choreographer.h
index 0a1fcbe..d650c26 100644
--- a/libs/nativedisplay/include-private/private/android/choreographer.h
+++ b/libs/nativedisplay/include-private/private/android/choreographer.h
@@ -65,7 +65,7 @@
const AChoreographerFrameCallbackData* data);
size_t AChoreographerFrameCallbackData_routeGetPreferredFrameTimelineIndex(
const AChoreographerFrameCallbackData* data);
-int64_t AChoreographerFrameCallbackData_routeGetFrameTimelineVsyncId(
+AVsyncId AChoreographerFrameCallbackData_routeGetFrameTimelineVsyncId(
const AChoreographerFrameCallbackData* data, size_t index);
int64_t AChoreographerFrameCallbackData_routeGetFrameTimelineExpectedPresentTimeNanos(
const AChoreographerFrameCallbackData* data, size_t index);
diff --git a/libs/nativedisplay/include/apex/display.h b/libs/nativedisplay/include/apex/display.h
index bd94b55..0f44902 100644
--- a/libs/nativedisplay/include/apex/display.h
+++ b/libs/nativedisplay/include/apex/display.h
@@ -107,11 +107,6 @@
int ADisplay_getCurrentConfig(ADisplay* display, ADisplayConfig** outConfig);
/**
- * Queries the density for a given display configuration.
- */
-float ADisplayConfig_getDensity(ADisplayConfig* config);
-
-/**
* Queries the width in pixels for a given display configuration.
*/
int32_t ADisplayConfig_getWidth(ADisplayConfig* config);
diff --git a/libs/nativedisplay/libnativedisplay.map.txt b/libs/nativedisplay/libnativedisplay.map.txt
index b1b6498..6579313 100644
--- a/libs/nativedisplay/libnativedisplay.map.txt
+++ b/libs/nativedisplay/libnativedisplay.map.txt
@@ -50,7 +50,6 @@
android::ADisplay_getDisplayType*;
android::ADisplay_getPreferredWideColorFormat*;
android::ADisplay_getCurrentConfig*;
- android::ADisplayConfig_getDensity*;
android::ADisplayConfig_getWidth*;
android::ADisplayConfig_getHeight*;
android::ADisplayConfig_getFps*;
diff --git a/libs/renderengine/include/renderengine/DisplaySettings.h b/libs/renderengine/include/renderengine/DisplaySettings.h
index b4cab39..2c51ccd 100644
--- a/libs/renderengine/include/renderengine/DisplaySettings.h
+++ b/libs/renderengine/include/renderengine/DisplaySettings.h
@@ -43,6 +43,9 @@
// Maximum luminance pulled from the display's HDR capabilities.
float maxLuminance = 1.0f;
+ // Current luminance of the display
+ float currentLuminanceNits = -1.f;
+
// Output dataspace that will be populated if wide color gamut is used, or
// DataSpace::UNKNOWN otherwise.
ui::Dataspace outputDataspace = ui::Dataspace::UNKNOWN;
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index cc90946..063ce67 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -656,6 +656,7 @@
parameters.layerDimmingRatio, 1.f));
return createLinearEffectShader(parameters.shader, effect, runtimeEffect, colorTransform,
parameters.display.maxLuminance,
+ parameters.display.currentLuminanceNits,
parameters.layer.source.buffer.maxLuminanceNits);
}
return parameters.shader;
diff --git a/libs/renderengine/skia/filters/LinearEffect.cpp b/libs/renderengine/skia/filters/LinearEffect.cpp
index 36305ae..6077c2e 100644
--- a/libs/renderengine/skia/filters/LinearEffect.cpp
+++ b/libs/renderengine/skia/filters/LinearEffect.cpp
@@ -44,14 +44,15 @@
const shaders::LinearEffect& linearEffect,
sk_sp<SkRuntimeEffect> runtimeEffect,
const mat4& colorTransform, float maxDisplayLuminance,
- float maxLuminance) {
+ float currentDisplayLuminanceNits, float maxLuminance) {
ATRACE_CALL();
SkRuntimeShaderBuilder effectBuilder(runtimeEffect);
effectBuilder.child("child") = shader;
- const auto uniforms = shaders::buildLinearEffectUniforms(linearEffect, colorTransform,
- maxDisplayLuminance, maxLuminance);
+ const auto uniforms =
+ shaders::buildLinearEffectUniforms(linearEffect, colorTransform, maxDisplayLuminance,
+ currentDisplayLuminanceNits, maxLuminance);
for (const auto& uniform : uniforms) {
effectBuilder.uniform(uniform.name.c_str()).set(uniform.value.data(), uniform.value.size());
diff --git a/libs/renderengine/skia/filters/LinearEffect.h b/libs/renderengine/skia/filters/LinearEffect.h
index 8eb6670..e0a556b 100644
--- a/libs/renderengine/skia/filters/LinearEffect.h
+++ b/libs/renderengine/skia/filters/LinearEffect.h
@@ -37,13 +37,14 @@
// matrix transforming from linear XYZ to linear RGB immediately before OETF.
// We also provide additional HDR metadata upon creating the shader:
// * The max display luminance is the max luminance of the physical display in nits
+// * The current luminance of the physical display in nits
// * The max luminance is provided as the max luminance for the buffer, either from the SMPTE 2086
// or as the max light level from the CTA 861.3 standard.
sk_sp<SkShader> createLinearEffectShader(sk_sp<SkShader> inputShader,
const shaders::LinearEffect& linearEffect,
sk_sp<SkRuntimeEffect> runtimeEffect,
const mat4& colorTransform, float maxDisplayLuminance,
- float maxLuminance);
+ float currentDisplayLuminanceNits, float maxLuminance);
} // namespace skia
} // namespace renderengine
} // namespace android
diff --git a/libs/shaders/include/shaders/shaders.h b/libs/shaders/include/shaders/shaders.h
index 712a27a..43828cc 100644
--- a/libs/shaders/include/shaders/shaders.h
+++ b/libs/shaders/include/shaders/shaders.h
@@ -100,6 +100,7 @@
std::vector<tonemap::ShaderUniform> buildLinearEffectUniforms(const LinearEffect& linearEffect,
const mat4& colorTransform,
float maxDisplayLuminance,
+ float currentDisplayLuminanceNits,
float maxLuminance);
} // namespace android::shaders
diff --git a/libs/shaders/shaders.cpp b/libs/shaders/shaders.cpp
index 6019c4a..4d88d5d 100644
--- a/libs/shaders/shaders.cpp
+++ b/libs/shaders/shaders.cpp
@@ -463,6 +463,7 @@
std::vector<tonemap::ShaderUniform> buildLinearEffectUniforms(const LinearEffect& linearEffect,
const mat4& colorTransform,
float maxDisplayLuminance,
+ float currentDisplayLuminanceNits,
float maxLuminance) {
std::vector<tonemap::ShaderUniform> uniforms;
if (linearEffect.inputDataspace == linearEffect.outputDataspace) {
@@ -480,6 +481,7 @@
}
tonemap::Metadata metadata{.displayMaxLuminance = maxDisplayLuminance,
+ .currentDisplayLuminanceNits = currentDisplayLuminanceNits,
// If the input luminance is unknown, use display luminance (aka,
// no-op any luminance changes)
// This will be the case for eg screenshots in addition to
diff --git a/libs/tonemap/include/tonemap/tonemap.h b/libs/tonemap/include/tonemap/tonemap.h
index bd7b72d..6233e6c 100644
--- a/libs/tonemap/include/tonemap/tonemap.h
+++ b/libs/tonemap/include/tonemap/tonemap.h
@@ -42,7 +42,11 @@
// This metadata should not be used for manipulating the source code of the shader program directly,
// as otherwise caching by other system of these shaders may break.
struct Metadata {
+ // The maximum luminance of the display in nits
float displayMaxLuminance = 0.0;
+ // The current luminance of the display in nits
+ float currentDisplayLuminanceNits = 0.0;
+ // The maximum luminance of the content in nits
float contentMaxLuminance = 0.0;
};
diff --git a/services/batteryservice/include/batteryservice/BatteryService.h b/services/batteryservice/include/batteryservice/BatteryService.h
index 1e8eb1e..178bc29 100644
--- a/services/batteryservice/include/batteryservice/BatteryService.h
+++ b/services/batteryservice/include/batteryservice/BatteryService.h
@@ -40,6 +40,7 @@
bool chargerAcOnline;
bool chargerUsbOnline;
bool chargerWirelessOnline;
+ bool chargerDockOnline;
int maxChargingCurrent;
int maxChargingVoltage;
int batteryStatus;
diff --git a/services/inputflinger/include/InputReaderBase.h b/services/inputflinger/include/InputReaderBase.h
index 1aab856..41ecef3 100644
--- a/services/inputflinger/include/InputReaderBase.h
+++ b/services/inputflinger/include/InputReaderBase.h
@@ -17,6 +17,7 @@
#ifndef _UI_INPUT_READER_BASE_H
#define _UI_INPUT_READER_BASE_H
+#include <android/os/IInputConstants.h>
#include <input/DisplayViewport.h>
#include <input/Input.h>
#include <input/InputDevice.h>
@@ -87,6 +88,8 @@
virtual int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask,
int32_t sw) = 0;
+ virtual int32_t getKeyCodeForKeyLocation(int32_t deviceId, int32_t locationKeyCode) const = 0;
+
/* Toggle Caps Lock */
virtual void toggleCapsLockState(int32_t deviceId) = 0;
@@ -286,7 +289,10 @@
InputReaderConfiguration()
: virtualKeyQuietTime(0),
- pointerVelocityControlParameters(1.0f, 500.0f, 3000.0f, 3.0f),
+ pointerVelocityControlParameters(1.0f, 500.0f, 3000.0f,
+ static_cast<float>(
+ android::os::IInputConstants::
+ DEFAULT_POINTER_ACCELERATION)),
wheelVelocityControlParameters(1.0f, 15.0f, 50.0f, 4.0f),
pointerGesturesEnabled(true),
pointerGestureQuietInterval(100 * 1000000LL), // 100 ms
diff --git a/services/inputflinger/reader/EventHub.cpp b/services/inputflinger/reader/EventHub.cpp
index 09a62f3..db67877 100644
--- a/services/inputflinger/reader/EventHub.cpp
+++ b/services/inputflinger/reader/EventHub.cpp
@@ -880,6 +880,42 @@
return AKEY_STATE_UNKNOWN;
}
+int32_t EventHub::getKeyCodeForKeyLocation(int32_t deviceId, int32_t locationKeyCode) const {
+ std::scoped_lock _l(mLock);
+
+ Device* device = getDeviceLocked(deviceId);
+ if (device == nullptr || !device->hasValidFd() || device->keyMap.keyCharacterMap == nullptr ||
+ device->keyMap.keyLayoutMap == nullptr) {
+ return AKEYCODE_UNKNOWN;
+ }
+ std::vector<int32_t> scanCodes;
+ device->keyMap.keyLayoutMap->findScanCodesForKey(locationKeyCode, &scanCodes);
+ if (scanCodes.empty()) {
+ ALOGW("Failed to get key code for key location: no scan code maps to key code %d for input"
+ "device %d",
+ locationKeyCode, deviceId);
+ return AKEYCODE_UNKNOWN;
+ }
+ if (scanCodes.size() > 1) {
+ ALOGW("Multiple scan codes map to the same key code %d, returning only the first match",
+ locationKeyCode);
+ }
+ int32_t outKeyCode;
+ status_t mapKeyRes =
+ device->getKeyCharacterMap()->mapKey(scanCodes[0], 0 /*usageCode*/, &outKeyCode);
+ switch (mapKeyRes) {
+ case OK:
+ return outKeyCode;
+ case NAME_NOT_FOUND:
+ // key character map doesn't re-map this scanCode, hence the keyCode remains the same
+ return locationKeyCode;
+ default:
+ ALOGW("Failed to get key code for key location: Key character map returned error %s",
+ statusToString(mapKeyRes).c_str());
+ return AKEYCODE_UNKNOWN;
+ }
+}
+
int32_t EventHub::getSwitchState(int32_t deviceId, int32_t sw) const {
if (sw >= 0 && sw <= SW_MAX) {
std::scoped_lock _l(mLock);
diff --git a/services/inputflinger/reader/InputDevice.cpp b/services/inputflinger/reader/InputDevice.cpp
index 7cff672..3e95fa9 100644
--- a/services/inputflinger/reader/InputDevice.cpp
+++ b/services/inputflinger/reader/InputDevice.cpp
@@ -475,6 +475,23 @@
return result;
}
+int32_t InputDevice::getKeyCodeForKeyLocation(int32_t locationKeyCode) const {
+ std::optional<int32_t> result = first_in_mappers<int32_t>(
+ [locationKeyCode](const InputMapper& mapper) -> std::optional<int32_t> const {
+ if (sourcesMatchMask(mapper.getSources(), AINPUT_SOURCE_KEYBOARD)) {
+ return std::make_optional(mapper.getKeyCodeForKeyLocation(locationKeyCode));
+ }
+ return std::nullopt;
+ });
+ if (!result) {
+ ALOGE("Failed to get key code for key location: No matching InputMapper with source mask "
+ "KEYBOARD found. The provided input device with id %d has sources %s.",
+ getId(), inputEventSourceToString(getSources()).c_str());
+ return AKEYCODE_UNKNOWN;
+ }
+ return *result;
+}
+
void InputDevice::vibrate(const VibrationSequence& sequence, ssize_t repeat, int32_t token) {
for_each_mapper([sequence, repeat, token](InputMapper& mapper) {
mapper.vibrate(sequence, repeat, token);
diff --git a/services/inputflinger/reader/InputReader.cpp b/services/inputflinger/reader/InputReader.cpp
index 564db56..31d331b 100644
--- a/services/inputflinger/reader/InputReader.cpp
+++ b/services/inputflinger/reader/InputReader.cpp
@@ -303,7 +303,7 @@
device->process(rawEvents, count);
}
-InputDevice* InputReader::findInputDeviceLocked(int32_t deviceId) {
+InputDevice* InputReader::findInputDeviceLocked(int32_t deviceId) const {
auto deviceIt =
std::find_if(mDevices.begin(), mDevices.end(), [deviceId](const auto& devicePair) {
return devicePair.second->getId() == deviceId;
@@ -589,6 +589,18 @@
return result;
}
+int32_t InputReader::getKeyCodeForKeyLocation(int32_t deviceId, int32_t locationKeyCode) const {
+ std::scoped_lock _l(mLock);
+
+ InputDevice* device = findInputDeviceLocked(deviceId);
+ if (device == nullptr) {
+ ALOGW("Failed to get key code for key location: Input device with id %d not found",
+ deviceId);
+ return AKEYCODE_UNKNOWN;
+ }
+ return device->getKeyCodeForKeyLocation(locationKeyCode);
+}
+
void InputReader::requestRefreshConfiguration(uint32_t changes) {
std::scoped_lock _l(mLock);
diff --git a/services/inputflinger/reader/include/EventHub.h b/services/inputflinger/reader/include/EventHub.h
index 1f96294..18e912d 100644
--- a/services/inputflinger/reader/include/EventHub.h
+++ b/services/inputflinger/reader/include/EventHub.h
@@ -306,6 +306,7 @@
virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const = 0;
virtual status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis,
int32_t* outValue) const = 0;
+ virtual int32_t getKeyCodeForKeyLocation(int32_t deviceId, int32_t locationKeyCode) const = 0;
/*
* Examine key input devices for specific framework keycode support
@@ -482,6 +483,8 @@
int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const override final;
int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const override final;
int32_t getSwitchState(int32_t deviceId, int32_t sw) const override final;
+ int32_t getKeyCodeForKeyLocation(int32_t deviceId,
+ int32_t locationKeyCode) const override final;
status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis,
int32_t* outValue) const override final;
diff --git a/services/inputflinger/reader/include/InputDevice.h b/services/inputflinger/reader/include/InputDevice.h
index 518aaa0..11c074a 100644
--- a/services/inputflinger/reader/include/InputDevice.h
+++ b/services/inputflinger/reader/include/InputDevice.h
@@ -84,6 +84,7 @@
int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode);
+ int32_t getKeyCodeForKeyLocation(int32_t locationKeyCode) const;
bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes, const int32_t* keyCodes,
uint8_t* outFlags);
void vibrate(const VibrationSequence& sequence, ssize_t repeat, int32_t token);
@@ -216,7 +217,8 @@
// return the first value returned by a function over every mapper.
// if all mappers return nullopt, return nullopt.
template <typename T>
- inline std::optional<T> first_in_mappers(std::function<std::optional<T>(InputMapper&)> f) {
+ inline std::optional<T> first_in_mappers(
+ std::function<std::optional<T>(InputMapper&)> f) const {
for (auto& deviceEntry : mDevices) {
auto& devicePair = deviceEntry.second;
auto& mappers = devicePair.second;
@@ -312,6 +314,9 @@
inline int32_t getKeyCodeState(int32_t keyCode) const {
return mEventHub->getKeyCodeState(mId, keyCode);
}
+ inline int32_t getKeyCodeForKeyLocation(int32_t locationKeyCode) const {
+ return mEventHub->getKeyCodeForKeyLocation(mId, locationKeyCode);
+ }
inline int32_t getSwitchState(int32_t sw) const { return mEventHub->getSwitchState(mId, sw); }
inline status_t getAbsoluteAxisValue(int32_t code, int32_t* outValue) const {
return mEventHub->getAbsoluteAxisValue(mId, code, outValue);
diff --git a/services/inputflinger/reader/include/InputReader.h b/services/inputflinger/reader/include/InputReader.h
index fb1d166..daeaa1d 100644
--- a/services/inputflinger/reader/include/InputReader.h
+++ b/services/inputflinger/reader/include/InputReader.h
@@ -69,6 +69,8 @@
int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask, int32_t keyCode) override;
int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t sw) override;
+ int32_t getKeyCodeForKeyLocation(int32_t deviceId, int32_t locationKeyCode) const override;
+
void toggleCapsLockState(int32_t deviceId) override;
bool hasKeys(int32_t deviceId, uint32_t sourceMask, size_t numCodes, const int32_t* keyCodes,
@@ -239,7 +241,7 @@
const int32_t* keyCodes, uint8_t* outFlags) REQUIRES(mLock);
// find an InputDevice from an InputDevice id
- InputDevice* findInputDeviceLocked(int32_t deviceId) REQUIRES(mLock);
+ InputDevice* findInputDeviceLocked(int32_t deviceId) const REQUIRES(mLock);
};
} // namespace android
diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.cpp b/services/inputflinger/reader/mapper/CursorInputMapper.cpp
index fcb56ef..dc5fcec 100644
--- a/services/inputflinger/reader/mapper/CursorInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/CursorInputMapper.cpp
@@ -66,7 +66,7 @@
CursorInputMapper::~CursorInputMapper() {}
-uint32_t CursorInputMapper::getSources() {
+uint32_t CursorInputMapper::getSources() const {
return mSource;
}
diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.h b/services/inputflinger/reader/mapper/CursorInputMapper.h
index 9a8ca01..c84c6c4 100644
--- a/services/inputflinger/reader/mapper/CursorInputMapper.h
+++ b/services/inputflinger/reader/mapper/CursorInputMapper.h
@@ -56,7 +56,7 @@
explicit CursorInputMapper(InputDeviceContext& deviceContext);
virtual ~CursorInputMapper();
- virtual uint32_t getSources() override;
+ virtual uint32_t getSources() const override;
virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo) override;
virtual void dump(std::string& dump) override;
virtual void configure(nsecs_t when, const InputReaderConfiguration* config,
diff --git a/services/inputflinger/reader/mapper/ExternalStylusInputMapper.cpp b/services/inputflinger/reader/mapper/ExternalStylusInputMapper.cpp
index 37d1d74..6b5d37f 100644
--- a/services/inputflinger/reader/mapper/ExternalStylusInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/ExternalStylusInputMapper.cpp
@@ -26,7 +26,7 @@
ExternalStylusInputMapper::ExternalStylusInputMapper(InputDeviceContext& deviceContext)
: InputMapper(deviceContext) {}
-uint32_t ExternalStylusInputMapper::getSources() {
+uint32_t ExternalStylusInputMapper::getSources() const {
return AINPUT_SOURCE_STYLUS;
}
diff --git a/services/inputflinger/reader/mapper/ExternalStylusInputMapper.h b/services/inputflinger/reader/mapper/ExternalStylusInputMapper.h
index 1d42b30..516aa51 100644
--- a/services/inputflinger/reader/mapper/ExternalStylusInputMapper.h
+++ b/services/inputflinger/reader/mapper/ExternalStylusInputMapper.h
@@ -30,7 +30,7 @@
explicit ExternalStylusInputMapper(InputDeviceContext& deviceContext);
virtual ~ExternalStylusInputMapper() = default;
- virtual uint32_t getSources() override;
+ virtual uint32_t getSources() const override;
virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo) override;
virtual void dump(std::string& dump) override;
virtual void configure(nsecs_t when, const InputReaderConfiguration* config,
diff --git a/services/inputflinger/reader/mapper/InputMapper.cpp b/services/inputflinger/reader/mapper/InputMapper.cpp
index b9aef54..7b185e0 100644
--- a/services/inputflinger/reader/mapper/InputMapper.cpp
+++ b/services/inputflinger/reader/mapper/InputMapper.cpp
@@ -51,6 +51,10 @@
return AKEY_STATE_UNKNOWN;
}
+int32_t InputMapper::getKeyCodeForKeyLocation(int32_t locationKeyCode) const {
+ return AKEYCODE_UNKNOWN;
+}
+
bool InputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
const int32_t* keyCodes, uint8_t* outFlags) {
return false;
diff --git a/services/inputflinger/reader/mapper/InputMapper.h b/services/inputflinger/reader/mapper/InputMapper.h
index d83d74d..fce6409 100644
--- a/services/inputflinger/reader/mapper/InputMapper.h
+++ b/services/inputflinger/reader/mapper/InputMapper.h
@@ -45,12 +45,13 @@
inline int32_t getDeviceId() { return mDeviceContext.getId(); }
inline InputDeviceContext& getDeviceContext() { return mDeviceContext; }
+ inline InputDeviceContext& getDeviceContext() const { return mDeviceContext; };
inline const std::string getDeviceName() const { return mDeviceContext.getName(); }
inline InputReaderContext* getContext() { return mDeviceContext.getContext(); }
inline InputReaderPolicyInterface* getPolicy() { return getContext()->getPolicy(); }
inline InputListenerInterface& getListener() { return getContext()->getListener(); }
- virtual uint32_t getSources() = 0;
+ virtual uint32_t getSources() const = 0;
virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
virtual void dump(std::string& dump);
virtual void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes);
@@ -61,6 +62,8 @@
virtual int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
virtual int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode);
+ virtual int32_t getKeyCodeForKeyLocation(int32_t locationKeyCode) const;
+
virtual bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
const int32_t* keyCodes, uint8_t* outFlags);
virtual void vibrate(const VibrationSequence& sequence, ssize_t repeat, int32_t token);
diff --git a/services/inputflinger/reader/mapper/JoystickInputMapper.cpp b/services/inputflinger/reader/mapper/JoystickInputMapper.cpp
index ad11b05..a8e9bae 100644
--- a/services/inputflinger/reader/mapper/JoystickInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/JoystickInputMapper.cpp
@@ -25,7 +25,7 @@
JoystickInputMapper::~JoystickInputMapper() {}
-uint32_t JoystickInputMapper::getSources() {
+uint32_t JoystickInputMapper::getSources() const {
return AINPUT_SOURCE_JOYSTICK;
}
diff --git a/services/inputflinger/reader/mapper/JoystickInputMapper.h b/services/inputflinger/reader/mapper/JoystickInputMapper.h
index bba95ad..307bf5b 100644
--- a/services/inputflinger/reader/mapper/JoystickInputMapper.h
+++ b/services/inputflinger/reader/mapper/JoystickInputMapper.h
@@ -26,7 +26,7 @@
explicit JoystickInputMapper(InputDeviceContext& deviceContext);
virtual ~JoystickInputMapper();
- virtual uint32_t getSources() override;
+ virtual uint32_t getSources() const override;
virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo) override;
virtual void dump(std::string& dump) override;
virtual void configure(nsecs_t when, const InputReaderConfiguration* config,
diff --git a/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp b/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
index a8602a4..1d63c0e 100644
--- a/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
@@ -95,7 +95,7 @@
KeyboardInputMapper::~KeyboardInputMapper() {}
-uint32_t KeyboardInputMapper::getSources() {
+uint32_t KeyboardInputMapper::getSources() const {
return mSource;
}
@@ -375,6 +375,10 @@
return getDeviceContext().getScanCodeState(scanCode);
}
+int32_t KeyboardInputMapper::getKeyCodeForKeyLocation(int32_t locationKeyCode) const {
+ return getDeviceContext().getKeyCodeForKeyLocation(locationKeyCode);
+}
+
bool KeyboardInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
const int32_t* keyCodes, uint8_t* outFlags) {
return getDeviceContext().markSupportedKeyCodes(numCodes, keyCodes, outFlags);
diff --git a/services/inputflinger/reader/mapper/KeyboardInputMapper.h b/services/inputflinger/reader/mapper/KeyboardInputMapper.h
index fc92320..3787696 100644
--- a/services/inputflinger/reader/mapper/KeyboardInputMapper.h
+++ b/services/inputflinger/reader/mapper/KeyboardInputMapper.h
@@ -26,7 +26,7 @@
KeyboardInputMapper(InputDeviceContext& deviceContext, uint32_t source, int32_t keyboardType);
virtual ~KeyboardInputMapper();
- virtual uint32_t getSources() override;
+ virtual uint32_t getSources() const override;
virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo) override;
virtual void dump(std::string& dump) override;
virtual void configure(nsecs_t when, const InputReaderConfiguration* config,
@@ -38,6 +38,7 @@
virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode) override;
virtual bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
const int32_t* keyCodes, uint8_t* outFlags) override;
+ virtual int32_t getKeyCodeForKeyLocation(int32_t locationKeyCode) const override;
virtual int32_t getMetaState() override;
virtual bool updateMetaState(int32_t keyCode) override;
diff --git a/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.cpp b/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.cpp
index b83a8fc..eca25f6 100644
--- a/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.cpp
@@ -31,7 +31,7 @@
RotaryEncoderInputMapper::~RotaryEncoderInputMapper() {}
-uint32_t RotaryEncoderInputMapper::getSources() {
+uint32_t RotaryEncoderInputMapper::getSources() const {
return mSource;
}
diff --git a/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.h b/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.h
index e0c9404..1859355 100644
--- a/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.h
+++ b/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.h
@@ -27,7 +27,7 @@
explicit RotaryEncoderInputMapper(InputDeviceContext& deviceContext);
virtual ~RotaryEncoderInputMapper();
- virtual uint32_t getSources() override;
+ virtual uint32_t getSources() const override;
virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo) override;
virtual void dump(std::string& dump) override;
virtual void configure(nsecs_t when, const InputReaderConfiguration* config,
diff --git a/services/inputflinger/reader/mapper/SensorInputMapper.cpp b/services/inputflinger/reader/mapper/SensorInputMapper.cpp
index 677a372..b01c2bc 100644
--- a/services/inputflinger/reader/mapper/SensorInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/SensorInputMapper.cpp
@@ -57,7 +57,7 @@
SensorInputMapper::~SensorInputMapper() {}
-uint32_t SensorInputMapper::getSources() {
+uint32_t SensorInputMapper::getSources() const {
return AINPUT_SOURCE_SENSOR;
}
diff --git a/services/inputflinger/reader/mapper/SensorInputMapper.h b/services/inputflinger/reader/mapper/SensorInputMapper.h
index 1797fe3..27a6177 100644
--- a/services/inputflinger/reader/mapper/SensorInputMapper.h
+++ b/services/inputflinger/reader/mapper/SensorInputMapper.h
@@ -28,7 +28,7 @@
explicit SensorInputMapper(InputDeviceContext& deviceContext);
~SensorInputMapper() override;
- uint32_t getSources() override;
+ uint32_t getSources() const override;
void populateDeviceInfo(InputDeviceInfo* deviceInfo) override;
void dump(std::string& dump) override;
void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes) override;
diff --git a/services/inputflinger/reader/mapper/SwitchInputMapper.cpp b/services/inputflinger/reader/mapper/SwitchInputMapper.cpp
index 3237824..ebb5de6 100644
--- a/services/inputflinger/reader/mapper/SwitchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/SwitchInputMapper.cpp
@@ -25,7 +25,7 @@
SwitchInputMapper::~SwitchInputMapper() {}
-uint32_t SwitchInputMapper::getSources() {
+uint32_t SwitchInputMapper::getSources() const {
return AINPUT_SOURCE_SWITCH;
}
diff --git a/services/inputflinger/reader/mapper/SwitchInputMapper.h b/services/inputflinger/reader/mapper/SwitchInputMapper.h
index 4d74163..64b9aa2 100644
--- a/services/inputflinger/reader/mapper/SwitchInputMapper.h
+++ b/services/inputflinger/reader/mapper/SwitchInputMapper.h
@@ -26,7 +26,7 @@
explicit SwitchInputMapper(InputDeviceContext& deviceContext);
virtual ~SwitchInputMapper();
- virtual uint32_t getSources() override;
+ virtual uint32_t getSources() const override;
virtual void process(const RawEvent* rawEvent) override;
virtual int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode) override;
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
index 0a5de27..4772beb 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
@@ -178,7 +178,7 @@
TouchInputMapper::~TouchInputMapper() {}
-uint32_t TouchInputMapper::getSources() {
+uint32_t TouchInputMapper::getSources() const {
return mSource;
}
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.h b/services/inputflinger/reader/mapper/TouchInputMapper.h
index 9fd30e4..c948f56 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.h
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.h
@@ -138,7 +138,7 @@
explicit TouchInputMapper(InputDeviceContext& deviceContext);
~TouchInputMapper() override;
- uint32_t getSources() override;
+ uint32_t getSources() const override;
void populateDeviceInfo(InputDeviceInfo* deviceInfo) override;
void dump(std::string& dump) override;
void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes) override;
diff --git a/services/inputflinger/reader/mapper/VibratorInputMapper.cpp b/services/inputflinger/reader/mapper/VibratorInputMapper.cpp
index 1976fed..33db527 100644
--- a/services/inputflinger/reader/mapper/VibratorInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/VibratorInputMapper.cpp
@@ -25,7 +25,7 @@
VibratorInputMapper::~VibratorInputMapper() {}
-uint32_t VibratorInputMapper::getSources() {
+uint32_t VibratorInputMapper::getSources() const {
return 0;
}
diff --git a/services/inputflinger/reader/mapper/VibratorInputMapper.h b/services/inputflinger/reader/mapper/VibratorInputMapper.h
index 7ce621a..d3c22b6 100644
--- a/services/inputflinger/reader/mapper/VibratorInputMapper.h
+++ b/services/inputflinger/reader/mapper/VibratorInputMapper.h
@@ -26,7 +26,7 @@
explicit VibratorInputMapper(InputDeviceContext& deviceContext);
virtual ~VibratorInputMapper();
- virtual uint32_t getSources() override;
+ virtual uint32_t getSources() const override;
virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo) override;
virtual void process(const RawEvent* rawEvent) override;
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 2c5b321..e2596f0 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -439,6 +439,8 @@
KeyedVector<int32_t, KeyInfo> keysByScanCode;
KeyedVector<int32_t, KeyInfo> keysByUsageCode;
KeyedVector<int32_t, bool> leds;
+ // fake mapping which would normally come from keyCharacterMap
+ std::unordered_map<int32_t, int32_t> keyCodeMapping;
std::unordered_map<int32_t, SensorInfo> sensorsByAbsCode;
BitArray<MSC_MAX> mscBitmask;
std::vector<VirtualKeyDefinition> virtualKeys;
@@ -600,6 +602,11 @@
}
}
+ void addKeyCodeMapping(int32_t deviceId, int32_t fromKeyCode, int32_t toKeyCode) {
+ Device* device = getDevice(deviceId);
+ device->keyCodeMapping.insert_or_assign(fromKeyCode, toKeyCode);
+ }
+
void addLed(int32_t deviceId, int32_t led, bool initialState) {
Device* device = getDevice(deviceId);
device->leds.add(led, initialState);
@@ -863,6 +870,15 @@
return -1;
}
+ int32_t getKeyCodeForKeyLocation(int32_t deviceId, int32_t locationKeyCode) const override {
+ Device* device = getDevice(deviceId);
+ if (!device) {
+ return AKEYCODE_UNKNOWN;
+ }
+ auto it = device->keyCodeMapping.find(locationKeyCode);
+ return it != device->keyCodeMapping.end() ? it->second : locationKeyCode;
+ }
+
// Return true if the device has non-empty key layout.
bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const int32_t* keyCodes,
uint8_t* outFlags) const override {
@@ -1034,6 +1050,8 @@
KeyedVector<int32_t, int32_t> mKeyCodeStates;
KeyedVector<int32_t, int32_t> mScanCodeStates;
KeyedVector<int32_t, int32_t> mSwitchStates;
+ // fake mapping which would normally come from keyCharacterMap
+ std::unordered_map<int32_t, int32_t> mKeyCodeMapping;
std::vector<int32_t> mSupportedKeyCodes;
std::mutex mLock;
@@ -1122,8 +1140,12 @@
mSupportedKeyCodes.push_back(keyCode);
}
+ void addKeyCodeMapping(int32_t fromKeyCode, int32_t toKeyCode) {
+ mKeyCodeMapping.insert_or_assign(fromKeyCode, toKeyCode);
+ }
+
private:
- uint32_t getSources() override { return mSources; }
+ uint32_t getSources() const override { return mSources; }
void populateDeviceInfo(InputDeviceInfo* deviceInfo) override {
InputMapper::populateDeviceInfo(deviceInfo);
@@ -1164,6 +1186,11 @@
return index >= 0 ? mKeyCodeStates.valueAt(index) : AKEY_STATE_UNKNOWN;
}
+ int32_t getKeyCodeForKeyLocation(int32_t locationKeyCode) const override {
+ auto it = mKeyCodeMapping.find(locationKeyCode);
+ return it != mKeyCodeMapping.end() ? it->second : locationKeyCode;
+ }
+
int32_t getScanCodeState(uint32_t, int32_t scanCode) override {
ssize_t index = mScanCodeStates.indexOfKey(scanCode);
return index >= 0 ? mScanCodeStates.valueAt(index) : AKEY_STATE_UNKNOWN;
@@ -1712,6 +1739,37 @@
<< "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
}
+TEST_F(InputReaderTest, GetKeyCodeForKeyLocation_ForwardsRequestsToMappers) {
+ constexpr int32_t deviceId = END_RESERVED_ID + 1000;
+ constexpr int32_t eventHubId = 1;
+ FakeInputMapper& mapper = addDeviceWithFakeInputMapper(deviceId, eventHubId, "keyboard",
+ InputDeviceClass::KEYBOARD,
+ AINPUT_SOURCE_KEYBOARD, nullptr);
+ mapper.addKeyCodeMapping(AKEYCODE_Y, AKEYCODE_Z);
+
+ ASSERT_EQ(AKEYCODE_UNKNOWN, mReader->getKeyCodeForKeyLocation(0, AKEYCODE_Y))
+ << "Should return unknown when the device with the specified id is not found.";
+
+ ASSERT_EQ(AKEYCODE_Z, mReader->getKeyCodeForKeyLocation(deviceId, AKEYCODE_Y))
+ << "Should return correct mapping when device id is valid and mapping exists.";
+
+ ASSERT_EQ(AKEYCODE_A, mReader->getKeyCodeForKeyLocation(deviceId, AKEYCODE_A))
+ << "Should return the location key code when device id is valid and there's no "
+ "mapping.";
+}
+
+TEST_F(InputReaderTest, GetKeyCodeForKeyLocation_NoKeyboardMapper) {
+ constexpr int32_t deviceId = END_RESERVED_ID + 1000;
+ constexpr int32_t eventHubId = 1;
+ FakeInputMapper& mapper = addDeviceWithFakeInputMapper(deviceId, eventHubId, "joystick",
+ InputDeviceClass::JOYSTICK,
+ AINPUT_SOURCE_GAMEPAD, nullptr);
+ mapper.addKeyCodeMapping(AKEYCODE_Y, AKEYCODE_Z);
+
+ ASSERT_EQ(AKEYCODE_UNKNOWN, mReader->getKeyCodeForKeyLocation(deviceId, AKEYCODE_Y))
+ << "Should return unknown when the device id is valid but there is no keyboard mapper";
+}
+
TEST_F(InputReaderTest, GetScanCodeState_ForwardsRequestsToMappers) {
constexpr int32_t deviceId = END_RESERVED_ID + 1000;
constexpr Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
@@ -3609,6 +3667,19 @@
ASSERT_EQ(0, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
}
+TEST_F(KeyboardInputMapperTest, GetKeyCodeForKeyLocation) {
+ KeyboardInputMapper& mapper =
+ addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
+ AINPUT_KEYBOARD_TYPE_ALPHABETIC);
+
+ mFakeEventHub->addKeyCodeMapping(EVENTHUB_ID, AKEYCODE_Y, AKEYCODE_Z);
+ ASSERT_EQ(AKEYCODE_Z, mapper.getKeyCodeForKeyLocation(AKEYCODE_Y))
+ << "If a mapping is available, the result is equal to the mapping";
+
+ ASSERT_EQ(AKEYCODE_A, mapper.getKeyCodeForKeyLocation(AKEYCODE_A))
+ << "If no mapping is available, the result is the key location";
+}
+
TEST_F(KeyboardInputMapperTest, GetScanCodeState) {
KeyboardInputMapper& mapper =
addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 192ee04..162d84e 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -1059,9 +1059,11 @@
// If we have a valid current display brightness use that, otherwise fall back to the
// display's max desired
- clientCompositionDisplay.maxLuminance = outputState.displayBrightnessNits > 0.f
+ clientCompositionDisplay.currentLuminanceNits = outputState.displayBrightnessNits > 0.f
? outputState.displayBrightnessNits
: mDisplayColorProfile->getHdrCapabilities().getDesiredMaxLuminance();
+ clientCompositionDisplay.maxLuminance =
+ mDisplayColorProfile->getHdrCapabilities().getDesiredMaxLuminance();
clientCompositionDisplay.targetLuminanceNits = outputState.clientTargetWhitePointNits;
// Compute the global color transform matrix.
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index b13e13c..655db4b 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -3072,6 +3072,8 @@
static constexpr float kDefaultMaxLuminance = 0.9f;
static constexpr float kDefaultAvgLuminance = 0.7f;
static constexpr float kDefaultMinLuminance = 0.1f;
+ static constexpr float kUnknownLuminance = -1.f;
+ static constexpr float kDisplayLuminance = 80.f;
static constexpr float kClientTargetLuminanceNits = 200.f;
static const Rect kDefaultOutputFrame;
@@ -3105,6 +3107,7 @@
const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
+
const HdrCapabilities OutputComposeSurfacesTest::
kHdrCapabilities{{},
OutputComposeSurfacesTest::kDefaultMaxLuminance,
@@ -3408,6 +3411,14 @@
auto andIfUsesHdr(bool used) {
EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
.WillOnce(Return(used));
+ return nextState<OutputWithDisplayBrightnessNits>();
+ }
+ };
+
+ struct OutputWithDisplayBrightnessNits
+ : public CallOrderStateMachineHelper<TestType, OutputWithDisplayBrightnessNits> {
+ auto withDisplayBrightnessNits(float nits) {
+ getInstance()->mOutput.mState.displayBrightnessNits = nits;
return nextState<SkipColorTransformState>();
}
};
@@ -3439,11 +3450,34 @@
TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
verify().ifMixedCompositionIs(true)
.andIfUsesHdr(true)
+ .withDisplayBrightnessNits(kUnknownLuminance)
.andIfSkipColorTransform(false)
- .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
- kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
- kDefaultOutputOrientationFlags,
- kClientTargetLuminanceNits})
+ .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
+ .clip = kDefaultOutputViewport,
+ .maxLuminance = kDefaultMaxLuminance,
+ .currentLuminanceNits = kDefaultMaxLuminance,
+ .outputDataspace = kDefaultOutputDataspace,
+ .colorTransform = mat4(),
+ .orientation = kDefaultOutputOrientationFlags,
+ .targetLuminanceNits = kClientTargetLuminanceNits})
+ .execute()
+ .expectAFenceWasReturned();
+}
+
+TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
+ forHdrMixedCompositionWithDisplayBrightness) {
+ verify().ifMixedCompositionIs(true)
+ .andIfUsesHdr(true)
+ .withDisplayBrightnessNits(kDisplayLuminance)
+ .andIfSkipColorTransform(false)
+ .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
+ .clip = kDefaultOutputViewport,
+ .maxLuminance = kDefaultMaxLuminance,
+ .currentLuminanceNits = kDisplayLuminance,
+ .outputDataspace = kDefaultOutputDataspace,
+ .colorTransform = mat4(),
+ .orientation = kDefaultOutputOrientationFlags,
+ .targetLuminanceNits = kClientTargetLuminanceNits})
.execute()
.expectAFenceWasReturned();
}
@@ -3451,11 +3485,16 @@
TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
verify().ifMixedCompositionIs(true)
.andIfUsesHdr(false)
+ .withDisplayBrightnessNits(kUnknownLuminance)
.andIfSkipColorTransform(false)
- .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
- kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
- kDefaultOutputOrientationFlags,
- kClientTargetLuminanceNits})
+ .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
+ .clip = kDefaultOutputViewport,
+ .maxLuminance = kDefaultMaxLuminance,
+ .currentLuminanceNits = kDefaultMaxLuminance,
+ .outputDataspace = kDefaultOutputDataspace,
+ .colorTransform = mat4(),
+ .orientation = kDefaultOutputOrientationFlags,
+ .targetLuminanceNits = kClientTargetLuminanceNits})
.execute()
.expectAFenceWasReturned();
}
@@ -3463,11 +3502,16 @@
TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
verify().ifMixedCompositionIs(false)
.andIfUsesHdr(true)
+ .withDisplayBrightnessNits(kUnknownLuminance)
.andIfSkipColorTransform(false)
- .thenExpectDisplaySettingsUsed(
- {kDefaultOutputDestinationClip, kDefaultOutputViewport, kDefaultMaxLuminance,
- kDefaultOutputDataspace, kDefaultColorTransformMat,
- kDefaultOutputOrientationFlags, kClientTargetLuminanceNits})
+ .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
+ .clip = kDefaultOutputViewport,
+ .maxLuminance = kDefaultMaxLuminance,
+ .currentLuminanceNits = kDefaultMaxLuminance,
+ .outputDataspace = kDefaultOutputDataspace,
+ .colorTransform = kDefaultColorTransformMat,
+ .orientation = kDefaultOutputOrientationFlags,
+ .targetLuminanceNits = kClientTargetLuminanceNits})
.execute()
.expectAFenceWasReturned();
}
@@ -3475,11 +3519,16 @@
TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
verify().ifMixedCompositionIs(false)
.andIfUsesHdr(false)
+ .withDisplayBrightnessNits(kUnknownLuminance)
.andIfSkipColorTransform(false)
- .thenExpectDisplaySettingsUsed(
- {kDefaultOutputDestinationClip, kDefaultOutputViewport, kDefaultMaxLuminance,
- kDefaultOutputDataspace, kDefaultColorTransformMat,
- kDefaultOutputOrientationFlags, kClientTargetLuminanceNits})
+ .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
+ .clip = kDefaultOutputViewport,
+ .maxLuminance = kDefaultMaxLuminance,
+ .currentLuminanceNits = kDefaultMaxLuminance,
+ .outputDataspace = kDefaultOutputDataspace,
+ .colorTransform = kDefaultColorTransformMat,
+ .orientation = kDefaultOutputOrientationFlags,
+ .targetLuminanceNits = kClientTargetLuminanceNits})
.execute()
.expectAFenceWasReturned();
}
@@ -3488,11 +3537,16 @@
usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
verify().ifMixedCompositionIs(false)
.andIfUsesHdr(true)
+ .withDisplayBrightnessNits(kUnknownLuminance)
.andIfSkipColorTransform(true)
- .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
- kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
- kDefaultOutputOrientationFlags,
- kClientTargetLuminanceNits})
+ .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
+ .clip = kDefaultOutputViewport,
+ .maxLuminance = kDefaultMaxLuminance,
+ .currentLuminanceNits = kDefaultMaxLuminance,
+ .outputDataspace = kDefaultOutputDataspace,
+ .colorTransform = mat4(),
+ .orientation = kDefaultOutputOrientationFlags,
+ .targetLuminanceNits = kClientTargetLuminanceNits})
.execute()
.expectAFenceWasReturned();
}
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 4cdd8fa..0f72a46 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -98,6 +98,7 @@
uid_t callingUid;
uint32_t textureName;
std::optional<uint32_t> sequence = std::nullopt;
+ bool addToRoot = true;
};
class Layer : public virtual RefBase, compositionengine::LayerFE {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 0a8f9ec..f7b243a 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2139,7 +2139,8 @@
bool needsTraversal = false;
if (clearTransactionFlags(eTransactionFlushNeeded)) {
- needsTraversal = flushTransactionQueues(vsyncId);
+ needsTraversal |= commitCreatedLayers();
+ needsTraversal |= flushTransactionQueues(vsyncId);
}
const bool shouldCommit =
@@ -2181,6 +2182,11 @@
updateCursorAsync();
updateInputFlinger();
+ if (mLayerTracingEnabled && !mLayerTracing.flagIsSet(LayerTracing::TRACE_COMPOSITION)) {
+ // This will block and tracing should only be enabled for debugging.
+ mLayerTracing.notify(mVisibleRegionsDirty, frameTime);
+ }
+
MAIN_THREAD_GUARD(persistDisplayBrightness(mustComposite));
return mustComposite && CC_LIKELY(mBootStage != BootStage::BOOTLOADER);
@@ -2282,13 +2288,9 @@
modulateVsync(&VsyncModulator::onDisplayRefresh, usedGpuComposition);
mLayersWithQueuedFrames.clear();
- if (mLayerTracingEnabled) {
+ if (mLayerTracingEnabled && mLayerTracing.flagIsSet(LayerTracing::TRACE_COMPOSITION)) {
// This will block and should only be used for debugging.
- if (mVisibleRegionsDirty) {
- mLayerTracing.notify("visibleRegionsDirty");
- } else if (mLayerTracing.flagIsSet(LayerTracing::TRACE_BUFFERS)) {
- mLayerTracing.notify("bufferLatched");
- }
+ mLayerTracing.notify(mVisibleRegionsDirty, frameTime);
}
mVisibleRegionsWereDirtyThisFrame = mVisibleRegionsDirty; // Cache value for use in post-comp
@@ -3605,7 +3607,7 @@
}
status_t SurfaceFlinger::addClientLayer(const sp<Client>& client, const sp<IBinder>& handle,
- const sp<Layer>& lbc, const wp<Layer>& parent,
+ const sp<Layer>& layer, const wp<Layer>& parent,
bool addToRoot, uint32_t* outTransformHint) {
if (mNumLayers >= ISurfaceComposer::MAX_LAYERS) {
ALOGE("AddClientLayer failed, mNumLayers (%zu) >= MAX_LAYERS (%zu)", mNumLayers.load(),
@@ -3613,31 +3615,22 @@
return NO_MEMORY;
}
- setLayerCreatedState(handle, lbc, parent, addToRoot);
+ {
+ std::scoped_lock<std::mutex> lock(mCreatedLayersLock);
+ mCreatedLayers.emplace_back(layer, parent, addToRoot);
+ }
- // Create a transaction includes the initial parent and producer.
- Vector<ComposerState> states;
- Vector<DisplayState> displays;
-
- ComposerState composerState;
- composerState.state.what = layer_state_t::eLayerCreated;
- composerState.state.surface = handle;
- states.add(composerState);
-
- lbc->updateTransformHint(mActiveDisplayTransformHint);
+ layer->updateTransformHint(mActiveDisplayTransformHint);
if (outTransformHint) {
*outTransformHint = mActiveDisplayTransformHint;
}
// attach this layer to the client
if (client != nullptr) {
- client->attachLayer(handle, lbc);
+ client->attachLayer(handle, layer);
}
- int64_t transactionId = (((int64_t)mPid) << 32) | mUniqueTransactionId++;
- return setTransactionState(FrameTimelineInfo{}, states, displays, 0 /* flags */, nullptr,
- InputWindowCommands{}, -1 /* desiredPresentTime */,
- true /* isAutoTimestamp */, {}, false /* hasListenerCallbacks */, {},
- transactionId);
+ setTransactionFlags(eTransactionNeeded);
+ return NO_ERROR;
}
uint32_t SurfaceFlinger::getTransactionFlags() const {
@@ -4222,15 +4215,7 @@
uint32_t flags = 0;
sp<Layer> layer = nullptr;
if (s.surface) {
- if (what & layer_state_t::eLayerCreated) {
- layer = handleLayerCreatedLocked(s.surface);
- if (layer) {
- flags |= eTransactionNeeded | eTraversalNeeded;
- mLayersAdded = true;
- }
- } else {
- layer = fromHandle(s.surface).promote();
- }
+ layer = fromHandle(s.surface).promote();
} else {
// The client may provide us a null handle. Treat it as if the layer was removed.
ALOGW("Attempt to set client state with a null layer handle");
@@ -4574,7 +4559,7 @@
args.name, mirrorFrom->sequence);
}
return addClientLayer(args.client, *outHandle, mirrorLayer /* layer */, nullptr /* parent */,
- false /* addAsRoot */, nullptr /* outTransformHint */);
+ false /* addToRoot */, nullptr /* outTransformHint */);
}
status_t SurfaceFlinger::createLayer(LayerCreationArgs& args, sp<IBinder>* outHandle,
@@ -4614,7 +4599,7 @@
return result;
}
- bool addToRoot = callingThreadHasUnscopedSurfaceFlingerAccess();
+ bool addToRoot = args.addToRoot && callingThreadHasUnscopedSurfaceFlingerAccess();
wp<Layer> parent(parentHandle != nullptr ? fromHandle(parentHandle) : parentLayer);
if (parentHandle != nullptr && parent == nullptr) {
ALOGE("Invalid parent handle %p.", parentHandle.get());
@@ -4641,7 +4626,6 @@
return result;
}
- setTransactionFlags(eTransactionNeeded);
*outLayerId = layer->sequence;
return result;
}
@@ -5605,9 +5589,9 @@
code == IBinder::SYSPROPS_TRANSACTION) {
return OK;
}
- // Numbers from 1000 to 1041 are currently used for backdoors. The code
+ // Numbers from 1000 to 1042 are currently used for backdoors. The code
// in onTransact verifies that the user is root, and has access to use SF.
- if (code >= 1000 && code <= 1041) {
+ if (code >= 1000 && code <= 1042) {
ALOGV("Accessing SurfaceFlinger through backdoor code: %u", code);
return OK;
}
@@ -5794,12 +5778,18 @@
}
case 1025: { // Set layer tracing
n = data.readInt32();
+ int64_t fixedStartingTime = data.readInt64();
bool tracingEnabledChanged;
if (n) {
ALOGD("LayerTracing enabled");
tracingEnabledChanged = mLayerTracing.enable();
if (tracingEnabledChanged) {
- mScheduler->schedule([&]() MAIN_THREAD { mLayerTracing.notify("start"); })
+ int64_t startingTime =
+ (fixedStartingTime) ? fixedStartingTime : systemTime();
+ mScheduler
+ ->schedule([&]() MAIN_THREAD {
+ mLayerTracing.notify("start", startingTime);
+ })
.wait();
}
} else {
@@ -6062,6 +6052,16 @@
reply->writeInt32(NO_ERROR);
return NO_ERROR;
}
+ case 1042: { // Write layers trace or transaction trace to file
+ if (mTransactionTracing) {
+ mTransactionTracing->writeToFile();
+ }
+ if (mLayerTracingEnabled) {
+ mLayerTracing.writeToFile();
+ }
+ reply->writeInt32(NO_ERROR);
+ return NO_ERROR;
+ }
}
}
return err;
@@ -7090,53 +7090,19 @@
}
}
-void SurfaceFlinger::setLayerCreatedState(const sp<IBinder>& handle, const wp<Layer>& layer,
- const wp<Layer> parent, bool addToRoot) {
- Mutex::Autolock lock(mCreatedLayersLock);
- mCreatedLayers[handle->localBinder()] =
- std::make_unique<LayerCreatedState>(layer, parent, addToRoot);
-}
-
-auto SurfaceFlinger::getLayerCreatedState(const sp<IBinder>& handle) {
- Mutex::Autolock lock(mCreatedLayersLock);
- BBinder* b = nullptr;
- if (handle) {
- b = handle->localBinder();
- }
-
- if (b == nullptr) {
- return std::unique_ptr<LayerCreatedState>(nullptr);
- }
-
- auto it = mCreatedLayers.find(b);
- if (it == mCreatedLayers.end()) {
- ALOGE("Can't find layer from handle %p", handle.get());
- return std::unique_ptr<LayerCreatedState>(nullptr);
- }
-
- auto state = std::move(it->second);
- mCreatedLayers.erase(it);
- return state;
-}
-
-sp<Layer> SurfaceFlinger::handleLayerCreatedLocked(const sp<IBinder>& handle) {
- const auto& state = getLayerCreatedState(handle);
- if (!state) {
- return nullptr;
- }
-
- sp<Layer> layer = state->layer.promote();
+void SurfaceFlinger::handleLayerCreatedLocked(const LayerCreatedState& state) {
+ sp<Layer> layer = state.layer.promote();
if (!layer) {
- ALOGE("Invalid layer %p", state->layer.unsafe_get());
- return nullptr;
+ ALOGD("Layer was destroyed soon after creation %p", state.layer.unsafe_get());
+ return;
}
sp<Layer> parent;
- bool addToRoot = state->addToRoot;
- if (state->initialParent != nullptr) {
- parent = state->initialParent.promote();
+ bool addToRoot = state.addToRoot;
+ if (state.initialParent != nullptr) {
+ parent = state.initialParent.promote();
if (parent == nullptr) {
- ALOGE("Invalid parent %p", state->initialParent.unsafe_get());
+ ALOGD("Parent was destroyed soon after creation %p", state.initialParent.unsafe_get());
addToRoot = false;
}
}
@@ -7156,7 +7122,6 @@
layer->updateTransformHint(mActiveDisplayTransformHint);
mInterceptor->saveSurfaceCreation(layer);
- return layer;
}
void SurfaceFlinger::sample() {
@@ -7238,6 +7203,26 @@
layerName);
return buffer;
}
+
+bool SurfaceFlinger::commitCreatedLayers() {
+ std::vector<LayerCreatedState> createdLayers;
+ {
+ std::scoped_lock<std::mutex> lock(mCreatedLayersLock);
+ createdLayers = std::move(mCreatedLayers);
+ mCreatedLayers.clear();
+ if (createdLayers.size() == 0) {
+ return false;
+ }
+ }
+
+ Mutex::Autolock _l(mStateLock);
+ for (const auto& createdLayer : createdLayers) {
+ handleLayerCreatedLocked(createdLayer);
+ }
+ createdLayers.clear();
+ mLayersAdded = true;
+ return true;
+}
} // namespace android
#if defined(__gl_h_)
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 8ca9982..38f527b 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -1327,7 +1327,7 @@
std::unordered_map<DisplayId, sp<HdrLayerInfoReporter>> mHdrLayerInfoListeners
GUARDED_BY(mStateLock);
- mutable Mutex mCreatedLayersLock;
+ mutable std::mutex mCreatedLayersLock;
struct LayerCreatedState {
LayerCreatedState(const wp<Layer>& layer, const wp<Layer> parent, bool addToRoot)
: layer(layer), initialParent(parent), addToRoot(addToRoot) {}
@@ -1343,11 +1343,9 @@
// A temporay pool that store the created layers and will be added to current state in main
// thread.
- std::unordered_map<BBinder*, std::unique_ptr<LayerCreatedState>> mCreatedLayers;
- void setLayerCreatedState(const sp<IBinder>& handle, const wp<Layer>& layer,
- const wp<Layer> parent, bool addToRoot);
- auto getLayerCreatedState(const sp<IBinder>& handle);
- sp<Layer> handleLayerCreatedLocked(const sp<IBinder>& handle) REQUIRES(mStateLock);
+ std::vector<LayerCreatedState> mCreatedLayers GUARDED_BY(mCreatedLayersLock);
+ bool commitCreatedLayers();
+ void handleLayerCreatedLocked(const LayerCreatedState& state) REQUIRES(mStateLock);
std::atomic<ui::Transform::RotationFlags> mActiveDisplayTransformHint;
diff --git a/services/surfaceflinger/Tracing/LayerTracing.cpp b/services/surfaceflinger/Tracing/LayerTracing.cpp
index d136e0b..006efdf 100644
--- a/services/surfaceflinger/Tracing/LayerTracing.cpp
+++ b/services/surfaceflinger/Tracing/LayerTracing.cpp
@@ -98,16 +98,20 @@
mBuffer->dump(result);
}
-void LayerTracing::notify(const char* where) {
- ATRACE_CALL();
+void LayerTracing::notify(bool visibleRegionDirty, int64_t time) {
std::scoped_lock lock(mTraceLock);
if (!mEnabled) {
return;
}
+ if (!visibleRegionDirty && !flagIsSet(LayerTracing::TRACE_BUFFERS)) {
+ return;
+ }
+
ATRACE_CALL();
LayersTraceProto entry;
- entry.set_elapsed_realtime_nanos(elapsedRealtimeNano());
+ entry.set_elapsed_realtime_nanos(time);
+ const char* where = visibleRegionDirty ? "visibleRegionsDirty" : "bufferLatched";
entry.set_where(where);
LayersProto layers(mFlinger.dumpDrawingStateProto(mFlags));
diff --git a/services/surfaceflinger/Tracing/LayerTracing.h b/services/surfaceflinger/Tracing/LayerTracing.h
index 8ca3587..bd448c9 100644
--- a/services/surfaceflinger/Tracing/LayerTracing.h
+++ b/services/surfaceflinger/Tracing/LayerTracing.h
@@ -47,7 +47,7 @@
bool isEnabled() const;
status_t writeToFile();
LayersTraceFileProto createTraceFileProto() const;
- void notify(const char* where);
+ void notify(bool visibleRegionDirty, int64_t time);
enum : uint32_t {
TRACE_INPUT = 1 << 1,
diff --git a/services/surfaceflinger/Tracing/TransactionTracing.cpp b/services/surfaceflinger/Tracing/TransactionTracing.cpp
index 5136295..a46b795 100644
--- a/services/surfaceflinger/Tracing/TransactionTracing.cpp
+++ b/services/surfaceflinger/Tracing/TransactionTracing.cpp
@@ -128,7 +128,9 @@
mCommittedTransactions.clear();
} // unlock mMainThreadLock
- addEntry(committedTransactions, removedLayers);
+ if (!committedTransactions.empty() || !removedLayers.empty()) {
+ addEntry(committedTransactions, removedLayers);
+ }
}
}
@@ -275,6 +277,7 @@
void TransactionTracing::updateStartingStateLocked(
const proto::TransactionTraceEntry& removedEntry) {
+ mStartingTimestamp = removedEntry.elapsed_realtime_nanos();
// Keep track of layer starting state so we can reconstruct the layer state as we purge
// transactions from the buffer.
for (const proto::LayerCreationArgs& addedLayer : removedEntry.added_layers()) {
@@ -303,13 +306,14 @@
}
void TransactionTracing::addStartingStateToProtoLocked(proto::TransactionTraceFile& proto) {
- proto::TransactionTraceEntry* entryProto = proto.add_entry();
- entryProto->set_elapsed_realtime_nanos(mStartingTimestamp);
- entryProto->set_vsync_id(0);
if (mStartingStates.size() == 0) {
return;
}
+ proto::TransactionTraceEntry* entryProto = proto.add_entry();
+ entryProto->set_elapsed_realtime_nanos(mStartingTimestamp);
+ entryProto->set_vsync_id(0);
+
entryProto->mutable_added_layers()->Reserve(static_cast<int32_t>(mStartingStates.size()));
for (auto& [layerId, state] : mStartingStates) {
entryProto->mutable_added_layers()->Add(TransactionProtoParser::toProto(state.args));
diff --git a/services/surfaceflinger/layerproto/transactions.proto b/services/surfaceflinger/layerproto/transactions.proto
index 9b076bd..fcf4499 100644
--- a/services/surfaceflinger/layerproto/transactions.proto
+++ b/services/surfaceflinger/layerproto/transactions.proto
@@ -89,7 +89,6 @@
eReleaseBufferListenerChanged = 0x00000400;
eShadowRadiusChanged = 0x00000800;
- eLayerCreated = 0x00001000;
eBufferCropChanged = 0x00002000;
eRelativeLayerChanged = 0x00004000;
eReparent = 0x00008000;
diff --git a/services/surfaceflinger/tests/unittests/TransactionTracingTest.cpp b/services/surfaceflinger/tests/unittests/TransactionTracingTest.cpp
index 5ac5812..39dbb07 100644
--- a/services/surfaceflinger/tests/unittests/TransactionTracingTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionTracingTest.cpp
@@ -91,10 +91,9 @@
flush(secondTransactionSetVsyncId);
proto::TransactionTraceFile proto = writeToProto();
- EXPECT_EQ(proto.entry().size(), 3);
- // skip starting entry
- verifyEntry(proto.entry(1), firstTransactionSet, firstTransactionSetVsyncId);
- verifyEntry(proto.entry(2), secondTransactionSet, secondTransactionSetVsyncId);
+ EXPECT_EQ(proto.entry().size(), 2);
+ verifyEntry(proto.entry(0), firstTransactionSet, firstTransactionSetVsyncId);
+ verifyEntry(proto.entry(1), secondTransactionSet, secondTransactionSetVsyncId);
}
class TransactionTracingLayerHandlingTest : public TransactionTracingTest {
@@ -274,15 +273,13 @@
TEST_F(TransactionTracingMirrorLayerTest, canAddMirrorLayers) {
proto::TransactionTraceFile proto = writeToProto();
// We don't have any starting states since no layer was removed from.
- EXPECT_EQ(proto.entry().size(), 2);
- EXPECT_EQ(proto.entry(0).transactions().size(), 0);
- EXPECT_EQ(proto.entry(0).added_layers().size(), 0);
+ EXPECT_EQ(proto.entry().size(), 1);
// Verify the mirror layer was added
- EXPECT_EQ(proto.entry(1).transactions().size(), 1);
- EXPECT_EQ(proto.entry(1).added_layers().size(), 2);
- EXPECT_EQ(proto.entry(1).added_layers(1).layer_id(), mMirrorLayerId);
- EXPECT_EQ(proto.entry(1).transactions(0).layer_changes().size(), 2);
- EXPECT_EQ(proto.entry(1).transactions(0).layer_changes(1).z(), 43);
+ EXPECT_EQ(proto.entry(0).transactions().size(), 1);
+ EXPECT_EQ(proto.entry(0).added_layers().size(), 2);
+ EXPECT_EQ(proto.entry(0).added_layers(1).layer_id(), mMirrorLayerId);
+ EXPECT_EQ(proto.entry(0).transactions(0).layer_changes().size(), 2);
+ EXPECT_EQ(proto.entry(0).transactions(0).layer_changes(1).z(), 43);
}
} // namespace android