2 * Copyright 2006, The Android Open Source Project
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #define LOG_TAG "webcoreglue"
29 #include "WebCoreFrameBridge.h"
32 #include "BackForwardList.h"
33 #include "MemoryCache.h"
35 #include "ChromeClientAndroid.h"
36 #include "ChromiumInit.h"
37 #include "ContextMenuClientAndroid.h"
38 #include "DeviceMotionClientAndroid.h"
39 #include "DeviceOrientationClientAndroid.h"
41 #include "DocumentLoader.h"
42 #include "DragClientAndroid.h"
43 #include "EditorClientAndroid.h"
45 #include "FocusController.h"
48 #include "FrameLoader.h"
49 #include "FrameLoaderClientAndroid.h"
50 #include "FrameLoadRequest.h"
51 #include "FrameTree.h"
52 #include "FrameView.h"
53 #include "GraphicsContext.h"
54 #include "HistoryItem.h"
55 #include "HTMLCollection.h"
56 #include "HTMLElement.h"
57 #include "HTMLFormElement.h"
58 #include "HTMLInputElement.h"
59 #include "HTMLNames.h"
60 #include "IconDatabase.h"
62 #include "InspectorClientAndroid.h"
65 #include "PageCache.h"
66 #include "PlatformString.h"
67 #include "RenderPart.h"
68 #include "RenderSkinAndroid.h"
69 #include "RenderTreeAsText.h"
70 #include "RenderView.h"
71 #include "ResourceHandle.h"
72 #include "ResourceHandleInternal.h"
73 #include "ScriptController.h"
74 #include "ScriptValue.h"
75 #include "SecurityOrigin.h"
76 #include "SelectionController.h"
78 #include "SubstituteData.h"
79 #include "UrlInterceptResponse.h"
80 #include "UserGestureIndicator.h"
82 #include "WebCoreJni.h"
83 #include "WebCoreResourceLoader.h"
84 #include "WebHistory.h"
85 #include "WebIconDatabase.h"
86 #include "WebFrameView.h"
87 #include "WebUrlLoaderClient.h"
88 #include "WebViewCore.h"
89 #include "android_graphics.h"
91 #include "wds/DebugServer.h"
93 #include <JNIUtility.h>
95 #include <SkGraphics.h>
96 #include <android_runtime/android_util_AssetManager.h>
97 #include <utils/misc.h>
98 #include <utils/AssetManager.h>
99 #include <wtf/CurrentTime.h>
100 #include <wtf/Platform.h>
101 #include <wtf/text/AtomicString.h>
102 #include <wtf/text/CString.h>
103 #include <wtf/text/StringBuilder.h>
106 #include "GCController.h"
107 #include "JSDOMWindow.h"
108 #include "JavaInstanceJSC.h"
109 #include <runtime_object.h>
110 #include <runtime_root.h>
111 #include <runtime/JSLock.h>
113 #include "JavaNPObjectV8.h"
114 #include "JavaInstanceV8.h"
115 #include "V8Counters.h"
118 #ifdef ANDROID_INSTRUMENT
119 #include "TimeCounter.h"
123 #include "WebArchiveAndroid.h"
126 #if ENABLE(WEB_AUTOFILL)
127 #include "autofill/WebAutoFill.h"
130 using namespace JSC::Bindings;
132 static String* gUploadFileLabel;
133 static String* gResetLabel;
134 static String* gSubmitLabel;
135 static String* gNoFileChosenLabel;
137 String* WebCore::PlatformBridge::globalLocalizedName(
138 WebCore::PlatformBridge::rawResId resId)
141 case WebCore::PlatformBridge::FileUploadLabel:
142 return gUploadFileLabel;
143 case WebCore::PlatformBridge::ResetLabel:
145 case WebCore::PlatformBridge::SubmitLabel:
147 case WebCore::PlatformBridge::FileUploadNoFileChosenLabel:
148 return gNoFileChosenLabel;
155 * Instantiate the localized name desired.
157 void initGlobalLocalizedName(WebCore::PlatformBridge::rawResId resId,
158 android::WebFrame* webFrame)
162 case WebCore::PlatformBridge::FileUploadLabel:
163 pointer = &gUploadFileLabel;
165 case WebCore::PlatformBridge::ResetLabel:
166 pointer = &gResetLabel;
168 case WebCore::PlatformBridge::SubmitLabel:
169 pointer = &gSubmitLabel;
171 case WebCore::PlatformBridge::FileUploadNoFileChosenLabel:
172 pointer = &gNoFileChosenLabel;
177 if (!(*pointer) && webFrame) {
178 (*pointer) = new String(webFrame->getRawResourceFilename(resId).impl());
184 // ----------------------------------------------------------------------------
186 #define WEBCORE_MEMORY_CAP 15 * 1024 * 1024
188 // ----------------------------------------------------------------------------
190 struct WebFrame::JavaBrowserFrame
193 jweak mHistoryList; // WebBackForwardList object
194 jmethodID mStartLoadingResource;
195 jmethodID mMaybeSavePassword;
196 jmethodID mShouldInterceptRequest;
197 jmethodID mLoadStarted;
198 jmethodID mTransitionToCommitted;
199 jmethodID mLoadFinished;
200 jmethodID mReportError;
202 jmethodID mWindowObjectCleared;
203 jmethodID mSetProgress;
204 jmethodID mDidReceiveIcon;
205 jmethodID mDidReceiveTouchIconUrl;
206 jmethodID mUpdateVisitedHistory;
207 jmethodID mHandleUrl;
208 jmethodID mCreateWindow;
209 jmethodID mCloseWindow;
210 jmethodID mDecidePolicyForFormResubmission;
211 jmethodID mRequestFocus;
212 jmethodID mGetRawResFilename;
214 jmethodID mGetFileSize;
216 jmethodID mDidReceiveAuthenticationChallenge;
217 jmethodID mReportSslCertError;
218 jmethodID mDownloadStart;
219 jmethodID mDidReceiveData;
220 jmethodID mDidFinishLoading;
221 jmethodID mSetCertificate;
222 jmethodID mShouldSaveFormData;
223 jmethodID mSaveFormData;
224 jmethodID mAutoLogin;
225 AutoJObject frame(JNIEnv* env) {
226 return getRealObject(env, mObj);
228 AutoJObject history(JNIEnv* env) {
229 return getRealObject(env, mHistoryList);
233 static jfieldID gFrameField;
234 #define GET_NATIVE_FRAME(env, obj) ((WebCore::Frame*)env->GetIntField(obj, gFrameField))
235 #define SET_NATIVE_FRAME(env, obj, frame) (env->SetIntField(obj, gFrameField, frame))
237 // ----------------------------------------------------------------------------
239 WebFrame::WebFrame(JNIEnv* env, jobject obj, jobject historyList, WebCore::Page* page)
242 jclass clazz = env->GetObjectClass(obj);
243 mJavaFrame = new JavaBrowserFrame;
244 mJavaFrame->mObj = env->NewWeakGlobalRef(obj);
245 mJavaFrame->mHistoryList = env->NewWeakGlobalRef(historyList);
246 mJavaFrame->mStartLoadingResource = env->GetMethodID(clazz, "startLoadingResource",
247 "(ILjava/lang/String;Ljava/lang/String;Ljava/util/HashMap;[BJIZZZLjava/lang/String;Ljava/lang/String;)Landroid/webkit/LoadListener;");
248 mJavaFrame->mMaybeSavePassword = env->GetMethodID(clazz, "maybeSavePassword",
249 "([BLjava/lang/String;Ljava/lang/String;)V");
250 mJavaFrame->mShouldInterceptRequest =
251 env->GetMethodID(clazz, "shouldInterceptRequest",
252 "(Ljava/lang/String;)Landroid/webkit/WebResourceResponse;");
253 mJavaFrame->mLoadStarted = env->GetMethodID(clazz, "loadStarted",
254 "(Ljava/lang/String;Landroid/graphics/Bitmap;IZ)V");
255 mJavaFrame->mTransitionToCommitted = env->GetMethodID(clazz, "transitionToCommitted",
257 mJavaFrame->mLoadFinished = env->GetMethodID(clazz, "loadFinished",
258 "(Ljava/lang/String;IZ)V");
259 mJavaFrame->mReportError = env->GetMethodID(clazz, "reportError",
260 "(ILjava/lang/String;Ljava/lang/String;)V");
261 mJavaFrame->mSetTitle = env->GetMethodID(clazz, "setTitle",
262 "(Ljava/lang/String;)V");
263 mJavaFrame->mWindowObjectCleared = env->GetMethodID(clazz, "windowObjectCleared",
265 mJavaFrame->mSetProgress = env->GetMethodID(clazz, "setProgress",
267 mJavaFrame->mDidReceiveIcon = env->GetMethodID(clazz, "didReceiveIcon",
268 "(Landroid/graphics/Bitmap;)V");
269 mJavaFrame->mDidReceiveTouchIconUrl = env->GetMethodID(clazz, "didReceiveTouchIconUrl",
270 "(Ljava/lang/String;Z)V");
271 mJavaFrame->mUpdateVisitedHistory = env->GetMethodID(clazz, "updateVisitedHistory",
272 "(Ljava/lang/String;Z)V");
273 mJavaFrame->mHandleUrl = env->GetMethodID(clazz, "handleUrl",
274 "(Ljava/lang/String;)Z");
275 mJavaFrame->mCreateWindow = env->GetMethodID(clazz, "createWindow",
276 "(ZZ)Landroid/webkit/BrowserFrame;");
277 mJavaFrame->mCloseWindow = env->GetMethodID(clazz, "closeWindow",
278 "(Landroid/webkit/WebViewCore;)V");
279 mJavaFrame->mDecidePolicyForFormResubmission = env->GetMethodID(clazz,
280 "decidePolicyForFormResubmission", "(I)V");
281 mJavaFrame->mRequestFocus = env->GetMethodID(clazz, "requestFocus",
283 mJavaFrame->mGetRawResFilename = env->GetMethodID(clazz, "getRawResFilename",
284 "(I)Ljava/lang/String;");
285 mJavaFrame->mDensity = env->GetMethodID(clazz, "density","()F");
286 mJavaFrame->mGetFileSize = env->GetMethodID(clazz, "getFileSize", "(Ljava/lang/String;)I");
287 mJavaFrame->mGetFile = env->GetMethodID(clazz, "getFile", "(Ljava/lang/String;[BII)I");
288 mJavaFrame->mDidReceiveAuthenticationChallenge = env->GetMethodID(clazz, "didReceiveAuthenticationChallenge",
289 "(ILjava/lang/String;Ljava/lang/String;Z)V");
290 mJavaFrame->mReportSslCertError = env->GetMethodID(clazz, "reportSslCertError", "(II[B)V");
291 mJavaFrame->mDownloadStart = env->GetMethodID(clazz, "downloadStart",
292 "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;J)V");
293 mJavaFrame->mDidReceiveData = env->GetMethodID(clazz, "didReceiveData", "([BI)V");
294 mJavaFrame->mDidFinishLoading = env->GetMethodID(clazz, "didFinishLoading", "()V");
295 mJavaFrame->mSetCertificate = env->GetMethodID(clazz, "setCertificate", "([B)V");
296 mJavaFrame->mShouldSaveFormData = env->GetMethodID(clazz, "shouldSaveFormData", "()Z");
297 mJavaFrame->mSaveFormData = env->GetMethodID(clazz, "saveFormData", "(Ljava/util/HashMap;)V");
298 mJavaFrame->mAutoLogin = env->GetMethodID(clazz, "autoLogin",
299 "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
300 env->DeleteLocalRef(clazz);
302 LOG_ASSERT(mJavaFrame->mStartLoadingResource, "Could not find method startLoadingResource");
303 LOG_ASSERT(mJavaFrame->mMaybeSavePassword, "Could not find method maybeSavePassword");
304 LOG_ASSERT(mJavaFrame->mShouldInterceptRequest, "Could not find method shouldInterceptRequest");
305 LOG_ASSERT(mJavaFrame->mLoadStarted, "Could not find method loadStarted");
306 LOG_ASSERT(mJavaFrame->mTransitionToCommitted, "Could not find method transitionToCommitted");
307 LOG_ASSERT(mJavaFrame->mLoadFinished, "Could not find method loadFinished");
308 LOG_ASSERT(mJavaFrame->mReportError, "Could not find method reportError");
309 LOG_ASSERT(mJavaFrame->mSetTitle, "Could not find method setTitle");
310 LOG_ASSERT(mJavaFrame->mWindowObjectCleared, "Could not find method windowObjectCleared");
311 LOG_ASSERT(mJavaFrame->mSetProgress, "Could not find method setProgress");
312 LOG_ASSERT(mJavaFrame->mDidReceiveIcon, "Could not find method didReceiveIcon");
313 LOG_ASSERT(mJavaFrame->mDidReceiveTouchIconUrl, "Could not find method didReceiveTouchIconUrl");
314 LOG_ASSERT(mJavaFrame->mUpdateVisitedHistory, "Could not find method updateVisitedHistory");
315 LOG_ASSERT(mJavaFrame->mHandleUrl, "Could not find method handleUrl");
316 LOG_ASSERT(mJavaFrame->mCreateWindow, "Could not find method createWindow");
317 LOG_ASSERT(mJavaFrame->mCloseWindow, "Could not find method closeWindow");
318 LOG_ASSERT(mJavaFrame->mDecidePolicyForFormResubmission, "Could not find method decidePolicyForFormResubmission");
319 LOG_ASSERT(mJavaFrame->mRequestFocus, "Could not find method requestFocus");
320 LOG_ASSERT(mJavaFrame->mGetRawResFilename, "Could not find method getRawResFilename");
321 LOG_ASSERT(mJavaFrame->mDensity, "Could not find method density");
322 LOG_ASSERT(mJavaFrame->mGetFileSize, "Could not find method getFileSize");
323 LOG_ASSERT(mJavaFrame->mGetFile, "Could not find method getFile");
324 LOG_ASSERT(mJavaFrame->mDidReceiveAuthenticationChallenge, "Could not find method didReceiveAuthenticationChallenge");
325 LOG_ASSERT(mJavaFrame->mReportSslCertError, "Could not find method reportSslCertError");
326 LOG_ASSERT(mJavaFrame->mDownloadStart, "Could not find method downloadStart");
327 LOG_ASSERT(mJavaFrame->mDidReceiveData, "Could not find method didReceiveData");
328 LOG_ASSERT(mJavaFrame->mDidFinishLoading, "Could not find method didFinishLoading");
329 LOG_ASSERT(mJavaFrame->mSetCertificate, "Could not find method setCertificate");
330 LOG_ASSERT(mJavaFrame->mShouldSaveFormData, "Could not find method shouldSaveFormData");
331 LOG_ASSERT(mJavaFrame->mSaveFormData, "Could not find method saveFormData");
332 LOG_ASSERT(mJavaFrame->mAutoLogin, "Could not find method autoLogin");
334 mUserAgent = WTF::String();
335 mUserInitiatedAction = false;
336 mBlockNetworkLoads = false;
340 WebFrame::~WebFrame()
342 if (mJavaFrame->mObj) {
343 JNIEnv* env = getJNIEnv();
344 env->DeleteWeakGlobalRef(mJavaFrame->mObj);
345 env->DeleteWeakGlobalRef(mJavaFrame->mHistoryList);
346 mJavaFrame->mObj = 0;
349 delete m_renderSkins;
352 WebFrame* WebFrame::getWebFrame(const WebCore::Frame* frame)
354 FrameLoaderClientAndroid* client =
355 static_cast<FrameLoaderClientAndroid*> (frame->loader()->client());
356 return client->webFrame();
359 static jobject createJavaMapFromHTTPHeaders(JNIEnv* env, const WebCore::HTTPHeaderMap& map)
361 jclass mapClass = env->FindClass("java/util/HashMap");
362 LOG_ASSERT(mapClass, "Could not find HashMap class!");
363 jmethodID init = env->GetMethodID(mapClass, "<init>", "(I)V");
364 LOG_ASSERT(init, "Could not find constructor for HashMap");
365 jobject hashMap = env->NewObject(mapClass, init, map.size());
366 LOG_ASSERT(hashMap, "Could not create a new HashMap");
367 jmethodID put = env->GetMethodID(mapClass, "put",
368 "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
369 LOG_ASSERT(put, "Could not find put method on HashMap");
371 WebCore::HTTPHeaderMap::const_iterator end = map.end();
372 for (WebCore::HTTPHeaderMap::const_iterator i = map.begin(); i != end; ++i) {
373 if (i->first.length() == 0 || i->second.length() == 0)
375 jstring key = wtfStringToJstring(env, i->first);
376 jstring val = wtfStringToJstring(env, i->second);
378 env->CallObjectMethod(hashMap, put, key, val);
380 env->DeleteLocalRef(key);
381 env->DeleteLocalRef(val);
384 env->DeleteLocalRef(mapClass);
389 // This class stores the URI and the size of each file for upload. The URI is
390 // stored so we do not have to create it again. The size is stored so we can
391 // compare the actual size of the file with the stated size. If the actual size
392 // is larger, we will not copy it, since we will not have enough space in our
396 FileInfo(JNIEnv* env, const WTF::String& name) {
397 m_uri = wtfStringToJstring(env, name);
403 m_env->DeleteLocalRef(m_uri);
405 int getSize() { return m_size; }
406 jstring getUri() { return m_uri; }
407 void setSize(int size) { m_size = size; }
409 // This is only a pointer to the JNIEnv* returned by
410 // JSC::Bindings::getJNIEnv(). Used to delete the jstring when finished.
416 PassRefPtr<WebCore::ResourceLoaderAndroid>
417 WebFrame::startLoadingResource(WebCore::ResourceHandle* loader,
418 const WebCore::ResourceRequest& request,
422 #ifdef ANDROID_INSTRUMENT
423 TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
425 LOGV("::WebCore:: startLoadingResource(%p, %s)",
426 loader, request.url().string().latin1().data());
428 WTF::String method = request.httpMethod();
429 WebCore::HTTPHeaderMap headers = request.httpHeaderFields();
431 JNIEnv* env = getJNIEnv();
432 WTF::String urlStr = request.url().string();
433 int colon = urlStr.find(':');
434 bool allLower = true;
435 for (int index = 0; index < colon; index++) {
436 UChar ch = urlStr[index];
437 if (!WTF::isASCIIAlpha(ch))
439 allLower &= WTF::isASCIILower(ch);
440 if (index == colon - 1 && !allLower) {
441 urlStr = urlStr.substring(0, colon).lower()
442 + urlStr.substring(colon);
445 LOGV("%s lower=%s", __FUNCTION__, urlStr.latin1().data());
446 jstring jUrlStr = wtfStringToJstring(env, urlStr);
447 jstring jMethodStr = NULL;
448 if (!method.isEmpty())
449 jMethodStr = wtfStringToJstring(env, method);
450 WebCore::FormData* formdata = request.httpBody();
451 jbyteArray jPostDataStr = getPostData(request);
452 jobject jHeaderMap = createJavaMapFromHTTPHeaders(env, headers);
454 // Convert the WebCore Cache Policy to a WebView Cache Policy.
455 int cacheMode = 0; // WebSettings.LOAD_NORMAL
456 switch (request.cachePolicy()) {
457 case WebCore::ReloadIgnoringCacheData:
458 cacheMode = 2; // WebSettings.LOAD_NO_CACHE
460 case WebCore::ReturnCacheDataDontLoad:
461 cacheMode = 3; // WebSettings.LOAD_CACHE_ONLY
463 case WebCore::ReturnCacheDataElseLoad:
464 cacheMode = 1; // WebSettings.LOAD_CACHE_ELSE_NETWORK
466 case WebCore::UseProtocolCachePolicy:
471 LOGV("::WebCore:: startLoadingResource %s with cacheMode %d", urlStr.ascii().data(), cacheMode);
473 ResourceHandleInternal* loaderInternal = loader->getInternal();
474 jstring jUsernameString = loaderInternal->m_user.isEmpty() ?
475 NULL : wtfStringToJstring(env, loaderInternal->m_user);
476 jstring jPasswordString = loaderInternal->m_pass.isEmpty() ?
477 NULL : wtfStringToJstring(env, loaderInternal->m_pass);
479 bool isUserGesture = UserGestureIndicator::processingUserGesture();
480 jobject jLoadListener =
481 env->CallObjectMethod(mJavaFrame->frame(env).get(), mJavaFrame->mStartLoadingResource,
482 (int)loader, jUrlStr, jMethodStr, jHeaderMap,
483 jPostDataStr, formdata ? formdata->identifier(): 0,
484 cacheMode, mainResource, isUserGesture,
485 synchronous, jUsernameString, jPasswordString);
487 env->DeleteLocalRef(jUrlStr);
488 env->DeleteLocalRef(jMethodStr);
489 env->DeleteLocalRef(jPostDataStr);
490 env->DeleteLocalRef(jHeaderMap);
491 env->DeleteLocalRef(jUsernameString);
492 env->DeleteLocalRef(jPasswordString);
493 if (checkException(env))
496 PassRefPtr<WebCore::ResourceLoaderAndroid> h;
498 h = WebCoreResourceLoader::create(env, jLoadListener);
499 env->DeleteLocalRef(jLoadListener);
503 UrlInterceptResponse*
504 WebFrame::shouldInterceptRequest(const WTF::String& url)
506 #ifdef ANDROID_INSTRUMENT
507 TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
509 LOGV("::WebCore:: shouldInterceptRequest(%s)", url.latin1().data());
511 JNIEnv* env = getJNIEnv();
512 jstring urlStr = wtfStringToJstring(env, url);
513 jobject response = env->CallObjectMethod(mJavaFrame->frame(env).get(), mJavaFrame->mShouldInterceptRequest, urlStr);
514 env->DeleteLocalRef(urlStr);
517 return new UrlInterceptResponse(env, response);
521 WebFrame::reportError(int errorCode, const WTF::String& description,
522 const WTF::String& failingUrl)
524 #ifdef ANDROID_INSTRUMENT
525 TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
527 LOGV("::WebCore:: reportError(%d, %s)", errorCode, description.ascii().data());
528 JNIEnv* env = getJNIEnv();
530 jstring descStr = wtfStringToJstring(env, description);
531 jstring failUrl = wtfStringToJstring(env, failingUrl);
532 env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mReportError,
533 errorCode, descStr, failUrl);
534 env->DeleteLocalRef(descStr);
535 env->DeleteLocalRef(failUrl);
539 WebFrame::loadStarted(WebCore::Frame* frame)
541 #ifdef ANDROID_INSTRUMENT
542 TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
544 // activeDocumentLoader() can return null.
545 DocumentLoader* documentLoader = frame->loader()->activeDocumentLoader();
546 if (documentLoader == NULL)
549 const WebCore::KURL& url = documentLoader->url();
552 LOGV("::WebCore:: loadStarted %s", url.string().ascii().data());
554 bool isMainFrame = (!frame->tree() || !frame->tree()->parent());
555 WebCore::FrameLoadType loadType = frame->loader()->loadType();
557 if (loadType == WebCore::FrameLoadTypeReplace ||
558 (loadType == WebCore::FrameLoadTypeRedirectWithLockedBackForwardList &&
562 JNIEnv* env = getJNIEnv();
563 const WTF::String& urlString = url.string();
564 // If this is the main frame and we already have a favicon in the database,
565 // send it along with the page started notification.
566 jobject favicon = NULL;
568 WebCore::Image* icon = WebCore::iconDatabase()->iconForPageURL(urlString, WebCore::IntSize(16, 16));
570 favicon = webcoreImageToJavaBitmap(env, icon);
571 LOGV("favicons", "Starting load with icon %p for %s", icon, url.string().utf8().data());
573 jstring urlStr = wtfStringToJstring(env, urlString);
575 env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mLoadStarted, urlStr, favicon,
576 (int)loadType, isMainFrame);
578 env->DeleteLocalRef(urlStr);
580 env->DeleteLocalRef(favicon);
582 // Inform the client that the main frame has started a new load.
583 if (isMainFrame && mPage) {
584 Chrome* chrome = mPage->chrome();
586 ChromeClientAndroid* client = static_cast<ChromeClientAndroid*>(chrome->client());
588 client->onMainFrameLoadStarted();
594 WebFrame::transitionToCommitted(WebCore::Frame* frame)
596 #ifdef ANDROID_INSTRUMENT
597 TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
599 JNIEnv* env = getJNIEnv();
600 WebCore::FrameLoadType loadType = frame->loader()->loadType();
601 bool isMainFrame = (!frame->tree() || !frame->tree()->parent());
602 env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mTransitionToCommitted,
603 (int)loadType, isMainFrame);
608 WebFrame::didFinishLoad(WebCore::Frame* frame)
610 #ifdef ANDROID_INSTRUMENT
611 TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
613 JNIEnv* env = getJNIEnv();
615 // activeDocumentLoader() can return null.
616 WebCore::FrameLoader* loader = frame->loader();
617 DocumentLoader* documentLoader = loader->activeDocumentLoader();
618 if (documentLoader == NULL)
621 const WebCore::KURL& url = documentLoader->url();
624 LOGV("::WebCore:: didFinishLoad %s", url.string().ascii().data());
626 bool isMainFrame = (!frame->tree() || !frame->tree()->parent());
627 WebCore::FrameLoadType loadType = loader->loadType();
628 const WTF::String& urlString = url.string();
629 jstring urlStr = wtfStringToJstring(env, urlString);
630 env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mLoadFinished, urlStr,
631 (int)loadType, isMainFrame);
633 env->DeleteLocalRef(urlStr);
637 WebFrame::addHistoryItem(WebCore::HistoryItem* item)
639 #ifdef ANDROID_INSTRUMENT
640 TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
642 LOGV("::WebCore:: addHistoryItem");
643 JNIEnv* env = getJNIEnv();
644 WebHistory::AddItem(mJavaFrame->history(env), item);
648 WebFrame::removeHistoryItem(int index)
650 #ifdef ANDROID_INSTRUMENT
651 TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
653 LOGV("::WebCore:: removeHistoryItem at %d", index);
654 JNIEnv* env = getJNIEnv();
655 WebHistory::RemoveItem(mJavaFrame->history(env), index);
659 WebFrame::updateHistoryIndex(int newIndex)
661 #ifdef ANDROID_INSTRUMENT
662 TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
664 LOGV("::WebCore:: updateHistoryIndex to %d", newIndex);
665 JNIEnv* env = getJNIEnv();
666 WebHistory::UpdateHistoryIndex(mJavaFrame->history(env), newIndex);
670 WebFrame::setTitle(const WTF::String& title)
672 #ifdef ANDROID_INSTRUMENT
673 TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
676 LOGV("setTitle(%s)", title.ascii().data());
678 JNIEnv* env = getJNIEnv();
679 jstring jTitleStr = wtfStringToJstring(env, title);
681 env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mSetTitle, jTitleStr);
683 env->DeleteLocalRef(jTitleStr);
687 WebFrame::windowObjectCleared(WebCore::Frame* frame)
689 #ifdef ANDROID_INSTRUMENT
690 TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
692 LOGV("::WebCore:: windowObjectCleared");
693 JNIEnv* env = getJNIEnv();
695 env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mWindowObjectCleared, (int)frame);
700 WebFrame::setProgress(float newProgress)
702 #ifdef ANDROID_INSTRUMENT
703 TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
705 JNIEnv* env = getJNIEnv();
706 int progress = (int) (100 * newProgress);
707 env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mSetProgress, progress);
712 WebFrame::userAgentForURL(const WebCore::KURL* url)
718 WebFrame::didReceiveIcon(WebCore::Image* icon)
720 #ifdef ANDROID_INSTRUMENT
721 TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
723 LOG_ASSERT(icon, "DidReceiveIcon called without an image!");
724 JNIEnv* env = getJNIEnv();
725 jobject bitmap = webcoreImageToJavaBitmap(env, icon);
729 env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mDidReceiveIcon, bitmap);
730 env->DeleteLocalRef(bitmap);
735 WebFrame::didReceiveTouchIconURL(const WTF::String& url, bool precomposed)
737 #ifdef ANDROID_INSTRUMENT
738 TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
740 JNIEnv* env = getJNIEnv();
741 jstring jUrlStr = wtfStringToJstring(env, url);
743 env->CallVoidMethod(mJavaFrame->frame(env).get(),
744 mJavaFrame->mDidReceiveTouchIconUrl, jUrlStr, precomposed);
745 env->DeleteLocalRef(jUrlStr);
750 WebFrame::updateVisitedHistory(const WebCore::KURL& url, bool reload)
752 #ifdef ANDROID_INSTRUMENT
753 TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
755 const WTF::String& urlStr = url.string();
756 JNIEnv* env = getJNIEnv();
757 jstring jUrlStr = wtfStringToJstring(env, urlStr);
759 env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mUpdateVisitedHistory, jUrlStr, reload);
760 env->DeleteLocalRef(jUrlStr);
765 WebFrame::canHandleRequest(const WebCore::ResourceRequest& request)
767 #ifdef ANDROID_INSTRUMENT
768 TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
770 // always handle "POST" in place
771 if (equalIgnoringCase(request.httpMethod(), "POST"))
773 const WebCore::KURL& requestUrl = request.url();
774 bool isUserGesture = UserGestureIndicator::processingUserGesture();
775 if (!mUserInitiatedAction && !isUserGesture &&
776 (requestUrl.protocolIs("http") || requestUrl.protocolIs("https") ||
777 requestUrl.protocolIs("file") || requestUrl.protocolIs("about") ||
778 WebCore::protocolIsJavaScript(requestUrl.string())))
780 const WTF::String& url = requestUrl.string();
781 // Empty urls should not be sent to java
784 JNIEnv* env = getJNIEnv();
785 jstring jUrlStr = wtfStringToJstring(env, url);
787 // check to see whether browser app wants to hijack url loading.
788 // if browser app handles the url, we will return false to bail out WebCore loading
789 jboolean ret = env->CallBooleanMethod(mJavaFrame->frame(env).get(), mJavaFrame->mHandleUrl, jUrlStr);
791 env->DeleteLocalRef(jUrlStr);
796 WebFrame::shouldSaveFormData()
798 JNIEnv* env = getJNIEnv();
799 jboolean ret = env->CallBooleanMethod(mJavaFrame->frame(env).get(),
800 mJavaFrame->mShouldSaveFormData);
806 WebFrame::createWindow(bool dialog, bool userGesture)
808 #ifdef ANDROID_INSTRUMENT
809 TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
811 JNIEnv* env = getJNIEnv();
812 jobject obj = env->CallObjectMethod(mJavaFrame->frame(env).get(),
813 mJavaFrame->mCreateWindow, dialog, userGesture);
815 WebCore::Frame* frame = GET_NATIVE_FRAME(env, obj);
822 WebFrame::requestFocus() const
824 #ifdef ANDROID_INSTRUMENT
825 TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
827 JNIEnv* env = getJNIEnv();
828 env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mRequestFocus);
833 WebFrame::closeWindow(WebViewCore* webViewCore)
835 #ifdef ANDROID_INSTRUMENT
836 TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
839 JNIEnv* env = getJNIEnv();
840 env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mCloseWindow,
841 webViewCore->getJavaObject().get());
844 struct PolicyFunctionWrapper {
845 WebCore::FramePolicyFunction func;
849 WebFrame::decidePolicyForFormResubmission(WebCore::FramePolicyFunction func)
851 #ifdef ANDROID_INSTRUMENT
852 TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
854 JNIEnv* env = getJNIEnv();
855 PolicyFunctionWrapper* p = new PolicyFunctionWrapper;
857 env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mDecidePolicyForFormResubmission, p);
861 WebFrame::getRawResourceFilename(WebCore::PlatformBridge::rawResId id) const
863 JNIEnv* env = getJNIEnv();
864 jstring ret = (jstring) env->CallObjectMethod(mJavaFrame->frame(env).get(),
865 mJavaFrame->mGetRawResFilename, (int)id);
867 return jstringToWtfString(env, ret);
871 WebFrame::density() const
873 JNIEnv* env = getJNIEnv();
874 jfloat dpi = env->CallFloatMethod(mJavaFrame->frame(env).get(), mJavaFrame->mDensity);
879 #if USE(CHROME_NETWORK_STACK)
881 WebFrame::didReceiveAuthenticationChallenge(WebUrlLoaderClient* client, const std::string& host, const std::string& realm, bool useCachedCredentials)
883 #ifdef ANDROID_INSTRUMENT
884 TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
886 JNIEnv* env = getJNIEnv();
887 int jHandle = reinterpret_cast<int>(client);
888 jstring jHost = stdStringToJstring(env, host, true);
889 jstring jRealm = stdStringToJstring(env, realm, true);
891 env->CallVoidMethod(mJavaFrame->frame(env).get(),
892 mJavaFrame->mDidReceiveAuthenticationChallenge, jHandle, jHost, jRealm, useCachedCredentials);
893 env->DeleteLocalRef(jHost);
894 env->DeleteLocalRef(jRealm);
900 WebFrame::reportSslCertError(WebUrlLoaderClient* client, int cert_error, const std::string& cert)
902 #ifdef ANDROID_INSTRUMENT
903 TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
905 JNIEnv* env = getJNIEnv();
906 int jHandle = reinterpret_cast<int>(client);
908 int len = cert.length();
909 jbyteArray jCert = env->NewByteArray(len);
910 jbyte* bytes = env->GetByteArrayElements(jCert, NULL);
911 cert.copy(reinterpret_cast<char*>(bytes), len);
913 env->CallVoidMethod(mJavaFrame->frame(env).get(),
914 mJavaFrame->mReportSslCertError, jHandle, cert_error, jCert);
915 env->DeleteLocalRef(jCert);
919 #if USE(CHROME_NETWORK_STACK)
921 WebFrame::downloadStart(const std::string& url, const std::string& userAgent, const std::string& contentDisposition, const std::string& mimetype, long long contentLength)
923 #ifdef ANDROID_INSTRUMENT
924 TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
926 JNIEnv* env = getJNIEnv();
927 jstring jUrl = stdStringToJstring(env, url, true);
928 jstring jUserAgent = stdStringToJstring(env, userAgent, true);
929 jstring jContentDisposition = stdStringToJstring(env, contentDisposition, true);
930 jstring jMimetype = stdStringToJstring(env, mimetype, true);
932 env->CallVoidMethod(mJavaFrame->frame(env).get(),
933 mJavaFrame->mDownloadStart, jUrl, jUserAgent, jContentDisposition, jMimetype, contentLength);
935 env->DeleteLocalRef(jUrl);
936 env->DeleteLocalRef(jUserAgent);
937 env->DeleteLocalRef(jContentDisposition);
938 env->DeleteLocalRef(jMimetype);
943 WebFrame::didReceiveData(const char* data, int size) {
944 #ifdef ANDROID_INSTRUMENT
945 TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
947 JNIEnv* env = getJNIEnv();
949 jbyteArray jData = env->NewByteArray(size);
950 jbyte* bytes = env->GetByteArrayElements(jData, NULL);
951 memcpy(reinterpret_cast<char*>(bytes), data, size);
953 env->CallVoidMethod(mJavaFrame->frame(env).get(),
954 mJavaFrame->mDidReceiveData, jData, size);
955 env->DeleteLocalRef(jData);
960 WebFrame::didFinishLoading() {
961 #ifdef ANDROID_INSTRUMENT
962 TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
964 JNIEnv* env = getJNIEnv();
966 env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mDidFinishLoading);
972 #if USE(CHROME_NETWORK_STACK)
973 void WebFrame::setCertificate(const std::string& cert)
975 #ifdef ANDROID_INSTRUMENT
976 TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
978 JNIEnv* env = getJNIEnv();
980 int len = cert.length();
981 jbyteArray jCert = env->NewByteArray(len);
982 jbyte* bytes = env->GetByteArrayElements(jCert, NULL);
983 cert.copy(reinterpret_cast<char*>(bytes), len);
985 env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mSetCertificate, jCert);
987 env->DeleteLocalRef(jCert);
992 void WebFrame::autoLogin(const std::string& loginHeader)
994 #ifdef ANDROID_INSTRUMENT
995 TimeCounterAuto counter(TimerCoutner::JavaCallbackTimeCounter);
997 WTF::String header(loginHeader.c_str(), loginHeader.length());
998 WTF::Vector<WTF::String> split;
999 header.split('&', split);
1000 if (!split.isEmpty()) {
1002 WTF::String account;
1004 int len = split.size();
1006 WTF::String& str = split[len];
1007 size_t equals = str.find('=');
1008 if (equals == WTF::notFound)
1011 WTF::String* result = 0;
1012 if (str.startsWith("realm", false))
1014 else if (str.startsWith("account", false))
1016 else if (str.startsWith("args", false))
1020 // Decode url escape sequences before sending to the app.
1021 *result = WebCore::decodeURLEscapeSequences(str.substring(equals + 1));
1024 // realm and args are required parameters.
1025 if (realm.isEmpty() || args.isEmpty())
1028 // Args is double-encoded as it contains urls.
1029 args = WebCore::decodeURLEscapeSequences(args);
1031 JNIEnv* env = getJNIEnv();
1032 jstring jRealm = wtfStringToJstring(env, realm, true);
1033 jstring jAccount = wtfStringToJstring(env, account);
1034 jstring jArgs = wtfStringToJstring(env, args, true);
1035 env->CallVoidMethod(mJavaFrame->frame(env).get(),
1036 mJavaFrame->mAutoLogin, jRealm, jAccount, jArgs);
1040 void WebFrame::maybeSavePassword(WebCore::Frame* frame, const WebCore::ResourceRequest& request)
1042 if (request.httpMethod() != "POST")
1045 WTF::String username;
1046 WTF::String password;
1047 if (!getUsernamePasswordFromDom(frame, username, password))
1050 JNIEnv* env = getJNIEnv();
1051 jstring jUsername = wtfStringToJstring(env, username);
1052 jstring jPassword = wtfStringToJstring(env, password);
1053 jbyteArray jPostData = getPostData(request);
1055 env->CallVoidMethod(mJavaFrame->frame(env).get(),
1056 mJavaFrame->mMaybeSavePassword, jPostData, jUsername, jPassword);
1059 env->DeleteLocalRef(jPostData);
1060 env->DeleteLocalRef(jUsername);
1061 env->DeleteLocalRef(jPassword);
1062 checkException(env);
1065 bool WebFrame::getUsernamePasswordFromDom(WebCore::Frame* frame, WTF::String& username, WTF::String& password)
1068 WTF::PassRefPtr<WebCore::HTMLCollection> form = frame->document()->forms();
1069 WebCore::Node* node = form->firstItem();
1070 while (node && !found && !node->namespaceURI().isNull() &&
1071 !node->namespaceURI().isEmpty()) {
1072 const WTF::Vector<WebCore::HTMLFormControlElement*>& elements =
1073 ((WebCore::HTMLFormElement*)node)->associatedElements();
1074 size_t size = elements.size();
1075 for (size_t i = 0; i< size && !found; i++) {
1076 WebCore::HTMLFormControlElement* e = elements[i];
1077 if (e->hasLocalName(WebCore::HTMLNames::inputTag)) {
1078 WebCore::HTMLInputElement* input = (WebCore::HTMLInputElement*)e;
1079 if (input->autoComplete() == false)
1081 if (input->isPasswordField())
1082 password = input->value();
1083 else if (input->isTextField() || input->isEmailField())
1084 username = input->value();
1085 if (!username.isNull() && !password.isNull())
1089 node = form->nextItem();
1094 jbyteArray WebFrame::getPostData(const WebCore::ResourceRequest& request)
1096 jbyteArray jPostDataStr = NULL;
1097 WebCore::FormData* formdata = request.httpBody();
1099 JNIEnv* env = getJNIEnv();
1100 AutoJObject obj = mJavaFrame->frame(env);
1102 // We can use the formdata->flatten() but it will result in two
1103 // memcpys, first through loading up the vector with the form data
1104 // then another to copy it out of the vector and into the java byte
1105 // array. Instead, we copy the form data ourselves below saving a
1107 const WTF::Vector<WebCore::FormDataElement>& elements =
1108 formdata->elements();
1112 size_t n = elements.size();
1113 FileInfo** fileinfos = new FileInfo*[n];
1114 for (size_t i = 0; i < n; ++i) {
1116 const WebCore::FormDataElement& e = elements[i];
1117 if (e.m_type == WebCore::FormDataElement::data) {
1118 size += e.m_data.size();
1119 } else if (e.m_type == WebCore::FormDataElement::encodedFile) {
1120 fileinfos[i] = new FileInfo(env, e.m_filename);
1121 int delta = env->CallIntMethod(obj.get(),
1122 mJavaFrame->mGetFileSize, fileinfos[i]->getUri());
1123 checkException(env);
1124 fileinfos[i]->setSize(delta);
1129 // Only create the byte array if there is POST data to pass up.
1130 // The Java code is expecting null if there is no data.
1132 // Copy the actual form data.
1133 jPostDataStr = env->NewByteArray(size);
1135 // Write the form data to the java array.
1136 jbyte* bytes = env->GetByteArrayElements(jPostDataStr, NULL);
1138 for (size_t i = 0; i < n; ++i) {
1139 const WebCore::FormDataElement& e = elements[i];
1140 if (e.m_type == WebCore::FormDataElement::data) {
1141 int delta = e.m_data.size();
1142 memcpy(bytes + offset, e.m_data.data(), delta);
1145 == WebCore::FormDataElement::encodedFile) {
1146 int delta = env->CallIntMethod(obj.get(),
1147 mJavaFrame->mGetFile, fileinfos[i]->getUri(),
1148 jPostDataStr, offset, fileinfos[i]->getSize());
1149 checkException(env);
1153 env->ReleaseByteArrayElements(jPostDataStr, bytes, 0);
1158 return jPostDataStr;
1161 // ----------------------------------------------------------------------------
1163 static void CallPolicyFunction(JNIEnv* env, jobject obj, jint func, jint decision)
1165 #ifdef ANDROID_INSTRUMENT
1166 TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter);
1168 WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
1169 LOG_ASSERT(pFrame, "nativeCallPolicyFunction must take a valid frame pointer!");
1170 PolicyFunctionWrapper* pFunc = (PolicyFunctionWrapper*)func;
1171 LOG_ASSERT(pFunc, "nativeCallPolicyFunction must take a valid function pointer!");
1173 // If we are resending the form then we should reset the multiple submission protection.
1174 if (decision == WebCore::PolicyUse)
1175 pFrame->loader()->resetMultipleFormSubmissionProtection();
1177 (pFrame->loader()->policyChecker()->*(pFunc->func))((WebCore::PolicyAction)decision);
1180 static void CreateFrame(JNIEnv* env, jobject obj, jobject javaview, jobject jAssetManager, jobject historyList)
1182 ScriptController::initializeThreading();
1184 #if USE(CHROME_NETWORK_STACK)
1185 // needs to be called before any other chromium code
1189 #ifdef ANDROID_INSTRUMENT
1191 V8Counters::initCounters();
1193 TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter);
1195 // Create a new page
1196 ChromeClientAndroid* chromeC = new ChromeClientAndroid;
1197 EditorClientAndroid* editorC = new EditorClientAndroid;
1198 DeviceMotionClientAndroid* deviceMotionC = new DeviceMotionClientAndroid;
1199 DeviceOrientationClientAndroid* deviceOrientationC = new DeviceOrientationClientAndroid;
1201 WebCore::Page::PageClients pageClients;
1202 pageClients.chromeClient = chromeC;
1203 pageClients.contextMenuClient = new ContextMenuClientAndroid;
1204 pageClients.editorClient = editorC;
1205 pageClients.dragClient = new DragClientAndroid;
1206 pageClients.inspectorClient = new InspectorClientAndroid;
1207 pageClients.deviceMotionClient = deviceMotionC;
1208 pageClients.deviceOrientationClient = deviceOrientationC;
1209 WebCore::Page* page = new WebCore::Page(pageClients);
1211 editorC->setPage(page);
1212 page->setGroupName("android.webkit");
1214 // Create a WebFrame to access the Java BrowserFrame associated with this page
1215 WebFrame* webFrame = new WebFrame(env, obj, historyList, page);
1216 // Attach webFrame to pageClients.chromeClient and release our ownership
1217 chromeC->setWebFrame(webFrame);
1220 FrameLoaderClientAndroid* loaderC = new FrameLoaderClientAndroid(webFrame);
1221 // Create a Frame and the page holds its reference
1222 WebCore::Frame* frame = WebCore::Frame::create(page, NULL, loaderC).get();
1223 loaderC->setFrame(frame);
1225 WDS::server()->addFrame(frame);
1228 // Create a WebViewCore to access the Java WebViewCore associated with this page
1229 WebViewCore* webViewCore = new WebViewCore(env, javaview, frame);
1231 #if ENABLE(WEB_AUTOFILL)
1232 editorC->getAutoFill()->setWebViewCore(webViewCore);
1235 // Create a FrameView
1236 RefPtr<WebCore::FrameView> frameView = WebCore::FrameView::create(frame);
1237 // Create a WebFrameView
1238 WebFrameView* webFrameView = new WebFrameView(frameView.get(), webViewCore);
1239 // As webFrameView Retains webViewCore, release our ownership
1240 Release(webViewCore);
1241 // As frameView Retains webFrameView, release our ownership
1242 Release(webFrameView);
1243 // Attach the frameView to the frame and release our ownership
1244 frame->setView(frameView);
1245 // Set the frame to active to turn on keyboard focus.
1247 frame->selection()->setFocused(true);
1248 frame->page()->focusController()->setFocused(true);
1249 deviceMotionC->setWebViewCore(webViewCore);
1250 deviceOrientationC->setWebViewCore(webViewCore);
1252 // Allow local access to file:/// and substitute data
1253 WebCore::SecurityOrigin::setLocalLoadPolicy(
1254 WebCore::SecurityOrigin::AllowLocalLoadsForLocalAndSubstituteData);
1256 LOGV("::WebCore:: createFrame %p", frame);
1258 // Set the mNativeFrame field in Frame
1259 SET_NATIVE_FRAME(env, obj, (int)frame);
1261 String directory = webFrame->getRawResourceFilename(
1262 WebCore::PlatformBridge::DrawableDir);
1263 if (directory.isEmpty())
1264 LOGE("Can't find the drawable directory");
1266 // Setup the asset manager.
1267 AssetManager* am = assetManagerForJavaObject(env, jAssetManager);
1268 // Initialize our skinning classes
1269 webFrame->setRenderSkins(new WebCore::RenderSkinAndroid(am, directory));
1271 for (int i = WebCore::PlatformBridge::FileUploadLabel;
1272 i <= WebCore::PlatformBridge::FileUploadNoFileChosenLabel; i++)
1273 initGlobalLocalizedName(
1274 static_cast<WebCore::PlatformBridge::rawResId>(i), webFrame);
1277 static void DestroyFrame(JNIEnv* env, jobject obj)
1279 #ifdef ANDROID_INSTRUMENT
1280 TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter);
1282 WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
1283 LOG_ASSERT(pFrame, "nativeDestroyFrame must take a valid frame pointer!");
1285 LOGV("::WebCore:: deleting frame %p", pFrame);
1287 WebCore::FrameView* view = pFrame->view();
1289 // detachFromParent will cause the page to be closed.
1290 WebCore::FrameLoader* fl = pFrame->loader();
1291 // retain a pointer because detachFromParent will set the page to null.
1292 WebCore::Page* page = pFrame->page();
1294 fl->detachFromParent();
1298 SET_NATIVE_FRAME(env, obj, 0);
1300 WDS::server()->removeFrame(pFrame);
1304 static void LoadUrl(JNIEnv *env, jobject obj, jstring url, jobject headers)
1306 #ifdef ANDROID_INSTRUMENT
1307 TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter);
1309 WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
1310 LOG_ASSERT(pFrame, "nativeLoadUrl must take a valid frame pointer!");
1312 WTF::String webcoreUrl = jstringToWtfString(env, url);
1313 WebCore::KURL kurl(WebCore::KURL(), webcoreUrl);
1314 WebCore::ResourceRequest request(kurl);
1316 // dalvikvm will raise exception if any of these fail
1317 jclass mapClass = env->FindClass("java/util/Map");
1318 jmethodID entrySet = env->GetMethodID(mapClass, "entrySet",
1319 "()Ljava/util/Set;");
1320 jobject set = env->CallObjectMethod(headers, entrySet);
1322 jclass setClass = env->FindClass("java/util/Set");
1323 jmethodID iterator = env->GetMethodID(setClass, "iterator",
1324 "()Ljava/util/Iterator;");
1325 jobject iter = env->CallObjectMethod(set, iterator);
1327 jclass iteratorClass = env->FindClass("java/util/Iterator");
1328 jmethodID hasNext = env->GetMethodID(iteratorClass, "hasNext", "()Z");
1329 jmethodID next = env->GetMethodID(iteratorClass, "next",
1330 "()Ljava/lang/Object;");
1331 jclass entryClass = env->FindClass("java/util/Map$Entry");
1332 jmethodID getKey = env->GetMethodID(entryClass, "getKey",
1333 "()Ljava/lang/Object;");
1334 jmethodID getValue = env->GetMethodID(entryClass, "getValue",
1335 "()Ljava/lang/Object;");
1337 while (env->CallBooleanMethod(iter, hasNext)) {
1338 jobject entry = env->CallObjectMethod(iter, next);
1339 jstring key = (jstring) env->CallObjectMethod(entry, getKey);
1340 jstring value = (jstring) env->CallObjectMethod(entry, getValue);
1341 request.setHTTPHeaderField(jstringToWtfString(env, key), jstringToWtfString(env, value));
1342 env->DeleteLocalRef(entry);
1343 env->DeleteLocalRef(key);
1344 env->DeleteLocalRef(value);
1347 env->DeleteLocalRef(entryClass);
1348 env->DeleteLocalRef(iteratorClass);
1349 env->DeleteLocalRef(iter);
1350 env->DeleteLocalRef(setClass);
1351 env->DeleteLocalRef(set);
1352 env->DeleteLocalRef(mapClass);
1354 LOGV("LoadUrl %s", kurl.string().latin1().data());
1355 pFrame->loader()->load(request, false);
1358 static void PostUrl(JNIEnv *env, jobject obj, jstring url, jbyteArray postData)
1360 #ifdef ANDROID_INSTRUMENT
1361 TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter);
1363 WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
1364 LOG_ASSERT(pFrame, "nativePostUrl must take a valid frame pointer!");
1366 WebCore::KURL kurl(WebCore::KURL(), jstringToWtfString(env, url));
1367 WebCore::ResourceRequest request(kurl);
1368 request.setHTTPMethod("POST");
1369 request.setHTTPContentType("application/x-www-form-urlencoded");
1372 jsize size = env->GetArrayLength(postData);
1373 jbyte* bytes = env->GetByteArrayElements(postData, NULL);
1374 RefPtr<FormData> formData = FormData::create((const void*)bytes, size);
1375 // the identifier uses the same logic as generateFormDataIdentifier() in
1376 // HTMLFormElement.cpp
1377 formData->setIdentifier(static_cast<int64_t>(WTF::currentTime() * 1000000.0));
1378 request.setHTTPBody(formData);
1379 env->ReleaseByteArrayElements(postData, bytes, 0);
1382 LOGV("PostUrl %s", kurl.string().latin1().data());
1383 WebCore::FrameLoadRequest frameRequest(request);
1384 pFrame->loader()->loadFrameRequest(frameRequest, false, false, 0, 0, WebCore::SendReferrer);
1387 static void LoadData(JNIEnv *env, jobject obj, jstring baseUrl, jstring data,
1388 jstring mimeType, jstring encoding, jstring failUrl)
1390 #ifdef ANDROID_INSTRUMENT
1391 TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter);
1393 WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
1394 LOG_ASSERT(pFrame, "nativeLoadData must take a valid frame pointer!");
1396 // Setup the resource request
1397 WebCore::ResourceRequest request(jstringToWtfString(env, baseUrl));
1399 // Setup the substituteData
1400 const char* dataStr = env->GetStringUTFChars(data, NULL);
1401 WTF::PassRefPtr<WebCore::SharedBuffer> sharedBuffer =
1402 WebCore::SharedBuffer::create();
1403 LOG_ASSERT(dataStr, "nativeLoadData has a null data string.");
1404 sharedBuffer->append(dataStr, strlen(dataStr));
1405 env->ReleaseStringUTFChars(data, dataStr);
1407 WebCore::SubstituteData substituteData(sharedBuffer,
1408 jstringToWtfString(env, mimeType), jstringToWtfString(env, encoding),
1409 WebCore::KURL(ParsedURLString, jstringToWtfString(env, failUrl)));
1412 pFrame->loader()->load(request, substituteData, false);
1415 static void StopLoading(JNIEnv *env, jobject obj)
1417 #ifdef ANDROID_INSTRUMENT
1418 TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter);
1420 WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
1421 LOG_ASSERT(pFrame, "nativeStopLoading must take a valid frame pointer!");
1422 LOGV("::WebCore:: stopLoading %p", pFrame);
1424 // Stop loading the page and do not send an unload event
1425 pFrame->loader()->stopForUserCancel();
1429 static String saveArchiveAutoname(String basename, String name, String extension) {
1430 if (name.isNull() || name.isEmpty()) {
1431 name = String("index");
1434 String testname = basename;
1435 testname.append(name);
1436 testname.append(extension);
1439 struct stat permissions;
1440 if (stat(testname.utf8().data(), &permissions) < 0) {
1441 if (errno == ENOENT)
1446 const int maxAttempts = 100;
1447 for (int i = 1; i < maxAttempts; i++) {
1448 String testname = basename;
1449 testname.append(name);
1450 testname.append("-");
1451 testname.append(String::number(i));
1452 testname.append(extension);
1455 if (stat(testname.utf8().data(), &permissions) < 0) {
1456 if (errno == ENOENT)
1466 static jstring SaveWebArchive(JNIEnv *env, jobject obj, jstring basename, jboolean autoname)
1469 WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
1470 LOG_ASSERT(pFrame, "nativeSaveWebArchive must take a valid frame pointer!");
1471 String mimeType = pFrame->loader()->documentLoader()->mainResource()->mimeType();
1472 if ((mimeType != "text/html") && (mimeType != "application/xhtml+xml"))
1475 const char* basenameNative = getCharactersFromJStringInEnv(env, basename);
1476 String basenameString = String::fromUTF8(basenameNative);
1480 String name = pFrame->loader()->documentLoader()->originalURL().lastPathComponent();
1481 String extension = String(".webarchivexml");
1482 filename = saveArchiveAutoname(basenameString, name, extension);
1484 filename = basenameString;
1487 if (filename.isNull() || filename.isEmpty()) {
1488 LOGD("saveWebArchive: Failed to select a filename to save.");
1489 releaseCharactersForJStringInEnv(env, basename, basenameNative);
1493 const int noCompression = 0;
1494 xmlTextWriterPtr writer = xmlNewTextWriterFilename(filename.utf8().data(), noCompression);
1495 if (writer == NULL) {
1496 LOGD("saveWebArchive: Failed to initialize xml writer.");
1497 releaseCharactersForJStringInEnv(env, basename, basenameNative);
1501 RefPtr<WebArchiveAndroid> archive = WebCore::WebArchiveAndroid::create(pFrame);
1503 bool result = archive->saveWebArchive(writer);
1505 releaseCharactersForJStringInEnv(env, basename, basenameNative);
1506 xmlFreeTextWriter(writer);
1509 return wtfStringToJstring(env, filename);
1515 static jstring ExternalRepresentation(JNIEnv *env, jobject obj)
1517 #ifdef ANDROID_INSTRUMENT
1518 TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter);
1520 WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
1521 LOG_ASSERT(pFrame, "android_webcore_nativeExternalRepresentation must take a valid frame pointer!");
1523 // Request external representation of the render tree
1524 WTF::String renderDump = WebCore::externalRepresentation(pFrame);
1525 return wtfStringToJstring(env, renderDump);
1528 static StringBuilder FrameAsText(WebCore::Frame *pFrame, jboolean dumpChildFrames) {
1529 StringBuilder renderDump;
1532 WebCore::Element *documentElement = pFrame->document()->documentElement();
1533 if (!documentElement)
1535 if (pFrame->tree()->parent()) {
1536 renderDump.append("\n--------\nFrame: '");
1537 renderDump.append(pFrame->tree()->name());
1538 renderDump.append("'\n--------\n");
1540 renderDump.append(((WebCore::HTMLElement*)documentElement)->innerText());
1541 renderDump.append("\n");
1542 if (dumpChildFrames) {
1543 for (unsigned i = 0; i < pFrame->tree()->childCount(); ++i) {
1544 renderDump.append(FrameAsText(pFrame->tree()->child(i), dumpChildFrames).toString());
1550 static jstring DocumentAsText(JNIEnv *env, jobject obj)
1552 #ifdef ANDROID_INSTRUMENT
1553 TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter);
1555 WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
1556 LOG_ASSERT(pFrame, "android_webcore_nativeDocumentAsText must take a valid frame pointer!");
1558 WTF::String renderDump = FrameAsText(pFrame, false /* dumpChildFrames */).toString();
1559 return wtfStringToJstring(env, renderDump);
1562 static jstring ChildFramesAsText(JNIEnv *env, jobject obj)
1564 #ifdef ANDROID_INSTRUMENT
1565 TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter);
1567 WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
1568 LOG_ASSERT(pFrame, "android_webcore_nativeDocumentAsText must take a valid frame pointer!");
1570 StringBuilder renderDumpBuilder;
1571 for (unsigned i = 0; i < pFrame->tree()->childCount(); ++i) {
1572 renderDumpBuilder.append(FrameAsText(pFrame->tree()->child(i), true /* dumpChildFrames */).toString());
1574 WTF::String renderDump = renderDumpBuilder.toString();
1575 return wtfStringToJstring(env, renderDump);
1578 static void Reload(JNIEnv *env, jobject obj, jboolean allowStale)
1580 #ifdef ANDROID_INSTRUMENT
1581 TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter);
1583 WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
1584 LOG_ASSERT(pFrame, "nativeReload must take a valid frame pointer!");
1586 WebCore::FrameLoader* loader = pFrame->loader();
1588 // load the current page with FrameLoadTypeIndexedBackForward so that it
1589 // will use cache when it is possible
1590 WebCore::Page* page = pFrame->page();
1591 WebCore::HistoryItem* item = page->backForwardList()->currentItem();
1593 page->goToItem(item, FrameLoadTypeIndexedBackForward);
1595 loader->reload(true);
1598 static void GoBackOrForward(JNIEnv *env, jobject obj, jint pos)
1600 #ifdef ANDROID_INSTRUMENT
1601 TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter);
1603 WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
1604 LOG_ASSERT(pFrame, "nativeGoBackOrForward must take a valid frame pointer!");
1607 pFrame->page()->goForward();
1609 pFrame->page()->goBack();
1611 pFrame->page()->goBackOrForward(pos);
1614 static jobject StringByEvaluatingJavaScriptFromString(JNIEnv *env, jobject obj, jstring script)
1616 #ifdef ANDROID_INSTRUMENT
1617 TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter);
1619 WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
1620 LOG_ASSERT(pFrame, "stringByEvaluatingJavaScriptFromString must take a valid frame pointer!");
1622 WebCore::ScriptValue value =
1623 pFrame->script()->executeScript(jstringToWtfString(env, script), true);
1624 WTF::String result = WTF::String();
1625 ScriptState* scriptState = mainWorldScriptState(pFrame);
1626 if (!value.getString(scriptState, result))
1628 return wtfStringToJstring(env, result);
1631 // Wrap the JavaInstance used when binding custom javascript interfaces. Use a
1632 // weak reference so that the gc can collect the WebView. Override virtualBegin
1633 // and virtualEnd and swap the weak reference for the real object.
1634 class WeakJavaInstance : public JavaInstance {
1637 static PassRefPtr<WeakJavaInstance> create(jobject obj, PassRefPtr<RootObject> root)
1639 return adoptRef(new WeakJavaInstance(obj, root));
1642 static PassRefPtr<WeakJavaInstance> create(jobject obj)
1644 return adoptRef(new WeakJavaInstance(obj));
1650 WeakJavaInstance(jobject instance, PassRefPtr<RootObject> rootObject)
1651 : JavaInstance(instance, rootObject)
1653 WeakJavaInstance(jobject instance)
1654 : JavaInstance(instance)
1656 , m_beginEndDepth(0)
1658 JNIEnv* env = getJNIEnv();
1659 // JavaInstance creates a global ref to instance in its constructor.
1660 env->DeleteGlobalRef(m_instance->instance());
1661 // Set the object to a weak reference.
1662 m_instance->setInstance(env->NewWeakGlobalRef(instance));
1666 JNIEnv* env = getJNIEnv();
1667 // Store the weak reference so we can delete it later.
1668 jweak weak = m_instance->instance();
1669 // The JavaInstance destructor attempts to delete the global ref stored
1670 // in m_instance. Since we replaced it in our constructor with a weak
1671 // reference, restore the global ref here so the vm will not complain.
1672 m_instance->setInstance(env->NewGlobalRef(
1673 getRealObject(env, m_instance->instance()).get()));
1674 // Delete the weak reference.
1675 env->DeleteWeakGlobalRef(weak);
1678 virtual void virtualBegin()
1680 if (m_beginEndDepth++ > 0)
1682 m_weakRef = m_instance->instance();
1683 JNIEnv* env = getJNIEnv();
1684 // This is odd. getRealObject returns an AutoJObject which is used to
1685 // cleanly create and delete a local reference. But, here we need to
1686 // maintain the local reference across calls to virtualBegin() and
1687 // virtualEnd(). So, release the local reference from the AutoJObject
1688 // and delete the local reference in virtualEnd().
1689 m_realObject = getRealObject(env, m_weakRef).release();
1690 // Point to the real object
1691 m_instance->setInstance(m_realObject);
1692 // Call the base class method
1693 INHERITED::virtualBegin();
1696 virtual void virtualEnd()
1698 if (--m_beginEndDepth > 0)
1700 // Call the base class method first to pop the local frame.
1701 INHERITED::virtualEnd();
1702 // Get rid of the local reference to the real object.
1703 getJNIEnv()->DeleteLocalRef(m_realObject);
1704 // Point back to the WeakReference.
1705 m_instance->setInstance(m_weakRef);
1709 typedef JavaInstance INHERITED;
1710 jobject m_realObject;
1712 // The current depth of nested calls to virtualBegin and virtualEnd.
1713 int m_beginEndDepth;
1716 static void AddJavascriptInterface(JNIEnv *env, jobject obj, jint nativeFramePointer,
1717 jobject javascriptObj, jstring interfaceName)
1719 #ifdef ANDROID_INSTRUMENT
1720 TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter);
1722 WebCore::Frame* pFrame = 0;
1723 if (nativeFramePointer == 0)
1724 pFrame = GET_NATIVE_FRAME(env, obj);
1726 pFrame = (WebCore::Frame*)nativeFramePointer;
1727 LOG_ASSERT(pFrame, "nativeAddJavascriptInterface must take a valid frame pointer!");
1730 env->GetJavaVM(&vm);
1731 LOGV("::WebCore:: addJSInterface: %p", pFrame);
1734 // Copied from qwebframe.cpp
1735 JSC::JSLock lock(JSC::SilenceAssertionsOnly);
1736 WebCore::JSDOMWindow *window = WebCore::toJSDOMWindow(pFrame, mainThreadNormalWorld());
1738 RootObject *root = pFrame->script()->bindingRootObject();
1740 // Add the binding to JS environment
1741 JSC::ExecState* exec = window->globalExec();
1742 JSC::JSObject* addedObject = WeakJavaInstance::create(javascriptObj,
1743 root)->createRuntimeObject(exec);
1744 const jchar* s = env->GetStringChars(interfaceName, NULL);
1746 // Add the binding name to the window's table of child objects.
1747 JSC::PutPropertySlot slot;
1748 window->put(exec, JSC::Identifier(exec, (const UChar *)s,
1749 env->GetStringLength(interfaceName)), addedObject, slot);
1750 env->ReleaseStringChars(interfaceName, s);
1751 checkException(env);
1756 RefPtr<JavaInstance> addedObject = WeakJavaInstance::create(javascriptObj);
1757 const char* name = getCharactersFromJStringInEnv(env, interfaceName);
1758 // Pass ownership of the added object to bindToWindowObject.
1759 NPObject* npObject = JavaInstanceToNPObject(addedObject.get());
1760 pFrame->script()->bindToWindowObject(pFrame, name, npObject);
1761 // bindToWindowObject calls NPN_RetainObject on the
1762 // returned one (see createV8ObjectForNPObject in V8NPObject.cpp).
1763 // bindToWindowObject also increases obj's ref count and decreases
1764 // the ref count when the object is not reachable from JavaScript
1765 // side. Code here must release the reference count increased by
1766 // bindToWindowObject.
1768 // Note that while this function is declared in WebCore/bridge/npruntime.h, for V8 builds
1769 // we use WebCore/bindings/v8/npruntime.cpp (rather than
1770 // WebCore/bridge/npruntime.cpp), so the function is implemented there.
1771 // TODO: Combine the two versions of these NPAPI files.
1772 NPN_ReleaseObject(npObject);
1773 releaseCharactersForJString(interfaceName, name);
1779 static void SetCacheDisabled(JNIEnv *env, jobject obj, jboolean disabled)
1781 #ifdef ANDROID_INSTRUMENT
1782 TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter);
1784 WebCore::cache()->setDisabled(disabled);
1787 static jboolean CacheDisabled(JNIEnv *env, jobject obj)
1789 #ifdef ANDROID_INSTRUMENT
1790 TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter);
1792 return WebCore::cache()->disabled();
1795 static void ClearWebCoreCache()
1797 if (!WebCore::cache()->disabled()) {
1798 // Disabling the cache will remove all resources from the cache. They may
1799 // still live on if they are referenced by some Web page though.
1800 WebCore::cache()->setDisabled(true);
1801 WebCore::cache()->setDisabled(false);
1805 int pageCapacity = WebCore::pageCache()->capacity();
1806 // Setting size to 0, makes all pages be released.
1807 WebCore::pageCache()->setCapacity(0);
1808 WebCore::pageCache()->releaseAutoreleasedPagesNow();
1809 WebCore::pageCache()->setCapacity(pageCapacity);
1812 static void ClearWebViewCache()
1814 #if USE(CHROME_NETWORK_STACK)
1815 WebCache::get(false /*privateBrowsing*/)->clear();
1817 // The Android network stack provides a WebView cache in CacheManager.java.
1818 // Clearing this is handled entirely Java-side.
1822 static void ClearCache(JNIEnv *env, jobject obj)
1824 #ifdef ANDROID_INSTRUMENT
1825 TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter);
1827 JSC::JSLock lock(false);
1828 JSC::Heap::Statistics jsHeapStatistics = WebCore::JSDOMWindow::commonJSGlobalData()->heap.statistics();
1829 LOGD("About to gc and JavaScript heap size is %d and has %d bytes free",
1830 jsHeapStatistics.size, jsHeapStatistics.free);
1832 LOGD("About to clear cache and current cache has %d bytes live and %d bytes dead",
1833 cache()->getLiveSize(), cache()->getDeadSize());
1834 #endif // ANDROID_INSTRUMENT
1835 ClearWebCoreCache();
1836 ClearWebViewCache();
1838 // force JavaScript to GC when clear cache
1839 WebCore::gcController().garbageCollectSoon();
1841 WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
1842 pFrame->script()->lowMemoryNotification();
1846 static jboolean DocumentHasImages(JNIEnv *env, jobject obj)
1848 #ifdef ANDROID_INSTRUMENT
1849 TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter);
1851 WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
1852 LOG_ASSERT(pFrame, "DocumentHasImages must take a valid frame pointer!");
1854 return pFrame->document()->images()->length() > 0;
1857 static jboolean HasPasswordField(JNIEnv *env, jobject obj)
1859 #ifdef ANDROID_INSTRUMENT
1860 TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter);
1862 WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
1863 LOG_ASSERT(pFrame, "HasPasswordField must take a valid frame pointer!");
1866 WTF::PassRefPtr<WebCore::HTMLCollection> form = pFrame->document()->forms();
1867 WebCore::Node* node = form->firstItem();
1868 // Null/Empty namespace means that node is not created in HTMLFormElement
1869 // class, but just normal Element class.
1870 while (node && !found && !node->namespaceURI().isNull() &&
1871 !node->namespaceURI().isEmpty()) {
1872 const WTF::Vector<WebCore::HTMLFormControlElement*>& elements =
1873 ((WebCore::HTMLFormElement*)node)->associatedElements();
1874 size_t size = elements.size();
1875 for (size_t i = 0; i< size && !found; i++) {
1876 WebCore::HTMLFormControlElement* e = elements[i];
1877 if (e->hasLocalName(WebCore::HTMLNames::inputTag)) {
1878 if (static_cast<WebCore::HTMLInputElement*>(e)->isPasswordField())
1882 node = form->nextItem();
1887 static jobjectArray GetUsernamePassword(JNIEnv *env, jobject obj)
1889 #ifdef ANDROID_INSTRUMENT
1890 TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter);
1892 WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
1893 LOG_ASSERT(pFrame, "GetUsernamePassword must take a valid frame pointer!");
1894 jobjectArray strArray = NULL;
1895 WTF::String username;
1896 WTF::String password;
1897 if (WebFrame::getWebFrame(pFrame)->getUsernamePasswordFromDom(pFrame, username, password)) {
1898 jclass stringClass = env->FindClass("java/lang/String");
1899 strArray = env->NewObjectArray(2, stringClass, NULL);
1900 env->DeleteLocalRef(stringClass);
1901 env->SetObjectArrayElement(strArray, 0, wtfStringToJstring(env, username));
1902 env->SetObjectArrayElement(strArray, 1, wtfStringToJstring(env, password));
1907 static void SetUsernamePassword(JNIEnv *env, jobject obj,
1908 jstring username, jstring password)
1910 #ifdef ANDROID_INSTRUMENT
1911 TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter);
1913 WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
1914 LOG_ASSERT(pFrame, "SetUsernamePassword must take a valid frame pointer!");
1916 WebCore::HTMLInputElement* usernameEle = NULL;
1917 WebCore::HTMLInputElement* passwordEle = NULL;
1919 WTF::PassRefPtr<WebCore::HTMLCollection> form = pFrame->document()->forms();
1920 WebCore::Node* node = form->firstItem();
1921 while (node && !found && !node->namespaceURI().isNull() &&
1922 !node->namespaceURI().isEmpty()) {
1923 const WTF::Vector<WebCore::HTMLFormControlElement*>& elements =
1924 ((WebCore::HTMLFormElement*)node)->associatedElements();
1925 size_t size = elements.size();
1926 for (size_t i = 0; i< size && !found; i++) {
1927 WebCore::HTMLFormControlElement* e = elements[i];
1928 if (e->hasLocalName(WebCore::HTMLNames::inputTag)) {
1929 WebCore::HTMLInputElement* input = (WebCore::HTMLInputElement*)e;
1930 if (input->autoComplete() == false)
1932 if (input->isPasswordField())
1933 passwordEle = input;
1934 else if (input->isTextField() || input->isEmailField())
1935 usernameEle = input;
1936 if (usernameEle != NULL && passwordEle != NULL)
1940 node = form->nextItem();
1943 usernameEle->setValue(jstringToWtfString(env, username));
1944 passwordEle->setValue(jstringToWtfString(env, password));
1949 WebFrame::saveFormData(HTMLFormElement* form)
1951 if (form->autoComplete()) {
1952 JNIEnv* env = getJNIEnv();
1953 jclass mapClass = env->FindClass("java/util/HashMap");
1954 LOG_ASSERT(mapClass, "Could not find HashMap class!");
1955 jmethodID init = env->GetMethodID(mapClass, "<init>", "(I)V");
1956 LOG_ASSERT(init, "Could not find constructor for HashMap");
1957 jobject hashMap = env->NewObject(mapClass, init, 1);
1958 LOG_ASSERT(hashMap, "Could not create a new HashMap");
1959 jmethodID put = env->GetMethodID(mapClass, "put",
1960 "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
1961 LOG_ASSERT(put, "Could not find put method on HashMap");
1962 WTF::Vector<WebCore::HTMLFormControlElement*> elements = form->associatedElements();
1963 size_t size = elements.size();
1964 for (size_t i = 0; i < size; i++) {
1965 WebCore::HTMLFormControlElement* e = elements[i];
1966 if (e->hasTagName(WebCore::HTMLNames::inputTag)) {
1967 WebCore::HTMLInputElement* input = static_cast<WebCore::HTMLInputElement*>(e);
1968 if (input->isTextField() && !input->isPasswordField()
1969 && input->autoComplete()) {
1970 WTF::String value = input->value();
1971 int len = value.length();
1973 const WTF::AtomicString& name = input->name();
1974 jstring key = wtfStringToJstring(env, name);
1975 jstring val = wtfStringToJstring(env, value);
1976 LOG_ASSERT(key && val, "name or value not set");
1977 env->CallObjectMethod(hashMap, put, key, val);
1978 env->DeleteLocalRef(key);
1979 env->DeleteLocalRef(val);
1984 env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mSaveFormData, hashMap);
1985 env->DeleteLocalRef(hashMap);
1986 env->DeleteLocalRef(mapClass);
1990 static void OrientationChanged(JNIEnv *env, jobject obj, int orientation)
1992 #ifdef ANDROID_INSTRUMENT
1993 TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter);
1995 WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
1996 LOGV("Sending orientation: %d", orientation);
1997 pFrame->sendOrientationChangeEvent(orientation);
2000 #if USE(CHROME_NETWORK_STACK)
2002 static void AuthenticationProceed(JNIEnv *env, jobject obj, int handle, jstring jUsername, jstring jPassword)
2004 WebUrlLoaderClient* client = reinterpret_cast<WebUrlLoaderClient*>(handle);
2005 std::string username = jstringToStdString(env, jUsername);
2006 std::string password = jstringToStdString(env, jPassword);
2007 client->setAuth(username, password);
2010 static void AuthenticationCancel(JNIEnv *env, jobject obj, int handle)
2012 WebUrlLoaderClient* client = reinterpret_cast<WebUrlLoaderClient*>(handle);
2013 client->cancelAuth();
2016 static void SslCertErrorProceed(JNIEnv *env, jobject obj, int handle)
2018 WebUrlLoaderClient* client = reinterpret_cast<WebUrlLoaderClient*>(handle);
2019 client->proceedSslCertError();
2022 static void SslCertErrorCancel(JNIEnv *env, jobject obj, int handle, int cert_error)
2024 WebUrlLoaderClient* client = reinterpret_cast<WebUrlLoaderClient*>(handle);
2025 client->cancelSslCertError(cert_error);
2030 static void AuthenticationProceed(JNIEnv *env, jobject obj, int handle, jstring jUsername, jstring jPassword)
2032 LOGW("Chromium authentication API called, but libchromium is not available");
2035 static void AuthenticationCancel(JNIEnv *env, jobject obj, int handle)
2037 LOGW("Chromium authentication API called, but libchromium is not available");
2040 static void SslCertErrorProceed(JNIEnv *env, jobject obj, int handle)
2042 LOGW("Chromium SSL API called, but libchromium is not available");
2045 static void SslCertErrorCancel(JNIEnv *env, jobject obj, int handle, int cert_error)
2047 LOGW("Chromium SSL API called, but libchromium is not available");
2050 #endif // USE(CHROME_NETWORK_STACK)
2052 // ----------------------------------------------------------------------------
2057 static JNINativeMethod gBrowserFrameNativeMethods[] = {
2058 /* name, signature, funcPtr */
2059 { "nativeCallPolicyFunction", "(II)V",
2060 (void*) CallPolicyFunction },
2061 { "nativeCreateFrame", "(Landroid/webkit/WebViewCore;Landroid/content/res/AssetManager;Landroid/webkit/WebBackForwardList;)V",
2062 (void*) CreateFrame },
2063 { "nativeDestroyFrame", "()V",
2064 (void*) DestroyFrame },
2065 { "nativeStopLoading", "()V",
2066 (void*) StopLoading },
2067 { "nativeLoadUrl", "(Ljava/lang/String;Ljava/util/Map;)V",
2069 { "nativePostUrl", "(Ljava/lang/String;[B)V",
2071 { "nativeLoadData", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
2073 { "nativeSaveWebArchive", "(Ljava/lang/String;Z)Ljava/lang/String;",
2074 (void*) SaveWebArchive },
2075 { "externalRepresentation", "()Ljava/lang/String;",
2076 (void*) ExternalRepresentation },
2077 { "documentAsText", "()Ljava/lang/String;",
2078 (void*) DocumentAsText },
2079 { "childFramesAsText", "()Ljava/lang/String;",
2080 (void*) ChildFramesAsText },
2083 { "nativeGoBackOrForward", "(I)V",
2084 (void*) GoBackOrForward },
2085 { "nativeAddJavascriptInterface", "(ILjava/lang/Object;Ljava/lang/String;)V",
2086 (void*) AddJavascriptInterface },
2087 { "stringByEvaluatingJavaScriptFromString",
2088 "(Ljava/lang/String;)Ljava/lang/String;",
2089 (void*) StringByEvaluatingJavaScriptFromString },
2090 { "setCacheDisabled", "(Z)V",
2091 (void*) SetCacheDisabled },
2092 { "cacheDisabled", "()Z",
2093 (void*) CacheDisabled },
2094 { "clearCache", "()V",
2095 (void*) ClearCache },
2096 { "documentHasImages", "()Z",
2097 (void*) DocumentHasImages },
2098 { "hasPasswordField", "()Z",
2099 (void*) HasPasswordField },
2100 { "getUsernamePassword", "()[Ljava/lang/String;",
2101 (void*) GetUsernamePassword },
2102 { "setUsernamePassword", "(Ljava/lang/String;Ljava/lang/String;)V",
2103 (void*) SetUsernamePassword },
2104 { "nativeOrientationChanged", "(I)V",
2105 (void*) OrientationChanged },
2106 { "nativeAuthenticationProceed", "(ILjava/lang/String;Ljava/lang/String;)V",
2107 (void*) AuthenticationProceed },
2108 { "nativeAuthenticationCancel", "(I)V",
2109 (void*) AuthenticationCancel },
2110 { "nativeSslCertErrorProceed", "(I)V",
2111 (void*) SslCertErrorProceed },
2112 { "nativeSslCertErrorCancel", "(II)V",
2113 (void*) SslCertErrorCancel },
2116 int registerWebFrame(JNIEnv* env)
2118 jclass clazz = env->FindClass("android/webkit/BrowserFrame");
2119 LOG_ASSERT(clazz, "Cannot find BrowserFrame");
2120 gFrameField = env->GetFieldID(clazz, "mNativeFrame", "I");
2121 LOG_ASSERT(gFrameField, "Cannot find mNativeFrame on BrowserFrame");
2122 env->DeleteLocalRef(clazz);
2124 return jniRegisterNativeMethods(env, "android/webkit/BrowserFrame",
2125 gBrowserFrameNativeMethods, NELEM(gBrowserFrameNativeMethods));
2128 } /* namespace android */