summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/WebCore/bridge/jni/v8/JNIUtilityPrivate.cpp10
-rw-r--r--Source/WebCore/bridge/jni/v8/JNIUtilityPrivate.h4
-rw-r--r--Source/WebCore/bridge/jni/v8/JavaClassJobjectV8.cpp74
-rw-r--r--Source/WebCore/bridge/jni/v8/JavaClassJobjectV8.h16
-rw-r--r--Source/WebCore/bridge/jni/v8/JavaInstanceJobjectV8.cpp17
-rw-r--r--Source/WebCore/bridge/jni/v8/JavaInstanceJobjectV8.h8
-rw-r--r--Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp9
-rw-r--r--Source/WebKit/android/jni/WebCoreFrameBridge.cpp18
8 files changed, 139 insertions, 17 deletions
diff --git a/Source/WebCore/bridge/jni/v8/JNIUtilityPrivate.cpp b/Source/WebCore/bridge/jni/v8/JNIUtilityPrivate.cpp
index 15b4bda..c6e0a6c 100644
--- a/Source/WebCore/bridge/jni/v8/JNIUtilityPrivate.cpp
+++ b/Source/WebCore/bridge/jni/v8/JNIUtilityPrivate.cpp
@@ -206,7 +206,7 @@ JavaValue convertNPVariantToJavaValue(NPVariant value, const String& javaClass)
break;
}
- result.m_objectValue = adoptRef(new JavaInstanceJobject(javaArray));
+ result.m_objectValue = adoptRef(new JavaInstanceJobject(javaArray, false));
env->DeleteLocalRef(javaArray);
}
break;
@@ -421,7 +421,11 @@ void convertJavaValueToNPVariant(JavaValue value, NPVariant* result)
}
}
+#if PLATFORM(ANDROID)
+JavaValue jvalueToJavaValue(const jvalue& value, const JavaType& type, bool requireAnnotation)
+#else
JavaValue jvalueToJavaValue(const jvalue& value, const JavaType& type)
+#endif
{
JavaValue result;
result.m_type = type;
@@ -429,7 +433,11 @@ JavaValue jvalueToJavaValue(const jvalue& value, const JavaType& type)
case JavaTypeVoid:
break;
case JavaTypeObject:
+#if PLATFORM(ANDROID)
+ result.m_objectValue = new JavaInstanceJobject(value.l, requireAnnotation);
+#else
result.m_objectValue = new JavaInstanceJobject(value.l);
+#endif
break;
case JavaTypeString:
{
diff --git a/Source/WebCore/bridge/jni/v8/JNIUtilityPrivate.h b/Source/WebCore/bridge/jni/v8/JNIUtilityPrivate.h
index 0282904..47ee45a 100644
--- a/Source/WebCore/bridge/jni/v8/JNIUtilityPrivate.h
+++ b/Source/WebCore/bridge/jni/v8/JNIUtilityPrivate.h
@@ -41,7 +41,11 @@ class JavaValue;
JavaValue convertNPVariantToJavaValue(NPVariant, const String& javaClass);
void convertJavaValueToNPVariant(JavaValue, NPVariant*);
+#if PLATFORM(ANDROID)
+JavaValue jvalueToJavaValue(const jvalue&, const JavaType&, bool requireAnnotation);
+#else
JavaValue jvalueToJavaValue(const jvalue&, const JavaType&);
+#endif
jvalue javaValueToJvalue(const JavaValue&);
} // namespace Bindings
diff --git a/Source/WebCore/bridge/jni/v8/JavaClassJobjectV8.cpp b/Source/WebCore/bridge/jni/v8/JavaClassJobjectV8.cpp
index 40bfd63..669eb49 100644
--- a/Source/WebCore/bridge/jni/v8/JavaClassJobjectV8.cpp
+++ b/Source/WebCore/bridge/jni/v8/JavaClassJobjectV8.cpp
@@ -33,7 +33,18 @@
using namespace JSC::Bindings;
+#if PLATFORM(ANDROID)
+const char kJavaScriptInterfaceAnnotation[] = "android/webkit/JavascriptInterface";
+const char kIsAnnotationPresent[] = "isAnnotationPresent";
+const char kGetMethods[] = "getMethods";
+
+static jclass safeAnnotationClazz = NULL;
+
+JavaClassJobject::JavaClassJobject(jobject anInstance, bool requireAnnotation)
+ : m_requireAnnotation(requireAnnotation)
+#else
JavaClassJobject::JavaClassJobject(jobject anInstance)
+#endif
{
jobject aClass = callJNIMethod<jobject>(anInstance, "getClass", "()Ljava/lang/Class;");
@@ -57,15 +68,28 @@ JavaClassJobject::JavaClassJobject(jobject anInstance)
// Get the methods
jarray methods = static_cast<jarray>(callJNIMethod<jobject>(aClass, "getMethods", "()[Ljava/lang/reflect/Method;"));
int numMethods = env->GetArrayLength(methods);
+#if PLATFORM(ANDROID)
+ jmethodID isAnnotationPresentMethodID = getAnnotationMethodID(env);
+ if (!isAnnotationPresentMethodID) {
+ LOG_ERROR("unable to find method %s on instance %p", kIsAnnotationPresent, anInstance);
+ return;
+ }
+#endif
for (int i = 0; i < numMethods; i++) {
jobject aJMethod = env->GetObjectArrayElement(static_cast<jobjectArray>(methods), i);
- JavaMethod* aMethod = new JavaMethodJobject(env, aJMethod); // deleted in the JavaClass destructor
- MethodList* methodList = m_methods.get(aMethod->name());
- if (!methodList) {
- methodList = new MethodList();
- m_methods.set(aMethod->name(), methodList);
+#if PLATFORM(ANDROID)
+ if (jsAccessAllowed(env, isAnnotationPresentMethodID, aJMethod)) {
+#endif
+ JavaMethod* aMethod = new JavaMethodJobject(env, aJMethod); // deleted in the JavaClass destructor
+ MethodList* methodList = m_methods.get(aMethod->name());
+ if (!methodList) {
+ methodList = new MethodList();
+ m_methods.set(aMethod->name(), methodList);
+ }
+ methodList->append(aMethod);
+#if PLATFORM(ANDROID)
}
- methodList->append(aMethod);
+#endif
env->DeleteLocalRef(aJMethod);
}
env->DeleteLocalRef(fields);
@@ -87,6 +111,44 @@ JavaClassJobject::~JavaClassJobject()
m_methods.clear();
}
+#if PLATFORM(ANDROID)
+bool JavaClassJobject::jsAccessAllowed(JNIEnv* env, jmethodID mid, jobject aJMethod)
+{
+ if (!m_requireAnnotation)
+ return true;
+ bool accessAllowed = env->CallBooleanMethod(aJMethod, mid, safeAnnotationClazz);
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ return false;
+ }
+ return accessAllowed;
+}
+
+jmethodID JavaClassJobject::getAnnotationMethodID(JNIEnv* env)
+{
+ jclass methodClass = env->FindClass("java/lang/reflect/Method");
+ jmethodID mid = 0;
+ if (methodClass)
+ mid = env->GetMethodID(methodClass, kIsAnnotationPresent, "(Ljava/lang/Class;)Z");
+ if (!methodClass || !mid) {
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ }
+ env->DeleteLocalRef(methodClass);
+ return mid;
+}
+
+bool JavaClassJobject::RegisterJavaClassJobject(JNIEnv* env) {
+ safeAnnotationClazz = reinterpret_cast<jclass>(env->NewGlobalRef(env->FindClass(kJavaScriptInterfaceAnnotation)));
+ if (!safeAnnotationClazz) {
+ LOG_ERROR("failed to register %s", kJavaScriptInterfaceAnnotation);
+ return false;
+ }
+ return true;
+}
+#endif
+
MethodList JavaClassJobject::methodsNamed(const char* name) const
{
MethodList* methodList = m_methods.get(name);
diff --git a/Source/WebCore/bridge/jni/v8/JavaClassJobjectV8.h b/Source/WebCore/bridge/jni/v8/JavaClassJobjectV8.h
index d27ca97..e4035aa 100644
--- a/Source/WebCore/bridge/jni/v8/JavaClassJobjectV8.h
+++ b/Source/WebCore/bridge/jni/v8/JavaClassJobjectV8.h
@@ -37,17 +37,33 @@ namespace Bindings {
class JavaClassJobject : public JavaClass {
public:
+#if PLATFORM(ANDROID)
+ JavaClassJobject(jobject, bool);
+#else
JavaClassJobject(jobject);
+#endif
virtual ~JavaClassJobject();
// JavaClass implementation
virtual MethodList methodsNamed(const char* name) const;
virtual JavaField* fieldNamed(const char* name) const;
+#if PLATFORM(ANDROID)
+ static bool RegisterJavaClassJobject(JNIEnv* env);
+#endif
+
private:
+#if PLATFORM(ANDROID)
+ bool jsAccessAllowed(JNIEnv* env, jmethodID mid, jobject aJMethod);
+ jmethodID getAnnotationMethodID(JNIEnv* env);
+#endif
+
typedef HashMap<WTF::String, MethodList*> MethodListMap;
MethodListMap m_methods;
FieldMap m_fields;
+#if PLATFORM(ANDROID)
+ bool m_requireAnnotation;
+#endif
};
} // namespace Bindings
diff --git a/Source/WebCore/bridge/jni/v8/JavaInstanceJobjectV8.cpp b/Source/WebCore/bridge/jni/v8/JavaInstanceJobjectV8.cpp
index e7b854d..c97a67f 100644
--- a/Source/WebCore/bridge/jni/v8/JavaInstanceJobjectV8.cpp
+++ b/Source/WebCore/bridge/jni/v8/JavaInstanceJobjectV8.cpp
@@ -41,8 +41,15 @@
using namespace JSC::Bindings;
+#if PLATFORM(ANDROID)
+JavaInstanceJobject::JavaInstanceJobject(jobject instance, bool requireAnnotation)
+#else
JavaInstanceJobject::JavaInstanceJobject(jobject instance)
+#endif
: m_instance(new JobjectWrapper(instance))
+#if PLATFORM(ANDROID)
+ , m_requireAnnotation(requireAnnotation)
+#endif
{
}
@@ -61,7 +68,11 @@ void JavaInstanceJobject::end()
JavaClass* JavaInstanceJobject::getClass() const
{
if (!m_class)
+#if PLATFORM(ANDROID)
+ m_class = adoptPtr(new JavaClassJobject(javaInstance(), m_requireAnnotation));
+#else
m_class = adoptPtr(new JavaClassJobject(javaInstance()));
+#endif
return m_class.get();
}
@@ -86,7 +97,7 @@ JavaValue JavaInstanceJobject::invokeMethod(const JavaMethod* method, JavaValue*
return JavaValue();
}
- return jvalueToJavaValue(result, method->returnType());
+ return jvalueToJavaValue(result, method->returnType(), m_requireAnnotation);
// END ANDROID
}
@@ -113,7 +124,11 @@ JavaValue JavaInstanceJobject::getField(const JavaField* field)
appendClassName(signature, field->typeClassName());
signature.append(';');
}
+#if PLATFORM(ANDROID)
+ return jvalueToJavaValue(getJNIField(javaInstance(), field->type(), field->name().utf8().data(), signature.toString().utf8().data()), field->type(), m_requireAnnotation);
+#else
return jvalueToJavaValue(getJNIField(javaInstance(), field->type(), field->name().utf8().data(), signature.toString().utf8().data()), field->type());
+#endif
}
#endif // ENABLE(JAVA_BRIDGE)
diff --git a/Source/WebCore/bridge/jni/v8/JavaInstanceJobjectV8.h b/Source/WebCore/bridge/jni/v8/JavaInstanceJobjectV8.h
index 255c190..77dcf28 100644
--- a/Source/WebCore/bridge/jni/v8/JavaInstanceJobjectV8.h
+++ b/Source/WebCore/bridge/jni/v8/JavaInstanceJobjectV8.h
@@ -48,8 +48,11 @@ namespace Bindings {
class JavaInstanceJobject : public JavaInstance {
public:
+#if PLATFORM(ANDROID)
+ JavaInstanceJobject(jobject instance, bool requireAnnotation);
+#else
JavaInstanceJobject(jobject instance);
-
+#endif
// JavaInstance implementation
virtual JavaClass* getClass() const;
// ANDROID
@@ -64,6 +67,9 @@ public:
protected:
RefPtr<JobjectWrapper> m_instance;
mutable OwnPtr<JavaClass> m_class;
+#if PLATFORM(ANDROID)
+ bool m_requireAnnotation;
+#endif
};
} // namespace Bindings
diff --git a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp
index 3237a80..03d9b81 100644
--- a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp
+++ b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp
@@ -47,8 +47,14 @@
#define NEW_OP(X) new (heap()) GraphicsOperation::X
#define USE_CLIPPING_PAINTER true
+
+// Operations smaller than this area aren't considered opaque, and thus don't
+// clip operations below. Chosen empirically.
#define MIN_TRACKED_OPAQUE_AREA 750
+// Cap on ClippingPainter's recursive depth. Chosen empirically.
+#define MAX_CLIPPING_RECURSION_COUNT 400
+
namespace WebCore {
static FloatRect approximateTextBounds(size_t numGlyphs,
@@ -445,7 +451,8 @@ void Recording::draw(SkCanvas* canvas)
nonCopyingSort(nodes.begin(), nodes.end(), CompareRecordingDataOrder);
PlatformGraphicsContextSkia context(canvas);
#if USE_CLIPPING_PAINTER
- if (canvas->getDevice() && canvas->getDevice()->config() != SkBitmap::kNo_Config) {
+ if (canvas->getDevice() && canvas->getDevice()->config() != SkBitmap::kNo_Config
+ && count < MAX_CLIPPING_RECURSION_COUNT) {
ClippingPainter painter(recording(), context, canvas->getTotalMatrix(), nodes);
painter.draw(canvas->getTotalClip().getBounds());
} else
diff --git a/Source/WebKit/android/jni/WebCoreFrameBridge.cpp b/Source/WebKit/android/jni/WebCoreFrameBridge.cpp
index 61ffd29..ecda831 100644
--- a/Source/WebKit/android/jni/WebCoreFrameBridge.cpp
+++ b/Source/WebKit/android/jni/WebCoreFrameBridge.cpp
@@ -61,6 +61,7 @@
#include "IconDatabase.h"
#include "Image.h"
#include "InspectorClientAndroid.h"
+#include "JavaClassJobjectV8.h"
#include "JavaNPObjectV8.h"
#include "JavaInstanceJobjectV8.h"
#include "KURL.h"
@@ -1504,14 +1505,14 @@ static jobject StringByEvaluatingJavaScriptFromString(JNIEnv *env, jobject obj,
// and virtualEnd and swap the weak reference for the real object.
class WeakJavaInstance : public JavaInstanceJobject {
public:
- static PassRefPtr<WeakJavaInstance> create(jobject obj)
+ static PassRefPtr<WeakJavaInstance> create(jobject obj, bool requireAnnotation)
{
- return adoptRef(new WeakJavaInstance(obj));
+ return adoptRef(new WeakJavaInstance(obj, requireAnnotation));
}
private:
- WeakJavaInstance(jobject instance)
- : JavaInstanceJobject(instance)
+ WeakJavaInstance(jobject instance, bool requireAnnotation)
+ : JavaInstanceJobject(instance, requireAnnotation)
, m_beginEndDepth(0)
{
JNIEnv* env = getJNIEnv();
@@ -1568,7 +1569,7 @@ private:
};
static void AddJavascriptInterface(JNIEnv *env, jobject obj, jint nativeFramePointer,
- jobject javascriptObj, jstring interfaceName)
+ jobject javascriptObj, jstring interfaceName, jboolean requireAnnotation)
{
WebCore::Frame* pFrame = 0;
if (nativeFramePointer == 0)
@@ -1582,7 +1583,8 @@ static void AddJavascriptInterface(JNIEnv *env, jobject obj, jint nativeFramePoi
ALOGV("::WebCore:: addJSInterface: %p", pFrame);
if (pFrame) {
- RefPtr<JavaInstance> addedObject = WeakJavaInstance::create(javascriptObj);
+ RefPtr<JavaInstance> addedObject = WeakJavaInstance::create(javascriptObj,
+ requireAnnotation);
const char* name = getCharactersFromJStringInEnv(env, interfaceName);
// Pass ownership of the added object to bindToWindowObject.
NPObject* npObject = JavaInstanceToNPObject(addedObject.get());
@@ -1950,7 +1952,7 @@ static JNINativeMethod gBrowserFrameNativeMethods[] = {
(void*) Reload },
{ "nativeGoBackOrForward", "(I)V",
(void*) GoBackOrForward },
- { "nativeAddJavascriptInterface", "(ILjava/lang/Object;Ljava/lang/String;)V",
+ { "nativeAddJavascriptInterface", "(ILjava/lang/Object;Ljava/lang/String;Z)V",
(void*) AddJavascriptInterface },
{ "stringByEvaluatingJavaScriptFromString",
"(Ljava/lang/String;)Ljava/lang/String;",
@@ -1985,6 +1987,8 @@ static JNINativeMethod gBrowserFrameNativeMethods[] = {
int registerWebFrame(JNIEnv* env)
{
+ JavaClassJobject::RegisterJavaClassJobject(env);
+
jclass clazz = env->FindClass("android/webkit/BrowserFrame");
ALOG_ASSERT(clazz, "Cannot find BrowserFrame");
gFrameField = env->GetFieldID(clazz, "mNativeFrame", "I");