EMMA Coverage Report (generated Fri Aug 23 16:39:17 PDT 2013)
[all classes][org.chromium.android_webview]

COVERAGE SUMMARY FOR SOURCE FILE [AwContents.java]

nameclass, %method, %block, %line, %
AwContents.java72%  (13/18)62%  (133/215)65%  (1713/2635)63%  (360.2/573)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class AwContents$20%   (0/1)0%   (0/2)0%   (0/10)0%   (0/2)
AwContents$2 (AwContents): void 0%   (0/1)0%   (0/6)0%   (0/1)
call (): Picture 0%   (0/1)0%   (0/4)0%   (0/1)
     
class AwContents$50%   (0/1)0%   (0/2)0%   (0/14)0%   (0/3)
AwContents$5 (AwContents, ValueCallback): void 0%   (0/1)0%   (0/9)0%   (0/1)
handleJavaScriptResult (String): void 0%   (0/1)0%   (0/5)0%   (0/2)
     
class AwContents$60%   (0/1)0%   (0/2)0%   (0/14)0%   (0/3)
AwContents$6 (AwContents, ValueCallback): void 0%   (0/1)0%   (0/9)0%   (0/1)
run (): void 0%   (0/1)0%   (0/5)0%   (0/2)
     
class AwContents$AwGeolocationCallback0%   (0/1)0%   (0/3)0%   (0/19)0%   (0/3)
AwContents$AwGeolocationCallback (AwContents): void 0%   (0/1)0%   (0/6)0%   (0/1)
AwContents$AwGeolocationCallback (AwContents, AwContents$1): void 0%   (0/1)0%   (0/4)0%   (0/1)
invoke (String, boolean, boolean): void 0%   (0/1)0%   (0/9)0%   (0/2)
     
class AwContents$AwGeolocationCallback$10%   (0/1)0%   (0/2)0%   (0/57)0%   (0/8)
AwContents$AwGeolocationCallback$1 (AwContents$AwGeolocationCallback, boolean... 0%   (0/1)0%   (0/15)0%   (0/1)
run (): void 0%   (0/1)0%   (0/42)0%   (0/7)
     
class AwContents$AwGestureStateListener100% (1/1)57%  (4/7)59%  (22/37)45%  (5/11)
onFlingCancelGesture (): void 0%   (0/1)0%   (0/5)0%   (0/2)
onPinchGestureEnd (): void 0%   (0/1)0%   (0/5)0%   (0/2)
onPinchGestureStart (): void 0%   (0/1)0%   (0/5)0%   (0/2)
AwContents$AwGestureStateListener (AwContents): void 100% (1/1)100% (6/6)100% (1/1)
AwContents$AwGestureStateListener (AwContents, AwContents$1): void 100% (1/1)100% (4/4)100% (1/1)
onFlingStartGesture (int, int): void 100% (1/1)100% (7/7)100% (2/2)
onUnhandledFlingStartEvent (): void 100% (1/1)100% (5/5)100% (2/2)
     
class AwContents100% (1/1)56%  (88/156)62%  (1275/2059)59%  (278/469)
AwContents (AwBrowserContext, ViewGroup, AwContents$InternalAccessDelegate, A... 0%   (0/1)0%   (0/11)0%   (0/2)
AwContents (AwBrowserContext, ViewGroup, AwContents$InternalAccessDelegate, A... 0%   (0/1)0%   (0/10)0%   (0/2)
access$1200 (AwContents): AwLayoutSizer 0%   (0/1)0%   (0/3)0%   (0/1)
access$2400 (AwContents): AwBrowserContext 0%   (0/1)0%   (0/3)0%   (0/1)
access$2500 (AwContents, int, boolean, String): void 0%   (0/1)0%   (0/6)0%   (0/1)
addPossiblyUnsafeJavascriptInterface (Object, String, Class): void 0%   (0/1)0%   (0/7)0%   (0/2)
canGoBack (): boolean 0%   (0/1)0%   (0/4)0%   (0/1)
canGoBackOrForward (int): boolean 0%   (0/1)0%   (0/5)0%   (0/1)
canGoForward (): boolean 0%   (0/1)0%   (0/4)0%   (0/1)
capturePicture (): Picture 0%   (0/1)0%   (0/19)0%   (0/2)
clearHistory (): void 0%   (0/1)0%   (0/4)0%   (0/2)
clearSslPreferences (): void 0%   (0/1)0%   (0/4)0%   (0/2)
computeVerticalScrollExtent (): int 0%   (0/1)0%   (0/4)0%   (0/1)
dispatchKeyEvent (KeyEvent): boolean 0%   (0/1)0%   (0/5)0%   (0/1)
evaluateJavaScript (String, ValueCallback): void 0%   (0/1)0%   (0/16)0%   (0/5)
evaluateJavaScriptEvenIfNotYetNavigated (String): void 0%   (0/1)0%   (0/5)0%   (0/2)
getAccessibilityNodeProvider (): AccessibilityNodeProvider 0%   (0/1)0%   (0/4)0%   (0/1)
getAwDrawGLFunction (): int 0%   (0/1)0%   (0/2)0%   (0/1)
getAwDrawGLViewContext (): int 0%   (0/1)0%   (0/14)0%   (0/2)
getCertificate (): SslCertificate 0%   (0/1)0%   (0/11)0%   (0/2)
getContentHeightCss (): int 0%   (0/1)0%   (0/7)0%   (0/1)
getContentSettings (): ContentSettings 0%   (0/1)0%   (0/4)0%   (0/1)
getContentWidthCss (): int 0%   (0/1)0%   (0/7)0%   (0/1)
getHttpAuthUsernamePassword (String, String): String [] 0%   (0/1)0%   (0/10)0%   (0/1)
getLocationOnScreen (): int [] 0%   (0/1)0%   (0/9)0%   (0/3)
getMostRecentProgress (): int 0%   (0/1)0%   (0/4)0%   (0/1)
getNavigationHistory (): NavigationHistory 0%   (0/1)0%   (0/4)0%   (0/1)
getTitle (): String 0%   (0/1)0%   (0/4)0%   (0/1)
getUrl (): String 0%   (0/1)0%   (0/14)0%   (0/3)
isPaused (): boolean 0%   (0/1)0%   (0/3)0%   (0/1)
onConfigurationChanged (Configuration): void 0%   (0/1)0%   (0/5)0%   (0/2)
onCreateInputConnection (EditorInfo): InputConnection 0%   (0/1)0%   (0/5)0%   (0/1)
onFocusChanged (boolean, int, Rect): void 0%   (0/1)0%   (0/16)0%   (0/3)
onGenericMotionEvent (MotionEvent): boolean 0%   (0/1)0%   (0/5)0%   (0/1)
onGeolocationPermissionsHidePrompt (): void 0%   (0/1)0%   (0/4)0%   (0/2)
onGeolocationPermissionsShowPrompt (String): void 0%   (0/1)0%   (0/42)0%   (0/10)
onHoverEvent (MotionEvent): boolean 0%   (0/1)0%   (0/5)0%   (0/1)
onInitializeAccessibilityEvent (AccessibilityEvent): void 0%   (0/1)0%   (0/5)0%   (0/2)
onInitializeAccessibilityNodeInfo (AccessibilityNodeInfo): void 0%   (0/1)0%   (0/5)0%   (0/2)
onKeyUp (int, KeyEvent): boolean 0%   (0/1)0%   (0/6)0%   (0/1)
onPause (): void 0%   (0/1)0%   (0/17)0%   (0/4)
onReceivedHttpAuthRequest (AwHttpAuthHandler, String, String): void 0%   (0/1)0%   (0/7)0%   (0/2)
onResume (): void 0%   (0/1)0%   (0/17)0%   (0/4)
onWindowFocusChanged (boolean): void 0%   (0/1)0%   (0/16)0%   (0/3)
overlayHorizontalScrollbar (): boolean 0%   (0/1)0%   (0/3)0%   (0/1)
overlayVerticalScrollbar (): boolean 0%   (0/1)0%   (0/3)0%   (0/1)
pauseTimers (): void 0%   (0/1)0%   (0/3)0%   (0/2)
performAccessibilityAction (int, Bundle): boolean 0%   (0/1)0%   (0/6)0%   (0/1)
performLongClick (): boolean 0%   (0/1)0%   (0/4)0%   (0/1)
receivePopupContents (int): void 0%   (0/1)0%   (0/71)0%   (0/17)
reload (): void 0%   (0/1)0%   (0/4)0%   (0/2)
removeJavascriptInterface (String): void 0%   (0/1)0%   (0/5)0%   (0/2)
requestChildRectangleOnScreen (View, Rect, boolean): boolean 0%   (0/1)0%   (0/16)0%   (0/1)
requestFocus (): void 0%   (0/1)0%   (0/17)0%   (0/4)
requestFocusNodeHref (Message): void 0%   (0/1)0%   (0/37)0%   (0/9)
requestImageRef (Message): void 0%   (0/1)0%   (0/25)0%   (0/7)
resumeTimers (): void 0%   (0/1)0%   (0/3)0%   (0/2)
setAwDrawGLFunctionTable (int): void 0%   (0/1)0%   (0/3)0%   (0/2)
setAwDrawSWFunctionTable (int): void 0%   (0/1)0%   (0/3)0%   (0/2)
setHorizontalScrollbarOverlay (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
setHttpAuthUsernamePassword (String, String, String, String): void 0%   (0/1)0%   (0/12)0%   (0/2)
setVerticalScrollbarOverlay (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
setViewVisibilityInternal (boolean): void 0%   (0/1)0%   (0/14)0%   (0/4)
stopLoading (): void 0%   (0/1)0%   (0/4)0%   (0/2)
supplyContentsForPopup (AwContents): void 0%   (0/1)0%   (0/25)0%   (0/10)
supportsAccessibilityAction (int): boolean 0%   (0/1)0%   (0/5)0%   (0/1)
zoomIn (): boolean 0%   (0/1)0%   (0/4)0%   (0/1)
zoomOut (): boolean 0%   (0/1)0%   (0/4)0%   (0/1)
onDetachedFromWindow (): void 100% (1/1)50%  (18/36)70%  (7/10)
setScrollBarStyle (int): void 100% (1/1)53%  (10/19)60%  (2.4/4)
enableOnNewPicture (boolean, boolean): void 100% (1/1)56%  (15/27)68%  (4.8/7)
postInvalidateOnAnimation (): void 100% (1/1)60%  (6/10)75%  (3/4)
generateArchiveAutoNamePath (String, String): String 100% (1/1)62%  (60/97)51%  (8.7/17)
saveWebArchiveInternal (String, ValueCallback): void 100% (1/1)63%  (12/19)75%  (3/4)
onVisibilityChanged (View, int): void 100% (1/1)65%  (11/17)46%  (1.8/4)
<static initializer> 100% (1/1)79%  (15/19)90%  (2.7/3)
destroy (): void 100% (1/1)79%  (42/53)85%  (10.2/12)
setOverScrollMode (int): void 100% (1/1)80%  (12/15)75%  (3/4)
saveState (Bundle): boolean 100% (1/1)82%  (18/22)90%  (4.5/5)
getLastHitTestResult (): AwContents$HitTestData 100% (1/1)83%  (10/12)87%  (2.6/3)
clearMatches (): void 100% (1/1)89%  (8/9)92%  (2.8/3)
clearCache (boolean): void 100% (1/1)90%  (9/10)92%  (2.8/3)
documentHasImages (Message): void 100% (1/1)90%  (9/10)92%  (2.8/3)
findAllAsync (String): void 100% (1/1)90%  (9/10)92%  (2.8/3)
findNext (boolean): void 100% (1/1)90%  (9/10)92%  (2.8/3)
getOriginalUrl (): String 100% (1/1)90%  (18/20)80%  (4/5)
setNewAwContents (int): void 100% (1/1)91%  (95/104)86%  (13.7/16)
generateMHTMLCallback (String, long, ValueCallback): void 100% (1/1)92%  (12/13)89%  (2.7/3)
setWindowVisibilityInternal (boolean): void 100% (1/1)93%  (13/14)96%  (3.8/4)
onWindowVisibilityChanged (int): void 100% (1/1)93%  (14/15)96%  (3.8/4)
restoreState (Bundle): boolean 100% (1/1)94%  (29/31)95%  (5.7/6)
onAttachedToWindow (): void 100% (1/1)95%  (20/21)95%  (4.8/5)
updateGlobalVisibleRect (): void 100% (1/1)96%  (23/24)95%  (4.8/5)
onTouchEvent (MotionEvent): boolean 100% (1/1)97%  (56/58)96%  (9.6/10)
AwContents (AwBrowserContext, ViewGroup, AwContents$InternalAccessDelegate, A... 100% (1/1)99%  (168/169)100% (30/30)
access$000 (int): void 100% (1/1)100% (3/3)100% (1/1)
access$100 (int): void 100% (1/1)100% (3/3)100% (1/1)
access$1000 (AwContents, int, float): void 100% (1/1)100% (5/5)100% (1/1)
access$1100 (AwContents, int, int, int): void 100% (1/1)100% (6/6)100% (1/1)
access$1600 (AwContents): ContentViewCore 100% (1/1)100% (3/3)100% (1/1)
access$200 (AwContents): AwSettings 100% (1/1)100% (3/3)100% (1/1)
access$2100 (AwContents, int, String []): void 100% (1/1)100% (5/5)100% (1/1)
access$2200 (String, String): String 100% (1/1)100% (4/4)100% (1/1)
access$2300 (AwContents, String, ValueCallback): void 100% (1/1)100% (5/5)100% (1/1)
access$300 (AwContents): DefaultVideoPosterRequestHandler 100% (1/1)100% (3/3)100% (1/1)
access$400 (AwContents): AwContentsClient 100% (1/1)100% (3/3)100% (1/1)
access$500 (AwContents): ViewGroup 100% (1/1)100% (3/3)100% (1/1)
access$600 (AwContents): AwContents$InternalAccessDelegate 100% (1/1)100% (3/3)100% (1/1)
access$700 (AwContents): int 100% (1/1)100% (3/3)100% (1/1)
access$800 (AwContents): double 100% (1/1)100% (3/3)100% (1/1)
access$900 (AwContents): AwScrollOffsetManager 100% (1/1)100% (3/3)100% (1/1)
canZoomIn (): boolean 100% (1/1)100% (4/4)100% (1/1)
canZoomOut (): boolean 100% (1/1)100% (4/4)100% (1/1)
computeHorizontalScrollOffset (): int 100% (1/1)100% (4/4)100% (1/1)
computeHorizontalScrollRange (): int 100% (1/1)100% (4/4)100% (1/1)
computeScroll (): void 100% (1/1)100% (6/6)100% (2/2)
computeVerticalScrollOffset (): int 100% (1/1)100% (4/4)100% (1/1)
computeVerticalScrollRange (): int 100% (1/1)100% (4/4)100% (1/1)
createAndInitializeContentViewCore (ViewGroup, AwContents$InternalAccessDeleg... 100% (1/1)100% (24/24)100% (6/6)
didOverscroll (int, int): void 100% (1/1)100% (24/24)100% (6/6)
flingScroll (int, int): void 100% (1/1)100% (6/6)100% (2/2)
getContentViewCore (): ContentViewCore 100% (1/1)100% (3/3)100% (1/1)
getEffectiveBackgroundColor (): int 100% (1/1)100% (14/14)100% (3/3)
getFavicon (): Bitmap 100% (1/1)100% (3/3)100% (1/1)
getNativeInstanceCount (): int 100% (1/1)100% (2/2)100% (1/1)
getScale (): float 100% (1/1)100% (9/9)100% (1/1)
getSettings (): AwSettings 100% (1/1)100% (3/3)100% (1/1)
getZoomControlsForTest (): View 100% (1/1)100% (4/4)100% (1/1)
goBack (): void 100% (1/1)100% (6/6)100% (3/3)
goBackOrForward (int): void 100% (1/1)100% (7/7)100% (3/3)
goForward (): void 100% (1/1)100% (6/6)100% (3/3)
hideAutofillPopup (): void 100% (1/1)100% (7/7)100% (3/3)
invokeZoomPicker (): void 100% (1/1)100% (4/4)100% (2/2)
isMultiTouchZoomSupported (): boolean 100% (1/1)100% (4/4)100% (1/1)
loadUrl (LoadUrlParams): void 100% (1/1)100% (50/50)100% (12/12)
onContainerViewOverScrolled (int, int, boolean, boolean): void 100% (1/1)100% (36/36)100% (6/6)
onContainerViewScrollChanged (int, int, int, int): void 100% (1/1)100% (6/6)100% (2/2)
onDocumentHasImagesResponse (boolean, Message): void 100% (1/1)100% (10/10)100% (3/3)
onDraw (Canvas): void 100% (1/1)100% (68/68)100% (11/11)
onFindResultReceived (int, int, boolean): void 100% (1/1)100% (7/7)100% (2/2)
onMeasure (int, int): void 100% (1/1)100% (6/6)100% (2/2)
onNewPicture (): void 100% (1/1)100% (7/7)100% (2/2)
onReceivedIcon (Bitmap): void 100% (1/1)100% (8/8)100% (3/3)
onReceivedTouchIconUrl (String, boolean): void 100% (1/1)100% (6/6)100% (2/2)
onSizeChanged (int, int, int, int): void 100% (1/1)100% (30/30)100% (6/6)
onWebLayoutPageScaleFactorChanged (float): void 100% (1/1)100% (6/6)100% (2/2)
pageDown (boolean): boolean 100% (1/1)100% (5/5)100% (1/1)
pageUp (boolean): boolean 100% (1/1)100% (5/5)100% (1/1)
requestDrawGL (Canvas): boolean 100% (1/1)100% (5/5)100% (1/1)
requestVisitedHistoryFromClient (): void 100% (1/1)100% (10/10)100% (3/3)
saveWebArchive (String, boolean, ValueCallback): void 100% (1/1)100% (18/18)100% (5/5)
scrollContainerViewTo (int, int): void 100% (1/1)100% (6/6)100% (2/2)
setAwAutofillManagerDelegate (AwAutofillManagerDelegate): void 100% (1/1)100% (8/8)100% (3/3)
setBackgroundColor (int): void 100% (1/1)100% (12/12)100% (3/3)
suppressInterceptionForThisNavigation (): void 100% (1/1)100% (10/10)100% (3/3)
updateHitTestData (int, String, String, String, String): void 100% (1/1)100% (21/21)100% (6/6)
     
class AwContents$InterceptNavigationDelegateImpl100% (1/1)100% (4/4)94%  (84/89)99%  (16.8/17)
shouldIgnoreNavigation (NavigationParams): boolean 100% (1/1)93%  (70/75)98%  (13.8/14)
AwContents$InterceptNavigationDelegateImpl (AwContents): void 100% (1/1)100% (6/6)100% (1/1)
AwContents$InterceptNavigationDelegateImpl (AwContents, AwContents$1): void 100% (1/1)100% (4/4)100% (1/1)
onUrlLoadRequested (String): void 100% (1/1)100% (4/4)100% (2/2)
     
class AwContents$IoThreadClientImpl100% (1/1)100% (9/9)98%  (97/99)99%  (16.8/17)
shouldBlockContentUrls (): boolean 100% (1/1)78%  (7/9)77%  (0.8/1)
AwContents$IoThreadClientImpl (AwContents): void 100% (1/1)100% (6/6)100% (1/1)
AwContents$IoThreadClientImpl (AwContents, AwContents$1): void 100% (1/1)100% (4/4)100% (1/1)
getCacheMode (): int 100% (1/1)100% (5/5)100% (1/1)
newLoginRequest (String, String, String): void 100% (1/1)100% (9/9)100% (2/2)
onDownloadStart (String, String, String, String, long): void 100% (1/1)100% (11/11)100% (2/2)
shouldBlockFileUrls (): boolean 100% (1/1)100% (9/9)100% (1/1)
shouldBlockNetworkLoads (): boolean 100% (1/1)100% (5/5)100% (1/1)
shouldInterceptRequest (String, boolean): InterceptedRequestData 100% (1/1)100% (41/41)100% (8/8)
     
class AwContents$AwContentUpdateFrameInfoListener100% (1/1)100% (3/3)98%  (52/53)97%  (6.8/7)
onFrameInfoUpdated (float, float, float): void 100% (1/1)98%  (42/43)97%  (5.8/6)
AwContents$AwContentUpdateFrameInfoListener (AwContents): void 100% (1/1)100% (6/6)100% (1/1)
AwContents$AwContentUpdateFrameInfoListener (AwContents, AwContents$1): void 100% (1/1)100% (4/4)100% (1/1)
     
class AwContents$AwScrollOffsetManagerDelegate100% (1/1)100% (8/8)98%  (59/60)98%  (11.8/12)
scrollNativeTo (int, int): void 100% (1/1)93%  (13/14)93%  (2.8/3)
AwContents$AwScrollOffsetManagerDelegate (AwContents): void 100% (1/1)100% (6/6)100% (1/1)
AwContents$AwScrollOffsetManagerDelegate (AwContents, AwContents$1): void 100% (1/1)100% (4/4)100% (1/1)
getContainerViewScrollX (): int 100% (1/1)100% (5/5)100% (1/1)
getContainerViewScrollY (): int 100% (1/1)100% (5/5)100% (1/1)
invalidate (): void 100% (1/1)100% (5/5)100% (2/2)
overScrollContainerViewBy (int, int, int, int, int, int, boolean): void 100% (1/1)100% (14/14)100% (2/2)
scrollContainerViewTo (int, int): void 100% (1/1)100% (7/7)100% (2/2)
     
class AwContents$1100% (1/1)100% (2/2)100% (17/17)100% (4/4)
AwContents$1 (AwContents): void 100% (1/1)100% (6/6)100% (1/1)
onGestureZoomSupportChanged (boolean): void 100% (1/1)100% (11/11)100% (3/3)
     
class AwContents$3100% (1/1)100% (2/2)100% (13/13)100% (3/3)
AwContents$3 (AwContents): void 100% (1/1)100% (6/6)100% (1/1)
onReceiveValue (String []): void 100% (1/1)100% (7/7)100% (2/2)
     
class AwContents$3$1100% (1/1)100% (2/2)100% (26/26)100% (4/4)
AwContents$3$1 (AwContents$3, String []): void 100% (1/1)100% (9/9)100% (1/1)
run (): void 100% (1/1)100% (17/17)100% (3/3)
     
class AwContents$4100% (1/1)100% (3/3)100% (26/26)100% (4/4)
AwContents$4 (AwContents, String, ValueCallback): void 100% (1/1)100% (12/12)100% (1/1)
doInBackground (Void []): String 100% (1/1)100% (7/7)100% (1/1)
onPostExecute (String): void 100% (1/1)100% (7/7)100% (2/2)
     
class AwContents$AwLayoutSizerDelegate100% (1/1)100% (4/4)100% (22/22)100% (5/5)
AwContents$AwLayoutSizerDelegate (AwContents): void 100% (1/1)100% (6/6)100% (1/1)
AwContents$AwLayoutSizerDelegate (AwContents, AwContents$1): void 100% (1/1)100% (4/4)100% (1/1)
requestLayout (): void 100% (1/1)100% (5/5)100% (2/2)
setMeasuredDimension (int, int): void 100% (1/1)100% (7/7)100% (2/2)
     
class AwContents$DestroyRunnable100% (1/1)100% (3/3)100% (17/17)100% (7/7)
AwContents$DestroyRunnable (int): void 100% (1/1)100% (6/6)100% (3/3)
AwContents$DestroyRunnable (int, AwContents$1): void 100% (1/1)100% (4/4)100% (1/1)
run (): void 100% (1/1)100% (7/7)100% (3/3)
     
class AwContents$HitTestData100% (1/1)100% (1/1)100% (3/3)100% (1/1)
AwContents$HitTestData (): void 100% (1/1)100% (3/3)100% (1/1)

1// Copyright 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4 
5package org.chromium.android_webview;
6 
7import android.content.pm.PackageManager;
8import android.content.res.Configuration;
9import android.graphics.Bitmap;
10import android.graphics.Canvas;
11import android.graphics.Color;
12import android.graphics.Picture;
13import android.graphics.Rect;
14import android.graphics.drawable.Drawable;
15import android.net.http.SslCertificate;
16import android.os.AsyncTask;
17import android.os.Build;
18import android.os.Bundle;
19import android.os.Message;
20import android.os.Process;
21import android.text.TextUtils;
22import android.util.Log;
23import android.view.KeyEvent;
24import android.view.MotionEvent;
25import android.view.View;
26import android.view.ViewGroup;
27import android.view.ViewTreeObserver;
28import android.view.accessibility.AccessibilityEvent;
29import android.view.accessibility.AccessibilityNodeInfo;
30import android.view.accessibility.AccessibilityNodeProvider;
31import android.view.inputmethod.EditorInfo;
32import android.view.inputmethod.InputConnection;
33import android.webkit.GeolocationPermissions;
34import android.webkit.ValueCallback;
35import android.widget.OverScroller;
36 
37import com.google.common.annotations.VisibleForTesting;
38 
39import org.chromium.base.CalledByNative;
40import org.chromium.base.JNINamespace;
41import org.chromium.base.ThreadUtils;
42import org.chromium.content.browser.ContentSettings;
43import org.chromium.content.browser.ContentVideoView;
44import org.chromium.content.browser.ContentViewClient;
45import org.chromium.content.browser.ContentViewCore;
46import org.chromium.content.browser.ContentViewStatics;
47import org.chromium.content.browser.LoadUrlParams;
48import org.chromium.content.browser.NavigationHistory;
49import org.chromium.content.browser.PageTransitionTypes;
50import org.chromium.content.common.CleanupReference;
51import org.chromium.components.navigation_interception.InterceptNavigationDelegate;
52import org.chromium.components.navigation_interception.NavigationParams;
53import org.chromium.net.GURLUtils;
54import org.chromium.ui.gfx.DeviceDisplayInfo;
55 
56import java.io.File;
57import java.lang.annotation.Annotation;
58import java.net.MalformedURLException;
59import java.net.URL;
60import java.util.concurrent.Callable;
61import java.util.ArrayList;
62import java.util.List;
63 
64/**
65 * Exposes the native AwContents class, and together these classes wrap the ContentViewCore
66 * and Browser components that are required to implement Android WebView API. This is the
67 * primary entry point for the WebViewProvider implementation; it holds a 1:1 object
68 * relationship with application WebView instances.
69 * (We define this class independent of the hidden WebViewProvider interfaces, to allow
70 * continuous build & test in the open source SDK-based tree).
71 */
72@JNINamespace("android_webview")
73public class AwContents {
74    private static final String TAG = "AwContents";
75 
76    private static final String WEB_ARCHIVE_EXTENSION = ".mht";
77 
78    /**
79     * WebKit hit test related data strcutre. These are used to implement
80     * getHitTestResult, requestFocusNodeHref, requestImageRef methods in WebView.
81     * All values should be updated together. The native counterpart is
82     * AwHitTestData.
83     */
84    public static class HitTestData {
85        // Used in getHitTestResult.
86        public int hitTestResultType;
87        public String hitTestResultExtraData;
88 
89        // Used in requestFocusNodeHref (all three) and requestImageRef (only imgSrc).
90        public String href;
91        public String anchorText;
92        public String imgSrc;
93    }
94 
95    /**
96     * Interface that consumers of {@link AwContents} must implement to allow the proper
97     * dispatching of view methods through the containing view.
98     */
99    public interface InternalAccessDelegate extends ContentViewCore.InternalAccessDelegate {
100        /**
101         * @see View#onScrollChanged(int, int, int, int)
102         *
103         * TODO(mkosiba): WebViewClassic calls this, AwContents doesn't. Check if there
104         * are any cases we're missing, if not - remove.
105         */
106        void onScrollChanged(int lPix, int tPix, int oldlPix, int oldtPix);
107 
108        /**
109         * @see View#overScrollBy(int, int, int, int, int, int, int, int, boolean);
110         */
111        void overScrollBy(int deltaX, int deltaY,
112                int scrollX, int scrollY,
113                int scrollRangeX, int scrollRangeY,
114                int maxOverScrollX, int maxOverScrollY,
115                boolean isTouchEvent);
116 
117        /**
118         * @see View#scrollTo(int, int)
119         */
120        void super_scrollTo(int scrollX, int scrollY);
121 
122        /**
123         * @see View#setMeasuredDimension(int, int)
124         */
125        void setMeasuredDimension(int measuredWidth, int measuredHeight);
126 
127        /**
128         * @see View#getScrollBarStyle()
129         */
130        int super_getScrollBarStyle();
131 
132        /**
133         * Requests a callback on the native DrawGL method (see getAwDrawGLFunction)
134         * if called from within onDraw, |canvas| will be non-null and hardware accelerated.
135         * otherwise, |canvas| will be null, and the container view itself will be hardware
136         * accelerated.
137         *
138         * @return false indicates the GL draw request was not accepted, and the caller
139         *         should fallback to the SW path.
140         */
141        boolean requestDrawGL(Canvas canvas);
142    }
143 
144    private int mNativeAwContents;
145    private final AwBrowserContext mBrowserContext;
146    private final ViewGroup mContainerView;
147    private ContentViewCore mContentViewCore;
148    private final AwContentsClient mContentsClient;
149    private final AwContentsClientBridge mContentsClientBridge;
150    private final AwWebContentsDelegate mWebContentsDelegate;
151    private final AwContentsIoThreadClient mIoThreadClient;
152    private final InterceptNavigationDelegateImpl mInterceptNavigationDelegate;
153    private final InternalAccessDelegate mInternalAccessAdapter;
154    private final AwLayoutSizer mLayoutSizer;
155    private final AwZoomControls mZoomControls;
156    private final AwScrollOffsetManager mScrollOffsetManager;
157    private OverScrollGlow mOverScrollGlow;
158    // This can be accessed on any thread after construction. See AwContentsIoThreadClient.
159    private final AwSettings mSettings;
160 
161    private boolean mIsPaused;
162    private boolean mIsViewVisible;
163    private boolean mIsWindowVisible;
164    private boolean mIsAttachedToWindow;
165    private Bitmap mFavicon;
166    private boolean mHasRequestedVisitedHistoryFromClient;
167    // TODO(boliu): This should be in a global context, not per webview.
168    private final double mDIPScale;
169 
170    // The base background color, i.e. not accounting for any CSS body from the current page.
171    private int mBaseBackgroundColor = Color.WHITE;
172 
173    // Must call nativeUpdateLastHitTestData first to update this before use.
174    private final HitTestData mPossiblyStaleHitTestData = new HitTestData();
175 
176    private DefaultVideoPosterRequestHandler mDefaultVideoPosterRequestHandler;
177 
178    // Bound method for suppling Picture instances to the AwContentsClient. Will be null if the
179    // picture listener API has not yet been enabled, or if it is using invalidation-only mode.
180    private Callable<Picture> mPictureListenerContentProvider;
181 
182    private boolean mContainerViewFocused;
183    private boolean mWindowFocused;
184 
185    private AwAutofillManagerDelegate mAwAutofillManagerDelegate;
186 
187    private static final class DestroyRunnable implements Runnable {
188        private int mNativeAwContents;
189        private DestroyRunnable(int nativeAwContents) {
190            mNativeAwContents = nativeAwContents;
191        }
192        @Override
193        public void run() {
194            // This is a no-op if not currently attached.
195            nativeOnDetachedFromWindow(mNativeAwContents);
196            nativeDestroy(mNativeAwContents);
197        }
198    }
199 
200    // Reference to the active mNativeAwContents pointer while it is active use
201    // (ie before it is destroyed).
202    private CleanupReference mCleanupReference;
203 
204    // A list of references to native pointers where the Java counterpart has been
205    // destroyed, but are held here because they are waiting for onDetachFromWindow
206    // to release GL resources. This is cleared inside onDetachFromWindow.
207    private List<CleanupReference> mPendingDetachCleanupReferences;
208 
209    //--------------------------------------------------------------------------------------------
210    private class IoThreadClientImpl implements AwContentsIoThreadClient {
211        // All methods are called on the IO thread.
212 
213        @Override
214        public int getCacheMode() {
215            return mSettings.getCacheMode();
216        }
217 
218        @Override
219        public InterceptedRequestData shouldInterceptRequest(final String url,
220                boolean isMainFrame) {
221            InterceptedRequestData interceptedRequestData;
222            // Return the response directly if the url is default video poster url.
223            interceptedRequestData = mDefaultVideoPosterRequestHandler.shouldInterceptRequest(url);
224            if (interceptedRequestData != null) return interceptedRequestData;
225 
226            interceptedRequestData = mContentsClient.shouldInterceptRequest(url);
227 
228            if (interceptedRequestData == null) {
229                mContentsClient.getCallbackHelper().postOnLoadResource(url);
230            }
231 
232            if (isMainFrame && interceptedRequestData != null &&
233                    interceptedRequestData.getData() == null) {
234                // In this case the intercepted URLRequest job will simulate an empty response
235                // which doesn't trigger the onReceivedError callback. For WebViewClassic
236                // compatibility we synthesize that callback. http://crbug.com/180950
237                mContentsClient.getCallbackHelper().postOnReceivedError(
238                        ErrorCodeConversionHelper.ERROR_UNKNOWN,
239                        null /* filled in by the glue layer */, url);
240            }
241            return interceptedRequestData;
242        }
243 
244        @Override
245        public boolean shouldBlockContentUrls() {
246            return !mSettings.getAllowContentAccess();
247        }
248 
249        @Override
250        public boolean shouldBlockFileUrls() {
251            return !mSettings.getAllowFileAccess();
252        }
253 
254        @Override
255        public boolean shouldBlockNetworkLoads() {
256            return mSettings.getBlockNetworkLoads();
257        }
258 
259        @Override
260        public void onDownloadStart(String url,
261                                    String userAgent,
262                                    String contentDisposition,
263                                    String mimeType,
264                                    long contentLength) {
265            mContentsClient.getCallbackHelper().postOnDownloadStart(url, userAgent,
266                    contentDisposition, mimeType, contentLength);
267        }
268 
269        @Override
270        public void newLoginRequest(String realm, String account, String args) {
271            mContentsClient.getCallbackHelper().postOnReceivedLoginRequest(realm, account, args);
272        }
273    }
274 
275    //--------------------------------------------------------------------------------------------
276    private class InterceptNavigationDelegateImpl implements InterceptNavigationDelegate {
277        private String mLastLoadUrlAddress;
278 
279        public void onUrlLoadRequested(String url) {
280            mLastLoadUrlAddress = url;
281        }
282 
283        @Override
284        public boolean shouldIgnoreNavigation(NavigationParams navigationParams) {
285            final String url = navigationParams.url;
286            final int transitionType = navigationParams.pageTransitionType;
287            final boolean isLoadUrl =
288                    (transitionType & PageTransitionTypes.PAGE_TRANSITION_FROM_API) != 0;
289            final boolean isBackForward =
290                    (transitionType & PageTransitionTypes.PAGE_TRANSITION_FORWARD_BACK) != 0;
291            final boolean isReload =
292                    (transitionType & PageTransitionTypes.PAGE_TRANSITION_CORE_MASK) ==
293                    PageTransitionTypes.PAGE_TRANSITION_RELOAD;
294            final boolean isRedirect = navigationParams.isRedirect;
295 
296            boolean ignoreNavigation = false;
297 
298            // Any navigation from loadUrl, goBack/Forward, or reload, are considered application
299            // initiated and hence will not yield a shouldOverrideUrlLoading() callback.
300            // TODO(joth): Using PageTransitionTypes should be sufficient to determine all app
301            // initiated navigations, and so mLastLoadUrlAddress should be removed.
302            if ((isLoadUrl && !isRedirect) || isBackForward || isReload ||
303                    mLastLoadUrlAddress != null && mLastLoadUrlAddress.equals(url)) {
304                // Support the case where the user clicks on a link that takes them back to the
305                // same page.
306                mLastLoadUrlAddress = null;
307 
308                // If the embedder requested the load of a certain URL via the loadUrl API, then we
309                // do not offer it to AwContentsClient.shouldOverrideUrlLoading.
310                // The embedder is also not allowed to intercept POST requests because of
311                // crbug.com/155250.
312            } else if (!navigationParams.isPost) {
313                ignoreNavigation = mContentsClient.shouldOverrideUrlLoading(url);
314            }
315 
316            // The existing contract is that shouldOverrideUrlLoading callbacks are delivered before
317            // onPageStarted callbacks; third party apps depend on this behavior.
318            // Using a ResouceThrottle to implement the navigation interception feature results in
319            // the WebContentsObserver.didStartLoading callback happening before the
320            // ResourceThrottle has a chance to run.
321            // To preserve the ordering the onPageStarted callback is synthesized from the
322            // shouldOverrideUrlLoading, and only if the navigation was not ignored (this
323            // balances out with the onPageFinished callback, which is suppressed in the
324            // AwContentsClient if the navigation was ignored).
325            if (!ignoreNavigation) {
326                // The shouldOverrideUrlLoading call might have resulted in posting messages to the
327                // UI thread. Using sendMessage here (instead of calling onPageStarted directly)
328                // will allow those to run in order.
329                mContentsClient.getCallbackHelper().postOnPageStarted(url);
330            }
331 
332            return ignoreNavigation;
333        }
334    }
335 
336    //--------------------------------------------------------------------------------------------
337    private class AwLayoutSizerDelegate implements AwLayoutSizer.Delegate {
338        @Override
339        public void requestLayout() {
340            mContainerView.requestLayout();
341        }
342 
343        @Override
344        public void setMeasuredDimension(int measuredWidth, int measuredHeight) {
345            mInternalAccessAdapter.setMeasuredDimension(measuredWidth, measuredHeight);
346        }
347    }
348 
349    //--------------------------------------------------------------------------------------------
350    // NOTE: This content size change notification comes from the compositor and reflects the size
351    // of the content on screen (but not neccessarily in the renderer main thread).
352    private class AwContentUpdateFrameInfoListener
353                implements ContentViewCore.UpdateFrameInfoListener {
354        @Override
355        public void onFrameInfoUpdated(float widthCss, float heightCss, float pageScaleFactor) {
356            if (mNativeAwContents == 0) return;
357            int widthPix = (int) Math.floor(widthCss * mDIPScale * pageScaleFactor);
358            int heightPix = (int) Math.floor(heightCss * mDIPScale * pageScaleFactor);
359            mScrollOffsetManager.setContentSize(widthPix, heightPix);
360 
361            nativeSetDisplayedPageScaleFactor(mNativeAwContents, pageScaleFactor);
362        }
363    }
364 
365    //--------------------------------------------------------------------------------------------
366    private class AwScrollOffsetManagerDelegate implements AwScrollOffsetManager.Delegate {
367        @Override
368        public void overScrollContainerViewBy(int deltaX, int deltaY, int scrollX, int scrollY,
369                int scrollRangeX, int scrollRangeY, boolean isTouchEvent) {
370            mInternalAccessAdapter.overScrollBy(deltaX, deltaY, scrollX, scrollY,
371                    scrollRangeX, scrollRangeY, 0, 0, isTouchEvent);
372        }
373 
374        @Override
375        public void scrollContainerViewTo(int x, int y) {
376            mInternalAccessAdapter.super_scrollTo(x, y);
377        }
378 
379        @Override
380        public void scrollNativeTo(int x, int y) {
381            if (mNativeAwContents == 0) return;
382            nativeScrollTo(mNativeAwContents, x, y);
383        }
384 
385        @Override
386        public int getContainerViewScrollX() {
387            return mContainerView.getScrollX();
388        }
389 
390        @Override
391        public int getContainerViewScrollY() {
392            return mContainerView.getScrollY();
393        }
394 
395        @Override
396        public void invalidate() {
397            mContainerView.invalidate();
398        }
399    }
400 
401    //--------------------------------------------------------------------------------------------
402    private class AwGestureStateListener implements ContentViewCore.GestureStateListener {
403        @Override
404        public void onPinchGestureStart() {
405            // While it's possible to re-layout the view during a pinch gesture, the effect is very
406            // janky (especially that the page scale update notification comes from the renderer
407            // main thread, not from the impl thread, so it's usually out of sync with what's on
408            // screen). It's also quite expensive to do a re-layout, so we simply postpone
409            // re-layout for the duration of the gesture. This is compatible with what
410            // WebViewClassic does.
411            mLayoutSizer.freezeLayoutRequests();
412        }
413 
414        @Override
415        public void onPinchGestureEnd() {
416            mLayoutSizer.unfreezeLayoutRequests();
417        }
418 
419        @Override
420        public void onFlingStartGesture(int velocityX, int velocityY) {
421            mScrollOffsetManager.onFlingStartGesture(velocityX, velocityY);
422        }
423 
424 
425        @Override
426        public void onFlingCancelGesture() {
427            mScrollOffsetManager.onFlingCancelGesture();
428        }
429 
430        @Override
431        public void onUnhandledFlingStartEvent() {
432            mScrollOffsetManager.onUnhandledFlingStartEvent();
433        }
434    }
435 
436    /**
437     * @param browserContext the browsing context to associate this view contents with.
438     * @param containerView the view-hierarchy item this object will be bound to.
439     * @param internalAccessAdapter to access private methods on containerView.
440     * @param contentsClient will receive API callbacks from this WebView Contents
441     * @param isAccessFromFileURLsGrantedByDefault passed to AwSettings.
442     *
443     * This constructor uses the default view sizing policy.
444     */
445    public AwContents(AwBrowserContext browserContext, ViewGroup containerView,
446            InternalAccessDelegate internalAccessAdapter, AwContentsClient contentsClient,
447            boolean isAccessFromFileURLsGrantedByDefault) {
448        this(browserContext, containerView, internalAccessAdapter, contentsClient,
449                isAccessFromFileURLsGrantedByDefault, new AwLayoutSizer());
450    }
451 
452    public AwContents(AwBrowserContext browserContext, ViewGroup containerView,
453            InternalAccessDelegate internalAccessAdapter, AwContentsClient contentsClient,
454            boolean isAccessFromFileURLsGrantedByDefault, AwLayoutSizer layoutSizer) {
455        this(browserContext, containerView, internalAccessAdapter, contentsClient,
456                isAccessFromFileURLsGrantedByDefault, layoutSizer, false);
457    }
458 
459    private static ContentViewCore createAndInitializeContentViewCore(ViewGroup containerView,
460            InternalAccessDelegate internalDispatcher, int nativeWebContents,
461            ContentViewCore.GestureStateListener pinchGestureStateListener,
462            ContentViewClient contentViewClient,
463            ContentViewCore.ZoomControlsDelegate zoomControlsDelegate) {
464      ContentViewCore contentViewCore = new ContentViewCore(containerView.getContext());
465      // Note INPUT_EVENTS_DELIVERED_IMMEDIATELY is passed to avoid triggering vsync in the
466      // compositor, not because input events are delivered immediately.
467      contentViewCore.initialize(containerView, internalDispatcher, nativeWebContents, null,
468                ContentViewCore.INPUT_EVENTS_DELIVERED_IMMEDIATELY);
469      contentViewCore.setGestureStateListener(pinchGestureStateListener);
470      contentViewCore.setContentViewClient(contentViewClient);
471      contentViewCore.setZoomControlsDelegate(zoomControlsDelegate);
472      return contentViewCore;
473    }
474 
475    /**
476     * @param layoutSizer the AwLayoutSizer instance implementing the sizing policy for the view.
477     *
478     * This version of the constructor is used in test code to inject test versions of the above
479     * documented classes
480     */
481    public AwContents(AwBrowserContext browserContext, ViewGroup containerView,
482            InternalAccessDelegate internalAccessAdapter, AwContentsClient contentsClient,
483            boolean isAccessFromFileURLsGrantedByDefault, AwLayoutSizer layoutSizer,
484            boolean supportsLegacyQuirks) {
485        mBrowserContext = browserContext;
486        mContainerView = containerView;
487        mInternalAccessAdapter = internalAccessAdapter;
488        mContentsClient = contentsClient;
489        mLayoutSizer = layoutSizer;
490        mDIPScale = DeviceDisplayInfo.create(containerView.getContext()).getDIPScale();
491        mLayoutSizer.setDelegate(new AwLayoutSizerDelegate());
492        mLayoutSizer.setDIPScale(mDIPScale);
493        mWebContentsDelegate = new AwWebContentsDelegateAdapter(contentsClient,
494                mLayoutSizer.getPreferredSizeChangedListener());
495        mContentsClientBridge = new AwContentsClientBridge(contentsClient);
496        mZoomControls = new AwZoomControls(this);
497        mIoThreadClient = new IoThreadClientImpl();
498        mInterceptNavigationDelegate = new InterceptNavigationDelegateImpl();
499 
500        boolean hasInternetPermission = containerView.getContext().checkPermission(
501                    android.Manifest.permission.INTERNET,
502                    Process.myPid(),
503                    Process.myUid()) == PackageManager.PERMISSION_GRANTED;
504        AwSettings.ZoomSupportChangeListener zoomListener =
505                new AwSettings.ZoomSupportChangeListener() {
506                    @Override
507                    public void onGestureZoomSupportChanged(boolean supportsGestureZoom) {
508                        mContentViewCore.updateMultiTouchZoomSupport(supportsGestureZoom);
509                        mContentViewCore.updateDoubleTapDragSupport(supportsGestureZoom);
510                    }
511 
512                };
513        mSettings = new AwSettings(mContainerView.getContext(), hasInternetPermission, zoomListener,
514                isAccessFromFileURLsGrantedByDefault, mDIPScale, supportsLegacyQuirks);
515        mDefaultVideoPosterRequestHandler = new DefaultVideoPosterRequestHandler(mContentsClient);
516        mSettings.setDefaultVideoPosterURL(
517                mDefaultVideoPosterRequestHandler.getDefaultVideoPosterURL());
518        mContentsClient.setDIPScale(mDIPScale);
519        mScrollOffsetManager = new AwScrollOffsetManager(new AwScrollOffsetManagerDelegate(),
520                new OverScroller(mContainerView.getContext()));
521 
522        setOverScrollMode(mContainerView.getOverScrollMode());
523        setScrollBarStyle(mInternalAccessAdapter.super_getScrollBarStyle());
524 
525        setNewAwContents(nativeInit(browserContext));
526    }
527 
528    /**
529     * Common initialization routine for adopting a native AwContents instance into this
530     * java instance.
531     *
532     * TAKE CARE! This method can get called multiple times per java instance. Code accordingly.
533     * ^^^^^^^^^  See the native class declaration for more details on relative object lifetimes.
534     */
535    private void setNewAwContents(int newAwContentsPtr) {
536        if (mNativeAwContents != 0) {
537            destroy();
538            mContentViewCore = null;
539        }
540 
541        assert mNativeAwContents == 0 && mCleanupReference == null && mContentViewCore == null;
542 
543        mNativeAwContents = newAwContentsPtr;
544        // TODO(joth): when the native and java counterparts of AwBrowserContext are hooked up to
545        // each other, we should update |mBrowserContext| according to the newly received native
546        // WebContent's browser context.
547 
548        // The native side object has been bound to this java instance, so now is the time to
549        // bind all the native->java relationships.
550        mCleanupReference = new CleanupReference(this, new DestroyRunnable(mNativeAwContents));
551 
552        int nativeWebContents = nativeGetWebContents(mNativeAwContents);
553        mContentViewCore = createAndInitializeContentViewCore(
554                mContainerView, mInternalAccessAdapter, nativeWebContents,
555                new AwGestureStateListener(), mContentsClient.getContentViewClient(),
556                mZoomControls);
557        nativeSetJavaPeers(mNativeAwContents, this, mWebContentsDelegate, mContentsClientBridge,
558                mIoThreadClient, mInterceptNavigationDelegate);
559        mContentsClient.installWebContentsObserver(mContentViewCore);
560        mContentViewCore.setUpdateFrameInfoListener(new AwContentUpdateFrameInfoListener());
561        mSettings.setWebContents(nativeWebContents);
562        nativeSetDipScale(mNativeAwContents, (float) mDIPScale);
563        updateGlobalVisibleRect();
564 
565        // The only call to onShow. onHide should never be called.
566        mContentViewCore.onShow();
567   }
568 
569    /**
570     * Called on the "source" AwContents that is opening the popup window to
571     * provide the AwContents to host the pop up content.
572     */
573    public void supplyContentsForPopup(AwContents newContents) {
574        int popupNativeAwContents = nativeReleasePopupAwContents(mNativeAwContents);
575        if (popupNativeAwContents == 0) {
576            Log.w(TAG, "Popup WebView bind failed: no pending content.");
577            if (newContents != null) newContents.destroy();
578            return;
579        }
580        if (newContents == null) {
581            nativeDestroy(popupNativeAwContents);
582            return;
583        }
584 
585        newContents.receivePopupContents(popupNativeAwContents);
586    }
587 
588    // Recap: supplyContentsForPopup() is called on the parent window's content, this method is
589    // called on the popup window's content.
590    private void receivePopupContents(int popupNativeAwContents) {
591        // Save existing view state.
592        final boolean wasAttached = mIsAttachedToWindow;
593        final boolean wasViewVisible = mIsViewVisible;
594        final boolean wasWindowVisible = mIsWindowVisible;
595        final boolean wasPaused = mIsPaused;
596        final boolean wasFocused = mWindowFocused;
597 
598        // Properly clean up existing mContentViewCore and mNativeAwContents.
599        if (wasFocused) onWindowFocusChanged(false);
600        if (wasViewVisible) setViewVisibilityInternal(false);
601        if (wasWindowVisible) setWindowVisibilityInternal(false);
602        if (!wasPaused) onPause();
603        // Not calling onDetachedFromWindow here because native code requires GL context to release
604        // GL resources. This case is properly handled when destroy is called while still attached
605        // to window.
606 
607        setNewAwContents(popupNativeAwContents);
608 
609        // Finally refresh all view state for mContentViewCore and mNativeAwContents.
610        if (!wasPaused) onResume();
611        if (wasAttached) onAttachedToWindow();
612        onSizeChanged(mContainerView.getWidth(), mContainerView.getHeight(), 0, 0);
613        if (wasWindowVisible) setWindowVisibilityInternal(true);
614        if (wasViewVisible) setViewVisibilityInternal(true);
615        if (wasFocused) onWindowFocusChanged(true);
616    }
617 
618    /**
619     * Deletes the native counterpart of this object. Normally happens immediately,
620     * but maybe deferred until the appropriate time for GL resource cleanup. Either way
621     * this is transparent to the caller: after this function returns the object is
622     * effectively dead and methods are no-ops.
623     */
624    public void destroy() {
625        if (mCleanupReference != null) {
626            // We explicitly do not null out the mContentViewCore reference here
627            // because ContentViewCore already has code to deal with the case
628            // methods are called on it after it's been destroyed, and other
629            // code relies on AwContents.mContentViewCore to be non-null.
630            mContentViewCore.destroy();
631            mNativeAwContents = 0;
632 
633            // We cannot destroy immediately if we are still attached to the window.
634            // Instead if we make sure to null out the native pointer so there is no more native
635            // calls, and delay the actual destroy until onDetachedFromWindow.
636            if (mIsAttachedToWindow) {
637                if (mPendingDetachCleanupReferences == null) {
638                    mPendingDetachCleanupReferences = new ArrayList<CleanupReference>();
639                }
640                mPendingDetachCleanupReferences.add(mCleanupReference);
641            } else {
642                mCleanupReference.cleanupNow();
643            }
644            mCleanupReference = null;
645        }
646 
647        assert !mContentViewCore.isAlive();
648        assert mNativeAwContents == 0;
649    }
650 
651    @VisibleForTesting
652    public ContentViewCore getContentViewCore() {
653        return mContentViewCore;
654    }
655 
656    // Can be called from any thread.
657    public AwSettings getSettings() {
658        return mSettings;
659    }
660 
661    public static void setAwDrawSWFunctionTable(int functionTablePointer) {
662        nativeSetAwDrawSWFunctionTable(functionTablePointer);
663    }
664 
665    public static void setAwDrawGLFunctionTable(int functionTablePointer) {
666        nativeSetAwDrawGLFunctionTable(functionTablePointer);
667    }
668 
669    public static int getAwDrawGLFunction() {
670        return nativeGetAwDrawGLFunction();
671    }
672 
673    /**
674     * Intended for test code.
675     * @return the number of native instances of this class.
676     */
677    @VisibleForTesting
678    public static int getNativeInstanceCount() {
679        return nativeGetNativeInstanceCount();
680    }
681 
682    public int getAwDrawGLViewContext() {
683        // Only called during early construction, so client should not have had a chance to
684        // call destroy yet.
685        assert mNativeAwContents != 0;
686 
687        // Using the native pointer as the returned viewContext. This is matched by the
688        // reinterpret_cast back to BrowserViewRenderer pointer in the native DrawGLFunction.
689        return nativeGetAwDrawGLViewContext(mNativeAwContents);
690    }
691 
692    // This is only to avoid heap allocations inside updateGLobalVisibleRect. It should treated
693    // as a local variable in the function and not used anywhere else.
694    private static final Rect sLocalGlobalVisibleRect = new Rect();
695 
696    @CalledByNative
697    private void updateGlobalVisibleRect() {
698        if (mNativeAwContents == 0) return;
699        if (!mContainerView.getGlobalVisibleRect(sLocalGlobalVisibleRect)) {
700            sLocalGlobalVisibleRect.setEmpty();
701        }
702 
703        nativeSetGlobalVisibleRect(mNativeAwContents, sLocalGlobalVisibleRect.left,
704                sLocalGlobalVisibleRect.top, sLocalGlobalVisibleRect.right,
705                sLocalGlobalVisibleRect.bottom);
706    }
707 
708    //--------------------------------------------------------------------------------------------
709    //  WebView[Provider] method implementations (where not provided by ContentViewCore)
710    //--------------------------------------------------------------------------------------------
711 
712    // Only valid within onDraw().
713    private final Rect mClipBoundsTemporary = new Rect();
714 
715    public void onDraw(Canvas canvas) {
716        if (mNativeAwContents == 0) {
717            canvas.drawColor(getEffectiveBackgroundColor());
718            return;
719        }
720 
721        mScrollOffsetManager.syncScrollOffsetFromOnDraw();
722 
723        canvas.getClipBounds(mClipBoundsTemporary);
724        if (!nativeOnDraw(mNativeAwContents, canvas, canvas.isHardwareAccelerated(),
725                    mContainerView.getScrollX(), mContainerView.getScrollY(),
726                    mClipBoundsTemporary.left, mClipBoundsTemporary.top,
727                    mClipBoundsTemporary.right, mClipBoundsTemporary.bottom)) {
728            Log.w(TAG, "nativeOnDraw failed; clearing to background color.");
729            canvas.drawColor(getEffectiveBackgroundColor());
730        }
731 
732        if (mOverScrollGlow != null && mOverScrollGlow.drawEdgeGlows(canvas,
733                    mScrollOffsetManager.computeMaximumHorizontalScrollOffset(),
734                    mScrollOffsetManager.computeMaximumVerticalScrollOffset())) {
735            mContainerView.invalidate();
736        }
737    }
738 
739    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
740        mLayoutSizer.onMeasure(widthMeasureSpec, heightMeasureSpec);
741    }
742 
743    public int getContentHeightCss() {
744        return (int) Math.ceil(mContentViewCore.getContentHeightCss());
745    }
746 
747    public int getContentWidthCss() {
748        return (int) Math.ceil(mContentViewCore.getContentWidthCss());
749    }
750 
751    public Picture capturePicture() {
752        if (mNativeAwContents == 0) return null;
753        return new AwPicture(nativeCapturePicture(mNativeAwContents,
754                    mScrollOffsetManager.computeHorizontalScrollRange(),
755                    mScrollOffsetManager.computeVerticalScrollRange()));
756    }
757 
758    /**
759     * Enable the onNewPicture callback.
760     * @param enabled Flag to enable the callback.
761     * @param invalidationOnly Flag to call back only on invalidation without providing a picture.
762     */
763    public void enableOnNewPicture(boolean enabled, boolean invalidationOnly) {
764        if (mNativeAwContents == 0) return;
765        if (invalidationOnly) {
766            mPictureListenerContentProvider = null;
767        } else if (enabled && mPictureListenerContentProvider == null) {
768            mPictureListenerContentProvider = new Callable<Picture>() {
769                @Override
770                public Picture call() {
771                    return capturePicture();
772                }
773            };
774        }
775        nativeEnableOnNewPicture(mNativeAwContents, enabled);
776    }
777 
778    public void findAllAsync(String searchString) {
779        if (mNativeAwContents == 0) return;
780        nativeFindAllAsync(mNativeAwContents, searchString);
781    }
782 
783    public void findNext(boolean forward) {
784        if (mNativeAwContents == 0) return;
785        nativeFindNext(mNativeAwContents, forward);
786    }
787 
788    public void clearMatches() {
789        if (mNativeAwContents == 0) return;
790        nativeClearMatches(mNativeAwContents);
791    }
792 
793    /**
794     * @return load progress of the WebContents.
795     */
796    public int getMostRecentProgress() {
797        // WebContentsDelegateAndroid conveniently caches the most recent notified value for us.
798        return mWebContentsDelegate.getMostRecentProgress();
799    }
800 
801    public Bitmap getFavicon() {
802        return mFavicon;
803    }
804 
805    private void requestVisitedHistoryFromClient() {
806        ValueCallback<String[]> callback = new ValueCallback<String[]>() {
807            @Override
808            public void onReceiveValue(final String[] value) {
809                ThreadUtils.runOnUiThread(new Runnable() {
810                    @Override
811                    public void run() {
812                        if (mNativeAwContents == 0) return;
813                        nativeAddVisitedLinks(mNativeAwContents, value);
814                    }
815                });
816            }
817        };
818        mContentsClient.getVisitedHistory(callback);
819    }
820 
821    /**
822     * Load url without fixing up the url string. Consumers of ContentView are responsible for
823     * ensuring the URL passed in is properly formatted (i.e. the scheme has been added if left
824     * off during user input).
825     *
826     * @param pararms Parameters for this load.
827     */
828    public void loadUrl(LoadUrlParams params) {
829        if (params.getLoadUrlType() == LoadUrlParams.LOAD_TYPE_DATA &&
830            !params.isBaseUrlDataScheme()) {
831            // This allows data URLs with a non-data base URL access to file:///android_asset/ and
832            // file:///android_res/ URLs. If AwSettings.getAllowFileAccess permits, it will also
833            // allow access to file:// URLs (subject to OS level permission checks).
834            params.setCanLoadLocalResources(true);
835        }
836 
837        // If we are reloading the same url, then set transition type as reload.
838        if (params.getUrl() != null &&
839            params.getUrl().equals(mContentViewCore.getUrl()) &&
840            params.getTransitionType() == PageTransitionTypes.PAGE_TRANSITION_LINK) {
841            params.setTransitionType(PageTransitionTypes.PAGE_TRANSITION_RELOAD);
842        }
843        params.setTransitionType(
844                params.getTransitionType() | PageTransitionTypes.PAGE_TRANSITION_FROM_API);
845 
846        // For WebView, always use the user agent override, which is set
847        // every time the user agent in AwSettings is modified.
848        params.setOverrideUserAgent(LoadUrlParams.UA_OVERRIDE_TRUE);
849 
850        mContentViewCore.loadUrl(params);
851 
852        suppressInterceptionForThisNavigation();
853 
854        // The behavior of WebViewClassic uses the populateVisitedLinks callback in WebKit.
855        // Chromium does not use this use code path and the best emulation of this behavior to call
856        // request visited links once on the first URL load of the WebView.
857        if (!mHasRequestedVisitedHistoryFromClient) {
858          mHasRequestedVisitedHistoryFromClient = true;
859          requestVisitedHistoryFromClient();
860        }
861    }
862 
863    private void suppressInterceptionForThisNavigation() {
864        if (mInterceptNavigationDelegate != null) {
865            // getUrl returns a sanitized address in the same format that will be used for
866            // callbacks, so it's safe to use string comparison as an equality check later on.
867            mInterceptNavigationDelegate.onUrlLoadRequested(mContentViewCore.getUrl());
868        }
869    }
870 
871    /**
872     * Get the URL of the current page.
873     *
874     * @return The URL of the current page or null if it's empty.
875     */
876    public String getUrl() {
877        String url =  mContentViewCore.getUrl();
878        if (url == null || url.trim().isEmpty()) return null;
879        return url;
880    }
881 
882    public void requestFocus() {
883        if (mNativeAwContents == 0) return;
884        if (!mContainerView.isInTouchMode() && mSettings.shouldFocusFirstNode()) {
885            nativeFocusFirstNode(mNativeAwContents);
886        }
887    }
888 
889    public void setBackgroundColor(int color) {
890        mBaseBackgroundColor = color;
891        if (mNativeAwContents != 0) nativeSetBackgroundColor(mNativeAwContents, color);
892    }
893 
894    private int getEffectiveBackgroundColor() {
895        // Do not ask the ContentViewCore for the background color, as it will always
896        // report white prior to initial navigation or post destruction,  whereas we want
897        // to use the client supplied base value in those cases.
898        if (mNativeAwContents == 0 || !mContentsClient.isCachedRendererBackgroundColorValid()) {
899            return mBaseBackgroundColor;
900        }
901        return mContentsClient.getCachedRendererBackgroundColor();
902    }
903 
904    public boolean isMultiTouchZoomSupported() {
905        return mSettings.supportsGestureZoom();
906    }
907 
908    public View getZoomControlsForTest() {
909        return mZoomControls.getZoomControlsViewForTest();
910    }
911 
912    /**
913     * @see ContentViewCore#getContentSettings()
914     */
915    public ContentSettings getContentSettings() {
916        return mContentViewCore.getContentSettings();
917    }
918 
919    /**
920     * @see View#setOverScrollMode(int)
921     */
922    public void setOverScrollMode(int mode) {
923        if (mode != View.OVER_SCROLL_NEVER) {
924            mOverScrollGlow = new OverScrollGlow(mContainerView);
925        } else {
926            mOverScrollGlow = null;
927        }
928    }
929 
930    // TODO(mkosiba): In WebViewClassic these appear in some of the scroll extent calculation
931    // methods but toggling them has no visiual effect on the content (in other words the scrolling
932    // code behaves as if the scrollbar-related padding is in place but the onDraw code doesn't
933    // take that into consideration).
934    // http://crbug.com/269032
935    private boolean mOverlayHorizontalScrollbar = true;
936    private boolean mOverlayVerticalScrollbar = false;
937 
938    /**
939     * @see View#setScrollBarStyle(int)
940     */
941    public void setScrollBarStyle(int style) {
942        if (style == View.SCROLLBARS_INSIDE_OVERLAY
943                || style == View.SCROLLBARS_OUTSIDE_OVERLAY) {
944            mOverlayHorizontalScrollbar = mOverlayVerticalScrollbar = true;
945        } else {
946            mOverlayHorizontalScrollbar = mOverlayVerticalScrollbar = false;
947        }
948    }
949 
950    /**
951     * @see View#setHorizontalScrollbarOverlay(boolean)
952     */
953    public void setHorizontalScrollbarOverlay(boolean overlay) {
954        mOverlayHorizontalScrollbar = overlay;
955    }
956 
957    /**
958     * @see View#setVerticalScrollbarOverlay(boolean)
959     */
960    public void setVerticalScrollbarOverlay(boolean overlay) {
961        mOverlayVerticalScrollbar = overlay;
962    }
963 
964    /**
965     * @see View#overlayHorizontalScrollbar()
966     */
967    public boolean overlayHorizontalScrollbar() {
968        return mOverlayHorizontalScrollbar;
969    }
970 
971    /**
972     * @see View#overlayVerticalScrollbar()
973     */
974    public boolean overlayVerticalScrollbar() {
975        return mOverlayVerticalScrollbar;
976    }
977 
978    /**
979     * Called by the embedder when the scroll offset of the containing view has changed.
980     * @see View#onScrollChanged(int,int)
981     */
982    public void onContainerViewScrollChanged(int l, int t, int oldl, int oldt) {
983        mScrollOffsetManager.onContainerViewScrollChanged(l, t);
984    }
985 
986    /**
987     * Called by the embedder when the containing view is to be scrolled or overscrolled.
988     * @see View#onOverScrolled(int,int,int,int)
989     */
990    public void onContainerViewOverScrolled(int scrollX, int scrollY, boolean clampedX,
991            boolean clampedY) {
992        int oldX = mContainerView.getScrollX();
993        int oldY = mContainerView.getScrollY();
994 
995        mScrollOffsetManager.onContainerViewOverScrolled(scrollX, scrollY, clampedX, clampedY);
996 
997        if (mOverScrollGlow != null) {
998            mOverScrollGlow.pullGlow(mContainerView.getScrollX(), mContainerView.getScrollY(),
999                    oldX, oldY,
1000                    mScrollOffsetManager.computeMaximumHorizontalScrollOffset(),
1001                    mScrollOffsetManager.computeMaximumVerticalScrollOffset());
1002        }
1003    }
1004 
1005    /**
1006     * @see WebView#requestChildRectangleOnScreen(View, Rect, boolean)
1007     */
1008    public boolean requestChildRectangleOnScreen(View child, Rect rect, boolean immediate) {
1009        return mScrollOffsetManager.requestChildRectangleOnScreen(
1010                child.getLeft() - child.getScrollX(), child.getTop() - child.getScrollY(),
1011                rect, immediate);
1012    }
1013 
1014    /**
1015     * @see View.computeScroll()
1016     */
1017    public void computeScroll() {
1018        mScrollOffsetManager.computeScrollAndAbsorbGlow(mOverScrollGlow);
1019    }
1020 
1021    /**
1022     * @see View#computeHorizontalScrollRange()
1023     */
1024    public int computeHorizontalScrollRange() {
1025        return mScrollOffsetManager.computeHorizontalScrollRange();
1026    }
1027 
1028    /**
1029     * @see View#computeHorizontalScrollOffset()
1030     */
1031    public int computeHorizontalScrollOffset() {
1032        return mScrollOffsetManager.computeHorizontalScrollOffset();
1033    }
1034 
1035    /**
1036     * @see View#computeVerticalScrollRange()
1037     */
1038    public int computeVerticalScrollRange() {
1039        return mScrollOffsetManager.computeVerticalScrollRange();
1040    }
1041 
1042    /**
1043     * @see View#computeVerticalScrollOffset()
1044     */
1045    public int computeVerticalScrollOffset() {
1046        return mScrollOffsetManager.computeVerticalScrollOffset();
1047    }
1048 
1049    /**
1050     * @see View#computeVerticalScrollExtent()
1051     */
1052    public int computeVerticalScrollExtent() {
1053        return mScrollOffsetManager.computeVerticalScrollExtent();
1054    }
1055 
1056    /**
1057     * @see android.webkit.WebView#stopLoading()
1058     */
1059    public void stopLoading() {
1060        mContentViewCore.stopLoading();
1061    }
1062 
1063    /**
1064     * @see android.webkit.WebView#reload()
1065     */
1066    public void reload() {
1067        mContentViewCore.reload();
1068    }
1069 
1070    /**
1071     * @see android.webkit.WebView#canGoBack()
1072     */
1073    public boolean canGoBack() {
1074        return mContentViewCore.canGoBack();
1075    }
1076 
1077    /**
1078     * @see android.webkit.WebView#goBack()
1079     */
1080    public void goBack() {
1081        mContentViewCore.goBack();
1082 
1083        suppressInterceptionForThisNavigation();
1084    }
1085 
1086    /**
1087     * @see android.webkit.WebView#canGoForward()
1088     */
1089    public boolean canGoForward() {
1090        return mContentViewCore.canGoForward();
1091    }
1092 
1093    /**
1094     * @see android.webkit.WebView#goForward()
1095     */
1096    public void goForward() {
1097        mContentViewCore.goForward();
1098 
1099        suppressInterceptionForThisNavigation();
1100    }
1101 
1102    /**
1103     * @see android.webkit.WebView#canGoBackOrForward(int)
1104     */
1105    public boolean canGoBackOrForward(int steps) {
1106        return mContentViewCore.canGoToOffset(steps);
1107    }
1108 
1109    /**
1110     * @see android.webkit.WebView#goBackOrForward(int)
1111     */
1112    public void goBackOrForward(int steps) {
1113        mContentViewCore.goToOffset(steps);
1114 
1115        suppressInterceptionForThisNavigation();
1116    }
1117 
1118    /**
1119     * @see android.webkit.WebView#pauseTimers()
1120     */
1121    public void pauseTimers() {
1122        ContentViewStatics.setWebKitSharedTimersSuspended(true);
1123    }
1124 
1125    /**
1126     * @see android.webkit.WebView#resumeTimers()
1127     */
1128    public void resumeTimers() {
1129        ContentViewStatics.setWebKitSharedTimersSuspended(false);
1130    }
1131 
1132    /**
1133     * @see android.webkit.WebView#onPause()
1134     */
1135    public void onPause() {
1136        if (mIsPaused || mNativeAwContents == 0) return;
1137        mIsPaused = true;
1138        nativeSetIsPaused(mNativeAwContents, mIsPaused);
1139    }
1140 
1141    /**
1142     * @see android.webkit.WebView#onResume()
1143     */
1144    public void onResume() {
1145        if (!mIsPaused || mNativeAwContents == 0) return;
1146        mIsPaused = false;
1147        nativeSetIsPaused(mNativeAwContents, mIsPaused);
1148    }
1149 
1150    /**
1151     * @see android.webkit.WebView#isPaused()
1152     */
1153    public boolean isPaused() {
1154        return mIsPaused;
1155    }
1156 
1157    /**
1158     * @see android.webkit.WebView#onCreateInputConnection(EditorInfo)
1159     */
1160    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
1161        return mContentViewCore.onCreateInputConnection(outAttrs);
1162    }
1163 
1164    /**
1165     * @see android.webkit.WebView#onKeyUp(int, KeyEvent)
1166     */
1167    public boolean onKeyUp(int keyCode, KeyEvent event) {
1168        return mContentViewCore.onKeyUp(keyCode, event);
1169    }
1170 
1171    /**
1172     * @see android.webkit.WebView#dispatchKeyEvent(KeyEvent)
1173     */
1174    public boolean dispatchKeyEvent(KeyEvent event) {
1175        return mContentViewCore.dispatchKeyEvent(event);
1176    }
1177 
1178    /**
1179     * Clears the resource cache. Note that the cache is per-application, so this will clear the
1180     * cache for all WebViews used.
1181     *
1182     * @param includeDiskFiles if false, only the RAM cache is cleared
1183     */
1184    public void clearCache(boolean includeDiskFiles) {
1185        if (mNativeAwContents == 0) return;
1186        nativeClearCache(mNativeAwContents, includeDiskFiles);
1187    }
1188 
1189    public void documentHasImages(Message message) {
1190        if (mNativeAwContents == 0) return;
1191        nativeDocumentHasImages(mNativeAwContents, message);
1192    }
1193 
1194    public void saveWebArchive(
1195            final String basename, boolean autoname, final ValueCallback<String> callback) {
1196        if (!autoname) {
1197            saveWebArchiveInternal(basename, callback);
1198            return;
1199        }
1200        // If auto-generating the file name, handle the name generation on a background thread
1201        // as it will require I/O access for checking whether previous files existed.
1202        new AsyncTask<Void, Void, String>() {
1203            @Override
1204            protected String doInBackground(Void... params) {
1205                return generateArchiveAutoNamePath(getOriginalUrl(), basename);
1206            }
1207 
1208            @Override
1209            protected void onPostExecute(String result) {
1210                saveWebArchiveInternal(result, callback);
1211            }
1212        }.execute();
1213    }
1214 
1215    public String getOriginalUrl() {
1216        NavigationHistory history = mContentViewCore.getNavigationHistory();
1217        int currentIndex = history.getCurrentEntryIndex();
1218        if (currentIndex >= 0 && currentIndex < history.getEntryCount()) {
1219            return history.getEntryAtIndex(currentIndex).getOriginalUrl();
1220        }
1221        return null;
1222    }
1223 
1224    /**
1225     * @see ContentViewCore#getNavigationHistory()
1226     */
1227    public NavigationHistory getNavigationHistory() {
1228        return mContentViewCore.getNavigationHistory();
1229    }
1230 
1231    /**
1232     * @see android.webkit.WebView#getTitle()
1233     */
1234    public String getTitle() {
1235        return mContentViewCore.getTitle();
1236    }
1237 
1238    /**
1239     * @see android.webkit.WebView#clearHistory()
1240     */
1241    public void clearHistory() {
1242        mContentViewCore.clearHistory();
1243    }
1244 
1245    public String[] getHttpAuthUsernamePassword(String host, String realm) {
1246        return mBrowserContext.getHttpAuthDatabase(mContentViewCore.getContext())
1247                .getHttpAuthUsernamePassword(host, realm);
1248    }
1249 
1250    public void setHttpAuthUsernamePassword(String host, String realm, String username,
1251            String password) {
1252        mBrowserContext.getHttpAuthDatabase(mContentViewCore.getContext())
1253                .setHttpAuthUsernamePassword(host, realm, username, password);
1254    }
1255 
1256    /**
1257     * @see android.webkit.WebView#getCertificate()
1258     */
1259    public SslCertificate getCertificate() {
1260        if (mNativeAwContents == 0) return null;
1261        return SslUtil.getCertificateFromDerBytes(nativeGetCertificate(mNativeAwContents));
1262    }
1263 
1264    /**
1265     * @see android.webkit.WebView#clearSslPreferences()
1266     */
1267    public void clearSslPreferences() {
1268        mContentViewCore.clearSslPreferences();
1269    }
1270 
1271    /**
1272     * Method to return all hit test values relevant to public WebView API.
1273     * Note that this expose more data than needed for WebView.getHitTestResult.
1274     * Unsafely returning reference to mutable internal object to avoid excessive
1275     * garbage allocation on repeated calls.
1276     */
1277    public HitTestData getLastHitTestResult() {
1278        if (mNativeAwContents == 0) return null;
1279        nativeUpdateLastHitTestData(mNativeAwContents);
1280        return mPossiblyStaleHitTestData;
1281    }
1282 
1283    /**
1284     * @see android.webkit.WebView#requestFocusNodeHref()
1285     */
1286    public void requestFocusNodeHref(Message msg) {
1287        if (msg == null || mNativeAwContents == 0) return;
1288 
1289        nativeUpdateLastHitTestData(mNativeAwContents);
1290        Bundle data = msg.getData();
1291        data.putString("url", mPossiblyStaleHitTestData.href);
1292        data.putString("title", mPossiblyStaleHitTestData.anchorText);
1293        data.putString("src", mPossiblyStaleHitTestData.imgSrc);
1294        msg.setData(data);
1295        msg.sendToTarget();
1296    }
1297 
1298    /**
1299     * @see android.webkit.WebView#requestImageRef()
1300     */
1301    public void requestImageRef(Message msg) {
1302        if (msg == null || mNativeAwContents == 0) return;
1303 
1304        nativeUpdateLastHitTestData(mNativeAwContents);
1305        Bundle data = msg.getData();
1306        data.putString("url", mPossiblyStaleHitTestData.imgSrc);
1307        msg.setData(data);
1308        msg.sendToTarget();
1309    }
1310 
1311    /**
1312     * @see android.webkit.WebView#getScale()
1313     *
1314     * Please note that the scale returned is the page scale multiplied by
1315     * the screen density factor. See CTS WebViewTest.testSetInitialScale.
1316     */
1317    public float getScale() {
1318        return (float)(mContentViewCore.getScale() * mDIPScale);
1319    }
1320 
1321    /**
1322     * @see android.webkit.WebView#flingScroll(int, int)
1323     */
1324    public void flingScroll(int velocityX, int velocityY) {
1325        mScrollOffsetManager.flingScroll(velocityX, velocityY);
1326    }
1327 
1328    /**
1329     * @see android.webkit.WebView#pageUp(boolean)
1330     */
1331    public boolean pageUp(boolean top) {
1332        return mScrollOffsetManager.pageUp(top);
1333    }
1334 
1335    /**
1336     * @see android.webkit.WebView#pageDown(boolean)
1337     */
1338    public boolean pageDown(boolean bottom) {
1339        return mScrollOffsetManager.pageDown(bottom);
1340    }
1341 
1342    /**
1343     * @see android.webkit.WebView#canZoomIn()
1344     */
1345    public boolean canZoomIn() {
1346        return mContentViewCore.canZoomIn();
1347    }
1348 
1349    /**
1350     * @see android.webkit.WebView#canZoomOut()
1351     */
1352    public boolean canZoomOut() {
1353        return mContentViewCore.canZoomOut();
1354    }
1355 
1356    /**
1357     * @see android.webkit.WebView#zoomIn()
1358     */
1359    public boolean zoomIn() {
1360        return mContentViewCore.zoomIn();
1361    }
1362 
1363    /**
1364     * @see android.webkit.WebView#zoomOut()
1365     */
1366    public boolean zoomOut() {
1367        return mContentViewCore.zoomOut();
1368    }
1369 
1370    /**
1371     * @see android.webkit.WebView#invokeZoomPicker()
1372     */
1373    public void invokeZoomPicker() {
1374        mContentViewCore.invokeZoomPicker();
1375    }
1376 
1377    /**
1378     * @see ContentViewCore.evaluateJavaScript(String, ContentViewCore.JavaScriptCallback)
1379     */
1380    public void evaluateJavaScript(String script, final ValueCallback<String> callback) {
1381        ContentViewCore.JavaScriptCallback jsCallback = null;
1382        if (callback != null) {
1383            jsCallback = new ContentViewCore.JavaScriptCallback() {
1384                @Override
1385                public void handleJavaScriptResult(String jsonResult) {
1386                    callback.onReceiveValue(jsonResult);
1387                }
1388            };
1389        }
1390 
1391        mContentViewCore.evaluateJavaScript(script, jsCallback);
1392    }
1393 
1394    /**
1395     * @see ContentViewCore.evaluateJavaScriptEvenIfNotYetNavigated(String)
1396     */
1397    public void evaluateJavaScriptEvenIfNotYetNavigated(String script) {
1398        mContentViewCore.evaluateJavaScriptEvenIfNotYetNavigated(script);
1399    }
1400 
1401    //--------------------------------------------------------------------------------------------
1402    //  View and ViewGroup method implementations
1403    //--------------------------------------------------------------------------------------------
1404 
1405    /**
1406     * @see android.webkit.View#onTouchEvent()
1407     */
1408    public boolean onTouchEvent(MotionEvent event) {
1409        if (mNativeAwContents == 0) return false;
1410 
1411        mScrollOffsetManager.setProcessingTouchEvent(true);
1412        boolean rv = mContentViewCore.onTouchEvent(event);
1413        mScrollOffsetManager.setProcessingTouchEvent(false);
1414 
1415        if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
1416            int actionIndex = event.getActionIndex();
1417 
1418            // Note this will trigger IPC back to browser even if nothing is hit.
1419            nativeRequestNewHitTestDataAt(mNativeAwContents,
1420                                          (int)Math.round(event.getX(actionIndex) / mDIPScale),
1421                                          (int)Math.round(event.getY(actionIndex) / mDIPScale));
1422        }
1423 
1424        if (mOverScrollGlow != null && event.getActionMasked() == MotionEvent.ACTION_UP) {
1425            mOverScrollGlow.releaseAll();
1426        }
1427 
1428        return rv;
1429    }
1430 
1431    /**
1432     * @see android.view.View#onHoverEvent()
1433     */
1434    public boolean onHoverEvent(MotionEvent event) {
1435        return mContentViewCore.onHoverEvent(event);
1436    }
1437 
1438    /**
1439     * @see android.view.View#onGenericMotionEvent()
1440     */
1441    public boolean onGenericMotionEvent(MotionEvent event) {
1442        return mContentViewCore.onGenericMotionEvent(event);
1443    }
1444 
1445    /**
1446     * @see android.view.View#onConfigurationChanged()
1447     */
1448    public void onConfigurationChanged(Configuration newConfig) {
1449        mContentViewCore.onConfigurationChanged(newConfig);
1450    }
1451 
1452    /**
1453     * @see android.view.View#onAttachedToWindow()
1454     *
1455     * Note that this is also called from receivePopupContents.
1456     */
1457    public void onAttachedToWindow() {
1458        if (mNativeAwContents == 0) return;
1459        mIsAttachedToWindow = true;
1460 
1461        mContentViewCore.onAttachedToWindow();
1462        nativeOnAttachedToWindow(mNativeAwContents, mContainerView.getWidth(),
1463                mContainerView.getHeight());
1464    }
1465 
1466    /**
1467     * @see android.view.View#onDetachedFromWindow()
1468     */
1469    public void onDetachedFromWindow() {
1470        mIsAttachedToWindow = false;
1471        hideAutofillPopup();
1472        if (mNativeAwContents != 0) {
1473            nativeOnDetachedFromWindow(mNativeAwContents);
1474        }
1475 
1476        mContentViewCore.onDetachedFromWindow();
1477 
1478        if (mPendingDetachCleanupReferences != null) {
1479            for (int i = 0; i < mPendingDetachCleanupReferences.size(); ++i) {
1480                mPendingDetachCleanupReferences.get(i).cleanupNow();
1481            }
1482            mPendingDetachCleanupReferences = null;
1483        }
1484    }
1485 
1486    /**
1487     * @see android.view.View#onWindowFocusChanged()
1488     */
1489    public void onWindowFocusChanged(boolean hasWindowFocus) {
1490        mWindowFocused = hasWindowFocus;
1491        mContentViewCore.onFocusChanged(mContainerViewFocused && mWindowFocused);
1492    }
1493 
1494    /**
1495     * @see android.view.View#onFocusChanged()
1496     */
1497    public void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
1498        mContainerViewFocused = focused;
1499        mContentViewCore.onFocusChanged(mContainerViewFocused && mWindowFocused);
1500    }
1501 
1502    /**
1503     * @see android.view.View#onSizeChanged()
1504     */
1505    public void onSizeChanged(int w, int h, int ow, int oh) {
1506        if (mNativeAwContents == 0) return;
1507        mScrollOffsetManager.setContainerViewSize(w, h);
1508        mContentViewCore.onPhysicalBackingSizeChanged(w, h);
1509        mContentViewCore.onSizeChanged(w, h, ow, oh);
1510        nativeOnSizeChanged(mNativeAwContents, w, h, ow, oh);
1511    }
1512 
1513    /**
1514     * @see android.view.View#onVisibilityChanged()
1515     */
1516    public void onVisibilityChanged(View changedView, int visibility) {
1517        boolean viewVisible = mContainerView.getVisibility() == View.VISIBLE;
1518        if (mIsViewVisible == viewVisible) return;
1519        setViewVisibilityInternal(viewVisible);
1520    }
1521 
1522    /**
1523     * @see android.view.View#onWindowVisibilityChanged()
1524     */
1525    public void onWindowVisibilityChanged(int visibility) {
1526        boolean windowVisible = visibility == View.VISIBLE;
1527        if (mIsWindowVisible == windowVisible) return;
1528        setWindowVisibilityInternal(windowVisible);
1529    }
1530 
1531    private void setViewVisibilityInternal(boolean visible) {
1532        mIsViewVisible = visible;
1533        if (mNativeAwContents == 0) return;
1534        nativeSetViewVisibility(mNativeAwContents, mIsViewVisible);
1535    }
1536 
1537    private void setWindowVisibilityInternal(boolean visible) {
1538        mIsWindowVisible = visible;
1539        if (mNativeAwContents == 0) return;
1540        nativeSetWindowVisibility(mNativeAwContents, mIsWindowVisible);
1541    }
1542 
1543    /**
1544     * Key for opaque state in bundle. Note this is only public for tests.
1545     */
1546    public static final String SAVE_RESTORE_STATE_KEY = "WEBVIEW_CHROMIUM_STATE";
1547 
1548    /**
1549     * Save the state of this AwContents into provided Bundle.
1550     * @return False if saving state failed.
1551     */
1552    public boolean saveState(Bundle outState) {
1553        if (mNativeAwContents == 0 || outState == null) return false;
1554 
1555        byte[] state = nativeGetOpaqueState(mNativeAwContents);
1556        if (state == null) return false;
1557 
1558        outState.putByteArray(SAVE_RESTORE_STATE_KEY, state);
1559        return true;
1560    }
1561 
1562    /**
1563     * Restore the state of this AwContents into provided Bundle.
1564     * @param inState Must be a bundle returned by saveState.
1565     * @return False if restoring state failed.
1566     */
1567    public boolean restoreState(Bundle inState) {
1568        if (mNativeAwContents == 0 || inState == null) return false;
1569 
1570        byte[] state = inState.getByteArray(SAVE_RESTORE_STATE_KEY);
1571        if (state == null) return false;
1572 
1573        boolean result = nativeRestoreFromOpaqueState(mNativeAwContents, state);
1574 
1575        // The onUpdateTitle callback normally happens when a page is loaded,
1576        // but is optimized out in the restoreState case because the title is
1577        // already restored. See WebContentsImpl::UpdateTitleForEntry. So we
1578        // call the callback explicitly here.
1579        if (result) mContentsClient.onReceivedTitle(mContentViewCore.getTitle());
1580 
1581        return result;
1582    }
1583 
1584    /**
1585     * @see ContentViewCore#addPossiblyUnsafeJavascriptInterface(Object, String, Class)
1586     */
1587    public void addPossiblyUnsafeJavascriptInterface(Object object, String name,
1588            Class<? extends Annotation> requiredAnnotation) {
1589        mContentViewCore.addPossiblyUnsafeJavascriptInterface(object, name, requiredAnnotation);
1590    }
1591 
1592    /**
1593     * @see android.webkit.WebView#removeJavascriptInterface(String)
1594     */
1595    public void removeJavascriptInterface(String interfaceName) {
1596        mContentViewCore.removeJavascriptInterface(interfaceName);
1597    }
1598 
1599    /**
1600     * If native accessibility (not script injection) is enabled, and if this is
1601     * running on JellyBean or later, returns an AccessibilityNodeProvider that
1602     * implements native accessibility for this view. Returns null otherwise.
1603     * @return The AccessibilityNodeProvider, if available, or null otherwise.
1604     */
1605    public AccessibilityNodeProvider getAccessibilityNodeProvider() {
1606        return mContentViewCore.getAccessibilityNodeProvider();
1607    }
1608 
1609    /**
1610     * @see android.webkit.WebView#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)
1611     */
1612    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
1613        mContentViewCore.onInitializeAccessibilityNodeInfo(info);
1614    }
1615 
1616    /**
1617     * @see android.webkit.WebView#onInitializeAccessibilityEvent(AccessibilityEvent)
1618     */
1619    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
1620        mContentViewCore.onInitializeAccessibilityEvent(event);
1621    }
1622 
1623    public boolean supportsAccessibilityAction(int action) {
1624        return mContentViewCore.supportsAccessibilityAction(action);
1625    }
1626 
1627    /**
1628     * @see android.webkit.WebView#performAccessibilityAction(int, Bundle)
1629     */
1630    public boolean performAccessibilityAction(int action, Bundle arguments) {
1631        return mContentViewCore.performAccessibilityAction(action, arguments);
1632    }
1633 
1634    /**
1635     * @see android.webkit.WebView#clearFormData()
1636     */
1637    public void hideAutofillPopup() {
1638        if (mAwAutofillManagerDelegate != null)
1639            mAwAutofillManagerDelegate.hideAutofillPopup();
1640    }
1641 
1642    //--------------------------------------------------------------------------------------------
1643    //  Methods called from native via JNI
1644    //--------------------------------------------------------------------------------------------
1645 
1646    @CalledByNative
1647    private static void onDocumentHasImagesResponse(boolean result, Message message) {
1648        message.arg1 = result ? 1 : 0;
1649        message.sendToTarget();
1650    }
1651 
1652    @CalledByNative
1653    private void onReceivedTouchIconUrl(String url, boolean precomposed) {
1654        mContentsClient.onReceivedTouchIconUrl(url, precomposed);
1655    }
1656 
1657    @CalledByNative
1658    private void onReceivedIcon(Bitmap bitmap) {
1659        mContentsClient.onReceivedIcon(bitmap);
1660        mFavicon = bitmap;
1661    }
1662 
1663    /** Callback for generateMHTML. */
1664    @CalledByNative
1665    private static void generateMHTMLCallback(
1666            String path, long size, ValueCallback<String> callback) {
1667        if (callback == null) return;
1668        callback.onReceiveValue(size < 0 ? null : path);
1669    }
1670 
1671    @CalledByNative
1672    private void onReceivedHttpAuthRequest(AwHttpAuthHandler handler, String host, String realm) {
1673        mContentsClient.onReceivedHttpAuthRequest(handler, host, realm);
1674    }
1675 
1676    private class AwGeolocationCallback implements GeolocationPermissions.Callback {
1677 
1678        @Override
1679        public void invoke(final String origin, final boolean allow, final boolean retain) {
1680            ThreadUtils.runOnUiThread(new Runnable() {
1681                @Override
1682                public void run() {
1683                    if (retain) {
1684                        if (allow) {
1685                            mBrowserContext.getGeolocationPermissions().allow(origin);
1686                        } else {
1687                            mBrowserContext.getGeolocationPermissions().deny(origin);
1688                        }
1689                    }
1690                    if (mNativeAwContents == 0) return;
1691                    nativeInvokeGeolocationCallback(mNativeAwContents, allow, origin);
1692                }
1693            });
1694        }
1695    }
1696 
1697    @CalledByNative
1698    private void onGeolocationPermissionsShowPrompt(String origin) {
1699        if (mNativeAwContents == 0) return;
1700        AwGeolocationPermissions permissions = mBrowserContext.getGeolocationPermissions();
1701        // Reject if geoloaction is disabled, or the origin has a retained deny
1702        if (!mSettings.getGeolocationEnabled()) {
1703            nativeInvokeGeolocationCallback(mNativeAwContents, false, origin);
1704            return;
1705        }
1706        // Allow if the origin has a retained allow
1707        if (permissions.hasOrigin(origin)) {
1708            nativeInvokeGeolocationCallback(mNativeAwContents, permissions.isOriginAllowed(origin),
1709                    origin);
1710            return;
1711        }
1712        mContentsClient.onGeolocationPermissionsShowPrompt(
1713                origin, new AwGeolocationCallback());
1714    }
1715 
1716    @CalledByNative
1717    private void onGeolocationPermissionsHidePrompt() {
1718        mContentsClient.onGeolocationPermissionsHidePrompt();
1719    }
1720 
1721    @CalledByNative
1722    public void onFindResultReceived(int activeMatchOrdinal, int numberOfMatches,
1723            boolean isDoneCounting) {
1724        mContentsClient.onFindResultReceived(activeMatchOrdinal, numberOfMatches, isDoneCounting);
1725    }
1726 
1727    @CalledByNative
1728    public void onNewPicture() {
1729        // Don't call capturePicture() here but instead defer it until the posted task runs within
1730        // the callback helper, to avoid doubling back into the renderer compositor in the middle
1731        // of the notification it is sending up to here.
1732        mContentsClient.getCallbackHelper().postOnNewPicture(mPictureListenerContentProvider);
1733    }
1734 
1735    // Called as a result of nativeUpdateLastHitTestData.
1736    @CalledByNative
1737    private void updateHitTestData(
1738            int type, String extra, String href, String anchorText, String imgSrc) {
1739        mPossiblyStaleHitTestData.hitTestResultType = type;
1740        mPossiblyStaleHitTestData.hitTestResultExtraData = extra;
1741        mPossiblyStaleHitTestData.href = href;
1742        mPossiblyStaleHitTestData.anchorText = anchorText;
1743        mPossiblyStaleHitTestData.imgSrc = imgSrc;
1744    }
1745 
1746    @CalledByNative
1747    private boolean requestDrawGL(Canvas canvas) {
1748        return mInternalAccessAdapter.requestDrawGL(canvas);
1749    }
1750 
1751    private static final boolean SUPPORTS_ON_ANIMATION =
1752            Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN;
1753 
1754    @CalledByNative
1755    private void postInvalidateOnAnimation() {
1756        if (SUPPORTS_ON_ANIMATION) {
1757            mContainerView.postInvalidateOnAnimation();
1758        } else {
1759            mContainerView.postInvalidate();
1760        }
1761    }
1762 
1763    @CalledByNative
1764    private boolean performLongClick() {
1765        return mContainerView.performLongClick();
1766    }
1767 
1768    @CalledByNative
1769    private int[] getLocationOnScreen() {
1770        int[] result = new int[2];
1771        mContainerView.getLocationOnScreen(result);
1772        return result;
1773    }
1774 
1775    @CalledByNative
1776    private void onWebLayoutPageScaleFactorChanged(float webLayoutPageScaleFactor) {
1777        // This change notification comes from the renderer thread, not from the cc/ impl thread.
1778        mLayoutSizer.onPageScaleChanged(webLayoutPageScaleFactor);
1779    }
1780 
1781    @CalledByNative
1782    private void scrollContainerViewTo(int x, int y) {
1783        mScrollOffsetManager.scrollContainerViewTo(x, y);
1784    }
1785 
1786    @CalledByNative
1787    private void setAwAutofillManagerDelegate(AwAutofillManagerDelegate delegate) {
1788        mAwAutofillManagerDelegate = delegate;
1789        delegate.init(mContentViewCore);
1790    }
1791 
1792    @CalledByNative
1793    private void didOverscroll(int deltaX, int deltaY) {
1794        if (mOverScrollGlow != null) {
1795            mOverScrollGlow.setOverScrollDeltas(deltaX, deltaY);
1796        }
1797 
1798        mScrollOffsetManager.overScrollBy(deltaX, deltaY);
1799 
1800        if (mOverScrollGlow != null && mOverScrollGlow.isAnimating()) {
1801            mContainerView.invalidate();
1802        }
1803    }
1804 
1805    // -------------------------------------------------------------------------------------------
1806    // Helper methods
1807    // -------------------------------------------------------------------------------------------
1808 
1809    private void saveWebArchiveInternal(String path, final ValueCallback<String> callback) {
1810        if (path == null || mNativeAwContents == 0) {
1811            ThreadUtils.runOnUiThread(new Runnable() {
1812                @Override
1813                public void run() {
1814                    callback.onReceiveValue(null);
1815                }
1816            });
1817        } else {
1818            nativeGenerateMHTML(mNativeAwContents, path, callback);
1819        }
1820    }
1821 
1822    /**
1823     * Try to generate a pathname for saving an MHTML archive. This roughly follows WebView's
1824     * autoname logic.
1825     */
1826    private static String generateArchiveAutoNamePath(String originalUrl, String baseName) {
1827        String name = null;
1828        if (originalUrl != null && !originalUrl.isEmpty()) {
1829            try {
1830                String path = new URL(originalUrl).getPath();
1831                int lastSlash = path.lastIndexOf('/');
1832                if (lastSlash > 0) {
1833                    name = path.substring(lastSlash + 1);
1834                } else {
1835                    name = path;
1836                }
1837            } catch (MalformedURLException e) {
1838                // If it fails parsing the URL, we'll just rely on the default name below.
1839            }
1840        }
1841 
1842        if (TextUtils.isEmpty(name)) name = "index";
1843 
1844        String testName = baseName + name + WEB_ARCHIVE_EXTENSION;
1845        if (!new File(testName).exists()) return testName;
1846 
1847        for (int i = 1; i < 100; i++) {
1848            testName = baseName + name + "-" + i + WEB_ARCHIVE_EXTENSION;
1849            if (!new File(testName).exists()) return testName;
1850        }
1851 
1852        Log.e(TAG, "Unable to auto generate archive name for path: " + baseName);
1853        return null;
1854    }
1855 
1856    //--------------------------------------------------------------------------------------------
1857    //  Native methods
1858    //--------------------------------------------------------------------------------------------
1859 
1860    private static native int nativeInit(AwBrowserContext browserContext);
1861    private static native void nativeDestroy(int nativeAwContents);
1862    private static native void nativeSetAwDrawSWFunctionTable(int functionTablePointer);
1863    private static native void nativeSetAwDrawGLFunctionTable(int functionTablePointer);
1864    private static native int nativeGetAwDrawGLFunction();
1865    private static native int nativeGetNativeInstanceCount();
1866    private native void nativeSetJavaPeers(int nativeAwContents, AwContents awContents,
1867            AwWebContentsDelegate webViewWebContentsDelegate,
1868            AwContentsClientBridge contentsClientBridge,
1869            AwContentsIoThreadClient ioThreadClient,
1870            InterceptNavigationDelegate navigationInterceptionDelegate);
1871    private native int nativeGetWebContents(int nativeAwContents);
1872 
1873    private native void nativeDocumentHasImages(int nativeAwContents, Message message);
1874    private native void nativeGenerateMHTML(
1875            int nativeAwContents, String path, ValueCallback<String> callback);
1876 
1877    private native void nativeAddVisitedLinks(int nativeAwContents, String[] visitedLinks);
1878    private native boolean nativeOnDraw(int nativeAwContents, Canvas canvas,
1879            boolean isHardwareAccelerated, int scrollX, int ScrollY,
1880            int clipLeft, int clipTop, int clipRight, int clipBottom);
1881    private native void nativeSetGlobalVisibleRect(int nativeAwContents, int visibleLeft,
1882            int visibleTop, int visibleRight, int visibleBottom);
1883    private native void nativeFindAllAsync(int nativeAwContents, String searchString);
1884    private native void nativeFindNext(int nativeAwContents, boolean forward);
1885    private native void nativeClearMatches(int nativeAwContents);
1886    private native void nativeClearCache(int nativeAwContents, boolean includeDiskFiles);
1887    private native byte[] nativeGetCertificate(int nativeAwContents);
1888 
1889    // Coordinates in desity independent pixels.
1890    private native void nativeRequestNewHitTestDataAt(int nativeAwContents, int x, int y);
1891    private native void nativeUpdateLastHitTestData(int nativeAwContents);
1892 
1893    private native void nativeOnSizeChanged(int nativeAwContents, int w, int h, int ow, int oh);
1894    private native void nativeScrollTo(int nativeAwContents, int x, int y);
1895    private native void nativeSetViewVisibility(int nativeAwContents, boolean visible);
1896    private native void nativeSetWindowVisibility(int nativeAwContents, boolean visible);
1897    private native void nativeSetIsPaused(int nativeAwContents, boolean paused);
1898    private native void nativeOnAttachedToWindow(int nativeAwContents, int w, int h);
1899    private static native void nativeOnDetachedFromWindow(int nativeAwContents);
1900    private native void nativeSetDipScale(int nativeAwContents, float dipScale);
1901    private native void nativeSetDisplayedPageScaleFactor(int nativeAwContents,
1902            float pageScaleFactor);
1903 
1904    // Returns null if save state fails.
1905    private native byte[] nativeGetOpaqueState(int nativeAwContents);
1906 
1907    // Returns false if restore state fails.
1908    private native boolean nativeRestoreFromOpaqueState(int nativeAwContents, byte[] state);
1909 
1910    private native int nativeReleasePopupAwContents(int nativeAwContents);
1911    private native void nativeFocusFirstNode(int nativeAwContents);
1912    private native void nativeSetBackgroundColor(int nativeAwContents, int color);
1913 
1914    private native int nativeGetAwDrawGLViewContext(int nativeAwContents);
1915    private native int nativeCapturePicture(int nativeAwContents, int width, int height);
1916    private native void nativeEnableOnNewPicture(int nativeAwContents, boolean enabled);
1917 
1918    private native void nativeInvokeGeolocationCallback(
1919            int nativeAwContents, boolean value, String requestingFrame);
1920}

[all classes][org.chromium.android_webview]
EMMA 2.0.5312 (C) Vladimir Roubtsov