| // 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_object.h" |
| |
| #include "base/strings/string_util.h" |
| #include "flutter/lib/jni/dart_jni.h" |
| #include "flutter/lib/jni/jni_array.h" |
| #include "flutter/lib/jni/jni_class.h" |
| #include "flutter/lib/jni/jni_string.h" |
| |
| namespace blink { |
| |
| IMPLEMENT_WRAPPERTYPEINFO(jni, JniObject); |
| |
| JniObject::JniObject(JNIEnv* env, jobject object) : object_(env, object) {} |
| |
| JniObject::~JniObject() {} |
| |
| ftl::RefPtr<JniObject> JniObject::Create(JNIEnv* env, jobject object) { |
| if (object == nullptr) |
| return nullptr; |
| |
| std::string class_name = DartJni::GetObjectClassName(env, object); |
| |
| ftl::RefPtr<JniObject> result; |
| |
| if (class_name == "java.lang.String") { |
| result = ftl::MakeRefCounted<JniString>(env, static_cast<jstring>(object)); |
| } else if (class_name == "java.lang.Class") { |
| result = ftl::MakeRefCounted<JniClass>(env, static_cast<jclass>(object)); |
| } else if (base::StartsWith(class_name, "[L", base::CompareCase::SENSITIVE)) { |
| result = ftl::MakeRefCounted<JniObjectArray>( |
| env, static_cast<jobjectArray>(object)); |
| } else if (class_name == "[Z") { |
| result = ftl::MakeRefCounted<JniBooleanArray>( |
| env, static_cast<jbooleanArray>(object)); |
| } else if (class_name == "[B") { |
| result = |
| ftl::MakeRefCounted<JniByteArray>(env, static_cast<jbyteArray>(object)); |
| } else if (class_name == "[C") { |
| result = |
| ftl::MakeRefCounted<JniCharArray>(env, static_cast<jcharArray>(object)); |
| } else if (class_name == "[S") { |
| result = ftl::MakeRefCounted<JniShortArray>( |
| env, static_cast<jshortArray>(object)); |
| } else if (class_name == "[I") { |
| result = |
| ftl::MakeRefCounted<JniIntArray>(env, static_cast<jintArray>(object)); |
| } else if (class_name == "[J") { |
| result = |
| ftl::MakeRefCounted<JniLongArray>(env, static_cast<jlongArray>(object)); |
| } else if (class_name == "[F") { |
| result = ftl::MakeRefCounted<JniFloatArray>( |
| env, static_cast<jfloatArray>(object)); |
| } else if (class_name == "[D") { |
| result = ftl::MakeRefCounted<JniDoubleArray>( |
| env, static_cast<jdoubleArray>(object)); |
| } else { |
| result = ftl::MakeRefCounted<JniObject>(env, object); |
| } |
| |
| return result; |
| } |
| |
| ftl::RefPtr<JniClass> JniObject::GetObjectClass() { |
| Dart_Handle exception = nullptr; |
| { |
| ENTER_JNI(); |
| |
| jclass clazz = env->GetObjectClass(java_object()); |
| if (CheckJniException(env, &exception)) |
| goto fail; |
| |
| return ftl::MakeRefCounted<JniClass>(env, clazz); |
| } |
| fail: |
| Dart_ThrowException(exception); |
| FTL_NOTREACHED(); |
| return nullptr; |
| } |
| |
| ftl::RefPtr<JniObject> JniObject::GetObjectField(jfieldID fieldId) { |
| Dart_Handle exception = nullptr; |
| { |
| ENTER_JNI(); |
| |
| jobject obj = env->GetObjectField(java_object(), fieldId); |
| if (CheckJniException(env, &exception)) |
| goto fail; |
| |
| return JniObject::Create(env, obj); |
| } |
| fail: |
| Dart_ThrowException(exception); |
| FTL_NOTREACHED(); |
| return nullptr; |
| } |
| |
| bool JniObject::GetBooleanField(jfieldID fieldId) { |
| Dart_Handle exception = nullptr; |
| { |
| ENTER_JNI(); |
| |
| jboolean result = env->GetBooleanField(java_object(), fieldId); |
| if (CheckJniException(env, &exception)) |
| goto fail; |
| |
| return result == JNI_TRUE; |
| } |
| fail: |
| Dart_ThrowException(exception); |
| FTL_NOTREACHED(); |
| return false; |
| } |
| |
| int64_t JniObject::GetByteField(jfieldID fieldId) { |
| Dart_Handle exception = nullptr; |
| { |
| ENTER_JNI(); |
| |
| jbyte result = env->GetByteField(java_object(), fieldId); |
| if (CheckJniException(env, &exception)) |
| goto fail; |
| |
| return result; |
| } |
| fail: |
| Dart_ThrowException(exception); |
| FTL_NOTREACHED(); |
| return 0; |
| } |
| |
| int64_t JniObject::GetCharField(jfieldID fieldId) { |
| Dart_Handle exception = nullptr; |
| { |
| ENTER_JNI(); |
| |
| jchar result = env->GetCharField(java_object(), fieldId); |
| if (CheckJniException(env, &exception)) |
| goto fail; |
| |
| return result; |
| } |
| fail: |
| Dart_ThrowException(exception); |
| FTL_NOTREACHED(); |
| return 0; |
| } |
| |
| int64_t JniObject::GetShortField(jfieldID fieldId) { |
| Dart_Handle exception = nullptr; |
| { |
| ENTER_JNI(); |
| |
| jshort result = env->GetShortField(java_object(), fieldId); |
| if (CheckJniException(env, &exception)) |
| goto fail; |
| |
| return result; |
| } |
| fail: |
| Dart_ThrowException(exception); |
| FTL_NOTREACHED(); |
| return 0; |
| } |
| |
| int64_t JniObject::GetIntField(jfieldID fieldId) { |
| Dart_Handle exception = nullptr; |
| { |
| ENTER_JNI(); |
| |
| jint result = env->GetIntField(java_object(), fieldId); |
| if (CheckJniException(env, &exception)) |
| goto fail; |
| |
| return result; |
| } |
| fail: |
| Dart_ThrowException(exception); |
| FTL_NOTREACHED(); |
| return 0; |
| } |
| |
| int64_t JniObject::GetLongField(jfieldID fieldId) { |
| Dart_Handle exception = nullptr; |
| { |
| ENTER_JNI(); |
| |
| jlong result = env->GetLongField(java_object(), fieldId); |
| if (CheckJniException(env, &exception)) |
| goto fail; |
| |
| return result; |
| } |
| fail: |
| Dart_ThrowException(exception); |
| FTL_NOTREACHED(); |
| return 0; |
| } |
| |
| double JniObject::GetFloatField(jfieldID fieldId) { |
| Dart_Handle exception = nullptr; |
| { |
| ENTER_JNI(); |
| |
| jfloat result = env->GetFloatField(java_object(), fieldId); |
| if (CheckJniException(env, &exception)) |
| goto fail; |
| |
| return result; |
| } |
| fail: |
| Dart_ThrowException(exception); |
| FTL_NOTREACHED(); |
| return 0; |
| } |
| |
| double JniObject::GetDoubleField(jfieldID fieldId) { |
| Dart_Handle exception = nullptr; |
| { |
| ENTER_JNI(); |
| |
| jfloat result = env->GetDoubleField(java_object(), fieldId); |
| if (CheckJniException(env, &exception)) |
| goto fail; |
| |
| return result; |
| } |
| fail: |
| Dart_ThrowException(exception); |
| FTL_NOTREACHED(); |
| return 0; |
| } |
| |
| void JniObject::SetObjectField(jfieldID fieldId, const JniObject* value) { |
| Dart_Handle exception = nullptr; |
| { |
| ENTER_JNI(); |
| |
| env->SetObjectField(java_object(), fieldId, |
| value ? value->java_object() : nullptr); |
| if (CheckJniException(env, &exception)) |
| goto fail; |
| |
| return; |
| } |
| fail: |
| Dart_ThrowException(exception); |
| FTL_NOTREACHED(); |
| return; |
| } |
| |
| void JniObject::SetBooleanField(jfieldID fieldId, bool value) { |
| Dart_Handle exception = nullptr; |
| { |
| ENTER_JNI(); |
| |
| env->SetBooleanField(java_object(), fieldId, value ? JNI_TRUE : JNI_FALSE); |
| if (CheckJniException(env, &exception)) |
| goto fail; |
| |
| return; |
| } |
| fail: |
| Dart_ThrowException(exception); |
| FTL_NOTREACHED(); |
| return; |
| } |
| |
| void JniObject::SetByteField(jfieldID fieldId, int64_t value) { |
| Dart_Handle exception = nullptr; |
| { |
| ENTER_JNI(); |
| |
| env->SetByteField(java_object(), fieldId, value); |
| if (CheckJniException(env, &exception)) |
| goto fail; |
| |
| return; |
| } |
| fail: |
| Dart_ThrowException(exception); |
| FTL_NOTREACHED(); |
| return; |
| } |
| |
| void JniObject::SetCharField(jfieldID fieldId, int64_t value) { |
| Dart_Handle exception = nullptr; |
| { |
| ENTER_JNI(); |
| |
| env->SetCharField(java_object(), fieldId, value); |
| if (CheckJniException(env, &exception)) |
| goto fail; |
| |
| return; |
| } |
| fail: |
| Dart_ThrowException(exception); |
| FTL_NOTREACHED(); |
| return; |
| } |
| |
| void JniObject::SetShortField(jfieldID fieldId, int64_t value) { |
| Dart_Handle exception = nullptr; |
| { |
| ENTER_JNI(); |
| |
| env->SetShortField(java_object(), fieldId, value); |
| if (CheckJniException(env, &exception)) |
| goto fail; |
| |
| return; |
| } |
| fail: |
| Dart_ThrowException(exception); |
| FTL_NOTREACHED(); |
| return; |
| } |
| |
| void JniObject::SetIntField(jfieldID fieldId, int64_t value) { |
| Dart_Handle exception = nullptr; |
| { |
| ENTER_JNI(); |
| |
| env->SetIntField(java_object(), fieldId, value); |
| if (CheckJniException(env, &exception)) |
| goto fail; |
| |
| return; |
| } |
| fail: |
| Dart_ThrowException(exception); |
| FTL_NOTREACHED(); |
| return; |
| } |
| |
| void JniObject::SetLongField(jfieldID fieldId, int64_t value) { |
| Dart_Handle exception = nullptr; |
| { |
| ENTER_JNI(); |
| |
| env->SetLongField(java_object(), fieldId, value); |
| if (CheckJniException(env, &exception)) |
| goto fail; |
| |
| return; |
| } |
| fail: |
| Dart_ThrowException(exception); |
| FTL_NOTREACHED(); |
| return; |
| } |
| |
| void JniObject::SetFloatField(jfieldID fieldId, double value) { |
| Dart_Handle exception = nullptr; |
| { |
| ENTER_JNI(); |
| |
| env->SetFloatField(java_object(), fieldId, value); |
| if (CheckJniException(env, &exception)) |
| goto fail; |
| |
| return; |
| } |
| fail: |
| Dart_ThrowException(exception); |
| FTL_NOTREACHED(); |
| return; |
| } |
| |
| void JniObject::SetDoubleField(jfieldID fieldId, double value) { |
| Dart_Handle exception = nullptr; |
| { |
| ENTER_JNI(); |
| |
| env->SetDoubleField(java_object(), fieldId, value); |
| if (CheckJniException(env, &exception)) |
| goto fail; |
| |
| return; |
| } |
| fail: |
| Dart_ThrowException(exception); |
| FTL_NOTREACHED(); |
| return; |
| } |
| |
| ftl::RefPtr<JniObject> JniObject::CallObjectMethod( |
| jmethodID methodId, |
| const std::vector<Dart_Handle>& args) { |
| Dart_Handle exception = nullptr; |
| { |
| ENTER_JNI(); |
| |
| JniMethodArgs java_args; |
| java_args.Convert(env, args, &exception); |
| if (exception) |
| goto fail; |
| |
| jobject obj = |
| env->CallObjectMethodA(java_object(), methodId, java_args.jvalues()); |
| if (CheckJniException(env, &exception)) |
| goto fail; |
| |
| return JniObject::Create(env, obj); |
| } |
| fail: |
| Dart_ThrowException(exception); |
| FTL_NOTREACHED(); |
| return nullptr; |
| } |
| |
| bool JniObject::CallBooleanMethod(jmethodID methodId, |
| const std::vector<Dart_Handle>& args) { |
| Dart_Handle exception = nullptr; |
| { |
| ENTER_JNI(); |
| |
| JniMethodArgs java_args; |
| java_args.Convert(env, args, &exception); |
| if (exception) |
| goto fail; |
| |
| jboolean result = |
| env->CallBooleanMethodA(java_object(), methodId, java_args.jvalues()); |
| if (CheckJniException(env, &exception)) |
| goto fail; |
| |
| return result == JNI_TRUE; |
| } |
| fail: |
| Dart_ThrowException(exception); |
| FTL_NOTREACHED(); |
| return false; |
| } |
| |
| int64_t JniObject::CallByteMethod(jmethodID methodId, |
| const std::vector<Dart_Handle>& args) { |
| Dart_Handle exception = nullptr; |
| { |
| ENTER_JNI(); |
| |
| JniMethodArgs java_args; |
| java_args.Convert(env, args, &exception); |
| if (exception) |
| goto fail; |
| |
| jbyte result = |
| env->CallByteMethodA(java_object(), methodId, java_args.jvalues()); |
| if (CheckJniException(env, &exception)) |
| goto fail; |
| |
| return result; |
| } |
| fail: |
| Dart_ThrowException(exception); |
| FTL_NOTREACHED(); |
| return 0; |
| } |
| |
| int64_t JniObject::CallCharMethod(jmethodID methodId, |
| const std::vector<Dart_Handle>& args) { |
| Dart_Handle exception = nullptr; |
| { |
| ENTER_JNI(); |
| |
| JniMethodArgs java_args; |
| java_args.Convert(env, args, &exception); |
| if (exception) |
| goto fail; |
| |
| jchar result = |
| env->CallCharMethodA(java_object(), methodId, java_args.jvalues()); |
| if (CheckJniException(env, &exception)) |
| goto fail; |
| |
| return result; |
| } |
| fail: |
| Dart_ThrowException(exception); |
| FTL_NOTREACHED(); |
| return 0; |
| } |
| |
| int64_t JniObject::CallShortMethod(jmethodID methodId, |
| const std::vector<Dart_Handle>& args) { |
| Dart_Handle exception = nullptr; |
| { |
| ENTER_JNI(); |
| |
| JniMethodArgs java_args; |
| java_args.Convert(env, args, &exception); |
| if (exception) |
| goto fail; |
| |
| jshort result = |
| env->CallShortMethodA(java_object(), methodId, java_args.jvalues()); |
| if (CheckJniException(env, &exception)) |
| goto fail; |
| |
| return result; |
| } |
| fail: |
| Dart_ThrowException(exception); |
| FTL_NOTREACHED(); |
| return 0; |
| } |
| |
| int64_t JniObject::CallIntMethod(jmethodID methodId, |
| const std::vector<Dart_Handle>& args) { |
| Dart_Handle exception = nullptr; |
| { |
| ENTER_JNI(); |
| |
| JniMethodArgs java_args; |
| java_args.Convert(env, args, &exception); |
| if (exception) |
| goto fail; |
| |
| jint result = |
| env->CallIntMethodA(java_object(), methodId, java_args.jvalues()); |
| if (CheckJniException(env, &exception)) |
| goto fail; |
| |
| return result; |
| } |
| fail: |
| Dart_ThrowException(exception); |
| FTL_NOTREACHED(); |
| return 0; |
| } |
| |
| int64_t JniObject::CallLongMethod(jmethodID methodId, |
| const std::vector<Dart_Handle>& args) { |
| Dart_Handle exception = nullptr; |
| { |
| ENTER_JNI(); |
| |
| JniMethodArgs java_args; |
| java_args.Convert(env, args, &exception); |
| if (exception) |
| goto fail; |
| |
| jlong result = |
| env->CallLongMethodA(java_object(), methodId, java_args.jvalues()); |
| if (CheckJniException(env, &exception)) |
| goto fail; |
| |
| return result; |
| } |
| fail: |
| Dart_ThrowException(exception); |
| FTL_NOTREACHED(); |
| return 0; |
| } |
| |
| double JniObject::CallFloatMethod(jmethodID methodId, |
| const std::vector<Dart_Handle>& args) { |
| Dart_Handle exception = nullptr; |
| { |
| ENTER_JNI(); |
| |
| JniMethodArgs java_args; |
| java_args.Convert(env, args, &exception); |
| if (exception) |
| goto fail; |
| |
| jfloat result = |
| env->CallFloatMethodA(java_object(), methodId, java_args.jvalues()); |
| if (CheckJniException(env, &exception)) |
| goto fail; |
| |
| return result; |
| } |
| fail: |
| Dart_ThrowException(exception); |
| FTL_NOTREACHED(); |
| return 0; |
| } |
| |
| double JniObject::CallDoubleMethod(jmethodID methodId, |
| const std::vector<Dart_Handle>& args) { |
| Dart_Handle exception = nullptr; |
| { |
| ENTER_JNI(); |
| |
| JniMethodArgs java_args; |
| java_args.Convert(env, args, &exception); |
| if (exception) |
| goto fail; |
| |
| jdouble result = |
| env->CallDoubleMethodA(java_object(), methodId, java_args.jvalues()); |
| if (CheckJniException(env, &exception)) |
| goto fail; |
| |
| return result; |
| } |
| fail: |
| Dart_ThrowException(exception); |
| FTL_NOTREACHED(); |
| return 0; |
| } |
| |
| void JniObject::CallVoidMethod(jmethodID methodId, |
| const std::vector<Dart_Handle>& args) { |
| Dart_Handle exception = nullptr; |
| { |
| ENTER_JNI(); |
| |
| JniMethodArgs java_args; |
| java_args.Convert(env, args, &exception); |
| if (exception) |
| goto fail; |
| |
| env->CallVoidMethodA(java_object(), methodId, java_args.jvalues()); |
| if (CheckJniException(env, &exception)) |
| goto fail; |
| |
| return; |
| } |
| fail: |
| Dart_ThrowException(exception); |
| FTL_NOTREACHED(); |
| return; |
| } |
| |
| } // namespace blink |