WebView.cpp revision 885e650b12d781be054b31ae6221925a0184dc33
1/* 2 * Copyright 2007, The Android Open Source Project 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * * Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#define LOG_TAG "webviewglue" 27 28#include "config.h" 29 30#include "AndroidAnimation.h" 31#include "AndroidLog.h" 32#include "BaseLayerAndroid.h" 33#include "DrawExtra.h" 34#include "Frame.h" 35#include "GraphicsJNI.h" 36#include "HTMLInputElement.h" 37#include "IntPoint.h" 38#include "IntRect.h" 39#include "LayerAndroid.h" 40#include "LayerContent.h" 41#include "Node.h" 42#include "utils/Functor.h" 43#include "private/hwui/DrawGlInfo.h" 44#include "PlatformGraphicsContext.h" 45#include "PlatformString.h" 46#include "ScrollableLayerAndroid.h" 47#include "SelectText.h" 48#include "SkCanvas.h" 49#include "SkDumpCanvas.h" 50#include "SkPicture.h" 51#include "SkRect.h" 52#include "SkTime.h" 53#include "TilesManager.h" 54#include "WebCoreJni.h" 55#include "WebRequestContext.h" 56#include "WebViewCore.h" 57#include "android_graphics.h" 58 59#ifdef GET_NATIVE_VIEW 60#undef GET_NATIVE_VIEW 61#endif 62 63#define GET_NATIVE_VIEW(env, obj) ((WebView*)env->GetIntField(obj, gWebViewField)) 64 65#include <JNIUtility.h> 66#include <JNIHelp.h> 67#include <jni.h> 68#include <androidfw/KeycodeLabels.h> 69#include <wtf/text/AtomicString.h> 70#include <wtf/text/CString.h> 71 72// Free as much as we possible can 73#define TRIM_MEMORY_COMPLETE 80 74// Free a lot (all textures gone) 75#define TRIM_MEMORY_MODERATE 60 76// More moderate free (keep bare minimum to restore quickly-ish - possibly clear all textures) 77#define TRIM_MEMORY_BACKGROUND 40 78// Moderate free (clear cached tiles, keep visible ones) 79#define TRIM_MEMORY_UI_HIDDEN 20 80// Duration to show the pressed cursor ring 81#define PRESSED_STATE_DURATION 400 82 83namespace android { 84 85static jfieldID gWebViewField; 86 87//------------------------------------- 88 89static jmethodID GetJMethod(JNIEnv* env, jclass clazz, const char name[], const char signature[]) 90{ 91 jmethodID m = env->GetMethodID(clazz, name, signature); 92 ALOG_ASSERT(m, "Could not find method %s", name); 93 return m; 94} 95 96//------------------------------------- 97// This class provides JNI for making calls into native code from the UI side 98// of the multi-threaded WebView. 99class WebView 100{ 101public: 102enum FrameCachePermission { 103 DontAllowNewer, 104 AllowNewer 105}; 106 107#define DRAW_EXTRAS_SIZE 2 108enum DrawExtras { // keep this in sync with WebView.java 109 DrawExtrasNone = 0, 110 DrawExtrasSelection = 1, 111 DrawExtrasCursorRing = 2 112}; 113 114struct JavaGlue { 115 jweak m_obj; 116 jmethodID m_scrollBy; 117 jmethodID m_getScaledMaxXScroll; 118 jmethodID m_getScaledMaxYScroll; 119 jmethodID m_getVisibleRect; 120 jmethodID m_viewInvalidate; 121 jmethodID m_viewInvalidateRect; 122 jmethodID m_postInvalidateDelayed; 123 jmethodID m_pageSwapCallback; 124 jfieldID m_rectLeft; 125 jfieldID m_rectTop; 126 jmethodID m_rectWidth; 127 jmethodID m_rectHeight; 128 AutoJObject object(JNIEnv* env) { 129 return getRealObject(env, m_obj); 130 } 131} m_javaGlue; 132 133WebView(JNIEnv* env, jobject javaWebView, int viewImpl, WTF::String drawableDir, 134 bool isHighEndGfx) 135 : m_isHighEndGfx(isHighEndGfx) 136{ 137 memset(m_extras, 0, DRAW_EXTRAS_SIZE * sizeof(DrawExtra*)); 138 jclass clazz = env->FindClass("android/webkit/WebViewClassic"); 139 m_javaGlue.m_obj = env->NewWeakGlobalRef(javaWebView); 140 m_javaGlue.m_scrollBy = GetJMethod(env, clazz, "setContentScrollBy", "(IIZ)Z"); 141 m_javaGlue.m_getScaledMaxXScroll = GetJMethod(env, clazz, "getScaledMaxXScroll", "()I"); 142 m_javaGlue.m_getScaledMaxYScroll = GetJMethod(env, clazz, "getScaledMaxYScroll", "()I"); 143 m_javaGlue.m_getVisibleRect = GetJMethod(env, clazz, "sendOurVisibleRect", "()Landroid/graphics/Rect;"); 144 m_javaGlue.m_viewInvalidate = GetJMethod(env, clazz, "viewInvalidate", "()V"); 145 m_javaGlue.m_viewInvalidateRect = GetJMethod(env, clazz, "viewInvalidate", "(IIII)V"); 146 m_javaGlue.m_postInvalidateDelayed = GetJMethod(env, clazz, 147 "viewInvalidateDelayed", "(JIIII)V"); 148 m_javaGlue.m_pageSwapCallback = GetJMethod(env, clazz, "pageSwapCallback", "(Z)V"); 149 env->DeleteLocalRef(clazz); 150 151 jclass rectClass = env->FindClass("android/graphics/Rect"); 152 ALOG_ASSERT(rectClass, "Could not find Rect class"); 153 m_javaGlue.m_rectLeft = env->GetFieldID(rectClass, "left", "I"); 154 m_javaGlue.m_rectTop = env->GetFieldID(rectClass, "top", "I"); 155 m_javaGlue.m_rectWidth = GetJMethod(env, rectClass, "width", "()I"); 156 m_javaGlue.m_rectHeight = GetJMethod(env, rectClass, "height", "()I"); 157 env->DeleteLocalRef(rectClass); 158 159 env->SetIntField(javaWebView, gWebViewField, (jint)this); 160 m_viewImpl = (WebViewCore*) viewImpl; 161 m_generation = 0; 162 m_heightCanMeasure = false; 163 m_lastDx = 0; 164 m_lastDxTime = 0; 165 m_baseLayer = 0; 166 m_glDrawFunctor = 0; 167 m_isDrawingPaused = false; 168#if USE(ACCELERATED_COMPOSITING) 169 m_glWebViewState = 0; 170#endif 171} 172 173~WebView() 174{ 175 if (m_javaGlue.m_obj) 176 { 177 JNIEnv* env = JSC::Bindings::getJNIEnv(); 178 env->DeleteWeakGlobalRef(m_javaGlue.m_obj); 179 m_javaGlue.m_obj = 0; 180 } 181#if USE(ACCELERATED_COMPOSITING) 182 // We must remove the m_glWebViewState prior to deleting m_baseLayer. If we 183 // do not remove it here, we risk having BaseTiles trying to paint using a 184 // deallocated base layer. 185 stopGL(); 186#endif 187 SkSafeUnref(m_baseLayer); 188 delete m_glDrawFunctor; 189 for (int i = 0; i < DRAW_EXTRAS_SIZE; i++) 190 delete m_extras[i]; 191} 192 193DrawExtra* getDrawExtra(DrawExtras extras) 194{ 195 if (extras == DrawExtrasNone) 196 return 0; 197 return m_extras[extras - 1]; 198} 199 200void stopGL() 201{ 202#if USE(ACCELERATED_COMPOSITING) 203 delete m_glWebViewState; 204 m_glWebViewState = 0; 205#endif 206} 207 208WebViewCore* getWebViewCore() const { 209 return m_viewImpl; 210} 211 212void scrollRectOnScreen(const IntRect& rect) 213{ 214 if (rect.isEmpty()) 215 return; 216 int dx = 0; 217 int left = rect.x(); 218 int right = rect.maxX(); 219 if (left < m_visibleRect.fLeft) 220 dx = left - m_visibleRect.fLeft; 221 // Only scroll right if the entire width can fit on screen. 222 else if (right > m_visibleRect.fRight 223 && right - left < m_visibleRect.width()) 224 dx = right - m_visibleRect.fRight; 225 int dy = 0; 226 int top = rect.y(); 227 int bottom = rect.maxY(); 228 if (top < m_visibleRect.fTop) 229 dy = top - m_visibleRect.fTop; 230 // Only scroll down if the entire height can fit on screen 231 else if (bottom > m_visibleRect.fBottom 232 && bottom - top < m_visibleRect.height()) 233 dy = bottom - m_visibleRect.fBottom; 234 if ((dx|dy) == 0 || !scrollBy(dx, dy)) 235 return; 236 viewInvalidate(); 237} 238 239bool drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect, 240 WebCore::IntRect& webViewRect, int titleBarHeight, 241 WebCore::IntRect& clip, float scale, int extras) 242{ 243#if USE(ACCELERATED_COMPOSITING) 244 if (!m_baseLayer) 245 return false; 246 247 if (!m_glWebViewState) { 248 TilesManager::instance()->setHighEndGfx(m_isHighEndGfx); 249 m_glWebViewState = new GLWebViewState(); 250 m_glWebViewState->setBaseLayer(m_baseLayer, false, true); 251 } 252 253 DrawExtra* extra = getDrawExtra((DrawExtras) extras); 254 255 m_glWebViewState->glExtras()->setDrawExtra(extra); 256 257 // Make sure we have valid coordinates. We might not have valid coords 258 // if the zoom manager is still initializing. We will be redrawn 259 // once the correct scale is set 260 if (!m_visibleRect.isFinite()) 261 return false; 262 bool treesSwapped = false; 263 bool newTreeHasAnim = false; 264 bool ret = m_glWebViewState->drawGL(viewRect, m_visibleRect, invalRect, 265 webViewRect, titleBarHeight, clip, scale, 266 &treesSwapped, &newTreeHasAnim); 267 if (treesSwapped) { 268 ALOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); 269 JNIEnv* env = JSC::Bindings::getJNIEnv(); 270 AutoJObject javaObject = m_javaGlue.object(env); 271 if (javaObject.get()) { 272 env->CallVoidMethod(javaObject.get(), m_javaGlue.m_pageSwapCallback, newTreeHasAnim); 273 checkException(env); 274 } 275 } 276 if (ret) 277 return !m_isDrawingPaused; 278#endif 279 return false; 280} 281 282PictureSet* draw(SkCanvas* canvas, SkColor bgColor, DrawExtras extras, bool split) 283{ 284 PictureSet* ret = 0; 285 if (!m_baseLayer) { 286 canvas->drawColor(bgColor); 287 return ret; 288 } 289 290 // draw the content of the base layer first 291 LayerContent* content = m_baseLayer->content(); 292 int sc = canvas->save(SkCanvas::kClip_SaveFlag); 293 canvas->clipRect(SkRect::MakeLTRB(0, 0, content->width(), 294 content->height()), SkRegion::kDifference_Op); 295 canvas->drawColor(bgColor); 296 canvas->restoreToCount(sc); 297 298 // call this to be sure we've adjusted for any scrolling or animations 299 // before we actually draw 300 m_baseLayer->updateLayerPositions(m_visibleRect); 301 m_baseLayer->updatePositions(); 302 303 // We have to set the canvas' matrix on the base layer 304 // (to have fixed layers work as intended) 305 SkAutoCanvasRestore restore(canvas, true); 306 m_baseLayer->setMatrix(canvas->getTotalMatrix()); 307 canvas->resetMatrix(); 308 m_baseLayer->draw(canvas, getDrawExtra(extras)); 309 310 return ret; 311} 312 313int getScaledMaxXScroll() 314{ 315 ALOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); 316 JNIEnv* env = JSC::Bindings::getJNIEnv(); 317 AutoJObject javaObject = m_javaGlue.object(env); 318 if (!javaObject.get()) 319 return 0; 320 int result = env->CallIntMethod(javaObject.get(), m_javaGlue.m_getScaledMaxXScroll); 321 checkException(env); 322 return result; 323} 324 325int getScaledMaxYScroll() 326{ 327 ALOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); 328 JNIEnv* env = JSC::Bindings::getJNIEnv(); 329 AutoJObject javaObject = m_javaGlue.object(env); 330 if (!javaObject.get()) 331 return 0; 332 int result = env->CallIntMethod(javaObject.get(), m_javaGlue.m_getScaledMaxYScroll); 333 checkException(env); 334 return result; 335} 336 337IntRect getVisibleRect() 338{ 339 IntRect rect; 340 ALOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); 341 JNIEnv* env = JSC::Bindings::getJNIEnv(); 342 AutoJObject javaObject = m_javaGlue.object(env); 343 if (!javaObject.get()) 344 return rect; 345 jobject jRect = env->CallObjectMethod(javaObject.get(), m_javaGlue.m_getVisibleRect); 346 checkException(env); 347 rect.setX(env->GetIntField(jRect, m_javaGlue.m_rectLeft)); 348 checkException(env); 349 rect.setY(env->GetIntField(jRect, m_javaGlue.m_rectTop)); 350 checkException(env); 351 rect.setWidth(env->CallIntMethod(jRect, m_javaGlue.m_rectWidth)); 352 checkException(env); 353 rect.setHeight(env->CallIntMethod(jRect, m_javaGlue.m_rectHeight)); 354 checkException(env); 355 env->DeleteLocalRef(jRect); 356 checkException(env); 357 return rect; 358} 359 360#if USE(ACCELERATED_COMPOSITING) 361static const ScrollableLayerAndroid* findScrollableLayer( 362 const LayerAndroid* parent, int x, int y, SkIRect* foundBounds) { 363 SkRect bounds; 364 parent->bounds(&bounds); 365 // Check the parent bounds first; this will clip to within a masking layer's 366 // bounds. 367 if (parent->masksToBounds() && !bounds.contains(x, y)) 368 return 0; 369 // Move the hit test local to parent. 370 x -= bounds.fLeft; 371 y -= bounds.fTop; 372 int count = parent->countChildren(); 373 while (count--) { 374 const LayerAndroid* child = parent->getChild(count); 375 const ScrollableLayerAndroid* result = findScrollableLayer(child, x, y, 376 foundBounds); 377 if (result) { 378 foundBounds->offset(bounds.fLeft, bounds.fTop); 379 if (parent->masksToBounds()) { 380 if (bounds.width() < foundBounds->width()) 381 foundBounds->fRight = foundBounds->fLeft + bounds.width(); 382 if (bounds.height() < foundBounds->height()) 383 foundBounds->fBottom = foundBounds->fTop + bounds.height(); 384 } 385 return result; 386 } 387 } 388 if (parent->contentIsScrollable()) { 389 foundBounds->set(0, 0, bounds.width(), bounds.height()); 390 return static_cast<const ScrollableLayerAndroid*>(parent); 391 } 392 return 0; 393} 394#endif 395 396int scrollableLayer(int x, int y, SkIRect* layerRect, SkIRect* bounds) 397{ 398#if USE(ACCELERATED_COMPOSITING) 399 if (!m_baseLayer) 400 return 0; 401 const ScrollableLayerAndroid* result = findScrollableLayer(m_baseLayer, x, y, bounds); 402 if (result) { 403 result->getScrollRect(layerRect); 404 return result->uniqueId(); 405 } 406#endif 407 return 0; 408} 409 410void scrollLayer(int layerId, int x, int y) 411{ 412 if (m_glWebViewState) 413 m_glWebViewState->scrollLayer(layerId, x, y); 414} 415 416void setHeightCanMeasure(bool measure) 417{ 418 m_heightCanMeasure = measure; 419} 420 421String getSelection() 422{ 423 SelectText* select = static_cast<SelectText*>( 424 getDrawExtra(WebView::DrawExtrasSelection)); 425 if (select) 426 return select->getText(); 427 return String(); 428} 429 430bool scrollBy(int dx, int dy) 431{ 432 ALOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); 433 434 JNIEnv* env = JSC::Bindings::getJNIEnv(); 435 AutoJObject javaObject = m_javaGlue.object(env); 436 if (!javaObject.get()) 437 return false; 438 bool result = env->CallBooleanMethod(javaObject.get(), m_javaGlue.m_scrollBy, dx, dy, true); 439 checkException(env); 440 return result; 441} 442 443void setIsScrolling(bool isScrolling) 444{ 445#if USE(ACCELERATED_COMPOSITING) 446 if (m_glWebViewState) 447 m_glWebViewState->setIsScrolling(isScrolling); 448#endif 449} 450 451void viewInvalidate() 452{ 453 JNIEnv* env = JSC::Bindings::getJNIEnv(); 454 AutoJObject javaObject = m_javaGlue.object(env); 455 if (!javaObject.get()) 456 return; 457 env->CallVoidMethod(javaObject.get(), m_javaGlue.m_viewInvalidate); 458 checkException(env); 459} 460 461void viewInvalidateRect(int l, int t, int r, int b) 462{ 463 JNIEnv* env = JSC::Bindings::getJNIEnv(); 464 AutoJObject javaObject = m_javaGlue.object(env); 465 if (!javaObject.get()) 466 return; 467 env->CallVoidMethod(javaObject.get(), m_javaGlue.m_viewInvalidateRect, l, r, t, b); 468 checkException(env); 469} 470 471void postInvalidateDelayed(int64_t delay, const WebCore::IntRect& bounds) 472{ 473 JNIEnv* env = JSC::Bindings::getJNIEnv(); 474 AutoJObject javaObject = m_javaGlue.object(env); 475 if (!javaObject.get()) 476 return; 477 env->CallVoidMethod(javaObject.get(), m_javaGlue.m_postInvalidateDelayed, 478 delay, bounds.x(), bounds.y(), bounds.maxX(), bounds.maxY()); 479 checkException(env); 480} 481 482#if ENABLE(ANDROID_OVERFLOW_SCROLL) 483static void copyScrollPositionRecursive(const LayerAndroid* from, 484 LayerAndroid* root) 485{ 486 if (!from || !root) 487 return; 488 for (int i = 0; i < from->countChildren(); i++) { 489 const LayerAndroid* l = from->getChild(i); 490 if (l->contentIsScrollable()) { 491 const SkPoint& pos = l->getPosition(); 492 LayerAndroid* match = root->findById(l->uniqueId()); 493 if (match && match->contentIsScrollable()) 494 match->setPosition(pos.fX, pos.fY); 495 } 496 copyScrollPositionRecursive(l, root); 497 } 498} 499#endif 500 501BaseLayerAndroid* getBaseLayer() const { return m_baseLayer; } 502 503bool setBaseLayer(BaseLayerAndroid* newBaseLayer, SkRegion& inval, bool showVisualIndicator, 504 bool isPictureAfterFirstLayout) 505{ 506 bool queueFull = false; 507#if USE(ACCELERATED_COMPOSITING) 508 if (m_glWebViewState) { 509 // TODO: mark as inval on webkit side 510 if (newBaseLayer) 511 newBaseLayer->markAsDirty(inval); 512 queueFull = m_glWebViewState->setBaseLayer(newBaseLayer, showVisualIndicator, 513 isPictureAfterFirstLayout); 514 } 515#endif 516 517#if ENABLE(ANDROID_OVERFLOW_SCROLL) 518 if (newBaseLayer) { 519 // TODO: the below tree position copies are only necessary in software rendering 520 copyScrollPositionRecursive(m_baseLayer, newBaseLayer); 521 } 522#endif 523 SkSafeUnref(m_baseLayer); 524 m_baseLayer = newBaseLayer; 525 526 return queueFull; 527} 528 529void replaceBaseContent(PictureSet* set) 530{ 531 if (!m_baseLayer) 532 return; 533 // TODO: remove the split picture codepath 534 delete set; 535} 536 537void copyBaseContentToPicture(SkPicture* picture) 538{ 539 if (!m_baseLayer) 540 return; 541 LayerContent* content = m_baseLayer->content(); 542 content->draw(picture->beginRecording(content->width(), content->height(), 543 SkPicture::kUsePathBoundsForClip_RecordingFlag)); 544 picture->endRecording(); 545} 546 547bool hasContent() { 548 if (!m_baseLayer) 549 return false; 550 return !m_baseLayer->content()->isEmpty(); 551} 552 553void setFunctor(Functor* functor) { 554 delete m_glDrawFunctor; 555 m_glDrawFunctor = functor; 556} 557 558Functor* getFunctor() { 559 return m_glDrawFunctor; 560} 561 562void setVisibleRect(SkRect& visibleRect) { 563 m_visibleRect = visibleRect; 564} 565 566void setDrawExtra(DrawExtra *extra, DrawExtras type) 567{ 568 if (type == DrawExtrasNone) 569 return; 570 DrawExtra* old = m_extras[type - 1]; 571 m_extras[type - 1] = extra; 572 if (old != extra) { 573 delete old; 574 } 575} 576 577void setTextSelection(SelectText *selection) { 578 setDrawExtra(selection, DrawExtrasSelection); 579} 580 581int getHandleLayerId(SelectText::HandleId handleId, SkIRect& cursorRect) { 582 SelectText* selectText = static_cast<SelectText*>(getDrawExtra(DrawExtrasSelection)); 583 if (!selectText || !m_baseLayer) 584 return -1; 585 int layerId = selectText->caretLayerId(handleId); 586 cursorRect = selectText->caretRect(handleId); 587 if (layerId != -1) { 588 // We need to make sure the drawTransform is up to date as this is 589 // called before a draw() or drawGL() 590 m_baseLayer->updateLayerPositions(m_visibleRect); 591 LayerAndroid* root = m_baseLayer; 592 LayerAndroid* layer = root ? root->findById(layerId) : 0; 593 if (layer && layer->drawTransform()) { 594 const TransformationMatrix* transform = layer->drawTransform(); 595 // We're overloading the concept of Rect to be just the two 596 // points (bottom-left and top-right. 597 // TODO: Use FloatQuad instead. 598 IntPoint bottomLeft = transform->mapPoint(IntPoint(cursorRect.fLeft, 599 cursorRect.fBottom)); 600 IntPoint topRight = transform->mapPoint(IntPoint(cursorRect.fRight, 601 cursorRect.fTop)); 602 cursorRect.setLTRB(bottomLeft.x(), topRight.y(), topRight.x(), 603 bottomLeft.y()); 604 } 605 } 606 return layerId; 607} 608 609void mapLayerRect(int layerId, SkIRect& rect) { 610 if (layerId != -1) { 611 // We need to make sure the drawTransform is up to date as this is 612 // called before a draw() or drawGL() 613 m_baseLayer->updateLayerPositions(m_visibleRect); 614 LayerAndroid* layer = m_baseLayer ? m_baseLayer->findById(layerId) : 0; 615 if (layer && layer->drawTransform()) 616 rect = layer->drawTransform()->mapRect(rect); 617 } 618} 619 620// This is called when WebView switches rendering modes in a more permanent fashion 621// such as when the layer type is set or the view is attached/detached from the window 622int setHwAccelerated(bool hwAccelerated) { 623 if (!m_glWebViewState) 624 return 0; 625 LayerAndroid* root = m_baseLayer; 626 if (root) 627 return root->setHwAccelerated(hwAccelerated); 628 return 0; 629} 630 631 bool m_isDrawingPaused; 632private: // local state for WebView 633 // private to getFrameCache(); other functions operate in a different thread 634 WebViewCore* m_viewImpl; 635 int m_generation; // associate unique ID with sent kit focus to match with ui 636 // Corresponds to the same-named boolean on the java side. 637 bool m_heightCanMeasure; 638 int m_lastDx; 639 SkMSec m_lastDxTime; 640 DrawExtra* m_extras[DRAW_EXTRAS_SIZE]; 641 BaseLayerAndroid* m_baseLayer; 642 Functor* m_glDrawFunctor; 643#if USE(ACCELERATED_COMPOSITING) 644 GLWebViewState* m_glWebViewState; 645#endif 646 SkRect m_visibleRect; 647 bool m_isHighEndGfx; 648}; // end of WebView class 649 650 651/** 652 * This class holds a function pointer and parameters for calling drawGL into a specific 653 * viewport. The pointer to the Functor will be put on a framework display list to be called 654 * when the display list is replayed. 655 */ 656class GLDrawFunctor : Functor { 657 public: 658 GLDrawFunctor(WebView* _wvInstance, 659 bool(WebView::*_funcPtr)(WebCore::IntRect&, WebCore::IntRect*, 660 WebCore::IntRect&, int, WebCore::IntRect&, jfloat, jint), 661 WebCore::IntRect _viewRect, float _scale, int _extras) { 662 wvInstance = _wvInstance; 663 funcPtr = _funcPtr; 664 viewRect = _viewRect; 665 scale = _scale; 666 extras = _extras; 667 }; 668 status_t operator()(int messageId, void* data) { 669 if (viewRect.isEmpty()) { 670 // NOOP operation if viewport is empty 671 return 0; 672 } 673 674 WebCore::IntRect inval; 675 int titlebarHeight = webViewRect.height() - viewRect.height(); 676 677 uirenderer::DrawGlInfo* info = reinterpret_cast<uirenderer::DrawGlInfo*>(data); 678 WebCore::IntRect localViewRect = viewRect; 679 if (info->isLayer) 680 localViewRect.move(-1 * localViewRect.x(), -1 * localViewRect.y()); 681 682 WebCore::IntRect clip(info->clipLeft, info->clipTop, 683 info->clipRight - info->clipLeft, 684 info->clipBottom - info->clipTop); 685 TilesManager::instance()->shader()->setWebViewMatrix(info->transform, info->isLayer); 686 687 bool retVal = (*wvInstance.*funcPtr)(localViewRect, &inval, webViewRect, 688 titlebarHeight, clip, scale, extras); 689 if (retVal) { 690 IntRect finalInval; 691 if (inval.isEmpty()) { 692 finalInval = webViewRect; 693 retVal = true; 694 } else { 695 finalInval.setX(webViewRect.x() + inval.x()); 696 finalInval.setY(webViewRect.y() + titlebarHeight + inval.y()); 697 finalInval.setWidth(inval.width()); 698 finalInval.setHeight(inval.height()); 699 } 700 info->dirtyLeft = finalInval.x(); 701 info->dirtyTop = finalInval.y(); 702 info->dirtyRight = finalInval.maxX(); 703 info->dirtyBottom = finalInval.maxY(); 704 } 705 // return 1 if invalidation needed, 0 otherwise 706 return retVal ? 1 : 0; 707 } 708 void updateRect(WebCore::IntRect& _viewRect) { 709 viewRect = _viewRect; 710 } 711 void updateViewRect(WebCore::IntRect& _viewRect) { 712 webViewRect = _viewRect; 713 } 714 void updateScale(float _scale) { 715 scale = _scale; 716 } 717 private: 718 WebView* wvInstance; 719 bool (WebView::*funcPtr)(WebCore::IntRect&, WebCore::IntRect*, 720 WebCore::IntRect&, int, WebCore::IntRect&, float, int); 721 WebCore::IntRect viewRect; 722 WebCore::IntRect webViewRect; 723 jfloat scale; 724 jint extras; 725}; 726 727/* 728 * Native JNI methods 729 */ 730 731static void nativeCreate(JNIEnv *env, jobject obj, int viewImpl, 732 jstring drawableDir, jboolean isHighEndGfx) 733{ 734 WTF::String dir = jstringToWtfString(env, drawableDir); 735 new WebView(env, obj, viewImpl, dir, isHighEndGfx); 736 // NEED THIS OR SOMETHING LIKE IT! 737 //Release(obj); 738} 739 740static WebCore::IntRect jrect_to_webrect(JNIEnv* env, jobject obj) 741{ 742 if (obj) { 743 int L, T, R, B; 744 GraphicsJNI::get_jrect(env, obj, &L, &T, &R, &B); 745 return WebCore::IntRect(L, T, R - L, B - T); 746 } else 747 return WebCore::IntRect(); 748} 749 750static SkRect jrectf_to_rect(JNIEnv* env, jobject obj) 751{ 752 SkRect rect = SkRect::MakeEmpty(); 753 if (obj) 754 GraphicsJNI::jrectf_to_rect(env, obj, &rect); 755 return rect; 756} 757 758static jint nativeDraw(JNIEnv *env, jobject obj, jobject canv, 759 jobject visible, jint color, 760 jint extras, jboolean split) { 761 SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, canv); 762 WebView* webView = GET_NATIVE_VIEW(env, obj); 763 SkRect visibleRect = jrectf_to_rect(env, visible); 764 webView->setVisibleRect(visibleRect); 765 PictureSet* pictureSet = webView->draw(canvas, color, 766 static_cast<WebView::DrawExtras>(extras), split); 767 return reinterpret_cast<jint>(pictureSet); 768} 769 770static jint nativeGetDrawGLFunction(JNIEnv *env, jobject obj, jint nativeView, 771 jobject jrect, jobject jviewrect, 772 jobject jvisiblerect, 773 jfloat scale, jint extras) { 774 WebCore::IntRect viewRect = jrect_to_webrect(env, jrect); 775 WebView *wvInstance = (WebView*) nativeView; 776 SkRect visibleRect = jrectf_to_rect(env, jvisiblerect); 777 wvInstance->setVisibleRect(visibleRect); 778 779 GLDrawFunctor* functor = new GLDrawFunctor(wvInstance, 780 &android::WebView::drawGL, viewRect, scale, extras); 781 wvInstance->setFunctor((Functor*) functor); 782 783 WebCore::IntRect webViewRect = jrect_to_webrect(env, jviewrect); 784 functor->updateViewRect(webViewRect); 785 786 return (jint)functor; 787} 788 789static void nativeUpdateDrawGLFunction(JNIEnv *env, jobject obj, jobject jrect, 790 jobject jviewrect, jobject jvisiblerect, jfloat scale) { 791 WebView *wvInstance = GET_NATIVE_VIEW(env, obj); 792 if (wvInstance) { 793 GLDrawFunctor* functor = (GLDrawFunctor*) wvInstance->getFunctor(); 794 if (functor) { 795 WebCore::IntRect viewRect = jrect_to_webrect(env, jrect); 796 functor->updateRect(viewRect); 797 798 SkRect visibleRect = jrectf_to_rect(env, jvisiblerect); 799 wvInstance->setVisibleRect(visibleRect); 800 801 WebCore::IntRect webViewRect = jrect_to_webrect(env, jviewrect); 802 functor->updateViewRect(webViewRect); 803 804 functor->updateScale(scale); 805 } 806 } 807} 808 809static bool nativeEvaluateLayersAnimations(JNIEnv *env, jobject obj, jint nativeView) 810{ 811 // only call in software rendering, initialize and evaluate animations 812#if USE(ACCELERATED_COMPOSITING) 813 BaseLayerAndroid* baseLayer = ((WebView*)nativeView)->getBaseLayer(); 814 if (baseLayer) { 815 baseLayer->initAnimations(); 816 return baseLayer->evaluateAnimations(); 817 } 818#endif 819 return false; 820} 821 822static bool nativeSetBaseLayer(JNIEnv *env, jobject obj, jint nativeView, jint layer, jobject inval, 823 jboolean showVisualIndicator, 824 jboolean isPictureAfterFirstLayout) 825{ 826 BaseLayerAndroid* layerImpl = reinterpret_cast<BaseLayerAndroid*>(layer); 827 SkRegion invalRegion; 828 if (inval) 829 invalRegion = *GraphicsJNI::getNativeRegion(env, inval); 830 return ((WebView*)nativeView)->setBaseLayer(layerImpl, invalRegion, showVisualIndicator, 831 isPictureAfterFirstLayout); 832} 833 834static BaseLayerAndroid* nativeGetBaseLayer(JNIEnv *env, jobject obj) 835{ 836 return GET_NATIVE_VIEW(env, obj)->getBaseLayer(); 837} 838 839static void nativeReplaceBaseContent(JNIEnv *env, jobject obj, jint content) 840{ 841 PictureSet* set = reinterpret_cast<PictureSet*>(content); 842 GET_NATIVE_VIEW(env, obj)->replaceBaseContent(set); 843} 844 845static void nativeCopyBaseContentToPicture(JNIEnv *env, jobject obj, jobject pict) 846{ 847 SkPicture* picture = GraphicsJNI::getNativePicture(env, pict); 848 GET_NATIVE_VIEW(env, obj)->copyBaseContentToPicture(picture); 849} 850 851static bool nativeHasContent(JNIEnv *env, jobject obj) 852{ 853 return GET_NATIVE_VIEW(env, obj)->hasContent(); 854} 855 856static jobject nativeLayerBounds(JNIEnv* env, jobject obj, jint jlayer) 857{ 858 SkRect r; 859#if USE(ACCELERATED_COMPOSITING) 860 LayerAndroid* layer = (LayerAndroid*) jlayer; 861 r = layer->bounds(); 862#else 863 r.setEmpty(); 864#endif 865 SkIRect irect; 866 r.round(&irect); 867 jclass rectClass = env->FindClass("android/graphics/Rect"); 868 jmethodID init = env->GetMethodID(rectClass, "<init>", "(IIII)V"); 869 jobject rect = env->NewObject(rectClass, init, irect.fLeft, irect.fTop, 870 irect.fRight, irect.fBottom); 871 env->DeleteLocalRef(rectClass); 872 return rect; 873} 874 875static void nativeSetHeightCanMeasure(JNIEnv *env, jobject obj, bool measure) 876{ 877 WebView* view = GET_NATIVE_VIEW(env, obj); 878 ALOG_ASSERT(view, "view not set in nativeSetHeightCanMeasure"); 879 view->setHeightCanMeasure(measure); 880} 881 882static void nativeDestroy(JNIEnv *env, jobject obj) 883{ 884 WebView* view = GET_NATIVE_VIEW(env, obj); 885 ALOGD("nativeDestroy view: %p", view); 886 ALOG_ASSERT(view, "view not set in nativeDestroy"); 887 delete view; 888} 889 890static void nativeStopGL(JNIEnv *env, jobject obj) 891{ 892 GET_NATIVE_VIEW(env, obj)->stopGL(); 893} 894 895static jobject nativeGetSelection(JNIEnv *env, jobject obj) 896{ 897 WebView* view = GET_NATIVE_VIEW(env, obj); 898 ALOG_ASSERT(view, "view not set in %s", __FUNCTION__); 899 String selection = view->getSelection(); 900 return wtfStringToJstring(env, selection); 901} 902 903static void nativeDiscardAllTextures(JNIEnv *env, jobject obj) 904{ 905 //discard all textures for debugging/test purposes, but not gl backing memory 906 bool allTextures = true, deleteGLTextures = false; 907 TilesManager::instance()->discardTextures(allTextures, deleteGLTextures); 908} 909 910static void nativeTileProfilingStart(JNIEnv *env, jobject obj) 911{ 912 TilesManager::instance()->getProfiler()->start(); 913} 914 915static float nativeTileProfilingStop(JNIEnv *env, jobject obj) 916{ 917 return TilesManager::instance()->getProfiler()->stop(); 918} 919 920static void nativeTileProfilingClear(JNIEnv *env, jobject obj) 921{ 922 TilesManager::instance()->getProfiler()->clear(); 923} 924 925static int nativeTileProfilingNumFrames(JNIEnv *env, jobject obj) 926{ 927 return TilesManager::instance()->getProfiler()->numFrames(); 928} 929 930static int nativeTileProfilingNumTilesInFrame(JNIEnv *env, jobject obj, int frame) 931{ 932 return TilesManager::instance()->getProfiler()->numTilesInFrame(frame); 933} 934 935static int nativeTileProfilingGetInt(JNIEnv *env, jobject obj, int frame, int tile, jstring jkey) 936{ 937 WTF::String key = jstringToWtfString(env, jkey); 938 TileProfileRecord* record = TilesManager::instance()->getProfiler()->getTile(frame, tile); 939 940 if (key == "left") 941 return record->left; 942 if (key == "top") 943 return record->top; 944 if (key == "right") 945 return record->right; 946 if (key == "bottom") 947 return record->bottom; 948 if (key == "level") 949 return record->level; 950 if (key == "isReady") 951 return record->isReady ? 1 : 0; 952 return -1; 953} 954 955static float nativeTileProfilingGetFloat(JNIEnv *env, jobject obj, int frame, int tile, jstring jkey) 956{ 957 TileProfileRecord* record = TilesManager::instance()->getProfiler()->getTile(frame, tile); 958 return record->scale; 959} 960 961#ifdef ANDROID_DUMP_DISPLAY_TREE 962static void dumpToFile(const char text[], void* file) { 963 fwrite(text, 1, strlen(text), reinterpret_cast<FILE*>(file)); 964 fwrite("\n", 1, 1, reinterpret_cast<FILE*>(file)); 965} 966#endif 967 968// Return true to view invalidate WebView 969static bool nativeSetProperty(JNIEnv *env, jobject obj, jstring jkey, jstring jvalue) 970{ 971 WTF::String key = jstringToWtfString(env, jkey); 972 WTF::String value = jstringToWtfString(env, jvalue); 973 if (key == "inverted") { 974 bool shouldInvert = (value == "true"); 975 TilesManager::instance()->setInvertedScreen(shouldInvert); 976 return true; 977 } 978 else if (key == "inverted_contrast") { 979 float contrast = value.toFloat(); 980 TilesManager::instance()->setInvertedScreenContrast(contrast); 981 return true; 982 } 983 else if (key == "enable_cpu_upload_path") { 984 TilesManager::instance()->transferQueue()->setTextureUploadType( 985 value == "true" ? CpuUpload : GpuUpload); 986 } 987 else if (key == "use_minimal_memory") { 988 TilesManager::instance()->setUseMinimalMemory(value == "true"); 989 } 990 else if (key == "use_double_buffering") { 991 TilesManager::instance()->setUseDoubleBuffering(value == "true"); 992 } 993 else if (key == "tree_updates") { 994 TilesManager::instance()->clearContentUpdates(); 995 } 996 return false; 997} 998 999static jstring nativeGetProperty(JNIEnv *env, jobject obj, jstring jkey) 1000{ 1001 WTF::String key = jstringToWtfString(env, jkey); 1002 if (key == "tree_updates") { 1003 int updates = TilesManager::instance()->getContentUpdates(); 1004 WTF::String wtfUpdates = WTF::String::number(updates); 1005 return wtfStringToJstring(env, wtfUpdates); 1006 } 1007 return 0; 1008} 1009 1010static void nativeOnTrimMemory(JNIEnv *env, jobject obj, jint level) 1011{ 1012 if (TilesManager::hardwareAccelerationEnabled()) { 1013 // When we got TRIM_MEMORY_MODERATE or TRIM_MEMORY_COMPLETE, we should 1014 // make sure the transfer queue is empty and then abandon the Surface 1015 // Texture to avoid ANR b/c framework may destroy the EGL context. 1016 // Refer to WindowManagerImpl.java for conditions we followed. 1017 TilesManager* tilesManager = TilesManager::instance(); 1018 if (level >= TRIM_MEMORY_MODERATE 1019 && !tilesManager->highEndGfx()) { 1020 ALOGD("OnTrimMemory with EGL Context %p", eglGetCurrentContext()); 1021 tilesManager->transferQueue()->emptyQueue(); 1022 tilesManager->shader()->cleanupGLResources(); 1023 tilesManager->videoLayerManager()->cleanupGLResources(); 1024 } 1025 1026 bool freeAllTextures = (level > TRIM_MEMORY_UI_HIDDEN), glTextures = true; 1027 tilesManager->discardTextures(freeAllTextures, glTextures); 1028 } 1029} 1030 1031static void nativeDumpDisplayTree(JNIEnv* env, jobject jwebview, jstring jurl) 1032{ 1033#ifdef ANDROID_DUMP_DISPLAY_TREE 1034 WebView* view = GET_NATIVE_VIEW(env, jwebview); 1035 ALOG_ASSERT(view, "view not set in %s", __FUNCTION__); 1036 1037 if (view && view->getWebViewCore()) { 1038 FILE* file = fopen(DISPLAY_TREE_LOG_FILE, "w"); 1039 if (file) { 1040 SkFormatDumper dumper(dumpToFile, file); 1041 // dump the URL 1042 if (jurl) { 1043 const char* str = env->GetStringUTFChars(jurl, 0); 1044 SkDebugf("Dumping %s to %s\n", str, DISPLAY_TREE_LOG_FILE); 1045 dumpToFile(str, file); 1046 env->ReleaseStringUTFChars(jurl, str); 1047 } 1048 // now dump the display tree 1049 SkDumpCanvas canvas(&dumper); 1050 // this will playback the picture into the canvas, which will 1051 // spew its contents to the dumper 1052 view->draw(&canvas, 0, WebView::DrawExtrasNone, false); 1053 // we're done with the file now 1054 fwrite("\n", 1, 1, file); 1055 fclose(file); 1056 } 1057#if USE(ACCELERATED_COMPOSITING) 1058 const LayerAndroid* baseLayer = view->getBaseLayer(); 1059 if (baseLayer) { 1060 FILE* file = fopen(LAYERS_TREE_LOG_FILE,"w"); 1061 if (file) { 1062 baseLayer->dumpLayers(file, 0); 1063 fclose(file); 1064 } 1065 } 1066#endif 1067 } 1068#endif 1069} 1070 1071static int nativeScrollableLayer(JNIEnv* env, jobject jwebview, jint x, jint y, 1072 jobject rect, jobject bounds) 1073{ 1074 WebView* view = GET_NATIVE_VIEW(env, jwebview); 1075 ALOG_ASSERT(view, "view not set in %s", __FUNCTION__); 1076 SkIRect nativeRect, nativeBounds; 1077 int id = view->scrollableLayer(x, y, &nativeRect, &nativeBounds); 1078 if (rect) 1079 GraphicsJNI::irect_to_jrect(nativeRect, env, rect); 1080 if (bounds) 1081 GraphicsJNI::irect_to_jrect(nativeBounds, env, bounds); 1082 return id; 1083} 1084 1085static bool nativeScrollLayer(JNIEnv* env, jobject obj, jint layerId, jint x, 1086 jint y) 1087{ 1088#if ENABLE(ANDROID_OVERFLOW_SCROLL) 1089 WebView* view = GET_NATIVE_VIEW(env, obj); 1090 view->scrollLayer(layerId, x, y); 1091 1092 //TODO: the below only needed for the SW rendering path 1093 LayerAndroid* baseLayer = view->getBaseLayer(); 1094 if (!baseLayer) 1095 return false; 1096 LayerAndroid* layer = baseLayer->findById(layerId); 1097 if (!layer || !layer->contentIsScrollable()) 1098 return false; 1099 return static_cast<ScrollableLayerAndroid*>(layer)->scrollTo(x, y); 1100#endif 1101 return false; 1102} 1103 1104static void nativeSetIsScrolling(JNIEnv* env, jobject jwebview, jboolean isScrolling) 1105{ 1106 WebView* view = GET_NATIVE_VIEW(env, jwebview); 1107 ALOG_ASSERT(view, "view not set in %s", __FUNCTION__); 1108 view->setIsScrolling(isScrolling); 1109} 1110 1111static void nativeUseHardwareAccelSkia(JNIEnv*, jobject, jboolean enabled) 1112{ 1113 BaseRenderer::setCurrentRendererType(enabled ? BaseRenderer::Ganesh : BaseRenderer::Raster); 1114} 1115 1116static int nativeGetBackgroundColor(JNIEnv* env, jobject obj) 1117{ 1118 WebView* view = GET_NATIVE_VIEW(env, obj); 1119 BaseLayerAndroid* baseLayer = view->getBaseLayer(); 1120 if (baseLayer) { 1121 WebCore::Color color = baseLayer->getBackgroundColor(); 1122 if (color.isValid()) 1123 return SkColorSetARGB(color.alpha(), color.red(), 1124 color.green(), color.blue()); 1125 } 1126 return SK_ColorWHITE; 1127} 1128 1129static void nativeSetPauseDrawing(JNIEnv *env, jobject obj, jint nativeView, 1130 jboolean pause) 1131{ 1132 ((WebView*)nativeView)->m_isDrawingPaused = pause; 1133} 1134 1135static void nativeSetTextSelection(JNIEnv *env, jobject obj, jint nativeView, 1136 jint selectionPtr) 1137{ 1138 SelectText* selection = reinterpret_cast<SelectText*>(selectionPtr); 1139 reinterpret_cast<WebView*>(nativeView)->setTextSelection(selection); 1140} 1141 1142static jint nativeGetHandleLayerId(JNIEnv *env, jobject obj, jint nativeView, 1143 jint handleIndex, jobject cursorRect) 1144{ 1145 WebView* webview = reinterpret_cast<WebView*>(nativeView); 1146 SkIRect nativeRect; 1147 int layerId = webview->getHandleLayerId((SelectText::HandleId) handleIndex, nativeRect); 1148 if (cursorRect) 1149 GraphicsJNI::irect_to_jrect(nativeRect, env, cursorRect); 1150 return layerId; 1151} 1152 1153static jboolean nativeIsBaseFirst(JNIEnv *env, jobject obj, jint nativeView) 1154{ 1155 WebView* webview = reinterpret_cast<WebView*>(nativeView); 1156 SelectText* select = static_cast<SelectText*>( 1157 webview->getDrawExtra(WebView::DrawExtrasSelection)); 1158 return select ? select->isBaseFirst() : false; 1159} 1160 1161static void nativeMapLayerRect(JNIEnv *env, jobject obj, jint nativeView, 1162 jint layerId, jobject rect) 1163{ 1164 WebView* webview = reinterpret_cast<WebView*>(nativeView); 1165 SkIRect nativeRect; 1166 GraphicsJNI::jrect_to_irect(env, rect, &nativeRect); 1167 webview->mapLayerRect(layerId, nativeRect); 1168 GraphicsJNI::irect_to_jrect(nativeRect, env, rect); 1169} 1170 1171static jint nativeSetHwAccelerated(JNIEnv *env, jobject obj, jint nativeView, 1172 jboolean hwAccelerated) 1173{ 1174 WebView* webview = reinterpret_cast<WebView*>(nativeView); 1175 return webview->setHwAccelerated(hwAccelerated); 1176} 1177 1178/* 1179 * JNI registration 1180 */ 1181static JNINativeMethod gJavaWebViewMethods[] = { 1182 { "nativeCreate", "(ILjava/lang/String;Z)V", 1183 (void*) nativeCreate }, 1184 { "nativeDestroy", "()V", 1185 (void*) nativeDestroy }, 1186 { "nativeDraw", "(Landroid/graphics/Canvas;Landroid/graphics/RectF;IIZ)I", 1187 (void*) nativeDraw }, 1188 { "nativeGetDrawGLFunction", "(ILandroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/RectF;FI)I", 1189 (void*) nativeGetDrawGLFunction }, 1190 { "nativeUpdateDrawGLFunction", "(Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/RectF;F)V", 1191 (void*) nativeUpdateDrawGLFunction }, 1192 { "nativeDumpDisplayTree", "(Ljava/lang/String;)V", 1193 (void*) nativeDumpDisplayTree }, 1194 { "nativeEvaluateLayersAnimations", "(I)Z", 1195 (void*) nativeEvaluateLayersAnimations }, 1196 { "nativeGetSelection", "()Ljava/lang/String;", 1197 (void*) nativeGetSelection }, 1198 { "nativeLayerBounds", "(I)Landroid/graphics/Rect;", 1199 (void*) nativeLayerBounds }, 1200 { "nativeSetHeightCanMeasure", "(Z)V", 1201 (void*) nativeSetHeightCanMeasure }, 1202 { "nativeSetBaseLayer", "(IILandroid/graphics/Region;ZZ)Z", 1203 (void*) nativeSetBaseLayer }, 1204 { "nativeGetBaseLayer", "()I", 1205 (void*) nativeGetBaseLayer }, 1206 { "nativeReplaceBaseContent", "(I)V", 1207 (void*) nativeReplaceBaseContent }, 1208 { "nativeCopyBaseContentToPicture", "(Landroid/graphics/Picture;)V", 1209 (void*) nativeCopyBaseContentToPicture }, 1210 { "nativeHasContent", "()Z", 1211 (void*) nativeHasContent }, 1212 { "nativeDiscardAllTextures", "()V", 1213 (void*) nativeDiscardAllTextures }, 1214 { "nativeTileProfilingStart", "()V", 1215 (void*) nativeTileProfilingStart }, 1216 { "nativeTileProfilingStop", "()F", 1217 (void*) nativeTileProfilingStop }, 1218 { "nativeTileProfilingClear", "()V", 1219 (void*) nativeTileProfilingClear }, 1220 { "nativeTileProfilingNumFrames", "()I", 1221 (void*) nativeTileProfilingNumFrames }, 1222 { "nativeTileProfilingNumTilesInFrame", "(I)I", 1223 (void*) nativeTileProfilingNumTilesInFrame }, 1224 { "nativeTileProfilingGetInt", "(IILjava/lang/String;)I", 1225 (void*) nativeTileProfilingGetInt }, 1226 { "nativeTileProfilingGetFloat", "(IILjava/lang/String;)F", 1227 (void*) nativeTileProfilingGetFloat }, 1228 { "nativeStopGL", "()V", 1229 (void*) nativeStopGL }, 1230 { "nativeScrollableLayer", "(IILandroid/graphics/Rect;Landroid/graphics/Rect;)I", 1231 (void*) nativeScrollableLayer }, 1232 { "nativeScrollLayer", "(III)Z", 1233 (void*) nativeScrollLayer }, 1234 { "nativeSetIsScrolling", "(Z)V", 1235 (void*) nativeSetIsScrolling }, 1236 { "nativeUseHardwareAccelSkia", "(Z)V", 1237 (void*) nativeUseHardwareAccelSkia }, 1238 { "nativeGetBackgroundColor", "()I", 1239 (void*) nativeGetBackgroundColor }, 1240 { "nativeSetProperty", "(Ljava/lang/String;Ljava/lang/String;)Z", 1241 (void*) nativeSetProperty }, 1242 { "nativeGetProperty", "(Ljava/lang/String;)Ljava/lang/String;", 1243 (void*) nativeGetProperty }, 1244 { "nativeOnTrimMemory", "(I)V", 1245 (void*) nativeOnTrimMemory }, 1246 { "nativeSetPauseDrawing", "(IZ)V", 1247 (void*) nativeSetPauseDrawing }, 1248 { "nativeSetTextSelection", "(II)V", 1249 (void*) nativeSetTextSelection }, 1250 { "nativeGetHandleLayerId", "(IILandroid/graphics/Rect;)I", 1251 (void*) nativeGetHandleLayerId }, 1252 { "nativeIsBaseFirst", "(I)Z", 1253 (void*) nativeIsBaseFirst }, 1254 { "nativeMapLayerRect", "(IILandroid/graphics/Rect;)V", 1255 (void*) nativeMapLayerRect }, 1256 { "nativeSetHwAccelerated", "(IZ)I", 1257 (void*) nativeSetHwAccelerated }, 1258}; 1259 1260int registerWebView(JNIEnv* env) 1261{ 1262 jclass clazz = env->FindClass("android/webkit/WebViewClassic"); 1263 ALOG_ASSERT(clazz, "Unable to find class android/webkit/WebViewClassic"); 1264 gWebViewField = env->GetFieldID(clazz, "mNativeClass", "I"); 1265 ALOG_ASSERT(gWebViewField, "Unable to find android/webkit/WebViewClassic.mNativeClass"); 1266 env->DeleteLocalRef(clazz); 1267 1268 return jniRegisterNativeMethods(env, "android/webkit/WebViewClassic", gJavaWebViewMethods, NELEM(gJavaWebViewMethods)); 1269} 1270 1271} // namespace android 1272