Skip to content

Commit 0f98616

Browse files
Michael KolbAndroid (Google) Code Review
authored andcommitted
Merge "fix callback NPEs when WebView is destroyed"
2 parents e61e667 + d78ad29 commit 0f98616

File tree

3 files changed

+33
-20
lines changed

3 files changed

+33
-20
lines changed

core/java/android/webkit/CallbackProxy.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ class CallbackProxy extends Handler {
7676
private volatile WebBackForwardListClient mWebBackForwardListClient;
7777
// Used to call startActivity during url override.
7878
private final Context mContext;
79+
// block messages flag for destroy
80+
private boolean mBlockMessages;
7981

8082
// Message IDs
8183
private static final int PAGE_STARTED = 100;
@@ -155,10 +157,18 @@ public CallbackProxy(Context context, WebViewClassic w) {
155157
mBackForwardList = new WebBackForwardList(this);
156158
}
157159

160+
protected synchronized void blockMessages() {
161+
mBlockMessages = true;
162+
}
163+
164+
protected synchronized boolean messagesBlocked() {
165+
return mBlockMessages;
166+
}
167+
158168
protected void shutdown() {
169+
removeCallbacksAndMessages(null);
159170
setWebViewClient(null);
160171
setWebChromeClient(null);
161-
removeCallbacksAndMessages(null);
162172
}
163173

164174
/**
@@ -265,6 +275,7 @@ public void handleMessage(Message msg) {
265275
// in the UI thread. The WebViewClient and WebChromeClient functions
266276
// that check for a non-null callback are ok because java ensures atomic
267277
// 32-bit reads and writes.
278+
if (messagesBlocked()) return;
268279
switch (msg.what) {
269280
case PAGE_STARTED:
270281
String startedUrl = msg.getData().getString("url");

core/java/android/webkit/WebViewClassic.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2070,6 +2070,7 @@ public void destroy() {
20702070
}
20712071

20722072
private void destroyImpl() {
2073+
mCallbackProxy.blockMessages();
20732074
clearHelpers();
20742075
if (mListBoxDialog != null) {
20752076
mListBoxDialog.dismiss();

core/java/android/webkit/WebViewCore.java

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,6 +1244,23 @@ public void handleMessage(Message msg) {
12441244
+ " arg1=" + msg.arg1 + " arg2=" + msg.arg2
12451245
+ " obj=" + msg.obj);
12461246
}
1247+
switch (msg.what) {
1248+
case PAUSE_TIMERS:
1249+
mSavedPriority = Process.getThreadPriority(mTid);
1250+
Process.setThreadPriority(mTid,
1251+
Process.THREAD_PRIORITY_BACKGROUND);
1252+
pauseTimers();
1253+
if (mNativeClass != 0) {
1254+
nativeCloseIdleConnections(mNativeClass);
1255+
}
1256+
return;
1257+
1258+
case RESUME_TIMERS:
1259+
Process.setThreadPriority(mTid, mSavedPriority);
1260+
resumeTimers();
1261+
return;
1262+
}
1263+
12471264
if (mWebView == null || mNativeClass == 0) {
12481265
if (DebugFlags.WEB_VIEW_CORE) {
12491266
Log.w(LOGTAG, "Rejecting message " + msg.what
@@ -1252,8 +1269,6 @@ public void handleMessage(Message msg) {
12521269
return;
12531270
}
12541271
if (mDestroying == true
1255-
&& msg.what != EventHub.RESUME_TIMERS
1256-
&& msg.what != EventHub.PAUSE_TIMERS
12571272
&& msg.what != EventHub.DESTROY) {
12581273
if (DebugFlags.WEB_VIEW_CORE) {
12591274
Log.v(LOGTAG, "Rejecting message " + msg.what
@@ -1419,18 +1434,6 @@ public void handleMessage(Message msg) {
14191434
restoreState(msg.arg1);
14201435
break;
14211436

1422-
case PAUSE_TIMERS:
1423-
mSavedPriority = Process.getThreadPriority(mTid);
1424-
Process.setThreadPriority(mTid,
1425-
Process.THREAD_PRIORITY_BACKGROUND);
1426-
pauseTimers();
1427-
nativeCloseIdleConnections(mNativeClass);
1428-
break;
1429-
1430-
case RESUME_TIMERS:
1431-
Process.setThreadPriority(mTid, mSavedPriority);
1432-
resumeTimers();
1433-
break;
14341437

14351438
case ON_PAUSE:
14361439
nativePause(mNativeClass);
@@ -1961,12 +1964,10 @@ void removeMessages() {
19611964
*/
19621965
void destroy() {
19631966
synchronized (mEventHub) {
1964-
// Do not call removeMessages as then we risk removing PAUSE_TIMERS
1965-
// or RESUME_TIMERS messages, which we must still handle as they
1966-
// are per process. DESTROY will instead trigger a white list in
1967-
// mEventHub, skipping any remaining messages in the queue
1967+
// send DESTROY to front of queue
1968+
// PAUSE/RESUME timers will still be processed even if they get handled later
19681969
mEventHub.mDestroying = true;
1969-
mEventHub.sendMessage(
1970+
mEventHub.sendMessageAtFrontOfQueue(
19701971
Message.obtain(null, EventHub.DESTROY));
19711972
mEventHub.blockMessages();
19721973
}

0 commit comments

Comments
 (0)