support const in parcelable/union

const values are now available in parcelable/union as well as interface.

Bug: 173225412
Test: CtsNdkBinderTestCases
Test: aidl_unittests
Test: aidl_integration_test
Change-Id: Ifab53c6b0e6674710f1206b7d2e2ca677d5430c6
diff --git a/aidl_unittest.cpp b/aidl_unittest.cpp
index 7bf63d9..4991b2f 100644
--- a/aidl_unittest.cpp
+++ b/aidl_unittest.cpp
@@ -1378,6 +1378,24 @@
   EXPECT_EQ(expected_stderr, GetCapturedStderr());
 }
 
+TEST_P(AidlTest, ParcelablesWithConstants) {
+  io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo { const int BIT = 0x1 << 3; }");
+  Options options =
+      Options::From("aidl Foo.aidl --lang=" + Options::LanguageToString(GetLanguage()));
+  CaptureStderr();
+  EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
+  EXPECT_EQ("", GetCapturedStderr());
+}
+
+TEST_P(AidlTest, UnionWithConstants) {
+  io_delegate_.SetFileContents("Foo.aidl", "union Foo { const int BIT = 0x1 << 3; int n; }");
+  Options options =
+      Options::From("aidl Foo.aidl --lang=" + Options::LanguageToString(GetLanguage()));
+  CaptureStderr();
+  EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
+  EXPECT_EQ("", GetCapturedStderr());
+}
+
 TEST_F(AidlTest, ApiDump) {
   io_delegate_.SetFileContents(
       "foo/bar/IFoo.aidl",
@@ -3735,6 +3753,44 @@
   EXPECT_EQ(expected_stderr, GetCapturedStderr());
 }
 
+TEST_F(AidlTest, GenericStructuredParcelableWithStringConstants_Cpp) {
+  io_delegate_.SetFileContents("Foo.aidl",
+                               "parcelable Foo<T, U> { int a; const String s = \"\"; }");
+  Options options =
+      Options::From("aidl Foo.aidl --lang=" + Options::LanguageToString(Options::Language::CPP) +
+                    " -o out -h out");
+  const string expected_stderr = "";
+  CaptureStderr();
+  EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
+  EXPECT_EQ(expected_stderr, GetCapturedStderr());
+
+  string code;
+  EXPECT_TRUE(io_delegate_.GetWrittenContents("out/Foo.h", &code));
+  EXPECT_THAT(code, testing::HasSubstr(R"--(template <typename T, typename U>
+const ::android::String16& Foo<T,U>::s() {
+  static const ::android::String16 value(::android::String16(""));
+  return value;
+})--"));
+}
+
+TEST_F(AidlTest, GenericStructuredParcelableWithStringConstants_Ndk) {
+  io_delegate_.SetFileContents("Foo.aidl",
+                               "parcelable Foo<T, U> { int a; const String s = \"\"; }");
+  Options options =
+      Options::From("aidl Foo.aidl --lang=" + Options::LanguageToString(Options::Language::NDK) +
+                    " -o out -h out");
+  const string expected_stderr = "";
+  CaptureStderr();
+  EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
+  EXPECT_EQ(expected_stderr, GetCapturedStderr());
+
+  string code;
+  EXPECT_TRUE(io_delegate_.GetWrittenContents("out/aidl/Foo.h", &code));
+  EXPECT_THAT(code, testing::HasSubstr(R"--(template <typename T, typename U>
+const char* Foo<T, U>::s = "";
+)--"));
+}
+
 TEST_F(AidlTest, NestedTypeArgs) {
   io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar<A> { }");
   io_delegate_.SetFileContents("a/Baz.aidl", "package a; parcelable Baz<A, B> { }");