1. drawPicture ANR由 => 169215 161813(PM) 161646(news.baidu) 2.__pthread_cond_timedwai => 167845 3. 新浪微博编辑横屏分屏 => 151337 4.0.3 选择相关的实现 #00 pc 000b517c /system/lib/libskia.so #01 pc 000b540c /system/lib/libskia.so #02 pc 000a9de8 /system/lib/libskia.so (FT_Get_Next_Char+68) #03 pc 000532d4 /system/lib/libskia.so (SkScalerContext_FreeType::generateGlyphToChar(unsigned short)+76) #04 pc 00093e28 /system/lib/libskia.so (SkScalerContext::glyphIDToChar(unsigned short)+96) #05 pc 00086d04 /system/lib/libskia.so (SkPaint::glyphsToUnichars(unsigned short const*, int, int*) const+48) #06 pc 002a2673 /system/lib/libwebcore.so #07 pc 002a387d /system/lib/libwebcore.so #08 pc 00075b30 /system/lib/libskia.so (SkBounder::doIRectGlyph(SkIRect const&, int, int, SkGlyph const&)+264) #09 pc 00076bd0 /system/lib/libskia.so #10 pc 00076a98 /system/lib/libskia.so (SkDraw::drawPosText(char const*, unsigned int, float const*, float, int, SkPaint const&) const+1276) #11 pc 0007156c /system/lib/libskia.so (SkCanvas::drawPosTextH(void const*, unsigned int, float const*, float, SkPaint const&)+720) #12 pc 002a1f47 /system/lib/libwebcore.so #13 pc 0008fd98 /system/lib/libskia.so (SkPicturePlayback::draw(SkCanvas&)+1536) #14 pc 0006d9dc /system/lib/libskia.so (SkCanvas::drawPicture(SkPicture&)+40) #15 pc 002a3e2b /system/lib/libwebcore.so buildSelection() SelectText.cpp #16 pc 002a3fa7 /system/lib/libwebcore.so wordSelection() SelectText.cpp #17 pc 002a4345 /system/lib/libwebcore.so wordSelection() WebView.cpp #18 pc 002a67d7 /system/lib/libwebcore.so nativeWordSelection() WebView.cpp #19 pc 00023670 /system/lib/libdvm.so (dvmPlatformInvoke+112) at android.webkit.WebView.nativeWordSelection(Native Method) at android.webkit.WebView.setUpSelect(WebView.java:5516) at android.webkit.WebView.selectText(WebView.java:4442) at android.webkit.WebView.selectText(WebView.java:4435) at android.webkit.WebView.performLongClick(WebView.java:4420) at android.webkit.WebView$PrivateHandler.handleMessage(WebView.java:8468) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:4477) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:591) at dalvik.system.NativeStart.main(Native Method) #00 pc 000a9990 /system/lib/libskia.so (FT_Get_Next_Char+72) #01 pc 00053224 /system/lib/libskia.so (SkScalerContext_FreeType::generateGlyphToChar(unsigned short)+76) #02 pc 00093a4c /system/lib/libskia.so (SkScalerContext::glyphIDToChar(unsigned short)+96) #03 pc 00086a9c /system/lib/libskia.so (SkPaint::glyphsToUnichars(unsigned short const*, int, int*) const+48) #04 pc 0029e73d /system/lib/libwebcore.so( RingCheck::onIRectGlyph CachedRoot.cpp:844) #05 pc 0007595c /system/lib/libskia.so (SkBounder::doIRectGlyph(SkIRect const&, int, int, SkGlyph const&)+264) #06 pc 000769fc /system/lib/libskia.so #07 pc 000768c4 /system/lib/libskia.so (SkDraw::drawPosText(char const*, unsigned int, float const*, float, int, SkPaint const&) const+1276) #08 pc 000713e4 /system/lib/libskia.so (SkCanvas::drawPosTextH(void const*, unsigned int, float const*, float, SkPaint const&)+720) #09 pc 0029efa1 /system/lib/libwebcore.so (BoundsCanvas::drawPosText CachedRoot.cpp:202) #10 pc 0029f08f /system/lib/libwebcore.so (RingCanvas::drawPosTextH CachedRoot.cpp:998) #11 pc 0008f9f8 /system/lib/libskia.so (SkPicturePlayback::draw(SkCanvas&)+1536) #12 pc 0006d894 /system/lib/libskia.so (SkCanvas::drawPicture(SkPicture&)+40) #13 pc 002a0111 /system/lib/libwebcore.so(BoundsCanvas::drawPicture CachedRoot.cpp:231) #14 pc 0029d7cb /system/lib/libwebcore.so(CachedFrame::checkRings CachedFrame.cpp:140) #15 pc 0029de19 /system/lib/libwebcore.so(CachedNode::fixUpCursorRects CachedNode.cpp:111) #16 pc 0029ffe7 /system/lib/libwebcore.so(CachedRoot::maskIfHidden CachedRoot.cpp:1521) #17 pc 0029cde3 /system/lib/libwebcore.so(CachedFrame::findBestAt CachedFrame.cpp:407) #18 pc 0029faa7 /system/lib/libwebcore.so(CachedRoot::findAt CachedRoot.cpp:1171) #19 pc 002a5e11 /system/lib/libwebcore.so(WebView::fixCursor WebView.cpp:643) #20 pc 002a8471 /system/lib/libwebcore.so(nativeCursorPosition WebView.cpp:1801) //BuilderCheck #0 BuilderCheck () SelectText.cpp:825 #1 MultilineBuilder () SelectText.cpp:970 #2 buildSelection () SelectText.cpp:1274 #3 android::SelectText::getSelectionRegion () SelectText.cpp:1500 #4 android::WebView::getTextSelectionRegion () WebView.cpp:1488 #5 nativeGetTextSelectionRegion () WebView.cpp:1951 //EdgeCheck::onIRectGlyph #0 android::SelectText::EdgeCheck::onIRectGlyph () SelectText.cpp:696 #1 SkBounder::doIRectGlyph () SkDraw.cpp:2472 #2 D1G_Bounder () SkDraw.cpp:1458 #3 SkDraw::drawPosText () SkDraw.cpp:1812 #4 SkCanvas::drawPosTextH () SkCanvas.cpp:1420 #5 android::TextCanvas::drawPosTextH () SelectText.cpp:1250 #6 SkPicturePlayback::draw () SkPicturePlayback.cpp:713 #7 SkCanvas::drawPicture () SkCanvas.cpp:1621 #8 android::SelectText::findEdge () SelectText.cpp:1718 #9 android::SelectText::findLeft () SelectText.cpp:1754 #10 android::SelectText::wordSelection () SelectText.cpp:2031 #11 android::WebView::wordSelection () WebView.cpp:1210 #12 nativeWordSelection () WebView.cpp:2488 #13 setUpSelect() WebView.java 选择基本上可以分为以下几个步骤: 1.用户长安WebView界面 2.默认是选中一行或一个单词,所以首先会计算选择区域 3.获取选中的文本区域或选中的字符都是通过重载不同的SkBounder和SkCanvas来实现的 selectText() WebView.java { //首先设置Select环境,setUpSelect的第一个参数是表示是否选择一个单词,进入 //setUpSelect会先判断选择一个单词是否成功,如果不成功就返回false了。 if (!setUpSelect(true, x, y)) { return false; } //设置为扩展选择模式 nativeSetExtendSelection(); } setUpSelect() WebView.java 选择区域的绘制是在WebView.java drawTextSelectionHandles()中完成的,但选择区域是从WebKit中获取的: getSelectionRegion() 4.1.2 选择相关的实现 //调用createSelectText void WebViewCore::initEditField(Node* node) { SelectText* selectText = createSelectText(focusedFrame()->selection()->selection()); } //EditorClientAndroid::respondToChangedSelection() 1.创建SelectText时机 void WebViewCore::updateTextSelection() { SelectText* selectText = createSelectText(selection); } 2.createSelectText中根据focusedFrame()->selection()->selection()来构建选择区域和文本 SelectText* WebViewCore::createSelectText(const VisibleSelection& selection) { bool isCaret = selection.isCaret(); RefPtr<Range> range = selection.firstRange(); Node* startContainer = range->startContainer(); Node* endContainer = range->endContainer(); if (!startContainer || !endContainer) return 0; if (!isCaret && startContainer == endContainer && range->startOffset() == range->endOffset()) return 0; IntPoint frameOffset = convertGlobalContentToFrameContent(IntPoint()); SelectText* selectTextContainer = new SelectText(); if (isCaret) { setSelectionCaretInfo(selectTextContainer, selection.start(), frameOffset, SelectText::LeftHandle, 0, selection.affinity()); setSelectionCaretInfo(selectTextContainer, selection.start(), frameOffset, SelectText::RightHandle, 0, selection.affinity()); } else { bool ltr = isLtr(selection.start()); Position left = ltr ? selection.start() : selection.end(); Position right = ltr ? selection.end() : selection.start(); int leftOffset = isLtr(left) ? 0 : -1; int rightOffset = isLtr(right) ? 0 : -1; setSelectionCaretInfo(selectTextContainer, left, frameOffset, SelectText::LeftHandle, leftOffset, selection.affinity()); setSelectionCaretInfo(selectTextContainer, right, frameOffset, SelectText::RightHandle, rightOffset, selection.affinity()); Node* stopNode = range->pastLastNode(); for (Node* node = range->firstNode(); node != stopNode; node = node->traverseNextNode()) { RenderObject* r = node->renderer(); if (!r || !r->isText() || r->style()->visibility() != VISIBLE) continue; RenderText* renderText = toRenderText(r); int startOffset = node == startContainer ? range->startOffset() : 0; int endOffset = node == endContainer ? range->endOffset() : numeric_limits<int>::max(); LayerAndroid* layer = 0; int layerId = platformLayerIdFromNode(node, &layer); Vector<IntRect> rects; renderText->absoluteRectsForRange(rects, startOffset, endOffset, true); selectTextContainer->addHighlightRegion(layer, rects, frameOffset); } } selectTextContainer->setText(range->text()); return selectTextContainer; } 3.使用前面两步构建的选择区域 static jobject nativeGetSelection(JNIEnv *env, jobject obj) { WebView* view = GET_NATIVE_VIEW(env, obj); String selection = view->getSelection(); return wtfStringToJstring(env, selection); } 4.绘制选择区域 void RegionLayerDrawExtra::draw(SkCanvas* canvas, LayerAndroid* layer) { SkRegion* region = getHighlightRegionsForLayer(layer); if (!region || region->isEmpty()) return; SkRegion::Iterator rgnIter(*region); SkPaint paint; paint.setColor(m_highlightColor.rgb()); while (!rgnIter.done()) { const SkIRect& rect = rgnIter.rect(); canvas->drawIRect(rect, paint); rgnIter.next(); } } void RegionLayerDrawExtra::drawGL(GLExtras* glExtras, const LayerAndroid* layer) { SkRegion* region = getHighlightRegionsForLayer(layer); if (!region || region->isEmpty()) return; const TransformationMatrix* transform = layer ? layer->drawTransform() : 0; glExtras->drawRegion(*region, true, false, transform, m_highlightColor); } ////////// void WebViewCore::selectText(int startX, int startY, int endX, int endY) { SelectionController* sc = focusedFrame()->selection(); IntPoint startPoint = convertGlobalContentToFrameContent(IntPoint(startX, startY)); VisiblePosition startPosition(visiblePositionForContentPoint(startPoint)); IntPoint endPoint = convertGlobalContentToFrameContent(IntPoint(endX, endY)); VisiblePosition endPosition(visiblePositionForContentPoint(endPoint)); if (startPosition.isNull() || endPosition.isNull()) return; // Ensure startPosition is before endPosition if (comparePositions(startPosition, endPosition) > 0) swap(startPosition, endPosition); if (sc->isContentEditable()) { startPosition = sc->selection().visibleStart().honorEditableBoundaryAtOrAfter(startPosition); endPosition = sc->selection().visibleEnd().honorEditableBoundaryAtOrBefore(endPosition); if (startPosition.isNull() || endPosition.isNull()) { return; } } // Ensure startPosition is not at end of block if (startPosition != endPosition && isEndOfBlock(startPosition)) { VisiblePosition nextStartPosition(startPosition.next()); if (!nextStartPosition.isNull()) startPosition = nextStartPosition; } // Ensure endPosition is not at start of block if (startPosition != endPosition && isStartOfBlock(endPosition)) { VisiblePosition prevEndPosition(endPosition.previous()); if (!prevEndPosition.isNull()) endPosition = prevEndPosition; } Position start = startPosition.deepEquivalent(); Position end = endPosition.deepEquivalent(); start = trimSelectionPosition(start, end); end = trimSelectionPosition(end, start); VisibleSelection selection(start, end); // Only allow changes between caret positions or to text selection. bool selectChangeAllowed = (!selection.isCaret() || sc->isCaret()); if (selectChangeAllowed && sc->shouldChangeSelection(selection)) sc->setSelection(selection); } #0 SkScalerContext_FreeType::generateGlyphToChar() SkFontHost_FreeType.cpp:842 #1 SkScalerContext::glyphIDToChar() SkScalerContext.cpp:273 #2 SkPaint::glyphsToUnichars() SkPaint.cpp:510 #3 android::RingCheck::onIRectGlyph () CachedRoot.cpp:844 #4 SkBounder::doIRectGlyph () SkDraw.cpp:2472 #5 D1G_Bounder () SkDraw.cpp:1458 #6 SkDraw::drawPosText () SkDraw.cpp:1812 #7 SkCanvas::drawPosTextH () SkCanvas.cpp:1420 #8 android::BoundsCanvas::drawPosTextH () CachedRoot.cpp:202 #9 android::RingCanvas::drawPosTextH () CachedRoot.cpp:998 #10 SkPicturePlayback::draw () SkPicturePlayback.cpp:658 #11 SkCanvas::drawPicture () SkCanvas.cpp:1621 #12 android::BoundsCanvas::drawPicture () CachedRoot.cpp:231 #13 android::CachedRoot::maskIfHidden () CachedRoot.cpp:1495 #14 android::CachedFrame::findBestAt () CachedFrame.cpp:407 #15 android::CachedRoot::findAt () CachedRoot.cpp:1171 #16 android::WebView::findAt () WebView.cpp:948 #17 android::WebView::selectBestAt () WebView.cpp:967 #18 nativeSelectBestAt () |
|