summaryrefslogtreecommitdiffstats
path: root/base/android
diff options
context:
space:
mode:
authorjoth@chromium.org <joth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-09 10:17:35 +0000
committerjoth@chromium.org <joth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-09 10:17:35 +0000
commitf98d7b97c373ad9d65cc102f19acdc43ec3da604 (patch)
treeca11bd5920735238b4fd4b6e62585e81ec39b020 /base/android
parentf2b7e994d1f0b4c12d91e7e93f6e617c318f062e (diff)
downloadchromium_src-f98d7b97c373ad9d65cc102f19acdc43ec3da604.zip
chromium_src-f98d7b97c373ad9d65cc102f19acdc43ec3da604.tar.gz
chromium_src-f98d7b97c373ad9d65cc102f19acdc43ec3da604.tar.bz2
Refactor ScopedJavaRef
- introduces JavaRef<> base class to allow passing refs without knowledge of their scope - makes the ScopedJavaLocalRef and ScopedJavaGlobalRef consistent, in name, in methods available, and in conversions allowed. Also updates some other minor base API changes whilst I'm in those files. BUG= TEST=doesn't break build... Review URL: http://codereview.chromium.org/7828084 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@100383 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/android')
-rw-r--r--base/android/jni_android.cc10
-rw-r--r--base/android/jni_android.h7
-rw-r--r--base/android/jni_array.cc44
-rw-r--r--base/android/jni_array.h3
-rw-r--r--base/android/jni_string.cc13
-rw-r--r--base/android/jni_string.h3
-rw-r--r--base/android/path_utils.cc6
-rw-r--r--base/android/scoped_java_global_reference.h63
-rw-r--r--base/android/scoped_java_ref.cc47
-rw-r--r--base/android/scoped_java_ref.h175
-rw-r--r--base/android/scoped_java_ref_unittest.cc114
-rw-r--r--base/android/scoped_java_reference.h69
12 files changed, 396 insertions, 158 deletions
diff --git a/base/android/jni_android.cc b/base/android/jni_android.cc
index 9c655ac..1dc02af 100644
--- a/base/android/jni_android.cc
+++ b/base/android/jni_android.cc
@@ -56,6 +56,16 @@ jmethodID GetMethodID(JNIEnv* env,
return id;
}
+jmethodID GetStaticMethodID(JNIEnv* env,
+ jclass clazz,
+ const char* const method,
+ const char* const jni_signature) {
+ jmethodID id = env->GetStaticMethodID(clazz, method, jni_signature);
+ DCHECK(id) << method;
+ CheckException(env);
+ return id;
+}
+
bool CheckException(JNIEnv* env) {
if (env->ExceptionCheck() == JNI_FALSE)
return false;
diff --git a/base/android/jni_android.h b/base/android/jni_android.h
index 9a15895..66b3134 100644
--- a/base/android/jni_android.h
+++ b/base/android/jni_android.h
@@ -37,6 +37,13 @@ jmethodID GetMethodID(JNIEnv* env,
const char* const method,
const char* const jni_signature);
+// Get the method ID for a class static method. Will clear the pending Java
+// exception and return 0 if the method is not found.
+jmethodID GetStaticMethodID(JNIEnv* env,
+ jclass clazz,
+ const char* const method,
+ const char* const jni_signature);
+
// Returns true if an exception is pending in the provided JNIEnv*.
// If an exception is pending, it is printed.
bool CheckException(JNIEnv* env);
diff --git a/base/android/jni_array.cc b/base/android/jni_array.cc
index 409b44a..08cb42e 100644
--- a/base/android/jni_array.cc
+++ b/base/android/jni_array.cc
@@ -5,7 +5,8 @@
#include "base/android/jni_array.h"
#include "base/android/jni_android.h"
-#include "base/android/scoped_java_reference.h"
+#include "base/android/jni_string.h"
+#include "base/android/scoped_java_ref.h"
#include "base/logging.h"
namespace base {
@@ -15,12 +16,10 @@ jbyteArray ToJavaByteArray(JNIEnv* env,
const unsigned char* bytes,
size_t len) {
jbyteArray byte_array = env->NewByteArray(len);
- if (!byte_array) {
- return NULL;
- }
+ CheckException(env);
+ CHECK(byte_array);
jbyte* elements = env->GetByteArrayElements(byte_array, NULL);
- DCHECK(elements);
memcpy(elements, bytes, len);
env->ReleaseByteArrayElements(byte_array, elements, 0);
CheckException(env);
@@ -30,24 +29,33 @@ jbyteArray ToJavaByteArray(JNIEnv* env,
jobjectArray ToJavaArrayOfByteArray(JNIEnv* env,
const std::vector<std::string>& v) {
- size_t count = v.size();
- DCHECK_GT(count, 0U);
- jclass byte_array_class = env->FindClass("[B");
- jobjectArray joa = env->NewObjectArray(count, byte_array_class, NULL);
- if (joa == NULL)
- return NULL;
-
- for (size_t i = 0; i < count; ++i) {
- ScopedJavaReference<jobject> byte_array(env, ToJavaByteArray(env,
+ ScopedJavaLocalRef<jclass> byte_array_clazz(env, env->FindClass("[B"));
+ jobjectArray joa = env->NewObjectArray(v.size(),
+ byte_array_clazz.obj(), NULL);
+ CheckException(env);
+
+ for (size_t i = 0; i < v.size(); ++i) {
+ ScopedJavaLocalRef<jobject> byte_array(env, ToJavaByteArray(env,
reinterpret_cast<const uint8*>(v[i].data()), v[i].length()));
- if (!byte_array.obj()) {
- env->DeleteLocalRef(joa);
- return NULL;
- }
env->SetObjectArrayElement(joa, i, byte_array.obj());
}
return joa;
}
+jobjectArray ToJavaArrayOfStrings(JNIEnv* env,
+ const std::vector<std::string>& v) {
+ ScopedJavaLocalRef<jclass> string_clazz(env,
+ env->FindClass("java/lang/String"));
+ jobjectArray joa = env->NewObjectArray(v.size(), string_clazz.obj(), NULL);
+ CheckException(env);
+
+ for (size_t i = 0; i < v.size(); ++i) {
+ ScopedJavaLocalRef<jstring> item(env,
+ ConvertUTF8ToJavaString(env, v[i]));
+ env->SetObjectArrayElement(joa, i, item.obj());
+ }
+ return joa;
+}
+
} // namespace android
} // namespace base
diff --git a/base/android/jni_array.h b/base/android/jni_array.h
index e3b0194..edf05c6 100644
--- a/base/android/jni_array.h
+++ b/base/android/jni_array.h
@@ -19,6 +19,9 @@ jbyteArray ToJavaByteArray(JNIEnv* env, const unsigned char* bytes, size_t len);
jobjectArray ToJavaArrayOfByteArray(JNIEnv* env,
const std::vector<std::string>& v);
+jobjectArray ToJavaArrayOfStrings(JNIEnv* env,
+ const std::vector<std::string>& v);
+
} // namespace android
} // namespace base
diff --git a/base/android/jni_string.cc b/base/android/jni_string.cc
index 3f3ba82..26e7114 100644
--- a/base/android/jni_string.cc
+++ b/base/android/jni_string.cc
@@ -17,10 +17,15 @@ std::string ConvertJavaStringToUTF8(JNIEnv* env, jstring str) {
return UTF16ToUTF8(ConvertJavaStringToUTF16(env, str));
}
-jstring ConvertUTF8ToJavaString(JNIEnv* env, const std::string& str) {
- jstring result = env->NewStringUTF(str.c_str());
- CheckException(env);
- return result;
+jstring ConvertUTF8ToJavaString(JNIEnv* env, const base::StringPiece& str) {
+ // JNI's NewStringUTF expects "modified" UTF8 so instead create the string
+ // via our own UTF16 conversion utility.
+ // Further, Dalvik requires the string passed into NewStringUTF() to come from
+ // a trusted source. We can't guarantee that all UTF8 will be sanitized before
+ // it gets here, so constructing via UTF16 side-steps this issue.
+ // (Dalvik stores strings internally as UTF16 anyway, so there shouldn't be
+ // a significant performance hit by doing it this way).
+ return ConvertUTF16ToJavaString(env, UTF8ToUTF16(str));
}
string16 ConvertJavaStringToUTF16(JNIEnv* env, jstring str) {
diff --git a/base/android/jni_string.h b/base/android/jni_string.h
index 7e45154..bb902d1 100644
--- a/base/android/jni_string.h
+++ b/base/android/jni_string.h
@@ -9,6 +9,7 @@
#include <string>
#include "base/string16.h"
+#include "base/string_piece.h"
namespace base {
namespace android {
@@ -17,7 +18,7 @@ namespace android {
std::string ConvertJavaStringToUTF8(JNIEnv* env, jstring str);
// Convert a std string to Java string.
-jstring ConvertUTF8ToJavaString(JNIEnv* env, const std::string& str);
+jstring ConvertUTF8ToJavaString(JNIEnv* env, const base::StringPiece& str);
// Convert a Java string to UTF16. Returns a string16.
string16 ConvertJavaStringToUTF16(JNIEnv* env, jstring str);
diff --git a/base/android/path_utils.cc b/base/android/path_utils.cc
index 623e030..dc45c28 100644
--- a/base/android/path_utils.cc
+++ b/base/android/path_utils.cc
@@ -6,7 +6,7 @@
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
-#include "base/android/scoped_java_reference.h"
+#include "base/android/scoped_java_ref.h"
#include "jni/path_utils_jni.h"
@@ -15,14 +15,14 @@ namespace android {
std::string GetDataDirectory() {
JNIEnv* env = AttachCurrentThread();
- ScopedJavaReference<jstring> path(env, Java_PathUtils_getDataDirectory(
+ ScopedJavaLocalRef<jstring> path(env, Java_PathUtils_getDataDirectory(
env, base::android::GetApplicationContext()));
return base::android::ConvertJavaStringToUTF8(env, path.obj());
}
std::string GetCacheDirectory() {
JNIEnv* env = AttachCurrentThread();
- ScopedJavaReference<jstring> path(env, Java_PathUtils_getCacheDirectory(
+ ScopedJavaLocalRef<jstring> path(env, Java_PathUtils_getCacheDirectory(
env, base::android::GetApplicationContext()));
return base::android::ConvertJavaStringToUTF8(env, path.obj());
}
diff --git a/base/android/scoped_java_global_reference.h b/base/android/scoped_java_global_reference.h
deleted file mode 100644
index a5f33f0..0000000
--- a/base/android/scoped_java_global_reference.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_ANDROID_SCOPED_JAVA_GLOBAL_REFERENCE_H_
-#define BASE_ANDROID_SCOPED_JAVA_GLOBAL_REFERENCE_H_
-
-#include <jni.h>
-#include <stddef.h>
-
-#include "base/android/scoped_java_reference.h"
-#include "base/basictypes.h"
-
-namespace base {
-namespace android {
-
-// Holds a global reference to a Java object. The global reference is scoped
-// to the lifetime of this object. Note that since a JNI Env is only suitable
-// for use on a single thread, objects of this class must be created, used and
-// destroyed on the same thread.
-template<typename T>
-class ScopedJavaGlobalReference {
- public:
- // Holds a NULL reference.
- ScopedJavaGlobalReference()
- : env_(NULL),
- obj_(NULL) {
- }
- // Takes a new global reference to the Java object held by obj.
- explicit ScopedJavaGlobalReference(const ScopedJavaReference<T>& obj)
- : env_(obj.env()),
- obj_(static_cast<T>(obj.env()->NewGlobalRef(obj.obj()))) {
- }
- ~ScopedJavaGlobalReference() {
- Reset();
- }
-
- void Reset() {
- if (env_ && obj_)
- env_->DeleteGlobalRef(obj_);
- env_ = NULL;
- obj_ = NULL;
- }
- void Reset(const ScopedJavaGlobalReference& other) {
- Reset();
- env_ = other.env_;
- obj_ = other.env_ ? static_cast<T>(other.env_->NewGlobalRef(other.obj_)) :
- NULL;
- }
-
- T obj() const { return obj_; }
-
- private:
- JNIEnv* env_;
- T obj_;
-
- DISALLOW_COPY_AND_ASSIGN(ScopedJavaGlobalReference);
-};
-
-} // namespace android
-} // namespace base
-
-#endif // BASE_ANDROID_SCOPED_JAVA_GLOBAL_REFERENCE_H_
diff --git a/base/android/scoped_java_ref.cc b/base/android/scoped_java_ref.cc
new file mode 100644
index 0000000..da932f8
--- /dev/null
+++ b/base/android/scoped_java_ref.cc
@@ -0,0 +1,47 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/android/scoped_java_ref.h"
+
+namespace base {
+namespace android {
+
+JavaRef<jobject>::JavaRef() : env_(NULL), obj_(NULL) {}
+
+JavaRef<jobject>::JavaRef(JNIEnv* env, jobject obj)
+ : env_(env),
+ obj_(obj) {
+ DCHECK_EQ(JNILocalRefType, env->GetObjectRefType(obj));
+}
+
+JavaRef<jobject>::~JavaRef() {
+}
+
+void JavaRef<jobject>::SetNewLocalRef(JNIEnv* env, jobject obj) {
+ if (obj)
+ obj = env->NewLocalRef(obj);
+ if (obj_)
+ env_->DeleteLocalRef(obj_);
+ env_ = env;
+ obj_ = obj;
+}
+
+void JavaRef<jobject>::SetNewGlobalRef(JNIEnv* env, jobject obj) {
+ if (obj)
+ obj = env->NewGlobalRef(obj);
+ if (obj_)
+ env_->DeleteGlobalRef(obj_);
+ env_ = env;
+ obj_ = obj;
+}
+
+jobject JavaRef<jobject>::ReleaseInternal() {
+ jobject obj = obj_;
+ env_ = NULL;
+ obj_ = NULL;
+ return obj;
+}
+
+} // namespace android
+} // namespace base
diff --git a/base/android/scoped_java_ref.h b/base/android/scoped_java_ref.h
new file mode 100644
index 0000000..a74cef7
--- /dev/null
+++ b/base/android/scoped_java_ref.h
@@ -0,0 +1,175 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_ANDROID_SCOPED_JAVA_REF_H_
+#define BASE_ANDROID_SCOPED_JAVA_REF_H_
+
+#include <jni.h>
+#include <stddef.h>
+
+#include "base/logging.h"
+
+namespace base {
+namespace android {
+
+// Forward declare the generic java reference template class.
+template<typename T> class JavaRef;
+
+// Template specialization of JavaRef, which acts as the base class for all
+// other JavaRef<> template types. This allows you to e.g. pass
+// ScopedJavaLocalRef<jstring> into a function taking const JavaRef<jobject>&
+template<>
+class JavaRef<jobject> {
+ public:
+ JNIEnv* env() const { return env_; }
+ jobject obj() const { return obj_; }
+
+ protected:
+ // Initializes a NULL reference.
+ JavaRef();
+
+ // Takes ownership of the |obj| reference passed; requires it to be a local
+ // reference type.
+ JavaRef(JNIEnv* env, jobject obj);
+
+ ~JavaRef();
+
+ // The following are implementation detail convenience methods, for
+ // use by the sub-classes.
+ void SetNewLocalRef(JNIEnv* env, jobject obj);
+ void SetNewGlobalRef(JNIEnv* env, jobject obj);
+ jobject ReleaseInternal();
+
+ private:
+ JNIEnv* env_;
+ jobject obj_;
+
+ DISALLOW_COPY_AND_ASSIGN(JavaRef);
+};
+
+// Generic base class for ScopedJavaLocalRef and ScopedJavaGlobalRef. Useful
+// for allowing functions to accept a reference without having to mandate
+// whether it is a local or global type.
+template<typename T>
+class JavaRef : public JavaRef<jobject> {
+ public:
+ T obj() const { return static_cast<T>(JavaRef<jobject>::obj()); }
+
+ protected:
+ JavaRef() {}
+ ~JavaRef() {}
+
+ JavaRef(JNIEnv* env, T obj) : JavaRef<jobject>(env, obj) {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(JavaRef);
+};
+
+// Holds a local reference to a Java object. The local reference is scoped
+// to the lifetime of this object. Note that since a JNI Env is only suitable
+// for use on a single thread, objects of this class must be created, used and
+// destroyed on the same thread.
+// In general, this class should only be used as a stack-based object. If you
+// wish to have the reference outlive the current callstack (e.g. as a class
+// member) use ScopedJavaGlobalRef instead.
+template<typename T>
+class ScopedJavaLocalRef : public JavaRef<T> {
+ public:
+ ScopedJavaLocalRef() {}
+
+ // Non-explicit copy constructor, to allow ScopedJavaLocalRef to be returned
+ // by value as this is the normal usage pattern.
+ ScopedJavaLocalRef(const ScopedJavaLocalRef<T>& other) {
+ this->Reset(other);
+ }
+
+ template<typename U>
+ explicit ScopedJavaLocalRef(const U& other) {
+ this->Reset(other);
+ }
+
+ // Assumes that |obj| is a local reference to a Java object and takes
+ // ownership of this local reference.
+ ScopedJavaLocalRef(JNIEnv* env, T obj) : JavaRef<T>(env, obj) {}
+
+ ~ScopedJavaLocalRef() {
+ this->Reset();
+ }
+
+ // Overloaded assignment operator defined for consistency with the implicit
+ // copy constructor.
+ void operator=(const ScopedJavaLocalRef<T>& other) {
+ this->Reset(other);
+ }
+
+ void Reset() {
+ this->SetNewLocalRef(NULL, NULL);
+ }
+
+ template<typename U>
+ void Reset(const U& other) {
+ this->Reset(other.env(), other.obj());
+ }
+
+ template<typename U>
+ void Reset(JNIEnv* env, U obj) {
+ implicit_cast<T>(obj); // Ensure U is assignable to T
+ this->SetNewLocalRef(env, obj);
+ }
+
+ // Releases the local reference to the caller. The caller *must* delete the
+ // local reference when it is done with it.
+ T Release() {
+ return static_cast<T>(this->ReleaseInternal());
+ }
+};
+
+// Holds a global reference to a Java object. The global reference is scoped
+// to the lifetime of this object. Note that since a JNI Env is only suitable
+// for use on a single thread, objects of this class must be created, used and
+// destroyed on the same thread.
+template<typename T>
+class ScopedJavaGlobalRef : public JavaRef<T> {
+ public:
+ ScopedJavaGlobalRef() {}
+
+ explicit ScopedJavaGlobalRef(const ScopedJavaGlobalRef<T>& other) {
+ this->Reset(other);
+ }
+
+ template<typename U>
+ explicit ScopedJavaGlobalRef(const U& other) {
+ this->Reset(other);
+ }
+
+ ~ScopedJavaGlobalRef() {
+ this->Reset();
+ }
+
+ void Reset() {
+ this->SetNewGlobalRef(NULL, NULL);
+ }
+
+ template<typename U>
+ void Reset(const U& other) {
+ this->Reset(other.env(), other.obj());
+ }
+
+ template<typename U>
+ void Reset(JNIEnv* env, U obj) {
+ implicit_cast<T>(obj); // Ensure U is assignable to T
+ this->SetNewGlobalRef(env, obj);
+ }
+
+ // Releases the global reference to the caller. The caller *must* delete the
+ // global reference when it is done with it.
+ T Release() {
+ return static_cast<T>(this->ReleaseInternal());
+ }
+};
+
+} // namespace android
+} // namespace base
+
+#endif // BASE_ANDROID_SCOPED_JAVA_REF_H_
diff --git a/base/android/scoped_java_ref_unittest.cc b/base/android/scoped_java_ref_unittest.cc
new file mode 100644
index 0000000..a6dfc7a
--- /dev/null
+++ b/base/android/scoped_java_ref_unittest.cc
@@ -0,0 +1,114 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/android/scoped_java_ref.h"
+
+#include "base/android/jni_android.h"
+#include "base/android/jni_string.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace base {
+namespace android {
+
+namespace {
+int g_local_refs = 0;
+int g_global_refs = 0;
+
+jobject NewGlobalRef(JNIEnv* env, jobject obj) {
+ ++g_global_refs;
+ return AttachCurrentThread()->NewGlobalRef(obj);
+}
+
+void DeleteGlobalRef(JNIEnv* env, jobject obj) {
+ --g_global_refs;
+ return AttachCurrentThread()->DeleteGlobalRef(obj);
+}
+
+jobject NewLocalRef(JNIEnv* env, jobject obj) {
+ ++g_local_refs;
+ return AttachCurrentThread()->NewLocalRef(obj);
+}
+
+void DeleteLocalRef(JNIEnv* env, jobject obj) {
+ --g_local_refs;
+ return AttachCurrentThread()->DeleteLocalRef(obj);
+}
+} // namespace
+
+class ScopedJavaRefTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ g_local_refs = 0;
+ g_global_refs = 0;
+ JNIEnv* env = AttachCurrentThread();
+ counting_env = *env;
+ counting_functions = *counting_env.functions;
+ counting_functions.NewGlobalRef = &NewGlobalRef;
+ counting_functions.DeleteGlobalRef = &DeleteGlobalRef;
+ counting_functions.NewLocalRef = &NewLocalRef;
+ counting_functions.DeleteLocalRef = &DeleteLocalRef;
+ counting_env.functions = &counting_functions;
+ }
+
+ // Special JNI env configured in SetUp to count in and out all local & global
+ // reference instances. Be careful to only use this with the ScopedJavaRef
+ // classes under test, else it's easy to get system references counted in
+ // here too.
+ JNIEnv counting_env;
+ JNINativeInterface counting_functions;
+};
+
+// The main purpose of this is testing the various conversions compile.
+TEST_F(ScopedJavaRefTest, Conversions) {
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jstring> str(env, ConvertUTF8ToJavaString(env, "string"));
+ ScopedJavaGlobalRef<jstring> global(str);
+ {
+ ScopedJavaGlobalRef<jobject> global_obj(str);
+ ScopedJavaLocalRef<jobject> local_obj(global);
+ const JavaRef<jobject>& obj_ref1(str);
+ const JavaRef<jobject>& obj_ref2(global);
+ EXPECT_TRUE(env->IsSameObject(obj_ref1.obj(), obj_ref2.obj()));
+ EXPECT_TRUE(env->IsSameObject(global_obj.obj(), obj_ref2.obj()));
+ }
+ global.Reset(str);
+ const JavaRef<jstring>& str_ref = str;
+ EXPECT_EQ("string", ConvertJavaStringToUTF8(env, str_ref.obj()));
+ str.Reset();
+}
+
+TEST_F(ScopedJavaRefTest, RefCounts) {
+ ScopedJavaLocalRef<jstring> str;
+ str.Reset(&counting_env, ConvertUTF8ToJavaString(AttachCurrentThread(),
+ "string"));
+ EXPECT_EQ(1, g_local_refs);
+ EXPECT_EQ(0, g_global_refs);
+
+ {
+ ScopedJavaGlobalRef<jstring> global_str(str);
+ ScopedJavaGlobalRef<jobject> global_obj(global_str);
+ EXPECT_EQ(1, g_local_refs);
+ EXPECT_EQ(2, g_global_refs);
+
+ ScopedJavaLocalRef<jstring> str2(&counting_env, str.Release());
+ EXPECT_EQ(1, g_local_refs);
+ {
+ ScopedJavaLocalRef<jstring> str3(str2);
+ EXPECT_EQ(2, g_local_refs);
+ }
+ EXPECT_EQ(1, g_local_refs);
+ str2.Reset();
+ EXPECT_EQ(0, g_local_refs);
+ global_str.Reset();
+ EXPECT_EQ(1, g_global_refs);
+ ScopedJavaGlobalRef<jobject> global_obj2(global_obj);
+ EXPECT_EQ(2, g_global_refs);
+ }
+
+ EXPECT_EQ(0, g_local_refs);
+ EXPECT_EQ(0, g_global_refs);
+}
+
+} // namespace android
+} // namespace base
diff --git a/base/android/scoped_java_reference.h b/base/android/scoped_java_reference.h
deleted file mode 100644
index 70e8610..0000000
--- a/base/android/scoped_java_reference.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_ANDROID_SCOPED_JAVA_REFERENCE_H_
-#define BASE_ANDROID_SCOPED_JAVA_REFERENCE_H_
-
-#include <jni.h>
-#include <stddef.h>
-
-namespace base {
-namespace android {
-
-// Holds a local reference to a Java object. The local reference is scoped
-// to the lifetime of this object. Note that since a JNI Env is only suitable
-// for use on a single thread, objects of this class must be created, used and
-// destroyed on the same thread.
-template<typename T>
-class ScopedJavaReference {
- public:
- // Holds a NULL reference.
- ScopedJavaReference()
- : env_(NULL),
- obj_(NULL) {
- }
- // Assumes that obj is a local reference to a Java object and takes ownership
- // of this local reference.
- ScopedJavaReference(JNIEnv* env, T obj)
- : env_(env),
- obj_(obj) {
- }
- // Takes a new local reference to the Java object held by other.
- ScopedJavaReference(const ScopedJavaReference& other)
- : env_(other.env_),
- obj_(other.obj_ ? static_cast<T>(other.env_->NewLocalRef(other.obj_)) :
- NULL) {
- }
- ~ScopedJavaReference() {
- if (obj_)
- env_->DeleteLocalRef(obj_);
- }
-
- void operator=(const ScopedJavaReference& other) {
- if (obj_)
- env_->DeleteLocalRef(obj_);
- env_ = other.env_;
- obj_ = other.obj_ ? static_cast<T>(env_->NewLocalRef(other.obj_)) : NULL;
- }
-
- JNIEnv* env() const { return env_; }
- T obj() const { return obj_; }
-
- // Releases the local reference to the caller. The caller *must* delete the
- // local reference when it is done with it.
- T Release() {
- jobject obj = obj_;
- obj_ = NULL;
- return obj;
- }
-
- private:
- JNIEnv* env_;
- T obj_;
-};
-
-} // namespace android
-} // namespace base
-
-#endif // BASE_ANDROID_SCOPED_JAVA_REFERENCE_H_