|  | // Copyright 2016 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #include "flutter/lib/jni/jni_array.h" | 
|  |  | 
|  | #include "flutter/lib/jni/dart_jni.h" | 
|  |  | 
|  | namespace blink { | 
|  |  | 
|  | IMPLEMENT_WRAPPERTYPEINFO(jni, JniArray); | 
|  |  | 
|  | JniArray::JniArray(JNIEnv* env, jarray array) : JniObject(env, array) {} | 
|  |  | 
|  | JniArray::~JniArray() {} | 
|  |  | 
|  | jsize JniArray::GetLength() { | 
|  | Dart_Handle exception = nullptr; | 
|  | { | 
|  | ENTER_JNI(); | 
|  |  | 
|  | jsize result = env->GetArrayLength(java_array<jarray>()); | 
|  | if (CheckJniException(env, &exception)) | 
|  | goto fail; | 
|  |  | 
|  | return result; | 
|  | } | 
|  | fail: | 
|  | Dart_ThrowException(exception); | 
|  | FTL_NOTREACHED(); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | template <typename JArrayType> | 
|  | JArrayType JniArray::java_array() const { | 
|  | return static_cast<JArrayType>(java_object()); | 
|  | } | 
|  |  | 
|  | IMPLEMENT_WRAPPERTYPEINFO(jni, JniObjectArray); | 
|  |  | 
|  | JniObjectArray::JniObjectArray(JNIEnv* env, jobjectArray array) | 
|  | : JniArray(env, array) {} | 
|  |  | 
|  | JniObjectArray::~JniObjectArray() {} | 
|  |  | 
|  | ftl::RefPtr<JniObjectArray> JniObjectArray::Create(const JniClass* clazz, | 
|  | jsize length) { | 
|  | Dart_Handle exception = nullptr; | 
|  | { | 
|  | ENTER_JNI(); | 
|  |  | 
|  | jobjectArray array = | 
|  | env->NewObjectArray(length, clazz->java_class(), nullptr); | 
|  | if (CheckJniException(env, &exception)) | 
|  | goto fail; | 
|  |  | 
|  | return ftl::MakeRefCounted<JniObjectArray>(env, array); | 
|  | } | 
|  | fail: | 
|  | Dart_ThrowException(exception); | 
|  | FTL_NOTREACHED(); | 
|  | return nullptr; | 
|  | } | 
|  |  | 
|  | ftl::RefPtr<JniObject> JniObjectArray::GetArrayElement(jsize index) { | 
|  | Dart_Handle exception = nullptr; | 
|  | { | 
|  | ENTER_JNI(); | 
|  |  | 
|  | jobject obj = env->GetObjectArrayElement(java_array<jobjectArray>(), index); | 
|  | if (CheckJniException(env, &exception)) | 
|  | goto fail; | 
|  |  | 
|  | return JniObject::Create(env, obj); | 
|  | } | 
|  | fail: | 
|  | Dart_ThrowException(exception); | 
|  | FTL_NOTREACHED(); | 
|  | return nullptr; | 
|  | } | 
|  |  | 
|  | void JniObjectArray::SetArrayElement(jsize index, const JniObject* value) { | 
|  | Dart_Handle exception = nullptr; | 
|  | { | 
|  | ENTER_JNI(); | 
|  |  | 
|  | env->SetObjectArrayElement(java_array<jobjectArray>(), index, | 
|  | value ? value->java_object() : nullptr); | 
|  | if (CheckJniException(env, &exception)) | 
|  | goto fail; | 
|  |  | 
|  | return; | 
|  | } | 
|  | fail: | 
|  | Dart_ThrowException(exception); | 
|  | FTL_NOTREACHED(); | 
|  | return; | 
|  | } | 
|  |  | 
|  | IMPLEMENT_WRAPPERTYPEINFO(jni, JniBooleanArray); | 
|  |  | 
|  | JniBooleanArray::JniBooleanArray(JNIEnv* env, jbooleanArray array) | 
|  | : JniArray(env, array) {} | 
|  |  | 
|  | JniBooleanArray::~JniBooleanArray() {} | 
|  |  | 
|  | ftl::RefPtr<JniBooleanArray> JniBooleanArray::Create(jsize length) { | 
|  | Dart_Handle exception = nullptr; | 
|  | { | 
|  | ENTER_JNI(); | 
|  |  | 
|  | jbooleanArray array = env->NewBooleanArray(length); | 
|  | if (CheckJniException(env, &exception)) | 
|  | goto fail; | 
|  |  | 
|  | return ftl::MakeRefCounted<JniBooleanArray>(env, array); | 
|  | } | 
|  | fail: | 
|  | Dart_ThrowException(exception); | 
|  | FTL_NOTREACHED(); | 
|  | return nullptr; | 
|  | } | 
|  |  | 
|  | bool JniBooleanArray::GetArrayElement(jsize index) { | 
|  | Dart_Handle exception = nullptr; | 
|  | { | 
|  | ENTER_JNI(); | 
|  |  | 
|  | jboolean result; | 
|  | env->GetBooleanArrayRegion(java_array<jbooleanArray>(), index, 1, &result); | 
|  | if (CheckJniException(env, &exception)) | 
|  | goto fail; | 
|  |  | 
|  | return result == JNI_TRUE; | 
|  | } | 
|  | fail: | 
|  | Dart_ThrowException(exception); | 
|  | FTL_NOTREACHED(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | void JniBooleanArray::SetArrayElement(jsize index, bool value) { | 
|  | Dart_Handle exception = nullptr; | 
|  | { | 
|  | ENTER_JNI(); | 
|  |  | 
|  | jboolean jni_value = value ? JNI_TRUE : JNI_FALSE; | 
|  | env->SetBooleanArrayRegion(java_array<jbooleanArray>(), index, 1, | 
|  | &jni_value); | 
|  | if (CheckJniException(env, &exception)) | 
|  | goto fail; | 
|  |  | 
|  | return; | 
|  | } | 
|  | fail: | 
|  | Dart_ThrowException(exception); | 
|  | FTL_NOTREACHED(); | 
|  | return; | 
|  | } | 
|  |  | 
|  | IMPLEMENT_WRAPPERTYPEINFO(jni, JniByteArray); | 
|  |  | 
|  | JniByteArray::JniByteArray(JNIEnv* env, jbyteArray array) | 
|  | : JniArray(env, array) {} | 
|  |  | 
|  | JniByteArray::~JniByteArray() {} | 
|  |  | 
|  | ftl::RefPtr<JniByteArray> JniByteArray::Create(jsize length) { | 
|  | Dart_Handle exception = nullptr; | 
|  | { | 
|  | ENTER_JNI(); | 
|  |  | 
|  | jbyteArray array = env->NewByteArray(length); | 
|  | if (CheckJniException(env, &exception)) | 
|  | goto fail; | 
|  |  | 
|  | return ftl::MakeRefCounted<JniByteArray>(env, array); | 
|  | } | 
|  | fail: | 
|  | Dart_ThrowException(exception); | 
|  | FTL_NOTREACHED(); | 
|  | return nullptr; | 
|  | } | 
|  |  | 
|  | int64_t JniByteArray::GetArrayElement(jsize index) { | 
|  | Dart_Handle exception = nullptr; | 
|  | { | 
|  | ENTER_JNI(); | 
|  |  | 
|  | jbyte result; | 
|  | env->GetByteArrayRegion(java_array<jbyteArray>(), index, 1, &result); | 
|  | if (CheckJniException(env, &exception)) | 
|  | goto fail; | 
|  |  | 
|  | return result; | 
|  | } | 
|  | fail: | 
|  | Dart_ThrowException(exception); | 
|  | FTL_NOTREACHED(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | void JniByteArray::SetArrayElement(jsize index, int64_t value) { | 
|  | Dart_Handle exception = nullptr; | 
|  | { | 
|  | ENTER_JNI(); | 
|  |  | 
|  | jbyte jni_value = static_cast<jbyte>(value); | 
|  | env->SetByteArrayRegion(java_array<jbyteArray>(), index, 1, &jni_value); | 
|  | if (CheckJniException(env, &exception)) | 
|  | goto fail; | 
|  |  | 
|  | return; | 
|  | } | 
|  | fail: | 
|  | Dart_ThrowException(exception); | 
|  | FTL_NOTREACHED(); | 
|  | return; | 
|  | } | 
|  |  | 
|  | IMPLEMENT_WRAPPERTYPEINFO(jni, JniCharArray); | 
|  |  | 
|  | JniCharArray::JniCharArray(JNIEnv* env, jcharArray array) | 
|  | : JniArray(env, array) {} | 
|  |  | 
|  | JniCharArray::~JniCharArray() {} | 
|  |  | 
|  | ftl::RefPtr<JniCharArray> JniCharArray::Create(jsize length) { | 
|  | Dart_Handle exception = nullptr; | 
|  | { | 
|  | ENTER_JNI(); | 
|  |  | 
|  | jcharArray array = env->NewCharArray(length); | 
|  | if (CheckJniException(env, &exception)) | 
|  | goto fail; | 
|  |  | 
|  | return ftl::MakeRefCounted<JniCharArray>(env, array); | 
|  | } | 
|  | fail: | 
|  | Dart_ThrowException(exception); | 
|  | FTL_NOTREACHED(); | 
|  | return nullptr; | 
|  | } | 
|  |  | 
|  | int64_t JniCharArray::GetArrayElement(jsize index) { | 
|  | Dart_Handle exception = nullptr; | 
|  | { | 
|  | ENTER_JNI(); | 
|  |  | 
|  | jchar result; | 
|  | env->GetCharArrayRegion(java_array<jcharArray>(), index, 1, &result); | 
|  | if (CheckJniException(env, &exception)) | 
|  | goto fail; | 
|  |  | 
|  | return result; | 
|  | } | 
|  | fail: | 
|  | Dart_ThrowException(exception); | 
|  | FTL_NOTREACHED(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | void JniCharArray::SetArrayElement(jsize index, int64_t value) { | 
|  | Dart_Handle exception = nullptr; | 
|  | { | 
|  | ENTER_JNI(); | 
|  |  | 
|  | jchar jni_value = static_cast<jchar>(value); | 
|  | env->SetCharArrayRegion(java_array<jcharArray>(), index, 1, &jni_value); | 
|  | if (CheckJniException(env, &exception)) | 
|  | goto fail; | 
|  |  | 
|  | return; | 
|  | } | 
|  | fail: | 
|  | Dart_ThrowException(exception); | 
|  | FTL_NOTREACHED(); | 
|  | return; | 
|  | } | 
|  |  | 
|  | IMPLEMENT_WRAPPERTYPEINFO(jni, JniShortArray); | 
|  |  | 
|  | JniShortArray::JniShortArray(JNIEnv* env, jshortArray array) | 
|  | : JniArray(env, array) {} | 
|  |  | 
|  | JniShortArray::~JniShortArray() {} | 
|  |  | 
|  | ftl::RefPtr<JniShortArray> JniShortArray::Create(jsize length) { | 
|  | Dart_Handle exception = nullptr; | 
|  | { | 
|  | ENTER_JNI(); | 
|  |  | 
|  | jshortArray array = env->NewShortArray(length); | 
|  | if (CheckJniException(env, &exception)) | 
|  | goto fail; | 
|  |  | 
|  | return ftl::MakeRefCounted<JniShortArray>(env, array); | 
|  | } | 
|  | fail: | 
|  | Dart_ThrowException(exception); | 
|  | FTL_NOTREACHED(); | 
|  | return nullptr; | 
|  | } | 
|  |  | 
|  | int64_t JniShortArray::GetArrayElement(jsize index) { | 
|  | Dart_Handle exception = nullptr; | 
|  | { | 
|  | ENTER_JNI(); | 
|  |  | 
|  | jshort result; | 
|  | env->GetShortArrayRegion(java_array<jshortArray>(), index, 1, &result); | 
|  | if (CheckJniException(env, &exception)) | 
|  | goto fail; | 
|  |  | 
|  | return result; | 
|  | } | 
|  | fail: | 
|  | Dart_ThrowException(exception); | 
|  | FTL_NOTREACHED(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | void JniShortArray::SetArrayElement(jsize index, int64_t value) { | 
|  | Dart_Handle exception = nullptr; | 
|  | { | 
|  | ENTER_JNI(); | 
|  |  | 
|  | jshort jni_value = static_cast<jshort>(value); | 
|  | env->SetShortArrayRegion(java_array<jshortArray>(), index, 1, &jni_value); | 
|  | if (CheckJniException(env, &exception)) | 
|  | goto fail; | 
|  |  | 
|  | return; | 
|  | } | 
|  | fail: | 
|  | Dart_ThrowException(exception); | 
|  | FTL_NOTREACHED(); | 
|  | return; | 
|  | } | 
|  |  | 
|  | IMPLEMENT_WRAPPERTYPEINFO(jni, JniIntArray); | 
|  |  | 
|  | JniIntArray::JniIntArray(JNIEnv* env, jintArray array) : JniArray(env, array) {} | 
|  |  | 
|  | JniIntArray::~JniIntArray() {} | 
|  |  | 
|  | ftl::RefPtr<JniIntArray> JniIntArray::Create(jsize length) { | 
|  | Dart_Handle exception = nullptr; | 
|  | { | 
|  | ENTER_JNI(); | 
|  |  | 
|  | jintArray array = env->NewIntArray(length); | 
|  | if (CheckJniException(env, &exception)) | 
|  | goto fail; | 
|  |  | 
|  | return ftl::MakeRefCounted<JniIntArray>(env, array); | 
|  | } | 
|  | fail: | 
|  | Dart_ThrowException(exception); | 
|  | FTL_NOTREACHED(); | 
|  | return nullptr; | 
|  | } | 
|  |  | 
|  | int64_t JniIntArray::GetArrayElement(jsize index) { | 
|  | Dart_Handle exception = nullptr; | 
|  | { | 
|  | ENTER_JNI(); | 
|  |  | 
|  | jint result; | 
|  | env->GetIntArrayRegion(java_array<jintArray>(), index, 1, &result); | 
|  | if (CheckJniException(env, &exception)) | 
|  | goto fail; | 
|  |  | 
|  | return result; | 
|  | } | 
|  | fail: | 
|  | Dart_ThrowException(exception); | 
|  | FTL_NOTREACHED(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | void JniIntArray::SetArrayElement(jsize index, int64_t value) { | 
|  | Dart_Handle exception = nullptr; | 
|  | { | 
|  | ENTER_JNI(); | 
|  |  | 
|  | jint jni_value = static_cast<jint>(value); | 
|  | env->SetIntArrayRegion(java_array<jintArray>(), index, 1, &jni_value); | 
|  | if (CheckJniException(env, &exception)) | 
|  | goto fail; | 
|  |  | 
|  | return; | 
|  | } | 
|  | fail: | 
|  | Dart_ThrowException(exception); | 
|  | FTL_NOTREACHED(); | 
|  | return; | 
|  | } | 
|  |  | 
|  | IMPLEMENT_WRAPPERTYPEINFO(jni, JniLongArray); | 
|  |  | 
|  | JniLongArray::JniLongArray(JNIEnv* env, jlongArray array) | 
|  | : JniArray(env, array) {} | 
|  |  | 
|  | JniLongArray::~JniLongArray() {} | 
|  |  | 
|  | ftl::RefPtr<JniLongArray> JniLongArray::Create(jsize length) { | 
|  | Dart_Handle exception = nullptr; | 
|  | { | 
|  | ENTER_JNI(); | 
|  |  | 
|  | jlongArray array = env->NewLongArray(length); | 
|  | if (CheckJniException(env, &exception)) | 
|  | goto fail; | 
|  |  | 
|  | return ftl::MakeRefCounted<JniLongArray>(env, array); | 
|  | } | 
|  | fail: | 
|  | Dart_ThrowException(exception); | 
|  | FTL_NOTREACHED(); | 
|  | return nullptr; | 
|  | } | 
|  |  | 
|  | int64_t JniLongArray::GetArrayElement(jsize index) { | 
|  | Dart_Handle exception = nullptr; | 
|  | { | 
|  | ENTER_JNI(); | 
|  |  | 
|  | jlong result; | 
|  | env->GetLongArrayRegion(java_array<jlongArray>(), index, 1, &result); | 
|  | if (CheckJniException(env, &exception)) | 
|  | goto fail; | 
|  |  | 
|  | return static_cast<int64_t>(result); | 
|  | } | 
|  | fail: | 
|  | Dart_ThrowException(exception); | 
|  | FTL_NOTREACHED(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | void JniLongArray::SetArrayElement(jsize index, int64_t value) { | 
|  | Dart_Handle exception = nullptr; | 
|  | { | 
|  | ENTER_JNI(); | 
|  |  | 
|  | jlong jni_value = static_cast<jlong>(value); | 
|  | env->SetLongArrayRegion(java_array<jlongArray>(), index, 1, &jni_value); | 
|  | if (CheckJniException(env, &exception)) | 
|  | goto fail; | 
|  |  | 
|  | return; | 
|  | } | 
|  | fail: | 
|  | Dart_ThrowException(exception); | 
|  | FTL_NOTREACHED(); | 
|  | return; | 
|  | } | 
|  |  | 
|  | IMPLEMENT_WRAPPERTYPEINFO(jni, JniFloatArray); | 
|  |  | 
|  | JniFloatArray::JniFloatArray(JNIEnv* env, jfloatArray array) | 
|  | : JniArray(env, array) {} | 
|  |  | 
|  | JniFloatArray::~JniFloatArray() {} | 
|  |  | 
|  | ftl::RefPtr<JniFloatArray> JniFloatArray::Create(jsize length) { | 
|  | Dart_Handle exception = nullptr; | 
|  | { | 
|  | ENTER_JNI(); | 
|  |  | 
|  | jfloatArray array = env->NewFloatArray(length); | 
|  | if (CheckJniException(env, &exception)) | 
|  | goto fail; | 
|  |  | 
|  | return ftl::MakeRefCounted<JniFloatArray>(env, array); | 
|  | } | 
|  | fail: | 
|  | Dart_ThrowException(exception); | 
|  | FTL_NOTREACHED(); | 
|  | return nullptr; | 
|  | } | 
|  |  | 
|  | double JniFloatArray::GetArrayElement(jsize index) { | 
|  | Dart_Handle exception = nullptr; | 
|  | { | 
|  | ENTER_JNI(); | 
|  |  | 
|  | jfloat result; | 
|  | env->GetFloatArrayRegion(java_array<jfloatArray>(), index, 1, &result); | 
|  | if (CheckJniException(env, &exception)) | 
|  | goto fail; | 
|  |  | 
|  | return result; | 
|  | } | 
|  | fail: | 
|  | Dart_ThrowException(exception); | 
|  | FTL_NOTREACHED(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | void JniFloatArray::SetArrayElement(jsize index, double value) { | 
|  | Dart_Handle exception = nullptr; | 
|  | { | 
|  | ENTER_JNI(); | 
|  |  | 
|  | jfloat jni_value = static_cast<jfloat>(value); | 
|  | env->SetFloatArrayRegion(java_array<jfloatArray>(), index, 1, &jni_value); | 
|  | if (CheckJniException(env, &exception)) | 
|  | goto fail; | 
|  |  | 
|  | return; | 
|  | } | 
|  | fail: | 
|  | Dart_ThrowException(exception); | 
|  | FTL_NOTREACHED(); | 
|  | return; | 
|  | } | 
|  |  | 
|  | IMPLEMENT_WRAPPERTYPEINFO(jni, JniDoubleArray); | 
|  |  | 
|  | JniDoubleArray::JniDoubleArray(JNIEnv* env, jdoubleArray array) | 
|  | : JniArray(env, array) {} | 
|  |  | 
|  | JniDoubleArray::~JniDoubleArray() {} | 
|  |  | 
|  | ftl::RefPtr<JniDoubleArray> JniDoubleArray::Create(jsize length) { | 
|  | Dart_Handle exception = nullptr; | 
|  | { | 
|  | ENTER_JNI(); | 
|  |  | 
|  | jdoubleArray array = env->NewDoubleArray(length); | 
|  | if (CheckJniException(env, &exception)) | 
|  | goto fail; | 
|  |  | 
|  | return ftl::MakeRefCounted<JniDoubleArray>(env, array); | 
|  | } | 
|  | fail: | 
|  | Dart_ThrowException(exception); | 
|  | FTL_NOTREACHED(); | 
|  | return nullptr; | 
|  | } | 
|  |  | 
|  | double JniDoubleArray::GetArrayElement(jsize index) { | 
|  | Dart_Handle exception = nullptr; | 
|  | { | 
|  | ENTER_JNI(); | 
|  |  | 
|  | jdouble result; | 
|  | env->GetDoubleArrayRegion(java_array<jdoubleArray>(), index, 1, &result); | 
|  | if (CheckJniException(env, &exception)) | 
|  | goto fail; | 
|  |  | 
|  | return result; | 
|  | } | 
|  | fail: | 
|  | Dart_ThrowException(exception); | 
|  | FTL_NOTREACHED(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | void JniDoubleArray::SetArrayElement(jsize index, double value) { | 
|  | Dart_Handle exception = nullptr; | 
|  | { | 
|  | ENTER_JNI(); | 
|  |  | 
|  | env->SetDoubleArrayRegion(java_array<jdoubleArray>(), index, 1, &value); | 
|  | if (CheckJniException(env, &exception)) | 
|  | goto fail; | 
|  |  | 
|  | return; | 
|  | } | 
|  | fail: | 
|  | Dart_ThrowException(exception); | 
|  | FTL_NOTREACHED(); | 
|  | return; | 
|  | } | 
|  |  | 
|  | }  // namespace blink |