summaryrefslogtreecommitdiffstats
path: root/WebKit/android
diff options
context:
space:
mode:
Diffstat (limited to 'WebKit/android')
-rw-r--r--WebKit/android/RenderSkinAndroid.cpp2
-rw-r--r--WebKit/android/RenderSkinCombo.cpp94
-rw-r--r--WebKit/android/RenderSkinCombo.h20
-rwxr-xr-xWebKit/android/jni/MockGeolocation.cpp2
-rw-r--r--WebKit/android/jni/WebViewCore.cpp74
-rw-r--r--WebKit/android/jni/WebViewCore.h6
-rw-r--r--WebKit/android/nav/CachedFrame.cpp29
-rw-r--r--WebKit/android/nav/CachedFrame.h12
-rw-r--r--WebKit/android/nav/CachedRoot.cpp9
-rw-r--r--WebKit/android/nav/CachedRoot.h8
-rw-r--r--WebKit/android/nav/WebView.cpp22
-rw-r--r--WebKit/android/plugins/ANPSurfaceInterface.cpp2
-rw-r--r--WebKit/android/plugins/PluginTimer.cpp19
-rw-r--r--WebKit/android/plugins/PluginTimer.h3
14 files changed, 192 insertions, 110 deletions
diff --git a/WebKit/android/RenderSkinAndroid.cpp b/WebKit/android/RenderSkinAndroid.cpp
index d148262..31c327a 100644
--- a/WebKit/android/RenderSkinAndroid.cpp
+++ b/WebKit/android/RenderSkinAndroid.cpp
@@ -45,7 +45,7 @@ RenderSkinAndroid::RenderSkinAndroid()
void RenderSkinAndroid::Init(android::AssetManager* am, String drawableDirectory)
{
RenderSkinButton::Init(am, drawableDirectory);
- RenderSkinCombo::Init(am);
+ RenderSkinCombo::Init(am, drawableDirectory);
RenderSkinRadio::Init(am, drawableDirectory);
}
diff --git a/WebKit/android/RenderSkinCombo.cpp b/WebKit/android/RenderSkinCombo.cpp
index 6f88ee3..4378371 100644
--- a/WebKit/android/RenderSkinCombo.cpp
+++ b/WebKit/android/RenderSkinCombo.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "RenderSkinCombo.h"
+#include "CString.h"
#include "Document.h"
#include "Element.h"
#include "Node.h"
@@ -36,43 +37,85 @@
namespace WebCore {
-static SkBitmap s_bitmap[2]; // Collection of assets for a combo box
-static bool s_decoded; // True if all assets were decoded
-static const int s_margin = 2;
-static const SkIRect s_mar = { s_margin, s_margin,
- RenderSkinCombo::extraWidth(), s_margin };
-static SkIRect s_subset;
+// Indicates if the entire asset is being drawn, or if the border is being
+// excluded and just the arrow drawn.
+enum BorderStyle {
+ FullAsset,
+ NoBorder
+};
+// There are 2.5 different concepts of a 'border' here, which results
+// in rather a lot of magic constants. In each case, there are 2
+// numbers, one for medium res and one for high-res. All sizes are in pixels.
-RenderSkinCombo::RenderSkinCombo()
-{
-}
+// Firstly, we have the extra padding that webkit needs to know about,
+// which defines how much bigger this element is made by the
+// asset. This is actually a bit broader than the actual border on the
+// asset, to make things look less cramped. The border is the same
+// width on all sides, except on the right when it's significantly
+// wider to allow for the arrow.
+const int RenderSkinCombo::arrowMargin[2] = {22, 34};
+const int RenderSkinCombo::padMargin[2] = {2, 5};
+
+// Then we have the borders used for the 9-patch stretch. The
+// rectangle at the centre of these borders is entirely below and to
+// the left of the arrow in the asset. Hence the border widths are the
+// same for the bottom and left, but are different for the top. The
+// right hand border width happens to be the same as arrowMargin
+// defined above.
+static const int stretchMargin[2] = {3, 5}; // border width for the bottom and left of the 9-patch
+static const int stretchTop[2] = {15, 23}; // border width for the top of the 9-patch
+
+// Finally, if the border is defined by the CSS, we only draw the
+// arrow and not the border. We do this by drawing the relevant subset
+// of the bitmap, which must now be precisely determined by what's in
+// the asset with no extra padding to make things look properly
+// spaced. The border to remove at the top, right and bottom of the
+// image is the same as stretchMargin above, but we need to know the width
+// of the arrow.
+static const int arrowWidth[2] = {22, 31};
+
+RenderSkinCombo::Resolution RenderSkinCombo::resolution = MedRes;
+
+const SkIRect RenderSkinCombo::margin[2][2] = {{{ stretchMargin[MedRes], stretchTop[MedRes],
+ RenderSkinCombo::arrowMargin[MedRes] + stretchMargin[MedRes], stretchMargin[MedRes] },
+ {0, stretchTop[MedRes], 0, stretchMargin[MedRes]}},
+ {{ stretchMargin[HighRes], stretchTop[HighRes],
+ RenderSkinCombo::arrowMargin[HighRes] + stretchMargin[HighRes], stretchMargin[HighRes] },
+ {0, stretchTop[HighRes], 0, stretchMargin[HighRes]}}};
+static SkBitmap bitmaps[2][2]; // Collection of assets for a combo box
+static bool isDecoded; // True if all assets were decoded
-void RenderSkinCombo::Init(android::AssetManager* am)
+void RenderSkinCombo::Init(android::AssetManager* am, String drawableDirectory)
{
- if (s_decoded)
+ if (isDecoded)
return;
- // Maybe short circuiting is fine, since I don't even draw if one state is not decoded properly
- // but is that necessary in the final version?
- s_decoded = RenderSkinAndroid::DecodeBitmap(am, "images/combobox-noHighlight.png", &s_bitmap[kNormal]);
- s_decoded = RenderSkinAndroid::DecodeBitmap(am, "images/combobox-disabled.png", &s_bitmap[kDisabled]) && s_decoded;
-
- int width = s_bitmap[kNormal].width();
- int height = s_bitmap[kNormal].height();
- s_subset.set(width - RenderSkinCombo::extraWidth() + s_margin, 0, width, height);
+
+ if (drawableDirectory[drawableDirectory.length() - 5] == 'h')
+ resolution = HighRes;
+
+ isDecoded = RenderSkinAndroid::DecodeBitmap(am, (drawableDirectory + "combobox_nohighlight.png").utf8().data(), &bitmaps[kNormal][FullAsset]);
+ isDecoded &= RenderSkinAndroid::DecodeBitmap(am, (drawableDirectory + "combobox_disabled.png").utf8().data(), &bitmaps[kDisabled][FullAsset]);
+
+ int width = bitmaps[kNormal][FullAsset].width();
+ int height = bitmaps[kNormal][FullAsset].height();
+ SkIRect subset;
+ subset.set(width - arrowWidth[resolution], 0, width, height);
+ bitmaps[kNormal][FullAsset].extractSubset(&bitmaps[kNormal][NoBorder], subset);
+ bitmaps[kDisabled][FullAsset].extractSubset(&bitmaps[kDisabled][NoBorder], subset);
}
bool RenderSkinCombo::Draw(SkCanvas* canvas, Node* element, int x, int y, int width, int height)
{
- if (!s_decoded)
+ if (!isDecoded)
return true;
State state = (element->isElementNode() && static_cast<Element*>(element)->isEnabledFormControl()) ? kNormal : kDisabled;
- if (height < (s_margin<<1) + 1) {
- height = (s_margin<<1) + 1;
- }
+ height = std::max(height, (stretchMargin[resolution]<<1) + 1);
+
SkRect bounds;
+ BorderStyle drawBorder = FullAsset;
bounds.set(SkIntToScalar(x+1), SkIntToScalar(y+1), SkIntToScalar(x + width-1), SkIntToScalar(y + height-1));
RenderStyle* style = element->renderStyle();
@@ -90,10 +133,9 @@ bool RenderSkinCombo::Draw(SkCanvas* canvas, Node* element, int x, int y, int wi
bounds.fRight -= SkIntToScalar(style->borderRightWidth());
bounds.fTop += SkIntToScalar(style->borderTopWidth());
bounds.fBottom -= SkIntToScalar(style->borderBottomWidth());
- canvas->drawBitmapRect(s_bitmap[state], &s_subset, bounds);
- } else {
- SkNinePatch::DrawNine(canvas, bounds, s_bitmap[state], s_mar);
+ drawBorder = NoBorder;
}
+ SkNinePatch::DrawNine(canvas, bounds, bitmaps[state][drawBorder], margin[resolution][drawBorder]);
return false;
}
diff --git a/WebKit/android/RenderSkinCombo.h b/WebKit/android/RenderSkinCombo.h
index 91c9367..38cd048 100644
--- a/WebKit/android/RenderSkinCombo.h
+++ b/WebKit/android/RenderSkinCombo.h
@@ -37,13 +37,10 @@ namespace WebCore {
class RenderSkinCombo : public RenderSkinAndroid
{
public:
- RenderSkinCombo();
- virtual ~RenderSkinCombo() {}
-
/**
* Initialize the class before use. Uses the AssetManager to initialize any bitmaps the class may use.
*/
- static void Init(android::AssetManager*);
+ static void Init(android::AssetManager*, String drawableDirectory);
/**
* Draw the provided Node on the SkCanvas, using the dimensions provided by
@@ -53,11 +50,18 @@ public:
static bool Draw(SkCanvas* , Node* , int x, int y, int w, int h);
// The image is wider than the RenderObject, so this accounts for that.
- static int extraWidth() { return arrowMargin; }
-
+ static int extraWidth() { return arrowMargin[resolution]; }
+ static int padding() { return padMargin[resolution]; }
+
+ enum Resolution {
+ MedRes,
+ HighRes
+ };
private:
-
- static const int arrowMargin = 22;
+ static Resolution resolution;
+ const static int arrowMargin[2];
+ const static int padMargin[2];
+ const static SkIRect margin[2][2];
};
} // WebCore
diff --git a/WebKit/android/jni/MockGeolocation.cpp b/WebKit/android/jni/MockGeolocation.cpp
index df580c3..1c236c3 100755
--- a/WebKit/android/jni/MockGeolocation.cpp
+++ b/WebKit/android/jni/MockGeolocation.cpp
@@ -53,7 +53,7 @@ static void setPosition(JNIEnv* env, jobject, double latitude, double longitude,
false, 0.0, // altitudeAccuracy,
false, 0.0, // heading
false, 0.0); // speed
- RefPtr<Geoposition> position = Geoposition::create(coordinates.release(), WTF::currentTime());
+ RefPtr<Geoposition> position = Geoposition::create(coordinates.release(), WTF::currentTimeMS());
GeolocationServiceMock::setPosition(position.release());
}
diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp
index 8dc58d2..14fd44e 100644
--- a/WebKit/android/jni/WebViewCore.cpp
+++ b/WebKit/android/jni/WebViewCore.cpp
@@ -252,6 +252,7 @@ struct WebViewCore::JavaGlue {
jmethodID m_sendFindAgain;
jmethodID m_showRect;
jmethodID m_centerFitRect;
+ jmethodID m_setScrollbarModes;
AutoJObject object(JNIEnv* env) {
return getRealObject(env, m_obj);
}
@@ -342,6 +343,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m
m_javaGlue->m_sendFindAgain = GetJMethod(env, clazz, "sendFindAgain", "()V");
m_javaGlue->m_showRect = GetJMethod(env, clazz, "showRect", "(IIIIIIFFFF)V");
m_javaGlue->m_centerFitRect = GetJMethod(env, clazz, "centerFitRect", "(IIII)V");
+ m_javaGlue->m_setScrollbarModes = GetJMethod(env, clazz, "setScrollbarModes", "(II)V");
env->SetIntField(javaWebViewCore, gWebViewCoreFields.m_nativeClass, (jint)this);
@@ -1220,37 +1222,37 @@ void WebViewCore::setSizeScreenWidthAndScale(int width, int height,
r->setNeedsLayoutAndPrefWidthsRecalc();
m_mainFrame->view()->forceLayout();
// scroll to restore current screen center
- if (!node)
- return;
- const WebCore::IntRect& newBounds = node->getRect();
- DBG_NAV_LOGD("nb:(x=%d,y=%d,w=%d,"
- "h=%d)", newBounds.x(), newBounds.y(),
- newBounds.width(), newBounds.height());
- if ((orsw && osh && bounds.width() && bounds.height())
- && (bounds != newBounds)) {
- WebCore::FrameView* view = m_mainFrame->view();
- // force left align if width is not changed while height changed.
- // the anchorPoint is probably at some white space in the node
- // which is affected by text wrap around the screen width.
- const bool leftAlign = (osw != m_screenWidth)
- && (bounds.width() == newBounds.width())
- && (bounds.height() != newBounds.height());
- const float xPercentInDoc =
- leftAlign ? 0.0 : (float) (anchorX - bounds.x()) / bounds.width();
- const float xPercentInView =
- leftAlign ? 0.0 : (float) (anchorX - m_scrollOffsetX) / orsw;
- const float yPercentInDoc = (float) (anchorY - bounds.y()) / bounds.height();
- const float yPercentInView = (float) (anchorY - m_scrollOffsetY) / osh;
- showRect(newBounds.x(), newBounds.y(), newBounds.width(),
- newBounds.height(), view->contentsWidth(),
- view->contentsHeight(),
- xPercentInDoc, xPercentInView,
- yPercentInDoc, yPercentInView);
+ if (node) {
+ const WebCore::IntRect& newBounds = node->getRect();
+ DBG_NAV_LOGD("nb:(x=%d,y=%d,w=%d,"
+ "h=%d)", newBounds.x(), newBounds.y(),
+ newBounds.width(), newBounds.height());
+ if ((orsw && osh && bounds.width() && bounds.height())
+ && (bounds != newBounds)) {
+ WebCore::FrameView* view = m_mainFrame->view();
+ // force left align if width is not changed while height changed.
+ // the anchorPoint is probably at some white space in the node
+ // which is affected by text wrap around the screen width.
+ const bool leftAlign = (osw != m_screenWidth)
+ && (bounds.width() == newBounds.width())
+ && (bounds.height() != newBounds.height());
+ const float xPercentInDoc =
+ leftAlign ? 0.0 : (float) (anchorX - bounds.x()) / bounds.width();
+ const float xPercentInView =
+ leftAlign ? 0.0 : (float) (anchorX - m_scrollOffsetX) / orsw;
+ const float yPercentInDoc = (float) (anchorY - bounds.y()) / bounds.height();
+ const float yPercentInView = (float) (anchorY - m_scrollOffsetY) / osh;
+ showRect(newBounds.x(), newBounds.y(), newBounds.width(),
+ newBounds.height(), view->contentsWidth(),
+ view->contentsHeight(),
+ xPercentInDoc, xPercentInView,
+ yPercentInDoc, yPercentInView);
+ }
}
}
}
- // update the currently visible screen
+ // update the currently visible screen as perceived by the plugin
sendPluginVisibleScreen();
}
@@ -1528,6 +1530,10 @@ void WebViewCore::notifyPluginsOnFrameLoad(const Frame* frame) {
void WebViewCore::sendPluginVisibleScreen()
{
+ /* We may want to cache the previous values and only send the notification
+ to the plugin in the event that one of the values has changed.
+ */
+
ANPRectI visibleRect;
visibleRect.left = m_scrollOffsetX;
visibleRect.top = m_scrollOffsetY;
@@ -2069,11 +2075,6 @@ bool WebViewCore::handleTouchEvent(int action, int x, int y, int metaState)
// Track previous touch and if stationary set the state.
WebCore::IntPoint pt(x - m_scrollOffsetX, y - m_scrollOffsetY);
- if (type == WebCore::TouchMove && pt == m_lastTouchPoint)
- touchState = WebCore::PlatformTouchPoint::TouchStationary;
-
- m_lastTouchPoint = pt;
-
WebCore::PlatformTouchEvent te(pt, type, touchState, metaState);
preventDefault = m_mainFrame->eventHandler()->handleTouchEvent(te);
#endif
@@ -2524,6 +2525,15 @@ void WebViewCore::centerFitRect(int x, int y, int width, int height)
checkException(env);
}
+
+void WebViewCore::setScrollbarModes(ScrollbarMode horizontalMode, ScrollbarMode verticalMode)
+{
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_setScrollbarModes,
+ horizontalMode, verticalMode);
+ checkException(env);
+}
+
//----------------------------------------------------------------------
// Native JNI methods
//----------------------------------------------------------------------
diff --git a/WebKit/android/jni/WebViewCore.h b/WebKit/android/jni/WebViewCore.h
index 8c885e6..4ed17bf 100644
--- a/WebKit/android/jni/WebViewCore.h
+++ b/WebKit/android/jni/WebViewCore.h
@@ -249,6 +249,11 @@ namespace android {
void addMessageToConsole(const String& message, unsigned int lineNumber, const String& sourceID, int msgLevel);
+ /**
+ * Tell the Java side of the scrollbar mode
+ */
+ void setScrollbarModes(ScrollbarMode horizontalMode, ScrollbarMode verticalMode);
+
//
// Followings support calls from Java to native WebCore
//
@@ -553,7 +558,6 @@ namespace android {
#if ENABLE(TOUCH_EVENTS)
bool m_forwardingTouchEvents;
- IntPoint m_lastTouchPoint;
#endif
#if DEBUG_NAV_UI
diff --git a/WebKit/android/nav/CachedFrame.cpp b/WebKit/android/nav/CachedFrame.cpp
index 21a4115..ce5600b 100644
--- a/WebKit/android/nav/CachedFrame.cpp
+++ b/WebKit/android/nav/CachedFrame.cpp
@@ -928,28 +928,27 @@ int CachedFrame::maxWorkingVertical() const
}
const CachedNode* CachedFrame::nextTextField(const CachedNode* start,
- const CachedFrame** framePtr) const
+ const CachedFrame** framePtr, bool* startFound) const
{
- CachedNode* test;
- if (start) {
- test = const_cast<CachedNode*>(start);
- test++;
- } else {
- test = const_cast<CachedNode*>(mCachedNodes.begin());
- }
- while (test != mCachedNodes.end()) {
- CachedFrame* frame = const_cast<CachedFrame*>(hasFrame(test));
+ const CachedNode* test = mCachedNodes.begin();
+ while ((test = test->traverseNextNode())) {
+ const CachedFrame* frame = hasFrame(test);
if (frame) {
+ if (!frame->validDocument())
+ continue;
const CachedNode* node
- = frame->nextTextField(0, framePtr);
+ = frame->nextTextField(start, framePtr, startFound);
if (node)
return node;
} else if (test->isTextInput()) {
- if (framePtr)
- *framePtr = this;
- return test;
+ if (test == start)
+ *startFound = true;
+ else if (*startFound) {
+ if (framePtr)
+ *framePtr = this;
+ return test;
+ }
}
- test++;
}
return 0;
}
diff --git a/WebKit/android/nav/CachedFrame.h b/WebKit/android/nav/CachedFrame.h
index ed76583..9334707 100644
--- a/WebKit/android/nav/CachedFrame.h
+++ b/WebKit/android/nav/CachedFrame.h
@@ -120,16 +120,6 @@ public:
#endif
WebCore::IntRect localBounds(const CachedNode* ,
const WebCore::IntRect& ) const;
- /**
- * Find the next textfield/textarea
- * @param start Must be a CachedNode in this CachedFrame's tree, or
- * null, in which case we start from the beginning.
- * @param framePtr If not null, and a textfield/textarea is found, its
- * CachedFrame will be pointed to by this pointer.
- * @return CachedNode* Next textfield (or area)
- */
- const CachedNode* nextTextField(const CachedNode* start,
- const CachedFrame** framePtr) const;
const CachedFrame* parent() const { return mParent; }
CachedFrame* parent() { return mParent; }
SkPicture* picture(const CachedNode* ) const;
@@ -152,6 +142,8 @@ public:
}
const CachedNode* validDocument() const;
protected:
+ const CachedNode* nextTextField(const CachedNode* start,
+ const CachedFrame** framePtr, bool* found) const;
struct BestData {
int mDistance;
int mSideDistance;
diff --git a/WebKit/android/nav/CachedRoot.cpp b/WebKit/android/nav/CachedRoot.cpp
index 71c0993..2d37a2a 100644
--- a/WebKit/android/nav/CachedRoot.cpp
+++ b/WebKit/android/nav/CachedRoot.cpp
@@ -1083,7 +1083,7 @@ WebCore::String CachedRoot::imageURI(int x, int y) const
bool CachedRoot::maskIfHidden(BestData* best) const
{
const CachedNode* bestNode = best->mNode;
- if (bestNode->isUnclipped())
+ if (bestNode->isUnclipped() || bestNode->isTransparent())
return false;
const CachedFrame* frame = best->mFrame;
SkPicture* picture = frame->picture(bestNode);
@@ -1288,6 +1288,13 @@ const CachedNode* CachedRoot::moveCursor(Direction direction, const CachedFrame*
return const_cast<CachedNode*>(bestData.mNode);
}
+const CachedNode* CachedRoot::nextTextField(const CachedNode* start,
+ const CachedFrame** framePtr) const
+{
+ bool startFound = false;
+ return CachedFrame::nextTextField(start, framePtr, &startFound);
+}
+
SkPicture* CachedRoot::pictureAt(int x, int y) const
{
#if USE(ACCELERATED_COMPOSITING)
diff --git a/WebKit/android/nav/CachedRoot.h b/WebKit/android/nav/CachedRoot.h
index 735f23b..6e9fff0 100644
--- a/WebKit/android/nav/CachedRoot.h
+++ b/WebKit/android/nav/CachedRoot.h
@@ -75,6 +75,14 @@ public:
WebCore::String imageURI(int x, int y) const;
bool maskIfHidden(BestData* ) const;
const CachedNode* moveCursor(Direction , const CachedFrame** , WebCore::IntPoint* scroll);
+ /**
+ * Find the next textfield/textarea
+ * @param start The textfield/textarea to search from.
+ * @param framePtr If non-zero, returns CachedFrame* containing result.
+ * @return CachedNode* Next textfield/textarea or null (0) if none.
+ */
+ const CachedNode* nextTextField(const CachedNode* start,
+ const CachedFrame** framePtr) const;
SkPicture* pictureAt(int x, int y) const;
void reset();
CachedHistory* rootHistory() const { return mHistory; }
diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp
index 0ac6bd6..bdcafbf 100644
--- a/WebKit/android/nav/WebView.cpp
+++ b/WebKit/android/nav/WebView.cpp
@@ -1223,10 +1223,15 @@ static const CachedNode* getFocusCandidate(JNIEnv *env, jobject obj,
static bool focusCandidateHasNextTextfield(JNIEnv *env, jobject obj)
{
- const CachedFrame* frame;
- const CachedNode* cursor = getFocusCandidate(env, obj, &frame);
+ WebView* view = GET_NATIVE_VIEW(env, obj);
+ CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer);
+ if (!root)
+ return false;
+ const CachedNode* cursor = root->currentCursor();
+ if (!cursor || !cursor->isTextInput())
+ cursor = root->currentFocus();
if (!cursor || !cursor->isTextInput()) return false;
- return frame->nextTextField(cursor, 0);
+ return root->nextTextField(cursor, 0);
}
static const CachedNode* getFocusNode(JNIEnv *env, jobject obj)
@@ -1760,14 +1765,13 @@ static bool nativeMoveCursorToNextTextInput(JNIEnv *env, jobject obj)
CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer);
if (!root)
return false;
- const CachedFrame* containingFrame;
- const CachedNode* current = root->currentCursor(&containingFrame);
- if (!current)
- current = root->currentFocus(&containingFrame);
- if (!current)
+ const CachedNode* current = root->currentCursor();
+ if (!current || !current->isTextInput())
+ current = root->currentFocus();
+ if (!current || !current->isTextInput())
return false;
const CachedFrame* frame;
- const CachedNode* next = containingFrame->nextTextField(current, &frame);
+ const CachedNode* next = root->nextTextField(current, &frame);
if (!next)
return false;
const WebCore::IntRect& bounds = next->bounds(frame);
diff --git a/WebKit/android/plugins/ANPSurfaceInterface.cpp b/WebKit/android/plugins/ANPSurfaceInterface.cpp
index cb32ed5..c78fe32 100644
--- a/WebKit/android/plugins/ANPSurfaceInterface.cpp
+++ b/WebKit/android/plugins/ANPSurfaceInterface.cpp
@@ -64,7 +64,7 @@ static inline sp<Surface> getSurface(JNIEnv* env, jobject view) {
jclass surfaceClass = env->FindClass("android/view/Surface");
gSurfaceJavaGlue.surfacePointer = env->GetFieldID(surfaceClass,
- "mSurface", "I");
+ ANDROID_VIEW_SURFACE_JNI_ID, "I");
env->DeleteLocalRef(surfaceClass);
env->DeleteLocalRef(surfaceViewClass);
diff --git a/WebKit/android/plugins/PluginTimer.cpp b/WebKit/android/plugins/PluginTimer.cpp
index cdcde9c..a813d25 100644
--- a/WebKit/android/plugins/PluginTimer.cpp
+++ b/WebKit/android/plugins/PluginTimer.cpp
@@ -36,7 +36,8 @@ namespace WebCore {
: m_list(list),
m_instance(instance),
m_timerFunc(timerFunc),
- m_repeat(repeat)
+ m_repeat(repeat),
+ m_unscheduled(false)
{
m_timerID = ++gTimerID;
@@ -62,10 +63,11 @@ namespace WebCore {
void PluginTimer::fired()
{
- m_timerFunc(m_instance, m_timerID);
- if (!m_repeat) {
+ if (!m_unscheduled)
+ m_timerFunc(m_instance, m_timerID);
+
+ if (!m_repeat || m_unscheduled)
delete this;
- }
}
// may return null if timerID is not found
@@ -106,7 +108,14 @@ namespace WebCore {
void PluginTimerList::unschedule(NPP instance, uint32 timerID)
{
- delete PluginTimer::Find(m_list, timerID);
+ // Although it looks like simply deleting the timer would work here
+ // (stop() will be executed by the dtor), we cannot do this, as
+ // the plugin can call us while we are in the fired() method,
+ // (when we execute the timerFunc callback). Deleting the object
+ // we are in would then be a rather bad move...
+ PluginTimer* timer = PluginTimer::Find(m_list, timerID);
+ if (timer)
+ timer->unschedule();
}
} // namespace WebCore
diff --git a/WebKit/android/plugins/PluginTimer.h b/WebKit/android/plugins/PluginTimer.h
index 3fbe728..2ffe437 100644
--- a/WebKit/android/plugins/PluginTimer.h
+++ b/WebKit/android/plugins/PluginTimer.h
@@ -42,6 +42,8 @@ namespace WebCore {
uint32 timerID() const { return m_timerID; }
+ void unschedule() { m_unscheduled = true; }
+
static PluginTimer* Find(PluginTimer* list, uint32 timerID);
private:
@@ -58,6 +60,7 @@ namespace WebCore {
void (*m_timerFunc)(NPP, uint32);
uint32 m_timerID;
bool m_repeat;
+ bool m_unscheduled;
};
class PluginTimerList {