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 "ChromeClientJava.h"
  29 #if ENABLE(INPUT_TYPE_COLOR)
  30 #include "ColorChooserJava.h"
  31 #endif
  32 #include "ContextMenu.h"
  33 #if ENABLE(DATE_AND_TIME_INPUT_TYPES)
  34 #include "DateTimeChooser.h"
  35 #endif
  36 #include "DocumentLoader.h"
  37 #include "FileChooser.h"
  38 #include "FileIconLoader.h"
  39 #include "FloatRect.h"
  40 #include "Frame.h"
  41 #include "MainFrame.h"
  42 #include "FrameLoadRequest.h"
  43 #include "FrameLoader.h"
  44 #include "FrameView.h"
  45 #include "HitTestResult.h"
  46 #include "Icon.h"
  47 #include "IntRect.h"
  48 #include "URL.h"
  49 #include "NotImplemented.h"
  50 #include "Page.h"
  51 #include "PopupMenuJava.h"
  52 #include "ResourceRequest.h"
  53 #include "SearchPopupMenuJava.h"
  54 #include "WebPage.h"
  55 #include "Widget.h"
  56 #include "WindowFeatures.h"
  57 #include "DragController.h"
  58 #include <wtf/text/StringBuilder.h>
  59 
  60 namespace ChromeClientJavaInternal {
  61 //MVM -ready initialization
  62 #define DECLARE_STATIC_CLASS(getFunctionName, sClassPath) \
  63 static jclass getFunctionName() { \
  64     static JGClass cls(WebCore_GetJavaEnv()->FindClass(sClassPath)); \
  65     ASSERT(cls); \
  66     return cls; \
  67 }
  68 
  69 DECLARE_STATIC_CLASS(getWebPageCls,   "com/sun/webkit/WebPage")
  70 DECLARE_STATIC_CLASS(getRectangleCls, "com/sun/webkit/graphics/WCRectangle")
  71 DECLARE_STATIC_CLASS(getPointCls,     "com/sun/webkit/graphics/WCPoint")
  72 
  73 static jfieldID rectxFID = NULL; // Rectangle
  74 static jfieldID rectyFID = NULL; // Rectangle
  75 static jfieldID rectwFID = NULL; // Rectangle
  76 static jfieldID recthFID = NULL; // Rectangle
  77 
  78 static jmethodID pointCTOR = NULL; //Point
  79 static jmethodID pointGetXMID = NULL; //Point
  80 static jmethodID pointGetYMID = NULL; //Point
  81 
  82 static jmethodID getHostWindowMID = NULL; // WebPage
  83 
  84 static jmethodID getWindowBoundsMID = NULL; // WebPage
  85 static jmethodID setWindowBoundsMID = NULL; // WebPage
  86 static jmethodID getPageBoundsMID = NULL; // WebPage
  87 static jmethodID setCursorMID = NULL; // WebPage
  88 static jmethodID setFocusMID = NULL; // WebPage
  89 static jmethodID transferFocusMID = NULL;
  90 static jmethodID setTooltipMID = NULL;
  91 
  92 static jmethodID createWindowMID = NULL;
  93 static jmethodID showWindowMID = NULL;
  94 static jmethodID closeWindowMID = NULL;
  95 
  96 static jmethodID setScrollbarsVisibleMID = NULL;
  97 static jmethodID setStatusbarTextMID = NULL;
  98 
  99 static jmethodID alertMID = NULL;
 100 static jmethodID confirmMID = NULL;
 101 static jmethodID promptMID = NULL;
 102 
 103 static jmethodID addMessageToConsoleMID = NULL; // WebPage
 104 
 105 static jmethodID canRunBeforeUnloadConfirmPanelMID = NULL; // WebPage
 106 static jmethodID runBeforeUnloadConfirmPanelMID = NULL; // WebPage
 107 
 108 static jmethodID screenToWindowMID = NULL; // WebPage
 109 static jmethodID windowToScreenMID = NULL; // WebPage
 110 
 111 
 112 static jmethodID chooseFileMID = NULL; // WebPage
 113 
 114 static void initRefs(JNIEnv* env)
 115 {
 116     if (!getHostWindowMID) {
 117         getHostWindowMID = env->GetMethodID(getWebPageCls(), "getHostWindow",
 118                                             "()Lcom/sun/webkit/WCWidget;");
 119         ASSERT(getHostWindowMID);
 120 
 121         getWindowBoundsMID = env->GetMethodID(getWebPageCls(), "fwkGetWindowBounds",
 122                                               "()Lcom/sun/webkit/graphics/WCRectangle;");
 123         ASSERT(getWindowBoundsMID);
 124         setWindowBoundsMID = env->GetMethodID(getWebPageCls(), "fwkSetWindowBounds", "(IIII)V");
 125         ASSERT(setWindowBoundsMID);
 126         getPageBoundsMID = env->GetMethodID(getWebPageCls(), "fwkGetPageBounds",
 127                                             "()Lcom/sun/webkit/graphics/WCRectangle;");
 128         ASSERT(getPageBoundsMID);
 129         setCursorMID = env->GetMethodID(getWebPageCls(), "fwkSetCursor", "(J)V");
 130         ASSERT(setCursorMID);
 131         setFocusMID = env->GetMethodID(getWebPageCls(), "fwkSetFocus", "(Z)V");
 132         ASSERT(setFocusMID);
 133         transferFocusMID = env->GetMethodID(getWebPageCls(), "fwkTransferFocus", "(Z)V");
 134         ASSERT(transferFocusMID);
 135         setTooltipMID = env->GetMethodID(getWebPageCls(), "fwkSetTooltip",
 136                                          "(Ljava/lang/String;)V");
 137         ASSERT(setTooltipMID);
 138 
 139         createWindowMID = env->GetMethodID(getWebPageCls(), "fwkCreateWindow",
 140             "(ZZZZ)Lcom/sun/webkit/WebPage;");
 141         ASSERT(createWindowMID);
 142         closeWindowMID = env->GetMethodID(getWebPageCls(), "fwkCloseWindow", "()V");
 143         ASSERT(closeWindowMID);
 144         showWindowMID = env->GetMethodID(getWebPageCls(), "fwkShowWindow", "()V");
 145         ASSERT(showWindowMID);
 146 
 147         setScrollbarsVisibleMID = env->GetMethodID(getWebPageCls(), "fwkSetScrollbarsVisible", "(Z)V");
 148         ASSERT(setScrollbarsVisibleMID);
 149         setStatusbarTextMID = env->GetMethodID(getWebPageCls(), "fwkSetStatusbarText",
 150                                                "(Ljava/lang/String;)V");
 151         ASSERT(setStatusbarTextMID);
 152         alertMID = env->GetMethodID(getWebPageCls(), "fwkAlert", "(Ljava/lang/String;)V");
 153         ASSERT(alertMID);
 154         confirmMID = env->GetMethodID(getWebPageCls(), "fwkConfirm", "(Ljava/lang/String;)Z");
 155         ASSERT(confirmMID);
 156         promptMID = env->GetMethodID(getWebPageCls(), "fwkPrompt",
 157                                      "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
 158         ASSERT(promptMID);
 159 
 160         addMessageToConsoleMID = env->GetMethodID(getWebPageCls(),
 161                 "fwkAddMessageToConsole",
 162                 "(Ljava/lang/String;ILjava/lang/String;)V");
 163         ASSERT(addMessageToConsoleMID);
 164 
 165 
 166         canRunBeforeUnloadConfirmPanelMID = env->GetMethodID(getWebPageCls(),
 167                 "fwkCanRunBeforeUnloadConfirmPanel",
 168                 "()Z");
 169         ASSERT(canRunBeforeUnloadConfirmPanelMID);
 170 
 171         runBeforeUnloadConfirmPanelMID = env->GetMethodID(getWebPageCls(),
 172                 "fwkRunBeforeUnloadConfirmPanel",
 173                 "(Ljava/lang/String;)Z");
 174         ASSERT(runBeforeUnloadConfirmPanelMID);
 175 
 176         screenToWindowMID = env->GetMethodID(getWebPageCls(), "fwkScreenToWindow",
 177             "(Lcom/sun/webkit/graphics/WCPoint;)Lcom/sun/webkit/graphics/WCPoint;");
 178         ASSERT(screenToWindowMID);
 179 
 180         windowToScreenMID = env->GetMethodID(getWebPageCls(), "fwkWindowToScreen",
 181             "(Lcom/sun/webkit/graphics/WCPoint;)Lcom/sun/webkit/graphics/WCPoint;");
 182         ASSERT(windowToScreenMID);
 183 
 184         chooseFileMID = env->GetMethodID(getWebPageCls(), "fwkChooseFile",
 185             "(Ljava/lang/String;ZLjava/lang/String;)[Ljava/lang/String;");
 186         ASSERT(chooseFileMID);
 187     }
 188     if (!rectxFID) {
 189         rectxFID = env->GetFieldID(getRectangleCls(), "x", "F");
 190         ASSERT(rectxFID);
 191         rectyFID = env->GetFieldID(getRectangleCls(), "y", "F");
 192         ASSERT(rectyFID);
 193         rectwFID = env->GetFieldID(getRectangleCls(), "w", "F");
 194         ASSERT(rectwFID);
 195         recthFID = env->GetFieldID(getRectangleCls(), "h", "F");
 196         ASSERT(recthFID);
 197     }
 198     if (!pointGetXMID) {
 199         pointGetXMID = env->GetMethodID(getPointCls(), "getX", "()F");
 200         ASSERT(pointGetXMID);
 201         pointGetYMID = env->GetMethodID(getPointCls(), "getY", "()F");
 202         ASSERT(pointGetYMID);
 203         pointCTOR = env->GetMethodID(getPointCls(), "<init>", "(FF)V");
 204         ASSERT(pointCTOR);
 205     }
 206 }
 207 }
 208 
 209 namespace WebCore {
 210 
 211 ChromeClientJava::ChromeClientJava(const JLObject &webPage)
 212     : m_webPage(webPage)
 213 {
 214 }
 215 
 216 void ChromeClientJava::chromeDestroyed()
 217 {
 218     delete this;
 219 }
 220 
 221 #if ENABLE(INPUT_TYPE_COLOR)
 222 std::unique_ptr<ColorChooser> ChromeClientJava::createColorChooser(ColorChooserClient& client, const Color& initialColor)
 223 {
 224     return std::make_unique<ColorChooserJava>(m_webPage, &client, initialColor);
 225 }
 226 #endif
 227 
 228 FloatRect ChromeClientJava::windowRect()
 229 {
 230     using namespace ChromeClientJavaInternal;
 231     JNIEnv* env = WebCore_GetJavaEnv();
 232     initRefs(env);
 233 
 234     JLObject rect(env->CallObjectMethod(m_webPage, getWindowBoundsMID));
 235     CheckAndClearException(env);
 236 
 237     if (rect) {
 238         jfloat x = env->GetFloatField(rect, rectxFID);
 239         jfloat y = env->GetFloatField(rect, rectyFID);
 240         jfloat width = env->GetFloatField(rect, rectwFID);
 241         jfloat height = env->GetFloatField(rect, recthFID);
 242         return FloatRect(float(x), float(y), float(width), float(height));
 243     } else {
 244         return IntRect(0, 0, 0, 0);
 245     }
 246 }
 247 
 248 void ChromeClientJava::setWindowRect(const FloatRect &r)
 249 {
 250     using namespace ChromeClientJavaInternal;
 251     JNIEnv* env = WebCore_GetJavaEnv();
 252     initRefs(env);
 253 
 254     env->CallObjectMethod(m_webPage, setWindowBoundsMID,
 255                           (int)(r.x()), (int)(r.y()), (int)(r.width()), (int)(r.height()));
 256     CheckAndClearException(env);
 257 }
 258 
 259 FloatRect ChromeClientJava::pageRect()
 260 {
 261     using namespace ChromeClientJavaInternal;
 262     JNIEnv* env = WebCore_GetJavaEnv();
 263     initRefs(env);
 264 
 265     ASSERT(m_webPage);
 266 
 267     JLObject rect(env->CallObjectMethod(m_webPage, getPageBoundsMID));
 268     CheckAndClearException(env);
 269 
 270     if (rect) {
 271         jfloat x = env->GetFloatField(rect, rectxFID);
 272         jfloat y = env->GetFloatField(rect, rectyFID);
 273         jfloat width = env->GetFloatField(rect, rectwFID);
 274         jfloat height = env->GetFloatField(rect, recthFID);
 275         return FloatRect(float(x), float(y), float(width), float(height));
 276     } else {
 277         return FloatRect(0, 0, 0, 0);
 278     }
 279 }
 280 
 281 void ChromeClientJava::focus()
 282 {
 283     using namespace ChromeClientJavaInternal;
 284     JNIEnv* env = WebCore_GetJavaEnv();
 285     initRefs(env);
 286 
 287     ASSERT(m_webPage);
 288 
 289     env->CallVoidMethod(m_webPage, setFocusMID, JNI_TRUE);
 290     CheckAndClearException(env);
 291 }
 292 
 293 void ChromeClientJava::unfocus()
 294 {
 295     using namespace ChromeClientJavaInternal;
 296     JNIEnv* env = WebCore_GetJavaEnv();
 297     initRefs(env);
 298 
 299     ASSERT(m_webPage);
 300 
 301     env->CallVoidMethod(m_webPage, setFocusMID, JNI_FALSE);
 302     CheckAndClearException(env);
 303 }
 304 
 305 bool ChromeClientJava::canTakeFocus(FocusDirection)
 306 {
 307     return true;
 308 }
 309 
 310 void ChromeClientJava::takeFocus(FocusDirection direction)
 311 {
 312     using namespace ChromeClientJavaInternal;
 313     JNIEnv* env = WebCore_GetJavaEnv();
 314     initRefs(env);
 315 
 316     ASSERT(m_webPage);
 317 
 318     env->CallVoidMethod(m_webPage, transferFocusMID, direction == FocusDirectionForward);
 319     CheckAndClearException(env);
 320 }
 321 
 322 void ChromeClientJava::focusedElementChanged(Element*)
 323 {
 324     notImplemented();
 325 }
 326 
 327 void ChromeClientJava::focusedFrameChanged(Frame*)
 328 {
 329     notImplemented();
 330 }
 331 
 332 Page* ChromeClientJava::createWindow(
 333     Frame&,
 334     const FrameLoadRequest& req,
 335     const WindowFeatures& features,
 336     const NavigationAction& na)
 337 {
 338     using namespace ChromeClientJavaInternal;
 339     JNIEnv* env = WebCore_GetJavaEnv();
 340     initRefs(env);
 341 
 342     JLObject newWebPage(
 343         env->CallObjectMethod(
 344             m_webPage, createWindowMID,
 345             bool_to_jbool(features.menuBarVisible),
 346             bool_to_jbool(features.statusBarVisible),
 347             bool_to_jbool(features.toolBarVisible || features.locationBarVisible),
 348             bool_to_jbool(features.resizable)));
 349     CheckAndClearException(env);
 350 
 351     if (!newWebPage) {
 352         return 0;
 353     }
 354 
 355     Page* p = WebPage::pageFromJObject(newWebPage);
 356     if (!req.isEmpty()) {
 357         p->mainFrame().loader().load(
 358             FrameLoadRequest(p->mainFrame(), ResourceRequest(na.url()), req.shouldOpenExternalURLsPolicy()));
 359     }
 360 
 361     return p;
 362 }
 363 
 364 void ChromeClientJava::closeWindowSoon()
 365 {
 366     using namespace ChromeClientJavaInternal;
 367     JNIEnv* env = WebCore_GetJavaEnv();
 368     initRefs(env);
 369 
 370     env->CallVoidMethod(m_webPage, closeWindowMID);
 371     CheckAndClearException(env);
 372 }
 373 
 374 void ChromeClientJava::show()
 375 {
 376     using namespace ChromeClientJavaInternal;
 377     JNIEnv* env = WebCore_GetJavaEnv();
 378     initRefs(env);
 379 
 380     env->CallVoidMethod(m_webPage, showWindowMID);
 381     CheckAndClearException(env);
 382 }
 383 
 384 bool ChromeClientJava::canRunModal()
 385 {
 386     notImplemented();
 387     return false;
 388 }
 389 
 390 void ChromeClientJava::runModal()
 391 {
 392     notImplemented();
 393 }
 394 
 395 void ChromeClientJava::setResizable(bool)
 396 {
 397     notImplemented();
 398 }
 399 
 400 void ChromeClientJava::setToolbarsVisible(bool)
 401 {
 402     notImplemented();
 403 }
 404 
 405 bool ChromeClientJava::toolbarsVisible()
 406 {
 407     notImplemented();
 408     return false;
 409 }
 410 
 411 void ChromeClientJava::setStatusbarVisible(bool)
 412 {
 413     notImplemented();
 414 }
 415 
 416 bool ChromeClientJava::statusbarVisible()
 417 {
 418     notImplemented();
 419     return false;
 420 }
 421 
 422 void ChromeClientJava::setScrollbarsVisible(bool v)
 423 {
 424     using namespace ChromeClientJavaInternal;
 425     JNIEnv* env = WebCore_GetJavaEnv();
 426     initRefs(env);
 427 
 428     env->CallVoidMethod(m_webPage, setScrollbarsVisibleMID, bool_to_jbool(v));
 429     CheckAndClearException(env);
 430 }
 431 
 432 bool ChromeClientJava::scrollbarsVisible()
 433 {
 434     notImplemented();
 435     return false;
 436 }
 437 
 438 void ChromeClientJava::setMenubarVisible(bool)
 439 {
 440     notImplemented();
 441 }
 442 
 443 bool ChromeClientJava::menubarVisible()
 444 {
 445     notImplemented();
 446     return false;
 447 }
 448 
 449 void ChromeClientJava::setStatusbarText(const String& text)
 450 {
 451     using namespace ChromeClientJavaInternal;
 452     JNIEnv* env = WebCore_GetJavaEnv();
 453     initRefs(env);
 454 
 455     env->CallVoidMethod(m_webPage, setStatusbarTextMID, (jstring)text.toJavaString(env));
 456     CheckAndClearException(env);
 457 }
 458 
 459 void ChromeClientJava::setCursor(const Cursor& c)
 460 {
 461     using namespace ChromeClientJavaInternal;
 462     JNIEnv* env = WebCore_GetJavaEnv();
 463     initRefs(env);
 464 
 465     ASSERT(m_webPage);
 466 
 467     env->CallVoidMethod(m_webPage, setCursorMID, c.platformCursor());
 468     CheckAndClearException(env);
 469 }
 470 
 471 void ChromeClientJava::setCursorHiddenUntilMouseMoves(bool)
 472 {
 473     notImplemented();
 474 }
 475 
 476 void ChromeClientJava::runJavaScriptAlert(Frame&, const String& text)
 477 {
 478     using namespace ChromeClientJavaInternal;
 479     JNIEnv* env = WebCore_GetJavaEnv();
 480     initRefs(env);
 481 
 482     env->CallVoidMethod(m_webPage, alertMID, (jstring)text.toJavaString(env));
 483     CheckAndClearException(env);
 484 }
 485 
 486 bool ChromeClientJava::runJavaScriptConfirm(Frame&, const String& text)
 487 {
 488     using namespace ChromeClientJavaInternal;
 489     JNIEnv* env = WebCore_GetJavaEnv();
 490     initRefs(env);
 491 
 492     jboolean res = env->CallBooleanMethod(m_webPage, confirmMID, (jstring)text.toJavaString(env));
 493     CheckAndClearException(env);
 494 
 495     return jbool_to_bool(res);
 496 }
 497 
 498 bool ChromeClientJava::runJavaScriptPrompt(Frame&, const String& text,
 499                                            const String& defaultValue, String& result)
 500 {
 501     using namespace ChromeClientJavaInternal;
 502     JNIEnv* env = WebCore_GetJavaEnv();
 503     initRefs(env);
 504 
 505     bool resb = false;
 506 
 507     JLString resJ(static_cast<jstring>(
 508         env->CallObjectMethod(m_webPage, promptMID,
 509             (jstring)text.toJavaString(env),
 510             (jstring)defaultValue.toJavaString(env))
 511     ));
 512     CheckAndClearException(env);
 513     if (resJ) {
 514         result = String(env, resJ);
 515         resb = true;
 516     }
 517 
 518     return resb;
 519 }
 520 
 521 void ChromeClientJava::runOpenPanel(Frame&, FileChooser& fileChooser)
 522 {
 523     using namespace ChromeClientJavaInternal;
 524     JNIEnv* env = WebCore_GetJavaEnv();
 525     initRefs(env);
 526 
 527     StringBuilder builder;
 528     const Vector<String>& acceptTypeList = fileChooser.settings().acceptMIMETypes;
 529     for (unsigned i = 0; i < acceptTypeList.size(); ++i) {
 530         if (i > 0)
 531             builder.append(',');
 532         builder.append(acceptTypeList[i]);
 533     }
 534 
 535     JLString initialFilename;
 536     const Vector<String> &filenames = fileChooser.settings().selectedFiles;
 537     if (filenames.size() > 0) {
 538         initialFilename = filenames[0].toJavaString(env);
 539     }
 540 
 541     bool multiple = fileChooser.settings().allowsMultipleFiles;
 542     JLocalRef<jobjectArray> jfiles(static_cast<jobjectArray>(
 543         env->CallObjectMethod(m_webPage, chooseFileMID,
 544                               (jstring)initialFilename, multiple,
 545                               (jstring)(builder.toString().toJavaString(env)))));
 546     CheckAndClearException(env);
 547 
 548     if (jfiles) {
 549         Vector<String> files;
 550         jsize length = env->GetArrayLength(jfiles);
 551         for (int i = 0; i < length; i++) {
 552             JLString f((jstring) env->GetObjectArrayElement(jfiles, i));
 553             files.append(String(env, f));
 554         }
 555         fileChooser.chooseFiles(files);
 556     }
 557 }
 558 
 559 void ChromeClientJava::loadIconForFiles(const Vector<String>& filenames, FileIconLoader& loader)
 560 {
 561     loader.iconLoaded(Icon::createIconForFiles(filenames));
 562 }
 563 
 564 bool ChromeClientJava::canRunBeforeUnloadConfirmPanel()
 565 {
 566     using namespace ChromeClientJavaInternal;
 567     JNIEnv* env = WebCore_GetJavaEnv();
 568     initRefs(env);
 569 
 570     auto result = env->CallBooleanMethod(m_webPage, canRunBeforeUnloadConfirmPanelMID);
 571     CheckAndClearException(env);
 572     return result;
 573 }
 574 
 575 bool ChromeClientJava::runBeforeUnloadConfirmPanel(const String& message, Frame&)
 576 {
 577     using namespace ChromeClientJavaInternal;
 578     JNIEnv* env = WebCore_GetJavaEnv();
 579     initRefs(env);
 580 
 581     auto result = env->CallBooleanMethod(m_webPage, runBeforeUnloadConfirmPanelMID, (jstring)message.toJavaString(env));
 582     CheckAndClearException(env);
 583     return result;
 584 }
 585 
 586 void ChromeClientJava::addMessageToConsole(MessageSource, MessageLevel, const String& message,
 587     unsigned lineNumber, unsigned, const String& sourceID)
 588 {
 589     using namespace ChromeClientJavaInternal;
 590     JNIEnv* env = WebCore_GetJavaEnv();
 591     initRefs(env);
 592 
 593     env->CallVoidMethod(m_webPage, addMessageToConsoleMID,
 594             (jstring)message.toJavaString(env),
 595             (jint)lineNumber,
 596             (jstring)sourceID.toJavaString(env));
 597     CheckAndClearException(env);
 598 }
 599 
 600 KeyboardUIMode ChromeClientJava::keyboardUIMode()
 601 {
 602     return KeyboardAccessTabsToLinks;
 603 }
 604 
 605 void ChromeClientJava::mouseDidMoveOverElement(const HitTestResult& htr, unsigned)
 606 {
 607     static Node* mouseOverNode = 0;
 608     Element* urlElement = htr.URLElement();
 609     if (urlElement && isDraggableLink(*urlElement)) {
 610         Node* overNode = htr.innerNode();
 611         URL url = htr.absoluteLinkURL();
 612         if (!url.isEmpty() && (overNode != mouseOverNode)) {
 613             setStatusbarText(url.string());
 614             mouseOverNode = overNode;
 615         }
 616     } else {
 617         if (mouseOverNode) {
 618             setStatusbarText("");
 619             mouseOverNode = 0;
 620         }
 621     }
 622 }
 623 
 624 void ChromeClientJava::setToolTip(const String& tooltip, TextDirection)
 625 {
 626     using namespace ChromeClientJavaInternal;
 627     JNIEnv* env = WebCore_GetJavaEnv();
 628     initRefs(env);
 629 
 630     JLString tooltipStr(NULL);
 631     if (tooltip.length() > 0) {
 632         tooltipStr = tooltip.toJavaString(env);
 633     }
 634     env->CallVoidMethod(m_webPage, setTooltipMID, (jstring)tooltipStr);
 635     CheckAndClearException(env);
 636 }
 637 
 638 void ChromeClientJava::print(Frame&)
 639 {
 640     using namespace ChromeClientJavaInternal;
 641     JNIEnv* env = WebCore_GetJavaEnv();
 642     initRefs(env);
 643 
 644     static jmethodID mid =  env->GetMethodID(
 645         getWebPageCls(),
 646         "fwkPrint",
 647         "()V");
 648     ASSERT(mid);
 649 
 650     env->CallVoidMethod(m_webPage, mid);
 651     CheckAndClearException(env);
 652 }
 653 
 654 void ChromeClientJava::exceededDatabaseQuota(Frame&, const String&, DatabaseDetails) {
 655     notImplemented();
 656 }
 657 
 658 void ChromeClientJava::reachedMaxAppCacheSize(int64_t)
 659 {
 660     // FIXME: Free some space.
 661     notImplemented();
 662 }
 663 
 664 void ChromeClientJava::reachedApplicationCacheOriginQuota(SecurityOrigin&, int64_t)
 665 {
 666     notImplemented();
 667 }
 668 
 669 #if USE(ACCELERATED_COMPOSITING)
 670 void ChromeClientJava::attachRootGraphicsLayer(Frame*, GraphicsLayer* layer)
 671 {
 672     WebPage::webPageFromJObject(m_webPage)->setRootChildLayer(layer);
 673 }
 674 
 675 void ChromeClientJava::setNeedsOneShotDrawingSynchronization()
 676 {
 677     WebPage::webPageFromJObject(m_webPage)
 678             ->setNeedsOneShotDrawingSynchronization();
 679 }
 680 
 681 void ChromeClientJava::scheduleCompositingLayerFlush()
 682 {
 683     WebPage::webPageFromJObject(m_webPage)->scheduleCompositingLayerSync();
 684 }
 685 #endif // USE(ACCELERATED_COMPOSITING)
 686 
 687 void ChromeClientJava::attachViewOverlayGraphicsLayer(Frame&, GraphicsLayer*) {
 688     notImplemented();
 689 }
 690 
 691 // HostWindow interface
 692 void ChromeClientJava::scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
 693 {
 694     WebPage::webPageFromJObject(m_webPage)->scroll(scrollDelta, rectToScroll, clipRect);
 695 }
 696 
 697 IntPoint ChromeClientJava::screenToRootView(const IntPoint& p) const
 698 {
 699     using namespace ChromeClientJavaInternal;
 700     JNIEnv* env = WebCore_GetJavaEnv();
 701     initRefs(env);
 702     JLObject ptScreen(env->NewObject(
 703         getPointCls(),
 704         pointCTOR,
 705         jfloat(p.x()),
 706         jfloat(p.y())
 707     ));
 708     JLObject ptWindows(env->CallObjectMethod(
 709         m_webPage,
 710         screenToWindowMID,
 711         jobject(ptScreen)));
 712     return IntPoint(
 713         int(env->CallFloatMethod(
 714             ptWindows,
 715             pointGetXMID)),
 716         int(env->CallFloatMethod(
 717             ptWindows,
 718             pointGetYMID))
 719     );
 720 }
 721 
 722 IntRect ChromeClientJava::rootViewToScreen(const IntRect& r) const
 723 {
 724     using namespace ChromeClientJavaInternal;
 725     JNIEnv* env = WebCore_GetJavaEnv();
 726     initRefs(env);
 727     JLObject ptWindow(env->NewObject(
 728         getPointCls(),
 729         pointCTOR,
 730         jfloat(r.x()),
 731         jfloat(r.y())
 732     ));
 733     JLObject ptScreen(env->CallObjectMethod(
 734         m_webPage,
 735         windowToScreenMID,
 736         jobject(ptWindow)));
 737     return IntRect(
 738         int(env->CallFloatMethod(
 739             ptScreen,
 740             pointGetXMID)),
 741         int(env->CallFloatMethod(
 742             ptScreen,
 743             pointGetYMID)),
 744         r.width(),
 745         r.height()
 746     );
 747 }
 748 
 749 PlatformPageClient ChromeClientJava::platformPageClient() const
 750 {
 751     using namespace ChromeClientJavaInternal;
 752     JNIEnv* env = WebCore_GetJavaEnv();
 753     initRefs(env);
 754 
 755     JLObject hostWindow(env->CallObjectMethod(m_webPage, getHostWindowMID));
 756     ASSERT(hostWindow);
 757     CheckAndClearException(env);
 758 
 759     return hostWindow;
 760 }
 761 
 762 void ChromeClientJava::contentsSizeChanged(Frame&, const IntSize&) const
 763 {
 764     notImplemented();
 765 }
 766 
 767 void ChromeClientJava::invalidateRootView(const IntRect&)
 768 {
 769     // Nothing to do here as all necessary repaints are scheduled
 770     // by ChromeClientJava::scroll(). See also RT-29123.
 771 }
 772 
 773 void ChromeClientJava::invalidateContentsAndRootView(const IntRect& updateRect)
 774 {
 775     repaint(updateRect);
 776 }
 777 
 778 void ChromeClientJava::invalidateContentsForSlowScroll(const IntRect& updateRect)
 779 {
 780     repaint(updateRect);
 781 }
 782 
 783 void ChromeClientJava::repaint(const IntRect& r)
 784 {
 785     WebPage::webPageFromJObject(m_webPage)->repaint(r);
 786 }
 787 
 788 bool ChromeClientJava::selectItemWritingDirectionIsNatural()
 789 {
 790     return false;
 791 }
 792 
 793 bool ChromeClientJava::selectItemAlignmentFollowsMenuWritingDirection()
 794 {
 795     return true;
 796 }
 797 
 798 
 799 RefPtr<PopupMenu> ChromeClientJava::createPopupMenu(PopupMenuClient& client) const
 800 {
 801     return adoptRef(new PopupMenuJava(&client));
 802 }
 803 
 804 RefPtr<SearchPopupMenu> ChromeClientJava::createSearchPopupMenu(PopupMenuClient& client) const
 805 {
 806     return adoptRef(new SearchPopupMenuJava(&client));
 807 }
 808 
 809 // End of HostWindow methods
 810 
 811 RefPtr<Icon> ChromeClientJava::createIconForFiles(const Vector<String>& filenames)
 812 {
 813     return Icon::createIconForFiles(filenames);
 814 }
 815 
 816 } // namespace WebCore