/*
 * Copyright 2006, The Android Open Source Project
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#define LOG_TAG "webcoreglue"

#include "config.h"
#include "WebCoreFrameBridge.h"

#include "Arena.h"
#include "BackForwardList.h"
#include "MemoryCache.h"
#include "Chrome.h"
#include "ChromeClientAndroid.h"
#include "ChromiumInit.h"
#include "ContextMenuClientAndroid.h"
#include "DeviceMotionClientAndroid.h"
#include "DeviceOrientationClientAndroid.h"
#include "Document.h"
#include "DocumentLoader.h"
#include "DragClientAndroid.h"
#include "EditorClientAndroid.h"
#include "Element.h"
#include "FocusController.h"
#include "Font.h"
#include "Frame.h"
#include "FrameLoader.h"
#include "FrameLoaderClientAndroid.h"
#include "FrameLoadRequest.h"
#include "FrameTree.h"
#include "FrameView.h"
#include "GeolocationClientAndroid.h"
#include "GraphicsContext.h"
#include "HistoryItem.h"
#include "HTMLCollection.h"
#include "HTMLElement.h"
#include "HTMLFormElement.h"
#include "HTMLInputElement.h"
#include "HTMLNames.h"
#include "IconDatabase.h"
#include "Image.h"
#include "InspectorClientAndroid.h"
#include "JavaClassJobjectV8.h"
#include "JavaNPObjectV8.h"
#include "JavaInstanceJobjectV8.h"
#include "KURL.h"
#include "Page.h"
#include "PageCache.h"
#include "PlatformString.h"
#include "RenderPart.h"
#include "RenderSkinAndroid.h"
#include "RenderTreeAsText.h"
#include "RenderView.h"
#include "ResourceHandle.h"
#include "ResourceHandleInternal.h"
#include "ScriptController.h"
#include "ScriptValue.h"
#include "SecurityOrigin.h"
#include "SelectionController.h"
#include "Settings.h"
#include "SubstituteData.h"
#include "UrlInterceptResponse.h"
#include "UserGestureIndicator.h"
#include "WebArchiveAndroid.h"
#include "WebCache.h"
#include "WebCoreJni.h"
#include "WebHistory.h"
#include "WebIconDatabase.h"
#include "WebFrameView.h"
#include "WebUrlLoaderClient.h"
#include "WebViewCore.h"
#include "jni.h"
#include "wds/DebugServer.h"

#include <JNIUtility.h>
#include <JNIHelp.h>
#include <ScopedPrimitiveArray.h>
#include <ScopedLocalRef.h>
#include <SkGraphics.h>
#include <android_runtime/android_util_AssetManager.h>
#include <openssl/x509.h>
#include <utils/misc.h>
#include <androidfw/AssetManager.h>
#include <wtf/CurrentTime.h>
#include <wtf/Platform.h>
#include <wtf/text/AtomicString.h>
#include <wtf/text/CString.h>
#include <wtf/text/StringBuilder.h>

#if ENABLE(WEB_AUTOFILL)
#include "autofill/WebAutofill.h"
#endif

using namespace JSC::Bindings;

static String* gUploadFileLabel;
static String* gResetLabel;
static String* gSubmitLabel;
static String* gNoFileChosenLabel;

String* WebCore::PlatformBridge::globalLocalizedName(
        WebCore::PlatformBridge::rawResId resId)
{
    switch (resId) {
    case WebCore::PlatformBridge::FileUploadLabel:
        return gUploadFileLabel;
    case WebCore::PlatformBridge::ResetLabel:
        return gResetLabel;
    case WebCore::PlatformBridge::SubmitLabel:
        return gSubmitLabel;
    case WebCore::PlatformBridge::FileUploadNoFileChosenLabel:
        return gNoFileChosenLabel;

    default:
        return 0;
    }
}
/**
 * Instantiate the localized name desired.
 */
void initGlobalLocalizedName(WebCore::PlatformBridge::rawResId resId,
        android::WebFrame* webFrame)
{
    String** pointer;
    switch (resId) {
    case WebCore::PlatformBridge::FileUploadLabel:
        pointer = &gUploadFileLabel;
        break;
    case WebCore::PlatformBridge::ResetLabel:
        pointer = &gResetLabel;
        break;
    case WebCore::PlatformBridge::SubmitLabel:
        pointer = &gSubmitLabel;
        break;
    case WebCore::PlatformBridge::FileUploadNoFileChosenLabel:
        pointer = &gNoFileChosenLabel;
        break;
    default:
        return;
    }
    if (!(*pointer) && webFrame) {
        (*pointer) = new String(webFrame->getRawResourceFilename(resId).impl());
    }
}

namespace android {

// ----------------------------------------------------------------------------

#define WEBCORE_MEMORY_CAP 15 * 1024 * 1024

// ----------------------------------------------------------------------------

struct WebFrame::JavaBrowserFrame
{
    jweak       mObj;
    jweak       mHistoryList; // WebBackForwardList object
    jmethodID   mStartLoadingResource;
    jmethodID   mMaybeSavePassword;
    jmethodID   mShouldInterceptRequest;
    jmethodID   mLoadStarted;
    jmethodID   mTransitionToCommitted;
    jmethodID   mLoadFinished;
    jmethodID   mReportError;
    jmethodID   mSetTitle;
    jmethodID   mWindowObjectCleared;
    jmethodID   mSetProgress;
    jmethodID   mDidReceiveIcon;
    jmethodID   mDidReceiveTouchIconUrl;
    jmethodID   mUpdateVisitedHistory;
    jmethodID   mHandleUrl;
    jmethodID   mCreateWindow;
    jmethodID   mCloseWindow;
    jmethodID   mDecidePolicyForFormResubmission;
    jmethodID   mRequestFocus;
    jmethodID   mGetRawResFilename;
    jmethodID   mDensity;
    jmethodID   mGetFileSize;
    jmethodID   mGetFile;
    jmethodID   mDidReceiveAuthenticationChallenge;
    jmethodID   mReportSslCertError;
    jmethodID   mRequestClientCert;
    jmethodID   mDownloadStart;
    jmethodID   mDidReceiveData;
    jmethodID   mDidFinishLoading;
    jmethodID   mSetCertificate;
    jmethodID   mShouldSaveFormData;
    jmethodID   mSaveFormData;
    jmethodID   mAutoLogin;
    AutoJObject frame(JNIEnv* env) {
        return getRealObject(env, mObj);
    }
    AutoJObject history(JNIEnv* env) {
        return getRealObject(env, mHistoryList);
    }
};

static jfieldID gFrameField;
#define GET_NATIVE_FRAME(env, obj) ((WebCore::Frame*)env->GetIntField(obj, gFrameField))
#define SET_NATIVE_FRAME(env, obj, frame) (env->SetIntField(obj, gFrameField, frame))

// ----------------------------------------------------------------------------

WebFrame::WebFrame(JNIEnv* env, jobject obj, jobject historyList, WebCore::Page* page)
    : mPage(page)
{
    jclass clazz = env->GetObjectClass(obj);
    mJavaFrame = new JavaBrowserFrame;
    mJavaFrame->mObj = env->NewWeakGlobalRef(obj);
    mJavaFrame->mHistoryList = env->NewWeakGlobalRef(historyList);
    mJavaFrame->mMaybeSavePassword = env->GetMethodID(clazz, "maybeSavePassword",
            "([BLjava/lang/String;Ljava/lang/String;)V");
    mJavaFrame->mShouldInterceptRequest =
            env->GetMethodID(clazz, "shouldInterceptRequest",
            "(Ljava/lang/String;)Landroid/webkit/WebResourceResponse;");
    mJavaFrame->mLoadStarted = env->GetMethodID(clazz, "loadStarted",
            "(Ljava/lang/String;Landroid/graphics/Bitmap;IZ)V");
    mJavaFrame->mTransitionToCommitted = env->GetMethodID(clazz, "transitionToCommitted",
            "(IZ)V");
    mJavaFrame->mLoadFinished = env->GetMethodID(clazz, "loadFinished",
            "(Ljava/lang/String;IZ)V");
    mJavaFrame->mReportError = env->GetMethodID(clazz, "reportError",
            "(ILjava/lang/String;Ljava/lang/String;)V");
    mJavaFrame->mSetTitle = env->GetMethodID(clazz, "setTitle",
            "(Ljava/lang/String;)V");
    mJavaFrame->mWindowObjectCleared = env->GetMethodID(clazz, "windowObjectCleared",
            "(I)V");
    mJavaFrame->mSetProgress = env->GetMethodID(clazz, "setProgress",
            "(I)V");
    mJavaFrame->mDidReceiveIcon = env->GetMethodID(clazz, "didReceiveIcon",
            "(Landroid/graphics/Bitmap;)V");
    mJavaFrame->mDidReceiveTouchIconUrl = env->GetMethodID(clazz, "didReceiveTouchIconUrl",
            "(Ljava/lang/String;Z)V");
    mJavaFrame->mUpdateVisitedHistory = env->GetMethodID(clazz, "updateVisitedHistory",
            "(Ljava/lang/String;Z)V");
    mJavaFrame->mHandleUrl = env->GetMethodID(clazz, "handleUrl",
            "(Ljava/lang/String;)Z");
    mJavaFrame->mCreateWindow = env->GetMethodID(clazz, "createWindow",
            "(ZZ)Landroid/webkit/BrowserFrame;");
    mJavaFrame->mCloseWindow = env->GetMethodID(clazz, "closeWindow",
            "(Landroid/webkit/WebViewCore;)V");
    mJavaFrame->mDecidePolicyForFormResubmission = env->GetMethodID(clazz,
            "decidePolicyForFormResubmission", "(I)V");
    mJavaFrame->mRequestFocus = env->GetMethodID(clazz, "requestFocus",
            "()V");
    mJavaFrame->mGetRawResFilename = env->GetMethodID(clazz, "getRawResFilename",
            "(I)Ljava/lang/String;");
    mJavaFrame->mDensity = env->GetMethodID(clazz, "density","()F");
    mJavaFrame->mGetFileSize = env->GetMethodID(clazz, "getFileSize", "(Ljava/lang/String;)I");
    mJavaFrame->mGetFile = env->GetMethodID(clazz, "getFile", "(Ljava/lang/String;[BII)I");
    mJavaFrame->mDidReceiveAuthenticationChallenge = env->GetMethodID(clazz, "didReceiveAuthenticationChallenge",
            "(ILjava/lang/String;Ljava/lang/String;ZZ)V");
    mJavaFrame->mReportSslCertError = env->GetMethodID(clazz, "reportSslCertError", "(II[BLjava/lang/String;)V");
    mJavaFrame->mRequestClientCert = env->GetMethodID(clazz, "requestClientCert", "(ILjava/lang/String;)V");
    mJavaFrame->mDownloadStart = env->GetMethodID(clazz, "downloadStart",
            "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;J)V");
    mJavaFrame->mDidReceiveData = env->GetMethodID(clazz, "didReceiveData", "([BI)V");
    mJavaFrame->mDidFinishLoading = env->GetMethodID(clazz, "didFinishLoading", "()V");
    mJavaFrame->mSetCertificate = env->GetMethodID(clazz, "setCertificate", "([B)V");
    mJavaFrame->mShouldSaveFormData = env->GetMethodID(clazz, "shouldSaveFormData", "()Z");
    mJavaFrame->mSaveFormData = env->GetMethodID(clazz, "saveFormData", "(Ljava/util/HashMap;)V");
    mJavaFrame->mAutoLogin = env->GetMethodID(clazz, "autoLogin",
            "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
    env->DeleteLocalRef(clazz);

    ALOG_ASSERT(mJavaFrame->mMaybeSavePassword, "Could not find method maybeSavePassword");
    ALOG_ASSERT(mJavaFrame->mShouldInterceptRequest, "Could not find method shouldInterceptRequest");
    ALOG_ASSERT(mJavaFrame->mLoadStarted, "Could not find method loadStarted");
    ALOG_ASSERT(mJavaFrame->mTransitionToCommitted, "Could not find method transitionToCommitted");
    ALOG_ASSERT(mJavaFrame->mLoadFinished, "Could not find method loadFinished");
    ALOG_ASSERT(mJavaFrame->mReportError, "Could not find method reportError");
    ALOG_ASSERT(mJavaFrame->mSetTitle, "Could not find method setTitle");
    ALOG_ASSERT(mJavaFrame->mWindowObjectCleared, "Could not find method windowObjectCleared");
    ALOG_ASSERT(mJavaFrame->mSetProgress, "Could not find method setProgress");
    ALOG_ASSERT(mJavaFrame->mDidReceiveIcon, "Could not find method didReceiveIcon");
    ALOG_ASSERT(mJavaFrame->mDidReceiveTouchIconUrl, "Could not find method didReceiveTouchIconUrl");
    ALOG_ASSERT(mJavaFrame->mUpdateVisitedHistory, "Could not find method updateVisitedHistory");
    ALOG_ASSERT(mJavaFrame->mHandleUrl, "Could not find method handleUrl");
    ALOG_ASSERT(mJavaFrame->mCreateWindow, "Could not find method createWindow");
    ALOG_ASSERT(mJavaFrame->mCloseWindow, "Could not find method closeWindow");
    ALOG_ASSERT(mJavaFrame->mDecidePolicyForFormResubmission, "Could not find method decidePolicyForFormResubmission");
    ALOG_ASSERT(mJavaFrame->mRequestFocus, "Could not find method requestFocus");
    ALOG_ASSERT(mJavaFrame->mGetRawResFilename, "Could not find method getRawResFilename");
    ALOG_ASSERT(mJavaFrame->mDensity, "Could not find method density");
    ALOG_ASSERT(mJavaFrame->mGetFileSize, "Could not find method getFileSize");
    ALOG_ASSERT(mJavaFrame->mGetFile, "Could not find method getFile");
    ALOG_ASSERT(mJavaFrame->mDidReceiveAuthenticationChallenge, "Could not find method didReceiveAuthenticationChallenge");
    ALOG_ASSERT(mJavaFrame->mReportSslCertError, "Could not find method reportSslCertError");
    ALOG_ASSERT(mJavaFrame->mRequestClientCert, "Could not find method requestClientCert");
    ALOG_ASSERT(mJavaFrame->mDownloadStart, "Could not find method downloadStart");
    ALOG_ASSERT(mJavaFrame->mDidReceiveData, "Could not find method didReceiveData");
    ALOG_ASSERT(mJavaFrame->mDidFinishLoading, "Could not find method didFinishLoading");
    ALOG_ASSERT(mJavaFrame->mSetCertificate, "Could not find method setCertificate");
    ALOG_ASSERT(mJavaFrame->mShouldSaveFormData, "Could not find method shouldSaveFormData");
    ALOG_ASSERT(mJavaFrame->mSaveFormData, "Could not find method saveFormData");
    ALOG_ASSERT(mJavaFrame->mAutoLogin, "Could not find method autoLogin");

    mUserAgent = WTF::String();
    mBlockNetworkLoads = false;
    m_renderSkins = 0;
}

WebFrame::~WebFrame()
{
    if (mJavaFrame->mObj) {
        JNIEnv* env = getJNIEnv();
        env->DeleteWeakGlobalRef(mJavaFrame->mObj);
        env->DeleteWeakGlobalRef(mJavaFrame->mHistoryList);
        mJavaFrame->mObj = 0;
    }
    delete mJavaFrame;
    delete m_renderSkins;
}

WebFrame* WebFrame::getWebFrame(const WebCore::Frame* frame)
{
    FrameLoaderClientAndroid* client =
            static_cast<FrameLoaderClientAndroid*> (frame->loader()->client());
    return client->webFrame();
}

static jobject createJavaMapFromHTTPHeaders(JNIEnv* env, const WebCore::HTTPHeaderMap& map)
{
    jclass mapClass = env->FindClass("java/util/HashMap");
    ALOG_ASSERT(mapClass, "Could not find HashMap class!");
    jmethodID init = env->GetMethodID(mapClass, "<init>", "(I)V");
    ALOG_ASSERT(init, "Could not find constructor for HashMap");
    jobject hashMap = env->NewObject(mapClass, init, map.size());
    ALOG_ASSERT(hashMap, "Could not create a new HashMap");
    jmethodID put = env->GetMethodID(mapClass, "put",
            "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
    ALOG_ASSERT(put, "Could not find put method on HashMap");

    WebCore::HTTPHeaderMap::const_iterator end = map.end();
    for (WebCore::HTTPHeaderMap::const_iterator i = map.begin(); i != end; ++i) {
        if (i->first.length() == 0 || i->second.length() == 0)
            continue;
        jstring key = wtfStringToJstring(env, i->first);
        jstring val = wtfStringToJstring(env, i->second);
        if (key && val) {
            env->CallObjectMethod(hashMap, put, key, val);
        }
        env->DeleteLocalRef(key);
        env->DeleteLocalRef(val);
    }

    env->DeleteLocalRef(mapClass);

    return hashMap;
}

// This class stores the URI and the size of each file for upload.  The URI is
// stored so we do not have to create it again.  The size is stored so we can
// compare the actual size of the file with the stated size.  If the actual size
// is larger, we will not copy it, since we will not have enough space in our
// buffer.
class FileInfo {
public:
    FileInfo(JNIEnv* env, const WTF::String& name) {
        m_uri = wtfStringToJstring(env, name);
        checkException(env);
        m_size = 0;
        m_env = env;
    }
    ~FileInfo() {
        m_env->DeleteLocalRef(m_uri);
    }
    int getSize() { return m_size; }
    jstring getUri() { return m_uri; }
    void setSize(int size) { m_size = size; }
private:
    // This is only a pointer to the JNIEnv* returned by
    // JSC::Bindings::getJNIEnv().  Used to delete the jstring when finished.
    JNIEnv* m_env;
    jstring m_uri;
    int m_size;
};

UrlInterceptResponse*
WebFrame::shouldInterceptRequest(const WTF::String& url)
{
    ALOGV("::WebCore:: shouldInterceptRequest(%s)", url.latin1().data());

    JNIEnv* env = getJNIEnv();
    AutoJObject javaFrame = mJavaFrame->frame(env);
    if (!javaFrame.get())
        return 0;

    jstring urlStr = wtfStringToJstring(env, url);
    jobject response = env->CallObjectMethod(javaFrame.get(), mJavaFrame->mShouldInterceptRequest, urlStr);
    env->DeleteLocalRef(urlStr);
    if (response == 0)
        return 0;
    UrlInterceptResponse* result = new UrlInterceptResponse(env, response);
    env->DeleteLocalRef(response);
    return result;
}

void
WebFrame::reportError(int errorCode, const WTF::String& description,
        const WTF::String& failingUrl)
{
    ALOGV("::WebCore:: reportError(%d, %s)", errorCode, description.ascii().data());
    JNIEnv* env = getJNIEnv();
    AutoJObject javaFrame = mJavaFrame->frame(env);
    if (!javaFrame.get())
        return;

    jstring descStr = wtfStringToJstring(env, description);
    jstring failUrl = wtfStringToJstring(env, failingUrl);
    env->CallVoidMethod(javaFrame.get(), mJavaFrame->mReportError, errorCode, descStr, failUrl);
    env->DeleteLocalRef(descStr);
    env->DeleteLocalRef(failUrl);
}

WTF::String
WebFrame::convertIDNToUnicode(const WebCore::KURL& url) {
    WTF::String converted = url.string();
    const WTF::String host = url.host();
    if (host.find("xn--") == notFound)  // no punycode IDN found.
        return converted;
    std::wstring languages;
    const WTF::CString cHost = host.utf8();
    std::wstring result = net::IDNToUnicode(cHost.data(), cHost.length(), languages, 0);
    const WTF::String convertedHost = String::fromUTF8(WideToUTF8(result).c_str());
    if (convertedHost.length() && convertedHost.length() != host.length()) {
        WebCore::KURL newUrl = url;
        newUrl.setHost(convertedHost);
        converted = newUrl.string();
    }
    return converted;
}

void
WebFrame::loadStarted(WebCore::Frame* frame)
{
    JNIEnv* env = getJNIEnv();
    AutoJObject javaFrame = mJavaFrame->frame(env);
    if (!javaFrame.get())
        return;

    // activeDocumentLoader() can return null.
    DocumentLoader* documentLoader = frame->loader()->activeDocumentLoader();
    if (documentLoader == NULL)
        return;

    const WebCore::KURL& url = documentLoader->url();
    if (url.isEmpty())
        return;
    ALOGV("::WebCore:: loadStarted %s", url.string().ascii().data());

    bool isMainFrame = (!frame->tree() || !frame->tree()->parent());
    WebCore::FrameLoadType loadType = frame->loader()->loadType();

    if (loadType == WebCore::FrameLoadTypeReplace ||
            (loadType == WebCore::FrameLoadTypeRedirectWithLockedBackForwardList &&
             !isMainFrame))
        return;

    const WTF::String urlString = convertIDNToUnicode(url);
    // If this is the main frame and we already have a favicon in the database,
    // send it along with the page started notification.
    jobject favicon = NULL;
    if (isMainFrame) {
        // FIXME: This method should not be used from outside WebCore and will be removed.
        // http://trac.webkit.org/changeset/81484
        WebCore::Image* icon = WebCore::iconDatabase().synchronousIconForPageURL(urlString, WebCore::IntSize(16, 16));
        if (icon)
            favicon = webcoreImageToJavaBitmap(env, icon);
        ALOGV("favicons", "Starting load with icon %p for %s", icon, url.string().utf8().data());
    }
    jstring urlStr = wtfStringToJstring(env, urlString);

    env->CallVoidMethod(javaFrame.get(), mJavaFrame->mLoadStarted, urlStr, favicon, static_cast<int>(loadType), isMainFrame);
    checkException(env);
    env->DeleteLocalRef(urlStr);
    if (favicon)
        env->DeleteLocalRef(favicon);

    // The main frame has started a new load.
    if (isMainFrame && mPage)
        WebViewCore::getWebViewCore(mPage->mainFrame()->view())->geolocationManager()->resetRealClientTemporaryPermissionStates();
}

void
WebFrame::transitionToCommitted(WebCore::Frame* frame)
{
    JNIEnv* env = getJNIEnv();
    AutoJObject javaFrame = mJavaFrame->frame(env);
    if (!javaFrame.get())
        return;

    WebCore::FrameLoadType loadType = frame->loader()->loadType();
    bool isMainFrame = (!frame->tree() || !frame->tree()->parent());
    env->CallVoidMethod(javaFrame.get(), mJavaFrame->mTransitionToCommitted, static_cast<int>(loadType), isMainFrame);
    checkException(env);
}

void
WebFrame::didFinishLoad(WebCore::Frame* frame)
{
    JNIEnv* env = getJNIEnv();
    AutoJObject javaFrame = mJavaFrame->frame(env);
    if (!javaFrame.get())
        return;

    // activeDocumentLoader() can return null.
    WebCore::FrameLoader* loader = frame->loader();
    DocumentLoader* documentLoader = loader->activeDocumentLoader();
    if (documentLoader == NULL)
      return;

    const WebCore::KURL& url = documentLoader->url();
    if (url.isEmpty())
        return;
    ALOGV("::WebCore:: didFinishLoad %s", url.string().ascii().data());

    bool isMainFrame = (!frame->tree() || !frame->tree()->parent());
    WebCore::FrameLoadType loadType = loader->loadType();
    const WTF::String urlString = convertIDNToUnicode(url);
    jstring urlStr = wtfStringToJstring(env, urlString);
    env->CallVoidMethod(javaFrame.get(), mJavaFrame->mLoadFinished, urlStr, static_cast<int>(loadType), isMainFrame);
    checkException(env);
    env->DeleteLocalRef(urlStr);
}

void
WebFrame::addHistoryItem(WebCore::HistoryItem* item)
{
    ALOGV("::WebCore:: addHistoryItem");
    JNIEnv* env = getJNIEnv();
    WebHistory::AddItem(mJavaFrame->history(env), item);
}

void
WebFrame::removeHistoryItem(int index)
{
    ALOGV("::WebCore:: removeHistoryItem at %d", index);
    JNIEnv* env = getJNIEnv();
    WebHistory::RemoveItem(mJavaFrame->history(env), index);
}

void
WebFrame::updateHistoryIndex(int newIndex)
{
    ALOGV("::WebCore:: updateHistoryIndex to %d", newIndex);
    JNIEnv* env = getJNIEnv();
    WebHistory::UpdateHistoryIndex(mJavaFrame->history(env), newIndex);
}

void
WebFrame::setTitle(const WTF::String& title)
{
#ifndef NDEBUG
    ALOGV("setTitle(%s)", title.ascii().data());
#endif
    JNIEnv* env = getJNIEnv();
    AutoJObject javaFrame = mJavaFrame->frame(env);
    if (!javaFrame.get())
        return;

    jstring jTitleStr = wtfStringToJstring(env, title);

    env->CallVoidMethod(javaFrame.get(), mJavaFrame->mSetTitle, jTitleStr);
    checkException(env);
    env->DeleteLocalRef(jTitleStr);
}

void
WebFrame::windowObjectCleared(WebCore::Frame* frame)
{
    ALOGV("::WebCore:: windowObjectCleared");
    JNIEnv* env = getJNIEnv();
    AutoJObject javaFrame = mJavaFrame->frame(env);
    if (!javaFrame.get())
        return;

    env->CallVoidMethod(javaFrame.get(), mJavaFrame->mWindowObjectCleared, (int)frame);
    checkException(env);
}

void
WebFrame::setProgress(float newProgress)
{
    JNIEnv* env = getJNIEnv();
    AutoJObject javaFrame = mJavaFrame->frame(env);
    if (!javaFrame.get())
        return;

    int progress = static_cast<int>(100 * newProgress);
    env->CallVoidMethod(javaFrame.get(), mJavaFrame->mSetProgress, progress);
    checkException(env);
}

const WTF::String
WebFrame::userAgentForURL(const WebCore::KURL* url)
{
    return mUserAgent;
}

void
WebFrame::didReceiveIcon(WebCore::Image* icon)
{
    ALOG_ASSERT(icon, "DidReceiveIcon called without an image!");
    JNIEnv* env = getJNIEnv();
    AutoJObject javaFrame = mJavaFrame->frame(env);
    if (!javaFrame.get())
        return;

    jobject bitmap = webcoreImageToJavaBitmap(env, icon);
    if (!bitmap)
        return;

    env->CallVoidMethod(javaFrame.get(), mJavaFrame->mDidReceiveIcon, bitmap);
    env->DeleteLocalRef(bitmap);
    checkException(env);
}

void
WebFrame::didReceiveTouchIconURL(const WTF::String& url, bool precomposed)
{
    JNIEnv* env = getJNIEnv();
    AutoJObject javaFrame = mJavaFrame->frame(env);
    if (!javaFrame.get())
        return;

    jstring jUrlStr = wtfStringToJstring(env, url);

    env->CallVoidMethod(javaFrame.get(), mJavaFrame->mDidReceiveTouchIconUrl, jUrlStr, precomposed);
    env->DeleteLocalRef(jUrlStr);
    checkException(env);
}

void
WebFrame::updateVisitedHistory(const WebCore::KURL& url, bool reload)
{
    JNIEnv* env = getJNIEnv();
    AutoJObject javaFrame = mJavaFrame->frame(env);
    if (!javaFrame.get())
        return;

    const WTF::String urlStr = convertIDNToUnicode(url);
    jstring jUrlStr = wtfStringToJstring(env, urlStr);

    env->CallVoidMethod(javaFrame.get(), mJavaFrame->mUpdateVisitedHistory, jUrlStr, reload);
    env->DeleteLocalRef(jUrlStr);
    checkException(env);
}

bool
WebFrame::canHandleRequest(const WebCore::ResourceRequest& request)
{
    JNIEnv* env = getJNIEnv();
    AutoJObject javaFrame = mJavaFrame->frame(env);
    if (!javaFrame.get())
        return true;

    // Always handle "POST" in place
    if (equalIgnoringCase(request.httpMethod(), "POST"))
        return true;
    const WebCore::KURL& requestUrl = request.url();
    const WTF::String& url = requestUrl.string();
    // Empty URLs should not be sent to Java
    if (url.isEmpty())
        return true;
    jstring jUrlStr = wtfStringToJstring(env, url);

    // Delegate to the Java side to make the decision. Note that the sense of
    // the return value of the Java method is reversed. It will return true if
    // the embedding application wishes to hijack the load and hence the WebView
    // should _not_ proceed with the load.
    jboolean ret = env->CallBooleanMethod(javaFrame.get(), mJavaFrame->mHandleUrl, jUrlStr);
    checkException(env);
    env->DeleteLocalRef(jUrlStr);
    return ret == JNI_FALSE;
}

bool
WebFrame::shouldSaveFormData()
{
    JNIEnv* env = getJNIEnv();
    AutoJObject javaFrame = mJavaFrame->frame(env);
    if (!javaFrame.get())
        return false;
    jboolean ret = env->CallBooleanMethod(javaFrame.get(), mJavaFrame->mShouldSaveFormData);
    checkException(env);
    return ret;
}

WebCore::Frame*
WebFrame::createWindow(bool dialog, bool userGesture)
{
    JNIEnv* env = getJNIEnv();
    AutoJObject javaFrame = mJavaFrame->frame(env);
    if (!javaFrame.get())
        return 0;
    jobject obj = env->CallObjectMethod(javaFrame.get(), mJavaFrame->mCreateWindow, dialog, userGesture);
    if (!obj)
        return 0;
    return GET_NATIVE_FRAME(env, obj);
}

void
WebFrame::requestFocus() const
{
    JNIEnv* env = getJNIEnv();
    AutoJObject javaFrame = mJavaFrame->frame(env);
    if (!javaFrame.get())
        return;
    env->CallVoidMethod(javaFrame.get(), mJavaFrame->mRequestFocus);
    checkException(env);
}

void
WebFrame::closeWindow(WebViewCore* webViewCore)
{
    assert(webViewCore);
    JNIEnv* env = getJNIEnv();
    AutoJObject javaFrame = mJavaFrame->frame(env);
    if (!javaFrame.get())
        return;
    AutoJObject javaObject = webViewCore->getJavaObject();
    if (!javaObject.get())
        return;
    env->CallVoidMethod(javaFrame.get(), mJavaFrame->mCloseWindow, javaObject.get());
}

struct PolicyFunctionWrapper {
    WebCore::FramePolicyFunction func;
};

void
WebFrame::decidePolicyForFormResubmission(WebCore::FramePolicyFunction func)
{
    JNIEnv* env = getJNIEnv();
    AutoJObject javaFrame = mJavaFrame->frame(env);
    if (!javaFrame.get())
        return;
    PolicyFunctionWrapper* p = new PolicyFunctionWrapper;
    p->func = func;
    env->CallVoidMethod(javaFrame.get(), mJavaFrame->mDecidePolicyForFormResubmission, p);
}

WTF::String
WebFrame::getRawResourceFilename(WebCore::PlatformBridge::rawResId id) const
{
    JNIEnv* env = getJNIEnv();
    AutoJObject javaFrame = mJavaFrame->frame(env);
    if (!javaFrame.get())
        return String();
    jstring ret = (jstring) env->CallObjectMethod(javaFrame.get(), mJavaFrame->mGetRawResFilename, static_cast<int>(id));

    return jstringToWtfString(env, ret);
}

float
WebFrame::density() const
{
    JNIEnv* env = getJNIEnv();
    AutoJObject javaFrame = mJavaFrame->frame(env);
    if (!javaFrame.get())
        return 0.0;
    jfloat dpi = env->CallFloatMethod(javaFrame.get(), mJavaFrame->mDensity);
    checkException(env);
    return dpi;
}

void
WebFrame::didReceiveAuthenticationChallenge(WebUrlLoaderClient* client, const std::string& host, const std::string& realm, bool useCachedCredentials, bool suppressDialog)
{
    JNIEnv* env = getJNIEnv();
    AutoJObject javaFrame = mJavaFrame->frame(env);
    if (!javaFrame.get())
        return;
    int jHandle = reinterpret_cast<int>(client);
    jstring jHost = stdStringToJstring(env, host, true);
    jstring jRealm = stdStringToJstring(env, realm, true);

    env->CallVoidMethod(javaFrame.get(), mJavaFrame->mDidReceiveAuthenticationChallenge, jHandle, jHost, jRealm, useCachedCredentials, suppressDialog);
    env->DeleteLocalRef(jHost);
    env->DeleteLocalRef(jRealm);
    checkException(env);
}

void
WebFrame::reportSslCertError(WebUrlLoaderClient* client, int error, const std::string& cert, const std::string& url)
{
    JNIEnv* env = getJNIEnv();
    AutoJObject javaFrame = mJavaFrame->frame(env);
    if (!javaFrame.get())
        return;
    int jHandle = reinterpret_cast<int>(client);

    // Don't copy the null terminator.
    int len = cert.length();
    ScopedLocalRef<jbyteArray> jCert(env, env->NewByteArray(len));
    env->SetByteArrayRegion(jCert.get(), 0, len, reinterpret_cast<const jbyte*>(cert.c_str()));

    ScopedLocalRef<jstring> jUrl(env, env->NewStringUTF(url.c_str()));

    env->CallVoidMethod(javaFrame.get(), mJavaFrame->mReportSslCertError, jHandle, error, jCert.get(), jUrl.get());
    checkException(env);
}

void
WebFrame::requestClientCert(WebUrlLoaderClient* client, const std::string& hostAndPort)
{
    JNIEnv* env = getJNIEnv();
    int jHandle = reinterpret_cast<int>(client);

    int len = hostAndPort.length();
    ScopedLocalRef<jstring> jHostAndPort(env, stdStringToJstring(env, hostAndPort, true));

    env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mRequestClientCert, jHandle, jHostAndPort.get());
    checkException(env);
}

void
WebFrame::downloadStart(const std::string& url, const std::string& userAgent, const std::string& contentDisposition, const std::string& mimetype, const std::string& referer, long long contentLength)
{
    JNIEnv* env = getJNIEnv();
    AutoJObject javaFrame = mJavaFrame->frame(env);
    if (!javaFrame.get())
        return;
    jstring jUrl = stdStringToJstring(env, url, true);
    jstring jUserAgent = stdStringToJstring(env, userAgent, true);
    jstring jContentDisposition = stdStringToJstring(env, contentDisposition, true);
    jstring jMimetype = stdStringToJstring(env, mimetype, true);
    jstring jReferer = stdStringToJstring(env, referer, true);

    env->CallVoidMethod(javaFrame.get(), mJavaFrame->mDownloadStart, jUrl, jUserAgent, jContentDisposition, jMimetype, jReferer, contentLength);

    env->DeleteLocalRef(jUrl);
    env->DeleteLocalRef(jUserAgent);
    env->DeleteLocalRef(jContentDisposition);
    env->DeleteLocalRef(jMimetype);
    env->DeleteLocalRef(jReferer);
    checkException(env);
}

void
WebFrame::didReceiveData(const char* data, int size) {
    JNIEnv* env = getJNIEnv();
    AutoJObject javaFrame = mJavaFrame->frame(env);
    if (!javaFrame.get())
        return;

    ScopedLocalRef<jbyteArray> jData(env, env->NewByteArray(size));
    env->SetByteArrayRegion(jData.get(), 0, size, reinterpret_cast<const jbyte*>(data));

    env->CallVoidMethod(javaFrame.get(), mJavaFrame->mDidReceiveData, jData.get(), size);
    checkException(env);
}

void
WebFrame::didFinishLoading() {
    JNIEnv* env = getJNIEnv();
    AutoJObject javaFrame = mJavaFrame->frame(env);
    if (!javaFrame.get())
        return;

    env->CallVoidMethod(javaFrame.get(), mJavaFrame->mDidFinishLoading);
    checkException(env);
}

void WebFrame::setCertificate(const std::string& cert)
{
    JNIEnv* env = getJNIEnv();
    AutoJObject javaFrame = mJavaFrame->frame(env);
    if (!javaFrame.get())
        return;

    int len = cert.length();
    ScopedLocalRef<jbyteArray> jCert(env, env->NewByteArray(len));
    env->SetByteArrayRegion(jCert.get(), 0, len, reinterpret_cast<const jbyte*>(cert.c_str()));

    env->CallVoidMethod(javaFrame.get(), mJavaFrame->mSetCertificate, jCert.get());

    checkException(env);
}

void WebFrame::autoLogin(const std::string& loginHeader)
{
    JNIEnv* env = getJNIEnv();
    AutoJObject javaFrame = mJavaFrame->frame(env);
    if (!javaFrame.get())
        return;

    WTF::String header(loginHeader.c_str(), loginHeader.length());
    WTF::Vector<WTF::String> split;
    header.split('&', split);
    if (!split.isEmpty()) {
        WTF::String realm;
        WTF::String account;
        WTF::String args;
        int len = split.size();
        while (len--) {
            WTF::String& str = split[len];
            size_t equals = str.find('=');
            if (equals == WTF::notFound)
                continue;

            WTF::String* result = 0;
            if (str.startsWith("realm", false))
                result = &realm;
            else if (str.startsWith("account", false))
                result = &account;
            else if (str.startsWith("args", false))
                result = &args;

            if (result)
                // Decode url escape sequences before sending to the app.
                *result = WebCore::decodeURLEscapeSequences(str.substring(equals + 1));
        }

        // realm and args are required parameters.
        if (realm.isEmpty() || args.isEmpty())
            return;

        jstring jRealm = wtfStringToJstring(env, realm, true);
        jstring jAccount = wtfStringToJstring(env, account);
        jstring jArgs = wtfStringToJstring(env, args, true);
        env->CallVoidMethod(javaFrame.get(), mJavaFrame->mAutoLogin, jRealm, jAccount, jArgs);
    }
}

void WebFrame::maybeSavePassword(WebCore::Frame* frame, const WebCore::ResourceRequest& request)
{
    JNIEnv* env = getJNIEnv();
    AutoJObject javaFrame = mJavaFrame->frame(env);
    if (!javaFrame.get())
        return;

    if (request.httpMethod() != "POST")
        return;

    WTF::String username;
    WTF::String password;
    if (!getUsernamePasswordFromDom(frame, username, password))
        return;

    jstring jUsername = wtfStringToJstring(env, username);
    jstring jPassword = wtfStringToJstring(env, password);
    jbyteArray jPostData = getPostData(request);
    if (jPostData)
        env->CallVoidMethod(javaFrame.get(), mJavaFrame->mMaybeSavePassword, jPostData, jUsername, jPassword);

    env->DeleteLocalRef(jPostData);
    env->DeleteLocalRef(jUsername);
    env->DeleteLocalRef(jPassword);
    checkException(env);
}

bool WebFrame::getUsernamePasswordFromDom(WebCore::Frame* frame, WTF::String& username, WTF::String& password)
{
    bool found = false;
    WTF::RefPtr<WebCore::HTMLCollection> form = frame->document()->forms();
    WebCore::Node* node = form->firstItem();
    while (node && !found && !node->namespaceURI().isNull() &&
           !node->namespaceURI().isEmpty()) {
        const WTF::Vector<WebCore::FormAssociatedElement*>& elements =
            ((WebCore::HTMLFormElement*)node)->associatedElements();
        size_t size = elements.size();
        for (size_t i = 0; i< size && !found; i++) {
            WebCore::HTMLElement* e = toHTMLElement(elements[i]);
            if (e->hasLocalName(WebCore::HTMLNames::inputTag)) {
                WebCore::HTMLInputElement* input = (WebCore::HTMLInputElement*)e;
                if (input->autoComplete() == false)
                    continue;
                if (input->isPasswordField())
                    password = input->value();
                else if (input->isTextField() || input->isEmailField())
                    username = input->value();
                if (!username.isNull() && !password.isNull())
                    found = true;
            }
        }
        node = form->nextItem();
    }
    return found;
}

jbyteArray WebFrame::getPostData(const WebCore::ResourceRequest& request)
{
    JNIEnv* env = getJNIEnv();
    AutoJObject javaFrame = mJavaFrame->frame(env);
    if (!javaFrame.get())
        return 0;

    jbyteArray jPostDataStr = 0;
    WebCore::FormData* formdata = request.httpBody();
    if (formdata) {
        // We can use the formdata->flatten() but it will result in two
        // memcpys, first through loading up the vector with the form data
        // then another to copy it out of the vector and into the java byte
        // array. Instead, we copy the form data ourselves below saving a
        // memcpy.
        const WTF::Vector<WebCore::FormDataElement>& elements =
                formdata->elements();

        // Sizing pass
        int size = 0;
        size_t n = elements.size();
        FileInfo** fileinfos = new FileInfo*[n];
        for (size_t i = 0; i < n; ++i) {
            fileinfos[i] = 0;
            const WebCore::FormDataElement& e = elements[i];
            if (e.m_type == WebCore::FormDataElement::data) {
                size += e.m_data.size();
            } else if (e.m_type == WebCore::FormDataElement::encodedFile) {
                fileinfos[i] = new FileInfo(env, e.m_filename);
                int delta = env->CallIntMethod(javaFrame.get(), mJavaFrame->mGetFileSize, fileinfos[i]->getUri());
                checkException(env);
                fileinfos[i]->setSize(delta);
                size += delta;
            }
        }

        // Only create the byte array if there is POST data to pass up.
        // The Java code is expecting null if there is no data.
        if (size > 0) {
            // Copy the actual form data.
            jPostDataStr = env->NewByteArray(size);
            if (jPostDataStr) {
                // Write  the form data to the java array.
                jbyte* bytes = env->GetByteArrayElements(jPostDataStr, NULL);
                int offset = 0;
                for (size_t i = 0; i < n; ++i) {
                    const WebCore::FormDataElement& e = elements[i];
                    if (e.m_type == WebCore::FormDataElement::data) {
                        int delta = e.m_data.size();
                        memcpy(bytes + offset, e.m_data.data(), delta);
                        offset += delta;
                    } else if (e.m_type == WebCore::FormDataElement::encodedFile) {
                        int delta = env->CallIntMethod(javaFrame.get(),
                                mJavaFrame->mGetFile, fileinfos[i]->getUri(),
                                jPostDataStr, offset, fileinfos[i]->getSize());
                        checkException(env);
                        offset += delta;
                    }
                }
                env->ReleaseByteArrayElements(jPostDataStr, bytes, 0);
            }
        }
        delete[] fileinfos;
    }
    return jPostDataStr;
}

// ----------------------------------------------------------------------------

static void CallPolicyFunction(JNIEnv* env, jobject obj, jint func, jint decision)
{
    WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
    ALOG_ASSERT(pFrame, "nativeCallPolicyFunction must take a valid frame pointer!");
    PolicyFunctionWrapper* pFunc = (PolicyFunctionWrapper*)func;
    ALOG_ASSERT(pFunc, "nativeCallPolicyFunction must take a valid function pointer!");

    // If we are resending the form then we should reset the multiple submission protection.
    if (decision == WebCore::PolicyUse)
        pFrame->loader()->resetMultipleFormSubmissionProtection();

    (pFrame->loader()->policyChecker()->*(pFunc->func))((WebCore::PolicyAction)decision);
}

static void CreateFrame(JNIEnv* env, jobject obj, jobject javaview, jobject jAssetManager, jobject historyList)
{
    ScriptController::initializeThreading();

    // needs to be called before any other chromium code
    initChromium();

    // Create a new page
    ChromeClientAndroid* chromeC = new ChromeClientAndroid;
    EditorClientAndroid* editorC = new EditorClientAndroid;
    DeviceMotionClientAndroid* deviceMotionC = new DeviceMotionClientAndroid;
    DeviceOrientationClientAndroid* deviceOrientationC = new DeviceOrientationClientAndroid;
    GeolocationClientAndroid* geolocationC = new GeolocationClientAndroid;

    WebCore::Page::PageClients pageClients;
    pageClients.chromeClient = chromeC;
    pageClients.contextMenuClient = new ContextMenuClientAndroid;
    pageClients.editorClient = editorC;
    pageClients.dragClient = new DragClientAndroid;
    pageClients.inspectorClient = new InspectorClientAndroid;
    pageClients.deviceMotionClient = deviceMotionC;
    pageClients.deviceOrientationClient = deviceOrientationC;
    pageClients.geolocationClient = geolocationC;
    WebCore::Page* page = new WebCore::Page(pageClients);

    editorC->setPage(page);
    page->setGroupName("android.webkit");

    // Create a WebFrame to access the Java BrowserFrame associated with this page
    WebFrame* webFrame = new WebFrame(env, obj, historyList, page);
    // Attach webFrame to pageClients.chromeClient and release our ownership
    chromeC->setWebFrame(webFrame);
    Release(webFrame);

    FrameLoaderClientAndroid* loaderC = new FrameLoaderClientAndroid(webFrame);
    // Create a Frame and the page holds its reference
    WebCore::Frame* frame = WebCore::Frame::create(page, NULL, loaderC).get();
    loaderC->setFrame(frame);
#if ENABLE(WDS)
    WDS::server()->addFrame(frame);
#endif

    // Create a WebViewCore to access the Java WebViewCore associated with this page
    WebViewCore* webViewCore = new WebViewCore(env, javaview, frame);

#if ENABLE(WEB_AUTOFILL)
    editorC->getAutofill()->setWebViewCore(webViewCore);
#endif

    // Create a FrameView
    RefPtr<WebCore::FrameView> frameView = WebCore::FrameView::create(frame);
    // Create a WebFrameView
    WebFrameView* webFrameView = new WebFrameView(frameView.get(), webViewCore);
    // As webFrameView Retains webViewCore, release our ownership
    Release(webViewCore);
    // As frameView Retains webFrameView, release our ownership
    Release(webFrameView);
    // Attach the frameView to the frame and release our ownership
    frame->setView(frameView);
    // Set the frame to active to turn on keyboard focus.
    frame->init();
    frame->selection()->setFocused(true);
    frame->page()->focusController()->setFocused(true);
    deviceMotionC->setWebViewCore(webViewCore);
    deviceOrientationC->setWebViewCore(webViewCore);
    geolocationC->setWebViewCore(webViewCore);

    // Allow local access to file:/// and substitute data
    WebCore::SecurityOrigin::setLocalLoadPolicy(
            WebCore::SecurityOrigin::AllowLocalLoadsForLocalAndSubstituteData);

    ALOGV("::WebCore:: createFrame %p", frame);

    // Set the mNativeFrame field in Frame
    SET_NATIVE_FRAME(env, obj, (int)frame);

    String directory = webFrame->getRawResourceFilename(
            WebCore::PlatformBridge::DrawableDir);
    if (directory.isEmpty())
        ALOGE("Can't find the drawable directory");
    else {
        // Initialize our skinning classes
        webFrame->setRenderSkins(new WebCore::RenderSkinAndroid(directory));
    }

    for (int i = WebCore::PlatformBridge::FileUploadLabel;
            i <= WebCore::PlatformBridge::FileUploadNoFileChosenLabel; i++)
        initGlobalLocalizedName(
                static_cast<WebCore::PlatformBridge::rawResId>(i), webFrame);
}

static void DestroyFrame(JNIEnv* env, jobject obj)
{
    WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
    ALOG_ASSERT(pFrame, "nativeDestroyFrame must take a valid frame pointer!");

    ALOGV("::WebCore:: deleting frame %p", pFrame);

    WebCore::FrameView* view = pFrame->view();
    view->ref();
    // detachFromParent will cause the page to be closed.
    WebCore::FrameLoader* fl = pFrame->loader();
    // retain a pointer because detachFromParent will set the page to null.
    WebCore::Page* page = pFrame->page();
    if (fl)
        fl->detachFromParent();
    delete page;

    // Force remove all deleted pages in the page cache
    WebCore::pageCache()->releaseAutoreleasedPagesNow();

    view->deref();

    SET_NATIVE_FRAME(env, obj, 0);
#if ENABLE(WDS)
    WDS::server()->removeFrame(pFrame);
#endif
}

static void LoadUrl(JNIEnv *env, jobject obj, jstring url, jobject headers)
{
    WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
    ALOG_ASSERT(pFrame, "nativeLoadUrl must take a valid frame pointer!");

    WTF::String webcoreUrl = jstringToWtfString(env, url);
    WebCore::KURL kurl(WebCore::KURL(), webcoreUrl);
    WebCore::ResourceRequest request(kurl);
    if (headers) {
        // dalvikvm will raise exception if any of these fail
        jclass mapClass = env->FindClass("java/util/Map");
        jmethodID entrySet = env->GetMethodID(mapClass, "entrySet",
                "()Ljava/util/Set;");
        jobject set = env->CallObjectMethod(headers, entrySet);

        jclass setClass = env->FindClass("java/util/Set");
        jmethodID iterator = env->GetMethodID(setClass, "iterator",
                "()Ljava/util/Iterator;");
        jobject iter = env->CallObjectMethod(set, iterator);

        jclass iteratorClass = env->FindClass("java/util/Iterator");
        jmethodID hasNext = env->GetMethodID(iteratorClass, "hasNext", "()Z");
        jmethodID next = env->GetMethodID(iteratorClass, "next",
                "()Ljava/lang/Object;");
        jclass entryClass = env->FindClass("java/util/Map$Entry");
        jmethodID getKey = env->GetMethodID(entryClass, "getKey",
                "()Ljava/lang/Object;");
        jmethodID getValue = env->GetMethodID(entryClass, "getValue",
                "()Ljava/lang/Object;");

        while (env->CallBooleanMethod(iter, hasNext)) {
            jobject entry = env->CallObjectMethod(iter, next);
            jstring key = (jstring) env->CallObjectMethod(entry, getKey);
            jstring value = (jstring) env->CallObjectMethod(entry, getValue);
            request.setHTTPHeaderField(jstringToWtfString(env, key), jstringToWtfString(env, value));
            env->DeleteLocalRef(entry);
            env->DeleteLocalRef(key);
            env->DeleteLocalRef(value);
        }

        env->DeleteLocalRef(entryClass);
        env->DeleteLocalRef(iteratorClass);
        env->DeleteLocalRef(iter);
        env->DeleteLocalRef(setClass);
        env->DeleteLocalRef(set);
        env->DeleteLocalRef(mapClass);
    }
    ALOGV("LoadUrl %s", kurl.string().latin1().data());
    pFrame->loader()->load(request, false);
}

static void PostUrl(JNIEnv *env, jobject obj, jstring url, jbyteArray postData)
{
    WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
    ALOG_ASSERT(pFrame, "nativePostUrl must take a valid frame pointer!");

    WebCore::KURL kurl(WebCore::KURL(), jstringToWtfString(env, url));
    WebCore::ResourceRequest request(kurl);
    request.setHTTPMethod("POST");
    request.setHTTPContentType("application/x-www-form-urlencoded");

    if (postData) {
        jsize size = env->GetArrayLength(postData);
        jbyte* bytes = env->GetByteArrayElements(postData, NULL);
        RefPtr<FormData> formData = FormData::create((const void*)bytes, size);
        // the identifier uses the same logic as generateFormDataIdentifier() in
        // HTMLFormElement.cpp
        formData->setIdentifier(static_cast<int64_t>(WTF::currentTime() * 1000000.0));
        request.setHTTPBody(formData);
        env->ReleaseByteArrayElements(postData, bytes, 0);
    }

    ALOGV("PostUrl %s", kurl.string().latin1().data());
    WebCore::FrameLoadRequest frameRequest(pFrame->document()->securityOrigin(), request);
    pFrame->loader()->loadFrameRequest(frameRequest, false, false, 0, 0, WebCore::SendReferrer);
}

static void LoadData(JNIEnv *env, jobject obj, jstring baseUrl, jstring data,
        jstring mimeType, jstring encoding, jstring failUrl)
{
    WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
    ALOG_ASSERT(pFrame, "nativeLoadData must take a valid frame pointer!");

    // Setup the resource request
    WebCore::ResourceRequest request(jstringToWtfString(env, baseUrl));

    // Setup the substituteData
    WTF::CString cData = jstringToWtfString(env, data).utf8();
    const char* dataStr = cData.data();
    WTF::RefPtr<WebCore::SharedBuffer> sharedBuffer =
        WebCore::SharedBuffer::create();
    ALOG_ASSERT(dataStr, "nativeLoadData has a null data string.");
    sharedBuffer->append(dataStr, strlen(dataStr)); // copy dataStr

    WebCore::SubstituteData substituteData(sharedBuffer,
            jstringToWtfString(env, mimeType), jstringToWtfString(env, encoding),
            WebCore::KURL(ParsedURLString, jstringToWtfString(env, failUrl)));

    // Perform the load
    pFrame->loader()->load(request, substituteData, false);
}

static void StopLoading(JNIEnv *env, jobject obj)
{
    WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
    ALOG_ASSERT(pFrame, "nativeStopLoading must take a valid frame pointer!");
    ALOGV("::WebCore:: stopLoading %p", pFrame);

    // Stop loading the page and do not send an unload event
    pFrame->loader()->stopForUserCancel();
}

#if ENABLE(WEB_ARCHIVE)
static String saveArchiveAutoname(String basename, String name, String extension) {
    if (name.isNull() || name.isEmpty()) {
        name = String("index");
    }

    String testname = basename;
    testname.append(name);
    testname.append(extension);

    errno = 0;
    struct stat permissions;
    if (stat(testname.utf8().data(), &permissions) < 0) {
        if (errno == ENOENT)
            return testname;
        return String();
    }

    const int maxAttempts = 100;
    for (int i = 1; i < maxAttempts; i++) {
        String testname = basename;
        testname.append(name);
        testname.append("-");
        testname.append(String::number(i));
        testname.append(extension);

        errno = 0;
        if (stat(testname.utf8().data(), &permissions) < 0) {
            if (errno == ENOENT)
                return testname;
            return String();
        }
    }

    return String();
}
#endif // ENABLE(WEB_ARCHIVE)

static jstring SaveWebArchive(JNIEnv *env, jobject obj, jstring basename, jboolean autoname)
{
#if ENABLE(WEB_ARCHIVE)
    WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
    ALOG_ASSERT(pFrame, "nativeSaveWebArchive must take a valid frame pointer!");
    String mimeType = pFrame->loader()->documentLoader()->mainResource()->mimeType();
    if ((mimeType != "text/html") && (mimeType != "application/xhtml+xml"))
        return NULL;

    const char* basenameNative = getCharactersFromJStringInEnv(env, basename);
    String basenameString = String::fromUTF8(basenameNative);
    String filename;

    if (autoname) {
        String name = pFrame->loader()->documentLoader()->originalURL().lastPathComponent();
        String extension = String(".webarchivexml");
        filename = saveArchiveAutoname(basenameString, name, extension);
    } else {
        filename = basenameString;
    }

    if (filename.isNull() || filename.isEmpty()) {
        ALOGD("saveWebArchive: Failed to select a filename to save.");
        releaseCharactersForJStringInEnv(env, basename, basenameNative);
        return NULL;
    }

    const int noCompression = 0;
    xmlTextWriterPtr writer = xmlNewTextWriterFilename(filename.utf8().data(), noCompression);
    if (writer == NULL) {
        ALOGD("saveWebArchive: Failed to initialize xml writer.");
        releaseCharactersForJStringInEnv(env, basename, basenameNative);
        return NULL;
    }

    RefPtr<WebArchiveAndroid> archive = WebCore::WebArchiveAndroid::create(pFrame);

    bool result = archive->saveWebArchive(writer);

    releaseCharactersForJStringInEnv(env, basename, basenameNative);
    xmlFreeTextWriter(writer);

    if (result)
        return wtfStringToJstring(env, filename);
#endif // ENABLE(WEB_ARCHIVE)

    return NULL;
}

static jstring ExternalRepresentation(JNIEnv *env, jobject obj)
{
    WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
    ALOG_ASSERT(pFrame, "android_webcore_nativeExternalRepresentation must take a valid frame pointer!");

    // Request external representation of the render tree
    WTF::String renderDump = WebCore::externalRepresentation(pFrame);
    return wtfStringToJstring(env, renderDump);
}

static StringBuilder FrameAsText(WebCore::Frame *pFrame, jboolean dumpChildFrames) {
    StringBuilder renderDump;
    if (!pFrame)
        return renderDump;
    WebCore::Element *documentElement = pFrame->document()->documentElement();
    if (!documentElement)
        return renderDump;
    if (pFrame->tree()->parent()) {
        renderDump.append("\n--------\nFrame: '");
        renderDump.append(pFrame->tree()->name());
        renderDump.append("'\n--------\n");
    }
    renderDump.append(((WebCore::HTMLElement*)documentElement)->innerText());
    renderDump.append("\n");
    if (dumpChildFrames) {
        for (unsigned i = 0; i < pFrame->tree()->childCount(); ++i) {
            renderDump.append(FrameAsText(pFrame->tree()->child(i), dumpChildFrames).toString());
        }
    }
    return renderDump;
}

static jstring DocumentAsText(JNIEnv *env, jobject obj)
{
    WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
    ALOG_ASSERT(pFrame, "android_webcore_nativeDocumentAsText must take a valid frame pointer!");

    WTF::String renderDump = FrameAsText(pFrame, false /* dumpChildFrames */).toString();
    return wtfStringToJstring(env, renderDump);
}

static jstring ChildFramesAsText(JNIEnv *env, jobject obj)
{
    WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
    ALOG_ASSERT(pFrame, "android_webcore_nativeDocumentAsText must take a valid frame pointer!");

    StringBuilder renderDumpBuilder;
    for (unsigned i = 0; i < pFrame->tree()->childCount(); ++i) {
        renderDumpBuilder.append(FrameAsText(pFrame->tree()->child(i), true /* dumpChildFrames */).toString());
    }
    WTF::String renderDump = renderDumpBuilder.toString();
    return wtfStringToJstring(env, renderDump);
}

static void Reload(JNIEnv *env, jobject obj, jboolean allowStale)
{
    WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
    ALOG_ASSERT(pFrame, "nativeReload must take a valid frame pointer!");

    WebCore::FrameLoader* loader = pFrame->loader();
    if (allowStale) {
        // load the current page with FrameLoadTypeIndexedBackForward so that it
        // will use cache when it is possible
        WebCore::Page* page = pFrame->page();
        WebCore::HistoryItem* item = page->backForwardList()->currentItem();
        if (item)
            page->goToItem(item, FrameLoadTypeIndexedBackForward);
    } else
        loader->reload(true);
}

static void GoBackOrForward(JNIEnv *env, jobject obj, jint pos)
{
    WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
    ALOG_ASSERT(pFrame, "nativeGoBackOrForward must take a valid frame pointer!");

    if (pos == 1)
        pFrame->page()->goForward();
    else if (pos == -1)
        pFrame->page()->goBack();
    else
        pFrame->page()->goBackOrForward(pos);
}

static jobject StringByEvaluatingJavaScriptFromString(JNIEnv *env, jobject obj, jstring script)
{
    WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
    ALOG_ASSERT(pFrame, "stringByEvaluatingJavaScriptFromString must take a valid frame pointer!");

    WebCore::ScriptValue value =
            pFrame->script()->executeScript(jstringToWtfString(env, script), true);
    WTF::String result = WTF::String();
    ScriptState* scriptState = mainWorldScriptState(pFrame);
    if (!value.getString(scriptState, result))
        return NULL;
    return wtfStringToJstring(env, result);
}

// Wrap the JavaInstance used when binding custom javascript interfaces. Use a
// weak reference so that the gc can collect the WebView. Override virtualBegin
// and virtualEnd and swap the weak reference for the real object.
class WeakJavaInstance : public JavaInstanceJobject {
public:
    static PassRefPtr<WeakJavaInstance> create(jobject obj, bool requireAnnotation)
    {
        return adoptRef(new WeakJavaInstance(obj, requireAnnotation));
    }

private:
    WeakJavaInstance(jobject instance, bool requireAnnotation)
        : JavaInstanceJobject(instance, requireAnnotation)
        , m_beginEndDepth(0)
    {
        JNIEnv* env = getJNIEnv();
        // JavaInstance creates a global ref to instance in its constructor.
        env->DeleteGlobalRef(m_instance->instance());
        // Create a weak ref, cache it, and set the underlying JavaInstance to use it.
        m_weakRef = env->NewWeakGlobalRef(instance);
        m_instance->setInstance(m_weakRef);
    }
    ~WeakJavaInstance()
    {
        ALOG_ASSERT(!m_beginEndDepth, "Unbalanced calls to WeakJavaInstance::begin() / end()");
        JNIEnv* env = getJNIEnv();
        // The JavaInstance destructor attempts to delete the global ref stored
        // in m_instance. Since we replaced it in our constructor with a weak
        // reference, restore the global ref here so the vm will not complain.
        m_instance->setInstance(env->NewGlobalRef(m_weakRef));
        // Delete the weak reference.
        env->DeleteWeakGlobalRef(m_weakRef);
    }

    virtual void begin()
    {
        if (m_beginEndDepth++ > 0)
            return;
        JNIEnv* env = getJNIEnv();
        // This is odd. getRealObject returns an AutoJObject which is used to
        // cleanly create and delete a local reference. But, here we need to
        // maintain the local reference across calls to virtualBegin() and
        // virtualEnd(). So, release the local reference from the AutoJObject
        // and delete the local reference in virtualEnd().
        m_instance->setInstance(getRealObject(env, m_weakRef).release());
        // Call the base class method
        INHERITED::begin();
    }

    virtual void end()
    {
        if (--m_beginEndDepth > 0)
            return;
        // Call the base class method first to pop the local frame.
        INHERITED::end();
        // Get rid of the local reference to the real object.
        getJNIEnv()->DeleteLocalRef(m_instance->instance());
        // Point back to the WeakReference.
        m_instance->setInstance(m_weakRef);
    }

private:
    typedef JavaInstanceJobject INHERITED;
    jweak m_weakRef;
    // The current depth of nested calls to virtualBegin and virtualEnd.
    int m_beginEndDepth;
};

static void AddJavascriptInterface(JNIEnv *env, jobject obj, jint nativeFramePointer,
        jobject javascriptObj, jstring interfaceName, jboolean requireAnnotation)
{
    WebCore::Frame* pFrame = 0;
    if (nativeFramePointer == 0)
        pFrame = GET_NATIVE_FRAME(env, obj);
    else
        pFrame = (WebCore::Frame*)nativeFramePointer;
    ALOG_ASSERT(pFrame, "nativeAddJavascriptInterface must take a valid frame pointer!");

    JavaVM* vm;
    env->GetJavaVM(&vm);
    ALOGV("::WebCore:: addJSInterface: %p", pFrame);

    if (pFrame) {
        RefPtr<JavaInstance> addedObject = WeakJavaInstance::create(javascriptObj,
                requireAnnotation);
        const char* name = getCharactersFromJStringInEnv(env, interfaceName);
        // Pass ownership of the added object to bindToWindowObject.
        NPObject* npObject = JavaInstanceToNPObject(addedObject.get());
        pFrame->script()->bindToWindowObject(pFrame, name, npObject);
        // bindToWindowObject calls NPN_RetainObject on the
        // returned one (see createV8ObjectForNPObject in V8NPObject.cpp).
        // bindToWindowObject also increases obj's ref count and decreases
        // the ref count when the object is not reachable from JavaScript
        // side. Code here must release the reference count increased by
        // bindToWindowObject.

        // Note that while this function is declared in WebCore/bridge/npruntime.h, for V8 builds
        // we use WebCore/bindings/v8/npruntime.cpp (rather than
        // WebCore/bridge/npruntime.cpp), so the function is implemented there.
        // TODO: Combine the two versions of these NPAPI files.
        NPN_ReleaseObject(npObject);
        releaseCharactersForJString(interfaceName, name);
    }
}

static void ClearWebCoreCache()
{
    if (!WebCore::memoryCache()->disabled()) {
        // Disabling the cache will remove all resources from the cache.  They may
        // still live on if they are referenced by some Web page though.
        WebCore::memoryCache()->setDisabled(true);
        WebCore::memoryCache()->setDisabled(false);
    }

    // clear page cache
    int pageCapacity = WebCore::pageCache()->capacity();
    // Setting size to 0, makes all pages be released.
    WebCore::pageCache()->setCapacity(0);
    WebCore::pageCache()->releaseAutoreleasedPagesNow();
    WebCore::pageCache()->setCapacity(pageCapacity);
}

static void ClearWebViewCache()
{
    WebCache::get(false /*privateBrowsing*/)->clear();
}

static void ClearCache(JNIEnv *env, jobject obj)
{
    ClearWebCoreCache();
    ClearWebViewCache();
    WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
    pFrame->script()->lowMemoryNotification();
}

static jboolean DocumentHasImages(JNIEnv *env, jobject obj)
{
    WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
    ALOG_ASSERT(pFrame, "DocumentHasImages must take a valid frame pointer!");

    return pFrame->document()->images()->length() > 0;
}

static jboolean HasPasswordField(JNIEnv *env, jobject obj)
{
    WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
    ALOG_ASSERT(pFrame, "HasPasswordField must take a valid frame pointer!");

    bool found = false;
    WTF::RefPtr<WebCore::HTMLCollection> form = pFrame->document()->forms();
    WebCore::Node* node = form->firstItem();
    // Null/Empty namespace means that node is not created in HTMLFormElement
    // class, but just normal Element class.
    while (node && !found && !node->namespaceURI().isNull() &&
           !node->namespaceURI().isEmpty()) {
        const WTF::Vector<WebCore::FormAssociatedElement*>& elements =
            ((WebCore::HTMLFormElement*)node)->associatedElements();
        size_t size = elements.size();
        for (size_t i = 0; i< size && !found; i++) {
            WebCore::HTMLElement* e = toHTMLElement(elements[i]);
            if (e->hasLocalName(WebCore::HTMLNames::inputTag)) {
                if (static_cast<WebCore::HTMLInputElement*>(e)->isPasswordField())
                    found = true;
            }
        }
        node = form->nextItem();
    }
    return found;
}

static jobjectArray GetUsernamePassword(JNIEnv *env, jobject obj)
{
    WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
    ALOG_ASSERT(pFrame, "GetUsernamePassword must take a valid frame pointer!");
    jobjectArray strArray = NULL;
    WTF::String username;
    WTF::String password;
    if (WebFrame::getWebFrame(pFrame)->getUsernamePasswordFromDom(pFrame, username, password)) {
        jclass stringClass = env->FindClass("java/lang/String");
        strArray = env->NewObjectArray(2, stringClass, NULL);
        env->DeleteLocalRef(stringClass);
        env->SetObjectArrayElement(strArray, 0, wtfStringToJstring(env, username));
        env->SetObjectArrayElement(strArray, 1, wtfStringToJstring(env, password));
    }
    return strArray;
}

static void SetUsernamePassword(JNIEnv *env, jobject obj,
    jstring username, jstring password)
{
    WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
    ALOG_ASSERT(pFrame, "SetUsernamePassword must take a valid frame pointer!");

    WebCore::HTMLInputElement* usernameEle = NULL;
    WebCore::HTMLInputElement* passwordEle = NULL;
    bool found = false;
    WTF::RefPtr<WebCore::HTMLCollection> form = pFrame->document()->forms();
    WebCore::Node* node = form->firstItem();
    while (node && !found && !node->namespaceURI().isNull() &&
           !node->namespaceURI().isEmpty()) {
        const WTF::Vector<WebCore::FormAssociatedElement*>& elements =
            ((WebCore::HTMLFormElement*)node)->associatedElements();
        size_t size = elements.size();
        for (size_t i = 0; i< size && !found; i++) {
            WebCore::HTMLElement* e = toHTMLElement(elements[i]);
            if (e->hasLocalName(WebCore::HTMLNames::inputTag)) {
                WebCore::HTMLInputElement* input = (WebCore::HTMLInputElement*)e;
                if (input->autoComplete() == false)
                    continue;
                if (input->isPasswordField())
                    passwordEle = input;
                else if (input->isTextField() || input->isEmailField())
                    usernameEle = input;
                if (usernameEle != NULL && passwordEle != NULL)
                    found = true;
            }
        }
        node = form->nextItem();
    }
    if (found) {
        usernameEle->setValue(jstringToWtfString(env, username));
        passwordEle->setValue(jstringToWtfString(env, password));
    }
}

void
WebFrame::saveFormData(HTMLFormElement* form)
{
    JNIEnv* env = getJNIEnv();
    AutoJObject javaFrame = mJavaFrame->frame(env);
    if (!javaFrame.get())
        return;

    if (form->autoComplete()) {
        JNIEnv* env = getJNIEnv();
        jclass mapClass = env->FindClass("java/util/HashMap");
        ALOG_ASSERT(mapClass, "Could not find HashMap class!");
        jmethodID init = env->GetMethodID(mapClass, "<init>", "(I)V");
        ALOG_ASSERT(init, "Could not find constructor for HashMap");
        jobject hashMap = env->NewObject(mapClass, init, 1);
        ALOG_ASSERT(hashMap, "Could not create a new HashMap");
        jmethodID put = env->GetMethodID(mapClass, "put",
                "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
        ALOG_ASSERT(put, "Could not find put method on HashMap");
        WTF::Vector<WebCore::FormAssociatedElement*> elements = form->associatedElements();
        size_t size = elements.size();
        for (size_t i = 0; i < size; i++) {
            WebCore::HTMLElement* e = toHTMLElement(elements[i]);
            if (e->hasTagName(WebCore::HTMLNames::inputTag)) {
                WebCore::HTMLInputElement* input = static_cast<WebCore::HTMLInputElement*>(e);
                if (input->isTextField() && !input->isPasswordField()
                        && input->autoComplete()) {
                    WTF::String value = input->value();
                    int len = value.length();
                    if (len) {
                        const WTF::AtomicString& name = input->name();
                        jstring key = wtfStringToJstring(env, name);
                        jstring val = wtfStringToJstring(env, value);
                        ALOG_ASSERT(key && val, "name or value not set");
                        env->CallObjectMethod(hashMap, put, key, val);
                        env->DeleteLocalRef(key);
                        env->DeleteLocalRef(val);
                    }
                }
            }
        }
        env->CallVoidMethod(javaFrame.get(), mJavaFrame->mSaveFormData, hashMap);
        env->DeleteLocalRef(hashMap);
        env->DeleteLocalRef(mapClass);
    }
}

static void OrientationChanged(JNIEnv *env, jobject obj, int orientation)
{
    WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
    ALOGV("Sending orientation: %d", orientation);
    pFrame->sendOrientationChangeEvent(orientation);
}

static jboolean GetShouldStartScrolledRight(JNIEnv *env, jobject obj,
        jint browserFrame)
{
    jboolean startScrolledRight = false; // default is start scrolled left
    WebCore::Frame* frame = reinterpret_cast<WebCore::Frame*>(browserFrame);
    WebCore::Document* document = frame->document();
    if (document) {
        RenderStyle* style = document->renderer()->style();
        WritingMode writingMode = style->writingMode();
        ALOG_ASSERT(writingMode != WebCore::BottomToTopWritingMode,
                "BottomToTopWritingMode isn't possible in any "
                "language and cannot be specified in w3c writing-mode.");
        if (writingMode == WebCore::RightToLeftWritingMode)
            startScrolledRight = true; // vertical-rl pages start scrolled right
        else if (writingMode == WebCore::TopToBottomWritingMode)
            startScrolledRight = !style->isLeftToRightDirection(); // RTL starts right
    }
    return startScrolledRight;
}

static void AuthenticationProceed(JNIEnv *env, jobject obj, int handle, jstring jUsername, jstring jPassword)
{
    WebUrlLoaderClient* client = reinterpret_cast<WebUrlLoaderClient*>(handle);
    std::string username = jstringToStdString(env, jUsername);
    std::string password = jstringToStdString(env, jPassword);
    client->setAuth(username, password);
}

static void AuthenticationCancel(JNIEnv *env, jobject obj, int handle)
{
    WebUrlLoaderClient* client = reinterpret_cast<WebUrlLoaderClient*>(handle);
    client->cancelAuth();
}

static void SslCertErrorProceed(JNIEnv *env, jobject obj, int handle)
{
    WebUrlLoaderClient* client = reinterpret_cast<WebUrlLoaderClient*>(handle);
    client->proceedSslCertError();
}

static void SslCertErrorCancel(JNIEnv *env, jobject obj, int handle, int cert_error)
{
    WebUrlLoaderClient* client = reinterpret_cast<WebUrlLoaderClient*>(handle);
    client->cancelSslCertError(cert_error);
}

static scoped_refptr<net::X509Certificate> getX509Cert(JNIEnv *env, jobjectArray chain)
{
    // Based on Android's NativeCrypto_SSL_use_certificate
    int length = env->GetArrayLength(chain);
    if (length == 0) {
        return NULL;
    }

    base::ScopedOpenSSL<X509, X509_free> first;
    ScopedVector<base::ScopedOpenSSL<X509, X509_free> > rest;
    for (int i = 0; i < length; i++) {
        ScopedLocalRef<jbyteArray> cert(env,
                reinterpret_cast<jbyteArray>(env->GetObjectArrayElement(chain, i)));
        if (cert.get() == NULL) {
            return NULL;
        }
        ScopedByteArrayRO certBytes(env, cert.get());
        if (certBytes.get() == NULL) {
            return NULL;
        }
        const char* data = reinterpret_cast<const char*>(certBytes.get());
        int length = certBytes.size();
        X509* x509 = net::X509Certificate::CreateOSCertHandleFromBytes(data, length);
        if (x509 == NULL) {
            return NULL;
        }
        if (i == 0) {
            first.reset(x509);
        } else {
            rest.push_back(new base::ScopedOpenSSL<X509, X509_free>(x509));
        }
    }

    std::vector<X509*> certChain(rest.size());
    for (size_t i = 0; i < rest.size(); i++) {
        certChain[i] = rest[i]->get();
    }
    return net::X509Certificate::CreateFromHandle(first.get(),
                                                  net::X509Certificate::SOURCE_FROM_NETWORK,
                                                  certChain);
}

static void SslClientCertPKCS8(JNIEnv *env, jobject obj, int handle, jbyteArray pkey, jobjectArray chain)
{
    WebUrlLoaderClient* client = reinterpret_cast<WebUrlLoaderClient*>(handle);
    if (pkey == NULL || chain == NULL) {
        client->sslClientCert(NULL, NULL);
        return;
    }

    // Based on Android's NativeCrypto_SSL_use_PrivateKey
    ScopedByteArrayRO pkeyBytes(env, pkey);
    if (pkeyBytes.get() == NULL) {
        client->sslClientCert(NULL, NULL);
        return;
    }

    base::ScopedOpenSSL<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free> pkcs8;
    const unsigned char* pkeyChars = reinterpret_cast<const unsigned char*>(pkeyBytes.get());
    pkcs8.reset(d2i_PKCS8_PRIV_KEY_INFO(NULL, &pkeyChars, pkeyBytes.size()));
    if (!pkcs8.get()) {
        client->sslClientCert(NULL, NULL);
        return;
    }
    base::ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free> privateKey(EVP_PKCS82PKEY(pkcs8.get()));
    if (!privateKey.get()) {
        client->sslClientCert(NULL, NULL);
        return;
    }
    scoped_refptr<net::X509Certificate> certificate = getX509Cert(env, chain);
    if (certificate == NULL) {
        client->sslClientCert(NULL, NULL);
        return;
    }
    client->sslClientCert(privateKey.release(), certificate);
}

static void SslClientCertCtx(JNIEnv *env, jobject obj, int handle, jint ctx, jobjectArray chain)
{
    WebUrlLoaderClient* client = reinterpret_cast<WebUrlLoaderClient*>(handle);
    EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(static_cast<uintptr_t>(ctx));
    if (pkey == NULL || chain == NULL) {
        client->sslClientCert(NULL, NULL);
        return;
    }
    scoped_refptr<net::X509Certificate> certificate = getX509Cert(env, chain);
    if (certificate == NULL) {
        client->sslClientCert(NULL, NULL);
        return;
    }
    CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
    client->sslClientCert(pkey, certificate);
}

// ----------------------------------------------------------------------------

/*
 * JNI registration.
 */
static JNINativeMethod gBrowserFrameNativeMethods[] = {
    /* name, signature, funcPtr */
    { "nativeCallPolicyFunction", "(II)V",
        (void*) CallPolicyFunction },
    { "nativeCreateFrame", "(Landroid/webkit/WebViewCore;Landroid/content/res/AssetManager;Landroid/webkit/WebBackForwardList;)V",
        (void*) CreateFrame },
    { "nativeDestroyFrame", "()V",
        (void*) DestroyFrame },
    { "nativeStopLoading", "()V",
        (void*) StopLoading },
    { "nativeLoadUrl", "(Ljava/lang/String;Ljava/util/Map;)V",
        (void*) LoadUrl },
    { "nativePostUrl", "(Ljava/lang/String;[B)V",
        (void*) PostUrl },
    { "nativeLoadData", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
        (void*) LoadData },
    { "nativeSaveWebArchive", "(Ljava/lang/String;Z)Ljava/lang/String;",
        (void*) SaveWebArchive },
    { "externalRepresentation", "()Ljava/lang/String;",
        (void*) ExternalRepresentation },
    { "documentAsText", "()Ljava/lang/String;",
        (void*) DocumentAsText },
    { "childFramesAsText", "()Ljava/lang/String;",
        (void*) ChildFramesAsText },
    { "reload", "(Z)V",
        (void*) Reload },
    { "nativeGoBackOrForward", "(I)V",
        (void*) GoBackOrForward },
    { "nativeAddJavascriptInterface", "(ILjava/lang/Object;Ljava/lang/String;Z)V",
        (void*) AddJavascriptInterface },
    { "stringByEvaluatingJavaScriptFromString",
            "(Ljava/lang/String;)Ljava/lang/String;",
        (void*) StringByEvaluatingJavaScriptFromString },
    { "clearCache", "()V",
        (void*) ClearCache },
    { "documentHasImages", "()Z",
        (void*) DocumentHasImages },
    { "hasPasswordField", "()Z",
        (void*) HasPasswordField },
    { "getUsernamePassword", "()[Ljava/lang/String;",
        (void*) GetUsernamePassword },
    { "setUsernamePassword", "(Ljava/lang/String;Ljava/lang/String;)V",
        (void*) SetUsernamePassword },
    { "nativeOrientationChanged", "(I)V",
        (void*) OrientationChanged },
    { "nativeAuthenticationProceed", "(ILjava/lang/String;Ljava/lang/String;)V",
        (void*) AuthenticationProceed },
    { "nativeAuthenticationCancel", "(I)V",
        (void*) AuthenticationCancel },
    { "nativeSslCertErrorProceed", "(I)V",
        (void*) SslCertErrorProceed },
    { "nativeSslCertErrorCancel", "(II)V",
        (void*) SslCertErrorCancel },
    { "nativeSslClientCert", "(II[[B)V",
        (void*) SslClientCertCtx },
    { "nativeSslClientCert", "(I[B[[B)V",
        (void*) SslClientCertPKCS8 },
    { "nativeGetShouldStartScrolledRight", "(I)Z",
        (void*) GetShouldStartScrolledRight },
};

int registerWebFrame(JNIEnv* env)
{
    JavaClassJobject::RegisterJavaClassJobject(env);

    jclass clazz = env->FindClass("android/webkit/BrowserFrame");
    ALOG_ASSERT(clazz, "Cannot find BrowserFrame");
    gFrameField = env->GetFieldID(clazz, "mNativeFrame", "I");
    ALOG_ASSERT(gFrameField, "Cannot find mNativeFrame on BrowserFrame");
    env->DeleteLocalRef(clazz);

    return jniRegisterNativeMethods(env, "android/webkit/BrowserFrame",
            gBrowserFrameNativeMethods, NELEM(gBrowserFrameNativeMethods));
}

} /* namespace android */
