diff options
Diffstat (limited to 'libs')
83 files changed, 1204 insertions, 2103 deletions
diff --git a/libs/arect/Android.bp b/libs/arect/Android.bp index 1a9766d72e..319716ec81 100644 --- a/libs/arect/Android.bp +++ b/libs/arect/Android.bp @@ -14,6 +14,7 @@ package { default_applicable_licenses: ["frameworks_native_libs_arect_license"], + default_team: "trendy_team_android_core_graphics_stack", } // Added automatically by a large-scale-change diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp index 941e0918f7..84ff9d74ef 100644 --- a/libs/binder/Android.bp +++ b/libs/binder/Android.bp @@ -664,9 +664,7 @@ cc_library { // Do not expand the visibility. visibility: [ ":__subpackages__", - "//packages/modules/Virtualization/javalib/jni", - "//packages/modules/Virtualization/vm_payload", - "//packages/modules/Virtualization/demo_native", + "//packages/modules/Virtualization:__subpackages__", "//device/google/cuttlefish/shared/minidroid:__subpackages__", "//system/software_defined_vehicle:__subpackages__", ], diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp index b92e504a9a..ef96f803c3 100644 --- a/libs/binder/IPCThreadState.cpp +++ b/libs/binder/IPCThreadState.cpp @@ -922,28 +922,10 @@ void IPCThreadState::decWeakHandle(int32_t handle) flushIfNeeded(); } -status_t IPCThreadState::attemptIncStrongHandle(int32_t handle) -{ -#if HAS_BC_ATTEMPT_ACQUIRE - LOG_REMOTEREFS("IPCThreadState::attemptIncStrongHandle(%d)\n", handle); - mOut.writeInt32(BC_ATTEMPT_ACQUIRE); - mOut.writeInt32(0); // xxx was thread priority - mOut.writeInt32(handle); - status_t result = UNKNOWN_ERROR; - - waitForResponse(NULL, &result); - -#if LOG_REFCOUNTS - ALOGV("IPCThreadState::attemptIncStrongHandle(%ld) = %s\n", - handle, result == NO_ERROR ? "SUCCESS" : "FAILURE"); -#endif - - return result; -#else +status_t IPCThreadState::attemptIncStrongHandle(int32_t handle) { (void)handle; ALOGE("%s(%d): Not supported\n", __func__, handle); return INVALID_OPERATION; -#endif } void IPCThreadState::expungeHandle(int32_t handle, IBinder* binder) diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index c1770b35d1..2dd310e9ca 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -256,7 +256,7 @@ status_t Parcel::flattenBinder(const sp<IBinder>& binder) { if (const auto* rpcFields = maybeRpcFields()) { if (binder) { - status_t status = writeInt32(1); // non-null + status_t status = writeInt32(RpcFields::TYPE_BINDER); // non-null if (status != OK) return status; uint64_t address; // TODO(b/167966510): need to undo this if the Parcel is not sent @@ -266,7 +266,7 @@ status_t Parcel::flattenBinder(const sp<IBinder>& binder) { status = writeUint64(address); if (status != OK) return status; } else { - status_t status = writeInt32(0); // null + status_t status = writeInt32(RpcFields::TYPE_BINDER_NULL); // null if (status != OK) return status; } return finishFlattenBinder(binder); @@ -740,6 +740,12 @@ bool Parcel::hasFileDescriptors() const return kernelFields->mHasFds; } +status_t Parcel::hasBinders(bool* result) const { + status_t status = hasBindersInRange(0, dataSize(), result); + ALOGE_IF(status != NO_ERROR, "Error %d calling hasBindersInRange()", status); + return status; +} + std::vector<sp<IBinder>> Parcel::debugReadAllStrongBinders() const { std::vector<sp<IBinder>> ret; @@ -799,6 +805,46 @@ std::vector<int> Parcel::debugReadAllFileDescriptors() const { return ret; } +status_t Parcel::hasBindersInRange(size_t offset, size_t len, bool* result) const { + if (len > INT32_MAX || offset > INT32_MAX) { + // Don't accept size_t values which may have come from an inadvertent conversion from a + // negative int. + return BAD_VALUE; + } + size_t limit; + if (__builtin_add_overflow(offset, len, &limit) || limit > mDataSize) { + return BAD_VALUE; + } + *result = false; + if (const auto* kernelFields = maybeKernelFields()) { +#ifdef BINDER_WITH_KERNEL_IPC + for (size_t i = 0; i < kernelFields->mObjectsSize; i++) { + size_t pos = kernelFields->mObjects[i]; + if (pos < offset) continue; + if (pos + sizeof(flat_binder_object) > offset + len) { + if (kernelFields->mObjectsSorted) { + break; + } else { + continue; + } + } + const flat_binder_object* flat = + reinterpret_cast<const flat_binder_object*>(mData + pos); + if (flat->hdr.type == BINDER_TYPE_BINDER || flat->hdr.type == BINDER_TYPE_HANDLE) { + *result = true; + break; + } + } +#else + LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time"); + return INVALID_OPERATION; +#endif // BINDER_WITH_KERNEL_IPC + } else if (const auto* rpcFields = maybeRpcFields()) { + return INVALID_OPERATION; + } + return NO_ERROR; +} + status_t Parcel::hasFileDescriptorsInRange(size_t offset, size_t len, bool* result) const { if (len > INT32_MAX || offset > INT32_MAX) { // Don't accept size_t values which may have come from an inadvertent conversion from a diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h index d7096d8a75..5e18b9197d 100644 --- a/libs/binder/include/binder/Parcel.h +++ b/libs/binder/include/binder/Parcel.h @@ -101,7 +101,9 @@ public: void restoreAllowFds(bool lastValue); bool hasFileDescriptors() const; + status_t hasBinders(bool* result) const; status_t hasFileDescriptorsInRange(size_t offset, size_t length, bool* result) const; + status_t hasBindersInRange(size_t offset, size_t length, bool* result) const; // returns all binder objects in the Parcel std::vector<sp<IBinder>> debugReadAllStrongBinders() const; @@ -647,6 +649,8 @@ private: void freeDataNoInit(); void initState(); void scanForFds() const; + status_t scanForBinders(bool* result) const; + status_t validateReadData(size_t len) const; void updateWorkSourceRequestHeaderPosition() const; diff --git a/libs/binder/ndk/include_platform/android/binder_manager.h b/libs/binder/ndk/include_platform/android/binder_manager.h index b34b30d638..a905dff4b1 100644 --- a/libs/binder/ndk/include_platform/android/binder_manager.h +++ b/libs/binder/ndk/include_platform/android/binder_manager.h @@ -248,6 +248,8 @@ void AServiceManager_getUpdatableApexName(const char* instance, void* context, * \param instance identifier of the passthrough service (e.g. "mapper") * \param instance identifier of the implemenatation (e.g. "default") * \param flag passed to dlopen() + * + * \return the result of dlopen of the specified HAL */ void* AServiceManager_openDeclaredPassthroughHal(const char* interface, const char* instance, int flag) diff --git a/libs/binder/tests/binderParcelUnitTest.cpp b/libs/binder/tests/binderParcelUnitTest.cpp index 34fc43f926..32a70e5b11 100644 --- a/libs/binder/tests/binderParcelUnitTest.cpp +++ b/libs/binder/tests/binderParcelUnitTest.cpp @@ -23,6 +23,7 @@ using android::BBinder; using android::IBinder; using android::IPCThreadState; +using android::NO_ERROR; using android::OK; using android::Parcel; using android::sp; @@ -164,6 +165,45 @@ TEST(Parcel, AppendPlainDataPartial) { ASSERT_EQ(2, p2.readInt32()); } +TEST(Parcel, HasBinders) { + sp<IBinder> b1 = sp<BBinder>::make(); + + Parcel p1; + p1.writeInt32(1); + p1.writeStrongBinder(b1); + + bool result = false; + ASSERT_EQ(NO_ERROR, p1.hasBinders(&result)); + ASSERT_EQ(true, result); + + p1.setDataSize(0); // clear data + result = false; + ASSERT_EQ(NO_ERROR, p1.hasBinders(&result)); + ASSERT_EQ(false, result); + p1.writeStrongBinder(b1); // reset with binder data + result = false; + ASSERT_EQ(NO_ERROR, p1.hasBinders(&result)); + ASSERT_EQ(true, result); + + Parcel p3; + p3.appendFrom(&p1, 0, p1.dataSize()); + result = false; + ASSERT_EQ(NO_ERROR, p1.hasBinders(&result)); + ASSERT_EQ(true, result); +} + +TEST(Parcel, HasBindersInRange) { + sp<IBinder> b1 = sp<BBinder>::make(); + Parcel p1; + p1.writeStrongBinder(b1); + bool result = false; + ASSERT_EQ(NO_ERROR, p1.hasBindersInRange(0, p1.dataSize(), &result)); + ASSERT_EQ(true, result); + result = false; + ASSERT_EQ(NO_ERROR, p1.hasBinders(&result)); + ASSERT_EQ(true, result); +} + TEST(Parcel, AppendWithBinder) { sp<IBinder> b1 = sp<BBinder>::make(); sp<IBinder> b2 = sp<BBinder>::make(); diff --git a/libs/binder/tests/parcel_fuzzer/binder.cpp b/libs/binder/tests/parcel_fuzzer/binder.cpp index 08fe071bfb..5c280f4b2c 100644 --- a/libs/binder/tests/parcel_fuzzer/binder.cpp +++ b/libs/binder/tests/parcel_fuzzer/binder.cpp @@ -353,6 +353,20 @@ std::vector<ParcelRead<::android::Parcel>> BINDER_PARCEL_READ_FUNCTIONS { FUZZ_LOG() << " status: " << status << " result: " << result; }, [] (const ::android::Parcel& p, FuzzedDataProvider& /*provider*/) { + FUZZ_LOG() << "about to call hasBinders() with status"; + bool result; + status_t status = p.hasBinders(&result); + FUZZ_LOG() << " status: " << status << " result: " << result; + }, + [] (const ::android::Parcel& p, FuzzedDataProvider& /*provider*/) { + FUZZ_LOG() << "about to call hasBindersInRange() with status"; + size_t offset = p.readUint32(); + size_t length = p.readUint32(); + bool result; + status_t status = p.hasBindersInRange(offset, length, &result); + FUZZ_LOG() << " status: " << status << " result: " << result; + }, + [] (const ::android::Parcel& p, FuzzedDataProvider& /*provider*/) { FUZZ_LOG() << "about to call compareDataInRange() with status"; size_t thisOffset = p.readUint32(); size_t otherOffset = p.readUint32(); diff --git a/libs/bufferqueueconverter/Android.bp b/libs/bufferqueueconverter/Android.bp index 3fe71cefce..3c8c41fdc8 100644 --- a/libs/bufferqueueconverter/Android.bp +++ b/libs/bufferqueueconverter/Android.bp @@ -5,6 +5,7 @@ package { // to get the below license kinds: // SPDX-license-identifier-Apache-2.0 default_applicable_licenses: ["frameworks_native_license"], + default_team: "trendy_team_android_core_graphics_stack", } cc_library_headers { diff --git a/libs/bufferstreams/Android.bp b/libs/bufferstreams/Android.bp index 6c2a980f71..03ab31e318 100644 --- a/libs/bufferstreams/Android.bp +++ b/libs/bufferstreams/Android.bp @@ -14,6 +14,7 @@ package { default_applicable_licenses: ["frameworks_native_license"], + default_team: "trendy_team_android_core_graphics_stack", } aconfig_declarations { diff --git a/libs/bufferstreams/aidl/Android.bp b/libs/bufferstreams/aidl/Android.bp new file mode 100644 index 0000000000..3f1fa4e532 --- /dev/null +++ b/libs/bufferstreams/aidl/Android.bp @@ -0,0 +1,43 @@ +// Copyright (C) 2024 The Android Open Source 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. + +aidl_interface { + name: "android.graphics.bufferstreams", + unstable: true, + flags: ["-Werror"], + srcs: ["android/graphics/bufferstreams/*.aidl"], + headers: [ + "HardwareBuffer_aidl", + ], + imports: [ + "android.hardware.common-V2", + ], + backend: { + cpp: { + enabled: false, + }, + java: { + enabled: false, + }, + ndk: { + enabled: false, + }, + rust: { + enabled: true, + additional_rustlibs: [ + "libnativewindow_rs", + ], + }, + }, +} diff --git a/libs/bufferstreams/aidl/android/graphics/bufferstreams/BufferAttachment.aidl b/libs/bufferstreams/aidl/android/graphics/bufferstreams/BufferAttachment.aidl new file mode 100644 index 0000000000..5c905b1d17 --- /dev/null +++ b/libs/bufferstreams/aidl/android/graphics/bufferstreams/BufferAttachment.aidl @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2024 The Android Open Source 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. + */ + +package android.graphics.bufferstreams; + +import android.graphics.bufferstreams.IBufferOwner; +import android.hardware.HardwareBuffer; + +// Single mapping between a buffer reference and heavy-weight data (like the +// buffer itself) and data that is stable between frames. +parcelable BufferAttachment { + // The HardwareBuffer itself. + // + // This field is @nullable for codegen, since HardwareBuffer doesn't implement Default in Rust. + // In practice, it should never be null. + @nullable HardwareBuffer buffer; + // The buffer owner to which this buffer should be returned. + IBufferOwner owner; +} diff --git a/libs/bufferstreams/aidl/android/graphics/bufferstreams/BufferCacheUpdate.aidl b/libs/bufferstreams/aidl/android/graphics/bufferstreams/BufferCacheUpdate.aidl new file mode 100644 index 0000000000..75041196a8 --- /dev/null +++ b/libs/bufferstreams/aidl/android/graphics/bufferstreams/BufferCacheUpdate.aidl @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2024 The Android Open Source 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. + */ + +package android.graphics.bufferstreams; + +import android.graphics.bufferstreams.BufferAttachment; + +// A event that changes the state downstream buffer caches. Clients are responsible for forwarding +// these messages to their clients. +union BufferCacheUpdate { + // Event requiring downstream caches to add new entries. + CacheBuffers cacheBuffers; + // Event requiring downstream caches to remove entries. + ForgetBuffers forgetBuffers; + + parcelable CacheBuffers { + // Attachments to add. + List<BufferAttachment> attachments; + } + + parcelable ForgetBuffers { + // References to remove. + long[] bufferIds; + } +} diff --git a/libs/bufferstreams/aidl/android/graphics/bufferstreams/Frame.aidl b/libs/bufferstreams/aidl/android/graphics/bufferstreams/Frame.aidl new file mode 100644 index 0000000000..1e0ec3b5db --- /dev/null +++ b/libs/bufferstreams/aidl/android/graphics/bufferstreams/Frame.aidl @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2024 The Android Open Source 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. + */ + +package android.graphics.bufferstreams; + +import android.os.ParcelFileDescriptor; + +// A Frame represents a single buffer passing through the stream. +parcelable Frame { + // The service must have provided an associated BufferAttachment and the client is required to + // maintain a cache between the two. + long bufferId; + // The expected present time of this frame, or -1 if immediate. + long presentTimeNs; + // The acquire fence of the buffer for this frame. + @nullable ParcelFileDescriptor fence; +} diff --git a/libs/bufferstreams/aidl/android/graphics/bufferstreams/IBufferOwner.aidl b/libs/bufferstreams/aidl/android/graphics/bufferstreams/IBufferOwner.aidl new file mode 100644 index 0000000000..8b25a6298e --- /dev/null +++ b/libs/bufferstreams/aidl/android/graphics/bufferstreams/IBufferOwner.aidl @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2024 The Android Open Source 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. + */ + +package android.graphics.bufferstreams; + +import android.os.ParcelFileDescriptor; + +// Interface from a client back to the owner of a buffer. +interface IBufferOwner { + // Called when the buffer is done being processed by the stream to return its owner. + oneway void onBufferReleased(in long bufferId, in @nullable ParcelFileDescriptor releaseFence); +} diff --git a/libs/bufferstreams/aidl/android/graphics/bufferstreams/IBufferSubscriber.aidl b/libs/bufferstreams/aidl/android/graphics/bufferstreams/IBufferSubscriber.aidl new file mode 100644 index 0000000000..52e8216e60 --- /dev/null +++ b/libs/bufferstreams/aidl/android/graphics/bufferstreams/IBufferSubscriber.aidl @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2024 The Android Open Source 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. + */ + +package android.graphics.bufferstreams; + +import android.graphics.bufferstreams.BufferCacheUpdate; +import android.graphics.bufferstreams.IBufferSubscription; +import android.graphics.bufferstreams.Frame; + +// Interface provided by clients to a service, mirroring the non-IPC interface. +// +// Clients are required to maintain a local cache of Buffer IDs to BufferAttachments. +interface IBufferSubscriber { + // Provide a BufferSubscription object which the client can use to request frames. + oneway void onSubscribe(in IBufferSubscription subscription); + + // Notifies the client to update its local caches. + oneway void onBufferCacheUpdate(in BufferCacheUpdate update); + + // Notifies the client that a requested frame is available. + oneway void onNext(in Frame frame); + + // Notifies the client that a fatal error has occurred. No subsequent on_next events will be + // sent by the service. + // + // Clients must empty their caches. + oneway void onError(); + + // Notifies the client that no further on_next events will be sent by the service in response + // to it cancelling the subscription. + // + // Clients must empty their caches. + oneway void onComplete(); +} diff --git a/libs/sensorprivacy/aidl/android/hardware/CameraPrivacyAllowlistEntry.aidl b/libs/bufferstreams/aidl/android/graphics/bufferstreams/IBufferSubscription.aidl index 03e153704b..c37f4e68ea 100644 --- a/libs/sensorprivacy/aidl/android/hardware/CameraPrivacyAllowlistEntry.aidl +++ b/libs/bufferstreams/aidl/android/graphics/bufferstreams/IBufferSubscription.aidl @@ -1,11 +1,11 @@ -/** - * Copyright (c) 2024, The Android Open Source Project +/* + * Copyright (C) 2024 The Android Open Source 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 + * 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, @@ -14,9 +14,13 @@ * limitations under the License. */ -package android.hardware; +package android.graphics.bufferstreams; -parcelable CameraPrivacyAllowlistEntry { - String packageName; - boolean isMandatory; +// Interface provided to a IBufferSubscriber to request frames or gracefully cancel their +// subscription. +interface IBufferSubscription { + // Request n more frames. + oneway void request(long n); + // Cancel the subscription. Requested frames may continue to arrive. + oneway void cancel(); } diff --git a/libs/bufferstreams/examples/app/Android.bp b/libs/bufferstreams/examples/app/Android.bp index bb573c596c..5b3ec30bd5 100644 --- a/libs/bufferstreams/examples/app/Android.bp +++ b/libs/bufferstreams/examples/app/Android.bp @@ -12,6 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. +package { + default_applicable_licenses: ["frameworks_native_license"], + default_team: "trendy_team_android_core_graphics_stack", +} + android_app { name: "BufferStreamsDemoApp", srcs: ["java/**/*.kt"], diff --git a/libs/bufferstreams/examples/app/jni/Android.bp b/libs/bufferstreams/examples/app/jni/Android.bp index 67910a1c4d..003f4ed2ad 100644 --- a/libs/bufferstreams/examples/app/jni/Android.bp +++ b/libs/bufferstreams/examples/app/jni/Android.bp @@ -12,6 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. +package { + default_applicable_licenses: ["frameworks_native_license"], + default_team: "trendy_team_android_core_graphics_stack", +} + cc_library_shared { name: "libbufferstreamdemoapp", cflags: [ diff --git a/libs/bufferstreams/rust/Android.bp b/libs/bufferstreams/rust/Android.bp index 7fcb222085..34feb5d2a5 100644 --- a/libs/bufferstreams/rust/Android.bp +++ b/libs/bufferstreams/rust/Android.bp @@ -12,6 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. +package { + default_applicable_licenses: ["frameworks_native_license"], + default_team: "trendy_team_android_core_graphics_stack", +} + rust_defaults { name: "libbufferstreams_defaults", srcs: ["src/lib.rs"], diff --git a/libs/bufferstreams/rust/src/buffers/buffer_owner.rs b/libs/bufferstreams/rust/src/buffers/buffer_owner.rs index a4abb9d3b7..155a8bf238 100644 --- a/libs/bufferstreams/rust/src/buffers/buffer_owner.rs +++ b/libs/bufferstreams/rust/src/buffers/buffer_owner.rs @@ -16,7 +16,7 @@ use super::Buffer; /// Trait that represents an owner of a buffer that might need to handle events such as a buffer /// being dropped. -pub trait BufferOwner { +pub trait BufferOwner: Send + Sync { /// Called when a buffer is dropped. fn on_return(&self, buffer: &Buffer); } diff --git a/libs/bufferstreams/rust/src/lib.rs b/libs/bufferstreams/rust/src/lib.rs index be1525d41f..17d4d8767f 100644 --- a/libs/bufferstreams/rust/src/lib.rs +++ b/libs/bufferstreams/rust/src/lib.rs @@ -23,8 +23,6 @@ pub mod subscriptions; use buffers::Buffer; pub use stream_config::*; -use std::time::Instant; - /// This function will print Hello World. #[no_mangle] pub extern "C" fn hello() -> bool { @@ -106,7 +104,8 @@ pub trait BufferSubscriber { /// BufferSubscriptions serve as the bridge between BufferPublishers and /// BufferSubscribers. BufferSubscribers receive a BufferSubscription when they /// subscribe to a BufferPublisher via on_subscribe. -/// This object is to be used by the BufferSubscriber to cancel its subscription +/// +/// This object is used by the BufferSubscriber to cancel its subscription /// or request more buffers. /// /// BufferSubcriptions are required to adhere to the following, based on the @@ -147,7 +146,7 @@ pub trait BufferSubscriber { /// no other Subscription exists at this point. /// * Calling Subscription.cancel MUST return normally. /// * Calling Subscription.request MUST return normally. -pub trait BufferSubscription { +pub trait BufferSubscription: Send + Sync + 'static { /// request fn request(&self, n: u64); /// cancel @@ -161,8 +160,8 @@ pub type BufferError = anyhow::Error; pub struct Frame { /// A buffer to be used this frame. pub buffer: Buffer, - /// The time at which the buffer was dispatched. - pub present_time: Instant, + /// The time at which this buffer is expected to be displayed. + pub present_time: i64, /// A fence used for reading/writing safely. pub fence: i32, } @@ -175,14 +174,12 @@ mod test { use anyhow::anyhow; use buffers::Buffer; use nativewindow::{AHardwareBuffer_Format, AHardwareBuffer_UsageFlags}; - use std::borrow::BorrowMut; - use std::error::Error; - use std::ops::Add; - use std::sync::Arc; - use std::time::Duration; + use std::{borrow::BorrowMut, error::Error, ops::Add, sync::Arc}; - use crate::publishers::testing::*; - use crate::subscribers::{testing::*, SharedSubscriber}; + use crate::{ + publishers::testing::*, + subscribers::{testing::*, SharedSubscriber}, + }; const STREAM_CONFIG: StreamConfig = StreamConfig { width: 1, @@ -200,7 +197,7 @@ mod test { .create_hardware_buffer() .expect("Unable to create hardware buffer for test"), ), - present_time: Instant::now() + Duration::from_secs(1), + present_time: 1, fence: 0, } } diff --git a/libs/bufferstreams/rust/src/publishers/buffer_pool_publisher.rs b/libs/bufferstreams/rust/src/publishers/buffer_pool_publisher.rs index 846105dacd..73a15be897 100644 --- a/libs/bufferstreams/rust/src/publishers/buffer_pool_publisher.rs +++ b/libs/bufferstreams/rust/src/publishers/buffer_pool_publisher.rs @@ -14,8 +14,6 @@ //! -use std::time::Instant; - use crate::{ buffers::BufferPool, subscriptions::SharedBufferSubscription, BufferPublisher, BufferSubscriber, Frame, StreamConfig, @@ -43,7 +41,7 @@ impl BufferPoolPublisher { /// If the [SharedBufferSubscription] is ready for a [Frame], a buffer will be requested from /// [BufferPool] and sent over to the [BufferSubscriber]. - pub fn send_next_frame(&mut self, present_time: Instant) -> bool { + pub fn send_next_frame(&mut self, present_time: i64) -> bool { if let Some(subscriber) = self.subscriber.as_mut() { if self.subscription.take_request() { if let Some(buffer) = self.buffer_pool.next_buffer() { @@ -103,7 +101,7 @@ mod test { subscriber.map_inner(|s| s.request(1)); - assert!(buffer_pool_publisher.send_next_frame(Instant::now())); + assert!(buffer_pool_publisher.send_next_frame(1)); let events = subscriber.map_inner_mut(|s| s.take_events()); assert!(matches!(events.last().unwrap(), TestingSubscriberEvent::Next(_))); diff --git a/libs/ftl/Android.bp b/libs/ftl/Android.bp index 5ac965f566..32b2b68b4d 100644 --- a/libs/ftl/Android.bp +++ b/libs/ftl/Android.bp @@ -5,6 +5,7 @@ package { // to get the below license kinds: // SPDX-license-identifier-Apache-2.0 default_applicable_licenses: ["frameworks_native_license"], + default_team: "trendy_team_android_core_graphics_stack", } cc_test { diff --git a/libs/gralloc/types/Android.bp b/libs/gralloc/types/Android.bp index aab1276b47..f300da57d8 100644 --- a/libs/gralloc/types/Android.bp +++ b/libs/gralloc/types/Android.bp @@ -19,6 +19,7 @@ package { // to get the below license kinds: // SPDX-license-identifier-Apache-2.0 default_applicable_licenses: ["frameworks_native_license"], + default_team: "trendy_team_android_core_graphics_stack", } cc_library { diff --git a/libs/gralloc/types/fuzzer/Android.bp b/libs/gralloc/types/fuzzer/Android.bp index 3c3b6af670..833718213a 100644 --- a/libs/gralloc/types/fuzzer/Android.bp +++ b/libs/gralloc/types/fuzzer/Android.bp @@ -5,6 +5,7 @@ package { // to get the below license kinds: // SPDX-license-identifier-Apache-2.0 default_applicable_licenses: ["frameworks_native_license"], + default_team: "trendy_team_android_core_graphics_stack", } cc_fuzz { diff --git a/libs/gralloc/types/tests/Android.bp b/libs/gralloc/types/tests/Android.bp index 66eb0aa2fe..b796c03d6a 100644 --- a/libs/gralloc/types/tests/Android.bp +++ b/libs/gralloc/types/tests/Android.bp @@ -21,6 +21,7 @@ package { // to get the below license kinds: // SPDX-license-identifier-Apache-2.0 default_applicable_licenses: ["frameworks_native_license"], + default_team: "trendy_team_android_core_graphics_stack", } cc_test { @@ -30,5 +31,8 @@ cc_test { "libhidlbase", ], srcs: ["Gralloc4_test.cpp"], - cflags: ["-Wall", "-Werror"], + cflags: [ + "-Wall", + "-Werror", + ], } diff --git a/libs/graphicsenv/GraphicsEnv.cpp b/libs/graphicsenv/GraphicsEnv.cpp index 394a0002ed..50c05f4e5b 100644 --- a/libs/graphicsenv/GraphicsEnv.cpp +++ b/libs/graphicsenv/GraphicsEnv.cpp @@ -265,7 +265,8 @@ android_namespace_t* GraphicsEnv::getDriverNamespace() { auto vndkNamespace = android_get_exported_namespace("vndk"); if (!vndkNamespace) { - return nullptr; + mDriverNamespace = nullptr; + return mDriverNamespace; } mDriverNamespace = android_create_namespace("updatable gfx driver", @@ -617,7 +618,8 @@ android_namespace_t* GraphicsEnv::getAngleNamespace() { auto vndkNamespace = android_get_exported_namespace("vndk"); if (!vndkNamespace) { - return nullptr; + mAngleNamespace = nullptr; + return mAngleNamespace; } if (!linkDriverNamespaceLocked(mAngleNamespace, vndkNamespace, "")) { diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp index 4c3cc6cc3d..70cb36bad3 100644 --- a/libs/gui/Android.bp +++ b/libs/gui/Android.bp @@ -18,6 +18,7 @@ package { // to get the below license kinds: // SPDX-license-identifier-Apache-2.0 default_applicable_licenses: ["frameworks_native_license"], + default_team: "trendy_team_android_core_graphics_stack", } aconfig_declarations { diff --git a/libs/gui/FrameRateUtils.cpp b/libs/gui/FrameRateUtils.cpp index 11524e2b51..01aa7ed43c 100644 --- a/libs/gui/FrameRateUtils.cpp +++ b/libs/gui/FrameRateUtils.cpp @@ -42,6 +42,7 @@ bool ValidateFrameRate(float frameRate, int8_t compatibility, int8_t changeFrame if (compatibility != ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT && compatibility != ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE && + compatibility != ANATIVEWINDOW_FRAME_RATE_GTE && (!privileged || (compatibility != ANATIVEWINDOW_FRAME_RATE_EXACT && compatibility != ANATIVEWINDOW_FRAME_RATE_NO_VOTE))) { diff --git a/libs/gui/WindowInfo.cpp b/libs/gui/WindowInfo.cpp index 9429d2cc15..86bf0ee745 100644 --- a/libs/gui/WindowInfo.cpp +++ b/libs/gui/WindowInfo.cpp @@ -262,8 +262,6 @@ void WindowInfoHandle::updateFrom(sp<WindowInfoHandle> handle) { } std::ostream& operator<<(std::ostream& out, const WindowInfo& info) { - std::string transform; - info.transform.dump(transform, "transform", " "); out << "name=" << info.name << ", id=" << info.id << ", displayId=" << info.displayId << ", inputConfig=" << info.inputConfig.string() << ", alpha=" << info.alpha << ", frame=[" << info.frame.left << "," << info.frame.top << "][" << info.frame.right << "," @@ -274,9 +272,11 @@ std::ostream& operator<<(std::ostream& out, const WindowInfo& info) { << ", ownerUid=" << info.ownerUid.toString() << ", dispatchingTimeout=" << std::chrono::duration_cast<std::chrono::milliseconds>(info.dispatchingTimeout).count() << "ms, token=" << info.token.get() - << ", touchOcclusionMode=" << ftl::enum_string(info.touchOcclusionMode) << "\n" - << transform; - if (info.canOccludePresentation) out << " canOccludePresentation"; + << ", touchOcclusionMode=" << ftl::enum_string(info.touchOcclusionMode); + if (info.canOccludePresentation) out << ", canOccludePresentation"; + std::string transform; + info.transform.dump(transform, "transform", " "); + out << "\n" << transform; return out; } diff --git a/libs/gui/fuzzer/Android.bp b/libs/gui/fuzzer/Android.bp deleted file mode 100644 index cd738acde2..0000000000 --- a/libs/gui/fuzzer/Android.bp +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright 2021 The Android Open Source 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. - */ -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_native_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_native_license"], -} - -cc_defaults { - name: "libgui_fuzzer_defaults", - defaults: ["android.hardware.power-ndk_shared"], - static_libs: [ - "android.hidl.token@1.0-utils", - "libbinder_random_parcel", - "libgui_aidl_static", - "libgui_window_info_static", - "libpdx", - "libgmock", - "libgui_mocks", - "libgmock_ndk", - "libgmock_main", - "libgtest_ndk_c++", - "libgmock_main_ndk", - "librenderengine_mocks", - "perfetto_trace_protos", - "libcompositionengine_mocks", - "perfetto_trace_protos", - ], - shared_libs: [ - "android.hardware.configstore@1.0", - "android.hardware.configstore-utils", - "android.hardware.graphics.bufferqueue@1.0", - "android.hardware.graphics.bufferqueue@2.0", - "android.hidl.token@1.0", - "libSurfaceFlingerProp", - "libgui", - "libbase", - "liblog", - "libEGL", - "libGLESv2", - "libbinder", - "libcutils", - "libhidlbase", - "libinput", - "libui", - "libutils", - "libnativewindow", - "libvndksupport", - ], - header_libs: [ - "libdvr_headers", - "libui_fuzzableDataspaces_headers", - ], - fuzz_config: { - cc: [ - "android-media-fuzzing-reports@google.com", - ], - componentid: 155276, - hotlists: [ - "4593311", - ], - description: "The fuzzer targets the APIs of libgui library", - vector: "local_no_privileges_required", - service_privilege: "privileged", - users: "multi_user", - fuzzed_code_usage: "shipped", - }, -} - -cc_fuzz { - name: "libgui_surfaceComposer_fuzzer", - srcs: [ - "libgui_surfaceComposer_fuzzer.cpp", - ], - defaults: [ - "libgui_fuzzer_defaults", - "service_fuzzer_defaults", - ], -} - -cc_fuzz { - name: "libgui_surfaceComposerClient_fuzzer", - srcs: [ - "libgui_surfaceComposerClient_fuzzer.cpp", - ], - defaults: [ - "libgui_fuzzer_defaults", - "service_fuzzer_defaults", - ], -} - -cc_fuzz { - name: "libgui_parcelable_fuzzer", - srcs: [ - "libgui_parcelable_fuzzer.cpp", - ], - defaults: [ - "libgui_fuzzer_defaults", - ], -} - -cc_fuzz { - name: "libgui_bufferQueue_fuzzer", - srcs: [ - "libgui_bufferQueue_fuzzer.cpp", - ], - defaults: [ - "libgui_fuzzer_defaults", - ], -} - -cc_fuzz { - name: "libgui_consumer_fuzzer", - srcs: [ - "libgui_consumer_fuzzer.cpp", - ], - defaults: [ - "libgui_fuzzer_defaults", - ], -} - -cc_fuzz { - name: "libgui_displayEvent_fuzzer", - srcs: [ - "libgui_displayEvent_fuzzer.cpp", - ], - defaults: [ - "libgui_fuzzer_defaults", - ], -} diff --git a/libs/gui/fuzzer/README.md b/libs/gui/fuzzer/README.md deleted file mode 100644 index 96e27c989f..0000000000 --- a/libs/gui/fuzzer/README.md +++ /dev/null @@ -1,219 +0,0 @@ -# Fuzzers for Libgui - -## Table of contents -+ [libgui_surfaceComposer_fuzzer](#SurfaceComposer) -+ [libgui_surfaceComposerClient_fuzzer](#SurfaceComposerClient) -+ [libgui_parcelable_fuzzer](#Libgui_Parcelable) -+ [libgui_bufferQueue_fuzzer](#BufferQueue) -+ [libgui_consumer_fuzzer](#Libgui_Consumer) -+ [libgui_displayEvent_fuzzer](#LibGui_DisplayEvent) - -# <a name="libgui_surfaceComposer_fuzzer"></a> Fuzzer for SurfaceComposer - -SurfaceComposer supports the following parameters: -1. SurfaceWidth (parameter name:`width`) -2. SurfaceHeight (parameter name:`height`) -3. TransactionStateFlags (parameter name:`flags`) -4. TransformHint (parameter name:`outTransformHint`) -5. SurfacePixelFormat (parameter name:`format`) -6. LayerId (parameter name:`outLayerId`) -7. SurfaceComposerTags (parameter name:`surfaceTag`) -8. PowerBoostID (parameter name:`boostId`) -9. VsyncSource (parameter name:`vsyncSource`) -10. EventRegistrationFlags (parameter name:`eventRegistration`) -11. FrameRateCompatibility (parameter name:`frameRateCompatibility`) -12. ChangeFrameRateStrategy (parameter name:`changeFrameRateStrategy`) -13. HdrTypes (parameter name:`hdrTypes`) - -| Parameter| Valid Values| Configured Value| -|------------- |-------------| ----- | -|`surfaceTag` | 0.`BnSurfaceComposer::BOOT_FINISHED`, 1.`BnSurfaceComposer::CREATE_CONNECTION`, 2.`BnSurfaceComposer::GET_STATIC_DISPLAY_INFO`, 3.`BnSurfaceComposer::CREATE_DISPLAY_EVENT_CONNECTION`, 4.`BnSurfaceComposer::CREATE_DISPLAY`, 5.`BnSurfaceComposer::DESTROY_DISPLAY`, 6.`BnSurfaceComposer::GET_PHYSICAL_DISPLAY_TOKEN`, 7.`BnSurfaceComposer::SET_TRANSACTION_STATE`, 8.`BnSurfaceComposer::AUTHENTICATE_SURFACE`, 9.`BnSurfaceComposer::GET_SUPPORTED_FRAME_TIMESTAMPS`, 10.`BnSurfaceComposer::GET_DISPLAY_STATE`, 11.`BnSurfaceComposer::CAPTURE_DISPLAY`, 12.`BnSurfaceComposer::CAPTURE_LAYERS`, 13.`BnSurfaceComposer::CLEAR_ANIMATION_FRAME_STATS`, 14.`BnSurfaceComposer::GET_ANIMATION_FRAME_STATS`, 15.`BnSurfaceComposer::SET_POWER_MODE`, 16.`BnSurfaceComposer::GET_DISPLAY_STATS`, 17.`BnSurfaceComposer::SET_ACTIVE_COLOR_MODE`, 18.`BnSurfaceComposer::ENABLE_VSYNC_INJECTIONS`, 19.`BnSurfaceComposer::INJECT_VSYNC`, 20.`BnSurfaceComposer::GET_LAYER_DEBUG_INFO`, 21.`BnSurfaceComposer::GET_COMPOSITION_PREFERENCE`, 22.`BnSurfaceComposer::GET_COLOR_MANAGEMENT`, 23.`BnSurfaceComposer::GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES`, 24.`BnSurfaceComposer::SET_DISPLAY_CONTENT_SAMPLING_ENABLED`, 25.`BnSurfaceComposer::GET_DISPLAYED_CONTENT_SAMPLE`, 26.`BnSurfaceComposer::GET_PROTECTED_CONTENT_SUPPORT`, 27.`BnSurfaceComposer::IS_WIDE_COLOR_DISPLAY`, 28.`BnSurfaceComposer::GET_DISPLAY_NATIVE_PRIMARIES`, 29.`BnSurfaceComposer::GET_PHYSICAL_DISPLAY_IDS`, 30.`BnSurfaceComposer::ADD_REGION_SAMPLING_LISTENER`, 31.`BnSurfaceComposer::REMOVE_REGION_SAMPLING_LISTENER`, 32.`BnSurfaceComposer::SET_DESIRED_DISPLAY_MODE_SPECS`, 33.`BnSurfaceComposer::GET_DESIRED_DISPLAY_MODE_SPECS`, 34.`BnSurfaceComposer::GET_DISPLAY_BRIGHTNESS_SUPPORT`, 35.`BnSurfaceComposer::SET_DISPLAY_BRIGHTNESS`, 36.`BnSurfaceComposer::CAPTURE_DISPLAY_BY_ID`, 37.`BnSurfaceComposer::NOTIFY_POWER_BOOST`, 38.`BnSurfaceComposer::SET_GLOBAL_SHADOW_SETTINGS`, 39.`BnSurfaceComposer::SET_AUTO_LOW_LATENCY_MODE`, 40.`BnSurfaceComposer::SET_GAME_CONTENT_TYPE`, 41.`BnSurfaceComposer::SET_FRAME_RATE`, 42.`BnSurfaceComposer::ACQUIRE_FRAME_RATE_FLEXIBILITY_TOKEN`, 43.`BnSurfaceComposer::SET_FRAME_TIMELINE_INFO`, 44.`BnSurfaceComposer::ADD_TRANSACTION_TRACE_LISTENER`, 45.`BnSurfaceComposer::GET_GPU_CONTEXT_PRIORITY`, 46.`BnSurfaceComposer::GET_MAX_ACQUIRED_BUFFER_COUNT`, 47.`BnSurfaceComposer::GET_DYNAMIC_DISPLAY_INFO`, 48.`BnSurfaceComposer::ADD_FPS_LISTENER`, 49.`BnSurfaceComposer::REMOVE_FPS_LISTENER`, 50.`BnSurfaceComposer::OVERRIDE_HDR_TYPES`, 51.`BnSurfaceComposer::ADD_HDR_LAYER_INFO_LISTENER`, 52.`BnSurfaceComposer::REMOVE_HDR_LAYER_INFO_LISTENER`, 53.`BnSurfaceComposer::ON_PULL_ATOM`, 54.`BnSurfaceComposer::ADD_TUNNEL_MODE_ENABLED_LISTENER`, 55.`BnSurfaceComposer::REMOVE_TUNNEL_MODE_ENABLED_LISTENER` | Value obtained from FuzzedDataProvider| -|`boostId`| 0.`hardware::power::Boost::INTERACTION`, 1.`hardware::power::Boost::DISPLAY_UPDATE_IMMINENT`, 2.`hardware::power::Boost::ML_ACC`, 3.`hardware::power::Boost::AUDIO_LAUNCH`, 4.`hardware::power::Boost::CAMERA_LAUNCH`, 5.`hardware::power::Boost::CAMERA_SHOT` |Value obtained from FuzzedDataProvider| -|`vsyncSource`| 0.`ISurfaceComposer::eVsyncSourceApp`, 1.`ISurfaceComposer::eVsyncSourceSurfaceFlinger`, |Value obtained from FuzzedDataProvider| -|`eventRegistration`| 0.`ISurfaceComposer::EventRegistration::modeChanged`, 1.`ISurfaceComposer::EventRegistration::frameRateOverride` |Value obtained from FuzzedDataProvider| -|`frameRateCompatibility`| 0.`ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT`, 1.`ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE` |Value obtained from FuzzedDataProvider| -|`changeFrameRateStrategy`| 0.`ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS`, 1.`ANATIVEWINDOW_CHANGE_FRAME_RATE_ALWAYS` |Value obtained from FuzzedDataProvider| -|`hdrTypes`| 0.`ui::Hdr::DOLBY_VISION`, 1.`ui::Hdr::HDR10`, 2.`ui::Hdr::HLG`, 3.`ui::Hdr::HDR10_PLUS` |Value obtained from FuzzedDataProvider| - -#### Steps to run -1. Build the fuzzer -``` - $ mm -j$(nproc) libgui_surfaceComposer_fuzzer -``` -2. Run on device -``` - $ adb sync data - $ adb shell /data/fuzz/arm64/libgui_surfaceComposer_fuzzer/libgui_surfaceComposer_fuzzer -``` - -# <a name="libgui_surfaceComposerClient_fuzzer"></a> Fuzzer for SurfaceComposerClient - -SurfaceComposerClient supports the following data sources: -1. SurfaceWidth (parameter name:`width`) -2. SurfaceHeight (parameter name:`height`) -3. TransactionStateFlags (parameter name:`flags`) -4. TransformHint (parameter name:`outTransformHint`) -5. SurfacePixelFormat (parameter name:`format`) -6. LayerId (parameter name:`outLayerId`) -7. SurfaceComposerClientTags (parameter name:`surfaceTag`) -8. DefaultMode (parameter name:`defaultMode`) -9. PrimaryRefreshRateMin (parameter name:`primaryRefreshRateMin`) -10. PrimaryRefreshRateMax (parameter name:`primaryRefreshRateMax`) -11. AppRefreshRateMin (parameter name:`appRefreshRateMin`) -12. AppRefreshRateMax (parameter name:`appRefreshRateMax`) -13. DisplayPowerMode (parameter name:`mode`) -14. CacheId (parameter name:`cacheId`) -15. DisplayBrightness (parameter name:`brightness`) -16. PowerBoostID (parameter name:`boostId`) -17. AtomId (parameter name:`atomId`) -18. ComponentMask (parameter name:`componentMask`) -19. MaxFrames (parameter name:`maxFrames`) -20. TaskId (parameter name:`taskId`) -21. Alpha (parameter name:`aplha`) -22. CornerRadius (parameter name:`cornerRadius`) -23. BackgroundBlurRadius (parameter name:`backgroundBlurRadius`) -24. Half3Color (parameter name:`color`) -25. LayerStack (parameter name:`layerStack`) -26. Dataspace (parameter name:`dataspace`) -27. Api (parameter name:`api`) -28. Priority (parameter name:`priority`) -29. TouchableRegionPointX (parameter name:`pointX`) -30. TouchableRegionPointY (parameter name:`pointY`) -31. ColorMode (parameter name:`colorMode`) -32. WindowInfoFlags (parameter name:`flags`) -33. WindowInfoTransformOrientation (parameter name:`transform`) - -| Parameter| Valid Values| Configured Value| -|------------- |-------------| ----- | -|`surfaceTag`| 0.`Tag::CREATE_SURFACE`, 1.`Tag::CREATE_WITH_SURFACE_PARENT`, 2.`Tag::CLEAR_LAYER_FRAME_STATS`, 3.`Tag::GET_LAYER_FRAME_STATS`, 4.`Tag::MIRROR_SURFACE`, 5.`Tag::LAST` |Value obtained from FuzzedDataProvider| -|`mode`| 0.`gui::TouchOcclusionMode::BLOCK_UNTRUSTED`, 1.`gui::TouchOcclusionMode::USE_OPACITY`, 2.`gui::TouchOcclusionMode::ALLOW` |Value obtained from FuzzedDataProvider| -|`boostId`| 0.`hardware::power::Boost::INTERACTION`, 1.`hardware::power::Boost::DISPLAY_UPDATE_IMMINENT`, 2.`hardware::power::Boost::ML_ACC`, 3.`hardware::power::Boost::AUDIO_LAUNCH`, 4.`hardware::power::Boost::CAMERA_LAUNCH`, 5.`hardware::power::Boost::CAMERA_SHOT` |Value obtained from FuzzedDataProvider| -|`colorMode`|0.`ui::ColorMode::NATIVE`, 1.`ui::ColorMode::STANDARD_BT601_625`, 2.`ui::ColorMode::STANDARD_BT601_625_UNADJUSTED`, 3.`ui::ColorMode::STANDARD_BT601_525`, 4.`ui::ColorMode::STANDARD_BT601_525_UNADJUSTED`, 5.`ui::ColorMode::STANDARD_BT709`, 6.`ui::ColorMode::DCI_P3`, 7.`ui::ColorMode::SRGB`, 8.`ui::ColorMode::ADOBE_RGB`, 9.`ui::ColorMode::DISPLAY_P3`, 10.`ui::ColorMode::BT2020`, 11.`ui::ColorMode::BT2100_PQ`, 12.`ui::ColorMode::BT2100_HLG`, 13.`ui::ColorMode::DISPLAY_BT2020` |Value obtained from FuzzedDataProvider| -|`flags`|0 .`gui::WindowInfo::Flag::ALLOW_LOCK_WHILE_SCREEN_ON`, 1.`gui::WindowInfo::Flag::DIM_BEHIND`, 2.`gui::WindowInfo::Flag::BLUR_BEHIND`, 3.`gui::WindowInfo::Flag::NOT_FOCUSABLE`, 4.`gui::WindowInfo::Flag::NOT_TOUCHABLE`, 5.`gui::WindowInfo::Flag::NOT_TOUCH_MODAL`, 6.`gui::WindowInfo::Flag::TOUCHABLE_WHEN_WAKING`, 7.`gui::WindowInfo::Flag::KEEP_SCREEN_ON`, 8.`gui::WindowInfo::Flag::LAYOUT_IN_SCREEN`, 9.`gui::WindowInfo::Flag::LAYOUT_NO_LIMITS`, 10.`gui::WindowInfo::Flag::FULLSCREEN`, 11.`gui::WindowInfo::Flag::FORCE_NOT_FULLSCREEN`, 12.`gui::WindowInfo::Flag::DITHER`, 13.`gui::WindowInfo::Flag::SECURE`, 14.`gui::WindowInfo::Flag::SCALED`, 15.`gui::WindowInfo::Flag::IGNORE_CHEEK_PRESSES`, 16.`gui::WindowInfo::Flag::LAYOUT_INSET_DECOR`, 17.`gui::WindowInfo::Flag::ALT_FOCUSABLE_IM`, 18.`gui::WindowInfo::Flag::WATCH_OUTSIDE_TOUCH`, 19.`gui::WindowInfo::Flag::SHOW_WHEN_LOCKED`, 20.`gui::WindowInfo::Flag::SHOW_WALLPAPER`, 21.`gui::WindowInfo::Flag::TURN_SCREEN_ON`, 22.`gui::WindowInfo::Flag::DISMISS_KEYGUARD`, 23.`gui::WindowInfo::Flag::SPLIT_TOUCH`, 24.`gui::WindowInfo::Flag::HARDWARE_ACCELERATED`, 25.`gui::WindowInfo::Flag::LAYOUT_IN_OVERSCAN`, 26.`gui::WindowInfo::Flag::TRANSLUCENT_STATUS`, 27.`gui::WindowInfo::Flag::TRANSLUCENT_NAVIGATION`, 28.`gui::WindowInfo::Flag::LOCAL_FOCUS_MODE`, 29.`gui::WindowInfo::Flag::SLIPPERY`, 30.`gui::WindowInfo::Flag::LAYOUT_ATTACHED_IN_DECOR`, 31.`gui::WindowInfo::Flag::DRAWS_SYSTEM_BAR_BACKGROUNDS`, |Value obtained from FuzzedDataProvider| -|`dataspace`| 0.`ui::Dataspace::UNKNOWN`, 1.`ui::Dataspace::ARBITRARY`, 2.`ui::Dataspace::STANDARD_SHIFT`, 3.`ui::Dataspace::STANDARD_MASK`, 4.`ui::Dataspace::STANDARD_UNSPECIFIED`, 5.`ui::Dataspace::STANDARD_BT709`, 6.`ui::Dataspace::STANDARD_BT601_625`, 7.`ui::Dataspace::STANDARD_BT601_625_UNADJUSTED`, 8.`ui::Dataspace::STANDARD_BT601_525`, 9.`ui::Dataspace::STANDARD_BT601_525_UNADJUSTED`, 10.`ui::Dataspace::STANDARD_BT2020`, 11.`ui::Dataspace::STANDARD_BT2020_CONSTANT_LUMINANCE`, 12.`ui::Dataspace::STANDARD_BT470M`, 13.`ui::Dataspace::STANDARD_FILM`, 14.`ui::Dataspace::STANDARD_DCI_P3`, 15.`ui::Dataspace::STANDARD_ADOBE_RGB`, 16.`ui::Dataspace::TRANSFER_SHIFT`, 17.`ui::Dataspace::TRANSFER_MASK`, 18.`ui::Dataspace::TRANSFER_UNSPECIFIED`, 19.`ui::Dataspace::TRANSFER_LINEAR`, 20.`ui::Dataspace::TRANSFER_SRGB`, 21.`ui::Dataspace::TRANSFER_SMPTE_170M`, 22.`ui::Dataspace::TRANSFER_GAMMA2_2`, 23.`ui::Dataspace::TRANSFER_GAMMA2_6`, 24.`ui::Dataspace::TRANSFER_GAMMA2_8`, 25.`ui::Dataspace::TRANSFER_ST2084`, 26.`ui::Dataspace::TRANSFER_HLG`, 27.`ui::Dataspace::RANGE_SHIFT`, 28.`ui::Dataspace::RANGE_MASK`, 29.`ui::Dataspace::RANGE_UNSPECIFIED`, 30.`ui::Dataspace::RANGE_FULL`, 31.`ui::Dataspace::RANGE_LIMITED`, 32.`ui::Dataspace::RANGE_EXTENDED`, 33.`ui::Dataspace::SRGB_LINEAR`, 34.`ui::Dataspace::V0_SRGB_LINEAR`, 35.`ui::Dataspace::V0_SCRGB_LINEAR`, 36.`ui::Dataspace::SRGB`, 37.`ui::Dataspace::V0_SRGB`, 38.`ui::Dataspace::V0_SCRGB`, 39.`ui::Dataspace::JFIF`, 40.`ui::Dataspace::V0_JFIF`, 41.`ui::Dataspace::BT601_625`, 42.`ui::Dataspace::V0_BT601_625`, 43.`ui::Dataspace::BT601_525`, 44.`ui::Dataspace::V0_BT601_525`, 45.`ui::Dataspace::BT709`, 46.`ui::Dataspace::V0_BT709`, 47.`ui::Dataspace::DCI_P3_LINEAR`, 48.`ui::Dataspace::DCI_P3`, 49.`ui::Dataspace::DISPLAY_P3_LINEAR`, 50.`ui::Dataspace::DISPLAY_P3`, 51.`ui::Dataspace::ADOBE_RGB`, 52.`ui::Dataspace::BT2020_LINEAR`, 53.`ui::Dataspace::BT2020`, 54.`ui::Dataspace::BT2020_PQ`, 55.`ui::Dataspace::DEPTH`, 56.`ui::Dataspace::SENSOR`, 57.`ui::Dataspace::BT2020_ITU`, 58.`ui::Dataspace::BT2020_ITU_PQ`, 59.`ui::Dataspace::BT2020_ITU_HLG`, 60.`ui::Dataspace::BT2020_HLG`, 61.`ui::Dataspace::DISPLAY_BT2020`, 62.`ui::Dataspace::DYNAMIC_DEPTH`, 63.`ui::Dataspace::JPEG_APP_SEGMENTS`, 64.`ui::Dataspace::HEIF`, |Value obtained from FuzzedDataProvider| -|`transform`| 0.`ui::Transform::ROT_0`, 1.`ui::Transform::FLIP_H`, 2.`ui::Transform::FLIP_V`, 3.`ui::Transform::ROT_90`, 4.`ui::Transform::ROT_180`, 5.`ui::Transform::ROT_270` |Value obtained from FuzzedDataProvider| - -#### Steps to run -1. Build the fuzzer -``` - $ mm -j$(nproc) libgui_surfaceComposerClient_fuzzer -``` -2. To run on device -``` - $ adb sync data - $ adb shell /data/fuzz/arm64/libgui_surfaceComposerClient_fuzzer/libgui_surfaceComposerClient_fuzzer -``` - -# <a name="libgui_parcelable_fuzzer"></a> Fuzzer for Libgui_Parcelable - -Libgui_Parcelable supports the following parameters: -1. LayerMetadataKey (parameter name:`key`) -2. Dataspace (parameter name:`mDataspace`) - -| Parameter| Valid Values| Configured Value| -|------------- |-------------| ----- | -|`key`| 0.`view::LayerMetadataKey::METADATA_OWNER_UID`, 1.`view::LayerMetadataKey::METADATA_WINDOW_TYPE`, 2.`view::LayerMetadataKey::METADATA_TASK_ID`, 3.`view::LayerMetadataKey::METADATA_MOUSE_CURSOR`, 4.`view::LayerMetadataKey::METADATA_ACCESSIBILITY_ID`, 5.`view::LayerMetadataKey::METADATA_OWNER_PID`, 6.`view::LayerMetadataKey::METADATA_DEQUEUE_TIME`, 7.`view::LayerMetadataKey::METADATA_GAME_MODE`, |Value obtained from FuzzedDataProvider| -|`mDataSpace`| 0.`ui::Dataspace::UNKNOWN`, 1.`ui::Dataspace::ARBITRARY`, 2.`ui::Dataspace::STANDARD_SHIFT`, 3.`ui::Dataspace::STANDARD_MASK`, 4.`ui::Dataspace::STANDARD_UNSPECIFIED`, 5.`ui::Dataspace::STANDARD_BT709`, 6.`ui::Dataspace::STANDARD_BT601_625`, 7.`ui::Dataspace::STANDARD_BT601_625_UNADJUSTED`, 8.`ui::Dataspace::STANDARD_BT601_525`, 9.`ui::Dataspace::STANDARD_BT601_525_UNADJUSTED`, 10.`ui::Dataspace::STANDARD_BT2020`, 11.`ui::Dataspace::STANDARD_BT2020_CONSTANT_LUMINANCE`, 12.`ui::Dataspace::STANDARD_BT470M`, 13.`ui::Dataspace::STANDARD_FILM`, 14.`ui::Dataspace::STANDARD_DCI_P3`, 15.`ui::Dataspace::STANDARD_ADOBE_RGB`, 16.`ui::Dataspace::TRANSFER_SHIFT`, 17.`ui::Dataspace::TRANSFER_MASK`, 18.`ui::Dataspace::TRANSFER_UNSPECIFIED`, 19.`ui::Dataspace::TRANSFER_LINEAR`, 20.`ui::Dataspace::TRANSFER_SRGB`, 21.`ui::Dataspace::TRANSFER_SMPTE_170M`, 22.`ui::Dataspace::TRANSFER_GAMMA2_2`, 23.`ui::Dataspace::TRANSFER_GAMMA2_6`, 24.`ui::Dataspace::TRANSFER_GAMMA2_8`, 25.`ui::Dataspace::TRANSFER_ST2084`, 26.`ui::Dataspace::TRANSFER_HLG`, 27.`ui::Dataspace::RANGE_SHIFT`, 28.`ui::Dataspace::RANGE_MASK`, 29.`ui::Dataspace::RANGE_UNSPECIFIED`, 30.`ui::Dataspace::RANGE_FULL`, 31.`ui::Dataspace::RANGE_LIMITED`, 32.`ui::Dataspace::RANGE_EXTENDED`, 33.`ui::Dataspace::SRGB_LINEAR`, 34.`ui::Dataspace::V0_SRGB_LINEAR`, 35.`ui::Dataspace::V0_SCRGB_LINEAR`, 36.`ui::Dataspace::SRGB`, 37.`ui::Dataspace::V0_SRGB`, 38.`ui::Dataspace::V0_SCRGB`, 39.`ui::Dataspace::JFIF`, 40.`ui::Dataspace::V0_JFIF`, 41.`ui::Dataspace::BT601_625`, 42.`ui::Dataspace::V0_BT601_625`, 43.`ui::Dataspace::BT601_525`, 44.`ui::Dataspace::V0_BT601_525`, 45.`ui::Dataspace::BT709`, 46.`ui::Dataspace::V0_BT709`, 47.`ui::Dataspace::DCI_P3_LINEAR`, 48.`ui::Dataspace::DCI_P3`, 49.`ui::Dataspace::DISPLAY_P3_LINEAR`, 50.`ui::Dataspace::DISPLAY_P3`, 51.`ui::Dataspace::ADOBE_RGB`, 52.`ui::Dataspace::BT2020_LINEAR`, 53.`ui::Dataspace::BT2020`, 54.`ui::Dataspace::BT2020_PQ`, 55.`ui::Dataspace::DEPTH`, 56.`ui::Dataspace::SENSOR`, 57.`ui::Dataspace::BT2020_ITU`, 58.`ui::Dataspace::BT2020_ITU_PQ`, 59.`ui::Dataspace::BT2020_ITU_HLG`, 60.`ui::Dataspace::BT2020_HLG`, 61.`ui::Dataspace::DISPLAY_BT2020`, 62.`ui::Dataspace::DYNAMIC_DEPTH`, 63.`ui::Dataspace::JPEG_APP_SEGMENTS`, 64.`ui::Dataspace::HEIF`, |Value obtained from FuzzedDataProvider| - -#### Steps to run -1. Build the fuzzer -``` - $ mm -j$(nproc) libgui_fuzzer -``` -2. Run on device -``` - $ adb sync data - $ adb shell /data/fuzz/arm64/libgui_fuzzer/libgui_fuzzer -``` - -# <a name="libgui_bufferQueue_fuzzer"></a> Fuzzer for BufferQueue - -BufferQueue supports the following parameters: -1. SurfaceWidth (parameter name:`width`) -2. SurfaceHeight (parameter name:`height`) -3. TransactionStateFlags (parameter name:`flags`) -4. TransformHint (parameter name:`outTransformHint`) -5. SurfacePixelFormat (parameter name:`format`) -6. LayerId (parameter name:`layerId`) -7. BufferId (parameter name:`bufferId`) -8. FrameNumber (parameter name:`frameNumber`) -9. FrameRate (parameter name:`frameRate`) -10. Compatability (parameter name:`compatability`) -11. LatchTime (parameter name:`latchTime`) -12. AcquireTime (parameter name:`acquireTime`) -13. RefreshTime (parameter name:`refreshTime`) -14. DequeueTime (parameter name:`dequeueTime`) -15. Slot (parameter name:`slot`) -16. MaxBuffers (parameter name:`maxBuffers`) -17. GenerationNumber (parameter name:`generationNumber`) -18. Api (parameter name:`api`) -19. Usage (parameter name:`usage`) -20. MaxFrameNumber (parameter name:`maxFrameNumber`) -21. BufferCount (parameter name:`bufferCount`) -22. MaxAcquredBufferCount (parameter name:`maxAcquredBufferCount`) -23. Status (parameter name:`status`) -24. ApiConnection (parameter name:`apiConnection`) -25. Dataspace (parameter name:`dataspace`) - -| Parameter| Valid Values| Configured Value| -|------------- |-------------| ----- | -|`status`| 0.`OK`, 1.`NO_MEMORY`, 2.`NO_INIT`, 3.`BAD_VALUE`, 4.`DEAD_OBJECT`, 5.`INVALID_OPERATION`, 6.`TIMED_OUT`, 7.`WOULD_BLOCK`, 8.`UNKNOWN_ERROR`, 9.`ALREADY_EXISTS`, |Value obtained from FuzzedDataProvider| -|`apiConnection`| 0.`BufferQueueCore::CURRENTLY_CONNECTED_API`, 1.`BufferQueueCore::NO_CONNECTED_API`, 2.`NATIVE_WINDOW_API_EGL`, 3.`NATIVE_WINDOW_API_CPU`, 4.`NATIVE_WINDOW_API_MEDIA`, 5.`NATIVE_WINDOW_API_CAMERA`, |Value obtained from FuzzedDataProvider| -|`dataspace`| 0.`ui::Dataspace::UNKNOWN`, 1.`ui::Dataspace::ARBITRARY`, 2.`ui::Dataspace::STANDARD_SHIFT`, 3.`ui::Dataspace::STANDARD_MASK`, 4.`ui::Dataspace::STANDARD_UNSPECIFIED`, 5.`ui::Dataspace::STANDARD_BT709`, 6.`ui::Dataspace::STANDARD_BT601_625`, 7.`ui::Dataspace::STANDARD_BT601_625_UNADJUSTED`, 8.`ui::Dataspace::STANDARD_BT601_525`, 9.`ui::Dataspace::STANDARD_BT601_525_UNADJUSTED`, 10.`ui::Dataspace::STANDARD_BT2020`, 11.`ui::Dataspace::STANDARD_BT2020_CONSTANT_LUMINANCE`, 12.`ui::Dataspace::STANDARD_BT470M`, 13.`ui::Dataspace::STANDARD_FILM`, 14.`ui::Dataspace::STANDARD_DCI_P3`, 15.`ui::Dataspace::STANDARD_ADOBE_RGB`, 16.`ui::Dataspace::TRANSFER_SHIFT`, 17.`ui::Dataspace::TRANSFER_MASK`, 18.`ui::Dataspace::TRANSFER_UNSPECIFIED`, 19.`ui::Dataspace::TRANSFER_LINEAR`, 20.`ui::Dataspace::TRANSFER_SRGB`, 21.`ui::Dataspace::TRANSFER_SMPTE_170M`, 22.`ui::Dataspace::TRANSFER_GAMMA2_2`, 23.`ui::Dataspace::TRANSFER_GAMMA2_6`, 24.`ui::Dataspace::TRANSFER_GAMMA2_8`, 25.`ui::Dataspace::TRANSFER_ST2084`, 26.`ui::Dataspace::TRANSFER_HLG`, 27.`ui::Dataspace::RANGE_SHIFT`, 28.`ui::Dataspace::RANGE_MASK`, 29.`ui::Dataspace::RANGE_UNSPECIFIED`, 30.`ui::Dataspace::RANGE_FULL`, 31.`ui::Dataspace::RANGE_LIMITED`, 32.`ui::Dataspace::RANGE_EXTENDED`, 33.`ui::Dataspace::SRGB_LINEAR`, 34.`ui::Dataspace::V0_SRGB_LINEAR`, 35.`ui::Dataspace::V0_SCRGB_LINEAR`, 36.`ui::Dataspace::SRGB`, 37.`ui::Dataspace::V0_SRGB`, 38.`ui::Dataspace::V0_SCRGB`, 39.`ui::Dataspace::JFIF`, 40.`ui::Dataspace::V0_JFIF`, 41.`ui::Dataspace::BT601_625`, 42.`ui::Dataspace::V0_BT601_625`, 43.`ui::Dataspace::BT601_525`, 44.`ui::Dataspace::V0_BT601_525`, 45.`ui::Dataspace::BT709`, 46.`ui::Dataspace::V0_BT709`, 47.`ui::Dataspace::DCI_P3_LINEAR`, 48.`ui::Dataspace::DCI_P3`, 49.`ui::Dataspace::DISPLAY_P3_LINEAR`, 50.`ui::Dataspace::DISPLAY_P3`, 51.`ui::Dataspace::ADOBE_RGB`, 52.`ui::Dataspace::BT2020_LINEAR`, 53.`ui::Dataspace::BT2020`, 54.`ui::Dataspace::BT2020_PQ`, 55.`ui::Dataspace::DEPTH`, 56.`ui::Dataspace::SENSOR`, 57.`ui::Dataspace::BT2020_ITU`, 58.`ui::Dataspace::BT2020_ITU_PQ`, 59.`ui::Dataspace::BT2020_ITU_HLG`, 60.`ui::Dataspace::BT2020_HLG`, 61.`ui::Dataspace::DISPLAY_BT2020`, 62.`ui::Dataspace::DYNAMIC_DEPTH`, 63.`ui::Dataspace::JPEG_APP_SEGMENTS`, 64.`ui::Dataspace::HEIF`, |Value obtained from FuzzedDataProvider| - -#### Steps to run -1. Build the fuzzer -``` - $ mm -j$(nproc) libgui_bufferQueue_fuzzer -``` -2. To run on device -``` - $ adb sync data - $ adb shell /data/fuzz/arm64/libgui_bufferQueue_fuzzer/libgui_bufferQueue_fuzzer -``` - -# <a name="libgui_consumer_fuzzer"></a> Fuzzer for Libgui_Consumer - -Libgui_Consumer supports the following parameters: -1. GraphicWidth (parameter name:`graphicWidth`) -2. GraphicHeight (parameter name:`graphicHeight`) -4. TransformHint (parameter name:`outTransformHint`) -5. GraphicPixelFormat (parameter name:`format`) -6. Usage (parameter name:`usage`) - -#### Steps to run -1. Build the fuzzer -``` - $ mm -j$(nproc) libgui_consumer_fuzzer -``` -2. Run on device -``` - $ adb sync data - $ adb shell /data/fuzz/arm64/libgui_consumer_fuzzer/libgui_consumer_fuzzer -``` - -# <a name="libgui_displayEvent_fuzzer"></a> Fuzzer for LibGui_DisplayEvent - -LibGui_DisplayEvent supports the following parameters: -1. DisplayEventType (parameter name:`type`) -2. Events (parameter name:`events`) -3. VsyncSource (parameter name:`vsyncSource`) -4. EventRegistrationFlags (parameter name:`flags`) - -| Parameter| Valid Values| Configured Value| -|------------- |-------------| ----- | -|`vsyncSource`| 0.`ISurfaceComposer::eVsyncSourceApp`, 1.`ISurfaceComposer::eVsyncSourceSurfaceFlinger`, |Value obtained from FuzzedDataProvider| -|`flags`| 0.`ISurfaceComposer::EventRegistration::modeChanged`, 1.`ISurfaceComposer::EventRegistration::frameRateOverride`, |Value obtained from FuzzedDataProvider| -|`type`| 0.`DisplayEventReceiver::DISPLAY_EVENT_NULL`, 1.`DisplayEventReceiver::DISPLAY_EVENT_VSYNC`, 2.`DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG`, 3.`DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE`, 4.`DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE`, 5.`DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH`, |Value obtained from FuzzedDataProvider| -|`events`| 0.`Looper::EVENT_INPUT`, 1.`Looper::EVENT_OUTPUT`, 2.`Looper::EVENT_ERROR`, 3.`Looper::EVENT_HANGUP`, 4.`Looper::EVENT_INVALID`, |Value obtained from FuzzedDataProvider| - -#### Steps to run -1. Build the fuzzer -``` - $ mm -j$(nproc) libgui_displayEvent_fuzzer -``` -2. Run on device -``` - $ adb sync data - $ adb shell /data/fuzz/arm64/libgui_displayEvent_fuzzer/libgui_displayEvent_fuzzer -``` diff --git a/libs/gui/fuzzer/libgui_bufferQueue_fuzzer.cpp b/libs/gui/fuzzer/libgui_bufferQueue_fuzzer.cpp deleted file mode 100644 index 2e270b721f..0000000000 --- a/libs/gui/fuzzer/libgui_bufferQueue_fuzzer.cpp +++ /dev/null @@ -1,392 +0,0 @@ -/* - * Copyright 2022 The Android Open Source 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 <android-base/stringprintf.h> -#include <gui/BufferQueueConsumer.h> -#include <gui/BufferQueueCore.h> -#include <gui/BufferQueueProducer.h> -#include <gui/bufferqueue/2.0/types.h> -#include <system/window.h> - -#include <libgui_fuzzer_utils.h> - -using namespace android; -using namespace hardware::graphics::bufferqueue; -using namespace V1_0::utils; -using namespace V2_0::utils; - -constexpr int32_t kMaxBytes = 256; - -constexpr int32_t kError[] = { - OK, NO_MEMORY, NO_INIT, BAD_VALUE, DEAD_OBJECT, INVALID_OPERATION, - TIMED_OUT, WOULD_BLOCK, UNKNOWN_ERROR, ALREADY_EXISTS, -}; - -constexpr int32_t kAPIConnection[] = { - BufferQueueCore::CURRENTLY_CONNECTED_API, - BufferQueueCore::NO_CONNECTED_API, - NATIVE_WINDOW_API_EGL, - NATIVE_WINDOW_API_CPU, - NATIVE_WINDOW_API_MEDIA, - NATIVE_WINDOW_API_CAMERA, -}; - -class BufferQueueFuzzer { -public: - BufferQueueFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){}; - void process(); - -private: - void invokeTypes(); - void invokeH2BGraphicBufferV1(); - void invokeH2BGraphicBufferV2(); - void invokeBufferQueueConsumer(); - void invokeBufferQueueProducer(); - void invokeBlastBufferQueue(); - void invokeQuery(sp<BufferQueueProducer>); - void invokeQuery(sp<V1_0::utils::H2BGraphicBufferProducer>); - void invokeQuery(sp<V2_0::utils::H2BGraphicBufferProducer>); - void invokeAcquireBuffer(sp<BufferQueueConsumer>); - void invokeOccupancyTracker(sp<BufferQueueConsumer>); - sp<SurfaceControl> makeSurfaceControl(); - sp<BLASTBufferQueue> makeBLASTBufferQueue(sp<SurfaceControl>); - - FuzzedDataProvider mFdp; -}; - -class ManageResourceHandle { -public: - ManageResourceHandle(FuzzedDataProvider* fdp) { - mNativeHandle = native_handle_create(0 /*numFds*/, 1 /*numInts*/); - mShouldOwn = fdp->ConsumeBool(); - mStream = NativeHandle::create(mNativeHandle, mShouldOwn); - } - ~ManageResourceHandle() { - if (!mShouldOwn) { - native_handle_close(mNativeHandle); - native_handle_delete(mNativeHandle); - } - } - sp<NativeHandle> getStream() { return mStream; } - -private: - bool mShouldOwn; - sp<NativeHandle> mStream; - native_handle_t* mNativeHandle; -}; - -sp<SurfaceControl> BufferQueueFuzzer::makeSurfaceControl() { - sp<IBinder> handle; - const sp<FakeBnSurfaceComposerClient> testClient(new FakeBnSurfaceComposerClient()); - sp<SurfaceComposerClient> client = new SurfaceComposerClient(testClient); - sp<BnGraphicBufferProducer> producer; - uint32_t layerId = mFdp.ConsumeIntegral<uint32_t>(); - std::string layerName = base::StringPrintf("#%d", layerId); - return sp<SurfaceControl>::make(client, handle, layerId, layerName, - mFdp.ConsumeIntegral<int32_t>(), - mFdp.ConsumeIntegral<uint32_t>(), - mFdp.ConsumeIntegral<int32_t>(), - mFdp.ConsumeIntegral<uint32_t>(), - mFdp.ConsumeIntegral<uint32_t>()); -} - -sp<BLASTBufferQueue> BufferQueueFuzzer::makeBLASTBufferQueue(sp<SurfaceControl> surface) { - return sp<BLASTBufferQueue>::make(mFdp.ConsumeRandomLengthString(kMaxBytes), surface, - mFdp.ConsumeIntegral<uint32_t>(), - mFdp.ConsumeIntegral<uint32_t>(), - mFdp.ConsumeIntegral<int32_t>()); -} - -void BufferQueueFuzzer::invokeBlastBufferQueue() { - sp<SurfaceControl> surface = makeSurfaceControl(); - sp<BLASTBufferQueue> queue = makeBLASTBufferQueue(surface); - - BufferItem item; - queue->onFrameAvailable(item); - queue->onFrameReplaced(item); - uint64_t bufferId = mFdp.ConsumeIntegral<uint64_t>(); - queue->onFrameDequeued(bufferId); - queue->onFrameCancelled(bufferId); - - SurfaceComposerClient::Transaction next; - uint64_t frameNumber = mFdp.ConsumeIntegral<uint64_t>(); - queue->mergeWithNextTransaction(&next, frameNumber); - queue->applyPendingTransactions(frameNumber); - - queue->update(surface, mFdp.ConsumeIntegral<uint32_t>(), mFdp.ConsumeIntegral<uint32_t>(), - mFdp.ConsumeIntegral<int32_t>()); - queue->setFrameRate(mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeIntegral<int8_t>(), - mFdp.ConsumeBool() /*shouldBeSeamless*/); - FrameTimelineInfo info; - queue->setFrameTimelineInfo(mFdp.ConsumeIntegral<uint64_t>(), info); - - ManageResourceHandle handle(&mFdp); - queue->setSidebandStream(handle.getStream()); - - queue->getLastTransformHint(); - queue->getLastAcquiredFrameNum(); - - CompositorTiming compTiming; - sp<Fence> previousFence = new Fence(memfd_create("pfd", MFD_ALLOW_SEALING)); - sp<Fence> gpuFence = new Fence(memfd_create("gfd", MFD_ALLOW_SEALING)); - FrameEventHistoryStats frameStats(frameNumber, mFdp.ConsumeIntegral<uint64_t>(), gpuFence, - compTiming, mFdp.ConsumeIntegral<int64_t>(), - mFdp.ConsumeIntegral<int64_t>()); - std::vector<SurfaceControlStats> stats; - sp<Fence> presentFence = new Fence(memfd_create("fd", MFD_ALLOW_SEALING)); - SurfaceControlStats controlStats(surface, mFdp.ConsumeIntegral<int64_t>(), - mFdp.ConsumeIntegral<int64_t>(), presentFence, previousFence, - mFdp.ConsumeIntegral<uint32_t>(), frameStats, - mFdp.ConsumeIntegral<uint32_t>()); - stats.push_back(controlStats); -} - -void BufferQueueFuzzer::invokeQuery(sp<BufferQueueProducer> producer) { - int32_t value; - producer->query(mFdp.ConsumeIntegral<int32_t>(), &value); -} - -void BufferQueueFuzzer::invokeQuery(sp<V1_0::utils::H2BGraphicBufferProducer> producer) { - int32_t value; - producer->query(mFdp.ConsumeIntegral<int32_t>(), &value); -} - -void BufferQueueFuzzer::invokeQuery(sp<V2_0::utils::H2BGraphicBufferProducer> producer) { - int32_t value; - producer->query(mFdp.ConsumeIntegral<int32_t>(), &value); -} - -void BufferQueueFuzzer::invokeBufferQueueProducer() { - sp<BufferQueueCore> core(new BufferQueueCore()); - sp<BufferQueueProducer> producer(new BufferQueueProducer(core)); - const sp<android::IProducerListener> listener; - android::IGraphicBufferProducer::QueueBufferOutput output; - uint32_t api = mFdp.ConsumeIntegral<uint32_t>(); - producer->connect(listener, api, mFdp.ConsumeBool() /*producerControlledByApp*/, &output); - - sp<GraphicBuffer> buffer; - int32_t slot = mFdp.ConsumeIntegral<int32_t>(); - uint32_t maxBuffers = mFdp.ConsumeIntegral<uint32_t>(); - producer->requestBuffer(slot, &buffer); - producer->setMaxDequeuedBufferCount(maxBuffers); - producer->setAsyncMode(mFdp.ConsumeBool() /*async*/); - - android::IGraphicBufferProducer::QueueBufferInput input; - producer->attachBuffer(&slot, buffer); - producer->queueBuffer(slot, input, &output); - - int32_t format = mFdp.ConsumeIntegral<int32_t>(); - uint32_t width = mFdp.ConsumeIntegral<uint32_t>(); - uint32_t height = mFdp.ConsumeIntegral<uint32_t>(); - uint64_t usage = mFdp.ConsumeIntegral<uint64_t>(); - uint64_t outBufferAge; - FrameEventHistoryDelta outTimestamps; - sp<android::Fence> fence; - producer->dequeueBuffer(&slot, &fence, width, height, format, usage, &outBufferAge, - &outTimestamps); - producer->detachBuffer(slot); - producer->detachNextBuffer(&buffer, &fence); - producer->cancelBuffer(slot, fence); - - invokeQuery(producer); - - ManageResourceHandle handle(&mFdp); - producer->setSidebandStream(handle.getStream()); - - producer->allocateBuffers(width, height, format, usage); - producer->allowAllocation(mFdp.ConsumeBool() /*allow*/); - producer->setSharedBufferMode(mFdp.ConsumeBool() /*sharedBufferMode*/); - producer->setAutoRefresh(mFdp.ConsumeBool() /*autoRefresh*/); - producer->setLegacyBufferDrop(mFdp.ConsumeBool() /*drop*/); - producer->setAutoPrerotation(mFdp.ConsumeBool() /*autoPrerotation*/); - - producer->setGenerationNumber(mFdp.ConsumeIntegral<uint32_t>()); - producer->setDequeueTimeout(mFdp.ConsumeIntegral<uint32_t>()); - producer->disconnect(api); -} - -void BufferQueueFuzzer::invokeAcquireBuffer(sp<BufferQueueConsumer> consumer) { - BufferItem item; - consumer->acquireBuffer(&item, mFdp.ConsumeIntegral<uint32_t>(), - mFdp.ConsumeIntegral<uint64_t>()); -} - -void BufferQueueFuzzer::invokeOccupancyTracker(sp<BufferQueueConsumer> consumer) { - String8 outResult; - String8 prefix((mFdp.ConsumeRandomLengthString(kMaxBytes)).c_str()); - consumer->dumpState(prefix, &outResult); - - std::vector<OccupancyTracker::Segment> outHistory; - consumer->getOccupancyHistory(mFdp.ConsumeBool() /*forceFlush*/, &outHistory); -} - -void BufferQueueFuzzer::invokeBufferQueueConsumer() { - sp<BufferQueueCore> core(new BufferQueueCore()); - sp<BufferQueueConsumer> consumer(new BufferQueueConsumer(core)); - sp<android::IConsumerListener> listener; - consumer->consumerConnect(listener, mFdp.ConsumeBool() /*controlledByApp*/); - invokeAcquireBuffer(consumer); - - int32_t slot = mFdp.ConsumeIntegral<int32_t>(); - sp<GraphicBuffer> buffer = - new GraphicBuffer(mFdp.ConsumeIntegral<uint32_t>(), mFdp.ConsumeIntegral<uint32_t>(), - mFdp.ConsumeIntegral<int32_t>(), mFdp.ConsumeIntegral<uint32_t>(), - mFdp.ConsumeIntegral<uint64_t>()); - consumer->attachBuffer(&slot, buffer); - consumer->detachBuffer(slot); - - consumer->setDefaultBufferSize(mFdp.ConsumeIntegral<uint32_t>(), - mFdp.ConsumeIntegral<uint32_t>()); - consumer->setMaxBufferCount(mFdp.ConsumeIntegral<int32_t>()); - consumer->setMaxAcquiredBufferCount(mFdp.ConsumeIntegral<int32_t>()); - - String8 name((mFdp.ConsumeRandomLengthString(kMaxBytes)).c_str()); - consumer->setConsumerName(name); - consumer->setDefaultBufferFormat(mFdp.ConsumeIntegral<int32_t>()); - android_dataspace dataspace = - static_cast<android_dataspace>(mFdp.PickValueInArray(kDataspaces)); - consumer->setDefaultBufferDataSpace(dataspace); - - consumer->setTransformHint(mFdp.ConsumeIntegral<uint32_t>()); - consumer->setConsumerUsageBits(mFdp.ConsumeIntegral<uint64_t>()); - consumer->setConsumerIsProtected(mFdp.ConsumeBool() /*isProtected*/); - invokeOccupancyTracker(consumer); - - sp<Fence> releaseFence = new Fence(memfd_create("fd", MFD_ALLOW_SEALING)); - consumer->releaseBuffer(mFdp.ConsumeIntegral<int32_t>(), mFdp.ConsumeIntegral<uint64_t>(), - EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, releaseFence); - consumer->consumerDisconnect(); -} - -void BufferQueueFuzzer::invokeTypes() { - HStatus hStatus; - int32_t status = mFdp.PickValueInArray(kError); - bool bufferNeedsReallocation = mFdp.ConsumeBool(); - bool releaseAllBuffers = mFdp.ConsumeBool(); - b2h(status, &hStatus, &bufferNeedsReallocation, &releaseAllBuffers); - h2b(hStatus, &status); - - HConnectionType type; - int32_t apiConnection = mFdp.PickValueInArray(kAPIConnection); - b2h(apiConnection, &type); - h2b(type, &apiConnection); -} - -void BufferQueueFuzzer::invokeH2BGraphicBufferV1() { - sp<V1_0::utils::H2BGraphicBufferProducer> producer( - new V1_0::utils::H2BGraphicBufferProducer(new FakeGraphicBufferProducerV1())); - const sp<android::IProducerListener> listener; - android::IGraphicBufferProducer::QueueBufferOutput output; - uint32_t api = mFdp.ConsumeIntegral<uint32_t>(); - producer->connect(listener, api, mFdp.ConsumeBool() /*producerControlledByApp*/, &output); - - sp<GraphicBuffer> buffer; - int32_t slot = mFdp.ConsumeIntegral<int32_t>(); - producer->requestBuffer(slot, &buffer); - producer->setMaxDequeuedBufferCount(mFdp.ConsumeIntegral<int32_t>()); - producer->setAsyncMode(mFdp.ConsumeBool()); - - android::IGraphicBufferProducer::QueueBufferInput input; - input.fence = new Fence(memfd_create("ffd", MFD_ALLOW_SEALING)); - producer->attachBuffer(&slot, buffer); - producer->queueBuffer(slot, input, &output); - - int32_t format = mFdp.ConsumeIntegral<int32_t>(); - uint32_t width = mFdp.ConsumeIntegral<uint32_t>(); - uint32_t height = mFdp.ConsumeIntegral<uint32_t>(); - uint64_t usage = mFdp.ConsumeIntegral<uint64_t>(); - uint64_t outBufferAge; - FrameEventHistoryDelta outTimestamps; - sp<android::Fence> fence; - producer->dequeueBuffer(&slot, &fence, width, height, format, usage, &outBufferAge, - &outTimestamps); - producer->detachBuffer(slot); - producer->cancelBuffer(slot, fence); - - invokeQuery(producer); - - ManageResourceHandle handle(&mFdp); - producer->setSidebandStream(handle.getStream()); - - producer->allocateBuffers(width, height, format, usage); - producer->allowAllocation(mFdp.ConsumeBool() /*allow*/); - producer->setSharedBufferMode(mFdp.ConsumeBool() /*sharedBufferMode*/); - producer->setAutoRefresh(mFdp.ConsumeBool() /*autoRefresh*/); - - producer->setGenerationNumber(mFdp.ConsumeIntegral<uint32_t>()); - producer->setDequeueTimeout(mFdp.ConsumeIntegral<uint32_t>()); - producer->disconnect(api); -} - -void BufferQueueFuzzer::invokeH2BGraphicBufferV2() { - sp<V2_0::utils::H2BGraphicBufferProducer> producer( - new V2_0::utils::H2BGraphicBufferProducer(new FakeGraphicBufferProducerV2())); - const sp<android::IProducerListener> listener; - android::IGraphicBufferProducer::QueueBufferOutput output; - uint32_t api = mFdp.ConsumeIntegral<uint32_t>(); - producer->connect(listener, api, mFdp.ConsumeBool() /*producerControlledByApp*/, &output); - - sp<GraphicBuffer> buffer; - int32_t slot = mFdp.ConsumeIntegral<int32_t>(); - producer->requestBuffer(slot, &buffer); - producer->setMaxDequeuedBufferCount(mFdp.ConsumeIntegral<uint32_t>()); - producer->setAsyncMode(mFdp.ConsumeBool()); - - android::IGraphicBufferProducer::QueueBufferInput input; - input.fence = new Fence(memfd_create("ffd", MFD_ALLOW_SEALING)); - producer->attachBuffer(&slot, buffer); - producer->queueBuffer(slot, input, &output); - - int32_t format = mFdp.ConsumeIntegral<int32_t>(); - uint32_t width = mFdp.ConsumeIntegral<uint32_t>(); - uint32_t height = mFdp.ConsumeIntegral<uint32_t>(); - uint64_t usage = mFdp.ConsumeIntegral<uint64_t>(); - uint64_t outBufferAge; - FrameEventHistoryDelta outTimestamps; - sp<android::Fence> fence; - producer->dequeueBuffer(&slot, &fence, width, height, format, usage, &outBufferAge, - &outTimestamps); - producer->detachBuffer(slot); - producer->cancelBuffer(slot, fence); - - invokeQuery(producer); - - ManageResourceHandle handle(&mFdp); - producer->setSidebandStream(handle.getStream()); - - producer->allocateBuffers(width, height, format, usage); - producer->allowAllocation(mFdp.ConsumeBool() /*allow*/); - producer->setSharedBufferMode(mFdp.ConsumeBool() /*sharedBufferMode*/); - producer->setAutoRefresh(mFdp.ConsumeBool() /*autoRefresh*/); - - producer->setGenerationNumber(mFdp.ConsumeIntegral<uint32_t>()); - producer->setDequeueTimeout(mFdp.ConsumeIntegral<uint32_t>()); - producer->disconnect(api); -} - -void BufferQueueFuzzer::process() { - invokeBlastBufferQueue(); - invokeH2BGraphicBufferV1(); - invokeH2BGraphicBufferV2(); - invokeTypes(); - invokeBufferQueueConsumer(); - invokeBufferQueueProducer(); -} - -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - BufferQueueFuzzer bufferQueueFuzzer(data, size); - bufferQueueFuzzer.process(); - return 0; -} diff --git a/libs/gui/fuzzer/libgui_consumer_fuzzer.cpp b/libs/gui/fuzzer/libgui_consumer_fuzzer.cpp deleted file mode 100644 index 24a046d3a9..0000000000 --- a/libs/gui/fuzzer/libgui_consumer_fuzzer.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2022 The Android Open Source 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 <gui/BufferQueueConsumer.h> -#include <gui/BufferQueueCore.h> -#include <gui/BufferQueueProducer.h> -#include <gui/GLConsumer.h> -#include <libgui_fuzzer_utils.h> - -using namespace android; - -constexpr int32_t kMinBuffer = 0; -constexpr int32_t kMaxBuffer = 100000; - -class ConsumerFuzzer { -public: - ConsumerFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){}; - void process(); - -private: - FuzzedDataProvider mFdp; -}; - -void ConsumerFuzzer::process() { - sp<BufferQueueCore> core(new BufferQueueCore()); - sp<IGraphicBufferConsumer> consumer(new BufferQueueConsumer(core)); - - uint64_t maxBuffers = mFdp.ConsumeIntegralInRange<uint64_t>(kMinBuffer, kMaxBuffer); - sp<CpuConsumer> cpu( - new CpuConsumer(consumer, maxBuffers, mFdp.ConsumeBool() /*controlledByApp*/)); - CpuConsumer::LockedBuffer lockBuffer; - cpu->lockNextBuffer(&lockBuffer); - cpu->unlockBuffer(lockBuffer); - cpu->abandon(); - - uint32_t tex = mFdp.ConsumeIntegral<uint32_t>(); - sp<GLConsumer> glComsumer(new GLConsumer(consumer, tex, GLConsumer::TEXTURE_EXTERNAL, - mFdp.ConsumeBool() /*useFenceSync*/, - mFdp.ConsumeBool() /*isControlledByApp*/)); - sp<Fence> releaseFence = new Fence(memfd_create("rfd", MFD_ALLOW_SEALING)); - glComsumer->setReleaseFence(releaseFence); - glComsumer->updateTexImage(); - glComsumer->releaseTexImage(); - - sp<GraphicBuffer> buffer = - new GraphicBuffer(mFdp.ConsumeIntegral<uint32_t>(), mFdp.ConsumeIntegral<uint32_t>(), - mFdp.ConsumeIntegral<int32_t>(), mFdp.ConsumeIntegral<uint32_t>(), - mFdp.ConsumeIntegral<uint64_t>()); - float mtx[16]; - glComsumer->getTransformMatrix(mtx); - glComsumer->computeTransformMatrix(mtx, buffer, getRect(&mFdp), - mFdp.ConsumeIntegral<uint32_t>(), - mFdp.ConsumeBool() /*filtering*/); - glComsumer->scaleDownCrop(getRect(&mFdp), mFdp.ConsumeIntegral<uint32_t>(), - mFdp.ConsumeIntegral<uint32_t>()); - - glComsumer->setDefaultBufferSize(mFdp.ConsumeIntegral<uint32_t>(), - mFdp.ConsumeIntegral<uint32_t>()); - glComsumer->setFilteringEnabled(mFdp.ConsumeBool() /*enabled*/); - - glComsumer->setConsumerUsageBits(mFdp.ConsumeIntegral<uint64_t>()); - glComsumer->attachToContext(tex); - glComsumer->abandon(); -} - -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - ConsumerFuzzer consumerFuzzer(data, size); - consumerFuzzer.process(); - return 0; -} diff --git a/libs/gui/fuzzer/libgui_displayEvent_fuzzer.cpp b/libs/gui/fuzzer/libgui_displayEvent_fuzzer.cpp deleted file mode 100644 index 0d2a52b576..0000000000 --- a/libs/gui/fuzzer/libgui_displayEvent_fuzzer.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2022 The Android Open Source 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 <android/gui/ISurfaceComposer.h> - -#include <libgui_fuzzer_utils.h> - -using namespace android; - -constexpr gui::ISurfaceComposer::VsyncSource kVsyncSource[] = { - gui::ISurfaceComposer::VsyncSource::eVsyncSourceApp, - gui::ISurfaceComposer::VsyncSource::eVsyncSourceSurfaceFlinger, -}; - -constexpr gui::ISurfaceComposer::EventRegistration kEventRegistration[] = { - gui::ISurfaceComposer::EventRegistration::modeChanged, - gui::ISurfaceComposer::EventRegistration::frameRateOverride, -}; - -constexpr uint32_t kDisplayEvent[] = { - DisplayEventReceiver::DISPLAY_EVENT_NULL, - DisplayEventReceiver::DISPLAY_EVENT_VSYNC, - DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG, - DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE, - DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE, - DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH, -}; - -constexpr int32_t kEvents[] = { - Looper::EVENT_INPUT, Looper::EVENT_OUTPUT, Looper::EVENT_ERROR, - Looper::EVENT_HANGUP, Looper::EVENT_INVALID, -}; - -DisplayEventReceiver::Event buildDisplayEvent(FuzzedDataProvider* fdp, uint32_t type, - DisplayEventReceiver::Event event) { - switch (type) { - case DisplayEventReceiver::DISPLAY_EVENT_VSYNC: { - event.vsync.count = fdp->ConsumeIntegral<uint32_t>(); - event.vsync.vsyncData.frameInterval = fdp->ConsumeIntegral<uint64_t>(); - event.vsync.vsyncData.preferredFrameTimelineIndex = fdp->ConsumeIntegral<uint32_t>(); - for (size_t idx = 0; idx < gui::VsyncEventData::kFrameTimelinesCapacity; ++idx) { - event.vsync.vsyncData.frameTimelines[idx].vsyncId = fdp->ConsumeIntegral<int64_t>(); - event.vsync.vsyncData.frameTimelines[idx].deadlineTimestamp = - fdp->ConsumeIntegral<uint64_t>(); - event.vsync.vsyncData.frameTimelines[idx].expectedPresentationTime = - fdp->ConsumeIntegral<uint64_t>(); - } - break; - - } - case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG: { - event.hotplug = - DisplayEventReceiver::Event::Hotplug{fdp->ConsumeBool() /*connected*/, - fdp->ConsumeIntegral< - int32_t>() /*connectionError*/}; - break; - } - case DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE: { - event.modeChange = - DisplayEventReceiver::Event::ModeChange{fdp->ConsumeIntegral<int32_t>(), - fdp->ConsumeIntegral<int64_t>()}; - break; - } - case DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE: - case DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH: { - event.frameRateOverride = - DisplayEventReceiver::Event::FrameRateOverride{fdp->ConsumeIntegral<uint32_t>(), - fdp->ConsumeFloatingPoint< - float>()}; - break; - } - } - return event; -} - -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - FuzzedDataProvider fdp(data, size); - sp<Looper> looper; - sp<FakeDisplayEventDispatcher> dispatcher( - new FakeDisplayEventDispatcher(looper, fdp.PickValueInArray(kVsyncSource), - fdp.PickValueInArray(kEventRegistration))); - - dispatcher->initialize(); - DisplayEventReceiver::Event event; - uint32_t type = fdp.PickValueInArray(kDisplayEvent); - PhysicalDisplayId displayId; - event.header = - DisplayEventReceiver::Event::Header{type, displayId, fdp.ConsumeIntegral<int64_t>()}; - event = buildDisplayEvent(&fdp, type, event); - - dispatcher->injectEvent(event); - dispatcher->handleEvent(0, fdp.PickValueInArray(kEvents), nullptr); - return 0; -} diff --git a/libs/gui/fuzzer/libgui_fuzzer_utils.h b/libs/gui/fuzzer/libgui_fuzzer_utils.h deleted file mode 100644 index 2bdbd43233..0000000000 --- a/libs/gui/fuzzer/libgui_fuzzer_utils.h +++ /dev/null @@ -1,332 +0,0 @@ -/* - * Copyright 2021 The Android Open Source 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 <android/gui/BnRegionSamplingListener.h> -#include <android/gui/BnSurfaceComposer.h> -#include <android/gui/BnSurfaceComposerClient.h> -#include <android/gui/IDisplayEventConnection.h> -#include <android/gui/ISurfaceComposerClient.h> -#include <fuzzer/FuzzedDataProvider.h> -#include <gmock/gmock.h> -#include <gui/BLASTBufferQueue.h> -#include <gui/DisplayEventDispatcher.h> -#include <gui/IGraphicBufferProducer.h> -#include <gui/LayerDebugInfo.h> -#include <gui/LayerState.h> -#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h> -#include <gui/bufferqueue/2.0/H2BGraphicBufferProducer.h> -#include <ui/fuzzer/FuzzableDataspaces.h> - -namespace android { - -constexpr uint32_t kOrientation[] = { - ui::Transform::ROT_0, ui::Transform::FLIP_H, ui::Transform::FLIP_V, - ui::Transform::ROT_90, ui::Transform::ROT_180, ui::Transform::ROT_270, -}; - -Rect getRect(FuzzedDataProvider* fdp) { - const int32_t left = fdp->ConsumeIntegral<int32_t>(); - const int32_t top = fdp->ConsumeIntegral<int32_t>(); - const int32_t right = fdp->ConsumeIntegral<int32_t>(); - const int32_t bottom = fdp->ConsumeIntegral<int32_t>(); - return Rect(left, top, right, bottom); -} - -gui::DisplayBrightness getBrightness(FuzzedDataProvider* fdp) { - static constexpr float kMinBrightness = 0; - static constexpr float kMaxBrightness = 1; - gui::DisplayBrightness brightness; - brightness.sdrWhitePoint = - fdp->ConsumeFloatingPointInRange<float>(kMinBrightness, kMaxBrightness); - brightness.sdrWhitePointNits = - fdp->ConsumeFloatingPointInRange<float>(kMinBrightness, kMaxBrightness); - brightness.displayBrightness = - fdp->ConsumeFloatingPointInRange<float>(kMinBrightness, kMaxBrightness); - brightness.displayBrightnessNits = - fdp->ConsumeFloatingPointInRange<float>(kMinBrightness, kMaxBrightness); - return brightness; -} - -class FakeBnSurfaceComposer : public gui::BnSurfaceComposer { -public: - MOCK_METHOD(binder::Status, bootFinished, (), (override)); - MOCK_METHOD(binder::Status, createDisplayEventConnection, - (gui::ISurfaceComposer::VsyncSource, gui::ISurfaceComposer::EventRegistration, - const sp<IBinder>& /*layerHandle*/, sp<gui::IDisplayEventConnection>*), - (override)); - MOCK_METHOD(binder::Status, createConnection, (sp<gui::ISurfaceComposerClient>*), (override)); - MOCK_METHOD(binder::Status, createDisplay, (const std::string&, bool, float, sp<IBinder>*), - (override)); - MOCK_METHOD(binder::Status, destroyDisplay, (const sp<IBinder>&), (override)); - MOCK_METHOD(binder::Status, getPhysicalDisplayIds, (std::vector<int64_t>*), (override)); - MOCK_METHOD(binder::Status, getPhysicalDisplayToken, (int64_t, sp<IBinder>*), (override)); - MOCK_METHOD(binder::Status, setPowerMode, (const sp<IBinder>&, int), (override)); - MOCK_METHOD(binder::Status, getSupportedFrameTimestamps, (std::vector<FrameEvent>*), - (override)); - MOCK_METHOD(binder::Status, getDisplayStats, (const sp<IBinder>&, gui::DisplayStatInfo*), - (override)); - MOCK_METHOD(binder::Status, getDisplayState, (const sp<IBinder>&, gui::DisplayState*), - (override)); - MOCK_METHOD(binder::Status, getStaticDisplayInfo, (int64_t, gui::StaticDisplayInfo*), - (override)); - MOCK_METHOD(binder::Status, getDynamicDisplayInfoFromId, (int64_t, gui::DynamicDisplayInfo*), - (override)); - MOCK_METHOD(binder::Status, getDynamicDisplayInfoFromToken, - (const sp<IBinder>&, gui::DynamicDisplayInfo*), (override)); - MOCK_METHOD(binder::Status, getDisplayNativePrimaries, - (const sp<IBinder>&, gui::DisplayPrimaries*), (override)); - MOCK_METHOD(binder::Status, setActiveColorMode, (const sp<IBinder>&, int), (override)); - MOCK_METHOD(binder::Status, setBootDisplayMode, (const sp<IBinder>&, int), (override)); - MOCK_METHOD(binder::Status, clearBootDisplayMode, (const sp<IBinder>&), (override)); - MOCK_METHOD(binder::Status, getBootDisplayModeSupport, (bool*), (override)); - MOCK_METHOD(binder::Status, getHdrConversionCapabilities, - (std::vector<gui::HdrConversionCapability>*), (override)); - MOCK_METHOD(binder::Status, setHdrConversionStrategy, - (const gui::HdrConversionStrategy&, int32_t*), (override)); - MOCK_METHOD(binder::Status, getHdrOutputConversionSupport, (bool*), (override)); - MOCK_METHOD(binder::Status, setAutoLowLatencyMode, (const sp<IBinder>&, bool), (override)); - MOCK_METHOD(binder::Status, setGameContentType, (const sp<IBinder>&, bool), (override)); - MOCK_METHOD(binder::Status, captureDisplay, - (const DisplayCaptureArgs&, const sp<IScreenCaptureListener>&), (override)); - MOCK_METHOD(binder::Status, captureDisplayById, - (int64_t, const gui::CaptureArgs&, const sp<IScreenCaptureListener>&), (override)); - MOCK_METHOD(binder::Status, captureLayers, - (const LayerCaptureArgs&, const sp<IScreenCaptureListener>&), (override)); - MOCK_METHOD(binder::Status, captureLayersSync, - (const LayerCaptureArgs&, gui::ScreenCaptureResults*), (override)); - MOCK_METHOD(binder::Status, clearAnimationFrameStats, (), (override)); - MOCK_METHOD(binder::Status, getAnimationFrameStats, (gui::FrameStats*), (override)); - MOCK_METHOD(binder::Status, overrideHdrTypes, (const sp<IBinder>&, const std::vector<int32_t>&), - (override)); - MOCK_METHOD(binder::Status, onPullAtom, (int32_t, gui::PullAtomData*), (override)); - MOCK_METHOD(binder::Status, getLayerDebugInfo, (std::vector<gui::LayerDebugInfo>*), (override)); - MOCK_METHOD(binder::Status, getCompositionPreference, (gui::CompositionPreference*), - (override)); - MOCK_METHOD(binder::Status, getDisplayedContentSamplingAttributes, - (const sp<IBinder>&, gui::ContentSamplingAttributes*), (override)); - MOCK_METHOD(binder::Status, setDisplayContentSamplingEnabled, - (const sp<IBinder>&, bool, int8_t, int64_t), (override)); - MOCK_METHOD(binder::Status, getDisplayedContentSample, - (const sp<IBinder>&, int64_t, int64_t, gui::DisplayedFrameStats*), (override)); - MOCK_METHOD(binder::Status, getProtectedContentSupport, (bool*), (override)); - MOCK_METHOD(binder::Status, isWideColorDisplay, (const sp<IBinder>&, bool*), (override)); - MOCK_METHOD(binder::Status, addRegionSamplingListener, - (const gui::ARect&, const sp<IBinder>&, const sp<gui::IRegionSamplingListener>&), - (override)); - MOCK_METHOD(binder::Status, removeRegionSamplingListener, - (const sp<gui::IRegionSamplingListener>&), (override)); - MOCK_METHOD(binder::Status, addFpsListener, (int32_t, const sp<gui::IFpsListener>&), - (override)); - MOCK_METHOD(binder::Status, removeFpsListener, (const sp<gui::IFpsListener>&), (override)); - MOCK_METHOD(binder::Status, addTunnelModeEnabledListener, - (const sp<gui::ITunnelModeEnabledListener>&), (override)); - MOCK_METHOD(binder::Status, removeTunnelModeEnabledListener, - (const sp<gui::ITunnelModeEnabledListener>&), (override)); - MOCK_METHOD(binder::Status, setDesiredDisplayModeSpecs, - (const sp<IBinder>&, const gui::DisplayModeSpecs&), (override)); - MOCK_METHOD(binder::Status, getDesiredDisplayModeSpecs, - (const sp<IBinder>&, gui::DisplayModeSpecs*), (override)); - MOCK_METHOD(binder::Status, getDisplayBrightnessSupport, (const sp<IBinder>&, bool*), - (override)); - MOCK_METHOD(binder::Status, setDisplayBrightness, - (const sp<IBinder>&, const gui::DisplayBrightness&), (override)); - MOCK_METHOD(binder::Status, addHdrLayerInfoListener, - (const sp<IBinder>&, const sp<gui::IHdrLayerInfoListener>&), (override)); - MOCK_METHOD(binder::Status, removeHdrLayerInfoListener, - (const sp<IBinder>&, const sp<gui::IHdrLayerInfoListener>&), (override)); - MOCK_METHOD(binder::Status, notifyPowerBoost, (int), (override)); - MOCK_METHOD(binder::Status, setGlobalShadowSettings, - (const gui::Color&, const gui::Color&, float, float, float), (override)); - MOCK_METHOD(binder::Status, getDisplayDecorationSupport, - (const sp<IBinder>&, std::optional<gui::DisplayDecorationSupport>*), (override)); - MOCK_METHOD(binder::Status, setGameModeFrameRateOverride, (int32_t, float), (override)); - MOCK_METHOD(binder::Status, setGameDefaultFrameRateOverride, (int32_t, float), (override)); - MOCK_METHOD(binder::Status, enableRefreshRateOverlay, (bool), (override)); - MOCK_METHOD(binder::Status, setDebugFlash, (int), (override)); - MOCK_METHOD(binder::Status, scheduleComposite, (), (override)); - MOCK_METHOD(binder::Status, scheduleCommit, (), (override)); - MOCK_METHOD(binder::Status, forceClientComposition, (bool), (override)); - MOCK_METHOD(binder::Status, updateSmallAreaDetection, - (const std::vector<int32_t>&, const std::vector<float>&), (override)); - MOCK_METHOD(binder::Status, setSmallAreaDetectionThreshold, (int32_t, float), (override)); - MOCK_METHOD(binder::Status, getGpuContextPriority, (int32_t*), (override)); - MOCK_METHOD(binder::Status, getMaxAcquiredBufferCount, (int32_t*), (override)); - MOCK_METHOD(binder::Status, addWindowInfosListener, - (const sp<gui::IWindowInfosListener>&, gui::WindowInfosListenerInfo*), (override)); - MOCK_METHOD(binder::Status, removeWindowInfosListener, (const sp<gui::IWindowInfosListener>&), - (override)); - MOCK_METHOD(binder::Status, getOverlaySupport, (gui::OverlayProperties*), (override)); - MOCK_METHOD(binder::Status, getStalledTransactionInfo, - (int32_t, std::optional<gui::StalledTransactionInfo>*), (override)); - MOCK_METHOD(binder::Status, getSchedulingPolicy, (gui::SchedulingPolicy*), (override)); -}; - -class FakeBnSurfaceComposerClient : public gui::BnSurfaceComposerClient { -public: - MOCK_METHOD(binder::Status, createSurface, - (const std::string& name, int32_t flags, const sp<IBinder>& parent, - const gui::LayerMetadata& metadata, gui::CreateSurfaceResult* outResult), - (override)); - - MOCK_METHOD(binder::Status, clearLayerFrameStats, (const sp<IBinder>& handle), (override)); - - MOCK_METHOD(binder::Status, getLayerFrameStats, - (const sp<IBinder>& handle, gui::FrameStats* outStats), (override)); - - MOCK_METHOD(binder::Status, mirrorSurface, - (const sp<IBinder>& mirrorFromHandle, gui::CreateSurfaceResult* outResult), - (override)); - - MOCK_METHOD(binder::Status, mirrorDisplay, - (int64_t displayId, gui::CreateSurfaceResult* outResult), (override)); - - MOCK_METHOD(binder::Status, getSchedulingPolicy, (gui::SchedulingPolicy*), (override)); -}; - -class FakeDisplayEventDispatcher : public DisplayEventDispatcher { -public: - FakeDisplayEventDispatcher(const sp<Looper>& looper, - gui::ISurfaceComposer::VsyncSource vsyncSource, - gui::ISurfaceComposer::EventRegistration eventRegistration) - : DisplayEventDispatcher(looper, vsyncSource, eventRegistration){}; - - MOCK_METHOD4(dispatchVsync, void(nsecs_t, PhysicalDisplayId, uint32_t, VsyncEventData)); - MOCK_METHOD3(dispatchHotplug, void(nsecs_t, PhysicalDisplayId, bool)); - MOCK_METHOD2(dispatchHotplugConnectionError, void(nsecs_t, int32_t)); - MOCK_METHOD4(dispatchModeChanged, void(nsecs_t, PhysicalDisplayId, int32_t, nsecs_t)); - MOCK_METHOD2(dispatchNullEvent, void(nsecs_t, PhysicalDisplayId)); - MOCK_METHOD3(dispatchFrameRateOverrides, - void(nsecs_t, PhysicalDisplayId, std::vector<FrameRateOverride>)); - MOCK_METHOD3(dispatchHdcpLevelsChanged, void(PhysicalDisplayId, int32_t, int32_t)); -}; - -} // namespace android - -namespace android::hardware { - -namespace graphics::bufferqueue::V1_0::utils { - -class FakeGraphicBufferProducerV1 : public HGraphicBufferProducer { -public: - FakeGraphicBufferProducerV1() { - ON_CALL(*this, setMaxDequeuedBufferCount).WillByDefault([]() { return 0; }); - ON_CALL(*this, setAsyncMode).WillByDefault([]() { return 0; }); - ON_CALL(*this, detachBuffer).WillByDefault([]() { return 0; }); - ON_CALL(*this, cancelBuffer).WillByDefault([]() { return 0; }); - ON_CALL(*this, disconnect).WillByDefault([]() { return 0; }); - ON_CALL(*this, setSidebandStream).WillByDefault([]() { return 0; }); - ON_CALL(*this, allowAllocation).WillByDefault([]() { return 0; }); - ON_CALL(*this, setGenerationNumber).WillByDefault([]() { return 0; }); - ON_CALL(*this, setSharedBufferMode).WillByDefault([]() { return 0; }); - ON_CALL(*this, setAutoRefresh).WillByDefault([]() { return 0; }); - ON_CALL(*this, setDequeueTimeout).WillByDefault([]() { return 0; }); - ON_CALL(*this, setLegacyBufferDrop).WillByDefault([]() { return 0; }); - }; - MOCK_METHOD2(requestBuffer, Return<void>(int, requestBuffer_cb)); - MOCK_METHOD1(setMaxDequeuedBufferCount, Return<int32_t>(int32_t)); - MOCK_METHOD1(setAsyncMode, Return<int32_t>(bool)); - MOCK_METHOD6(dequeueBuffer, - Return<void>(uint32_t, uint32_t, graphics::common::V1_0::PixelFormat, uint32_t, - bool, dequeueBuffer_cb)); - MOCK_METHOD1(detachBuffer, Return<int32_t>(int)); - MOCK_METHOD1(detachNextBuffer, Return<void>(detachNextBuffer_cb)); - MOCK_METHOD2(attachBuffer, Return<void>(const media::V1_0::AnwBuffer&, attachBuffer_cb)); - MOCK_METHOD3( - queueBuffer, - Return<void>( - int, - const graphics::bufferqueue::V1_0::IGraphicBufferProducer::QueueBufferInput&, - queueBuffer_cb)); - MOCK_METHOD2(cancelBuffer, Return<int32_t>(int, const hidl_handle&)); - MOCK_METHOD2(query, Return<void>(int32_t, query_cb)); - MOCK_METHOD4(connect, - Return<void>(const sp<graphics::bufferqueue::V1_0::IProducerListener>&, int32_t, - bool, connect_cb)); - MOCK_METHOD2(disconnect, - Return<int32_t>( - int, graphics::bufferqueue::V1_0::IGraphicBufferProducer::DisconnectMode)); - MOCK_METHOD1(setSidebandStream, Return<int32_t>(const hidl_handle&)); - MOCK_METHOD4(allocateBuffers, - Return<void>(uint32_t, uint32_t, graphics::common::V1_0::PixelFormat, uint32_t)); - MOCK_METHOD1(allowAllocation, Return<int32_t>(bool)); - MOCK_METHOD1(setGenerationNumber, Return<int32_t>(uint32_t)); - MOCK_METHOD1(getConsumerName, Return<void>(getConsumerName_cb)); - MOCK_METHOD1(setSharedBufferMode, Return<int32_t>(bool)); - MOCK_METHOD1(setAutoRefresh, Return<int32_t>(bool)); - MOCK_METHOD1(setDequeueTimeout, Return<int32_t>(nsecs_t)); - MOCK_METHOD1(setLegacyBufferDrop, Return<int32_t>(bool)); - MOCK_METHOD1(getLastQueuedBuffer, Return<void>(getLastQueuedBuffer_cb)); - MOCK_METHOD1(getFrameTimestamps, Return<void>(getFrameTimestamps_cb)); - MOCK_METHOD1(getUniqueId, Return<void>(getUniqueId_cb)); -}; - -}; // namespace graphics::bufferqueue::V1_0::utils - -namespace graphics::bufferqueue::V2_0::utils { - -class FakeGraphicBufferProducerV2 : public HGraphicBufferProducer { -public: - FakeGraphicBufferProducerV2() { - ON_CALL(*this, setMaxDequeuedBufferCount).WillByDefault([]() { return Status::OK; }); - ON_CALL(*this, setAsyncMode).WillByDefault([]() { return Status::OK; }); - ON_CALL(*this, detachBuffer).WillByDefault([]() { return Status::OK; }); - ON_CALL(*this, cancelBuffer).WillByDefault([]() { return Status::OK; }); - ON_CALL(*this, disconnect).WillByDefault([]() { return Status::OK; }); - ON_CALL(*this, allocateBuffers).WillByDefault([]() { return Status::OK; }); - ON_CALL(*this, allowAllocation).WillByDefault([]() { return Status::OK; }); - ON_CALL(*this, setGenerationNumber).WillByDefault([]() { return Status::OK; }); - ON_CALL(*this, setDequeueTimeout).WillByDefault([]() { return Status::OK; }); - ON_CALL(*this, getUniqueId).WillByDefault([]() { return 0; }); - }; - MOCK_METHOD2(requestBuffer, Return<void>(int, requestBuffer_cb)); - MOCK_METHOD1(setMaxDequeuedBufferCount, Return<graphics::bufferqueue::V2_0::Status>(int)); - MOCK_METHOD1(setAsyncMode, Return<graphics::bufferqueue::V2_0::Status>(bool)); - MOCK_METHOD2( - dequeueBuffer, - Return<void>( - const graphics::bufferqueue::V2_0::IGraphicBufferProducer::DequeueBufferInput&, - dequeueBuffer_cb)); - MOCK_METHOD1(detachBuffer, Return<graphics::bufferqueue::V2_0::Status>(int)); - MOCK_METHOD1(detachNextBuffer, Return<void>(detachNextBuffer_cb)); - MOCK_METHOD3(attachBuffer, - Return<void>(const graphics::common::V1_2::HardwareBuffer&, uint32_t, - attachBuffer_cb)); - MOCK_METHOD3( - queueBuffer, - Return<void>( - int, - const graphics::bufferqueue::V2_0::IGraphicBufferProducer::QueueBufferInput&, - queueBuffer_cb)); - MOCK_METHOD2(cancelBuffer, - Return<graphics::bufferqueue::V2_0::Status>(int, const hidl_handle&)); - MOCK_METHOD2(query, Return<void>(int32_t, query_cb)); - MOCK_METHOD4(connect, - Return<void>(const sp<graphics::bufferqueue::V2_0::IProducerListener>&, - graphics::bufferqueue::V2_0::ConnectionType, bool, connect_cb)); - MOCK_METHOD1(disconnect, - Return<graphics::bufferqueue::V2_0::Status>( - graphics::bufferqueue::V2_0::ConnectionType)); - MOCK_METHOD4(allocateBuffers, - Return<graphics::bufferqueue::V2_0::Status>(uint32_t, uint32_t, uint32_t, - uint64_t)); - MOCK_METHOD1(allowAllocation, Return<graphics::bufferqueue::V2_0::Status>(bool)); - MOCK_METHOD1(setGenerationNumber, Return<graphics::bufferqueue::V2_0::Status>(uint32_t)); - MOCK_METHOD1(getConsumerName, Return<void>(getConsumerName_cb)); - MOCK_METHOD1(setDequeueTimeout, Return<graphics::bufferqueue::V2_0::Status>(int64_t)); - MOCK_METHOD0(getUniqueId, Return<uint64_t>()); -}; - -}; // namespace graphics::bufferqueue::V2_0::utils -}; // namespace android::hardware diff --git a/libs/gui/fuzzer/libgui_parcelable_fuzzer.cpp b/libs/gui/fuzzer/libgui_parcelable_fuzzer.cpp deleted file mode 100644 index 9f0f6cac19..0000000000 --- a/libs/gui/fuzzer/libgui_parcelable_fuzzer.cpp +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright 2022 The Android Open Source 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 <gui/BufferQueueConsumer.h> -#include <gui/BufferQueueCore.h> -#include <gui/BufferQueueProducer.h> -#include <gui/LayerMetadata.h> -#include <gui/OccupancyTracker.h> -#include <gui/StreamSplitter.h> -#include <gui/Surface.h> -#include <gui/SurfaceControl.h> -#include <gui/view/Surface.h> -#include <libgui_fuzzer_utils.h> -#include "android/view/LayerMetadataKey.h" - -using namespace android; - -constexpr int32_t kMaxBytes = 256; -constexpr int32_t kMatrixSize = 4; -constexpr int32_t kLayerMetadataKeyCount = 8; - -constexpr uint32_t kMetadataKey[] = { - (uint32_t)view::LayerMetadataKey::METADATA_OWNER_UID, - (uint32_t)view::LayerMetadataKey::METADATA_WINDOW_TYPE, - (uint32_t)view::LayerMetadataKey::METADATA_TASK_ID, - (uint32_t)view::LayerMetadataKey::METADATA_MOUSE_CURSOR, - (uint32_t)view::LayerMetadataKey::METADATA_ACCESSIBILITY_ID, - (uint32_t)view::LayerMetadataKey::METADATA_OWNER_PID, - (uint32_t)view::LayerMetadataKey::METADATA_DEQUEUE_TIME, - (uint32_t)view::LayerMetadataKey::METADATA_GAME_MODE, -}; - -class ParcelableFuzzer { -public: - ParcelableFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){}; - void process(); - -private: - void invokeStreamSplitter(); - void invokeOccupancyTracker(); - void invokeLayerDebugInfo(); - void invokeLayerMetadata(); - void invokeViewSurface(); - - FuzzedDataProvider mFdp; -}; - -void ParcelableFuzzer::invokeViewSurface() { - view::Surface surface; - surface.name = String16((mFdp.ConsumeRandomLengthString(kMaxBytes)).c_str()); - Parcel parcel; - surface.writeToParcel(&parcel); - parcel.setDataPosition(0); - surface.readFromParcel(&parcel); - bool nameAlreadyWritten = mFdp.ConsumeBool(); - surface.writeToParcel(&parcel, nameAlreadyWritten); - parcel.setDataPosition(0); - surface.readFromParcel(&parcel, mFdp.ConsumeBool()); -} - -void ParcelableFuzzer::invokeLayerMetadata() { - std::unordered_map<uint32_t, std::vector<uint8_t>> map; - for (size_t idx = 0; idx < kLayerMetadataKeyCount; ++idx) { - std::vector<uint8_t> data; - for (size_t idx1 = 0; idx1 < mFdp.ConsumeIntegral<uint32_t>(); ++idx1) { - data.push_back(mFdp.ConsumeIntegral<uint8_t>()); - } - map[kMetadataKey[idx]] = data; - } - LayerMetadata metadata(map); - uint32_t key = mFdp.PickValueInArray(kMetadataKey); - metadata.setInt32(key, mFdp.ConsumeIntegral<int32_t>()); - metadata.itemToString(key, (mFdp.ConsumeRandomLengthString(kMaxBytes)).c_str()); - - Parcel parcel; - metadata.writeToParcel(&parcel); - parcel.setDataPosition(0); - metadata.readFromParcel(&parcel); -} - -void ParcelableFuzzer::invokeLayerDebugInfo() { - gui::LayerDebugInfo info; - info.mName = mFdp.ConsumeRandomLengthString(kMaxBytes); - info.mParentName = mFdp.ConsumeRandomLengthString(kMaxBytes); - info.mType = mFdp.ConsumeRandomLengthString(kMaxBytes); - info.mLayerStack = mFdp.ConsumeIntegral<uint32_t>(); - info.mX = mFdp.ConsumeFloatingPoint<float>(); - info.mY = mFdp.ConsumeFloatingPoint<float>(); - info.mZ = mFdp.ConsumeIntegral<uint32_t>(); - info.mWidth = mFdp.ConsumeIntegral<int32_t>(); - info.mHeight = mFdp.ConsumeIntegral<int32_t>(); - info.mActiveBufferWidth = mFdp.ConsumeIntegral<int32_t>(); - info.mActiveBufferHeight = mFdp.ConsumeIntegral<int32_t>(); - info.mActiveBufferStride = mFdp.ConsumeIntegral<int32_t>(); - info.mActiveBufferFormat = mFdp.ConsumeIntegral<int32_t>(); - info.mNumQueuedFrames = mFdp.ConsumeIntegral<int32_t>(); - - info.mFlags = mFdp.ConsumeIntegral<uint32_t>(); - info.mPixelFormat = mFdp.ConsumeIntegral<int32_t>(); - info.mTransparentRegion = Region(getRect(&mFdp)); - info.mVisibleRegion = Region(getRect(&mFdp)); - info.mSurfaceDamageRegion = Region(getRect(&mFdp)); - info.mCrop = getRect(&mFdp); - info.mDataSpace = static_cast<android_dataspace>(mFdp.PickValueInArray(kDataspaces)); - info.mColor = half4(mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeFloatingPoint<float>(), - mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeFloatingPoint<float>()); - for (size_t idx = 0; idx < kMatrixSize; ++idx) { - info.mMatrix[idx / 2][idx % 2] = mFdp.ConsumeFloatingPoint<float>(); - } - info.mIsOpaque = mFdp.ConsumeBool(); - info.mContentDirty = mFdp.ConsumeBool(); - info.mStretchEffect.width = mFdp.ConsumeFloatingPoint<float>(); - info.mStretchEffect.height = mFdp.ConsumeFloatingPoint<float>(); - info.mStretchEffect.vectorX = mFdp.ConsumeFloatingPoint<float>(); - info.mStretchEffect.vectorY = mFdp.ConsumeFloatingPoint<float>(); - info.mStretchEffect.maxAmountX = mFdp.ConsumeFloatingPoint<float>(); - info.mStretchEffect.maxAmountY = mFdp.ConsumeFloatingPoint<float>(); - info.mStretchEffect.mappedChildBounds = - FloatRect(mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeFloatingPoint<float>(), - mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeFloatingPoint<float>()); - - Parcel parcel; - info.writeToParcel(&parcel); - parcel.setDataPosition(0); - info.readFromParcel(&parcel); -} - -void ParcelableFuzzer::invokeOccupancyTracker() { - nsecs_t totalTime = mFdp.ConsumeIntegral<uint32_t>(); - size_t numFrames = mFdp.ConsumeIntegral<size_t>(); - float occupancyAverage = mFdp.ConsumeFloatingPoint<float>(); - OccupancyTracker::Segment segment(totalTime, numFrames, occupancyAverage, - mFdp.ConsumeBool() /*usedThirdBuffer*/); - Parcel parcel; - segment.writeToParcel(&parcel); - parcel.setDataPosition(0); - segment.readFromParcel(&parcel); -} - -void ParcelableFuzzer::invokeStreamSplitter() { - sp<IGraphicBufferProducer> producer; - sp<IGraphicBufferConsumer> consumer; - BufferQueue::createBufferQueue(&producer, &consumer); - sp<StreamSplitter> splitter; - StreamSplitter::createSplitter(consumer, &splitter); - splitter->addOutput(producer); - std::string name = mFdp.ConsumeRandomLengthString(kMaxBytes); - splitter->setName(String8(name.c_str())); -} - -void ParcelableFuzzer::process() { - invokeStreamSplitter(); - invokeOccupancyTracker(); - invokeLayerDebugInfo(); - invokeLayerMetadata(); - invokeViewSurface(); -} - -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - ParcelableFuzzer libGuiFuzzer(data, size); - libGuiFuzzer.process(); - return 0; -} diff --git a/libs/gui/fuzzer/libgui_surfaceComposerClient_fuzzer.cpp b/libs/gui/fuzzer/libgui_surfaceComposerClient_fuzzer.cpp deleted file mode 100644 index 4daa3be36f..0000000000 --- a/libs/gui/fuzzer/libgui_surfaceComposerClient_fuzzer.cpp +++ /dev/null @@ -1,328 +0,0 @@ -/* - * Copyright 2022 The Android Open Source 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 <aidl/android/hardware/power/Boost.h> -#include <fuzzbinder/libbinder_driver.h> -#include <gui/Surface.h> -#include <gui/SurfaceComposerClient.h> -#include <libgui_fuzzer_utils.h> -#include "android-base/stringprintf.h" - -using namespace android; - -constexpr int32_t kRandomStringMaxBytes = 256; - -constexpr ui::ColorMode kColormodes[] = {ui::ColorMode::NATIVE, - ui::ColorMode::STANDARD_BT601_625, - ui::ColorMode::STANDARD_BT601_625_UNADJUSTED, - ui::ColorMode::STANDARD_BT601_525, - ui::ColorMode::STANDARD_BT601_525_UNADJUSTED, - ui::ColorMode::STANDARD_BT709, - ui::ColorMode::DCI_P3, - ui::ColorMode::SRGB, - ui::ColorMode::ADOBE_RGB, - ui::ColorMode::DISPLAY_P3, - ui::ColorMode::BT2020, - ui::ColorMode::BT2100_PQ, - ui::ColorMode::BT2100_HLG, - ui::ColorMode::DISPLAY_BT2020}; - -constexpr aidl::android::hardware::power::Boost kBoost[] = { - aidl::android::hardware::power::Boost::INTERACTION, - aidl::android::hardware::power::Boost::DISPLAY_UPDATE_IMMINENT, - aidl::android::hardware::power::Boost::ML_ACC, - aidl::android::hardware::power::Boost::AUDIO_LAUNCH, - aidl::android::hardware::power::Boost::CAMERA_LAUNCH, - aidl::android::hardware::power::Boost::CAMERA_SHOT, -}; - -constexpr gui::TouchOcclusionMode kMode[] = { - gui::TouchOcclusionMode::BLOCK_UNTRUSTED, - gui::TouchOcclusionMode::USE_OPACITY, - gui::TouchOcclusionMode::ALLOW, -}; - -constexpr gui::WindowInfo::Flag kFlags[] = { - gui::WindowInfo::Flag::ALLOW_LOCK_WHILE_SCREEN_ON, - gui::WindowInfo::Flag::DIM_BEHIND, - gui::WindowInfo::Flag::BLUR_BEHIND, - gui::WindowInfo::Flag::NOT_FOCUSABLE, - gui::WindowInfo::Flag::NOT_TOUCHABLE, - gui::WindowInfo::Flag::NOT_TOUCH_MODAL, - gui::WindowInfo::Flag::TOUCHABLE_WHEN_WAKING, - gui::WindowInfo::Flag::KEEP_SCREEN_ON, - gui::WindowInfo::Flag::LAYOUT_IN_SCREEN, - gui::WindowInfo::Flag::LAYOUT_NO_LIMITS, - gui::WindowInfo::Flag::FULLSCREEN, - gui::WindowInfo::Flag::FORCE_NOT_FULLSCREEN, - gui::WindowInfo::Flag::DITHER, - gui::WindowInfo::Flag::SECURE, - gui::WindowInfo::Flag::SCALED, - gui::WindowInfo::Flag::IGNORE_CHEEK_PRESSES, - gui::WindowInfo::Flag::LAYOUT_INSET_DECOR, - gui::WindowInfo::Flag::ALT_FOCUSABLE_IM, - gui::WindowInfo::Flag::WATCH_OUTSIDE_TOUCH, - gui::WindowInfo::Flag::SHOW_WHEN_LOCKED, - gui::WindowInfo::Flag::SHOW_WALLPAPER, - gui::WindowInfo::Flag::TURN_SCREEN_ON, - gui::WindowInfo::Flag::DISMISS_KEYGUARD, - gui::WindowInfo::Flag::SPLIT_TOUCH, - gui::WindowInfo::Flag::HARDWARE_ACCELERATED, - gui::WindowInfo::Flag::LAYOUT_IN_OVERSCAN, - gui::WindowInfo::Flag::TRANSLUCENT_STATUS, - gui::WindowInfo::Flag::TRANSLUCENT_NAVIGATION, - gui::WindowInfo::Flag::LOCAL_FOCUS_MODE, - gui::WindowInfo::Flag::SLIPPERY, - gui::WindowInfo::Flag::LAYOUT_ATTACHED_IN_DECOR, - gui::WindowInfo::Flag::DRAWS_SYSTEM_BAR_BACKGROUNDS, -}; - -constexpr gui::WindowInfo::Type kType[] = { - gui::WindowInfo::Type::UNKNOWN, - gui::WindowInfo::Type::FIRST_APPLICATION_WINDOW, - gui::WindowInfo::Type::BASE_APPLICATION, - gui::WindowInfo::Type::APPLICATION, - gui::WindowInfo::Type::APPLICATION_STARTING, - gui::WindowInfo::Type::LAST_APPLICATION_WINDOW, - gui::WindowInfo::Type::FIRST_SUB_WINDOW, - gui::WindowInfo::Type::APPLICATION_PANEL, - gui::WindowInfo::Type::APPLICATION_MEDIA, - gui::WindowInfo::Type::APPLICATION_SUB_PANEL, - gui::WindowInfo::Type::APPLICATION_ATTACHED_DIALOG, - gui::WindowInfo::Type::APPLICATION_MEDIA_OVERLAY, -}; - -constexpr gui::WindowInfo::InputConfig kFeatures[] = { - gui::WindowInfo::InputConfig::NO_INPUT_CHANNEL, - gui::WindowInfo::InputConfig::DISABLE_USER_ACTIVITY, - gui::WindowInfo::InputConfig::DROP_INPUT, - gui::WindowInfo::InputConfig::DROP_INPUT_IF_OBSCURED, - gui::WindowInfo::InputConfig::SPY, - gui::WindowInfo::InputConfig::INTERCEPTS_STYLUS, -}; - -class SurfaceComposerClientFuzzer { -public: - SurfaceComposerClientFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){}; - void process(); - -private: - void invokeSurfaceComposerClient(); - void invokeSurfaceComposerClientBinder(); - void invokeSurfaceComposerTransaction(); - void getWindowInfo(gui::WindowInfo*); - sp<SurfaceControl> makeSurfaceControl(); - BlurRegion getBlurRegion(); - void fuzzOnPullAtom(); - gui::DisplayModeSpecs getDisplayModeSpecs(); - - FuzzedDataProvider mFdp; -}; - -gui::DisplayModeSpecs SurfaceComposerClientFuzzer::getDisplayModeSpecs() { - const auto getRefreshRateRange = [&] { - gui::DisplayModeSpecs::RefreshRateRanges::RefreshRateRange range; - range.min = mFdp.ConsumeFloatingPoint<float>(); - range.max = mFdp.ConsumeFloatingPoint<float>(); - return range; - }; - - const auto getRefreshRateRanges = [&] { - gui::DisplayModeSpecs::RefreshRateRanges ranges; - ranges.physical = getRefreshRateRange(); - ranges.render = getRefreshRateRange(); - return ranges; - }; - - String8 displayName((mFdp.ConsumeRandomLengthString(kRandomStringMaxBytes)).c_str()); - sp<IBinder> displayToken = - SurfaceComposerClient::createDisplay(displayName, mFdp.ConsumeBool() /*secure*/); - gui::DisplayModeSpecs specs; - specs.defaultMode = mFdp.ConsumeIntegral<int32_t>(); - specs.allowGroupSwitching = mFdp.ConsumeBool(); - specs.primaryRanges = getRefreshRateRanges(); - specs.appRequestRanges = getRefreshRateRanges(); - return specs; -} - -BlurRegion SurfaceComposerClientFuzzer::getBlurRegion() { - int32_t left = mFdp.ConsumeIntegral<int32_t>(); - int32_t right = mFdp.ConsumeIntegral<int32_t>(); - int32_t top = mFdp.ConsumeIntegral<int32_t>(); - int32_t bottom = mFdp.ConsumeIntegral<int32_t>(); - uint32_t blurRadius = mFdp.ConsumeIntegral<uint32_t>(); - float alpha = mFdp.ConsumeFloatingPoint<float>(); - float cornerRadiusTL = mFdp.ConsumeFloatingPoint<float>(); - float cornerRadiusTR = mFdp.ConsumeFloatingPoint<float>(); - float cornerRadiusBL = mFdp.ConsumeFloatingPoint<float>(); - float cornerRadiusBR = mFdp.ConsumeFloatingPoint<float>(); - return BlurRegion{blurRadius, cornerRadiusTL, cornerRadiusTR, cornerRadiusBL, - cornerRadiusBR, alpha, left, top, - right, bottom}; -} - -void SurfaceComposerClientFuzzer::getWindowInfo(gui::WindowInfo* windowInfo) { - windowInfo->id = mFdp.ConsumeIntegral<int32_t>(); - windowInfo->name = mFdp.ConsumeRandomLengthString(kRandomStringMaxBytes); - windowInfo->layoutParamsFlags = mFdp.PickValueInArray(kFlags); - windowInfo->layoutParamsType = mFdp.PickValueInArray(kType); - windowInfo->frame = Rect(mFdp.ConsumeIntegral<int32_t>(), mFdp.ConsumeIntegral<int32_t>(), - mFdp.ConsumeIntegral<int32_t>(), mFdp.ConsumeIntegral<int32_t>()); - windowInfo->surfaceInset = mFdp.ConsumeIntegral<int32_t>(); - windowInfo->alpha = mFdp.ConsumeFloatingPointInRange<float>(0, 1); - ui::Transform transform(mFdp.PickValueInArray(kOrientation)); - windowInfo->transform = transform; - windowInfo->touchableRegion = Region(getRect(&mFdp)); - windowInfo->replaceTouchableRegionWithCrop = mFdp.ConsumeBool(); - windowInfo->touchOcclusionMode = mFdp.PickValueInArray(kMode); - windowInfo->ownerPid = gui::Pid{mFdp.ConsumeIntegral<pid_t>()}; - windowInfo->ownerUid = gui::Uid{mFdp.ConsumeIntegral<uid_t>()}; - windowInfo->packageName = mFdp.ConsumeRandomLengthString(kRandomStringMaxBytes); - windowInfo->inputConfig = mFdp.PickValueInArray(kFeatures); -} - -sp<SurfaceControl> SurfaceComposerClientFuzzer::makeSurfaceControl() { - sp<IBinder> handle; - const sp<FakeBnSurfaceComposerClient> testClient(new FakeBnSurfaceComposerClient()); - sp<SurfaceComposerClient> client = new SurfaceComposerClient(testClient); - sp<BnGraphicBufferProducer> producer; - uint32_t width = mFdp.ConsumeIntegral<uint32_t>(); - uint32_t height = mFdp.ConsumeIntegral<uint32_t>(); - uint32_t transformHint = mFdp.ConsumeIntegral<uint32_t>(); - uint32_t flags = mFdp.ConsumeIntegral<uint32_t>(); - int32_t format = mFdp.ConsumeIntegral<int32_t>(); - int32_t layerId = mFdp.ConsumeIntegral<int32_t>(); - std::string layerName = base::StringPrintf("#%d", layerId); - return new SurfaceControl(client, handle, layerId, layerName, width, height, format, - transformHint, flags); -} - -void SurfaceComposerClientFuzzer::invokeSurfaceComposerTransaction() { - sp<SurfaceControl> surface = makeSurfaceControl(); - - SurfaceComposerClient::Transaction transaction; - int32_t layer = mFdp.ConsumeIntegral<int32_t>(); - transaction.setLayer(surface, layer); - - sp<SurfaceControl> relativeSurface = makeSurfaceControl(); - transaction.setRelativeLayer(surface, relativeSurface, layer); - - Region transparentRegion(getRect(&mFdp)); - transaction.setTransparentRegionHint(surface, transparentRegion); - transaction.setAlpha(surface, mFdp.ConsumeFloatingPoint<float>()); - - transaction.setCornerRadius(surface, mFdp.ConsumeFloatingPoint<float>()); - transaction.setBackgroundBlurRadius(surface, mFdp.ConsumeFloatingPoint<float>()); - std::vector<BlurRegion> regions; - uint32_t vectorSize = mFdp.ConsumeIntegralInRange<uint32_t>(0, 100); - regions.resize(vectorSize); - for (size_t idx = 0; idx < vectorSize; ++idx) { - regions.push_back(getBlurRegion()); - } - transaction.setBlurRegions(surface, regions); - - transaction.setLayerStack(surface, {mFdp.ConsumeIntegral<uint32_t>()}); - half3 color = {mFdp.ConsumeIntegral<uint32_t>(), mFdp.ConsumeIntegral<uint32_t>(), - mFdp.ConsumeIntegral<uint32_t>()}; - transaction.setColor(surface, color); - transaction.setBackgroundColor(surface, color, mFdp.ConsumeFloatingPoint<float>(), - mFdp.PickValueInArray(kDataspaces)); - - transaction.setApi(surface, mFdp.ConsumeIntegral<int32_t>()); - transaction.setFrameRateSelectionPriority(surface, mFdp.ConsumeIntegral<int32_t>()); - transaction.setColorSpaceAgnostic(surface, mFdp.ConsumeBool() /*agnostic*/); - - gui::WindowInfo windowInfo; - getWindowInfo(&windowInfo); - transaction.setInputWindowInfo(surface, windowInfo); - Parcel windowParcel; - windowInfo.writeToParcel(&windowParcel); - windowParcel.setDataPosition(0); - windowInfo.readFromParcel(&windowParcel); - - windowInfo.addTouchableRegion(getRect(&mFdp)); - int32_t pointX = mFdp.ConsumeIntegral<int32_t>(); - int32_t pointY = mFdp.ConsumeIntegral<int32_t>(); - windowInfo.touchableRegionContainsPoint(pointX, pointY); - windowInfo.frameContainsPoint(pointX, pointY); - - Parcel transactionParcel; - transaction.writeToParcel(&transactionParcel); - transactionParcel.setDataPosition(0); - transaction.readFromParcel(&transactionParcel); - SurfaceComposerClient::Transaction::createFromParcel(&transactionParcel); -} - -void SurfaceComposerClientFuzzer::fuzzOnPullAtom() { - std::string outData; - bool success; - SurfaceComposerClient::onPullAtom(mFdp.ConsumeIntegral<int32_t>(), &outData, &success); -} - -void SurfaceComposerClientFuzzer::invokeSurfaceComposerClient() { - String8 displayName((mFdp.ConsumeRandomLengthString(kRandomStringMaxBytes)).c_str()); - sp<IBinder> displayToken = - SurfaceComposerClient::createDisplay(displayName, mFdp.ConsumeBool() /*secure*/); - SurfaceComposerClient::setDesiredDisplayModeSpecs(displayToken, getDisplayModeSpecs()); - - ui::ColorMode colorMode = mFdp.PickValueInArray(kColormodes); - SurfaceComposerClient::setActiveColorMode(displayToken, colorMode); - SurfaceComposerClient::setAutoLowLatencyMode(displayToken, mFdp.ConsumeBool() /*on*/); - SurfaceComposerClient::setGameContentType(displayToken, mFdp.ConsumeBool() /*on*/); - SurfaceComposerClient::setDisplayPowerMode(displayToken, mFdp.ConsumeIntegral<int32_t>()); - SurfaceComposerClient::doUncacheBufferTransaction(mFdp.ConsumeIntegral<uint64_t>()); - - SurfaceComposerClient::setDisplayBrightness(displayToken, getBrightness(&mFdp)); - aidl::android::hardware::power::Boost boostId = mFdp.PickValueInArray(kBoost); - SurfaceComposerClient::notifyPowerBoost((int32_t)boostId); - - String8 surfaceName((mFdp.ConsumeRandomLengthString(kRandomStringMaxBytes)).c_str()); - sp<BBinder> handle(new BBinder()); - sp<BnGraphicBufferProducer> producer; - sp<Surface> surfaceParent( - new Surface(producer, mFdp.ConsumeBool() /*controlledByApp*/, handle)); - - fuzzOnPullAtom(); - SurfaceComposerClient::setDisplayContentSamplingEnabled(displayToken, - mFdp.ConsumeBool() /*enable*/, - mFdp.ConsumeIntegral<uint8_t>(), - mFdp.ConsumeIntegral<uint64_t>()); - - sp<IBinder> stopLayerHandle; - sp<gui::IRegionSamplingListener> listener = sp<gui::IRegionSamplingListenerDefault>::make(); - sp<gui::IRegionSamplingListenerDelegator> sampleListener = - new gui::IRegionSamplingListenerDelegator(listener); - SurfaceComposerClient::addRegionSamplingListener(getRect(&mFdp), stopLayerHandle, - sampleListener); - sp<gui::IFpsListenerDefault> fpsListener; - SurfaceComposerClient::addFpsListener(mFdp.ConsumeIntegral<int32_t>(), fpsListener); -} - -void SurfaceComposerClientFuzzer::invokeSurfaceComposerClientBinder() { - sp<FakeBnSurfaceComposerClient> client(new FakeBnSurfaceComposerClient()); - fuzzService(client.get(), std::move(mFdp)); -} - -void SurfaceComposerClientFuzzer::process() { - invokeSurfaceComposerClient(); - invokeSurfaceComposerTransaction(); - invokeSurfaceComposerClientBinder(); -} - -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - SurfaceComposerClientFuzzer surfaceComposerClientFuzzer(data, size); - surfaceComposerClientFuzzer.process(); - return 0; -} diff --git a/libs/gui/fuzzer/libgui_surfaceComposer_fuzzer.cpp b/libs/gui/fuzzer/libgui_surfaceComposer_fuzzer.cpp deleted file mode 100644 index 6d5427bc9e..0000000000 --- a/libs/gui/fuzzer/libgui_surfaceComposer_fuzzer.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2021 The Android Open Source 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 <fuzzbinder/libbinder_driver.h> -#include <fuzzer/FuzzedDataProvider.h> -#include <libgui_fuzzer_utils.h> - -using namespace android; - -class SurfaceComposerFuzzer { -public: - SurfaceComposerFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){}; - void process(); - -private: - FuzzedDataProvider mFdp; -}; - -void SurfaceComposerFuzzer::process() { - sp<FakeBnSurfaceComposer> composer(new FakeBnSurfaceComposer()); - fuzzService(composer.get(), std::move(mFdp)); -} - -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - SurfaceComposerFuzzer surfaceComposerFuzzer(data, size); - surfaceComposerFuzzer.process(); - return 0; -} diff --git a/libs/gui/sysprop/Android.bp b/libs/gui/sysprop/Android.bp index cc33e4c27d..386767ba9e 100644 --- a/libs/gui/sysprop/Android.bp +++ b/libs/gui/sysprop/Android.bp @@ -5,6 +5,7 @@ package { // to get the below license kinds: // SPDX-license-identifier-Apache-2.0 default_applicable_licenses: ["frameworks_native_license"], + default_team: "trendy_team_android_core_graphics_stack", } sysprop_library { diff --git a/libs/gui/tests/AndroidTest.xml b/libs/gui/tests/AndroidTest.xml index 31b10d7f54..b4ccf87349 100644 --- a/libs/gui/tests/AndroidTest.xml +++ b/libs/gui/tests/AndroidTest.xml @@ -18,6 +18,7 @@ <option name="cleanup" value="true" /> <option name="push" value="libgui_test->/data/local/tmp/libgui_test" /> </target_preparer> + <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" /> <target_preparer class="com.android.tradefed.targetprep.DeviceSetup"> <option name="force-skip-system-props" value="true" /> <!-- avoid restarting device --> <option name="screen-always-on" value="on" /> diff --git a/libs/gui/tests/FrameRateUtilsTest.cpp b/libs/gui/tests/FrameRateUtilsTest.cpp index 5fe22b05f9..04bfb28f65 100644 --- a/libs/gui/tests/FrameRateUtilsTest.cpp +++ b/libs/gui/tests/FrameRateUtilsTest.cpp @@ -34,6 +34,8 @@ TEST(FrameRateUtilsTest, ValidateFrameRate) { ANATIVEWINDOW_CHANGE_FRAME_RATE_ALWAYS, "")); EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, "")); + EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_GTE, + ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, "")); // Privileged APIs. EXPECT_FALSE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_EXACT, diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp index 0d29b4db96..d58fb42f05 100644 --- a/libs/input/Input.cpp +++ b/libs/input/Input.cpp @@ -60,6 +60,45 @@ bool shouldDisregardOffset(uint32_t source) { return !isFromSource(source, AINPUT_SOURCE_CLASS_POINTER); } +int32_t resolveActionForSplitMotionEvent( + int32_t action, int32_t flags, const std::vector<PointerProperties>& pointerProperties, + const std::vector<PointerProperties>& splitPointerProperties) { + LOG_ALWAYS_FATAL_IF(splitPointerProperties.empty()); + const auto maskedAction = MotionEvent::getActionMasked(action); + if (maskedAction != AMOTION_EVENT_ACTION_POINTER_DOWN && + maskedAction != AMOTION_EVENT_ACTION_POINTER_UP) { + // The action is unaffected by splitting this motion event. + return action; + } + const auto actionIndex = MotionEvent::getActionIndex(action); + if (CC_UNLIKELY(actionIndex >= pointerProperties.size())) { + LOG(FATAL) << "Action index is out of bounds, index: " << actionIndex; + } + + const auto affectedPointerId = pointerProperties[actionIndex].id; + std::optional<uint32_t> splitActionIndex; + for (uint32_t i = 0; i < splitPointerProperties.size(); i++) { + if (affectedPointerId == splitPointerProperties[i].id) { + splitActionIndex = i; + break; + } + } + if (!splitActionIndex.has_value()) { + // The affected pointer is not part of the split motion event. + return AMOTION_EVENT_ACTION_MOVE; + } + + if (splitPointerProperties.size() > 1) { + return maskedAction | (*splitActionIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT); + } + + if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) { + return ((flags & AMOTION_EVENT_FLAG_CANCELED) != 0) ? AMOTION_EVENT_ACTION_CANCEL + : AMOTION_EVENT_ACTION_UP; + } + return AMOTION_EVENT_ACTION_DOWN; +} + } // namespace const char* motionClassificationToString(MotionClassification classification) { @@ -584,6 +623,28 @@ void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) { } } +void MotionEvent::splitFrom(const android::MotionEvent& other, + std::bitset<MAX_POINTER_ID + 1> splitPointerIds, int32_t newEventId) { + // TODO(b/327503168): The down time should be a parameter to the split function, because only + // the caller can know when the first event went down on the target. + const nsecs_t splitDownTime = other.mDownTime; + + auto [action, pointerProperties, pointerCoords] = + split(other.getAction(), other.getFlags(), other.getHistorySize(), + other.mPointerProperties, other.mSamplePointerCoords, splitPointerIds); + + // Initialize the event with zero pointers, and manually set the split pointers. + initialize(newEventId, other.mDeviceId, other.mSource, other.mDisplayId, /*hmac=*/{}, action, + other.mActionButton, other.mFlags, other.mEdgeFlags, other.mMetaState, + other.mButtonState, other.mClassification, other.mTransform, other.mXPrecision, + other.mYPrecision, other.mRawXCursorPosition, other.mRawYCursorPosition, + other.mRawTransform, splitDownTime, other.getEventTime(), /*pointerCount=*/0, + pointerProperties.data(), pointerCoords.data()); + mPointerProperties = std::move(pointerProperties); + mSamplePointerCoords = std::move(pointerCoords); + mSampleEventTimes = other.mSampleEventTimes; +} + void MotionEvent::addSample( int64_t eventTime, const PointerCoords* pointerCoords) { @@ -934,6 +995,45 @@ std::string MotionEvent::actionToString(int32_t action) { return android::base::StringPrintf("%" PRId32, action); } +std::tuple<int32_t, std::vector<PointerProperties>, std::vector<PointerCoords>> MotionEvent::split( + int32_t action, int32_t flags, int32_t historySize, + const std::vector<PointerProperties>& pointerProperties, + const std::vector<PointerCoords>& pointerCoords, + std::bitset<MAX_POINTER_ID + 1> splitPointerIds) { + LOG_ALWAYS_FATAL_IF(!splitPointerIds.any()); + const auto pointerCount = pointerProperties.size(); + LOG_ALWAYS_FATAL_IF(pointerCoords.size() != (pointerCount * (historySize + 1))); + const auto splitCount = splitPointerIds.count(); + + std::vector<PointerProperties> splitPointerProperties; + std::vector<PointerCoords> splitPointerCoords; + + for (uint32_t i = 0; i < pointerCount; i++) { + if (splitPointerIds.test(pointerProperties[i].id)) { + splitPointerProperties.emplace_back(pointerProperties[i]); + } + } + for (uint32_t i = 0; i < pointerCoords.size(); i++) { + if (splitPointerIds.test(pointerProperties[i % pointerCount].id)) { + splitPointerCoords.emplace_back(pointerCoords[i]); + } + } + LOG_ALWAYS_FATAL_IF(splitPointerCoords.size() != + (splitPointerProperties.size() * (historySize + 1))); + + if (CC_UNLIKELY(splitPointerProperties.size() != splitCount)) { + LOG(FATAL) << "Cannot split MotionEvent: Requested splitting " << splitCount + << " pointers from the original event, but the original event only contained " + << splitPointerProperties.size() << " of those pointers."; + } + + // TODO(b/327503168): Verify the splitDownTime here once it is used correctly. + + const auto splitAction = resolveActionForSplitMotionEvent(action, flags, pointerProperties, + splitPointerProperties); + return {splitAction, splitPointerProperties, splitPointerCoords}; +} + // Apply the given transformation to the point without checking whether the entire transform // should be disregarded altogether for the provided source. static inline vec2 calculateTransformedXYUnchecked(uint32_t source, const ui::Transform& transform, @@ -1007,6 +1107,33 @@ PointerCoords MotionEvent::calculateTransformedCoords(uint32_t source, return out; } +bool MotionEvent::operator==(const android::MotionEvent& o) const { + // We use NaN values to represent invalid cursor positions. Since NaN values are not equal + // to themselves according to IEEE 754, we cannot use the default equality operator to compare + // MotionEvents. Therefore we define a custom equality operator with special handling for NaNs. + // clang-format off + return InputEvent::operator==(static_cast<const InputEvent&>(o)) && + mAction == o.mAction && + mActionButton == o.mActionButton && + mFlags == o.mFlags && + mEdgeFlags == o.mEdgeFlags && + mMetaState == o.mMetaState && + mButtonState == o.mButtonState && + mClassification == o.mClassification && + mTransform == o.mTransform && + mXPrecision == o.mXPrecision && + mYPrecision == o.mYPrecision && + ((std::isnan(mRawXCursorPosition) && std::isnan(o.mRawXCursorPosition)) || + mRawXCursorPosition == o.mRawXCursorPosition) && + ((std::isnan(mRawYCursorPosition) && std::isnan(o.mRawYCursorPosition)) || + mRawYCursorPosition == o.mRawYCursorPosition) && + mRawTransform == o.mRawTransform && mDownTime == o.mDownTime && + mPointerProperties == o.mPointerProperties && + mSampleEventTimes == o.mSampleEventTimes && + mSamplePointerCoords == o.mSamplePointerCoords; + // clang-format on +} + std::ostream& operator<<(std::ostream& out, const MotionEvent& event) { out << "MotionEvent { action=" << MotionEvent::actionToString(event.getAction()); if (event.getActionButton() != 0) { @@ -1037,6 +1164,9 @@ std::ostream& operator<<(std::ostream& out, const MotionEvent& event) { if (event.getMetaState() != 0) { out << ", metaState=" << event.getMetaState(); } + if (event.getFlags() != 0) { + out << ", flags=0x" << std::hex << event.getFlags() << std::dec; + } if (event.getEdgeFlags() != 0) { out << ", edgeFlags=" << event.getEdgeFlags(); } diff --git a/libs/input/InputDevice.cpp b/libs/input/InputDevice.cpp index d4dbc45090..c348833747 100644 --- a/libs/input/InputDevice.cpp +++ b/libs/input/InputDevice.cpp @@ -20,12 +20,14 @@ #include <unistd.h> #include <ctype.h> +#include <android-base/properties.h> #include <android-base/stringprintf.h> #include <ftl/enum.h> #include <gui/constants.h> #include <input/InputDevice.h> #include <input/InputEventLabels.h> +using android::base::GetProperty; using android::base::StringPrintf; namespace android { @@ -96,21 +98,22 @@ std::string getInputDeviceConfigurationFilePathByName( // Treblized input device config files will be located /product/usr, /system_ext/usr, // /odm/usr or /vendor/usr. - // These files may also be in the com.android.input.config APEX. - const char* rootsForPartition[]{ - "/product", - "/system_ext", - "/odm", - "/vendor", - "/apex/com.android.input.config/etc", - getenv("ANDROID_ROOT"), + std::vector<std::string> pathPrefixes{ + "/product/usr/", + "/system_ext/usr/", + "/odm/usr/", + "/vendor/usr/", }; - for (size_t i = 0; i < size(rootsForPartition); i++) { - if (rootsForPartition[i] == nullptr) { - continue; - } - path = rootsForPartition[i]; - path += "/usr/"; + // These files may also be in the APEX pointed by input_device.config_file.apex sysprop. + if (auto apex = GetProperty("input_device.config_file.apex", ""); !apex.empty()) { + pathPrefixes.push_back("/apex/" + apex + "/etc/usr/"); + } + // ANDROID_ROOT may not be set on host + if (auto android_root = getenv("ANDROID_ROOT"); android_root != nullptr) { + pathPrefixes.push_back(std::string(android_root) + "/usr/"); + } + for (const auto& prefix : pathPrefixes) { + path = prefix; appendInputDeviceConfigurationFileRelativePath(path, name, type); #if DEBUG_PROBE ALOGD("Probing for system provided input device configuration file: path='%s'", diff --git a/libs/input/input_flags.aconfig b/libs/input/input_flags.aconfig index 5af48550c6..bdec5c33cd 100644 --- a/libs/input/input_flags.aconfig +++ b/libs/input/input_flags.aconfig @@ -119,3 +119,10 @@ flag { description: "Controls the API to provide InputDevice view behavior." bug: "246946631" } + +flag { + name: "enable_touchpad_fling_stop" + namespace: "input" + description: "Enable fling scrolling to be stopped by putting a finger on the touchpad again" + bug: "281106755" +} diff --git a/libs/input/tests/InputEvent_test.cpp b/libs/input/tests/InputEvent_test.cpp index a9655730fc..540766d66c 100644 --- a/libs/input/tests/InputEvent_test.cpp +++ b/libs/input/tests/InputEvent_test.cpp @@ -23,6 +23,7 @@ #include <gtest/gtest.h> #include <gui/constants.h> #include <input/Input.h> +#include <input/InputEventBuilders.h> namespace android { @@ -31,6 +32,18 @@ static constexpr int32_t DISPLAY_ID = ADISPLAY_ID_DEFAULT; static constexpr float EPSILON = MotionEvent::ROUNDING_PRECISION; +static constexpr auto POINTER_0_DOWN = + AMOTION_EVENT_ACTION_POINTER_DOWN | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT); + +static constexpr auto POINTER_1_DOWN = + AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT); + +static constexpr auto POINTER_0_UP = + AMOTION_EVENT_ACTION_POINTER_UP | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT); + +static constexpr auto POINTER_1_UP = + AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT); + class BaseTest : public testing::Test { protected: static constexpr std::array<uint8_t, 32> HMAC = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, @@ -554,6 +567,145 @@ TEST_F(MotionEventTest, CopyFrom_DoNotKeepHistory) { ASSERT_EQ(event.getX(0), copy.getX(0)); } +TEST_F(MotionEventTest, SplitPointerDown) { + MotionEvent event = MotionEventBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN) + .downTime(ARBITRARY_DOWN_TIME) + .pointer(PointerBuilder(/*id=*/4, ToolType::FINGER).x(4).y(4)) + .pointer(PointerBuilder(/*id=*/6, ToolType::FINGER).x(6).y(6)) + .pointer(PointerBuilder(/*id=*/8, ToolType::FINGER).x(8).y(8)) + .build(); + + MotionEvent splitDown; + std::bitset<MAX_POINTER_ID + 1> splitDownIds{}; + splitDownIds.set(6, true); + splitDown.splitFrom(event, splitDownIds, /*eventId=*/42); + ASSERT_EQ(splitDown.getAction(), AMOTION_EVENT_ACTION_DOWN); + ASSERT_EQ(splitDown.getPointerCount(), 1u); + ASSERT_EQ(splitDown.getPointerId(0), 6); + ASSERT_EQ(splitDown.getX(0), 6); + ASSERT_EQ(splitDown.getY(0), 6); + + MotionEvent splitPointerDown; + std::bitset<MAX_POINTER_ID + 1> splitPointerDownIds{}; + splitPointerDownIds.set(6, true); + splitPointerDownIds.set(8, true); + splitPointerDown.splitFrom(event, splitPointerDownIds, /*eventId=*/42); + ASSERT_EQ(splitPointerDown.getAction(), POINTER_0_DOWN); + ASSERT_EQ(splitPointerDown.getPointerCount(), 2u); + ASSERT_EQ(splitPointerDown.getPointerId(0), 6); + ASSERT_EQ(splitPointerDown.getX(0), 6); + ASSERT_EQ(splitPointerDown.getY(0), 6); + ASSERT_EQ(splitPointerDown.getPointerId(1), 8); + ASSERT_EQ(splitPointerDown.getX(1), 8); + ASSERT_EQ(splitPointerDown.getY(1), 8); + + MotionEvent splitMove; + std::bitset<MAX_POINTER_ID + 1> splitMoveIds{}; + splitMoveIds.set(4, true); + splitMove.splitFrom(event, splitMoveIds, /*eventId=*/43); + ASSERT_EQ(splitMove.getAction(), AMOTION_EVENT_ACTION_MOVE); + ASSERT_EQ(splitMove.getPointerCount(), 1u); + ASSERT_EQ(splitMove.getPointerId(0), 4); + ASSERT_EQ(splitMove.getX(0), 4); + ASSERT_EQ(splitMove.getY(0), 4); +} + +TEST_F(MotionEventTest, SplitPointerUp) { + MotionEvent event = MotionEventBuilder(POINTER_0_UP, AINPUT_SOURCE_TOUCHSCREEN) + .downTime(ARBITRARY_DOWN_TIME) + .pointer(PointerBuilder(/*id=*/4, ToolType::FINGER).x(4).y(4)) + .pointer(PointerBuilder(/*id=*/6, ToolType::FINGER).x(6).y(6)) + .pointer(PointerBuilder(/*id=*/8, ToolType::FINGER).x(8).y(8)) + .build(); + + MotionEvent splitUp; + std::bitset<MAX_POINTER_ID + 1> splitUpIds{}; + splitUpIds.set(4, true); + splitUp.splitFrom(event, splitUpIds, /*eventId=*/42); + ASSERT_EQ(splitUp.getAction(), AMOTION_EVENT_ACTION_UP); + ASSERT_EQ(splitUp.getPointerCount(), 1u); + ASSERT_EQ(splitUp.getPointerId(0), 4); + ASSERT_EQ(splitUp.getX(0), 4); + ASSERT_EQ(splitUp.getY(0), 4); + + MotionEvent splitPointerUp; + std::bitset<MAX_POINTER_ID + 1> splitPointerUpIds{}; + splitPointerUpIds.set(4, true); + splitPointerUpIds.set(8, true); + splitPointerUp.splitFrom(event, splitPointerUpIds, /*eventId=*/42); + ASSERT_EQ(splitPointerUp.getAction(), POINTER_0_UP); + ASSERT_EQ(splitPointerUp.getPointerCount(), 2u); + ASSERT_EQ(splitPointerUp.getPointerId(0), 4); + ASSERT_EQ(splitPointerUp.getX(0), 4); + ASSERT_EQ(splitPointerUp.getY(0), 4); + ASSERT_EQ(splitPointerUp.getPointerId(1), 8); + ASSERT_EQ(splitPointerUp.getX(1), 8); + ASSERT_EQ(splitPointerUp.getY(1), 8); + + MotionEvent splitMove; + std::bitset<MAX_POINTER_ID + 1> splitMoveIds{}; + splitMoveIds.set(6, true); + splitMoveIds.set(8, true); + splitMove.splitFrom(event, splitMoveIds, /*eventId=*/43); + ASSERT_EQ(splitMove.getAction(), AMOTION_EVENT_ACTION_MOVE); + ASSERT_EQ(splitMove.getPointerCount(), 2u); + ASSERT_EQ(splitMove.getPointerId(0), 6); + ASSERT_EQ(splitMove.getX(0), 6); + ASSERT_EQ(splitMove.getY(0), 6); + ASSERT_EQ(splitMove.getPointerId(1), 8); + ASSERT_EQ(splitMove.getX(1), 8); + ASSERT_EQ(splitMove.getY(1), 8); +} + +TEST_F(MotionEventTest, SplitPointerUpCancel) { + MotionEvent event = MotionEventBuilder(POINTER_1_UP, AINPUT_SOURCE_TOUCHSCREEN) + .downTime(ARBITRARY_DOWN_TIME) + .pointer(PointerBuilder(/*id=*/4, ToolType::FINGER).x(4).y(4)) + .pointer(PointerBuilder(/*id=*/6, ToolType::FINGER).x(6).y(6)) + .pointer(PointerBuilder(/*id=*/8, ToolType::FINGER).x(8).y(8)) + .addFlag(AMOTION_EVENT_FLAG_CANCELED) + .build(); + + MotionEvent splitUp; + std::bitset<MAX_POINTER_ID + 1> splitUpIds{}; + splitUpIds.set(6, true); + splitUp.splitFrom(event, splitUpIds, /*eventId=*/42); + ASSERT_EQ(splitUp.getAction(), AMOTION_EVENT_ACTION_CANCEL); + ASSERT_EQ(splitUp.getPointerCount(), 1u); + ASSERT_EQ(splitUp.getPointerId(0), 6); + ASSERT_EQ(splitUp.getX(0), 6); + ASSERT_EQ(splitUp.getY(0), 6); +} + +TEST_F(MotionEventTest, SplitPointerMove) { + MotionEvent event = MotionEventBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN) + .downTime(ARBITRARY_DOWN_TIME) + .pointer(PointerBuilder(/*id=*/4, ToolType::FINGER).x(4).y(4)) + .pointer(PointerBuilder(/*id=*/6, ToolType::FINGER).x(6).y(6)) + .pointer(PointerBuilder(/*id=*/8, ToolType::FINGER).x(8).y(8)) + .transform(ui::Transform(ui::Transform::ROT_90, 100, 100)) + .rawTransform(ui::Transform(ui::Transform::FLIP_H, 50, 50)) + .build(); + + MotionEvent splitMove; + std::bitset<MAX_POINTER_ID + 1> splitMoveIds{}; + splitMoveIds.set(4, true); + splitMoveIds.set(8, true); + splitMove.splitFrom(event, splitMoveIds, /*eventId=*/42); + ASSERT_EQ(splitMove.getAction(), AMOTION_EVENT_ACTION_MOVE); + ASSERT_EQ(splitMove.getPointerCount(), 2u); + ASSERT_EQ(splitMove.getPointerId(0), 4); + ASSERT_EQ(splitMove.getX(0), event.getX(0)); + ASSERT_EQ(splitMove.getY(0), event.getY(0)); + ASSERT_EQ(splitMove.getRawX(0), event.getRawX(0)); + ASSERT_EQ(splitMove.getRawY(0), event.getRawY(0)); + ASSERT_EQ(splitMove.getPointerId(1), 8); + ASSERT_EQ(splitMove.getX(1), event.getX(2)); + ASSERT_EQ(splitMove.getY(1), event.getY(2)); + ASSERT_EQ(splitMove.getRawX(1), event.getRawX(2)); + ASSERT_EQ(splitMove.getRawY(1), event.getRawY(2)); +} + TEST_F(MotionEventTest, OffsetLocation) { MotionEvent event; initializeEventWithHistory(&event); diff --git a/libs/nativedisplay/Android.bp b/libs/nativedisplay/Android.bp index 342f5de337..03f4f399d0 100644 --- a/libs/nativedisplay/Android.bp +++ b/libs/nativedisplay/Android.bp @@ -16,6 +16,7 @@ package { default_applicable_licenses: [ "frameworks_native_libs_nativedisplay_license", ], + default_team: "trendy_team_android_core_graphics_stack", } // Added automatically by a large-scale-change @@ -33,7 +34,13 @@ license { cc_library_headers { name: "libnativedisplay_headers", + host_supported: true, export_include_dirs: ["include"], + target: { + windows: { + enabled: true, + }, + }, } cc_library_shared { diff --git a/libs/nativewindow/Android.bp b/libs/nativewindow/Android.bp index bc0bfc52d5..855807472e 100644 --- a/libs/nativewindow/Android.bp +++ b/libs/nativewindow/Android.bp @@ -16,6 +16,7 @@ package { default_applicable_licenses: [ "frameworks_native_libs_nativewindow_license", ], + default_team: "trendy_team_android_core_graphics_stack", } // Added automatically by a large-scale-change @@ -53,6 +54,11 @@ cc_library_headers { "test_com.android.media.swcodec", ], host_supported: true, + target: { + windows: { + enabled: true, + }, + }, } ndk_library { diff --git a/libs/nativewindow/include/android/hardware_buffer.h b/libs/nativewindow/include/android/hardware_buffer.h index e0e30c3283..6fcb3a4842 100644 --- a/libs/nativewindow/include/android/hardware_buffer.h +++ b/libs/nativewindow/include/android/hardware_buffer.h @@ -52,6 +52,10 @@ #include <inttypes.h> #include <sys/cdefs.h> +#if !defined(__INTRODUCED_IN) +#define __INTRODUCED_IN(__api_level) /* nothing */ +#endif + __BEGIN_DECLS // clang-format off diff --git a/libs/nativewindow/include/vndk/hardware_buffer.h b/libs/nativewindow/include/vndk/hardware_buffer.h index bcfae10201..48fb02f69d 100644 --- a/libs/nativewindow/include/vndk/hardware_buffer.h +++ b/libs/nativewindow/include/vndk/hardware_buffer.h @@ -107,7 +107,7 @@ enum { }; /** - * Additional options for AHardwareBuffer_allocate2. These correspond to + * Additional options for AHardwareBuffer_allocateWithOptions. These correspond to * android.hardware.graphics.common.ExtendableType */ typedef struct { diff --git a/libs/nativewindow/rust/Android.bp b/libs/nativewindow/rust/Android.bp index 90d0a8e400..a3df4820ba 100644 --- a/libs/nativewindow/rust/Android.bp +++ b/libs/nativewindow/rust/Android.bp @@ -16,6 +16,7 @@ package { default_applicable_licenses: [ "frameworks_native_libs_nativewindow_license", ], + default_team: "trendy_team_android_core_graphics_stack", } rust_bindgen { diff --git a/libs/nativewindow/tests/Android.bp b/libs/nativewindow/tests/Android.bp index d7c7eb3153..a4ebcaca0e 100644 --- a/libs/nativewindow/tests/Android.bp +++ b/libs/nativewindow/tests/Android.bp @@ -23,6 +23,7 @@ package { default_applicable_licenses: [ "frameworks_native_libs_nativewindow_license", ], + default_team: "trendy_team_android_core_graphics_stack", } cc_test { diff --git a/libs/nativewindow/tests/benchmark/Android.bp b/libs/nativewindow/tests/benchmark/Android.bp index 6f844cf864..b815d80142 100644 --- a/libs/nativewindow/tests/benchmark/Android.bp +++ b/libs/nativewindow/tests/benchmark/Android.bp @@ -12,6 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. +package { + default_applicable_licenses: ["frameworks_native_license"], + default_team: "trendy_team_android_core_graphics_stack", +} + cc_defaults { name: "nativewindow_benchmark_defaults_cc", shared_libs: ["libnativewindow"], diff --git a/libs/renderengine/Android.bp b/libs/renderengine/Android.bp index fd45840cf8..b501d40f26 100644 --- a/libs/renderengine/Android.bp +++ b/libs/renderengine/Android.bp @@ -5,6 +5,7 @@ package { // to get the below license kinds: // SPDX-license-identifier-Apache-2.0 default_applicable_licenses: ["frameworks_native_license"], + default_team: "trendy_team_android_core_graphics_stack", } cc_defaults { diff --git a/libs/renderengine/benchmark/Android.bp b/libs/renderengine/benchmark/Android.bp index 87e21c2d70..e1a6f6af0d 100644 --- a/libs/renderengine/benchmark/Android.bp +++ b/libs/renderengine/benchmark/Android.bp @@ -19,6 +19,7 @@ package { // to get the below license kinds: // SPDX-license-identifier-Apache-2.0 default_applicable_licenses: ["frameworks_native_license"], + default_team: "trendy_team_android_core_graphics_stack", } cc_benchmark { diff --git a/libs/renderengine/include/renderengine/RenderEngine.h b/libs/renderengine/include/renderengine/RenderEngine.h index 7047358e62..de05268a67 100644 --- a/libs/renderengine/include/renderengine/RenderEngine.h +++ b/libs/renderengine/include/renderengine/RenderEngine.h @@ -104,6 +104,8 @@ public: static std::unique_ptr<RenderEngine> create(const RenderEngineCreationArgs& args); + static bool canSupport(GraphicsApi); + virtual ~RenderEngine() = 0; // ----- BEGIN DEPRECATED INTERFACE ----- diff --git a/libs/renderengine/skia/SkiaVkRenderEngine.cpp b/libs/renderengine/skia/SkiaVkRenderEngine.cpp index bff12ce7ff..eb7a9d5bfa 100644 --- a/libs/renderengine/skia/SkiaVkRenderEngine.cpp +++ b/libs/renderengine/skia/SkiaVkRenderEngine.cpp @@ -287,6 +287,7 @@ static GrVkGetProc sGetProc = [](const char* proc_name, VkInstance instance, VkD CHECK_NONNULL(vk##F) VulkanInterface initVulkanInterface(bool protectedContent = false) { + const nsecs_t timeBefore = systemTime(); VulkanInterface interface; VK_GET_PROC(EnumerateInstanceVersion); @@ -377,6 +378,11 @@ VulkanInterface initVulkanInterface(bool protectedContent = false) { BAIL("Could not find a Vulkan 1.1+ physical device"); } + if (physDevProps.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU) { + // TODO: b/326633110 - SkiaVK is not working correctly on swiftshader path. + BAIL("CPU implementations of Vulkan is not supported"); + } + // Check for syncfd support. Bail if we cannot both import and export them. VkPhysicalDeviceExternalSemaphoreInfo semInfo = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO, @@ -598,7 +604,9 @@ VulkanInterface initVulkanInterface(bool protectedContent = false) { interface.isProtected = protectedContent; // funcs already initialized - ALOGD("%s: Success init Vulkan interface", __func__); + const nsecs_t timeAfter = systemTime(); + const float initTimeMs = static_cast<float>(timeAfter - timeBefore) / 1.0E6; + ALOGD("%s: Success init Vulkan interface in %f ms", __func__, initTimeMs); return interface; } @@ -654,17 +662,25 @@ static void sSetupVulkanInterface() { } } +bool RenderEngine::canSupport(GraphicsApi graphicsApi) { + switch (graphicsApi) { + case GraphicsApi::GL: + return true; + case GraphicsApi::VK: { + if (!sVulkanInterface.initialized) { + sVulkanInterface = initVulkanInterface(false /* no protected content */); + ALOGD("%s: initialized == %s.", __func__, + sVulkanInterface.initialized ? "true" : "false"); + } + return sVulkanInterface.initialized; + } + } +} + namespace skia { using base::StringAppendF; -bool SkiaVkRenderEngine::canSupportSkiaVkRenderEngine() { - VulkanInterface temp = initVulkanInterface(false /* no protected content */); - ALOGD("SkiaVkRenderEngine::canSupportSkiaVkRenderEngine(): initialized == %s.", - temp.initialized ? "true" : "false"); - return temp.initialized; -} - std::unique_ptr<SkiaVkRenderEngine> SkiaVkRenderEngine::create( const RenderEngineCreationArgs& args) { std::unique_ptr<SkiaVkRenderEngine> engine(new SkiaVkRenderEngine(args)); diff --git a/libs/renderengine/skia/SkiaVkRenderEngine.h b/libs/renderengine/skia/SkiaVkRenderEngine.h index 2e0cf45220..52bc500a5a 100644 --- a/libs/renderengine/skia/SkiaVkRenderEngine.h +++ b/libs/renderengine/skia/SkiaVkRenderEngine.h @@ -27,8 +27,6 @@ namespace skia { class SkiaVkRenderEngine : public SkiaRenderEngine { public: - // Returns false if Vulkan implementation can't support SkiaVkRenderEngine. - static bool canSupportSkiaVkRenderEngine(); static std::unique_ptr<SkiaVkRenderEngine> create(const RenderEngineCreationArgs& args); ~SkiaVkRenderEngine() override; diff --git a/libs/renderengine/tests/Android.bp b/libs/renderengine/tests/Android.bp index 473e1d46b8..0eea187407 100644 --- a/libs/renderengine/tests/Android.bp +++ b/libs/renderengine/tests/Android.bp @@ -19,6 +19,7 @@ package { // to get the below license kinds: // SPDX-license-identifier-Apache-2.0 default_applicable_licenses: ["frameworks_native_license"], + default_team: "trendy_team_android_core_graphics_stack", } cc_test { diff --git a/libs/renderengine/tests/RenderEngineTest.cpp b/libs/renderengine/tests/RenderEngineTest.cpp index 4c18704f52..7b8eb8470f 100644 --- a/libs/renderengine/tests/RenderEngineTest.cpp +++ b/libs/renderengine/tests/RenderEngineTest.cpp @@ -107,7 +107,7 @@ public: virtual std::string name() = 0; virtual renderengine::RenderEngine::GraphicsApi graphicsApi() = 0; - virtual bool apiSupported() = 0; + bool apiSupported() { return renderengine::RenderEngine::canSupport(graphicsApi()); } std::unique_ptr<renderengine::RenderEngine> createRenderEngine() { renderengine::RenderEngineCreationArgs reCreationArgs = renderengine::RenderEngineCreationArgs::Builder() @@ -131,10 +131,6 @@ public: renderengine::RenderEngine::GraphicsApi graphicsApi() override { return renderengine::RenderEngine::GraphicsApi::VK; } - - bool apiSupported() override { - return skia::SkiaVkRenderEngine::canSupportSkiaVkRenderEngine(); - } }; class SkiaGLESRenderEngineFactory : public RenderEngineFactory { @@ -144,8 +140,6 @@ public: renderengine::RenderEngine::GraphicsApi graphicsApi() { return renderengine::RenderEngine::GraphicsApi::GL; } - - bool apiSupported() override { return true; } }; class RenderEngineTest : public ::testing::TestWithParam<std::shared_ptr<RenderEngineFactory>> { diff --git a/libs/sensorprivacy/Android.bp b/libs/sensorprivacy/Android.bp index 1e7e70775a..00514c4417 100644 --- a/libs/sensorprivacy/Android.bp +++ b/libs/sensorprivacy/Android.bp @@ -57,7 +57,6 @@ cc_library_shared { filegroup { name: "libsensorprivacy_aidl", srcs: [ - "aidl/android/hardware/CameraPrivacyAllowlistEntry.aidl", "aidl/android/hardware/ISensorPrivacyListener.aidl", "aidl/android/hardware/ISensorPrivacyManager.aidl", ], diff --git a/libs/sensorprivacy/SensorPrivacyManager.cpp b/libs/sensorprivacy/SensorPrivacyManager.cpp index fe9378616d..3f3ad9343c 100644 --- a/libs/sensorprivacy/SensorPrivacyManager.cpp +++ b/libs/sensorprivacy/SensorPrivacyManager.cpp @@ -155,10 +155,9 @@ int SensorPrivacyManager::getToggleSensorPrivacyState(int toggleType, int sensor return DISABLED; } -std::vector<hardware::CameraPrivacyAllowlistEntry> - SensorPrivacyManager::getCameraPrivacyAllowlist(){ +std::vector<String16> SensorPrivacyManager::getCameraPrivacyAllowlist(){ sp<hardware::ISensorPrivacyManager> service = getService(); - std::vector<hardware::CameraPrivacyAllowlistEntry> result; + std::vector<String16> result; if (service != nullptr) { service->getCameraPrivacyAllowlist(&result); return result; diff --git a/libs/sensorprivacy/aidl/android/hardware/ISensorPrivacyManager.aidl b/libs/sensorprivacy/aidl/android/hardware/ISensorPrivacyManager.aidl index b6bd39e557..f7071872bf 100644 --- a/libs/sensorprivacy/aidl/android/hardware/ISensorPrivacyManager.aidl +++ b/libs/sensorprivacy/aidl/android/hardware/ISensorPrivacyManager.aidl @@ -16,7 +16,6 @@ package android.hardware; -import android.hardware.CameraPrivacyAllowlistEntry; import android.hardware.ISensorPrivacyListener; /** @hide */ @@ -43,7 +42,7 @@ interface ISensorPrivacyManager { void setToggleSensorPrivacyForProfileGroup(int userId, int source, int sensor, boolean enable); - List<CameraPrivacyAllowlistEntry> getCameraPrivacyAllowlist(); + List<String> getCameraPrivacyAllowlist(); int getToggleSensorPrivacyState(int toggleType, int sensor); diff --git a/libs/sensorprivacy/include/sensorprivacy/SensorPrivacyManager.h b/libs/sensorprivacy/include/sensorprivacy/SensorPrivacyManager.h index 9e97e166be..8935b76adc 100644 --- a/libs/sensorprivacy/include/sensorprivacy/SensorPrivacyManager.h +++ b/libs/sensorprivacy/include/sensorprivacy/SensorPrivacyManager.h @@ -45,9 +45,7 @@ public: enum { ENABLED = 1, DISABLED = 2, - AUTOMOTIVE_DRIVER_ASSISTANCE_HELPFUL_APPS = 3, - AUTOMOTIVE_DRIVER_ASSISTANCE_REQUIRED_APPS = 4, - AUTOMOTIVE_DRIVER_ASSISTANCE_APPS = 5 + ENABLED_EXCEPT_ALLOWLISTED_APPS = 3 }; SensorPrivacyManager(); @@ -62,7 +60,7 @@ public: bool isToggleSensorPrivacyEnabled(int toggleType, int sensor); status_t isToggleSensorPrivacyEnabled(int toggleType, int sensor, bool &result); int getToggleSensorPrivacyState(int toggleType, int sensor); - std::vector<hardware::CameraPrivacyAllowlistEntry> getCameraPrivacyAllowlist(); + std::vector<String16> getCameraPrivacyAllowlist(); bool isCameraPrivacyEnabled(String16 packageName); status_t linkToDeath(const sp<IBinder::DeathRecipient>& recipient); diff --git a/libs/shaders/Android.bp b/libs/shaders/Android.bp index 960f845488..82fbfda0da 100644 --- a/libs/shaders/Android.bp +++ b/libs/shaders/Android.bp @@ -19,6 +19,7 @@ package { // to get the below license kinds: // SPDX-license-identifier-Apache-2.0 default_applicable_licenses: ["frameworks_native_license"], + default_team: "trendy_team_android_core_graphics_stack", } cc_library_static { diff --git a/libs/shaders/tests/Android.bp b/libs/shaders/tests/Android.bp index 5639d744df..2103679efe 100644 --- a/libs/shaders/tests/Android.bp +++ b/libs/shaders/tests/Android.bp @@ -19,6 +19,7 @@ package { // to get the below license kinds: // SPDX-license-identifier-Apache-2.0 default_applicable_licenses: ["frameworks_native_license"], + default_team: "trendy_team_android_core_graphics_stack", } cc_test { diff --git a/libs/tonemap/Android.bp b/libs/tonemap/Android.bp index 8c8815d0e4..d569ac3ba6 100644 --- a/libs/tonemap/Android.bp +++ b/libs/tonemap/Android.bp @@ -19,6 +19,7 @@ package { // to get the below license kinds: // SPDX-license-identifier-Apache-2.0 default_applicable_licenses: ["frameworks_native_license"], + default_team: "trendy_team_android_core_graphics_stack", } cc_library_static { diff --git a/libs/tonemap/tests/Android.bp b/libs/tonemap/tests/Android.bp index 5c5fc6c8b3..79ee7c2de9 100644 --- a/libs/tonemap/tests/Android.bp +++ b/libs/tonemap/tests/Android.bp @@ -19,6 +19,7 @@ package { // to get the below license kinds: // SPDX-license-identifier-Apache-2.0 default_applicable_licenses: ["frameworks_native_license"], + default_team: "trendy_team_android_core_graphics_stack", } cc_test { diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp index ec0ab4e464..9cb298a132 100644 --- a/libs/ui/Android.bp +++ b/libs/ui/Android.bp @@ -14,6 +14,7 @@ package { default_applicable_licenses: ["frameworks_native_libs_ui_license"], + default_team: "trendy_team_android_core_graphics_stack", } // Added automatically by a large-scale-change diff --git a/libs/ui/DisplayIdentification.cpp b/libs/ui/DisplayIdentification.cpp index a45ffe1a19..82e5427317 100644 --- a/libs/ui/DisplayIdentification.cpp +++ b/libs/ui/DisplayIdentification.cpp @@ -47,6 +47,7 @@ uint64_t shiftMix(uint64_t val) { return val ^ (val >> 47); } +__attribute__((no_sanitize("unsigned-integer-overflow"))) uint64_t hash64Len16(uint64_t u, uint64_t v) { constexpr uint64_t kMul = 0x9ddfea08eb382d69; uint64_t a = (u ^ v) * kMul; @@ -57,6 +58,7 @@ uint64_t hash64Len16(uint64_t u, uint64_t v) { return b; } +__attribute__((no_sanitize("unsigned-integer-overflow"))) uint64_t hash64Len0To16(const char* s, uint64_t len) { constexpr uint64_t k2 = 0x9ae16a3b2f90404f; constexpr uint64_t k3 = 0xc949d7c7509e6557; @@ -401,4 +403,4 @@ uint64_t cityHash64Len0To16(std::string_view sv) { return hash64Len0To16(sv.data(), len); } -} // namespace android
\ No newline at end of file +} // namespace android diff --git a/libs/ui/Gralloc4.cpp b/libs/ui/Gralloc4.cpp index d6970e0477..2a607308d1 100644 --- a/libs/ui/Gralloc4.cpp +++ b/libs/ui/Gralloc4.cpp @@ -262,37 +262,8 @@ void Gralloc4Mapper::getTransportSize(buffer_handle_t bufferHandle, uint32_t* ou status_t Gralloc4Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds, int acquireFence, void** outData, int32_t* outBytesPerPixel, int32_t* outBytesPerStride) const { - std::vector<ui::PlaneLayout> planeLayouts; - status_t err = getPlaneLayouts(bufferHandle, &planeLayouts); - - if (err == NO_ERROR && !planeLayouts.empty()) { - if (outBytesPerPixel) { - int32_t bitsPerPixel = planeLayouts.front().sampleIncrementInBits; - for (const auto& planeLayout : planeLayouts) { - if (bitsPerPixel != planeLayout.sampleIncrementInBits) { - bitsPerPixel = -1; - } - } - if (bitsPerPixel >= 0 && bitsPerPixel % 8 == 0) { - *outBytesPerPixel = bitsPerPixel / 8; - } else { - *outBytesPerPixel = -1; - } - } - if (outBytesPerStride) { - int32_t bytesPerStride = planeLayouts.front().strideInBytes; - for (const auto& planeLayout : planeLayouts) { - if (bytesPerStride != planeLayout.strideInBytes) { - bytesPerStride = -1; - } - } - if (bytesPerStride >= 0) { - *outBytesPerStride = bytesPerStride; - } else { - *outBytesPerStride = -1; - } - } - } + if (outBytesPerPixel) *outBytesPerPixel = -1; + if (outBytesPerStride) *outBytesPerStride = -1; auto buffer = const_cast<native_handle_t*>(bufferHandle); diff --git a/libs/ui/Gralloc5.cpp b/libs/ui/Gralloc5.cpp index f217810b6a..11064ae7fc 100644 --- a/libs/ui/Gralloc5.cpp +++ b/libs/ui/Gralloc5.cpp @@ -597,37 +597,8 @@ void Gralloc5Mapper::getTransportSize(buffer_handle_t bufferHandle, uint32_t *ou status_t Gralloc5Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect &bounds, int acquireFence, void **outData, int32_t *outBytesPerPixel, int32_t *outBytesPerStride) const { - std::vector<ui::PlaneLayout> planeLayouts; - status_t err = getPlaneLayouts(bufferHandle, &planeLayouts); - - if (err == NO_ERROR && !planeLayouts.empty()) { - if (outBytesPerPixel) { - int32_t bitsPerPixel = planeLayouts.front().sampleIncrementInBits; - for (const auto &planeLayout : planeLayouts) { - if (bitsPerPixel != planeLayout.sampleIncrementInBits) { - bitsPerPixel = -1; - } - } - if (bitsPerPixel >= 0 && bitsPerPixel % 8 == 0) { - *outBytesPerPixel = bitsPerPixel / 8; - } else { - *outBytesPerPixel = -1; - } - } - if (outBytesPerStride) { - int32_t bytesPerStride = planeLayouts.front().strideInBytes; - for (const auto &planeLayout : planeLayouts) { - if (bytesPerStride != planeLayout.strideInBytes) { - bytesPerStride = -1; - } - } - if (bytesPerStride >= 0) { - *outBytesPerStride = bytesPerStride; - } else { - *outBytesPerStride = -1; - } - } - } + if (outBytesPerPixel) *outBytesPerPixel = -1; + if (outBytesPerStride) *outBytesPerStride = -1; auto status = mMapper->v5.lock(bufferHandle, usage, bounds, acquireFence, outData); diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp index c007fdb587..ffb6cdb6ef 100644 --- a/libs/ui/GraphicBuffer.cpp +++ b/libs/ui/GraphicBuffer.cpp @@ -22,7 +22,7 @@ #include <cutils/atomic.h> #include <grallocusage/GrallocUsageConversion.h> - +#include <sync/sync.h> #include <ui/GraphicBufferAllocator.h> #include <ui/GraphicBufferMapper.h> #include <utils/Trace.h> @@ -40,6 +40,38 @@ static uint64_t getUniqueId() { return id; } +static void resolveLegacyByteLayoutFromPlaneLayout(const std::vector<ui::PlaneLayout>& planeLayouts, + int32_t* outBytesPerPixel, + int32_t* outBytesPerStride) { + if (planeLayouts.empty()) return; + if (outBytesPerPixel) { + int32_t bitsPerPixel = planeLayouts.front().sampleIncrementInBits; + for (const auto& planeLayout : planeLayouts) { + if (bitsPerPixel != planeLayout.sampleIncrementInBits) { + bitsPerPixel = -1; + } + } + if (bitsPerPixel >= 0 && bitsPerPixel % 8 == 0) { + *outBytesPerPixel = bitsPerPixel / 8; + } else { + *outBytesPerPixel = -1; + } + } + if (outBytesPerStride) { + int32_t bytesPerStride = planeLayouts.front().strideInBytes; + for (const auto& planeLayout : planeLayouts) { + if (bytesPerStride != planeLayout.strideInBytes) { + bytesPerStride = -1; + } + } + if (bytesPerStride >= 0) { + *outBytesPerStride = bytesPerStride; + } else { + *outBytesPerStride = -1; + } + } +} + sp<GraphicBuffer> GraphicBuffer::from(ANativeWindowBuffer* anwb) { return static_cast<GraphicBuffer *>(anwb); } @@ -279,10 +311,7 @@ status_t GraphicBuffer::lock(uint32_t inUsage, const Rect& rect, void** vaddr, return BAD_VALUE; } - status_t res = getBufferMapper().lock(handle, inUsage, rect, vaddr, outBytesPerPixel, - outBytesPerStride); - - return res; + return lockAsync(inUsage, rect, vaddr, -1, outBytesPerPixel, outBytesPerStride); } status_t GraphicBuffer::lockYCbCr(uint32_t inUsage, android_ycbcr* ycbcr) @@ -302,14 +331,12 @@ status_t GraphicBuffer::lockYCbCr(uint32_t inUsage, const Rect& rect, width, height); return BAD_VALUE; } - status_t res = getBufferMapper().lockYCbCr(handle, inUsage, rect, ycbcr); - return res; + return lockAsyncYCbCr(inUsage, rect, ycbcr, -1); } status_t GraphicBuffer::unlock() { - status_t res = getBufferMapper().unlock(handle); - return res; + return unlockAsync(nullptr); } status_t GraphicBuffer::lockAsync(uint32_t inUsage, void** vaddr, int fenceFd, @@ -336,10 +363,49 @@ status_t GraphicBuffer::lockAsync(uint64_t inProducerUsage, uint64_t inConsumerU return BAD_VALUE; } - status_t res = getBufferMapper().lockAsync(handle, inProducerUsage, inConsumerUsage, rect, - vaddr, fenceFd, outBytesPerPixel, outBytesPerStride); + // Resolve the bpp & bps before doing a lock in case this fails we don't have to worry about + // doing an unlock + int32_t legacyBpp = -1, legacyBps = -1; + if (outBytesPerPixel || outBytesPerStride) { + const auto mapperVersion = getBufferMapperVersion(); + // For gralloc2 we need to guess at the bpp & bps + // For gralloc3 the lock() call will return it + // For gralloc4 & later the PlaneLayout metadata query is vastly superior and we + // resolve bpp & bps just for compatibility + + // TODO: See if we can't just remove gralloc2 support. + if (mapperVersion == GraphicBufferMapper::GRALLOC_2) { + legacyBpp = bytesPerPixel(format); + if (legacyBpp > 0) { + legacyBps = stride * legacyBpp; + } else { + legacyBpp = -1; + } + } else if (mapperVersion >= GraphicBufferMapper::GRALLOC_4) { + auto planeLayout = getBufferMapper().getPlaneLayouts(handle); + if (!planeLayout.has_value()) return planeLayout.asStatus(); + resolveLegacyByteLayoutFromPlaneLayout(planeLayout.value(), &legacyBpp, &legacyBps); + } + } - return res; + const uint64_t usage = static_cast<uint64_t>( + android_convertGralloc1To0Usage(inProducerUsage, inConsumerUsage)); + + auto result = getBufferMapper().lock(handle, usage, rect, base::unique_fd{fenceFd}); + + if (!result.has_value()) { + return result.error().asStatus(); + } + auto value = result.value(); + *vaddr = value.address; + + if (outBytesPerPixel) { + *outBytesPerPixel = legacyBpp != -1 ? legacyBpp : value.bytesPerPixel; + } + if (outBytesPerStride) { + *outBytesPerStride = legacyBps != -1 ? legacyBps : value.bytesPerStride; + } + return OK; } status_t GraphicBuffer::lockAsyncYCbCr(uint32_t inUsage, android_ycbcr* ycbcr, @@ -360,14 +426,18 @@ status_t GraphicBuffer::lockAsyncYCbCr(uint32_t inUsage, const Rect& rect, width, height); return BAD_VALUE; } - status_t res = getBufferMapper().lockAsyncYCbCr(handle, inUsage, rect, ycbcr, fenceFd); - return res; + auto result = getBufferMapper().lockYCbCr(handle, static_cast<int64_t>(inUsage), rect, + base::unique_fd{fenceFd}); + if (!result.has_value()) { + return result.error().asStatus(); + } + *ycbcr = result.value(); + return OK; } status_t GraphicBuffer::unlockAsync(int *fenceFd) { - status_t res = getBufferMapper().unlockAsync(handle, fenceFd); - return res; + return getBufferMapper().unlockAsync(handle, fenceFd); } status_t GraphicBuffer::isSupported(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp index 7086e0470c..b6ab2f5a47 100644 --- a/libs/ui/GraphicBufferMapper.cpp +++ b/libs/ui/GraphicBufferMapper.cpp @@ -41,9 +41,13 @@ #include <system/graphics.h> +using unique_fd = ::android::base::unique_fd; + namespace android { // --------------------------------------------------------------------------- +using LockResult = GraphicBufferMapper::LockResult; + ANDROID_SINGLETON_STATIC_INSTANCE( GraphicBufferMapper ) void GraphicBufferMapper::preloadHal() { @@ -135,63 +139,86 @@ status_t GraphicBufferMapper::freeBuffer(buffer_handle_t handle) return NO_ERROR; } -status_t GraphicBufferMapper::lock(buffer_handle_t handle, uint32_t usage, const Rect& bounds, - void** vaddr, int32_t* outBytesPerPixel, - int32_t* outBytesPerStride) { - return lockAsync(handle, usage, bounds, vaddr, -1, outBytesPerPixel, outBytesPerStride); -} - -status_t GraphicBufferMapper::lockYCbCr(buffer_handle_t handle, uint32_t usage, - const Rect& bounds, android_ycbcr *ycbcr) -{ - return lockAsyncYCbCr(handle, usage, bounds, ycbcr, -1); -} +ui::Result<LockResult> GraphicBufferMapper::lock(buffer_handle_t handle, int64_t usage, + const Rect& bounds, unique_fd&& acquireFence) { + ATRACE_CALL(); -status_t GraphicBufferMapper::unlock(buffer_handle_t handle) -{ - int32_t fenceFd = -1; - status_t error = unlockAsync(handle, &fenceFd); - if (error == NO_ERROR && fenceFd >= 0) { - sync_wait(fenceFd, -1); - close(fenceFd); + LockResult result; + status_t status = mMapper->lock(handle, usage, bounds, acquireFence.release(), &result.address, + &result.bytesPerPixel, &result.bytesPerStride); + if (status != OK) { + return base::unexpected(ui::Error::statusToCode(status)); + } else { + return result; } - return error; -} - -status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle, uint32_t usage, const Rect& bounds, - void** vaddr, int fenceFd, int32_t* outBytesPerPixel, - int32_t* outBytesPerStride) { - return lockAsync(handle, usage, usage, bounds, vaddr, fenceFd, outBytesPerPixel, - outBytesPerStride); } -status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle, uint64_t producerUsage, - uint64_t consumerUsage, const Rect& bounds, void** vaddr, - int fenceFd, int32_t* outBytesPerPixel, - int32_t* outBytesPerStride) { +ui::Result<android_ycbcr> GraphicBufferMapper::lockYCbCr(buffer_handle_t handle, int64_t usage, + const Rect& bounds, + base::unique_fd&& acquireFence) { ATRACE_CALL(); - const uint64_t usage = static_cast<uint64_t>( - android_convertGralloc1To0Usage(producerUsage, consumerUsage)); - return mMapper->lock(handle, usage, bounds, fenceFd, vaddr, outBytesPerPixel, - outBytesPerStride); + android_ycbcr result = {}; + status_t status = mMapper->lock(handle, usage, bounds, acquireFence.release(), &result); + if (status != OK) { + return base::unexpected(ui::Error::statusToCode(status)); + } else { + return result; + } } -status_t GraphicBufferMapper::lockAsyncYCbCr(buffer_handle_t handle, - uint32_t usage, const Rect& bounds, android_ycbcr *ycbcr, int fenceFd) -{ +status_t GraphicBufferMapper::unlock(buffer_handle_t handle, base::unique_fd* outFence) { ATRACE_CALL(); + int fence = mMapper->unlock(handle); + if (outFence) { + *outFence = unique_fd{fence}; + } else { + sync_wait(fence, -1); + close(fence); + } + return OK; +} - return mMapper->lock(handle, usage, bounds, fenceFd, ycbcr); +status_t GraphicBufferMapper::lock(buffer_handle_t handle, uint32_t usage, const Rect& bounds, + void** vaddr) { + auto result = lock(handle, static_cast<int64_t>(usage), bounds); + if (!result.has_value()) return result.asStatus(); + auto val = result.value(); + *vaddr = val.address; + return OK; } -status_t GraphicBufferMapper::unlockAsync(buffer_handle_t handle, int *fenceFd) -{ - ATRACE_CALL(); +status_t GraphicBufferMapper::lockYCbCr(buffer_handle_t handle, uint32_t usage, const Rect& bounds, + android_ycbcr* ycbcr) { + auto result = lockYCbCr(handle, static_cast<int64_t>(usage), bounds); + if (!result.has_value()) return result.asStatus(); + *ycbcr = result.value(); + return OK; +} + +status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle, uint32_t usage, const Rect& bounds, + void** vaddr, int fenceFd) { + auto result = lock(handle, static_cast<int64_t>(usage), bounds, unique_fd{fenceFd}); + if (!result.has_value()) return result.asStatus(); + auto val = result.value(); + *vaddr = val.address; + return OK; +} - *fenceFd = mMapper->unlock(handle); +status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle, uint64_t producerUsage, + uint64_t consumerUsage, const Rect& bounds, void** vaddr, + int fenceFd) { + return lockAsync(handle, android_convertGralloc1To0Usage(producerUsage, consumerUsage), bounds, + vaddr, fenceFd); +} - return NO_ERROR; +status_t GraphicBufferMapper::lockAsyncYCbCr(buffer_handle_t handle, uint32_t usage, + const Rect& bounds, android_ycbcr* ycbcr, + int fenceFd) { + auto result = lockYCbCr(handle, static_cast<int64_t>(usage), bounds, unique_fd{fenceFd}); + if (!result.has_value()) return result.asStatus(); + *ycbcr = result.value(); + return OK; } status_t GraphicBufferMapper::isSupported(uint32_t width, uint32_t height, @@ -287,6 +314,17 @@ status_t GraphicBufferMapper::getPlaneLayouts(buffer_handle_t bufferHandle, return mMapper->getPlaneLayouts(bufferHandle, outPlaneLayouts); } +ui::Result<std::vector<ui::PlaneLayout>> GraphicBufferMapper::getPlaneLayouts( + buffer_handle_t bufferHandle) { + std::vector<ui::PlaneLayout> temp; + status_t status = mMapper->getPlaneLayouts(bufferHandle, &temp); + if (status == OK) { + return std::move(temp); + } else { + return base::unexpected(ui::Error::statusToCode(status)); + } +} + status_t GraphicBufferMapper::getDataspace(buffer_handle_t bufferHandle, ui::Dataspace* outDataspace) { return mMapper->getDataspace(bufferHandle, outDataspace); diff --git a/libs/ui/include/ui/GraphicBufferMapper.h b/libs/ui/include/ui/GraphicBufferMapper.h index 3a5167ab25..9da1447aed 100644 --- a/libs/ui/include/ui/GraphicBufferMapper.h +++ b/libs/ui/include/ui/GraphicBufferMapper.h @@ -22,9 +22,11 @@ #include <memory> +#include <android-base/unique_fd.h> #include <ui/GraphicTypes.h> #include <ui/PixelFormat.h> #include <ui/Rect.h> +#include <ui/Result.h> #include <utils/Singleton.h> // Needed by code that still uses the GRALLOC_USAGE_* constants. @@ -38,6 +40,12 @@ namespace android { class GrallocMapper; +/** + * This class is a thin wrapper over the various gralloc HALs. It is a "raw" wrapper, having + * version-specific behaviors & features. It is not recommend for general use. It is instead + * strongly recommended to use AHardwareBuffer or ui::GraphicBuffer which will provide stronger + * API compatibility & consistency behaviors. + */ class GraphicBufferMapper : public Singleton<GraphicBufferMapper> { public: @@ -66,27 +74,50 @@ public: void getTransportSize(buffer_handle_t handle, uint32_t* outTransportNumFds, uint32_t* outTransportNumInts); - status_t lock(buffer_handle_t handle, uint32_t usage, const Rect& bounds, void** vaddr, - int32_t* outBytesPerPixel = nullptr, int32_t* outBytesPerStride = nullptr); + struct LockResult { + void* address = nullptr; + /** + * Note: bytesPerPixel is only populated if version is gralloc 3 + * Gralloc 4 & later should use instead getPlaneLayout() + */ + int32_t bytesPerPixel = -1; + /** + * Note: bytesPerPixel is only populated if version is gralloc 3 + * Gralloc 4 & later should use instead getPlaneLayout() + */ + int32_t bytesPerStride = -1; + }; + + ui::Result<LockResult> lock(buffer_handle_t handle, int64_t usage, const Rect& bounds, + base::unique_fd&& acquireFence = {}); + + ui::Result<android_ycbcr> lockYCbCr(buffer_handle_t handle, int64_t usage, const Rect& bounds, + base::unique_fd&& acquireFence = {}); + + status_t lock(buffer_handle_t handle, uint32_t usage, const Rect& bounds, void** vaddr); status_t lockYCbCr(buffer_handle_t handle, uint32_t usage, const Rect& bounds, android_ycbcr *ycbcr); - status_t unlock(buffer_handle_t handle); - status_t lockAsync(buffer_handle_t handle, uint32_t usage, const Rect& bounds, void** vaddr, - int fenceFd, int32_t* outBytesPerPixel = nullptr, - int32_t* outBytesPerStride = nullptr); + int fenceFd); status_t lockAsync(buffer_handle_t handle, uint64_t producerUsage, uint64_t consumerUsage, - const Rect& bounds, void** vaddr, int fenceFd, - int32_t* outBytesPerPixel = nullptr, int32_t* outBytesPerStride = nullptr); + const Rect& bounds, void** vaddr, int fenceFd); status_t lockAsyncYCbCr(buffer_handle_t handle, uint32_t usage, const Rect& bounds, android_ycbcr *ycbcr, int fenceFd); - status_t unlockAsync(buffer_handle_t handle, int *fenceFd); + status_t unlock(buffer_handle_t handle, base::unique_fd* outFence = nullptr); + status_t unlockAsync(buffer_handle_t handle, int* fenceFd) { + base::unique_fd temp; + status_t result = unlock(handle, fenceFd ? &temp : nullptr); + if (fenceFd) { + *fenceFd = temp.release(); + } + return result; + } status_t isSupported(uint32_t width, uint32_t height, android::PixelFormat format, uint32_t layerCount, uint64_t usage, bool* outSupported); @@ -122,6 +153,7 @@ public: status_t getChromaSiting(buffer_handle_t bufferHandle, ui::ChromaSiting* outChromaSiting); status_t getPlaneLayouts(buffer_handle_t bufferHandle, std::vector<ui::PlaneLayout>* outPlaneLayouts); + ui::Result<std::vector<ui::PlaneLayout>> getPlaneLayouts(buffer_handle_t bufferHandle); status_t getDataspace(buffer_handle_t bufferHandle, ui::Dataspace* outDataspace); status_t setDataspace(buffer_handle_t bufferHandle, ui::Dataspace dataspace); status_t getBlendMode(buffer_handle_t bufferHandle, ui::BlendMode* outBlendMode); diff --git a/libs/ui/include/ui/Result.h b/libs/ui/include/ui/Result.h new file mode 100644 index 0000000000..d73c3e23b7 --- /dev/null +++ b/libs/ui/include/ui/Result.h @@ -0,0 +1,121 @@ +/* + * Copyright 2023 The Android Open Source 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. + */ + +#pragma once + +#include <android-base/expected.h> +#include <utils/Errors.h> + +namespace android::ui { + +enum class ErrorCode : int32_t { + /** + * No error. + */ + None = 0, + /** + * Invalid BufferDescriptor. + */ + BadDescriptor = 1, + /** + * Invalid buffer handle. + */ + BadBuffer = 2, + /** + * Invalid HardwareBufferDescription. + */ + BadValue = 3, + /** + * Resource unavailable. + */ + NoResources = 5, + /** + * Permanent failure. + */ + Unsupported = 7, +}; + +class Error { +public: + Error(ErrorCode err) : mCode(err) {} + + Error(ErrorCode err, std::string&& message) : mCode(err), mMessage(std::move(message)) {} + Error(ErrorCode err, const std::string_view& message) : mCode(err), mMessage(message) {} + + static constexpr status_t codeToStatus(ErrorCode code) { + switch (code) { + case ErrorCode::None: + return OK; + case ErrorCode::BadDescriptor: + return BAD_VALUE; + case ErrorCode::BadValue: + return BAD_VALUE; + case ErrorCode::BadBuffer: + return BAD_TYPE; + case ErrorCode::NoResources: + return NO_MEMORY; + case ErrorCode::Unsupported: + return INVALID_OPERATION; + default: + return UNKNOWN_ERROR; + } + } + + static constexpr ErrorCode statusToCode(status_t status) { + switch (status) { + case OK: + return ErrorCode::None; + case BAD_VALUE: + return ErrorCode::BadValue; + case BAD_TYPE: + return ErrorCode::BadBuffer; + case NO_MEMORY: + return ErrorCode::NoResources; + case INVALID_OPERATION: + return ErrorCode::Unsupported; + default: + return ErrorCode::Unsupported; + } + } + + constexpr status_t asStatus() const { return codeToStatus(mCode); } + + ErrorCode code() const { return mCode; } + + const std::string& message() const { return mMessage; } + + bool operator==(const ErrorCode code) { return mCode == code; } + +private: + ErrorCode mCode; + std::string mMessage; +}; + +template <typename T> +class Result : public base::expected<T, Error> { +public: + using base::expected<T, Error>::expected; + + [[nodiscard]] constexpr status_t asStatus() const { + return this->has_value() ? OK : this->error().asStatus(); + } + + [[nodiscard]] constexpr ErrorCode errorCode() const { + return this->has_value() ? ErrorCode::None : this->error().code(); + } +}; + +} // namespace android::ui diff --git a/libs/ui/tests/Android.bp b/libs/ui/tests/Android.bp index 9a202150c5..2d8a1e326c 100644 --- a/libs/ui/tests/Android.bp +++ b/libs/ui/tests/Android.bp @@ -21,6 +21,7 @@ package { // to get the below license kinds: // SPDX-license-identifier-Apache-2.0 default_applicable_licenses: ["frameworks_native_libs_ui_license"], + default_team: "trendy_team_android_core_graphics_stack", } cc_test { diff --git a/libs/ui/tools/Android.bp b/libs/ui/tools/Android.bp index 5d6070cf95..cc233b917b 100644 --- a/libs/ui/tools/Android.bp +++ b/libs/ui/tools/Android.bp @@ -21,6 +21,7 @@ package { // to get the below license kinds: // SPDX-license-identifier-Apache-2.0 default_applicable_licenses: ["frameworks_native_libs_ui_license"], + default_team: "trendy_team_android_core_graphics_stack", } cc_defaults { diff --git a/libs/vibrator/ExternalVibration.cpp b/libs/vibrator/ExternalVibration.cpp index 80e911c65d..c97e496083 100644 --- a/libs/vibrator/ExternalVibration.cpp +++ b/libs/vibrator/ExternalVibration.cpp @@ -17,7 +17,7 @@ #include <vibrator/ExternalVibration.h> #include <vibrator/ExternalVibrationUtils.h> -#include <android/os/IExternalVibratorService.h> +#include <android/os/ExternalVibrationScale.h> #include <binder/Parcel.h> #include <log/log.h> #include <utils/Errors.h> @@ -65,24 +65,36 @@ inline bool ExternalVibration::operator==(const ExternalVibration& rhs) const { return mToken == rhs.mToken; } -os::HapticScale ExternalVibration::externalVibrationScaleToHapticScale(int externalVibrationScale) { - switch (externalVibrationScale) { - case IExternalVibratorService::SCALE_MUTE: - return os::HapticScale::MUTE; - case IExternalVibratorService::SCALE_VERY_LOW: - return os::HapticScale::VERY_LOW; - case IExternalVibratorService::SCALE_LOW: - return os::HapticScale::LOW; - case IExternalVibratorService::SCALE_NONE: - return os::HapticScale::NONE; - case IExternalVibratorService::SCALE_HIGH: - return os::HapticScale::HIGH; - case IExternalVibratorService::SCALE_VERY_HIGH: - return os::HapticScale::VERY_HIGH; +os::HapticScale ExternalVibration::externalVibrationScaleToHapticScale( + os::ExternalVibrationScale externalVibrationScale) { + os::HapticLevel scaleLevel = os::HapticLevel::NONE; + + switch (externalVibrationScale.scaleLevel) { + case os::ExternalVibrationScale::ScaleLevel::SCALE_MUTE: + scaleLevel = os::HapticLevel::MUTE; + break; + case os::ExternalVibrationScale::ScaleLevel::SCALE_VERY_LOW: + scaleLevel = os::HapticLevel::VERY_LOW; + break; + case os::ExternalVibrationScale::ScaleLevel::SCALE_LOW: + scaleLevel = os::HapticLevel::LOW; + break; + case os::ExternalVibrationScale::ScaleLevel::SCALE_NONE: + scaleLevel = os::HapticLevel::NONE; + break; + case os::ExternalVibrationScale::ScaleLevel::SCALE_HIGH: + scaleLevel = os::HapticLevel::HIGH; + break; + case os::ExternalVibrationScale::ScaleLevel::SCALE_VERY_HIGH: + scaleLevel = os::HapticLevel::VERY_HIGH; + break; default: - ALOGE("Unknown ExternalVibrationScale %d, not applying scaling", externalVibrationScale); - return os::HapticScale::NONE; - } + ALOGE("Unknown ExternalVibrationScale %d, not applying scaling", + externalVibrationScale.scaleLevel); + } + + return {/*level=*/scaleLevel, /*adaptiveScaleFactor=*/ + externalVibrationScale.adaptiveHapticsScale}; } } // namespace os diff --git a/libs/vibrator/ExternalVibrationUtils.cpp b/libs/vibrator/ExternalVibrationUtils.cpp index 980b08ba36..761ac1bf3b 100644 --- a/libs/vibrator/ExternalVibrationUtils.cpp +++ b/libs/vibrator/ExternalVibrationUtils.cpp @@ -26,30 +26,30 @@ static constexpr float HAPTIC_SCALE_VERY_LOW_RATIO = 2.0f / 3.0f; static constexpr float HAPTIC_SCALE_LOW_RATIO = 3.0f / 4.0f; static constexpr float HAPTIC_MAX_AMPLITUDE_FLOAT = 1.0f; -float getHapticScaleGamma(HapticScale scale) { - switch (scale) { - case HapticScale::VERY_LOW: +float getHapticScaleGamma(HapticLevel level) { + switch (level) { + case HapticLevel::VERY_LOW: return 2.0f; - case HapticScale::LOW: + case HapticLevel::LOW: return 1.5f; - case HapticScale::HIGH: + case HapticLevel::HIGH: return 0.5f; - case HapticScale::VERY_HIGH: + case HapticLevel::VERY_HIGH: return 0.25f; default: return 1.0f; } } -float getHapticMaxAmplitudeRatio(HapticScale scale) { - switch (scale) { - case HapticScale::VERY_LOW: +float getHapticMaxAmplitudeRatio(HapticLevel level) { + switch (level) { + case HapticLevel::VERY_LOW: return HAPTIC_SCALE_VERY_LOW_RATIO; - case HapticScale::LOW: + case HapticLevel::LOW: return HAPTIC_SCALE_LOW_RATIO; - case HapticScale::NONE: - case HapticScale::HIGH: - case HapticScale::VERY_HIGH: + case HapticLevel::NONE: + case HapticLevel::HIGH: + case HapticLevel::VERY_HIGH: return 1.0f; default: return 0.0f; @@ -57,19 +57,28 @@ float getHapticMaxAmplitudeRatio(HapticScale scale) { } void applyHapticScale(float* buffer, size_t length, HapticScale scale) { - if (scale == HapticScale::MUTE) { + if (scale.isScaleMute()) { memset(buffer, 0, length * sizeof(float)); return; } - if (scale == HapticScale::NONE) { + if (scale.isScaleNone()) { return; } - float gamma = getHapticScaleGamma(scale); - float maxAmplitudeRatio = getHapticMaxAmplitudeRatio(scale); + HapticLevel hapticLevel = scale.getLevel(); + float adaptiveScaleFactor = scale.getAdaptiveScaleFactor(); + float gamma = getHapticScaleGamma(hapticLevel); + float maxAmplitudeRatio = getHapticMaxAmplitudeRatio(hapticLevel); + for (size_t i = 0; i < length; i++) { - float sign = buffer[i] >= 0 ? 1.0 : -1.0; - buffer[i] = powf(fabsf(buffer[i] / HAPTIC_MAX_AMPLITUDE_FLOAT), gamma) - * maxAmplitudeRatio * HAPTIC_MAX_AMPLITUDE_FLOAT * sign; + if (hapticLevel != HapticLevel::NONE) { + float sign = buffer[i] >= 0 ? 1.0 : -1.0; + buffer[i] = powf(fabsf(buffer[i] / HAPTIC_MAX_AMPLITUDE_FLOAT), gamma) + * maxAmplitudeRatio * HAPTIC_MAX_AMPLITUDE_FLOAT * sign; + } + + if (adaptiveScaleFactor != 1.0f) { + buffer[i] *= adaptiveScaleFactor; + } } } @@ -89,13 +98,13 @@ void clipHapticData(float* buffer, size_t length, float limit) { } // namespace bool isValidHapticScale(HapticScale scale) { - switch (scale) { - case HapticScale::MUTE: - case HapticScale::VERY_LOW: - case HapticScale::LOW: - case HapticScale::NONE: - case HapticScale::HIGH: - case HapticScale::VERY_HIGH: + switch (scale.getLevel()) { + case HapticLevel::MUTE: + case HapticLevel::VERY_LOW: + case HapticLevel::LOW: + case HapticLevel::NONE: + case HapticLevel::HIGH: + case HapticLevel::VERY_HIGH: return true; } return false; diff --git a/libs/vibrator/include/vibrator/ExternalVibration.h b/libs/vibrator/include/vibrator/ExternalVibration.h index 00cd3cd256..ac2767e17e 100644 --- a/libs/vibrator/include/vibrator/ExternalVibration.h +++ b/libs/vibrator/include/vibrator/ExternalVibration.h @@ -24,6 +24,7 @@ #include <system/audio.h> #include <utils/RefBase.h> #include <vibrator/ExternalVibrationUtils.h> +#include <android/os/ExternalVibrationScale.h> namespace android { namespace os { @@ -45,10 +46,11 @@ public : audio_attributes_t getAudioAttributes() const { return mAttrs; } sp<IExternalVibrationController> getController() { return mController; } - /* Converts the scale from non-public ExternalVibrationService into the HapticScale + /* Converts the scale from non-public ExternalVibrationService into the HapticScaleLevel * used by the utils. */ - static os::HapticScale externalVibrationScaleToHapticScale(int externalVibrationScale); + static os::HapticScale externalVibrationScaleToHapticScale( + os::ExternalVibrationScale externalVibrationScale); private: int32_t mUid; diff --git a/libs/vibrator/include/vibrator/ExternalVibrationUtils.h b/libs/vibrator/include/vibrator/ExternalVibrationUtils.h index ca219d3cbf..d9a2b81ddf 100644 --- a/libs/vibrator/include/vibrator/ExternalVibrationUtils.h +++ b/libs/vibrator/include/vibrator/ExternalVibrationUtils.h @@ -19,7 +19,7 @@ namespace android::os { -enum class HapticScale { +enum class HapticLevel { MUTE = -100, VERY_LOW = -2, LOW = -1, @@ -28,10 +28,41 @@ enum class HapticScale { VERY_HIGH = 2, }; +class HapticScale { +private: +HapticLevel mLevel = HapticLevel::NONE; +float mAdaptiveScaleFactor = 1.0f; + +public: +constexpr HapticScale(HapticLevel level, float adaptiveScaleFactor) + : mLevel(level), mAdaptiveScaleFactor(adaptiveScaleFactor) {} +constexpr HapticScale(HapticLevel level) : mLevel(level) {} +constexpr HapticScale() {} + +HapticLevel getLevel() const { return mLevel; } +float getAdaptiveScaleFactor() const { return mAdaptiveScaleFactor; } + +bool operator==(const HapticScale& other) const { + return mLevel == other.mLevel && mAdaptiveScaleFactor == other.mAdaptiveScaleFactor; +} + +bool isScaleNone() const { + return mLevel == HapticLevel::NONE && mAdaptiveScaleFactor == 1.0f; +} + +bool isScaleMute() const { + return mLevel == HapticLevel::MUTE; +} + +static HapticScale mute() { + return {/*level=*/os::HapticLevel::MUTE}; +} +}; + bool isValidHapticScale(HapticScale scale); -/* Scales the haptic data in given buffer using the selected HapticScale and ensuring no absolute - * value will be larger than the absolute of given limit. +/* Scales the haptic data in given buffer using the selected HapticScaleLevel and ensuring no + * absolute value will be larger than the absolute of given limit. * The limit will be ignored if it is NaN or zero. */ void scaleHapticData(float* buffer, size_t length, HapticScale scale, float limit); |