Skip to content

Commit ee3b562

Browse files
committed
Save and load snapshots async
Bug: 5416822 The overload of webkitDraw is temporary, but this gets the plumbing in place and works correctly Change-Id: Ib3e23b9a4a1862dd445c8dc68a3936590787a62b
1 parent 9687433 commit ee3b562

File tree

3 files changed

+84
-28
lines changed

3 files changed

+84
-28
lines changed

core/java/android/webkit/ViewStateSerializer.java

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,21 +34,21 @@ class ViewStateSerializer {
3434

3535
static final int VERSION = 1;
3636

37-
static boolean serializeViewState(OutputStream stream, WebViewClassic web)
37+
static boolean serializeViewState(OutputStream stream, DrawData draw)
3838
throws IOException {
39-
int baseLayer = web.getBaseLayer();
39+
int baseLayer = draw.mBaseLayer;
4040
if (baseLayer == 0) {
4141
return false;
4242
}
4343
DataOutputStream dos = new DataOutputStream(stream);
4444
dos.writeInt(VERSION);
45-
dos.writeInt(web.getContentWidth());
46-
dos.writeInt(web.getContentHeight());
45+
dos.writeInt(draw.mContentSize.x);
46+
dos.writeInt(draw.mContentSize.y);
4747
return nativeSerializeViewState(baseLayer, dos,
4848
new byte[WORKING_STREAM_STORAGE]);
4949
}
5050

51-
static DrawData deserializeViewState(InputStream stream, WebViewClassic web)
51+
static DrawData deserializeViewState(InputStream stream)
5252
throws IOException {
5353
DataInputStream dis = new DataInputStream(stream);
5454
int version = dis.readInt();
@@ -62,13 +62,10 @@ static DrawData deserializeViewState(InputStream stream, WebViewClassic web)
6262

6363
final WebViewCore.DrawData draw = new WebViewCore.DrawData();
6464
draw.mViewState = new WebViewCore.ViewState();
65-
int viewWidth = web.getViewWidth();
66-
int viewHeight = web.getViewHeightWithTitle() - web.getTitleHeight();
67-
draw.mViewSize = new Point(viewWidth, viewHeight);
6865
draw.mContentSize = new Point(contentWidth, contentHeight);
69-
draw.mViewState.mDefaultScale = web.getDefaultZoomScale();
7066
draw.mBaseLayer = baseLayer;
7167
draw.mInvalRegion = new Region(0, 0, contentWidth, contentHeight);
68+
stream.close();
7269
return draw;
7370
}
7471

core/java/android/webkit/WebViewClassic.java

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2439,34 +2439,51 @@ public void run() {
24392439
* version specific, and may not be able to be loaded by newer versions
24402440
* of WebView.
24412441
* @param stream The {@link OutputStream} to save to
2442-
* @return True if saved successfully
2442+
* @param callback The {@link ValueCallback} to call with the result
24432443
*/
2444-
public boolean saveViewState(OutputStream stream) {
2445-
try {
2446-
return ViewStateSerializer.serializeViewState(stream, this);
2447-
} catch (IOException e) {
2448-
Log.w(LOGTAG, "Failed to saveViewState", e);
2444+
public void saveViewState(OutputStream stream, ValueCallback<Boolean> callback) {
2445+
if (mWebViewCore == null) {
2446+
callback.onReceiveValue(false);
2447+
return;
24492448
}
2450-
return false;
2449+
mWebViewCore.sendMessageAtFrontOfQueue(EventHub.SAVE_VIEW_STATE,
2450+
new WebViewCore.SaveViewStateRequest(stream, callback));
24512451
}
24522452

24532453
/**
24542454
* Loads the view data from the input stream. See
24552455
* {@link #saveViewState(OutputStream)} for more information.
24562456
* @param stream The {@link InputStream} to load from
2457-
* @return True if loaded successfully
24582457
*/
2459-
public boolean loadViewState(InputStream stream) {
2460-
try {
2461-
mLoadedPicture = ViewStateSerializer.deserializeViewState(stream, this);
2462-
mBlockWebkitViewMessages = true;
2463-
setNewPicture(mLoadedPicture, true);
2464-
mLoadedPicture.mViewState = null;
2465-
return true;
2466-
} catch (IOException e) {
2467-
Log.w(LOGTAG, "Failed to loadViewState", e);
2468-
}
2469-
return false;
2458+
public void loadViewState(InputStream stream) {
2459+
mBlockWebkitViewMessages = true;
2460+
new AsyncTask<InputStream, Void, DrawData>() {
2461+
2462+
@Override
2463+
protected DrawData doInBackground(InputStream... params) {
2464+
try {
2465+
return ViewStateSerializer.deserializeViewState(params[0]);
2466+
} catch (IOException e) {
2467+
return null;
2468+
}
2469+
}
2470+
2471+
@Override
2472+
protected void onPostExecute(DrawData draw) {
2473+
if (draw == null) {
2474+
Log.e(LOGTAG, "Failed to load view state!");
2475+
return;
2476+
}
2477+
int viewWidth = getViewWidth();
2478+
int viewHeight = getViewHeightWithTitle() - getTitleHeight();
2479+
draw.mViewSize = new Point(viewWidth, viewHeight);
2480+
draw.mViewState.mDefaultScale = getDefaultZoomScale();
2481+
mLoadedPicture = draw;
2482+
setNewPicture(mLoadedPicture, true);
2483+
mLoadedPicture.mViewState = null;
2484+
}
2485+
2486+
}.execute(stream);
24702487
}
24712488

24722489
/**

core/java/android/webkit/WebViewCore.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444

4545
import junit.framework.Assert;
4646

47+
import java.io.OutputStream;
4748
import java.util.ArrayList;
4849
import java.util.Collection;
4950
import java.util.Map;
@@ -1046,6 +1047,15 @@ public FindAllRequest(String text) {
10461047
public int mMatchIndex;
10471048
}
10481049

1050+
static class SaveViewStateRequest {
1051+
SaveViewStateRequest(OutputStream s, ValueCallback<Boolean> cb) {
1052+
mStream = s;
1053+
mCallback = cb;
1054+
}
1055+
public OutputStream mStream;
1056+
public ValueCallback<Boolean> mCallback;
1057+
}
1058+
10491059
/**
10501060
* @hide
10511061
*/
@@ -1178,6 +1188,8 @@ public class EventHub implements WebViewInputDispatcher.WebKitCallbacks {
11781188
static final int KEY_PRESS = 223;
11791189
static final int SET_INITIAL_FOCUS = 224;
11801190

1191+
static final int SAVE_VIEW_STATE = 225;
1192+
11811193
// Private handler for WebCore messages.
11821194
private Handler mHandler;
11831195
// Message queue for containing messages before the WebCore thread is
@@ -1752,8 +1764,13 @@ public void handleMessage(Message msg) {
17521764
case SET_INITIAL_FOCUS:
17531765
nativeSetInitialFocus(mNativeClass, msg.arg1);
17541766
break;
1767+
case SAVE_VIEW_STATE:
1768+
SaveViewStateRequest request = (SaveViewStateRequest) msg.obj;
1769+
saveViewState(request.mStream, request.mCallback);
1770+
break;
17551771
}
17561772
}
1773+
17571774
};
17581775
// Take all queued messages and resend them to the new handler.
17591776
synchronized (this) {
@@ -2249,6 +2266,31 @@ private void webkitDraw(DrawData draw) {
22492266
}
22502267
}
22512268

2269+
private void saveViewState(OutputStream stream,
2270+
ValueCallback<Boolean> callback) {
2271+
// TODO: Create a native method to do this better without overloading
2272+
// the draw path (and fix saving <canvas>)
2273+
DrawData draw = new DrawData();
2274+
if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "saveViewState start");
2275+
draw.mBaseLayer = nativeRecordContent(mNativeClass, draw.mInvalRegion,
2276+
draw.mContentSize);
2277+
boolean result = false;
2278+
try {
2279+
result = ViewStateSerializer.serializeViewState(stream, draw);
2280+
} catch (Throwable t) {
2281+
Log.w(LOGTAG, "Failed to save view state", t);
2282+
}
2283+
callback.onReceiveValue(result);
2284+
if (draw.mBaseLayer != 0) {
2285+
if (mDrawIsScheduled) {
2286+
mDrawIsScheduled = false;
2287+
mEventHub.removeMessages(EventHub.WEBKIT_DRAW);
2288+
}
2289+
mLastDrawData = draw;
2290+
webkitDraw(draw);
2291+
}
2292+
}
2293+
22522294
static void reducePriority() {
22532295
// remove the pending REDUCE_PRIORITY and RESUME_PRIORITY messages
22542296
sWebCoreHandler.removeMessages(WebCoreThread.REDUCE_PRIORITY);

0 commit comments

Comments
 (0)