Merge "blast: drop buffer from SF's cache when destroyed"
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 738c20f..1fbd2b3 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1583,6 +1583,9 @@
RunDumpsys("DUMPSYS", {"connectivity"}, CommandOptions::WithTimeout(90).Build(),
SEC_TO_MSEC(10));
+ RunDumpsys("DUMPSYS", {"connmetrics"}, CommandOptions::WithTimeout(90).Build(),
+ SEC_TO_MSEC(10));
+ RunDumpsys("DUMPSYS", {"netd"}, CommandOptions::WithTimeout(90).Build(), SEC_TO_MSEC(10));
RunDumpsys("DUMPSYS", {"carrier_config"}, CommandOptions::WithTimeout(90).Build(),
SEC_TO_MSEC(10));
RunDumpsys("DUMPSYS", {"wifi"}, CommandOptions::WithTimeout(90).Build(),
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index 2efcf11..92fac66 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -1648,7 +1648,8 @@
ATRACE_BEGIN("obb");
for (const auto& packageName : packageNames) {
- auto obbCodePath = create_data_media_obb_path(uuid_, packageName.c_str());
+ auto obbCodePath = create_data_media_package_path(uuid_, userId,
+ "obb", packageName.c_str());
calculate_tree_size(obbCodePath, &extStats.codeSize);
}
ATRACE_END();
@@ -1982,7 +1983,8 @@
ATRACE_END();
ATRACE_BEGIN("obb");
- auto obbPath = create_data_media_obb_path(uuid_, "");
+ auto obbPath = StringPrintf("%s/Android/obb",
+ create_data_media_path(uuid_, userId).c_str());
calculate_tree_size(obbPath, &obbSize);
ATRACE_END();
}
diff --git a/cmds/installd/otapreopt_chroot.cpp b/cmds/installd/otapreopt_chroot.cpp
index 0fdc9d6..2e2cc18 100644
--- a/cmds/installd/otapreopt_chroot.cpp
+++ b/cmds/installd/otapreopt_chroot.cpp
@@ -25,6 +25,7 @@
#include <android-base/logging.h>
#include <android-base/macros.h>
#include <android-base/stringprintf.h>
+#include <libdm/dm.h>
#include <selinux/android.h>
#include <apexd.h>
@@ -77,6 +78,37 @@
}
}
+static void TryExtraMount(const char* name, const char* slot, const char* target) {
+ std::string partition_name = StringPrintf("%s%s", name, slot);
+
+ // See whether update_engine mounted a logical partition.
+ {
+ auto& dm = dm::DeviceMapper::Instance();
+ if (dm.GetState(partition_name) != dm::DmDeviceState::INVALID) {
+ std::string path;
+ if (dm.GetDmDevicePathByName(partition_name, &path)) {
+ int mount_result = mount(path.c_str(),
+ target,
+ "ext4",
+ MS_RDONLY,
+ /* data */ nullptr);
+ if (mount_result == 0) {
+ return;
+ }
+ }
+ }
+ }
+
+ // Fall back and attempt a direct mount.
+ std::string block_device = StringPrintf("/dev/block/by-name/%s", partition_name.c_str());
+ int mount_result = mount(block_device.c_str(),
+ target,
+ "ext4",
+ MS_RDONLY,
+ /* data */ nullptr);
+ UNUSED(mount_result);
+}
+
// Entry for otapreopt_chroot. Expected parameters are:
// [cmd] [status-fd] [target-slot] "dexopt" [dexopt-params]
// The file descriptor denoted by status-fd will be closed. The rest of the parameters will
@@ -137,29 +169,11 @@
LOG(ERROR) << "Target slot suffix not legal: " << arg[2];
exit(207);
}
- {
- std::string vendor_partition = StringPrintf("/dev/block/by-name/vendor%s",
- arg[2]);
- int vendor_result = mount(vendor_partition.c_str(),
- "/postinstall/vendor",
- "ext4",
- MS_RDONLY,
- /* data */ nullptr);
- UNUSED(vendor_result);
- }
+ TryExtraMount("vendor", arg[2], "/postinstall/vendor");
// Try to mount the product partition. update_engine doesn't do this for us, but we
// want it for product APKs. Same notes as vendor above.
- {
- std::string product_partition = StringPrintf("/dev/block/by-name/product%s",
- arg[2]);
- int product_result = mount(product_partition.c_str(),
- "/postinstall/product",
- "ext4",
- MS_RDONLY,
- /* data */ nullptr);
- UNUSED(product_result);
- }
+ TryExtraMount("product", arg[2], "/postinstall/product");
// Setup APEX mount point and its security context.
static constexpr const char* kPostinstallApexDir = "/postinstall/apex";
diff --git a/cmds/installd/utils.cpp b/cmds/installd/utils.cpp
index da097db..4eb1df0 100644
--- a/cmds/installd/utils.cpp
+++ b/cmds/installd/utils.cpp
@@ -244,10 +244,6 @@
return StringPrintf("%s/media/%u", create_data_path(volume_uuid).c_str(), userid);
}
-std::string create_data_media_obb_path(const char* volume_uuid, const char* package_name) {
- return StringPrintf("%s/media/obb/%s", create_data_path(volume_uuid).c_str(), package_name);
-}
-
std::string create_data_media_package_path(const char* volume_uuid, userid_t userid,
const char* data_type, const char* package_name) {
return StringPrintf("%s/Android/%s/%s", create_data_media_path(volume_uuid, userid).c_str(),
diff --git a/cmds/installd/utils.h b/cmds/installd/utils.h
index 955d524..6a42026 100644
--- a/cmds/installd/utils.h
+++ b/cmds/installd/utils.h
@@ -75,7 +75,6 @@
userid_t user, int32_t snapshot_id, const char* package_name);
std::string create_data_media_path(const char* volume_uuid, userid_t userid);
-std::string create_data_media_obb_path(const char* volume_uuid, const char* package_name);
std::string create_data_media_package_path(const char* volume_uuid, userid_t userid,
const char* data_type, const char* package_name);
diff --git a/data/etc/car_core_hardware.xml b/data/etc/car_core_hardware.xml
index 5c1cab6..ad7791e 100644
--- a/data/etc/car_core_hardware.xml
+++ b/data/etc/car_core_hardware.xml
@@ -46,12 +46,6 @@
<feature name="android.software.cant_save_state" />
<feature name="android.software.secure_lock_screen" />
- <!-- Feature to specify if the device supports adding device admins. -->
- <feature name="android.software.device_admin" />
-
- <!-- Feature to specify if the device support managed users. -->
- <feature name="android.software.managed_users" />
-
<!-- devices with GPS must include android.hardware.location.gps.xml -->
<!-- devices with an autofocus camera and/or flash must include either
android.hardware.camera.autofocus.xml or
diff --git a/libs/nativewindow/include/android/hardware_buffer.h b/libs/nativewindow/include/android/hardware_buffer.h
index 165b75a..da959e3 100644
--- a/libs/nativewindow/include/android/hardware_buffer.h
+++ b/libs/nativewindow/include/android/hardware_buffer.h
@@ -422,18 +422,6 @@
int32_t fence, const ARect* rect, void** outVirtualAddress) __INTRODUCED_IN(26);
/**
- * Lock an AHardwareBuffer for direct CPU access.
- *
- * This function is the same as the above lock function, but passes back
- * additional information about the bytes per pixel and the bytes per stride
- * of the locked buffer. If the bytes per pixel or bytes per stride are unknown
- * or variable, or if the underlying mapper implementation does not support returning
- * additional information, then this call will fail with INVALID_OPERATION
- */
-int AHardwareBuffer_lockAndGetInfo(AHardwareBuffer* buffer, uint64_t usage,
- int32_t fence, const ARect* rect, void** outVirtualAddress,
- int32_t* outBytesPerPixel, int32_t* outBytesPerStride) __INTRODUCED_IN(29);
-/**
* Lock a potentially multi-planar AHardwareBuffer for direct CPU access.
*
* This function is similar to AHardwareBuffer_lock, but can lock multi-planar
@@ -518,6 +506,18 @@
*/
int AHardwareBuffer_isSupported(const AHardwareBuffer_Desc* desc) __INTRODUCED_IN(29);
+/**
+ * Lock an AHardwareBuffer for direct CPU access.
+ *
+ * This function is the same as the above lock function, but passes back
+ * additional information about the bytes per pixel and the bytes per stride
+ * of the locked buffer. If the bytes per pixel or bytes per stride are unknown
+ * or variable, or if the underlying mapper implementation does not support returning
+ * additional information, then this call will fail with INVALID_OPERATION
+ */
+int AHardwareBuffer_lockAndGetInfo(AHardwareBuffer* buffer, uint64_t usage,
+ int32_t fence, const ARect* rect, void** outVirtualAddress,
+ int32_t* outBytesPerPixel, int32_t* outBytesPerStride) __INTRODUCED_IN(29);
#endif // __ANDROID_API__ >= 29
__END_DECLS
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index e521b61..755418e 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -167,6 +167,12 @@
override_export_include_dirs: ["include_vndk"],
},
},
+ header_libs: [
+ "libnativewindow_headers",
+ ],
+ export_header_lib_headers: [
+ "libnativewindow_headers",
+ ],
}
subdirs = [
diff --git a/libs/ui/Fence.cpp b/libs/ui/Fence.cpp
index ed7ccb0b..4ce891e 100644
--- a/libs/ui/Fence.cpp
+++ b/libs/ui/Fence.cpp
@@ -110,7 +110,7 @@
}
struct sync_file_info* finfo = sync_file_info(mFenceFd);
- if (finfo == NULL) {
+ if (finfo == nullptr) {
ALOGE("sync_file_info returned NULL for fd %d", mFenceFd.get());
return SIGNAL_TIME_INVALID;
}
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index 637a9cf..40df260 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -76,7 +76,7 @@
usage_deprecated = 0;
usage = 0;
layerCount = 0;
- handle = NULL;
+ handle = nullptr;
}
// deprecated
@@ -146,7 +146,7 @@
GraphicBufferAllocator& allocator(GraphicBufferAllocator::get());
allocator.free(handle);
}
- handle = NULL;
+ handle = nullptr;
}
status_t GraphicBuffer::initCheck() const {
@@ -181,7 +181,7 @@
if (handle) {
GraphicBufferAllocator& allocator(GraphicBufferAllocator::get());
allocator.free(handle);
- handle = 0;
+ handle = nullptr;
}
return initWithSize(inWidth, inHeight, inFormat, inLayerCount, inUsage, "[Reallocation]");
}
@@ -374,14 +374,29 @@
}
size_t GraphicBuffer::getFlattenedSize() const {
+#ifndef LIBUI_IN_VNDK
+ if (mBufferHubBuffer != nullptr) {
+ return 48;
+ }
+#endif
return static_cast<size_t>(13 + (handle ? mTransportNumInts : 0)) * sizeof(int);
}
size_t GraphicBuffer::getFdCount() const {
+#ifndef LIBUI_IN_VNDK
+ if (mBufferHubBuffer != nullptr) {
+ return 0;
+ }
+#endif
return static_cast<size_t>(handle ? mTransportNumFds : 0);
}
status_t GraphicBuffer::flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const {
+#ifndef LIBUI_IN_VNDK
+ if (mBufferHubBuffer != nullptr) {
+ return flattenBufferHubBuffer(buffer, size, fds, count);
+ }
+#endif
size_t sizeNeeded = GraphicBuffer::getFlattenedSize();
if (size < sizeNeeded) return NO_MEMORY;
@@ -408,7 +423,7 @@
buf[11] = int32_t(mTransportNumInts);
memcpy(fds, handle->data, static_cast<size_t>(mTransportNumFds) * sizeof(int));
memcpy(buf + 13, handle->data + handle->numFds,
- static_cast<size_t>(mTransportNumInts) * sizeof(int));
+ static_cast<size_t>(mTransportNumInts) * sizeof(int));
}
buffer = static_cast<void*>(static_cast<uint8_t*>(buffer) + sizeNeeded);
@@ -417,17 +432,11 @@
fds += mTransportNumFds;
count -= static_cast<size_t>(mTransportNumFds);
}
-
return NO_ERROR;
}
-status_t GraphicBuffer::unflatten(
- void const*& buffer, size_t& size, int const*& fds, size_t& count) {
- if (size < 12 * sizeof(int)) {
- android_errorWriteLog(0x534e4554, "114223584");
- return NO_MEMORY;
- }
-
+status_t GraphicBuffer::unflatten(void const*& buffer, size_t& size, int const*& fds,
+ size_t& count) {
int const* buf = static_cast<int const*>(buffer);
// NOTE: it turns out that some media code generates a flattened GraphicBuffer manually!!!!!
@@ -439,10 +448,21 @@
} else if (buf[0] == 'GBFR') {
// old version, when usage bits were 32-bits
flattenWordCount = 12;
+ } else if (buf[0] == 'BHBB') { // BufferHub backed buffer.
+#ifndef LIBUI_IN_VNDK
+ return unflattenBufferHubBuffer(buffer, size, fds, count);
+#else
+ return BAD_TYPE;
+#endif
} else {
return BAD_TYPE;
}
+ if (size < 12 * sizeof(int)) {
+ android_errorWriteLog(0x534e4554, "114223584");
+ return NO_MEMORY;
+ }
+
const size_t numFds = static_cast<size_t>(buf[10]);
const size_t numInts = static_cast<size_t>(buf[11]);
@@ -455,7 +475,7 @@
width = height = stride = format = usage_deprecated = 0;
layerCount = 0;
usage = 0;
- handle = NULL;
+ handle = nullptr;
ALOGE("unflatten: numFds or numInts is too large: %zd, %zd", numFds, numInts);
return BAD_VALUE;
}
@@ -483,13 +503,13 @@
} else {
usage = uint64_t(usage_deprecated);
}
- native_handle* h = native_handle_create(
- static_cast<int>(numFds), static_cast<int>(numInts));
+ native_handle* h =
+ native_handle_create(static_cast<int>(numFds), static_cast<int>(numInts));
if (!h) {
width = height = stride = format = usage_deprecated = 0;
layerCount = 0;
usage = 0;
- handle = NULL;
+ handle = nullptr;
ALOGE("unflatten: native_handle_create failed");
return NO_MEMORY;
}
@@ -500,7 +520,7 @@
width = height = stride = format = usage_deprecated = 0;
layerCount = 0;
usage = 0;
- handle = NULL;
+ handle = nullptr;
}
mId = static_cast<uint64_t>(buf[7]) << 32;
@@ -510,7 +530,7 @@
mOwner = ownHandle;
- if (handle != 0) {
+ if (handle != nullptr) {
buffer_handle_t importedHandle;
status_t err = mBufferMapper.importBuffer(handle, uint32_t(width), uint32_t(height),
uint32_t(layerCount), format, usage, uint32_t(stride), &importedHandle);
@@ -518,7 +538,7 @@
width = height = stride = format = usage_deprecated = 0;
layerCount = 0;
usage = 0;
- handle = NULL;
+ handle = nullptr;
ALOGE("unflatten: registerBuffer failed: %s (%d)", strerror(-err), err);
return err;
}
@@ -533,7 +553,6 @@
size -= sizeNeeded;
fds += numFds;
count -= numFds;
-
return NO_ERROR;
}
@@ -542,6 +561,79 @@
}
#ifndef LIBUI_IN_VNDK
+status_t GraphicBuffer::flattenBufferHubBuffer(void*& buffer, size_t& size, int*& fds,
+ size_t& count) const {
+ sp<NativeHandle> tokenHandle = mBufferHubBuffer->duplicate();
+ if (tokenHandle == nullptr || tokenHandle->handle() == nullptr ||
+ tokenHandle->handle()->numFds != 0) {
+ return BAD_VALUE;
+ }
+
+ // Size needed for one label, one number of ints inside the token, one generation number and
+ // the token itself.
+ int numIntsInToken = tokenHandle->handle()->numInts;
+ const size_t sizeNeeded = static_cast<size_t>(3 + numIntsInToken) * sizeof(int);
+ if (size < sizeNeeded) {
+ ALOGE("%s: needed size %d, given size %d. Not enough memory.", __FUNCTION__,
+ static_cast<int>(sizeNeeded), static_cast<int>(size));
+ return NO_MEMORY;
+ }
+ size -= sizeNeeded;
+
+ int* buf = static_cast<int*>(buffer);
+ buf[0] = 'BHBB';
+ buf[1] = numIntsInToken;
+ memcpy(buf + 2, tokenHandle->handle()->data, static_cast<size_t>(numIntsInToken) * sizeof(int));
+ buf[2 + numIntsInToken] = static_cast<int32_t>(mGenerationNumber);
+
+ // Do not pass fds if it is BufferHubBuffer backed GraphicBuffer. Not modifying fds or count.
+ fds += 0;
+ count -= 0;
+ return NO_ERROR;
+}
+
+status_t GraphicBuffer::unflattenBufferHubBuffer(void const*& buffer, size_t& size, int const*& fds,
+ size_t& count) {
+ const int* buf = static_cast<const int*>(buffer);
+ int numIntsInToken = buf[1];
+ // Size needed for one label, one number of ints inside the token, one generation number and
+ // the token itself.
+ const size_t sizeNeeded = static_cast<size_t>(3 + numIntsInToken) * sizeof(int);
+ if (size < sizeNeeded) {
+ ALOGE("%s: needed size %d, given size %d. Not enough memory.", __FUNCTION__,
+ static_cast<int>(sizeNeeded), static_cast<int>(size));
+ return NO_MEMORY;
+ }
+ size -= sizeNeeded;
+ native_handle_t* importToken = native_handle_create(/*numFds=*/0, /*numInts=*/numIntsInToken);
+ memcpy(importToken->data, buf + 2, static_cast<size_t>(buf[1]) * sizeof(int));
+ sp<NativeHandle> importTokenHandle = NativeHandle::create(importToken, /*ownHandle=*/true);
+ std::unique_ptr<BufferHubBuffer> bufferHubBuffer = BufferHubBuffer::import(importTokenHandle);
+ if (bufferHubBuffer == nullptr || bufferHubBuffer.get() == nullptr) {
+ return BAD_VALUE;
+ }
+ // Reconstruct this GraphicBuffer object using the new BufferHubBuffer object.
+ if (handle) {
+ free_handle();
+ }
+ mId = 0;
+ mGenerationNumber = static_cast<uint32_t>(buf[2 + numIntsInToken]);
+ mInitCheck =
+ initWithHandle(bufferHubBuffer->duplicateHandle(), /*method=*/TAKE_UNREGISTERED_HANDLE,
+ bufferHubBuffer->desc().width, bufferHubBuffer->desc().height,
+ static_cast<PixelFormat>(bufferHubBuffer->desc().format),
+ bufferHubBuffer->desc().layers, bufferHubBuffer->desc().usage,
+ bufferHubBuffer->desc().stride);
+ mBufferId = bufferHubBuffer->id();
+ mBufferHubBuffer.reset(std::move(bufferHubBuffer.get()));
+
+ // BufferHubBuffer backed GraphicBuffer does not have flattened handle. Not modifying fds or
+ // count.
+ fds += 0;
+ count -= 0;
+ return NO_ERROR;
+}
+
bool GraphicBuffer::isBufferHubBuffer() const {
return mBufferHubBuffer != nullptr;
}
diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp
index 3bd3748..224dc2c 100644
--- a/libs/ui/Region.cpp
+++ b/libs/ui/Region.cpp
@@ -820,7 +820,7 @@
}
if (numRects > (UINT32_MAX / sizeof(Rect))) {
- android_errorWriteWithInfoLog(0x534e4554, "29983260", -1, NULL, 0);
+ android_errorWriteWithInfoLog(0x534e4554, "29983260", -1, nullptr, 0);
return NO_MEMORY;
}
diff --git a/libs/ui/include/ui/GraphicBuffer.h b/libs/ui/include/ui/GraphicBuffer.h
index f86ca59..c137860 100644
--- a/libs/ui/include/ui/GraphicBuffer.h
+++ b/libs/ui/include/ui/GraphicBuffer.h
@@ -301,6 +301,18 @@
mDeathCallbacks;
#ifndef LIBUI_IN_VNDK
+ // Flatten this GraphicBuffer object if backed by BufferHubBuffer.
+ status_t flattenBufferHubBuffer(void*& buffer, size_t& size, int*& fds, size_t& count) const;
+
+ // Unflatten into BufferHubBuffer backed GraphicBuffer.
+ // Unflatten will fail if the original GraphicBuffer object is destructed. For instance, a
+ // GraphicBuffer backed by BufferHubBuffer_1 flatten in process/thread A, transport the token
+ // to process/thread B through a socket, BufferHubBuffer_1 dies and bufferhub invalidated the
+ // token. Race condition occurs between the invalidation of the token in bufferhub process and
+ // process/thread B trying to unflatten and import the buffer with that token.
+ status_t unflattenBufferHubBuffer(void const*& buffer, size_t& size, int const*& fds,
+ size_t& count);
+
// Stores a BufferHubBuffer that handles buffer signaling, identification.
std::unique_ptr<BufferHubBuffer> mBufferHubBuffer;
#endif // LIBUI_IN_VNDK
diff --git a/libs/ui/tests/GraphicBuffer_test.cpp b/libs/ui/tests/GraphicBuffer_test.cpp
index c767ce0..a7c248c 100644
--- a/libs/ui/tests/GraphicBuffer_test.cpp
+++ b/libs/ui/tests/GraphicBuffer_test.cpp
@@ -74,4 +74,49 @@
EXPECT_EQ(gb->getBufferId(), b1_id);
}
+TEST_F(GraphicBufferTest, flattenAndUnflatten) {
+ std::unique_ptr<BufferHubBuffer> b1 =
+ BufferHubBuffer::create(kTestWidth, kTestHeight, kTestLayerCount, kTestFormat,
+ kTestUsage, /*userMetadataSize=*/0);
+ ASSERT_NE(b1, nullptr);
+ sp<GraphicBuffer> gb1(new GraphicBuffer(std::move(b1)));
+ gb1->setGenerationNumber(42);
+
+ size_t flattenedSize = gb1->getFlattenedSize();
+ EXPECT_EQ(flattenedSize, 48);
+ size_t fdCount = gb1->getFdCount();
+ EXPECT_EQ(fdCount, 0);
+
+ int data[flattenedSize];
+ int fds[0];
+
+ // Make copies of needed items since flatten modifies them.
+ size_t flattenedSizeCopy = flattenedSize;
+ size_t fdCountCopy = fdCount;
+ void* dataStart = data;
+ int* fdsStart = fds;
+ status_t err = gb1->flatten(dataStart, flattenedSizeCopy, fdsStart, fdCountCopy);
+ ASSERT_EQ(err, NO_ERROR);
+ EXPECT_EQ(flattenedSizeCopy, 0);
+ EXPECT_EQ(fdCountCopy, 0);
+
+ size_t unflattenSize = flattenedSize;
+ size_t unflattenFdCount = fdCount;
+ const void* unflattenData = static_cast<const void*>(dataStart);
+ const int* unflattenFdData = static_cast<const int*>(fdsStart);
+
+ GraphicBuffer* gb2 = new GraphicBuffer();
+ err = gb2->unflatten(unflattenData, unflattenSize, unflattenFdData, unflattenFdCount);
+ ASSERT_EQ(err, NO_ERROR);
+ EXPECT_TRUE(gb2->isBufferHubBuffer());
+
+ EXPECT_EQ(gb2->getWidth(), kTestWidth);
+ EXPECT_EQ(gb2->getHeight(), kTestHeight);
+ EXPECT_EQ(static_cast<uint32_t>(gb2->getPixelFormat()), kTestFormat);
+ EXPECT_EQ(gb2->getUsage(), kTestUsage);
+ EXPECT_EQ(gb2->getLayerCount(), kTestLayerCount);
+ EXPECT_EQ(gb1->getBufferId(), gb2->getBufferId());
+ EXPECT_EQ(gb2->getGenerationNumber(), 42);
+}
+
} // namespace android
diff --git a/libs/ui/tools/lutgen.cpp b/libs/ui/tools/lutgen.cpp
index 97b0822..85a1ceb 100644
--- a/libs/ui/tools/lutgen.cpp
+++ b/libs/ui/tools/lutgen.cpp
@@ -85,11 +85,11 @@
static int handleCommandLineArgments(int argc, char* argv[]) {
static constexpr const char* OPTSTR = "h:d:s:t:";
static const struct option OPTIONS[] = {
- { "help", no_argument, 0, 'h' },
- { "dimension", required_argument, 0, 'd' },
- { "source", required_argument, 0, 's' },
- { "target", required_argument, 0, 't' },
- { 0, 0, 0, 0 } // termination of the option list
+ { "help", no_argument, nullptr, 'h' },
+ { "dimension", required_argument, nullptr, 'd' },
+ { "source", required_argument, nullptr, 's' },
+ { "target", required_argument, nullptr, 't' },
+ { nullptr, 0, nullptr, 0 } // termination of the option list
};
int opt;
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index c100db7..54fa89f 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -314,6 +314,24 @@
}
}
+ if (cnx->minor == 5) {
+ // full list in egl_entries.in
+ if (!cnx->egl.eglCreateImage ||
+ !cnx->egl.eglDestroyImage ||
+ !cnx->egl.eglGetPlatformDisplay ||
+ !cnx->egl.eglCreatePlatformWindowSurface ||
+ !cnx->egl.eglCreatePlatformPixmapSurface ||
+ !cnx->egl.eglCreateSync ||
+ !cnx->egl.eglDestroySync ||
+ !cnx->egl.eglClientWaitSync ||
+ !cnx->egl.eglGetSyncAttrib ||
+ !cnx->egl.eglWaitSync) {
+ ALOGE("Driver indicates EGL 1.5 support, but does not have "
+ "a critical API");
+ cnx->minor = 4;
+ }
+ }
+
// the query strings are per-display
mVendorString = sVendorString;
mVersionString.clear();
diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp
index 0cc37a0..a45b8a5 100644
--- a/services/inputflinger/InputReader.cpp
+++ b/services/inputflinger/InputReader.cpp
@@ -4314,7 +4314,8 @@
nsecs_t timeSinceLastReport = now - mStatistics.lastReportTime;
if (timeSinceLastReport > STATISTICS_REPORT_FREQUENCY) {
android::util::stats_write(android::util::TOUCH_EVENT_REPORTED,
- mStatistics.min, mStatistics.max, mStatistics.mean(), mStatistics.stdev());
+ mStatistics.min, mStatistics.max,
+ mStatistics.mean(), mStatistics.stdev(), mStatistics.count);
mStatistics.reset(now);
}
}
diff --git a/services/surfaceflinger/BufferLayerConsumer.cpp b/services/surfaceflinger/BufferLayerConsumer.cpp
index cc78ece..f2d4c51 100644
--- a/services/surfaceflinger/BufferLayerConsumer.cpp
+++ b/services/surfaceflinger/BufferLayerConsumer.cpp
@@ -323,7 +323,8 @@
mCurrentTextureBuffer == nullptr
? nullptr
: mCurrentTextureBuffer->graphicBuffer(),
- mCurrentCrop, mCurrentTransform, mFilteringEnabled);
+ getCurrentCropLocked(), mCurrentTransform,
+ mFilteringEnabled);
}
nsecs_t BufferLayerConsumer::getTimestamp() {
@@ -380,6 +381,10 @@
Rect BufferLayerConsumer::getCurrentCrop() const {
Mutex::Autolock lock(mMutex);
+ return getCurrentCropLocked();
+}
+
+Rect BufferLayerConsumer::getCurrentCropLocked() const {
return (mCurrentScalingMode == NATIVE_WINDOW_SCALING_MODE_SCALE_CROP)
? GLConsumer::scaleDownCrop(mCurrentCrop, mDefaultWidth, mDefaultHeight)
: mCurrentCrop;
diff --git a/services/surfaceflinger/BufferLayerConsumer.h b/services/surfaceflinger/BufferLayerConsumer.h
index 32ccfbb..f4ca846 100644
--- a/services/surfaceflinger/BufferLayerConsumer.h
+++ b/services/surfaceflinger/BufferLayerConsumer.h
@@ -253,6 +253,9 @@
// access the current texture buffer.
status_t doFenceWaitLocked() const;
+ // getCurrentCropLocked returns the cropping rectangle of the current buffer.
+ Rect getCurrentCropLocked() const;
+
// The default consumer usage flags that BufferLayerConsumer always sets on its
// BufferQueue instance; these will be OR:d with any additional flags passed
// from the BufferLayerConsumer user. In particular, BufferLayerConsumer will always
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 1ca0b02..5efa4e0 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -139,7 +139,6 @@
bool BufferStateLayer::setTransform(uint32_t transform) {
if (mCurrentState.transform == transform) return false;
- mCurrentState.sequence++;
mCurrentState.transform = transform;
mCurrentState.modified = true;
setTransactionFlags(eTransactionNeeded);
@@ -170,7 +169,6 @@
}
if (mCurrentState.crop == c) return false;
- mCurrentState.sequence++;
mCurrentState.crop = c;
mCurrentState.modified = true;
setTransactionFlags(eTransactionNeeded);
@@ -242,7 +240,6 @@
bool BufferStateLayer::setHdrMetadata(const HdrMetadata& hdrMetadata) {
if (mCurrentState.hdrMetadata == hdrMetadata) return false;
- mCurrentState.sequence++;
mCurrentState.hdrMetadata = hdrMetadata;
mCurrentState.modified = true;
setTransactionFlags(eTransactionNeeded);
@@ -250,7 +247,6 @@
}
bool BufferStateLayer::setSurfaceDamageRegion(const Region& surfaceDamage) {
- mCurrentState.sequence++;
mCurrentState.surfaceDamageRegion = surfaceDamage;
mCurrentState.modified = true;
setTransactionFlags(eTransactionNeeded);
@@ -259,7 +255,6 @@
bool BufferStateLayer::setApi(int32_t api) {
if (mCurrentState.api == api) return false;
- mCurrentState.sequence++;
mCurrentState.api = api;
mCurrentState.modified = true;
setTransactionFlags(eTransactionNeeded);
@@ -268,7 +263,6 @@
bool BufferStateLayer::setSidebandStream(const sp<NativeHandle>& sidebandStream) {
if (mCurrentState.sidebandStream == sidebandStream) return false;
- mCurrentState.sequence++;
mCurrentState.sidebandStream = sidebandStream;
mCurrentState.modified = true;
setTransactionFlags(eTransactionNeeded);
@@ -551,6 +545,8 @@
mFlinger->mTimeStats->setAcquireFence(layerID, getFrameNumber(), getCurrentFenceTime());
mFlinger->mTimeStats->setLatchTime(layerID, getFrameNumber(), latchTime);
+ mCurrentStateModified = false;
+
return NO_ERROR;
}
@@ -600,7 +596,6 @@
s.buffer->handle, to_string(error).c_str(), static_cast<int32_t>(error));
}
- mCurrentStateModified = false;
mFrameNumber++;
}
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 07fe03e..898d37e 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1845,7 +1845,8 @@
setTransactionFlags(eTransactionNeeded);
}
-void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet) {
+void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet,
+ uint32_t traceFlags) {
const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
const State& state = useDrawing ? mDrawingState : mCurrentState;
@@ -1853,114 +1854,129 @@
ui::Transform requestedTransform = state.active_legacy.transform;
ui::Transform transform = getTransform();
- layerInfo->set_id(sequence);
- layerInfo->set_name(getName().c_str());
- layerInfo->set_type(String8(getTypeId()));
+ if (traceFlags & SurfaceTracing::TRACE_CRITICAL) {
+ layerInfo->set_id(sequence);
+ layerInfo->set_name(getName().c_str());
+ layerInfo->set_type(String8(getTypeId()));
- for (const auto& child : children) {
- layerInfo->add_children(child->sequence);
- }
-
- for (const wp<Layer>& weakRelative : state.zOrderRelatives) {
- sp<Layer> strongRelative = weakRelative.promote();
- if (strongRelative != nullptr) {
- layerInfo->add_relatives(strongRelative->sequence);
+ for (const auto& child : children) {
+ layerInfo->add_children(child->sequence);
}
- }
- LayerProtoHelper::writeToProto(state.activeTransparentRegion_legacy,
- [&]() { return layerInfo->mutable_transparent_region(); });
- LayerProtoHelper::writeToProto(visibleRegion,
- [&]() { return layerInfo->mutable_visible_region(); });
- LayerProtoHelper::writeToProto(surfaceDamageRegion,
- [&]() { return layerInfo->mutable_damage_region(); });
-
- layerInfo->set_layer_stack(getLayerStack());
- layerInfo->set_z(state.z);
-
- LayerProtoHelper::writePositionToProto(transform.tx(), transform.ty(),
- [&]() { return layerInfo->mutable_position(); });
-
- LayerProtoHelper::writePositionToProto(requestedTransform.tx(), requestedTransform.ty(), [&]() {
- return layerInfo->mutable_requested_position();
- });
-
- LayerProtoHelper::writeSizeToProto(state.active_legacy.w, state.active_legacy.h,
- [&]() { return layerInfo->mutable_size(); });
-
- LayerProtoHelper::writeToProto(state.crop_legacy, [&]() { return layerInfo->mutable_crop(); });
- layerInfo->set_corner_radius(getRoundedCornerState().radius);
-
- layerInfo->set_is_opaque(isOpaque(state));
- layerInfo->set_invalidate(contentDirty);
-
- // XXX (b/79210409) mCurrentDataSpace is not protected
- layerInfo->set_dataspace(dataspaceDetails(static_cast<android_dataspace>(mCurrentDataSpace)));
-
- layerInfo->set_pixel_format(decodePixelFormat(getPixelFormat()));
- LayerProtoHelper::writeToProto(getColor(), [&]() { return layerInfo->mutable_color(); });
- LayerProtoHelper::writeToProto(state.color,
- [&]() { return layerInfo->mutable_requested_color(); });
- layerInfo->set_flags(state.flags);
-
- LayerProtoHelper::writeToProto(transform, layerInfo->mutable_transform());
- LayerProtoHelper::writeToProto(requestedTransform, layerInfo->mutable_requested_transform());
-
- auto parent = useDrawing ? mDrawingParent.promote() : mCurrentParent.promote();
- if (parent != nullptr) {
- layerInfo->set_parent(parent->sequence);
- } else {
- layerInfo->set_parent(-1);
- }
-
- auto zOrderRelativeOf = state.zOrderRelativeOf.promote();
- if (zOrderRelativeOf != nullptr) {
- layerInfo->set_z_order_relative_of(zOrderRelativeOf->sequence);
- } else {
- layerInfo->set_z_order_relative_of(-1);
- }
-
- auto buffer = mActiveBuffer;
- if (buffer != nullptr) {
- LayerProtoHelper::writeToProto(buffer,
- [&]() { return layerInfo->mutable_active_buffer(); });
- LayerProtoHelper::writeToProto(ui::Transform(mCurrentTransform),
- layerInfo->mutable_buffer_transform());
- }
-
- layerInfo->set_queued_frames(getQueuedFrameCount());
- layerInfo->set_refresh_pending(isBufferLatched());
- layerInfo->set_curr_frame(mCurrentFrameNumber);
- layerInfo->set_effective_scaling_mode(getEffectiveScalingMode());
-
- for (const auto& pendingState : mPendingStates) {
- auto barrierLayer = pendingState.barrierLayer_legacy.promote();
- if (barrierLayer != nullptr) {
- BarrierLayerProto* barrierLayerProto = layerInfo->add_barrier_layer();
- barrierLayerProto->set_id(barrierLayer->sequence);
- barrierLayerProto->set_frame_number(pendingState.frameNumber_legacy);
+ for (const wp<Layer>& weakRelative : state.zOrderRelatives) {
+ sp<Layer> strongRelative = weakRelative.promote();
+ if (strongRelative != nullptr) {
+ layerInfo->add_relatives(strongRelative->sequence);
+ }
}
+
+ LayerProtoHelper::writeToProto(state.activeTransparentRegion_legacy,
+ [&]() { return layerInfo->mutable_transparent_region(); });
+ LayerProtoHelper::writeToProto(visibleRegion,
+ [&]() { return layerInfo->mutable_visible_region(); });
+ LayerProtoHelper::writeToProto(surfaceDamageRegion,
+ [&]() { return layerInfo->mutable_damage_region(); });
+
+ layerInfo->set_layer_stack(getLayerStack());
+ layerInfo->set_z(state.z);
+
+ LayerProtoHelper::writePositionToProto(transform.tx(), transform.ty(),
+ [&]() { return layerInfo->mutable_position(); });
+
+ LayerProtoHelper::writePositionToProto(requestedTransform.tx(), requestedTransform.ty(),
+ [&]() {
+ return layerInfo->mutable_requested_position();
+ });
+
+ LayerProtoHelper::writeSizeToProto(state.active_legacy.w, state.active_legacy.h,
+ [&]() { return layerInfo->mutable_size(); });
+
+ LayerProtoHelper::writeToProto(state.crop_legacy,
+ [&]() { return layerInfo->mutable_crop(); });
+ layerInfo->set_corner_radius(getRoundedCornerState().radius);
+
+ layerInfo->set_is_opaque(isOpaque(state));
+ layerInfo->set_invalidate(contentDirty);
+
+ // XXX (b/79210409) mCurrentDataSpace is not protected
+ layerInfo->set_dataspace(
+ dataspaceDetails(static_cast<android_dataspace>(mCurrentDataSpace)));
+
+ layerInfo->set_pixel_format(decodePixelFormat(getPixelFormat()));
+ LayerProtoHelper::writeToProto(getColor(), [&]() { return layerInfo->mutable_color(); });
+ LayerProtoHelper::writeToProto(state.color,
+ [&]() { return layerInfo->mutable_requested_color(); });
+ layerInfo->set_flags(state.flags);
+
+ LayerProtoHelper::writeToProto(transform, layerInfo->mutable_transform());
+ LayerProtoHelper::writeToProto(requestedTransform,
+ layerInfo->mutable_requested_transform());
+
+ auto parent = useDrawing ? mDrawingParent.promote() : mCurrentParent.promote();
+ if (parent != nullptr) {
+ layerInfo->set_parent(parent->sequence);
+ } else {
+ layerInfo->set_parent(-1);
+ }
+
+ auto zOrderRelativeOf = state.zOrderRelativeOf.promote();
+ if (zOrderRelativeOf != nullptr) {
+ layerInfo->set_z_order_relative_of(zOrderRelativeOf->sequence);
+ } else {
+ layerInfo->set_z_order_relative_of(-1);
+ }
+
+ auto buffer = mActiveBuffer;
+ if (buffer != nullptr) {
+ LayerProtoHelper::writeToProto(buffer,
+ [&]() { return layerInfo->mutable_active_buffer(); });
+ LayerProtoHelper::writeToProto(ui::Transform(mCurrentTransform),
+ layerInfo->mutable_buffer_transform());
+ }
+
+ layerInfo->set_queued_frames(getQueuedFrameCount());
+ layerInfo->set_refresh_pending(isBufferLatched());
+ layerInfo->set_curr_frame(mCurrentFrameNumber);
+ layerInfo->set_effective_scaling_mode(getEffectiveScalingMode());
+
+ for (const auto& pendingState : mPendingStates) {
+ auto barrierLayer = pendingState.barrierLayer_legacy.promote();
+ if (barrierLayer != nullptr) {
+ BarrierLayerProto* barrierLayerProto = layerInfo->add_barrier_layer();
+ barrierLayerProto->set_id(barrierLayer->sequence);
+ barrierLayerProto->set_frame_number(pendingState.frameNumber_legacy);
+ }
+ }
+ LayerProtoHelper::writeToProto(mBounds, [&]() { return layerInfo->mutable_bounds(); });
}
- auto protoMap = layerInfo->mutable_metadata();
- for (const auto& entry : state.metadata.mMap) {
- (*protoMap)[entry.first] = std::string(entry.second.cbegin(), entry.second.cend());
+ if (traceFlags & SurfaceTracing::TRACE_INPUT) {
+ LayerProtoHelper::writeToProto(state.inputInfo, state.touchableRegionCrop,
+ [&]() { return layerInfo->mutable_input_window_info(); });
}
- LayerProtoHelper::writeToProto(mEffectiveTransform, layerInfo->mutable_effective_transform());
- LayerProtoHelper::writeToProto(mSourceBounds,
- [&]() { return layerInfo->mutable_source_bounds(); });
- LayerProtoHelper::writeToProto(mScreenBounds,
- [&]() { return layerInfo->mutable_screen_bounds(); });
- LayerProtoHelper::writeToProto(mBounds, [&]() { return layerInfo->mutable_bounds(); });
+
+ if (traceFlags & SurfaceTracing::TRACE_EXTRA) {
+ auto protoMap = layerInfo->mutable_metadata();
+ for (const auto& entry : state.metadata.mMap) {
+ (*protoMap)[entry.first] = std::string(entry.second.cbegin(), entry.second.cend());
+ }
+ LayerProtoHelper::writeToProto(mEffectiveTransform,
+ layerInfo->mutable_effective_transform());
+ LayerProtoHelper::writeToProto(mSourceBounds,
+ [&]() { return layerInfo->mutable_source_bounds(); });
+ LayerProtoHelper::writeToProto(mScreenBounds,
+ [&]() { return layerInfo->mutable_screen_bounds(); });
+ }
}
-void Layer::writeToProto(LayerProto* layerInfo, const sp<DisplayDevice>& displayDevice) {
+void Layer::writeToProto(LayerProto* layerInfo, const sp<DisplayDevice>& displayDevice,
+ uint32_t traceFlags) {
auto outputLayer = findOutputLayerForDisplay(displayDevice);
if (!outputLayer) {
return;
}
- writeToProto(layerInfo, LayerVector::StateSet::Drawing);
+ writeToProto(layerInfo, LayerVector::StateSet::Drawing, traceFlags);
const auto& compositionState = outputLayer->getState();
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index b7cfc16..83ff3b6 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -433,10 +433,11 @@
bool isRemovedFromCurrentState() const;
- void writeToProto(LayerProto* layerInfo,
- LayerVector::StateSet stateSet = LayerVector::StateSet::Drawing);
+ void writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet,
+ uint32_t traceFlags = SurfaceTracing::TRACE_ALL);
- void writeToProto(LayerProto* layerInfo, const sp<DisplayDevice>& displayDevice);
+ void writeToProto(LayerProto* layerInfo, const sp<DisplayDevice>& displayDevice,
+ uint32_t traceFlags = SurfaceTracing::TRACE_ALL);
virtual Geometry getActiveGeometry(const Layer::State& s) const { return s.active_legacy; }
virtual uint32_t getActiveWidth(const Layer::State& s) const { return s.active_legacy.w; }
diff --git a/services/surfaceflinger/LayerProtoHelper.cpp b/services/surfaceflinger/LayerProtoHelper.cpp
index c25c418..c94e439 100644
--- a/services/surfaceflinger/LayerProtoHelper.cpp
+++ b/services/surfaceflinger/LayerProtoHelper.cpp
@@ -119,5 +119,41 @@
}
}
+void LayerProtoHelper::writeToProto(
+ const InputWindowInfo& inputInfo, const wp<Layer>& touchableRegionBounds,
+ std::function<InputWindowInfoProto*()> getInputWindowInfoProto) {
+ if (inputInfo.token == nullptr) {
+ return;
+ }
+
+ InputWindowInfoProto* proto = getInputWindowInfoProto();
+ proto->set_layout_params_flags(inputInfo.layoutParamsFlags);
+ proto->set_layout_params_type(inputInfo.layoutParamsType);
+
+ LayerProtoHelper::writeToProto({inputInfo.frameLeft, inputInfo.frameTop, inputInfo.frameRight,
+ inputInfo.frameBottom},
+ [&]() { return proto->mutable_frame(); });
+ LayerProtoHelper::writeToProto(inputInfo.touchableRegion,
+ [&]() { return proto->mutable_touchable_region(); });
+
+ proto->set_surface_inset(inputInfo.surfaceInset);
+ proto->set_visible(inputInfo.visible);
+ proto->set_can_receive_keys(inputInfo.canReceiveKeys);
+ proto->set_has_focus(inputInfo.hasFocus);
+ proto->set_has_wallpaper(inputInfo.hasWallpaper);
+
+ proto->set_global_scale_factor(inputInfo.globalScaleFactor);
+ proto->set_window_x_scale(inputInfo.windowXScale);
+ proto->set_window_y_scale(inputInfo.windowYScale);
+ proto->set_replace_touchable_region_with_crop(inputInfo.replaceTouchableRegionWithCrop);
+ auto cropLayer = touchableRegionBounds.promote();
+ if (cropLayer != nullptr) {
+ proto->set_crop_layer_id(cropLayer->sequence);
+ LayerProtoHelper::writeToProto(cropLayer->getScreenBounds(
+ false /* reduceTransparentRegion */),
+ [&]() { return proto->mutable_touchable_region_crop(); });
+ }
+}
+
} // namespace surfaceflinger
} // namespace android
diff --git a/services/surfaceflinger/LayerProtoHelper.h b/services/surfaceflinger/LayerProtoHelper.h
index dca9a5e..1754a3f 100644
--- a/services/surfaceflinger/LayerProtoHelper.h
+++ b/services/surfaceflinger/LayerProtoHelper.h
@@ -16,6 +16,8 @@
#include <layerproto/LayerProtoHeader.h>
+#include <Layer.h>
+#include <input/InputWindow.h>
#include <math/vec4.h>
#include <ui/GraphicBuffer.h>
#include <ui/Rect.h>
@@ -38,6 +40,9 @@
static void writeToProto(const ui::Transform& transform, TransformProto* transformProto);
static void writeToProto(const sp<GraphicBuffer>& buffer,
std::function<ActiveBufferProto*()> getActiveBufferProto);
+ static void writeToProto(const InputWindowInfo& inputInfo,
+ const wp<Layer>& touchableRegionBounds,
+ std::function<InputWindowInfoProto*()> getInputWindowInfoProto);
};
} // namespace surfaceflinger
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 547f30f..ad4a769 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -4657,13 +4657,14 @@
result.append("\n");
}
-LayersProto SurfaceFlinger::dumpProtoInfo(LayerVector::StateSet stateSet) const {
+LayersProto SurfaceFlinger::dumpProtoInfo(LayerVector::StateSet stateSet,
+ uint32_t traceFlags) const {
LayersProto layersProto;
const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
const State& state = useDrawing ? mDrawingState : mCurrentState;
state.traverseInZOrder([&](Layer* layer) {
LayerProto* layerProto = layersProto.add_layers();
- layer->writeToProto(layerProto, stateSet);
+ layer->writeToProto(layerProto, stateSet, traceFlags);
});
return layersProto;
@@ -5006,9 +5007,9 @@
code == IBinder::SYSPROPS_TRANSACTION) {
return OK;
}
- // Numbers from 1000 to 1032 are currently use for backdoors. The code
+ // Numbers from 1000 to 1033 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 <= 1032) {
+ if (code >= 1000 && code <= 1033) {
ALOGV("Accessing SurfaceFlinger through backdoor code: %u", code);
return OK;
}
@@ -5316,6 +5317,14 @@
mDebugEnableProtectedContent = n;
return NO_ERROR;
}
+ // Set trace flags
+ case 1033: {
+ n = data.readUint32();
+ ALOGD("Updating trace flags to 0x%x", n);
+ mTracing.setTraceFlags(n);
+ reply->writeInt32(NO_ERROR);
+ return NO_ERROR;
+ }
}
}
return err;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 03146d6..26d0cd1 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -897,7 +897,8 @@
void dumpBufferingStats(std::string& result) const;
void dumpDisplayIdentificationData(std::string& result) const;
void dumpWideColorInfo(std::string& result) const;
- LayersProto dumpProtoInfo(LayerVector::StateSet stateSet) const;
+ LayersProto dumpProtoInfo(LayerVector::StateSet stateSet,
+ uint32_t traceFlags = SurfaceTracing::TRACE_ALL) const;
void withTracingLock(std::function<void()> operation) REQUIRES(mStateLock);
LayersProto dumpVisibleLayersProtoInfo(const sp<DisplayDevice>& display) const;
diff --git a/services/surfaceflinger/SurfaceTracing.cpp b/services/surfaceflinger/SurfaceTracing.cpp
index db78f1d..c4ab066 100644
--- a/services/surfaceflinger/SurfaceTracing.cpp
+++ b/services/surfaceflinger/SurfaceTracing.cpp
@@ -28,46 +28,56 @@
namespace android {
-void SurfaceTracing::mainLoop() {
- bool enabled = true;
- // Upon activation, logs the first frame
- traceLayers("tracing.enable");
- do {
- std::unique_lock<std::mutex> sfLock(mFlinger.mDrawingStateLock);
- mConditionalVariable.wait(sfLock);
- LayersTraceProto entry = traceLayersLocked(mWhere);
- sfLock.unlock();
- {
- std::scoped_lock bufferLock(mTraceLock);
- mBuffer.emplace(std::move(entry));
- if (mWriteToFile) {
- writeProtoFileLocked();
- mWriteToFile = false;
- }
+SurfaceTracing::SurfaceTracing(SurfaceFlinger& flinger)
+ : mFlinger(flinger), mSfLock(flinger.mDrawingStateLock) {}
- enabled = mEnabled;
- }
- } while (enabled);
+void SurfaceTracing::mainLoop() {
+ addFirstEntry();
+ bool enabled = true;
+ while (enabled) {
+ LayersTraceProto entry = traceWhenNotified();
+ enabled = addTraceToBuffer(entry);
+ }
}
-void SurfaceTracing::traceLayers(const char* where) {
- std::unique_lock<std::mutex> sfLock(mFlinger.mDrawingStateLock);
- LayersTraceProto entry = traceLayersLocked(where);
- sfLock.unlock();
- std::scoped_lock bufferLock(mTraceLock);
+void SurfaceTracing::addFirstEntry() {
+ LayersTraceProto entry;
+ {
+ std::scoped_lock lock(mSfLock);
+ entry = traceLayersLocked("tracing.enable");
+ }
+ addTraceToBuffer(entry);
+}
+
+LayersTraceProto SurfaceTracing::traceWhenNotified() {
+ std::unique_lock<std::mutex> lock(mSfLock);
+ mCanStartTrace.wait(lock);
+ android::base::ScopedLockAssertion assumeLock(mSfLock);
+ LayersTraceProto entry = traceLayersLocked(mWhere);
+ lock.unlock();
+ return entry;
+}
+
+bool SurfaceTracing::addTraceToBuffer(LayersTraceProto& entry) {
+ std::scoped_lock lock(mTraceLock);
mBuffer.emplace(std::move(entry));
+ if (mWriteToFile) {
+ writeProtoFileLocked();
+ mWriteToFile = false;
+ }
+ return mEnabled;
}
void SurfaceTracing::notify(const char* where) {
- std::lock_guard<std::mutex> sfLock(mFlinger.mDrawingStateLock);
+ std::scoped_lock lock(mSfLock);
mWhere = where;
- mConditionalVariable.notify_one();
+ mCanStartTrace.notify_one();
}
void SurfaceTracing::writeToFileAsync() {
- std::lock_guard<std::mutex> bufferLock(mTraceLock);
+ std::scoped_lock lock(mTraceLock);
mWriteToFile = true;
- mConditionalVariable.notify_one();
+ mCanStartTrace.notify_one();
}
void SurfaceTracing::LayersTraceBuffer::reset(size_t newSize) {
@@ -102,12 +112,11 @@
}
void SurfaceTracing::enable() {
- std::lock_guard<std::mutex> bufferLock(mTraceLock);
+ std::scoped_lock lock(mTraceLock);
if (mEnabled) {
return;
}
-
mBuffer.reset(mBufferSize);
mEnabled = true;
mThread = std::thread(&SurfaceTracing::mainLoop, this);
@@ -119,7 +128,7 @@
}
bool SurfaceTracing::disable() {
- std::lock_guard<std::mutex> bufferLock(mTraceLock);
+ std::scoped_lock lock(mTraceLock);
if (!mEnabled) {
return false;
@@ -127,28 +136,33 @@
mEnabled = false;
mWriteToFile = true;
- mConditionalVariable.notify_all();
+ mCanStartTrace.notify_all();
return true;
}
bool SurfaceTracing::isEnabled() const {
- std::lock_guard<std::mutex> bufferLock(mTraceLock);
+ std::scoped_lock lock(mTraceLock);
return mEnabled;
}
void SurfaceTracing::setBufferSize(size_t bufferSizeInByte) {
- std::lock_guard<std::mutex> bufferLock(mTraceLock);
+ std::scoped_lock lock(mTraceLock);
mBufferSize = bufferSizeInByte;
mBuffer.setSize(bufferSizeInByte);
}
+void SurfaceTracing::setTraceFlags(uint32_t flags) {
+ std::scoped_lock lock(mSfLock);
+ mTraceFlags = flags;
+}
+
LayersTraceProto SurfaceTracing::traceLayersLocked(const char* where) {
ATRACE_CALL();
LayersTraceProto entry;
entry.set_elapsed_realtime_nanos(elapsedRealtimeNano());
entry.set_where(where);
- LayersProto layers(mFlinger.dumpProtoInfo(LayerVector::StateSet::Drawing));
+ LayersProto layers(mFlinger.dumpProtoInfo(LayerVector::StateSet::Drawing, mTraceFlags));
entry.mutable_layers()->Swap(&layers);
return entry;
@@ -179,8 +193,7 @@
}
void SurfaceTracing::dump(std::string& result) const {
- std::lock_guard<std::mutex> bufferLock(mTraceLock);
-
+ std::scoped_lock lock(mTraceLock);
base::StringAppendF(&result, "Tracing state: %s\n", mEnabled ? "enabled" : "disabled");
base::StringAppendF(&result, " number of entries: %zu (%.2fMB / %.2fMB)\n",
mBuffer.frameCount(), float(mBuffer.used()) / float(1_MB),
diff --git a/services/surfaceflinger/SurfaceTracing.h b/services/surfaceflinger/SurfaceTracing.h
index 9484480..4be2ee9 100644
--- a/services/surfaceflinger/SurfaceTracing.h
+++ b/services/surfaceflinger/SurfaceTracing.h
@@ -41,7 +41,7 @@
*/
class SurfaceTracing {
public:
- SurfaceTracing(SurfaceFlinger& flinger) : mFlinger(flinger) {}
+ SurfaceTracing(SurfaceFlinger& flinger);
void enable();
bool disable();
status_t writeToFile();
@@ -52,6 +52,14 @@
void writeToFileAsync();
void dump(std::string& result) const;
+ enum : uint32_t {
+ TRACE_CRITICAL = 1 << 0,
+ TRACE_INPUT = 1 << 1,
+ TRACE_EXTRA = 1 << 2,
+ TRACE_ALL = 0xffffffff
+ };
+ void setTraceFlags(uint32_t flags);
+
private:
static constexpr auto kDefaultBufferCapInByte = 100_MB;
static constexpr auto kDefaultFileName = "/data/misc/wmtrace/layers_trace.pb";
@@ -74,18 +82,24 @@
};
void mainLoop();
- void traceLayers(const char* where);
- LayersTraceProto traceLayersLocked(const char* where);
+ void addFirstEntry();
+ LayersTraceProto traceWhenNotified();
+ LayersTraceProto traceLayersLocked(const char* where) REQUIRES(mSfLock);
+
+ // Returns true if trace is enabled.
+ bool addTraceToBuffer(LayersTraceProto& entry);
void writeProtoFileLocked() REQUIRES(mTraceLock);
const SurfaceFlinger& mFlinger;
-
- const char* mWhere = "";
status_t mLastErr = NO_ERROR;
std::thread mThread;
- std::condition_variable mConditionalVariable;
- mutable std::mutex mTraceLock;
+ std::condition_variable mCanStartTrace;
+ std::mutex& mSfLock;
+ uint32_t mTraceFlags GUARDED_BY(mSfLock) = TRACE_ALL;
+ const char* mWhere GUARDED_BY(mSfLock) = "";
+
+ mutable std::mutex mTraceLock;
LayersTraceBuffer mBuffer GUARDED_BY(mTraceLock);
size_t mBufferSize GUARDED_BY(mTraceLock) = kDefaultBufferCapInByte;
bool mEnabled GUARDED_BY(mTraceLock) = false;
diff --git a/services/surfaceflinger/layerproto/layers.proto b/services/surfaceflinger/layerproto/layers.proto
index fd4695e..b097505 100644
--- a/services/surfaceflinger/layerproto/layers.proto
+++ b/services/surfaceflinger/layerproto/layers.proto
@@ -96,6 +96,8 @@
FloatRectProto source_bounds = 44;
FloatRectProto bounds = 45;
FloatRectProto screen_bounds = 46;
+
+ InputWindowInfoProto input_window_info = 47;
}
message PositionProto {
@@ -155,3 +157,24 @@
// frame number the barrier is waiting on.
uint64 frame_number = 2;
}
+
+message InputWindowInfoProto {
+ uint32 layout_params_flags = 1;
+ uint32 layout_params_type = 2;
+ RectProto frame = 3;
+ RegionProto touchable_region = 4;
+
+ uint32 surface_inset = 5;
+ bool visible = 6;
+ bool can_receive_keys = 7;
+ bool has_focus = 8;
+ bool has_wallpaper = 9;
+
+ float global_scale_factor = 10;
+ float window_x_scale = 11;
+ float window_y_scale = 12;
+
+ uint32 crop_layer_id = 13;
+ bool replace_touchable_region_with_crop = 14;
+ RectProto touchable_region_crop = 15;
+}