aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-02-21 00:21:30 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-02-21 00:21:30 +0000
commitb954e4cbd748da80e64bdea0dc654404d7b326d7 (patch)
treeb5e6cfe1f61f8679e3b15ff40fd8e3191dcac076
parent053b7f4247dc72e23103d3dd3fbec95fef04e5fa (diff)
parent40b07b8734e1c472db5e9ea7a43c9f0fb05bb814 (diff)
downloaddittosuite-b954e4cbd748da80e64bdea0dc654404d7b326d7.tar.gz
Snap for 11473990 from 40b07b8734e1c472db5e9ea7a43c9f0fb05bb814 to sdk-release
Change-Id: Ifb5813c7e3ba50dfefb5d9203f8475628f9a6e8f
-rw-r--r--Android.bp1
-rw-r--r--example/android/binder_gen.ditto24
-rw-r--r--include/ditto/binder_request.h18
-rw-r--r--schema/benchmark.proto37
-rw-r--r--src/binder_request.cpp133
-rw-r--r--src/instruction.cpp2
-rw-r--r--src/instruction_factory.cpp7
7 files changed, 221 insertions, 1 deletions
diff --git a/Android.bp b/Android.bp
index 1db33aa..9c99e38 100644
--- a/Android.bp
+++ b/Android.bp
@@ -29,6 +29,7 @@ cc_defaults {
],
shared_libs: [
"libbinder",
+ "libcutils",
"liblog",
"libutils",
"libprotobuf-cpp-full",
diff --git a/example/android/binder_gen.ditto b/example/android/binder_gen.ditto
new file mode 100644
index 0000000..a4b0374
--- /dev/null
+++ b/example/android/binder_gen.ditto
@@ -0,0 +1,24 @@
+main: {
+ multithreading: {
+ threads: [
+ {
+ instruction: {
+ binder_request: {
+ generic_service: {
+ name: "time_zone_detector",
+ code: 6,
+ parcel_input: [{
+ type: STRING_16,
+ data: "Asia/Calcutta"
+ }]
+ },
+ },
+ repeat: 2,
+ period_us: 1000,
+ }
+ spawn: 2,
+ }
+ ]
+ }
+},
+global {}
diff --git a/include/ditto/binder_request.h b/include/ditto/binder_request.h
index 3c856b2..3a8629e 100644
--- a/include/ditto/binder_request.h
+++ b/include/ditto/binder_request.h
@@ -72,6 +72,24 @@ class BinderRequestMountService : public BinderRequest {
void TearDownSingle(bool last) override;
};
+class GenericBinderRequest : public BinderRequest {
+ public:
+ inline static const std::string kName = "binder_request_generic";
+ explicit GenericBinderRequest(const Params& params,
+ std::string service_name, int32_t code,
+ const google::protobuf::RepeatedPtrField<dittosuiteproto::BinderRequest_GenericService_ParcelInput> parcel_input);
+
+ protected:
+ void RunSingle() override;
+ const google::protobuf::RepeatedPtrField<dittosuiteproto::BinderRequest_GenericService_ParcelInput> parcel_input_;
+ std::string service_name_;
+ int32_t code_;
+ android::sp<android::IBinder> service_;
+
+ private:
+ void SetUp() override;
+ void TearDownSingle(bool is_last) override;
+};
} // namespace dittosuite
#endif
diff --git a/schema/benchmark.proto b/schema/benchmark.proto
index 197c1d7..166b7f8 100644
--- a/schema/benchmark.proto
+++ b/schema/benchmark.proto
@@ -39,9 +39,46 @@ message BinderRequest {
enum RunningService {
MOUNT_SERVICE = 0;
};
+ message GenericService {
+ message ParcelInput {
+ enum Type {
+ // Write the 32-bit integer into the send parcel.
+ I32 = 0;
+ // Write the 64-bit integer into the send parcel.
+ I64 = 1;
+ // Write the UTF-16 string STR into the send parcel.
+ STRING_16 = 2;
+ // Write the 32-bit single-precision number into the send parcel.
+ F = 3;
+ // Write the 64-bit double-precision number into the send parcel.
+ D = 4;
+ // Write a null binder into the send parcel.
+ NULL = 5;
+ // Data: File name
+ // Write a file descriptor for the file with given path into the send
+ // parcel.
+ FD_PATH = 6;
+ // Data: FD number
+ // Write the file descriptor into the send parcel.
+ FD = 8;
+ // Data: File name
+ // Write an ashmem file descriptor for a region containing the data
+ // from file the given path into the send parcel.
+ ASHMEM_FD_PATH = 7;
+ }
+ optional Type type = 1;
+ oneof data_oneof {
+ string data = 2;
+ }
+ }
+ optional string name = 1;
+ optional int32 code = 2;
+ repeated ParcelInput parcel_input = 3;
+ }
oneof service_oneof {
string service_name = 1;
RunningService running_service = 2;
+ GenericService generic_service = 3;
}
}
diff --git a/src/binder_request.cpp b/src/binder_request.cpp
index d9a31b3..321c926 100644
--- a/src/binder_request.cpp
+++ b/src/binder_request.cpp
@@ -17,6 +17,9 @@
#include <ditto/binder.h>
#include <ditto/binder_request.h>
#include <ditto/logger.h>
+#include <cutils/ashmem.h>
+#include <sys/mman.h>
+
namespace dittosuite {
@@ -70,6 +73,136 @@ void BinderRequestMountService::TearDownSingle(bool last) {
Instruction::TearDownSingle(last);
}
+GenericBinderRequest::GenericBinderRequest(const Params& params,
+ std::string service_name, int32_t code,
+ const google::protobuf::RepeatedPtrField
+ <dittosuiteproto::BinderRequest_GenericService_ParcelInput> parcel_input)
+ : BinderRequest(kName, params, service_name), parcel_input_(parcel_input),
+ service_name_(service_name), code_(code) {}
+
+void GenericBinderRequest::SetUp() {
+ android::sp<android::IServiceManager> sm = android::defaultServiceManager();
+ service_ = sm->checkService(String16(service_name_.c_str(), service_name_.length()));
+}
+
+void GenericBinderRequest::TearDownSingle(bool last) {
+ Instruction::TearDownSingle(last);
+}
+
+int ParseAshmemWithPath(std::string path, android::Parcel& parcel) {
+ int fd = open(path.c_str(), O_RDONLY);
+ struct stat statbuf;
+ int afd = -1;
+ void* ptr = MAP_FAILED;
+ if (fd < 0) {
+ LOGF("Could not open " + path);
+ return -1;
+ }
+ if (fstat(fd, &statbuf) != 0) {
+ LOGF("Could not stat " + path);
+ goto error_close_fd;
+ }
+ afd = ashmem_create_region("ditto", statbuf.st_size);
+ if (afd < 0) {
+ LOGF("ashmem_create_region failed " + path);
+ goto error_close_fd;
+ }
+ ptr = mmap(NULL, statbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, afd, 0);
+ if (ptr == MAP_FAILED) {
+ LOGF("mmap failed " + path);
+ goto error_close_afd;
+ }
+ if (read(fd, ptr, statbuf.st_size) < 0) {
+ LOGF("read failed " + path);
+ goto error_unmap;
+ }
+ if (parcel.writeFileDescriptor(afd, true /* take ownership */) == android::OK) {
+ // successfully parsed. unmap and afd close is done by the binder server.
+ close(fd);
+ return 0;
+ }
+ LOGF("writeFileDescriptor failed " + path);
+
+error_unmap:
+ munmap(ptr, statbuf.st_size);
+error_close_afd:
+ close(afd);
+error_close_fd:
+ close(fd);
+ return -1;
+}
+
+int ParseParcelString(const google::protobuf::RepeatedPtrField
+ <dittosuiteproto::BinderRequest_GenericService_ParcelInput>& input,
+ android::Parcel& parcel) {
+ for (const auto &it : input ) {
+ std::string data_str = it.data();
+ switch (it.type()) {
+ case dittosuiteproto::BinderRequest_GenericService_ParcelInput_Type_I32: {
+ parcel.writeInt32(atoi(data_str.c_str()));
+ break;
+ }
+ case dittosuiteproto::BinderRequest_GenericService_ParcelInput_Type_I64: {
+ parcel.writeInt64(atoll(data_str.c_str()));
+ break;
+ }
+ case dittosuiteproto::BinderRequest_GenericService_ParcelInput_Type_STRING_16: {
+ parcel.writeString16(String16(data_str.c_str(), data_str.length()));
+ break;
+ }
+ case dittosuiteproto::BinderRequest_GenericService_ParcelInput_Type_F: {
+ parcel.writeFloat(atof(data_str.c_str()));
+ break;
+ }
+ case dittosuiteproto::BinderRequest_GenericService_ParcelInput_Type_D: {
+ parcel.writeDouble(atof(data_str.c_str()));
+ break;
+ }
+ case dittosuiteproto::BinderRequest_GenericService_ParcelInput_Type_NULL_: {
+ parcel.writeStrongBinder(nullptr);
+ break;
+ }
+ case dittosuiteproto::BinderRequest_GenericService_ParcelInput_Type_FD: {
+ parcel.writeFileDescriptor(atoi(data_str.c_str()), true /* take ownership */);
+ break;
+ }
+ case dittosuiteproto::BinderRequest_GenericService_ParcelInput_Type_FD_PATH: {
+ int fd = open(data_str.c_str(), O_RDONLY);
+ if (fd < 0) {
+ LOGF("Could not open " + data_str);
+ return -1;
+ }
+ parcel.writeFileDescriptor(fd, true /* take ownership */);
+ break;
+ }
+ case dittosuiteproto::BinderRequest_GenericService_ParcelInput_Type_ASHMEM_FD_PATH: {
+ if (ParseAshmemWithPath(data_str.c_str(), parcel) < 0) {
+ return -1;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ return 0;
+}
+
+void GenericBinderRequest::RunSingle() {
+ android::Parcel data, reply;
+ data.markForBinder(service_);
+ data.writeInterfaceToken(service_ ? service_->getInterfaceDescriptor() : String16());
+ if (ParseParcelString(parcel_input_, data)) {
+ LOGF("Error parsing parcel string\n");
+ return;
+ }
+
+ service_->transact(code_, data, &reply);
+
+ std::stringstream ss;
+ ss << reply;
+ LOGD("Returned from Binder transact:\n" + ss.str());
+}
} // namespace dittosuite
#endif
diff --git a/src/instruction.cpp b/src/instruction.cpp
index 41e0964..8cdd7da 100644
--- a/src/instruction.cpp
+++ b/src/instruction.cpp
@@ -65,7 +65,7 @@ void Instruction::RunSynchronized(pthread_barrier_t* barrier, const Multithreadi
std::thread Instruction::SpawnThread(pthread_barrier_t* barrier,
const MultithreadingParams& params) {
- return std::thread([=] { RunSynchronized(barrier, params); });
+ return std::thread([=, this] { RunSynchronized(barrier, params); });
}
void Instruction::TearDown() {}
diff --git a/src/instruction_factory.cpp b/src/instruction_factory.cpp
index cef9c1b..69c48d0 100644
--- a/src/instruction_factory.cpp
+++ b/src/instruction_factory.cpp
@@ -258,11 +258,17 @@ std::unique_ptr<Instruction> InstructionFactory::CreateFromProtoInstruction(
return std::make_unique<BinderRequestMountService>(instruction_params);
break;
}
+ case RequestService::kGenericService: {
+ const auto& options = proto_instruction.binder_request();
+ const auto& generic_service = options.generic_service();
+ return std::make_unique<GenericBinderRequest>(instruction_params, generic_service.name(), generic_service.code(), generic_service.parcel_input());
+ }
case RequestService::SERVICE_ONEOF_NOT_SET: {
LOGF("No service specified for BinderRequest");
break;
}
}
+ break;
}
case InstructionType::kBinderService: {
const auto& options = proto_instruction.binder_service();
@@ -295,6 +301,7 @@ std::unique_ptr<Instruction> InstructionFactory::CreateFromProtoInstruction(
}
case InstructionType::INSTRUCTION_ONEOF_NOT_SET: {
LOGF("Instruction was not set in .ditto file");
+ break;
}
default: {
LOGF("Invalid instruction was set in .ditto file");