void WebHistory::AddItem(const AutoJObject& list, WebCore::HistoryItem* item) { LOG_ASSERT(item, "newItem must take a valid HistoryItem!"); // Item already added. Should only happen when we are inflating the list. if (item->bridge() || !list.get()) return; JNIEnv* env = list.env(); // Allocate a blank WebHistoryItem jclass clazz = env->FindClass("android/webkit/WebHistoryItem"); jobject newItem = env->NewObject(clazz, gWebHistoryItem.mInit); // Create the bridge, make it active, and attach it to the item. WebHistoryItem* bridge = new WebHistoryItem(env, newItem, item); bridge->setActive(); item->setBridge(bridge); // Update the history item which will flatten the data and call update on // the java item. bridge->updateHistoryItem(item); // Add it to the list. env->CallVoidMethod(list.get(), gWebBackForwardList.mAddHistoryItem, newItem); // Delete our local reference. env->DeleteLocalRef(newItem); }
static void WebHistoryInflate(JNIEnv* env, jobject obj, jint frame, jbyteArray data) { LOG_ASSERT(frame, "Inflate needs a valid frame pointer!"); LOG_ASSERT(data, "Inflate needs a valid data pointer!"); // Inflate the history tree into one HistoryItem or null if the inflation // failed. RefPtr<WebCore::HistoryItem> newItem = WebCore::HistoryItem::create(); WebHistoryItem* bridge = new WebHistoryItem(env, obj, newItem.get()); // Get the actual bytes and the length from the java array. const jbyte* bytes = env->GetByteArrayElements(data, NULL); jsize size = env->GetArrayLength(data); newItem->setBridge(bridge); // Inflate the item recursively. If it fails, that is ok. We'll have an // incomplete HistoryItem but that is better than crashing due to a null // item. // We have a 2nd local variable since read_item_recursive may change the // ptr's value. We can't pass &bytes since we have to send bytes to // ReleaseByteArrayElements unchanged. const char* ptr = reinterpret_cast<const char*>(bytes); bool readCheck = read_item_recursive(newItem.get(), &ptr, (int)size); if(!readCheck) LOGV("read_item_recursive returned %d ",readCheck); env->ReleaseByteArrayElements(data, const_cast<jbyte*>(bytes), JNI_ABORT); bridge->setActive(); // Add the new item to the back/forward list. WebCore::Frame* pFrame = (WebCore::Frame*)frame; pFrame->page()->backForwardList()->addItem(newItem); // Update the item. bridge->updateHistoryItem(newItem.get()); }
static jint WebHistoryInflate(JNIEnv* env, jobject obj, jint frame, jbyteArray data) { ALOG_ASSERT(frame, "Inflate needs a valid frame pointer!"); ALOG_ASSERT(data, "Inflate needs a valid data pointer!"); // Get the actual bytes and the length from the java array. const jbyte* bytes = env->GetByteArrayElements(data, NULL); jsize size = env->GetArrayLength(data); // Inflate the history tree into one HistoryItem or null if the inflation // failed. RefPtr<WebCore::HistoryItem> newItem = WebCore::HistoryItem::create(); WebHistoryItem* bridge = new WebHistoryItem(newItem.get()); newItem->setBridge(bridge); // Inflate the item recursively. If it fails, that is ok. We'll have an // incomplete HistoryItem but that is better than crashing due to a null // item. // We have a 2nd local variable since read_item_recursive may change the // ptr's value. We can't pass &bytes since we have to send bytes to // ReleaseByteArrayElements unchanged. const char* ptr = reinterpret_cast<const char*>(bytes); readItemRecursive(newItem.get(), &ptr, (int)size); env->ReleaseByteArrayElements(data, const_cast<jbyte*>(bytes), JNI_ABORT); bridge->setActive(); // Add the new item to the back/forward list. WebCore::Frame* pFrame = (WebCore::Frame*)frame; pFrame->page()->backForwardList()->addItem(newItem); // Update the item. bridge->updateHistoryItem(newItem.get()); // Ref here because Java expects to adopt the reference, and as such will not // call ref on it. However, setBridge has also adopted the reference // TODO: This is confusing as hell, clean up ownership and have setBridge // take a RefPtr instead of a raw ptr and calling adoptRef on it bridge->ref(); return reinterpret_cast<jint>(bridge); }