| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 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" |
| 11 #include "base/stringprintf.h" | 11 #include "base/stringprintf.h" |
| 12 #include "content/browser/renderer_host/java/java_type.h" | 12 #include "content/browser/renderer_host/java/java_type.h" |
| 13 #include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h" | 13 #include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h" |
| 14 | 14 |
| 15 using base::StringPrintf; | 15 using base::StringPrintf; |
| 16 using base::android::AttachCurrentThread; | 16 using base::android::AttachCurrentThread; |
| 17 using base::android::ConvertUTF8ToJavaString; | 17 using base::android::ConvertUTF8ToJavaString; |
| 18 using base::android::GetMethodIDFromClassName; |
| 18 using base::android::JavaRef; | 19 using base::android::JavaRef; |
| 19 using base::android::MethodID; | |
| 20 using base::android::ScopedJavaGlobalRef; | 20 using base::android::ScopedJavaGlobalRef; |
| 21 using base::android::ScopedJavaLocalRef; | 21 using base::android::ScopedJavaLocalRef; |
| 22 using WebKit::WebBindings; | 22 using WebKit::WebBindings; |
| 23 | 23 |
| 24 // The conversion between JavaScript and Java types is based on the Live | 24 // The conversion between JavaScript and Java types is based on the Live |
| 25 // Connect 2 spec. See | 25 // Connect 2 spec. See |
| 26 // http://jdk6.java.net/plugin2/liveconnect/#JS_JAVA_CONVERSIONS. | 26 // http://jdk6.java.net/plugin2/liveconnect/#JS_JAVA_CONVERSIONS. |
| 27 | 27 |
| 28 // Note that in some cases, we differ from from the spec in order to maintain | 28 // Note that in some cases, we differ from from the spec in order to maintain |
| 29 // existing behavior. These areas are marked LIVECONNECT_COMPLIANCE. We may | 29 // existing behavior. These areas are marked LIVECONNECT_COMPLIANCE. We may |
| 30 // revisit this decision in the future. | 30 // revisit this decision in the future. |
| 31 | 31 |
| 32 namespace { | 32 namespace { |
| 33 | 33 |
| 34 const char kJavaLangClass[] = "java/lang/Class"; |
| 35 const char kJavaLangObject[] = "java/lang/Object"; |
| 36 const char kGetClass[] = "getClass"; |
| 37 const char kGetMethods[] = "getMethods"; |
| 38 const char kReturningJavaLangClass[] = "()Ljava/lang/Class;"; |
| 39 const char kReturningJavaLangReflectMethodArray[] = |
| 40 "()[Ljava/lang/reflect/Method;"; |
| 41 |
| 34 // Our special NPObject type. We extend an NPObject with a pointer to a | 42 // Our special NPObject type. We extend an NPObject with a pointer to a |
| 35 // JavaBoundObject. We also add static methods for each of the NPObject | 43 // JavaBoundObject. We also add static methods for each of the NPObject |
| 36 // callbacks, which are registered by our NPClass. These methods simply | 44 // callbacks, which are registered by our NPClass. These methods simply |
| 37 // delegate to the private implementation methods of JavaBoundObject. | 45 // delegate to the private implementation methods of JavaBoundObject. |
| 38 struct JavaNPObject : public NPObject { | 46 struct JavaNPObject : public NPObject { |
| 39 JavaBoundObject* bound_object; | 47 JavaBoundObject* bound_object; |
| 40 | 48 |
| 41 static const NPClass kNPClass; | 49 static const NPClass kNPClass; |
| 42 | 50 |
| 43 static NPObject* Allocate(NPP npp, NPClass* np_class); | 51 static NPObject* Allocate(NPP npp, NPClass* np_class); |
| (...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 474 case NPVariantType_Object: | 482 case NPVariantType_Object: |
| 475 return CoerceJavaScriptObjectToJavaValue(variant, target_type); | 483 return CoerceJavaScriptObjectToJavaValue(variant, target_type); |
| 476 case NPVariantType_Null: | 484 case NPVariantType_Null: |
| 477 case NPVariantType_Void: | 485 case NPVariantType_Void: |
| 478 return CoerceJavaScriptNullOrUndefinedToJavaValue(variant, target_type); | 486 return CoerceJavaScriptNullOrUndefinedToJavaValue(variant, target_type); |
| 479 } | 487 } |
| 480 NOTREACHED(); | 488 NOTREACHED(); |
| 481 return jvalue(); | 489 return jvalue(); |
| 482 } | 490 } |
| 483 | 491 |
| 484 class ObjectGetClassID : public MethodID { | |
| 485 public: | |
| 486 static ObjectGetClassID* GetInstance() { | |
| 487 return Singleton<ObjectGetClassID>::get(); | |
| 488 } | |
| 489 private: | |
| 490 friend struct DefaultSingletonTraits<ObjectGetClassID>; | |
| 491 ObjectGetClassID() | |
| 492 : MethodID(AttachCurrentThread(), "java/lang/Object", "getClass", | |
| 493 "()Ljava/lang/Class;") { | |
| 494 } | |
| 495 DISALLOW_COPY_AND_ASSIGN(ObjectGetClassID); | |
| 496 }; | |
| 497 | |
| 498 class ClassGetMethodsID : public MethodID { | |
| 499 public: | |
| 500 static ClassGetMethodsID* GetInstance() { | |
| 501 return Singleton<ClassGetMethodsID>::get(); | |
| 502 } | |
| 503 private: | |
| 504 friend struct DefaultSingletonTraits<ClassGetMethodsID>; | |
| 505 ClassGetMethodsID() | |
| 506 : MethodID(AttachCurrentThread(), "java/lang/Class", "getMethods", | |
| 507 "()[Ljava/lang/reflect/Method;") { | |
| 508 } | |
| 509 DISALLOW_COPY_AND_ASSIGN(ClassGetMethodsID); | |
| 510 }; | |
| 511 | |
| 512 } // namespace | 492 } // namespace |
| 513 | 493 |
| 514 | 494 |
| 515 NPObject* JavaBoundObject::Create(const JavaRef<jobject>& object) { | 495 NPObject* JavaBoundObject::Create(const JavaRef<jobject>& object) { |
| 516 // The first argument (a plugin's instance handle) is passed through to the | 496 // The first argument (a plugin's instance handle) is passed through to the |
| 517 // allocate function directly, and we don't use it, so it's ok to be 0. | 497 // allocate function directly, and we don't use it, so it's ok to be 0. |
| 518 // The object is created with a ref count of one. | 498 // The object is created with a ref count of one. |
| 519 NPObject* np_object = WebBindings::createObject(0, const_cast<NPClass*>( | 499 NPObject* np_object = WebBindings::createObject(0, const_cast<NPClass*>( |
| 520 &JavaNPObject::kNPClass)); | 500 &JavaNPObject::kNPClass)); |
| 521 // The NPObject takes ownership of the JavaBoundObject. | 501 // The NPObject takes ownership of the JavaBoundObject. |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 584 return true; | 564 return true; |
| 585 } | 565 } |
| 586 | 566 |
| 587 void JavaBoundObject::EnsureMethodsAreSetUp() const { | 567 void JavaBoundObject::EnsureMethodsAreSetUp() const { |
| 588 if (!methods_.empty()) { | 568 if (!methods_.empty()) { |
| 589 return; | 569 return; |
| 590 } | 570 } |
| 591 | 571 |
| 592 JNIEnv* env = AttachCurrentThread(); | 572 JNIEnv* env = AttachCurrentThread(); |
| 593 ScopedJavaLocalRef<jclass> clazz(env, static_cast<jclass>( | 573 ScopedJavaLocalRef<jclass> clazz(env, static_cast<jclass>( |
| 594 env->CallObjectMethod(java_object_, | 574 env->CallObjectMethod(java_object_, GetMethodIDFromClassName( |
| 595 ObjectGetClassID::GetInstance()->id()))); | 575 env, |
| 576 kJavaLangObject, |
| 577 kGetClass, |
| 578 kReturningJavaLangClass)))); |
| 596 ScopedJavaLocalRef<jobjectArray> methods(env, static_cast<jobjectArray>( | 579 ScopedJavaLocalRef<jobjectArray> methods(env, static_cast<jobjectArray>( |
| 597 env->CallObjectMethod(clazz.obj(), | 580 env->CallObjectMethod(clazz.obj(), GetMethodIDFromClassName( |
| 598 ClassGetMethodsID::GetInstance()->id()))); | 581 env, |
| 582 kJavaLangClass, |
| 583 kGetMethods, |
| 584 kReturningJavaLangReflectMethodArray)))); |
| 599 size_t num_methods = env->GetArrayLength(methods.obj()); | 585 size_t num_methods = env->GetArrayLength(methods.obj()); |
| 600 DCHECK(num_methods) << "Java objects always have public methods"; | 586 DCHECK(num_methods) << "Java objects always have public methods"; |
| 601 for (size_t i = 0; i < num_methods; ++i) { | 587 for (size_t i = 0; i < num_methods; ++i) { |
| 602 ScopedJavaLocalRef<jobject> java_method( | 588 ScopedJavaLocalRef<jobject> java_method( |
| 603 env, | 589 env, |
| 604 env->GetObjectArrayElement(methods.obj(), i)); | 590 env->GetObjectArrayElement(methods.obj(), i)); |
| 605 JavaMethod* method = new JavaMethod(java_method); | 591 JavaMethod* method = new JavaMethod(java_method); |
| 606 methods_.insert(std::make_pair(method->name(), method)); | 592 methods_.insert(std::make_pair(method->name(), method)); |
| 607 } | 593 } |
| 608 } | 594 } |
| OLD | NEW |