summaryrefslogtreecommitdiffstats
path: root/WebKit
diff options
context:
space:
mode:
Diffstat (limited to 'WebKit')
-rw-r--r--WebKit/Android.mk3
-rw-r--r--WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp7
-rw-r--r--WebKit/android/WebCoreSupport/ChromeClientAndroid.h3
-rw-r--r--WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp12
-rw-r--r--WebKit/android/jni/WebSettings.cpp5
-rw-r--r--WebKit/android/jni/WebStorage.cpp62
-rw-r--r--WebKit/android/jni/WebViewCore.cpp135
-rw-r--r--WebKit/android/jni/WebViewCore.h18
-rw-r--r--WebKit/android/nav/WebView.cpp1
-rw-r--r--WebKit/android/plugins/ANPSoundInterface.cpp4
-rw-r--r--WebKit/android/plugins/ANPSurfaceInterface.cpp44
-rw-r--r--WebKit/android/plugins/ANPWindowInterface.cpp17
-rw-r--r--WebKit/android/plugins/PluginSurface.cpp186
-rw-r--r--WebKit/android/plugins/PluginSurface.h75
-rw-r--r--WebKit/android/plugins/PluginWidgetAndroid.cpp153
-rw-r--r--WebKit/android/plugins/PluginWidgetAndroid.h51
-rw-r--r--WebKit/android/plugins/SurfaceCallback.h42
-rw-r--r--WebKit/android/plugins/android_npapi.h67
-rw-r--r--WebKit/gtk/WebCoreSupport/ChromeClientGtk.cpp8
-rw-r--r--WebKit/gtk/WebCoreSupport/ChromeClientGtk.h3
-rw-r--r--WebKit/mac/WebCoreSupport/WebChromeClient.h3
-rw-r--r--WebKit/mac/WebCoreSupport/WebChromeClient.mm7
-rw-r--r--WebKit/mac/WebKit.exp1
-rw-r--r--WebKit/qt/WebCoreSupport/ChromeClientQt.cpp8
-rw-r--r--WebKit/qt/WebCoreSupport/ChromeClientQt.h3
-rw-r--r--WebKit/win/WebCoreSupport/WebChromeClient.cpp9
-rw-r--r--WebKit/win/WebCoreSupport/WebChromeClient.h4
-rw-r--r--WebKit/wx/WebKitSupport/ChromeClientWx.cpp7
-rw-r--r--WebKit/wx/WebKitSupport/ChromeClientWx.h5
29 files changed, 860 insertions, 83 deletions
diff --git a/WebKit/Android.mk b/WebKit/Android.mk
index 4fff70e..5e79d5a 100644
--- a/WebKit/Android.mk
+++ b/WebKit/Android.mk
@@ -62,8 +62,9 @@ LOCAL_SRC_FILES := \
android/plugins/ANPPathInterface.cpp \
android/plugins/ANPSoundInterface.cpp \
android/plugins/ANPSurfaceInterface.cpp \
- android/plugins/ANPTypefaceInterface.cpp \
+ android/plugins/ANPTypefaceInterface.cpp \
android/plugins/ANPWindowInterface.cpp \
+ android/plugins/PluginSurface.cpp \
android/plugins/PluginTimer.cpp \
android/plugins/PluginViewBridgeAndroid.cpp \
android/plugins/PluginWidgetAndroid.cpp \
diff --git a/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp b/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
index 39bc004..71d9f59 100644
--- a/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
+++ b/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
@@ -311,6 +311,13 @@ void ChromeClientAndroid::exceededDatabaseQuota(Frame* frame, const String& name
}
}
#endif
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+void ChromeClientAndroid::reachedMaxAppCacheSize(int64_t spaceNeeded)
+{
+ // FIXME: Free some space.
+ notImplemented();
+}
+#endif
void ChromeClientAndroid::requestGeolocationPermissionForFrame(Frame*, Geolocation*) { notImplemented(); }
void ChromeClientAndroid::runOpenPanel(Frame*, PassRefPtr<FileChooser>) { notImplemented(); }
diff --git a/WebKit/android/WebCoreSupport/ChromeClientAndroid.h b/WebKit/android/WebCoreSupport/ChromeClientAndroid.h
index 966d5c7..93426b8 100644
--- a/WebKit/android/WebCoreSupport/ChromeClientAndroid.h
+++ b/WebKit/android/WebCoreSupport/ChromeClientAndroid.h
@@ -111,6 +111,9 @@ namespace android {
#if ENABLE(DATABASE)
virtual void exceededDatabaseQuota(Frame*, const String&);
#endif
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ virtual void reachedMaxAppCacheSize(int64_t spaceNeeded);
+#endif
virtual void requestGeolocationPermissionForFrame(Frame*, Geolocation*);
virtual void runOpenPanel(Frame*, PassRefPtr<FileChooser>);
virtual bool setCursor(PlatformCursorHandle);
diff --git a/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp b/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp
index 24d027a..b81e5f3 100644
--- a/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp
+++ b/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp
@@ -29,13 +29,12 @@
#include "android_graphics.h"
#include "CString.h"
#include "DocumentLoader.h"
+#include "DOMImplementation.h"
#include "Frame.h"
#include "FrameLoader.h"
#include "FrameLoaderClientAndroid.h"
#include "FrameTree.h"
#include "GraphicsContext.h"
-// HTMLFormElement needed for a bad include
-#include "HTMLFormElement.h"
#include "HTMLFrameOwnerElement.h"
#include "HTMLPlugInElement.h"
#include "IconDatabase.h"
@@ -46,11 +45,6 @@
#include "PlatformString.h"
#include "PluginDatabase.h"
#include "PluginView.h"
-#ifdef ANDROID_PLUGINS
-// Removed.
-#else
-#include "PluginViewBridgeAndroid.h"
-#endif
#include "ProgressTracker.h"
#include "RenderPart.h"
#include "ResourceError.h"
@@ -663,7 +657,9 @@ bool FrameLoaderClientAndroid::canShowMIMEType(const String& mimeType) const {
if (MIMETypeRegistry::isSupportedImageResourceMIMEType(mimeType) ||
MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType) ||
MIMETypeRegistry::isSupportedJavaScriptMIMEType(mimeType) ||
- PluginDatabase::installedPlugins()->isMIMETypeRegistered(mimeType))
+ PluginDatabase::installedPlugins()->isMIMETypeRegistered(mimeType) ||
+ DOMImplementation::isTextMIMEType(mimeType) ||
+ DOMImplementation::isXMLMIMEType(mimeType))
return true;
return false;
}
diff --git a/WebKit/android/jni/WebSettings.cpp b/WebKit/android/jni/WebSettings.cpp
index 7d2b12d..73ebf63 100644
--- a/WebKit/android/jni/WebSettings.cpp
+++ b/WebKit/android/jni/WebSettings.cpp
@@ -92,6 +92,7 @@ struct FieldIds {
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
mAppCacheEnabled = env->GetFieldID(clazz, "mAppCacheEnabled", "Z");
mAppCachePath = env->GetFieldID(clazz, "mAppCachePath", "Ljava/lang/String;");
+ mAppCacheMaxSize = env->GetFieldID(clazz, "mAppCacheMaxSize", "J");
#endif
mJavaScriptCanOpenWindowsAutomatically = env->GetFieldID(clazz,
"mJavaScriptCanOpenWindowsAutomatically", "Z");
@@ -123,6 +124,7 @@ struct FieldIds {
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
LOG_ASSERT(mAppCacheEnabled, "Could not find field mAppCacheEnabled");
LOG_ASSERT(mAppCachePath, "Could not find field mAppCachePath");
+ LOG_ASSERT(mAppCacheMaxSize, "Could not find field mAppCacheMaxSize");
#endif
LOG_ASSERT(mJavaScriptCanOpenWindowsAutomatically,
"Could not find field mJavaScriptCanOpenWindowsAutomatically");
@@ -164,6 +166,7 @@ struct FieldIds {
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
jfieldID mAppCacheEnabled;
jfieldID mAppCachePath;
+ jfieldID mAppCacheMaxSize;
#endif
jfieldID mJavaScriptCanOpenWindowsAutomatically;
jfieldID mUseWideViewport;
@@ -299,6 +302,8 @@ public:
WebCore::cacheStorage().setCacheDirectory(path);
}
}
+ jlong maxsize = env->GetIntField(obj, gFieldIds->mAppCacheMaxSize);
+ WebCore::cacheStorage().setMaximumSize(maxsize);
#endif
flag = env->GetBooleanField(obj, gFieldIds->mJavaScriptCanOpenWindowsAutomatically);
s->setJavaScriptCanOpenWindowsAutomatically(flag);
diff --git a/WebKit/android/jni/WebStorage.cpp b/WebKit/android/jni/WebStorage.cpp
index f625939..aa83892 100644
--- a/WebKit/android/jni/WebStorage.cpp
+++ b/WebKit/android/jni/WebStorage.cpp
@@ -29,6 +29,7 @@
#include <JNIHelp.h>
+#include <WebCore/loader/appcache/ApplicationCacheStorage.h>
#include <WebCore/page/SecurityOrigin.h>
#include <WebCore/storage/DatabaseTracker.h>
@@ -43,21 +44,31 @@ static jobject GetOrigins(JNIEnv* env, jobject obj)
{
Vector<RefPtr<WebCore::SecurityOrigin> > coreOrigins;
WebCore::DatabaseTracker::tracker().origins(coreOrigins);
+ Vector<WebCore::KURL> manifestUrls;
+ if (WebCore::cacheStorage().manifestURLs(&manifestUrls)) {
+ int size = manifestUrls.size();
+ for (int i = 0; i < size; ++i) {
+ RefPtr<WebCore::SecurityOrigin> manifestOrigin = WebCore::SecurityOrigin::create(manifestUrls[i]);
+ if (manifestOrigin.get() == 0)
+ continue;
+ coreOrigins.append(manifestOrigin);
+ }
+ }
- jclass vectorClass = env->FindClass("java/util/Vector");
- jmethodID cid = env->GetMethodID(vectorClass, "<init>", "()V");
- jmethodID mid = env->GetMethodID(vectorClass, "addElement", "(Ljava/lang/Object;)V");
- jobject vector = env->NewObject(vectorClass, cid);
+ jclass setClass = env->FindClass("java/util/HashSet");
+ jmethodID cid = env->GetMethodID(setClass, "<init>", "()V");
+ jmethodID mid = env->GetMethodID(setClass, "add", "(Ljava/lang/Object;)Z");
+ jobject set = env->NewObject(setClass, cid);
for (unsigned i = 0; i < coreOrigins.size(); ++i) {
WebCore::SecurityOrigin* origin = coreOrigins[i].get();
WebCore::String url = origin->toString();
jstring jUrl = env->NewString(url.characters(), url.length());
- env->CallVoidMethod(vector, mid, jUrl);
+ env->CallBooleanMethod(set, mid, jUrl);
env->DeleteLocalRef(jUrl);
}
- return vector;
+ return set;
}
static unsigned long long GetQuotaForOrigin(JNIEnv* env, jobject obj, jstring origin)
@@ -72,8 +83,22 @@ static unsigned long long GetUsageForOrigin(JNIEnv* env, jobject obj, jstring or
{
WebCore::String originStr = to_string(env, origin);
RefPtr<WebCore::SecurityOrigin> securityOrigin = WebCore::SecurityOrigin::createFromString(originStr);
- unsigned long long quota = WebCore::DatabaseTracker::tracker().usageForOrigin(securityOrigin.get());
- return quota;
+ unsigned long long usage = WebCore::DatabaseTracker::tracker().usageForOrigin(securityOrigin.get());
+ Vector<WebCore::KURL> manifestUrls;
+ if (!WebCore::cacheStorage().manifestURLs(&manifestUrls))
+ return usage;
+ int size = manifestUrls.size();
+ for (int i = 0; i < size; ++i) {
+ RefPtr<WebCore::SecurityOrigin> manifestOrigin = WebCore::SecurityOrigin::create(manifestUrls[i]);
+ if (manifestOrigin.get() == 0)
+ continue;
+ if (manifestOrigin->isSameSchemeHostPort(securityOrigin.get())) {
+ int64_t size = 0;
+ WebCore::cacheStorage().cacheGroupSize(manifestUrls[i].string(), &size);
+ usage += size;
+ }
+ }
+ return usage;
}
static void SetQuotaForOrigin(JNIEnv* env, jobject obj, jstring origin, unsigned long long quota)
@@ -88,18 +113,31 @@ static void DeleteOrigin(JNIEnv* env, jobject obj, jstring origin)
WebCore::String originStr = to_string(env, origin);
RefPtr<WebCore::SecurityOrigin> securityOrigin = WebCore::SecurityOrigin::createFromString(originStr);
WebCore::DatabaseTracker::tracker().deleteOrigin(securityOrigin.get());
+
+ Vector<WebCore::KURL> manifestUrls;
+ if (!WebCore::cacheStorage().manifestURLs(&manifestUrls))
+ return;
+ int size = manifestUrls.size();
+ for (int i = 0; i < size; ++i) {
+ RefPtr<WebCore::SecurityOrigin> manifestOrigin = WebCore::SecurityOrigin::create(manifestUrls[i]);
+ if (manifestOrigin.get() == 0)
+ continue;
+ if (manifestOrigin->isSameSchemeHostPort(securityOrigin.get()))
+ WebCore::cacheStorage().deleteCacheGroup(manifestUrls[i]);
+ }
}
-static void DeleteAllDatabases(JNIEnv* env, jobject obj)
+static void DeleteAllData(JNIEnv* env, jobject obj)
{
WebCore::DatabaseTracker::tracker().deleteAllDatabases();
+ WebCore::cacheStorage().empty();
}
/*
* JNI registration
*/
static JNINativeMethod gWebStorageMethods[] = {
- { "nativeGetOrigins", "()Ljava/util/Vector;",
+ { "nativeGetOrigins", "()Ljava/util/Set;",
(void*) GetOrigins },
{ "nativeGetUsageForOrigin", "(Ljava/lang/String;)J",
(void*) GetUsageForOrigin },
@@ -109,8 +147,8 @@ static JNINativeMethod gWebStorageMethods[] = {
(void*) SetQuotaForOrigin },
{ "nativeDeleteOrigin", "(Ljava/lang/String;)V",
(void*) DeleteOrigin },
- { "nativeDeleteAllDatabases", "()V",
- (void*) DeleteAllDatabases }
+ { "nativeDeleteAllData", "()V",
+ (void*) DeleteAllData }
};
int register_webstorage(JNIEnv* env)
diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp
index f88b1d2..51293b8 100644
--- a/WebKit/android/jni/WebViewCore.cpp
+++ b/WebKit/android/jni/WebViewCore.cpp
@@ -88,6 +88,7 @@
#include "SkCanvas.h"
#include "SkPicture.h"
#include "SkUtils.h"
+#include "SurfaceCallback.h"
#include "StringImpl.h"
#include "Text.h"
#include "TypingCommand.h"
@@ -176,6 +177,9 @@ struct WebViewCore::JavaGlue {
jmethodID m_requestKeyboard;
jmethodID m_exceededDatabaseQuota;
jmethodID m_addMessageToConsole;
+ jmethodID m_createSurface;
+ jmethodID m_destroySurface;
+ jmethodID m_attachSurface;
AutoJObject object(JNIEnv* env) {
return getRealObject(env, m_obj);
}
@@ -241,6 +245,9 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m
m_javaGlue->m_requestKeyboard = GetJMethod(env, clazz, "requestKeyboard", "(Z)V");
m_javaGlue->m_exceededDatabaseQuota = GetJMethod(env, clazz, "exceededDatabaseQuota", "(Ljava/lang/String;Ljava/lang/String;J)V");
m_javaGlue->m_addMessageToConsole = GetJMethod(env, clazz, "addMessageToConsole", "(Ljava/lang/String;ILjava/lang/String;)V");
+ m_javaGlue->m_createSurface = GetJMethod(env, clazz, "createSurface", "(I)Landroid/view/SurfaceView;");
+ m_javaGlue->m_destroySurface = GetJMethod(env, clazz, "destroySurface", "(Landroid/view/SurfaceView;)V");
+ m_javaGlue->m_attachSurface = GetJMethod(env, clazz, "attachSurface", "(Landroid/view/SurfaceView;IIII)V");
env->SetIntField(javaWebViewCore, gWebViewCoreFields.m_nativeClass, (jint)this);
@@ -890,8 +897,8 @@ void WebViewCore::setScrollOffset(int moveGeneration, int dx, int dy)
m_scrollOffsetY);
m_mainFrame->eventHandler()->sendScrollEvent();
- // update the currently visible window
- sendVisibleRectBounds();
+ // update the currently visible screen
+ sendPluginVisibleScreen();
}
gCursorBoundsMutex.lock();
bool hasCursorBounds = m_hasCursorBounds;
@@ -967,20 +974,8 @@ void WebViewCore::setSizeScreenWidthAndScale(int width, int height,
}
}
- // update the currently visible window
- sendVisibleRectBounds();
-}
-
-void WebViewCore::sendVisibleRectBounds()
-{
- ANPEvent event;
- SkANP::InitEvent(&event, kVisibleRect_ANPEventType);
- event.data.visibleRect.rect.left = m_scrollOffsetX;
- event.data.visibleRect.rect.top = m_scrollOffsetY;
- event.data.visibleRect.rect.right = m_scrollOffsetX + m_screenWidth;
- event.data.visibleRect.rect.bottom = m_scrollOffsetY + m_screenHeight;
- event.data.visibleRect.zoomScale = m_scale;
- sendPluginEvent(event, kVisibleRect_ANPEventFlag);
+ // update the currently visible screen
+ sendPluginVisibleScreen();
}
void WebViewCore::dumpDomTree(bool useFile)
@@ -1172,6 +1167,21 @@ void WebViewCore::drawPlugins()
}
}
+void WebViewCore::sendPluginVisibleScreen()
+{
+ ANPRectI visibleRect;
+ visibleRect.left = m_scrollOffsetX;
+ visibleRect.top = m_scrollOffsetY;
+ visibleRect.right = m_scrollOffsetX + m_screenWidth;
+ visibleRect.bottom = m_scrollOffsetY + m_screenHeight;
+
+ PluginWidgetAndroid** iter = m_plugins.begin();
+ PluginWidgetAndroid** stop = m_plugins.end();
+ for (; iter < stop; ++iter) {
+ (*iter)->setVisibleScreen(visibleRect, m_scale);
+ }
+}
+
void WebViewCore::sendPluginEvent(const ANPEvent& evt, ANPEventFlag flag)
{
PluginWidgetAndroid** iter = m_plugins.begin();
@@ -1362,11 +1372,17 @@ WebCore::String WebViewCore::getSelection(SkRegion* selRgn)
DBG_NAV_LOG("!node");
return result;
}
- WebCore::IntPoint endPt = WebCore::IntPoint(rect.fRight - 2, cy);
+ WebCore::IntPoint endPt = WebCore::IntPoint(rect.fRight - 1, cy);
hitTestResult = m_mainFrame->eventHandler()->hitTestResultAtPoint(endPt, false);
WebCore::Node* endNode = hitTestResult.innerNode();
if (!endNode) {
- DBG_NAV_LOG("!endNode");
+ DBG_NAV_LOG("!endNode (right-1)");
+ endPt = WebCore::IntPoint(rect.fRight - 2, cy);
+ hitTestResult = m_mainFrame->eventHandler()->hitTestResultAtPoint(endPt, false);
+ endNode = hitTestResult.innerNode();
+ }
+ if (!endNode) {
+ DBG_NAV_LOG("!endNode (right-2)");
return result;
}
int start = findTextBoxIndex(node, startPt);
@@ -1501,6 +1517,26 @@ void WebViewCore::passToJs(int generation, const WebCore::String& current,
updateTextfield(focus, false, test);
}
+void WebViewCore::scrollFocusedTextInput(int x, int y)
+{
+ WebCore::Node* focus = currentFocus();
+ if (!focus) {
+ DBG_NAV_LOG("!focus");
+ clearTextEntry();
+ return;
+ }
+ WebCore::RenderObject* renderer = focus->renderer();
+ if (!renderer || (!renderer->isTextField() && !renderer->isTextArea())) {
+ DBG_NAV_LOGD("renderer==%p || not text", renderer);
+ clearTextEntry();
+ return;
+ }
+ WebCore::RenderTextControl* renderText =
+ static_cast<WebCore::RenderTextControl*>(renderer);
+ renderText->setScrollLeft(x);
+ renderText->setScrollTop(y);
+}
+
void WebViewCore::setFocusControllerActive(bool active)
{
m_mainFrame->page()->focusController()->setActive(active);
@@ -2021,6 +2057,32 @@ void WebViewCore::setBackgroundColor(SkColor c)
view->setBaseBackgroundColor(bcolor);
}
+jobject WebViewCore::createSurface(SurfaceCallback* cb)
+{
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ jobject surface = env->CallObjectMethod(m_javaGlue->object(env).get(),
+ m_javaGlue->m_createSurface, (int) cb);
+ checkException(env);
+ return surface;
+}
+
+void WebViewCore::destroySurface(jobject surface)
+{
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ env->CallVoidMethod(m_javaGlue->object(env).get(),
+ m_javaGlue->m_destroySurface, surface);
+ checkException(env);
+}
+
+void WebViewCore::attachSurface(jobject surface, int x, int y, int width,
+ int height)
+{
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ env->CallVoidMethod(m_javaGlue->object(env).get(),
+ m_javaGlue->m_attachSurface, surface, x, y, width, height);
+ checkException(env);
+}
+
//----------------------------------------------------------------------
// Native JNI methods
//----------------------------------------------------------------------
@@ -2138,6 +2200,15 @@ static void PassToJs(JNIEnv *env, jobject obj,
PlatformKeyboardEvent(keyCode, keyValue, 0, down, cap, fn, sym));
}
+static void ScrollFocusedTextInput(JNIEnv *env, jobject obj, jint x, jint y)
+{
+#ifdef ANDROID_INSTRUMENT
+ TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter);
+#endif
+ WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj);
+ viewImpl->scrollFocusedTextInput(x, y);
+}
+
static void SetFocusControllerActive(JNIEnv *env, jobject obj, jboolean active)
{
#ifdef ANDROID_INSTRUMENT
@@ -2503,6 +2574,28 @@ static void UpdatePluginState(JNIEnv* env, jobject obj, jint framePtr, jint node
(PluginState) state);
}
+static void SurfaceChanged(JNIEnv* env, jobject obj, jint pointer, jint state,
+ jint format, jint width, jint height)
+{
+ // Be safe and check for a valid callback
+ if (!pointer)
+ return;
+ SurfaceCallback* cb = reinterpret_cast<SurfaceCallback*>(pointer);
+ switch (state) {
+ case 0:
+ cb->surfaceCreated();
+ break;
+ case 1:
+ cb->surfaceChanged(format, width, height);
+ break;
+ case 2:
+ cb->surfaceDestroyed();
+ break;
+ default:
+ break;
+ }
+}
+
static void Pause(JNIEnv* env, jobject obj)
{
ANPEvent event;
@@ -2566,7 +2659,9 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = {
{ "nativeMoveMouseIfLatest", "(IIII)V",
(void*) MoveMouseIfLatest },
{ "passToJs", "(ILjava/lang/String;IIZZZZ)V",
- (void*) PassToJs } ,
+ (void*) PassToJs },
+ { "nativeScrollFocusedTextInput", "(II)V",
+ (void*) ScrollFocusedTextInput },
{ "nativeSetFocusControllerActive", "(Z)V",
(void*) SetFocusControllerActive },
{ "nativeSaveDocumentState", "(I)V",
@@ -2607,6 +2702,8 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = {
(void*) DumpNavTree },
{ "nativeSetDatabaseQuota", "(J)V",
(void*) SetDatabaseQuota },
+ { "nativeSurfaceChanged", "(IIIII)V",
+ (void*) SurfaceChanged },
{ "nativePause", "()V", (void*) Pause },
{ "nativeResume", "()V", (void*) Resume },
{ "nativeFreeMemory", "()V", (void*) FreeMemory },
diff --git a/WebKit/android/jni/WebViewCore.h b/WebKit/android/jni/WebViewCore.h
index 2af849f..be08830 100644
--- a/WebKit/android/jni/WebViewCore.h
+++ b/WebKit/android/jni/WebViewCore.h
@@ -67,6 +67,7 @@ namespace android {
class CachedRoot;
class ListBoxReply;
+ class SurfaceCallback;
class WebCoreReply : public WebCoreRefObject {
public:
@@ -265,6 +266,10 @@ namespace android {
int textGeneration);
void passToJs(int generation,
const WebCore::String& , const WebCore::PlatformKeyboardEvent& );
+ /**
+ * Scroll the focused textfield to (x, y) in document space
+ */
+ void scrollFocusedTextInput(int x, int y);
void setFocusControllerActive(bool active);
void saveDocumentState(WebCore::Frame* frame);
@@ -295,6 +300,9 @@ namespace android {
void invalPlugin(PluginWidgetAndroid*);
void drawPlugins();
+ // send the current screen size/zoom to all of the plugins in our list
+ void sendPluginVisibleScreen();
+
// send this event to all of the plugins in our list
void sendPluginEvent(const ANPEvent&);
@@ -313,6 +321,15 @@ namespace android {
// Notify the Java side that webkit is requesting a keyboard
void requestKeyboard(bool);
+ // Creates a SurfaceView for a plugin
+ jobject createSurface(SurfaceCallback* cb);
+
+ // Destroys the SurfaceView after removing from the view system.
+ void destroySurface(jobject surface);
+
+ // Positions the SurfaceView at x,y with dimensions width x height
+ void attachSurface(jobject surface, int x, int y, int width, int height);
+
// other public functions
public:
// reset the picture set to empty
@@ -420,7 +437,6 @@ namespace android {
SkPicture* rebuildPicture(const SkIRect& inval);
void rebuildPictureSet(PictureSet* );
void sendNotifyProgressFinished();
- void sendVisibleRectBounds();
bool handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* nodePtr);
#if DEBUG_NAV_UI
uint32_t m_now;
diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp
index cf1e486..ec57a3b 100644
--- a/WebKit/android/nav/WebView.cpp
+++ b/WebKit/android/nav/WebView.cpp
@@ -955,6 +955,7 @@ bool motionUp(int x, int y, int slop)
rebuildWebTextView();
displaySoftKeyboard(true);
} else {
+ clearTextEntry();
setFollowedLink(true);
if (type != NORMAL_CACHEDNODETYPE)
overrideUrlLoading(result->getExport());
diff --git a/WebKit/android/plugins/ANPSoundInterface.cpp b/WebKit/android/plugins/ANPSoundInterface.cpp
index 6b019d1..c4bec1c 100644
--- a/WebKit/android/plugins/ANPSoundInterface.cpp
+++ b/WebKit/android/plugins/ANPSoundInterface.cpp
@@ -46,7 +46,7 @@ static ANPSampleFormat toANPFormat(int fm) {
}
}
-static android::AudioSystem::audio_format fromANPFormat(ANPSampleFormat fm) {
+static int fromANPFormat(ANPSampleFormat fm) {
switch (fm) {
case kPCM16Bit_ANPSampleFormat:
return android::AudioSystem::PCM_16_BIT;
@@ -97,7 +97,7 @@ static ANPAudioTrack* ANPCreateTrack(uint32_t sampleRate,
track->mTrack = new android::AudioTrack(android::AudioSystem::MUSIC,
sampleRate,
fromANPFormat(format),
- channelCount,
+ (channelCount > 1) ? android::AudioSystem::CHANNEL_OUT_STEREO : android::AudioSystem::CHANNEL_OUT_MONO,
0, // frameCount
0, // flags
callbackProc,
diff --git a/WebKit/android/plugins/ANPSurfaceInterface.cpp b/WebKit/android/plugins/ANPSurfaceInterface.cpp
index a64af1e..835f45a 100644
--- a/WebKit/android/plugins/ANPSurfaceInterface.cpp
+++ b/WebKit/android/plugins/ANPSurfaceInterface.cpp
@@ -25,23 +25,61 @@
// must include config.h first for webkit to fiddle with new/delete
#include "config.h"
+
+#include "PluginSurface.h"
+#include "PluginView.h"
+#include "PluginWidgetAndroid.h"
#include "SkANP.h"
-static ANPSurface* anp_newSurface(NPP instance, ANPSurfaceType) {
+using namespace WebCore;
+
+static ANPSurface* anp_newSurface(NPP instance, ANPSurfaceType type) {
+ if (instance && instance->ndata) {
+ PluginView* view = static_cast<PluginView*>(instance->ndata);
+ PluginWidgetAndroid* widget = view->platformPluginWidget();
+ return widget->createSurface(type);
+ }
return NULL;
}
static void anp_deleteSurface(ANPSurface* surface) {
-
+ if (surface) {
+ if (surface->data) {
+ android::PluginSurface* s =
+ static_cast<android::PluginSurface*>(surface->data);
+ s->destroy();
+ }
+ delete surface;
+ }
}
static bool anp_lock(ANPSurface* surface, ANPBitmap* bitmap,
ANPRectI* dirtyRect) {
+ if (bitmap && surface && surface->data) {
+ android::PluginSurface* s =
+ static_cast<android::PluginSurface*>(surface->data);
+ SkBitmap src;
+ bool res = false;
+ if (dirtyRect) {
+ SkIRect rect;
+ res = s->lock(SkANP::SetRect(&rect, *dirtyRect), &src);
+ } else {
+ res = s->lock(NULL, &src);
+ }
+ if (res) {
+ res &= SkANP::SetBitmap(bitmap, src);
+ }
+ return res;
+ }
return false;
}
static void anp_unlock(ANPSurface* surface) {
-
+ if (surface && surface->data) {
+ android::PluginSurface* s =
+ static_cast<android::PluginSurface*>(surface->data);
+ s->unlock();
+ }
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/WebKit/android/plugins/ANPWindowInterface.cpp b/WebKit/android/plugins/ANPWindowInterface.cpp
index 7773e6e..41e00e9 100644
--- a/WebKit/android/plugins/ANPWindowInterface.cpp
+++ b/WebKit/android/plugins/ANPWindowInterface.cpp
@@ -26,9 +26,9 @@
// must include config.h first for webkit to fiddle with new/delete
#include "config.h"
#include "SkANP.h"
-#include "ScrollView.h"
#include "WebViewCore.h"
#include "PluginView.h"
+#include "PluginWidgetAndroid.h"
static bool anp_lockRect(void* window, const ANPRectI* inval,
ANPBitmap* bitmap) {
@@ -57,10 +57,14 @@ static PluginView* pluginViewForInstance(NPP instance) {
return PluginView::currentPluginView();
}
-static void anp_scrollTo(NPP instance, int32_t x, int32_t y) {
- ScrollView* scrollView = pluginViewForInstance(instance)->parent();
- android::WebViewCore* core = android::WebViewCore::getWebViewCore(scrollView);
- core->scrollTo(x,y,true);
+static void anp_setVisibleRects(NPP instance, const ANPRectI rects[], int32_t count) {
+ PluginView* pluginView = pluginViewForInstance(instance);
+ PluginWidgetAndroid* pluginWidget = pluginView->platformPluginWidget();
+ pluginWidget->setVisibleRects(rects, count);
+}
+
+static void anp_clearVisibleRects(NPP instance) {
+ anp_setVisibleRects(instance, NULL, 0);
}
static void anp_showKeyboard(NPP instance, bool value) {
@@ -78,7 +82,8 @@ void ANPWindowInterfaceV0_Init(ANPInterface* value) {
ASSIGN(i, lockRect);
ASSIGN(i, lockRegion);
- ASSIGN(i, scrollTo);
+ ASSIGN(i, setVisibleRects);
+ ASSIGN(i, clearVisibleRects);
ASSIGN(i, showKeyboard);
ASSIGN(i, unlock);
}
diff --git a/WebKit/android/plugins/PluginSurface.cpp b/WebKit/android/plugins/PluginSurface.cpp
new file mode 100644
index 0000000..aba0263
--- /dev/null
+++ b/WebKit/android/plugins/PluginSurface.cpp
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "PluginSurface.h"
+
+#include "android_graphics.h"
+#include "PluginWidgetAndroid.h"
+#include "WebViewCore.h"
+#include "jni_utility.h"
+
+#include <ui/Rect.h>
+#include <ui/Region.h>
+#include <ui/Surface.h>
+
+namespace android {
+
+// jni field offset for the native surface pointer.
+static jfieldID gSurfaceField;
+static jmethodID gGetHolder;
+static jmethodID gGetSurface;
+
+static void initFields(JNIEnv* env) {
+ if (gSurfaceField)
+ return;
+
+ jclass clazz = env->FindClass("android/view/Surface");
+ gSurfaceField = env->GetFieldID(clazz, "mSurface", "I");
+
+ clazz = env->FindClass("android/view/SurfaceView");
+ gGetHolder = env->GetMethodID(clazz, "getHolder", "()Landroid/view/SurfaceHolder;");
+
+ clazz = env->FindClass("android/view/SurfaceHolder");
+ gGetSurface = env->GetMethodID(clazz, "getSurface", "()Landroid/view/Surface;");
+}
+
+static inline sp<Surface> getSurface(jobject view) {
+ if (!view) {
+ return NULL;
+ }
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ initFields(env);
+ jobject holder = env->CallObjectMethod(view, gGetHolder);
+ jobject surface = env->CallObjectMethod(holder, gGetSurface);
+ return sp<Surface>((Surface*) env->GetIntField(surface, gSurfaceField));
+}
+
+static inline SkBitmap::Config convertPixelFormat(PixelFormat format) {
+ switch (format) {
+ case PIXEL_FORMAT_RGBA_8888: return SkBitmap::kARGB_8888_Config;
+ case PIXEL_FORMAT_RGBA_4444: return SkBitmap::kARGB_4444_Config;
+ case PIXEL_FORMAT_RGB_565: return SkBitmap::kRGB_565_Config;
+ case PIXEL_FORMAT_A_8: return SkBitmap::kA8_Config;
+ default: return SkBitmap::kNo_Config;
+ }
+}
+
+PluginSurface::PluginSurface(PluginWidgetAndroid* widget)
+ : m_jSurfaceView(0)
+ , m_widget(widget) {
+ // Create our java SurfaceView.
+ jobject obj = widget->webViewCore()->createSurface(this);
+ if (obj) {
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ m_jSurfaceView = env->NewGlobalRef(obj);
+ env->DeleteLocalRef(obj);
+ }
+}
+
+void PluginSurface::attach(int x, int y, int width, int height) {
+ if (m_jSurfaceView) {
+ m_widget->webViewCore()->attachSurface(m_jSurfaceView, x, y, width,
+ height);
+ }
+}
+
+void PluginSurface::destroy() {
+ m_surface.clear();
+ if (m_jSurfaceView) {
+ m_widget->webViewCore()->destroySurface(m_jSurfaceView);
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ env->DeleteGlobalRef(m_jSurfaceView);
+ m_jSurfaceView = 0;
+ }
+}
+
+bool PluginSurface::lock(SkIRect* dirty, SkBitmap* bitmap) {
+ if (!bitmap || !Surface::isValid(m_surface)) {
+ return false;
+ }
+
+ Region dirtyRegion;
+ if (dirty) {
+ Rect rect(dirty->fLeft, dirty->fTop, dirty->fRight, dirty->fBottom);
+ if (!rect.isEmpty()) {
+ dirtyRegion.set(rect);
+ }
+ } else {
+ dirtyRegion.set(Rect(0x3FFF, 0x3FFF));
+ }
+
+ Surface::SurfaceInfo info;
+ status_t err = m_surface->lock(&info, &dirtyRegion);
+ if (err < 0) {
+ return false;
+ }
+
+ ssize_t bpr = info.s * bytesPerPixel(info.format);
+ bitmap->setConfig(convertPixelFormat(info.format), info.w, info.h, bpr);
+ if (info.w > 0 && info.h > 0) {
+ bitmap->setPixels(info.bits);
+ } else {
+ bitmap->setPixels(NULL);
+ }
+
+ return true;
+}
+
+void PluginSurface::unlock() {
+ if (!Surface::isValid(m_surface)) {
+ return;
+ }
+
+ m_surface->unlockAndPost();
+}
+
+static void sendSurfaceEvent(PluginWidgetAndroid* widget,
+ ANPSurfaceAction action, int format = 0, int width = 0,
+ int height = 0) {
+ // format is currently not reported to the plugin. The plumbing from Java
+ // to C is still provided in case we add the format back to the event.
+ ANPEvent event;
+ SkANP::InitEvent(&event, kSurface_ANPEventType);
+
+ event.data.surface.action = action;
+ if (action == kChanged_ANPSurfaceAction) {
+ event.data.surface.data.changed.width = width;
+ event.data.surface.data.changed.height = height;
+ }
+
+ widget->sendEvent(event);
+}
+
+// SurfaceCallback methods
+void PluginSurface::surfaceCreated() {
+ m_surface = getSurface(m_jSurfaceView);
+ // Not sure what values for format, width, and height should be here.
+ sendSurfaceEvent(m_widget, kCreated_ANPSurfaceAction);
+}
+
+void PluginSurface::surfaceChanged(int format, int width, int height) {
+ m_surface = getSurface(m_jSurfaceView);
+ sendSurfaceEvent(m_widget, kChanged_ANPSurfaceAction, format, width,
+ height);
+}
+
+void PluginSurface::surfaceDestroyed() {
+ m_surface = getSurface(m_jSurfaceView);
+ // Not sure what values for format, width, and height should be here.
+ sendSurfaceEvent(m_widget, kDestroyed_ANPSurfaceAction);
+}
+
+} // namespace android
diff --git a/WebKit/android/plugins/PluginSurface.h b/WebKit/android/plugins/PluginSurface.h
new file mode 100644
index 0000000..b8cbac9
--- /dev/null
+++ b/WebKit/android/plugins/PluginSurface.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ * Copyright (C) 2008 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PluginSurface_H
+#define PluginSurface_H
+
+#include "android_npapi.h"
+#include "SkANP.h"
+#include "SurfaceCallback.h"
+
+#include <jni.h>
+#include <ui/Surface.h>
+#include <utils/RefBase.h>
+
+struct PluginWidgetAndroid;
+class SkBitmap;
+struct SkIRect;
+
+struct ANPSurface {
+ void* data;
+ ANPSurfaceType type;
+};
+
+namespace android {
+
+class Surface;
+
+class PluginSurface : public SurfaceCallback {
+public:
+ PluginSurface(PluginWidgetAndroid* widget);
+ virtual ~PluginSurface() {
+ destroy();
+ }
+
+ void attach(int x, int y, int width, int height);
+ void destroy();
+ bool lock(SkIRect* dirty, SkBitmap* bitmap);
+ void unlock();
+
+ virtual void surfaceCreated();
+ virtual void surfaceChanged(int format, int width, int height);
+ virtual void surfaceDestroyed();
+
+private:
+ jobject m_jSurfaceView;
+ sp<Surface> m_surface;
+ PluginWidgetAndroid* m_widget;
+};
+
+} // namespace android
+
+#endif
diff --git a/WebKit/android/plugins/PluginWidgetAndroid.cpp b/WebKit/android/plugins/PluginWidgetAndroid.cpp
index 7566d63..30a55cb 100644
--- a/WebKit/android/plugins/PluginWidgetAndroid.cpp
+++ b/WebKit/android/plugins/PluginWidgetAndroid.cpp
@@ -29,8 +29,10 @@
#include "Element.h"
#include "Frame.h"
#include "PluginPackage.h"
+#include "PluginSurface.h"
#include "PluginView.h"
#include "PluginWidgetAndroid.h"
+#include "ScrollView.h"
#include "SkANP.h"
#include "SkFlipPixelRef.h"
#include "WebViewCore.h"
@@ -41,7 +43,10 @@ PluginWidgetAndroid::PluginWidgetAndroid(WebCore::PluginView* view)
m_core = NULL;
m_drawingModel = kBitmap_ANPDrawingModel;
m_eventFlags = 0;
- m_x = m_y = 0;
+ m_pluginWindow = NULL;
+ m_requestedVisibleRectCount = 0;
+ m_requestedFrameRect.setEmpty();
+ m_visibleDocRect.setEmpty();
}
PluginWidgetAndroid::~PluginWidgetAndroid() {
@@ -61,13 +66,18 @@ static SkBitmap::Config computeConfig(bool isTransparent) {
: SkBitmap::kRGB_565_Config;
}
-void PluginWidgetAndroid::setWindow(int x, int y, int width, int height,
- bool isTransparent) {
- m_x = x;
- m_y = y;
- m_flipPixelRef->safeUnref();
- m_flipPixelRef = new SkFlipPixelRef(computeConfig(isTransparent),
- width, height);
+void PluginWidgetAndroid::setWindow(NPWindow* window, bool isTransparent) {
+ m_pluginWindow = window;
+
+ if (m_drawingModel == kSurface_ANPDrawingModel) {
+ if (m_surface) {
+ m_surface->attach(window->x, window->y, window->width, window->height);
+ }
+ } else {
+ m_flipPixelRef->safeUnref();
+ m_flipPixelRef = new SkFlipPixelRef(computeConfig(isTransparent),
+ window->width, window->height);
+ }
}
bool PluginWidgetAndroid::setDrawingModel(ANPDrawingModel model) {
@@ -76,7 +86,8 @@ bool PluginWidgetAndroid::setDrawingModel(ANPDrawingModel model) {
}
void PluginWidgetAndroid::localToPageCoords(SkIRect* rect) const {
- rect->offset(m_x, m_y);
+ if (m_pluginWindow)
+ rect->offset(m_pluginWindow->x, m_pluginWindow->y);
}
bool PluginWidgetAndroid::isDirty(SkIRect* rect) const {
@@ -98,7 +109,8 @@ bool PluginWidgetAndroid::isDirty(SkIRect* rect) const {
void PluginWidgetAndroid::inval(const WebCore::IntRect& rect,
bool signalRedraw) {
- // nothing to do if we haven't had setWindow() called yet
+ // nothing to do if we haven't had setWindow() called yet. m_flipPixelRef
+ // will also be null if this is a Surface model.
if (NULL == m_flipPixelRef) {
return;
}
@@ -134,11 +146,11 @@ void PluginWidgetAndroid::draw(SkCanvas* canvas) {
bitmap) &&
pkg->pluginFuncs()->event(instance, &event)) {
- if (canvas) {
+ if (canvas && m_pluginWindow) {
SkBitmap bm(bitmap);
bm.setPixelRef(m_flipPixelRef);
- canvas->drawBitmap(bm, SkIntToScalar(m_x),
- SkIntToScalar(m_y), NULL);
+ canvas->drawBitmap(bm, SkIntToScalar(m_pluginWindow->x),
+ SkIntToScalar(m_pluginWindow->y), NULL);
}
}
break;
@@ -182,3 +194,118 @@ void PluginWidgetAndroid::updateEventFlags(ANPEventFlags flags) {
bool PluginWidgetAndroid::isAcceptingEvent(ANPEventFlag flag) {
return m_eventFlags & flag;
}
+
+ANPSurface* PluginWidgetAndroid::createSurface(ANPSurfaceType ignored) {
+ if (m_drawingModel != kSurface_ANPDrawingModel) {
+ return NULL;
+ }
+ m_surface.set(new android::PluginSurface(this));
+ ANPSurface* surface = new ANPSurface;
+ surface->data = m_surface.get();
+ surface->type = ignored;
+ return surface;
+}
+
+void PluginWidgetAndroid::setVisibleScreen(const ANPRectI& visibleDocRect, float zoom) {
+
+ //TODO send an event to the plugin that communicates the zoom
+
+ int oldScreenW = m_visibleDocRect.width();
+ int oldScreenH = m_visibleDocRect.height();
+
+ m_visibleDocRect.set(visibleDocRect.left, visibleDocRect.top,
+ visibleDocRect.right, visibleDocRect.bottom);
+
+ int newScreenW = m_visibleDocRect.width();
+ int newScreenH = m_visibleDocRect.height();
+
+ if (oldScreenW != newScreenW || oldScreenH != newScreenH)
+ computeVisibleFrameRect();
+}
+
+void PluginWidgetAndroid::setVisibleRects(const ANPRectI rects[], int32_t count) {
+
+ // ensure the count does not exceed our allocated space
+ if (count > MAX_REQUESTED_RECTS)
+ count = MAX_REQUESTED_RECTS;
+
+ // store the values in member variables
+ m_requestedVisibleRectCount = count;
+ memcpy(m_requestedVisibleRect, rects, count * sizeof(rects[0]));
+
+ computeVisibleFrameRect();
+}
+
+void PluginWidgetAndroid::computeVisibleFrameRect() {
+
+ // ensure the visibleDocRect has been set (i.e. not equal to zero)
+ if (m_visibleDocRect.isEmpty() || !m_pluginWindow)
+ return;
+
+ // create a rect that represents the plugin's bounds
+ SkIRect pluginBounds;
+ pluginBounds.set(m_pluginWindow->x, m_pluginWindow->y,
+ m_pluginWindow->x + m_pluginWindow->width,
+ m_pluginWindow->y + m_pluginWindow->height);
+
+ // create a rect that will contain as many of the rects that will fit on screen
+ SkIRect visibleRect;
+ visibleRect.setEmpty();
+
+ for (int counter = 0; counter < m_requestedVisibleRectCount; counter++) {
+
+ ANPRectI* rect = &m_requestedVisibleRect[counter];
+
+ // create skia rect for easier manipulation and convert it to frame coordinates
+ SkIRect pluginRect;
+ pluginRect.set(rect->left, rect->top, rect->right, rect->bottom);
+ pluginRect.offset(m_pluginWindow->x, m_pluginWindow->y);
+
+ // ensure the rect falls within the plugin's bounds
+ if (!pluginBounds.contains(pluginRect))
+ continue;
+
+ // combine this new rect with the higher priority rects
+ pluginRect.join(visibleRect);
+
+ // check to see if the new rect fits within the screen bounds. If this
+ // is the highest priority rect then attempt to center even if it doesn't
+ // fit on the screen.
+ if (counter > 0 && (m_visibleDocRect.width() < pluginRect.width() ||
+ m_visibleDocRect.height() < pluginRect.height()))
+ break;
+
+ // set the new visible rect
+ visibleRect = pluginRect;
+ }
+
+ m_requestedFrameRect = visibleRect;
+ scrollToVisibleFrameRect();
+}
+
+void PluginWidgetAndroid::scrollToVisibleFrameRect() {
+
+ if (m_requestedFrameRect.isEmpty() || m_visibleDocRect.isEmpty())
+ return;
+
+ // TODO if the entire rect is already visible then we don't need to scroll,
+ // this requires converting the m_requestedFrameRect from frame to doc coordinates
+
+ // find the center of the visibleRect in document coordinates
+ ScrollView* scrollView = m_pluginView->parent();
+ IntPoint pluginFramePoint = IntPoint(m_requestedFrameRect.fLeft, m_requestedFrameRect.fTop);
+ IntPoint pluginDocPoint = scrollView->convertToContainingWindow(pluginFramePoint);
+ int rectCenterX = pluginDocPoint.x() + m_requestedFrameRect.width()/2;
+ int rectCenterY = pluginDocPoint.y() + m_requestedFrameRect.height()/2;
+
+ // find document coordinates for center of the visible screen
+ int screenCenterX = m_visibleDocRect.fLeft + m_visibleDocRect.width()/2;
+ int screenCenterY = m_visibleDocRect.fTop + m_visibleDocRect.height()/2;
+
+ //compute the delta of the two points
+ int deltaX = rectCenterX - screenCenterX;
+ int deltaY = rectCenterY - screenCenterY;
+
+ android::WebViewCore* core = android::WebViewCore::getWebViewCore(scrollView);
+ core->scrollBy(deltaX, deltaY, true);
+}
diff --git a/WebKit/android/plugins/PluginWidgetAndroid.h b/WebKit/android/plugins/PluginWidgetAndroid.h
index c8d1ffe..1da618f 100644
--- a/WebKit/android/plugins/PluginWidgetAndroid.h
+++ b/WebKit/android/plugins/PluginWidgetAndroid.h
@@ -27,12 +27,16 @@
#define PluginWidgetAndroid_H
#include "android_npapi.h"
+#include "SkRect.h"
+
+#include <wtf/OwnPtr.h>
namespace WebCore {
class PluginView;
}
namespace android {
+ class PluginSurface;
class WebViewCore;
}
@@ -52,13 +56,17 @@ struct PluginWidgetAndroid {
WebCore::PluginView* pluginView() const { return m_pluginView; }
+ // Needed by PluginSurface to manage the java SurfaceView.
+ android::WebViewCore* webViewCore() const { return m_core; }
+
/* Can't determine our core at construction time, so PluginView calls this
as soon as it has a parent.
*/
void init(android::WebViewCore*);
/* Called each time the PluginView gets a new size or position.
*/
- void setWindow(int x, int y, int width, int height, bool isTransparent);
+ void setWindow(NPWindow* window, bool isTransparent);
+
/* Called whenever the plugin itself requests a new drawing model. If the
hardware does not support the requested model then false is returned,
otherwise true is returned.
@@ -101,14 +109,51 @@ struct PluginWidgetAndroid {
*/
bool isAcceptingEvent(ANPEventFlag);
+ /* Create an ANPSurface that the plugin may draw in to. The drawing model
+ must be kSurface_ANPDrawingModel for this call to succeed. The type
+ specifies what kind of pixel access will be available.
+ */
+ ANPSurface* createSurface(ANPSurfaceType type);
+
+ /* Notify the plugin of the currently visible screen coordinates (document
+ space) and the current zoom level.
+ */
+ void setVisibleScreen(const ANPRectI& visibleScreenRect, float zoom);
+
+ /** Registers a set of rectangles that the plugin would like to keep on
+ screen. The rectangles are listed in order of priority with the highest
+ priority rectangle in location rects[0]. The browser will attempt to keep
+ as many of the rectangles on screen as possible and will scroll them into
+ view in response to the invocation of this method and other various events.
+ The count specifies how many rectangles are in the array. If the count is
+ zero it signals the plugin that any existing rectangles should be cleared
+ and no rectangles will be tracked.
+ */
+ void setVisibleRects(const ANPRectI rects[], int32_t count);
+
private:
+ void computeVisibleFrameRect();
+ void scrollToVisibleFrameRect();
+
WebCore::PluginView* m_pluginView;
android::WebViewCore* m_core;
SkFlipPixelRef* m_flipPixelRef;
ANPDrawingModel m_drawingModel;
ANPEventFlags m_eventFlags;
- int m_x;
- int m_y;
+ NPWindow* m_pluginWindow;
+ SkIRect m_visibleDocRect;
+ SkIRect m_requestedFrameRect;
+ OwnPtr<android::PluginSurface> m_surface;
+
+ /* We limit the number of rectangles to minimize storage and ensure adequate
+ speed.
+ */
+ enum {
+ MAX_REQUESTED_RECTS = 5,
+ };
+
+ ANPRectI m_requestedVisibleRect[MAX_REQUESTED_RECTS];
+ int32_t m_requestedVisibleRectCount;
};
#endif
diff --git a/WebKit/android/plugins/SurfaceCallback.h b/WebKit/android/plugins/SurfaceCallback.h
new file mode 100644
index 0000000..fb2e015
--- /dev/null
+++ b/WebKit/android/plugins/SurfaceCallback.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ * Copyright (C) 2008 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SurfaceCallback_H
+#define SurfaceCallback_H
+
+namespace android {
+
+ class SurfaceCallback {
+ public:
+ virtual ~SurfaceCallback() {}
+ virtual void surfaceCreated() = 0;
+ virtual void surfaceChanged(int format, int width, int height) = 0;
+ virtual void surfaceDestroyed() = 0;
+ };
+
+} // namespace android
+
+#endif
diff --git a/WebKit/android/plugins/android_npapi.h b/WebKit/android/plugins/android_npapi.h
index 41c1080..e50f031 100644
--- a/WebKit/android/plugins/android_npapi.h
+++ b/WebKit/android/plugins/android_npapi.h
@@ -164,7 +164,6 @@ typedef int32_t ANPDrawingModel;
enum ANPEventFlag {
kKey_ANPEventFlag = 0x01,
kTouch_ANPEventFlag = 0x02,
- kVisibleRect_ANPEventFlag = 0x04,
};
typedef uint32_t ANPEventFlags;
@@ -200,11 +199,6 @@ struct ANPBitmapInterfaceV0 : ANPInterface {
bool (*getPixelPacking)(ANPBitmapFormat, ANPPixelPacking* packing);
};
-/** The ANPSurface acts as a handle between the plugin and the native libraries
- that render the surface to the screen.
- */
-struct ANPSurface;
-
/** The surfaceType is the mechanism by which the plugin informs the native
libraries which type of surface view it wishes to use.
*/
@@ -213,6 +207,11 @@ enum ANPSurfaceTypes {
};
typedef int32_t ANPSurfaceType;
+/** The ANPSurface acts as a handle between the plugin and the native libraries
+ that render the surface to the screen.
+ */
+struct ANPSurface;
+
struct ANPSurfaceInterfaceV0 : ANPInterface {
/** Creates a new surface handle based on the given surface type. If the
given surface type is not supported then NULL is returned.
@@ -615,11 +614,20 @@ struct ANPWindowInterfaceV0 : ANPInterface {
results. If lock returned false, unlock should not be called.
*/
void (*unlock)(void* window);
- /** Given (x,y) coordinates in the document space the currently visible
- window will be shifted so that window's upper left corner will be as
- closely aligned to the coordinates as possible.
- */
- void (*scrollTo)(NPP instance, int32_t x, int32_t y);
+ /** Registers a set of rectangles that the plugin would like to keep on
+ screen. The rectangles are listed in order of priority with the highest
+ priority rectangle in location rects[0]. The browser will attempt to keep
+ as many of the rectangles on screen as possible and will scroll them into
+ view in response to the invocation of this method and other various events.
+ The count specifies how many rectangles are in the array. If the count is
+ zero it signals the browser that any existing rectangles should be cleared
+ and no rectangles will be tracked.
+ */
+ void (*setVisibleRects)(NPP instance, const ANPRectI rects[], int32_t count);
+ /** Clears any rectangles that are being tracked as a result of a call to
+ setVisibleRects. This call is equivalent to setVisibleRect(inst, NULL, 0).
+ */
+ void (*clearVisibleRects)(NPP instance);
/** Given a boolean value of true the device will be requested to provide
a keyboard. A value of false will result in a request to hide the
keyboard. Further, the on-screen keyboard will not be displayed if a
@@ -716,7 +724,7 @@ enum ANPEventTypes {
kTouch_ANPEventType = 3,
kDraw_ANPEventType = 4,
kLifecycle_ANPEventType = 5,
- kVisibleRect_ANPEventType = 6,
+ kSurface_ANPEventType = 6,
};
typedef int32_t ANPEventType;
@@ -759,6 +767,23 @@ enum ANPLifecycleActions {
};
typedef uint32_t ANPLifecycleAction;
+enum ANPSurfaceActions {
+ /** The surface has been created and is ready to be used. Any calls to
+ lock/unlock before this action will fail.
+ */
+ kCreated_ANPSurfaceAction = 0,
+ /** The surface's dimension has changed.
+ */
+ kChanged_ANPSurfaceAction = 1,
+ /** The surface has been destroyed. This happens when the view system has
+ remove the surface (possibly due to the plugin being offscreen). Calls
+ to lock/unlock will fail after this action and before
+ kCreate_ANPSurfaceAction.
+ */
+ kDestroyed_ANPSurfaceAction = 2,
+};
+typedef uint32_t ANPSurfaceAction;
+
/* This is what is passed to NPP_HandleEvent() */
struct ANPEvent {
uint32_t inSize; // size of this struct in bytes
@@ -797,9 +822,21 @@ struct ANPEvent {
} data;
} draw;
struct {
- ANPRectI rect; // in global document coordinates
- float zoomScale; // 1.0 means no zoom scale
- } visibleRect;
+ ANPSurfaceAction action;
+ /** This union is based on the value of action and contains data
+ specific to the given action.
+ */
+ union {
+ /** This struct is filled in only during the
+ kChanged_ANPSurfaceAction action. For all other actions,
+ this struct is undefined.
+ */
+ struct {
+ int32_t width;
+ int32_t height;
+ } changed;
+ } data;
+ } surface;
int32_t other[8];
} data;
};
diff --git a/WebKit/gtk/WebCoreSupport/ChromeClientGtk.cpp b/WebKit/gtk/WebCoreSupport/ChromeClientGtk.cpp
index 892be74..7125305 100644
--- a/WebKit/gtk/WebCoreSupport/ChromeClientGtk.cpp
+++ b/WebKit/gtk/WebCoreSupport/ChromeClientGtk.cpp
@@ -418,6 +418,14 @@ void ChromeClient::exceededDatabaseQuota(Frame* frame, const String&)
}
#endif
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+void ChromeClient::reachedMaxAppCacheSize(int64_t spaceNeeded)
+{
+ // FIXME: Free some space.
+ notImplemented();
+}
+#endif
+
void ChromeClient::runOpenPanel(Frame*, PassRefPtr<FileChooser> prpFileChooser)
{
RefPtr<FileChooser> chooser = prpFileChooser;
diff --git a/WebKit/gtk/WebCoreSupport/ChromeClientGtk.h b/WebKit/gtk/WebCoreSupport/ChromeClientGtk.h
index fc0ea8a..bac9940 100644
--- a/WebKit/gtk/WebCoreSupport/ChromeClientGtk.h
+++ b/WebKit/gtk/WebCoreSupport/ChromeClientGtk.h
@@ -99,6 +99,9 @@ namespace WebKit {
#if ENABLE(DATABASE)
virtual void exceededDatabaseQuota(WebCore::Frame*, const WebCore::String&);
#endif
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ virtual void reachedMaxAppCacheSize(int64_t spaceNeeded);
+#endif
virtual void runOpenPanel(WebCore::Frame*, PassRefPtr<WebCore::FileChooser>);
virtual void formStateDidChange(const WebCore::Node*) { }
diff --git a/WebKit/mac/WebCoreSupport/WebChromeClient.h b/WebKit/mac/WebCoreSupport/WebChromeClient.h
index 6c3d71e..6974cb1 100644
--- a/WebKit/mac/WebCoreSupport/WebChromeClient.h
+++ b/WebKit/mac/WebCoreSupport/WebChromeClient.h
@@ -107,6 +107,9 @@ public:
#if ENABLE(DATABASE)
virtual void exceededDatabaseQuota(WebCore::Frame*, const WebCore::String& databaseName);
#endif
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ virtual void reachedMaxAppCacheSize(int64_t spaceNeeded);
+#endif
virtual void populateVisitedLinks();
#if ENABLE(DASHBOARD_SUPPORT)
diff --git a/WebKit/mac/WebCoreSupport/WebChromeClient.mm b/WebKit/mac/WebCoreSupport/WebChromeClient.mm
index 18c73e9..2ca86d1 100644
--- a/WebKit/mac/WebCoreSupport/WebChromeClient.mm
+++ b/WebKit/mac/WebCoreSupport/WebChromeClient.mm
@@ -517,6 +517,13 @@ void WebChromeClient::exceededDatabaseQuota(Frame* frame, const String& database
END_BLOCK_OBJC_EXCEPTIONS;
}
#endif
+
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+void WebChromeClient::reachedMaxAppCacheSize(int64_t spaceNeeded)
+{
+ // FIXME: Free some space.
+}
+#endif
void WebChromeClient::populateVisitedLinks()
{
diff --git a/WebKit/mac/WebKit.exp b/WebKit/mac/WebKit.exp
index d166894..cb26943 100644
--- a/WebKit/mac/WebKit.exp
+++ b/WebKit/mac/WebKit.exp
@@ -1,3 +1,4 @@
+.objc_class_name_WebApplicationCache
.objc_class_name_WebArchive
.objc_class_name_WebBackForwardList
.objc_class_name_WebCache
diff --git a/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp b/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp
index 5df554b..5199a5a 100644
--- a/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp
+++ b/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp
@@ -399,6 +399,14 @@ void ChromeClientQt::exceededDatabaseQuota(Frame* frame, const String& databaseN
}
#endif
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+void ChromeClientQt::reachedMaxAppCacheSize(int64_t spaceNeeded)
+{
+ // FIXME: Free some space.
+ notImplemented();
+}
+#endif
+
void ChromeClientQt::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> prpFileChooser)
{
RefPtr<FileChooser> fileChooser = prpFileChooser;
diff --git a/WebKit/qt/WebCoreSupport/ChromeClientQt.h b/WebKit/qt/WebCoreSupport/ChromeClientQt.h
index 77c56fc..7922000 100644
--- a/WebKit/qt/WebCoreSupport/ChromeClientQt.h
+++ b/WebKit/qt/WebCoreSupport/ChromeClientQt.h
@@ -116,6 +116,9 @@ namespace WebCore {
#if ENABLE(DATABASE)
virtual void exceededDatabaseQuota(Frame*, const String&);
#endif
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ virtual void reachedMaxAppCacheSize(int64_t spaceNeeded);
+#endif
virtual void runOpenPanel(Frame*, PassRefPtr<FileChooser>);
virtual void formStateDidChange(const Node*) { }
diff --git a/WebKit/win/WebCoreSupport/WebChromeClient.cpp b/WebKit/win/WebCoreSupport/WebChromeClient.cpp
index 45b07cf..1f0c09c 100644
--- a/WebKit/win/WebCoreSupport/WebChromeClient.cpp
+++ b/WebKit/win/WebCoreSupport/WebChromeClient.cpp
@@ -543,6 +543,15 @@ void WebChromeClient::exceededDatabaseQuota(Frame* frame, const String& database
}
#endif
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+#include "ApplicationCacheStorage.h"
+void WebChromeClient::reachedMaxAppCacheSize(int64_t spaceNeeded)
+{
+ // FIXME: Free some space.
+ notImplemented();
+}
+#endif
+
void WebChromeClient::populateVisitedLinks()
{
WebHistory* history = WebHistory::sharedHistory();
diff --git a/WebKit/win/WebCoreSupport/WebChromeClient.h b/WebKit/win/WebCoreSupport/WebChromeClient.h
index 44c6107..4aa7422 100644
--- a/WebKit/win/WebCoreSupport/WebChromeClient.h
+++ b/WebKit/win/WebCoreSupport/WebChromeClient.h
@@ -109,6 +109,10 @@ public:
virtual void exceededDatabaseQuota(WebCore::Frame*, const WebCore::String&);
#endif
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ virtual void reachedMaxAppCacheSize(int64_t spaceNeeded);
+#endif
+
virtual void populateVisitedLinks();
virtual bool paintCustomScrollbar(WebCore::GraphicsContext*, const WebCore::FloatRect&, WebCore::ScrollbarControlSize,
diff --git a/WebKit/wx/WebKitSupport/ChromeClientWx.cpp b/WebKit/wx/WebKitSupport/ChromeClientWx.cpp
index 6dfe7a4..411f795 100644
--- a/WebKit/wx/WebKitSupport/ChromeClientWx.cpp
+++ b/WebKit/wx/WebKitSupport/ChromeClientWx.cpp
@@ -355,6 +355,13 @@ void ChromeClientWx::exceededDatabaseQuota(Frame*, const String&)
}
#endif
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+void ChromeClientWx::reachedMaxAppCacheSize(int64_t spaceNeeded)
+{
+ notImplemented();
+}
+#endif
+
void ChromeClientWx::scroll(const IntSize&, const IntRect&, const IntRect&)
{
notImplemented();
diff --git a/WebKit/wx/WebKitSupport/ChromeClientWx.h b/WebKit/wx/WebKitSupport/ChromeClientWx.h
index df1fdd8..d7f4152 100644
--- a/WebKit/wx/WebKitSupport/ChromeClientWx.h
+++ b/WebKit/wx/WebKitSupport/ChromeClientWx.h
@@ -113,6 +113,11 @@ public:
#if ENABLE(DATABASE)
virtual void exceededDatabaseQuota(Frame*, const String&);
#endif
+
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ virtual void reachedMaxAppCacheSize(int64_t spaceNeeded);
+#endif
+
virtual void runOpenPanel(Frame*, PassRefPtr<FileChooser>);
virtual void formStateDidChange(const Node*) { }