1 // Copyright 2014 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 CONTENT_BROWSER_ANDROID_JAVA_GIN_JAVA_BOUND_OBJECT_H_ 6 #define CONTENT_BROWSER_ANDROID_JAVA_GIN_JAVA_BOUND_OBJECT_H_ 7 8 #include <map> 9 #include <set> 10 11 #include "base/android/jni_weak_ref.h" 12 #include "base/android/scoped_java_ref.h" 13 #include "base/id_map.h" 14 #include "base/memory/linked_ptr.h" 15 #include "base/memory/ref_counted.h" 16 #include "base/memory/weak_ptr.h" 17 #include "base/values.h" 18 #include "content/browser/android/java/java_method.h" 19 20 namespace content { 21 22 class RenderFrameHost; 23 24 class GinJavaBoundObject 25 : public base::RefCountedThreadSafe<GinJavaBoundObject> { 26 public: 27 // Using scoped_refptr<> as a value type is somewhat not IDMap had been 28 // designed for (it returns T* from lookups, so we have to de-ref it), but on 29 // the other hand, this allows us to manage lifetime of GinJavaBoundObject 30 // automatically. 31 typedef IDMap<scoped_refptr<GinJavaBoundObject>, IDMapOwnPointer> ObjectMap; 32 typedef ObjectMap::KeyType ObjectID; 33 34 static GinJavaBoundObject* CreateNamed( 35 const JavaObjectWeakGlobalRef& ref, 36 const base::android::JavaRef<jclass>& safe_annotation_clazz); 37 static GinJavaBoundObject* CreateTransient( 38 const JavaObjectWeakGlobalRef& ref, 39 const base::android::JavaRef<jclass>& safe_annotation_clazz, 40 RenderFrameHost* holder); 41 GetWeakRef()42 JavaObjectWeakGlobalRef& GetWeakRef() { return ref_; } GetLocalRef(JNIEnv * env)43 base::android::ScopedJavaLocalRef<jobject> GetLocalRef(JNIEnv* env) { 44 return ref_.get(env); 45 } 46 IsNamed()47 bool IsNamed() { return names_count_ > 0; } AddName()48 void AddName() { ++names_count_; } RemoveName()49 void RemoveName() { --names_count_; } 50 HasHolders()51 bool HasHolders() { return !holders_.empty(); } AddHolder(RenderFrameHost * holder)52 void AddHolder(RenderFrameHost* holder) { holders_.insert(holder); } RemoveHolder(RenderFrameHost * holder)53 void RemoveHolder(RenderFrameHost* holder) { holders_.erase(holder); } 54 55 // The following methods are called on the background thread. 56 std::set<std::string> GetMethodNames(); 57 bool HasMethod(const std::string& method_name); 58 const JavaMethod* FindMethod(const std::string& method_name, 59 size_t num_parameters); 60 bool IsObjectGetClassMethod(const JavaMethod* method); 61 const base::android::JavaRef<jclass>& GetSafeAnnotationClass(); 62 base::android::ScopedJavaLocalRef<jclass> GetLocalClassRef(JNIEnv* env); 63 64 private: 65 friend class base::RefCountedThreadSafe<GinJavaBoundObject>; 66 67 GinJavaBoundObject( 68 const JavaObjectWeakGlobalRef& ref, 69 const base::android::JavaRef<jclass>& safe_annotation_clazz); 70 GinJavaBoundObject( 71 const JavaObjectWeakGlobalRef& ref, 72 const base::android::JavaRef<jclass>& safe_annotation_clazz, 73 const std::set<RenderFrameHost*> holders); 74 ~GinJavaBoundObject(); 75 76 // The following methods are called on the background thread. 77 void EnsureMethodsAreSetUp(); 78 79 JavaObjectWeakGlobalRef ref_; 80 81 // An object must be kept in retained_object_set_ either if it has 82 // names or if it has a non-empty holders set. 83 int names_count_; 84 std::set<RenderFrameHost*> holders_; 85 86 // The following fields are accessed on the background thread. 87 typedef std::multimap<std::string, linked_ptr<JavaMethod> > JavaMethodMap; 88 JavaMethodMap methods_; 89 jmethodID object_get_class_method_id_; 90 bool are_methods_set_up_; 91 base::android::ScopedJavaGlobalRef<jclass> safe_annotation_clazz_; 92 }; 93 94 } // namespace content 95 96 #endif // CONTENT_BROWSER_ANDROID_JAVA_GIN_JAVA_BOUND_OBJECT_H_ 97