Пример #1
0
static void write_item(WTF::Vector<char>& v, WebCore::HistoryItem* item)
{
    // Original url
    write_string(v, item->originalURLString());

    // Url
    write_string(v, item->urlString());

    // Title
    write_string(v, item->title());

    // Form content type
    write_string(v, item->formContentType());

    // Form data
    const WebCore::FormData* formData = item->formData();
    if (formData) {
        write_string(v, formData->flattenToString());
        // save the identifier as it is not included in the flatten data
        int64_t id = formData->identifier();
        v.append((char*)&id, sizeof(int64_t));
    } else
        write_string(v, WebCore::String()); // Empty constructor does not allocate a buffer.

    // Target
    write_string(v, item->target());

    AndroidWebHistoryBridge* bridge = item->bridge();
    LOG_ASSERT(bridge, "We should have a bridge here!");
    // Screen scale
    const int scale = bridge->scale();
    LOGV("Writing scale %d", scale);
    v.append((char*)&scale, sizeof(int));
    const int screenWidthScale = bridge->screenWidthScale();
    LOGV("Writing screen width scale %d", screenWidthScale);
    v.append((char*)&screenWidthScale, sizeof(int));

    // Document state
    const WTF::Vector<WebCore::String>& docState = item->documentState();
    WTF::Vector<WebCore::String>::const_iterator end = docState.end();
    unsigned stateSize = docState.size();
    LOGV("Writing docState     %d", stateSize);
    v.append((char*)&stateSize, sizeof(unsigned));
    for (WTF::Vector<WebCore::String>::const_iterator i = docState.begin(); i != end; ++i) {
        write_string(v, *i);
    }

    // Is target item
    LOGV("Writing isTargetItem %d", item->isTargetItem());
    v.append((char)item->isTargetItem());

    // Children count
    unsigned childCount = item->children().size();
    LOGV("Writing childCount   %d", childCount);
    v.append((char*)&childCount, sizeof(unsigned));
}
void FrameLoaderClientAndroid::restoreViewState() {
    WebViewCore* webViewCore = WebViewCore::getWebViewCore(m_frame->view());
    HistoryItem* item = m_frame->loader()->history()->currentItem();
    AndroidWebHistoryBridge* bridge = item->bridge();
    // restore the scale (only) for the top frame
    if (!m_frame->tree()->parent()) {
        int scale = bridge->scale();
        webViewCore->restoreScale(scale);
        int screenWidthScale = bridge->screenWidthScale();
        if (screenWidthScale != scale)
            webViewCore->restoreScreenWidthScale(screenWidthScale);
    }
}
void FrameLoaderClientAndroid::saveViewStateToItem(HistoryItem* item) {
    ASSERT(m_frame);
    ASSERT(item);
    // We should have added a bridge when the child item was added to its
    // parent.
    AndroidWebHistoryBridge* bridge = item->bridge();
    ASSERT(bridge);
    // store the current scale (only) for the top frame
    if (!m_frame->tree()->parent()) {
        WebViewCore* webViewCore = WebViewCore::getWebViewCore(m_frame->view());
        bridge->setScale((int)(webViewCore->scale() * 100));
        bridge->setScreenWidthScale((int)(webViewCore->screenWidthScale() * 100));
    }

    WebCore::notifyHistoryItemChanged(item);
}
Пример #4
0
static bool read_item_recursive(WebCore::HistoryItem* newItem,
        const char** pData, int length)
{
    if (!pData || length < HISTORY_MIN_SIZE)
        return false;

    const WebCore::TextEncoding& e = WebCore::UTF8Encoding();
    const char* data = *pData;
    const char* end = data + length;
    int sizeofUnsigned = (int)sizeof(unsigned);

    // Read the original url
    // Read the expected length of the string.
    int l;
    memcpy(&l, data, sizeofUnsigned);
    // Increment data pointer by the size of an unsigned int.
    data += sizeofUnsigned;
    if (l) {
        LOGV("Original url    %d %.*s", l, l, data);
        // If we have a length, check if that length exceeds the data length
        // and return null if there is not enough data.
        if (data + l < end)
            newItem->setOriginalURLString(e.decode(data, l));
        else
            return false;
        // Increment the data pointer by the length of the string.
        data += l;
    }
    // Check if we have enough data left to continue.
    if (end - data < sizeofUnsigned)
        return false;

    // Read the url
    memcpy(&l, data, sizeofUnsigned);
    data += sizeofUnsigned;
    if (l) {
        LOGV("Url             %d %.*s", l, l, data);
        if (data + l < end)
            newItem->setURLString(e.decode(data, l));
        else
            return false;
        data += l;
    }
    if (end - data < sizeofUnsigned)
        return false;

    // Read the title
    memcpy(&l, data, sizeofUnsigned);
    data += sizeofUnsigned;
    if (l) {
        LOGV("Title           %d %.*s", l, l, data);
        if (data + l < end)
            newItem->setTitle(e.decode(data, l));
        else
            return false;
        data += l;
    }
    if (end - data < sizeofUnsigned)
        return false;

    // Generate a new ResourceRequest object for populating form information.
    WebCore::String formContentType;
    WTF::PassRefPtr<WebCore::FormData> formData = NULL;

    // Read the form content type
    memcpy(&l, data, sizeofUnsigned);
    data += sizeofUnsigned;
    if (l) {
        LOGV("Content type    %d %.*s", l, l, data);
        if (data + l < end)
            formContentType = e.decode(data, l);
        else
            return false;
        data += l;
    }
    if (end - data < sizeofUnsigned)
        return false;

    // Read the form data
    memcpy(&l, data, sizeofUnsigned);
    data += sizeofUnsigned;
    if (l) {
        LOGV("Form data       %d %.*s", l, l, data);
        if (data + l < end)
            formData = WebCore::FormData::create(data, l);
        else
            return false;
        data += l;
        // Read the identifier
        {
            int64_t id;
            int size = (int)sizeof(int64_t);
            memcpy(&id, data, size);
            data += size;
            if (id)
                formData->setIdentifier(id);
        }
    }
    if (end - data < sizeofUnsigned)
        return false;

    // Set up the form info
    if (formData != NULL) {
        WebCore::ResourceRequest r;
        r.setHTTPMethod("POST");
        r.setHTTPContentType(formContentType);
        r.setHTTPBody(formData);
        newItem->setFormInfoFromRequest(r);
    }

    // Read the target
    memcpy(&l, data, sizeofUnsigned);
    data += sizeofUnsigned;
    if (l) {
        LOGV("Target          %d %.*s", l, l, data);
        if (data + l < end)
            newItem->setTarget(e.decode(data, l));
        else
            return false;
        data += l;
    }
    if (end - data < sizeofUnsigned)
        return false;

    AndroidWebHistoryBridge* bridge = newItem->bridge();
    LOG_ASSERT(bridge, "There should be a bridge object during inflate");
    // Read the screen scale
    memcpy(&l, data, sizeofUnsigned);
    LOGV("Screen scale    %d", l);
    bridge->setScale(l);
    data += sizeofUnsigned;
    memcpy(&l, data, sizeofUnsigned);
    LOGV("Screen width scale    %d", l);
    bridge->setScreenWidthScale(l);
    data += sizeofUnsigned;

    if (end - data < sizeofUnsigned)
        return false;

    // Read the document state
    memcpy(&l, data, sizeofUnsigned);
    LOGV("Document state  %d", l);
    data += sizeofUnsigned;
    if (l) {
        // Check if we have enough data to at least parse the sizes of each
        // document state string.
        if (data + l * sizeofUnsigned >= end)
            return false;
        // Create a new vector and reserve enough space for the document state.
        WTF::Vector<WebCore::String> docState;
        docState.reserveCapacity(l);
        while (l--) {
            // Check each time if we have enough to parse the length of the next
            // string.
            if (end - data < sizeofUnsigned)
                return false;
            int strLen;
            memcpy(&strLen, data, sizeofUnsigned);
            data += sizeofUnsigned;
            if (data + strLen < end)
                docState.append(e.decode(data, strLen));
            else
                return false;
            LOGV("\t\t%d %.*s", strLen, strLen, data);
            data += strLen;
        }
        newItem->setDocumentState(docState);
    }
    // Check if we have enough to read the next byte
    if (data >= end)
        return false;

    // Read is target item
    // Cast the value to unsigned char in order to make a negative value larger
    // than 1. A value that is not 0 or 1 is a failure.
    unsigned char c = (unsigned char)data[0];
    if (c > 1)
        return false;
    LOGV("Target item     %d", c);
    newItem->setIsTargetItem((bool)c);
    data++;
    if (end - data < sizeofUnsigned)
        return false;

    // Read the child count
    memcpy(&l, data, sizeofUnsigned);
    LOGV("Child count     %d", l);
    data += sizeofUnsigned;
    *pData = data;
    if (l) {
        // Check if we have the minimum amount need to parse l children.
        if (data + l * HISTORY_MIN_SIZE >= end)
            return false;
        while (l--) {
            // No need to check the length each time because read_item_recursive
            // will return null if there isn't enough data left to parse.
            WTF::PassRefPtr<WebCore::HistoryItem> child = WebCore::HistoryItem::create();
            // Set a bridge that will not call into java.
            child->setBridge(new WebHistoryItem(static_cast<WebHistoryItem*>(bridge)));
            // Read the child item.
            if (!read_item_recursive(child.get(), pData, end - data)) {
                child.clear();
                return false;
            }
            child->bridge()->setActive();
            newItem->addChildItem(child);
        }
    }
    return true;
}
static bool readItemRecursive(WebCore::HistoryItem* newItem,
        const char** pData, int length)
{
    if (!pData || length < HISTORY_MIN_SIZE) {
        ALOGW("readItemRecursive() bad params; pData=%p length=%d", pData, length);
        return false;
    }

    const char* data = *pData;
    const char* end = data + length;
    String content;

    // Read the original url
    if (readString(data, end, content, "Original url"))
        newItem->setOriginalURLString(content);
    else
        return false;

    // Read the url
    if (readString(data, end, content, "Url"))
        newItem->setURLString(content);
    else
        return false;

    // Read the title
    if (readString(data, end, content, "Title"))
        newItem->setTitle(content);
    else
        return false;

    // Generate a new ResourceRequest object for populating form information.
    // Read the form content type
    WTF::String formContentType;
    if (!readString(data, end, formContentType, "Content type"))
        return false;

    // Read the form data size
    unsigned formDataSize;
    if (!readUnsigned(data, end, formDataSize, "Form data size"))
        return false;

    // Read the form data
    WTF::RefPtr<WebCore::FormData> formData;
    if (formDataSize) {
        ALOGV("Reading Form data       %d %.*s", formDataSize, formDataSize, data);
        if ((end < data) || ((size_t)(end - data) < formDataSize)) {
            ALOGW("\tNot enough data to read form data; returning");
            return false;
        }
        formData = WebCore::FormData::create(data, formDataSize);
        data += formDataSize;
        // Read the identifier
        int64_t id;
        if (!readInt64(data, end, id, "Form id"))
            return false;
        if (id)
            formData->setIdentifier(id);
    }

    // Set up the form info
    if (formData != NULL) {
        WebCore::ResourceRequest r;
        r.setHTTPMethod("POST");
        r.setHTTPContentType(formContentType);
        r.setHTTPBody(formData);
        newItem->setFormInfoFromRequest(r);
    }

    // Read the target
    if (readString(data, end, content, "Target"))
        newItem->setTarget(content);
    else
        return false;

    AndroidWebHistoryBridge* bridge = newItem->bridge();
    ALOG_ASSERT(bridge, "There should be a bridge object during inflate");

    // Read the screen scale
    float fValue;
    if (readFloat(data, end, fValue, "Screen scale"))
        bridge->setScale(fValue);
    else
        return false;

    // Read the text wrap scale
    if (readFloat(data, end, fValue, "Text wrap scale"))
        bridge->setTextWrapScale(fValue);
    else
        return false;

    // Read scroll position.
    int scrollX;
    if (!readInt(data, end, scrollX, "Scroll pos x"))
        return false;
    int scrollY;
    if (!readInt(data, end, scrollY, "Scroll pos y"))
        return false;
    newItem->setScrollPoint(IntPoint(scrollX, scrollY));

    // Read the document state
    unsigned docStateCount;
    if (!readUnsigned(data, end, docStateCount, "Doc state count"))
        return false;
    if (docStateCount) {
        // Create a new vector and reserve enough space for the document state.
        WTF::Vector<WTF::String> docState;
        docState.reserveCapacity(docStateCount);
        while (docStateCount--) {
            // Read a document state string
            if (readString(data, end, content, "Document state"))
                docState.append(content);
            else
                return false;
        }
        newItem->setDocumentState(docState);
    }

    // Read is target item
    bool c;
    if (readBool(data, end, c, "Target item"))
        newItem->setIsTargetItem(c);
    else
        return false;

    // Read the child count
    unsigned count;
    if (!readUnsigned(data, end, count, "Child count"))
        return false;
    *pData = data;
    if (count) {
        while (count--) {
            // No need to check the length each time because read_item_recursive
            // will return null if there isn't enough data left to parse.
            WTF::RefPtr<WebCore::HistoryItem> child = WebCore::HistoryItem::create();
            // Set a bridge that will not call into java.
            child->setBridge(new WebHistoryItem(static_cast<WebHistoryItem*>(bridge)));
            // Read the child item.
            if (!readItemRecursive(child.get(), pData, end - data))
                return false;
            child->bridge()->setActive();
            newItem->addChildItem(child);
        }
    }
    return true;
}
Пример #6
0
static void writeItem(WTF::Vector<char>& vector, WebCore::HistoryItem* item)
{
    // Original url
    writeString(vector, item->originalURLString());

    // Url
    writeString(vector, item->urlString());

    // Title
    writeString(vector, item->title());

    // Form content type
    writeString(vector, item->formContentType());

    // Form data
    const WebCore::FormData* formData = item->formData();
    if (formData) {
        // write a flag means formData is not null.
        unsigned flag = FLAG_NOT_NULL;
        vector.append((char*)&flag, sizeof(unsigned));
        //LOGD("Writing Form data if {} Tag");
        /*guoxiaolei 20120827 end>*/
        writeString(vector, formData->flattenToString());
        // save the identifier as it is not included in the flatten data
        int64_t id = formData->identifier();
        //LOGD("Writing the identifier       %d ", id);
        /*guoxiaolei 20120827 end>*/
        vector.append((char*)&id, sizeof(int64_t));
    } else{
        //LOGD("Writing Form data else {} Tag");
        //write_string(v, WTF::String()); // Empty constructor does not allocate a buffer.
        // write a flag means formData is null.
        unsigned flag = FLAG_IS_NULL;
        vector.append((char*)&flag, sizeof(unsigned));
    }
    /*guoxiaolei 20120827 end>*/

    // Target
    writeString(vector, item->target());

    AndroidWebHistoryBridge* bridge = item->bridge();
    ALOG_ASSERT(bridge, "We should have a bridge here!");
    // Screen scale
    const float scale = bridge->scale();
    ALOGV("Writing scale           %f", scale);
    vector.append((char*)&scale, sizeof(float));
    const float textWrapScale = bridge->textWrapScale();
    ALOGV("Writing text wrap scale %f", textWrapScale);
    vector.append((char*)&textWrapScale, sizeof(float));

    // Scroll position.
    const int scrollX = item->scrollPoint().x();
    vector.append((char*)&scrollX, sizeof(int));
    const int scrollY = item->scrollPoint().y();
    vector.append((char*)&scrollY, sizeof(int));

    // Document state
    const WTF::Vector<WTF::String>& docState = item->documentState();
    WTF::Vector<WTF::String>::const_iterator end = docState.end();
    unsigned stateSize = docState.size();
    ALOGV("Writing docState        %d", stateSize);
    vector.append((char*)&stateSize, sizeof(unsigned));
    for (WTF::Vector<WTF::String>::const_iterator i = docState.begin(); i != end; ++i) {
        writeString(vector, *i);
    }

    // Is target item
    ALOGV("Writing isTargetItem    %d", item->isTargetItem());
    vector.append((char)item->isTargetItem());

    // Children count
    unsigned childCount = item->children().size();
    ALOGV("Writing childCount      %d", childCount);
    vector.append((char*)&childCount, sizeof(unsigned));
}