Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / base / android / scoped_java_ref_unittest.cc
blob3f4419af6d2b648174632dd9fa04ed24728ae1b4
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.
5 #include "base/android/scoped_java_ref.h"
7 #include "base/android/jni_android.h"
8 #include "base/android/jni_string.h"
9 #include "testing/gtest/include/gtest/gtest.h"
11 namespace base {
12 namespace android {
14 namespace {
15 int g_local_refs = 0;
16 int g_global_refs = 0;
18 const JNINativeInterface* g_previous_functions;
20 jobject NewGlobalRef(JNIEnv* env, jobject obj) {
21 ++g_global_refs;
22 return g_previous_functions->NewGlobalRef(env, obj);
25 void DeleteGlobalRef(JNIEnv* env, jobject obj) {
26 --g_global_refs;
27 return g_previous_functions->DeleteGlobalRef(env, obj);
30 jobject NewLocalRef(JNIEnv* env, jobject obj) {
31 ++g_local_refs;
32 return g_previous_functions->NewLocalRef(env, obj);
35 void DeleteLocalRef(JNIEnv* env, jobject obj) {
36 --g_local_refs;
37 return g_previous_functions->DeleteLocalRef(env, obj);
39 } // namespace
41 class ScopedJavaRefTest : public testing::Test {
42 protected:
43 void SetUp() override {
44 g_local_refs = 0;
45 g_global_refs = 0;
46 JNIEnv* env = AttachCurrentThread();
47 g_previous_functions = env->functions;
48 hooked_functions = *g_previous_functions;
49 env->functions = &hooked_functions;
50 // We inject our own functions in JNINativeInterface so we can keep track
51 // of the reference counting ourselves.
52 hooked_functions.NewGlobalRef = &NewGlobalRef;
53 hooked_functions.DeleteGlobalRef = &DeleteGlobalRef;
54 hooked_functions.NewLocalRef = &NewLocalRef;
55 hooked_functions.DeleteLocalRef = &DeleteLocalRef;
58 void TearDown() override {
59 JNIEnv* env = AttachCurrentThread();
60 env->functions = g_previous_functions;
62 // From JellyBean release, the instance of this struct provided in JNIEnv is
63 // read-only, so we deep copy it to allow individual functions to be hooked.
64 JNINativeInterface hooked_functions;
67 // The main purpose of this is testing the various conversions compile.
68 TEST_F(ScopedJavaRefTest, Conversions) {
69 JNIEnv* env = AttachCurrentThread();
70 ScopedJavaLocalRef<jstring> str = ConvertUTF8ToJavaString(env, "string");
71 ScopedJavaGlobalRef<jstring> global(str);
73 ScopedJavaGlobalRef<jobject> global_obj(str);
74 ScopedJavaLocalRef<jobject> local_obj(global);
75 const JavaRef<jobject>& obj_ref1(str);
76 const JavaRef<jobject>& obj_ref2(global);
77 EXPECT_TRUE(env->IsSameObject(obj_ref1.obj(), obj_ref2.obj()));
78 EXPECT_TRUE(env->IsSameObject(global_obj.obj(), obj_ref2.obj()));
80 global.Reset(str);
81 const JavaRef<jstring>& str_ref = str;
82 EXPECT_EQ("string", ConvertJavaStringToUTF8(str_ref));
83 str.Reset();
86 TEST_F(ScopedJavaRefTest, RefCounts) {
87 JNIEnv* env = AttachCurrentThread();
88 ScopedJavaLocalRef<jstring> str;
89 // The ConvertJavaStringToUTF8 below creates a new string that would normally
90 // return a local ref. We simulate that by starting the g_local_refs count at
91 // 1.
92 g_local_refs = 1;
93 str.Reset(ConvertUTF8ToJavaString(env, "string"));
94 EXPECT_EQ(1, g_local_refs);
95 EXPECT_EQ(0, g_global_refs);
97 ScopedJavaGlobalRef<jstring> global_str(str);
98 ScopedJavaGlobalRef<jobject> global_obj(global_str);
99 EXPECT_EQ(1, g_local_refs);
100 EXPECT_EQ(2, g_global_refs);
102 ScopedJavaLocalRef<jstring> str2(env, str.Release());
103 EXPECT_EQ(1, g_local_refs);
105 ScopedJavaLocalRef<jstring> str3(str2);
106 EXPECT_EQ(2, g_local_refs);
108 EXPECT_EQ(1, g_local_refs);
109 str2.Reset();
110 EXPECT_EQ(0, g_local_refs);
111 global_str.Reset();
112 EXPECT_EQ(1, g_global_refs);
113 ScopedJavaGlobalRef<jobject> global_obj2(global_obj);
114 EXPECT_EQ(2, g_global_refs);
117 EXPECT_EQ(0, g_local_refs);
118 EXPECT_EQ(0, g_global_refs);
121 } // namespace android
122 } // namespace base