| // Copyright 2024 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "third_party/jni_zero/java_refs.h" |
| |
| #include "third_party/jni_zero/jni_methods.h" |
| |
| namespace jni_zero { |
| namespace { |
| const int kDefaultLocalFrameCapacity = 16; |
| } |
| |
| ScopedJavaLocalFrame::ScopedJavaLocalFrame(JNIEnv* env) : env_(env) { |
| int failed = env_->PushLocalFrame(kDefaultLocalFrameCapacity); |
| JNI_ZERO_DCHECK(!failed); |
| } |
| |
| ScopedJavaLocalFrame::ScopedJavaLocalFrame(JNIEnv* env, int capacity) |
| : env_(env) { |
| int failed = env_->PushLocalFrame(capacity); |
| JNI_ZERO_DCHECK(!failed); |
| } |
| |
| ScopedJavaLocalFrame::~ScopedJavaLocalFrame() { |
| env_->PopLocalFrame(nullptr); |
| } |
| |
| #if JNI_ZERO_DCHECK_IS_ON() |
| // This constructor is inlined when DCHECKs are disabled; don't add anything |
| // else here. |
| JavaRef<jobject>::JavaRef(JNIEnv* env, jobject obj) : obj_(obj) { |
| if (obj) { |
| JNI_ZERO_DCHECK(env && env->GetObjectRefType(obj) == JNILocalRefType); |
| } |
| } |
| #endif |
| |
| JNIEnv* JavaRef<jobject>::SetNewLocalRef(JNIEnv* env, jobject obj) { |
| if (!env) { |
| env = AttachCurrentThread(); |
| } else { |
| JNI_ZERO_DCHECK(env == |
| AttachCurrentThread()); // Is |env| on correct thread. |
| } |
| if (obj) { |
| obj = env->NewLocalRef(obj); |
| } |
| if (obj_) { |
| env->DeleteLocalRef(obj_); |
| } |
| obj_ = obj; |
| return env; |
| } |
| |
| void JavaRef<jobject>::SetNewGlobalRef(JNIEnv* env, jobject obj) { |
| if (!env) { |
| env = AttachCurrentThread(); |
| } else { |
| JNI_ZERO_DCHECK(env == |
| AttachCurrentThread()); // Is |env| on correct thread. |
| } |
| if (obj) { |
| obj = env->NewGlobalRef(obj); |
| } |
| if (obj_) { |
| env->DeleteGlobalRef(obj_); |
| } |
| obj_ = obj; |
| } |
| |
| void JavaRef<jobject>::ResetLocalRef(JNIEnv* env) { |
| if (obj_) { |
| JNI_ZERO_DCHECK(env == |
| AttachCurrentThread()); // Is |env| on correct thread. |
| env->DeleteLocalRef(obj_); |
| obj_ = nullptr; |
| } |
| } |
| |
| void JavaRef<jobject>::ResetGlobalRef() { |
| if (obj_) { |
| AttachCurrentThread()->DeleteGlobalRef(obj_); |
| obj_ = nullptr; |
| } |
| } |
| |
| ScopedJavaGlobalWeakRef::ScopedJavaGlobalWeakRef( |
| const ScopedJavaGlobalWeakRef& orig) { |
| Assign(orig); |
| } |
| |
| ScopedJavaGlobalWeakRef::ScopedJavaGlobalWeakRef(JNIEnv* env, |
| const JavaRef<jobject>& obj) |
| : obj_(env->NewWeakGlobalRef(obj.obj())) {} |
| |
| void ScopedJavaGlobalWeakRef::reset() { |
| if (obj_) { |
| AttachCurrentThread()->DeleteWeakGlobalRef(obj_); |
| obj_ = nullptr; |
| } |
| } |
| |
| ScopedJavaLocalRef<jobject> ScopedJavaGlobalWeakRef::get(JNIEnv* env) const { |
| jobject real = obj_ ? real = env->NewLocalRef(obj_) : nullptr; |
| return ScopedJavaLocalRef<jobject>::Adopt(env, real); |
| } |
| |
| void ScopedJavaGlobalWeakRef::Assign(const ScopedJavaGlobalWeakRef& other) { |
| if (&other == this) { |
| return; |
| } |
| |
| JNIEnv* env = AttachCurrentThread(); |
| if (obj_) { |
| env->DeleteWeakGlobalRef(obj_); |
| } |
| |
| obj_ = other.obj_ ? env->NewWeakGlobalRef(other.obj_) : nullptr; |
| } |
| |
| } // namespace jni_zero |