WebHistory.cpp revision 4d31493c3fa47a28b2753bc5b99e2074b6a7a4df
18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright 2007, The Android Open Source Project 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met: 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * * Redistributions of source code must retain the above copyright 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer. 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * * Redistributions in binary form must reproduce the above copyright 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * documentation and/or other materials provided with the distribution. 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 163298a7d84b96ade73c6b170671711a8f2792ae59Steve Block * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define LOG_TAG "webhistory" 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2820ab751acc0d49d74648373f701f3d0c4ff187c0Steve Block#include "config.h" 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "WebHistory.h" 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 31e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck#include "AndroidLog.h" 328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "BackForwardList.h" 33d0dada9ef392026973da2fbb2cb4d9b9504f91f0Teng-Hui Zhu#include "BackForwardListImpl.h" 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "DocumentLoader.h" 358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Frame.h" 368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameLoader.h" 378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameLoaderClientAndroid.h" 388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameTree.h" 39e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck#include "GraphicsJNI.h" 408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HistoryItem.h" 41635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "IconDatabase.h" 428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Page.h" 438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "TextEncoding.h" 448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "WebCoreFrameBridge.h" 458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "WebCoreJni.h" 4694f369b3daaa736ae6488f8f206884d0dcf600aaPatrick Scott#include "WebIconDatabase.h" 478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <JNIHelp.h> 4920ab751acc0d49d74648373f701f3d0c4ff187c0Steve Block#include "JNIUtility.h" 508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <SkUtils.h> 518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <utils/misc.h> 5220ab751acc0d49d74648373f701f3d0c4ff187c0Steve Block#include <wtf/OwnPtr.h> 5320ab751acc0d49d74648373f701f3d0c4ff187c0Steve Block#include <wtf/Platform.h> 5479768700a853c40c66ff0b0591957958667fdd9eSteve Block#include <wtf/text/CString.h> 558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace android { 578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Forward declarations 59c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brennerstatic void writeItem(WTF::Vector<char>& vector, WebCore::HistoryItem* item); 60c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brennerstatic void writeChildrenRecursive(WTF::Vector<char>& vector, WebCore::HistoryItem* parent); 61c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brennerstatic bool readItemRecursive(WebCore::HistoryItem* child, const char** pData, int length); 628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Field ids for WebHistoryItems 648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstruct WebHistoryItemFields { 658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project jmethodID mInit; 668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} gWebHistoryItem; 678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstruct WebBackForwardListFields { 698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project jmethodID mAddHistoryItem; 708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project jmethodID mRemoveHistoryItem; 71730ce864fef32412598ac6b1f5e48a02f217ca25Patrick Scott jmethodID mSetCurrentIndex; 728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} gWebBackForwardList; 738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project//-------------------------------------------------------------------------- 758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// WebBackForwardList native methods. 768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project//-------------------------------------------------------------------------- 778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void WebHistoryClose(JNIEnv* env, jobject obj, jint frame) 798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 806dd76b804786ec760bb04b137a6bf017064226dcSteve Block ALOG_ASSERT(frame, "Close needs a valid Frame pointer!"); 818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebCore::Frame* pFrame = (WebCore::Frame*)frame; 828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 83d0dada9ef392026973da2fbb2cb4d9b9504f91f0Teng-Hui Zhu WebCore::BackForwardListImpl* list = static_cast<WebCore::BackForwardListImpl*>(pFrame->page()->backForwardList()); 848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RefPtr<WebCore::HistoryItem> current = list->currentItem(); 858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Remove each item instead of using close(). close() is intended to be used 868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // right before the list is deleted. 878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebCore::HistoryItemVector& entries = list->entries(); 888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int size = entries.size(); 898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (int i = size - 1; i >= 0; --i) 908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project list->removeItem(entries[i].get()); 918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Add the current item back to the list. 928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (current) { 93be33b78f63b17f1b6f5a36a503d797d5f9b941eeBen Murdoch current->setBridge(0); 948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // addItem will update the children to match the newly created bridge 958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project list->addItem(current); 968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* 988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * The Grand Prix site uses anchor navigations to change the display. 998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * WebKit tries to be smart and not load child frames that have the 1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * same history urls during an anchor navigation. This means that the 1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * current history item stored in the child frame's loader does not 1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * match the item found in the history tree. If we remove all the 1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * entries in the back/foward list, we have to restore the entire tree 1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * or else a HistoryItem might have a deleted parent. 1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * In order to restore the history tree correctly, we have to look up 1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * all the frames first and then look up the history item. We do this 1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * because the history item in the tree may be null at this point. 1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Unfortunately, a HistoryItem can only search its immediately 1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * children so we do a breadth-first rebuild of the tree. 1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Keep a small list of child frames to traverse. 1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WTF::Vector<WebCore::Frame*> frameQueue; 1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Fix the top-level item. 11667ed0edeb2ad5bb22ec778472b78d41e7eb3b68aSteve Block pFrame->loader()->history()->setCurrentItem(current.get()); 1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebCore::Frame* child = pFrame->tree()->firstChild(); 1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Remember the parent history item so we can search for a child item. 1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RefPtr<WebCore::HistoryItem> parent = current; 1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (child) { 1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Use the old history item since the current one may have a 1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // deleted parent. 1235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian WebCore::HistoryItem* item = parent->childItemWithTarget(child->tree()->name()); 12467ed0edeb2ad5bb22ec778472b78d41e7eb3b68aSteve Block child->loader()->history()->setCurrentItem(item); 125db239ca3504af9998d5717708fdef4676e286602Patrick Scott // Append the first child to the queue if it exists. If there is no 126db239ca3504af9998d5717708fdef4676e286602Patrick Scott // item, then we do not need to traverse the children since there 127db239ca3504af9998d5717708fdef4676e286602Patrick Scott // will be no parent history item. 128db239ca3504af9998d5717708fdef4676e286602Patrick Scott WebCore::Frame* firstChild; 129db239ca3504af9998d5717708fdef4676e286602Patrick Scott if (item && (firstChild = child->tree()->firstChild())) 130db239ca3504af9998d5717708fdef4676e286602Patrick Scott frameQueue.append(firstChild); 1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project child = child->tree()->nextSibling(); 1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If we don't have a sibling for this frame and the queue isn't 1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // empty, use the next entry in the queue. 1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!child && !frameQueue.isEmpty()) { 1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project child = frameQueue.at(0); 1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project frameQueue.remove(0); 1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Figure out the parent history item used when searching for 1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // the history item to use. 13967ed0edeb2ad5bb22ec778472b78d41e7eb3b68aSteve Block parent = child->tree()->parent()->loader()->history()->currentItem(); 1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void WebHistoryRestoreIndex(JNIEnv* env, jobject obj, jint frame, jint index) 1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1476dd76b804786ec760bb04b137a6bf017064226dcSteve Block ALOG_ASSERT(frame, "RestoreState needs a valid Frame pointer!"); 1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebCore::Frame* pFrame = (WebCore::Frame*)frame; 149635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project WebCore::Page* page = pFrame->page(); 150fa1ac15a8417461f160824c688d94b80150f799ePatrick Scott WebCore::HistoryItem* currentItem = 151d0dada9ef392026973da2fbb2cb4d9b9504f91f0Teng-Hui Zhu static_cast<WebCore::BackForwardListImpl*>(page->backForwardList())->entries()[index].get(); 1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 153635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // load the current page with FrameLoadTypeIndexedBackForward so that it 154635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // will use cache when it is possible 155635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project page->goToItem(currentItem, FrameLoadTypeIndexedBackForward); 1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 158e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reckstatic jint WebHistoryInflate(JNIEnv* env, jobject obj, jint frame, jbyteArray data) 1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1606dd76b804786ec760bb04b137a6bf017064226dcSteve Block ALOG_ASSERT(frame, "Inflate needs a valid frame pointer!"); 1616dd76b804786ec760bb04b137a6bf017064226dcSteve Block ALOG_ASSERT(data, "Inflate needs a valid data pointer!"); 1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Get the actual bytes and the length from the java array. 1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const jbyte* bytes = env->GetByteArrayElements(data, NULL); 1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project jsize size = env->GetArrayLength(data); 1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Inflate the history tree into one HistoryItem or null if the inflation 1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // failed. 1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RefPtr<WebCore::HistoryItem> newItem = WebCore::HistoryItem::create(); 170e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck WebHistoryItem* bridge = new WebHistoryItem(newItem.get()); 1718c5d18443e0c51c5762b25da443b1a76c75a5d86Patrick Scott newItem->setBridge(bridge); 172be33b78f63b17f1b6f5a36a503d797d5f9b941eeBen Murdoch 1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Inflate the item recursively. If it fails, that is ok. We'll have an 1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // incomplete HistoryItem but that is better than crashing due to a null 1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // item. 1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We have a 2nd local variable since read_item_recursive may change the 1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // ptr's value. We can't pass &bytes since we have to send bytes to 1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // ReleaseByteArrayElements unchanged. 1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const char* ptr = reinterpret_cast<const char*>(bytes); 180c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner readItemRecursive(newItem.get(), &ptr, (int)size); 1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project env->ReleaseByteArrayElements(data, const_cast<jbyte*>(bytes), JNI_ABORT); 1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bridge->setActive(); 1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Add the new item to the back/forward list. 1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebCore::Frame* pFrame = (WebCore::Frame*)frame; 1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project pFrame->page()->backForwardList()->addItem(newItem); 1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Update the item. 1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bridge->updateHistoryItem(newItem.get()); 190e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck // Ref here because Java expects to adopt the reference, and as such will not 191e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck // call ref on it. However, setBridge has also adopted the reference 192e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck // TODO: This is confusing as hell, clean up ownership and have setBridge 193e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck // take a RefPtr instead of a raw ptr and calling adoptRef on it 194e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck bridge->ref(); 195e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck return reinterpret_cast<jint>(bridge); 196e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck} 197e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck 198e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reckstatic void WebHistoryRef(JNIEnv* env, jobject obj, jint ptr) 199e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck{ 200e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck if (ptr) 201e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck reinterpret_cast<WebHistoryItem*>(ptr)->ref(); 202e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck} 203e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck 204e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reckstatic void WebHistoryUnref(JNIEnv* env, jobject obj, jint ptr) 205e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck{ 206e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck if (ptr) 207e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck reinterpret_cast<WebHistoryItem*>(ptr)->deref(); 208e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck} 209e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck 210e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reckstatic jobject WebHistoryGetTitle(JNIEnv* env, jobject obj, jint ptr) 211e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck{ 212e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck if (!ptr) 213e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck return 0; 214e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck WebHistoryItem* item = reinterpret_cast<WebHistoryItem*>(ptr); 215e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck MutexLocker locker(item->m_lock); 216e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck return wtfStringToJstring(env, item->m_title, false); 217e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck} 218e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck 219e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reckstatic jobject WebHistoryGetUrl(JNIEnv* env, jobject obj, jint ptr) 220e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck{ 221e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck if (!ptr) 222e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck return 0; 223e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck WebHistoryItem* item = reinterpret_cast<WebHistoryItem*>(ptr); 224e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck MutexLocker locker(item->m_lock); 225e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck return wtfStringToJstring(env, item->m_url, false); 226e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck} 227e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck 228e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reckstatic jobject WebHistoryGetOriginalUrl(JNIEnv* env, jobject obj, jint ptr) 229e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck{ 230e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck if (!ptr) 231e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck return 0; 232e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck WebHistoryItem* item = reinterpret_cast<WebHistoryItem*>(ptr); 233e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck MutexLocker locker(item->m_lock); 234e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck return wtfStringToJstring(env, item->m_originalUrl, false); 235e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck} 236e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck 237e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reckstatic jobject WebHistoryGetFlattenedData(JNIEnv* env, jobject obj, jint ptr) 238e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck{ 239e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck if (!ptr) 240e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck return 0; 241e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck 242e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck WebHistoryItem* item = reinterpret_cast<WebHistoryItem*>(ptr); 243e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck MutexLocker locker(item->m_lock); 244e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck 245e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck if (!item->m_dataCached) { 246e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck // Try to create a new java byte array. 247e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck jbyteArray b = env->NewByteArray(item->m_data.size()); 248e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck if (!b) 249e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck return NULL; 250e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck 251e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck // Write our flattened data to the java array. 252e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck env->SetByteArrayRegion(b, 0, item->m_data.size(), 253e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck (const jbyte*)item->m_data.data()); 254e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck item->m_dataCached = env->NewGlobalRef(b); 255e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck env->DeleteLocalRef(b); 256e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck } 257e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck return item->m_dataCached; 258e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck} 259e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck 260e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reckstatic jobject WebHistoryGetFavicon(JNIEnv* env, jobject obj, jint ptr) 261e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck{ 262e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck if (!ptr) 263e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck return 0; 264e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck WebHistoryItem* item = reinterpret_cast<WebHistoryItem*>(ptr); 265e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck MutexLocker locker(item->m_lock); 2664d31493c3fa47a28b2753bc5b99e2074b6a7a4dfJohn Reck if (!item->m_faviconCached && item->m_favicon) { 267e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck jobject favicon = GraphicsJNI::createBitmap(env, 2684d31493c3fa47a28b2753bc5b99e2074b6a7a4dfJohn Reck item->m_favicon, 269e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck false, NULL); 2704d31493c3fa47a28b2753bc5b99e2074b6a7a4dfJohn Reck item->m_favicon = 0; // Framework now owns the pointer 271e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck item->m_faviconCached = env->NewGlobalRef(favicon); 272e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck env->DeleteLocalRef(favicon); 273e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck } 274e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck return item->m_faviconCached; 2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 27761e86687816f581053a96dc2686208fe3616ae40Shimeng (Simon) Wang// 6 empty strings + no document state + children count + 2 scales = 10 unsigned values 27861e86687816f581053a96dc2686208fe3616ae40Shimeng (Simon) Wang// 1 char for isTargetItem. 27961e86687816f581053a96dc2686208fe3616ae40Shimeng (Simon) Wang#define HISTORY_MIN_SIZE ((int)(sizeof(unsigned) * 10 + sizeof(char))) 2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 281e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reckvoid WebHistory::Flatten(JNIEnv* env, WTF::Vector<char>& vector, WebCore::HistoryItem* item) 2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!item) 284e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck return; 2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Reserve a vector of chars with an initial size of HISTORY_MIN_SIZE. 287c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner vector.reserveCapacity(HISTORY_MIN_SIZE); 2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Write the top-level history item and then write all the children 2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // recursively. 2916dd76b804786ec760bb04b137a6bf017064226dcSteve Block ALOG_ASSERT(item->bridge(), "Why don't we have a bridge object here?"); 292c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner writeItem(vector, item); 293c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner writeChildrenRecursive(vector, item); 2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid WebHistoryItem::updateHistoryItem(WebCore::HistoryItem* item) { 2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Do not want to update during inflation. 298be33b78f63b17f1b6f5a36a503d797d5f9b941eeBen Murdoch if (!m_active) 2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebHistoryItem* webItem = this; 3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Now we need to update the top-most WebHistoryItem based on the top-most 3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // HistoryItem. 303be33b78f63b17f1b6f5a36a503d797d5f9b941eeBen Murdoch if (m_parent) { 304be33b78f63b17f1b6f5a36a503d797d5f9b941eeBen Murdoch webItem = m_parent.get(); 3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (webItem->hasOneRef()) { 3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // if the parent only has one ref, it is from this WebHistoryItem. 3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // This means that the matching WebCore::HistoryItem has been freed. 3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // This can happen during clear(). 3097d99b5804f0800191b03d83fc8f8d2886271475bSteve Block ALOGW("Can't updateHistoryItem as the top HistoryItem is gone"); 3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (webItem->parent()) 3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project webItem = webItem->parent(); 3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project item = webItem->historyItem(); 315fdd2ae400181744b916fcc8319e68f1cec57c981Grace Kloba if (!item) { 316fdd2ae400181744b916fcc8319e68f1cec57c981Grace Kloba // If a HistoryItem only exists for page cache, it is possible that 317fdd2ae400181744b916fcc8319e68f1cec57c981Grace Kloba // the parent HistoryItem destroyed before the child HistoryItem. If 318fdd2ae400181744b916fcc8319e68f1cec57c981Grace Kloba // it happens, skip updating. 3197d99b5804f0800191b03d83fc8f8d2886271475bSteve Block ALOGW("Can't updateHistoryItem as the top HistoryItem is gone"); 320fdd2ae400181744b916fcc8319e68f1cec57c981Grace Kloba return; 321fdd2ae400181744b916fcc8319e68f1cec57c981Grace Kloba } 3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JNIEnv* env = JSC::Bindings::getJNIEnv(); 3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!env) 3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 327e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck MutexLocker locker(webItem->m_lock); 3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 329e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck // TODO: Figure out if we can't just use item->urlString() instead... 330d20466cbeb31c73eace8f0c4eb6c717b1e1ae540Shimeng (Simon) Wang const WTF::String urlString = WebFrame::convertIDNToUnicode(item->url()); 331e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck webItem->m_url = urlString.threadsafeCopy(); 332d20466cbeb31c73eace8f0c4eb6c717b1e1ae540Shimeng (Simon) Wang const WTF::String originalUrlString = WebFrame::convertIDNToUnicode(item->originalURL()); 333e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck webItem->m_originalUrl = originalUrlString.threadsafeCopy(); 33445b64f60af3cbfa8c78388e35e9b669a0c284bdcBen Murdoch const WTF::String& titleString = item->title(); 335e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck webItem->m_title = titleString.threadsafeCopy(); 3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Try to get the favicon from the history item. For some pages like Grand 3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Prix, there are history items with anchors. If the icon fails for the 3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // item, try to get the icon using the url without the ref. 3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project jobject favicon = NULL; 34145b64f60af3cbfa8c78388e35e9b669a0c284bdcBen Murdoch WTF::String url = item->urlString(); 3429e2ee40924101fa594b0b31d866f896154b47caaBen Murdoch if (item->url().hasFragmentIdentifier()) { 3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int refIndex = url.reverseFind('#'); 3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project url = url.substring(0, refIndex); 3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3462f4ef9300ef5b74c660927a63057e2fcff0e1905Steve Block // FIXME: This method should not be used from outside WebCore and will be removed. 3472f4ef9300ef5b74c660927a63057e2fcff0e1905Steve Block // http://trac.webkit.org/changeset/81484 3482f4ef9300ef5b74c660927a63057e2fcff0e1905Steve Block WebCore::Image* icon = WebCore::iconDatabase().synchronousIconForPageURL(url, WebCore::IntSize(16, 16)); 3494d31493c3fa47a28b2753bc5b99e2074b6a7a4dfJohn Reck delete webItem->m_favicon; 350e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck webItem->m_favicon = webcoreImageToSkBitmap(icon); 351e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck if (webItem->m_faviconCached) { 352e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck env->DeleteGlobalRef(webItem->m_faviconCached); 353e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck webItem->m_faviconCached = 0; 354e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck } 3558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 356e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck webItem->m_data.clear(); 357e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck WebHistory::Flatten(env, webItem->m_data, item); 358e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck if (webItem->m_dataCached) { 359e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck env->DeleteGlobalRef(webItem->m_dataCached); 360e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck webItem->m_dataCached = 0; 361e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck } 362e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck} 363e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck 364e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn ReckWebHistoryItem::~WebHistoryItem() 365e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck{ 3664d31493c3fa47a28b2753bc5b99e2074b6a7a4dfJohn Reck delete m_favicon; 367e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck JNIEnv* env = JSC::Bindings::getJNIEnv(); 368e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck if (!env) { 369e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck ALOGW("Failed to get JNIEnv*! Potential memory leak!"); 370e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck return; 371e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck } 372e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck if (m_faviconCached) { 373e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck env->DeleteGlobalRef(m_faviconCached); 374e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck m_faviconCached = 0; 375e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck } 376e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck if (m_dataCached) { 377e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck env->DeleteGlobalRef(m_dataCached); 378e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck m_dataCached = 0; 379e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck } 3808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void historyItemChanged(WebCore::HistoryItem* item) { 3836dd76b804786ec760bb04b137a6bf017064226dcSteve Block ALOG_ASSERT(item, "historyItemChanged called with a null item"); 384be33b78f63b17f1b6f5a36a503d797d5f9b941eeBen Murdoch 3858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (item->bridge()) 3868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project item->bridge()->updateHistoryItem(item); 3878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid WebHistory::AddItem(const AutoJObject& list, WebCore::HistoryItem* item) 3908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3916dd76b804786ec760bb04b137a6bf017064226dcSteve Block ALOG_ASSERT(item, "newItem must take a valid HistoryItem!"); 3928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Item already added. Should only happen when we are inflating the list. 3938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (item->bridge() || !list.get()) 3948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 3958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JNIEnv* env = list.env(); 3978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Create the bridge, make it active, and attach it to the item. 398e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck WebHistoryItem* bridge = new WebHistoryItem(item); 3998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bridge->setActive(); 4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project item->setBridge(bridge); 401e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck // Allocate a blank WebHistoryItem 402e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck jclass clazz = env->FindClass("android/webkit/WebHistoryItem"); 403e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck jobject newItem = env->NewObject(clazz, gWebHistoryItem.mInit, 404e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck reinterpret_cast<int>(bridge)); 405e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck env->DeleteLocalRef(clazz); 4068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Update the history item which will flatten the data and call update on 4088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // the java item. 4098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bridge->updateHistoryItem(item); 4108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Add it to the list. 4128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project env->CallVoidMethod(list.get(), gWebBackForwardList.mAddHistoryItem, newItem); 4138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Delete our local reference. 4158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project env->DeleteLocalRef(newItem); 4168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid WebHistory::RemoveItem(const AutoJObject& list, int index) 4198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (list.get()) 4218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project list.env()->CallVoidMethod(list.get(), gWebBackForwardList.mRemoveHistoryItem, index); 4228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid WebHistory::UpdateHistoryIndex(const AutoJObject& list, int newIndex) 4258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (list.get()) 427730ce864fef32412598ac6b1f5e48a02f217ca25Patrick Scott list.env()->CallVoidMethod(list.get(), gWebBackForwardList.mSetCurrentIndex, newIndex); 4288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 430c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brennerstatic void writeString(WTF::Vector<char>& vector, const WTF::String& str) 4318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned strLen = str.length(); 4338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Only do work if the string has data. 4348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (strLen) { 4358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Determine how much to grow the vector. Use the worst case for utf8 to 4368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // avoid reading the string twice. Add sizeof(unsigned) to hold the 4378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // string length in utf8. 438c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner unsigned vectorLen = vector.size() + sizeof(unsigned); 4398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned length = (strLen << 2) + vectorLen; 4408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Grow the vector. This will change the value of v.size() but we 4418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // remember the original size above. 442c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner vector.grow(length); 4438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Grab the position to write to. 444c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner char* data = vector.begin() + vectorLen; 4458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Write the actual string 4468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int l = SkUTF16_ToUTF8(str.characters(), strLen, data); 447c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner ALOGV("Writing string %d %.*s", l, l, data); 4488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Go back and write the utf8 length. Subtract sizeof(unsigned) from 4498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // data to get the position to write the length. 4508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memcpy(data - sizeof(unsigned), (char*)&l, sizeof(unsigned)); 4518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Shrink the internal state of the vector so we match what was 4528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // actually written. 453c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner vector.shrink(vectorLen + l); 4548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else 455c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner vector.append((char*)&strLen, sizeof(unsigned)); 4568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 458c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brennerstatic void writeItem(WTF::Vector<char>& vector, WebCore::HistoryItem* item) 4598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Original url 461c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner writeString(vector, item->originalURLString()); 4628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Url 464c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner writeString(vector, item->urlString()); 4658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Title 467c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner writeString(vector, item->title()); 4688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Form content type 470c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner writeString(vector, item->formContentType()); 4718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Form data 4738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const WebCore::FormData* formData = item->formData(); 474ef7b176b34c6a1fe082a87dd17523e47737c1e19Grace Kloba if (formData) { 475c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner writeString(vector, formData->flattenToString()); 476ef7b176b34c6a1fe082a87dd17523e47737c1e19Grace Kloba // save the identifier as it is not included in the flatten data 477ef7b176b34c6a1fe082a87dd17523e47737c1e19Grace Kloba int64_t id = formData->identifier(); 478c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner vector.append((char*)&id, sizeof(int64_t)); 479ef7b176b34c6a1fe082a87dd17523e47737c1e19Grace Kloba } else 480c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner writeString(vector, WTF::String()); // Empty constructor does not allocate a buffer. 4818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Target 483c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner writeString(vector, item->target()); 4848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 485be33b78f63b17f1b6f5a36a503d797d5f9b941eeBen Murdoch AndroidWebHistoryBridge* bridge = item->bridge(); 4866dd76b804786ec760bb04b137a6bf017064226dcSteve Block ALOG_ASSERT(bridge, "We should have a bridge here!"); 4878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Screen scale 488c4683829d0d4932156a97ce14ea15deed71bf21dShimeng (Simon) Wang const float scale = bridge->scale(); 489c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner ALOGV("Writing scale %f", scale); 490c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner vector.append((char*)&scale, sizeof(float)); 491c4683829d0d4932156a97ce14ea15deed71bf21dShimeng (Simon) Wang const float textWrapScale = bridge->textWrapScale(); 492c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner ALOGV("Writing text wrap scale %f", textWrapScale); 493c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner vector.append((char*)&textWrapScale, sizeof(float)); 4948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 495bfc0ebd2ace64845c11b40ce5dae09347ce0020dShimeng (Simon) Wang // Scroll position. 496bfc0ebd2ace64845c11b40ce5dae09347ce0020dShimeng (Simon) Wang const int scrollX = item->scrollPoint().x(); 497c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner vector.append((char*)&scrollX, sizeof(int)); 498bfc0ebd2ace64845c11b40ce5dae09347ce0020dShimeng (Simon) Wang const int scrollY = item->scrollPoint().y(); 499c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner vector.append((char*)&scrollY, sizeof(int)); 500bfc0ebd2ace64845c11b40ce5dae09347ce0020dShimeng (Simon) Wang 5018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Document state 50245b64f60af3cbfa8c78388e35e9b669a0c284bdcBen Murdoch const WTF::Vector<WTF::String>& docState = item->documentState(); 50345b64f60af3cbfa8c78388e35e9b669a0c284bdcBen Murdoch WTF::Vector<WTF::String>::const_iterator end = docState.end(); 5048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned stateSize = docState.size(); 505c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner ALOGV("Writing docState %d", stateSize); 506c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner vector.append((char*)&stateSize, sizeof(unsigned)); 50745b64f60af3cbfa8c78388e35e9b669a0c284bdcBen Murdoch for (WTF::Vector<WTF::String>::const_iterator i = docState.begin(); i != end; ++i) { 508c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner writeString(vector, *i); 5098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Is target item 512c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner ALOGV("Writing isTargetItem %d", item->isTargetItem()); 513c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner vector.append((char)item->isTargetItem()); 5148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Children count 5168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned childCount = item->children().size(); 517c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner ALOGV("Writing childCount %d", childCount); 518c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner vector.append((char*)&childCount, sizeof(unsigned)); 5198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 521c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brennerstatic void writeChildrenRecursive(WTF::Vector<char>& vector, WebCore::HistoryItem* parent) 5228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const WebCore::HistoryItemVector& children = parent->children(); 5248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebCore::HistoryItemVector::const_iterator end = children.end(); 5258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (WebCore::HistoryItemVector::const_iterator i = children.begin(); i != end; ++i) { 5268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebCore::HistoryItem* item = (*i).get(); 5276dd76b804786ec760bb04b137a6bf017064226dcSteve Block ALOG_ASSERT(parent->bridge(), 5288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project "The parent item should have a bridge object!"); 5298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!item->bridge()) { 530be33b78f63b17f1b6f5a36a503d797d5f9b941eeBen Murdoch WebHistoryItem* bridge = new WebHistoryItem(static_cast<WebHistoryItem*>(parent->bridge())); 5318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project item->setBridge(bridge); 5328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bridge->setActive(); 5338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 5348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // The only time this item's parent may not be the same as the 5358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // parent's bridge is during history close. In that case, the 5368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // parent must not have a parent bridge. 537be33b78f63b17f1b6f5a36a503d797d5f9b941eeBen Murdoch WebHistoryItem* bridge = static_cast<WebHistoryItem*>(item->bridge()); 538be33b78f63b17f1b6f5a36a503d797d5f9b941eeBen Murdoch WebHistoryItem* parentBridge = static_cast<WebHistoryItem*>(parent->bridge()); 5396dd76b804786ec760bb04b137a6bf017064226dcSteve Block ALOG_ASSERT(parentBridge->parent() == 0 || 540be33b78f63b17f1b6f5a36a503d797d5f9b941eeBen Murdoch bridge->parent() == parentBridge, 5418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project "Somehow this item has an incorrect parent"); 542be33b78f63b17f1b6f5a36a503d797d5f9b941eeBen Murdoch bridge->setParent(parentBridge); 5438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 544c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner writeItem(vector, item); 545c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner writeChildrenRecursive(vector, item); 5468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 54908767a79b9fae453edaed3c64afe1f52ba64b195Russell Brennerbool readUnsigned(const char*& data, const char* end, unsigned& result, const char* dbgLabel = 0); 55008767a79b9fae453edaed3c64afe1f52ba64b195Russell Brennerbool readInt(const char*& data, const char* end, int& result, const char* dbgLabel = 0); 55108767a79b9fae453edaed3c64afe1f52ba64b195Russell Brennerbool readInt64(const char*& data, const char* end, int64_t& result, const char* dbgLabel = 0); 55208767a79b9fae453edaed3c64afe1f52ba64b195Russell Brennerbool readFloat(const char*& data, const char* end, float& result, const char* dbgLabel = 0); 55308767a79b9fae453edaed3c64afe1f52ba64b195Russell Brennerbool readBool(const char*& data, const char* end, bool& result, const char* dbgLabel = 0); 55408767a79b9fae453edaed3c64afe1f52ba64b195Russell Brennerbool readString(const char*& data, const char* end, String& result, const char* dbgLabel = 0); 55508767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner 55608767a79b9fae453edaed3c64afe1f52ba64b195Russell Brennerbool readUnsigned(const char*& data, const char* end, unsigned& result, const char* dbgLabel) 55708767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner{ 55808767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner // Check if we have enough data left to continue. 55908767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if ((end < data) || (static_cast<size_t>(end - data) < sizeof(unsigned))) { 560541839a11103a72d486edaab8a5c9e9499554511Russell Brenner ALOGW("\tNot enough data to read unsigned; tag=\"%s\" end=%p data=%p", 561541839a11103a72d486edaab8a5c9e9499554511Russell Brenner dbgLabel ? dbgLabel : "<no tag>", end, data); 56208767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner return false; 56308767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner } 56408767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner 56508767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner memcpy(&result, data, sizeof(unsigned)); 56608767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner data += sizeof(unsigned); 56708767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if (dbgLabel) 56808767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner ALOGV("Reading %-16s %u", dbgLabel, result); 56908767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner return true; 57008767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner} 57108767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner 57208767a79b9fae453edaed3c64afe1f52ba64b195Russell Brennerbool readInt(const char*& data, const char* end, int& result, const char* dbgLabel) 57308767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner{ 57408767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner // Check if we have enough data left to continue. 57508767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if ((end < data) || (static_cast<size_t>(end - data) < sizeof(int))) { 576541839a11103a72d486edaab8a5c9e9499554511Russell Brenner ALOGW("Not enough data to read int; tag=\"%s\" end=%p data=%p", 577541839a11103a72d486edaab8a5c9e9499554511Russell Brenner dbgLabel ? dbgLabel : "<no tag>", end, data); 57808767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner return false; 57908767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner } 58008767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner 58108767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner memcpy(&result, data, sizeof(int)); 58208767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner data += sizeof(int); 58308767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if (dbgLabel) 58408767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner ALOGV("Reading %-16s %d", dbgLabel, result); 58508767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner return true; 58608767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner} 58708767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner 58808767a79b9fae453edaed3c64afe1f52ba64b195Russell Brennerbool readInt64(const char*& data, const char* end, int64_t& result, const char* dbgLabel) 58908767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner{ 59008767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner // Check if we have enough data left to continue. 59108767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if ((end < data) || (static_cast<size_t>(end - data) < sizeof(int64_t))) { 592541839a11103a72d486edaab8a5c9e9499554511Russell Brenner ALOGW("Not enough data to read int64_t; tag=\"%s\" end=%p data=%p", 593541839a11103a72d486edaab8a5c9e9499554511Russell Brenner dbgLabel ? dbgLabel : "<no tag>", end, data); 59408767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner return false; 59508767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner } 59608767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner 59708767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner memcpy(&result, data, sizeof(int64_t)); 59808767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner data += sizeof(int64_t); 59908767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if (dbgLabel) 60008767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner ALOGV("Reading %-16s %ll", dbgLabel, result); 60108767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner return true; 60208767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner} 60308767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner 60408767a79b9fae453edaed3c64afe1f52ba64b195Russell Brennerbool readFloat(const char*& data, const char* end, float& result, const char* dbgLabel) 60508767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner{ 60608767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner // Check if we have enough data left to continue. 60708767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if ((end < data) || (static_cast<size_t>(end - data) < sizeof(float))) { 608541839a11103a72d486edaab8a5c9e9499554511Russell Brenner ALOGW("Not enough data to read float; tag=\"%s\" end=%p data=%p", 609541839a11103a72d486edaab8a5c9e9499554511Russell Brenner dbgLabel ? dbgLabel : "<no tag>", end, data); 61008767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner return false; 61108767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner } 61208767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner 61308767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner memcpy(&result, data, sizeof(float)); 61408767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner data += sizeof(float); 61508767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if (dbgLabel) 61608767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner ALOGV("Reading %-16s %f", dbgLabel, result); 61708767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner return true; 61808767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner} 61908767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner 62008767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner// Note that the return value indicates success or failure, while the result 62108767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner// parameter indicates the read value of the bool 62208767a79b9fae453edaed3c64afe1f52ba64b195Russell Brennerbool readBool(const char*& data, const char* end, bool& result, const char* dbgLabel) 62308767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner{ 62408767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner // Check if we have enough data left to continue. 62508767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if ((end < data) || (static_cast<size_t>(end - data) < sizeof(char))) { 626541839a11103a72d486edaab8a5c9e9499554511Russell Brenner ALOGW("Not enough data to read bool; tag=\"%s\" end=%p data=%p", 627541839a11103a72d486edaab8a5c9e9499554511Russell Brenner dbgLabel ? dbgLabel : "<no tag>", end, data); 62808767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner return false; 62908767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner } 63008767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner 63108767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner char c; 63208767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner memcpy(&c, data, sizeof(char)); 63308767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner data += sizeof(char); 63408767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if (dbgLabel) 63508767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner ALOGV("Reading %-16s %d", dbgLabel, c); 63608767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner result = c; 63708767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner 63808767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner // Valid bool results are 0 or 1 63908767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if ((c != 0) && (c != 1)) { 640541839a11103a72d486edaab8a5c9e9499554511Russell Brenner ALOGW("Invalid value for bool; tag=\"%s\" end=%p data=%p c=%u", 641541839a11103a72d486edaab8a5c9e9499554511Russell Brenner dbgLabel ? dbgLabel : "<no tag>", end, data, c); 64208767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner return false; 64308767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner } 64408767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner 64508767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner return true; 64608767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner} 64708767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner 64808767a79b9fae453edaed3c64afe1f52ba64b195Russell Brennerbool readString(const char*& data, const char* end, String& result, const char* dbgLabel) 64908767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner{ 65008767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner unsigned stringLength; 65108767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if (!readUnsigned(data, end, stringLength)) { 652541839a11103a72d486edaab8a5c9e9499554511Russell Brenner ALOGW("Not enough data to read string length; tag=\"%s\" end=%p data=%p", 653541839a11103a72d486edaab8a5c9e9499554511Russell Brenner dbgLabel ? dbgLabel : "<no tag>", end, data); 65408767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner return false; 65508767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner } 65608767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner 65708767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if (dbgLabel) 65808767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner ALOGV("Reading %-16s %d %.*s", dbgLabel, stringLength, stringLength, data); 65908767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner 66008767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner // If length was 0, there will be no string content, but still return true 66108767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if (!stringLength) { 66208767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner result = String(); 66308767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner return true; 66408767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner } 66508767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner 66608767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if ((end < data) || ((unsigned)(end - data) < stringLength)) { 667541839a11103a72d486edaab8a5c9e9499554511Russell Brenner ALOGW("Not enough data to read content; tag=\"%s\" end=%p data=%p stringLength=%u", 668541839a11103a72d486edaab8a5c9e9499554511Russell Brenner dbgLabel ? dbgLabel : "<no tag>", end, data, stringLength); 66908767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner return false; 67008767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner } 67108767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner 672541839a11103a72d486edaab8a5c9e9499554511Russell Brenner const unsigned MAX_REASONABLE_STRING_LENGTH = 10000; 673541839a11103a72d486edaab8a5c9e9499554511Russell Brenner if (stringLength > MAX_REASONABLE_STRING_LENGTH) { 674541839a11103a72d486edaab8a5c9e9499554511Russell Brenner ALOGW("String length is suspiciously large (>%d); tag=\"%s\" end=%p data=%p stringLength=%u", 675541839a11103a72d486edaab8a5c9e9499554511Russell Brenner MAX_REASONABLE_STRING_LENGTH, dbgLabel ? dbgLabel : "<no tag>", 676541839a11103a72d486edaab8a5c9e9499554511Russell Brenner end, data, stringLength); 677541839a11103a72d486edaab8a5c9e9499554511Russell Brenner } 678541839a11103a72d486edaab8a5c9e9499554511Russell Brenner 679859c01f9680c58ddff5938862087b41478acd0a0Russell Brenner bool decodeFailed = false; 68008767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner static const WebCore::TextEncoding& encoding = WebCore::UTF8Encoding(); 68108767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner result = encoding.decode(data, stringLength, true, decodeFailed); 68208767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if (decodeFailed) { 683541839a11103a72d486edaab8a5c9e9499554511Russell Brenner ALOGW("Decode failed, tag=\"%s\" end=%p data=%p stringLength=%u content=\"%s\"", 684541839a11103a72d486edaab8a5c9e9499554511Russell Brenner dbgLabel ? dbgLabel : "<no tag>", end, data, stringLength, 685541839a11103a72d486edaab8a5c9e9499554511Russell Brenner result.utf8().data()); 686859c01f9680c58ddff5938862087b41478acd0a0Russell Brenner return false; 68708767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner } 68808767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner 689541839a11103a72d486edaab8a5c9e9499554511Russell Brenner if (stringLength > MAX_REASONABLE_STRING_LENGTH) { 690541839a11103a72d486edaab8a5c9e9499554511Russell Brenner ALOGW("\tdecodeFailed=%d (flag is ignored) content=\"%s\"", 691541839a11103a72d486edaab8a5c9e9499554511Russell Brenner decodeFailed, result.utf8().data()); 692541839a11103a72d486edaab8a5c9e9499554511Russell Brenner } 693541839a11103a72d486edaab8a5c9e9499554511Russell Brenner 69408767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner data += stringLength; 69508767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner return true; 69608767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner} 69708767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner 698c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brennerstatic bool readItemRecursive(WebCore::HistoryItem* newItem, 6998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const char** pData, int length) 7008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 70108767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if (!pData || length < HISTORY_MIN_SIZE) { 70208767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner ALOGW("readItemRecursive() bad params; pData=%p length=%d", pData, length); 7038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 70408767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner } 7058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const char* data = *pData; 7078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const char* end = data + length; 70808767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner String content; 7098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Read the original url 71108767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if (readString(data, end, content, "Original url")) 71208767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner newItem->setOriginalURLString(content); 71308767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner else 7148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 7158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Read the url 71708767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if (readString(data, end, content, "Url")) 71808767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner newItem->setURLString(content); 71908767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner else 7208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 7218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Read the title 72308767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if (readString(data, end, content, "Title")) 72408767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner newItem->setTitle(content); 72508767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner else 7268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 7278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Generate a new ResourceRequest object for populating form information. 72908767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner // Read the form content type 73045b64f60af3cbfa8c78388e35e9b669a0c284bdcBen Murdoch WTF::String formContentType; 73108767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if (!readString(data, end, formContentType, "Content type")) 73208767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner return false; 7338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 73408767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner // Read the form data size 73508767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner unsigned formDataSize; 73608767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if (!readUnsigned(data, end, formDataSize, "Form data size")) 7378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 7388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Read the form data 74008767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner WTF::RefPtr<WebCore::FormData> formData; 74108767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if (formDataSize) { 74208767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner ALOGV("Reading Form data %d %.*s", formDataSize, formDataSize, data); 74308767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if ((end < data) || ((size_t)(end - data) < formDataSize)) { 74408767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner ALOGW("\tNot enough data to read form data; returning"); 7458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 746ef7b176b34c6a1fe082a87dd17523e47737c1e19Grace Kloba } 74708767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner formData = WebCore::FormData::create(data, formDataSize); 74808767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner data += formDataSize; 74908767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner // Read the identifier 75008767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner int64_t id; 75108767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if (!readInt64(data, end, id, "Form id")) 75208767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner return false; 75308767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if (id) 75408767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner formData->setIdentifier(id); 7558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 7568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Set up the form info 7588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (formData != NULL) { 7598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebCore::ResourceRequest r; 7608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project r.setHTTPMethod("POST"); 7618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project r.setHTTPContentType(formContentType); 7628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project r.setHTTPBody(formData); 7638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project newItem->setFormInfoFromRequest(r); 7648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 7658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Read the target 76708767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if (readString(data, end, content, "Target")) 76808767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner newItem->setTarget(content); 76908767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner else 7708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 7718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 772be33b78f63b17f1b6f5a36a503d797d5f9b941eeBen Murdoch AndroidWebHistoryBridge* bridge = newItem->bridge(); 7736dd76b804786ec760bb04b137a6bf017064226dcSteve Block ALOG_ASSERT(bridge, "There should be a bridge object during inflate"); 77408767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner 7758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Read the screen scale 77608767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner float fValue; 77708767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if (readFloat(data, end, fValue, "Screen scale")) 77808767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner bridge->setScale(fValue); 77908767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner else 78008767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner return false; 78161e86687816f581053a96dc2686208fe3616ae40Shimeng (Simon) Wang 78208767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner // Read the text wrap scale 78308767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if (readFloat(data, end, fValue, "Text wrap scale")) 78408767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner bridge->setTextWrapScale(fValue); 78508767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner else 7868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 7878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 788bfc0ebd2ace64845c11b40ce5dae09347ce0020dShimeng (Simon) Wang // Read scroll position. 78908767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner int scrollX; 79008767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if (!readInt(data, end, scrollX, "Scroll pos x")) 79108767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner return false; 79208767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner int scrollY; 79308767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if (!readInt(data, end, scrollY, "Scroll pos y")) 794bfc0ebd2ace64845c11b40ce5dae09347ce0020dShimeng (Simon) Wang return false; 79508767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner newItem->setScrollPoint(IntPoint(scrollX, scrollY)); 796bfc0ebd2ace64845c11b40ce5dae09347ce0020dShimeng (Simon) Wang 7978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Read the document state 79808767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner unsigned docStateCount; 79908767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if (!readUnsigned(data, end, docStateCount, "Doc state count")) 80008767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner return false; 80108767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if (docStateCount) { 8028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Create a new vector and reserve enough space for the document state. 80345b64f60af3cbfa8c78388e35e9b669a0c284bdcBen Murdoch WTF::Vector<WTF::String> docState; 80408767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner docState.reserveCapacity(docStateCount); 80508767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner while (docStateCount--) { 80608767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner // Read a document state string 80708767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if (readString(data, end, content, "Document state")) 80808767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner docState.append(content); 8098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 8108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 8118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 8128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project newItem->setDocumentState(docState); 8138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 8148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Read is target item 81608767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner bool c; 81708767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if (readBool(data, end, c, "Target item")) 81808767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner newItem->setIsTargetItem(c); 81908767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner else 8208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 8218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Read the child count 82308767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner unsigned count; 82408767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if (!readUnsigned(data, end, count, "Child count")) 82508767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner return false; 8268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *pData = data; 82708767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if (count) { 82808767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner while (count--) { 8298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // No need to check the length each time because read_item_recursive 8308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // will return null if there isn't enough data left to parse. 8313577745d3cfbfe2b7ebb3cddb1abda7026a61ac5Russell Brenner WTF::RefPtr<WebCore::HistoryItem> child = WebCore::HistoryItem::create(); 8328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Set a bridge that will not call into java. 833be33b78f63b17f1b6f5a36a503d797d5f9b941eeBen Murdoch child->setBridge(new WebHistoryItem(static_cast<WebHistoryItem*>(bridge))); 8348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Read the child item. 83508767a79b9fae453edaed3c64afe1f52ba64b195Russell Brenner if (!readItemRecursive(child.get(), pData, end - data)) 8368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 8378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project child->bridge()->setActive(); 8388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project newItem->addChildItem(child); 8398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 8408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 8418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 8428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 8438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// On arm, this test will cause memory corruption since converting char* will 8458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// byte align the result and this test does not use memset (it probably 8468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// should). 8478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// On the simulator, using HistoryItem will invoke the IconDatabase which will 8488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// initialize the main thread. Since this is invoked by the Zygote process, the 8498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// main thread will be incorrect and an assert will fire later. 8508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// In conclusion, define UNIT_TEST only if you know what you are doing. 8518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef UNIT_TEST 852c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brennerstatic void unitTest() 8538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 854a09e7cf49f43950a799f936bf42a9912d696547bSteve Block ALOGD("Entering history unit test!"); 8558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const char* test1 = new char[0]; 8568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WTF::RefPtr<WebCore::HistoryItem> item = WebCore::HistoryItem::create(); 8578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebCore::HistoryItem* testItem = item.get(); 858be33b78f63b17f1b6f5a36a503d797d5f9b941eeBen Murdoch testItem->setBridge(new WebHistoryItem(0)); 859c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner ALOG_ASSERT(!readItemRecursive(testItem, &test1, 0), "0 length array should fail!"); 8608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delete[] test1; 8618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const char* test2 = new char[2]; 862c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner ALOG_ASSERT(!readItemRecursive(testItem, &test2, 2), "Small array should fail!"); 8638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delete[] test2; 864c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner ALOG_ASSERT(!readItemRecursive(testItem, NULL, HISTORY_MIN_SIZE), "Null data should fail!"); 8658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Original Url 8668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project char* test3 = new char[HISTORY_MIN_SIZE]; 8678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const char* ptr = (const char*)test3; 8688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memset(test3, 0, HISTORY_MIN_SIZE); 8698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *(int*)test3 = 4000; 870c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner ALOG_ASSERT(!readItemRecursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length originalUrl should fail!"); 8718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Url 8728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int offset = 4; 8738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memset(test3, 0, HISTORY_MIN_SIZE); 8748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ptr = (const char*)test3; 8758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *(int*)(test3 + offset) = 4000; 876c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner ALOG_ASSERT(!readItemRecursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length url should fail!"); 8778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Title 8788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project offset += 4; 8798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memset(test3, 0, HISTORY_MIN_SIZE); 8808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ptr = (const char*)test3; 8818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *(int*)(test3 + offset) = 4000; 882c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner ALOG_ASSERT(!readItemRecursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length title should fail!"); 8838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Form content type 8848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project offset += 4; 8858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memset(test3, 0, HISTORY_MIN_SIZE); 8868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ptr = (const char*)test3; 8878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *(int*)(test3 + offset) = 4000; 888c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner ALOG_ASSERT(!readItemRecursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length contentType should fail!"); 8898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Form data 8908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project offset += 4; 8918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memset(test3, 0, HISTORY_MIN_SIZE); 8928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ptr = (const char*)test3; 8938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *(int*)(test3 + offset) = 4000; 894c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner ALOG_ASSERT(!readItemRecursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length form data should fail!"); 8958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Target 8968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project offset += 4; 8978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memset(test3, 0, HISTORY_MIN_SIZE); 8988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ptr = (const char*)test3; 8998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *(int*)(test3 + offset) = 4000; 900c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner ALOG_ASSERT(!readItemRecursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length target should fail!"); 9019cff7e8839f4cd5caf01f005647176461f329a8dRussell Brenner offset += 4; // Screen scale 9029cff7e8839f4cd5caf01f005647176461f329a8dRussell Brenner offset += 4; // Text wrap scale 9039cff7e8839f4cd5caf01f005647176461f329a8dRussell Brenner offset += 4; // Scroll pos x 9049cff7e8839f4cd5caf01f005647176461f329a8dRussell Brenner offset += 4; // Scroll pos y 9058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Document state 9068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project offset += 4; 9078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memset(test3, 0, HISTORY_MIN_SIZE); 9088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ptr = (const char*)test3; 9098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *(int*)(test3 + offset) = 4000; 910c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner ALOG_ASSERT(!readItemRecursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length document state should fail!"); 9118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Is target item 9128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project offset += 1; 9138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memset(test3, 0, HISTORY_MIN_SIZE); 9148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ptr = (const char*)test3; 9158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *(char*)(test3 + offset) = '!'; 916c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner ALOG_ASSERT(!readItemRecursive(testItem, &ptr, HISTORY_MIN_SIZE), "IsTargetItem should fail with ! as the value!"); 9178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Child count 9188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project offset += 4; 9198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memset(test3, 0, HISTORY_MIN_SIZE); 9208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ptr = (const char*)test3; 9218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *(int*)(test3 + offset) = 4000; 922c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner ALOG_ASSERT(!readItemRecursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 kids should fail!"); 9238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Test document state 9249cff7e8839f4cd5caf01f005647176461f329a8dRussell Brenner offset = 40; 9258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delete[] test3; 9268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project test3 = new char[HISTORY_MIN_SIZE + sizeof(unsigned)]; 9278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memset(test3, 0, HISTORY_MIN_SIZE + sizeof(unsigned)); 9288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ptr = (const char*)test3; 9298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *(int*)(test3 + offset) = 1; 9308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *(int*)(test3 + offset + 4) = 20; 931c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner ALOG_ASSERT(!readItemRecursive(testItem, &ptr, HISTORY_MIN_SIZE + sizeof(unsigned)), "1 20 length document state string should fail!"); 9328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delete[] test3; 9338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project test3 = new char[HISTORY_MIN_SIZE + 2 * sizeof(unsigned)]; 9348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memset(test3, 0, HISTORY_MIN_SIZE + 2 * sizeof(unsigned)); 9358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ptr = (const char*)test3; 9368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *(int*)(test3 + offset) = 2; 9378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *(int*)(test3 + offset + 4) = 0; 9388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *(int*)(test3 + offset + 8) = 20; 939c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner ALOG_ASSERT(!readItemRecursive(testItem, &ptr, HISTORY_MIN_SIZE + 2 * sizeof(unsigned) ), "2 20 length document state string should fail!"); 9408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delete[] test3; 9419cff7e8839f4cd5caf01f005647176461f329a8dRussell Brenner ALOGD("Leaving history unit test!"); 9428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 9438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 9448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project//--------------------------------------------------------- 9468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// JNI registration 9478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project//--------------------------------------------------------- 9488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic JNINativeMethod gWebBackForwardListMethods[] = { 9498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { "nativeClose", "(I)V", 9508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project (void*) WebHistoryClose }, 9518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { "restoreIndex", "(II)V", 9528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project (void*) WebHistoryRestoreIndex } 9538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}; 9548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic JNINativeMethod gWebHistoryItemMethods[] = { 956e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck { "inflate", "(I[B)I", 957e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck (void*) WebHistoryInflate }, 958e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck { "nativeRef", "(I)V", 959e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck (void*) WebHistoryRef }, 960e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck { "nativeUnref", "(I)V", 961e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck (void*) WebHistoryUnref }, 962e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck { "nativeGetTitle", "(I)Ljava/lang/String;", 963e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck (void*) WebHistoryGetTitle }, 964e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck { "nativeGetUrl", "(I)Ljava/lang/String;", 965e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck (void*) WebHistoryGetUrl }, 966e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck { "nativeGetOriginalUrl", "(I)Ljava/lang/String;", 967e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck (void*) WebHistoryGetOriginalUrl }, 968e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck { "nativeGetFlattenedData", "(I)[B", 969e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck (void*) WebHistoryGetFlattenedData }, 970e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck { "nativeGetFavicon", "(I)Landroid/graphics/Bitmap;", 971e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck (void*) WebHistoryGetFavicon }, 9728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}; 9738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 974b92850e0391d674b9c4826b66105aaa3dd3eef96Steve Blockint registerWebHistory(JNIEnv* env) 9758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 9768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Get notified of all changes to history items. 9778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebCore::notifyHistoryItemChanged = historyItemChanged; 9788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef UNIT_TEST 979c8c13e36333629a06a196f84e75f2cc8ae5df24eRussell Brenner unitTest(); 9808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 9818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Find WebHistoryItem, its constructor, and the update method. 9828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project jclass clazz = env->FindClass("android/webkit/WebHistoryItem"); 9836dd76b804786ec760bb04b137a6bf017064226dcSteve Block ALOG_ASSERT(clazz, "Unable to find class android/webkit/WebHistoryItem"); 984e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck gWebHistoryItem.mInit = env->GetMethodID(clazz, "<init>", "(I)V"); 9856dd76b804786ec760bb04b137a6bf017064226dcSteve Block ALOG_ASSERT(gWebHistoryItem.mInit, "Could not find WebHistoryItem constructor"); 986e38a6c283211dcfd3b1fb390e4c108a86481dd8aJohn Reck 987bf3f67c4fcfd68df256e5c001c67969997a63e28Steve Block env->DeleteLocalRef(clazz); 9888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 989730ce864fef32412598ac6b1f5e48a02f217ca25Patrick Scott // Find the WebBackForwardList object and method. 9908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project clazz = env->FindClass("android/webkit/WebBackForwardList"); 9916dd76b804786ec760bb04b137a6bf017064226dcSteve Block ALOG_ASSERT(clazz, "Unable to find class android/webkit/WebBackForwardList"); 9928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gWebBackForwardList.mAddHistoryItem = env->GetMethodID(clazz, "addHistoryItem", 9938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project "(Landroid/webkit/WebHistoryItem;)V"); 9946dd76b804786ec760bb04b137a6bf017064226dcSteve Block ALOG_ASSERT(gWebBackForwardList.mAddHistoryItem, "Could not find method addHistoryItem"); 9958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gWebBackForwardList.mRemoveHistoryItem = env->GetMethodID(clazz, "removeHistoryItem", 9968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project "(I)V"); 9976dd76b804786ec760bb04b137a6bf017064226dcSteve Block ALOG_ASSERT(gWebBackForwardList.mRemoveHistoryItem, "Could not find method removeHistoryItem"); 998730ce864fef32412598ac6b1f5e48a02f217ca25Patrick Scott gWebBackForwardList.mSetCurrentIndex = env->GetMethodID(clazz, "setCurrentIndex", "(I)V"); 9996dd76b804786ec760bb04b137a6bf017064226dcSteve Block ALOG_ASSERT(gWebBackForwardList.mSetCurrentIndex, "Could not find method setCurrentIndex"); 1000bf3f67c4fcfd68df256e5c001c67969997a63e28Steve Block env->DeleteLocalRef(clazz); 10018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 10028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int result = jniRegisterNativeMethods(env, "android/webkit/WebBackForwardList", 10038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gWebBackForwardListMethods, NELEM(gWebBackForwardListMethods)); 10048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return (result < 0) ? result : jniRegisterNativeMethods(env, "android/webkit/WebHistoryItem", 10058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gWebHistoryItemMethods, NELEM(gWebHistoryItemMethods)); 10068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 10078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 10088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} /* namespace android */ 1009