1 /*
   2  * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
   3  */
   4 #include "config.h"
   5 
   6 #include "FrameLoaderClientJava.h"
   7 
   8 #include "NotImplemented.h"
   9 #include "CSSParser.h"
  10 #include "CString.h"
  11 #include "Chrome.h"
  12 #include "DocumentLoader.h"
  13 #include "IconURL.h"
  14 #include "FormState.h"
  15 #include "FrameLoadRequest.h"
  16 #include "FrameNetworkingContextJava.h"
  17 #include "FrameTree.h"
  18 #include "MainFrame.h"
  19 #include "HistoryItem.h"
  20 #include "HTMLFormElement.h"
  21 #include "HTTPParsers.h"
  22 #include "MIMETypeRegistry.h"
  23 #include "Page.h"
  24 //critical!!! MSVC bug:
  25 //
  26 //forward decelerated class member reference accepted as non-virtual, but virtual in fact
  27 //  no problem in gcc
  28 //  GPF with ms cc (_fastcall in caller, but _stdcall/_thiscall in fact)
  29 #include "PolicyChecker.h"
  30 #include "ProgressTracker.h"
  31 #include "ScriptController.h"
  32 #include "Settings.h"
  33 #include "SharedBuffer.h"
  34 #include "FrameNetworkingContext.h"
  35 #include "WebPage.h"
  36 #include "WindowFeatures.h"
  37 
  38 #include <bindings/js/DOMWrapperWorld.h>
  39 #include <API/APICast.h>
  40 #include <API/JavaScript.h>
  41 #include <wtf/text/WTFString.h>
  42 
  43 
  44 
  45 #include "com_sun_webkit_LoadListenerClient.h"
  46 
  47 static JGClass webPageClass;
  48 static JGClass networkContextClass;
  49 
  50 static jmethodID updateForStandardLoadMID;
  51 static jmethodID updateForReloadMID;
  52 
  53 static jmethodID setRequestURLMID;
  54 static jmethodID removeRequestURLMID;
  55 
  56 static jmethodID fireLoadEventMID;
  57 static jmethodID fireResourceLoadEventMID;
  58 static jmethodID canHandleURLMID;
  59 
  60 static jmethodID permitNavigateActionMID;
  61 static jmethodID permitRedirectActionMID;
  62 static jmethodID permitAcceptResourceActionMID;
  63 static jmethodID permitSubmitDataActionMID;
  64 static jmethodID permitEnableScriptsActionMID;
  65 static jmethodID permitNewWindowActionMID;
  66 
  67 static jmethodID didClearWindowObjectMID;
  68 
  69 static jmethodID frameCreatedMID;
  70 static jmethodID frameDestroyedMID;
  71 
  72 static void initRefs(JNIEnv* env)
  73 {
  74     if (!webPageClass) {
  75         webPageClass = JLClass(env->FindClass(
  76             "com/sun/webkit/WebPage"));
  77         ASSERT(webPageClass);
  78 
  79         setRequestURLMID = env->GetMethodID(webPageClass, "fwkSetRequestURL", "(JILjava/lang/String;)V");
  80         ASSERT(setRequestURLMID);
  81         removeRequestURLMID = env->GetMethodID(webPageClass, "fwkRemoveRequestURL", "(JI)V");
  82         ASSERT(removeRequestURLMID);
  83 
  84         fireLoadEventMID = env->GetMethodID(webPageClass, "fwkFireLoadEvent",
  85                                             "(JILjava/lang/String;Ljava/lang/String;DI)V");
  86         ASSERT(fireLoadEventMID);
  87         fireResourceLoadEventMID = env->GetMethodID(webPageClass, "fwkFireResourceLoadEvent",
  88                                                     "(JIILjava/lang/String;DI)V");
  89         ASSERT(fireResourceLoadEventMID);
  90 
  91         permitNavigateActionMID = env->GetMethodID(webPageClass, "fwkPermitNavigateAction",
  92                                                    "(JLjava/lang/String;)Z");
  93         ASSERT(permitNavigateActionMID);
  94 
  95         permitRedirectActionMID = env->GetMethodID(webPageClass, "fwkPermitRedirectAction",
  96                                                    "(JLjava/lang/String;)Z");
  97         ASSERT(permitRedirectActionMID);
  98 
  99         permitAcceptResourceActionMID = env->GetMethodID(webPageClass, "fwkPermitAcceptResourceAction",
 100                                                          "(JLjava/lang/String;)Z");
 101         ASSERT(permitAcceptResourceActionMID);
 102 
 103         permitSubmitDataActionMID = env->GetMethodID(webPageClass, "fwkPermitSubmitDataAction",
 104                                                      "(JLjava/lang/String;Ljava/lang/String;Z)Z");
 105         ASSERT(permitSubmitDataActionMID);
 106 
 107         permitEnableScriptsActionMID = env->GetMethodID(webPageClass, "fwkPermitEnableScriptsAction",
 108                                                         "(JLjava/lang/String;)Z");
 109         ASSERT(permitEnableScriptsActionMID);
 110 
 111         permitNewWindowActionMID = env->GetMethodID(webPageClass, "fwkPermitNewWindowAction",
 112                                                     "(JLjava/lang/String;)Z");
 113         ASSERT(permitNewWindowActionMID);
 114 
 115         didClearWindowObjectMID = env->GetMethodID(webPageClass, "fwkDidClearWindowObject", "(JJ)V");
 116         ASSERT(didClearWindowObjectMID);
 117 
 118         frameCreatedMID = env->GetMethodID(webPageClass, "fwkFrameCreated", "(J)V");
 119         ASSERT(frameCreatedMID);
 120 
 121         frameDestroyedMID = env->GetMethodID(webPageClass, "fwkFrameDestroyed", "(J)V");
 122         ASSERT(frameDestroyedMID);
 123     }
 124     if (!networkContextClass) {
 125         networkContextClass = JLClass(env->FindClass("com/sun/webkit/network/NetworkContext"));
 126         ASSERT(networkContextClass);
 127 
 128         canHandleURLMID = env->GetStaticMethodID(networkContextClass, "canHandleURL", "(Ljava/lang/String;)Z");
 129         ASSERT(canHandleURLMID);
 130     }
 131 }
 132 
 133 namespace WebCore {
 134 
 135 // This was copied from file "WebKit/Source/WebKit/mac/Misc/WebKitErrors.h".
 136 enum {
 137     WebKitErrorCannotShowMIMEType =                             100,
 138     WebKitErrorCannotShowURL =                                  101,
 139     WebKitErrorFrameLoadInterruptedByPolicyChange =             102,
 140     WebKitErrorCannotUseRestrictedPort =                        103,
 141     WebKitErrorCannotFindPlugIn =                               200,
 142     WebKitErrorCannotLoadPlugIn =                               201,
 143     WebKitErrorJavaUnavailable =                                202,
 144     WebKitErrorPluginWillHandleLoad =                           203
 145 };
 146 
 147 FrameLoaderClientJava::FrameLoaderClientJava(const JLObject &webPage)
 148     : m_page(0)
 149     , m_frame(0)
 150 //    , m_pluginWidget(0)
 151     , m_isPageRedirected(false)
 152     , m_webPage(webPage)
 153     , m_hasRepresentation(false)
 154     , m_FrameLoaderClientDestroyed(false)
 155     , m_ProgressTrackerClientDestroyed(false)
 156 {
 157 //   CRASH();
 158 }
 159 
 160 void FrameLoaderClientJava::destroyIfNeeded() {
 161     if (m_FrameLoaderClientDestroyed && m_ProgressTrackerClientDestroyed) {
 162 
 163     WC_GETJAVAENV_CHKRET(env);
 164         initRefs(env);
 165 
 166         ASSERT(m_webPage);
 167         ASSERT(m_frame);
 168         env->CallVoidMethod(m_webPage, frameDestroyedMID, ptr_to_jlong(m_frame));
 169         CheckAndClearException(env);
 170 
 171         m_page = 0;
 172         m_frame = 0;
 173 
 174         delete this;
 175     }
 176 }
 177 
 178 void FrameLoaderClientJava::frameLoaderDestroyed()
 179 {
 180     m_FrameLoaderClientDestroyed = true;
 181     destroyIfNeeded();
 182 }
 183 
 184 void FrameLoaderClientJava::progressTrackerDestroyed()
 185 {
 186     m_ProgressTrackerClientDestroyed = true;
 187     destroyIfNeeded();
 188 }
 189 
 190 Page* FrameLoaderClientJava::page()
 191 {
 192     if (!m_page) {
 193         m_page = WebPage::pageFromJObject(m_webPage);
 194         ASSERT(m_page);
 195     }
 196     return m_page;
 197 }
 198 
 199 Frame* FrameLoaderClientJava::frame()
 200 {
 201     return m_frame;
 202 }
 203 
 204 void FrameLoaderClientJava::setFrame(Frame* frame)
 205 {
 206     ASSERT(frame);
 207     m_frame = frame;
 208 }
 209 
 210 void FrameLoaderClientJava::setRequestURL(Frame* f, int identifier, String url)
 211 {
 212     JNIEnv* env = WebCore_GetJavaEnv();
 213     initRefs(env);
 214 
 215     JLString urlJavaString(url.toJavaString(env));
 216     env->CallVoidMethod(m_webPage, setRequestURLMID, ptr_to_jlong(f), identifier, (jstring)urlJavaString);
 217     CheckAndClearException(env);
 218 }
 219 
 220 void FrameLoaderClientJava::removeRequestURL(Frame* f, int identifier)
 221 {
 222     JNIEnv* env = WebCore_GetJavaEnv();
 223     initRefs(env);
 224 
 225     env->CallVoidMethod(m_webPage, removeRequestURLMID, ptr_to_jlong(f), identifier);
 226     CheckAndClearException(env);
 227 }
 228 
 229 void FrameLoaderClientJava::postLoadEvent(Frame* f, int state,
 230                                           String url, String contentType,
 231                                           double progress, int errorCode)
 232 {
 233     JNIEnv* env = WebCore_GetJavaEnv();
 234     initRefs(env);
 235 
 236     JLString urlJavaString(url.toJavaString(env));
 237     JLString contentTypeJavaString(contentType.toJavaString(env));
 238 
 239     // First, notify SharedBufferManager, so users can get the full source
 240     // in CONTENT_RECEIVED handler
 241     if (state == com_sun_webkit_LoadListenerClient_PAGE_STARTED ||
 242         state == com_sun_webkit_LoadListenerClient_PROGRESS_CHANGED ||
 243         state == com_sun_webkit_LoadListenerClient_CONTENT_RECEIVED)
 244     {
 245         DocumentLoader* dl = f->loader().activeDocumentLoader();
 246         unsigned size = 0;
 247         if (dl && dl->mainResourceData()) {
 248             size = dl->mainResourceData()->size(); //XXX recheck
 249         }
 250     }
 251 
 252     // Second, send a load event
 253     env->CallVoidMethod(m_webPage, fireLoadEventMID,
 254                         ptr_to_jlong(f), state, (jstring)urlJavaString,
 255                         (jstring)contentTypeJavaString, progress, errorCode);
 256     CheckAndClearException(env);
 257 }
 258 
 259 void FrameLoaderClientJava::postResourceLoadEvent(Frame* f, int state,
 260                                                   int id, String contentType,
 261                                                   double progress, int errorCode)
 262 {
 263     JNIEnv* env = WebCore_GetJavaEnv();
 264     initRefs(env);
 265 
 266     JLString contentTypeJavaString(contentType.toJavaString(env));
 267     // notification for resource event listeners
 268     env->CallVoidMethod(m_webPage, fireResourceLoadEventMID,
 269                         ptr_to_jlong(f), state, id,
 270                         (jstring)contentTypeJavaString, progress, errorCode);
 271     CheckAndClearException(env);
 272 }
 273 
 274 String FrameLoaderClientJava::userAgent(const URL&)
 275 {
 276     return page()->settings().userAgent();
 277 }
 278 
 279 void FrameLoaderClientJava::savePlatformDataToCachedFrame(CachedFrame*)
 280 {
 281     notImplemented();
 282 }
 283 
 284 void FrameLoaderClientJava::transitionToCommittedFromCachedFrame(CachedFrame*)
 285 {
 286     notImplemented();
 287 }
 288 
 289 void FrameLoaderClientJava::transitionToCommittedForNewPage()
 290 {
 291     FloatRect pageRect = frame()->page()->chrome().pageRect();
 292     Color bkColor(Color::white);
 293     bool isTransparent = false;
 294     FrameView *fv = frame()->view();
 295     if (fv) {
 296         bkColor = fv->baseBackgroundColor();
 297         isTransparent = fv->isTransparent();
 298     }
 299     frame()->createView(IntRect(pageRect).size(), bkColor, isTransparent);
 300 }
 301 
 302 WTF::Ref<WebCore::DocumentLoader> FrameLoaderClientJava::createDocumentLoader(const WebCore::ResourceRequest& request, const SubstituteData& substituteData)
 303 {
 304     return DocumentLoader::create(request, substituteData);
 305 }
 306 
 307 void FrameLoaderClientJava::dispatchWillSubmitForm(PassRefPtr<FormState>, FramePolicyFunction policyFunction)
 308 {
 309     // FIXME: This is surely too simple
 310     ASSERT(frame() && policyFunction);
 311     if (!frame() || !policyFunction) {
 312         return;
 313     }
 314     policyFunction(PolicyUse);
 315 }
 316 
 317 void FrameLoaderClientJava::committedLoad(DocumentLoader* loader, const char* data, int length)
 318 {
 319     //uta: for m_pluginWidget we need to do something different
 320     loader->commitData(data, length);
 321 }
 322 
 323 
 324 void FrameLoaderClientJava::dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, unsigned long  identifier, const AuthenticationChallenge&)
 325 {
 326     notImplemented();
 327 }
 328 
 329 void FrameLoaderClientJava::dispatchDidCancelAuthenticationChallenge(DocumentLoader*, unsigned long  identifier, const AuthenticationChallenge&)
 330 {
 331     notImplemented();
 332 }
 333 
 334 void FrameLoaderClientJava::progressStarted(Frame& originatingProgressFrame)
 335 {
 336     // shouldn't post PROGRESS_CHANGED before PAGE_STARTED
 337 }
 338 
 339 void FrameLoaderClientJava::progressEstimateChanged(Frame& originatingProgressFrame)
 340 {
 341     double progress = page()->progress().estimatedProgress();
 342     // We have a redundant notification from webkit (with progress == 1)
 343     // after PAGE_FINISHED has already been posted.
 344     DocumentLoader* dl = frame()->loader().activeDocumentLoader();
 345     if (dl && progress < 1) {
 346         postLoadEvent(frame(),
 347                       com_sun_webkit_LoadListenerClient_PROGRESS_CHANGED,
 348                       dl->url(),
 349                       dl->responseMIMEType(),
 350                       progress);
 351     }
 352 }
 353 
 354 void FrameLoaderClientJava::progressFinished(Frame& originatingProgressFrame)
 355 {
 356     // shouldn't post PROGRESS_CHANGED after PAGE_FINISHED
 357 }
 358 
 359   void FrameLoaderClientJava::dispatchDecidePolicyForResponse(const ResourceResponse& response, const ResourceRequest& request, FramePolicyFunction policyFunction)
 360 {
 361     PolicyAction action;
 362 
 363     int statusCode = response.httpStatusCode();
 364     if (statusCode == 204 || statusCode == 205) {
 365         // The server does not want us to replace the page contents.
 366         action = PolicyIgnore;
 367     } else if (WebCore::contentDispositionType(response.httpHeaderField(HTTPHeaderName::ContentDisposition)) == WebCore::ContentDispositionAttachment) {
 368         // The server wants us to download instead of replacing the page contents.
 369         // Downloading is handled by the embedder, but we still get the initial
 370         // response so that we can ignore it and clean up properly.
 371         action = PolicyIgnore;
 372     } else if (!canShowMIMEType(response.mimeType())) {
 373         // Make sure that we can actually handle this type internally.
 374         action = PolicyIgnore;
 375     } else {
 376         // OK, we will render this page.
 377         action = PolicyUse;
 378     }
 379 
 380     // NOTE: PolicyChangeError will be generated when action is not PolicyUse.
 381     policyFunction(action);
 382 }
 383 
 384 void FrameLoaderClientJava::dispatchDidReceiveResponse(DocumentLoader* l, unsigned long identifier, const ResourceResponse& response)
 385 {
 386     m_response = response;
 387 
 388     if (identifier == mainResourceRequestID) {
 389         double progress = page()->progress().estimatedProgress();
 390         postLoadEvent(frame(),
 391                       com_sun_webkit_LoadListenerClient_CONTENTTYPE_RECEIVED,
 392                       response.url().string(),
 393                       response.mimeType(),
 394                       progress);
 395     }
 396 }
 397 
 398 void FrameLoaderClientJava::dispatchDecidePolicyForNewWindowAction(const NavigationAction&,
 399                                                                    const ResourceRequest& req,
 400                                                                    PassRefPtr<FormState>,
 401                                                                    const String&,
 402                                    FramePolicyFunction policyFunction)
 403 {
 404     JNIEnv* env = WebCore_GetJavaEnv();
 405     initRefs(env);
 406 
 407     ASSERT(frame() && policyFunction);
 408     if (!frame() || !policyFunction) {
 409         return;
 410     }
 411 
 412     JLString urlString(req.url().string().toJavaString(env));
 413     bool permit = jbool_to_bool(env->CallBooleanMethod(m_webPage, permitNewWindowActionMID,
 414                                                        ptr_to_jlong(frame()), (jstring)urlString));
 415     CheckAndClearException(env);
 416 
 417     // FIXME: I think Qt version marshals this to another thread so when we
 418     // have multi-threaded download, we might need to do the same
 419     policyFunction(permit ? PolicyUse : PolicyIgnore);
 420 }
 421 
 422 void FrameLoaderClientJava::dispatchDecidePolicyForNavigationAction(const NavigationAction& action,
 423                                                                     const ResourceRequest& req,
 424                                                                     PassRefPtr<FormState> state,
 425                                                                     FramePolicyFunction policyFunction)
 426 {
 427     JNIEnv* env = WebCore_GetJavaEnv();
 428     initRefs(env);
 429 
 430     ASSERT(frame() && policyFunction);
 431     if (!frame() || !policyFunction) {
 432         return;
 433     }
 434 
 435     bool permit = true;
 436 
 437     JLString urlJavaString(req.url().string().toJavaString(env));
 438 
 439     // 1. Submitting/resubmitting data.
 440     if (action.type() == NavigationType::FormSubmitted ||
 441         action.type() == NavigationType::FormResubmitted)
 442     {
 443         JLString httpMethodString(req.httpMethod().toJavaString(env));
 444         permit = env->CallBooleanMethod(m_webPage, permitSubmitDataActionMID,
 445                                         ptr_to_jlong(frame()), (jstring)urlJavaString,
 446                                         (jstring)httpMethodString,
 447                                         bool_to_jbool(action.type() == NavigationType::FormSubmitted));
 448         CheckAndClearException(env);
 449     // 2. Redirecting page.
 450     } else if (m_isPageRedirected) {
 451         permit = env->CallBooleanMethod(m_webPage, permitRedirectActionMID,
 452                                         ptr_to_jlong(frame()), (jstring)urlJavaString);
 453         CheckAndClearException(env);
 454         m_isPageRedirected = false;
 455     // 3. Loading document.
 456     } else {
 457         permit = env->CallBooleanMethod(m_webPage, permitNavigateActionMID,
 458                                         ptr_to_jlong(frame()), (jstring)urlJavaString);
 459         CheckAndClearException(env);
 460     }
 461 
 462     policyFunction(permit ? PolicyUse : PolicyIgnore);
 463 }
 464 
 465 RefPtr<Widget> FrameLoaderClientJava::createPlugin(const IntSize& intSize, HTMLPlugInElement* element, const URL& url,
 466                                             const Vector<String>& paramNames, const Vector<String>& paramValues,
 467                                             const String& mimeType, bool loadManually)
 468 {
 469     return adoptRef(new PluginWidgetJava(
 470         m_webPage,
 471         element,
 472         intSize,
 473         url.string(),
 474         mimeType,
 475         paramNames,
 476         paramValues)); //XXX adoptRef to ?
 477 }
 478 
 479 RefPtr<Frame> FrameLoaderClientJava::createFrame(const URL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
 480                                         const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight)
 481 {
 482     JNIEnv* env = WebCore_GetJavaEnv();
 483 
 484     FrameLoaderClientJava* frameLoaderClient = new FrameLoaderClientJava(m_webPage);
 485     RefPtr<Frame> childFrame(Frame::create(page(), ownerElement, frameLoaderClient));
 486     frameLoaderClient->setFrame(childFrame.get());
 487 
 488     childFrame->tree().setName(name);
 489     m_frame->tree().appendChild(childFrame);
 490 
 491     PassRefPtr<FrameView> frameView = FrameView::create(*childFrame.get());
 492     childFrame->setView(frameView.get());
 493 
 494     childFrame->init();
 495 
 496     // gtk: The creation of the frame may have run arbitrary JS that removed it from the page already.
 497     if (!childFrame->page()) {
 498         return 0;
 499     }
 500 
 501     m_frame->loader().loadURLIntoChildFrame(url, referrer, childFrame.get());
 502 
 503     // gtk: The frame's onload handler may have removed it from the document.
 504     if (!childFrame->tree().parent()) {
 505         return 0;
 506     }
 507 
 508     env->CallVoidMethod(m_webPage, frameCreatedMID, ptr_to_jlong(childFrame.get()));
 509     CheckAndClearException(env);
 510 
 511     return childFrame;
 512 }
 513 
 514 void FrameLoaderClientJava::redirectDataToPlugin(Widget* pluginWidget)
 515 {
 516     /*
 517     ASSERT(!m_pluginWidget);
 518     m_pluginWidget = static_cast<PluginWidgetJava*>(pluginWidget);
 519     */
 520 }
 521 
 522 PassRefPtr<Widget> FrameLoaderClientJava::createJavaAppletWidget(const IntSize& intSize, HTMLAppletElement*, const URL& url,
 523                                                       const Vector<String>& paramNames, const Vector<String>& paramValues)
 524 {
 525 //    return new PluginWidgetJava(webPage(), intSize, url.string(), "application/x-java-applet", paramNames, paramValues);
 526     return 0;
 527 }
 528 
 529 ObjectContentType FrameLoaderClientJava::objectContentType(const URL& url, const String& mimeType, bool shouldPreferPlugInsForImages)
 530 {
 531     //copied from FrameLoaderClientEfl.cpp
 532 
 533     // FIXME: once plugin support is enabled, this method needs to correctly handle the 'shouldPreferPlugInsForImages' flag. See
 534     // WebCore::FrameLoader::defaultObjectContentType() for an example.
 535     UNUSED_PARAM(shouldPreferPlugInsForImages);
 536 
 537     if (url.isEmpty() && mimeType.isEmpty())
 538         return ObjectContentNone;
 539 
 540     // We don't use MIMETypeRegistry::getMIMETypeForPath() because it returns "application/octet-stream" upon failure
 541     String type = mimeType;
 542     if (type.isEmpty())
 543         type = MIMETypeRegistry::getMIMETypeForExtension(url.path().substring(url.path().reverseFind('.') + 1));
 544 
 545     if (type.isEmpty())
 546         return ObjectContentFrame;
 547 
 548     if (MIMETypeRegistry::isSupportedImageMIMEType(type))
 549         return ObjectContentImage;
 550 
 551 #if 0 // PluginDatabase is disabled until we have Plugin system done.
 552     if (PluginDatabase::installedPlugins()->isMIMETypeRegistered(mimeType))
 553         return ObjectContentNetscapePlugin;
 554 #endif
 555 
 556     if (MIMETypeRegistry::isSupportedNonImageMIMEType(type))
 557         return ObjectContentFrame;
 558 
 559     if (url.protocol() == "about")
 560         return ObjectContentFrame;
 561 
 562     return ObjectContentNone;
 563 }
 564 
 565 String FrameLoaderClientJava::overrideMediaType() const
 566 {
 567     notImplemented();
 568     return String();
 569 }
 570 
 571 void FrameLoaderClientJava::setMainFrameDocumentReady(bool)
 572 {
 573     // this is only interesting once we provide an external API for the DOM
 574 }
 575 
 576 bool FrameLoaderClientJava::hasWebView() const
 577 {
 578     notImplemented();
 579     return true;
 580 }
 581 
 582 void FrameLoaderClientJava::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* l, const ResourceRequest& req)
 583 {
 584     notImplemented();
 585 }
 586 
 587 void FrameLoaderClientJava::willReplaceMultipartContent() {
 588     notImplemented(); //XXX: recheck
 589 }
 590 
 591 void FrameLoaderClientJava::didReplaceMultipartContent() {
 592     notImplemented(); //XXX: recheck
 593 }
 594 
 595 void FrameLoaderClientJava::updateCachedDocumentLoader(DocumentLoader&) {
 596     notImplemented(); //XXX: recheck
 597 }
 598 
 599 void FrameLoaderClientJava::dispatchDidStartProvisionalLoad()
 600 {
 601     mainResourceRequestID = -1;
 602 }
 603 
 604 void FrameLoaderClientJava::dispatchWillSendRequest(DocumentLoader* l, unsigned long identifier, ResourceRequest& req, const ResourceResponse& res)
 605 {
 606     JNIEnv* env = WebCore_GetJavaEnv();
 607     initRefs(env);
 608 
 609     Frame* f = l->frame();
 610     if (!f) {
 611         f = frame();
 612     }
 613 
 614     double progress = 0.0;
 615     progress = page()->progress().estimatedProgress();
 616 
 617     if (mainResourceRequestID < 0) {
 618         mainResourceRequestID = identifier;
 619         postLoadEvent(f,
 620                       com_sun_webkit_LoadListenerClient_PAGE_STARTED,
 621                       req.url().string(),
 622                       res.mimeType(),
 623                       progress);
 624     } else if (mainResourceRequestID == identifier) { // serever-side redirection
 625         m_isPageRedirected = true;
 626         postLoadEvent(f,
 627                       com_sun_webkit_LoadListenerClient_PAGE_REDIRECTED,
 628                       req.url().string(),
 629                       res.mimeType(),
 630                       progress);
 631     } else {
 632         // Check resource policy.
 633         JLString urlJavaString(req.url().string().toJavaString(env));
 634         bool permit = jbool_to_bool(env->CallBooleanMethod(m_webPage, permitAcceptResourceActionMID,
 635                                                            ptr_to_jlong(f), (jstring)urlJavaString));
 636         CheckAndClearException(env);
 637         if (!permit) {
 638 /*
 639             req.setURL(NULL); // will cancel loading
 640 */
 641             req.setURL(URL());
 642         } else {
 643             setRequestURL(f, identifier, req.url().string());
 644             postResourceLoadEvent(f,
 645                                   com_sun_webkit_LoadListenerClient_RESOURCE_STARTED,
 646                                   identifier,
 647                                   res.mimeType(),
 648                                   0.0 /* progress */);
 649         }
 650     }
 651 }
 652 
 653 void FrameLoaderClientJava::dispatchDidFailLoading(DocumentLoader* dl, unsigned long identifier, const ResourceError& error)
 654 {
 655     Frame* f = dl->frame();
 656     if (!f) {
 657         f = frame();
 658     }
 659     postResourceLoadEvent(f,
 660                           com_sun_webkit_LoadListenerClient_RESOURCE_FAILED,
 661                           identifier,
 662                           dl->responseMIMEType(),
 663                           0.0 /* progress */,
 664                           error.errorCode());
 665     removeRequestURL(f, identifier);
 666 }
 667 
 668 void FrameLoaderClientJava::dispatchDidFailProvisionalLoad(const ResourceError& error)
 669 {
 670     ASSERT(frame());
 671     if (!frame()) {
 672         return;
 673     }
 674     DocumentLoader* dl = frame()->loader().activeDocumentLoader();
 675     if (!dl) {
 676         return;
 677     }
 678 
 679     double progress = page()->progress().estimatedProgress();
 680     int state = error.isCancellation()
 681         ? com_sun_webkit_LoadListenerClient_LOAD_STOPPED
 682         : com_sun_webkit_LoadListenerClient_LOAD_FAILED;
 683     postLoadEvent(frame(), state,
 684                   dl->url().string(),
 685                   dl->responseMIMEType(),
 686                   progress,
 687                   error.errorCode());
 688 }
 689 
 690 void FrameLoaderClientJava::dispatchDidFailLoad(const ResourceError& error)
 691 {
 692     dispatchDidFailProvisionalLoad(error);
 693 }
 694 
 695 // client-side redirection
 696 void FrameLoaderClientJava::dispatchWillPerformClientRedirect(const URL& url, double, double)
 697 {
 698 }
 699 
 700 void FrameLoaderClientJava::dispatchDidReceiveTitle(const StringWithDirection& title)
 701 {
 702     double progress = page()->progress().estimatedProgress();
 703     postLoadEvent(frame(),
 704                   com_sun_webkit_LoadListenerClient_TITLE_RECEIVED,
 705                   frame()->document()->url(),
 706                   frame()->loader().documentLoader()->responseMIMEType(),
 707                   progress);
 708 }
 709 
 710 void FrameLoaderClientJava::dispatchDidChangeIcons(IconType)
 711 {
 712     // FIXME: In order to get notified of icon URLS' changes, add a notification.
 713     // emit iconsChanged();
 714 }
 715 
 716 
 717 void FrameLoaderClientJava::dispatchDidReceiveIcon()
 718 {
 719     // not called without IconDatabase support, so sending the notification
 720     // from dispatchDidLoadMainResource()
 721     /*
 722     Frame* f = page()->mainFrame();
 723     if (!f->loader() || !f->document()) {
 724         return;
 725     }
 726 
 727     double progress = page()->progress()->estimatedProgress();
 728     postLoadEvent(com_sun_webkit_LoadListenerClient_ICON_RECEIVED,
 729                   0, // request id
 730                   f->document()->url(),
 731                   f->loader()->documentLoader()->responseMIMEType(),
 732                   progress);
 733     */
 734 }
 735 
 736 void FrameLoaderClientJava::dispatchDidReceiveContentLength(DocumentLoader* l, unsigned long identifier, int lengthReceived)
 737 {
 738     notImplemented();
 739 }
 740 
 741 void FrameLoaderClientJava::dispatchDidFinishDocumentLoad()
 742 {
 743     if (!frame()->isMainFrame()) {
 744         // send the notification for the main frame only
 745         return;
 746     }
 747 
 748     double progress = page()->progress().estimatedProgress();
 749     postLoadEvent(frame(),
 750                   com_sun_webkit_LoadListenerClient_DOCUMENT_AVAILABLE,
 751                   frame()->document()->url(),
 752                   frame()->loader().documentLoader()->responseMIMEType(),
 753                   progress);
 754 }
 755 
 756 void FrameLoaderClientJava::dispatchDidLoadMainResource(DocumentLoader* l)
 757 {
 758     double progress = page()->progress().estimatedProgress();
 759     // send ICON_RECEIVED here instead of dispatchDidReceiveIcon(),
 760     // see comments in the method for details
 761     postLoadEvent(frame(),
 762                   com_sun_webkit_LoadListenerClient_ICON_RECEIVED,
 763                   frame()->document()->url(),
 764                   l->responseMIMEType(),
 765                   progress);
 766     postLoadEvent(frame(),
 767                   com_sun_webkit_LoadListenerClient_CONTENT_RECEIVED,
 768                   l->responseURL().string(),
 769                   l->responseMIMEType(),
 770                   progress);
 771 }
 772 
 773 void FrameLoaderClientJava::dispatchDidFinishLoading(DocumentLoader* l, unsigned long identifier)
 774 {
 775     double progress = page()->progress().estimatedProgress();
 776     postResourceLoadEvent(frame(),
 777                           com_sun_webkit_LoadListenerClient_RESOURCE_FINISHED,
 778                           identifier,
 779                           l->responseMIMEType(),
 780                           1.0 /* progress */);
 781     removeRequestURL(frame(), identifier);
 782 }
 783 
 784 void FrameLoaderClientJava::dispatchDidFinishLoad()
 785 {
 786     double progress = page()->progress().estimatedProgress();
 787     postLoadEvent(frame(),
 788                   com_sun_webkit_LoadListenerClient_PAGE_FINISHED,
 789                   frame()->document()->url(),
 790                   frame()->loader().documentLoader()->responseMIMEType(),
 791                   progress);
 792 }
 793 
 794 void FrameLoaderClientJava::finishedLoading(DocumentLoader* dl)
 795 {
 796     // This is necessary to create an empty document. See bug 634004.
 797     // However, we only want to do this if makeRepresentation has been called, to
 798     // match the behavior on the Mac.
 799     if (m_hasRepresentation)
 800         dl->writer().setEncoding("", false);
 801 }
 802 
 803 void FrameLoaderClientJava::frameLoadCompleted()
 804 {
 805     notImplemented();
 806 }
 807 
 808 void FrameLoaderClientJava::saveViewStateToItem(HistoryItem*)
 809 {
 810     notImplemented();
 811 }
 812 
 813 void FrameLoaderClientJava::restoreViewState()
 814 {
 815     notImplemented();
 816 }
 817 
 818 Frame* FrameLoaderClientJava::dispatchCreatePage(const NavigationAction& action)
 819 {
 820     struct WindowFeatures features;
 821     Page* newPage = frame()->page()->chrome().createWindow(
 822         frame(),
 823         FrameLoadRequest( frame()->document()->securityOrigin(), LockHistory::No,
 824                             LockBackForwardList::No, ShouldSendReferrer::MaybeSendReferrer,
 825                             AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, //XXX check params
 826                             ShouldOpenExternalURLsPolicy::ShouldNotAllow),
 827         features,
 828         action);
 829 
 830     // createWindow can return null (e.g., popup blocker denies the window).
 831     if (!newPage)
 832         return 0;
 833 
 834     return (Frame*)(&newPage->mainFrame());
 835 }
 836 
 837 bool FrameLoaderClientJava::shouldGoToHistoryItem(HistoryItem* item) const
 838 {
 839     // FIXME: This is a very simple implementation. More sophisticated
 840     // implementation would delegate the decision to a PolicyDelegate.
 841     // See mac implementation for example.
 842     return item != 0;
 843 }
 844 
 845 const char backForwardNavigationScheme[] = "chrome-back-forward";
 846 bool FrameLoaderClientJava::shouldStopLoadingForHistoryItem(WebCore::HistoryItem *targetItem) const
 847 {
 848     // Don't stop loading for pseudo-back-forward URLs, since they will get
 849     // translated and then pass through again.
 850     const URL& url = targetItem->url();
 851     return !url.protocolIs(backForwardNavigationScheme);
 852 }
 853 
 854 void FrameLoaderClientJava::didDisplayInsecureContent()
 855 {
 856     notImplemented();
 857 }
 858 
 859 void FrameLoaderClientJava::didRunInsecureContent(SecurityOrigin*, const URL&)
 860 {
 861     notImplemented();
 862 }
 863 
 864 void FrameLoaderClientJava::didDetectXSS(const URL&, bool)
 865 {
 866     notImplemented();
 867 }
 868 
 869 bool FrameLoaderClientJava::privateBrowsingEnabled() const
 870 {
 871     notImplemented();
 872     return false;
 873 }
 874 
 875 void FrameLoaderClientJava::makeDocumentView()
 876 {
 877     notImplemented();
 878 }
 879 
 880 void FrameLoaderClientJava::makeRepresentation(DocumentLoader*)
 881 {
 882     m_hasRepresentation = true;
 883 }
 884 
 885 void FrameLoaderClientJava::forceLayout()
 886 {
 887     notImplemented();
 888 
 889     FrameView* frameView = frame()->view();
 890     if (frameView) {
 891         frameView->forceLayout(true);
 892     }
 893 }
 894 
 895 void FrameLoaderClientJava::forceLayoutForNonHTML() { notImplemented(); }
 896 void FrameLoaderClientJava::setCopiesOnScroll() { notImplemented(); }
 897 void FrameLoaderClientJava::detachedFromParent1() { notImplemented(); }
 898 void FrameLoaderClientJava::detachedFromParent2() { notImplemented(); }
 899 void FrameLoaderClientJava::detachedFromParent3() { notImplemented(); }
 900 void FrameLoaderClientJava::detachedFromParent4() { notImplemented(); }
 901 void FrameLoaderClientJava::loadedFromCachedPage() { notImplemented(); }
 902 void FrameLoaderClientJava::dispatchDidHandleOnloadEvents() {notImplemented(); }
 903 void FrameLoaderClientJava::dispatchDidPushStateWithinPage() { notImplemented(); }
 904 void FrameLoaderClientJava::dispatchDidReplaceStateWithinPage() { notImplemented(); }
 905 void FrameLoaderClientJava::dispatchDidPopStateWithinPage() { notImplemented(); }
 906 void FrameLoaderClientJava::dispatchDidAddBackForwardItem(HistoryItem*) const {
 907     // TODO: revise BackForwardList::notifyBackForwardListChanged function usage.
 908     notImplemented();
 909 }
 910 void FrameLoaderClientJava::dispatchDidRemoveBackForwardItem(HistoryItem*) const {
 911     // TODO: revise BackForwardList::notifyBackForwardListChanged function usage.
 912     notImplemented();
 913 }
 914 void FrameLoaderClientJava::dispatchDidChangeBackForwardIndex() const {
 915     // TODO: revise BackForwardList::notifyBackForwardListChanged function usage.
 916     notImplemented();
 917 }
 918 void FrameLoaderClientJava::dispatchDidReceiveServerRedirectForProvisionalLoad() { notImplemented(); }
 919 void FrameLoaderClientJava::dispatchDidCancelClientRedirect() { notImplemented(); }
 920 void FrameLoaderClientJava::dispatchDidChangeLocationWithinPage() { notImplemented(); }
 921 void FrameLoaderClientJava::dispatchWillClose() { notImplemented(); }
 922 void FrameLoaderClientJava::dispatchDidCommitLoad() {
 923     // TODO: Look at GTK version
 924     notImplemented();
 925 }
 926 void FrameLoaderClientJava::dispatchDidFirstLayout() { notImplemented(); }
 927 void FrameLoaderClientJava::dispatchDidFirstVisuallyNonEmptyLayout() { notImplemented(); }
 928 void FrameLoaderClientJava::dispatchShow() { notImplemented(); }
 929 void FrameLoaderClientJava::cancelPolicyCheck() { notImplemented(); }
 930 void FrameLoaderClientJava::revertToProvisionalState(DocumentLoader*) { notImplemented(); }
 931 void FrameLoaderClientJava::clearUnarchivingState(DocumentLoader*) { notImplemented(); }
 932 void FrameLoaderClientJava::willChangeTitle(DocumentLoader*) { notImplemented(); }
 933 void FrameLoaderClientJava::didChangeTitle(DocumentLoader *l) { setTitle(l->title(), l->url()); }
 934 void FrameLoaderClientJava::finalSetupForReplace(DocumentLoader*) { notImplemented(); }
 935 bool FrameLoaderClientJava::isArchiveLoadPending(ResourceLoader*) const { notImplemented(); return false; }
 936 void FrameLoaderClientJava::cancelPendingArchiveLoad(ResourceLoader*) { notImplemented(); }
 937 void FrameLoaderClientJava::clearArchivedResources() { notImplemented(); }
 938 
 939 bool FrameLoaderClientJava::canHandleRequest(const ResourceRequest& req) const
 940 {
 941     JNIEnv* env = WebCore_GetJavaEnv();
 942     initRefs(env);
 943 
 944     JLString urlJavaString(req.url().string().toJavaString(env));
 945     jboolean ret = env->CallStaticBooleanMethod(networkContextClass, canHandleURLMID, (jstring)urlJavaString);
 946     CheckAndClearException(env);
 947 
 948     return jbool_to_bool(ret);
 949 }
 950 
 951 bool FrameLoaderClientJava::canShowMIMEType(const String& mimeType) const
 952 {
 953     //copy from QT implementation
 954     String type(mimeType);
 955     type.lower();
 956     if (MIMETypeRegistry::isSupportedImageMIMEType(type))
 957         return true;
 958 
 959     if (MIMETypeRegistry::isSupportedNonImageMIMEType(type))
 960         return true;
 961 
 962     if (MIMETypeRegistry::isSupportedMediaMIMEType(type))
 963         return true;
 964 
 965 #if 0 // PluginDatabase is disabled until we have Plugin system done.
 966     if (m_frame && m_frame->settings().arePluginsEnabled()
 967         && PluginDatabase::installedPlugins()->isMIMETypeRegistered(type))
 968         return true;
 969 #endif
 970 
 971     return false;
 972 }
 973 
 974 bool FrameLoaderClientJava::canShowMIMETypeAsHTML(const String& MIMEType) const
 975 {
 976     notImplemented();
 977     return false;
 978 }
 979 
 980 
 981 bool FrameLoaderClientJava::representationExistsForURLScheme(const String&) const {
 982     notImplemented();
 983     return false;
 984 }
 985 
 986 String FrameLoaderClientJava::generatedMIMETypeForURLScheme(const String&) const {
 987     notImplemented();
 988     return String();
 989 }
 990 
 991 void FrameLoaderClientJava::provisionalLoadStarted() {
 992     notImplemented();
 993 }
 994 
 995 void FrameLoaderClientJava::didFinishLoad() {
 996     notImplemented();
 997 }
 998 
 999 void FrameLoaderClientJava::prepareForDataSourceReplacement() {
1000     notImplemented();
1001 }
1002 
1003 void FrameLoaderClientJava::setTitle(const StringWithDirection&, const URL&) {
1004     notImplemented();
1005 }
1006 
1007 void FrameLoaderClientJava::setDocumentViewFromCachedPage(WebCore::CachedPage*) {
1008     notImplemented();
1009 }
1010 
1011 bool FrameLoaderClientJava::dispatchDidLoadResourceFromMemoryCache(
1012     DocumentLoader*,
1013     const ResourceRequest&,
1014     const ResourceResponse&,
1015     int length)
1016 {
1017     notImplemented();
1018     return false;
1019 }
1020 
1021 void FrameLoaderClientJava::download(
1022     ResourceHandle*,
1023     const ResourceRequest&,
1024     const ResourceResponse&)
1025 {
1026     notImplemented();
1027 }
1028 
1029 ResourceError FrameLoaderClientJava::cancelledError(const ResourceRequest& request)
1030 {
1031     ResourceError error("Error", -999, request.url().string(),
1032                         "Request cancelled");
1033     error.setIsCancellation(true);
1034     return error;
1035 }
1036 
1037 ResourceError FrameLoaderClientJava::blockedError(const ResourceRequest& request)
1038 {
1039     return ResourceError("Error", WebKitErrorCannotUseRestrictedPort, request.url().string(),
1040                          "Request blocked");
1041 }
1042 
1043 ResourceError FrameLoaderClientJava::cannotShowURLError(const ResourceRequest& request)
1044 {
1045     return ResourceError("Error", WebKitErrorCannotShowURL, request.url().string(),
1046                          "Cannot show URL");
1047 }
1048 
1049 ResourceError FrameLoaderClientJava::interruptedForPolicyChangeError(const ResourceRequest& request)
1050 {
1051     return ResourceError("Error", WebKitErrorFrameLoadInterruptedByPolicyChange,
1052                          request.url().string(), "Frame load interrupted by policy change");
1053 }
1054 
1055 ResourceError FrameLoaderClientJava::cannotShowMIMETypeError(const ResourceResponse& response)
1056 {
1057     return ResourceError("Error", WebKitErrorCannotShowMIMEType, response.url().string(),
1058                          "Cannot show mimetype");
1059 }
1060 
1061 ResourceError FrameLoaderClientJava::fileDoesNotExistError(const ResourceResponse& response)
1062 {
1063     return ResourceError("Error", -998 /* ### */, response.url().string(),
1064                          "File does not exist");
1065 }
1066 
1067 ResourceError FrameLoaderClientJava::pluginWillHandleLoadError(const ResourceResponse& response)
1068 {
1069     return ResourceError("Error", WebKitErrorPluginWillHandleLoad, response.url().string(), "Loading is handled by the media engine");
1070 }
1071 
1072 bool FrameLoaderClientJava::shouldFallBack(const ResourceError& error) {
1073     //Font fallback supported by Java Fonts internaly
1074     return !(error.isCancellation() || (error.errorCode() == WebKitErrorFrameLoadInterruptedByPolicyChange));
1075 }
1076 
1077 bool FrameLoaderClientJava::canCachePage() const {
1078     return true;
1079 }
1080 
1081 void FrameLoaderClientJava::didSaveToPageCache() {
1082 }
1083 
1084 void FrameLoaderClientJava::didRestoreFromPageCache() {
1085 }
1086 
1087 void FrameLoaderClientJava::dispatchUnableToImplementPolicy(const ResourceError&) {
1088     notImplemented();
1089 }
1090 
1091 void FrameLoaderClientJava::dispatchDidBecomeFrameset(bool) {
1092    notImplemented();
1093 }
1094 
1095 
1096 void FrameLoaderClientJava::setMainDocumentError(
1097     DocumentLoader*,
1098     const ResourceError&)
1099 {
1100 //    if (m_pluginWidget) {
1101 //        m_pluginWidget = 0;
1102 //    }
1103     notImplemented();
1104 }
1105 
1106 void FrameLoaderClientJava::startDownload(const ResourceRequest&, const String& suggestedName) {
1107     notImplemented();
1108 }
1109 
1110 void FrameLoaderClientJava::updateGlobalHistory() {
1111     notImplemented();
1112 }
1113 
1114 void FrameLoaderClientJava::updateGlobalHistoryRedirectLinks() {
1115     notImplemented();
1116 }
1117 
1118 void FrameLoaderClientJava::dispatchDidClearWindowObjectInWorld(
1119     DOMWrapperWorld& world)
1120 {
1121     JNIEnv* env = WebCore_GetJavaEnv();
1122     initRefs(env);
1123 
1124     if (&world != &mainThreadNormalWorld()) {
1125         return;
1126     }
1127 
1128     JSGlobalContextRef context = toGlobalRef(frame()->script().globalObject(
1129             mainThreadNormalWorld())->globalExec());
1130     JSObjectRef windowObject = JSContextGetGlobalObject(context);
1131 
1132     env->CallVoidMethod(m_webPage, didClearWindowObjectMID,
1133             ptr_to_jlong(context), ptr_to_jlong(windowObject));
1134     CheckAndClearException(env);
1135 }
1136 
1137 void FrameLoaderClientJava::documentElementAvailable()
1138 {
1139 }
1140 
1141 void FrameLoaderClientJava::didPerformFirstNavigation() const {
1142     //notImplemented();
1143 }
1144 
1145 void FrameLoaderClientJava::registerForIconNotification(bool) {
1146     //notImplemented();
1147 }
1148 
1149 void FrameLoaderClientJava::didTransferChildFrameToNewDocument(Page*) {
1150     //notImplemented();
1151 }
1152 
1153 void FrameLoaderClientJava::transferLoadingResourceFromPage(ResourceLoader*, const ResourceRequest&, Page*)
1154 {
1155     //notImplemented();
1156 }
1157 
1158 void FrameLoaderClientJava::convertMainResourceLoadToDownload(DocumentLoader*, const ResourceRequest&, const ResourceResponse&)
1159 {
1160     //notImplemented();
1161 }
1162 
1163 PassRefPtr<FrameNetworkingContext> FrameLoaderClientJava::createNetworkingContext() {
1164     return FrameNetworkingContextJava::create(frame());
1165 }
1166 
1167 
1168 bool FrameLoaderClientJava::shouldUseCredentialStorage(
1169     DocumentLoader*,
1170     unsigned long identifier)
1171 {
1172     notImplemented();
1173     return false;
1174 }
1175 
1176 
1177 }