のねのBlog

パソコンの問題や、ソフトウェアの開発で起きた問題など書いていきます。よろしくお願いします^^。

JB43R11 saveViewState その2

その2

7:frameworks/base/core/java/android/webkit/WebViewCore.java

   2255     private void saveViewState(OutputStream stream,
   2256             ValueCallback<Boolean> callback) {
   2257         // TODO: Create a native method to do this better without overloading
   2258         // the draw path (and fix saving <canvas>)
   2259         DrawData draw = new DrawData(); <=8
   2260         if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "saveViewState start");
   2261         draw.mBaseLayer = nativeRecordContent(mNativeClass, draw.mContentSize);<==Native
   2262         boolean result = false;
   2263         try {
   2264             result = ViewStateSerializer.serializeViewState(stream, draw);
   2265         } catch (Throwable t) {
   2266             Log.w(LOGTAG, "Failed to save view state", t);
   2267         }
   2268         callback.onReceiveValue(result);
   2269         if (draw.mBaseLayer != 0) {
   2270             if (mDrawIsScheduled) {
   2271                 mDrawIsScheduled = false;
   2272                 mEventHub.removeMessages(EventHub.WEBKIT_DRAW);
   2273             }
   2274             mLastDrawData = draw;
   2275             webkitDraw(draw);
   2276         }
   2277     }

8:DrawDataは、以下のようなクラスです。

   2165     static class DrawData {
   2166         DrawData() {
   2167             mBaseLayer = 0;
   2168             mContentSize = new Point();
   2169         }
   2170         int mBaseLayer;
   2171         // view size that was used by webkit during the most recent layout
   2172         Point mViewSize;
   2173         Point mContentSize;
   2174         int mMinPrefWidth;
   2175         // only non-null if it is for the first picture set after the first layout
   2176         ViewState mViewState; <=9
   2177         boolean mFirstLayoutForNonStandardLoad;
   2178     }

9:ViewStateは以下のようなクラスです。

   2152     static class ViewState {
   2153         float mMinScale;
   2154         float mMaxScale;
   2155         float mViewScale;
   2156         float mTextWrapScale;
   2157         float mDefaultScale;
   2158         int mScrollX;
   2159         int mScrollY;
   2160         boolean mMobileSite;
   2161         boolean mIsRestored;
   2162         boolean mShouldStartScrolledRight;
   2163     }

C++の方へ入る。

10:jni/WebViewCore.cpp

    898 BaseLayerAndroid* WebViewCore::recordContent(SkIPoint* point)
    899 {
    900     m_skipContentDraw = true;
    901     layout(); <==11へ
    902     ChromeClientAndroid* chromeC = static_cast<ChromeClientAndroid*>(m_mainFrame->page()->chrome()->client());
    903     GraphicsLayerAndroid* root = static_cast<GraphicsLayerAndroid*>(chromeC->layersSync());
    904     m_skipContentDraw = false;
    905     recordPicturePile(); <==12へ
    906 
    907     BaseLayerAndroid* baseLayer = createBaseLayer(root);
    908 
    909     baseLayer->markAsDirty(m_content.dirtyRegion());
    910     m_content.dirtyRegion().setEmpty();
    911 #if USE(ACCELERATED_COMPOSITING)
    912 #else
    913     baseLayer->markAsDirty(m_rebuildInval);
    914 #endif
    915     point->fX = m_content.size().width();
    916     point->fY = m_content.size().height();
    917 
    918     return baseLayer;
    919 }

11:jni/WebViewCore.cpp

    625 void WebViewCore::layout()
    626 {
    627     TRACE_METHOD();
    628 
    629     // if there is no document yet, just return
    630     if (!m_mainFrame->document()) {
    631         ALOGV("!m_mainFrame->document()");
    632         return;
    633     }
    634 
    635     // Call layout to ensure that the contentWidth and contentHeight are correct
    636     // it's fine for layout to gather invalidates, but defeat sending a message
    637     // back to java to call webkitDraw, since we're already in the middle of
    638     // doing that
    639     bool success = layoutIfNeededRecursive(m_mainFrame);
    640 
    641     // We may be mid-layout and thus cannot draw.
    642     if (!success)
    643         return;
    644 
    645     // if the webkit page dimensions changed, discard the pictureset and redraw.
    646     WebCore::FrameView* view = m_mainFrame->view();
    647     int width = view->contentsWidth();
    648     int height = view->contentsHeight();
    649 
    650     // Use the contents width and height as a starting point.
    651     SkIRect contentRect;
    652     contentRect.set(0, 0, width, height);
    653     SkIRect total(contentRect);
    654 
    655     // Traverse all the frames and add their sizes if they are in the visible
    656     // rectangle.
    657     for (WebCore::Frame* frame = m_mainFrame->tree()->traverseNext(); frame;
    658             frame = frame->tree()->traverseNext()) {
    659         // If the frame doesn't have an owner then it is the top frame and the
    660         // view size is the frame size.
    661         WebCore::RenderPart* owner = frame->ownerRenderer();
    662         if (owner && owner->style()->visibility() == VISIBLE) {
    663             int x = owner->x();
    664             int y = owner->y();
    665 
    666             // Traverse the tree up to the parent to find the absolute position
    667             // of this frame.
    668             WebCore::Frame* parent = frame->tree()->parent();
    669             while (parent) {
    670                 WebCore::RenderPart* parentOwner = parent->ownerRenderer();
    671                 if (parentOwner) {
    672                     x += parentOwner->x();
    673                     y += parentOwner->y();
    674                 }
    675                 parent = parent->tree()->parent();
    676             }
    677             // Use the owner dimensions so that padding and border are
    678             // included.
    679             int right = x + owner->width();
    680             int bottom = y + owner->height();
    681             SkIRect frameRect = {x, y, right, bottom};
    682             // Ignore a width or height that is smaller than 1. Some iframes
    683             // have small dimensions in order to be hidden. The iframe
    684             // expansion code does not expand in that case so we should ignore
    685             // them here.
    686             if (frameRect.width() > 1 && frameRect.height() > 1
    687                     && SkIRect::Intersects(total, frameRect))
    688                 total.join(x, y, right, bottom);
    689         }
    690     }
    691 
    692     // If the new total is larger than the content, resize the view to include
    693     // all the content.
    694     if (!contentRect.contains(total)) {
    695         // TODO: Does this ever happen? Is this needed now that we don't flatten
    696         // frames?
    697         // Resize the view to change the overflow clip.
    698         view->resize(total.fRight, total.fBottom);
    699 
    700         // We have to force a layout in order for the clip to change.
    701         m_mainFrame->contentRenderer()->setNeedsLayoutAndPrefWidthsRecalc();
    702         view->forceLayout();
    703 
    704         // Relayout similar to above
    705         layoutIfNeededRecursive(m_mainFrame);
    706     }
    707 }

12:jni/WebViewCore.cpp

    709 void WebViewCore::recordPicturePile()
    710 {
    711     // if the webkit page dimensions changed, discard the pictureset and redraw.
    712     WebCore::FrameView* view = m_mainFrame->view();
    713     int width = view ? view->contentsWidth() : 0;
    714     int height = view ? view->contentsHeight() : 0;
    715 
    716     m_content.setSize(IntSize(width, height));
    717 
    718     // Rebuild the pictureset (webkit repaint)
    719     m_content.updatePicturesIfNeeded(this);
    720 }