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