| OLD | NEW |
| (Empty) |
| 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 #ifndef BASE_ANDROID_SCOPED_JAVA_REF_H_ | |
| 6 #define BASE_ANDROID_SCOPED_JAVA_REF_H_ | |
| 7 | |
| 8 #include <jni.h> | |
| 9 #include <stddef.h> | |
| 10 | |
| 11 #include "base/base_export.h" | |
| 12 #include "base/basictypes.h" | |
| 13 | |
| 14 namespace base { | |
| 15 namespace android { | |
| 16 | |
| 17 // Creates a new local reference frame, in which at least a given number of | |
| 18 // local references can be created. Note that local references already created | |
| 19 // in previous local frames are still valid in the current local frame. | |
| 20 class BASE_EXPORT ScopedJavaLocalFrame { | |
| 21 public: | |
| 22 explicit ScopedJavaLocalFrame(JNIEnv* env); | |
| 23 ScopedJavaLocalFrame(JNIEnv* env, int capacity); | |
| 24 ~ScopedJavaLocalFrame(); | |
| 25 | |
| 26 private: | |
| 27 // This class is only good for use on the thread it was created on so | |
| 28 // it's safe to cache the non-threadsafe JNIEnv* inside this object. | |
| 29 JNIEnv* env_; | |
| 30 | |
| 31 DISALLOW_COPY_AND_ASSIGN(ScopedJavaLocalFrame); | |
| 32 }; | |
| 33 | |
| 34 // Forward declare the generic java reference template class. | |
| 35 template<typename T> class JavaRef; | |
| 36 | |
| 37 // Template specialization of JavaRef, which acts as the base class for all | |
| 38 // other JavaRef<> template types. This allows you to e.g. pass | |
| 39 // ScopedJavaLocalRef<jstring> into a function taking const JavaRef<jobject>& | |
| 40 template<> | |
| 41 class BASE_EXPORT JavaRef<jobject> { | |
| 42 public: | |
| 43 jobject obj() const { return obj_; } | |
| 44 | |
| 45 bool is_null() const { return obj_ == NULL; } | |
| 46 | |
| 47 protected: | |
| 48 // Initializes a NULL reference. | |
| 49 JavaRef(); | |
| 50 | |
| 51 // Takes ownership of the |obj| reference passed; requires it to be a local | |
| 52 // reference type. | |
| 53 JavaRef(JNIEnv* env, jobject obj); | |
| 54 | |
| 55 ~JavaRef(); | |
| 56 | |
| 57 // The following are implementation detail convenience methods, for | |
| 58 // use by the sub-classes. | |
| 59 JNIEnv* SetNewLocalRef(JNIEnv* env, jobject obj); | |
| 60 void SetNewGlobalRef(JNIEnv* env, jobject obj); | |
| 61 void ResetLocalRef(JNIEnv* env); | |
| 62 void ResetGlobalRef(); | |
| 63 jobject ReleaseInternal(); | |
| 64 | |
| 65 private: | |
| 66 jobject obj_; | |
| 67 | |
| 68 DISALLOW_COPY_AND_ASSIGN(JavaRef); | |
| 69 }; | |
| 70 | |
| 71 // Generic base class for ScopedJavaLocalRef and ScopedJavaGlobalRef. Useful | |
| 72 // for allowing functions to accept a reference without having to mandate | |
| 73 // whether it is a local or global type. | |
| 74 template<typename T> | |
| 75 class JavaRef : public JavaRef<jobject> { | |
| 76 public: | |
| 77 T obj() const { return static_cast<T>(JavaRef<jobject>::obj()); } | |
| 78 | |
| 79 protected: | |
| 80 JavaRef() {} | |
| 81 ~JavaRef() {} | |
| 82 | |
| 83 JavaRef(JNIEnv* env, T obj) : JavaRef<jobject>(env, obj) {} | |
| 84 | |
| 85 private: | |
| 86 DISALLOW_COPY_AND_ASSIGN(JavaRef); | |
| 87 }; | |
| 88 | |
| 89 // Holds a local reference to a Java object. The local reference is scoped | |
| 90 // to the lifetime of this object. | |
| 91 // Instances of this class may hold onto any JNIEnv passed into it until | |
| 92 // destroyed. Therefore, since a JNIEnv is only suitable for use on a single | |
| 93 // thread, objects of this class must be created, used, and destroyed, on a | |
| 94 // single thread. | |
| 95 // Therefore, this class should only be used as a stack-based object and from a | |
| 96 // single thread. If you wish to have the reference outlive the current | |
| 97 // callstack (e.g. as a class member) or you wish to pass it across threads, | |
| 98 // use a ScopedJavaGlobalRef instead. | |
| 99 template<typename T> | |
| 100 class ScopedJavaLocalRef : public JavaRef<T> { | |
| 101 public: | |
| 102 ScopedJavaLocalRef() : env_(NULL) {} | |
| 103 | |
| 104 // Non-explicit copy constructor, to allow ScopedJavaLocalRef to be returned | |
| 105 // by value as this is the normal usage pattern. | |
| 106 ScopedJavaLocalRef(const ScopedJavaLocalRef<T>& other) | |
| 107 : env_(other.env_) { | |
| 108 this->SetNewLocalRef(env_, other.obj()); | |
| 109 } | |
| 110 | |
| 111 template<typename U> | |
| 112 explicit ScopedJavaLocalRef(const U& other) | |
| 113 : env_(NULL) { | |
| 114 this->Reset(other); | |
| 115 } | |
| 116 | |
| 117 // Assumes that |obj| is a local reference to a Java object and takes | |
| 118 // ownership of this local reference. | |
| 119 ScopedJavaLocalRef(JNIEnv* env, T obj) : JavaRef<T>(env, obj), env_(env) {} | |
| 120 | |
| 121 ~ScopedJavaLocalRef() { | |
| 122 this->Reset(); | |
| 123 } | |
| 124 | |
| 125 // Overloaded assignment operator defined for consistency with the implicit | |
| 126 // copy constructor. | |
| 127 void operator=(const ScopedJavaLocalRef<T>& other) { | |
| 128 this->Reset(other); | |
| 129 } | |
| 130 | |
| 131 void Reset() { | |
| 132 this->ResetLocalRef(env_); | |
| 133 } | |
| 134 | |
| 135 template<typename U> | |
| 136 void Reset(const ScopedJavaLocalRef<U>& other) { | |
| 137 // We can copy over env_ here as |other| instance must be from the same | |
| 138 // thread as |this| local ref. (See class comment for multi-threading | |
| 139 // limitations, and alternatives). | |
| 140 this->Reset(other.env_, other.obj()); | |
| 141 } | |
| 142 | |
| 143 template<typename U> | |
| 144 void Reset(const U& other) { | |
| 145 // If |env_| was not yet set (is still NULL) it will be attached to the | |
| 146 // current thread in SetNewLocalRef(). | |
| 147 this->Reset(env_, other.obj()); | |
| 148 } | |
| 149 | |
| 150 template<typename U> | |
| 151 void Reset(JNIEnv* env, U obj) { | |
| 152 implicit_cast<T>(obj); // Ensure U is assignable to T | |
| 153 env_ = this->SetNewLocalRef(env, obj); | |
| 154 } | |
| 155 | |
| 156 // Releases the local reference to the caller. The caller *must* delete the | |
| 157 // local reference when it is done with it. | |
| 158 T Release() { | |
| 159 return static_cast<T>(this->ReleaseInternal()); | |
| 160 } | |
| 161 | |
| 162 private: | |
| 163 // This class is only good for use on the thread it was created on so | |
| 164 // it's safe to cache the non-threadsafe JNIEnv* inside this object. | |
| 165 JNIEnv* env_; | |
| 166 }; | |
| 167 | |
| 168 // Holds a global reference to a Java object. The global reference is scoped | |
| 169 // to the lifetime of this object. This class does not hold onto any JNIEnv* | |
| 170 // passed to it, hence it is safe to use across threads (within the constraints | |
| 171 // imposed by the underlying Java object that it references). | |
| 172 template<typename T> | |
| 173 class ScopedJavaGlobalRef : public JavaRef<T> { | |
| 174 public: | |
| 175 ScopedJavaGlobalRef() {} | |
| 176 | |
| 177 explicit ScopedJavaGlobalRef(const ScopedJavaGlobalRef<T>& other) { | |
| 178 this->Reset(other); | |
| 179 } | |
| 180 | |
| 181 ScopedJavaGlobalRef(JNIEnv* env, T obj) { this->Reset(env, obj); } | |
| 182 | |
| 183 template<typename U> | |
| 184 explicit ScopedJavaGlobalRef(const U& other) { | |
| 185 this->Reset(other); | |
| 186 } | |
| 187 | |
| 188 ~ScopedJavaGlobalRef() { | |
| 189 this->Reset(); | |
| 190 } | |
| 191 | |
| 192 void Reset() { | |
| 193 this->ResetGlobalRef(); | |
| 194 } | |
| 195 | |
| 196 template<typename U> | |
| 197 void Reset(const U& other) { | |
| 198 this->Reset(NULL, other.obj()); | |
| 199 } | |
| 200 | |
| 201 template<typename U> | |
| 202 void Reset(JNIEnv* env, U obj) { | |
| 203 implicit_cast<T>(obj); // Ensure U is assignable to T | |
| 204 this->SetNewGlobalRef(env, obj); | |
| 205 } | |
| 206 | |
| 207 // Releases the global reference to the caller. The caller *must* delete the | |
| 208 // global reference when it is done with it. | |
| 209 T Release() { | |
| 210 return static_cast<T>(this->ReleaseInternal()); | |
| 211 } | |
| 212 }; | |
| 213 | |
| 214 } // namespace android | |
| 215 } // namespace base | |
| 216 | |
| 217 #endif // BASE_ANDROID_SCOPED_JAVA_REF_H_ | |
| OLD | NEW |