Snap for 8303596 from dc3d2632dd81cad257d7f20b6beb89c34869ca4c to mainline-sdkext-release

Change-Id: I07ebd644b7f484bd1c10b314ad38b4dd4b73423b
diff --git a/aidl_api/aidl-test-versioned-interface/current/android/aidl/versioned/tests/Foo.aidl b/aidl_api/aidl-test-versioned-interface/current/android/aidl/versioned/tests/Foo.aidl
index dad05e6..7e5e4df 100644
--- a/aidl_api/aidl-test-versioned-interface/current/android/aidl/versioned/tests/Foo.aidl
+++ b/aidl_api/aidl-test-versioned-interface/current/android/aidl/versioned/tests/Foo.aidl
@@ -17,6 +17,7 @@
 // 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_checkapi.cpp b/aidl_checkapi.cpp
index b132494..8e18374 100644
--- a/aidl_checkapi.cpp
+++ b/aidl_checkapi.cpp
@@ -88,6 +88,7 @@
       AidlAnnotation::Type::JAVA_DERIVE,
       AidlAnnotation::Type::JAVA_DEFAULT,
       AidlAnnotation::Type::JAVA_ONLY_IMMUTABLE,
+      AidlAnnotation::Type::JAVA_SUPPRESS_LINT,
       // @Backing for a enum type is checked by the enum checker
       AidlAnnotation::Type::BACKING,
       // @RustDerive doesn't affect read/write
diff --git a/aidl_language.cpp b/aidl_language.cpp
index 2210477..733d5e2 100644
--- a/aidl_language.cpp
+++ b/aidl_language.cpp
@@ -134,6 +134,10 @@
        CONTEXT_TYPE_STRUCTURED_PARCELABLE | CONTEXT_TYPE_UNION |
            CONTEXT_TYPE_UNSTRUCTURED_PARCELABLE,
        {}},
+      {AidlAnnotation::Type::JAVA_SUPPRESS_LINT,
+       "JavaSuppressLint",
+       CONTEXT_ALL,
+       {{"value", kStringArrayType, /* required= */ true}}},
       {AidlAnnotation::Type::FIXED_SIZE, "FixedSize", CONTEXT_TYPE_STRUCTURED_PARCELABLE, {}},
       {AidlAnnotation::Type::DESCRIPTOR,
        "Descriptor",
diff --git a/aidl_language.h b/aidl_language.h
index 36c5066..69cf38f 100644
--- a/aidl_language.h
+++ b/aidl_language.h
@@ -211,6 +211,7 @@
     JAVA_DERIVE,
     JAVA_DEFAULT,
     JAVA_ONLY_IMMUTABLE,
+    JAVA_SUPPRESS_LINT,
     FIXED_SIZE,
     DESCRIPTOR,
     RUST_DERIVE,
diff --git a/aidl_unittest.cpp b/aidl_unittest.cpp
index f825cfd..eef607f 100644
--- a/aidl_unittest.cpp
+++ b/aidl_unittest.cpp
@@ -2238,6 +2238,21 @@
   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
 }
 
+TEST_F(AidlTestCompatibleChanges, NewJavaSuppressLint) {
+  io_delegate_.SetFileContents("old/p/IFoo.aidl",
+                               "package p;"
+                               "interface IFoo {"
+                               "  void foo(int a);"
+                               "}");
+  io_delegate_.SetFileContents("new/p/IFoo.aidl",
+                               "package p;"
+                               "@JavaSuppressLint({\"NewApi\"})"
+                               "interface IFoo {"
+                               "  void foo(int a);"
+                               "}");
+  EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
+}
+
 class AidlTestIncompatibleChanges : public AidlTest {
  protected:
   Options options_ = Options::From("aidl --checkapi old new");
@@ -3064,6 +3079,21 @@
   EXPECT_EQ(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
 }
 
+TEST_F(AidlTest, JavaSuppressLint) {
+  io_delegate_.SetFileContents("a/IFoo.aidl", R"(package a;
+    @JavaSuppressLint({"NewApi"})
+    interface IFoo {
+    })");
+
+  Options options = Options::From("aidl --lang=java -o out a/IFoo.aidl");
+  CaptureStderr();
+  EXPECT_TRUE(compile_aidl(options, io_delegate_));
+  EXPECT_EQ(GetCapturedStderr(), "");
+  string code;
+  EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/IFoo.java", &code));
+  EXPECT_THAT(code, HasSubstr("@android.annotation.SuppressLint(value = {\"NewApi\"})"));
+}
+
 class AidlOutputPathTest : public AidlTest {
  protected:
   void SetUp() override {
diff --git a/build/aidl_interface.go b/build/aidl_interface.go
index 80ba3d6..7be12e8 100644
--- a/build/aidl_interface.go
+++ b/build/aidl_interface.go
@@ -375,6 +375,8 @@
 			// Whether to compile against platform APIs instead of
 			// an SDK.
 			Platform_apis *bool
+			// Lint properties for generated java module
+			java.LintProperties
 		}
 		// Backend of the compiler generating code for C++ clients using
 		// libbinder (unstable C++ interface)
diff --git a/build/aidl_interface_backends.go b/build/aidl_interface_backends.go
index 6c778af..21f0a31 100644
--- a/build/aidl_interface_backends.go
+++ b/build/aidl_interface_backends.go
@@ -253,7 +253,7 @@
 			Srcs:            []string{":" + javaSourceGen},
 			Apex_available:  i.properties.Backend.Java.Apex_available,
 			Min_sdk_version: i.properties.Backend.Java.Min_sdk_version,
-		}},
+		}, &i.properties.Backend.Java.LintProperties},
 	})
 
 	return javaModuleGen
diff --git a/generate_java.cpp b/generate_java.cpp
index f3b7a93..e1d8298 100644
--- a/generate_java.cpp
+++ b/generate_java.cpp
@@ -966,6 +966,13 @@
     if (annotation.GetType() == AidlAnnotation::Type::JAVA_PASSTHROUGH) {
       result.emplace_back(annotation.ParamValue<std::string>("annotation").value());
     }
+    if (annotation.GetType() == AidlAnnotation::Type::JAVA_SUPPRESS_LINT) {
+      std::vector<std::string> values;
+      for (const auto& [name, value] : annotation.AnnotationParams(ConstantValueDecorator)) {
+        values.emplace_back(name + " = " + value);
+      }
+      result.emplace_back("@android.annotation.SuppressLint(" + Join(values, ", ") + ")");
+    }
   }
 
   return result;
diff --git a/tests/versioned/android/aidl/versioned/tests/Foo.aidl b/tests/versioned/android/aidl/versioned/tests/Foo.aidl
index acf7620..3651ed8 100644
--- a/tests/versioned/android/aidl/versioned/tests/Foo.aidl
+++ b/tests/versioned/android/aidl/versioned/tests/Foo.aidl
@@ -1,5 +1,6 @@
 package android.aidl.versioned.tests;
 
+@JavaSuppressLint(value={"NewApi"})
 parcelable Foo {
     // V1 is empty
     // V2