1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/android/scoped_java_ref.h"
6
7#include "base/android/jni_android.h"
8#include "base/logging.h"
9
10namespace base {
11namespace android {
12namespace {
13
14const int kDefaultLocalFrameCapacity = 16;
15
16}  // namespace
17
18ScopedJavaLocalFrame::ScopedJavaLocalFrame(JNIEnv* env) : env_(env) {
19  int failed = env_->PushLocalFrame(kDefaultLocalFrameCapacity);
20  DCHECK(!failed);
21}
22
23ScopedJavaLocalFrame::ScopedJavaLocalFrame(JNIEnv* env, int capacity)
24    : env_(env) {
25  int failed = env_->PushLocalFrame(capacity);
26  DCHECK(!failed);
27}
28
29ScopedJavaLocalFrame::~ScopedJavaLocalFrame() {
30  env_->PopLocalFrame(nullptr);
31}
32
33#if DCHECK_IS_ON()
34// This constructor is inlined when DCHECKs are disabled; don't add anything
35// else here.
36JavaRef<jobject>::JavaRef(JNIEnv* env, jobject obj) : obj_(obj) {
37  if (obj) {
38    DCHECK(env && env->GetObjectRefType(obj) == JNILocalRefType);
39  }
40}
41#endif
42
43JNIEnv* JavaRef<jobject>::SetNewLocalRef(JNIEnv* env, jobject obj) {
44  if (!env) {
45    env = AttachCurrentThread();
46  } else {
47    DCHECK_EQ(env, AttachCurrentThread());  // Is |env| on correct thread.
48  }
49  if (obj)
50    obj = env->NewLocalRef(obj);
51  if (obj_)
52    env->DeleteLocalRef(obj_);
53  obj_ = obj;
54  return env;
55}
56
57void JavaRef<jobject>::SetNewGlobalRef(JNIEnv* env, jobject obj) {
58  if (!env) {
59    env = AttachCurrentThread();
60  } else {
61    DCHECK_EQ(env, AttachCurrentThread());  // Is |env| on correct thread.
62  }
63  if (obj)
64    obj = env->NewGlobalRef(obj);
65  if (obj_)
66    env->DeleteGlobalRef(obj_);
67  obj_ = obj;
68}
69
70void JavaRef<jobject>::ResetLocalRef(JNIEnv* env) {
71  if (obj_) {
72    DCHECK_EQ(env, AttachCurrentThread());  // Is |env| on correct thread.
73    env->DeleteLocalRef(obj_);
74    obj_ = nullptr;
75  }
76}
77
78void JavaRef<jobject>::ResetGlobalRef() {
79  if (obj_) {
80    AttachCurrentThread()->DeleteGlobalRef(obj_);
81    obj_ = nullptr;
82  }
83}
84
85jobject JavaRef<jobject>::ReleaseInternal() {
86  jobject obj = obj_;
87  obj_ = NULL;
88  return obj;
89}
90
91}  // namespace android
92}  // namespace base
93