diff options
author | Jooyung Han <jooyung@google.com> | 2021-11-17 01:41:11 +0900 |
---|---|---|
committer | Jooyung Han <jooyung@google.com> | 2021-11-17 23:59:28 +0000 |
commit | 97be5845253b8a16d3448bd8cad2dd23b156732c (patch) | |
tree | 633478897d5b5955ee255f30cbe7587a50127fea | |
parent | 87c92e71f5edacb6c4424141d361f8d96e4ad440 (diff) | |
download | aidl-97be5845253b8a16d3448bd8cad2dd23b156732c.tar.gz |
Add @FixedSize union
@FixedSize union uses a custom implementation rather than std::variant
so that its value can have a stable/fixed layout and be passed via FMQ.
A custom implementation relies on the fact that @FixedSize
union/parcelable should have "trivially copyable" fields. So we can't
use it for union in general.
It would be nice if we could replace std::variant with it and have the
same implementation for union types. Maybe in the future.
Bug: 206496560
Test: golden_test.sh check
Test: aidl_integration_test (no regression)
atest fmq_test fmq_unit_test
Change-Id: I86351ecb1990818d0fe2faaad7c4b8c2c33881b5
21 files changed, 1875 insertions, 26 deletions
@@ -289,6 +289,7 @@ filegroup { "tests/android/aidl/tests/DeprecatedEnum.aidl", "tests/android/aidl/tests/DeprecatedParcelable.aidl", "tests/android/aidl/tests/GenericStructuredParcelable.aidl", + "tests/android/aidl/tests/FixedSize.aidl", "tests/android/aidl/tests/IDeprecated.aidl", "tests/android/aidl/tests/INamedCallback.aidl", "tests/android/aidl/tests/INewName.aidl", diff --git a/aidl_language.cpp b/aidl_language.cpp index b56e7ac5..e92086ae 100644 --- a/aidl_language.cpp +++ b/aidl_language.cpp @@ -160,7 +160,10 @@ const std::vector<AidlAnnotation::Schema>& AidlAnnotation::AllSchemas() { CONTEXT_TYPE_STRUCTURED_PARCELABLE | CONTEXT_TYPE_UNION | CONTEXT_TYPE_UNSTRUCTURED_PARCELABLE, {}}, - {AidlAnnotation::Type::FIXED_SIZE, "FixedSize", CONTEXT_TYPE_STRUCTURED_PARCELABLE, {}}, + {AidlAnnotation::Type::FIXED_SIZE, + "FixedSize", + CONTEXT_TYPE_STRUCTURED_PARCELABLE | CONTEXT_TYPE_UNION, + {}}, {AidlAnnotation::Type::DESCRIPTOR, "Descriptor", CONTEXT_TYPE_INTERFACE, diff --git a/aidl_to_cpp_common.cpp b/aidl_to_cpp_common.cpp index 3822f0e5..6a2f60ea 100644 --- a/aidl_to_cpp_common.cpp +++ b/aidl_to_cpp_common.cpp @@ -19,6 +19,7 @@ #include <android-base/stringprintf.h> #include <android-base/strings.h> +#include <limits> #include <set> #include <unordered_map> @@ -298,6 +299,39 @@ std::string TemplateDecl(const AidlParcelable& defined_type) { void GenerateParcelableComparisonOperators(CodeWriter& out, const AidlParcelable& parcelable) { std::set<string> operators{"<", ">", "==", ">=", "<=", "!="}; + + if (parcelable.AsUnionDeclaration() && parcelable.IsFixedSize()) { + auto name = parcelable.GetName(); + auto max_tag = parcelable.GetFields().back()->GetName(); + auto min_tag = parcelable.GetFields().front()->GetName(); + auto tmpl = R"--(static int _cmp(const {name}& _lhs, const {name}& _rhs) {{ + return _cmp_value(_lhs.getTag(), _rhs.getTag()) || _cmp_value_at<{max_tag}>(_lhs, _rhs); +}} +template <Tag _Tag> +static int _cmp_value_at(const {name}& _lhs, const {name}& _rhs) {{ + if constexpr (_Tag == {min_tag}) {{ + return _cmp_value(_lhs.get<_Tag>(), _rhs.get<_Tag>()); + }} else {{ + return (_lhs.getTag() == _Tag) + ? _cmp_value(_lhs.get<_Tag>(), _rhs.get<_Tag>()) + : _cmp_value_at<(Tag)(_Tag-1)>(_lhs, _rhs); + }} +}} +template <typename _Type> +static int _cmp_value(const _Type& _lhs, const _Type& _rhs) {{ + return (_lhs == _rhs) ? 0 : (_lhs < _rhs) ? -1 : 1; +}} +)--"; + out << fmt::format(tmpl, fmt::arg("name", name), fmt::arg("min_tag", min_tag), + fmt::arg("max_tag", max_tag)); + for (const auto& op : operators) { + out << "inline bool operator" << op << "(const " << name << "&_rhs) const {\n"; + out << " return _cmp(*this, _rhs) " << op << " 0;\n"; + out << "}\n"; + } + return; + } + bool is_empty = false; auto comparable = [&](const string& prefix) { @@ -396,25 +430,94 @@ std::string GetDeprecatedAttribute(const AidlCommentable& type) { return ""; } -const vector<string> UnionWriter::headers{ - "cassert", // __assert for logging - "type_traits", // std::is_same_v - "utility", // std::mode/forward for value - "variant", // std::variant for value -}; +size_t AlignmentOf(const AidlTypeSpecifier& type, const AidlTypenames& typenames) { + static map<string, size_t> alignment = { + {"boolean", 1}, {"byte", 1}, {"char", 2}, {"double", 8}, + {"float", 4}, {"int", 4}, {"long", 8}, + }; + + string name = type.GetName(); + if (auto enum_decl = typenames.GetEnumDeclaration(type); enum_decl) { + name = enum_decl->GetBackingType().GetName(); + } + // default to 0 for parcelable types + return alignment[name]; +} + +std::set<std::string> UnionWriter::GetHeaders(const AidlUnionDecl& decl) { + std::set<std::string> union_headers = { + "cassert", // __assert for logging + "type_traits", // std::is_same_v + "utility", // std::mode/forward for value + "variant", // union's impl + }; + if (decl.IsFixedSize()) { + union_headers.insert("tuple"); // fixed-sized union's typelist + } + return union_headers; +} + +// fixed-sized union class looks like: +// class Union { +// public: +// enum Tag : uint8_t { +// field1 = 0, +// field2, +// }; +// ... methods ... +// private: +// Tag _tag; +// union { +// type1 field1; +// type2 field2; +// } _value; +// }; void UnionWriter::PrivateFields(CodeWriter& out) const { - vector<string> field_types; - for (const auto& f : decl.GetFields()) { - field_types.push_back(name_of(f->GetType(), typenames)); + if (decl.IsFixedSize()) { + AIDL_FATAL_IF(decl.GetFields().empty(), decl) << "Union '" << decl.GetName() << "' is empty."; + const auto& first_field = decl.GetFields()[0]; + const auto& default_name = first_field->GetName(); + const auto& default_value = name_of(first_field->GetType(), typenames) + "(" + + first_field->ValueString(decorator) + ")"; + + out << "Tag _tag __attribute__((aligned (1))) = " << default_name << ";\n"; + out << "union {\n"; + out.Indent(); + for (const auto& f : decl.GetFields()) { + const auto& fn = f->GetName(); + out << name_of(f->GetType(), typenames) << " " << fn; + if (decl.IsFixedSize()) { + int alignment = AlignmentOf(f->GetType(), typenames); + if (alignment > 0) { + out << " __attribute__((aligned (" << std::to_string(alignment) << ")))"; + } + } + if (fn == default_name) { + out << " = " << default_value; + } + out << ";\n"; + } + out.Dedent(); + out << "} _value;\n"; + } else { + vector<string> field_types; + for (const auto& f : decl.GetFields()) { + field_types.push_back(name_of(f->GetType(), typenames)); + } + out << "std::variant<" + Join(field_types, ", ") + "> _value;\n"; } - out << "std::variant<" + Join(field_types, ", ") + "> _value;\n"; } void UnionWriter::PublicFields(CodeWriter& out) const { - auto tag_type = typenames.MakeResolvedType(AIDL_LOCATION_HERE, "int", /* is_array= */ false); - - out << "enum Tag : " << name_of(*tag_type, typenames) << " {\n"; + std::string tag_type = "int32_t"; + if (decl.IsFixedSize()) { + // For @FixedSize union, we use a smaller type for a tag to minimize the size overhead. + AIDL_FATAL_IF(decl.GetFields().size() > std::numeric_limits<uint8_t>::max(), decl) + << "Too many fields for @FixedSize"; + tag_type = "uint8_t"; + } + out << "enum Tag : " << tag_type << " {\n"; bool is_first = true; for (const auto& f : decl.GetFields()) { out << " " << f->GetName(); @@ -427,13 +530,49 @@ void UnionWriter::PublicFields(CodeWriter& out) const { const auto& name = decl.GetName(); - AIDL_FATAL_IF(decl.GetFields().empty(), decl) << "Union '" << name << "' is empty."; - const auto& first_field = decl.GetFields()[0]; - const auto& default_name = first_field->GetName(); - const auto& default_value = - name_of(first_field->GetType(), typenames) + "(" + first_field->ValueString(decorator) + ")"; + if (decl.IsFixedSize()) { + vector<string> field_types; + for (const auto& f : decl.GetFields()) { + field_types.push_back(name_of(f->GetType(), typenames)); + } + auto typelist = Join(field_types, ", "); + auto tmpl = R"--( +template <Tag _Tag> +using _at = typename std::tuple_element<_Tag, std::tuple<{typelist}>>::type; +template <Tag _Tag, typename _Type> +static {name} make(_Type&& _arg) {{ + {name} _inst; + _inst.set<_Tag>(std::forward<_Type>(_arg)); + return _inst; +}} +constexpr Tag getTag() const {{ + return _tag; +}} +template <Tag _Tag> +const _at<_Tag>& get() const {{ + if (_Tag != _tag) {{ __assert2(__FILE__, __LINE__, __PRETTY_FUNCTION__, "bad access: a wrong tag"); }} + return *(_at<_Tag>*)(&_value); +}} +template <Tag _Tag> +_at<_Tag>& get() {{ + if (_Tag != _tag) {{ __assert2(__FILE__, __LINE__, __PRETTY_FUNCTION__, "bad access: a wrong tag"); }} + return *(_at<_Tag>*)(&_value); +}} +template <Tag _Tag, typename _Type> +void set(_Type&& _arg) {{ + _tag = _Tag; + get<_Tag>() = std::forward<_Type>(_arg); +}} +)--"; + out << fmt::format(tmpl, fmt::arg("name", name), fmt::arg("typelist", typelist)); + } else { + AIDL_FATAL_IF(decl.GetFields().empty(), decl) << "Union '" << name << "' is empty."; + const auto& first_field = decl.GetFields()[0]; + const auto& default_name = first_field->GetName(); + const auto& default_value = name_of(first_field->GetType(), typenames) + "(" + + first_field->ValueString(decorator) + ")"; - auto tmpl = R"--( + auto tmpl = R"--( template<typename _Tp> static constexpr bool _not_self = !std::is_same_v<std::remove_cv_t<std::remove_reference_t<_Tp>>, {name}>; @@ -480,11 +619,14 @@ void set(_Tp&&... _args) {{ }} )--"; - out << fmt::format(tmpl, fmt::arg("name", name), fmt::arg("default_name", default_name), - fmt::arg("default_value", default_value)); + out << fmt::format(tmpl, fmt::arg("name", name), fmt::arg("default_name", default_name), + fmt::arg("default_value", default_value)); + } } void UnionWriter::ReadFromParcel(CodeWriter& out, const ParcelWriterContext& ctx) const { + // Even though @FixedSize union may use a smaller type than int32_t, we need to read/write it + // as if it is int32_t for compatibility with other bckends. auto tag_type = typenames.MakeResolvedType(AIDL_LOCATION_HERE, "int", /* is_array= */ false); const string tag = "_aidl_tag"; @@ -527,6 +669,8 @@ void UnionWriter::ReadFromParcel(CodeWriter& out, const ParcelWriterContext& ctx } void UnionWriter::WriteToParcel(CodeWriter& out, const ParcelWriterContext& ctx) const { + // Even though @FixedSize union may use a smaller type than int32_t, we need to read/write it + // as if it is int32_t for compatibility with other bckends. auto tag_type = typenames.MakeResolvedType(AIDL_LOCATION_HERE, "int", /* is_array= */ false); const string tag = "_aidl_tag"; diff --git a/aidl_to_cpp_common.h b/aidl_to_cpp_common.h index df657cee..e639a7c5 100644 --- a/aidl_to_cpp_common.h +++ b/aidl_to_cpp_common.h @@ -114,7 +114,8 @@ struct UnionWriter { const AidlTypenames& typenames; const std::function<std::string(const AidlTypeSpecifier&, const AidlTypenames&)> name_of; const ::ConstantValueDecorator& decorator; - static const std::vector<std::string> headers; + + static std::set<std::string> GetHeaders(const AidlUnionDecl&); void PrivateFields(CodeWriter& out) const; void PublicFields(CodeWriter& out) const; diff --git a/generate_cpp.cpp b/generate_cpp.cpp index c7a36ae2..f3c29576 100644 --- a/generate_cpp.cpp +++ b/generate_cpp.cpp @@ -1229,9 +1229,10 @@ void GenerateHeaderIncludes(CodeWriter& out, const AidlDefinedType& defined_type includes.insert("tuple"); // std::tie in comparison operators } - void Visit(const AidlUnionDecl&) override { + void Visit(const AidlUnionDecl& union_decl) override { AddParcelableCommonHeaders(); - includes.insert(std::begin(UnionWriter::headers), std::end(UnionWriter::headers)); + auto union_headers = cpp::UnionWriter::GetHeaders(union_decl); + includes.insert(std::begin(union_headers), std::end(union_headers)); } void Visit(const AidlEnumDeclaration&) override { diff --git a/generate_ndk.cpp b/generate_ndk.cpp index 2af14a07..0863149f 100644 --- a/generate_ndk.cpp +++ b/generate_ndk.cpp @@ -310,7 +310,8 @@ void GenerateHeaderIncludes(CodeWriter& out, const AidlTypenames& types, includes.insert("android/binder_interface_utils.h"); includes.insert("android/binder_parcelable_utils.h"); includes.insert("android/binder_to_string.h"); // used by toString() - includes.insert(std::begin(cpp::UnionWriter::headers), std::end(cpp::UnionWriter::headers)); + auto union_headers = cpp::UnionWriter::GetHeaders(union_decl); + includes.insert(std::begin(union_headers), std::end(union_headers)); } void Visit(const AidlEnumDeclaration& enum_decl) override { diff --git a/tests/android/aidl/tests/FixedSize.aidl b/tests/android/aidl/tests/FixedSize.aidl new file mode 100644 index 00000000..295199f3 --- /dev/null +++ b/tests/android/aidl/tests/FixedSize.aidl @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.aidl.tests; + +import android.aidl.tests.LongEnum; + +parcelable FixedSize { + @FixedSize + parcelable FixedParcelable { + boolean booleanValue; + byte byteValue; + char charValue; + int intValue; + long longValue; + float floatValue; + double doubleValue; + LongEnum enumValue = LongEnum.FOO; + FixedUnion parcelableValue; + } + + @FixedSize + union FixedUnion { + boolean booleanValue = false; + byte byteValue; + char charValue; + int intValue; + long longValue; + float floatValue; + double doubleValue; + LongEnum enumValue; + } +} diff --git a/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/FixedSize.cpp b/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/FixedSize.cpp new file mode 100644 index 00000000..5ccbcee4 --- /dev/null +++ b/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/FixedSize.cpp @@ -0,0 +1,275 @@ +#include <android/aidl/tests/FixedSize.h> + +namespace android { +namespace aidl { +namespace tests { +::android::status_t FixedSize::readFromParcel(const ::android::Parcel* _aidl_parcel) { + ::android::status_t _aidl_ret_status = ::android::OK; + [[maybe_unused]] size_t _aidl_start_pos = _aidl_parcel->dataPosition(); + int32_t _aidl_parcelable_raw_size = _aidl_parcel->readInt32(); + if (_aidl_parcelable_raw_size < 0) return ::android::BAD_VALUE; + [[maybe_unused]] size_t _aidl_parcelable_size = static_cast<size_t>(_aidl_parcelable_raw_size); + if (_aidl_start_pos > SIZE_MAX - _aidl_parcelable_size) return ::android::BAD_VALUE; + _aidl_parcel->setDataPosition(_aidl_start_pos + _aidl_parcelable_size); + return _aidl_ret_status; +} +::android::status_t FixedSize::writeToParcel(::android::Parcel* _aidl_parcel) const { + ::android::status_t _aidl_ret_status = ::android::OK; + auto _aidl_start_pos = _aidl_parcel->dataPosition(); + _aidl_parcel->writeInt32(0); + auto _aidl_end_pos = _aidl_parcel->dataPosition(); + _aidl_parcel->setDataPosition(_aidl_start_pos); + _aidl_parcel->writeInt32(_aidl_end_pos - _aidl_start_pos); + _aidl_parcel->setDataPosition(_aidl_end_pos); + return _aidl_ret_status; +} +} // namespace tests +} // namespace aidl +} // namespace android +#include <android/aidl/tests/FixedSize.h> + +namespace android { +namespace aidl { +namespace tests { +::android::status_t FixedSize::FixedParcelable::readFromParcel(const ::android::Parcel* _aidl_parcel) { + ::android::status_t _aidl_ret_status = ::android::OK; + [[maybe_unused]] size_t _aidl_start_pos = _aidl_parcel->dataPosition(); + int32_t _aidl_parcelable_raw_size = _aidl_parcel->readInt32(); + if (_aidl_parcelable_raw_size < 0) return ::android::BAD_VALUE; + [[maybe_unused]] size_t _aidl_parcelable_size = static_cast<size_t>(_aidl_parcelable_raw_size); + if (_aidl_start_pos > SIZE_MAX - _aidl_parcelable_size) return ::android::BAD_VALUE; + if (_aidl_parcel->dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) { + _aidl_parcel->setDataPosition(_aidl_start_pos + _aidl_parcelable_size); + return _aidl_ret_status; + } + _aidl_ret_status = _aidl_parcel->readBool(&booleanValue); + if (((_aidl_ret_status) != (::android::OK))) { + return _aidl_ret_status; + } + if (_aidl_parcel->dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) { + _aidl_parcel->setDataPosition(_aidl_start_pos + _aidl_parcelable_size); + return _aidl_ret_status; + } + _aidl_ret_status = _aidl_parcel->readByte(&byteValue); + if (((_aidl_ret_status) != (::android::OK))) { + return _aidl_ret_status; + } + if (_aidl_parcel->dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) { + _aidl_parcel->setDataPosition(_aidl_start_pos + _aidl_parcelable_size); + return _aidl_ret_status; + } + _aidl_ret_status = _aidl_parcel->readChar(&charValue); + if (((_aidl_ret_status) != (::android::OK))) { + return _aidl_ret_status; + } + if (_aidl_parcel->dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) { + _aidl_parcel->setDataPosition(_aidl_start_pos + _aidl_parcelable_size); + return _aidl_ret_status; + } + _aidl_ret_status = _aidl_parcel->readInt32(&intValue); + if (((_aidl_ret_status) != (::android::OK))) { + return _aidl_ret_status; + } + if (_aidl_parcel->dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) { + _aidl_parcel->setDataPosition(_aidl_start_pos + _aidl_parcelable_size); + return _aidl_ret_status; + } + _aidl_ret_status = _aidl_parcel->readInt64(&longValue); + if (((_aidl_ret_status) != (::android::OK))) { + return _aidl_ret_status; + } + if (_aidl_parcel->dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) { + _aidl_parcel->setDataPosition(_aidl_start_pos + _aidl_parcelable_size); + return _aidl_ret_status; + } + _aidl_ret_status = _aidl_parcel->readFloat(&floatValue); + if (((_aidl_ret_status) != (::android::OK))) { + return _aidl_ret_status; + } + if (_aidl_parcel->dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) { + _aidl_parcel->setDataPosition(_aidl_start_pos + _aidl_parcelable_size); + return _aidl_ret_status; + } + _aidl_ret_status = _aidl_parcel->readDouble(&doubleValue); + if (((_aidl_ret_status) != (::android::OK))) { + return _aidl_ret_status; + } + if (_aidl_parcel->dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) { + _aidl_parcel->setDataPosition(_aidl_start_pos + _aidl_parcelable_size); + return _aidl_ret_status; + } + _aidl_ret_status = _aidl_parcel->readInt64(reinterpret_cast<int64_t *>(&enumValue)); + if (((_aidl_ret_status) != (::android::OK))) { + return _aidl_ret_status; + } + if (_aidl_parcel->dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) { + _aidl_parcel->setDataPosition(_aidl_start_pos + _aidl_parcelable_size); + return _aidl_ret_status; + } + _aidl_ret_status = _aidl_parcel->readParcelable(&parcelableValue); + if (((_aidl_ret_status) != (::android::OK))) { + return _aidl_ret_status; + } + _aidl_parcel->setDataPosition(_aidl_start_pos + _aidl_parcelable_size); + return _aidl_ret_status; +} +::android::status_t FixedSize::FixedParcelable::writeToParcel(::android::Parcel* _aidl_parcel) const { + ::android::status_t _aidl_ret_status = ::android::OK; + auto _aidl_start_pos = _aidl_parcel->dataPosition(); + _aidl_parcel->writeInt32(0); + _aidl_ret_status = _aidl_parcel->writeBool(booleanValue); + if (((_aidl_ret_status) != (::android::OK))) { + return _aidl_ret_status; + } + _aidl_ret_status = _aidl_parcel->writeByte(byteValue); + if (((_aidl_ret_status) != (::android::OK))) { + return _aidl_ret_status; + } + _aidl_ret_status = _aidl_parcel->writeChar(charValue); + if (((_aidl_ret_status) != (::android::OK))) { + return _aidl_ret_status; + } + _aidl_ret_status = _aidl_parcel->writeInt32(intValue); + if (((_aidl_ret_status) != (::android::OK))) { + return _aidl_ret_status; + } + _aidl_ret_status = _aidl_parcel->writeInt64(longValue); + if (((_aidl_ret_status) != (::android::OK))) { + return _aidl_ret_status; + } + _aidl_ret_status = _aidl_parcel->writeFloat(floatValue); + if (((_aidl_ret_status) != (::android::OK))) { + return _aidl_ret_status; + } + _aidl_ret_status = _aidl_parcel->writeDouble(doubleValue); + if (((_aidl_ret_status) != (::android::OK))) { + return _aidl_ret_status; + } + _aidl_ret_status = _aidl_parcel->writeInt64(static_cast<int64_t>(enumValue)); + if (((_aidl_ret_status) != (::android::OK))) { + return _aidl_ret_status; + } + _aidl_ret_status = _aidl_parcel->writeParcelable(parcelableValue); + if (((_aidl_ret_status) != (::android::OK))) { + return _aidl_ret_status; + } + auto _aidl_end_pos = _aidl_parcel->dataPosition(); + _aidl_parcel->setDataPosition(_aidl_start_pos); + _aidl_parcel->writeInt32(_aidl_end_pos - _aidl_start_pos); + _aidl_parcel->setDataPosition(_aidl_end_pos); + return _aidl_ret_status; +} +} // namespace tests +} // namespace aidl +} // namespace android +#include <android/aidl/tests/FixedSize.h> + +namespace android { +namespace aidl { +namespace tests { +::android::status_t FixedSize::FixedUnion::readFromParcel(const ::android::Parcel* _aidl_parcel) { + ::android::status_t _aidl_ret_status; + int32_t _aidl_tag; + if ((_aidl_ret_status = _aidl_parcel->readInt32(&_aidl_tag)) != ::android::OK) return _aidl_ret_status; + switch (_aidl_tag) { + case booleanValue: { + bool _aidl_value; + if ((_aidl_ret_status = _aidl_parcel->readBool(&_aidl_value)) != ::android::OK) return _aidl_ret_status; + if constexpr (std::is_trivially_copyable_v<bool>) { + set<booleanValue>(_aidl_value); + } else { + // NOLINTNEXTLINE(performance-move-const-arg) + set<booleanValue>(std::move(_aidl_value)); + } + return ::android::OK; } + case byteValue: { + int8_t _aidl_value; + if ((_aidl_ret_status = _aidl_parcel->readByte(&_aidl_value)) != ::android::OK) return _aidl_ret_status; + if constexpr (std::is_trivially_copyable_v<int8_t>) { + set<byteValue>(_aidl_value); + } else { + // NOLINTNEXTLINE(performance-move-const-arg) + set<byteValue>(std::move(_aidl_value)); + } + return ::android::OK; } + case charValue: { + char16_t _aidl_value; + if ((_aidl_ret_status = _aidl_parcel->readChar(&_aidl_value)) != ::android::OK) return _aidl_ret_status; + if constexpr (std::is_trivially_copyable_v<char16_t>) { + set<charValue>(_aidl_value); + } else { + // NOLINTNEXTLINE(performance-move-const-arg) + set<charValue>(std::move(_aidl_value)); + } + return ::android::OK; } + case intValue: { + int32_t _aidl_value; + if ((_aidl_ret_status = _aidl_parcel->readInt32(&_aidl_value)) != ::android::OK) return _aidl_ret_status; + if constexpr (std::is_trivially_copyable_v<int32_t>) { + set<intValue>(_aidl_value); + } else { + // NOLINTNEXTLINE(performance-move-const-arg) + set<intValue>(std::move(_aidl_value)); + } + return ::android::OK; } + case longValue: { + int64_t _aidl_value; + if ((_aidl_ret_status = _aidl_parcel->readInt64(&_aidl_value)) != ::android::OK) return _aidl_ret_status; + if constexpr (std::is_trivially_copyable_v<int64_t>) { + set<longValue>(_aidl_value); + } else { + // NOLINTNEXTLINE(performance-move-const-arg) + set<longValue>(std::move(_aidl_value)); + } + return ::android::OK; } + case floatValue: { + float _aidl_value; + if ((_aidl_ret_status = _aidl_parcel->readFloat(&_aidl_value)) != ::android::OK) return _aidl_ret_status; + if constexpr (std::is_trivially_copyable_v<float>) { + set<floatValue>(_aidl_value); + } else { + // NOLINTNEXTLINE(performance-move-const-arg) + set<floatValue>(std::move(_aidl_value)); + } + return ::android::OK; } + case doubleValue: { + double _aidl_value; + if ((_aidl_ret_status = _aidl_parcel->readDouble(&_aidl_value)) != ::android::OK) return _aidl_ret_status; + if constexpr (std::is_trivially_copyable_v<double>) { + set<doubleValue>(_aidl_value); + } else { + // NOLINTNEXTLINE(performance-move-const-arg) + set<doubleValue>(std::move(_aidl_value)); + } + return ::android::OK; } + case enumValue: { + ::android::aidl::tests::LongEnum _aidl_value; + if ((_aidl_ret_status = _aidl_parcel->readInt64(reinterpret_cast<int64_t *>(&_aidl_value))) != ::android::OK) return _aidl_ret_status; + if constexpr (std::is_trivially_copyable_v<::android::aidl::tests::LongEnum>) { + set<enumValue>(_aidl_value); + } else { + // NOLINTNEXTLINE(performance-move-const-arg) + set<enumValue>(std::move(_aidl_value)); + } + return ::android::OK; } + } + return ::android::BAD_VALUE; +} +::android::status_t FixedSize::FixedUnion::writeToParcel(::android::Parcel* _aidl_parcel) const { + ::android::status_t _aidl_ret_status = _aidl_parcel->writeInt32(getTag()); + if (_aidl_ret_status != ::android::OK) return _aidl_ret_status; + switch (getTag()) { + case booleanValue: return _aidl_parcel->writeBool(get<booleanValue>()); + case byteValue: return _aidl_parcel->writeByte(get<byteValue>()); + case charValue: return _aidl_parcel->writeChar(get<charValue>()); + case intValue: return _aidl_parcel->writeInt32(get<intValue>()); + case longValue: return _aidl_parcel->writeInt64(get<longValue>()); + case floatValue: return _aidl_parcel->writeFloat(get<floatValue>()); + case doubleValue: return _aidl_parcel->writeDouble(get<doubleValue>()); + case enumValue: return _aidl_parcel->writeInt64(static_cast<int64_t>(get<enumValue>())); + } + __assert2(__FILE__, __LINE__, __PRETTY_FUNCTION__, "can't reach here"); +} +} // namespace tests +} // namespace aidl +} // namespace android diff --git a/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/FixedSize.cpp.d b/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/FixedSize.cpp.d new file mode 100644 index 00000000..b5640414 --- /dev/null +++ b/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/FixedSize.cpp.d @@ -0,0 +1,3 @@ +out/soong/.intermediates/system/tools/aidl/aidl-test-interface-cpp-source/gen/android/aidl/tests/FixedSize.cpp : \ + system/tools/aidl/tests/android/aidl/tests/FixedSize.aidl \ + system/tools/aidl/tests/android/aidl/tests/LongEnum.aidl diff --git a/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/BnFixedSize.h b/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/BnFixedSize.h new file mode 100644 index 00000000..ce72aa31 --- /dev/null +++ b/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/BnFixedSize.h @@ -0,0 +1 @@ +#error TODO(b/111362593) parcelables do not have bn classes
\ No newline at end of file diff --git a/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/BpFixedSize.h b/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/BpFixedSize.h new file mode 100644 index 00000000..27af6b1c --- /dev/null +++ b/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/BpFixedSize.h @@ -0,0 +1 @@ +#error TODO(b/111362593) parcelables do not have bp classes
\ No newline at end of file diff --git a/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/FixedSize.h b/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/FixedSize.h new file mode 100644 index 00000000..2c889e7b --- /dev/null +++ b/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/FixedSize.h @@ -0,0 +1,220 @@ +#pragma once + +#include <android/aidl/tests/FixedSize.h> +#include <android/aidl/tests/LongEnum.h> +#include <android/binder_to_string.h> +#include <binder/Parcel.h> +#include <binder/Status.h> +#include <cassert> +#include <cstdint> +#include <tuple> +#include <type_traits> +#include <utility> +#include <utils/String16.h> +#include <variant> + +#ifndef __BIONIC__ +#define __assert2(a,b,c,d) ((void)0) +#endif + +namespace android { +namespace aidl { +namespace tests { +class FixedSize : public ::android::Parcelable { +public: + class FixedUnion : public ::android::Parcelable { + public: + enum Tag : uint8_t { + booleanValue = 0, // boolean booleanValue; + byteValue, // byte byteValue; + charValue, // char charValue; + intValue, // int intValue; + longValue, // long longValue; + floatValue, // float floatValue; + doubleValue, // double doubleValue; + enumValue, // android.aidl.tests.LongEnum enumValue; + }; + + template <Tag _Tag> + using _at = typename std::tuple_element<_Tag, std::tuple<bool, int8_t, char16_t, int32_t, int64_t, float, double, ::android::aidl::tests::LongEnum>>::type; + template <Tag _Tag, typename _Type> + static FixedUnion make(_Type&& _arg) { + FixedUnion _inst; + _inst.set<_Tag>(std::forward<_Type>(_arg)); + return _inst; + } + constexpr Tag getTag() const { + return _tag; + } + template <Tag _Tag> + const _at<_Tag>& get() const { + if (_Tag != _tag) { __assert2(__FILE__, __LINE__, __PRETTY_FUNCTION__, "bad access: a wrong tag"); } + return *(_at<_Tag>*)(&_value); + } + template <Tag _Tag> + _at<_Tag>& get() { + if (_Tag != _tag) { __assert2(__FILE__, __LINE__, __PRETTY_FUNCTION__, "bad access: a wrong tag"); } + return *(_at<_Tag>*)(&_value); + } + template <Tag _Tag, typename _Type> + void set(_Type&& _arg) { + _tag = _Tag; + get<_Tag>() = std::forward<_Type>(_arg); + } + static int _cmp(const FixedUnion& _lhs, const FixedUnion& _rhs) { + return _cmp_value(_lhs.getTag(), _rhs.getTag()) || _cmp_value_at<enumValue>(_lhs, _rhs); + } + template <Tag _Tag> + static int _cmp_value_at(const FixedUnion& _lhs, const FixedUnion& _rhs) { + if constexpr (_Tag == booleanValue) { + return _cmp_value(_lhs.get<_Tag>(), _rhs.get<_Tag>()); + } else { + return (_lhs.getTag() == _Tag) + ? _cmp_value(_lhs.get<_Tag>(), _rhs.get<_Tag>()) + : _cmp_value_at<(Tag)(_Tag-1)>(_lhs, _rhs); + } + } + template <typename _Type> + static int _cmp_value(const _Type& _lhs, const _Type& _rhs) { + return (_lhs == _rhs) ? 0 : (_lhs < _rhs) ? -1 : 1; + } + inline bool operator!=(const FixedUnion&_rhs) const { + return _cmp(*this, _rhs) != 0; + } + inline bool operator<(const FixedUnion&_rhs) const { + return _cmp(*this, _rhs) < 0; + } + inline bool operator<=(const FixedUnion&_rhs) const { + return _cmp(*this, _rhs) <= 0; + } + inline bool operator==(const FixedUnion&_rhs) const { + return _cmp(*this, _rhs) == 0; + } + inline bool operator>(const FixedUnion&_rhs) const { + return _cmp(*this, _rhs) > 0; + } + inline bool operator>=(const FixedUnion&_rhs) const { + return _cmp(*this, _rhs) >= 0; + } + ::android::status_t readFromParcel(const ::android::Parcel* _aidl_parcel) final; + ::android::status_t writeToParcel(::android::Parcel* _aidl_parcel) const final; + static const ::android::String16& getParcelableDescriptor() { + static const ::android::StaticString16 DESCIPTOR (u"android.aidl.tests.FixedSize.FixedUnion"); + return DESCIPTOR; + } + inline std::string toString() const { + std::ostringstream os; + os << "FixedUnion{"; + switch (getTag()) { + case booleanValue: os << "booleanValue: " << ::android::internal::ToString(get<booleanValue>()); break; + case byteValue: os << "byteValue: " << ::android::internal::ToString(get<byteValue>()); break; + case charValue: os << "charValue: " << ::android::internal::ToString(get<charValue>()); break; + case intValue: os << "intValue: " << ::android::internal::ToString(get<intValue>()); break; + case longValue: os << "longValue: " << ::android::internal::ToString(get<longValue>()); break; + case floatValue: os << "floatValue: " << ::android::internal::ToString(get<floatValue>()); break; + case doubleValue: os << "doubleValue: " << ::android::internal::ToString(get<doubleValue>()); break; + case enumValue: os << "enumValue: " << ::android::internal::ToString(get<enumValue>()); break; + } + os << "}"; + return os.str(); + } + private: + Tag _tag __attribute__((aligned (1))) = booleanValue; + union { + bool booleanValue __attribute__((aligned (1))) = bool(false); + int8_t byteValue __attribute__((aligned (1))); + char16_t charValue __attribute__((aligned (2))); + int32_t intValue __attribute__((aligned (4))); + int64_t longValue __attribute__((aligned (8))); + float floatValue __attribute__((aligned (4))); + double doubleValue __attribute__((aligned (8))); + ::android::aidl::tests::LongEnum enumValue __attribute__((aligned (8))); + } _value; + }; // class FixedUnion + class FixedParcelable : public ::android::Parcelable { + public: + bool booleanValue = false; + int8_t byteValue = 0; + char16_t charValue; + int32_t intValue = 0; + int64_t longValue = 0L; + float floatValue = 0.000000f; + double doubleValue = 0.000000; + ::android::aidl::tests::LongEnum enumValue = ::android::aidl::tests::LongEnum::FOO; + ::android::aidl::tests::FixedSize::FixedUnion parcelableValue; + inline bool operator!=(const FixedParcelable& rhs) const { + return std::tie(booleanValue, byteValue, charValue, intValue, longValue, floatValue, doubleValue, enumValue, parcelableValue) != std::tie(rhs.booleanValue, rhs.byteValue, rhs.charValue, rhs.intValue, rhs.longValue, rhs.floatValue, rhs.doubleValue, rhs.enumValue, rhs.parcelableValue); + } + inline bool operator<(const FixedParcelable& rhs) const { + return std::tie(booleanValue, byteValue, charValue, intValue, longValue, floatValue, doubleValue, enumValue, parcelableValue) < std::tie(rhs.booleanValue, rhs.byteValue, rhs.charValue, rhs.intValue, rhs.longValue, rhs.floatValue, rhs.doubleValue, rhs.enumValue, rhs.parcelableValue); + } + inline bool operator<=(const FixedParcelable& rhs) const { + return std::tie(booleanValue, byteValue, charValue, intValue, longValue, floatValue, doubleValue, enumValue, parcelableValue) <= std::tie(rhs.booleanValue, rhs.byteValue, rhs.charValue, rhs.intValue, rhs.longValue, rhs.floatValue, rhs.doubleValue, rhs.enumValue, rhs.parcelableValue); + } + inline bool operator==(const FixedParcelable& rhs) const { + return std::tie(booleanValue, byteValue, charValue, intValue, longValue, floatValue, doubleValue, enumValue, parcelableValue) == std::tie(rhs.booleanValue, rhs.byteValue, rhs.charValue, rhs.intValue, rhs.longValue, rhs.floatValue, rhs.doubleValue, rhs.enumValue, rhs.parcelableValue); + } + inline bool operator>(const FixedParcelable& rhs) const { + return std::tie(booleanValue, byteValue, charValue, intValue, longValue, floatValue, doubleValue, enumValue, parcelableValue) > std::tie(rhs.booleanValue, rhs.byteValue, rhs.charValue, rhs.intValue, rhs.longValue, rhs.floatValue, rhs.doubleValue, rhs.enumValue, rhs.parcelableValue); + } + inline bool operator>=(const FixedParcelable& rhs) const { + return std::tie(booleanValue, byteValue, charValue, intValue, longValue, floatValue, doubleValue, enumValue, parcelableValue) >= std::tie(rhs.booleanValue, rhs.byteValue, rhs.charValue, rhs.intValue, rhs.longValue, rhs.floatValue, rhs.doubleValue, rhs.enumValue, rhs.parcelableValue); + } + + ::android::status_t readFromParcel(const ::android::Parcel* _aidl_parcel) final; + ::android::status_t writeToParcel(::android::Parcel* _aidl_parcel) const final; + static const ::android::String16& getParcelableDescriptor() { + static const ::android::StaticString16 DESCIPTOR (u"android.aidl.tests.FixedSize.FixedParcelable"); + return DESCIPTOR; + } + inline std::string toString() const { + std::ostringstream os; + os << "FixedParcelable{"; + os << "booleanValue: " << ::android::internal::ToString(booleanValue); + os << ", byteValue: " << ::android::internal::ToString(byteValue); + os << ", charValue: " << ::android::internal::ToString(charValue); + os << ", intValue: " << ::android::internal::ToString(intValue); + os << ", longValue: " << ::android::internal::ToString(longValue); + os << ", floatValue: " << ::android::internal::ToString(floatValue); + os << ", doubleValue: " << ::android::internal::ToString(doubleValue); + os << ", enumValue: " << ::android::internal::ToString(enumValue); + os << ", parcelableValue: " << ::android::internal::ToString(parcelableValue); + os << "}"; + return os.str(); + } + }; // class FixedParcelable + inline bool operator!=(const FixedSize&) const { + return std::tie() != std::tie(); + } + inline bool operator<(const FixedSize&) const { + return std::tie() < std::tie(); + } + inline bool operator<=(const FixedSize&) const { + return std::tie() <= std::tie(); + } + inline bool operator==(const FixedSize&) const { + return std::tie() == std::tie(); + } + inline bool operator>(const FixedSize&) const { + return std::tie() > std::tie(); + } + inline bool operator>=(const FixedSize&) const { + return std::tie() >= std::tie(); + } + + ::android::status_t readFromParcel(const ::android::Parcel* _aidl_parcel) final; + ::android::status_t writeToParcel(::android::Parcel* _aidl_parcel) const final; + static const ::android::String16& getParcelableDescriptor() { + static const ::android::StaticString16 DESCIPTOR (u"android.aidl.tests.FixedSize"); + return DESCIPTOR; + } + inline std::string toString() const { + std::ostringstream os; + os << "FixedSize{"; + os << "}"; + return os.str(); + } +}; // class FixedSize +} // namespace tests +} // namespace aidl +} // namespace android diff --git a/tests/golden_output/aidl-test-interface-java-source/gen/android/aidl/tests/FixedSize.java b/tests/golden_output/aidl-test-interface-java-source/gen/android/aidl/tests/FixedSize.java new file mode 100644 index 00000000..43ae1252 --- /dev/null +++ b/tests/golden_output/aidl-test-interface-java-source/gen/android/aidl/tests/FixedSize.java @@ -0,0 +1,408 @@ +/* + * This file is auto-generated. DO NOT MODIFY. + */ +package android.aidl.tests; +public class FixedSize implements android.os.Parcelable +{ + public static final android.os.Parcelable.Creator<FixedSize> CREATOR = new android.os.Parcelable.Creator<FixedSize>() { + @Override + public FixedSize createFromParcel(android.os.Parcel _aidl_source) { + FixedSize _aidl_out = new FixedSize(); + _aidl_out.readFromParcel(_aidl_source); + return _aidl_out; + } + @Override + public FixedSize[] newArray(int _aidl_size) { + return new FixedSize[_aidl_size]; + } + }; + @Override public final void writeToParcel(android.os.Parcel _aidl_parcel, int _aidl_flag) + { + int _aidl_start_pos = _aidl_parcel.dataPosition(); + _aidl_parcel.writeInt(0); + int _aidl_end_pos = _aidl_parcel.dataPosition(); + _aidl_parcel.setDataPosition(_aidl_start_pos); + _aidl_parcel.writeInt(_aidl_end_pos - _aidl_start_pos); + _aidl_parcel.setDataPosition(_aidl_end_pos); + } + public final void readFromParcel(android.os.Parcel _aidl_parcel) + { + int _aidl_start_pos = _aidl_parcel.dataPosition(); + int _aidl_parcelable_size = _aidl_parcel.readInt(); + try { + if (_aidl_parcelable_size < 0) return; + } finally { + if (_aidl_start_pos > (Integer.MAX_VALUE - _aidl_parcelable_size)) { + throw new android.os.BadParcelableException("Overflow in the size of parcelable"); + } + _aidl_parcel.setDataPosition(_aidl_start_pos + _aidl_parcelable_size); + } + } + @Override + public int describeContents() { + int _mask = 0; + return _mask; + } + public static class FixedParcelable implements android.os.Parcelable + { + public boolean booleanValue = false; + public byte byteValue = 0; + public char charValue; + public int intValue = 0; + public long longValue = 0L; + public float floatValue = 0.000000f; + public double doubleValue = 0.000000; + public long enumValue = android.aidl.tests.LongEnum.FOO; + public android.aidl.tests.FixedSize.FixedUnion parcelableValue; + public static final android.os.Parcelable.Creator<FixedParcelable> CREATOR = new android.os.Parcelable.Creator<FixedParcelable>() { + @Override + public FixedParcelable createFromParcel(android.os.Parcel _aidl_source) { + FixedParcelable _aidl_out = new FixedParcelable(); + _aidl_out.readFromParcel(_aidl_source); + return _aidl_out; + } + @Override + public FixedParcelable[] newArray(int _aidl_size) { + return new FixedParcelable[_aidl_size]; + } + }; + @Override public final void writeToParcel(android.os.Parcel _aidl_parcel, int _aidl_flag) + { + int _aidl_start_pos = _aidl_parcel.dataPosition(); + _aidl_parcel.writeInt(0); + _aidl_parcel.writeBoolean(booleanValue); + _aidl_parcel.writeByte(byteValue); + _aidl_parcel.writeInt(((int)charValue)); + _aidl_parcel.writeInt(intValue); + _aidl_parcel.writeLong(longValue); + _aidl_parcel.writeFloat(floatValue); + _aidl_parcel.writeDouble(doubleValue); + _aidl_parcel.writeLong(enumValue); + _aidl_parcel.writeTypedObject(parcelableValue, 0); + int _aidl_end_pos = _aidl_parcel.dataPosition(); + _aidl_parcel.setDataPosition(_aidl_start_pos); + _aidl_parcel.writeInt(_aidl_end_pos - _aidl_start_pos); + _aidl_parcel.setDataPosition(_aidl_end_pos); + } + public final void readFromParcel(android.os.Parcel _aidl_parcel) + { + int _aidl_start_pos = _aidl_parcel.dataPosition(); + int _aidl_parcelable_size = _aidl_parcel.readInt(); + try { + if (_aidl_parcelable_size < 0) return; + if (_aidl_parcel.dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) return; + booleanValue = _aidl_parcel.readBoolean(); + if (_aidl_parcel.dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) return; + byteValue = _aidl_parcel.readByte(); + if (_aidl_parcel.dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) return; + charValue = (char)_aidl_parcel.readInt(); + if (_aidl_parcel.dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) return; + intValue = _aidl_parcel.readInt(); + if (_aidl_parcel.dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) return; + longValue = _aidl_parcel.readLong(); + if (_aidl_parcel.dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) return; + floatValue = _aidl_parcel.readFloat(); + if (_aidl_parcel.dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) return; + doubleValue = _aidl_parcel.readDouble(); + if (_aidl_parcel.dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) return; + enumValue = _aidl_parcel.readLong(); + if (_aidl_parcel.dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) return; + parcelableValue = _aidl_parcel.readTypedObject(android.aidl.tests.FixedSize.FixedUnion.CREATOR); + } finally { + if (_aidl_start_pos > (Integer.MAX_VALUE - _aidl_parcelable_size)) { + throw new android.os.BadParcelableException("Overflow in the size of parcelable"); + } + _aidl_parcel.setDataPosition(_aidl_start_pos + _aidl_parcelable_size); + } + } + @Override + public int describeContents() { + int _mask = 0; + _mask |= describeContents(parcelableValue); + return _mask; + } + private int describeContents(Object _v) { + if (_v == null) return 0; + if (_v instanceof android.os.Parcelable) { + return ((android.os.Parcelable) _v).describeContents(); + } + return 0; + } + } + public static final class FixedUnion implements android.os.Parcelable { + // tags for union fields + public final static int booleanValue = 0; // boolean booleanValue; + public final static int byteValue = 1; // byte byteValue; + public final static int charValue = 2; // char charValue; + public final static int intValue = 3; // int intValue; + public final static int longValue = 4; // long longValue; + public final static int floatValue = 5; // float floatValue; + public final static int doubleValue = 6; // double doubleValue; + public final static int enumValue = 7; // android.aidl.tests.LongEnum enumValue; + + private int _tag; + private Object _value; + + public FixedUnion() { + boolean _value = false; + this._tag = booleanValue; + this._value = _value; + } + + private FixedUnion(android.os.Parcel _aidl_parcel) { + readFromParcel(_aidl_parcel); + } + + private FixedUnion(int _tag, Object _value) { + this._tag = _tag; + this._value = _value; + } + + public int getTag() { + return _tag; + } + + // boolean booleanValue; + + public static FixedUnion booleanValue(boolean _value) { + return new FixedUnion(booleanValue, _value); + } + + public boolean getBooleanValue() { + _assertTag(booleanValue); + return (boolean) _value; + } + + public void setBooleanValue(boolean _value) { + _set(booleanValue, _value); + } + + // byte byteValue; + + public static FixedUnion byteValue(byte _value) { + return new FixedUnion(byteValue, _value); + } + + public byte getByteValue() { + _assertTag(byteValue); + return (byte) _value; + } + + public void setByteValue(byte _value) { + _set(byteValue, _value); + } + + // char charValue; + + public static FixedUnion charValue(char _value) { + return new FixedUnion(charValue, _value); + } + + public char getCharValue() { + _assertTag(charValue); + return (char) _value; + } + + public void setCharValue(char _value) { + _set(charValue, _value); + } + + // int intValue; + + public static FixedUnion intValue(int _value) { + return new FixedUnion(intValue, _value); + } + + public int getIntValue() { + _assertTag(intValue); + return (int) _value; + } + + public void setIntValue(int _value) { + _set(intValue, _value); + } + + // long longValue; + + public static FixedUnion longValue(long _value) { + return new FixedUnion(longValue, _value); + } + + public long getLongValue() { + _assertTag(longValue); + return (long) _value; + } + + public void setLongValue(long _value) { + _set(longValue, _value); + } + + // float floatValue; + + public static FixedUnion floatValue(float _value) { + return new FixedUnion(floatValue, _value); + } + + public float getFloatValue() { + _assertTag(floatValue); + return (float) _value; + } + + public void setFloatValue(float _value) { + _set(floatValue, _value); + } + + // double doubleValue; + + public static FixedUnion doubleValue(double _value) { + return new FixedUnion(doubleValue, _value); + } + + public double getDoubleValue() { + _assertTag(doubleValue); + return (double) _value; + } + + public void setDoubleValue(double _value) { + _set(doubleValue, _value); + } + + // android.aidl.tests.LongEnum enumValue; + + public static FixedUnion enumValue(long _value) { + return new FixedUnion(enumValue, _value); + } + + public long getEnumValue() { + _assertTag(enumValue); + return (long) _value; + } + + public void setEnumValue(long _value) { + _set(enumValue, _value); + } + + public static final android.os.Parcelable.Creator<FixedUnion> CREATOR = new android.os.Parcelable.Creator<FixedUnion>() { + @Override + public FixedUnion createFromParcel(android.os.Parcel _aidl_source) { + return new FixedUnion(_aidl_source); + } + @Override + public FixedUnion[] newArray(int _aidl_size) { + return new FixedUnion[_aidl_size]; + } + }; + + @Override + public final void writeToParcel(android.os.Parcel _aidl_parcel, int _aidl_flag) { + _aidl_parcel.writeInt(_tag); + switch (_tag) { + case booleanValue: + _aidl_parcel.writeBoolean(getBooleanValue()); + break; + case byteValue: + _aidl_parcel.writeByte(getByteValue()); + break; + case charValue: + _aidl_parcel.writeInt(((int)getCharValue())); + break; + case intValue: + _aidl_parcel.writeInt(getIntValue()); + break; + case longValue: + _aidl_parcel.writeLong(getLongValue()); + break; + case floatValue: + _aidl_parcel.writeFloat(getFloatValue()); + break; + case doubleValue: + _aidl_parcel.writeDouble(getDoubleValue()); + break; + case enumValue: + _aidl_parcel.writeLong(getEnumValue()); + break; + } + } + + public void readFromParcel(android.os.Parcel _aidl_parcel) { + int _aidl_tag; + _aidl_tag = _aidl_parcel.readInt(); + switch (_aidl_tag) { + case booleanValue: { + boolean _aidl_value; + _aidl_value = _aidl_parcel.readBoolean(); + _set(_aidl_tag, _aidl_value); + return; } + case byteValue: { + byte _aidl_value; + _aidl_value = _aidl_parcel.readByte(); + _set(_aidl_tag, _aidl_value); + return; } + case charValue: { + char _aidl_value; + _aidl_value = (char)_aidl_parcel.readInt(); + _set(_aidl_tag, _aidl_value); + return; } + case intValue: { + int _aidl_value; + _aidl_value = _aidl_parcel.readInt(); + _set(_aidl_tag, _aidl_value); + return; } + case longValue: { + long _aidl_value; + _aidl_value = _aidl_parcel.readLong(); + _set(_aidl_tag, _aidl_value); + return; } + case floatValue: { + float _aidl_value; + _aidl_value = _aidl_parcel.readFloat(); + _set(_aidl_tag, _aidl_value); + return; } + case doubleValue: { + double _aidl_value; + _aidl_value = _aidl_parcel.readDouble(); + _set(_aidl_tag, _aidl_value); + return; } + case enumValue: { + long _aidl_value; + _aidl_value = _aidl_parcel.readLong(); + _set(_aidl_tag, _aidl_value); + return; } + } + throw new IllegalArgumentException("union: unknown tag: " + _aidl_tag); + } + + @Override + public int describeContents() { + int _mask = 0; + switch (getTag()) { + } + return _mask; + } + + private void _assertTag(int tag) { + if (getTag() != tag) { + throw new IllegalStateException("bad access: " + _tagString(tag) + ", " + _tagString(getTag()) + " is available."); + } + } + + private String _tagString(int _tag) { + switch (_tag) { + case booleanValue: return "booleanValue"; + case byteValue: return "byteValue"; + case charValue: return "charValue"; + case intValue: return "intValue"; + case longValue: return "longValue"; + case floatValue: return "floatValue"; + case doubleValue: return "doubleValue"; + case enumValue: return "enumValue"; + } + throw new IllegalStateException("unknown field: " + _tag); + } + + private void _set(int _tag, Object _value) { + this._tag = _tag; + this._value = _value; + } + } +} diff --git a/tests/golden_output/aidl-test-interface-java-source/gen/android/aidl/tests/FixedSize.java.d b/tests/golden_output/aidl-test-interface-java-source/gen/android/aidl/tests/FixedSize.java.d new file mode 100644 index 00000000..74b092c2 --- /dev/null +++ b/tests/golden_output/aidl-test-interface-java-source/gen/android/aidl/tests/FixedSize.java.d @@ -0,0 +1,3 @@ +out/soong/.intermediates/system/tools/aidl/aidl-test-interface-java-source/gen/android/aidl/tests/FixedSize.java : \ + system/tools/aidl/tests/android/aidl/tests/FixedSize.aidl \ + system/tools/aidl/tests/android/aidl/tests/LongEnum.aidl diff --git a/tests/golden_output/aidl-test-interface-ndk-source/gen/android/aidl/tests/FixedSize.cpp b/tests/golden_output/aidl-test-interface-ndk-source/gen/android/aidl/tests/FixedSize.cpp new file mode 100644 index 00000000..1a80e55c --- /dev/null +++ b/tests/golden_output/aidl-test-interface-ndk-source/gen/android/aidl/tests/FixedSize.cpp @@ -0,0 +1,276 @@ +#include "aidl/android/aidl/tests/FixedSize.h" + +#include <android/binder_parcel_utils.h> + +namespace aidl { +namespace android { +namespace aidl { +namespace tests { +const char* FixedSize::descriptor = "android.aidl.tests.FixedSize"; + +binder_status_t FixedSize::readFromParcel(const AParcel* _aidl_parcel) { + int32_t _aidl_parcelable_size; + int32_t _aidl_start_pos = AParcel_getDataPosition(_aidl_parcel); + binder_status_t _aidl_ret_status = AParcel_readInt32(_aidl_parcel, &_aidl_parcelable_size); + if (_aidl_start_pos > INT32_MAX - _aidl_parcelable_size) return STATUS_BAD_VALUE; + if (_aidl_parcelable_size < 0) return STATUS_BAD_VALUE; + if (_aidl_ret_status != STATUS_OK) return _aidl_ret_status; + + AParcel_setDataPosition(_aidl_parcel, _aidl_start_pos + _aidl_parcelable_size); + return _aidl_ret_status; +} +binder_status_t FixedSize::writeToParcel(AParcel* _aidl_parcel) const { + binder_status_t _aidl_ret_status; + size_t _aidl_start_pos = AParcel_getDataPosition(_aidl_parcel); + _aidl_ret_status = AParcel_writeInt32(_aidl_parcel, 0); + if (_aidl_ret_status != STATUS_OK) return _aidl_ret_status; + + size_t _aidl_end_pos = AParcel_getDataPosition(_aidl_parcel); + AParcel_setDataPosition(_aidl_parcel, _aidl_start_pos); + AParcel_writeInt32(_aidl_parcel, _aidl_end_pos - _aidl_start_pos); + AParcel_setDataPosition(_aidl_parcel, _aidl_end_pos); + return _aidl_ret_status; +} + +} // namespace tests +} // namespace aidl +} // namespace android +} // namespace aidl +namespace aidl { +namespace android { +namespace aidl { +namespace tests { +const char* FixedSize::FixedParcelable::descriptor = "android.aidl.tests.FixedSize.FixedParcelable"; + +binder_status_t FixedSize::FixedParcelable::readFromParcel(const AParcel* _aidl_parcel) { + int32_t _aidl_parcelable_size; + int32_t _aidl_start_pos = AParcel_getDataPosition(_aidl_parcel); + binder_status_t _aidl_ret_status = AParcel_readInt32(_aidl_parcel, &_aidl_parcelable_size); + if (_aidl_start_pos > INT32_MAX - _aidl_parcelable_size) return STATUS_BAD_VALUE; + if (_aidl_parcelable_size < 0) return STATUS_BAD_VALUE; + if (_aidl_ret_status != STATUS_OK) return _aidl_ret_status; + + if (AParcel_getDataPosition(_aidl_parcel) - _aidl_start_pos >= _aidl_parcelable_size) { + AParcel_setDataPosition(_aidl_parcel, _aidl_start_pos + _aidl_parcelable_size); + return _aidl_ret_status; + } + _aidl_ret_status = AParcel_readBool(_aidl_parcel, &booleanValue); + if (_aidl_ret_status != STATUS_OK) return _aidl_ret_status; + + if (AParcel_getDataPosition(_aidl_parcel) - _aidl_start_pos >= _aidl_parcelable_size) { + AParcel_setDataPosition(_aidl_parcel, _aidl_start_pos + _aidl_parcelable_size); + return _aidl_ret_status; + } + _aidl_ret_status = AParcel_readByte(_aidl_parcel, &byteValue); + if (_aidl_ret_status != STATUS_OK) return _aidl_ret_status; + + if (AParcel_getDataPosition(_aidl_parcel) - _aidl_start_pos >= _aidl_parcelable_size) { + AParcel_setDataPosition(_aidl_parcel, _aidl_start_pos + _aidl_parcelable_size); + return _aidl_ret_status; + } + _aidl_ret_status = AParcel_readChar(_aidl_parcel, &charValue); + if (_aidl_ret_status != STATUS_OK) return _aidl_ret_status; + + if (AParcel_getDataPosition(_aidl_parcel) - _aidl_start_pos >= _aidl_parcelable_size) { + AParcel_setDataPosition(_aidl_parcel, _aidl_start_pos + _aidl_parcelable_size); + return _aidl_ret_status; + } + _aidl_ret_status = AParcel_readInt32(_aidl_parcel, &intValue); + if (_aidl_ret_status != STATUS_OK) return _aidl_ret_status; + + if (AParcel_getDataPosition(_aidl_parcel) - _aidl_start_pos >= _aidl_parcelable_size) { + AParcel_setDataPosition(_aidl_parcel, _aidl_start_pos + _aidl_parcelable_size); + return _aidl_ret_status; + } + _aidl_ret_status = AParcel_readInt64(_aidl_parcel, &longValue); + if (_aidl_ret_status != STATUS_OK) return _aidl_ret_status; + + if (AParcel_getDataPosition(_aidl_parcel) - _aidl_start_pos >= _aidl_parcelable_size) { + AParcel_setDataPosition(_aidl_parcel, _aidl_start_pos + _aidl_parcelable_size); + return _aidl_ret_status; + } + _aidl_ret_status = AParcel_readFloat(_aidl_parcel, &floatValue); + if (_aidl_ret_status != STATUS_OK) return _aidl_ret_status; + + if (AParcel_getDataPosition(_aidl_parcel) - _aidl_start_pos >= _aidl_parcelable_size) { + AParcel_setDataPosition(_aidl_parcel, _aidl_start_pos + _aidl_parcelable_size); + return _aidl_ret_status; + } + _aidl_ret_status = AParcel_readDouble(_aidl_parcel, &doubleValue); + if (_aidl_ret_status != STATUS_OK) return _aidl_ret_status; + + if (AParcel_getDataPosition(_aidl_parcel) - _aidl_start_pos >= _aidl_parcelable_size) { + AParcel_setDataPosition(_aidl_parcel, _aidl_start_pos + _aidl_parcelable_size); + return _aidl_ret_status; + } + _aidl_ret_status = AParcel_readInt64(_aidl_parcel, reinterpret_cast<int64_t*>(&enumValue)); + if (_aidl_ret_status != STATUS_OK) return _aidl_ret_status; + + if (AParcel_getDataPosition(_aidl_parcel) - _aidl_start_pos >= _aidl_parcelable_size) { + AParcel_setDataPosition(_aidl_parcel, _aidl_start_pos + _aidl_parcelable_size); + return _aidl_ret_status; + } + _aidl_ret_status = ::ndk::AParcel_readParcelable(_aidl_parcel, &parcelableValue); + if (_aidl_ret_status != STATUS_OK) return _aidl_ret_status; + + AParcel_setDataPosition(_aidl_parcel, _aidl_start_pos + _aidl_parcelable_size); + return _aidl_ret_status; +} +binder_status_t FixedSize::FixedParcelable::writeToParcel(AParcel* _aidl_parcel) const { + binder_status_t _aidl_ret_status; + size_t _aidl_start_pos = AParcel_getDataPosition(_aidl_parcel); + _aidl_ret_status = AParcel_writeInt32(_aidl_parcel, 0); + if (_aidl_ret_status != STATUS_OK) return _aidl_ret_status; + + _aidl_ret_status = AParcel_writeBool(_aidl_parcel, booleanValue); + if (_aidl_ret_status != STATUS_OK) return _aidl_ret_status; + + _aidl_ret_status = AParcel_writeByte(_aidl_parcel, byteValue); + if (_aidl_ret_status != STATUS_OK) return _aidl_ret_status; + + _aidl_ret_status = AParcel_writeChar(_aidl_parcel, charValue); + if (_aidl_ret_status != STATUS_OK) return _aidl_ret_status; + + _aidl_ret_status = AParcel_writeInt32(_aidl_parcel, intValue); + if (_aidl_ret_status != STATUS_OK) return _aidl_ret_status; + + _aidl_ret_status = AParcel_writeInt64(_aidl_parcel, longValue); + if (_aidl_ret_status != STATUS_OK) return _aidl_ret_status; + + _aidl_ret_status = AParcel_writeFloat(_aidl_parcel, floatValue); + if (_aidl_ret_status != STATUS_OK) return _aidl_ret_status; + + _aidl_ret_status = AParcel_writeDouble(_aidl_parcel, doubleValue); + if (_aidl_ret_status != STATUS_OK) return _aidl_ret_status; + + _aidl_ret_status = AParcel_writeInt64(_aidl_parcel, static_cast<int64_t>(enumValue)); + if (_aidl_ret_status != STATUS_OK) return _aidl_ret_status; + + _aidl_ret_status = ::ndk::AParcel_writeParcelable(_aidl_parcel, parcelableValue); + if (_aidl_ret_status != STATUS_OK) return _aidl_ret_status; + + size_t _aidl_end_pos = AParcel_getDataPosition(_aidl_parcel); + AParcel_setDataPosition(_aidl_parcel, _aidl_start_pos); + AParcel_writeInt32(_aidl_parcel, _aidl_end_pos - _aidl_start_pos); + AParcel_setDataPosition(_aidl_parcel, _aidl_end_pos); + return _aidl_ret_status; +} + +} // namespace tests +} // namespace aidl +} // namespace android +} // namespace aidl +namespace aidl { +namespace android { +namespace aidl { +namespace tests { +const char* FixedSize::FixedUnion::descriptor = "android.aidl.tests.FixedSize.FixedUnion"; + +binder_status_t FixedSize::FixedUnion::readFromParcel(const AParcel* _parcel) { + binder_status_t _aidl_ret_status; + int32_t _aidl_tag; + if ((_aidl_ret_status = AParcel_readInt32(_parcel, &_aidl_tag)) != STATUS_OK) return _aidl_ret_status; + switch (_aidl_tag) { + case booleanValue: { + bool _aidl_value; + if ((_aidl_ret_status = AParcel_readBool(_parcel, &_aidl_value)) != STATUS_OK) return _aidl_ret_status; + if constexpr (std::is_trivially_copyable_v<bool>) { + set<booleanValue>(_aidl_value); + } else { + // NOLINTNEXTLINE(performance-move-const-arg) + set<booleanValue>(std::move(_aidl_value)); + } + return STATUS_OK; } + case byteValue: { + int8_t _aidl_value; + if ((_aidl_ret_status = AParcel_readByte(_parcel, &_aidl_value)) != STATUS_OK) return _aidl_ret_status; + if constexpr (std::is_trivially_copyable_v<int8_t>) { + set<byteValue>(_aidl_value); + } else { + // NOLINTNEXTLINE(performance-move-const-arg) + set<byteValue>(std::move(_aidl_value)); + } + return STATUS_OK; } + case charValue: { + char16_t _aidl_value; + if ((_aidl_ret_status = AParcel_readChar(_parcel, &_aidl_value)) != STATUS_OK) return _aidl_ret_status; + if constexpr (std::is_trivially_copyable_v<char16_t>) { + set<charValue>(_aidl_value); + } else { + // NOLINTNEXTLINE(performance-move-const-arg) + set<charValue>(std::move(_aidl_value)); + } + return STATUS_OK; } + case intValue: { + int32_t _aidl_value; + if ((_aidl_ret_status = AParcel_readInt32(_parcel, &_aidl_value)) != STATUS_OK) return _aidl_ret_status; + if constexpr (std::is_trivially_copyable_v<int32_t>) { + set<intValue>(_aidl_value); + } else { + // NOLINTNEXTLINE(performance-move-const-arg) + set<intValue>(std::move(_aidl_value)); + } + return STATUS_OK; } + case longValue: { + int64_t _aidl_value; + if ((_aidl_ret_status = AParcel_readInt64(_parcel, &_aidl_value)) != STATUS_OK) return _aidl_ret_status; + if constexpr (std::is_trivially_copyable_v<int64_t>) { + set<longValue>(_aidl_value); + } else { + // NOLINTNEXTLINE(performance-move-const-arg) + set<longValue>(std::move(_aidl_value)); + } + return STATUS_OK; } + case floatValue: { + float _aidl_value; + if ((_aidl_ret_status = AParcel_readFloat(_parcel, &_aidl_value)) != STATUS_OK) return _aidl_ret_status; + if constexpr (std::is_trivially_copyable_v<float>) { + set<floatValue>(_aidl_value); + } else { + // NOLINTNEXTLINE(performance-move-const-arg) + set<floatValue>(std::move(_aidl_value)); + } + return STATUS_OK; } + case doubleValue: { + double _aidl_value; + if ((_aidl_ret_status = AParcel_readDouble(_parcel, &_aidl_value)) != STATUS_OK) return _aidl_ret_status; + if constexpr (std::is_trivially_copyable_v<double>) { + set<doubleValue>(_aidl_value); + } else { + // NOLINTNEXTLINE(performance-move-const-arg) + set<doubleValue>(std::move(_aidl_value)); + } + return STATUS_OK; } + case enumValue: { + ::aidl::android::aidl::tests::LongEnum _aidl_value; + if ((_aidl_ret_status = AParcel_readInt64(_parcel, reinterpret_cast<int64_t*>(&_aidl_value))) != STATUS_OK) return _aidl_ret_status; + if constexpr (std::is_trivially_copyable_v<::aidl::android::aidl::tests::LongEnum>) { + set<enumValue>(_aidl_value); + } else { + // NOLINTNEXTLINE(performance-move-const-arg) + set<enumValue>(std::move(_aidl_value)); + } + return STATUS_OK; } + } + return STATUS_BAD_VALUE; +} +binder_status_t FixedSize::FixedUnion::writeToParcel(AParcel* _parcel) const { + binder_status_t _aidl_ret_status = AParcel_writeInt32(_parcel, getTag()); + if (_aidl_ret_status != STATUS_OK) return _aidl_ret_status; + switch (getTag()) { + case booleanValue: return AParcel_writeBool(_parcel, get<booleanValue>()); + case byteValue: return AParcel_writeByte(_parcel, get<byteValue>()); + case charValue: return AParcel_writeChar(_parcel, get<charValue>()); + case intValue: return AParcel_writeInt32(_parcel, get<intValue>()); + case longValue: return AParcel_writeInt64(_parcel, get<longValue>()); + case floatValue: return AParcel_writeFloat(_parcel, get<floatValue>()); + case doubleValue: return AParcel_writeDouble(_parcel, get<doubleValue>()); + case enumValue: return AParcel_writeInt64(_parcel, static_cast<int64_t>(get<enumValue>())); + } + __assert2(__FILE__, __LINE__, __PRETTY_FUNCTION__, "can't reach here"); +} + +} // namespace tests +} // namespace aidl +} // namespace android +} // namespace aidl diff --git a/tests/golden_output/aidl-test-interface-ndk-source/gen/android/aidl/tests/FixedSize.cpp.d b/tests/golden_output/aidl-test-interface-ndk-source/gen/android/aidl/tests/FixedSize.cpp.d new file mode 100644 index 00000000..b27ad3e7 --- /dev/null +++ b/tests/golden_output/aidl-test-interface-ndk-source/gen/android/aidl/tests/FixedSize.cpp.d @@ -0,0 +1,3 @@ +out/soong/.intermediates/system/tools/aidl/aidl-test-interface-ndk-source/gen/android/aidl/tests/FixedSize.cpp : \ + system/tools/aidl/tests/android/aidl/tests/FixedSize.aidl \ + system/tools/aidl/tests/android/aidl/tests/LongEnum.aidl diff --git a/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/BnFixedSize.h b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/BnFixedSize.h new file mode 100644 index 00000000..42911089 --- /dev/null +++ b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/BnFixedSize.h @@ -0,0 +1 @@ +#error TODO(b/111362593) defined_types do not have bn classes diff --git a/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/BpFixedSize.h b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/BpFixedSize.h new file mode 100644 index 00000000..e8a0db3b --- /dev/null +++ b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/BpFixedSize.h @@ -0,0 +1 @@ +#error TODO(b/111362593) defined_types do not have bp classes diff --git a/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/FixedSize.h b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/FixedSize.h new file mode 100644 index 00000000..91da0ce3 --- /dev/null +++ b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/FixedSize.h @@ -0,0 +1,233 @@ +#pragma once + +#include <cassert> +#include <cstdint> +#include <memory> +#include <optional> +#include <string> +#include <tuple> +#include <type_traits> +#include <utility> +#include <variant> +#include <vector> +#include <android/binder_interface_utils.h> +#include <android/binder_parcelable_utils.h> +#include <android/binder_to_string.h> +#include <aidl/android/aidl/tests/FixedSize.h> +#include <aidl/android/aidl/tests/LongEnum.h> +#ifdef BINDER_STABILITY_SUPPORT +#include <android/binder_stability.h> +#endif // BINDER_STABILITY_SUPPORT + +#ifndef __BIONIC__ +#define __assert2(a,b,c,d) ((void)0) +#endif + +namespace aidl { +namespace android { +namespace aidl { +namespace tests { +class FixedSize { +public: + typedef std::false_type fixed_size; + static const char* descriptor; + + class FixedUnion { + public: + typedef std::true_type fixed_size; + static const char* descriptor; + + enum Tag : uint8_t { + booleanValue = 0, // boolean booleanValue; + byteValue, // byte byteValue; + charValue, // char charValue; + intValue, // int intValue; + longValue, // long longValue; + floatValue, // float floatValue; + doubleValue, // double doubleValue; + enumValue, // android.aidl.tests.LongEnum enumValue; + }; + + template <Tag _Tag> + using _at = typename std::tuple_element<_Tag, std::tuple<bool, int8_t, char16_t, int32_t, int64_t, float, double, ::aidl::android::aidl::tests::LongEnum>>::type; + template <Tag _Tag, typename _Type> + static FixedUnion make(_Type&& _arg) { + FixedUnion _inst; + _inst.set<_Tag>(std::forward<_Type>(_arg)); + return _inst; + } + constexpr Tag getTag() const { + return _tag; + } + template <Tag _Tag> + const _at<_Tag>& get() const { + if (_Tag != _tag) { __assert2(__FILE__, __LINE__, __PRETTY_FUNCTION__, "bad access: a wrong tag"); } + return *(_at<_Tag>*)(&_value); + } + template <Tag _Tag> + _at<_Tag>& get() { + if (_Tag != _tag) { __assert2(__FILE__, __LINE__, __PRETTY_FUNCTION__, "bad access: a wrong tag"); } + return *(_at<_Tag>*)(&_value); + } + template <Tag _Tag, typename _Type> + void set(_Type&& _arg) { + _tag = _Tag; + get<_Tag>() = std::forward<_Type>(_arg); + } + binder_status_t readFromParcel(const AParcel* _parcel); + binder_status_t writeToParcel(AParcel* _parcel) const; + + static int _cmp(const FixedUnion& _lhs, const FixedUnion& _rhs) { + return _cmp_value(_lhs.getTag(), _rhs.getTag()) || _cmp_value_at<enumValue>(_lhs, _rhs); + } + template <Tag _Tag> + static int _cmp_value_at(const FixedUnion& _lhs, const FixedUnion& _rhs) { + if constexpr (_Tag == booleanValue) { + return _cmp_value(_lhs.get<_Tag>(), _rhs.get<_Tag>()); + } else { + return (_lhs.getTag() == _Tag) + ? _cmp_value(_lhs.get<_Tag>(), _rhs.get<_Tag>()) + : _cmp_value_at<(Tag)(_Tag-1)>(_lhs, _rhs); + } + } + template <typename _Type> + static int _cmp_value(const _Type& _lhs, const _Type& _rhs) { + return (_lhs == _rhs) ? 0 : (_lhs < _rhs) ? -1 : 1; + } + inline bool operator!=(const FixedUnion&_rhs) const { + return _cmp(*this, _rhs) != 0; + } + inline bool operator<(const FixedUnion&_rhs) const { + return _cmp(*this, _rhs) < 0; + } + inline bool operator<=(const FixedUnion&_rhs) const { + return _cmp(*this, _rhs) <= 0; + } + inline bool operator==(const FixedUnion&_rhs) const { + return _cmp(*this, _rhs) == 0; + } + inline bool operator>(const FixedUnion&_rhs) const { + return _cmp(*this, _rhs) > 0; + } + inline bool operator>=(const FixedUnion&_rhs) const { + return _cmp(*this, _rhs) >= 0; + } + static const ::ndk::parcelable_stability_t _aidl_stability = ::ndk::STABILITY_LOCAL; + inline std::string toString() const { + std::ostringstream os; + os << "FixedUnion{"; + switch (getTag()) { + case booleanValue: os << "booleanValue: " << ::android::internal::ToString(get<booleanValue>()); break; + case byteValue: os << "byteValue: " << ::android::internal::ToString(get<byteValue>()); break; + case charValue: os << "charValue: " << ::android::internal::ToString(get<charValue>()); break; + case intValue: os << "intValue: " << ::android::internal::ToString(get<intValue>()); break; + case longValue: os << "longValue: " << ::android::internal::ToString(get<longValue>()); break; + case floatValue: os << "floatValue: " << ::android::internal::ToString(get<floatValue>()); break; + case doubleValue: os << "doubleValue: " << ::android::internal::ToString(get<doubleValue>()); break; + case enumValue: os << "enumValue: " << ::android::internal::ToString(get<enumValue>()); break; + } + os << "}"; + return os.str(); + } + private: + Tag _tag __attribute__((aligned (1))) = booleanValue; + union { + bool booleanValue __attribute__((aligned (1))) = bool(false); + int8_t byteValue __attribute__((aligned (1))); + char16_t charValue __attribute__((aligned (2))); + int32_t intValue __attribute__((aligned (4))); + int64_t longValue __attribute__((aligned (8))); + float floatValue __attribute__((aligned (4))); + double doubleValue __attribute__((aligned (8))); + ::aidl::android::aidl::tests::LongEnum enumValue __attribute__((aligned (8))); + } _value; + }; + class FixedParcelable { + public: + typedef std::true_type fixed_size; + static const char* descriptor; + + bool booleanValue __attribute__((aligned (1))) = false; + int8_t byteValue __attribute__((aligned (1))) = 0; + char16_t charValue __attribute__((aligned (2))); + int32_t intValue __attribute__((aligned (4))) = 0; + int64_t longValue __attribute__((aligned (8))) = 0L; + float floatValue __attribute__((aligned (4))) = 0.000000f; + double doubleValue __attribute__((aligned (8))) = 0.000000; + ::aidl::android::aidl::tests::LongEnum enumValue __attribute__((aligned (8))) = ::aidl::android::aidl::tests::LongEnum::FOO; + ::aidl::android::aidl::tests::FixedSize::FixedUnion parcelableValue; + + binder_status_t readFromParcel(const AParcel* parcel); + binder_status_t writeToParcel(AParcel* parcel) const; + + inline bool operator!=(const FixedParcelable& rhs) const { + return std::tie(booleanValue, byteValue, charValue, intValue, longValue, floatValue, doubleValue, enumValue, parcelableValue) != std::tie(rhs.booleanValue, rhs.byteValue, rhs.charValue, rhs.intValue, rhs.longValue, rhs.floatValue, rhs.doubleValue, rhs.enumValue, rhs.parcelableValue); + } + inline bool operator<(const FixedParcelable& rhs) const { + return std::tie(booleanValue, byteValue, charValue, intValue, longValue, floatValue, doubleValue, enumValue, parcelableValue) < std::tie(rhs.booleanValue, rhs.byteValue, rhs.charValue, rhs.intValue, rhs.longValue, rhs.floatValue, rhs.doubleValue, rhs.enumValue, rhs.parcelableValue); + } + inline bool operator<=(const FixedParcelable& rhs) const { + return std::tie(booleanValue, byteValue, charValue, intValue, longValue, floatValue, doubleValue, enumValue, parcelableValue) <= std::tie(rhs.booleanValue, rhs.byteValue, rhs.charValue, rhs.intValue, rhs.longValue, rhs.floatValue, rhs.doubleValue, rhs.enumValue, rhs.parcelableValue); + } + inline bool operator==(const FixedParcelable& rhs) const { + return std::tie(booleanValue, byteValue, charValue, intValue, longValue, floatValue, doubleValue, enumValue, parcelableValue) == std::tie(rhs.booleanValue, rhs.byteValue, rhs.charValue, rhs.intValue, rhs.longValue, rhs.floatValue, rhs.doubleValue, rhs.enumValue, rhs.parcelableValue); + } + inline bool operator>(const FixedParcelable& rhs) const { + return std::tie(booleanValue, byteValue, charValue, intValue, longValue, floatValue, doubleValue, enumValue, parcelableValue) > std::tie(rhs.booleanValue, rhs.byteValue, rhs.charValue, rhs.intValue, rhs.longValue, rhs.floatValue, rhs.doubleValue, rhs.enumValue, rhs.parcelableValue); + } + inline bool operator>=(const FixedParcelable& rhs) const { + return std::tie(booleanValue, byteValue, charValue, intValue, longValue, floatValue, doubleValue, enumValue, parcelableValue) >= std::tie(rhs.booleanValue, rhs.byteValue, rhs.charValue, rhs.intValue, rhs.longValue, rhs.floatValue, rhs.doubleValue, rhs.enumValue, rhs.parcelableValue); + } + + static const ::ndk::parcelable_stability_t _aidl_stability = ::ndk::STABILITY_LOCAL; + inline std::string toString() const { + std::ostringstream os; + os << "FixedParcelable{"; + os << "booleanValue: " << ::android::internal::ToString(booleanValue); + os << ", byteValue: " << ::android::internal::ToString(byteValue); + os << ", charValue: " << ::android::internal::ToString(charValue); + os << ", intValue: " << ::android::internal::ToString(intValue); + os << ", longValue: " << ::android::internal::ToString(longValue); + os << ", floatValue: " << ::android::internal::ToString(floatValue); + os << ", doubleValue: " << ::android::internal::ToString(doubleValue); + os << ", enumValue: " << ::android::internal::ToString(enumValue); + os << ", parcelableValue: " << ::android::internal::ToString(parcelableValue); + os << "}"; + return os.str(); + } + }; + + binder_status_t readFromParcel(const AParcel* parcel); + binder_status_t writeToParcel(AParcel* parcel) const; + + inline bool operator!=(const FixedSize&) const { + return std::tie() != std::tie(); + } + inline bool operator<(const FixedSize&) const { + return std::tie() < std::tie(); + } + inline bool operator<=(const FixedSize&) const { + return std::tie() <= std::tie(); + } + inline bool operator==(const FixedSize&) const { + return std::tie() == std::tie(); + } + inline bool operator>(const FixedSize&) const { + return std::tie() > std::tie(); + } + inline bool operator>=(const FixedSize&) const { + return std::tie() >= std::tie(); + } + + static const ::ndk::parcelable_stability_t _aidl_stability = ::ndk::STABILITY_LOCAL; + inline std::string toString() const { + std::ostringstream os; + os << "FixedSize{"; + os << "}"; + return os.str(); + } +}; +} // namespace tests +} // namespace aidl +} // namespace android +} // namespace aidl diff --git a/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/FixedSize.rs b/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/FixedSize.rs new file mode 100644 index 00000000..1048f286 --- /dev/null +++ b/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/FixedSize.rs @@ -0,0 +1,224 @@ +#![forbid(unsafe_code)] +#![rustfmt::skip] +#[derive(Debug)] +pub struct FixedSize { +} +impl Default for FixedSize { + fn default() -> Self { + Self { + } + } +} +impl binder::parcel::Parcelable for FixedSize { + fn write_to_parcel(&self, parcel: &mut binder::parcel::BorrowedParcel) -> binder::Result<()> { + parcel.sized_write(|subparcel| { + Ok(()) + }) + } + fn read_from_parcel(&mut self, parcel: &binder::parcel::BorrowedParcel) -> binder::Result<()> { + parcel.sized_read(|subparcel| { + Ok(()) + }) + } +} +binder::impl_serialize_for_parcelable!(FixedSize); +binder::impl_deserialize_for_parcelable!(FixedSize); +impl binder::parcel::ParcelableMetadata for FixedSize { + fn get_descriptor() -> &'static str { "android.aidl.tests.FixedSize" } +} +pub mod FixedParcelable { + #[derive(Debug)] + pub struct FixedParcelable { + pub booleanValue: bool, + pub byteValue: i8, + pub charValue: u16, + pub intValue: i32, + pub longValue: i64, + pub floatValue: f32, + pub doubleValue: f64, + pub enumValue: crate::mangled::_7_android_4_aidl_5_tests_8_LongEnum, + pub parcelableValue: crate::mangled::_7_android_4_aidl_5_tests_9_FixedSize_10_FixedUnion, + } + impl Default for FixedParcelable { + fn default() -> Self { + Self { + booleanValue: false, + byteValue: 0, + charValue: Default::default(), + intValue: 0, + longValue: 0, + floatValue: 0.000000f32, + doubleValue: 0.000000f64, + enumValue: crate::mangled::_7_android_4_aidl_5_tests_8_LongEnum::FOO, + parcelableValue: Default::default(), + } + } + } + impl binder::parcel::Parcelable for FixedParcelable { + fn write_to_parcel(&self, parcel: &mut binder::parcel::BorrowedParcel) -> binder::Result<()> { + parcel.sized_write(|subparcel| { + subparcel.write(&self.booleanValue)?; + subparcel.write(&self.byteValue)?; + subparcel.write(&self.charValue)?; + subparcel.write(&self.intValue)?; + subparcel.write(&self.longValue)?; + subparcel.write(&self.floatValue)?; + subparcel.write(&self.doubleValue)?; + subparcel.write(&self.enumValue)?; + subparcel.write(&self.parcelableValue)?; + Ok(()) + }) + } + fn read_from_parcel(&mut self, parcel: &binder::parcel::BorrowedParcel) -> binder::Result<()> { + parcel.sized_read(|subparcel| { + if subparcel.has_more_data() { + self.booleanValue = subparcel.read()?; + } + if subparcel.has_more_data() { + self.byteValue = subparcel.read()?; + } + if subparcel.has_more_data() { + self.charValue = subparcel.read()?; + } + if subparcel.has_more_data() { + self.intValue = subparcel.read()?; + } + if subparcel.has_more_data() { + self.longValue = subparcel.read()?; + } + if subparcel.has_more_data() { + self.floatValue = subparcel.read()?; + } + if subparcel.has_more_data() { + self.doubleValue = subparcel.read()?; + } + if subparcel.has_more_data() { + self.enumValue = subparcel.read()?; + } + if subparcel.has_more_data() { + self.parcelableValue = subparcel.read()?; + } + Ok(()) + }) + } + } + binder::impl_serialize_for_parcelable!(FixedParcelable); + binder::impl_deserialize_for_parcelable!(FixedParcelable); + impl binder::parcel::ParcelableMetadata for FixedParcelable { + fn get_descriptor() -> &'static str { "android.aidl.tests.FixedSize.FixedParcelable" } + } +} +pub mod FixedUnion { + #[derive(Debug)] + pub enum FixedUnion { + BooleanValue(bool), + ByteValue(i8), + CharValue(u16), + IntValue(i32), + LongValue(i64), + FloatValue(f32), + DoubleValue(f64), + EnumValue(crate::mangled::_7_android_4_aidl_5_tests_8_LongEnum), + } + impl Default for FixedUnion { + fn default() -> Self { + Self::BooleanValue(false) + } + } + impl binder::parcel::Parcelable for FixedUnion { + fn write_to_parcel(&self, parcel: &mut binder::parcel::BorrowedParcel) -> binder::Result<()> { + match self { + Self::BooleanValue(v) => { + parcel.write(&0i32)?; + parcel.write(v) + } + Self::ByteValue(v) => { + parcel.write(&1i32)?; + parcel.write(v) + } + Self::CharValue(v) => { + parcel.write(&2i32)?; + parcel.write(v) + } + Self::IntValue(v) => { + parcel.write(&3i32)?; + parcel.write(v) + } + Self::LongValue(v) => { + parcel.write(&4i32)?; + parcel.write(v) + } + Self::FloatValue(v) => { + parcel.write(&5i32)?; + parcel.write(v) + } + Self::DoubleValue(v) => { + parcel.write(&6i32)?; + parcel.write(v) + } + Self::EnumValue(v) => { + parcel.write(&7i32)?; + parcel.write(v) + } + } + } + fn read_from_parcel(&mut self, parcel: &binder::parcel::BorrowedParcel) -> binder::Result<()> { + let tag: i32 = parcel.read()?; + match tag { + 0 => { + let value: bool = parcel.read()?; + *self = Self::BooleanValue(value); + Ok(()) + } + 1 => { + let value: i8 = parcel.read()?; + *self = Self::ByteValue(value); + Ok(()) + } + 2 => { + let value: u16 = parcel.read()?; + *self = Self::CharValue(value); + Ok(()) + } + 3 => { + let value: i32 = parcel.read()?; + *self = Self::IntValue(value); + Ok(()) + } + 4 => { + let value: i64 = parcel.read()?; + *self = Self::LongValue(value); + Ok(()) + } + 5 => { + let value: f32 = parcel.read()?; + *self = Self::FloatValue(value); + Ok(()) + } + 6 => { + let value: f64 = parcel.read()?; + *self = Self::DoubleValue(value); + Ok(()) + } + 7 => { + let value: crate::mangled::_7_android_4_aidl_5_tests_8_LongEnum = parcel.read()?; + *self = Self::EnumValue(value); + Ok(()) + } + _ => { + Err(binder::StatusCode::BAD_VALUE) + } + } + } + } + binder::impl_serialize_for_parcelable!(FixedUnion); + binder::impl_deserialize_for_parcelable!(FixedUnion); + impl binder::parcel::ParcelableMetadata for FixedUnion { + fn get_descriptor() -> &'static str { "android.aidl.tests.FixedSize.FixedUnion" } + } +} +pub(crate) mod mangled { + pub use super::FixedSize as _7_android_4_aidl_5_tests_9_FixedSize; + pub use super::FixedParcelable::FixedParcelable as _7_android_4_aidl_5_tests_9_FixedSize_15_FixedParcelable; + pub use super::FixedUnion::FixedUnion as _7_android_4_aidl_5_tests_9_FixedSize_10_FixedUnion; +} diff --git a/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/FixedSize.rs.d b/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/FixedSize.rs.d new file mode 100644 index 00000000..0635f5e0 --- /dev/null +++ b/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/FixedSize.rs.d @@ -0,0 +1,3 @@ +out/soong/.intermediates/system/tools/aidl/aidl-test-interface-rust-source/gen/android/aidl/tests/FixedSize.rs : \ + system/tools/aidl/tests/android/aidl/tests/FixedSize.aidl \ + system/tools/aidl/tests/android/aidl/tests/LongEnum.aidl |