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() { env_->PopLocalFrame(NULL); }
30
31JavaRef<jobject>::JavaRef() : obj_(NULL) {}
32
33JavaRef<jobject>::JavaRef(JNIEnv* env, jobject obj) : obj_(obj) {
34  if (obj) {
35    DCHECK(env && env->GetObjectRefType(obj) == JNILocalRefType);
36  }
37}
38
39JavaRef<jobject>::~JavaRef() {
40}
41
42JNIEnv* JavaRef<jobject>::SetNewLocalRef(JNIEnv* env, jobject obj) {
43  if (!env) {
44    env = AttachCurrentThread();
45  } else {
46    DCHECK_EQ(env, AttachCurrentThread());  // Is |env| on correct thread.
47  }
48  if (obj)
49    obj = env->NewLocalRef(obj);
50  if (obj_)
51    env->DeleteLocalRef(obj_);
52  obj_ = obj;
53  return env;
54}
55
56void JavaRef<jobject>::SetNewGlobalRef(JNIEnv* env, jobject obj) {
57  if (!env) {
58    env = AttachCurrentThread();
59  } else {
60    DCHECK_EQ(env, AttachCurrentThread());  // Is |env| on correct thread.
61  }
62  if (obj)
63    obj = env->NewGlobalRef(obj);
64  if (obj_)
65    env->DeleteGlobalRef(obj_);
66  obj_ = obj;
67}
68
69void JavaRef<jobject>::ResetLocalRef(JNIEnv* env) {
70  if (obj_) {
71    DCHECK_EQ(env, AttachCurrentThread());  // Is |env| on correct thread.
72    env->DeleteLocalRef(obj_);
73    obj_ = NULL;
74  }
75}
76
77void JavaRef<jobject>::ResetGlobalRef() {
78  if (obj_) {
79    AttachCurrentThread()->DeleteGlobalRef(obj_);
80    obj_ = NULL;
81  }
82}
83
84jobject JavaRef<jobject>::ReleaseInternal() {
85  jobject obj = obj_;
86  obj_ = NULL;
87  return obj;
88}
89
90}  // namespace android
91}  // namespace base
92