From daa8318de3c63a28eccb52546c230e5c5caee962 Mon Sep 17 00:00:00 2001 From: Grace Kloba Date: Fri, 2 Oct 2009 17:38:57 -0700 Subject: [PATCH] DO NOT MERGE. This is cherry picked from https://android-git.corp.google.com/g/#change,28737 Fix http://b/issue?id=2304741 Add check null of getRealObject(). When a WebView is removed, there is a slight chance that getRealObject() for WebView's JavaObject be null. Fix http://b/issue?id=2159815 --- WebKit/android/jni/JavaBridge.cpp | 23 +++- WebKit/android/jni/WebCoreFrameBridge.cpp | 96 ++++++++++--- WebKit/android/jni/WebViewCore.cpp | 222 +++++++++++++++++++++++++----- WebKit/android/nav/WebView.cpp | 112 ++++++++++++--- 4 files changed, 372 insertions(+), 81 deletions(-) diff --git a/WebKit/android/jni/JavaBridge.cpp b/WebKit/android/jni/JavaBridge.cpp index 3f9a056f8..f1b532d2f 100644 --- a/WebKit/android/jni/JavaBridge.cpp +++ b/WebKit/android/jni/JavaBridge.cpp @@ -167,6 +167,8 @@ JavaBridge::setSharedTimer(long long timemillis) { JNIEnv* env = JSC::Bindings::getJNIEnv(); AutoJObject obj = getRealObject(env, mJavaObject); + if (!obj.get()) + return; env->CallVoidMethod(obj.get(), mSetSharedTimer, timemillis); } @@ -175,6 +177,8 @@ JavaBridge::stopSharedTimer() { JNIEnv* env = JSC::Bindings::getJNIEnv(); AutoJObject obj = getRealObject(env, mJavaObject); + if (!obj.get()) + return; env->CallVoidMethod(obj.get(), mStopSharedTimer); } @@ -182,11 +186,13 @@ void JavaBridge::setCookies(WebCore::KURL const& url, WebCore::String const& value) { JNIEnv* env = JSC::Bindings::getJNIEnv(); + AutoJObject obj = getRealObject(env, mJavaObject); + if (!obj.get()) + return; const WebCore::String& urlStr = url.string(); jstring jUrlStr = env->NewString(urlStr.characters(), urlStr.length()); jstring jValueStr = env->NewString(value.characters(), value.length()); - AutoJObject obj = getRealObject(env, mJavaObject); env->CallVoidMethod(obj.get(), mSetCookies, jUrlStr, jValueStr); env->DeleteLocalRef(jUrlStr); env->DeleteLocalRef(jValueStr); @@ -197,9 +203,10 @@ JavaBridge::cookies(WebCore::KURL const& url) { JNIEnv* env = JSC::Bindings::getJNIEnv(); const WebCore::String& urlStr = url.string(); - jstring jUrlStr = env->NewString(urlStr.characters(), urlStr.length()); - AutoJObject obj = getRealObject(env, mJavaObject); + if (!obj.get()) + return WebCore::String(); + jstring jUrlStr = env->NewString(urlStr.characters(), urlStr.length()); jstring string = (jstring)(env->CallObjectMethod(obj.get(), mCookies, jUrlStr)); WebCore::String ret = to_string(env, string); @@ -213,6 +220,8 @@ JavaBridge::cookiesEnabled() { JNIEnv* env = JSC::Bindings::getJNIEnv(); AutoJObject obj = getRealObject(env, mJavaObject); + if (!obj.get()) + return false; jboolean ret = env->CallBooleanMethod(obj.get(), mCookiesEnabled); return (ret != 0); } @@ -223,6 +232,8 @@ JavaBridge::getPluginDirectories() WTF::Vector directories; JNIEnv* env = JSC::Bindings::getJNIEnv(); AutoJObject obj = getRealObject(env, mJavaObject); + if (!obj.get()) + return directories; jobjectArray array = (jobjectArray) env->CallObjectMethod(obj.get(), mGetPluginDirectories); int count = env->GetArrayLength(array); @@ -241,6 +252,8 @@ JavaBridge::getPluginSharedDataDirectory() { JNIEnv* env = JSC::Bindings::getJNIEnv(); AutoJObject obj = getRealObject(env, mJavaObject); + if (!obj.get()) + return WebCore::String(); jstring ret = (jstring)env->CallObjectMethod(obj.get(), mGetPluginSharedDataDirectory); WebCore::String path = to_string(env, ret); checkException(env); @@ -263,6 +276,8 @@ void JavaBridge::signalServiceFuncPtrQueue() // environment is setup. JNIEnv* env = JSC::Bindings::getJNIEnv(); AutoJObject obj = getRealObject(env, mJavaObject); + if (!obj.get()) + return; env->CallVoidMethod(obj.get(), mSignalFuncPtrQueue); } @@ -270,6 +285,8 @@ WTF::VectorJavaBridge::getSupportedKeyStrengthList() { WTF::Vector list; JNIEnv* env = JSC::Bindings::getJNIEnv(); AutoJObject obj = getRealObject(env, mJavaObject); + if (!obj.get()) + return list; jobjectArray array = (jobjectArray) env->CallObjectMethod(obj.get(), mGetKeyStrengthList); int count = env->GetArrayLength(array); diff --git a/WebKit/android/jni/WebCoreFrameBridge.cpp b/WebKit/android/jni/WebCoreFrameBridge.cpp index 298144100..745cc575c 100644 --- a/WebKit/android/jni/WebCoreFrameBridge.cpp +++ b/WebKit/android/jni/WebCoreFrameBridge.cpp @@ -289,6 +289,10 @@ WebFrame::startLoadingResource(WebCore::ResourceHandle* loader, WebCore::HTTPHeaderMap headers = request.httpHeaderFields(); JNIEnv* env = JSC::Bindings::getJNIEnv(); + AutoJObject obj = mJavaFrame->frame(env); + if (!obj.get()) + return 0; + WebCore::String urlStr = request.url().string(); int colon = urlStr.find(':'); bool allLower = true; @@ -373,7 +377,7 @@ WebFrame::startLoadingResource(WebCore::ResourceHandle* loader, jobject jLoadListener = - env->CallObjectMethod(mJavaFrame->frame(env).get(), mJavaFrame->mStartLoadingResource, + env->CallObjectMethod(obj.get(), mJavaFrame->mStartLoadingResource, (int)loader, jUrlStr, jMethodStr, jHeaderMap, jPostDataStr, cacheMode, synchronous); @@ -400,10 +404,13 @@ WebFrame::reportError(int errorCode, const WebCore::String& description, #endif LOGV("::WebCore:: reportError(%d, %s)", errorCode, description.ascii().data()); JNIEnv* env = JSC::Bindings::getJNIEnv(); + AutoJObject obj = mJavaFrame->frame(env); + if (!obj.get()) + return; jstring descStr = env->NewString((unsigned short*)description.characters(), description.length()); jstring failUrl = env->NewString((unsigned short*)failingUrl.characters(), failingUrl.length()); - env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mReportError, errorCode, descStr, failUrl); + env->CallVoidMethod(obj.get(), mJavaFrame->mReportError, errorCode, descStr, failUrl); env->DeleteLocalRef(descStr); env->DeleteLocalRef(failUrl); } @@ -429,6 +436,9 @@ WebFrame::loadStarted(WebCore::Frame* frame) return; JNIEnv* env = JSC::Bindings::getJNIEnv(); + AutoJObject obj = mJavaFrame->frame(env); + if (!obj.get()) + return; WebCore::String urlString(url.string()); // If this is the main frame and we already have a favicon in the database, // send it along with the page started notification. @@ -441,7 +451,7 @@ WebFrame::loadStarted(WebCore::Frame* frame) } jstring urlStr = env->NewString((unsigned short*)urlString.characters(), urlString.length()); - env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mLoadStarted, urlStr, favicon, + env->CallVoidMethod(obj.get(), mJavaFrame->mLoadStarted, urlStr, favicon, (int)loadType, isMainFrame); checkException(env); env->DeleteLocalRef(urlStr); @@ -466,9 +476,12 @@ WebFrame::transitionToCommitted(WebCore::Frame* frame) TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); #endif JNIEnv* env = JSC::Bindings::getJNIEnv(); + AutoJObject obj = mJavaFrame->frame(env); + if (!obj.get()) + return; WebCore::FrameLoadType loadType = frame->loader()->loadType(); bool isMainFrame = (!frame->tree() || !frame->tree()->parent()); - env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mTransitionToCommitted, + env->CallVoidMethod(obj.get(), mJavaFrame->mTransitionToCommitted, (int)loadType, isMainFrame); checkException(env); } @@ -480,6 +493,9 @@ WebFrame::didFinishLoad(WebCore::Frame* frame) TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); #endif JNIEnv* env = JSC::Bindings::getJNIEnv(); + AutoJObject obj = mJavaFrame->frame(env); + if (!obj.get()) + return; WebCore::FrameLoader* loader = frame->loader(); const WebCore::KURL& url = loader->activeDocumentLoader()->url(); if (url.isEmpty()) @@ -490,7 +506,7 @@ WebFrame::didFinishLoad(WebCore::Frame* frame) WebCore::FrameLoadType loadType = loader->loadType(); WebCore::String urlString(url.string()); jstring urlStr = env->NewString((unsigned short*)urlString.characters(), urlString.length()); - env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mLoadFinished, urlStr, + env->CallVoidMethod(obj.get(), mJavaFrame->mLoadFinished, urlStr, (int)loadType, isMainFrame); checkException(env); env->DeleteLocalRef(urlStr); @@ -539,9 +555,12 @@ WebFrame::setTitle(const WebCore::String& title) LOGV("setTitle(%s)", title.ascii().data()); #endif JNIEnv* env = JSC::Bindings::getJNIEnv(); + AutoJObject obj = mJavaFrame->frame(env); + if (!obj.get()) + return; jstring jTitleStr = env->NewString((unsigned short *)title.characters(), title.length()); - env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mSetTitle, + env->CallVoidMethod(obj.get(), mJavaFrame->mSetTitle, jTitleStr); checkException(env); env->DeleteLocalRef(jTitleStr); @@ -555,8 +574,11 @@ WebFrame::windowObjectCleared(WebCore::Frame* frame) #endif LOGV("::WebCore:: windowObjectCleared"); JNIEnv* env = JSC::Bindings::getJNIEnv(); + AutoJObject obj = mJavaFrame->frame(env); + if (!obj.get()) + return; - env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mWindowObjectCleared, (int)frame); + env->CallVoidMethod(obj.get(), mJavaFrame->mWindowObjectCleared, (int)frame); checkException(env); } @@ -567,8 +589,11 @@ WebFrame::setProgress(float newProgress) TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); #endif JNIEnv* env = JSC::Bindings::getJNIEnv(); + AutoJObject obj = mJavaFrame->frame(env); + if (!obj.get()) + return; int progress = (int) (100 * newProgress); - env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mSetProgress, progress); + env->CallVoidMethod(obj.get(), mJavaFrame->mSetProgress, progress); checkException(env); } @@ -586,11 +611,14 @@ WebFrame::didReceiveIcon(WebCore::Image* icon) #endif LOG_ASSERT(icon, "DidReceiveIcon called without an image!"); JNIEnv* env = JSC::Bindings::getJNIEnv(); + AutoJObject obj = mJavaFrame->frame(env); + if (!obj.get()) + return; jobject bitmap = webcoreImageToJavaBitmap(env, icon); if (!bitmap) return; - env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mDidReceiveIcon, bitmap); + env->CallVoidMethod(obj.get(), mJavaFrame->mDidReceiveIcon, bitmap); env->DeleteLocalRef(bitmap); checkException(env); } @@ -602,10 +630,13 @@ WebFrame::didReceiveTouchIconURL(const WebCore::String& url, bool precomposed) TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); #endif JNIEnv* env = JSC::Bindings::getJNIEnv(); + AutoJObject obj = mJavaFrame->frame(env); + if (!obj.get()) + return; jstring jUrlStr = env->NewString((unsigned short*)url.characters(), url.length()); - env->CallVoidMethod(mJavaFrame->frame(env).get(), + env->CallVoidMethod(obj.get(), mJavaFrame->mDidReceiveTouchIconUrl, jUrlStr, precomposed); checkException(env); } @@ -618,9 +649,13 @@ WebFrame::updateVisitedHistory(const WebCore::KURL& url, bool reload) #endif WebCore::String urlStr(url.string()); JNIEnv* env = JSC::Bindings::getJNIEnv(); + AutoJObject obj = mJavaFrame->frame(env); + if (!obj.get()) + return; + jstring jUrlStr = env->NewString((unsigned short*)urlStr.characters(), urlStr.length()); - env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mUpdateVisitedHistory, jUrlStr, reload); + env->CallVoidMethod(obj.get(), mJavaFrame->mUpdateVisitedHistory, jUrlStr, reload); checkException(env); } @@ -644,11 +679,14 @@ WebFrame::canHandleRequest(const WebCore::ResourceRequest& request) if (url.isEmpty()) return true; JNIEnv* env = JSC::Bindings::getJNIEnv(); + AutoJObject obj = mJavaFrame->frame(env); + if (!obj.get()) + return true; jstring jUrlStr = env->NewString((unsigned short *)url.characters(), url.length()); // check to see whether browser app wants to hijack url loading. // if browser app handles the url, we will return false to bail out WebCore loading - jboolean ret = env->CallBooleanMethod(mJavaFrame->frame(env).get(), mJavaFrame->mHandleUrl, jUrlStr); + jboolean ret = env->CallBooleanMethod(obj.get(), mJavaFrame->mHandleUrl, jUrlStr); checkException(env); return (ret == 0); } @@ -660,10 +698,13 @@ WebFrame::createWindow(bool dialog, bool userGesture) TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); #endif JNIEnv* env = JSC::Bindings::getJNIEnv(); - jobject obj = env->CallObjectMethod(mJavaFrame->frame(env).get(), + AutoJObject obj = mJavaFrame->frame(env); + if (!obj.get()) + return NULL; + jobject jobj = env->CallObjectMethod(obj.get(), mJavaFrame->mCreateWindow, dialog, userGesture); - if (obj) { - WebCore::Frame* frame = GET_NATIVE_FRAME(env, obj); + if (jobj) { + WebCore::Frame* frame = GET_NATIVE_FRAME(env, jobj); return frame; } return NULL; @@ -676,7 +717,10 @@ WebFrame::requestFocus() const TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); #endif JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mRequestFocus); + AutoJObject obj = mJavaFrame->frame(env); + if (!obj.get()) + return; + env->CallVoidMethod(obj.get(), mJavaFrame->mRequestFocus); checkException(env); } @@ -688,7 +732,10 @@ WebFrame::closeWindow(WebViewCore* webViewCore) #endif assert(webViewCore); JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mCloseWindow, + AutoJObject obj = mJavaFrame->frame(env); + if (!obj.get()) + return; + env->CallVoidMethod(obj.get(), mJavaFrame->mCloseWindow, webViewCore->getJavaObject().get()); } @@ -703,16 +750,22 @@ WebFrame::decidePolicyForFormResubmission(WebCore::FramePolicyFunction func) TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); #endif JNIEnv* env = JSC::Bindings::getJNIEnv(); + AutoJObject obj = mJavaFrame->frame(env); + if (!obj.get()) + return; PolicyFunctionWrapper* p = new PolicyFunctionWrapper; p->func = func; - env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mDecidePolicyForFormResubmission, p); + env->CallVoidMethod(obj.get(), mJavaFrame->mDecidePolicyForFormResubmission, p); } WebCore::String WebFrame::getRawResourceFilename(RAW_RES_ID id) const { JNIEnv* env = JSC::Bindings::getJNIEnv(); - jstring ret = (jstring) env->CallObjectMethod(mJavaFrame->frame(env).get(), + AutoJObject obj = mJavaFrame->frame(env); + if (!obj.get()) + return WebCore::String(); + jstring ret = (jstring) env->CallObjectMethod(obj.get(), mJavaFrame->mGetRawResFilename, (int)id); return to_string(env, ret); @@ -722,7 +775,10 @@ float WebFrame::density() const { JNIEnv* env = JSC::Bindings::getJNIEnv(); - jfloat dpi = env->CallFloatMethod(mJavaFrame->frame(env).get(), mJavaFrame->mDensity); + AutoJObject obj = mJavaFrame->frame(env); + if (!obj.get()) + return 1.0; + jfloat dpi = env->CallFloatMethod(obj.get(), mJavaFrame->mDensity); checkException(env); return dpi; } diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp index b16a69d8d..e5c1549f0 100644 --- a/WebKit/android/jni/WebViewCore.cpp +++ b/WebKit/android/jni/WebViewCore.cpp @@ -772,7 +772,12 @@ void WebViewCore::scrollTo(int x, int y, bool animate) // LOGD("WebViewCore::scrollTo(%d %d)\n", x, y); JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), animate ? m_javaGlue->m_spawnScrollTo : m_javaGlue->m_scrollTo, x, y); + AutoJObject obj = m_javaGlue->object(env); + // if it is called during DESTROY is handled, the real object of WebViewCore + // can be gone. Check before using it. + if (!obj.get()) + return; + env->CallVoidMethod(obj.get(), animate ? m_javaGlue->m_spawnScrollTo : m_javaGlue->m_scrollTo, x, y); checkException(env); } @@ -780,7 +785,12 @@ void WebViewCore::sendNotifyProgressFinished() { LOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!"); JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_sendNotifyProgressFinished); + AutoJObject obj = m_javaGlue->object(env); + // if it is called during DESTROY is handled, the real object of WebViewCore + // can be gone. Check before using it. + if (!obj.get()) + return; + env->CallVoidMethod(obj.get(), m_javaGlue->m_sendNotifyProgressFinished); checkException(env); } @@ -788,7 +798,12 @@ void WebViewCore::viewInvalidate(const WebCore::IntRect& rect) { LOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!"); JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), + AutoJObject obj = m_javaGlue->object(env); + // if it is called during DESTROY is handled, the real object of WebViewCore + // can be gone. Check before using it. + if (!obj.get()) + return; + env->CallVoidMethod(obj.get(), m_javaGlue->m_sendViewInvalidate, rect.x(), rect.y(), rect.right(), rect.bottom()); checkException(env); @@ -799,7 +814,12 @@ void WebViewCore::scrollBy(int dx, int dy, bool animate) if (!(dx | dy)) return; JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_scrollBy, + AutoJObject obj = m_javaGlue->object(env); + // if it is called during DESTROY is handled, the real object of WebViewCore + // can be gone. Check before using it. + if (!obj.get()) + return; + env->CallVoidMethod(obj.get(), m_javaGlue->m_scrollBy, dx, dy, animate); checkException(env); } @@ -807,7 +827,12 @@ void WebViewCore::scrollBy(int dx, int dy, bool animate) void WebViewCore::contentDraw() { JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_contentDraw); + AutoJObject obj = m_javaGlue->object(env); + // if it is called during DESTROY is handled, the real object of WebViewCore + // can be gone. Check before using it. + if (!obj.get()) + return; + env->CallVoidMethod(obj.get(), m_javaGlue->m_contentDraw); checkException(env); } @@ -856,14 +881,18 @@ void WebViewCore::didFirstLayout() WebCore::FrameLoadType loadType = loader->loadType(); JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_didFirstLayout, + AutoJObject obj = m_javaGlue->object(env); + // if it is called during DESTROY is handled, the real object of WebViewCore + // can be gone. Check before using it. + if (!obj.get()) + return; + env->CallVoidMethod(obj.get(), m_javaGlue->m_didFirstLayout, loadType == WebCore::FrameLoadTypeStandard // When redirect with locked history, we would like to reset the // scale factor. This is important for www.yahoo.com as it is // redirected to www.yahoo.com/?rs=1 on load. || loadType == WebCore::FrameLoadTypeRedirectWithLockedBackForwardList); checkException(env); - DBG_NAV_LOG("call updateFrameCache"); m_check_domtree_version = false; updateFrameCache(); @@ -876,7 +905,12 @@ void WebViewCore::updateViewport() LOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!"); JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_updateViewport); + AutoJObject obj = m_javaGlue->object(env); + // if it is called during DESTROY is handled, the real object of WebViewCore + // can be gone. Check before using it. + if (!obj.get()) + return; + env->CallVoidMethod(obj.get(), m_javaGlue->m_updateViewport); checkException(env); } @@ -886,7 +920,12 @@ void WebViewCore::restoreScale(int scale) LOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!"); JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_restoreScale, scale); + AutoJObject obj = m_javaGlue->object(env); + // if it is called during DESTROY is handled, the real object of WebViewCore + // can be gone. Check before using it. + if (!obj.get()) + return; + env->CallVoidMethod(obj.get(), m_javaGlue->m_restoreScale, scale); checkException(env); } @@ -896,7 +935,12 @@ void WebViewCore::restoreScreenWidthScale(int scale) LOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!"); JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_restoreScreenWidthScale, scale); + AutoJObject obj = m_javaGlue->object(env); + // if it is called during DESTROY is handled, the real object of WebViewCore + // can be gone. Check before using it. + if (!obj.get()) + return; + env->CallVoidMethod(obj.get(), m_javaGlue->m_restoreScreenWidthScale, scale); checkException(env); } @@ -910,10 +954,10 @@ void WebViewCore::needTouchEvents(bool need) AutoJObject obj = m_javaGlue->object(env); // if it is called during DESTROY is handled, the real object of WebViewCore // can be gone. Check before using it. - if (env && obj.get()) { - env->CallVoidMethod(obj.get(), m_javaGlue->m_needTouchEvents, need); - checkException(env); - } + if (!obj.get()) + return; + env->CallVoidMethod(obj.get(), m_javaGlue->m_needTouchEvents, need); + checkException(env); #endif } @@ -923,7 +967,12 @@ void WebViewCore::requestKeyboard(bool showKeyboard) LOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!"); JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_requestKeyboard, showKeyboard); + AutoJObject obj = m_javaGlue->object(env); + // if it is called during DESTROY is handled, the real object of WebViewCore + // can be gone. Check before using it. + if (!obj.get()) + return; + env->CallVoidMethod(obj.get(), m_javaGlue->m_requestKeyboard, showKeyboard); checkException(env); } @@ -1815,6 +1864,11 @@ void WebViewCore::listBoxRequest(WebCoreReply* reply, const uint16_t** labels, s // Create an array of java Strings for the drop down. JNIEnv* env = JSC::Bindings::getJNIEnv(); + AutoJObject obj = m_javaGlue->object(env); + // if it is called during DESTROY is handled, the real object of WebViewCore + // can be gone. Check before using it. + if (!obj.get()) + return; jobjectArray labelArray = makeLabelArray(env, labels, count); // Create an array determining whether each item is enabled. @@ -1839,11 +1893,11 @@ void WebViewCore::listBoxRequest(WebCoreReply* reply, const uint16_t** labels, s } env->ReleaseIntArrayElements(selectedArray, selArray, 0); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_requestListBox, labelArray, enabledArray, selectedArray); + env->CallVoidMethod(obj.get(), m_javaGlue->m_requestListBox, labelArray, enabledArray, selectedArray); env->DeleteLocalRef(selectedArray); } else { // Pass up the single selection. - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_requestSingleListBox, labelArray, enabledArray, selectedCountOrSelection); + env->CallVoidMethod(obj.get(), m_javaGlue->m_requestSingleListBox, labelArray, enabledArray, selectedCountOrSelection); } env->DeleteLocalRef(labelArray); @@ -2051,9 +2105,14 @@ void WebViewCore::popupReply(const int* array, int count) void WebViewCore::addMessageToConsole(const WebCore::String& message, unsigned int lineNumber, const WebCore::String& sourceID) { JNIEnv* env = JSC::Bindings::getJNIEnv(); + AutoJObject obj = m_javaGlue->object(env); + // if it is called during DESTROY is handled, the real object of WebViewCore + // can be gone. Check before using it. + if (!obj.get()) + return; jstring jMessageStr = env->NewString((unsigned short *)message.characters(), message.length()); jstring jSourceIDStr = env->NewString((unsigned short *)sourceID.characters(), sourceID.length()); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_addMessageToConsole, jMessageStr, lineNumber, jSourceIDStr); + env->CallVoidMethod(obj.get(), m_javaGlue->m_addMessageToConsole, jMessageStr, lineNumber, jSourceIDStr); env->DeleteLocalRef(jMessageStr); env->DeleteLocalRef(jSourceIDStr); checkException(env); @@ -2062,9 +2121,14 @@ void WebViewCore::addMessageToConsole(const WebCore::String& message, unsigned i void WebViewCore::jsAlert(const WebCore::String& url, const WebCore::String& text) { JNIEnv* env = JSC::Bindings::getJNIEnv(); + AutoJObject obj = m_javaGlue->object(env); + // if it is called during DESTROY is handled, the real object of WebViewCore + // can be gone. Check before using it. + if (!obj.get()) + return; jstring jInputStr = env->NewString((unsigned short *)text.characters(), text.length()); jstring jUrlStr = env->NewString((unsigned short *)url.characters(), url.length()); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_jsAlert, jUrlStr, jInputStr); + env->CallVoidMethod(obj.get(), m_javaGlue->m_jsAlert, jUrlStr, jInputStr); env->DeleteLocalRef(jInputStr); env->DeleteLocalRef(jUrlStr); checkException(env); @@ -2074,9 +2138,14 @@ void WebViewCore::exceededDatabaseQuota(const WebCore::String& url, const WebCor { #if ENABLE(DATABASE) JNIEnv* env = JSC::Bindings::getJNIEnv(); + AutoJObject obj = m_javaGlue->object(env); + // if it is called during DESTROY is handled, the real object of WebViewCore + // can be gone. Check before using it. + if (!obj.get()) + return; jstring jDatabaseIdentifierStr = env->NewString((unsigned short *)databaseIdentifier.characters(), databaseIdentifier.length()); jstring jUrlStr = env->NewString((unsigned short *)url.characters(), url.length()); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_exceededDatabaseQuota, jUrlStr, jDatabaseIdentifierStr, currentQuota, estimatedSize); + env->CallVoidMethod(obj.get(), m_javaGlue->m_exceededDatabaseQuota, jUrlStr, jDatabaseIdentifierStr, currentQuota, estimatedSize); env->DeleteLocalRef(jDatabaseIdentifierStr); env->DeleteLocalRef(jUrlStr); checkException(env); @@ -2087,7 +2156,12 @@ void WebViewCore::reachedMaxAppCacheSize(const unsigned long long spaceNeeded) { #if ENABLE(OFFLINE_WEB_APPLICATIONS) JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_reachedMaxAppCacheSize, spaceNeeded); + AutoJObject obj = m_javaGlue->object(env); + // if it is called during DESTROY is handled, the real object of WebViewCore + // can be gone. Check before using it. + if (!obj.get()) + return; + env->CallVoidMethod(obj.get(), m_javaGlue->m_reachedMaxAppCacheSize, spaceNeeded); checkException(env); #endif } @@ -2096,15 +2170,25 @@ void WebViewCore::populateVisitedLinks(WebCore::PageGroup* group) { m_groupForVisitedLinks = group; JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_populateVisitedLinks); + AutoJObject obj = m_javaGlue->object(env); + // if it is called during DESTROY is handled, the real object of WebViewCore + // can be gone. Check before using it. + if (!obj.get()) + return; + env->CallVoidMethod(obj.get(), m_javaGlue->m_populateVisitedLinks); checkException(env); } void WebViewCore::geolocationPermissionsShowPrompt(const WebCore::String& origin) { JNIEnv* env = JSC::Bindings::getJNIEnv(); + AutoJObject obj = m_javaGlue->object(env); + // if it is called during DESTROY is handled, the real object of WebViewCore + // can be gone. Check before using it. + if (!obj.get()) + return; jstring originString = env->NewString((unsigned short *)origin.characters(), origin.length()); - env->CallVoidMethod(m_javaGlue->object(env).get(), + env->CallVoidMethod(obj.get(), m_javaGlue->m_geolocationPermissionsShowPrompt, originString); env->DeleteLocalRef(originString); @@ -2114,7 +2198,12 @@ void WebViewCore::geolocationPermissionsShowPrompt(const WebCore::String& origin void WebViewCore::geolocationPermissionsHidePrompt() { JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), + AutoJObject obj = m_javaGlue->object(env); + // if it is called during DESTROY is handled, the real object of WebViewCore + // can be gone. Check before using it. + if (!obj.get()) + return; + env->CallVoidMethod(obj.get(), m_javaGlue->m_geolocationPermissionsHidePrompt); checkException(env); } @@ -2122,9 +2211,14 @@ void WebViewCore::geolocationPermissionsHidePrompt() bool WebViewCore::jsConfirm(const WebCore::String& url, const WebCore::String& text) { JNIEnv* env = JSC::Bindings::getJNIEnv(); + AutoJObject obj = m_javaGlue->object(env); + // if it is called during DESTROY is handled, the real object of WebViewCore + // can be gone. Check before using it. + if (!obj.get()) + return false; jstring jInputStr = env->NewString((unsigned short *)text.characters(), text.length()); jstring jUrlStr = env->NewString((unsigned short *)url.characters(), url.length()); - jboolean result = env->CallBooleanMethod(m_javaGlue->object(env).get(), m_javaGlue->m_jsConfirm, jUrlStr, jInputStr); + jboolean result = env->CallBooleanMethod(obj.get(), m_javaGlue->m_jsConfirm, jUrlStr, jInputStr); env->DeleteLocalRef(jInputStr); env->DeleteLocalRef(jUrlStr); checkException(env); @@ -2134,10 +2228,16 @@ bool WebViewCore::jsConfirm(const WebCore::String& url, const WebCore::String& t bool WebViewCore::jsPrompt(const WebCore::String& url, const WebCore::String& text, const WebCore::String& defaultValue, WebCore::String& result) { JNIEnv* env = JSC::Bindings::getJNIEnv(); + AutoJObject obj = m_javaGlue->object(env); + // if it is called during DESTROY is handled, the real object of WebViewCore + // can be gone. Check before using it. + if (!obj.get()) + return false; + jstring jInputStr = env->NewString((unsigned short *)text.characters(), text.length()); jstring jDefaultStr = env->NewString((unsigned short *)defaultValue.characters(), defaultValue.length()); jstring jUrlStr = env->NewString((unsigned short *)url.characters(), url.length()); - jstring returnVal = (jstring) env->CallObjectMethod(m_javaGlue->object(env).get(), m_javaGlue->m_jsPrompt, jUrlStr, jInputStr, jDefaultStr); + jstring returnVal = (jstring) env->CallObjectMethod(obj.get(), m_javaGlue->m_jsPrompt, jUrlStr, jInputStr, jDefaultStr); // If returnVal is null, it means that the user cancelled the dialog. if (!returnVal) return false; @@ -2153,9 +2253,14 @@ bool WebViewCore::jsPrompt(const WebCore::String& url, const WebCore::String& te bool WebViewCore::jsUnload(const WebCore::String& url, const WebCore::String& message) { JNIEnv* env = JSC::Bindings::getJNIEnv(); + AutoJObject obj = m_javaGlue->object(env); + // if it is called during DESTROY is handled, the real object of WebViewCore + // can be gone. Check before using it. + if (!obj.get()) + return false; jstring jInputStr = env->NewString((unsigned short *)message.characters(), message.length()); jstring jUrlStr = env->NewString((unsigned short *)url.characters(), url.length()); - jboolean result = env->CallBooleanMethod(m_javaGlue->object(env).get(), m_javaGlue->m_jsUnload, jUrlStr, jInputStr); + jboolean result = env->CallBooleanMethod(obj.get(), m_javaGlue->m_jsUnload, jUrlStr, jInputStr); env->DeleteLocalRef(jInputStr); env->DeleteLocalRef(jUrlStr); checkException(env); @@ -2165,7 +2270,12 @@ bool WebViewCore::jsUnload(const WebCore::String& url, const WebCore::String& me bool WebViewCore::jsInterrupt() { JNIEnv* env = JSC::Bindings::getJNIEnv(); - jboolean result = env->CallBooleanMethod(m_javaGlue->object(env).get(), m_javaGlue->m_jsInterrupt); + AutoJObject obj = m_javaGlue->object(env); + // if it is called during DESTROY is handled, the real object of WebViewCore + // can be gone. Check before using it. + if (!obj.get()) + return true; // default to interrupt + jboolean result = env->CallBooleanMethod(obj.get(), m_javaGlue->m_jsInterrupt); checkException(env); return result; } @@ -2180,7 +2290,12 @@ jobject WebViewCore::getWebViewJavaObject() { JNIEnv* env = JSC::Bindings::getJNIEnv(); - return env->GetObjectField(m_javaGlue->object(env).get(), gWebViewCoreFields.m_webView); + AutoJObject obj = m_javaGlue->object(env); + // if it is called during DESTROY is handled, the real object of WebViewCore + // can be gone. Check before using it. + if (!obj.get()) + return 0; + return env->GetObjectField(obj.get(), gWebViewCoreFields.m_webView); } void WebViewCore::updateTextSelection() { @@ -2192,7 +2307,12 @@ void WebViewCore::updateTextSelection() { return; RenderTextControl* rtc = static_cast(renderer); JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), + AutoJObject obj = m_javaGlue->object(env); + // if it is called during DESTROY is handled, the real object of WebViewCore + // can be gone. Check before using it. + if (!obj.get()) + return; + env->CallVoidMethod(obj.get(), m_javaGlue->m_updateTextSelection, reinterpret_cast(focusNode), rtc->selectionStart(), rtc->selectionEnd(), m_textGeneration); checkException(env); @@ -2204,15 +2324,21 @@ void WebViewCore::updateTextfield(WebCore::Node* ptr, bool changeToPassword, if (m_blockTextfieldUpdates) return; JNIEnv* env = JSC::Bindings::getJNIEnv(); + AutoJObject obj = m_javaGlue->object(env); + // if it is called during DESTROY is handled, the real object of WebViewCore + // can be gone. Check before using it. + if (!obj.get()) + return; + if (changeToPassword) { - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_updateTextfield, + env->CallVoidMethod(obj.get(), m_javaGlue->m_updateTextfield, (int) ptr, true, 0, m_textGeneration); checkException(env); return; } int length = text.length(); jstring string = env->NewString((unsigned short *) text.characters(), length); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_updateTextfield, + env->CallVoidMethod(obj.get(), m_javaGlue->m_updateTextfield, (int) ptr, false, string, m_textGeneration); env->DeleteLocalRef(string); checkException(env); @@ -2221,8 +2347,13 @@ void WebViewCore::updateTextfield(WebCore::Node* ptr, bool changeToPassword, void WebViewCore::clearTextEntry() { JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), - m_javaGlue->m_clearTextEntry); + AutoJObject obj = m_javaGlue->object(env); + // if it is called during DESTROY is handled, the real object of WebViewCore + // can be gone. Check before using it. + if (!obj.get()) + return; + + env->CallVoidMethod(obj.get(), m_javaGlue->m_clearTextEntry); } void WebViewCore::setBackgroundColor(SkColor c) @@ -2243,8 +2374,14 @@ void WebViewCore::startFullScreenPluginActivity(const char* libName, JNIEnv* env = JSC::Bindings::getJNIEnv(); jstring libString = env->NewStringUTF(libName); + AutoJObject obj = m_javaGlue->object(env); + // if it is called during DESTROY is handled, the real object of WebViewCore + // can be gone. Check before using it. + if (!obj.get()) + return; + jstring classString = env->NewStringUTF(className); - env->CallVoidMethod(m_javaGlue->object(env).get(), + env->CallVoidMethod(obj.get(), m_javaGlue->m_startFullScreenPluginActivity, libString, classString, (int) npp); checkException(env); @@ -2254,10 +2391,15 @@ jobject WebViewCore::createSurface(const char* libName, const char* className, NPP npp, int x, int y, int width, int height) { JNIEnv* env = JSC::Bindings::getJNIEnv(); + AutoJObject obj = m_javaGlue->object(env); + // if it is called during DESTROY is handled, the real object of WebViewCore + // can be gone. Check before using it. + if (!obj.get()) + return 0; jstring libString = env->NewStringUTF(libName); jstring classString = env->NewStringUTF(className); - jobject result = env->CallObjectMethod(m_javaGlue->object(env).get(), + jobject result = env->CallObjectMethod(obj.get(), m_javaGlue->m_createSurface, libString, classString,(int) npp, x, y, width, height); checkException(env); @@ -2268,7 +2410,13 @@ jobject WebViewCore::createSurface(const char* libName, const char* className, void WebViewCore::destroySurface(jobject childView) { JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_destroySurface, childView); + AutoJObject obj = m_javaGlue->object(env); + // if it is called during DESTROY is handled, the real object of WebViewCore + // can be gone. Check before using it. + if (!obj.get()) + return; + + env->CallVoidMethod(obj.get(), m_javaGlue->m_destroySurface, childView); checkException(env); } diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp index b51235b9b..6f01fec2e 100644 --- a/WebKit/android/nav/WebView.cpp +++ b/WebKit/android/nav/WebView.cpp @@ -215,7 +215,12 @@ void clearTextEntry() { DEBUG_NAV_UI_LOGD("%s", __FUNCTION__); JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue.object(env).get(), m_javaGlue.m_clearTextEntry); + AutoJObject obj = m_javaGlue.object(env); + // if it is called during or after DESTROY is handled, the real object of + // WebView can be gone. Check before using it. + if (!obj.get()) + return; + env->CallVoidMethod(obj.get(), m_javaGlue.m_clearTextEntry); checkException(env); } @@ -633,7 +638,12 @@ int getScaledMaxXScroll() { LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); JNIEnv* env = JSC::Bindings::getJNIEnv(); - int result = env->CallIntMethod(m_javaGlue.object(env).get(), m_javaGlue.m_getScaledMaxXScroll); + AutoJObject obj = m_javaGlue.object(env); + // if it is called during or after DESTROY is handled, the real object of + // WebView can be gone. Check before using it. + if (!obj.get()) + return 0; + int result = env->CallIntMethod(obj.get(), m_javaGlue.m_getScaledMaxXScroll); checkException(env); return result; } @@ -642,7 +652,12 @@ int getScaledMaxYScroll() { LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); JNIEnv* env = JSC::Bindings::getJNIEnv(); - int result = env->CallIntMethod(m_javaGlue.object(env).get(), m_javaGlue.m_getScaledMaxYScroll); + AutoJObject obj = m_javaGlue.object(env); + // if it is called during or after DESTROY is handled, the real object of + // WebView can be gone. Check before using it. + if (!obj.get()) + return 0; + int result = env->CallIntMethod(obj.get(), m_javaGlue.m_getScaledMaxYScroll); checkException(env); return result; } @@ -651,7 +666,12 @@ void getVisibleRect(WebCore::IntRect* rect) { LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); JNIEnv* env = JSC::Bindings::getJNIEnv(); - jobject jRect = env->CallObjectMethod(m_javaGlue.object(env).get(), m_javaGlue.m_getVisibleRect); + AutoJObject obj = m_javaGlue.object(env); + // if it is called during or after DESTROY is handled, the real object of + // WebView can be gone. Check before using it. + if (!obj.get()) + return; + jobject jRect = env->CallObjectMethod(obj.get(), m_javaGlue.m_getVisibleRect); checkException(env); int left = (int) env->GetIntField(jRect, m_javaGlue.m_rectLeft); checkException(env); @@ -994,9 +1014,13 @@ int getBlockLeftEdge(int x, int y, float scale) void overrideUrlLoading(const WebCore::String& url) { JNIEnv* env = JSC::Bindings::getJNIEnv(); + AutoJObject obj = m_javaGlue.object(env); + // if it is called during or after DESTROY is handled, the real object of + // WebView can be gone. Check before using it. + if (!obj.get()) + return; jstring jName = env->NewString((jchar*) url.characters(), url.length()); - env->CallVoidMethod(m_javaGlue.object(env).get(), - m_javaGlue.m_overrideLoading, jName); + env->CallVoidMethod(obj.get(), m_javaGlue.m_overrideLoading, jName); env->DeleteLocalRef(jName); } @@ -1014,11 +1038,14 @@ void setPluginReceivesEvents(bool value) //send message to plugin in webkit JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue.object(env).get(), - m_javaGlue.m_sendPluginState, + AutoJObject obj = m_javaGlue.object(env); + // if it is called during or after DESTROY is handled, the real object of + // WebView can be gone. Check before using it. + if (!obj.get()) + return; + env->CallVoidMethod(obj.get(), m_javaGlue.m_sendPluginState, value ? kGainFocus_PluginState : kLoseFocus_PluginState); checkException(env); - m_pluginReceivesEvents = value; } @@ -1175,7 +1202,12 @@ void sendMoveMouse(WebCore::Frame* framePtr, WebCore::Node* nodePtr, int x, int { DBG_NAV_LOGD("framePtr=%p nodePtr=%p x=%d y=%d", framePtr, nodePtr, x, y); JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue.object(env).get(), m_javaGlue.m_sendMoveMouse, + AutoJObject obj = m_javaGlue.object(env); + // if it is called during or after DESTROY is handled, the real object of + // WebView can be gone. Check before using it. + if (!obj.get()) + return; + env->CallVoidMethod(obj.get(), m_javaGlue.m_sendMoveMouse, (jint) framePtr, (jint) nodePtr, x, y); checkException(env); } @@ -1184,8 +1216,12 @@ void sendMoveMouseIfLatest(bool disableFocusController) { LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue.object(env).get(), - m_javaGlue.m_sendMoveMouseIfLatest, disableFocusController); + AutoJObject obj = m_javaGlue.object(env); + // if it is called during or after DESTROY is handled, the real object of + // WebView can be gone. Check before using it. + if (!obj.get()) + return; + env->CallVoidMethod(obj.get(), m_javaGlue.m_sendMoveMouseIfLatest, disableFocusController); checkException(env); } @@ -1197,7 +1233,12 @@ void sendMotionUp( m_generation, framePtr, nodePtr, x, y); LOG_ASSERT(m_javaGlue.m_obj, "A WebView was not associated with this WebViewNative!"); JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue.object(env).get(), m_javaGlue.m_sendMotionUp, + AutoJObject obj = m_javaGlue.object(env); + // if it is called during or after DESTROY is handled, the real object of + // WebView can be gone. Check before using it. + if (!obj.get()) + return; + env->CallVoidMethod(obj.get(), m_javaGlue.m_sendMotionUp, m_generation, (jint) framePtr, (jint) nodePtr, x, y); checkException(env); } @@ -1266,7 +1307,12 @@ bool scrollBy(int dx, int dy) LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); JNIEnv* env = JSC::Bindings::getJNIEnv(); - bool result = env->CallBooleanMethod(m_javaGlue.object(env).get(), + AutoJObject obj = m_javaGlue.object(env); + // if it is called during or after DESTROY is handled, the real object of + // WebView can be gone. Check before using it. + if (!obj.get()) + return false; + bool result = env->CallBooleanMethod(obj.get(), m_javaGlue.m_scrollBy, dx, dy, true); checkException(env); return result; @@ -1303,15 +1349,24 @@ bool hasFocusNode() void rebuildWebTextView() { JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue.object(env).get(), - m_javaGlue.m_rebuildWebTextView); + AutoJObject obj = m_javaGlue.object(env); + // if it is called during or after DESTROY is handled, the real object of + // WebView can be gone. Check before using it. + if (!obj.get()) + return; + env->CallVoidMethod(obj.get(), m_javaGlue.m_rebuildWebTextView); checkException(env); } void displaySoftKeyboard(bool isTextView) { JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue.object(env).get(), + AutoJObject obj = m_javaGlue.object(env); + // if it is called during or after DESTROY is handled, the real object of + // WebView can be gone. Check before using it. + if (!obj.get()) + return; + env->CallVoidMethod(obj.get(), m_javaGlue.m_displaySoftKeyboard, isTextView); checkException(env); } @@ -1319,22 +1374,37 @@ void displaySoftKeyboard(bool isTextView) void viewInvalidate() { JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue.object(env).get(), m_javaGlue.m_viewInvalidate); + AutoJObject obj = m_javaGlue.object(env); + // if it is called during or after DESTROY is handled, the real object of + // WebView can be gone. Check before using it. + if (!obj.get()) + return; + env->CallVoidMethod(obj.get(), m_javaGlue.m_viewInvalidate); checkException(env); } void viewInvalidateRect(int l, int t, int r, int b) { JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue.object(env).get(), m_javaGlue.m_viewInvalidateRect, l, r, t, b); + AutoJObject obj = m_javaGlue.object(env); + // if it is called during or after DESTROY is handled, the real object of + // WebView can be gone. Check before using it. + if (!obj.get()) + return; + env->CallVoidMethod(obj.get(), m_javaGlue.m_viewInvalidateRect, l, r, t, b); checkException(env); } void postInvalidateDelayed(int64_t delay, const WebCore::IntRect& bounds) { JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue.object(env).get(), m_javaGlue.m_postInvalidateDelayed, - delay, bounds.x(), bounds.y(), bounds.right(), bounds.bottom()); + AutoJObject obj = m_javaGlue.object(env); + // if it is called during or after DESTROY is handled, the real object of + // WebView can be gone. Check before using it. + if (!obj.get()) + return; + env->CallVoidMethod(obj.get(), m_javaGlue.m_postInvalidateDelayed, + delay, bounds.x(), bounds.y(), bounds.right(), bounds.bottom()); checkException(env); } -- 2.11.0