diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2018-03-25 07:27:21 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2018-03-25 07:27:21 +0000 |
commit | 0a0b47e1e67c20f6b6d6e76a2e9abf33216446c2 (patch) | |
tree | af1e6202837e0644f9c1fd19fc468e25af6fd37a | |
parent | 8d198d61bab837521bdd93665c8c49dae93a80b2 (diff) | |
parent | b06c82923869f50e9641f7dac56df0aebe637845 (diff) | |
download | aidl-android-security-9.0.0_r70.tar.gz |
Snap for 4677756 from b06c82923869f50e9641f7dac56df0aebe637845 to pi-releaseandroid-wear-9.0.0_r9android-wear-9.0.0_r8android-wear-9.0.0_r7android-wear-9.0.0_r6android-wear-9.0.0_r5android-wear-9.0.0_r4android-wear-9.0.0_r34android-wear-9.0.0_r33android-wear-9.0.0_r32android-wear-9.0.0_r31android-wear-9.0.0_r30android-wear-9.0.0_r3android-wear-9.0.0_r29android-wear-9.0.0_r28android-wear-9.0.0_r27android-wear-9.0.0_r26android-wear-9.0.0_r25android-wear-9.0.0_r24android-wear-9.0.0_r23android-wear-9.0.0_r22android-wear-9.0.0_r21android-wear-9.0.0_r20android-wear-9.0.0_r2android-wear-9.0.0_r19android-wear-9.0.0_r18android-wear-9.0.0_r17android-wear-9.0.0_r16android-wear-9.0.0_r15android-wear-9.0.0_r14android-wear-9.0.0_r13android-wear-9.0.0_r12android-wear-9.0.0_r11android-wear-9.0.0_r10android-wear-9.0.0_r1android-vts-9.0_r9android-vts-9.0_r8android-vts-9.0_r7android-vts-9.0_r6android-vts-9.0_r5android-vts-9.0_r4android-vts-9.0_r19android-vts-9.0_r18android-vts-9.0_r17android-vts-9.0_r16android-vts-9.0_r15android-vts-9.0_r14android-vts-9.0_r13android-vts-9.0_r12android-vts-9.0_r11android-vts-9.0_r10android-security-9.0.0_r76android-security-9.0.0_r75android-security-9.0.0_r74android-security-9.0.0_r73android-security-9.0.0_r72android-security-9.0.0_r71android-security-9.0.0_r70android-security-9.0.0_r69android-security-9.0.0_r68android-security-9.0.0_r67android-security-9.0.0_r66android-security-9.0.0_r65android-security-9.0.0_r64android-security-9.0.0_r63android-security-9.0.0_r62android-cts-9.0_r9android-cts-9.0_r8android-cts-9.0_r7android-cts-9.0_r6android-cts-9.0_r5android-cts-9.0_r4android-cts-9.0_r3android-cts-9.0_r20android-cts-9.0_r2android-cts-9.0_r19android-cts-9.0_r18android-cts-9.0_r17android-cts-9.0_r16android-cts-9.0_r15android-cts-9.0_r14android-cts-9.0_r13android-cts-9.0_r12android-cts-9.0_r11android-cts-9.0_r10android-cts-9.0_r1android-9.0.0_r9android-9.0.0_r8android-9.0.0_r7android-9.0.0_r61android-9.0.0_r60android-9.0.0_r6android-9.0.0_r59android-9.0.0_r58android-9.0.0_r57android-9.0.0_r56android-9.0.0_r55android-9.0.0_r54android-9.0.0_r53android-9.0.0_r52android-9.0.0_r51android-9.0.0_r50android-9.0.0_r5android-9.0.0_r49android-9.0.0_r48android-9.0.0_r3android-9.0.0_r2android-9.0.0_r18android-9.0.0_r17android-9.0.0_r10android-9.0.0_r1security-pi-releasepie-vts-releasepie-security-releasepie-s2-releasepie-release-2pie-releasepie-r2-s2-releasepie-r2-s1-releasepie-r2-releasepie-platform-releasepie-gsipie-cuttlefish-testingpie-cts-release
Change-Id: I3e22914eee11c7539daabc36d1219bb309f546dd
-rw-r--r-- | aidl.cpp | 5 | ||||
-rw-r--r-- | aidl.h | 1 | ||||
-rw-r--r-- | aidl_language.h | 9 | ||||
-rw-r--r-- | aidl_unittest.cpp | 1 | ||||
-rw-r--r-- | generate_cpp.cpp | 30 | ||||
-rw-r--r-- | generate_cpp_unittest.cpp | 578 | ||||
-rw-r--r-- | generate_java_binder.cpp | 79 | ||||
-rw-r--r-- | options.cpp | 10 | ||||
-rw-r--r-- | options.h | 4 | ||||
-rw-r--r-- | tests/end_to_end_tests.cpp | 23 | ||||
-rw-r--r-- | tests/test_data.h | 1 | ||||
-rw-r--r-- | tests/test_data_example_interface.cpp | 452 |
12 files changed, 1180 insertions, 13 deletions
@@ -548,6 +548,7 @@ AidlError load_and_validate_aidl( const std::vector<std::string>& preprocessed_files, const std::vector<std::string>& import_paths, const std::string& input_file_name, + const bool generate_traces, const IoDelegate& io_delegate, TypeNamespace* types, std::unique_ptr<AidlInterface>* returned_interface, @@ -633,6 +634,8 @@ AidlError load_and_validate_aidl( interface->SetLanguageType(types->GetInterfaceType(*interface)); + interface->SetGenerateTraces(generate_traces); + for (const auto& import : p.GetImports()) { // If we skipped an unresolved import above (see comment there) we'll have // an empty bucket here. @@ -685,6 +688,7 @@ int compile_aidl_to_cpp(const CppOptions& options, std::vector<std::string>{}, // no preprocessed files options.ImportPaths(), options.InputFileName(), + options.ShouldGenTraces(), io_delegate, types.get(), &interface, @@ -710,6 +714,7 @@ int compile_aidl_to_java(const JavaOptions& options, options.preprocessed_files_, options.import_paths_, options.input_file_name_, + options.gen_traces_, io_delegate, types.get(), &interface, @@ -58,6 +58,7 @@ AidlError load_and_validate_aidl( const std::vector<std::string>& preprocessed_files, const std::vector<std::string>& import_paths, const std::string& input_file_name, + const bool generate_traces, const IoDelegate& io_delegate, TypeNamespace* types, std::unique_ptr<AidlInterface>* returned_interface, diff --git a/aidl_language.h b/aidl_language.h index 7982e761..41196286 100644 --- a/aidl_language.h +++ b/aidl_language.h @@ -345,6 +345,14 @@ class AidlInterface : public AidlAnnotatable { return reinterpret_cast<const T*>(language_type_); } + void SetGenerateTraces(bool generate_traces) { + generate_traces_ = generate_traces; + } + + bool ShouldGenerateTraces() const { + return generate_traces_; + } + private: std::string name_; std::string comments_; @@ -356,6 +364,7 @@ class AidlInterface : public AidlAnnotatable { std::vector<std::string> package_; const android::aidl::ValidatableType* language_type_ = nullptr; + bool generate_traces_ = false; DISALLOW_COPY_AND_ASSIGN(AidlInterface); }; diff --git a/aidl_unittest.cpp b/aidl_unittest.cpp index 570ecc74..597a766d 100644 --- a/aidl_unittest.cpp +++ b/aidl_unittest.cpp @@ -80,6 +80,7 @@ class AidlTest : public ::testing::Test { preprocessed_files_, import_paths_, path, + false, /* generate_traces */ io_delegate_, types, &ret, diff --git a/generate_cpp.cpp b/generate_cpp.cpp index 41e9fb40..7e8892b1 100644 --- a/generate_cpp.cpp +++ b/generate_cpp.cpp @@ -52,6 +52,7 @@ const char kImplVarName[] = "_aidl_impl"; const char kReplyVarName[] = "_aidl_reply"; const char kReturnVarName[] = "_aidl_return"; const char kStatusVarName[] = "_aidl_status"; +const char kTraceVarName[] = "_aidl_trace"; const char kAndroidParcelLiteral[] = "::android::Parcel"; const char kAndroidStatusLiteral[] = "::android::status_t"; const char kAndroidStatusOk[] = "::android::OK"; @@ -61,6 +62,7 @@ const char kIInterfaceHeader[] = "binder/IInterface.h"; const char kParcelHeader[] = "binder/Parcel.h"; const char kStatusHeader[] = "binder/Status.h"; const char kString16Header[] = "utils/String16.h"; +const char kTraceHeader[] = "utils/Trace.h"; const char kStrongPointerHeader[] = "utils/StrongPointer.h"; unique_ptr<AstNode> BreakOnStatusNotOk() { @@ -271,6 +273,12 @@ unique_ptr<Declaration> DefineClientTransaction(const TypeNamespace& types, // We unconditionally return a Status object. b->AddLiteral(StringPrintf("%s %s", kBinderStatusLiteral, kStatusVarName)); + if (interface.ShouldGenerateTraces()) { + b->AddLiteral( + StringPrintf("ScopedTrace %s(ATRACE_TAG_AIDL, \"%s::%s::cppClient\")", + kTraceVarName, interface.GetName().c_str(), method.GetName().c_str())); + } + // Add the name of the interface we're hoping to call. b->AddStatement(new Assignment( kAndroidStatusVarName, @@ -378,6 +386,7 @@ unique_ptr<Declaration> DefineClientTransaction(const TypeNamespace& types, b->AddLiteral( StringPrintf("%s.setFromStatusT(%s)", kStatusVarName, kAndroidStatusVarName)); + b->AddLiteral(StringPrintf("return %s", kStatusVarName)); return unique_ptr<Declaration>(ret.release()); @@ -417,6 +426,7 @@ unique_ptr<Document> BuildClientSource(const TypeNamespace& types, namespace { bool HandleServerTransaction(const TypeNamespace& types, + const AidlInterface& interface, const AidlMethod& method, StatementBlock* b) { // Declare all the parameters now. In the common case, we expect no errors @@ -469,6 +479,14 @@ bool HandleServerTransaction(const TypeNamespace& types, } } + if (interface.ShouldGenerateTraces()) { + b->AddStatement(new Statement(new MethodCall("atrace_begin", + ArgList{{"ATRACE_TAG_AIDL", + StringPrintf("\"%s::%s::cppServer\"", + interface.GetName().c_str(), + method.GetName().c_str())}}))); + } + // Call the actual method. This is implemented by the subclass. vector<unique_ptr<AstNode>> status_args; status_args.emplace_back(new MethodCall( @@ -478,6 +496,11 @@ bool HandleServerTransaction(const TypeNamespace& types, StringPrintf("%s %s", kBinderStatusLiteral, kStatusVarName), ArgList(std::move(status_args))))); + if (interface.ShouldGenerateTraces()) { + b->AddStatement(new Statement(new MethodCall("atrace_end", + "ATRACE_TAG_AIDL"))); + } + // Write exceptions during transaction handling to parcel. if (!method.IsOneway()) { b->AddStatement(new Assignment( @@ -551,7 +574,7 @@ unique_ptr<Document> BuildServerSource(const TypeNamespace& types, StatementBlock* b = s->AddCase("Call::" + UpperCase(method->GetName())); if (!b) { return nullptr; } - if (!HandleServerTransaction(types, *method, b)) { return nullptr; } + if (!HandleServerTransaction(types, interface, *method, b)) { return nullptr; } } // The switch statement has a default case which defers to the super class. @@ -727,6 +750,11 @@ unique_ptr<Document> BuildInterfaceHeader(const TypeNamespace& types, if (!interface.GetStringConstants().empty()) { includes.insert(kString16Header); } + + if (interface.ShouldGenerateTraces()) { + includes.insert(kTraceHeader); + } + for (const auto& constant : interface.GetStringConstants()) { unique_ptr<MethodDecl> getter(new MethodDecl( "const ::android::String16&", constant->GetName(), diff --git a/generate_cpp_unittest.cpp b/generate_cpp_unittest.cpp index 50bfd9c9..32e93624 100644 --- a/generate_cpp_unittest.cpp +++ b/generate_cpp_unittest.cpp @@ -378,6 +378,304 @@ return _aidl_status; } // namespace android )"; +const char kExpectedComplexTypeClientWithTraceSourceOutput[] = +R"(#include <android/os/BpComplexTypeInterface.h> +#include <binder/Parcel.h> + +namespace android { + +namespace os { + +BpComplexTypeInterface::BpComplexTypeInterface(const ::android::sp<::android::IBinder>& _aidl_impl) + : BpInterface<IComplexTypeInterface>(_aidl_impl){ +} + +::android::binder::Status BpComplexTypeInterface::Send(const ::std::unique_ptr<::std::vector<int32_t>>& goes_in, ::std::vector<double>* goes_in_and_out, ::std::vector<bool>* goes_out, ::std::vector<int32_t>* _aidl_return) { +::android::Parcel _aidl_data; +::android::Parcel _aidl_reply; +::android::status_t _aidl_ret_status = ::android::OK; +::android::binder::Status _aidl_status; +ScopedTrace _aidl_trace(ATRACE_TAG_AIDL, "IComplexTypeInterface::Send::cppClient"); +_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor()); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_ret_status = _aidl_data.writeInt32Vector(goes_in); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_ret_status = _aidl_data.writeDoubleVector(*goes_in_and_out); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_ret_status = _aidl_data.writeVectorSize(*goes_out); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_ret_status = remote()->transact(IComplexTypeInterface::SEND, _aidl_data, &_aidl_reply); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +if (!_aidl_status.isOk()) { +return _aidl_status; +} +_aidl_ret_status = _aidl_reply.readInt32Vector(_aidl_return); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_ret_status = _aidl_reply.readDoubleVector(goes_in_and_out); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_ret_status = _aidl_reply.readBoolVector(goes_out); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_error: +_aidl_status.setFromStatusT(_aidl_ret_status); +return _aidl_status; +} + +::android::binder::Status BpComplexTypeInterface::Piff(int32_t times) { +::android::Parcel _aidl_data; +::android::Parcel _aidl_reply; +::android::status_t _aidl_ret_status = ::android::OK; +::android::binder::Status _aidl_status; +ScopedTrace _aidl_trace(ATRACE_TAG_AIDL, "IComplexTypeInterface::Piff::cppClient"); +_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor()); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_ret_status = _aidl_data.writeInt32(times); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_ret_status = remote()->transact(IComplexTypeInterface::PIFF, _aidl_data, &_aidl_reply, ::android::IBinder::FLAG_ONEWAY); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_error: +_aidl_status.setFromStatusT(_aidl_ret_status); +return _aidl_status; +} + +::android::binder::Status BpComplexTypeInterface::TakesABinder(const ::android::sp<::foo::IFooType>& f, ::android::sp<::foo::IFooType>* _aidl_return) { +::android::Parcel _aidl_data; +::android::Parcel _aidl_reply; +::android::status_t _aidl_ret_status = ::android::OK; +::android::binder::Status _aidl_status; +ScopedTrace _aidl_trace(ATRACE_TAG_AIDL, "IComplexTypeInterface::TakesABinder::cppClient"); +_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor()); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_ret_status = _aidl_data.writeStrongBinder(::foo::IFooType::asBinder(f)); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_ret_status = remote()->transact(IComplexTypeInterface::TAKESABINDER, _aidl_data, &_aidl_reply); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +if (!_aidl_status.isOk()) { +return _aidl_status; +} +_aidl_ret_status = _aidl_reply.readStrongBinder(_aidl_return); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_error: +_aidl_status.setFromStatusT(_aidl_ret_status); +return _aidl_status; +} + +::android::binder::Status BpComplexTypeInterface::NullableBinder(::android::sp<::foo::IFooType>* _aidl_return) { +::android::Parcel _aidl_data; +::android::Parcel _aidl_reply; +::android::status_t _aidl_ret_status = ::android::OK; +::android::binder::Status _aidl_status; +ScopedTrace _aidl_trace(ATRACE_TAG_AIDL, "IComplexTypeInterface::NullableBinder::cppClient"); +_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor()); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_ret_status = remote()->transact(IComplexTypeInterface::NULLABLEBINDER, _aidl_data, &_aidl_reply); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +if (!_aidl_status.isOk()) { +return _aidl_status; +} +_aidl_ret_status = _aidl_reply.readNullableStrongBinder(_aidl_return); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_error: +_aidl_status.setFromStatusT(_aidl_ret_status); +return _aidl_status; +} + +::android::binder::Status BpComplexTypeInterface::StringListMethod(const ::std::vector<::android::String16>& input, ::std::vector<::android::String16>* output, ::std::vector<::android::String16>* _aidl_return) { +::android::Parcel _aidl_data; +::android::Parcel _aidl_reply; +::android::status_t _aidl_ret_status = ::android::OK; +::android::binder::Status _aidl_status; +ScopedTrace _aidl_trace(ATRACE_TAG_AIDL, "IComplexTypeInterface::StringListMethod::cppClient"); +_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor()); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_ret_status = _aidl_data.writeString16Vector(input); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_ret_status = remote()->transact(IComplexTypeInterface::STRINGLISTMETHOD, _aidl_data, &_aidl_reply); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +if (!_aidl_status.isOk()) { +return _aidl_status; +} +_aidl_ret_status = _aidl_reply.readString16Vector(_aidl_return); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_ret_status = _aidl_reply.readString16Vector(output); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_error: +_aidl_status.setFromStatusT(_aidl_ret_status); +return _aidl_status; +} + +::android::binder::Status BpComplexTypeInterface::BinderListMethod(const ::std::vector<::android::sp<::android::IBinder>>& input, ::std::vector<::android::sp<::android::IBinder>>* output, ::std::vector<::android::sp<::android::IBinder>>* _aidl_return) { +::android::Parcel _aidl_data; +::android::Parcel _aidl_reply; +::android::status_t _aidl_ret_status = ::android::OK; +::android::binder::Status _aidl_status; +ScopedTrace _aidl_trace(ATRACE_TAG_AIDL, "IComplexTypeInterface::BinderListMethod::cppClient"); +_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor()); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_ret_status = _aidl_data.writeStrongBinderVector(input); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_ret_status = remote()->transact(IComplexTypeInterface::BINDERLISTMETHOD, _aidl_data, &_aidl_reply); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +if (!_aidl_status.isOk()) { +return _aidl_status; +} +_aidl_ret_status = _aidl_reply.readStrongBinderVector(_aidl_return); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_ret_status = _aidl_reply.readStrongBinderVector(output); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_error: +_aidl_status.setFromStatusT(_aidl_ret_status); +return _aidl_status; +} + +::android::binder::Status BpComplexTypeInterface::TakesAFileDescriptor(const ::android::base::unique_fd& f, ::android::base::unique_fd* _aidl_return) { +::android::Parcel _aidl_data; +::android::Parcel _aidl_reply; +::android::status_t _aidl_ret_status = ::android::OK; +::android::binder::Status _aidl_status; +ScopedTrace _aidl_trace(ATRACE_TAG_AIDL, "IComplexTypeInterface::TakesAFileDescriptor::cppClient"); +_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor()); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_ret_status = _aidl_data.writeUniqueFileDescriptor(f); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_ret_status = remote()->transact(IComplexTypeInterface::TAKESAFILEDESCRIPTOR, _aidl_data, &_aidl_reply); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +if (!_aidl_status.isOk()) { +return _aidl_status; +} +_aidl_ret_status = _aidl_reply.readUniqueFileDescriptor(_aidl_return); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_error: +_aidl_status.setFromStatusT(_aidl_ret_status); +return _aidl_status; +} + +::android::binder::Status BpComplexTypeInterface::TakesAFileDescriptorArray(const ::std::vector<::android::base::unique_fd>& f, ::std::vector<::android::base::unique_fd>* _aidl_return) { +::android::Parcel _aidl_data; +::android::Parcel _aidl_reply; +::android::status_t _aidl_ret_status = ::android::OK; +::android::binder::Status _aidl_status; +ScopedTrace _aidl_trace(ATRACE_TAG_AIDL, "IComplexTypeInterface::TakesAFileDescriptorArray::cppClient"); +_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor()); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_ret_status = _aidl_data.writeUniqueFileDescriptorVector(f); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_ret_status = remote()->transact(IComplexTypeInterface::TAKESAFILEDESCRIPTORARRAY, _aidl_data, &_aidl_reply); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +if (!_aidl_status.isOk()) { +return _aidl_status; +} +_aidl_ret_status = _aidl_reply.readUniqueFileDescriptorVector(_aidl_return); +if (((_aidl_ret_status) != (::android::OK))) { +goto _aidl_error; +} +_aidl_error: +_aidl_status.setFromStatusT(_aidl_ret_status); +return _aidl_status; +} + +} // namespace os + +} // namespace android +)"; + const char kExpectedComplexTypeServerHeaderOutput[] = R"(#ifndef AIDL_GENERATED_ANDROID_OS_BN_COMPLEX_TYPE_INTERFACE_H_ #define AIDL_GENERATED_ANDROID_OS_BN_COMPLEX_TYPE_INTERFACE_H_ @@ -648,6 +946,269 @@ return _aidl_ret_status; } // namespace android )"; +const char kExpectedComplexTypeServerWithTraceSourceOutput[] = +R"(#include <android/os/BnComplexTypeInterface.h> +#include <binder/Parcel.h> + +namespace android { + +namespace os { + +::android::status_t BnComplexTypeInterface::onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) { +::android::status_t _aidl_ret_status = ::android::OK; +switch (_aidl_code) { +case Call::SEND: +{ +::std::unique_ptr<::std::vector<int32_t>> in_goes_in; +::std::vector<double> in_goes_in_and_out; +::std::vector<bool> out_goes_out; +::std::vector<int32_t> _aidl_return; +if (!(_aidl_data.checkInterface(this))) { +_aidl_ret_status = ::android::BAD_TYPE; +break; +} +_aidl_ret_status = _aidl_data.readInt32Vector(&in_goes_in); +if (((_aidl_ret_status) != (::android::OK))) { +break; +} +_aidl_ret_status = _aidl_data.readDoubleVector(&in_goes_in_and_out); +if (((_aidl_ret_status) != (::android::OK))) { +break; +} +_aidl_ret_status = _aidl_data.resizeOutVector(&out_goes_out); +if (((_aidl_ret_status) != (::android::OK))) { +break; +} +atrace_begin(ATRACE_TAG_AIDL, "IComplexTypeInterface::Send::cppServer"); +::android::binder::Status _aidl_status(Send(in_goes_in, &in_goes_in_and_out, &out_goes_out, &_aidl_return)); +atrace_end(ATRACE_TAG_AIDL); +_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply); +if (((_aidl_ret_status) != (::android::OK))) { +break; +} +if (!_aidl_status.isOk()) { +break; +} +_aidl_ret_status = _aidl_reply->writeInt32Vector(_aidl_return); +if (((_aidl_ret_status) != (::android::OK))) { +break; +} +_aidl_ret_status = _aidl_reply->writeDoubleVector(in_goes_in_and_out); +if (((_aidl_ret_status) != (::android::OK))) { +break; +} +_aidl_ret_status = _aidl_reply->writeBoolVector(out_goes_out); +if (((_aidl_ret_status) != (::android::OK))) { +break; +} +} +break; +case Call::PIFF: +{ +int32_t in_times; +if (!(_aidl_data.checkInterface(this))) { +_aidl_ret_status = ::android::BAD_TYPE; +break; +} +_aidl_ret_status = _aidl_data.readInt32(&in_times); +if (((_aidl_ret_status) != (::android::OK))) { +break; +} +atrace_begin(ATRACE_TAG_AIDL, "IComplexTypeInterface::Piff::cppServer"); +::android::binder::Status _aidl_status(Piff(in_times)); +atrace_end(ATRACE_TAG_AIDL); +} +break; +case Call::TAKESABINDER: +{ +::android::sp<::foo::IFooType> in_f; +::android::sp<::foo::IFooType> _aidl_return; +if (!(_aidl_data.checkInterface(this))) { +_aidl_ret_status = ::android::BAD_TYPE; +break; +} +_aidl_ret_status = _aidl_data.readStrongBinder(&in_f); +if (((_aidl_ret_status) != (::android::OK))) { +break; +} +atrace_begin(ATRACE_TAG_AIDL, "IComplexTypeInterface::TakesABinder::cppServer"); +::android::binder::Status _aidl_status(TakesABinder(in_f, &_aidl_return)); +atrace_end(ATRACE_TAG_AIDL); +_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply); +if (((_aidl_ret_status) != (::android::OK))) { +break; +} +if (!_aidl_status.isOk()) { +break; +} +_aidl_ret_status = _aidl_reply->writeStrongBinder(::foo::IFooType::asBinder(_aidl_return)); +if (((_aidl_ret_status) != (::android::OK))) { +break; +} +} +break; +case Call::NULLABLEBINDER: +{ +::android::sp<::foo::IFooType> _aidl_return; +if (!(_aidl_data.checkInterface(this))) { +_aidl_ret_status = ::android::BAD_TYPE; +break; +} +atrace_begin(ATRACE_TAG_AIDL, "IComplexTypeInterface::NullableBinder::cppServer"); +::android::binder::Status _aidl_status(NullableBinder(&_aidl_return)); +atrace_end(ATRACE_TAG_AIDL); +_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply); +if (((_aidl_ret_status) != (::android::OK))) { +break; +} +if (!_aidl_status.isOk()) { +break; +} +_aidl_ret_status = _aidl_reply->writeStrongBinder(::foo::IFooType::asBinder(_aidl_return)); +if (((_aidl_ret_status) != (::android::OK))) { +break; +} +} +break; +case Call::STRINGLISTMETHOD: +{ +::std::vector<::android::String16> in_input; +::std::vector<::android::String16> out_output; +::std::vector<::android::String16> _aidl_return; +if (!(_aidl_data.checkInterface(this))) { +_aidl_ret_status = ::android::BAD_TYPE; +break; +} +_aidl_ret_status = _aidl_data.readString16Vector(&in_input); +if (((_aidl_ret_status) != (::android::OK))) { +break; +} +atrace_begin(ATRACE_TAG_AIDL, "IComplexTypeInterface::StringListMethod::cppServer"); +::android::binder::Status _aidl_status(StringListMethod(in_input, &out_output, &_aidl_return)); +atrace_end(ATRACE_TAG_AIDL); +_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply); +if (((_aidl_ret_status) != (::android::OK))) { +break; +} +if (!_aidl_status.isOk()) { +break; +} +_aidl_ret_status = _aidl_reply->writeString16Vector(_aidl_return); +if (((_aidl_ret_status) != (::android::OK))) { +break; +} +_aidl_ret_status = _aidl_reply->writeString16Vector(out_output); +if (((_aidl_ret_status) != (::android::OK))) { +break; +} +} +break; +case Call::BINDERLISTMETHOD: +{ +::std::vector<::android::sp<::android::IBinder>> in_input; +::std::vector<::android::sp<::android::IBinder>> out_output; +::std::vector<::android::sp<::android::IBinder>> _aidl_return; +if (!(_aidl_data.checkInterface(this))) { +_aidl_ret_status = ::android::BAD_TYPE; +break; +} +_aidl_ret_status = _aidl_data.readStrongBinderVector(&in_input); +if (((_aidl_ret_status) != (::android::OK))) { +break; +} +atrace_begin(ATRACE_TAG_AIDL, "IComplexTypeInterface::BinderListMethod::cppServer"); +::android::binder::Status _aidl_status(BinderListMethod(in_input, &out_output, &_aidl_return)); +atrace_end(ATRACE_TAG_AIDL); +_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply); +if (((_aidl_ret_status) != (::android::OK))) { +break; +} +if (!_aidl_status.isOk()) { +break; +} +_aidl_ret_status = _aidl_reply->writeStrongBinderVector(_aidl_return); +if (((_aidl_ret_status) != (::android::OK))) { +break; +} +_aidl_ret_status = _aidl_reply->writeStrongBinderVector(out_output); +if (((_aidl_ret_status) != (::android::OK))) { +break; +} +} +break; +case Call::TAKESAFILEDESCRIPTOR: +{ +::android::base::unique_fd in_f; +::android::base::unique_fd _aidl_return; +if (!(_aidl_data.checkInterface(this))) { +_aidl_ret_status = ::android::BAD_TYPE; +break; +} +_aidl_ret_status = _aidl_data.readUniqueFileDescriptor(&in_f); +if (((_aidl_ret_status) != (::android::OK))) { +break; +} +atrace_begin(ATRACE_TAG_AIDL, "IComplexTypeInterface::TakesAFileDescriptor::cppServer"); +::android::binder::Status _aidl_status(TakesAFileDescriptor(in_f, &_aidl_return)); +atrace_end(ATRACE_TAG_AIDL); +_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply); +if (((_aidl_ret_status) != (::android::OK))) { +break; +} +if (!_aidl_status.isOk()) { +break; +} +_aidl_ret_status = _aidl_reply->writeUniqueFileDescriptor(_aidl_return); +if (((_aidl_ret_status) != (::android::OK))) { +break; +} +} +break; +case Call::TAKESAFILEDESCRIPTORARRAY: +{ +::std::vector<::android::base::unique_fd> in_f; +::std::vector<::android::base::unique_fd> _aidl_return; +if (!(_aidl_data.checkInterface(this))) { +_aidl_ret_status = ::android::BAD_TYPE; +break; +} +_aidl_ret_status = _aidl_data.readUniqueFileDescriptorVector(&in_f); +if (((_aidl_ret_status) != (::android::OK))) { +break; +} +atrace_begin(ATRACE_TAG_AIDL, "IComplexTypeInterface::TakesAFileDescriptorArray::cppServer"); +::android::binder::Status _aidl_status(TakesAFileDescriptorArray(in_f, &_aidl_return)); +atrace_end(ATRACE_TAG_AIDL); +_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply); +if (((_aidl_ret_status) != (::android::OK))) { +break; +} +if (!_aidl_status.isOk()) { +break; +} +_aidl_ret_status = _aidl_reply->writeUniqueFileDescriptorVector(_aidl_return); +if (((_aidl_ret_status) != (::android::OK))) { +break; +} +} +break; +default: +{ +_aidl_ret_status = ::android::BBinder::onTransact(_aidl_code, _aidl_data, _aidl_reply, _aidl_flags); +} +break; +} +if (_aidl_ret_status == ::android::UNEXPECTED_NULL) { +_aidl_ret_status = ::android::binder::Status::fromExceptionCode(::android::binder::Status::EX_NULL_POINTER).writeToParcel(_aidl_reply); +} +return _aidl_ret_status; +} + +} // namespace os + +} // namespace android +)"; + const char kExpectedComplexTypeInterfaceHeaderOutput[] = R"(#ifndef AIDL_GENERATED_ANDROID_OS_I_COMPLEX_TYPE_INTERFACE_H_ #define AIDL_GENERATED_ANDROID_OS_I_COMPLEX_TYPE_INTERFACE_H_ @@ -734,6 +1295,7 @@ class ASTTest : public ::testing::Test { {}, // no preprocessed files {"."}, file_path_, + false, // generate_traces io_delegate_, &types_, &ret, @@ -789,6 +1351,14 @@ TEST_F(ComplexTypeInterfaceASTTest, GeneratesClientSource) { Compare(doc.get(), kExpectedComplexTypeClientSourceOutput); } +TEST_F(ComplexTypeInterfaceASTTest, GeneratesClientSourceWithTrace) { + unique_ptr<AidlInterface> interface = Parse(); + ASSERT_NE(interface, nullptr); + interface->SetGenerateTraces(true); + unique_ptr<Document> doc = internals::BuildClientSource(types_, *interface); + Compare(doc.get(), kExpectedComplexTypeClientWithTraceSourceOutput); +} + TEST_F(ComplexTypeInterfaceASTTest, GeneratesServerHeader) { unique_ptr<AidlInterface> interface = Parse(); ASSERT_NE(interface, nullptr); @@ -803,6 +1373,14 @@ TEST_F(ComplexTypeInterfaceASTTest, GeneratesServerSource) { Compare(doc.get(), kExpectedComplexTypeServerSourceOutput); } +TEST_F(ComplexTypeInterfaceASTTest, GeneratesServerSourceWithTrace) { + unique_ptr<AidlInterface> interface = Parse(); + ASSERT_NE(interface, nullptr); + interface->SetGenerateTraces(true); + unique_ptr<Document> doc = internals::BuildServerSource(types_, *interface); + Compare(doc.get(), kExpectedComplexTypeServerWithTraceSourceOutput); +} + TEST_F(ComplexTypeInterfaceASTTest, GeneratesInterfaceHeader) { unique_ptr<AidlInterface> interface = Parse(); ASSERT_NE(interface, nullptr); diff --git a/generate_java_binder.cpp b/generate_java_binder.cpp index ad993a80..522715c5 100644 --- a/generate_java_binder.cpp +++ b/generate_java_binder.cpp @@ -342,7 +342,8 @@ static std::unique_ptr<Method> generate_interface_method( return decl; } -static void generate_stub_code(const AidlMethod& method, +static void generate_stub_code(const AidlInterface& iface, + const AidlMethod& method, const std::string& transactCodeName, bool oneway, Variable* transact_data, @@ -350,6 +351,8 @@ static void generate_stub_code(const AidlMethod& method, JavaTypeNamespace* types, StatementBlock* statements, StubClass* stubClass) { + TryStatement* tryStatement = nullptr; + FinallyStatement* finallyStatement = nullptr; MethodCall* realCall = new MethodCall(THIS_VALUE, method.GetName()); // interface token validation is the very first thing we do @@ -391,9 +394,31 @@ static void generate_stub_code(const AidlMethod& method, } } + if (iface.ShouldGenerateTraces()) { + // try and finally, but only when generating trace code + tryStatement = new TryStatement(); + finallyStatement = new FinallyStatement(); + + tryStatement->statements->Add(new MethodCall( + new LiteralExpression("android.os.Trace"), "traceBegin", 2, + new LiteralExpression("android.os.Trace.TRACE_TAG_AIDL"), + new StringLiteralExpression(iface.GetName() + "::" + + method.GetName() + "::server"))); + + finallyStatement->statements->Add(new MethodCall( + new LiteralExpression("android.os.Trace"), "traceEnd", 1, + new LiteralExpression("android.os.Trace.TRACE_TAG_AIDL"))); + } + // the real call if (method.GetType().GetName() == "void") { - statements->Add(realCall); + if (iface.ShouldGenerateTraces()) { + statements->Add(tryStatement); + tryStatement->statements->Add(realCall); + statements->Add(finallyStatement); + } else { + statements->Add(realCall); + } if (!oneway) { // report that there were no exceptions @@ -406,7 +431,14 @@ static void generate_stub_code(const AidlMethod& method, new Variable(method.GetType().GetLanguageType<Type>(), "_result", method.GetType().IsArray() ? 1 : 0); - statements->Add(new VariableDeclaration(_result, realCall)); + if (iface.ShouldGenerateTraces()) { + statements->Add(new VariableDeclaration(_result)); + statements->Add(tryStatement); + tryStatement->statements->Add(new Assignment(_result, realCall)); + statements->Add(finallyStatement); + } else { + statements->Add(new VariableDeclaration(_result, realCall)); + } if (!oneway) { // report that there were no exceptions @@ -443,14 +475,16 @@ static void generate_stub_code(const AidlMethod& method, } -static void generate_stub_case(const AidlMethod& method, +static void generate_stub_case(const AidlInterface& iface, + const AidlMethod& method, const std::string& transactCodeName, bool oneway, StubClass* stubClass, JavaTypeNamespace* types) { Case* c = new Case(transactCodeName); - generate_stub_code(method, + generate_stub_code(iface, + method, transactCodeName, oneway, stubClass->transact_data, @@ -462,7 +496,8 @@ static void generate_stub_case(const AidlMethod& method, stubClass->transact_switch->cases.push_back(c); } -static void generate_stub_case_outline(const AidlMethod& method, +static void generate_stub_case_outline(const AidlInterface& iface, + const AidlMethod& method, const std::string& transactCodeName, bool oneway, StubClass* stubClass, @@ -482,7 +517,8 @@ static void generate_stub_case_outline(const AidlMethod& method, onTransact_case->exceptions.push_back(types->RemoteExceptionType()); stubClass->elements.push_back(onTransact_case); - generate_stub_code(method, + generate_stub_code(iface, + method, transactCodeName, oneway, transact_data, @@ -508,6 +544,7 @@ static void generate_stub_case_outline(const AidlMethod& method, } static std::unique_ptr<Method> generate_proxy_method( + const AidlInterface& iface, const AidlMethod& method, const std::string& transactCodeName, bool oneway, @@ -552,6 +589,14 @@ static std::unique_ptr<Method> generate_proxy_method( FinallyStatement* finallyStatement = new FinallyStatement(); proxy->statements->Add(finallyStatement); + if (iface.ShouldGenerateTraces()) { + tryStatement->statements->Add(new MethodCall( + new LiteralExpression("android.os.Trace"), "traceBegin", 2, + new LiteralExpression("android.os.Trace.TRACE_TAG_AIDL"), + new StringLiteralExpression(iface.GetName() + "::" + + method.GetName() + "::client"))); + } + // the interface identifier token: the DESCRIPTOR constant, marshalled as a // string tryStatement->statements->Add(new MethodCall( @@ -615,6 +660,12 @@ static std::unique_ptr<Method> generate_proxy_method( } finallyStatement->statements->Add(new MethodCall(_data, "recycle")); + if (iface.ShouldGenerateTraces()) { + finallyStatement->statements->Add(new MethodCall( + new LiteralExpression("android.os.Trace"), "traceEnd", 1, + new LiteralExpression("android.os.Trace.TRACE_TAG_AIDL"))); + } + if (_result != NULL) { proxy->statements->Add(new ReturnStatement(_result)); } @@ -622,7 +673,8 @@ static std::unique_ptr<Method> generate_proxy_method( return proxy; } -static void generate_methods(const AidlMethod& method, +static void generate_methods(const AidlInterface& iface, + const AidlMethod& method, Class* interface, StubClass* stubClass, ProxyClass* proxyClass, @@ -648,17 +700,19 @@ static void generate_methods(const AidlMethod& method, bool outline_stub = stubClass->transact_outline && stubClass->outline_methods.count(&method) != 0; if (outline_stub) { - generate_stub_case_outline(method, + generate_stub_case_outline(iface, + method, transactCodeName, oneway, stubClass, types); } else { - generate_stub_case(method, transactCodeName, oneway, stubClass, types); + generate_stub_case(iface, method, transactCodeName, oneway, stubClass, types); } // == the proxy method =================================================== - Method* proxy = generate_proxy_method(method, + Method* proxy = generate_proxy_method(iface, + method, transactCodeName, oneway, proxyClass, @@ -768,7 +822,8 @@ Class* generate_binder_interface_class(const AidlInterface* iface, // all the declared methods of the interface for (const auto& item : iface->GetMethods()) { - generate_methods(*item, + generate_methods(*iface, + *item, interface, stub, proxy, diff --git a/options.cpp b/options.cpp index 72c75758..3ed110b0 100644 --- a/options.cpp +++ b/options.cpp @@ -48,6 +48,9 @@ unique_ptr<JavaOptions> java_usage() { " -p<FILE> file created by --preprocess to import.\n" " -o<FOLDER> base output folder for generated files.\n" " -b fail when trying to compile a parcelable.\n" + " -t include tracing code for systrace. Note that if either " + "the client or server code is not auto-generated by this tool, that " + "part will not be traced.\n" "\n" "INPUT:\n" " An aidl interface file.\n" @@ -126,6 +129,8 @@ unique_ptr<JavaOptions> JavaOptions::Parse(int argc, const char* const* argv) { options->fail_on_parcelable_ = true; } else if (strcmp(s, "-ninja") == 0) { options->dep_file_ninja_ = true; + } else if (strcmp(s, "-t") == 0) { + options->gen_traces_ = true; } else { // s[1] is not known fprintf(stderr, "unknown option (%d): %s\n", i, s); @@ -190,6 +195,9 @@ unique_ptr<CppOptions> cpp_usage() { << "OPTIONS:" << endl << " -I<DIR> search path for import statements" << endl << " -d<FILE> generate dependency file" << endl + << " -t include tracing code for systrace. Note that if the " + "client or server code is not auto-generated by this tool, that part " + "will not be traced." << endl << " -ninja generate dependency file in a format ninja " "understands" << endl << endl @@ -224,6 +232,8 @@ unique_ptr<CppOptions> CppOptions::Parse(int argc, const char* const* argv) { options->import_paths_.push_back(the_rest); } else if (s[1] == 'd') { options->dep_file_name_ = the_rest; + } else if (s[1] == 't') { + options->gen_traces_ = true; } else if (strcmp(s, "-ninja") == 0) { options->dep_file_ninja_ = true; } else { @@ -54,6 +54,7 @@ class JavaOptions final { std::string dep_file_name_; bool auto_dep_file_{false}; bool dep_file_ninja_{false}; + bool gen_traces_{false}; std::vector<std::string> files_to_preprocess_; // The following are for testability, but cannot be influenced on the command line. @@ -67,6 +68,7 @@ class JavaOptions final { JavaOptions() = default; FRIEND_TEST(EndToEndTest, IExampleInterface); + FRIEND_TEST(EndToEndTest, IExampleInterface_WithTrace); FRIEND_TEST(EndToEndTest, IExampleInterface_Outlining); FRIEND_TEST(AidlTest, FailOnParcelable); FRIEND_TEST(AidlTest, WritePreprocessedFile); @@ -94,6 +96,7 @@ class CppOptions final { std::vector<std::string> ImportPaths() const { return import_paths_; } std::string DependencyFilePath() const { return dep_file_name_; } bool DependencyFileNinja() const { return dep_file_ninja_; } + bool ShouldGenTraces() const { return gen_traces_; } private: CppOptions() = default; @@ -103,6 +106,7 @@ class CppOptions final { std::string output_header_dir_; std::string output_file_name_; std::string dep_file_name_; + bool gen_traces_{false}; bool dep_file_ninja_{false}; FRIEND_TEST(CppOptionsTests, ParsesCompileCpp); diff --git a/tests/end_to_end_tests.cpp b/tests/end_to_end_tests.cpp index 344c4c2a..555d8dce 100644 --- a/tests/end_to_end_tests.cpp +++ b/tests/end_to_end_tests.cpp @@ -92,6 +92,29 @@ TEST_F(EndToEndTest, IExampleInterface) { CheckFileContents(options.DependencyFilePath(), kExpectedJavaDepsOutput); } +TEST_F(EndToEndTest, IExampleInterface_WithTrace) { + using namespace ::android::aidl::test_data::example_interface; + + JavaOptions options; + options.fail_on_parcelable_ = true; + options.import_paths_.push_back(""); + options.input_file_name_ = CanonicalNameToPath(kCanonicalName, ".aidl"); + options.output_file_name_ = kJavaOutputPath; + options.dep_file_name_ = "an/arbitrary/path/to/deps.P"; + options.gen_traces_ = true; + + // Load up our fake file system with data. + io_delegate_.SetFileContents(options.input_file_name_, kInterfaceDefinition); + io_delegate_.AddCompoundParcelable("android.test.CompoundParcelable", + {"Subclass1", "Subclass2"}); + AddStubAidls(kImportedParcelables, kImportedInterfaces); + + // Check that we parse correctly. + EXPECT_EQ(android::aidl::compile_aidl_to_java(options, io_delegate_), 0); + CheckFileContents(kJavaOutputPath, kExpectedJavaOutputWithTrace); + CheckFileContents(options.DependencyFilePath(), kExpectedJavaDepsOutput); +} + TEST_F(EndToEndTest, IExampleInterface_Outlining) { using namespace ::android::aidl::test_data::example_interface; diff --git a/tests/test_data.h b/tests/test_data.h index ae2c573e..0b5aaf09 100644 --- a/tests/test_data.h +++ b/tests/test_data.h @@ -33,6 +33,7 @@ extern const char* kImportedInterfaces[]; extern const char kExpectedJavaDepsOutput[]; extern const char kExpectedJavaOutput[]; extern const char kExpectedJavaOutputOutlining[]; +extern const char kExpectedJavaOutputWithTrace[]; } // namespace example_interface diff --git a/tests/test_data_example_interface.cpp b/tests/test_data_example_interface.cpp index 731efcd0..9b0e0ee6 100644 --- a/tests/test_data_example_interface.cpp +++ b/tests/test_data_example_interface.cpp @@ -485,6 +485,458 @@ public int takesAParcelable(android.test.CompoundParcelable.Subclass1 arg, andro } )"; +const char kExpectedJavaOutputWithTrace[] = +R"(/* + * This file is auto-generated. DO NOT MODIFY. + * Original file: android/test/IExampleInterface.aidl + */ +package android.test; +public interface IExampleInterface extends android.os.IInterface +{ +/** Local-side IPC implementation stub class. */ +public static abstract class Stub extends android.os.Binder implements android.test.IExampleInterface +{ +private static final java.lang.String DESCRIPTOR = "android.test.IExampleInterface"; +/** Construct the stub at attach it to the interface. */ +public Stub() +{ +this.attachInterface(this, DESCRIPTOR); +} +/** + * Cast an IBinder object into an android.test.IExampleInterface interface, + * generating a proxy if needed. + */ +public static android.test.IExampleInterface asInterface(android.os.IBinder obj) +{ +if ((obj==null)) { +return null; +} +android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); +if (((iin!=null)&&(iin instanceof android.test.IExampleInterface))) { +return ((android.test.IExampleInterface)iin); +} +return new android.test.IExampleInterface.Stub.Proxy(obj); +} +@Override public android.os.IBinder asBinder() +{ +return this; +} +@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException +{ +java.lang.String descriptor = DESCRIPTOR; +switch (code) +{ +case INTERFACE_TRANSACTION: +{ +reply.writeString(descriptor); +return true; +} +case TRANSACTION_isEnabled: +{ +data.enforceInterface(descriptor); +boolean _result; +try { +android.os.Trace.traceBegin(android.os.Trace.TRACE_TAG_AIDL, "IExampleInterface::isEnabled::server"); +_result = this.isEnabled(); +} +finally { +android.os.Trace.traceEnd(android.os.Trace.TRACE_TAG_AIDL); +} +reply.writeNoException(); +reply.writeInt(((_result)?(1):(0))); +return true; +} +case TRANSACTION_getState: +{ +data.enforceInterface(descriptor); +int _result; +try { +android.os.Trace.traceBegin(android.os.Trace.TRACE_TAG_AIDL, "IExampleInterface::getState::server"); +_result = this.getState(); +} +finally { +android.os.Trace.traceEnd(android.os.Trace.TRACE_TAG_AIDL); +} +reply.writeNoException(); +reply.writeInt(_result); +return true; +} +case TRANSACTION_getAddress: +{ +data.enforceInterface(descriptor); +java.lang.String _result; +try { +android.os.Trace.traceBegin(android.os.Trace.TRACE_TAG_AIDL, "IExampleInterface::getAddress::server"); +_result = this.getAddress(); +} +finally { +android.os.Trace.traceEnd(android.os.Trace.TRACE_TAG_AIDL); +} +reply.writeNoException(); +reply.writeString(_result); +return true; +} +case TRANSACTION_getParcelables: +{ +data.enforceInterface(descriptor); +android.foo.ExampleParcelable[] _result; +try { +android.os.Trace.traceBegin(android.os.Trace.TRACE_TAG_AIDL, "IExampleInterface::getParcelables::server"); +_result = this.getParcelables(); +} +finally { +android.os.Trace.traceEnd(android.os.Trace.TRACE_TAG_AIDL); +} +reply.writeNoException(); +reply.writeTypedArray(_result, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE); +return true; +} +case TRANSACTION_setScanMode: +{ +data.enforceInterface(descriptor); +int _arg0; +_arg0 = data.readInt(); +int _arg1; +_arg1 = data.readInt(); +boolean _result; +try { +android.os.Trace.traceBegin(android.os.Trace.TRACE_TAG_AIDL, "IExampleInterface::setScanMode::server"); +_result = this.setScanMode(_arg0, _arg1); +} +finally { +android.os.Trace.traceEnd(android.os.Trace.TRACE_TAG_AIDL); +} +reply.writeNoException(); +reply.writeInt(((_result)?(1):(0))); +return true; +} +case TRANSACTION_registerBinder: +{ +data.enforceInterface(descriptor); +android.bar.IAuxInterface _arg0; +_arg0 = android.bar.IAuxInterface.Stub.asInterface(data.readStrongBinder()); +try { +android.os.Trace.traceBegin(android.os.Trace.TRACE_TAG_AIDL, "IExampleInterface::registerBinder::server"); +this.registerBinder(_arg0); +} +finally { +android.os.Trace.traceEnd(android.os.Trace.TRACE_TAG_AIDL); +} +reply.writeNoException(); +return true; +} +case TRANSACTION_getRecursiveBinder: +{ +data.enforceInterface(descriptor); +android.test.IExampleInterface _result; +try { +android.os.Trace.traceBegin(android.os.Trace.TRACE_TAG_AIDL, "IExampleInterface::getRecursiveBinder::server"); +_result = this.getRecursiveBinder(); +} +finally { +android.os.Trace.traceEnd(android.os.Trace.TRACE_TAG_AIDL); +} +reply.writeNoException(); +reply.writeStrongBinder((((_result!=null))?(_result.asBinder()):(null))); +return true; +} +case TRANSACTION_takesAnInterface: +{ +data.enforceInterface(descriptor); +android.test.IAuxInterface2 _arg0; +_arg0 = android.test.IAuxInterface2.Stub.asInterface(data.readStrongBinder()); +int _result; +try { +android.os.Trace.traceBegin(android.os.Trace.TRACE_TAG_AIDL, "IExampleInterface::takesAnInterface::server"); +_result = this.takesAnInterface(_arg0); +} +finally { +android.os.Trace.traceEnd(android.os.Trace.TRACE_TAG_AIDL); +} +reply.writeNoException(); +reply.writeInt(_result); +return true; +} +case TRANSACTION_takesAParcelable: +{ +data.enforceInterface(descriptor); +android.test.CompoundParcelable.Subclass1 _arg0; +if ((0!=data.readInt())) { +_arg0 = android.test.CompoundParcelable.Subclass1.CREATOR.createFromParcel(data); +} +else { +_arg0 = null; +} +android.test.CompoundParcelable.Subclass2 _arg1; +if ((0!=data.readInt())) { +_arg1 = android.test.CompoundParcelable.Subclass2.CREATOR.createFromParcel(data); +} +else { +_arg1 = null; +} +int _result; +try { +android.os.Trace.traceBegin(android.os.Trace.TRACE_TAG_AIDL, "IExampleInterface::takesAParcelable::server"); +_result = this.takesAParcelable(_arg0, _arg1); +} +finally { +android.os.Trace.traceEnd(android.os.Trace.TRACE_TAG_AIDL); +} +reply.writeNoException(); +reply.writeInt(_result); +if ((_arg1!=null)) { +reply.writeInt(1); +_arg1.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE); +} +else { +reply.writeInt(0); +} +return true; +} +default: +{ +return super.onTransact(code, data, reply, flags); +} +} +} +private static class Proxy implements android.test.IExampleInterface +{ +private android.os.IBinder mRemote; +Proxy(android.os.IBinder remote) +{ +mRemote = remote; +} +@Override public android.os.IBinder asBinder() +{ +return mRemote; +} +public java.lang.String getInterfaceDescriptor() +{ +return DESCRIPTOR; +} +@Override public boolean isEnabled() throws android.os.RemoteException +{ +android.os.Parcel _data = android.os.Parcel.obtain(); +android.os.Parcel _reply = android.os.Parcel.obtain(); +boolean _result; +try { +android.os.Trace.traceBegin(android.os.Trace.TRACE_TAG_AIDL, "IExampleInterface::isEnabled::client"); +_data.writeInterfaceToken(DESCRIPTOR); +mRemote.transact(Stub.TRANSACTION_isEnabled, _data, _reply, 0); +_reply.readException(); +_result = (0!=_reply.readInt()); +} +finally { +_reply.recycle(); +_data.recycle(); +android.os.Trace.traceEnd(android.os.Trace.TRACE_TAG_AIDL); +} +return _result; +} +@Override public int getState() throws android.os.RemoteException +{ +android.os.Parcel _data = android.os.Parcel.obtain(); +android.os.Parcel _reply = android.os.Parcel.obtain(); +int _result; +try { +android.os.Trace.traceBegin(android.os.Trace.TRACE_TAG_AIDL, "IExampleInterface::getState::client"); +_data.writeInterfaceToken(DESCRIPTOR); +mRemote.transact(Stub.TRANSACTION_getState, _data, _reply, 0); +_reply.readException(); +_result = _reply.readInt(); +} +finally { +_reply.recycle(); +_data.recycle(); +android.os.Trace.traceEnd(android.os.Trace.TRACE_TAG_AIDL); +} +return _result; +} +@Override public java.lang.String getAddress() throws android.os.RemoteException +{ +android.os.Parcel _data = android.os.Parcel.obtain(); +android.os.Parcel _reply = android.os.Parcel.obtain(); +java.lang.String _result; +try { +android.os.Trace.traceBegin(android.os.Trace.TRACE_TAG_AIDL, "IExampleInterface::getAddress::client"); +_data.writeInterfaceToken(DESCRIPTOR); +mRemote.transact(Stub.TRANSACTION_getAddress, _data, _reply, 0); +_reply.readException(); +_result = _reply.readString(); +} +finally { +_reply.recycle(); +_data.recycle(); +android.os.Trace.traceEnd(android.os.Trace.TRACE_TAG_AIDL); +} +return _result; +} +/* Test long comment */ +@Override public android.foo.ExampleParcelable[] getParcelables() throws android.os.RemoteException +{ +android.os.Parcel _data = android.os.Parcel.obtain(); +android.os.Parcel _reply = android.os.Parcel.obtain(); +android.foo.ExampleParcelable[] _result; +try { +android.os.Trace.traceBegin(android.os.Trace.TRACE_TAG_AIDL, "IExampleInterface::getParcelables::client"); +_data.writeInterfaceToken(DESCRIPTOR); +mRemote.transact(Stub.TRANSACTION_getParcelables, _data, _reply, 0); +_reply.readException(); +_result = _reply.createTypedArray(android.foo.ExampleParcelable.CREATOR); +} +finally { +_reply.recycle(); +_data.recycle(); +android.os.Trace.traceEnd(android.os.Trace.TRACE_TAG_AIDL); +} +return _result; +} +// Test short comment + +@Override public boolean setScanMode(int mode, int duration) throws android.os.RemoteException +{ +android.os.Parcel _data = android.os.Parcel.obtain(); +android.os.Parcel _reply = android.os.Parcel.obtain(); +boolean _result; +try { +android.os.Trace.traceBegin(android.os.Trace.TRACE_TAG_AIDL, "IExampleInterface::setScanMode::client"); +_data.writeInterfaceToken(DESCRIPTOR); +_data.writeInt(mode); +_data.writeInt(duration); +mRemote.transact(Stub.TRANSACTION_setScanMode, _data, _reply, 0); +_reply.readException(); +_result = (0!=_reply.readInt()); +} +finally { +_reply.recycle(); +_data.recycle(); +android.os.Trace.traceEnd(android.os.Trace.TRACE_TAG_AIDL); +} +return _result; +} +/* Test long comment */// And short comment + +@Override public void registerBinder(android.bar.IAuxInterface foo) throws android.os.RemoteException +{ +android.os.Parcel _data = android.os.Parcel.obtain(); +android.os.Parcel _reply = android.os.Parcel.obtain(); +try { +android.os.Trace.traceBegin(android.os.Trace.TRACE_TAG_AIDL, "IExampleInterface::registerBinder::client"); +_data.writeInterfaceToken(DESCRIPTOR); +_data.writeStrongBinder((((foo!=null))?(foo.asBinder()):(null))); +mRemote.transact(Stub.TRANSACTION_registerBinder, _data, _reply, 0); +_reply.readException(); +} +finally { +_reply.recycle(); +_data.recycle(); +android.os.Trace.traceEnd(android.os.Trace.TRACE_TAG_AIDL); +} +} +@Override public android.test.IExampleInterface getRecursiveBinder() throws android.os.RemoteException +{ +android.os.Parcel _data = android.os.Parcel.obtain(); +android.os.Parcel _reply = android.os.Parcel.obtain(); +android.test.IExampleInterface _result; +try { +android.os.Trace.traceBegin(android.os.Trace.TRACE_TAG_AIDL, "IExampleInterface::getRecursiveBinder::client"); +_data.writeInterfaceToken(DESCRIPTOR); +mRemote.transact(Stub.TRANSACTION_getRecursiveBinder, _data, _reply, 0); +_reply.readException(); +_result = android.test.IExampleInterface.Stub.asInterface(_reply.readStrongBinder()); +} +finally { +_reply.recycle(); +_data.recycle(); +android.os.Trace.traceEnd(android.os.Trace.TRACE_TAG_AIDL); +} +return _result; +} +@Override public int takesAnInterface(android.test.IAuxInterface2 arg) throws android.os.RemoteException +{ +android.os.Parcel _data = android.os.Parcel.obtain(); +android.os.Parcel _reply = android.os.Parcel.obtain(); +int _result; +try { +android.os.Trace.traceBegin(android.os.Trace.TRACE_TAG_AIDL, "IExampleInterface::takesAnInterface::client"); +_data.writeInterfaceToken(DESCRIPTOR); +_data.writeStrongBinder((((arg!=null))?(arg.asBinder()):(null))); +mRemote.transact(Stub.TRANSACTION_takesAnInterface, _data, _reply, 0); +_reply.readException(); +_result = _reply.readInt(); +} +finally { +_reply.recycle(); +_data.recycle(); +android.os.Trace.traceEnd(android.os.Trace.TRACE_TAG_AIDL); +} +return _result; +} +@Override public int takesAParcelable(android.test.CompoundParcelable.Subclass1 arg, android.test.CompoundParcelable.Subclass2 arg2) throws android.os.RemoteException +{ +android.os.Parcel _data = android.os.Parcel.obtain(); +android.os.Parcel _reply = android.os.Parcel.obtain(); +int _result; +try { +android.os.Trace.traceBegin(android.os.Trace.TRACE_TAG_AIDL, "IExampleInterface::takesAParcelable::client"); +_data.writeInterfaceToken(DESCRIPTOR); +if ((arg!=null)) { +_data.writeInt(1); +arg.writeToParcel(_data, 0); +} +else { +_data.writeInt(0); +} +if ((arg2!=null)) { +_data.writeInt(1); +arg2.writeToParcel(_data, 0); +} +else { +_data.writeInt(0); +} +mRemote.transact(Stub.TRANSACTION_takesAParcelable, _data, _reply, 0); +_reply.readException(); +_result = _reply.readInt(); +if ((0!=_reply.readInt())) { +arg2.readFromParcel(_reply); +} +} +finally { +_reply.recycle(); +_data.recycle(); +android.os.Trace.traceEnd(android.os.Trace.TRACE_TAG_AIDL); +} +return _result; +} +} +static final int TRANSACTION_isEnabled = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); +static final int TRANSACTION_getState = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1); +static final int TRANSACTION_getAddress = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2); +static final int TRANSACTION_getParcelables = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3); +static final int TRANSACTION_setScanMode = (android.os.IBinder.FIRST_CALL_TRANSACTION + 4); +static final int TRANSACTION_registerBinder = (android.os.IBinder.FIRST_CALL_TRANSACTION + 5); +static final int TRANSACTION_getRecursiveBinder = (android.os.IBinder.FIRST_CALL_TRANSACTION + 6); +static final int TRANSACTION_takesAnInterface = (android.os.IBinder.FIRST_CALL_TRANSACTION + 7); +static final int TRANSACTION_takesAParcelable = (android.os.IBinder.FIRST_CALL_TRANSACTION + 8); +} +public static final int EXAMPLE_CONSTANT = 3; +public boolean isEnabled() throws android.os.RemoteException; +public int getState() throws android.os.RemoteException; +public java.lang.String getAddress() throws android.os.RemoteException; +/* Test long comment */ +public android.foo.ExampleParcelable[] getParcelables() throws android.os.RemoteException; +// Test short comment + +public boolean setScanMode(int mode, int duration) throws android.os.RemoteException; +/* Test long comment */// And short comment + +public void registerBinder(android.bar.IAuxInterface foo) throws android.os.RemoteException; +public android.test.IExampleInterface getRecursiveBinder() throws android.os.RemoteException; +public int takesAnInterface(android.test.IAuxInterface2 arg) throws android.os.RemoteException; +public int takesAParcelable(android.test.CompoundParcelable.Subclass1 arg, android.test.CompoundParcelable.Subclass2 arg2) throws android.os.RemoteException; +} +)"; + const char kExpectedJavaOutputOutlining[] = R"(/* * This file is auto-generated. DO NOT MODIFY. |