Snap for 8146243 from dc3d2632dd81cad257d7f20b6beb89c34869ca4c to mainline-neuralnetworks-release

Change-Id: Ib3e8280e579d73357737a94572941dddda5241b1
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 47733c1..8e18374 100644
--- a/aidl_checkapi.cpp
+++ b/aidl_checkapi.cpp
@@ -86,7 +86,9 @@
       AidlAnnotation::Type::NULLABLE,
       // @JavaDerive doesn't affect read/write
       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_const_expressions.cpp b/aidl_const_expressions.cpp
index b97889d..b9b62ea 100644
--- a/aidl_const_expressions.cpp
+++ b/aidl_const_expressions.cpp
@@ -242,12 +242,6 @@
   return false;
 }
 
-static bool isValidLiteralChar(char c) {
-  return !(c <= 0x1f ||  // control characters are < 0x20
-           c >= 0x7f ||  // DEL is 0x7f
-           c == '\\');   // Disallow backslashes for future proofing.
-}
-
 bool ParseFloating(std::string_view sv, double* parsed) {
   // float literal should be parsed successfully.
   android::base::ConsumeSuffix(&sv, "f");
@@ -338,6 +332,9 @@
   if (name == "boolean") {
     return Boolean(location, false);
   }
+  if (name == "char") {
+    return Character(location, "'\\0'");  // literal to be used in backends
+  }
   if (name == "byte" || name == "int" || name == "long") {
     return Integral(location, "0");
   }
@@ -354,13 +351,9 @@
   return new AidlConstantValue(location, Type::BOOLEAN, value ? "true" : "false");
 }
 
-AidlConstantValue* AidlConstantValue::Character(const AidlLocation& location, char value) {
-  const std::string explicit_value = string("'") + value + "'";
-  if (!isValidLiteralChar(value)) {
-    AIDL_ERROR(location) << "Invalid character literal " << value;
-    return new AidlConstantValue(location, Type::ERROR, explicit_value);
-  }
-  return new AidlConstantValue(location, Type::CHARACTER, explicit_value);
+AidlConstantValue* AidlConstantValue::Character(const AidlLocation& location,
+                                                const std::string& value) {
+  return new AidlConstantValue(location, Type::CHARACTER, value);
 }
 
 AidlConstantValue* AidlConstantValue::Floating(const AidlLocation& location,
@@ -453,14 +446,6 @@
 }
 
 AidlConstantValue* AidlConstantValue::String(const AidlLocation& location, const string& value) {
-  for (size_t i = 0; i < value.length(); ++i) {
-    if (!isValidLiteralChar(value[i])) {
-      AIDL_ERROR(location) << "Found invalid character at index " << i << " in string constant '"
-                           << value << "'";
-      return new AidlConstantValue(location, Type::ERROR, value);
-    }
-  }
-
   return new AidlConstantValue(location, Type::STRING, value);
 }
 
@@ -1007,6 +992,8 @@
   return false;
 }
 
+// Constructor for integer(byte, int, long)
+// Keep parsed integer & literal
 AidlConstantValue::AidlConstantValue(const AidlLocation& location, Type parsed_type,
                                      int64_t parsed_value, const string& checked_value)
     : AidlNode(location),
@@ -1018,6 +1005,8 @@
   AIDL_FATAL_IF(type_ != Type::INT8 && type_ != Type::INT32 && type_ != Type::INT64, location);
 }
 
+// Constructor for non-integer(String, char, boolean, float, double)
+// Keep literal as it is. (e.g. String literal has double quotes at both ends)
 AidlConstantValue::AidlConstantValue(const AidlLocation& location, Type type,
                                      const string& checked_value)
     : AidlNode(location),
@@ -1037,6 +1026,7 @@
   }
 }
 
+// Constructor for array
 AidlConstantValue::AidlConstantValue(const AidlLocation& location, Type type,
                                      std::unique_ptr<vector<unique_ptr<AidlConstantValue>>> values,
                                      const std::string& value)
diff --git a/aidl_language.cpp b/aidl_language.cpp
index 5bff95e..733d5e2 100644
--- a/aidl_language.cpp
+++ b/aidl_language.cpp
@@ -128,11 +128,16 @@
        "JavaDerive",
        CONTEXT_TYPE_STRUCTURED_PARCELABLE | CONTEXT_TYPE_UNION,
        {{"toString", kBooleanType}, {"equals", kBooleanType}}},
+      {AidlAnnotation::Type::JAVA_DEFAULT, "JavaDefault", CONTEXT_TYPE_INTERFACE, {}},
       {AidlAnnotation::Type::JAVA_ONLY_IMMUTABLE,
        "JavaOnlyImmutable",
        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",
@@ -403,6 +408,10 @@
   return false;
 }
 
+bool AidlAnnotatable::IsJavaDefault() const {
+  return GetAnnotation(annotations_, AidlAnnotation::Type::JAVA_DEFAULT);
+}
+
 std::string AidlAnnotatable::GetDescriptor() const {
   auto annotation = GetAnnotation(annotations_, AidlAnnotation::Type::DESCRIPTOR);
   if (annotation != nullptr) {
diff --git a/aidl_language.h b/aidl_language.h
index e0c28a0..69cf38f 100644
--- a/aidl_language.h
+++ b/aidl_language.h
@@ -209,7 +209,9 @@
     SENSITIVE_DATA,
     JAVA_PASSTHROUGH,
     JAVA_DERIVE,
+    JAVA_DEFAULT,
     JAVA_ONLY_IMMUTABLE,
+    JAVA_SUPPRESS_LINT,
     FIXED_SIZE,
     DESCRIPTOR,
     RUST_DERIVE,
@@ -325,6 +327,7 @@
   bool IsStableApiParcelable(Options::Language lang) const;
   bool IsHide() const;
   bool JavaDerive(const std::string& method) const;
+  bool IsJavaDefault() const;
   std::string GetDescriptor() const;
 
   const AidlAnnotation* UnsupportedAppUsage() const;
@@ -608,7 +611,7 @@
     } else if constexpr (is_one_of<T, int8_t, int32_t, int64_t>::value) {
       AIDL_FATAL_IF(final_type_ < Type::INT8 && final_type_ > Type::INT64, this);
       return static_cast<T>(final_value_);
-    } else if constexpr (std::is_same<T, char>::value) {
+    } else if constexpr (std::is_same<T, char16_t>::value) {
       AIDL_FATAL_IF(final_type_ != Type::CHARACTER, this);
       return final_string_value_.at(1);  // unquote '
     } else if constexpr (std::is_same<T, bool>::value) {
@@ -633,9 +636,9 @@
   static AidlConstantValue* Default(const AidlTypeSpecifier& specifier);
 
   static AidlConstantValue* Boolean(const AidlLocation& location, bool value);
-  static AidlConstantValue* Character(const AidlLocation& location, char value);
+  static AidlConstantValue* Character(const AidlLocation& location, const std::string& value);
   // example: 123, -5498, maybe any size
-  static AidlConstantValue* Integral(const AidlLocation& location, const string& value);
+  static AidlConstantValue* Integral(const AidlLocation& location, const std::string& value);
   static AidlConstantValue* Floating(const AidlLocation& location, const std::string& value);
   static AidlConstantValue* Array(const AidlLocation& location,
                                   std::unique_ptr<vector<unique_ptr<AidlConstantValue>>> values);
diff --git a/aidl_language_l.ll b/aidl_language_l.ll
index e43ef45..2b63b82 100644
--- a/aidl_language_l.ll
+++ b/aidl_language_l.ll
@@ -142,9 +142,8 @@
 {identifier}          { yylval->token = new AidlToken(yytext, comments);
                         return yy::parser::token::IDENTIFIER;
                       }
-'.'                   { yylval->character = yytext[1];
-                        return yy::parser::token::CHARVALUE;
-                      }
+'.'                   { yylval->token = new AidlToken(yytext, comments);
+                        return yy::parser::token::CHARVALUE; }
 {intvalue}            { yylval->token = new AidlToken(yytext, comments);
                         return yy::parser::token::INTVALUE; }
 {floatvalue}          { yylval->token = new AidlToken(yytext, comments);
diff --git a/aidl_language_y.yy b/aidl_language_y.yy
index ab3e479..079bda6 100644
--- a/aidl_language_y.yy
+++ b/aidl_language_y.yy
@@ -96,7 +96,6 @@
     std::vector<std::unique_ptr<AidlDefinedType>>* declarations;
 }
 
-%destructor { } <character>
 %destructor { } <direction>
 %destructor { delete ($$); } <*>
 
@@ -112,7 +111,7 @@
 %token<token> UNION "union"
 %token<token> CONST "const"
 
-%token<character> CHARVALUE "char literal"
+%token<token> CHARVALUE "char literal"
 %token<token> FLOATVALUE "float literal"
 %token<token> HEXVALUE "hex literal"
 %token<token> INTVALUE "int literal"
@@ -395,7 +394,10 @@
 const_expr
  : TRUE_LITERAL { $$ = AidlConstantValue::Boolean(loc(@1), true); }
  | FALSE_LITERAL { $$ = AidlConstantValue::Boolean(loc(@1), false); }
- | CHARVALUE { $$ = AidlConstantValue::Character(loc(@1), $1); }
+ | CHARVALUE {
+    $$ = AidlConstantValue::Character(loc(@1), $1->GetText());
+    delete $1;
+  }
  | INTVALUE {
     $$ = AidlConstantValue::Integral(loc(@1), $1->GetText());
     if ($$ == nullptr) {
diff --git a/aidl_unittest.cpp b/aidl_unittest.cpp
index 7ea8c17..eef607f 100644
--- a/aidl_unittest.cpp
+++ b/aidl_unittest.cpp
@@ -32,6 +32,7 @@
 #include "aidl_language.h"
 #include "aidl_to_cpp.h"
 #include "aidl_to_java.h"
+#include "aidl_to_ndk.h"
 #include "comments.h"
 #include "logging.h"
 #include "options.h"
@@ -1025,7 +1026,7 @@
   using Ptr = unique_ptr<AidlConstantValue>;
   const AidlLocation& loc = AIDL_LOCATION_HERE;
 
-  EXPECT_EQ('c', Ptr(AidlConstantValue::Character(loc, 'c'))->EvaluatedValue<char>());
+  EXPECT_EQ('c', Ptr(AidlConstantValue::Character(loc, "'c'"))->EvaluatedValue<char16_t>());
   EXPECT_EQ("abc", Ptr(AidlConstantValue::String(loc, "\"abc\""))->EvaluatedValue<string>());
   EXPECT_FLOAT_EQ(1.0f, Ptr(AidlConstantValue::Floating(loc, "1.0f"))->EvaluatedValue<float>());
   EXPECT_EQ(true, Ptr(AidlConstantValue::Boolean(loc, true))->EvaluatedValue<bool>());
@@ -1043,6 +1044,14 @@
       Ptr(AidlConstantValue::Array(loc, std::move(values)))->EvaluatedValue<vector<string>>());
 }
 
+TEST_F(AidlTest, AidlConstantCharacterDefault) {
+  AidlTypeSpecifier char_type(AIDL_LOCATION_HERE, "char", false, nullptr, {});
+  auto default_value = unique_ptr<AidlConstantValue>(AidlConstantValue::Default(char_type));
+  EXPECT_EQ("'\\0'", default_value->ValueString(char_type, cpp::ConstantValueDecorator));
+  EXPECT_EQ("'\\0'", default_value->ValueString(char_type, ndk::ConstantValueDecorator));
+  EXPECT_EQ("'\\0'", default_value->ValueString(char_type, java::ConstantValueDecorator));
+}
+
 TEST_P(AidlTest, FailOnManyDefinedTypes) {
   AidlError error;
   const string expected_stderr =
@@ -2229,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");
@@ -3055,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