Allow utf8InCpp constants (std::string).

Bug: N/A
Test: runtests.sh
Change-Id: Ib905f48d2c02fb2b3474a11c965eecfca8ad3b56
diff --git a/aidl.cpp b/aidl.cpp
index 7c4f9b1..c79d627 100644
--- a/aidl.cpp
+++ b/aidl.cpp
@@ -166,6 +166,12 @@
       arg->GetMutableType()->SetLanguageType(arg_type);
     }
   }
+
+  for (const std::unique_ptr<AidlConstantDeclaration>& constant : c->GetConstantDeclarations()) {
+    AidlTypeSpecifier* specifier = constant->GetMutableType();
+    const ValidatableType* return_type = types->GetReturnType(*specifier, *c);
+    specifier->SetLanguageType(return_type);
+  }
 }
 
 bool write_dep_file(const Options& options, const AidlDefinedType& defined_type,
@@ -311,21 +317,6 @@
   return true;
 }
 
-bool validate_constants(const AidlInterface& interface, const AidlTypenames& typenames) {
-  bool success = true;
-  set<string> names;
-  for (const std::unique_ptr<AidlConstantDeclaration>& constant :
-       interface.GetConstantDeclarations()) {
-    if (names.count(constant->GetName()) > 0) {
-      LOG(ERROR) << "Found duplicate constant name '" << constant->GetName() << "'";
-      success = false;
-    }
-    names.insert(constant->GetName());
-    success = success && constant->CheckValid(typenames);
-  }
-  return success;
-}
-
 // TODO: Remove this in favor of using the YACC parser b/25479378
 bool ParsePreprocessedLine(const string& line, string* decl,
                            vector<string>* package, string* class_name) {
@@ -621,9 +612,6 @@
       if (!check_and_assign_method_ids(interface->GetMethods())) {
         return AidlError::BAD_METHOD_ID;
       }
-      if (!validate_constants(*interface, typenames)) {
-        return AidlError::BAD_CONSTANTS;
-      }
     }
   }
 
diff --git a/aidl.h b/aidl.h
index 9b94ae6..965aa71 100644
--- a/aidl.h
+++ b/aidl.h
@@ -40,7 +40,6 @@
   BAD_TYPE,
   BAD_METHOD_ID,
   GENERATION_ERROR,
-  BAD_CONSTANTS,
   BAD_INPUT,
   NOT_STRUCTURED,
 
diff --git a/aidl_language.cpp b/aidl_language.cpp
index 7134717..ec97053 100644
--- a/aidl_language.cpp
+++ b/aidl_language.cpp
@@ -730,7 +730,19 @@
       return false;
     }
   }
-  return true;
+
+  bool success = true;
+  set<string> constant_names;
+  for (const std::unique_ptr<AidlConstantDeclaration>& constant : GetConstantDeclarations()) {
+    if (constant_names.count(constant->GetName()) > 0) {
+      LOG(ERROR) << "Found duplicate constant name '" << constant->GetName() << "'";
+      success = false;
+    }
+    constant_names.insert(constant->GetName());
+    success = success && constant->CheckValid(typenames);
+  }
+
+  return success;
 }
 
 AidlQualifiedName::AidlQualifiedName(const AidlLocation& location, const std::string& term,
diff --git a/aidl_language.h b/aidl_language.h
index 10b048f..75f3579 100644
--- a/aidl_language.h
+++ b/aidl_language.h
@@ -353,6 +353,7 @@
   virtual ~AidlConstantDeclaration() = default;
 
   const AidlTypeSpecifier& GetType() const { return *type_; }
+  AidlTypeSpecifier* GetMutableType() { return type_.get(); }
   const std::string& GetName() const { return name_; }
   const AidlConstantValue& GetValue() const { return *value_; }
   bool CheckValid(const AidlTypenames& typenames) const;
diff --git a/aidl_unittest.cpp b/aidl_unittest.cpp
index a117173..c1851bf 100644
--- a/aidl_unittest.cpp
+++ b/aidl_unittest.cpp
@@ -333,7 +333,7 @@
                    )",
                    &cpp_types_,
                    &reported_error));
-  EXPECT_EQ(AidlError::BAD_CONSTANTS, reported_error);
+  EXPECT_EQ(AidlError::BAD_TYPE, reported_error);
 }
 
 TEST_F(AidlTest, FailOnManyDefinedTypes) {
@@ -369,7 +369,7 @@
                    )",
                    &cpp_types_,
                    &reported_error));
-  EXPECT_EQ(AidlError::BAD_CONSTANTS, reported_error);
+  EXPECT_EQ(AidlError::BAD_TYPE, reported_error);
 }
 
 TEST_F(AidlTest, ParsePositiveConstHexValue) {
diff --git a/generate_cpp.cpp b/generate_cpp.cpp
index 1711074..5e001ea 100644
--- a/generate_cpp.cpp
+++ b/generate_cpp.cpp
@@ -796,13 +796,13 @@
     const AidlConstantValue& value = constant->GetValue();
     if (value.GetType() != AidlConstantValue::Type::STRING) continue;
 
-    unique_ptr<MethodImpl> getter(new MethodImpl(
-        "const ::android::String16&",
-        ClassName(interface, ClassNames::INTERFACE),
-        constant->GetName(),
-        {}));
+    std::string cppType = constant->GetType().GetLanguageType<Type>()->CppType();
+
+    unique_ptr<MethodImpl> getter(new MethodImpl("const " + cppType + "&",
+                                                 ClassName(interface, ClassNames::INTERFACE),
+                                                 constant->GetName(), {}));
     getter->GetStatementBlock()->AddLiteral(
-        StringPrintf("static const ::android::String16 value(%s)",
+        StringPrintf("static const %s value(%s)", cppType.c_str(),
                      constant->ValueString(ConstantValueDecorator).c_str()));
     getter->GetStatementBlock()->AddLiteral("return value");
     decls.push_back(std::move(getter));
@@ -972,8 +972,9 @@
 
     switch (value.GetType()) {
       case AidlConstantValue::Type::STRING: {
-        unique_ptr<Declaration> getter(new MethodDecl(
-            "const ::android::String16&", constant->GetName(), {}, MethodDecl::IS_STATIC));
+        std::string cppType = constant->GetType().GetLanguageType<Type>()->CppType();
+        unique_ptr<Declaration> getter(new MethodDecl("const " + cppType + "&", constant->GetName(),
+                                                      {}, MethodDecl::IS_STATIC));
         string_constants.push_back(std::move(getter));
         break;
       }
diff --git a/tests/aidl_test_client_utf8_strings.cpp b/tests/aidl_test_client_utf8_strings.cpp
index 3688a32..658759c 100644
--- a/tests/aidl_test_client_utf8_strings.cpp
+++ b/tests/aidl_test_client_utf8_strings.cpp
@@ -47,11 +47,12 @@
 
 bool ConfirmUtf8InCppStringRepeat(const sp<ITestService>& s) {
   const vector<string> utf8_inputs = {
-    string("Deliver us from evil."),
-    string(),
-    string("\0\0", 2),
-    // Similarly, the utf8 encodings of the small letter yee and euro sign.
-    string("\xF0\x90\x90\xB7\xE2\x82\xAC"),
+      string("Deliver us from evil."),
+      string(),
+      string("\0\0", 2),
+      // Similarly, the utf8 encodings of the small letter yee and euro sign.
+      string("\xF0\x90\x90\xB7\xE2\x82\xAC"),
+      ITestService::STRING_TEST_CONSTANT_UTF8(),
   };
   LOG(INFO) << "Confirming repeating utf8 strings works.";
 
diff --git a/tests/android/aidl/tests/ITestService.aidl b/tests/android/aidl/tests/ITestService.aidl
index cda2ff8..4143ba7 100644
--- a/tests/android/aidl/tests/ITestService.aidl
+++ b/tests/android/aidl/tests/ITestService.aidl
@@ -39,6 +39,8 @@
   const String STRING_TEST_CONSTANT = "foo";
   const String STRING_TEST_CONSTANT2 = "bar";
 
+  const @utf8InCpp String STRING_TEST_CONSTANT_UTF8 = "baz";
+
   // Test that primitives work as parameters and return types.
   boolean RepeatBoolean(boolean token);
   byte RepeatByte(byte token);