SaveViewState その2
2274 private void saveViewState(OutputStream stream, 2275 ValueCallback<Boolean> callback) { 2276 // TODO: Create a native method to do this better without overloading 2277 // the draw path (and fix saving <canvas&>) 2278 DrawData draw = new DrawData(); <=8 2279 if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "saveViewState start"); 2280 draw.mBaseLayer = nativeRecordContent(mNativeClass, draw.mContentSize); =>10へ 2281 boolean result = false; 2282 try { 2283 result = ViewStateSerializer.serializeViewState(stream, draw); 2284 } catch (Throwable t) { 2285 Log.w(LOGTAG, "Failed to save view state", t); 2286 } 2287 callback.onReceiveValue(result); 2288 if (draw.mBaseLayer != 0) { 2289 if (mDrawIsScheduled) { 2290 mDrawIsScheduled = false; 2291 mEventHub.removeMessages(EventHub.WEBKIT_DRAW); 2292 } 2293 mLastDrawData = draw; 2294 webkitDraw(draw); 2295 } 2296 }
8:DrawDataは、以下のようなクラスです。
2182 static class DrawData { 2183 DrawData() { 2184 mBaseLayer = 0; 2185 mContentSize = new Point(); 2186 } 2187 int mBaseLayer; 2188 // view size that was used by webkit during the most recent layout 2189 Point mViewSize; 2190 Point mContentSize; 2191 int mMinPrefWidth; 2192 // only non-null if it is for the first picture set after the first layout 2193 ViewState mViewState; <= 9 2194 boolean mFirstLayoutForNonStandardLoad; 2195 boolean mFocusSizeChanged; 2196 }
9:ViewStateは以下のようなクラスです。
2169 static class ViewState { 2170 float mMinScale; 2171 float mMaxScale; 2172 float mViewScale; 2173 float mTextWrapScale; 2174 float mDefaultScale; 2175 int mScrollX; 2176 int mScrollY; 2177 boolean mMobileSite; 2178 boolean mIsRestored; 2179 boolean mShouldStartScrolledRight; 2180 }
C++の方へ入る。
10:jni/WebViewCore.cpp
908 BaseLayerAndroid* WebViewCore::recordContent(SkIPoint* point) 909 { 910 m_skipContentDraw = true; 911 layout(); =>11へ 912 ChromeClientAndroid* chromeC = static_cast<ChromeClientAndroid*> (m_mainFrame->page()->chrome()->client()); 913 GraphicsLayerAndroid* root = static_cast<GraphicsLayerAndroid*> (chromeC->layersSync()); 914 m_skipContentDraw = false; 915 recordPicturePile(); =>12 916 917 BaseLayerAndroid* baseLayer = createBaseLayer(root); 918 919 baseLayer->markAsDirty(m_content.dirtyRegion()); 920 m_content.dirtyRegion().setEmpty(); 921 #if USE(ACCELERATED_COMPOSITING) 922 #else 923 baseLayer->markAsDirty(m_rebuildInval); 924 #endif 925 point->fX = m_content.size().width(); 926 point->fY = m_content.size().height(); 927 928 return baseLayer; 929 }
11:jni/WebViewCore.cpp
628 void WebViewCore::layout() 629 { 630 TRACE_METHOD(); 631 632 // if there is no document yet, just return 633 if (!m_mainFrame->document()) { 634 ALOGV("!m_mainFrame->document()"); 635 return; 636 } 637 638 // Call layout to ensure that the contentWidth and contentHeight are correct 639 // it's fine for layout to gather invalidates, but defeat sending a message 640 // back to java to call webkitDraw, since we're already in the middle of 641 // doing that 642 bool success = layoutIfNeededRecursive(m_mainFrame); 643 644 // We may be mid-layout and thus cannot draw. 645 if (!success) 646 return; 647 648 // if the webkit page dimensions changed, discard the pictureset and redraw. 649 WebCore::FrameView* view = m_mainFrame->view(); 650 int width = view->contentsWidth(); 651 int height = view->contentsHeight(); 652 653 // Use the contents width and height as a starting point. 654 SkIRect contentRect; 655 contentRect.set(0, 0, width, height); 656 SkIRect total(contentRect); 657 658 // Traverse all the frames and add their sizes if they are in the visible 659 // rectangle. 660 for (WebCore::Frame* frame = m_mainFrame->tree()->traverseNext(); frame; 661 frame = frame->tree()->traverseNext()) { 662 // If the frame doesn't have an owner then it is the top frame and the 663 // view size is the frame size. 664 WebCore::RenderPart* owner = frame->ownerRenderer(); 665 if (owner && owner->style()->visibility() == VISIBLE) { 666 int x = owner->x(); 667 int y = owner->y(); 668 669 // Traverse the tree up to the parent to find the absolute position 670 // of this frame. 671 WebCore::Frame* parent = frame->tree()->parent(); 672 while (parent) { 673 WebCore::RenderPart* parentOwner = parent->ownerRenderer(); 674 if (parentOwner) { 675 x += parentOwner->x(); 676 y += parentOwner->y(); 677 } 678 parent = parent->tree()->parent(); 679 } 680 // Use the owner dimensions so that padding and border are 681 // included. 682 int right = x + owner->width(); 683 int bottom = y + owner->height(); 684 SkIRect frameRect = {x, y, right, bottom}; 685 // Ignore a width or height that is smaller than 1. Some iframes 686 // have small dimensions in order to be hidden. The iframe 687 // expansion code does not expand in that case so we should ignore 688 // them here. 689 if (frameRect.width() > 1 && frameRect.height() > 1 690 && SkIRect::Intersects(total, frameRect)) 691 total.join(x, y, right, bottom); 692 } 693 } 694 695 // If the new total is larger than the content, resize the view to include 696 // all the content. 697 if (!contentRect.contains(total)) { 698 // TODO: Does this ever happen? Is this needed now that we don't flatten 699 // frames? 700 // Resize the view to change the overflow clip. 701 view->resize(total.fRight, total.fBottom); 702 703 // We have to force a layout in order for the clip to change. 704 m_mainFrame->contentRenderer()->setNeedsLayoutAndPrefWidthsRecalc(); 705 view->forceLayout(); 706 707 // Relayout similar to above 708 layoutIfNeededRecursive(m_mainFrame); 709 } 710 } 711
12:jni/WebViewCore.cpp
712 void WebViewCore::recordPicturePile() 713 { 714 // if the webkit page dimensions changed, discard the pictureset and redraw. 715 WebCore::FrameView* view = m_mainFrame->view(); 716 int width = view ? view->contentsWidth() : 0; 717 int height = view ? view->contentsHeight() : 0; 718 719 m_content.setSize(IntSize(width, height)); 720 721 // Rebuild the pictureset (webkit repaint) 722 m_content.updatePicturesIfNeeded(this); 723 }