Merge tag 'android-15.0.0_r10' into staging/lineage-22.1_merge-android-15.0.0_r10
Android 15.0.0 release 10
# -----BEGIN PGP SIGNATURE-----
#
# iF0EABECAB0WIQRDQNE1cO+UXoOBCWTorT+BmrEOeAUCZ32Y6wAKCRDorT+BmrEO
# eF+uAJ4ih5KzthOgb0Kd4LK/qvlPoIuQyACgiUklzqenLL/7h+KfWlr4somovr4=
# =rWiQ
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue Jan 7 23:13:15 2025 EET
# gpg: using DSA key 4340D13570EF945E83810964E8AD3F819AB10E78
# gpg: Can't check signature: No public key
# By Steven Moreland (2) and Frederick Mayle (1)
# Via Android Build Coastguard Worker
* tag 'android-15.0.0_r10':
binder: fix FD handling in continueWrite
libbinder: Parcel: validate read data before write
libbinder: Parcel: grow rejects large data pos
Change-Id: I8a0f49b42ecfa84a3007533dd36a74e437fa516e
diff --git a/include/powermanager/PowerManager.h b/include/powermanager/PowerManager.h
index 9bac242..d73e19f 100644
--- a/include/powermanager/PowerManager.h
+++ b/include/powermanager/PowerManager.h
@@ -44,6 +44,12 @@
THERMAL_STATUS_SHUTDOWN = 6,
};
+enum {
+ USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS = 1 << 0,
+ USER_ACTIVITY_FLAG_INDIRECT = 1 << 1,
+ USER_ACTIVITY_FLAG_NO_BUTTON_LIGHTS = 1 << 2,
+};
+
}; // namespace android
#endif // ANDROID_POWERMANAGER_H
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 1243b21..4a2ee20 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -309,10 +309,8 @@
],
}
-cc_library_shared {
- name: "libgui",
- vendor_available: true,
- double_loadable: true,
+cc_defaults {
+ name: "libgui_defaults",
defaults: [
"libgui-defaults",
@@ -505,4 +503,17 @@
],
}
+cc_library_shared {
+ name: "libgui",
+ double_loadable: true,
+ vendor_available: true,
+ defaults: ["libgui_defaults"]
+}
+
+cc_library_shared {
+ name: "libgui_vendor",
+ vendor: true,
+ defaults: ["libgui_defaults"]
+}
+
subdirs = ["tests"]
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index da74e9c..f1e5eb7 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -167,13 +167,14 @@
return BAD_VALUE;
}
- int bufferCount = mCore->getMinUndequeuedBufferCountLocked();
- bufferCount += maxDequeuedBuffers;
+ int minUndequedBufferCount = mCore->getMinUndequeuedBufferCountLocked();
+ int bufferCount = minUndequedBufferCount + maxDequeuedBuffers;
if (bufferCount > BufferQueueDefs::NUM_BUFFER_SLOTS) {
BQ_LOGE("setMaxDequeuedBufferCount: bufferCount %d too large "
"(max %d)", bufferCount, BufferQueueDefs::NUM_BUFFER_SLOTS);
- return BAD_VALUE;
+ bufferCount = BufferQueueDefs::NUM_BUFFER_SLOTS;
+ maxDequeuedBuffers = bufferCount - minUndequedBufferCount;
}
const int minBufferSlots = mCore->getMinMaxBufferCountLocked();
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index 12230f9..4664d04 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -153,6 +153,7 @@
"android.hardware.graphics.allocator-ndk_shared",
"android.hardware.graphics.common-ndk_shared",
"libui-defaults",
+ "gralloc_10_usage_bits_defaults",
// Uncomment the following line to enable VALIDATE_REGIONS traces
//defaults: ["libui-validate-regions-defaults"],
],
diff --git a/libs/ui/Gralloc2.cpp b/libs/ui/Gralloc2.cpp
index a5aca99..41306b5 100644
--- a/libs/ui/Gralloc2.cpp
+++ b/libs/ui/Gralloc2.cpp
@@ -48,6 +48,13 @@
for (const auto bit : hardware::hidl_enum_range<BufferUsage>()) {
bits = bits | bit;
}
+
+ if (ADDNL_GRALLOC_10_USAGE_BITS) {
+ uint64_t addnl_bits = static_cast<uint64_t>(ADDNL_GRALLOC_10_USAGE_BITS);
+ ALOGI("Adding additional valid usage bits: 0x%" PRIx64, addnl_bits);
+ bits = bits | addnl_bits;
+ }
+
return bits;
}();
return valid10UsageBits;
diff --git a/libs/ui/Gralloc3.cpp b/libs/ui/Gralloc3.cpp
index 152b35a..e9aa9c8 100644
--- a/libs/ui/Gralloc3.cpp
+++ b/libs/ui/Gralloc3.cpp
@@ -47,6 +47,13 @@
hardware::hidl_enum_range<hardware::graphics::common::V1_2::BufferUsage>()) {
bits = bits | bit;
}
+
+ if (ADDNL_GRALLOC_10_USAGE_BITS) {
+ uint64_t addnl_bits = static_cast<uint64_t>(ADDNL_GRALLOC_10_USAGE_BITS);
+ ALOGI("Adding additional valid usage bits: 0x%" PRIx64, addnl_bits);
+ bits = bits | addnl_bits;
+ }
+
return bits;
}();
return validUsageBits;
diff --git a/libs/ui/Gralloc4.cpp b/libs/ui/Gralloc4.cpp
index 2a60730..f1322f1 100644
--- a/libs/ui/Gralloc4.cpp
+++ b/libs/ui/Gralloc4.cpp
@@ -75,6 +75,13 @@
hardware::hidl_enum_range<hardware::graphics::common::V1_2::BufferUsage>()) {
bits = bits | bit;
}
+
+ if (ADDNL_GRALLOC_10_USAGE_BITS) {
+ uint64_t addnl_bits = static_cast<uint64_t>(ADDNL_GRALLOC_10_USAGE_BITS);
+ ALOGI("Adding additional valid usage bits: 0x%" PRIx64, addnl_bits);
+ bits = bits | addnl_bits;
+ }
+
return bits;
}();
return validUsageBits | kRemovedUsageBits;
diff --git a/opengl/libs/Android.bp b/opengl/libs/Android.bp
index 5159ffe..e4616a8 100644
--- a/opengl/libs/Android.bp
+++ b/opengl/libs/Android.bp
@@ -139,7 +139,11 @@
cc_library_shared {
name: "libEGL",
- defaults: ["egl_libs_defaults"],
+ defaults: [
+ "egl_libs_defaults",
+ "egl_display_array_defaults",
+ "nvidia_enhancements_defaults"
+ ],
llndk: {
symbol_file: "libEGL.map.txt",
export_llndk_headers: ["gl_headers"],
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index bf0e38e..7616e59 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -703,6 +703,11 @@
ALOGE_IF(!getProcAddress,
"can't find eglGetProcAddress() in EGL driver library");
+#ifdef NV_ANDROID_FRAMEWORK_ENHANCEMENTS
+ // This internally sets a bit in the main Nvidia EGL driver to enable desktop openGL
+ getProcAddress("eglSentinelForNVFrameworks");
+#endif
+
egl_t* egl = &cnx->egl;
__eglMustCastToProperFunctionPointerType* curr =
(__eglMustCastToProperFunctionPointerType*)egl;
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index b1a287f..132d97f 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -69,8 +69,12 @@
return eglDisplay ? eglDisplay->getRefsCount() : 0;
}
+#ifdef EGL_DISPLAY_ARRAY
+egl_display_t egl_display_t::sDisplay[NUM_DISPLAYS];
+#else
std::map<EGLDisplay, std::unique_ptr<egl_display_t>> egl_display_t::displayMap;
std::mutex egl_display_t::displayMapLock;
+#endif
egl_display_t::egl_display_t()
: magic('_dpy'),
@@ -89,12 +93,21 @@
return nullptr;
}
+#ifdef EGL_DISPLAY_ARRAY
+ uintptr_t index = uintptr_t(dpy) - 1U;
+ if (index >= NUM_DISPLAYS || !sDisplay[index].isValid()) {
+#else
const std::lock_guard<std::mutex> lock(displayMapLock);
auto search = displayMap.find(dpy);
if (search == displayMap.end() || !search->second->isValid()) {
+#endif
return nullptr;
}
+#ifdef EGL_DISPLAY_ARRAY
+ return &sDisplay[index];
+#else
return search->second.get();
+#endif
}
void egl_display_t::addObject(egl_object_t* object) {
@@ -122,7 +135,11 @@
const EGLAttrib* attrib_list) {
if (uintptr_t(disp) >= NUM_DISPLAYS) return nullptr;
+#ifdef EGL_DISPLAY_ARRAY
+ return sDisplay[uintptr_t(disp)].getPlatformDisplay(disp, attrib_list);
+#else
return getPlatformDisplay(disp, attrib_list);
+#endif
}
static EGLDisplay getPlatformDisplayAngle(EGLNativeDisplayType display, egl_connection_t* const cnx,
@@ -177,6 +194,9 @@
EGLDisplay egl_display_t::getPlatformDisplay(EGLNativeDisplayType display,
const EGLAttrib* attrib_list) {
+#ifdef EGL_DISPLAY_ARRAY
+ std::lock_guard<std::mutex> _l(lock);
+#endif
ATRACE_CALL();
// get our driver loader
@@ -212,9 +232,14 @@
}
}
+#ifdef EGL_DISPLAY_ARRAY
+ disp.dpy = dpy;
+#endif
if (dpy == EGL_NO_DISPLAY) {
loader.close(cnx);
- } else {
+ }
+#ifndef EGL_DISPLAY_ARRAY
+ else {
const std::lock_guard<std::mutex> lock(displayMapLock);
if (displayMap.find(dpy) == displayMap.end()) {
auto d = std::make_unique<egl_display_t>();
@@ -223,9 +248,14 @@
}
return dpy;
}
+#endif
}
+#ifdef EGL_DISPLAY_ARRAY
+ return EGLDisplay(uintptr_t(display) + 1U);
+#else
return nullptr;
+#endif
}
EGLBoolean egl_display_t::initialize(EGLint* major, EGLint* minor) {
diff --git a/opengl/libs/EGL/egl_display.h b/opengl/libs/EGL/egl_display.h
index 867a117..f6fc266 100644
--- a/opengl/libs/EGL/egl_display.h
+++ b/opengl/libs/EGL/egl_display.h
@@ -23,8 +23,10 @@
#include <stdint.h>
#include <condition_variable>
+#ifndef EGL_DISPLAY_ARRAY
#include <map>
#include <memory>
+#endif
#include <mutex>
#include <string>
#include <unordered_set>
@@ -41,11 +43,19 @@
bool findExtension(const char* exts, const char* name, size_t nameLen = 0);
class EGLAPI egl_display_t { // marked as EGLAPI for testing purposes
+#ifdef EGL_DISPLAY_ARRAY
+ static egl_display_t sDisplay[NUM_DISPLAYS];
+#else
static std::map<EGLDisplay, std::unique_ptr<egl_display_t>> displayMap;
static std::mutex displayMapLock;
+#endif
EGLDisplay getDisplay(EGLNativeDisplayType display);
+#ifdef EGL_DISPLAY_ARRAY
+ EGLDisplay getPlatformDisplay(EGLNativeDisplayType display, const EGLAttrib* attrib_list);
+#else
static EGLDisplay getPlatformDisplay(EGLNativeDisplayType display,
const EGLAttrib* attrib_list);
+#endif
void loseCurrentImpl(egl_context_t* cur_c);
public:
diff --git a/opengl/libs/EGL/egl_object.cpp b/opengl/libs/EGL/egl_object.cpp
index 33a77c4..9a787d4 100644
--- a/opengl/libs/EGL/egl_object.cpp
+++ b/opengl/libs/EGL/egl_object.cpp
@@ -317,7 +317,14 @@
// call the implementation's glGetString(GL_EXTENSIONS)
const char* exts = (const char*)gEGLImpl.hooks[version]->gl.glGetString(GL_EXTENSIONS);
- if (!exts) return;
+ if (!exts) {
+#ifndef NV_ANDROID_FRAMEWORK_ENHANCEMENTS
+ return;
+#else
+ gEGLImpl.hooks[version]->gl.glGetError();
+ exts = "";
+#endif
+}
// If this context is sharing with another context, and the other context was reset
// e.g. due to robustness failure, this context might also be reset and glGetString can
diff --git a/opengl/libs/EGL/egl_platform_entries.cpp b/opengl/libs/EGL/egl_platform_entries.cpp
index 6e35041..39e7dda 100644
--- a/opengl/libs/EGL/egl_platform_entries.cpp
+++ b/opengl/libs/EGL/egl_platform_entries.cpp
@@ -968,6 +968,12 @@
if (context != EGL_NO_CONTEXT) {
// figure out if it's a GLESv1 or GLESv2
int version = egl_connection_t::GLESv1_INDEX;
+
+#ifdef NV_ANDROID_FRAMEWORK_ENHANCEMENTS
+ if (cnx->egl.eglQueryAPI() == EGL_OPENGL_API)
+ version = egl_connection_t::GLESv2_INDEX;
+#endif
+
GLint version_value;
if (findAttribute(attrib_list, EGL_CONTEXT_CLIENT_VERSION, &version_value)) {
if (version_value == 2 || version_value == 3) {
@@ -1195,6 +1201,10 @@
addr = findBuiltinWrapper(procname);
if (addr) return addr;
+#ifdef NV_ANDROID_FRAMEWORK_ENHANCEMENTS
+ if (gEGLImpl.dso && gEGLImpl.egl.eglGetProcAddress)
+ addr = gEGLImpl.egl.eglGetProcAddress(procname);
+#else
// this protects accesses to sGLExtensionMap, sGLExtensionSlot, and sGLExtensionSlotMap
pthread_mutex_lock(&sExtensionMapMutex);
@@ -1279,6 +1289,7 @@
}
pthread_mutex_unlock(&sExtensionMapMutex);
+#endif
return addr;
}
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 05139cf..fa90cae 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -3299,6 +3299,7 @@
}
}
+ int32_t keyCode = AKEYCODE_UNKNOWN;
switch (eventEntry.type) {
case EventEntry::Type::MOTION: {
const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
@@ -3329,6 +3330,8 @@
}
return;
}
+
+ keyCode = keyEntry.keyCode;
break;
}
default: {
@@ -3339,10 +3342,10 @@
}
mLastUserActivityTimes[eventType] = eventEntry.eventTime;
- auto command = [this, eventTime = eventEntry.eventTime, eventType, displayId]()
+ auto command = [this, eventTime = eventEntry.eventTime, eventType, displayId, keyCode]()
REQUIRES(mLock) {
scoped_unlock unlock(mLock);
- mPolicy.pokeUserActivity(eventTime, eventType, displayId);
+ mPolicy.pokeUserActivity(eventTime, eventType, displayId, keyCode);
};
postCommandLocked(std::move(command));
}
diff --git a/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h b/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h
index b885ba1..489e5e9 100644
--- a/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h
+++ b/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h
@@ -123,7 +123,7 @@
/* Poke user activity for an event dispatched to a window. */
virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType,
- ui::LogicalDisplayId displayId) = 0;
+ ui::LogicalDisplayId displayId, int32_t keyCode) = 0;
/*
* Return true if the provided event is stale, and false otherwise. Used for determining
diff --git a/services/inputflinger/include/InputReaderBase.h b/services/inputflinger/include/InputReaderBase.h
index 2f6c6d7..d8e0507 100644
--- a/services/inputflinger/include/InputReaderBase.h
+++ b/services/inputflinger/include/InputReaderBase.h
@@ -96,6 +96,9 @@
// The key remapping has changed.
KEY_REMAPPING = 1u << 14,
+ // Volume keys rotation option changed.
+ VOLUME_KEYS_ROTATION = 1u << 15,
+
// All devices must be reopened.
MUST_REOPEN = 1u << 31,
};
@@ -252,6 +255,10 @@
// Keycodes to be remapped.
std::map<int32_t /* fromKeyCode */, int32_t /* toKeyCode */> keyRemapping;
+ // Remap volume keys according to display rotation
+ // 0 - disabled, 1 - phone or hybrid rotation mode, 2 - tablet rotation mode
+ int volumeKeysRotationMode;
+
InputReaderConfiguration()
: virtualKeyQuietTime(0),
defaultPointerDisplayId(ui::LogicalDisplayId::DEFAULT),
@@ -282,7 +289,8 @@
shouldNotifyTouchpadHardwareState(false),
touchpadRightClickZoneEnabled(false),
stylusButtonMotionEventsEnabled(true),
- stylusPointerIconEnabled(false) {}
+ stylusPointerIconEnabled(false),
+ volumeKeysRotationMode(0) {}
std::optional<DisplayViewport> getDisplayViewportByType(ViewportType type) const;
std::optional<DisplayViewport> getDisplayViewportByUniqueId(const std::string& uniqueDisplayId)
diff --git a/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp b/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
index 38dcd65..c1742d9 100644
--- a/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
@@ -28,10 +28,20 @@
// --- Static Definitions ---
-static int32_t rotateKeyCode(int32_t keyCode, ui::Rotation orientation) {
+static int32_t rotateKeyCode(int32_t keyCode, ui::Rotation orientation, int rotationMapOffset) {
static constexpr int32_t KEYCODE_ROTATION_MAP[][4] = {
// key codes enumerated counter-clockwise with the original (unrotated) key first
// no rotation, 90 degree rotation, 180 degree rotation, 270 degree rotation
+
+ // volume keys - tablet
+ {AKEYCODE_VOLUME_UP, AKEYCODE_VOLUME_UP, AKEYCODE_VOLUME_DOWN, AKEYCODE_VOLUME_DOWN},
+ {AKEYCODE_VOLUME_DOWN, AKEYCODE_VOLUME_DOWN, AKEYCODE_VOLUME_UP, AKEYCODE_VOLUME_UP},
+
+ // volume keys - phone or hybrid
+ {AKEYCODE_VOLUME_UP, AKEYCODE_VOLUME_DOWN, AKEYCODE_VOLUME_DOWN, AKEYCODE_VOLUME_UP},
+ {AKEYCODE_VOLUME_DOWN, AKEYCODE_VOLUME_UP, AKEYCODE_VOLUME_UP, AKEYCODE_VOLUME_DOWN},
+
+ // dpad keys - common
{AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT},
{AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN},
{AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT},
@@ -45,9 +55,12 @@
{AKEYCODE_SYSTEM_NAVIGATION_LEFT, AKEYCODE_SYSTEM_NAVIGATION_DOWN,
AKEYCODE_SYSTEM_NAVIGATION_RIGHT, AKEYCODE_SYSTEM_NAVIGATION_UP},
};
+ static const size_t KEYCODE_ROTATION_MAP_SIZE =
+ sizeof(KEYCODE_ROTATION_MAP) / sizeof(KEYCODE_ROTATION_MAP[0]);
if (orientation != ui::ROTATION_0) {
- for (const auto& rotation : KEYCODE_ROTATION_MAP) {
+ for (size_t i = rotationMapOffset; i < KEYCODE_ROTATION_MAP_SIZE; i++) {
+ const auto& rotation = KEYCODE_ROTATION_MAP[i];
if (rotation[static_cast<size_t>(ui::ROTATION_0)] == keyCode) {
return rotation[static_cast<size_t>(orientation)];
}
@@ -200,6 +213,14 @@
bumpGeneration();
}
}
+
+ if (!changes.any() || changes.test(InputReaderConfiguration::Change::VOLUME_KEYS_ROTATION)) {
+ // mode 0 (disabled) ~ offset 4
+ // mode 1 (phone) ~ offset 2
+ // mode 2 (tablet) ~ offset 0
+ mRotationMapOffset = 4 - 2 * config.volumeKeysRotationMode;
+ }
+
return out;
}
@@ -215,7 +236,8 @@
void KeyboardInputMapper::configureParameters() {
const PropertyMap& config = getDeviceContext().getConfiguration();
- mParameters.orientationAware = config.getBool("keyboard.orientationAware").value_or(false);
+ mParameters.orientationAware = config.getBool("keyboard.orientationAware").value_or(
+ !getDeviceContext().isExternal());
mParameters.handlesKeyRepeat = config.getBool("keyboard.handlesKeyRepeat").value_or(false);
mParameters.doNotWakeByDefault = config.getBool("keyboard.doNotWakeByDefault").value_or(false);
}
@@ -273,7 +295,7 @@
if (down) {
// Rotate key codes according to orientation if needed.
if (mParameters.orientationAware) {
- keyCode = rotateKeyCode(keyCode, getOrientation());
+ keyCode = rotateKeyCode(keyCode, getOrientation(), mRotationMapOffset);
}
// Add key down.
diff --git a/services/inputflinger/reader/mapper/KeyboardInputMapper.h b/services/inputflinger/reader/mapper/KeyboardInputMapper.h
index 2df0b85..3c811f9 100644
--- a/services/inputflinger/reader/mapper/KeyboardInputMapper.h
+++ b/services/inputflinger/reader/mapper/KeyboardInputMapper.h
@@ -66,6 +66,8 @@
std::optional<KeyboardLayoutInfo> mKeyboardLayoutInfo;
+ int32_t mRotationMapOffset; // determines if and how volume keys rotate
+
std::vector<KeyDown> mKeyDowns{}; // keys that are down
int32_t mMetaState{};
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index c2a9880..a0a49c1 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -48,6 +48,7 @@
"libsurfaceflinger_common_deps",
"surfaceflinger_defaults",
"libsurfaceflinger_proto_deps",
+ "surfaceflinger_qcom_ext_defaults",
],
cflags: [
"-DLOG_TAG=\"SurfaceFlinger\"",
diff --git a/services/surfaceflinger/CompositionEngine/Android.bp b/services/surfaceflinger/CompositionEngine/Android.bp
index b4ac9ba..3006077 100644
--- a/services/surfaceflinger/CompositionEngine/Android.bp
+++ b/services/surfaceflinger/CompositionEngine/Android.bp
@@ -86,6 +86,7 @@
"src/OutputLayer.cpp",
"src/OutputLayerCompositionState.cpp",
"src/RenderSurface.cpp",
+ "src/UdfpsExtension.cpp",
],
}
@@ -94,6 +95,7 @@
defaults: [
"libcompositionengine_defaults",
"libsurfaceflinger_common_deps",
+ "surfaceflinger_udfps_lib_defaults",
],
srcs: [
":libcompositionengine_sources",
@@ -128,6 +130,14 @@
export_include_dirs: ["include"],
}
+cc_library_static {
+ name: "surfaceflinger_udfps_lib",
+ srcs: [
+ "src/UdfpsExtension.cpp",
+ ],
+ export_include_dirs: ["include"],
+}
+
cc_test {
name: "libcompositionengine_test",
test_suites: ["device-tests"],
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/UdfpsExtension.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/UdfpsExtension.h
new file mode 100644
index 0000000..cf69da9
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/UdfpsExtension.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2021-2024 The LineageOS Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdint.h>
+
+#ifndef __UDFPS_EXTENSION__H__
+#define __UDFPS_EXTENSION__H__
+
+#define UDFPS_BIOMETRIC_PROMPT_LAYER_NAME "BiometricPrompt"
+#define UDFPS_DIM_LAYER_NAME "Dim Layer for UDFPS"
+#define UDFPS_LAYER_NAME "UdfpsControllerOverlay"
+#define UDFPS_TOUCHED_LAYER_NAME "SurfaceView[UdfpsControllerOverlay](BLAST)"
+
+extern uint32_t getUdfpsDimZOrder(uint32_t z);
+extern uint32_t getUdfpsZOrder(uint32_t z, bool touched);
+extern uint64_t getUdfpsUsageBits(uint64_t usageBits, bool touched);
+
+#endif /* __UDFPS_EXTENSION__H__ */
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 2d8f98f..9c145b6 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -24,6 +24,7 @@
#include <compositionengine/LayerFE.h>
#include <compositionengine/LayerFECompositionState.h>
#include <compositionengine/RenderSurface.h>
+#include <compositionengine/UdfpsExtension.h>
#include <compositionengine/impl/HwcAsyncWorker.h>
#include <compositionengine/impl/Output.h>
#include <compositionengine/impl/OutputCompositionState.h>
@@ -911,7 +912,10 @@
compositionengine::OutputLayer* Output::findLayerRequestingBackgroundComposition() const {
compositionengine::OutputLayer* layerRequestingBgComposition = nullptr;
- for (auto* layer : getOutputLayersOrderedByZ()) {
+ for (size_t i = 0; i < getOutputLayerCount(); i++) {
+ compositionengine::OutputLayer* layer = getOutputLayerOrderedByZByIndex(i);
+ compositionengine::OutputLayer* nextLayer = getOutputLayerOrderedByZByIndex(i + 1);
+
const auto* compState = layer->getLayerFE().getCompositionState();
// If any layer has a sideband stream, we will disable blurs. In that case, we don't
@@ -931,6 +935,16 @@
if (compState->backgroundBlurRadius > 0 || compState->blurRegions.size() > 0) {
layerRequestingBgComposition = layer;
}
+
+ // If the next layer is the Udfps touched layer, enable client composition for it
+ // because that somehow leads to the Udfps touched layer getting device composition
+ // consistently.
+ if ((nextLayer != nullptr && layerRequestingBgComposition == nullptr) &&
+ (strncmp(nextLayer->getLayerFE().getDebugName(), UDFPS_TOUCHED_LAYER_NAME,
+ strlen(UDFPS_TOUCHED_LAYER_NAME)) == 0)) {
+ layerRequestingBgComposition = layer;
+ break;
+ }
}
return layerRequestingBgComposition;
}
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
index 091c207..45f98eb 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
@@ -18,6 +18,7 @@
#include <compositionengine/DisplayColorProfile.h>
#include <compositionengine/LayerFECompositionState.h>
#include <compositionengine/Output.h>
+#include <compositionengine/UdfpsExtension.h>
#include <compositionengine/impl/HwcBufferCache.h>
#include <compositionengine/impl/OutputCompositionState.h>
#include <compositionengine/impl/OutputLayer.h>
@@ -457,7 +458,20 @@
sourceCrop.bottom, to_string(error).c_str(), static_cast<int32_t>(error));
}
- if (auto error = hwcLayer->setZOrder(z); error != hal::Error::NONE) {
+ uint32_t z_udfps = z;
+ if ((strncmp(getLayerFE().getDebugName(), UDFPS_LAYER_NAME, strlen(UDFPS_LAYER_NAME)) == 0) ||
+ (strncmp(getLayerFE().getDebugName(), UDFPS_BIOMETRIC_PROMPT_LAYER_NAME,
+ strlen(UDFPS_BIOMETRIC_PROMPT_LAYER_NAME)) == 0)) {
+ z_udfps = getUdfpsZOrder(z, false);
+ } else if (strncmp(getLayerFE().getDebugName(), UDFPS_DIM_LAYER_NAME,
+ strlen(UDFPS_DIM_LAYER_NAME)) == 0) {
+ z_udfps = getUdfpsDimZOrder(z);
+ } else if (strncmp(getLayerFE().getDebugName(), UDFPS_TOUCHED_LAYER_NAME,
+ strlen(UDFPS_TOUCHED_LAYER_NAME)) == 0) {
+ z_udfps = getUdfpsZOrder(z, true);
+ }
+
+ if (auto error = hwcLayer->setZOrder(z_udfps); error != hal::Error::NONE) {
ALOGE("[%s] Failed to set Z %u: %s (%d)", getLayerFE().getDebugName(), z,
to_string(error).c_str(), static_cast<int32_t>(error));
}
diff --git a/services/surfaceflinger/CompositionEngine/src/UdfpsExtension.cpp b/services/surfaceflinger/CompositionEngine/src/UdfpsExtension.cpp
new file mode 100644
index 0000000..5ae3815
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/src/UdfpsExtension.cpp
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2020-2024 The LineageOS Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef TARGET_PROVIDES_UDFPS_LIB
+#include <compositionengine/UdfpsExtension.h>
+
+uint32_t getUdfpsDimZOrder(uint32_t z) {
+ return z;
+}
+
+uint32_t getUdfpsZOrder(uint32_t z, __unused bool touched) {
+ return z;
+}
+
+uint64_t getUdfpsUsageBits(uint64_t usageBits, __unused bool touched) {
+ return usageBits;
+}
+#endif
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index 384f7b2..7e29bff 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -51,7 +51,7 @@
const sp<IGraphicBufferProducer>& sink,
const sp<IGraphicBufferProducer>& bqProducer,
const sp<IGraphicBufferConsumer>& bqConsumer,
- const std::string& name)
+ const std::string& name, bool secure)
#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
: ConsumerBase(bqProducer, bqConsumer),
#else
@@ -74,7 +74,9 @@
mOutputFence(Fence::NO_FENCE),
mFbProducerSlot(BufferQueue::INVALID_BUFFER_SLOT),
mOutputProducerSlot(BufferQueue::INVALID_BUFFER_SLOT),
- mForceHwcCopy(SurfaceFlinger::useHwcForRgbToYuv) {
+ mForceHwcCopy(SurfaceFlinger::useHwcForRgbToYuv),
+ mSecure(secure),
+ mSinkUsage(0) {
mSource[SOURCE_SINK] = sink;
mSource[SOURCE_SCRATCH] = bqProducer;
@@ -92,6 +94,8 @@
// on usage bits.
int sinkUsage;
sink->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, &sinkUsage);
+ mSinkUsage |= (GRALLOC_USAGE_HW_COMPOSER | sinkUsage);
+ setOutputUsage(mSinkUsage);
if (sinkUsage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) {
int sinkFormat;
sink->query(NATIVE_WINDOW_FORMAT, &sinkFormat);
@@ -124,7 +128,11 @@
}
mMustRecompose = mustRecompose;
-
+ //For WFD use cases we must always set the recompose flag in order
+ //to support pause/resume functionality
+ if (mOutputUsage & GRALLOC_USAGE_HW_VIDEO_ENCODER) {
+ mMustRecompose = true;
+ }
VDS_LOGW_IF(mDebugState != DebugState::Idle, "Unexpected %s in %s state", __func__,
ftl::enum_string(mDebugState).c_str());
mDebugState = DebugState::Begun;
@@ -161,7 +169,7 @@
}
if (mCompositionType != CompositionType::Gpu &&
- (mOutputFormat != mDefaultOutputFormat || mOutputUsage != GRALLOC_USAGE_HW_COMPOSER)) {
+ (mOutputFormat != mDefaultOutputFormat || !(mOutputUsage & GRALLOC_USAGE_HW_COMPOSER))) {
// We must have just switched from GPU-only to MIXED or HWC
// composition. Stop using the format and usage requested by the GPU
// driver; they may be suboptimal when HWC is writing to the output
@@ -173,7 +181,7 @@
// format/usage and get a new buffer when the GPU driver calls
// dequeueBuffer().
mOutputFormat = mDefaultOutputFormat;
- mOutputUsage = GRALLOC_USAGE_HW_COMPOSER;
+ setOutputUsage(GRALLOC_USAGE_HW_COMPOSER);
refreshOutputBuffer();
}
@@ -259,7 +267,7 @@
int sslot = mapProducer2SourceSlot(SOURCE_SINK, mOutputProducerSlot);
QueueBufferOutput qbo;
VDS_LOGV("%s: queue sink sslot=%d", __func__, sslot);
- if (mMustRecompose) {
+ if (retireFence->isValid() && mMustRecompose) {
status_t result = mSource[SOURCE_SINK]->queueBuffer(sslot,
QueueBufferInput(
systemTime(), false /* isAutoTimestamp */,
@@ -323,6 +331,14 @@
PixelFormat format, uint64_t usage, int* sslot, sp<Fence>* fence) {
LOG_ALWAYS_FATAL_IF(GpuVirtualDisplayId::tryCast(mDisplayId).has_value());
+ // Exclude video encoder usage flag from scratch buffer usage flags.
+ if (source == SOURCE_SCRATCH) {
+ usage |= GRALLOC_USAGE_HW_FB;
+ usage &= ~(GRALLOC_USAGE_HW_VIDEO_ENCODER);
+ VDS_LOGV("%s(%s): updated scratch buffer usage flags=%#" PRIx64,
+ __func__, ftl::enum_string(source).c_str(), usage);
+ }
+
status_t result =
mSource[source]->dequeueBuffer(sslot, fence, mSinkBufferWidth, mSinkBufferHeight,
format, usage, nullptr, nullptr);
@@ -352,11 +368,11 @@
}
}
if (result & BUFFER_NEEDS_REALLOCATION) {
- result = mSource[source]->requestBuffer(*sslot, &mProducerBuffers[pslot]);
- if (result < 0) {
+ auto status = mSource[source]->requestBuffer(*sslot, &mProducerBuffers[pslot]);
+ if (status < 0) {
mProducerBuffers[pslot].clear();
mSource[source]->cancelBuffer(*sslot, *fence);
- return result;
+ return status;
}
VDS_LOGV("%s(%s): buffers[%d]=%p fmt=%d usage=%#" PRIx64, __func__,
ftl::enum_string(source).c_str(), pslot, mProducerBuffers[pslot].get(),
@@ -417,7 +433,7 @@
__func__, w, h, format, usage, mSinkBufferWidth, mSinkBufferHeight,
buf->getPixelFormat(), buf->getUsage());
mOutputFormat = format;
- mOutputUsage = usage;
+ setOutputUsage(usage);
result = refreshOutputBuffer();
if (result < 0)
return result;
@@ -671,6 +687,21 @@
return type == CompositionType::Unknown ? "Unknown"s : ftl::Flags(type).string();
}
+/* Helper to update the output usage when the display is secure */
+
+void VirtualDisplaySurface::setOutputUsage(uint64_t /*flag*/) {
+
+ mOutputUsage = mSinkUsage;
+ if (mSecure && (mOutputUsage & GRALLOC_USAGE_HW_VIDEO_ENCODER)) {
+ /*TODO: Currently, the framework can only say whether the display
+ * and its subsequent session are secure or not. However, there is
+ * no mechanism to distinguish the different levels of security.
+ * The current solution assumes WV L3 protection.
+ */
+ mOutputUsage |= GRALLOC_USAGE_PROTECTED;
+ }
+}
+
} // namespace android
// TODO(b/129481165): remove the #pragma below and fix conversion issues
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
index 90426f7..805fce9 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
@@ -77,7 +77,8 @@
public:
VirtualDisplaySurface(HWComposer&, VirtualDisplayId, const sp<IGraphicBufferProducer>& sink,
const sp<IGraphicBufferProducer>& bqProducer,
- const sp<IGraphicBufferConsumer>& bqConsumer, const std::string& name);
+ const sp<IGraphicBufferConsumer>& bqConsumer,
+ const std::string& name, bool secure);
//
// DisplaySurface interface
@@ -134,6 +135,7 @@
sp<Fence>* outFence, float outTransformMatrix[16]) override;
virtual status_t getUniqueId(uint64_t* outId) const override;
virtual status_t getConsumerUsage(uint64_t* outUsage) const override;
+ virtual void setOutputUsage(uint64_t flag);
//
// Utility methods
@@ -265,6 +267,8 @@
bool mMustRecompose = false;
bool mForceHwcCopy;
+ bool mSecure;
+ int mSinkUsage;
};
} // namespace android
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 65a0ed3..23a2f9f 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -165,6 +165,14 @@
#include "Utils/Dumper.h"
#include "WindowInfosListenerInvoker.h"
+#ifdef QCOM_UM_FAMILY
+#if __has_include("QtiGralloc.h")
+#include "QtiGralloc.h"
+#else
+#include "gralloc_priv.h"
+#endif
+#endif
+
#include <aidl/android/hardware/graphics/common/DisplayDecorationSupport.h>
#include <aidl/android/hardware/graphics/composer3/DisplayCapability.h>
#include <aidl/android/hardware/graphics/composer3/RenderIntent.h>
@@ -640,8 +648,10 @@
}
VirtualDisplayId SurfaceFlinger::acquireVirtualDisplay(ui::Size resolution,
- ui::PixelFormat format) {
- if (auto& generator = mVirtualDisplayIdGenerators.hal) {
+ ui::PixelFormat format,
+ bool canAllocateHwcForVDS) {
+ auto& generator = mVirtualDisplayIdGenerators.hal;
+ if (canAllocateHwcForVDS && generator) {
if (const auto id = generator->generateId()) {
if (getHwComposer().allocateVirtualDisplay(*id, resolution, &format)) {
return *id;
@@ -899,9 +909,9 @@
enableLatchUnsignaledConfig = getLatchUnsignaledConfig();
- if (base::GetBoolProperty("debug.sf.enable_hwc_vds"s, false)) {
- enableHalVirtualDisplays(true);
- }
+ mAllowHwcForWFD = base::GetBoolProperty("vendor.display.vds_allow_hwc"s, false);
+ mAllowHwcForVDS = mAllowHwcForWFD && base::GetBoolProperty("debug.sf.enable_hwc_vds"s, false);
+ mFirstApiLevel = android::base::GetIntProperty("ro.product.first_api_level", 0);
// Process hotplug for displays connected at boot.
LOG_ALWAYS_FATAL_IF(!configureLocked(),
@@ -3657,6 +3667,11 @@
void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken,
const DisplayDeviceState& state) {
+#ifdef QCOM_UM_FAMILY
+ bool canAllocateHwcForVDS = false;
+#else
+ bool canAllocateHwcForVDS = true;
+#endif
ui::Size resolution(0, 0);
ui::PixelFormat pixelFormat = static_cast<ui::PixelFormat>(PIXEL_FORMAT_UNKNOWN);
if (state.physical) {
@@ -3671,6 +3686,20 @@
status = state.surface->query(NATIVE_WINDOW_FORMAT, &format);
ALOGE_IF(status != NO_ERROR, "Unable to query format (%d)", status);
pixelFormat = static_cast<ui::PixelFormat>(format);
+#ifdef QCOM_UM_FAMILY
+ // Check if VDS is allowed to use HWC
+ size_t maxVirtualDisplaySize = getHwComposer().getMaxVirtualDisplayDimension();
+ if (maxVirtualDisplaySize == 0 || ((uint64_t)resolution.width <= maxVirtualDisplaySize &&
+ (uint64_t)resolution.height <= maxVirtualDisplaySize)) {
+ uint64_t usage = 0;
+ // Replace with native_window_get_consumer_usage ?
+ status = state .surface->getConsumerUsage(&usage);
+ ALOGW_IF(status != NO_ERROR, "Unable to query usage (%d)", status);
+ if ((status == NO_ERROR) && canAllocateHwcDisplayIdForVDS(usage)) {
+ canAllocateHwcForVDS = true;
+ }
+ }
+#endif
} else {
// Virtual displays without a surface are dormant:
// they have external state (layer stack, projection,
@@ -3682,7 +3711,7 @@
if (const auto& physical = state.physical) {
builder.setId(physical->id);
} else {
- builder.setId(acquireVirtualDisplay(resolution, pixelFormat));
+ builder.setId(acquireVirtualDisplay(resolution, pixelFormat, canAllocateHwcForVDS));
}
builder.setPixels(resolution);
@@ -3703,7 +3732,8 @@
const auto displayId = VirtualDisplayId::tryCast(compositionDisplay->getId());
LOG_FATAL_IF(!displayId);
auto surface = sp<VirtualDisplaySurface>::make(getHwComposer(), *displayId, state.surface,
- bqProducer, bqConsumer, state.displayName);
+ bqProducer, bqConsumer, state.displayName,
+ state.isSecure);
displaySurface = surface;
producer = std::move(surface);
} else {
@@ -7787,6 +7817,35 @@
} // namespace
+#ifdef QCOM_UM_FAMILY
+bool SurfaceFlinger::canAllocateHwcDisplayIdForVDS(uint64_t usage) {
+ uint64_t flag_mask_pvt_wfd = ~0;
+ uint64_t flag_mask_hw_video = ~0;
+ // Reserve hardware acceleration for WFD use-case
+ // GRALLOC_USAGE_PRIVATE_WFD + GRALLOC_USAGE_HW_VIDEO_ENCODER = WFD using HW composer.
+ flag_mask_pvt_wfd = GRALLOC_USAGE_PRIVATE_WFD;
+ flag_mask_hw_video = GRALLOC_USAGE_HW_VIDEO_ENCODER;
+ bool isWfd = (usage & flag_mask_pvt_wfd) && (usage & flag_mask_hw_video);
+ // Enabling only the vendor property would allow WFD to use HWC
+ // Enabling both the aosp and vendor properties would allow all other VDS to use HWC
+ // Disabling both would set all virtual displays to fall back to GPU
+ // In vendor frozen targets, allow WFD to use HWC without any property settings.
+ bool canAllocate = mAllowHwcForVDS || (isWfd && mAllowHwcForWFD) || (isWfd &&
+ mFirstApiLevel < __ANDROID_API_T__);
+
+ if (canAllocate) {
+ enableHalVirtualDisplays(true);
+ }
+
+ return canAllocate;
+
+}
+#else
+bool SurfaceFlinger::canAllocateHwcDisplayIdForVDS(uint64_t) {
+ return true;
+}
+#endif
+
status_t SurfaceFlinger::setDesiredDisplayModeSpecs(const sp<IBinder>& displayToken,
const gui::DisplayModeSpecs& specs) {
SFTRACE_CALL();
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 3eb72cc..1ccfdc9 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -893,6 +893,8 @@
std::vector<std::pair<Layer*, sp<LayerFE>>>& layers,
std::vector<sp<LayerFE>>& layerFEs);
+ bool canAllocateHwcDisplayIdForVDS(uint64_t usage);
+
void readPersistentProperties();
uint32_t getMaxAcquiredBufferCountForCurrentRefreshRate(uid_t uid) const;
@@ -1078,7 +1080,8 @@
void enableHalVirtualDisplays(bool);
// Virtual display lifecycle for ID generation and HAL allocation.
- VirtualDisplayId acquireVirtualDisplay(ui::Size, ui::PixelFormat) REQUIRES(mStateLock);
+ VirtualDisplayId acquireVirtualDisplay(ui::Size, ui::PixelFormat, bool canAllocateHwcForVDS)
+ REQUIRES(mStateLock);
void releaseVirtualDisplay(VirtualDisplayId);
// Returns a display other than `mActiveDisplayId` that can be activated, if any.
@@ -1406,6 +1409,10 @@
const sp<WindowInfosListenerInvoker> mWindowInfosListenerInvoker;
+ bool mAllowHwcForVDS = false;
+ bool mAllowHwcForWFD = false;
+ int mFirstApiLevel = 0;
+
// returns the framerate of the layer with the given sequence ID
float getLayerFramerate(nsecs_t now, int32_t id) const {
return mScheduler->getLayerFramerate(now, id);