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() {