OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/renderer_host/java/java_bound_object.h" | 5 #include "content/browser/renderer_host/java/java_bound_object.h" |
6 | 6 |
7 #include "base/android/jni_android.h" | 7 #include "base/android/jni_android.h" |
8 #include "base/android/jni_string.h" | 8 #include "base/android/jni_string.h" |
9 #include "base/memory/singleton.h" | 9 #include "base/memory/singleton.h" |
10 #include "base/string_number_conversions.h" | 10 #include "base/string_number_conversions.h" |
(...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
581 NPObject* object = NPVARIANT_TO_OBJECT(variant); | 581 NPObject* object = NPVARIANT_TO_OBJECT(variant); |
582 bool is_java_object = &JavaNPObject::kNPClass == object->_class; | 582 bool is_java_object = &JavaNPObject::kNPClass == object->_class; |
583 | 583 |
584 jvalue result; | 584 jvalue result; |
585 switch (target_type.type) { | 585 switch (target_type.type) { |
586 case JavaType::TypeObject: | 586 case JavaType::TypeObject: |
587 if (is_java_object) { | 587 if (is_java_object) { |
588 // LIVECONNECT_COMPLIANCE: Existing behavior is to pass all Java | 588 // LIVECONNECT_COMPLIANCE: Existing behavior is to pass all Java |
589 // objects. Spec requires passing only Java objects which are | 589 // objects. Spec requires passing only Java objects which are |
590 // assignment-compatibile. | 590 // assignment-compatibile. |
591 result.l = AttachCurrentThread()->NewLocalRef( | 591 result.l = JavaBoundObject::GetJavaObject(object); |
joth
2013/01/07 19:32:41
this may now be NULL. Any idea what that might bre
benm (inactive)
2013/01/08 14:43:05
I think this is for the case that during a JS -> j
joth
2013/01/09 00:28:22
Yes. I chatted with sgurun and looks like classic
benm (inactive)
2013/01/09 11:17:00
Happy to add this in a follow up change but just w
benm (inactive)
2013/01/09 14:46:13
For 3, I guess we could remove from the set in Jav
| |
592 JavaBoundObject::GetJavaObject(object)); | |
593 } else { | 592 } else { |
594 // LIVECONNECT_COMPLIANCE: Existing behavior is to pass null. Spec | 593 // LIVECONNECT_COMPLIANCE: Existing behavior is to pass null. Spec |
595 // requires converting if the target type is | 594 // requires converting if the target type is |
596 // netscape.javascript.JSObject, otherwise raising a JavaScript | 595 // netscape.javascript.JSObject, otherwise raising a JavaScript |
597 // exception. | 596 // exception. |
598 result.l = NULL; | 597 result.l = NULL; |
599 } | 598 } |
600 break; | 599 break; |
601 case JavaType::TypeString: | 600 case JavaType::TypeString: |
602 // LIVECONNECT_COMPLIANCE: Existing behavior is to convert to | 601 // LIVECONNECT_COMPLIANCE: Existing behavior is to convert to |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
735 &JavaNPObject::kNPClass)); | 734 &JavaNPObject::kNPClass)); |
736 // The NPObject takes ownership of the JavaBoundObject. | 735 // The NPObject takes ownership of the JavaBoundObject. |
737 reinterpret_cast<JavaNPObject*>(np_object)->bound_object = | 736 reinterpret_cast<JavaNPObject*>(np_object)->bound_object = |
738 new JavaBoundObject(object, safe_annotation_clazz); | 737 new JavaBoundObject(object, safe_annotation_clazz); |
739 return np_object; | 738 return np_object; |
740 } | 739 } |
741 | 740 |
742 JavaBoundObject::JavaBoundObject( | 741 JavaBoundObject::JavaBoundObject( |
743 const JavaRef<jobject>& object, | 742 const JavaRef<jobject>& object, |
744 base::android::JavaRef<jclass>& safe_annotation_clazz) | 743 base::android::JavaRef<jclass>& safe_annotation_clazz) |
745 : java_object_(object), | 744 : java_object_(AttachCurrentThread(), object.obj()), |
746 are_methods_set_up_(false), | 745 are_methods_set_up_(false), |
747 safe_annotation_clazz_(safe_annotation_clazz) { | 746 safe_annotation_clazz_(safe_annotation_clazz) { |
748 // We don't do anything with our Java object when first created. We do it all | 747 // We don't do anything with our Java object when first created. We do it all |
749 // lazily when a method is first invoked. | 748 // lazily when a method is first invoked. |
750 } | 749 } |
751 | 750 |
752 JavaBoundObject::~JavaBoundObject() { | 751 JavaBoundObject::~JavaBoundObject() { |
753 } | 752 } |
754 | 753 |
755 jobject JavaBoundObject::GetJavaObject(NPObject* object) { | 754 jobject JavaBoundObject::GetJavaObject(NPObject* object) { |
756 DCHECK_EQ(&JavaNPObject::kNPClass, object->_class); | 755 DCHECK_EQ(&JavaNPObject::kNPClass, object->_class); |
757 JavaBoundObject* jbo = reinterpret_cast<JavaNPObject*>(object)->bound_object; | 756 JavaBoundObject* jbo = reinterpret_cast<JavaNPObject*>(object)->bound_object; |
758 return jbo->java_object_.obj(); | 757 JNIEnv* env = AttachCurrentThread(); |
758 return env->NewLocalRef(jbo->java_object_.get(env).obj()); | |
759 } | 759 } |
760 | 760 |
761 bool JavaBoundObject::HasMethod(const std::string& name) const { | 761 bool JavaBoundObject::HasMethod(const std::string& name) const { |
762 EnsureMethodsAreSetUp(); | 762 EnsureMethodsAreSetUp(); |
763 return methods_.find(name) != methods_.end(); | 763 return methods_.find(name) != methods_.end(); |
764 } | 764 } |
765 | 765 |
766 bool JavaBoundObject::Invoke(const std::string& name, const NPVariant* args, | 766 bool JavaBoundObject::Invoke(const std::string& name, const NPVariant* args, |
767 size_t arg_count, NPVariant* result) { | 767 size_t arg_count, NPVariant* result) { |
768 EnsureMethodsAreSetUp(); | 768 EnsureMethodsAreSetUp(); |
(...skipping 19 matching lines...) Expand all Loading... | |
788 } | 788 } |
789 | 789 |
790 // Coerce | 790 // Coerce |
791 std::vector<jvalue> parameters(arg_count); | 791 std::vector<jvalue> parameters(arg_count); |
792 for (size_t i = 0; i < arg_count; ++i) { | 792 for (size_t i = 0; i < arg_count; ++i) { |
793 parameters[i] = CoerceJavaScriptValueToJavaValue(args[i], | 793 parameters[i] = CoerceJavaScriptValueToJavaValue(args[i], |
794 method->parameter_type(i), | 794 method->parameter_type(i), |
795 true); | 795 true); |
796 } | 796 } |
797 | 797 |
798 // Call | 798 ScopedJavaLocalRef<jobject> obj = java_object_.get(AttachCurrentThread()); |
799 bool ok = CallJNIMethod(java_object_.obj(), method->return_type(), | 799 |
800 method->id(), ¶meters[0], result, | 800 bool ok = false; |
801 safe_annotation_clazz_); | 801 if (!obj.is_null()) { |
802 // Call | |
803 ok = CallJNIMethod(obj.obj(), method->return_type(), | |
804 method->id(), ¶meters[0], result, | |
805 safe_annotation_clazz_); | |
806 } | |
802 | 807 |
803 // Now that we're done with the jvalue, release any local references created | 808 // Now that we're done with the jvalue, release any local references created |
804 // by CoerceJavaScriptValueToJavaValue(). | 809 // by CoerceJavaScriptValueToJavaValue(). |
805 JNIEnv* env = AttachCurrentThread(); | 810 JNIEnv* env = AttachCurrentThread(); |
806 for (size_t i = 0; i < arg_count; ++i) { | 811 for (size_t i = 0; i < arg_count; ++i) { |
807 ReleaseJavaValueIfRequired(env, ¶meters[i], method->parameter_type(i)); | 812 ReleaseJavaValueIfRequired(env, ¶meters[i], method->parameter_type(i)); |
808 } | 813 } |
809 | 814 |
810 return ok; | 815 return ok; |
811 } | 816 } |
812 | 817 |
813 void JavaBoundObject::EnsureMethodsAreSetUp() const { | 818 void JavaBoundObject::EnsureMethodsAreSetUp() const { |
814 if (are_methods_set_up_) | 819 if (are_methods_set_up_) |
815 return; | 820 return; |
816 are_methods_set_up_ = true; | 821 are_methods_set_up_ = true; |
817 | 822 |
818 JNIEnv* env = AttachCurrentThread(); | 823 JNIEnv* env = AttachCurrentThread(); |
824 ScopedJavaLocalRef<jobject> obj = java_object_.get(env); | |
825 | |
826 DCHECK(!obj.is_null()); | |
joth
2013/01/07 19:32:41
this could happen though. If the java side ophen's
benm (inactive)
2013/01/08 14:43:05
No, I think your first comment is correct. EnsureM
| |
827 | |
819 ScopedJavaLocalRef<jclass> clazz(env, static_cast<jclass>( | 828 ScopedJavaLocalRef<jclass> clazz(env, static_cast<jclass>( |
820 env->CallObjectMethod(java_object_.obj(), GetMethodIDFromClassName( | 829 env->CallObjectMethod(obj.obj(), GetMethodIDFromClassName( |
821 env, | 830 env, |
822 kJavaLangObject, | 831 kJavaLangObject, |
823 kGetClass, | 832 kGetClass, |
824 kReturningJavaLangClass)))); | 833 kReturningJavaLangClass)))); |
825 | 834 |
826 ScopedJavaLocalRef<jobjectArray> methods(env, static_cast<jobjectArray>( | 835 ScopedJavaLocalRef<jobjectArray> methods(env, static_cast<jobjectArray>( |
827 env->CallObjectMethod(clazz.obj(), GetMethodIDFromClassName( | 836 env->CallObjectMethod(clazz.obj(), GetMethodIDFromClassName( |
828 env, | 837 env, |
829 kJavaLangClass, | 838 kJavaLangClass, |
830 kGetMethods, | 839 kGetMethods, |
(...skipping 20 matching lines...) Expand all Loading... | |
851 if (!safe) | 860 if (!safe) |
852 continue; | 861 continue; |
853 } | 862 } |
854 | 863 |
855 JavaMethod* method = new JavaMethod(java_method); | 864 JavaMethod* method = new JavaMethod(java_method); |
856 methods_.insert(std::make_pair(method->name(), method)); | 865 methods_.insert(std::make_pair(method->name(), method)); |
857 } | 866 } |
858 } | 867 } |
859 | 868 |
860 } // namespace content | 869 } // namespace content |
OLD | NEW |