15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/android/jni_array.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/android/jni_android.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/android/scoped_java_ref.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace android {
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(JniArray, BasicConversions) {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const uint8 kBytes[] = { 0, 1, 2, 3 };
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kLen = arraysize(kBytes);
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  JNIEnv* env = AttachCurrentThread();
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedJavaLocalRef<jbyteArray> bytes = ToJavaByteArray(env, kBytes, kLen);
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(bytes.obj());
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<uint8> vec(5);
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  JavaByteArrayToByteVector(env, bytes.obj(), &vec);
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4U, vec.size());
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::vector<uint8>(kBytes, kBytes + kLen), vec);
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppendJavaByteArrayToByteVector(env, bytes.obj(), &vec);
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(8U, vec.size());
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CheckLongConversion(
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    JNIEnv* env,
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const int64* long_array,
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const size_t len,
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ScopedJavaLocalRef<jlongArray>& longs) {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(longs.obj());
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  jsize java_array_len = env->GetArrayLength(longs.obj());
3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ASSERT_EQ(static_cast<jsize>(len), java_array_len);
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  jlong value;
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < len; ++i) {
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    env->GetLongArrayRegion(longs.obj(), i, 1, &value);
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_EQ(long_array[i], value);
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(JniArray, LongConversions) {
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int64 kLongs[] = { 0, 1, -1, kint64min, kint64max};
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const size_t kLen = arraysize(kLongs);
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  JNIEnv* env = AttachCurrentThread();
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckLongConversion(env, kLongs, kLen, ToJavaLongArray(env, kLongs, kLen));
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const std::vector<int64> vec(kLongs, kLongs + kLen);
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckLongConversion(env, kLongs, kLen, ToJavaLongArray(env, vec));
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST(JniArray, JavaIntArrayToIntVector) {
5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const int kInts[] = {0, 1, -1};
6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const size_t kLen = arraysize(kInts);
6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  JNIEnv* env = AttachCurrentThread();
6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ScopedJavaLocalRef<jintArray> jints(env, env->NewIntArray(kLen));
6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ASSERT_TRUE(jints.obj());
6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  for (size_t i = 0; i < kLen; ++i) {
6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    jint j = static_cast<jint>(kInts[i]);
6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    env->SetIntArrayRegion(jints.obj(), i, 1, &j);
6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ASSERT_FALSE(HasException(env));
7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<int> ints;
7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  JavaIntArrayToIntVector(env, jints.obj(), &ints);
7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ASSERT_EQ(static_cast<jsize>(ints.size()), env->GetArrayLength(jints.obj()));
7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  jint value;
7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  for (size_t i = 0; i < kLen; ++i) {
7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    env->GetIntArrayRegion(jints.obj(), i, 1, &value);
8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ASSERT_EQ(ints[i], value);
8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST(JniArray, JavaFloatArrayToFloatVector) {
8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const float kFloats[] = {0.0, 0.5, -0.5};
8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const size_t kLen = arraysize(kFloats);
8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  JNIEnv* env = AttachCurrentThread();
8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ScopedJavaLocalRef<jfloatArray> jfloats(env, env->NewFloatArray(kLen));
9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ASSERT_TRUE(jfloats.obj());
9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  for (size_t i = 0; i < kLen; ++i) {
9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    jfloat j = static_cast<jfloat>(kFloats[i]);
9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    env->SetFloatArrayRegion(jfloats.obj(), i, 1, &j);
9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ASSERT_FALSE(HasException(env));
9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<float> floats;
9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  JavaFloatArrayToFloatVector(env, jfloats.obj(), &floats);
10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ASSERT_EQ(static_cast<jsize>(floats.size()),
10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      env->GetArrayLength(jfloats.obj()));
10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  jfloat value;
10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  for (size_t i = 0; i < kLen; ++i) {
10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    env->GetFloatArrayRegion(jfloats.obj(), i, 1, &value);
10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ASSERT_EQ(floats[i], value);
10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(JniArray, JavaArrayOfByteArrayToStringVector) {
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int kMaxItems = 50;
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  JNIEnv* env = AttachCurrentThread();
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create a byte[][] object.
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedJavaLocalRef<jclass> byte_array_clazz(env, env->FindClass("[B"));
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(byte_array_clazz.obj());
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedJavaLocalRef<jobjectArray> array(
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      env, env->NewObjectArray(kMaxItems, byte_array_clazz.obj(), NULL));
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(array.obj());
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create kMaxItems byte buffers.
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  char text[16];
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < kMaxItems; ++i) {
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    snprintf(text, sizeof text, "%d", i);
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedJavaLocalRef<jbyteArray> byte_array = ToJavaByteArray(
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        env, reinterpret_cast<uint8*>(text),
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        static_cast<size_t>(strlen(text)));
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(byte_array.obj());
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    env->SetObjectArrayElement(array.obj(), i, byte_array.obj());
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_FALSE(HasException(env));
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Convert to std::vector<std::string>, check the content.
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<std::string> vec;
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  JavaArrayOfByteArrayToStringVector(env, array.obj(), &vec);
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(static_cast<size_t>(kMaxItems), vec.size());
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < kMaxItems; ++i) {
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    snprintf(text, sizeof text, "%d", i);
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_STREQ(text, vec[i].c_str());
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace android
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace base
149