分享

Bug笔记

 yujiawang 2013-05-29
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 ()

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多