/*
 * 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;
#if ENABLE(INSPECTOR)
    pageClients.inspectorClient = new InspectorClientAndroid;
#endif
    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, jlong 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", "(IJ[[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 */
