Snap for 9989322 from 77c96f8cac1458077a33039439aebfa9e4d24936 to mainline-rkpd-release
Change-Id: Ic7418ad4488d010e1bbf22146a3ded04a5145400
diff --git a/Android.bp b/Android.bp
index edf70ca..14ff04b 100644
--- a/Android.bp
+++ b/Android.bp
@@ -64,6 +64,7 @@
cflags: ["-DPLATFORM_SDK_VERSION=%d"],
},
},
+ defaults_visibility: [":__subpackages__"],
}
// Logic shared between aidl and its unittests
@@ -111,6 +112,7 @@
gen_location_hh: true,
gen_position_hh: true,
},
+ visibility: [":__subpackages__"],
}
// aidl executable
@@ -334,9 +336,7 @@
filegroup {
name: "libaidl-integration-permission-test-files",
srcs: [
- "tests/android/aidl/tests/permission/IProtected.aidl",
- "tests/android/aidl/tests/permission/IProtectedInterface.aidl",
- "tests/android/aidl/tests/permission/platform/*.aidl",
+ "tests/android/aidl/tests/permission/**/*.aidl",
],
path: "tests",
}
@@ -348,10 +348,7 @@
srcs: [
"tests/versioned/**/*.aidl",
],
- versions: [
- "1",
- "2",
- ],
+
backend: {
java: {
gen_rpc: true,
@@ -360,6 +357,23 @@
enabled: true,
},
},
+ versions_with_info: [
+ {
+ version: "1",
+ imports: [],
+ },
+ {
+ version: "2",
+ imports: [],
+ },
+ {
+ version: "3",
+ imports: [],
+ },
+
+ ],
+ frozen: true,
+
}
cc_library_static {
@@ -555,6 +569,9 @@
"tests/java/src/android/aidl/tests/NullableTests.java",
"tests/java/src/android/aidl/tests/VintfTests.java",
],
+ data: [
+ ":cts-dalvik-device-test-runner",
+ ],
}
java_test {
@@ -567,6 +584,9 @@
srcs: [
"tests/java/src/android/aidl/service/**/*.java",
],
+ data: [
+ ":cts-dalvik-device-test-runner",
+ ],
}
filegroup {
@@ -589,6 +609,9 @@
name: "aidl_test_java_client_sdk29",
defaults: ["aidl_test_java_sdkversion_defaults"],
min_sdk_version: "29",
+ data: [
+ ":cts-dalvik-device-test-runner",
+ ],
srcs: [
"tests/java/src/android/aidl/sdkversion/tests/*.java",
],
@@ -601,6 +624,9 @@
srcs: [
"tests/java/src/android/aidl/sdkversion/service/*.java",
],
+ data: [
+ ":cts-dalvik-device-test-runner",
+ ],
}
java_test {
@@ -610,12 +636,18 @@
srcs: [
"tests/java/src/android/aidl/sdkversion/tests/*.java",
],
+ data: [
+ ":cts-dalvik-device-test-runner",
+ ],
}
java_test {
name: "aidl_test_java_service_sdk1",
defaults: ["aidl_test_java_sdkversion_defaults"],
min_sdk_version: "1",
+ data: [
+ ":cts-dalvik-device-test-runner",
+ ],
srcs: [
"tests/java/src/android/aidl/sdkversion/service/*.java",
],
@@ -631,6 +663,9 @@
"tests/java/src/android/aidl/permission/tests/*.java",
"tests/java/src/android/aidl/permission/service/*.java",
],
+ data: [
+ ":cts-dalvik-device-test-runner",
+ ],
}
java_test {
@@ -639,6 +674,9 @@
static_libs: [
"aidl-test-interface-permission-java",
],
+ data: [
+ ":cts-dalvik-device-test-runner",
+ ],
srcs: [
"tests/java/src/android/aidl/permission/service/*.java",
],
@@ -871,6 +909,6 @@
shared_libs: [
"libbase",
"libbinder",
- "libutils"
+ "libutils",
],
}
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 6845bbf..b4837f8 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -25,11 +25,19 @@
"include-filter": "com.android.internal.telephony.ServiceStateTrackerTest"
}
]
+ },
+ {
+ "name": "EnforcePermissionTests"
}
],
"imports": [
{
"path": "frameworks/native/libs/binder"
}
+ ],
+ "auto-presubmit": [
+ {
+ "name": "hal_implementation_test"
+ }
]
}
diff --git a/aidl.cpp b/aidl.cpp
index 2572dfb..3b6f2ee 100644
--- a/aidl.cpp
+++ b/aidl.cpp
@@ -402,6 +402,8 @@
namespace internals {
+// WARNING: options are passed here and below, but only the file contents should determine
+// what is generated for portability.
AidlError load_and_validate_aidl(const std::string& input_file_name, const Options& options,
const IoDelegate& io_delegate, AidlTypenames* typenames,
vector<string>* imported_files) {
@@ -639,7 +641,8 @@
!isStable) {
err = AidlError::NOT_STRUCTURED;
AIDL_ERROR(type) << type.GetCanonicalName()
- << " does not have VINTF level stability, but this interface requires it in "
+ << " does not have VINTF level stability (marked @VintfStability), but this "
+ "interface requires it in "
<< to_string(options.TargetLanguage());
}
diff --git a/aidl_api/aidl-test-versioned-interface/3/.hash b/aidl_api/aidl-test-versioned-interface/3/.hash
new file mode 100644
index 0000000..de1b53f
--- /dev/null
+++ b/aidl_api/aidl-test-versioned-interface/3/.hash
@@ -0,0 +1 @@
+70d76c61eb0c82288e924862c10b910d1b7d8cf8
diff --git a/aidl_api/aidl-test-versioned-interface/3/android/aidl/versioned/tests/BazUnion.aidl b/aidl_api/aidl-test-versioned-interface/3/android/aidl/versioned/tests/BazUnion.aidl
new file mode 100644
index 0000000..668973f
--- /dev/null
+++ b/aidl_api/aidl-test-versioned-interface/3/android/aidl/versioned/tests/BazUnion.aidl
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.aidl.versioned.tests;
+union BazUnion {
+ int intNum;
+ long longNum;
+}
diff --git a/aidl_api/aidl-test-versioned-interface/3/android/aidl/versioned/tests/Foo.aidl b/aidl_api/aidl-test-versioned-interface/3/android/aidl/versioned/tests/Foo.aidl
new file mode 100644
index 0000000..7e5e4df
--- /dev/null
+++ b/aidl_api/aidl-test-versioned-interface/3/android/aidl/versioned/tests/Foo.aidl
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.aidl.versioned.tests;
+@JavaSuppressLint(value={"NewApi"})
+parcelable Foo {
+ int intDefault42 = 42;
+}
diff --git a/aidl_api/aidl-test-versioned-interface/3/android/aidl/versioned/tests/IFooInterface.aidl b/aidl_api/aidl-test-versioned-interface/3/android/aidl/versioned/tests/IFooInterface.aidl
new file mode 100644
index 0000000..7e4be6e
--- /dev/null
+++ b/aidl_api/aidl-test-versioned-interface/3/android/aidl/versioned/tests/IFooInterface.aidl
@@ -0,0 +1,27 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.aidl.versioned.tests;
+@JavaDelegator
+interface IFooInterface {
+ void originalApi();
+ @utf8InCpp String acceptUnionAndReturnString(in android.aidl.versioned.tests.BazUnion u);
+ @SuppressWarnings(value={"inout-parameter"}) int ignoreParcelablesAndRepeatInt(in android.aidl.versioned.tests.Foo inFoo, inout android.aidl.versioned.tests.Foo inoutFoo, out android.aidl.versioned.tests.Foo outFoo, int value);
+ int returnsLengthOfFooArray(in android.aidl.versioned.tests.Foo[] foos);
+ void newApi();
+}
diff --git a/aidl_dumpapi.cpp b/aidl_dumpapi.cpp
index 5162021..0095714 100644
--- a/aidl_dumpapi.cpp
+++ b/aidl_dumpapi.cpp
@@ -250,7 +250,8 @@
static string GetApiDumpPathFor(const AidlDefinedType& defined_type, const Options& options) {
string package_as_path = Join(Split(defined_type.GetPackage(), "."), OS_PATH_SEPARATOR);
- AIDL_FATAL_IF(options.OutputDir().empty() || options.OutputDir().back() != '/', defined_type);
+ AIDL_FATAL_IF(options.OutputDir().empty() || options.OutputDir().back() != OS_PATH_SEPARATOR,
+ defined_type);
return options.OutputDir() + package_as_path + OS_PATH_SEPARATOR + defined_type.GetName() +
".aidl";
}
diff --git a/aidl_language.cpp b/aidl_language.cpp
index 42c291c..6720818 100644
--- a/aidl_language.cpp
+++ b/aidl_language.cpp
@@ -1066,7 +1066,8 @@
valid = valid && !ValueString(AidlConstantValueDecorator).empty();
if (!valid) return false;
- const static set<string> kSupportedConstTypes = {"String", "byte", "int", "long"};
+ const static set<string> kSupportedConstTypes = {"String", "byte", "int",
+ "long", "float", "double"};
if (kSupportedConstTypes.find(type_->Signature()) == kSupportedConstTypes.end()) {
AIDL_ERROR(this) << "Constant of type " << type_->Signature() << " is not supported.";
return false;
@@ -1761,11 +1762,11 @@
}
bool AidlInterface::UsesPermissions() const {
- if (IsPermissionAnnotated()) {
+ if (EnforceExpression()) {
return true;
}
for (auto& m : GetMethods()) {
- if (m->GetType().IsPermissionAnnotated()) {
+ if (m->GetType().EnforceExpression()) {
return true;
}
}
diff --git a/aidl_to_rust.cpp b/aidl_to_rust.cpp
index 3213266..c00a994 100644
--- a/aidl_to_rust.cpp
+++ b/aidl_to_rust.cpp
@@ -100,6 +100,13 @@
return rust_name;
}
+// Usually, this means that the type implements `Default`, however `ParcelableHolder` is also
+// included in this list because the code generator knows how to call `::new(stability)`.
+bool AutoConstructor(const AidlTypeSpecifier& type, const AidlTypenames& typenames) {
+ return !(type.GetName() == "ParcelFileDescriptor" || type.GetName() == "IBinder" ||
+ TypeIsInterface(type, typenames));
+}
+
std::string GetRustName(const AidlTypeSpecifier& type, const AidlTypenames& typenames,
StorageMode mode) {
// map from AIDL built-in type name to the corresponding Rust type name
@@ -117,38 +124,26 @@
{"ParcelFileDescriptor", "binder::ParcelFileDescriptor"},
{"ParcelableHolder", "binder::ParcelableHolder"},
};
- const bool is_vector = type.IsArray() || typenames.IsList(type);
- // If the type is an array/List<T>, get the inner element type
- AIDL_FATAL_IF(typenames.IsList(type) && type.GetTypeParameters().size() != 1, type);
- const auto& element_type = type.IsGeneric() ? (*type.GetTypeParameters().at(0)) : type;
- const string& element_type_name = element_type.GetName();
- if (m.find(element_type_name) != m.end()) {
- AIDL_FATAL_IF(!AidlTypenames::IsBuiltinTypename(element_type_name), type);
- if (element_type_name == "byte" && type.IsArray()) {
- return "u8";
- } else if (element_type_name == "String" && mode == StorageMode::UNSIZED_ARGUMENT) {
+ const string& type_name = type.GetName();
+ if (m.find(type_name) != m.end()) {
+ AIDL_FATAL_IF(!AidlTypenames::IsBuiltinTypename(type_name), type);
+ if (type_name == "String" && mode == StorageMode::UNSIZED_ARGUMENT) {
return "str";
- } else if (element_type_name == "ParcelFileDescriptor" || element_type_name == "IBinder") {
- if (is_vector && mode == StorageMode::DEFAULT_VALUE) {
- // Out-arguments of ParcelFileDescriptors arrays need to
- // be Vec<Option<ParcelFileDescriptor>> so resize_out_vec
- // can initialize all elements to None (it requires Default
- // and ParcelFileDescriptor doesn't implement that)
- return "Option<" + m[element_type_name] + ">";
- } else {
- return m[element_type_name];
- }
+ } else {
+ return m[type_name];
}
- return m[element_type_name];
}
- auto name = GetRawRustName(element_type);
- if (TypeIsInterface(element_type, typenames)) {
+ auto name = GetRawRustName(type);
+ if (TypeIsInterface(type, typenames)) {
name = "binder::Strong<dyn " + name + ">";
- if (is_vector && mode == StorageMode::DEFAULT_VALUE) {
- // Out-arguments of interface arrays need to be Vec<Option<...>> so resize_out_vec
- // can initialize all elements to None.
- name = "Option<" + name + ">";
+ }
+ if (type.IsGeneric()) {
+ name += "<";
+ for (const auto& param : type.GetTypeParameters()) {
+ name += GetRustName(*param, typenames, mode);
+ name += ",";
}
+ name += ">";
}
return name;
}
@@ -215,6 +210,7 @@
StorageMode mode, Lifetime lifetime) {
std::string rust_name;
if (type.IsArray() || typenames.IsList(type)) {
+ const auto& element_type = type.IsGeneric() ? (*type.GetTypeParameters().at(0)) : type;
StorageMode element_mode;
if (type.IsFixedSizeArray() && mode == StorageMode::PARCELABLE_FIELD) {
// Elements of fixed-size array field need to have Default.
@@ -225,16 +221,21 @@
} else {
element_mode = StorageMode::VALUE;
}
- rust_name = GetRustName(type, typenames, element_mode);
- if (type.IsNullable() && UsesOptionInNullableVector(type, typenames)) {
- // The mapping for nullable string arrays is
- // optional<vector<optional<string>>> in the NDK,
- // so we do the same
- // However, we don't need to when GetRustName() already wraps it with Option.
- if (!base::StartsWith(rust_name, "Option<")) {
- rust_name = "Option<" + rust_name + ">";
- }
+ if (type.IsArray() && element_type.GetName() == "byte") {
+ rust_name = "u8";
+ } else {
+ rust_name = GetRustName(element_type, typenames, element_mode);
}
+
+ // Needs `Option` wrapping because type is not default constructible
+ const bool default_option =
+ element_mode == StorageMode::DEFAULT_VALUE && !AutoConstructor(element_type, typenames);
+ // Needs `Option` wrapping due to being a nullable, non-primitive, non-enum type in a vector.
+ const bool nullable_option = type.IsNullable() && UsesOptionInNullableVector(type, typenames);
+ if (default_option || nullable_option) {
+ rust_name = "Option<" + rust_name + ">";
+ }
+
if (mode == StorageMode::UNSIZED_ARGUMENT) {
rust_name = "[" + rust_name + "]";
} else if (type.IsFixedSizeArray()) {
diff --git a/aidl_unittest.cpp b/aidl_unittest.cpp
index 41a2082..7111a86 100644
--- a/aidl_unittest.cpp
+++ b/aidl_unittest.cpp
@@ -88,6 +88,10 @@
} // namespace
+const string INVALID_INT8_VALUE = "Invalid type specifier for an int8 literal";
+const string INVALID_FLOAT_VALUE = "Invalid type specifier for a literal float";
+const string INVALID_OPERATION = "Cannot perform operation";
+
class AidlTest : public ::testing::TestWithParam<Options::Language> {
protected:
AidlDefinedType* Parse(const string& path, const string& contents, AidlTypenames& typenames_,
@@ -129,6 +133,22 @@
return defined_types.front().get();
}
+ void EvaluateInvalidAssignment(string content, string expected_stderr, AidlTypenames& typenames_,
+ Options::Language lang) {
+ AidlError error;
+ CaptureStderr();
+ EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", content, typenames_, lang, &error));
+ EXPECT_THAT(GetCapturedStderr(), HasSubstr(expected_stderr));
+ };
+
+ void EvaluateValidAssignment(string content, string expected_stderr, AidlTypenames& typenames_,
+ Options::Language lang) {
+ AidlError error;
+ CaptureStderr();
+ EXPECT_NE(nullptr, Parse("a/IFoo.aidl", content, typenames_, lang, &error));
+ EXPECT_THAT(GetCapturedStderr(), HasSubstr(expected_stderr));
+ };
+
Options::Language GetLanguage() { return GetParam(); }
FakeIoDelegate io_delegate_;
@@ -476,7 +496,8 @@
CaptureStderr();
EXPECT_EQ(nullptr, Parse("Foo.aidl", "parcelable Foo {}", typenames_, GetLanguage(), nullptr,
{"--structured", "--stability", "vintf"}));
- EXPECT_THAT(GetCapturedStderr(), HasSubstr("Foo does not have VINTF level stability"));
+ EXPECT_THAT(GetCapturedStderr(),
+ HasSubstr("Foo does not have VINTF level stability (marked @VintfStability)"));
}
TEST_F(AidlTest, ParsesJavaOnlyStableParcelable) {
@@ -547,8 +568,9 @@
EXPECT_EQ(GetCapturedStderr(), "");
} else {
EXPECT_EQ(result, nullptr);
- EXPECT_THAT(GetCapturedStderr(),
- HasSubstr("NonPortableThing does not have VINTF level stability"));
+ EXPECT_THAT(
+ GetCapturedStderr(),
+ HasSubstr("NonPortableThing does not have VINTF level stability (marked @VintfStability)"));
}
}
@@ -1500,6 +1522,76 @@
EXPECT_EQ(AidlError::PARSE_ERROR, error);
}
+TEST_P(AidlTest, FailOnAssigningDoubleInFloatConst) {
+ EvaluateInvalidAssignment(R"(package a; interface IFoo { const float DOUBLE_VALUE = 1.1; })",
+ INVALID_FLOAT_VALUE, typenames_, GetLanguage());
+}
+
+TEST_P(AidlTest, FailOnAssigningFloatInDoubleConst) {
+ EvaluateValidAssignment(R"(package a; interface IFoo { const double FLOAT_VALUE = 1.1f; })", "",
+ typenames_, GetLanguage());
+}
+
+TEST_P(AidlTest, FailOnAssigningIntInFloatConst) {
+ EvaluateInvalidAssignment(R"(package a; interface IFoo { const float INT_VALUE = 1; })",
+ INVALID_INT8_VALUE, typenames_, GetLanguage());
+}
+
+TEST_P(AidlTest, FailOnAssigningFloatInIntConst) {
+ EvaluateInvalidAssignment(R"(package a; interface IFoo { const int FLOAT_VALUE = 1.1f; })",
+ INVALID_FLOAT_VALUE, typenames_, GetLanguage());
+}
+
+TEST_P(AidlTest, FailOnAssigningIntInDoubleConst) {
+ EvaluateInvalidAssignment(R"(package a; interface IFoo { const double INT_VALUE = 1; })",
+ INVALID_INT8_VALUE, typenames_, GetLanguage());
+}
+
+TEST_P(AidlTest, FailOnAssigningDoubleInIntConst) {
+ EvaluateInvalidAssignment(R"(package a; interface IFoo { const int DOUBLE_VALUE = 1.1; })",
+ INVALID_FLOAT_VALUE, typenames_, GetLanguage());
+}
+
+TEST_P(AidlTest, FailOnAssigningFloatPlusIntConst) {
+ EvaluateInvalidAssignment(R"(package a; interface IFoo { const float FLOAT_VALUE = 1.1f + 1; })",
+ INVALID_OPERATION, typenames_, GetLanguage());
+}
+
+TEST_P(AidlTest, FailOnAssigningIntPlusFloatConst) {
+ EvaluateInvalidAssignment(R"(package a; interface IFoo { const float FLOAT_VALUE = 1 + 1.1f; })",
+ INVALID_OPERATION, typenames_, GetLanguage());
+}
+
+TEST_P(AidlTest, FailOnAssigningDoublePlusIntConst) {
+ EvaluateInvalidAssignment(R"(package a; interface IFoo { const double DOUBLE_VALUE = 1.1 + 1; })",
+ INVALID_OPERATION, typenames_, GetLanguage());
+}
+
+TEST_P(AidlTest, FailOnAssigningIntPlusDoubleConst) {
+ EvaluateInvalidAssignment(R"(package a; interface IFoo { const double DOUBLE_VALUE = 1 + 1.1; })",
+ INVALID_OPERATION, typenames_, GetLanguage());
+}
+
+TEST_P(AidlTest, FailOnAssigningTooLargeFloatConst) {
+ EvaluateInvalidAssignment(R"(package a; interface IFoo { const float DOUBLE_VALUE = 1e50f; })",
+ INVALID_FLOAT_VALUE, typenames_, GetLanguage());
+}
+
+TEST_P(AidlTest, FailOnAssigningTooLargeDoubleConst) {
+ EvaluateInvalidAssignment(R"(package a; interface IFoo { const double DOUBLE_VALUE = 1e310; })",
+ INVALID_FLOAT_VALUE, typenames_, GetLanguage());
+}
+
+TEST_P(AidlTest, PassOnAssigningLargeFloatConst) {
+ EvaluateValidAssignment(R"(package a; interface IFoo { const float DOUBLE_VALUE = 1e20f; })", "",
+ typenames_, GetLanguage());
+}
+
+TEST_P(AidlTest, PassOnAssigningLargeDoubleConst) {
+ EvaluateValidAssignment(R"(package a; interface IFoo { const double DOUBLE_VALUE = 1e150; })", "",
+ typenames_, GetLanguage());
+}
+
TEST_P(AidlTest, FailOnMalformedQualifiedNameAsPackage) {
AidlError error;
const string expected_stderr =
diff --git a/build/Android.bp b/build/Android.bp
index 03e326c..a24dd0c 100644
--- a/build/Android.bp
+++ b/build/Android.bp
@@ -95,6 +95,7 @@
name: "test-piece-1",
local_include_dir: "tests_1",
vendor_available: true,
+ product_available: true,
double_loadable: true,
host_supported: true,
flags: ["-Werror"],
@@ -301,7 +302,13 @@
version: "1",
imports: ["test-piece-2-V1"],
},
+ {
+ version: "2",
+ imports: ["test-piece-2-V1"],
+ },
+
],
+ frozen: true,
}
cc_test_library {
diff --git a/build/aidl_api.go b/build/aidl_api.go
index 5e9d807..e6256d6 100644
--- a/build/aidl_api.go
+++ b/build/aidl_api.go
@@ -598,8 +598,7 @@
rb := android.NewRuleBuilder(pctx, ctx)
ifaceName := m.properties.BaseName
rb.Command().Text(fmt.Sprintf(`echo "API dump for the current version of AIDL interface %s does not exist."`, ifaceName))
- rb.Command().Text(fmt.Sprintf(`echo Run "m %s-update-api", or add "unstable: true" to the build rule `+
- `for the interface if it does not need to be versioned`, ifaceName))
+ rb.Command().Text(fmt.Sprintf(`echo "Run the command \"m %s-update-api\" or add \"unstable: true\" to the build rule for the interface if it does not need to be versioned"`, ifaceName))
// This file will never be created. Otherwise, the build will pass simply by running 'm; m'.
alwaysChecked := android.PathForModuleOut(ctx, "checkapi_current.timestamp")
rb.Command().Text("false").ImplicitOutput(alwaysChecked)
diff --git a/build/aidl_api/test-piece-3/2/.hash b/build/aidl_api/test-piece-3/2/.hash
new file mode 100644
index 0000000..c815cf2
--- /dev/null
+++ b/build/aidl_api/test-piece-3/2/.hash
@@ -0,0 +1 @@
+4be68328b234e427de4c612783612c3eda330235
diff --git a/build/aidl_api/test-piece-3/2/other_package/Enum.aidl b/build/aidl_api/test-piece-3/2/other_package/Enum.aidl
new file mode 100644
index 0000000..cbfbaf9
--- /dev/null
+++ b/build/aidl_api/test-piece-3/2/other_package/Enum.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package other_package;
+enum Enum {
+ ZERO,
+ ONE,
+}
diff --git a/build/aidl_api/test-piece-3/2/other_package/IBaz.aidl b/build/aidl_api/test-piece-3/2/other_package/IBaz.aidl
new file mode 100644
index 0000000..7cba2e4
--- /dev/null
+++ b/build/aidl_api/test-piece-3/2/other_package/IBaz.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package other_package;
+interface IBaz {
+ void CanYouDealWithThisBar(in some_package.IBar bar);
+ const int ZERO = other_package.Enum.ZERO /* 0 */;
+}
diff --git a/build/aidl_interface.go b/build/aidl_interface.go
index 25ff47c..1f0fef8 100644
--- a/build/aidl_interface.go
+++ b/build/aidl_interface.go
@@ -696,6 +696,11 @@
"%q imports %q which is not frozen. Either %q must set 'frozen: false' or must explicitly import %q where * is one of %q",
i.ModuleBase.Name(), anImport, i.ModuleBase.Name(), anImport+"-V*", candidateVersions)
}
+ if i.Owner() == "" && other.Owner() != "" {
+ mctx.PropertyErrorf("imports",
+ "%q imports %q which is an interface owned by %q. This is not allowed because the owned interface will not be frozen at the same time.",
+ i.ModuleBase.Name(), anImport, other.Owner())
+ }
})
}
}
@@ -1116,7 +1121,6 @@
type aidlInterfaceAttributes struct {
aidlLibraryAttributes
- Versions bazel.StringListAttribute
Stability *string
Versions_with_info []versionWithInfoAttribute
Java_config *javaConfigAttributes
@@ -1201,20 +1205,6 @@
}
func (i *aidlInterface) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
- imports := getBazelLabelListForImports(ctx, i.properties.Imports)
- headers := android.BazelLabelForModuleDeps(ctx, i.properties.Headers)
- imports.Append(headers)
-
- var deps bazel.LabelListAttribute
- if !imports.IsEmpty() {
- deps = bazel.MakeLabelListAttribute(imports)
- }
-
- var versions bazel.StringListAttribute
- if len(i.properties.Versions) > 0 {
- versions = bazel.MakeStringListAttribute(append([]string{}, i.properties.Versions...))
- }
-
var javaConfig *javaConfigAttributes
var cppConfig *cppConfigAttributes
var ndkConfig *ndkConfigAttributes
@@ -1237,25 +1227,68 @@
ndkConfig.Tags = android.ConvertApexAvailableToTags(i.properties.Backend.Ndk.Apex_available)
}
+ imports := getBazelLabelListForImports(ctx, i.properties.Imports)
+
var versionsWithInfos []versionWithInfoAttribute
+
if len(i.properties.Versions_with_info) > 0 {
for _, versionWithInfo := range i.properties.Versions_with_info {
- imports := getBazelLabelListForImports(ctx, versionWithInfo.Imports)
- var attributes versionWithInfoAttribute
- if !imports.IsEmpty() {
- attributes = versionWithInfoAttribute{
- Version: versionWithInfo.Version,
- Deps: bazel.MakeLabelListAttribute(imports),
- }
+ versionedImports := getBazelLabelListForImports(ctx, versionWithInfo.Imports)
+ if !versionedImports.IsEmpty() {
+ versionsWithInfos = append(
+ versionsWithInfos,
+ versionWithInfoAttribute{
+ Version: versionWithInfo.Version,
+ Deps: bazel.MakeLabelListAttribute(versionedImports),
+ },
+ )
} else {
- attributes = versionWithInfoAttribute{
- Version: versionWithInfo.Version,
- }
+ versionsWithInfos = append(
+ versionsWithInfos,
+ versionWithInfoAttribute{
+ Version: versionWithInfo.Version,
+ },
+ )
}
- versionsWithInfos = append(versionsWithInfos, attributes)
+ }
+ } else if len(i.properties.Versions) > 0 {
+ for _, version := range i.properties.Versions {
+ if !imports.IsEmpty() {
+ versionsWithInfos = append(
+ versionsWithInfos,
+ versionWithInfoAttribute{
+ Version: version,
+ Deps: bazel.MakeLabelListAttribute(imports),
+ },
+ )
+ } else {
+ versionsWithInfos = append(
+ versionsWithInfos,
+ versionWithInfoAttribute{
+ Version: version,
+ },
+ )
+ }
}
}
+ var deps bazel.LabelListAttribute
+
+ if len(i.properties.Srcs) > 0 && !imports.IsEmpty() {
+ // imports is only needed for (non-frozen) srcs
+ // frozen verions use imports in versions_with_info
+ deps = bazel.MakeLabelListAttribute(imports)
+ }
+
+ deps.Append(
+ bazel.MakeLabelListAttribute(
+ android.BazelLabelForModuleDeps(
+ ctx,
+ i.properties.Headers,
+ ),
+ ),
+ )
+
srcsAttr := bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, i.properties.Srcs))
var stripImportPrefixAttr *string = nil
if i.properties.Local_include_dir != "" && !srcsAttr.IsEmpty() {
@@ -1269,7 +1302,6 @@
Deps: deps,
Strip_import_prefix: stripImportPrefixAttr,
},
- Versions: versions,
Stability: i.properties.Stability,
Versions_with_info: versionsWithInfos,
Java_config: javaConfig,
@@ -1284,7 +1316,7 @@
ctx.CreateBazelTargetModule(
bazel.BazelTargetModuleProperties{
Rule_class: "aidl_interface",
- Bzl_load_location: "//build/bazel/rules/aidl:interface.bzl",
+ Bzl_load_location: "//build/bazel/rules/aidl:aidl_interface.bzl",
},
android.CommonAttributes{Name: interfaceName},
attrs,
diff --git a/build/aidl_interface_backends.go b/build/aidl_interface_backends.go
index 71f8964..de3b14a 100644
--- a/build/aidl_interface_backends.go
+++ b/build/aidl_interface_backends.go
@@ -418,15 +418,16 @@
rustCrateName := fixRustName(i.ModuleBase.Name())
mctx.CreateModule(wrapLibraryFactory(aidlRustLibraryFactory), &rustProperties{
- Name: proptools.StringPtr(rustModuleGen),
- Crate_name: rustCrateName,
- Stem: proptools.StringPtr("lib" + versionedRustName),
- Defaults: []string{"aidl-rust-module-defaults"},
- Host_supported: i.properties.Host_supported,
- Vendor_available: i.properties.Vendor_available,
- Apex_available: i.properties.Backend.Rust.Apex_available,
- Min_sdk_version: i.minSdkVersion(langRust),
- Target: rustTargetProperties{Darwin: darwinProperties{Enabled: proptools.BoolPtr(false)}},
+ Name: proptools.StringPtr(rustModuleGen),
+ Crate_name: rustCrateName,
+ Stem: proptools.StringPtr("lib" + versionedRustName),
+ Defaults: []string{"aidl-rust-module-defaults"},
+ Host_supported: i.properties.Host_supported,
+ Vendor_available: i.properties.Vendor_available,
+ Product_available: i.properties.Product_available,
+ Apex_available: i.properties.Backend.Rust.Apex_available,
+ Min_sdk_version: i.minSdkVersion(langRust),
+ Target: rustTargetProperties{Darwin: darwinProperties{Enabled: proptools.BoolPtr(false)}},
}, &rust.SourceProviderProperties{
Source_stem: proptools.StringPtr(versionedRustName),
}, &aidlRustSourceProviderProperties{
diff --git a/build/aidl_interface_bp2build_test.go b/build/aidl_interface_bp2build_test.go
index 319af91..b60c5dc 100644
--- a/build/aidl_interface_bp2build_test.go
+++ b/build/aidl_interface_bp2build_test.go
@@ -79,9 +79,13 @@
"ndk_config": `{
"enabled": True,
}`,
- "versions": `[
- "1",
- "2",
+ "versions_with_info": `[
+ {
+ "version": "1",
+ },
+ {
+ "version": "2",
+ },
]`,
}),
bp2build.MakeBazelTargetNoRestrictions("aidl_interface", "aidl-interface1", bp2build.AttrNameToString{
@@ -94,15 +98,21 @@
"ndk_config": `{
"enabled": True,
}`,
- "deps": `[
- ":aidl-interface-import-V1",
- ":aidl-interface-headers",
- ]`,
+ "deps": `[":aidl-interface-headers"]`,
"flags": `["--flag1"]`,
- "versions": `[
- "1",
- "2",
- "3",
+ "versions_with_info": `[
+ {
+ "deps": [":aidl-interface-import-V1"],
+ "version": "1",
+ },
+ {
+ "deps": [":aidl-interface-import-V1"],
+ "version": "2",
+ },
+ {
+ "deps": [":aidl-interface-import-V1"],
+ "version": "3",
+ },
]`,
}),
},
@@ -190,9 +200,13 @@
"ndk_config": `{
"enabled": True,
}`,
- "versions": `[
- "1",
- "2",
+ "versions_with_info": `[
+ {
+ "version": "1",
+ },
+ {
+ "version": "2",
+ },
]`,
}),
bp2build.MakeBazelTargetNoRestrictions("aidl_interface", "aidl-interface1", bp2build.AttrNameToString{
@@ -205,11 +219,19 @@
"ndk_config": `{
"enabled": True,
}`,
- "deps": `[":aidl-interface-import-latest"]`,
- "versions": `[
- "1",
- "2",
- "3",
+ "versions_with_info": `[
+ {
+ "deps": [":aidl-interface-import-latest"],
+ "version": "1",
+ },
+ {
+ "deps": [":aidl-interface-import-latest"],
+ "version": "2",
+ },
+ {
+ "deps": [":aidl-interface-import-latest"],
+ "version": "3",
+ },
]`,
}),
},
@@ -249,9 +271,13 @@
"ndk_config": `{
"enabled": True,
}`,
- "versions": `[
- "1",
- "2",
+ "versions_with_info": `[
+ {
+ "version": "1",
+ },
+ {
+ "version": "2",
+ },
]`,
}),
bp2build.MakeBazelTargetNoRestrictions("aidl_interface", "aidl-interface1", bp2build.AttrNameToString{
@@ -264,11 +290,19 @@
"ndk_config": `{
"enabled": True,
}`,
- "deps": `[":aidl-interface-import-V2"]`,
- "versions": `[
- "1",
- "2",
- "3",
+ "versions_with_info": `[
+ {
+ "deps": [":aidl-interface-import-V2"],
+ "version": "1",
+ },
+ {
+ "deps": [":aidl-interface-import-V2"],
+ "version": "2",
+ },
+ {
+ "deps": [":aidl-interface-import-V2"],
+ "version": "3",
+ },
]`,
}),
},
@@ -354,8 +388,10 @@
}`,
ExpectedBazelTargets: []string{
bp2build.MakeBazelTargetNoRestrictions("aidl_interface", "foo", bp2build.AttrNameToString{
- "frozen": "True",
- "versions": `["1"]`,
+ "frozen": "True",
+ "versions_with_info": `[{
+ "version": "1",
+ }]`,
"ndk_config": `{
"enabled": True,
}`,
@@ -363,3 +399,39 @@
},
})
}
+
+func TestAidlInterfaceWithApexAvailable(t *testing.T) {
+ runAidlInterfaceTestCase(t, bp2build.Bp2buildTestCase{
+ Description: `aidl_interface apex_available`,
+ Blueprint: `
+ aidl_interface {
+ name: "aidl-interface1",
+ backend: {
+ java: {
+ enabled: false,
+ },
+ cpp: {
+ enabled: false,
+ },
+ ndk: {
+ enabled: true,
+ apex_available: [
+ "com.android.abd",
+ "//apex_available:platform",
+ ],
+ },
+ }
+ }`,
+ ExpectedBazelTargets: []string{
+ bp2build.MakeBazelTargetNoRestrictions("aidl_interface", "aidl-interface1", bp2build.AttrNameToString{
+ "ndk_config": `{
+ "enabled": True,
+ "tags": [
+ "apex_available=com.android.abd",
+ "apex_available=//apex_available:platform",
+ ],
+ }`,
+ }),
+ },
+ })
+}
diff --git a/build/aidl_interface_headers.go b/build/aidl_interface_headers.go
index 6ad2a8c..523526e 100644
--- a/build/aidl_interface_headers.go
+++ b/build/aidl_interface_headers.go
@@ -75,7 +75,7 @@
ctx.CreateBazelTargetModule(
bazel.BazelTargetModuleProperties{
Rule_class: "aidl_library",
- Bzl_load_location: "//build/bazel/rules/aidl:library.bzl",
+ Bzl_load_location: "//build/bazel/rules/aidl:aidl_library.bzl",
},
android.CommonAttributes{Name: i.Name()},
attrs,
diff --git a/build/aidl_interface_metadata_singleton.go b/build/aidl_interface_metadata_singleton.go
index 8b421a5..ef3af3c 100644
--- a/build/aidl_interface_metadata_singleton.go
+++ b/build/aidl_interface_metadata_singleton.go
@@ -116,7 +116,7 @@
})
var metadataOutputs android.Paths
- for _, name := range android.SortedStringKeys(moduleInfos) {
+ for _, name := range android.SortedKeys(moduleInfos) {
info := moduleInfos[name]
metadataPath := android.PathForModuleOut(ctx, "metadata_"+name)
metadataOutputs = append(metadataOutputs, metadataPath)
diff --git a/build/aidl_test.go b/build/aidl_test.go
index 0c9abb8..f0a951b 100644
--- a/build/aidl_test.go
+++ b/build/aidl_test.go
@@ -226,7 +226,7 @@
ctx.VisitAllModules(func(m blueprint.Module) {
allModuleNames[ctx.ModuleName(m)] = true
})
- t.Errorf("expected modules(%v) not found. all modules: %v", missing, android.SortedStringKeys(allModuleNames))
+ t.Errorf("expected modules(%v) not found. all modules: %v", missing, android.SortedKeys(allModuleNames))
}
}
@@ -612,6 +612,62 @@
testAidlError(t, expectedError, frozenTest, files)
}
+func TestImportingOwned(t *testing.T) {
+ frozenTest := `
+ aidl_interface {
+ name: "xxx",
+ srcs: ["IFoo.aidl"],
+ owner: "unknown-owner",
+ frozen: false,
+ }
+ aidl_interface {
+ name: "foo",
+ imports: ["xxx-V1"],
+ frozen: false,
+ versions_with_info: [
+ {version: "1", imports: []},
+ ],
+ srcs: ["IFoo.aidl"],
+ }`
+ files := withFiles(map[string][]byte{
+ "aidl_api/foo/1/foo.1.aidl": nil,
+ "aidl_api/foo/1/.hash": nil,
+ })
+
+ expectedError := "Android.bp:10:10: module \"foo_interface\": imports: \"foo\" imports \"xxx\" which is an interface owned by \"unknown-owner\". This is not allowed because the owned interface will not be frozen at the same time."
+ testAidlError(t, expectedError, frozenTest, files, setReleaseEnv())
+ testAidlError(t, expectedError, frozenTest, files, setTestFreezeEnv())
+ testAidlError(t, expectedError, frozenTest, files)
+}
+
+func TestImportingOwnedBothOwned(t *testing.T) {
+ frozenTest := `
+ aidl_interface {
+ name: "xxx",
+ srcs: ["IFoo.aidl"],
+ owner: "unknown-owner",
+ frozen: false,
+ }
+ aidl_interface {
+ name: "foo",
+ imports: ["xxx-V1"],
+ frozen: false,
+ versions_with_info: [
+ {version: "1", imports: []},
+ ],
+ srcs: ["IFoo.aidl"],
+ owner: "unknown-owner-any",
+ }`
+ files := withFiles(map[string][]byte{
+ "aidl_api/foo/1/foo.1.aidl": nil,
+ "aidl_api/foo/1/.hash": nil,
+ })
+
+ testAidl(t, frozenTest, files, setReleaseEnv())
+ testAidl(t, frozenTest, files, setTestFreezeEnv())
+ testAidl(t, frozenTest, files)
+}
+
func TestFrozenImportingNewExplicit(t *testing.T) {
frozenTest := `
aidl_interface {
diff --git a/build/properties.go b/build/properties.go
index 95c925d..8c47792 100644
--- a/build/properties.go
+++ b/build/properties.go
@@ -91,18 +91,19 @@
}
type rustProperties struct {
- Name *string
- Crate_name string
- Owner *string
- Defaults []string
- Host_supported *bool
- Vendor_available *bool
- Srcs []string
- Rustlibs []string
- Stem *string
- Target rustTargetProperties
- Apex_available []string
- Min_sdk_version *string
+ Name *string
+ Crate_name string
+ Owner *string
+ Defaults []string
+ Host_supported *bool
+ Vendor_available *bool
+ Product_available *bool
+ Srcs []string
+ Rustlibs []string
+ Stem *string
+ Target rustTargetProperties
+ Apex_available []string
+ Min_sdk_version *string
}
type Bazel_module struct {
diff --git a/generate_cpp.cpp b/generate_cpp.cpp
index fcbe007..874fa13 100644
--- a/generate_cpp.cpp
+++ b/generate_cpp.cpp
@@ -436,6 +436,10 @@
out << "static const " << cpp_type << "& " << constant->GetName() << "()";
GenerateDeprecated(out, *constant);
out << ";\n";
+ } else if (type.Signature() == "float" || type.Signature() == "double") {
+ out << "static constexpr " << cpp_type << " " << constant->GetName();
+ GenerateDeprecated(out, *constant);
+ out << " = " << constant->ValueString(ConstantValueDecorator) << ";\n";
} else {
out << "enum : " << cpp_type << " { " << constant->GetName();
GenerateDeprecated(out, *constant);
diff --git a/generate_java_binder.cpp b/generate_java_binder.cpp
index 9c21a1c..04add06 100644
--- a/generate_java_binder.cpp
+++ b/generate_java_binder.cpp
@@ -472,7 +472,37 @@
// Visitor for the permission declared in the @EnforcePermission annotation.
class PermissionVisitor {
public:
- PermissionVisitor(CodeWriter* code) : code_(code) {}
+ PermissionVisitor(CodeWriter* code, const AidlMethod& method) : code_(code), method_(method) {
+ use_attribution_source_ = std::any_of(
+ method_.GetArguments().begin(), method_.GetArguments().end(), [](const auto& arg) {
+ return arg->GetType().GetName() == "android.content.AttributionSource";
+ });
+ }
+
+ ~PermissionVisitor() {
+ code_->Dedent();
+ *code_ << "}\n";
+ }
+
+ string Credentials() const {
+ if (use_attribution_source_) {
+ return "source";
+ }
+ return "getCallingPid(), getCallingUid()";
+ }
+
+ void Prologue() {
+ *code_ << "/** Helper method to enforce permissions for " << method_.GetName() << " */\n";
+ *code_ << "protected void " << method_.GetName() << "_enforcePermission("
+ << (use_attribution_source_ ? "android.content.AttributionSource source" : "")
+ << ") throws SecurityException {\n";
+ code_->Indent();
+ }
+
+ void AddStaticArrayPermissions(const std::vector<std::string>& permissions) {
+ *code_ << "static final String[] PERMISSIONS_" << method_.GetName() << " = {"
+ << Join(permissions, ", ") << "};\n";
+ }
void operator()(const perm::AllOf& quantifier) {
std::vector<std::string> permissions;
@@ -480,8 +510,10 @@
for (auto const& permission : quantifier.operands) {
permissions.push_back(android::aidl::perm::JavaFullName(permission));
}
- *code_ << "mEnforcer.enforcePermissionAllOf(new String[]{" << Join(permissions, ", ")
- << "}, source);\n";
+ AddStaticArrayPermissions(permissions);
+ Prologue();
+ *code_ << "mEnforcer.enforcePermissionAllOf(PERMISSIONS_" << method_.GetName() << ", "
+ << Credentials() << ");\n";
}
void operator()(const perm::AnyOf& quantifier) {
@@ -490,47 +522,34 @@
for (auto const& permission : quantifier.operands) {
permissions.push_back(android::aidl::perm::JavaFullName(permission));
}
- *code_ << "mEnforcer.enforcePermissionAnyOf(new String[]{" << Join(permissions, ", ")
- << "}, source);\n";
+ AddStaticArrayPermissions(permissions);
+ Prologue();
+ *code_ << "mEnforcer.enforcePermissionAnyOf(PERMISSIONS_" << method_.GetName() << ", "
+ << Credentials() << ");\n";
}
void operator()(const std::string& permission) {
auto permissionName = android::aidl::perm::JavaFullName(permission);
- *code_ << "mEnforcer.enforcePermission(" << permissionName << ", source);\n";
+ Prologue();
+ *code_ << "mEnforcer.enforcePermission(" << permissionName << ", " << Credentials() << ");\n";
}
private:
CodeWriter* code_;
+ const AidlMethod& method_;
+ bool use_attribution_source_;
};
static void GeneratePermissionMethod(const AidlInterface& iface, const AidlMethod& method,
const std::shared_ptr<Class>& addTo) {
string code;
CodeWriterPtr writer = CodeWriter::ForString(&code);
- *writer << "/** Helper method to enforce permissions for " << method.GetName() << " */\n";
-
- auto has_attribution_source =
- std::any_of(method.GetArguments().begin(), method.GetArguments().end(), [](const auto& arg) {
- return arg->GetType().GetName() == "android.content.AttributionSource";
- });
-
- *writer << "protected void " << method.GetName() << "_enforcePermission("
- << (has_attribution_source ? "android.content.AttributionSource source" : "")
- << ") throws SecurityException {\n";
- writer->Indent();
-
- if (!has_attribution_source) {
- *writer << "android.content.AttributionSource source = "
- "new android.content.AttributionSource(getCallingUid(), null, null);\n";
- }
if (auto ifacePermExpr = iface.EnforceExpression(); ifacePermExpr) {
- std::visit(PermissionVisitor(writer.get()), *ifacePermExpr.get());
+ std::visit(PermissionVisitor(writer.get(), method), *ifacePermExpr.get());
} else if (auto methodPermExpr = method.GetType().EnforceExpression(); methodPermExpr) {
- std::visit(PermissionVisitor(writer.get()), *methodPermExpr.get());
+ std::visit(PermissionVisitor(writer.get(), method), *methodPermExpr.get());
}
- writer->Dedent();
- *writer << "}\n";
writer->Close();
addTo->elements.push_back(std::make_shared<LiteralClassElement>(code));
}
@@ -796,6 +815,8 @@
out << "}\n";
}
+ // TODO(b/274144762): we shouldn't have different behavior for versioned interfaces
+ // also this set to false for all exceptions, not just unimplemented methods.
if (options.Version() > 0) {
out << "throw new android.os.RemoteException(\"Method " << method.GetName()
<< " is unimplemented.\");\n";
@@ -1049,6 +1070,10 @@
auto descriptor = std::make_shared<Field>(
STATIC | FINAL | PUBLIC, std::make_shared<Variable>("java.lang.String", "DESCRIPTOR"));
std::string name = iface->GetDescriptor();
+
+ // TODO(b/242862858): avoid differentiating behahavior. This is currently blocked
+ // to fix because of a metalava lint which disallows running code to generate
+ // static fields.
if (options.IsStructured()) {
// mangle the interface name at build time and demangle it at runtime, to avoid
// being renamed by jarjar. See b/153843174
diff --git a/generate_ndk.cpp b/generate_ndk.cpp
index 09168ed..bd554e7 100644
--- a/generate_ndk.cpp
+++ b/generate_ndk.cpp
@@ -425,6 +425,11 @@
out << "static const char*";
cpp::GenerateDeprecated(out, *constant);
out << " " << constant->GetName() << ";\n";
+ } else if (type.Signature() == "float" || type.Signature() == "double") {
+ out << "static constexpr " << NdkNameOf(types, type, StorageMode::STACK) << " ";
+ out << constant->GetName();
+ cpp::GenerateDeprecated(out, *constant);
+ out << " = " << constant->ValueString(ConstantValueDecorator) << ";\n";
} else {
out << "enum : " << NdkNameOf(types, type, StorageMode::STACK) << " { ";
out << constant->GetName();
diff --git a/generate_rust.cpp b/generate_rust.cpp
index e6d14e0..17beb36 100644
--- a/generate_rust.cpp
+++ b/generate_rust.cpp
@@ -548,7 +548,8 @@
if (type.Signature() == "String") {
const_type = "&str";
} else if (type.Signature() == "byte" || type.Signature() == "int" ||
- type.Signature() == "long") {
+ type.Signature() == "long" || type.Signature() == "float" ||
+ type.Signature() == "double") {
const_type = RustNameOf(type, typenames, StorageMode::VALUE, Lifetime::NONE);
} else {
AIDL_FATAL(value) << "Unrecognized constant type: " << type.Signature();
@@ -853,10 +854,50 @@
GenerateServerItems(*code_writer, iface, typenames);
}
+void RemoveUsed(std::set<std::string>* params, const AidlTypeSpecifier& type) {
+ if (!type.IsResolved()) {
+ params->erase(type.GetName());
+ }
+ if (type.IsGeneric()) {
+ for (const auto& param : type.GetTypeParameters()) {
+ RemoveUsed(params, *param);
+ }
+ }
+}
+
+std::set<std::string> FreeParams(const AidlStructuredParcelable* parcel) {
+ if (!parcel->IsGeneric()) {
+ return std::set<std::string>();
+ }
+ auto typeParams = parcel->GetTypeParameters();
+ std::set<std::string> unusedParams(typeParams.begin(), typeParams.end());
+ for (const auto& variable : parcel->GetFields()) {
+ RemoveUsed(&unusedParams, variable->GetType());
+ }
+ return unusedParams;
+}
+
+void WriteParams(CodeWriter& out, const AidlParameterizable<std::string>* parcel,
+ std::string extra) {
+ if (parcel->IsGeneric()) {
+ out << "<";
+ for (const auto& param : parcel->GetTypeParameters()) {
+ out << param << extra << ",";
+ }
+ out << ">";
+ }
+}
+
+void WriteParams(CodeWriter& out, const AidlParameterizable<std::string>* parcel) {
+ WriteParams(out, parcel, "");
+}
+
void GenerateParcelBody(CodeWriter& out, const AidlStructuredParcelable* parcel,
const AidlTypenames& typenames) {
GenerateDeprecated(out, *parcel);
- out << "pub struct r#" << parcel->GetName() << " {\n";
+ out << "pub struct r#" << parcel->GetName();
+ WriteParams(out, parcel);
+ out << " {\n";
out.Indent();
for (const auto& variable : parcel->GetFields()) {
GenerateDeprecated(out, *variable);
@@ -864,12 +905,19 @@
RustNameOf(variable->GetType(), typenames, StorageMode::PARCELABLE_FIELD, Lifetime::NONE);
out << "pub r#" << variable->GetName() << ": " << field_type << ",\n";
}
+ for (const auto& unused_param : FreeParams(parcel)) {
+ out << "_phantom_" << unused_param << ": std::marker::PhantomData<" << unused_param << ">,\n";
+ }
out.Dedent();
out << "}\n";
}
void GenerateParcelDefault(CodeWriter& out, const AidlStructuredParcelable* parcel) {
- out << "impl Default for r#" << parcel->GetName() << " {\n";
+ out << "impl";
+ WriteParams(out, parcel, ": Default");
+ out << " Default for r#" << parcel->GetName();
+ WriteParams(out, parcel);
+ out << " {\n";
out.Indent();
out << "fn default() -> Self {\n";
out.Indent();
@@ -899,6 +947,9 @@
}
out << ",\n";
}
+ for (const auto& unused_param : FreeParams(parcel)) {
+ out << "r#_phantom_" << unused_param << ": Default::default(),\n";
+ }
out.Dedent();
out << "}\n";
out.Dedent();
@@ -962,7 +1013,11 @@
}
void GenerateParcelDefault(CodeWriter& out, const AidlUnionDecl* parcel) {
- out << "impl Default for r#" << parcel->GetName() << " {\n";
+ out << "impl";
+ WriteParams(out, parcel, ": Default");
+ out << " Default for r#" << parcel->GetName();
+ WriteParams(out, parcel);
+ out << " {\n";
out.Indent();
out << "fn default() -> Self {\n";
out.Indent();
@@ -1040,7 +1095,11 @@
template <typename ParcelableType>
void GenerateParcelableTrait(CodeWriter& out, const ParcelableType* parcel,
const AidlTypenames& typenames) {
- out << "impl binder::Parcelable for r#" << parcel->GetName() << " {\n";
+ out << "impl";
+ WriteParams(out, parcel);
+ out << " binder::Parcelable for r#" << parcel->GetName();
+ WriteParams(out, parcel);
+ out << " {\n";
out.Indent();
out << "fn write_to_parcel(&self, "
@@ -1064,13 +1123,21 @@
out << "}\n";
// Emit the outer (de)serialization traits
- out << "binder::impl_serialize_for_parcelable!(r#" << parcel->GetName() << ");\n";
- out << "binder::impl_deserialize_for_parcelable!(r#" << parcel->GetName() << ");\n";
+ out << "binder::impl_serialize_for_parcelable!(r#" << parcel->GetName();
+ WriteParams(out, parcel);
+ out << ");\n";
+ out << "binder::impl_deserialize_for_parcelable!(r#" << parcel->GetName();
+ WriteParams(out, parcel);
+ out << ");\n";
}
template <typename ParcelableType>
void GenerateMetadataTrait(CodeWriter& out, const ParcelableType* parcel) {
- out << "impl binder::binder_impl::ParcelableMetadata for r#" << parcel->GetName() << " {\n";
+ out << "impl";
+ WriteParams(out, parcel);
+ out << " binder::binder_impl::ParcelableMetadata for r#" << parcel->GetName();
+ WriteParams(out, parcel);
+ out << " {\n";
out.Indent();
out << "fn get_descriptor() -> &'static str { \"" << parcel->GetCanonicalName() << "\" }\n";
diff --git a/io_delegate.cpp b/io_delegate.cpp
index d40bf1d..b903f1f 100644
--- a/io_delegate.cpp
+++ b/io_delegate.cpp
@@ -18,6 +18,7 @@
#include <cstring>
#include <fstream>
+#include <type_traits>
#include <vector>
#ifdef _WIN32
@@ -184,10 +185,51 @@
}
#ifdef _WIN32
-Result<vector<string>> IoDelegate::ListFiles(const string&) const {
- return Error() << "File listing not implemented on Windows";
-}
+static Result<void> add_list_files(const string& dirname, vector<string>* result) {
+ AIDL_FATAL_IF(result == nullptr, dirname);
+
+ WIN32_FIND_DATA find_data;
+ // Look up the first file.
+ // See https://stackoverflow.com/a/14841564/112950 for why we use remove_pointer_t
+ // here.
+ // Note: we need to use a wildcard expression like `\*` to ensure we traverse
+ // the directory. Otherwise Find{First,Next}File will only return the directory
+ // itself and stop.
+ const string path(dirname + "\\*");
+ std::unique_ptr<std::remove_pointer_t<HANDLE>, decltype(&FindClose)> search_handle(
+ FindFirstFile(path.c_str(), &find_data), FindClose);
+
+ if (search_handle.get() == INVALID_HANDLE_VALUE) {
+ return Error() << "Failed to read directory '" << dirname << "': " << GetLastError();
+ }
+
+ bool has_more_files = true;
+ do {
+ const bool skip = !strcmp(find_data.cFileName, ".") || !strcmp(find_data.cFileName, "..");
+
+ if (!skip) {
+ if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ if (auto ret = add_list_files(dirname + OS_PATH_SEPARATOR + find_data.cFileName, result);
+ !ret.ok()) {
+ return ret;
+ }
+ } else {
+ result->emplace_back(dirname + OS_PATH_SEPARATOR + find_data.cFileName);
+ }
+ }
+
+ has_more_files = FindNextFile(search_handle.get(), &find_data);
+ if (!has_more_files) {
+ const DWORD err = GetLastError();
+ if (err != ERROR_NO_MORE_FILES) {
+ return Error() << "Failed to read directory entry in '" << dirname << "': " << err;
+ }
+ }
+ } while (has_more_files);
+
+ return Result<void>();
+}
#else
static Result<void> add_list_files(const string& dirname, vector<string>* result) {
AIDL_FATAL_IF(result == nullptr, dirname);
@@ -222,6 +264,7 @@
return Result<void>();
}
+#endif
Result<vector<string>> IoDelegate::ListFiles(const string& dir) const {
vector<string> result;
@@ -230,7 +273,6 @@
}
return result;
}
-#endif
string IoDelegate::CleanPath(const string& path) {
if (base::StartsWith(path, string{'.', OS_PATH_SEPARATOR})) {
diff --git a/options.cpp b/options.cpp
index 924f1ee..adf1e1b 100644
--- a/options.cpp
+++ b/options.cpp
@@ -56,14 +56,12 @@
<< myname_ << " --preprocess OUTPUT INPUT..." << endl
<< " Create an AIDL file having declarations of AIDL file(s)." << endl
<< endl
-#ifndef _WIN32
<< myname_ << " --dumpapi --out=DIR INPUT..." << endl
<< " Dump API signature of AIDL file(s) to DIR." << endl
<< endl
<< myname_ << " --checkapi[={compatible|equal}] OLD_DIR NEW_DIR" << endl
<< " Check whether NEW_DIR API dump is {compatible|equal} extension " << endl
<< " of the API dump OLD_DIR. Default: compatible" << endl
-#endif
<< endl
<< myname_ << " --apimapping OUTPUT INPUT..." << endl
<< " Generate a mapping of declared aidl method signatures to" << endl
@@ -198,6 +196,7 @@
static const std::map<std::string, uint32_t> codeNameToVersion = {
{"S", 31},
{"Tiramisu", SDK_VERSION_Tiramisu},
+ {"UpsideDownCake", SDK_VERSION_UpsideDownCake},
// this is an alias for the latest in-development platform version
{"current", SDK_VERSION_current},
// this is an alias for use of all APIs, including those not in any API surface
@@ -267,11 +266,9 @@
static struct option long_options[] = {
{"lang", required_argument, 0, 'l'},
{"preprocess", no_argument, 0, 's'},
-#ifndef _WIN32
{"dumpapi", no_argument, 0, 'u'},
{"no_license", no_argument, 0, 'x'},
{"checkapi", optional_argument, 0, 'A'},
-#endif
{"apimapping", required_argument, 0, 'i'},
{"include", required_argument, 0, 'I'},
{"preprocessed", required_argument, 0, 'p'},
@@ -331,7 +328,6 @@
case 's':
task_ = Options::Task::PREPROCESS;
break;
-#ifndef _WIN32
case 'u':
task_ = Options::Task::DUMP_API;
break;
@@ -353,7 +349,6 @@
}
}
break;
-#endif
case 'I': {
import_dirs_.emplace(Trim(optarg));
break;
diff --git a/options.h b/options.h
index b3a7c34..01cd00c 100644
--- a/options.h
+++ b/options.h
@@ -40,6 +40,7 @@
constexpr uint32_t SDK_VERSION_current = 10000;
constexpr uint32_t SDK_VERSION_Tiramisu = 33;
+constexpr uint32_t SDK_VERSION_UpsideDownCake = 34;
constexpr uint32_t JAVA_PROPAGATE_VERSION = SDK_VERSION_Tiramisu;
@@ -88,6 +89,12 @@
std::set<std::string> no_errors_; // -Wno-error=foo
};
+// Options for AIDL
+//
+// These are passed all throughout the compiler, but they should not affect the
+// code which is generated. In order to avoid ODR issues, and also in order to
+// make sure the language is orthogonal and portable, we should only generate
+// different things based on the file contents themselves.
class Options final {
public:
enum class Language { UNSPECIFIED, JAVA, CPP, NDK, RUST, CPP_ANALYZER };
diff --git a/options_unittest.cpp b/options_unittest.cpp
index 2931bc6..4bec8a7 100644
--- a/options_unittest.cpp
+++ b/options_unittest.cpp
@@ -454,7 +454,7 @@
EXPECT_EQ(30u, options->GetMinSdkVersion());
}
-TEST(OptionsTests, AcceptCodeNameAsMinSdkVersion) {
+TEST(OptionsTests, AcceptTCodeNameAsMinSdkVersion) {
const char* args[] = {
"aidl", "--lang=java", "--min_sdk_version=Tiramisu", "--out=out", "input.aidl", nullptr,
};
@@ -463,6 +463,15 @@
EXPECT_EQ(33u, options->GetMinSdkVersion());
}
+TEST(OptionsTests, AcceptUCodeNameAsMinSdkVersion) {
+ const char* args[] = {
+ "aidl", "--lang=java", "--min_sdk_version=UpsideDownCake", "--out=out", "input.aidl", nullptr,
+ };
+ auto options = GetOptions(args);
+ EXPECT_TRUE(options->Ok());
+ EXPECT_EQ(34u, options->GetMinSdkVersion());
+}
+
TEST(OptionsTest, DefaultMinSdkVersion) {
const char* args[] = {
"aidl", "--lang=java", "--out=out", "input.aidl", nullptr,
diff --git a/tests/aidl_integration_test.py b/tests/aidl_integration_test.py
index 9fc3c3a..ae73531 100755
--- a/tests/aidl_integration_test.py
+++ b/tests/aidl_integration_test.py
@@ -1,6 +1,8 @@
#!/usr/bin/env python3
from itertools import product
+from time import sleep
+
import pipes
import re
import subprocess
@@ -273,8 +275,14 @@
def make_test(client, server):
def test(self):
try:
- client.cleanup()
+ # Server is unregistered first so that we give more time
+ # for servicemanager to clear the old notification.
+ # Otherwise, it may race that the client gets ahold
+ # of the service.
server.cleanup()
+ client.cleanup()
+ sleep(0.2)
+
server.run()
client.run()
finally:
diff --git a/tests/aidl_test_client_primitives.cpp b/tests/aidl_test_client_primitives.cpp
index eff67c4..040804d 100644
--- a/tests/aidl_test_client_primitives.cpp
+++ b/tests/aidl_test_client_primitives.cpp
@@ -120,6 +120,31 @@
}
}
+TEST_F(AidlPrimitiveTest, floatConstants) {
+ constexpr float consts[] = {
+ ITestService::FLOAT_TEST_CONSTANT, ITestService::FLOAT_TEST_CONSTANT2,
+ ITestService::FLOAT_TEST_CONSTANT3, ITestService::FLOAT_TEST_CONSTANT4,
+ ITestService::FLOAT_TEST_CONSTANT5, ITestService::FLOAT_TEST_CONSTANT6,
+ ITestService::FLOAT_TEST_CONSTANT7,
+ };
+ for (auto sent : consts) {
+ DoTest(&ITestService::RepeatFloat, sent);
+ }
+}
+
+TEST_F(AidlPrimitiveTest, doubleConstants) {
+ constexpr double consts[] = {
+ ITestService::DOUBLE_TEST_CONSTANT, ITestService::DOUBLE_TEST_CONSTANT2,
+ ITestService::DOUBLE_TEST_CONSTANT3, ITestService::DOUBLE_TEST_CONSTANT4,
+ ITestService::DOUBLE_TEST_CONSTANT5, ITestService::DOUBLE_TEST_CONSTANT6,
+ ITestService::DOUBLE_TEST_CONSTANT7, ITestService::DOUBLE_TEST_CONSTANT8,
+ ITestService::DOUBLE_TEST_CONSTANT9,
+ };
+ for (auto sent : consts) {
+ DoTest(&ITestService::RepeatDouble, sent);
+ }
+}
+
TEST_F(AidlPrimitiveTest, strings) {
std::vector<String16> strings = {
String16("Deliver us from evil."), String16(), String16("\0\0", 2),
@@ -336,4 +361,8 @@
EXPECT_THAT(ITestService::A55, Eq(1));
EXPECT_THAT(ITestService::A56, Eq(1));
EXPECT_THAT(ITestService::A57, Eq(1));
+ EXPECT_THAT(ITestService::FLOAT_TEST_CONSTANT4, Eq(2.2f));
+ EXPECT_THAT(ITestService::FLOAT_TEST_CONSTANT5, Eq(-2.2f));
+ EXPECT_THAT(ITestService::DOUBLE_TEST_CONSTANT4, Eq(2.2));
+ EXPECT_THAT(ITestService::DOUBLE_TEST_CONSTANT5, Eq(-2.2));
}
diff --git a/tests/android/aidl/tests/GenericStructuredParcelable.aidl b/tests/android/aidl/tests/GenericStructuredParcelable.aidl
index 066b24f..ffbe6bd 100644
--- a/tests/android/aidl/tests/GenericStructuredParcelable.aidl
+++ b/tests/android/aidl/tests/GenericStructuredParcelable.aidl
@@ -17,6 +17,7 @@
package android.aidl.tests;
@JavaDerive(toString=true)
+@RustDerive(PartialEq=true, Eq=true, Clone=true, Copy=true)
parcelable GenericStructuredParcelable<T, U, B> {
int a;
int b;
diff --git a/tests/android/aidl/tests/ITestService.aidl b/tests/android/aidl/tests/ITestService.aidl
index 8bee759..fd8b6b5 100644
--- a/tests/android/aidl/tests/ITestService.aidl
+++ b/tests/android/aidl/tests/ITestService.aidl
@@ -69,6 +69,24 @@
const String STRING_TEST_CONSTANT = "foo";
const String STRING_TEST_CONSTANT2 = "bar";
+ const float FLOAT_TEST_CONSTANT = 1.0f;
+ const float FLOAT_TEST_CONSTANT2 = -1.0f;
+ const float FLOAT_TEST_CONSTANT3 = +1.0f;
+ const float FLOAT_TEST_CONSTANT4 = +2.2f;
+ const float FLOAT_TEST_CONSTANT5 = -2.2f;
+ const float FLOAT_TEST_CONSTANT6 = -0.0f;
+ const float FLOAT_TEST_CONSTANT7 = +0.0f;
+
+ const double DOUBLE_TEST_CONSTANT = 1.0;
+ const double DOUBLE_TEST_CONSTANT2 = -1.0;
+ const double DOUBLE_TEST_CONSTANT3 = +1.0;
+ const double DOUBLE_TEST_CONSTANT4 = +2.2;
+ const double DOUBLE_TEST_CONSTANT5 = -2.2;
+ const double DOUBLE_TEST_CONSTANT6 = -0.0;
+ const double DOUBLE_TEST_CONSTANT7 = +0.0;
+ const double DOUBLE_TEST_CONSTANT8 = 1.1f;
+ const double DOUBLE_TEST_CONSTANT9 = -1.1f;
+
const @utf8InCpp String STRING_TEST_CONSTANT_UTF8 = "baz";
// This is to emulate a method that is added after the service is implemented.
diff --git a/tests/android/aidl/tests/permission/INoPermission.aidl b/tests/android/aidl/tests/permission/INoPermission.aidl
new file mode 100644
index 0000000..f72f0bf
--- /dev/null
+++ b/tests/android/aidl/tests/permission/INoPermission.aidl
@@ -0,0 +1,6 @@
+package android.aidl.tests.permission;
+
+@RequiresNoPermission
+interface INoPermission {
+ void foo();
+}
diff --git a/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/ITestService.h b/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/ITestService.h
index ed0afc3..cbf30fc 100644
--- a/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/ITestService.h
+++ b/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/ITestService.h
@@ -346,6 +346,22 @@
enum : int64_t { LONG_TEST_CONSTANT = 1099511627776L };
static const ::android::String16& STRING_TEST_CONSTANT();
static const ::android::String16& STRING_TEST_CONSTANT2();
+ static constexpr float FLOAT_TEST_CONSTANT = 1.000000f;
+ static constexpr float FLOAT_TEST_CONSTANT2 = -1.000000f;
+ static constexpr float FLOAT_TEST_CONSTANT3 = 1.000000f;
+ static constexpr float FLOAT_TEST_CONSTANT4 = 2.200000f;
+ static constexpr float FLOAT_TEST_CONSTANT5 = -2.200000f;
+ static constexpr float FLOAT_TEST_CONSTANT6 = -0.000000f;
+ static constexpr float FLOAT_TEST_CONSTANT7 = 0.000000f;
+ static constexpr double DOUBLE_TEST_CONSTANT = 1.000000;
+ static constexpr double DOUBLE_TEST_CONSTANT2 = -1.000000;
+ static constexpr double DOUBLE_TEST_CONSTANT3 = 1.000000;
+ static constexpr double DOUBLE_TEST_CONSTANT4 = 2.200000;
+ static constexpr double DOUBLE_TEST_CONSTANT5 = -2.200000;
+ static constexpr double DOUBLE_TEST_CONSTANT6 = -0.000000;
+ static constexpr double DOUBLE_TEST_CONSTANT7 = 0.000000;
+ static constexpr double DOUBLE_TEST_CONSTANT8 = 1.100000;
+ static constexpr double DOUBLE_TEST_CONSTANT9 = -1.100000;
static const ::std::string& STRING_TEST_CONSTANT_UTF8();
enum : int32_t { A1 = 1 };
enum : int32_t { A2 = 1 };
diff --git a/tests/golden_output/aidl-test-interface-java-source/gen/android/aidl/tests/ITestService.java b/tests/golden_output/aidl-test-interface-java-source/gen/android/aidl/tests/ITestService.java
index 480489a..650d907 100644
--- a/tests/golden_output/aidl-test-interface-java-source/gen/android/aidl/tests/ITestService.java
+++ b/tests/golden_output/aidl-test-interface-java-source/gen/android/aidl/tests/ITestService.java
@@ -3558,6 +3558,22 @@
public static final long LONG_TEST_CONSTANT = 1099511627776L;
public static final String STRING_TEST_CONSTANT = "foo";
public static final String STRING_TEST_CONSTANT2 = "bar";
+ public static final float FLOAT_TEST_CONSTANT = 1.000000f;
+ public static final float FLOAT_TEST_CONSTANT2 = -1.000000f;
+ public static final float FLOAT_TEST_CONSTANT3 = 1.000000f;
+ public static final float FLOAT_TEST_CONSTANT4 = 2.200000f;
+ public static final float FLOAT_TEST_CONSTANT5 = -2.200000f;
+ public static final float FLOAT_TEST_CONSTANT6 = -0.000000f;
+ public static final float FLOAT_TEST_CONSTANT7 = 0.000000f;
+ public static final double DOUBLE_TEST_CONSTANT = 1.000000;
+ public static final double DOUBLE_TEST_CONSTANT2 = -1.000000;
+ public static final double DOUBLE_TEST_CONSTANT3 = 1.000000;
+ public static final double DOUBLE_TEST_CONSTANT4 = 2.200000;
+ public static final double DOUBLE_TEST_CONSTANT5 = -2.200000;
+ public static final double DOUBLE_TEST_CONSTANT6 = -0.000000;
+ public static final double DOUBLE_TEST_CONSTANT7 = 0.000000;
+ public static final double DOUBLE_TEST_CONSTANT8 = 1.100000;
+ public static final double DOUBLE_TEST_CONSTANT9 = -1.100000;
public static final String STRING_TEST_CONSTANT_UTF8 = "baz";
// All these constant expressions should be equal to 1
public static final int A1 = 1;
diff --git a/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/ITestService.h b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/ITestService.h
index 09e36a7..c23f776 100644
--- a/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/ITestService.h
+++ b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/ITestService.h
@@ -361,6 +361,22 @@
enum : int64_t { LONG_TEST_CONSTANT = 1099511627776L };
static const char* STRING_TEST_CONSTANT;
static const char* STRING_TEST_CONSTANT2;
+ static constexpr float FLOAT_TEST_CONSTANT = 1.000000f;
+ static constexpr float FLOAT_TEST_CONSTANT2 = -1.000000f;
+ static constexpr float FLOAT_TEST_CONSTANT3 = 1.000000f;
+ static constexpr float FLOAT_TEST_CONSTANT4 = 2.200000f;
+ static constexpr float FLOAT_TEST_CONSTANT5 = -2.200000f;
+ static constexpr float FLOAT_TEST_CONSTANT6 = -0.000000f;
+ static constexpr float FLOAT_TEST_CONSTANT7 = 0.000000f;
+ static constexpr double DOUBLE_TEST_CONSTANT = 1.000000;
+ static constexpr double DOUBLE_TEST_CONSTANT2 = -1.000000;
+ static constexpr double DOUBLE_TEST_CONSTANT3 = 1.000000;
+ static constexpr double DOUBLE_TEST_CONSTANT4 = 2.200000;
+ static constexpr double DOUBLE_TEST_CONSTANT5 = -2.200000;
+ static constexpr double DOUBLE_TEST_CONSTANT6 = -0.000000;
+ static constexpr double DOUBLE_TEST_CONSTANT7 = 0.000000;
+ static constexpr double DOUBLE_TEST_CONSTANT8 = 1.100000;
+ static constexpr double DOUBLE_TEST_CONSTANT9 = -1.100000;
static const char* STRING_TEST_CONSTANT_UTF8;
enum : int32_t { A1 = 1 };
enum : int32_t { A2 = 1 };
diff --git a/tests/golden_output/aidl-test-interface-permission-java-source/gen/android/aidl/tests/permission/INoPermission.java b/tests/golden_output/aidl-test-interface-permission-java-source/gen/android/aidl/tests/permission/INoPermission.java
new file mode 100644
index 0000000..fc65b93
--- /dev/null
+++ b/tests/golden_output/aidl-test-interface-permission-java-source/gen/android/aidl/tests/permission/INoPermission.java
@@ -0,0 +1,134 @@
+/*
+ * This file is auto-generated. DO NOT MODIFY.
+ */
+package android.aidl.tests.permission;
+public interface INoPermission extends android.os.IInterface
+{
+ /** Default implementation for INoPermission. */
+ public static class Default implements android.aidl.tests.permission.INoPermission
+ {
+ @Override public void foo() throws android.os.RemoteException
+ {
+ }
+ @Override
+ public android.os.IBinder asBinder() {
+ return null;
+ }
+ }
+ /** Local-side IPC implementation stub class. */
+ public static abstract class Stub extends android.os.Binder implements android.aidl.tests.permission.INoPermission
+ {
+ /** Construct the stub at attach it to the interface. */
+ public Stub()
+ {
+ this.attachInterface(this, DESCRIPTOR);
+ }
+ /**
+ * Cast an IBinder object into an android.aidl.tests.permission.INoPermission interface,
+ * generating a proxy if needed.
+ */
+ public static android.aidl.tests.permission.INoPermission asInterface(android.os.IBinder obj)
+ {
+ if ((obj==null)) {
+ return null;
+ }
+ android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
+ if (((iin!=null)&&(iin instanceof android.aidl.tests.permission.INoPermission))) {
+ return ((android.aidl.tests.permission.INoPermission)iin);
+ }
+ return new android.aidl.tests.permission.INoPermission.Stub.Proxy(obj);
+ }
+ @Override public android.os.IBinder asBinder()
+ {
+ return this;
+ }
+ /** @hide */
+ public static java.lang.String getDefaultTransactionName(int transactionCode)
+ {
+ switch (transactionCode)
+ {
+ case TRANSACTION_foo:
+ {
+ return "foo";
+ }
+ default:
+ {
+ return null;
+ }
+ }
+ }
+ /** @hide */
+ public java.lang.String getTransactionName(int transactionCode)
+ {
+ return this.getDefaultTransactionName(transactionCode);
+ }
+ @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;
+ if (code >= android.os.IBinder.FIRST_CALL_TRANSACTION && code <= android.os.IBinder.LAST_CALL_TRANSACTION) {
+ data.enforceInterface(descriptor);
+ }
+ switch (code)
+ {
+ case INTERFACE_TRANSACTION:
+ {
+ reply.writeString(descriptor);
+ return true;
+ }
+ }
+ switch (code)
+ {
+ case TRANSACTION_foo:
+ {
+ this.foo();
+ reply.writeNoException();
+ break;
+ }
+ default:
+ {
+ return super.onTransact(code, data, reply, flags);
+ }
+ }
+ return true;
+ }
+ private static class Proxy implements android.aidl.tests.permission.INoPermission
+ {
+ 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 void foo() throws android.os.RemoteException
+ {
+ android.os.Parcel _data = android.os.Parcel.obtain(asBinder());
+ android.os.Parcel _reply = android.os.Parcel.obtain();
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ boolean _status = mRemote.transact(Stub.TRANSACTION_foo, _data, _reply, 0);
+ _reply.readException();
+ }
+ finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ }
+ }
+ static final int TRANSACTION_foo = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
+ /** @hide */
+ public int getMaxTransactionId()
+ {
+ return 0;
+ }
+ }
+ public static final java.lang.String DESCRIPTOR = "android$aidl$tests$permission$INoPermission".replace('$', '.');
+ @android.annotation.RequiresNoPermission
+ public void foo() throws android.os.RemoteException;
+}
diff --git a/tests/golden_output/aidl-test-interface-permission-java-source/gen/android/aidl/tests/permission/INoPermission.java.d b/tests/golden_output/aidl-test-interface-permission-java-source/gen/android/aidl/tests/permission/INoPermission.java.d
new file mode 100644
index 0000000..c213fdc
--- /dev/null
+++ b/tests/golden_output/aidl-test-interface-permission-java-source/gen/android/aidl/tests/permission/INoPermission.java.d
@@ -0,0 +1,2 @@
+out/soong/.intermediates/system/tools/aidl/aidl-test-interface-permission-java-source/gen/android/aidl/tests/permission/INoPermission.java : \
+ system/tools/aidl/tests/android/aidl/tests/permission/INoPermission.aidl
diff --git a/tests/golden_output/aidl-test-interface-permission-java-source/gen/android/aidl/tests/permission/IProtected.java b/tests/golden_output/aidl-test-interface-permission-java-source/gen/android/aidl/tests/permission/IProtected.java
index 6c35028..1e10c08 100644
--- a/tests/golden_output/aidl-test-interface-permission-java-source/gen/android/aidl/tests/permission/IProtected.java
+++ b/tests/golden_output/aidl-test-interface-permission-java-source/gen/android/aidl/tests/permission/IProtected.java
@@ -249,26 +249,24 @@
static final int TRANSACTION_PermissionProtected = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
/** Helper method to enforce permissions for PermissionProtected */
protected void PermissionProtected_enforcePermission() throws SecurityException {
- android.content.AttributionSource source = new android.content.AttributionSource(getCallingUid(), null, null);
- mEnforcer.enforcePermission(android.Manifest.permission.READ_PHONE_STATE, source);
+ mEnforcer.enforcePermission(android.Manifest.permission.READ_PHONE_STATE, getCallingPid(), getCallingUid());
}
static final int TRANSACTION_MultiplePermissionsAll = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
+ static final String[] PERMISSIONS_MultiplePermissionsAll = {android.Manifest.permission.INTERNET, android.Manifest.permission.VIBRATE};
/** Helper method to enforce permissions for MultiplePermissionsAll */
protected void MultiplePermissionsAll_enforcePermission() throws SecurityException {
- android.content.AttributionSource source = new android.content.AttributionSource(getCallingUid(), null, null);
- mEnforcer.enforcePermissionAllOf(new String[]{android.Manifest.permission.INTERNET, android.Manifest.permission.VIBRATE}, source);
+ mEnforcer.enforcePermissionAllOf(PERMISSIONS_MultiplePermissionsAll, getCallingPid(), getCallingUid());
}
static final int TRANSACTION_MultiplePermissionsAny = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
+ static final String[] PERMISSIONS_MultiplePermissionsAny = {android.Manifest.permission.INTERNET, android.Manifest.permission.VIBRATE};
/** Helper method to enforce permissions for MultiplePermissionsAny */
protected void MultiplePermissionsAny_enforcePermission() throws SecurityException {
- android.content.AttributionSource source = new android.content.AttributionSource(getCallingUid(), null, null);
- mEnforcer.enforcePermissionAnyOf(new String[]{android.Manifest.permission.INTERNET, android.Manifest.permission.VIBRATE}, source);
+ mEnforcer.enforcePermissionAnyOf(PERMISSIONS_MultiplePermissionsAny, getCallingPid(), getCallingUid());
}
static final int TRANSACTION_NonManifestPermission = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
/** Helper method to enforce permissions for NonManifestPermission */
protected void NonManifestPermission_enforcePermission() throws SecurityException {
- android.content.AttributionSource source = new android.content.AttributionSource(getCallingUid(), null, null);
- mEnforcer.enforcePermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, source);
+ mEnforcer.enforcePermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, getCallingPid(), getCallingUid());
}
static final int TRANSACTION_SetGranted = (android.os.IBinder.FIRST_CALL_TRANSACTION + 4);
/** @hide */
diff --git a/tests/golden_output/aidl-test-interface-permission-java-source/gen/android/aidl/tests/permission/IProtectedInterface.java b/tests/golden_output/aidl-test-interface-permission-java-source/gen/android/aidl/tests/permission/IProtectedInterface.java
index 24f1f2d..5a97ed0 100644
--- a/tests/golden_output/aidl-test-interface-permission-java-source/gen/android/aidl/tests/permission/IProtectedInterface.java
+++ b/tests/golden_output/aidl-test-interface-permission-java-source/gen/android/aidl/tests/permission/IProtectedInterface.java
@@ -162,14 +162,12 @@
static final int TRANSACTION_Method1 = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
/** Helper method to enforce permissions for Method1 */
protected void Method1_enforcePermission() throws SecurityException {
- android.content.AttributionSource source = new android.content.AttributionSource(getCallingUid(), null, null);
- mEnforcer.enforcePermission(android.Manifest.permission.ACCESS_FINE_LOCATION, source);
+ mEnforcer.enforcePermission(android.Manifest.permission.ACCESS_FINE_LOCATION, getCallingPid(), getCallingUid());
}
static final int TRANSACTION_Method2 = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
/** Helper method to enforce permissions for Method2 */
protected void Method2_enforcePermission() throws SecurityException {
- android.content.AttributionSource source = new android.content.AttributionSource(getCallingUid(), null, null);
- mEnforcer.enforcePermission(android.Manifest.permission.ACCESS_FINE_LOCATION, source);
+ mEnforcer.enforcePermission(android.Manifest.permission.ACCESS_FINE_LOCATION, getCallingPid(), getCallingUid());
}
/** @hide */
public int getMaxTransactionId()
diff --git a/tests/golden_output/aidl-test-interface-permission-java-source/gen/android/aidl/tests/permission/platform/IProtected.java b/tests/golden_output/aidl-test-interface-permission-java-source/gen/android/aidl/tests/permission/platform/IProtected.java
index d6fde91..954527f 100644
--- a/tests/golden_output/aidl-test-interface-permission-java-source/gen/android/aidl/tests/permission/platform/IProtected.java
+++ b/tests/golden_output/aidl-test-interface-permission-java-source/gen/android/aidl/tests/permission/platform/IProtected.java
@@ -137,9 +137,10 @@
}
}
static final int TRANSACTION_ProtectedWithSourceAttribution = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
+ static final String[] PERMISSIONS_ProtectedWithSourceAttribution = {android.Manifest.permission.INTERNET, android.Manifest.permission.VIBRATE};
/** Helper method to enforce permissions for ProtectedWithSourceAttribution */
protected void ProtectedWithSourceAttribution_enforcePermission(android.content.AttributionSource source) throws SecurityException {
- mEnforcer.enforcePermissionAllOf(new String[]{android.Manifest.permission.INTERNET, android.Manifest.permission.VIBRATE}, source);
+ mEnforcer.enforcePermissionAllOf(PERMISSIONS_ProtectedWithSourceAttribution, source);
}
/** @hide */
public int getMaxTransactionId()
diff --git a/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/GenericStructuredParcelable.rs b/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/GenericStructuredParcelable.rs
index 290e34f..9323b15 100644
--- a/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/GenericStructuredParcelable.rs
+++ b/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/GenericStructuredParcelable.rs
@@ -1,19 +1,25 @@
#![forbid(unsafe_code)]
#![rustfmt::skip]
-#[derive(Debug)]
-pub struct r#GenericStructuredParcelable {
+#[derive(Debug, Clone, Copy, Eq, PartialEq)]
+pub struct r#GenericStructuredParcelable<T,U,B,> {
pub r#a: i32,
pub r#b: i32,
+ _phantom_B: std::marker::PhantomData<B>,
+ _phantom_T: std::marker::PhantomData<T>,
+ _phantom_U: std::marker::PhantomData<U>,
}
-impl Default for r#GenericStructuredParcelable {
+impl<T: Default,U: Default,B: Default,> Default for r#GenericStructuredParcelable<T,U,B,> {
fn default() -> Self {
Self {
r#a: 0,
r#b: 0,
+ r#_phantom_B: Default::default(),
+ r#_phantom_T: Default::default(),
+ r#_phantom_U: Default::default(),
}
}
}
-impl binder::Parcelable for r#GenericStructuredParcelable {
+impl<T,U,B,> binder::Parcelable for r#GenericStructuredParcelable<T,U,B,> {
fn write_to_parcel(&self, parcel: &mut binder::binder_impl::BorrowedParcel) -> std::result::Result<(), binder::StatusCode> {
parcel.sized_write(|subparcel| {
subparcel.write(&self.r#a)?;
@@ -33,9 +39,9 @@
})
}
}
-binder::impl_serialize_for_parcelable!(r#GenericStructuredParcelable);
-binder::impl_deserialize_for_parcelable!(r#GenericStructuredParcelable);
-impl binder::binder_impl::ParcelableMetadata for r#GenericStructuredParcelable {
+binder::impl_serialize_for_parcelable!(r#GenericStructuredParcelable<T,U,B,>);
+binder::impl_deserialize_for_parcelable!(r#GenericStructuredParcelable<T,U,B,>);
+impl<T,U,B,> binder::binder_impl::ParcelableMetadata for r#GenericStructuredParcelable<T,U,B,> {
fn get_descriptor() -> &'static str { "android.aidl.tests.GenericStructuredParcelable" }
}
pub(crate) mod mangled {
diff --git a/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/ITestService.rs b/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/ITestService.rs
index b924f9b..b9b36d3 100644
--- a/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/ITestService.rs
+++ b/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/ITestService.rs
@@ -761,6 +761,22 @@
pub const r#LONG_TEST_CONSTANT: i64 = 1099511627776;
pub const r#STRING_TEST_CONSTANT: &str = "foo";
pub const r#STRING_TEST_CONSTANT2: &str = "bar";
+pub const r#FLOAT_TEST_CONSTANT: f32 = 1.000000f32;
+pub const r#FLOAT_TEST_CONSTANT2: f32 = -1.000000f32;
+pub const r#FLOAT_TEST_CONSTANT3: f32 = 1.000000f32;
+pub const r#FLOAT_TEST_CONSTANT4: f32 = 2.200000f32;
+pub const r#FLOAT_TEST_CONSTANT5: f32 = -2.200000f32;
+pub const r#FLOAT_TEST_CONSTANT6: f32 = -0.000000f32;
+pub const r#FLOAT_TEST_CONSTANT7: f32 = 0.000000f32;
+pub const r#DOUBLE_TEST_CONSTANT: f64 = 1.000000f64;
+pub const r#DOUBLE_TEST_CONSTANT2: f64 = -1.000000f64;
+pub const r#DOUBLE_TEST_CONSTANT3: f64 = 1.000000f64;
+pub const r#DOUBLE_TEST_CONSTANT4: f64 = 2.200000f64;
+pub const r#DOUBLE_TEST_CONSTANT5: f64 = -2.200000f64;
+pub const r#DOUBLE_TEST_CONSTANT6: f64 = -0.000000f64;
+pub const r#DOUBLE_TEST_CONSTANT7: f64 = 0.000000f64;
+pub const r#DOUBLE_TEST_CONSTANT8: f64 = 1.100000f64;
+pub const r#DOUBLE_TEST_CONSTANT9: f64 = -1.100000f64;
pub const r#STRING_TEST_CONSTANT_UTF8: &str = "baz";
pub const r#A1: i32 = 1;
pub const r#A2: i32 = 1;
diff --git a/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/ParcelableForToString.rs b/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/ParcelableForToString.rs
index 4283a73..9dec2a4 100644
--- a/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/ParcelableForToString.rs
+++ b/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/ParcelableForToString.rs
@@ -23,7 +23,7 @@
pub r#enumArray: Vec<crate::mangled::_7_android_4_aidl_5_tests_7_IntEnum>,
pub r#nullArray: Vec<String>,
pub r#nullList: Vec<String>,
- pub r#parcelableGeneric: i32,
+ pub r#parcelableGeneric: crate::mangled::_7_android_4_aidl_5_tests_27_GenericStructuredParcelable<i32,crate::mangled::_7_android_4_aidl_5_tests_20_StructuredParcelable,crate::mangled::_7_android_4_aidl_5_tests_7_IntEnum,>,
pub r#unionValue: crate::mangled::_7_android_4_aidl_5_tests_5_Union,
}
impl Default for r#ParcelableForToString {
diff --git a/tests/java/src/android/aidl/permission/service/FakePermissionEnforcer.java b/tests/java/src/android/aidl/permission/service/FakePermissionEnforcer.java
index 92ec830..f7b694a 100644
--- a/tests/java/src/android/aidl/permission/service/FakePermissionEnforcer.java
+++ b/tests/java/src/android/aidl/permission/service/FakePermissionEnforcer.java
@@ -31,6 +31,14 @@
public void setGranted(List<String> granted) { mGranted = granted; }
@Override
+ protected int checkPermission(@NonNull String permission, int pid, int uid) {
+ if (mGranted != null && mGranted.contains(permission)) {
+ return PERMISSION_GRANTED;
+ }
+ return PERMISSION_HARD_DENIED;
+ }
+
+ @Override
protected int checkPermission(@NonNull String permission, @NonNull AttributionSource source) {
if (mGranted != null && mGranted.contains(permission)) {
return PERMISSION_GRANTED;
diff --git a/tests/java/src/android/aidl/tests/TestServiceClient.java b/tests/java/src/android/aidl/tests/TestServiceClient.java
index 4dd383c..6f29886 100644
--- a/tests/java/src/android/aidl/tests/TestServiceClient.java
+++ b/tests/java/src/android/aidl/tests/TestServiceClient.java
@@ -134,6 +134,28 @@
}
@Test
+ public void testConstFloatRepeat() throws RemoteException {
+ float query[] = {ITestService.FLOAT_TEST_CONSTANT, ITestService.FLOAT_TEST_CONSTANT2,
+ ITestService.FLOAT_TEST_CONSTANT3, ITestService.FLOAT_TEST_CONSTANT4,
+ ITestService.FLOAT_TEST_CONSTANT5, ITestService.FLOAT_TEST_CONSTANT6,
+ ITestService.FLOAT_TEST_CONSTANT7};
+ for (int i = 0; i < query.length; i++) {
+ assertThat(service.RepeatFloat(query[i]), is(query[i]));
+ }
+ }
+
+ @Test
+ public void testConstDoubleRepeat() throws RemoteException {
+ double query[] = {ITestService.DOUBLE_TEST_CONSTANT, ITestService.DOUBLE_TEST_CONSTANT2,
+ ITestService.DOUBLE_TEST_CONSTANT3, ITestService.DOUBLE_TEST_CONSTANT4,
+ ITestService.DOUBLE_TEST_CONSTANT5, ITestService.DOUBLE_TEST_CONSTANT6,
+ ITestService.DOUBLE_TEST_CONSTANT7};
+ for (int i = 0; i < query.length; i++) {
+ assertThat(service.RepeatDouble(query[i]), is(query[i]));
+ }
+ }
+
+ @Test
public void testLongRepeat() throws RemoteException {
long query = 1L << 60;
assertThat(service.RepeatLong(query), is(query));
diff --git a/tests/rust/test_client.rs b/tests/rust/test_client.rs
index a22f094..cd24eae 100644
--- a/tests/rust/test_client.rs
+++ b/tests/rust/test_client.rs
@@ -121,6 +121,10 @@
assert_eq!(ITestService::A55, 1);
assert_eq!(ITestService::A56, 1);
assert_eq!(ITestService::A57, 1);
+ assert_eq!(ITestService::FLOAT_TEST_CONSTANT4, 2.2_f32);
+ assert_eq!(ITestService::FLOAT_TEST_CONSTANT5, -2.2_f32);
+ assert_eq!(ITestService::DOUBLE_TEST_CONSTANT4, 2.2_f64);
+ assert_eq!(ITestService::DOUBLE_TEST_CONSTANT5, -2.2_f64);
}
#[test]
@@ -165,6 +169,20 @@
test_primitive! {test_primitive_byte_enum, RepeatByteEnum, ByteEnum::FOO}
test_primitive! {test_primitive_int_enum, RepeatIntEnum, IntEnum::BAR}
test_primitive! {test_primitive_long_enum, RepeatLongEnum, LongEnum::FOO}
+test_primitive! {test_primitive_float_constant, RepeatFloat, ITestService::FLOAT_TEST_CONSTANT}
+test_primitive! {test_primitive_float_constant2, RepeatFloat, ITestService::FLOAT_TEST_CONSTANT2}
+test_primitive! {test_primitive_float_constant3, RepeatFloat, ITestService::FLOAT_TEST_CONSTANT3}
+test_primitive! {test_primitive_float_constant4, RepeatFloat, ITestService::FLOAT_TEST_CONSTANT4}
+test_primitive! {test_primitive_float_constant5, RepeatFloat, ITestService::FLOAT_TEST_CONSTANT5}
+test_primitive! {test_primitive_float_constant6, RepeatFloat, ITestService::FLOAT_TEST_CONSTANT6}
+test_primitive! {test_primitive_float_constant7, RepeatFloat, ITestService::FLOAT_TEST_CONSTANT7}
+test_primitive! {test_primitive_double_constant, RepeatDouble, ITestService::DOUBLE_TEST_CONSTANT}
+test_primitive! {test_primitive_double_constant2, RepeatDouble, ITestService::DOUBLE_TEST_CONSTANT2}
+test_primitive! {test_primitive_double_constant3, RepeatDouble, ITestService::DOUBLE_TEST_CONSTANT3}
+test_primitive! {test_primitive_double_constant4, RepeatDouble, ITestService::DOUBLE_TEST_CONSTANT4}
+test_primitive! {test_primitive_double_constant5, RepeatDouble, ITestService::DOUBLE_TEST_CONSTANT5}
+test_primitive! {test_primitive_double_constant6, RepeatDouble, ITestService::DOUBLE_TEST_CONSTANT6}
+test_primitive! {test_primitive_double_constant7, RepeatDouble, ITestService::DOUBLE_TEST_CONSTANT7}
#[test]
fn test_repeat_string() {