OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011 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/android/jni_string.h" |
| 9 #include "testing/gtest/include/gtest/gtest.h" |
| 10 |
| 11 namespace base { |
| 12 namespace android { |
| 13 |
| 14 namespace { |
| 15 int g_local_refs = 0; |
| 16 int g_global_refs = 0; |
| 17 |
| 18 jobject NewGlobalRef(JNIEnv* env, jobject obj) { |
| 19 ++g_global_refs; |
| 20 return AttachCurrentThread()->NewGlobalRef(obj); |
| 21 } |
| 22 |
| 23 void DeleteGlobalRef(JNIEnv* env, jobject obj) { |
| 24 --g_global_refs; |
| 25 return AttachCurrentThread()->DeleteGlobalRef(obj); |
| 26 } |
| 27 |
| 28 jobject NewLocalRef(JNIEnv* env, jobject obj) { |
| 29 ++g_local_refs; |
| 30 return AttachCurrentThread()->NewLocalRef(obj); |
| 31 } |
| 32 |
| 33 void DeleteLocalRef(JNIEnv* env, jobject obj) { |
| 34 --g_local_refs; |
| 35 return AttachCurrentThread()->DeleteLocalRef(obj); |
| 36 } |
| 37 } // namespace |
| 38 |
| 39 class ScopedJavaRefTest : public testing::Test { |
| 40 protected: |
| 41 virtual void SetUp() { |
| 42 g_local_refs = 0; |
| 43 g_global_refs = 0; |
| 44 JNIEnv* env = AttachCurrentThread(); |
| 45 counting_env = *env; |
| 46 counting_functions = *counting_env.functions; |
| 47 counting_functions.NewGlobalRef = &NewGlobalRef; |
| 48 counting_functions.DeleteGlobalRef = &DeleteGlobalRef; |
| 49 counting_functions.NewLocalRef = &NewLocalRef; |
| 50 counting_functions.DeleteLocalRef = &DeleteLocalRef; |
| 51 counting_env.functions = &counting_functions; |
| 52 } |
| 53 |
| 54 // Special JNI env configured in SetUp to count in and out all local & global |
| 55 // reference instances. Be careful to only use this with the ScopedJavaRef |
| 56 // classes under test, else it's easy to get system references counted in |
| 57 // here too. |
| 58 JNIEnv counting_env; |
| 59 JNINativeInterface counting_functions; |
| 60 }; |
| 61 |
| 62 // The main purpose of this is testing the various conversions compile. |
| 63 TEST_F(ScopedJavaRefTest, Conversions) { |
| 64 JNIEnv* env = AttachCurrentThread(); |
| 65 ScopedJavaLocalRef<jstring> str(env, ConvertUTF8ToJavaString(env, "string")); |
| 66 ScopedJavaGlobalRef<jstring> global(str); |
| 67 { |
| 68 ScopedJavaGlobalRef<jobject> global_obj(str); |
| 69 ScopedJavaLocalRef<jobject> local_obj(global); |
| 70 const JavaRef<jobject>& obj_ref1(str); |
| 71 const JavaRef<jobject>& obj_ref2(global); |
| 72 EXPECT_TRUE(env->IsSameObject(obj_ref1.obj(), obj_ref2.obj())); |
| 73 EXPECT_TRUE(env->IsSameObject(global_obj.obj(), obj_ref2.obj())); |
| 74 } |
| 75 global.Reset(str); |
| 76 const JavaRef<jstring>& str_ref = str; |
| 77 EXPECT_EQ("string", ConvertJavaStringToUTF8(env, str_ref.obj())); |
| 78 str.Reset(); |
| 79 } |
| 80 |
| 81 TEST_F(ScopedJavaRefTest, RefCounts) { |
| 82 ScopedJavaLocalRef<jstring> str; |
| 83 str.Reset(&counting_env, ConvertUTF8ToJavaString(AttachCurrentThread(), |
| 84 "string")); |
| 85 EXPECT_EQ(1, g_local_refs); |
| 86 EXPECT_EQ(0, g_global_refs); |
| 87 |
| 88 { |
| 89 ScopedJavaGlobalRef<jstring> global_str(str); |
| 90 ScopedJavaGlobalRef<jobject> global_obj(global_str); |
| 91 EXPECT_EQ(1, g_local_refs); |
| 92 EXPECT_EQ(2, g_global_refs); |
| 93 |
| 94 ScopedJavaLocalRef<jstring> str2(&counting_env, str.Release()); |
| 95 EXPECT_EQ(1, g_local_refs); |
| 96 { |
| 97 ScopedJavaLocalRef<jstring> str3(str2); |
| 98 EXPECT_EQ(2, g_local_refs); |
| 99 } |
| 100 EXPECT_EQ(1, g_local_refs); |
| 101 str2.Reset(); |
| 102 EXPECT_EQ(0, g_local_refs); |
| 103 global_str.Reset(); |
| 104 EXPECT_EQ(1, g_global_refs); |
| 105 ScopedJavaGlobalRef<jobject> global_obj2(global_obj); |
| 106 EXPECT_EQ(2, g_global_refs); |
| 107 } |
| 108 |
| 109 EXPECT_EQ(0, g_local_refs); |
| 110 EXPECT_EQ(0, g_global_refs); |
| 111 } |
| 112 |
| 113 } // namespace android |
| 114 } // namespace base |
OLD | NEW |