// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/android/jni_array.h"

#include <stddef.h>
#include <stdint.h>

#include <algorithm>
#include <array>
#include <limits>

#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/android/scoped_java_ref.h"
#include "base/containers/span.h"
#include "base/containers/to_vector.h"
#include "base/strings/string_view_util.h"
#include "base/strings/utf_string_conversions.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base::android {

TEST(JniArray, GetLength) {
  const auto bytes = std::to_array<uint8_t>({0, 1, 2, 3});
  JNIEnv* env = AttachCurrentThread();
  ScopedJavaLocalRef<jbyteArray> j_bytes = ToJavaByteArray(env, bytes);
  ASSERT_TRUE(j_bytes);
  ASSERT_EQ(4U, SafeGetArrayLength(env, j_bytes));

  ScopedJavaLocalRef<jbyteArray> j_empty_bytes =
      ToJavaByteArray(env, base::span<uint8_t>());
  ASSERT_TRUE(j_empty_bytes);
  ASSERT_EQ(0U, SafeGetArrayLength(env, j_empty_bytes));
}

TEST(JniArray, BasicConversions) {
  const auto bytes = std::to_array<uint8_t>({0, 1, 2, 3});
  JNIEnv* env = AttachCurrentThread();
  ScopedJavaLocalRef<jbyteArray> bytes_from_span = ToJavaByteArray(env, bytes);
  ASSERT_TRUE(bytes_from_span);
  ASSERT_EQ(4U, SafeGetArrayLength(env, bytes_from_span));

  auto input_string = std::string(base::as_string_view(bytes));
  ScopedJavaLocalRef<jbyteArray> bytes_from_string =
      ToJavaByteArray(env, input_string);
  ASSERT_TRUE(bytes_from_string);
  ASSERT_EQ(4U, SafeGetArrayLength(env, bytes_from_string));

  ScopedJavaLocalRef<jbyteArray> bytes_from_ptr =
      UNSAFE_BUFFERS(ToJavaByteArray(env, bytes.data(), bytes.size()));
  ASSERT_TRUE(bytes_from_ptr);
  ASSERT_EQ(4U, SafeGetArrayLength(env, bytes_from_ptr));

  std::vector<uint8_t> vector_from_span(5);
  std::vector<uint8_t> vector_from_string(5);
  std::vector<uint8_t> vector_from_ptr(5);
  JavaByteArrayToByteVector(env, bytes_from_span, &vector_from_span);
  JavaByteArrayToByteVector(env, bytes_from_string, &vector_from_string);
  JavaByteArrayToByteVector(env, bytes_from_ptr, &vector_from_ptr);
  EXPECT_EQ(4U, vector_from_span.size());
  EXPECT_EQ(4U, vector_from_string.size());
  EXPECT_EQ(4U, vector_from_ptr.size());
  EXPECT_EQ(bytes, span(vector_from_span));
  EXPECT_EQ(bytes, span(vector_from_string));
  EXPECT_EQ(bytes, span(vector_from_ptr));
}

TEST(JniArray, ByteArrayStringConversions) {
  JNIEnv* env = AttachCurrentThread();
  std::string input_string("hello\0world", 11u);
  ScopedJavaLocalRef<jbyteArray> bytes_from_string =
      ToJavaByteArray(env, input_string);
  ASSERT_TRUE(bytes_from_string);

  std::string string_from_string;
  JavaByteArrayToString(env, bytes_from_string, &string_from_string);
  EXPECT_EQ(input_string, string_from_string);
}

void CheckBoolConversion(JNIEnv* env,
                         span<const bool> bool_array,
                         const ScopedJavaLocalRef<jbooleanArray>& booleans) {
  ASSERT_TRUE(booleans);

  jsize java_array_len = env->GetArrayLength(booleans.obj());
  ASSERT_EQ(checked_cast<jsize>(bool_array.size()), java_array_len);

  jboolean value;
  for (size_t i = 0; i < bool_array.size(); ++i) {
    env->GetBooleanArrayRegion(booleans.obj(), checked_cast<jsize>(i), jsize{1},
                               &value);
    ASSERT_EQ(bool_array[i], value);
  }
}

TEST(JniArray, BoolConversions) {
  const bool kBools[] = {false, true, false};

  JNIEnv* env = AttachCurrentThread();
  CheckBoolConversion(env, kBools, ToJavaBooleanArray(env, kBools));
}

TEST(JniArray, BoolVectorConversions) {
  const auto kBools = std::to_array<bool>({false, true, false});
  const auto kBoolVector = std::vector<bool>({false, true, false});

  JNIEnv* env = AttachCurrentThread();
  CheckBoolConversion(env, kBools, ToJavaBooleanArray(env, kBoolVector));
}

void CheckIntConversion(JNIEnv* env,
                        span<const int> in,
                        const ScopedJavaLocalRef<jintArray>& ints) {
  ASSERT_TRUE(ints);

  jsize java_array_len = env->GetArrayLength(ints.obj());
  ASSERT_EQ(checked_cast<jsize>(in.size()), java_array_len);

  jint value;
  for (size_t i = 0; i < in.size(); ++i) {
    env->GetIntArrayRegion(ints.obj(), i, 1, &value);
    ASSERT_EQ(in[i], value);
  }
}

TEST(JniArray, IntConversions) {
  const int kInts[] = {0, 1, -1, std::numeric_limits<int32_t>::min(),
                       std::numeric_limits<int32_t>::max()};

  JNIEnv* env = AttachCurrentThread();
  CheckIntConversion(env, kInts, ToJavaIntArray(env, kInts));
}

void CheckLongConversion(JNIEnv* env,
                         span<const int64_t> in,
                         const ScopedJavaLocalRef<jlongArray>& longs) {
  ASSERT_TRUE(longs);

  jsize java_array_len = env->GetArrayLength(longs.obj());
  ASSERT_EQ(checked_cast<jsize>(in.size()), java_array_len);

  jlong value;
  for (size_t i = 0; i < in.size(); ++i) {
    env->GetLongArrayRegion(longs.obj(), i, 1, &value);
    ASSERT_EQ(in[i], value);
  }
}

TEST(JniArray, LongConversions) {
  const int64_t kLongs[] = {0, 1, -1, std::numeric_limits<int64_t>::min(),
                            std::numeric_limits<int64_t>::max()};

  JNIEnv* env = AttachCurrentThread();
  CheckLongConversion(env, kLongs, ToJavaLongArray(env, kLongs));
}

void CheckFloatConversion(JNIEnv* env,
                          span<const float> in,
                          const ScopedJavaLocalRef<jfloatArray>& floats) {
  ASSERT_TRUE(floats);

  jsize java_array_len = env->GetArrayLength(floats.obj());
  ASSERT_EQ(checked_cast<jsize>(in.size()), java_array_len);

  jfloat value;
  for (size_t i = 0; i < in.size(); ++i) {
    env->GetFloatArrayRegion(floats.obj(), i, 1, &value);
    ASSERT_EQ(in[i], value);
  }
}

TEST(JniArray, FloatConversions) {
  const float kFloats[] = {0.0f, 1.0f, -10.0f};

  JNIEnv* env = AttachCurrentThread();
  CheckFloatConversion(env, kFloats, ToJavaFloatArray(env, kFloats));
}

void CheckDoubleConversion(JNIEnv* env,
                           span<const double> in,
                           const ScopedJavaLocalRef<jdoubleArray>& doubles) {
  ASSERT_TRUE(doubles);

  jsize java_array_len = env->GetArrayLength(doubles.obj());
  ASSERT_EQ(checked_cast<jsize>(in.size()), java_array_len);

  jdouble value;
  for (size_t i = 0; i < in.size(); ++i) {
    env->GetDoubleArrayRegion(doubles.obj(), i, 1, &value);
    ASSERT_EQ(in[i], value);
  }
}

TEST(JniArray, DoubleConversions) {
  const double kDoubles[] = {0.0, 1.0, -10.0};

  JNIEnv* env = AttachCurrentThread();
  CheckDoubleConversion(env, kDoubles, ToJavaDoubleArray(env, kDoubles));
}

TEST(JniArray, ArrayOfStringArrayConversionUTF8) {
  std::vector<std::vector<std::string>> kArrays = {
      {"a", "f"}, {"a", ""}, {}, {""}, {"今日は"}};

  JNIEnv* env = AttachCurrentThread();
  ScopedJavaLocalRef<jobjectArray> joa = ToJavaArrayOfStringArray(env, kArrays);

  std::vector<std::vector<std::string>> out;
  Java2dStringArrayTo2dStringVector(env, joa, &out);
  ASSERT_TRUE(kArrays == out);
}

TEST(JniArray, ArrayOfStringArrayConversionUTF16) {
  std::vector<std::vector<std::u16string>> kArrays = {
      {u"a", u"f"}, {u"a", u""}, {}, {u""}};

  JNIEnv* env = AttachCurrentThread();
  ScopedJavaLocalRef<jobjectArray> joa = ToJavaArrayOfStringArray(env, kArrays);

  std::vector<std::vector<std::u16string>> out;
  Java2dStringArrayTo2dStringVector(env, joa, &out);
  ASSERT_TRUE(kArrays == out);
}

void CheckBoolArrayConversion(JNIEnv* env,
                              ScopedJavaLocalRef<jbooleanArray> jbooleans,
                              std::vector<bool> bool_vector) {
  jboolean value;
  for (size_t i = 0; i < bool_vector.size(); ++i) {
    env->GetBooleanArrayRegion(jbooleans.obj(), i, 1, &value);
    ASSERT_EQ(bool_vector[i], value);
  }
}

TEST(JniArray, JavaBooleanArrayToBoolVector) {
  const auto kBools = std::to_array<bool>({false, true, false});

  JNIEnv* env = AttachCurrentThread();
  auto jbooleans = ScopedJavaLocalRef<jbooleanArray>::Adopt(
      env, env->NewBooleanArray(kBools.size()));
  ASSERT_TRUE(jbooleans);

  for (size_t i = 0; i < kBools.size(); ++i) {
    jboolean j = static_cast<jboolean>(kBools[i]);
    env->SetBooleanArrayRegion(jbooleans.obj(), i, 1, &j);
    ASSERT_FALSE(HasException(env));
  }

  std::vector<bool> bools;
  JavaBooleanArrayToBoolVector(env, jbooleans, &bools);

  ASSERT_EQ(checked_cast<jsize>(bools.size()),
            env->GetArrayLength(jbooleans.obj()));
  ASSERT_EQ(bools.size(), kBools.size());

  CheckBoolArrayConversion(env, jbooleans, bools);
}

void CheckIntArrayConversion(JNIEnv* env,
                             ScopedJavaLocalRef<jintArray> jints,
                             std::vector<int> int_vector) {
  jint value;
  for (size_t i = 0; i < int_vector.size(); ++i) {
    env->GetIntArrayRegion(jints.obj(), i, 1, &value);
    ASSERT_EQ(int_vector[i], value);
  }
}

TEST(JniArray, JavaIntArrayToIntVector) {
  const auto kInts = std::to_array<int>({0, 1, -1});

  JNIEnv* env = AttachCurrentThread();
  auto jints =
      ScopedJavaLocalRef<jintArray>::Adopt(env, env->NewIntArray(kInts.size()));
  ASSERT_TRUE(jints);

  for (size_t i = 0; i < kInts.size(); ++i) {
    jint j = static_cast<jint>(kInts[i]);
    env->SetIntArrayRegion(jints.obj(), i, 1, &j);
    ASSERT_FALSE(HasException(env));
  }

  std::vector<int> ints;
  JavaIntArrayToIntVector(env, jints, &ints);

  ASSERT_EQ(checked_cast<jsize>(ints.size()), env->GetArrayLength(jints.obj()));
  ASSERT_EQ(ints.size(), kInts.size());

  CheckIntArrayConversion(env, jints, ints);
}

TEST(JniArray, JavaLongArrayToInt64Vector) {
  const auto kInt64s = std::to_array<int64_t>({0LL, 1LL, -1LL});

  JNIEnv* env = AttachCurrentThread();
  auto jlongs = ScopedJavaLocalRef<jlongArray>::Adopt(
      env, env->NewLongArray(kInt64s.size()));
  ASSERT_TRUE(jlongs);

  for (size_t i = 0; i < kInt64s.size(); ++i) {
    jlong j = static_cast<jlong>(kInt64s[i]);
    env->SetLongArrayRegion(jlongs.obj(), i, 1, &j);
    ASSERT_FALSE(HasException(env));
  }

  std::vector<int64_t> int64s;
  JavaLongArrayToInt64Vector(env, jlongs, &int64s);

  ASSERT_EQ(checked_cast<jsize>(int64s.size()),
            env->GetArrayLength(jlongs.obj()));
  ASSERT_EQ(int64s.size(), kInt64s.size());

  jlong value;
  for (size_t i = 0; i < kInt64s.size(); ++i) {
    env->GetLongArrayRegion(jlongs.obj(), i, 1, &value);
    ASSERT_EQ(int64s[i], value);
    ASSERT_EQ(kInt64s[i], int64s[i]);
  }
}

TEST(JniArray, JavaLongArrayToLongVector) {
  const auto kInt64s = std::to_array<int64_t>({0LL, 1LL, -1LL});

  JNIEnv* env = AttachCurrentThread();
  auto jlongs = ScopedJavaLocalRef<jlongArray>::Adopt(
      env, env->NewLongArray(kInt64s.size()));
  ASSERT_TRUE(jlongs);

  for (size_t i = 0; i < kInt64s.size(); ++i) {
    jlong j = static_cast<jlong>(kInt64s[i]);
    env->SetLongArrayRegion(jlongs.obj(), i, 1, &j);
    ASSERT_FALSE(HasException(env));
  }

  std::vector<jlong> jlongs_vector;
  JavaLongArrayToLongVector(env, jlongs, &jlongs_vector);

  ASSERT_EQ(checked_cast<jsize>(jlongs_vector.size()),
            env->GetArrayLength(jlongs.obj()));
  ASSERT_EQ(jlongs_vector.size(), kInt64s.size());

  jlong value;
  for (size_t i = 0; i < kInt64s.size(); ++i) {
    env->GetLongArrayRegion(jlongs.obj(), i, 1, &value);
    ASSERT_EQ(jlongs_vector[i], value);
  }
}

TEST(JniArray, JavaFloatArrayToFloatVector) {
  const auto kFloats = std::to_array<float>({0.0, 0.5, -0.5});

  JNIEnv* env = AttachCurrentThread();
  auto jfloats = ScopedJavaLocalRef<jfloatArray>::Adopt(
      env, env->NewFloatArray(kFloats.size()));
  ASSERT_TRUE(jfloats);

  for (size_t i = 0; i < kFloats.size(); ++i) {
    jfloat j = static_cast<jfloat>(kFloats[i]);
    env->SetFloatArrayRegion(jfloats.obj(), i, 1, &j);
    ASSERT_FALSE(HasException(env));
  }

  std::vector<float> floats;
  JavaFloatArrayToFloatVector(env, jfloats, &floats);

  ASSERT_EQ(checked_cast<jsize>(floats.size()),
            env->GetArrayLength(jfloats.obj()));
  ASSERT_EQ(floats.size(), kFloats.size());

  jfloat value;
  for (size_t i = 0; i < kFloats.size(); ++i) {
    env->GetFloatArrayRegion(jfloats.obj(), i, 1, &value);
    ASSERT_EQ(floats[i], value);
  }
}

TEST(JniArray, JavaDoubleArrayToDoubleVector) {
  const auto kDoubles = std::to_array<double>(
      {0.0, 0.5, -0.5, std::numeric_limits<double>::min()});
  JNIEnv* env = AttachCurrentThread();
  auto jdoubles = ScopedJavaLocalRef<jdoubleArray>::Adopt(
      env, env->NewDoubleArray(kDoubles.size()));
  ASSERT_TRUE(jdoubles);

  env->SetDoubleArrayRegion(jdoubles.obj(), 0, kDoubles.size(),
                            reinterpret_cast<const jdouble*>(kDoubles.data()));
  ASSERT_FALSE(HasException(env));

  std::vector<double> doubles;
  JavaDoubleArrayToDoubleVector(env, jdoubles, &doubles);
  ASSERT_EQ(kDoubles, base::span(doubles));
}

TEST(JniArray, JavaArrayOfByteArrayToStringVector) {
  const int kMaxItems = 50;
  JNIEnv* env = AttachCurrentThread();

  // Create a byte[][] object.
  auto byte_array_clazz =
      ScopedJavaLocalRef<jclass>::Adopt(env, env->FindClass("[B"));
  ASSERT_TRUE(byte_array_clazz);

  auto array = ScopedJavaLocalRef<jobjectArray>::Adopt(
      env, env->NewObjectArray(kMaxItems, byte_array_clazz.obj(), NULL));
  ASSERT_TRUE(array);

  // Create kMaxItems byte buffers.
  char text[16];
  for (int i = 0; i < kMaxItems; ++i) {
    snprintf(text, std::ranges::size(text), "%d", i);
    ScopedJavaLocalRef<jbyteArray> byte_array =
        ToJavaByteArray(env, base::as_byte_span(text));
    ASSERT_TRUE(byte_array);

    env->SetObjectArrayElement(array.obj(), i, byte_array.obj());
    ASSERT_FALSE(HasException(env));
  }

  // Convert to std::vector<std::string>, check the content.
  std::vector<std::string> vec;
  JavaArrayOfByteArrayToStringVector(env, array, &vec);

  EXPECT_EQ(static_cast<size_t>(kMaxItems), vec.size());
  for (int i = 0; i < kMaxItems; ++i) {
    snprintf(text, sizeof text, "%d", i);
    EXPECT_STREQ(text, vec[i].c_str());
  }
}

TEST(JniArray, JavaArrayOfByteArrayToBytesVector) {
  const size_t kMaxItems = 50;
  const uint8_t kStep = 37;
  JNIEnv* env = AttachCurrentThread();

  // Create a byte[][] object.
  auto byte_array_clazz =
      ScopedJavaLocalRef<jclass>::Adopt(env, env->FindClass("[B"));
  ASSERT_TRUE(byte_array_clazz);

  auto array = ScopedJavaLocalRef<jobjectArray>::Adopt(
      env, env->NewObjectArray(kMaxItems, byte_array_clazz.obj(), nullptr));
  ASSERT_TRUE(array);

  // Create kMaxItems byte buffers with size |i|+1 on each step;
  std::vector<std::vector<uint8_t>> input_bytes;
  input_bytes.reserve(kMaxItems);
  for (size_t i = 0; i < kMaxItems; ++i) {
    std::vector<uint8_t> cur_bytes(i + 1);
    for (size_t j = 0; j < cur_bytes.size(); ++j) {
      cur_bytes[j] = static_cast<uint8_t>(i + j * kStep);
    }
    ScopedJavaLocalRef<jbyteArray> byte_array = ToJavaByteArray(env, cur_bytes);
    ASSERT_TRUE(byte_array);

    env->SetObjectArrayElement(array.obj(), i, byte_array.obj());
    ASSERT_FALSE(HasException(env));

    input_bytes.push_back(std::move(cur_bytes));
  }
  ASSERT_EQ(kMaxItems, input_bytes.size());

  // Convert to std::vector<std::vector<uint8_t>>, check the content.
  std::vector<std::vector<uint8_t>> result;
  JavaArrayOfByteArrayToBytesVector(env, array, &result);

  EXPECT_EQ(input_bytes.size(), result.size());
  for (size_t i = 0; i < kMaxItems; ++i) {
    EXPECT_THAT(result[i], ::testing::ElementsAreArray(input_bytes.at(i)));
  }
}

TEST(JniArray, JavaArrayOfStringArrayToVectorOfStringVector) {
  const std::vector<std::vector<std::u16string>> kArrays = {
      {u"a", u"f"}, {u"a", u""}, {}, {u""}};

  JNIEnv* env = AttachCurrentThread();

  auto array = ScopedJavaLocalRef<jobjectArray>::Adopt(
      env, env->NewObjectArray(kArrays.size(),
                               env->FindClass("[Ljava/lang/String;"), NULL));
  ASSERT_TRUE(array);

  auto string_clazz = ScopedJavaLocalRef<jclass>::Adopt(
      env, env->FindClass("java/lang/String"));
  ASSERT_TRUE(string_clazz);

  for (size_t i = 0; i < kArrays.size(); ++i) {
    const std::vector<std::u16string>& child_data = kArrays[i];

    auto child_array = ScopedJavaLocalRef<jobjectArray>::Adopt(
        env, env->NewObjectArray(child_data.size(), string_clazz.obj(), NULL));
    ASSERT_TRUE(child_array);

    for (size_t j = 0; j < child_data.size(); ++j) {
      ScopedJavaLocalRef<jstring> item =
          base::android::ConvertUTF16ToJavaString(env, child_data[j]);
      env->SetObjectArrayElement(child_array.obj(), j, item.obj());
      ASSERT_FALSE(HasException(env));
    }
    env->SetObjectArrayElement(array.obj(), i, child_array.obj());
  }

  std::vector<std::vector<std::u16string>> vec;
  Java2dStringArrayTo2dStringVector(env, array, &vec);

  ASSERT_EQ(kArrays, vec);
}

TEST(JniArray, JavaArrayOfIntArrayToIntVector) {
  const size_t kNumItems = 4;
  JNIEnv* env = AttachCurrentThread();

  // Create an int[][] object.
  auto int_array_clazz =
      ScopedJavaLocalRef<jclass>::Adopt(env, env->FindClass("[I"));
  ASSERT_TRUE(int_array_clazz);

  auto array = ScopedJavaLocalRef<jobjectArray>::Adopt(
      env, env->NewObjectArray(kNumItems, int_array_clazz.obj(), nullptr));
  ASSERT_TRUE(array);

  // Populate int[][] object.
  const auto kInts0 =
      std::to_array<int>({0, 1, -1, std::numeric_limits<int32_t>::min(),
                          std::numeric_limits<int32_t>::max()});
  ScopedJavaLocalRef<jintArray> int_array0 = ToJavaIntArray(env, kInts0);
  env->SetObjectArrayElement(array.obj(), 0, int_array0.obj());

  const auto kInts1 = std::to_array<int>({3, 4, 5});
  ScopedJavaLocalRef<jintArray> int_array1 = ToJavaIntArray(env, kInts1);
  env->SetObjectArrayElement(array.obj(), 1, int_array1.obj());

  const auto kInts2 = std::array<int, 0>();
  ScopedJavaLocalRef<jintArray> int_array2 = ToJavaIntArray(env, kInts2);
  env->SetObjectArrayElement(array.obj(), 2, int_array2.obj());

  const auto kInts3 = std::to_array<int>({16});
  ScopedJavaLocalRef<jintArray> int_array3 = ToJavaIntArray(env, kInts3);
  env->SetObjectArrayElement(array.obj(), 3, int_array3.obj());

  // Convert to std::vector<std::vector<int>>, check the content.
  std::vector<std::vector<int>> out;
  JavaArrayOfIntArrayToIntVector(env, array, &out);

  EXPECT_EQ(kNumItems, out.size());
  EXPECT_EQ(kInts0.size(), out[0].size());
  EXPECT_EQ(kInts1.size(), out[1].size());
  EXPECT_EQ(kInts2.size(), out[2].size());
  EXPECT_EQ(kInts3.size(), out[3].size());
  CheckIntArrayConversion(env, int_array0, out[0]);
  CheckIntArrayConversion(env, int_array1, out[1]);
  CheckIntArrayConversion(env, int_array2, out[2]);
  CheckIntArrayConversion(env, int_array3, out[3]);
}

TEST(JniArray, ToJavaArrayOfObjectsOfClass) {
  JNIEnv* env = AttachCurrentThread();

  std::vector<ScopedJavaLocalRef<jobject>> objects = {
      ScopedJavaLocalRef<jobject>(ConvertUTF8ToJavaString(env, "one")),
      ScopedJavaLocalRef<jobject>(ConvertUTF8ToJavaString(env, "two")),
      ScopedJavaLocalRef<jobject>(ConvertUTF8ToJavaString(env, "three")),
  };

  ScopedJavaLocalRef<jobjectArray> j_array =
      ToJavaArrayOfObjects(env, jni_zero::g_string_class, objects);
  ASSERT_TRUE(j_array);

  EXPECT_EQ("one",
            ConvertJavaStringToUTF8(
                env, ScopedJavaLocalRef<jstring>::Adopt(
                         env, static_cast<jstring>(env->GetObjectArrayElement(
                                  j_array.obj(), 0)))));
  EXPECT_EQ("two",
            ConvertJavaStringToUTF8(
                env, ScopedJavaLocalRef<jstring>::Adopt(
                         env, static_cast<jstring>(env->GetObjectArrayElement(
                                  j_array.obj(), 1)))));
  EXPECT_EQ("three",
            ConvertJavaStringToUTF8(
                env, ScopedJavaLocalRef<jstring>::Adopt(
                         env, static_cast<jstring>(env->GetObjectArrayElement(
                                  j_array.obj(), 2)))));
}

TEST(JniArray, ToJavaArrayOfObjectLocalRef) {
  JNIEnv* env = AttachCurrentThread();

  std::vector<ScopedJavaLocalRef<jobject>> objects = {
      ScopedJavaLocalRef<jobject>(ConvertUTF8ToJavaString(env, "one")),
      ScopedJavaLocalRef<jobject>(ConvertUTF8ToJavaString(env, "two")),
      ScopedJavaLocalRef<jobject>(ConvertUTF8ToJavaString(env, "three")),
  };

  ScopedJavaLocalRef<jobjectArray> j_array = ToJavaArrayOfObjects(env, objects);
  ASSERT_TRUE(j_array);

  EXPECT_EQ("one",
            ConvertJavaStringToUTF8(
                env, ScopedJavaLocalRef<jstring>::Adopt(
                         env, static_cast<jstring>(env->GetObjectArrayElement(
                                  j_array.obj(), 0)))));
  EXPECT_EQ("two",
            ConvertJavaStringToUTF8(
                env, ScopedJavaLocalRef<jstring>::Adopt(
                         env, static_cast<jstring>(env->GetObjectArrayElement(
                                  j_array.obj(), 1)))));
  EXPECT_EQ("three",
            ConvertJavaStringToUTF8(
                env, ScopedJavaLocalRef<jstring>::Adopt(
                         env, static_cast<jstring>(env->GetObjectArrayElement(
                                  j_array.obj(), 2)))));
}

TEST(JniArray, ToJavaArrayOfObjectGlobalRef) {
  JNIEnv* env = AttachCurrentThread();

  std::vector<ScopedJavaGlobalRef<jobject>> objects = {
      ScopedJavaGlobalRef<jobject>(ConvertUTF8ToJavaString(env, "one")),
      ScopedJavaGlobalRef<jobject>(ConvertUTF8ToJavaString(env, "two")),
      ScopedJavaGlobalRef<jobject>(ConvertUTF8ToJavaString(env, "three")),
  };

  ScopedJavaLocalRef<jobjectArray> j_array = ToJavaArrayOfObjects(env, objects);
  ASSERT_TRUE(j_array);

  EXPECT_EQ("one",
            ConvertJavaStringToUTF8(
                env, ScopedJavaLocalRef<jstring>::Adopt(
                         env, static_cast<jstring>(env->GetObjectArrayElement(
                                  j_array.obj(), 0)))));
  EXPECT_EQ("two",
            ConvertJavaStringToUTF8(
                env, ScopedJavaLocalRef<jstring>::Adopt(
                         env, static_cast<jstring>(env->GetObjectArrayElement(
                                  j_array.obj(), 1)))));
  EXPECT_EQ("three",
            ConvertJavaStringToUTF8(
                env, ScopedJavaLocalRef<jstring>::Adopt(
                         env, static_cast<jstring>(env->GetObjectArrayElement(
                                  j_array.obj(), 2)))));
}
}  // namespace base::android
