Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ee3b562d authored by John Reck's avatar John Reck
Browse files

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
parent 9687433d
Loading
Loading
Loading
Loading
+6 −9
Original line number Diff line number Diff line
@@ -34,21 +34,21 @@ class ViewStateSerializer {

    static final int VERSION = 1;

    static boolean serializeViewState(OutputStream stream, WebViewClassic web)
    static boolean serializeViewState(OutputStream stream, DrawData draw)
            throws IOException {
        int baseLayer = web.getBaseLayer();
        int baseLayer = draw.mBaseLayer;
        if (baseLayer == 0) {
            return false;
        }
        DataOutputStream dos = new DataOutputStream(stream);
        dos.writeInt(VERSION);
        dos.writeInt(web.getContentWidth());
        dos.writeInt(web.getContentHeight());
        dos.writeInt(draw.mContentSize.x);
        dos.writeInt(draw.mContentSize.y);
        return nativeSerializeViewState(baseLayer, dos,
                new byte[WORKING_STREAM_STORAGE]);
    }

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

        final WebViewCore.DrawData draw = new WebViewCore.DrawData();
        draw.mViewState = new WebViewCore.ViewState();
        int viewWidth = web.getViewWidth();
        int viewHeight = web.getViewHeightWithTitle() - web.getTitleHeight();
        draw.mViewSize = new Point(viewWidth, viewHeight);
        draw.mContentSize = new Point(contentWidth, contentHeight);
        draw.mViewState.mDefaultScale = web.getDefaultZoomScale();
        draw.mBaseLayer = baseLayer;
        draw.mInvalRegion = new Region(0, 0, contentWidth, contentHeight);
        stream.close();
        return draw;
    }

+36 −19
Original line number Diff line number Diff line
@@ -2439,34 +2439,51 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
     * version specific, and may not be able to be loaded by newer versions
     * of WebView.
     * @param stream The {@link OutputStream} to save to
     * @return True if saved successfully
     * @param callback The {@link ValueCallback} to call with the result
     */
    public boolean saveViewState(OutputStream stream) {
        try {
            return ViewStateSerializer.serializeViewState(stream, this);
        } catch (IOException e) {
            Log.w(LOGTAG, "Failed to saveViewState", e);
    public void saveViewState(OutputStream stream, ValueCallback<Boolean> callback) {
        if (mWebViewCore == null) {
            callback.onReceiveValue(false);
            return;
        }
        return false;
        mWebViewCore.sendMessageAtFrontOfQueue(EventHub.SAVE_VIEW_STATE,
                new WebViewCore.SaveViewStateRequest(stream, callback));
    }

    /**
     * Loads the view data from the input stream. See
     * {@link #saveViewState(OutputStream)} for more information.
     * @param stream The {@link InputStream} to load from
     * @return True if loaded successfully
     */
    public boolean loadViewState(InputStream stream) {
        try {
            mLoadedPicture = ViewStateSerializer.deserializeViewState(stream, this);
    public void loadViewState(InputStream stream) {
        mBlockWebkitViewMessages = true;
        new AsyncTask<InputStream, Void, DrawData>() {

            @Override
            protected DrawData doInBackground(InputStream... params) {
                try {
                    return ViewStateSerializer.deserializeViewState(params[0]);
                } catch (IOException e) {
                    return null;
                }
            }

            @Override
            protected void onPostExecute(DrawData draw) {
                if (draw == null) {
                    Log.e(LOGTAG, "Failed to load view state!");
                    return;
                }
                int viewWidth = getViewWidth();
                int viewHeight = getViewHeightWithTitle() - getTitleHeight();
                draw.mViewSize = new Point(viewWidth, viewHeight);
                draw.mViewState.mDefaultScale = getDefaultZoomScale();
                mLoadedPicture = draw;
                setNewPicture(mLoadedPicture, true);
                mLoadedPicture.mViewState = null;
            return true;
        } catch (IOException e) {
            Log.w(LOGTAG, "Failed to loadViewState", e);
            }
        return false;

        }.execute(stream);
    }

    /**
+42 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ import android.webkit.WebViewInputDispatcher.WebKitCallbacks;

import junit.framework.Assert;

import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
@@ -1046,6 +1047,15 @@ public final class WebViewCore {
        public int mMatchIndex;
    }

    static class SaveViewStateRequest {
        SaveViewStateRequest(OutputStream s, ValueCallback<Boolean> cb) {
            mStream = s;
            mCallback = cb;
        }
        public OutputStream mStream;
        public ValueCallback<Boolean> mCallback;
    }

    /**
     * @hide
     */
@@ -1178,6 +1188,8 @@ public final class WebViewCore {
        static final int KEY_PRESS = 223;
        static final int SET_INITIAL_FOCUS = 224;

        static final int SAVE_VIEW_STATE = 225;

        // Private handler for WebCore messages.
        private Handler mHandler;
        // Message queue for containing messages before the WebCore thread is
@@ -1752,8 +1764,13 @@ public final class WebViewCore {
                        case SET_INITIAL_FOCUS:
                            nativeSetInitialFocus(mNativeClass, msg.arg1);
                            break;
                        case SAVE_VIEW_STATE:
                            SaveViewStateRequest request = (SaveViewStateRequest) msg.obj;
                            saveViewState(request.mStream, request.mCallback);
                            break;
                    }
                }

            };
            // Take all queued messages and resend them to the new handler.
            synchronized (this) {
@@ -2249,6 +2266,31 @@ public final class WebViewCore {
        }
    }

    private void saveViewState(OutputStream stream,
            ValueCallback<Boolean> callback) {
        // TODO: Create a native method to do this better without overloading
        // the draw path (and fix saving <canvas>)
        DrawData draw = new DrawData();
        if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "saveViewState start");
        draw.mBaseLayer = nativeRecordContent(mNativeClass, draw.mInvalRegion,
                draw.mContentSize);
        boolean result = false;
        try {
            result = ViewStateSerializer.serializeViewState(stream, draw);
        } catch (Throwable t) {
            Log.w(LOGTAG, "Failed to save view state", t);
        }
        callback.onReceiveValue(result);
        if (draw.mBaseLayer != 0) {
            if (mDrawIsScheduled) {
                mDrawIsScheduled = false;
                mEventHub.removeMessages(EventHub.WEBKIT_DRAW);
            }
            mLastDrawData = draw;
            webkitDraw(draw);
        }
    }

    static void reducePriority() {
        // remove the pending REDUCE_PRIORITY and RESUME_PRIORITY messages
        sWebCoreHandler.removeMessages(WebCoreThread.REDUCE_PRIORITY);