Defaults for List in structured parcelables.

parcelable MyFoo {
    String[] a = {"a", "b", "c"};
}

Test: runtests.sh (added tests)
Bug: 110758329
Change-Id: Iada2f2aaf620cc8b1af45f24090ffd98a617d6f9
diff --git a/Android.bp b/Android.bp
index 255ce02..cfa438d 100644
--- a/Android.bp
+++ b/Android.bp
@@ -45,6 +45,7 @@
         "aidl_language_l.ll",
         "aidl_language_y.yy",
         "aidl_typenames.cpp",
+        "aidl_to_cpp.cpp",
         "aidl_to_java.cpp",
         "ast_cpp.cpp",
         "ast_java.cpp",
diff --git a/aidl_language.cpp b/aidl_language.cpp
index 86a2dc2..0e0dba9 100644
--- a/aidl_language.cpp
+++ b/aidl_language.cpp
@@ -196,6 +196,11 @@
   return true;
 }
 
+std::string AidlConstantValueDecorator(const AidlTypeSpecifier& /*type*/,
+                                       const std::string& raw_value) {
+  return raw_value;
+}
+
 AidlVariableDeclaration::AidlVariableDeclaration(const AidlLocation& location,
                                                  AidlTypeSpecifier* type, const std::string& name)
     : AidlVariableDeclaration(location, type, name, nullptr /*default_value*/) {}
@@ -214,13 +219,13 @@
 
   if (!valid) return false;
 
-  return !ValueString().empty();
+  return !ValueString(AidlConstantValueDecorator).empty();
 }
 
 string AidlVariableDeclaration::ToString() const {
   string ret = type_->ToString() + " " + name_;
   if (default_value_ != nullptr) {
-    ret += " = " + ValueString();
+    ret += " = " + ValueString(AidlConstantValueDecorator);
   }
   return ret;
 }
@@ -229,8 +234,8 @@
   return type_->Signature() + " " + name_;
 }
 
-std::string AidlVariableDeclaration::ValueString() const {
-  return GetDefaultValue()->As(GetType());
+std::string AidlVariableDeclaration::ValueString(const ConstantValueDecorator& decorator) const {
+  return GetDefaultValue()->As(GetType(), decorator);
 }
 
 AidlArgument::AidlArgument(const AidlLocation& location, AidlArgument::Direction direction,
@@ -283,8 +288,13 @@
                                      const std::string& checked_value)
     : AidlNode(location), type_(type), value_(checked_value) {
   CHECK(!value_.empty() || type_ == Type::ERROR);
+  CHECK(type_ != Type::ARRAY);
 }
 
+AidlConstantValue::AidlConstantValue(const AidlLocation& location, Type type,
+                                     std::vector<std::unique_ptr<AidlConstantValue>>* values)
+    : AidlNode(location), type_(type), values_(std::move(*values)) {}
+
 static bool isValidLiteralChar(char c) {
   return !(c <= 0x1f ||  // control characters are < 0x20
            c >= 0x7f ||  // DEL is 0x7f
@@ -317,6 +327,11 @@
   return new AidlConstantValue(location, Type::INTEGRAL, value);
 }
 
+AidlConstantValue* AidlConstantValue::Array(
+    const AidlLocation& location, std::vector<std::unique_ptr<AidlConstantValue>>* values) {
+  return new AidlConstantValue(location, Type::ARRAY, values);
+}
+
 AidlConstantValue* AidlConstantValue::String(const AidlLocation& location,
                                              const std::string& value) {
   for (size_t i = 0; i < value.length(); ++i) {
@@ -343,15 +358,43 @@
   return str;
 }
 
-string AidlConstantValue::As(const AidlTypeSpecifier& type) const {
-  const std::string type_string = type.ToString();
+string AidlConstantValue::As(const AidlTypeSpecifier& type,
+                             const ConstantValueDecorator& decorator) const {
+  if (type.IsGeneric()) {
+    AIDL_ERROR(type) << "Generic type cannot be specified with a constant literal.";
+    return "";
+  }
+
+  const std::string& type_string = type.GetName();
+
+  if ((type_ == Type::ARRAY) != type.IsArray()) {
+    goto mismatch_error;
+  }
 
   switch (type_) {
+    case AidlConstantValue::Type::ARRAY: {
+      vector<string> raw_values;
+      raw_values.reserve(values_.size());
+
+      bool success = true;
+      for (const auto& value : values_) {
+        const AidlTypeSpecifier& array_base = type.ArrayBase();
+        const std::string raw_value = value->As(array_base, decorator);
+
+        success &= !raw_value.empty();
+        raw_values.push_back(decorator(array_base, raw_value));
+      }
+      if (!success) {
+        AIDL_ERROR(this) << "Default value must be a literal array of " << type_string << ".";
+        return "";
+      }
+      return decorator(type, "{" + Join(raw_values, ", ") + "}");
+    }
     case AidlConstantValue::Type::BOOLEAN:
-      if (type_string == "boolean") return value_;
+      if (type_string == "boolean") return decorator(type, value_);
       goto mismatch_error;
     case AidlConstantValue::Type::CHARACTER:
-      if (type_string == "char") return value_;
+      if (type_string == "char") return decorator(type, value_);
       goto mismatch_error;
     case AidlConstantValue::Type::FLOATING: {
       bool is_float_literal = value_.back() == 'f';
@@ -360,12 +403,12 @@
       if (type_string == "double") {
         double parsed_value;
         if (!android::base::ParseDouble(raw_value, &parsed_value)) goto parse_error;
-        return std::to_string(parsed_value);
+        return decorator(type, std::to_string(parsed_value));
       }
       if (is_float_literal && type_string == "float") {
         float parsed_value;
         if (!android::base::ParseFloat(raw_value, &parsed_value)) goto parse_error;
-        return std::to_string(parsed_value) + "f";
+        return decorator(type, std::to_string(parsed_value) + "f");
       }
       goto mismatch_error;
     }
@@ -375,42 +418,42 @@
       if (type_string == "byte") {
         uint8_t unsigned_value;
         if (!android::base::ParseUint<uint8_t>(value_, &unsigned_value)) goto parse_error;
-        return std::to_string((int8_t)unsigned_value);
+        return decorator(type, std::to_string((int8_t)unsigned_value));
       }
       if (type_string == "int") {
         uint32_t unsigned_value;
         if (!android::base::ParseUint<uint32_t>(value_, &unsigned_value)) goto parse_error;
-        return std::to_string((int32_t)unsigned_value);
+        return decorator(type, std::to_string((int32_t)unsigned_value));
       }
       if (type_string == "long") {
         uint64_t unsigned_value;
         if (!android::base::ParseUint<uint64_t>(value_, &unsigned_value)) goto parse_error;
-        return std::to_string((int64_t)unsigned_value);
+        return decorator(type, std::to_string((int64_t)unsigned_value));
       }
       goto mismatch_error;
     case AidlConstantValue::Type::INTEGRAL:
       if (type_string == "byte") {
         if (!android::base::ParseInt<int8_t>(value_, nullptr)) goto parse_error;
-        return value_;
+        return decorator(type, value_);
       }
       if (type_string == "int") {
         if (!android::base::ParseInt<int32_t>(value_, nullptr)) goto parse_error;
-        return value_;
+        return decorator(type, value_);
       }
       if (type_string == "long") {
         if (!android::base::ParseInt<int64_t>(value_, nullptr)) goto parse_error;
-        return value_;
+        return decorator(type, value_);
       }
       goto mismatch_error;
     case AidlConstantValue::Type::STRING:
-      if (type_string == "String") return value_;
+      if (type_string == "String") return decorator(type, value_);
       goto mismatch_error;
     default:
       AIDL_FATAL(this) << "Unrecognized constant value type";
   }
 
 mismatch_error:
-  AIDL_ERROR(this) << "Type is declared " << type_string << " but constant is " << ToString(type_);
+  AIDL_ERROR(this) << "Expecting type " << type_string << " but constant is " << ToString(type_);
   return "";
 parse_error:
   AIDL_ERROR(this) << "Could not parse " << value_ << " as " << type_string;
@@ -419,6 +462,8 @@
 
 string AidlConstantValue::ToString(Type type) {
   switch (type) {
+    case Type::ARRAY:
+      return "a literal array";
     case Type::BOOLEAN:
       return "a literal boolean";
     case Type::CHARACTER:
@@ -456,7 +501,7 @@
     return false;
   }
 
-  return !ValueString().empty();
+  return !ValueString(AidlConstantValueDecorator).empty();
 }
 
 AidlMethod::AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type,
diff --git a/aidl_language.h b/aidl_language.h
index 8eea7fd..36b9bb0 100644
--- a/aidl_language.h
+++ b/aidl_language.h
@@ -237,6 +237,14 @@
   const android::aidl::ValidatableType* language_type_ = nullptr;
 };
 
+// Transforms a value string into a language specific form. Raw value as produced by
+// AidlConstantValue.
+using ConstantValueDecorator =
+    std::function<std::string(const AidlTypeSpecifier& type, const std::string& raw_value)>;
+
+// Returns the universal value unaltered.
+std::string AidlConstantValueDecorator(const AidlTypeSpecifier& type, const std::string& raw_value);
+
 class AidlConstantValue;
 class AidlVariableDeclaration : public AidlNode {
  public:
@@ -256,7 +264,7 @@
   std::string ToString() const;
   std::string Signature() const;
 
-  std::string ValueString() const;
+  std::string ValueString(const ConstantValueDecorator& decorator) const;
 
  private:
   std::unique_ptr<AidlTypeSpecifier> type_;
@@ -307,7 +315,7 @@
 
 class AidlConstantValue : public AidlNode {
  public:
-  enum class Type { ERROR, BOOLEAN, CHARACTER, FLOATING, HEXIDECIMAL, INTEGRAL, STRING };
+  enum class Type { ERROR, ARRAY, BOOLEAN, CHARACTER, FLOATING, HEXIDECIMAL, INTEGRAL, STRING };
 
   virtual ~AidlConstantValue() = default;
 
@@ -318,20 +326,27 @@
   static AidlConstantValue* Hex(const AidlLocation& location, const std::string& value);
   // example: 123, -5498, maybe any size
   static AidlConstantValue* Integral(const AidlLocation& location, const std::string& value);
+  static AidlConstantValue* Array(const AidlLocation& location,
+                                  std::vector<std::unique_ptr<AidlConstantValue>>* values);
   // example: "\"asdf\""
   static AidlConstantValue* String(const AidlLocation& location, const std::string& value);
 
   Type GetType() const { return type_; }
 
   bool CheckValid() const;
-  string As(const AidlTypeSpecifier& type) const;
+
+  // Raw value of type (currently valid in C++ and Java). Empty string on error.
+  string As(const AidlTypeSpecifier& type, const ConstantValueDecorator& decorator) const;
 
  private:
   AidlConstantValue(const AidlLocation& location, Type type, const std::string& checked_value);
+  AidlConstantValue(const AidlLocation& location, Type type,
+                    std::vector<std::unique_ptr<AidlConstantValue>>* values);
   static string ToString(Type type);
 
   const Type type_ = Type::ERROR;
-  const std::string value_;
+  const std::vector<std::unique_ptr<AidlConstantValue>> values_;  // if type_ == ARRAY
+  const std::string value_;                                       // otherwise
 
   DISALLOW_COPY_AND_ASSIGN(AidlConstantValue);
 };
@@ -347,7 +362,9 @@
   const AidlConstantValue& GetValue() const { return *value_; }
   bool CheckValid() const;
 
-  string ValueString() const { return GetValue().As(GetType()); }
+  string ValueString(const ConstantValueDecorator& decorator) const {
+    return GetValue().As(GetType(), decorator);
+  }
 
   AidlConstantDeclaration* AsConstantDeclaration() override { return this; }
 
diff --git a/aidl_language_y.yy b/aidl_language_y.yy
index ecf1bea..7af614e 100644
--- a/aidl_language_y.yy
+++ b/aidl_language_y.yy
@@ -52,6 +52,7 @@
     AidlArgument* arg;
     AidlArgument::Direction direction;
     AidlConstantValue* constant_value;
+    std::vector<std::unique_ptr<AidlConstantValue>>* constant_value_list;
     std::vector<std::unique_ptr<AidlArgument>>* arg_list;
     AidlVariableDeclaration* variable;
     std::vector<std::unique_ptr<AidlVariableDeclaration>>* variable_list;
@@ -108,6 +109,8 @@
 %type<type_args> type_args
 %type<qname> qualified_name
 %type<constant_value> constant_value
+%type<constant_value_list> constant_value_list
+%type<constant_value_list> constant_value_non_empty_list
 
 %type<token> identifier error
 %%
@@ -220,7 +223,8 @@
 
 variable_decls
  : /* empty */ {
-    $$ = new std::vector<std::unique_ptr<AidlVariableDeclaration>>; }
+    $$ = new std::vector<std::unique_ptr<AidlVariableDeclaration>>;
+ }
  | variable_decls variable_decl {
     $$ = $1;
     if ($2 != nullptr) {
@@ -292,6 +296,30 @@
     $$ = AidlConstantValue::String(loc(@1), $1->GetText());
     delete $1;
   }
+ | '{' constant_value_list '}' {
+    $$ = AidlConstantValue::Array(loc(@1), $2);
+    delete $2;
+  }
+ ;
+
+constant_value_list
+ : /* empty */ {
+    $$ = new std::vector<std::unique_ptr<AidlConstantValue>>;
+ }
+ | constant_value_non_empty_list {
+    $$ = $1;
+ }
+ ;
+
+constant_value_non_empty_list
+ : constant_value {
+    $$ = new std::vector<std::unique_ptr<AidlConstantValue>>;
+    $$->push_back(std::unique_ptr<AidlConstantValue>($1));
+ }
+ | constant_value_non_empty_list ',' constant_value {
+    $$ = $1;
+    $$->push_back(std::unique_ptr<AidlConstantValue>($3));
+ }
  ;
 
 constant_decl
diff --git a/aidl_to_cpp.cpp b/aidl_to_cpp.cpp
new file mode 100644
index 0000000..2668408
--- /dev/null
+++ b/aidl_to_cpp.cpp
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+#include "aidl_to_cpp.h"
+#include "aidl_language.h"
+
+namespace android {
+namespace aidl {
+namespace cpp {
+
+std::string ConstantValueDecorator(const AidlTypeSpecifier& type, const std::string& raw_value) {
+  if (type.GetName() == "String" && !type.IsArray() && !type.IsUtf8InCpp()) {
+    return "::android::String16(" + raw_value + ")";
+  }
+
+  return raw_value;
+};
+
+}  // namespace cpp
+}  // namespace aidl
+}  // namespace android
diff --git a/aidl_to_cpp.h b/aidl_to_cpp.h
new file mode 100644
index 0000000..7895cd9
--- /dev/null
+++ b/aidl_to_cpp.h
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+#ifndef AIDL_AIDL_TO_CPP_H_
+#define AIDL_AIDL_TO_CPP_H_
+
+#include "aidl_language.h"
+
+namespace android {
+namespace aidl {
+namespace cpp {
+
+// This header provides functions that translate AIDL things to cpp things.
+
+std::string ConstantValueDecorator(const AidlTypeSpecifier& type, const std::string& raw_value);
+
+}  // namespace cpp
+}  // namespace aidl
+}  // namespace android
+
+#endif  // AIDL_AIDL_TO_CPP_H_
diff --git a/aidl_to_java.cpp b/aidl_to_java.cpp
index 4262361..a46d8e3 100644
--- a/aidl_to_java.cpp
+++ b/aidl_to_java.cpp
@@ -41,6 +41,12 @@
 using std::string;
 using std::vector;
 
+std::string ConstantValueDecorator(const AidlTypeSpecifier& /*type*/,
+                                   const std::string& raw_value) {
+  // no difference
+  return raw_value;
+};
+
 const string& JavaNameOf(const AidlTypeSpecifier& aidl) {
   CHECK(aidl.IsResolved()) << aidl.ToString();
 
diff --git a/aidl_to_java.h b/aidl_to_java.h
index 1145d9b..c1e1809 100644
--- a/aidl_to_java.h
+++ b/aidl_to_java.h
@@ -38,7 +38,9 @@
 using std::unique_ptr;
 using std::vector;
 
-// This header provides functions that translate AIDL thing to Java thing.
+// This header provides functions that translate AIDL things to Java things.
+
+std::string ConstantValueDecorator(const AidlTypeSpecifier& type, const std::string& raw_value);
 
 // Returns the corresponding Java type name for an AIDL type spec
 // This excludes generic type parameters and array modifiers.
diff --git a/aidl_unittest.cpp b/aidl_unittest.cpp
index f51c195..e8b4fa4 100644
--- a/aidl_unittest.cpp
+++ b/aidl_unittest.cpp
@@ -25,6 +25,7 @@
 #include "aidl.h"
 #include "aidl_apicheck.h"
 #include "aidl_language.h"
+#include "aidl_to_cpp.h"
 #include "tests/fake_io_delegate.h"
 #include "type_cpp.h"
 #include "type_java.h"
@@ -361,7 +362,7 @@
   const auto& cpp_constants = interface->GetConstantDeclarations();
   EXPECT_EQ((size_t)1, cpp_constants.size());
   EXPECT_EQ("POSITIVE_HEX_VALUE", cpp_constants[0]->GetName());
-  EXPECT_EQ("245", cpp_constants[0]->ValueString());
+  EXPECT_EQ("245", cpp_constants[0]->ValueString(cpp::ConstantValueDecorator));
 }
 
 TEST_F(AidlTest, ParseNegativeConstHexValue) {
@@ -381,7 +382,7 @@
   const auto& cpp_constants = interface->GetConstantDeclarations();
   EXPECT_EQ((size_t)1, cpp_constants.size());
   EXPECT_EQ("NEGATIVE_HEX_VALUE", cpp_constants[0]->GetName());
-  EXPECT_EQ("-1", cpp_constants[0]->ValueString());
+  EXPECT_EQ("-1", cpp_constants[0]->ValueString(cpp::ConstantValueDecorator));
 }
 
 TEST_F(AidlTest, UnderstandsNestedParcelables) {
diff --git a/generate_cpp.cpp b/generate_cpp.cpp
index 0742df5..a09ae12 100644
--- a/generate_cpp.cpp
+++ b/generate_cpp.cpp
@@ -730,8 +730,9 @@
         ClassName(interface, ClassNames::INTERFACE),
         constant->GetName(),
         {}));
-    getter->GetStatementBlock()->AddLiteral(StringPrintf(
-        "static const ::android::String16 value(%s)", constant->ValueString().c_str()));
+    getter->GetStatementBlock()->AddLiteral(
+        StringPrintf("static const ::android::String16 value(%s)",
+                     constant->ValueString(ConstantValueDecorator).c_str()));
     getter->GetStatementBlock()->AddLiteral("return value");
     decls.push_back(std::move(getter));
   }
@@ -899,7 +900,8 @@
       }
       case AidlConstantValue::Type::INTEGRAL:
       case AidlConstantValue::Type::HEXIDECIMAL: {
-        int_constant_enum->AddValue(constant->GetName(), constant->ValueString());
+        int_constant_enum->AddValue(constant->GetName(),
+                                    constant->ValueString(ConstantValueDecorator));
         break;
       }
       default: {
@@ -984,7 +986,8 @@
     std::ostringstream out;
     out << type->CppType().c_str() << " " << variable->GetName().c_str();
     if (variable->GetDefaultValue()) {
-      out << " = " << type->CppType().c_str() << "(" << variable->ValueString() << ")";
+      out << " = " << type->CppType().c_str() << "("
+          << variable->ValueString(ConstantValueDecorator) << ")";
     }
     out << ";\n";
 
diff --git a/generate_cpp.h b/generate_cpp.h
index 772fb38..6274d4e 100644
--- a/generate_cpp.h
+++ b/generate_cpp.h
@@ -21,6 +21,7 @@
 #include <string>
 
 #include "aidl_language.h"
+#include "aidl_to_cpp.h"
 #include "ast_cpp.h"
 #include "options.h"
 #include "type_cpp.h"
diff --git a/generate_java.cpp b/generate_java.cpp
index 8d15d15..5660734 100644
--- a/generate_java.cpp
+++ b/generate_java.cpp
@@ -100,7 +100,7 @@
     out << "public " << type->JavaType() << (variable->GetType().IsArray() ? "[]" : "") << " "
         << variable->GetName();
     if (variable->GetDefaultValue()) {
-      out << " = " << variable->ValueString();
+      out << " = " << variable->ValueString(AidlConstantValueDecorator);
     }
     out << ";\n";
     parcel_class->elements.push_back(new LiteralClassElement(out.str()));
diff --git a/generate_java_binder.cpp b/generate_java_binder.cpp
index 8c96190..69f2df3 100644
--- a/generate_java_binder.cpp
+++ b/generate_java_binder.cpp
@@ -1029,12 +1029,14 @@
 
     switch (value.GetType()) {
       case AidlConstantValue::Type::STRING: {
-        generate_string_constant(interface, constant->GetName(), constant->ValueString());
+        generate_string_constant(interface, constant->GetName(),
+                                 constant->ValueString(ConstantValueDecorator));
         break;
       }
       case AidlConstantValue::Type::INTEGRAL:
       case AidlConstantValue::Type::HEXIDECIMAL: {
-        generate_int_constant(interface, constant->GetName(), constant->ValueString());
+        generate_int_constant(interface, constant->GetName(),
+                              constant->ValueString(ConstantValueDecorator));
         break;
       }
       default: {
diff --git a/tests/aidl_test_client_parcelables.cpp b/tests/aidl_test_client_parcelables.cpp
index 8f6e8ed..d8adf1f 100644
--- a/tests/aidl_test_client_parcelables.cpp
+++ b/tests/aidl_test_client_parcelables.cpp
@@ -176,7 +176,6 @@
     cout << "charDefaultsToC is " << parcelable.charDefaultsToC << endl;
     return false;
   }
-
   if (parcelable.floatDefaultsToPi != 3.14f) {
     cout << "floatDefaultsToPi is " << parcelable.floatDefaultsToPi << endl;
     return false;
@@ -186,6 +185,21 @@
          << endl;
     return false;
   }
+  if (parcelable.arrayDefaultsTo123.size() != 3) {
+    cout << "arrayDefaultsTo123 is of length " << parcelable.arrayDefaultsTo123.size() << endl;
+    return false;
+  }
+  for (int i = 0; i < 3; i++) {
+    if (parcelable.arrayDefaultsTo123[i] != i + 1) {
+      cout << "arrayDefaultsTo123[" << i << "] is " << parcelable.arrayDefaultsTo123[i]
+           << " but should be " << i + 1 << endl;
+      return false;
+    }
+  }
+  if (!parcelable.arrayDefaultsToEmpty.empty()) {
+    cout << "arrayDefaultsToEmpty is not empty " << parcelable.arrayDefaultsToEmpty.size() << endl;
+    return false;
+  }
 
   s->FillOutStructuredParcelable(&parcelable);
 
diff --git a/tests/android/aidl/tests/StructuredParcelable.aidl b/tests/android/aidl/tests/StructuredParcelable.aidl
index edb443a..2ced1e8 100644
--- a/tests/android/aidl/tests/StructuredParcelable.aidl
+++ b/tests/android/aidl/tests/StructuredParcelable.aidl
@@ -29,7 +29,11 @@
     char charDefaultsToC = 'C';
     float floatDefaultsToPi = 3.14f;
     double doubleWithDefault = -3.14e17;
+    int[] arrayDefaultsTo123 = { 1, 2, 3 };
+    int[] arrayDefaultsToEmpty = { };
 
     // parse checks only
     double checkDoubleFromFloat = 3.14f;
+    String[] checkStringArray1 = { "a", "b" };
+    @utf8InCpp String[] checkStringArray2 = { "a", "b" };
 }
diff --git a/tests/java_app/src/android/aidl/tests/TestServiceClient.java b/tests/java_app/src/android/aidl/tests/TestServiceClient.java
index 61edfbe..9de1ae5 100644
--- a/tests/java_app/src/android/aidl/tests/TestServiceClient.java
+++ b/tests/java_app/src/android/aidl/tests/TestServiceClient.java
@@ -735,6 +735,14 @@
         mLog.logAndThrow(
             "doubleWithDefault is " + parcelable.doubleWithDefault + " but should be -3.14e17");
       }
+      if (!Arrays.equals(parcelable.arrayDefaultsTo123, new int[] {1, 2, 3})) {
+        mLog.logAndThrow("arrayDefaultsTo123 should be [1,2,3] but is "
+            + Arrays.toString(parcelable.arrayDefaultsTo123));
+      }
+      if (parcelable.arrayDefaultsToEmpty.length != 0) {
+        mLog.logAndThrow("arrayDefaultsToEmpty should be empty but is "
+            + Arrays.toString(parcelable.arrayDefaultsToEmpty));
+      }
 
       try {
         service.FillOutStructuredParcelable(parcelable);
@@ -743,15 +751,10 @@
         mLog.logAndThrow("Service failed to handle structured parcelable.");
       }
 
-      if (parcelable.shouldContainThreeFs.length != 3) {
+      if (!Arrays.equals(parcelable.shouldContainThreeFs,
+              new int[] {kDesiredFValue, kDesiredFValue, kDesiredFValue})) {
         mLog.logAndThrow(
-            "shouldContainThreeFs is of length " + parcelable.shouldContainThreeFs.length);
-      }
-      for (int i = 0; i < 3; i++) {
-        if (parcelable.shouldContainThreeFs[i] != kDesiredFValue) {
-          mLog.logAndThrow("shouldContainThreeFs[" + i + "] is "
-              + parcelable.shouldContainThreeFs[i] + " but should be " + kDesiredFValue);
-        }
+            "shouldContainThreeFs is " + Arrays.toString(parcelable.shouldContainThreeFs));
       }
 
       if (!parcelable.shouldBeJerry.equals("Jerry")) {
diff --git a/tests/test_data_string_constants.cpp b/tests/test_data_string_constants.cpp
index aa7feef..b008d49 100644
--- a/tests/test_data_string_constants.cpp
+++ b/tests/test_data_string_constants.cpp
@@ -170,7 +170,7 @@
 IMPLEMENT_META_INTERFACE(StringConstants, "android.os.IStringConstants")
 
 const ::android::String16& IStringConstants::EXAMPLE_CONSTANT() {
-  static const ::android::String16 value("foo");
+  static const ::android::String16 value(::android::String16("foo"));
   return value;
 }
 
@@ -389,7 +389,7 @@
 )";
 
 const char kExpectedCppOutputWithVersion[] =
-R"(#include <android/os/IStringConstants.h>
+    R"(#include <android/os/IStringConstants.h>
 #include <android/os/BpStringConstants.h>
 
 namespace android {
@@ -399,7 +399,7 @@
 IMPLEMENT_META_INTERFACE(StringConstants, "android.os.IStringConstants")
 
 const ::android::String16& IStringConstants::EXAMPLE_CONSTANT() {
-  static const ::android::String16 value("foo");
+  static const ::android::String16 value(::android::String16("foo"));
   return value;
 }