WebHistory.cpp revision 3298a7d84b96ade73c6b170671711a8f2792ae59
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 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <config.h> 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/OwnPtr.h> 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/Platform.h> 318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "WebHistory.h" 338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "BackForwardList.h" 358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CString.h" 368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "DocumentLoader.h" 378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Frame.h" 388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameLoader.h" 398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameLoaderClientAndroid.h" 408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameTree.h" 418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HistoryItem.h" 42635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "IconDatabase.h" 438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Page.h" 448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "TextEncoding.h" 458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "WebCoreFrameBridge.h" 468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "WebCoreJni.h" 478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "jni_utility.h" 488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <JNIHelp.h> 508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <SkUtils.h> 518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <utils/misc.h> 528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace android { 548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Forward declarations 568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void write_item(WTF::Vector<char>& v, WebCore::HistoryItem* item); 578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void write_children_recursive(WTF::Vector<char>& v, WebCore::HistoryItem* parent); 588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic bool read_item_recursive(WebCore::HistoryItem* child, const char** pData, int length); 598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Field ids for WebHistoryItems 618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstruct WebHistoryItemFields { 628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project jmethodID mInit; 638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project jmethodID mUpdate; 648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project jfieldID mTitle; 658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project jfieldID mUrl; 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; 718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project jfieldID mCurrentIndex; 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{ 808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(frame, "Close needs a valid Frame pointer!"); 818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebCore::Frame* pFrame = (WebCore::Frame*)frame; 828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebCore::BackForwardList* list = 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) { 938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project current->setBridge(NULL); 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); 1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Append the first child to the queue if it exists. 1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (WebCore::Frame* f = child->tree()->firstChild()) 1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project frameQueue.append(f); 1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project child = child->tree()->nextSibling(); 1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If we don't have a sibling for this frame and the queue isn't 1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // empty, use the next entry in the queue. 1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!child && !frameQueue.isEmpty()) { 1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project child = frameQueue.at(0); 1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project frameQueue.remove(0); 1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Figure out the parent history item used when searching for 1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // the history item to use. 13667ed0edeb2ad5bb22ec778472b78d41e7eb3b68aSteve Block parent = child->tree()->parent()->loader()->history()->currentItem(); 1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void WebHistoryRestoreIndex(JNIEnv* env, jobject obj, jint frame, jint index) 1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(frame, "RestoreState needs a valid Frame pointer!"); 1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebCore::Frame* pFrame = (WebCore::Frame*)frame; 146635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project WebCore::Page* page = pFrame->page(); 1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Set the current index in the list. 149635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project WebCore::BackForwardList* list = page->backForwardList(); 1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebCore::HistoryItem* currentItem = list->entries()[index].get(); 1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project list->goToItem(currentItem); 1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Update the current and previous history item. 1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebCore::FrameLoader* loader = pFrame->loader(); 15567ed0edeb2ad5bb22ec778472b78d41e7eb3b68aSteve Block loader->history()->setCurrentItem(currentItem); 1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 157635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // load the current page with FrameLoadTypeIndexedBackForward so that it 158635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // will use cache when it is possible 159635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project page->goToItem(currentItem, FrameLoadTypeIndexedBackForward); 1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void WebHistoryInflate(JNIEnv* env, jobject obj, jint frame, jbyteArray data) 1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(frame, "Inflate needs a valid frame pointer!"); 1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(data, "Inflate needs a valid data pointer!"); 1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Get the actual bytes and the length from the java array. 1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const jbyte* bytes = env->GetByteArrayElements(data, NULL); 1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project jsize size = env->GetArrayLength(data); 1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Inflate the history tree into one HistoryItem or null if the inflation 1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // failed. 1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RefPtr<WebCore::HistoryItem> newItem = WebCore::HistoryItem::create(); 1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef ANDROID_HISTORY_CLIENT 1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RefPtr<WebHistoryItem> bridge = new WebHistoryItem(env, obj, newItem.get()); 1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project newItem->setBridge(bridge.get()); 1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Inflate the item recursively. If it fails, that is ok. We'll have an 1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // incomplete HistoryItem but that is better than crashing due to a null 1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // item. 1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We have a 2nd local variable since read_item_recursive may change the 1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // ptr's value. We can't pass &bytes since we have to send bytes to 1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // ReleaseByteArrayElements unchanged. 1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const char* ptr = reinterpret_cast<const char*>(bytes); 1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project read_item_recursive(newItem.get(), &ptr, (int)size); 1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project env->ReleaseByteArrayElements(data, const_cast<jbyte*>(bytes), JNI_ABORT); 1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef ANDROID_HISTORY_CLIENT 1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bridge->setActive(); 1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Add the new item to the back/forward list. 1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebCore::Frame* pFrame = (WebCore::Frame*)frame; 1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project pFrame->page()->backForwardList()->addItem(newItem); 1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef ANDROID_HISTORY_CLIENT 1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Update the item. 1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bridge->updateHistoryItem(newItem.get()); 1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 201635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// 6 empty strings + no document state + children count = 8 unsigned values 2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// 1 char for isTargetItem 2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// ANDROID_HISTORY_CLIENT adds 1 int for scale. 2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef ANDROID_HISTORY_CLIENT 2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define HISTORY_MIN_SIZE ((int)(sizeof(unsigned) * 9 + sizeof(char))) 206635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#else 207635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#define HISTORY_MIN_SIZE ((int)(sizeof(unsigned) * 8 + sizeof(char))) 2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectjbyteArray WebHistory::Flatten(JNIEnv* env, WTF::Vector<char>& v, WebCore::HistoryItem* item) 2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!item) 2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return NULL; 2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Reserve a vector of chars with an initial size of HISTORY_MIN_SIZE. 2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project v.reserveCapacity(HISTORY_MIN_SIZE); 2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Write the top-level history item and then write all the children 2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // recursively. 2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef ANDROID_HISTORY_CLIENT 2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(item->bridge(), "Why don't we have a bridge object here?"); 2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project write_item(v, item); 2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project write_children_recursive(v, item); 2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Try to create a new java byte array. 2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project jbyteArray b = env->NewByteArray(v.size()); 2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!b) 2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return NULL; 2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Write our flattened data to the java array. 2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project env->SetByteArrayRegion(b, 0, v.size(), (const jbyte*)v.data()); 2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return b; 2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectWebHistoryItem::WebHistoryItem(JNIEnv* env, jobject obj, 2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebCore::HistoryItem* item) { 2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project mObject = adoptGlobalRef(env, obj); 2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project mScale = 100; 2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project mActive = false; 2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project mParent = NULL; 2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project mHistoryItem = item; 2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectWebHistoryItem::~WebHistoryItem() { 2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (mObject) { 2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JNIEnv* env = JSC::Bindings::getJNIEnv(); 2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!env) 2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project env->DeleteGlobalRef(mObject); 2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid WebHistoryItem::updateHistoryItem(WebCore::HistoryItem* item) { 2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef ANDROID_HISTORY_CLIENT 2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Do not want to update during inflation. 2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!mActive) 2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebHistoryItem* webItem = this; 2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Now we need to update the top-most WebHistoryItem based on the top-most 2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // HistoryItem. 2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (mParent) { 2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project webItem = mParent.get(); 2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (webItem->hasOneRef()) { 2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // if the parent only has one ref, it is from this WebHistoryItem. 2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // This means that the matching WebCore::HistoryItem has been freed. 2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // This can happen during clear(). 2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOGW("Can't updateHistoryItem as the top HistoryItem is gone"); 2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (webItem->parent()) 2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project webItem = webItem->parent(); 2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project item = webItem->historyItem(); 2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JNIEnv* env = JSC::Bindings::getJNIEnv(); 2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!env) 2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Don't do anything if the item has been gc'd already 2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project AutoJObject realItem = getRealObject(env, webItem->mObject); 2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!realItem.get()) 2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const WebCore::String& urlString = item->urlString(); 2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project jstring urlStr = NULL; 2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!urlString.isNull()) 2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project urlStr = env->NewString((unsigned short*)urlString.characters(), urlString.length()); 2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const WebCore::String& originalUrlString = item->originalURLString(); 2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project jstring originalUrlStr = NULL; 2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!originalUrlString.isNull()) { 2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project originalUrlStr = env->NewString( 2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project (unsigned short*) originalUrlString.characters(), 2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project originalUrlString.length()); 2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const WebCore::String& titleString = item->title(); 2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project jstring titleStr = NULL; 2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!titleString.isNull()) 2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project titleStr = env->NewString((unsigned short*)titleString.characters(), titleString.length()); 2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Try to get the favicon from the history item. For some pages like Grand 3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Prix, there are history items with anchors. If the icon fails for the 3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // item, try to get the icon using the url without the ref. 3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project jobject favicon = NULL; 3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebCore::String url = item->urlString(); 3059e2ee40924101fa594b0b31d866f896154b47caaBen Murdoch if (item->url().hasFragmentIdentifier()) { 3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int refIndex = url.reverseFind('#'); 3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project url = url.substring(0, refIndex); 3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebCore::Image* icon = WebCore::iconDatabase()->iconForPageURL(url, 3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebCore::IntSize(16, 16)); 3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (icon) 3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project favicon = webcoreImageToJavaBitmap(env, icon); 3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WTF::Vector<char> data; 3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project jbyteArray array = WebHistory::Flatten(env, data, item); 3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project env->CallVoidMethod(realItem.get(), gWebHistoryItem.mUpdate, urlStr, 3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project originalUrlStr, titleStr, favicon, array); 3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project env->DeleteLocalRef(urlStr); 3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project env->DeleteLocalRef(originalUrlStr); 3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project env->DeleteLocalRef(titleStr); 3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (favicon) 3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project env->DeleteLocalRef(favicon); 3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project env->DeleteLocalRef(array); 3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void historyItemChanged(WebCore::HistoryItem* item) { 3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef ANDROID_HISTORY_CLIENT 3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(item, 3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project "historyItemChanged called with a null item"); 3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (item->bridge()) 3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project item->bridge()->updateHistoryItem(item); 3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid WebHistory::AddItem(const AutoJObject& list, WebCore::HistoryItem* item) 3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef ANDROID_HISTORY_CLIENT 3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(item, "newItem must take a valid HistoryItem!"); 3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Item already added. Should only happen when we are inflating the list. 3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (item->bridge() || !list.get()) 3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JNIEnv* env = list.env(); 3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Allocate a blank WebHistoryItem 3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project jclass clazz = env->FindClass("android/webkit/WebHistoryItem"); 3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project jobject newItem = env->NewObject(clazz, gWebHistoryItem.mInit); 3498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Create the bridge, make it active, and attach it to the item. 3518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebHistoryItem* bridge = new WebHistoryItem(env, newItem, item); 3528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bridge->setActive(); 3538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project item->setBridge(bridge); 3548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Update the history item which will flatten the data and call update on 3568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // the java item. 3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bridge->updateHistoryItem(item); 3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Add it to the list. 3608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project env->CallVoidMethod(list.get(), gWebBackForwardList.mAddHistoryItem, newItem); 3618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Delete our local reference. 3638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project env->DeleteLocalRef(newItem); 3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid WebHistory::RemoveItem(const AutoJObject& list, int index) 3688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (list.get()) 3708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project list.env()->CallVoidMethod(list.get(), gWebBackForwardList.mRemoveHistoryItem, index); 3718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid WebHistory::UpdateHistoryIndex(const AutoJObject& list, int newIndex) 3748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (list.get()) 3768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project list.env()->SetIntField(list.get(), gWebBackForwardList.mCurrentIndex, newIndex); 3778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void write_string(WTF::Vector<char>& v, const WebCore::String& str) 3808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned strLen = str.length(); 3828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Only do work if the string has data. 3838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (strLen) { 3848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Determine how much to grow the vector. Use the worst case for utf8 to 3858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // avoid reading the string twice. Add sizeof(unsigned) to hold the 3868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // string length in utf8. 3878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned vectorLen = v.size() + sizeof(unsigned); 3888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned length = (strLen << 2) + vectorLen; 3898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Grow the vector. This will change the value of v.size() but we 3908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // remember the original size above. 3918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project v.grow(length); 3928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Grab the position to write to. 3938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project char* data = v.begin() + vectorLen; 3948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Write the actual string 3958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int l = SkUTF16_ToUTF8(str.characters(), strLen, data); 3968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOGV("Writing string %d %.*s", l, l, data); 3978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Go back and write the utf8 length. Subtract sizeof(unsigned) from 3988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // data to get the position to write the length. 3998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memcpy(data - sizeof(unsigned), (char*)&l, sizeof(unsigned)); 4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Shrink the internal state of the vector so we match what was 4018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // actually written. 4028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project v.shrink(vectorLen + l); 4038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else 4048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project v.append((char*)&strLen, sizeof(unsigned)); 4058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void write_item(WTF::Vector<char>& v, WebCore::HistoryItem* item) 4088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Original url 4108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project write_string(v, item->originalURLString()); 4118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Url 4138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project write_string(v, item->urlString()); 4148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Title 4168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project write_string(v, item->title()); 4178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Form content type 4198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project write_string(v, item->formContentType()); 4208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Form data 4228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const WebCore::FormData* formData = item->formData(); 423ef7b176b34c6a1fe082a87dd17523e47737c1e19Grace Kloba if (formData) { 4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project write_string(v, formData->flattenToString()); 425ef7b176b34c6a1fe082a87dd17523e47737c1e19Grace Kloba // save the identifier as it is not included in the flatten data 426ef7b176b34c6a1fe082a87dd17523e47737c1e19Grace Kloba int64_t id = formData->identifier(); 427ef7b176b34c6a1fe082a87dd17523e47737c1e19Grace Kloba v.append((char*)&id, sizeof(int64_t)); 428ef7b176b34c6a1fe082a87dd17523e47737c1e19Grace Kloba } else 4298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project write_string(v, WebCore::String()); // Empty constructor does not allocate a buffer. 4308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Target 4328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project write_string(v, item->target()); 4338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef ANDROID_HISTORY_CLIENT 4358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebHistoryItem* bridge = item->bridge(); 4368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(bridge, "We should have a bridge here!"); 4378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Screen scale 4388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int scale = bridge->scale(); 4398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOGV("Writing scale %d", scale); 4408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project v.append((char*)&scale, sizeof(int)); 4418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 4428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Document state 4448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const WTF::Vector<WebCore::String>& docState = item->documentState(); 4458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WTF::Vector<WebCore::String>::const_iterator end = docState.end(); 4468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned stateSize = docState.size(); 4478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOGV("Writing docState %d", stateSize); 4488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project v.append((char*)&stateSize, sizeof(unsigned)); 4498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (WTF::Vector<WebCore::String>::const_iterator i = docState.begin(); i != end; ++i) { 4508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project write_string(v, *i); 4518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Is target item 4548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOGV("Writing isTargetItem %d", item->isTargetItem()); 4558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project v.append((char)item->isTargetItem()); 4568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Children count 4588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned childCount = item->children().size(); 4598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOGV("Writing childCount %d", childCount); 4608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project v.append((char*)&childCount, sizeof(unsigned)); 4618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void write_children_recursive(WTF::Vector<char>& v, WebCore::HistoryItem* parent) 4648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const WebCore::HistoryItemVector& children = parent->children(); 4668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebCore::HistoryItemVector::const_iterator end = children.end(); 4678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (WebCore::HistoryItemVector::const_iterator i = children.begin(); i != end; ++i) { 4688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebCore::HistoryItem* item = (*i).get(); 4698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef ANDROID_HISTORY_CLIENT 4708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(parent->bridge(), 4718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project "The parent item should have a bridge object!"); 4728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!item->bridge()) { 4738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebHistoryItem* bridge = new WebHistoryItem(parent->bridge()); 4748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project item->setBridge(bridge); 4758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bridge->setActive(); 4768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 4778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // The only time this item's parent may not be the same as the 4788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // parent's bridge is during history close. In that case, the 4798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // parent must not have a parent bridge. 4808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(parent->bridge()->parent() == NULL || 4818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project item->bridge()->parent() == parent->bridge(), 4828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project "Somehow this item has an incorrect parent"); 4838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project item->bridge()->setParent(parent->bridge()); 4848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 4868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project write_item(v, item); 4878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project write_children_recursive(v, item); 4888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic bool read_item_recursive(WebCore::HistoryItem* newItem, 4928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const char** pData, int length) 4938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!pData || length < HISTORY_MIN_SIZE) 4958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 4968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const WebCore::TextEncoding& e = WebCore::UTF8Encoding(); 4988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const char* data = *pData; 4998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const char* end = data + length; 5008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int sizeofUnsigned = (int)sizeof(unsigned); 5018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Read the original url 5038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Read the expected length of the string. 5048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int l; 5058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memcpy(&l, data, sizeofUnsigned); 5068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Increment data pointer by the size of an unsigned int. 5078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project data += sizeofUnsigned; 5088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (l) { 5098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOGV("Original url %d %.*s", l, l, data); 5108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If we have a length, check if that length exceeds the data length 5118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // and return null if there is not enough data. 5128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (data + l < end) 5138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project newItem->setOriginalURLString(e.decode(data, l)); 5148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 5158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 5168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Increment the data pointer by the length of the string. 5178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project data += l; 5188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Check if we have enough data left to continue. 5208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (end - data < sizeofUnsigned) 5218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 5228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Read the url 5248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memcpy(&l, data, sizeofUnsigned); 5258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project data += sizeofUnsigned; 5268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (l) { 5278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOGV("Url %d %.*s", l, l, data); 5288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (data + l < end) 5298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project newItem->setURLString(e.decode(data, l)); 5308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 5318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 5328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project data += l; 5338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (end - data < sizeofUnsigned) 5358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 5368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Read the title 5388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memcpy(&l, data, sizeofUnsigned); 5398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project data += sizeofUnsigned; 5408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (l) { 5418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOGV("Title %d %.*s", l, l, data); 5428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (data + l < end) 5438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project newItem->setTitle(e.decode(data, l)); 5448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 5458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 5468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project data += l; 5478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (end - data < sizeofUnsigned) 5498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 5508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Generate a new ResourceRequest object for populating form information. 5528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebCore::String formContentType; 5538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WTF::PassRefPtr<WebCore::FormData> formData = NULL; 5548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Read the form content type 5568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memcpy(&l, data, sizeofUnsigned); 5578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project data += sizeofUnsigned; 5588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (l) { 5598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOGV("Content type %d %.*s", l, l, data); 5608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (data + l < end) 5618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project formContentType = e.decode(data, l); 5628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 5638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 5648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project data += l; 5658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (end - data < sizeofUnsigned) 5678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 5688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Read the form data 5708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memcpy(&l, data, sizeofUnsigned); 5718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project data += sizeofUnsigned; 5728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (l) { 5738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOGV("Form data %d %.*s", l, l, data); 5748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (data + l < end) 5758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project formData = WebCore::FormData::create(data, l); 5768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 5778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 5788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project data += l; 579ef7b176b34c6a1fe082a87dd17523e47737c1e19Grace Kloba // Read the identifier 580ef7b176b34c6a1fe082a87dd17523e47737c1e19Grace Kloba { 581ef7b176b34c6a1fe082a87dd17523e47737c1e19Grace Kloba int64_t id; 582ef7b176b34c6a1fe082a87dd17523e47737c1e19Grace Kloba int size = (int)sizeof(int64_t); 583ef7b176b34c6a1fe082a87dd17523e47737c1e19Grace Kloba memcpy(&id, data, size); 584ef7b176b34c6a1fe082a87dd17523e47737c1e19Grace Kloba data += size; 585ef7b176b34c6a1fe082a87dd17523e47737c1e19Grace Kloba if (id) 586ef7b176b34c6a1fe082a87dd17523e47737c1e19Grace Kloba formData->setIdentifier(id); 587ef7b176b34c6a1fe082a87dd17523e47737c1e19Grace Kloba } 5888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (end - data < sizeofUnsigned) 5908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 5918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Set up the form info 5938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (formData != NULL) { 5948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebCore::ResourceRequest r; 5958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project r.setHTTPMethod("POST"); 5968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project r.setHTTPContentType(formContentType); 5978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project r.setHTTPBody(formData); 5988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project newItem->setFormInfoFromRequest(r); 5998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 6008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Read the target 6028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memcpy(&l, data, sizeofUnsigned); 6038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project data += sizeofUnsigned; 6048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (l) { 6058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOGV("Target %d %.*s", l, l, data); 6068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (data + l < end) 6078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project newItem->setTarget(e.decode(data, l)); 6088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 6098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 6108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project data += l; 6118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 6128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (end - data < sizeofUnsigned) 6138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 6148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef ANDROID_HISTORY_CLIENT 6168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebHistoryItem* bridge = newItem->bridge(); 6178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(bridge, "There should be a bridge object during inflate"); 6188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Read the screen scale 6198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memcpy(&l, data, sizeofUnsigned); 6208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOGV("Screen scale %d", l); 6218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bridge->setScale(l); 6228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project data += sizeofUnsigned; 6238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (end - data < sizeofUnsigned) 6248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 6258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 6268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Read the document state 6288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memcpy(&l, data, sizeofUnsigned); 6298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOGV("Document state %d", l); 6308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project data += sizeofUnsigned; 6318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (l) { 6328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Check if we have enough data to at least parse the sizes of each 6338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // document state string. 6348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (data + l * sizeofUnsigned >= end) 6358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 6368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Create a new vector and reserve enough space for the document state. 6378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WTF::Vector<WebCore::String> docState; 6388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project docState.reserveCapacity(l); 6398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (l--) { 6408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Check each time if we have enough to parse the length of the next 6418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // string. 6428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (end - data < sizeofUnsigned) 6438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 6448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int strLen; 6458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memcpy(&strLen, data, sizeofUnsigned); 6468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project data += sizeofUnsigned; 6478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (data + strLen < end) 6488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project docState.append(e.decode(data, strLen)); 6498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 6508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 6518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOGV("\t\t%d %.*s", strLen, strLen, data); 6528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project data += strLen; 6538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 6548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project newItem->setDocumentState(docState); 6558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 6568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Check if we have enough to read the next byte 6578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (data >= end) 6588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 6598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Read is target item 6618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Cast the value to unsigned char in order to make a negative value larger 6628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // than 1. A value that is not 0 or 1 is a failure. 6638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned char c = (unsigned char)data[0]; 6648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (c > 1) 6658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 6668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOGV("Target item %d", c); 6678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project newItem->setIsTargetItem((bool)c); 6688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project data++; 6698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (end - data < sizeofUnsigned) 6708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 6718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Read the child count 6738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memcpy(&l, data, sizeofUnsigned); 6748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOGV("Child count %d", l); 6758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project data += sizeofUnsigned; 6768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *pData = data; 6778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (l) { 6788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Check if we have the minimum amount need to parse l children. 6798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (data + l * HISTORY_MIN_SIZE >= end) 6808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 6818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (l--) { 6828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // No need to check the length each time because read_item_recursive 6838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // will return null if there isn't enough data left to parse. 6848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WTF::PassRefPtr<WebCore::HistoryItem> child = WebCore::HistoryItem::create(); 6858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef ANDROID_HISTORY_CLIENT 6868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Set a bridge that will not call into java. 6878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project child->setBridge(new WebHistoryItem(bridge)); 6888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 6898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Read the child item. 6908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!read_item_recursive(child.get(), pData, end - data)) { 6918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project child.clear(); 6928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 6938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 6948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef ANDROID_HISTORY_CLIENT 6958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project child->bridge()->setActive(); 6968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 6978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project newItem->addChildItem(child); 6988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 6998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 7008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 7018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// On arm, this test will cause memory corruption since converting char* will 7048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// byte align the result and this test does not use memset (it probably 7058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// should). 7068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// On the simulator, using HistoryItem will invoke the IconDatabase which will 7078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// initialize the main thread. Since this is invoked by the Zygote process, the 7088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// main thread will be incorrect and an assert will fire later. 7098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// In conclusion, define UNIT_TEST only if you know what you are doing. 7108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef UNIT_TEST 7118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void unit_test() 7128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOGD("Entering history unit test!"); 7148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const char* test1 = new char[0]; 7158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WTF::RefPtr<WebCore::HistoryItem> item = WebCore::HistoryItem::create(); 7168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebCore::HistoryItem* testItem = item.get(); 7178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef ANDROID_HISTORY_CLIENT 7188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project testItem->setBridge(new WebHistoryItem(NULL)); 7198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 7208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(!read_item_recursive(testItem, &test1, 0), "0 length array should fail!"); 7218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delete[] test1; 7228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const char* test2 = new char[2]; 7238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(!read_item_recursive(testItem, &test2, 2), "Small array should fail!"); 7248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delete[] test2; 7258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(!read_item_recursive(testItem, NULL, HISTORY_MIN_SIZE), "Null data should fail!"); 7268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Original Url 7278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project char* test3 = new char[HISTORY_MIN_SIZE]; 7288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const char* ptr = (const char*)test3; 7298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memset(test3, 0, HISTORY_MIN_SIZE); 7308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *(int*)test3 = 4000; 7318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length originalUrl should fail!"); 7328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Url 7338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int offset = 4; 7348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memset(test3, 0, HISTORY_MIN_SIZE); 7358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ptr = (const char*)test3; 7368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *(int*)(test3 + offset) = 4000; 7378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length url should fail!"); 7388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Title 7398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project offset += 4; 7408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memset(test3, 0, HISTORY_MIN_SIZE); 7418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ptr = (const char*)test3; 7428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *(int*)(test3 + offset) = 4000; 7438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length title should fail!"); 7448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Form content type 7458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project offset += 4; 7468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memset(test3, 0, HISTORY_MIN_SIZE); 7478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ptr = (const char*)test3; 7488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *(int*)(test3 + offset) = 4000; 7498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length contentType should fail!"); 7508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Form data 7518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project offset += 4; 7528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memset(test3, 0, HISTORY_MIN_SIZE); 7538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ptr = (const char*)test3; 7548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *(int*)(test3 + offset) = 4000; 7558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length form data should fail!"); 7568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Target 7578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project offset += 4; 7588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memset(test3, 0, HISTORY_MIN_SIZE); 7598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ptr = (const char*)test3; 7608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *(int*)(test3 + offset) = 4000; 7618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length target should fail!"); 7628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef ANDROID_HISTORY_CLIENT 7638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project offset += 4; // Scale 7648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 7658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Document state 7668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project offset += 4; 7678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memset(test3, 0, HISTORY_MIN_SIZE); 7688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ptr = (const char*)test3; 7698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *(int*)(test3 + offset) = 4000; 7708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length document state should fail!"); 7718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Is target item 7728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project offset += 1; 7738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memset(test3, 0, HISTORY_MIN_SIZE); 7748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ptr = (const char*)test3; 7758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *(char*)(test3 + offset) = '!'; 7768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "IsTargetItem should fail with ! as the value!"); 7778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Child count 7788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project offset += 4; 7798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memset(test3, 0, HISTORY_MIN_SIZE); 7808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ptr = (const char*)test3; 7818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *(int*)(test3 + offset) = 4000; 7828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 kids should fail!"); 7838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef ANDROID_HISTORY_CLIENT 7858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project offset = 36; 7868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#else 7878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project offset = 28; 7888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 7898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Test document state 7908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delete[] test3; 7918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project test3 = new char[HISTORY_MIN_SIZE + sizeof(unsigned)]; 7928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memset(test3, 0, HISTORY_MIN_SIZE + sizeof(unsigned)); 7938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ptr = (const char*)test3; 7948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *(int*)(test3 + offset) = 1; 7958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *(int*)(test3 + offset + 4) = 20; 7968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE + sizeof(unsigned)), "1 20 length document state string should fail!"); 7978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delete[] test3; 7988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project test3 = new char[HISTORY_MIN_SIZE + 2 * sizeof(unsigned)]; 7998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project memset(test3, 0, HISTORY_MIN_SIZE + 2 * sizeof(unsigned)); 8008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ptr = (const char*)test3; 8018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *(int*)(test3 + offset) = 2; 8028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *(int*)(test3 + offset + 4) = 0; 8038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *(int*)(test3 + offset + 8) = 20; 8048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE + 2 * sizeof(unsigned) ), "2 20 length document state string should fail!"); 8058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delete[] test3; 8068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 8078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 8088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project//--------------------------------------------------------- 8108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// JNI registration 8118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project//--------------------------------------------------------- 8128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic JNINativeMethod gWebBackForwardListMethods[] = { 8138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { "nativeClose", "(I)V", 8148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project (void*) WebHistoryClose }, 8158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { "restoreIndex", "(II)V", 8168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project (void*) WebHistoryRestoreIndex } 8178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}; 8188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic JNINativeMethod gWebHistoryItemMethods[] = { 8208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { "inflate", "(I[B)V", 8218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project (void*) WebHistoryInflate } 8228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}; 8238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint register_webhistory(JNIEnv* env) 8258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 8268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef ANDROID_HISTORY_CLIENT 8278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Get notified of all changes to history items. 8288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebCore::notifyHistoryItemChanged = historyItemChanged; 8298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 8308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef UNIT_TEST 8318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unit_test(); 8328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 8338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Find WebHistoryItem, its constructor, and the update method. 8348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project jclass clazz = env->FindClass("android/webkit/WebHistoryItem"); 8358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(clazz, "Unable to find class android/webkit/WebHistoryItem"); 8368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gWebHistoryItem.mInit = env->GetMethodID(clazz, "<init>", "()V"); 8378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(gWebHistoryItem.mInit, "Could not find WebHistoryItem constructor"); 8388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gWebHistoryItem.mUpdate = env->GetMethodID(clazz, "update", 8398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/graphics/Bitmap;[B)V"); 8408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(gWebHistoryItem.mUpdate, "Could not find method update in WebHistoryItem"); 8418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Find the field ids for mTitle and mUrl. 8438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gWebHistoryItem.mTitle = env->GetFieldID(clazz, "mTitle", "Ljava/lang/String;"); 8448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(gWebHistoryItem.mTitle, "Could not find field mTitle in WebHistoryItem"); 8458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gWebHistoryItem.mUrl = env->GetFieldID(clazz, "mUrl", "Ljava/lang/String;"); 8468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(gWebHistoryItem.mUrl, "Could not find field mUrl in WebHistoryItem"); 8478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Find the WebBackForwardList object, the addHistoryItem and 8498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // removeHistoryItem methods and the mCurrentIndex field. 8508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project clazz = env->FindClass("android/webkit/WebBackForwardList"); 8518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(clazz, "Unable to find class android/webkit/WebBackForwardList"); 8528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gWebBackForwardList.mAddHistoryItem = env->GetMethodID(clazz, "addHistoryItem", 8538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project "(Landroid/webkit/WebHistoryItem;)V"); 8548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(gWebBackForwardList.mAddHistoryItem, "Could not find method addHistoryItem"); 8558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gWebBackForwardList.mRemoveHistoryItem = env->GetMethodID(clazz, "removeHistoryItem", 8568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project "(I)V"); 8578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(gWebBackForwardList.mRemoveHistoryItem, "Could not find method removeHistoryItem"); 8588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gWebBackForwardList.mCurrentIndex = env->GetFieldID(clazz, "mCurrentIndex", "I"); 8598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(gWebBackForwardList.mCurrentIndex, "Could not find field mCurrentIndex"); 8608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int result = jniRegisterNativeMethods(env, "android/webkit/WebBackForwardList", 8628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gWebBackForwardListMethods, NELEM(gWebBackForwardListMethods)); 8638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return (result < 0) ? result : jniRegisterNativeMethods(env, "android/webkit/WebHistoryItem", 8648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gWebHistoryItemMethods, NELEM(gWebHistoryItemMethods)); 8658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 8668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} /* namespace android */ 868