summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-02-28 21:13:43 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-02-28 21:13:43 +0000
commitf5bbc68d5500b2ecae8ef40b7acbdb16a708a817 (patch)
tree11cc912f8b1b2778f3b8003f4698c87c13aa1e94
parentb5510935039cae5758dae532a6c8031f3124df24 (diff)
parentc2e69665235335d5964bc61b689f587193f95a05 (diff)
downloadnative-f5bbc68d5500b2ecae8ef40b7acbdb16a708a817.tar.gz
Snap for 11510257 from c2e69665235335d5964bc61b689f587193f95a05 to simpleperf-release
Change-Id: I235c6e637add785f88478c0015f41d8f955e2c4a
-rw-r--r--libs/binder/Android.bp22
-rw-r--r--libs/binder/IPCThreadState.cpp20
-rw-r--r--libs/binder/IServiceManager.cpp26
-rw-r--r--libs/binder/RecordedTransaction.cpp59
-rw-r--r--libs/binder/include/binder/IServiceManager.h2
-rw-r--r--libs/binder/include/binder/Parcel.h6
-rw-r--r--libs/binder/include/binder/RecordedTransaction.h6
-rw-r--r--libs/binder/ndk/include_platform/android/binder_manager.h14
-rw-r--r--libs/binder/ndk/libbinder_ndk.map.txt1
-rw-r--r--libs/binder/ndk/service_manager.cpp7
-rw-r--r--libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp2
-rw-r--r--libs/binder/tests/Android.bp12
-rw-r--r--libs/binder/tests/IBinderRecordReplayTest.aidl6
-rw-r--r--libs/binder/tests/binderLibTest.cpp2
-rw-r--r--libs/binder/tests/binderRecordReplayTest.cpp86
-rw-r--r--libs/binder/tests/parcel_fuzzer/Android.bp12
-rw-r--r--libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_binder.h14
-rw-r--r--libs/binder/tests/parcel_fuzzer/random_binder.cpp66
-rw-r--r--libs/binder/tests/parcel_fuzzer/random_parcel.cpp4
-rw-r--r--libs/binder/tests/parcel_fuzzer/random_parcel_seeds.cpp180
-rw-r--r--libs/gui/tests/Android.bp1
-rw-r--r--libs/gui/tests/AndroidTest.xml1
-rw-r--r--libs/input/InputDevice.cpp31
-rw-r--r--libs/ui/DisplayIdentification.cpp24
-rw-r--r--libs/ui/Gralloc5.cpp14
-rw-r--r--libs/vibrator/fuzzer/Android.bp1
-rw-r--r--libs/vr/libpdx/private/pdx/rpc/string_wrapper.h4
-rw-r--r--services/inputflinger/benchmarks/Android.bp1
-rw-r--r--services/inputflinger/tests/Android.bp1
-rw-r--r--services/inputflinger/tests/fuzzers/Android.bp1
-rw-r--r--services/vibratorservice/benchmarks/Android.bp1
-rw-r--r--services/vibratorservice/test/Android.bp1
32 files changed, 506 insertions, 122 deletions
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index ae0fb018ef..84ff9d74ef 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -320,6 +320,24 @@ cc_defaults {
"ServiceManagerHost.cpp",
],
},
+ android: {
+ shared_libs: [
+ "libapexsupport",
+ "libvndksupport",
+ ],
+ },
+ recovery: {
+ exclude_shared_libs: [
+ "libapexsupport",
+ "libvndksupport",
+ ],
+ },
+ native_bridge: {
+ exclude_shared_libs: [
+ "libapexsupport",
+ "libvndksupport",
+ ],
+ },
},
cflags: [
"-DBINDER_WITH_KERNEL_IPC",
@@ -646,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/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index fe566fccb2..39573ec54d 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -40,6 +40,11 @@
#include "ServiceManagerHost.h"
#endif
+#if defined(__ANDROID__) && !defined(__ANDROID_RECOVERY__) && !defined(__ANDROID_NATIVE_BRIDGE__)
+#include <android/apexsupport.h>
+#include <vndksupport/linker.h>
+#endif
+
#include "Static.h"
namespace android {
@@ -259,6 +264,27 @@ bool checkPermission(const String16& permission, pid_t pid, uid_t uid, bool logP
}
}
+void* openDeclaredPassthroughHal(const String16& interface, const String16& instance, int flag) {
+#if defined(__ANDROID__) && !defined(__ANDROID_RECOVERY__) && !defined(__ANDROID_NATIVE_BRIDGE__)
+ sp<IServiceManager> sm = defaultServiceManager();
+ String16 name = interface + String16("/") + instance;
+ if (!sm->isDeclared(name)) {
+ return nullptr;
+ }
+ String16 libraryName = interface + String16(".") + instance + String16(".so");
+ if (auto updatableViaApex = sm->updatableViaApex(name); updatableViaApex.has_value()) {
+ return AApexSupport_loadLibrary(String8(libraryName).c_str(),
+ String8(*updatableViaApex).c_str(), flag);
+ }
+ return android_load_sphal_library(String8(libraryName).c_str(), flag);
+#else
+ (void)interface;
+ (void)instance;
+ (void)flag;
+ return nullptr;
+#endif
+}
+
#endif //__ANDROID_VNDK__
// ----------------------------------------------------------------------
diff --git a/libs/binder/RecordedTransaction.cpp b/libs/binder/RecordedTransaction.cpp
index 525ba2e9b9..de2a69f7cf 100644
--- a/libs/binder/RecordedTransaction.cpp
+++ b/libs/binder/RecordedTransaction.cpp
@@ -114,8 +114,8 @@ static_assert(PADDING8(8) == 0);
RecordedTransaction::RecordedTransaction(RecordedTransaction&& t) noexcept {
mData = t.mData;
- mSent.setData(t.getDataParcel().data(), t.getDataParcel().dataSize());
- mReply.setData(t.getReplyParcel().data(), t.getReplyParcel().dataSize());
+ mSentDataOnly.setData(t.getDataParcel().data(), t.getDataParcel().dataSize());
+ mReplyDataOnly.setData(t.getReplyParcel().data(), t.getReplyParcel().dataSize());
}
std::optional<RecordedTransaction> RecordedTransaction::fromDetails(
@@ -136,12 +136,21 @@ std::optional<RecordedTransaction> RecordedTransaction::fromDetails(
return std::nullopt;
}
- if (t.mSent.setData(dataParcel.data(), dataParcel.dataBufferSize()) != android::NO_ERROR) {
+ if (const auto* kernelFields = dataParcel.maybeKernelFields()) {
+ for (size_t i = 0; i < kernelFields->mObjectsSize; i++) {
+ uint64_t offset = kernelFields->mObjects[i];
+ t.mData.mSentObjectData.push_back(offset);
+ }
+ }
+
+ if (t.mSentDataOnly.setData(dataParcel.data(), dataParcel.dataBufferSize()) !=
+ android::NO_ERROR) {
ALOGE("Failed to set sent parcel data.");
return std::nullopt;
}
- if (t.mReply.setData(replyParcel.data(), replyParcel.dataBufferSize()) != android::NO_ERROR) {
+ if (t.mReplyDataOnly.setData(replyParcel.data(), replyParcel.dataBufferSize()) !=
+ android::NO_ERROR) {
ALOGE("Failed to set reply parcel data.");
return std::nullopt;
}
@@ -154,6 +163,7 @@ enum {
DATA_PARCEL_CHUNK = 2,
REPLY_PARCEL_CHUNK = 3,
INTERFACE_NAME_CHUNK = 4,
+ DATA_PARCEL_OBJECT_CHUNK = 5,
END_CHUNK = 0x00ffffff,
};
@@ -265,21 +275,30 @@ std::optional<RecordedTransaction> RecordedTransaction::fromFile(const unique_fd
break;
}
case DATA_PARCEL_CHUNK: {
- if (t.mSent.setData(reinterpret_cast<const unsigned char*>(payloadMap),
- chunk.dataSize) != android::NO_ERROR) {
+ if (t.mSentDataOnly.setData(reinterpret_cast<const unsigned char*>(payloadMap),
+ chunk.dataSize) != android::NO_ERROR) {
ALOGE("Failed to set sent parcel data.");
return std::nullopt;
}
break;
}
case REPLY_PARCEL_CHUNK: {
- if (t.mReply.setData(reinterpret_cast<const unsigned char*>(payloadMap),
- chunk.dataSize) != android::NO_ERROR) {
+ if (t.mReplyDataOnly.setData(reinterpret_cast<const unsigned char*>(payloadMap),
+ chunk.dataSize) != android::NO_ERROR) {
ALOGE("Failed to set reply parcel data.");
return std::nullopt;
}
break;
}
+ case DATA_PARCEL_OBJECT_CHUNK: {
+ const uint64_t* objects = reinterpret_cast<const uint64_t*>(payloadMap);
+ size_t metaDataSize = (chunk.dataSize / sizeof(uint64_t));
+ ALOGI("Total objects found in saved parcel %zu", metaDataSize);
+ for (size_t index = 0; index < metaDataSize; ++index) {
+ t.mData.mSentObjectData.push_back(objects[index]);
+ }
+ break;
+ }
case END_CHUNK:
break;
default:
@@ -343,14 +362,26 @@ android::status_t RecordedTransaction::dumpToFile(const unique_fd& fd) const {
return UNKNOWN_ERROR;
}
- if (NO_ERROR != writeChunk(fd, DATA_PARCEL_CHUNK, mSent.dataBufferSize(), mSent.data())) {
+ if (NO_ERROR !=
+ writeChunk(fd, DATA_PARCEL_CHUNK, mSentDataOnly.dataBufferSize(), mSentDataOnly.data())) {
ALOGE("Failed to write sent Parcel to fd %d", fd.get());
return UNKNOWN_ERROR;
}
- if (NO_ERROR != writeChunk(fd, REPLY_PARCEL_CHUNK, mReply.dataBufferSize(), mReply.data())) {
+
+ if (NO_ERROR !=
+ writeChunk(fd, REPLY_PARCEL_CHUNK, mReplyDataOnly.dataBufferSize(),
+ mReplyDataOnly.data())) {
ALOGE("Failed to write reply Parcel to fd %d", fd.get());
return UNKNOWN_ERROR;
}
+
+ if (NO_ERROR !=
+ writeChunk(fd, DATA_PARCEL_OBJECT_CHUNK, mData.mSentObjectData.size() * sizeof(uint64_t),
+ reinterpret_cast<const uint8_t*>(mData.mSentObjectData.data()))) {
+ ALOGE("Failed to write sent parcel object metadata to fd %d", fd.get());
+ return UNKNOWN_ERROR;
+ }
+
if (NO_ERROR != writeChunk(fd, END_CHUNK, 0, NULL)) {
ALOGE("Failed to write end chunk to fd %d", fd.get());
return UNKNOWN_ERROR;
@@ -384,10 +415,14 @@ uint32_t RecordedTransaction::getVersion() const {
return mData.mHeader.version;
}
+const std::vector<uint64_t>& RecordedTransaction::getObjectOffsets() const {
+ return mData.mSentObjectData;
+}
+
const Parcel& RecordedTransaction::getDataParcel() const {
- return mSent;
+ return mSentDataOnly;
}
const Parcel& RecordedTransaction::getReplyParcel() const {
- return mReply;
+ return mReplyDataOnly;
}
diff --git a/libs/binder/include/binder/IServiceManager.h b/libs/binder/include/binder/IServiceManager.h
index 55167a7db0..486bdfba78 100644
--- a/libs/binder/include/binder/IServiceManager.h
+++ b/libs/binder/include/binder/IServiceManager.h
@@ -207,6 +207,8 @@ status_t getService(const String16& name, sp<INTERFACE>* outService)
return NAME_NOT_FOUND;
}
+void* openDeclaredPassthroughHal(const String16& interface, const String16& instance, int flag);
+
bool checkCallingPermission(const String16& permission);
bool checkCallingPermission(const String16& permission,
int32_t* outPid, int32_t* outUid);
diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h
index 09da6e3c4a..d7096d8a75 100644
--- a/libs/binder/include/binder/Parcel.h
+++ b/libs/binder/include/binder/Parcel.h
@@ -55,6 +55,9 @@ class String8;
class TextOutput;
namespace binder {
class Status;
+namespace debug {
+class RecordedTransaction;
+}
}
class Parcel {
@@ -1443,6 +1446,9 @@ private:
// TODO(b/202029388): Remove 'getBlobAshmemSize' once no prebuilts reference
// this
size_t getBlobAshmemSize() const;
+
+ // Needed so that we can save object metadata to the disk
+ friend class android::binder::debug::RecordedTransaction;
};
// ---------------------------------------------------------------------------
diff --git a/libs/binder/include/binder/RecordedTransaction.h b/libs/binder/include/binder/RecordedTransaction.h
index 505c1992b9..f0bee7f39e 100644
--- a/libs/binder/include/binder/RecordedTransaction.h
+++ b/libs/binder/include/binder/RecordedTransaction.h
@@ -50,6 +50,7 @@ public:
uint32_t getVersion() const;
const Parcel& getDataParcel() const;
const Parcel& getReplyParcel() const;
+ const std::vector<uint64_t>& getObjectOffsets() const;
private:
RecordedTransaction() = default;
@@ -75,10 +76,11 @@ private:
struct MovableData { // movable
TransactionHeader mHeader;
std::string mInterfaceName;
+ std::vector<uint64_t> mSentObjectData; /* Object Offsets */
};
MovableData mData;
- Parcel mSent;
- Parcel mReply;
+ Parcel mSentDataOnly;
+ Parcel mReplyDataOnly;
};
} // namespace binder::debug
diff --git a/libs/binder/ndk/include_platform/android/binder_manager.h b/libs/binder/ndk/include_platform/android/binder_manager.h
index 316a79cfee..a905dff4b1 100644
--- a/libs/binder/ndk/include_platform/android/binder_manager.h
+++ b/libs/binder/ndk/include_platform/android/binder_manager.h
@@ -243,6 +243,20 @@ void AServiceManager_getUpdatableApexName(const char* instance, void* context,
__INTRODUCED_IN(__ANDROID_API_U__);
/**
+ * Opens a declared passthrough HAL.
+ *
+ * \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)
+ // TODO(b/302113279) use __INTRODUCED_LLNDK for vendor variants
+ __INTRODUCED_IN(__ANDROID_API_V__);
+
+/**
* Prevent lazy services without client from shutting down their process
*
* This should only be used if it is every eventually set to false. If a
diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt
index 0843a8e648..de624e44f6 100644
--- a/libs/binder/ndk/libbinder_ndk.map.txt
+++ b/libs/binder/ndk/libbinder_ndk.map.txt
@@ -204,6 +204,7 @@ LIBBINDER_NDK35 { # introduced=VanillaIceCream
APersistableBundle_getDoubleVectorKeys;
APersistableBundle_getStringVectorKeys;
APersistableBundle_getPersistableBundleKeys;
+ AServiceManager_openDeclaredPassthroughHal; # systemapi llndk
};
LIBBINDER_NDK_PLATFORM {
diff --git a/libs/binder/ndk/service_manager.cpp b/libs/binder/ndk/service_manager.cpp
index 3bfdc59ec2..5529455cc6 100644
--- a/libs/binder/ndk/service_manager.cpp
+++ b/libs/binder/ndk/service_manager.cpp
@@ -200,6 +200,13 @@ void AServiceManager_getUpdatableApexName(const char* instance, void* context,
callback(String8(updatableViaApex.value()).c_str(), context);
}
}
+void* AServiceManager_openDeclaredPassthroughHal(const char* interface, const char* instance,
+ int flag) {
+ LOG_ALWAYS_FATAL_IF(interface == nullptr, "interface == nullptr");
+ LOG_ALWAYS_FATAL_IF(instance == nullptr, "instance == nullptr");
+
+ return openDeclaredPassthroughHal(String16(interface), String16(instance), flag);
+}
void AServiceManager_forceLazyServicesPersist(bool persist) {
auto serviceRegistrar = android::binder::LazyServiceRegistrar::getInstance();
serviceRegistrar.forcePersist(persist);
diff --git a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
index cab1a60370..966ec959b6 100644
--- a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
+++ b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
@@ -984,7 +984,7 @@ int main(int argc, char* argv[]) {
return generatedFlaggedService(test_flags, kBinderNdkUnitTestServiceFlagged);
}
- ABinderProcess_setThreadPoolMaxThreadCount(1); // to receive death notifications/callbacks
+ ABinderProcess_setThreadPoolMaxThreadCount(0);
ABinderProcess_startThreadPool();
return RUN_ALL_TESTS();
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index dd2be94a76..2f0987fd1a 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -69,10 +69,14 @@ cc_test {
cc_test {
name: "binderRecordReplayTest",
srcs: ["binderRecordReplayTest.cpp"],
+ cflags: [
+ "-DBINDER_WITH_KERNEL_IPC",
+ ],
shared_libs: [
"libbinder",
"libcutils",
"libutils",
+ "liblog",
],
static_libs: [
"binderRecordReplayTestIface-cpp",
@@ -96,6 +100,14 @@ aidl_interface {
enabled: true,
platform_apis: true,
},
+
+ // TODO: switch from FileDescriptor to ParcelFileDescriptor
+ ndk: {
+ enabled: false,
+ },
+ rust: {
+ enabled: false,
+ },
},
}
diff --git a/libs/binder/tests/IBinderRecordReplayTest.aidl b/libs/binder/tests/IBinderRecordReplayTest.aidl
index bd6b03c6e0..29267e91c6 100644
--- a/libs/binder/tests/IBinderRecordReplayTest.aidl
+++ b/libs/binder/tests/IBinderRecordReplayTest.aidl
@@ -69,4 +69,10 @@ interface IBinderRecordReplayTest {
void setSingleDataParcelableArray(in SingleDataParcelable[] input);
SingleDataParcelable[] getSingleDataParcelableArray();
+
+ void setBinder(in IBinder binder);
+ IBinder getBinder();
+
+ void setFileDescriptor(in FileDescriptor fd);
+ FileDescriptor getFileDescriptor();
}
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index cb1a1ee443..0ee96e7317 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -70,7 +70,7 @@ MATCHER_P(StatusEq, expected, (negation ? "not " : "") + statusToString(expected
}
static ::testing::AssertionResult IsPageAligned(void *buf) {
- if (((unsigned long)buf & ((unsigned long)PAGE_SIZE - 1)) == 0)
+ if (((unsigned long)buf & ((unsigned long)getpagesize() - 1)) == 0)
return ::testing::AssertionSuccess();
else
return ::testing::AssertionFailure() << buf << " is not page aligned";
diff --git a/libs/binder/tests/binderRecordReplayTest.cpp b/libs/binder/tests/binderRecordReplayTest.cpp
index 73c0a94ce2..b975fad2c9 100644
--- a/libs/binder/tests/binderRecordReplayTest.cpp
+++ b/libs/binder/tests/binderRecordReplayTest.cpp
@@ -24,7 +24,10 @@
#include <binder/RecordedTransaction.h>
#include <binder/unique_fd.h>
+#include <cutils/ashmem.h>
+
#include <fuzzbinder/libbinder_driver.h>
+#include <fuzzbinder/random_binder.h>
#include <fuzzer/FuzzedDataProvider.h>
#include <fuzzseeds/random_parcel_seeds.h>
@@ -37,6 +40,7 @@
using namespace android;
using android::generateSeedsFromRecording;
+using android::RandomBinder;
using android::binder::borrowed_fd;
using android::binder::Status;
using android::binder::unique_fd;
@@ -44,6 +48,7 @@ using android::binder::debug::RecordedTransaction;
using parcelables::SingleDataParcelable;
const String16 kServerName = String16("binderRecordReplay");
+extern std::string kRandomInterfaceName;
#define GENERATE_GETTER_SETTER_PRIMITIVE(name, T) \
Status set##name(T input) { \
@@ -81,6 +86,7 @@ public:
GENERATE_GETTER_SETTER(String, String16);
GENERATE_GETTER_SETTER(SingleDataParcelable, SingleDataParcelable);
+ GENERATE_GETTER_SETTER(Binder, sp<IBinder>);
GENERATE_GETTER_SETTER(BooleanArray, std::vector<bool>);
GENERATE_GETTER_SETTER(ByteArray, std::vector<uint8_t>);
@@ -91,12 +97,22 @@ public:
GENERATE_GETTER_SETTER(DoubleArray, std::vector<double>);
GENERATE_GETTER_SETTER(StringArray, std::vector<::android::String16>);
GENERATE_GETTER_SETTER(SingleDataParcelableArray, std::vector<SingleDataParcelable>);
+
+ Status setFileDescriptor(unique_fd input) {
+ mFd = std::move(unique_fd(dup(input)));
+ return Status::ok();
+ }
+
+ Status getFileDescriptor(unique_fd* output) {
+ *output = std::move(unique_fd(dup(mFd)));
+ return Status::ok();
+ }
+ unique_fd mFd;
};
std::vector<uint8_t> retrieveData(borrowed_fd fd) {
struct stat fdStat;
EXPECT_TRUE(fstat(fd.get(), &fdStat) != -1);
- EXPECT_TRUE(fdStat.st_size != 0);
std::vector<uint8_t> buffer(fdStat.st_size);
auto readResult = android::base::ReadFully(fd, buffer.data(), fdStat.st_size);
@@ -115,6 +131,7 @@ void replayFuzzService(const sp<BpBinder>& binder, const RecordedTransaction& tr
// Read the data which has been written to seed corpus
ASSERT_EQ(0, lseek(seedFd.get(), 0, SEEK_SET));
std::vector<uint8_t> seedData = retrieveData(seedFd);
+ EXPECT_TRUE(seedData.size() != 0);
// use fuzzService to replay the corpus
FuzzedDataProvider provider(seedData.data(), seedData.size());
@@ -148,7 +165,14 @@ public:
template <typename T, typename U>
void recordReplay(Status (IBinderRecordReplayTest::*set)(T), U recordedValue,
Status (IBinderRecordReplayTest::*get)(U*), U changedValue) {
- auto replayFunctions = {&replayBinder, &replayFuzzService};
+ using ReplayFunc = decltype(&replayFuzzService);
+ vector<ReplayFunc> replayFunctions = {&replayFuzzService};
+ if (!std::is_same_v<U, unique_fd> && !std::is_same_v<U, sp<IBinder>>) {
+ // Parcel retrieved from record replay doesn't have object information. use it for
+ // replaying primitive types only.
+ replayFunctions.push_back(&replayBinder);
+ }
+
for (auto replayFunc : replayFunctions) {
unique_fd fd(open("/data/local/tmp/binderRecordReplayTest.rec",
O_RDWR | O_CREAT | O_CLOEXEC, 0666));
@@ -156,7 +180,7 @@ public:
// record a transaction
mBpBinder->startRecordingBinder(fd);
- auto status = (*mInterface.*set)(recordedValue);
+ auto status = (*mInterface.*set)(std::move(recordedValue));
EXPECT_TRUE(status.isOk());
mBpBinder->stopRecordingBinder();
@@ -164,16 +188,22 @@ public:
U output;
status = (*mInterface.*get)(&output);
EXPECT_TRUE(status.isOk());
- EXPECT_EQ(output, recordedValue);
+
+ // Expect this equal only if types are primitives
+ if (!std::is_same_v<U, unique_fd> && !std::is_same_v<U, sp<IBinder>>) {
+ EXPECT_EQ(output, recordedValue);
+ }
// write over the existing state
- status = (*mInterface.*set)(changedValue);
+ status = (*mInterface.*set)(std::move(changedValue));
EXPECT_TRUE(status.isOk());
status = (*mInterface.*get)(&output);
EXPECT_TRUE(status.isOk());
- EXPECT_EQ(output, changedValue);
+ if (!std::is_same_v<U, unique_fd> && !std::is_same_v<U, sp<IBinder>>) {
+ EXPECT_EQ(output, changedValue);
+ }
// replay transaction
ASSERT_EQ(0, lseek(fd.get(), 0, SEEK_SET));
@@ -186,7 +216,23 @@ public:
status = (*mInterface.*get)(&output);
EXPECT_TRUE(status.isOk());
- EXPECT_EQ(output, recordedValue);
+
+ // FDs and binders will be replaced with random fd and random binders
+ if constexpr (std::is_same_v<U, unique_fd>) {
+ // verify that replayed fd is /dev/null. This is being replayed from random_fd.cpp
+ // and choosing /dav/null while generating seed in binder2corpus
+ std::string fdPath = "/proc/self/fd/" + std::to_string(output.get());
+ char path[PATH_MAX];
+ ASSERT_GT(readlink(fdPath.c_str(), path, sizeof(path)), 0);
+ EXPECT_EQ(strcmp("/dev/null", path), 0);
+ } else if constexpr (std::is_same_v<U, sp<IBinder>>) {
+ // This is binder is replayed from random_binder.cpp using seed data which writes
+ // this interface.
+ EXPECT_EQ(String16(kRandomInterfaceName.c_str(), kRandomInterfaceName.size()),
+ output->getInterfaceDescriptor());
+ } else {
+ ASSERT_EQ(recordedValue, output);
+ }
}
}
@@ -319,6 +365,32 @@ TEST_F(BinderRecordReplayTest, ReplaySingleDataParcelableArray) {
&IBinderRecordReplayTest::getSingleDataParcelableArray, changed);
}
+TEST_F(BinderRecordReplayTest, ReplayBinder) {
+ vector<uint8_t> data = {0x8A, 0x19, 0x0D, 0x44, 0x37, 0x0D, 0x38, 0x5E, 0x9B, 0xAA, 0xF3, 0xDA};
+ sp<IBinder> saved = new RandomBinder(String16("random_interface"), std::move(data));
+ sp<IBinder> changed = IInterface::asBinder(defaultServiceManager());
+ recordReplay(&IBinderRecordReplayTest::setBinder, saved, &IBinderRecordReplayTest::getBinder,
+ changed);
+}
+
+TEST_F(BinderRecordReplayTest, ReplayFd) {
+ // Write something to both fds we are setting
+ unique_fd saved(open("/data/local/tmp/test_fd", O_RDWR | O_CREAT | O_CLOEXEC, 0666));
+ std::string contentSaved = "This will be never read again for recorded fd!";
+ CHECK(android::base::WriteFully(saved, contentSaved.data(), contentSaved.size()))
+ << saved.get();
+
+ unique_fd changed(open("/data/local/tmp/test_des", O_RDWR | O_CREAT | O_CLOEXEC, 0666));
+ std::string contentChanged = "This will be never read again from changed fd!";
+ CHECK(android::base::WriteFully(changed, contentChanged.data(), contentChanged.size()))
+ << changed.get();
+
+ // When fds are replayed, it will be replaced by /dev/null..reading from it should yield
+ // null data
+ recordReplay(&IBinderRecordReplayTest::setFileDescriptor, std::move(unique_fd(dup(saved))),
+ &IBinderRecordReplayTest::getFileDescriptor, std::move(unique_fd(dup(changed))));
+}
+
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
diff --git a/libs/binder/tests/parcel_fuzzer/Android.bp b/libs/binder/tests/parcel_fuzzer/Android.bp
index 83db6c9b6d..fbab8f08a9 100644
--- a/libs/binder/tests/parcel_fuzzer/Android.bp
+++ b/libs/binder/tests/parcel_fuzzer/Android.bp
@@ -131,6 +131,13 @@ cc_library {
"libcutils",
"libutils",
],
+ static_libs: [
+ "libbinder_random_parcel",
+ ],
+ include_dirs: [
+ "bionic/libc/kernel/android/uapi/",
+ "bionic/libc/kernel/uapi/",
+ ],
local_include_dirs: [
"include_random_parcel_seeds",
],
@@ -140,8 +147,12 @@ cc_library {
cc_binary_host {
name: "binder2corpus",
static_libs: [
+ "libbinder_random_parcel",
"libbinder_random_parcel_seeds",
],
+ cflags: [
+ "-DBINDER_WITH_KERNEL_IPC",
+ ],
srcs: [
"binder2corpus/binder2corpus.cpp",
],
@@ -149,5 +160,6 @@ cc_binary_host {
"libbase",
"libbinder",
"libutils",
+ "libcutils",
],
}
diff --git a/libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_binder.h b/libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_binder.h
index 8fc9263b98..7a1688b7b7 100644
--- a/libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_binder.h
+++ b/libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_binder.h
@@ -16,11 +16,25 @@
#pragma once
+#include <binder/Binder.h>
#include <binder/IBinder.h>
#include <fuzzer/FuzzedDataProvider.h>
namespace android {
+class RandomBinder : public BBinder {
+public:
+ RandomBinder(const String16& descriptor, std::vector<uint8_t>&& bytes);
+ const String16& getInterfaceDescriptor() const override;
+ status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) override;
+
+private:
+ String16 mDescriptor;
+ // note may not all be used
+ std::vector<uint8_t> mBytes;
+ FuzzedDataProvider mProvider;
+};
+
// Get a random binder object for use in fuzzing.
//
// May return nullptr.
diff --git a/libs/binder/tests/parcel_fuzzer/random_binder.cpp b/libs/binder/tests/parcel_fuzzer/random_binder.cpp
index 8a1fecb212..f41c35bfbe 100644
--- a/libs/binder/tests/parcel_fuzzer/random_binder.cpp
+++ b/libs/binder/tests/parcel_fuzzer/random_binder.cpp
@@ -21,56 +21,52 @@
#include <binder/IInterface.h>
#include <binder/IServiceManager.h>
+size_t kRandomInterfaceLength = 50;
namespace android {
-class RandomBinder : public BBinder {
-public:
- RandomBinder(const String16& descriptor, std::vector<uint8_t>&& bytes)
- : mDescriptor(descriptor),
- mBytes(std::move(bytes)),
- mProvider(mBytes.data(), mBytes.size()) {}
- const String16& getInterfaceDescriptor() const override { return mDescriptor; }
+RandomBinder::RandomBinder(const String16& descriptor, std::vector<uint8_t>&& bytes)
+ : mDescriptor(descriptor),
+ mBytes(std::move(bytes)),
+ mProvider(mBytes.data(), mBytes.size()) {}
- status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) override {
- (void)code;
- (void)data;
- (void)reply;
- (void)flags; // note - for maximum coverage even ignore if oneway
+const String16& RandomBinder::getInterfaceDescriptor() const {
+ return mDescriptor;
+}
- if (mProvider.ConsumeBool()) {
- return mProvider.ConsumeIntegral<status_t>();
- }
+status_t RandomBinder::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
+ uint32_t flags) {
+ (void)code;
+ (void)data;
+ (void)reply;
+ (void)flags; // note - for maximum coverage even ignore if oneway
- if (reply == nullptr) return OK;
+ if (mProvider.ConsumeBool()) {
+ return mProvider.ConsumeIntegral<status_t>();
+ }
- // TODO: things we could do to increase state space
- // - also pull FDs and binders from 'data'
- // (optionally combine these into random parcel 'options')
- // - also pull FDs and binders from random parcel 'options'
- RandomParcelOptions options;
+ if (reply == nullptr) return OK;
- // random output
- std::vector<uint8_t> subData = mProvider.ConsumeBytes<uint8_t>(
- mProvider.ConsumeIntegralInRange<size_t>(0, mProvider.remaining_bytes()));
- fillRandomParcel(reply, FuzzedDataProvider(subData.data(), subData.size()), &options);
+ // TODO: things we could do to increase state space
+ // - also pull FDs and binders from 'data'
+ // (optionally combine these into random parcel 'options')
+ // - also pull FDs and binders from random parcel 'options'
+ RandomParcelOptions options;
- return OK;
- }
+ // random output
+ std::vector<uint8_t> subData = mProvider.ConsumeBytes<uint8_t>(
+ mProvider.ConsumeIntegralInRange<size_t>(0, mProvider.remaining_bytes()));
+ fillRandomParcel(reply, FuzzedDataProvider(subData.data(), subData.size()), &options);
-private:
- String16 mDescriptor;
-
- // note may not all be used
- std::vector<uint8_t> mBytes;
- FuzzedDataProvider mProvider;
-};
+ return OK;
+}
sp<IBinder> getRandomBinder(FuzzedDataProvider* provider) {
auto makeFunc = provider->PickValueInArray<const std::function<sp<IBinder>()>>({
[&]() {
// descriptor is the length of a class name, e.g.
// "some.package.Foo"
- std::string str = provider->ConsumeRandomLengthString(100 /*max length*/);
+ std::string str =
+ provider->ConsumeRandomLengthString(kRandomInterfaceLength /*max length*/);
// arbitrarily consume remaining data to create a binder that can return
// random results - coverage guided fuzzer should ensure all of the remaining
diff --git a/libs/binder/tests/parcel_fuzzer/random_parcel.cpp b/libs/binder/tests/parcel_fuzzer/random_parcel.cpp
index 4e58dc4899..62b84330cd 100644
--- a/libs/binder/tests/parcel_fuzzer/random_parcel.cpp
+++ b/libs/binder/tests/parcel_fuzzer/random_parcel.cpp
@@ -73,7 +73,7 @@ void fillRandomParcel(Parcel* p, FuzzedDataProvider&& provider, RandomParcelOpti
return;
}
- if (options->extraFds.size() > 0 && provider.ConsumeBool()) {
+ if (provider.ConsumeBool() && options->extraFds.size() > 0) {
const unique_fd& fd = options->extraFds.at(
provider.ConsumeIntegralInRange<size_t>(0,
options->extraFds.size() -
@@ -102,7 +102,7 @@ void fillRandomParcel(Parcel* p, FuzzedDataProvider&& provider, RandomParcelOpti
}
sp<IBinder> binder;
- if (options->extraBinders.size() > 0 && provider.ConsumeBool()) {
+ if (provider.ConsumeBool() && options->extraBinders.size() > 0) {
binder = options->extraBinders.at(
provider.ConsumeIntegralInRange<size_t>(0,
options->extraBinders
diff --git a/libs/binder/tests/parcel_fuzzer/random_parcel_seeds.cpp b/libs/binder/tests/parcel_fuzzer/random_parcel_seeds.cpp
index 7b3c80642b..fd9777a916 100644
--- a/libs/binder/tests/parcel_fuzzer/random_parcel_seeds.cpp
+++ b/libs/binder/tests/parcel_fuzzer/random_parcel_seeds.cpp
@@ -14,16 +14,26 @@
* limitations under the License.
*/
+#include <linux/android/binder.h>
+
#include <android-base/logging.h>
+#include <binder/Parcel.h>
#include <binder/RecordedTransaction.h>
#include <fuzzseeds/random_parcel_seeds.h>
+#include <stack>
+#include <string>
#include "../../file.h"
using android::binder::borrowed_fd;
using android::binder::WriteFully;
+using std::stack;
+
+extern size_t kRandomInterfaceLength;
+// Keep this in sync with max_length in random_binder.cpp while creating a RandomBinder
+std::string kRandomInterfaceName(kRandomInterfaceLength, 'i');
namespace android {
namespace impl {
@@ -66,6 +76,162 @@ void writeReversedBuffer(std::vector<uint8_t>& integralBuffer, T val) {
} // namespace impl
+struct ProviderMetadata {
+ size_t position;
+ size_t value;
+
+ ProviderMetadata() {
+ value = 0;
+ position = 0;
+ }
+};
+
+// Assuming current seed path is inside the fillRandomParcel function, start of the loop.
+void writeRandomBinder(borrowed_fd fd, vector<uint8_t>& fillParcelBuffer,
+ stack<ProviderMetadata>& remainingPositions) {
+ // Choose 2 index in array
+ size_t fillFuncIndex = 2;
+ impl::writeReversedBuffer(fillParcelBuffer, static_cast<size_t>(0), static_cast<size_t>(2),
+ fillFuncIndex);
+
+ // navigate to getRandomBinder. provide consume bool false
+ bool flag = false;
+ impl::writeReversedBuffer(fillParcelBuffer, flag);
+
+ // selecting RandomBinder, other binders in the list are not recorded as KernelObjects
+ size_t randomBinderIndex = 0;
+ impl::writeReversedBuffer(fillParcelBuffer, static_cast<size_t>(0), static_cast<size_t>(2),
+ randomBinderIndex);
+
+ // write random string of length 100 in actual buffer array.
+ CHECK(WriteFully(fd, kRandomInterfaceName.c_str(), kRandomInterfaceName.size())) << fd.get();
+
+ // These will be bytes which are used inside of RandomBinder
+ // simplest path for these bytes is going to be consume bool -> return random status
+ vector<uint8_t> randomBinderBuffer;
+
+ bool returnRandomInt = true;
+ impl::writeReversedBuffer(randomBinderBuffer, returnRandomInt);
+
+ status_t randomStatus = 0;
+ impl::writeReversedBuffer(randomBinderBuffer, randomStatus);
+
+ // write integral in range to consume bytes for random binder
+ ProviderMetadata providerData;
+ providerData.position = fillParcelBuffer.size();
+ providerData.value = randomBinderBuffer.size();
+ remainingPositions.push(providerData);
+
+ // Write to fd
+ CHECK(WriteFully(fd, randomBinderBuffer.data(), randomBinderBuffer.size())) << fd.get();
+}
+
+// Assuming current seed path is inside the fillRandomParcelFunction, start of the loop.
+void writeRandomFd(vector<uint8_t>& fillParcelBuffer) {
+ // path to random fd
+ size_t fillFuncIndex = 1;
+ impl::writeReversedBuffer(fillParcelBuffer, static_cast<size_t>(0), static_cast<size_t>(2),
+ fillFuncIndex);
+
+ bool flag = false;
+ impl::writeReversedBuffer(fillParcelBuffer, flag);
+
+ // go for /dev/null index 1
+ size_t fdIndex = 1;
+ impl::writeReversedBuffer(fillParcelBuffer, static_cast<size_t>(0), static_cast<size_t>(3),
+ fdIndex);
+}
+
+void writeParcelData(borrowed_fd fd, vector<uint8_t>& fillParcelBuffer,
+ stack<ProviderMetadata>& remainingPositions, const uint8_t* data, size_t start,
+ size_t length) {
+ // need to write parcel data till next offset with instructions to pick random bytes till offset
+ size_t fillFuncIndex = 0;
+ impl::writeReversedBuffer(fillParcelBuffer, static_cast<size_t>(0), static_cast<size_t>(2),
+ fillFuncIndex);
+
+ // provide how much bytes to read in control buffer
+ ProviderMetadata providerData;
+ providerData.position = fillParcelBuffer.size();
+ providerData.value = length;
+ remainingPositions.push(providerData);
+
+ // provide actual bytes
+ CHECK(WriteFully(fd, data + start, length)) << fd.get();
+}
+
+/**
+ * Generate sequence of copy data, write fd and write binder instructions and required data.
+ * Data which will be read using consumeBytes is written to fd directly. Data which is read in
+ * form integer is consumed from rear end FuzzedDataProvider. So insert it in fillParcelBuffer and
+ * then write to fd
+ */
+size_t regenerateParcel(borrowed_fd fd, vector<uint8_t>& fillParcelBuffer, const Parcel& p,
+ size_t dataSize, const vector<uint64_t>& objectOffsets) {
+ stack<ProviderMetadata> remainingPositions;
+ size_t copiedDataPosition = 0;
+ const uint8_t* parcelData = p.data();
+ size_t numBinders = 0;
+ size_t numFds = 0;
+
+ for (auto offset : objectOffsets) {
+ // Check what type of object is present here
+ const flat_binder_object* flatObject =
+ reinterpret_cast<const flat_binder_object*>(parcelData + offset);
+ // Copy till the object offset
+ writeParcelData(fd, fillParcelBuffer, remainingPositions, parcelData, copiedDataPosition,
+ offset - copiedDataPosition);
+ copiedDataPosition = offset;
+ if (flatObject->hdr.type == BINDER_TYPE_BINDER ||
+ flatObject->hdr.type == BINDER_TYPE_HANDLE) {
+ writeRandomBinder(fd, fillParcelBuffer, remainingPositions);
+ numBinders++;
+ // In case of binder, stability is written after the binder object.
+ // We want to move the copiedDataPosition further to account for this stability field
+ copiedDataPosition += sizeof(int32_t) + sizeof(flat_binder_object);
+ } else if (flatObject->hdr.type == BINDER_TYPE_FD) {
+ writeRandomFd(fillParcelBuffer);
+ numFds++;
+ copiedDataPosition += sizeof(flat_binder_object);
+ }
+ }
+
+ if (copiedDataPosition < dataSize) {
+ // copy remaining data from recorded parcel -> last Object to end of the data
+ writeParcelData(fd, fillParcelBuffer, remainingPositions, parcelData, copiedDataPosition,
+ dataSize - copiedDataPosition);
+ }
+
+ // We need to write bytes for selecting integer within range of 0 to provide.remaining_bytes()
+ // is called.
+ size_t totalWrittenBytes = dataSize - (sizeof(flat_binder_object) * objectOffsets.size()) -
+ (sizeof(int32_t) * numBinders) +
+ (kRandomInterfaceName.size() /*Interface String*/ + sizeof(bool) + sizeof(status_t)) *
+ numBinders;
+
+ // Code in fuzzService relies on provider.remaining_bytes() to select random bytes using
+ // consume integer. use the calculated remaining_bytes to generate byte buffer which can
+ // generate required fds and binders in fillRandomParcel function.
+ while (!remainingPositions.empty()) {
+ auto meta = remainingPositions.top();
+ remainingPositions.pop();
+ size_t remainingBytes = totalWrittenBytes + fillParcelBuffer.size() - meta.position;
+
+ vector<uint8_t> remReversedBytes;
+ impl::writeReversedBuffer(remReversedBytes, static_cast<size_t>(0), remainingBytes,
+ meta.value);
+ // Check the order of buffer which is being written
+ fillParcelBuffer.insert(fillParcelBuffer.end() - meta.position, remReversedBytes.begin(),
+ remReversedBytes.end());
+ }
+
+ return totalWrittenBytes;
+}
+
+/**
+ * Current corpus format
+ * |Reserved bytes(8)|parcel data|fillParcelBuffer|integralBuffer|
+ */
void generateSeedsFromRecording(borrowed_fd fd,
const binder::debug::RecordedTransaction& transaction) {
// Write Reserved bytes for future use
@@ -123,17 +289,9 @@ void generateSeedsFromRecording(borrowed_fd fd,
uint8_t writeHeaderInternal = 0;
impl::writeReversedBuffer(fillParcelBuffer, writeHeaderInternal);
- // Choose to write data in parcel
- size_t fillFuncIndex = 0;
- impl::writeReversedBuffer(fillParcelBuffer, static_cast<size_t>(0), static_cast<size_t>(2),
- fillFuncIndex);
-
- // Write parcel data size from recorded transaction
- size_t toWrite = transaction.getDataParcel().dataBufferSize();
- impl::writeReversedBuffer(fillParcelBuffer, static_cast<size_t>(0), toWrite, toWrite);
-
- // Write parcel data with size towrite from recorded transaction
- CHECK(WriteFully(fd, dataParcel.data(), toWrite)) << fd.get();
+ auto objectMetadata = transaction.getObjectOffsets();
+ size_t toWrite = regenerateParcel(fd, fillParcelBuffer, dataParcel, dataParcel.dataBufferSize(),
+ objectMetadata);
// Write Fill Parcel buffer size in integralBuffer so that fuzzService knows size of data
size_t subDataSize = toWrite + fillParcelBuffer.size();
diff --git a/libs/gui/tests/Android.bp b/libs/gui/tests/Android.bp
index 462ce6e14f..15e8744713 100644
--- a/libs/gui/tests/Android.bp
+++ b/libs/gui/tests/Android.bp
@@ -3,6 +3,7 @@
// Build the binary to $(TARGET_OUT_DATA_NATIVE_TESTS)/$(LOCAL_MODULE)
// to integrate with auto-test framework.
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// 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"
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/input/InputDevice.cpp b/libs/input/InputDevice.cpp
index 9c7c0c19ed..ccc83231fa 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/ui/DisplayIdentification.cpp b/libs/ui/DisplayIdentification.cpp
index 16ed82af7c..82e5427317 100644
--- a/libs/ui/DisplayIdentification.cpp
+++ b/libs/ui/DisplayIdentification.cpp
@@ -21,6 +21,7 @@
#include <cctype>
#include <numeric>
#include <optional>
+#include <span>
#include <log/log.h>
@@ -46,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;
@@ -56,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;
@@ -81,7 +84,7 @@ uint64_t hash64Len0To16(const char* s, uint64_t len) {
return k2;
}
-using byte_view = std::basic_string_view<uint8_t>;
+using byte_view = std::span<const uint8_t>;
constexpr size_t kEdidBlockSize = 128;
constexpr size_t kEdidHeaderLength = 5;
@@ -89,7 +92,8 @@ constexpr size_t kEdidHeaderLength = 5;
constexpr uint16_t kVirtualEdidManufacturerId = 0xffffu;
std::optional<uint8_t> getEdidDescriptorType(const byte_view& view) {
- if (view.size() < kEdidHeaderLength || view[0] || view[1] || view[2] || view[4]) {
+ if (static_cast<size_t>(view.size()) < kEdidHeaderLength || view[0] || view[1] || view[2] ||
+ view[4]) {
return {};
}
@@ -164,7 +168,7 @@ Cea861ExtensionBlock parseCea861Block(const byte_view& block) {
constexpr size_t kDataBlockHeaderSize = 1;
const size_t dataBlockSize = bodyLength + kDataBlockHeaderSize;
- if (block.size() < dataBlockOffset + dataBlockSize) {
+ if (static_cast<size_t>(block.size()) < dataBlockOffset + dataBlockSize) {
ALOGW("Invalid EDID: CEA 861 data block is truncated.");
break;
}
@@ -264,7 +268,7 @@ std::optional<Edid> parseEdid(const DisplayIdentificationData& edid) {
}
byte_view view(edid.data(), edid.size());
- view.remove_prefix(kDescriptorOffset);
+ view = view.subspan(kDescriptorOffset);
std::string_view displayName;
std::string_view serialNumber;
@@ -274,13 +278,13 @@ std::optional<Edid> parseEdid(const DisplayIdentificationData& edid) {
constexpr size_t kDescriptorLength = 18;
for (size_t i = 0; i < kDescriptorCount; i++) {
- if (view.size() < kDescriptorLength) {
+ if (static_cast<size_t>(view.size()) < kDescriptorLength) {
break;
}
if (const auto type = getEdidDescriptorType(view)) {
byte_view descriptor(view.data(), kDescriptorLength);
- descriptor.remove_prefix(kEdidHeaderLength);
+ descriptor = descriptor.subspan(kEdidHeaderLength);
switch (*type) {
case 0xfc:
@@ -295,7 +299,7 @@ std::optional<Edid> parseEdid(const DisplayIdentificationData& edid) {
}
}
- view.remove_prefix(kDescriptorLength);
+ view = view.subspan(kDescriptorLength);
}
std::string_view modelString = displayName;
@@ -327,8 +331,8 @@ std::optional<Edid> parseEdid(const DisplayIdentificationData& edid) {
const size_t numExtensions = edid[kNumExtensionsOffset];
view = byte_view(edid.data(), edid.size());
for (size_t blockNumber = 1; blockNumber <= numExtensions; blockNumber++) {
- view.remove_prefix(kEdidBlockSize);
- if (view.size() < kEdidBlockSize) {
+ view = view.subspan(kEdidBlockSize);
+ if (static_cast<size_t>(view.size()) < kEdidBlockSize) {
ALOGW("Invalid EDID: block %zu is truncated.", blockNumber);
break;
}
@@ -399,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/Gralloc5.cpp b/libs/ui/Gralloc5.cpp
index c3b2d3d808..123bef4a4f 100644
--- a/libs/ui/Gralloc5.cpp
+++ b/libs/ui/Gralloc5.cpp
@@ -83,10 +83,18 @@ static void *loadIMapperLibrary() {
return nullptr;
}
- std::string lib_name = "mapper." + mapperSuffix + ".so";
- void *so = android_load_sphal_library(lib_name.c_str(), RTLD_LOCAL | RTLD_NOW);
+ void* so = nullptr;
+ // TODO(b/322384429) switch this to __ANDROID_API_V__ when V is finalized
+ // TODO(b/302113279) use __ANDROID_VENDOR_API__ for vendor variant
+ if (__builtin_available(android __ANDROID_API_FUTURE__, *)) {
+ so = AServiceManager_openDeclaredPassthroughHal("mapper", mapperSuffix.c_str(),
+ RTLD_LOCAL | RTLD_NOW);
+ } else {
+ std::string lib_name = "mapper." + mapperSuffix + ".so";
+ so = android_load_sphal_library(lib_name.c_str(), RTLD_LOCAL | RTLD_NOW);
+ }
if (!so) {
- ALOGE("Failed to load %s", lib_name.c_str());
+ ALOGE("Failed to load mapper.%s.so", mapperSuffix.c_str());
}
return so;
}();
diff --git a/libs/vibrator/fuzzer/Android.bp b/libs/vibrator/fuzzer/Android.bp
index cb063af2f6..faa77ca9df 100644
--- a/libs/vibrator/fuzzer/Android.bp
+++ b/libs/vibrator/fuzzer/Android.bp
@@ -18,6 +18,7 @@
*/
package {
+ default_team: "trendy_team_haptics_framework",
// 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"
diff --git a/libs/vr/libpdx/private/pdx/rpc/string_wrapper.h b/libs/vr/libpdx/private/pdx/rpc/string_wrapper.h
index 2d0a4ea6ec..371ed89fc9 100644
--- a/libs/vr/libpdx/private/pdx/rpc/string_wrapper.h
+++ b/libs/vr/libpdx/private/pdx/rpc/string_wrapper.h
@@ -17,12 +17,12 @@ namespace rpc {
// C strings more efficient by avoiding unnecessary copies when remote method
// signatures specify std::basic_string arguments or return values.
template <typename CharT = std::string::value_type,
- typename Traits = std::char_traits<CharT>>
+ typename Traits = std::char_traits<std::remove_cv_t<CharT>>>
class StringWrapper {
public:
// Define types in the style of STL strings to support STL operators.
typedef Traits traits_type;
- typedef typename Traits::char_type value_type;
+ typedef CharT value_type;
typedef std::size_t size_type;
typedef value_type& reference;
typedef const value_type& const_reference;
diff --git a/services/inputflinger/benchmarks/Android.bp b/services/inputflinger/benchmarks/Android.bp
index 4e2a6fbf87..e5d2b705c3 100644
--- a/services/inputflinger/benchmarks/Android.bp
+++ b/services/inputflinger/benchmarks/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_input_framework",
// 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"
diff --git a/services/inputflinger/tests/Android.bp b/services/inputflinger/tests/Android.bp
index 1585fddfb3..a5564d2c7d 100644
--- a/services/inputflinger/tests/Android.bp
+++ b/services/inputflinger/tests/Android.bp
@@ -13,6 +13,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_input_framework",
// 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"
diff --git a/services/inputflinger/tests/fuzzers/Android.bp b/services/inputflinger/tests/fuzzers/Android.bp
index 47b0824fd0..59af4934fa 100644
--- a/services/inputflinger/tests/fuzzers/Android.bp
+++ b/services/inputflinger/tests/fuzzers/Android.bp
@@ -13,6 +13,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_input_framework",
// 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"
diff --git a/services/vibratorservice/benchmarks/Android.bp b/services/vibratorservice/benchmarks/Android.bp
index a468146bc0..5437995899 100644
--- a/services/vibratorservice/benchmarks/Android.bp
+++ b/services/vibratorservice/benchmarks/Android.bp
@@ -13,6 +13,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_haptics_framework",
// 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"
diff --git a/services/vibratorservice/test/Android.bp b/services/vibratorservice/test/Android.bp
index 32947246d8..be71dc2ce3 100644
--- a/services/vibratorservice/test/Android.bp
+++ b/services/vibratorservice/test/Android.bp
@@ -13,6 +13,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_haptics_framework",
// 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"