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 }