Can't call super.foo() through reflection -> can't implement WebView.PrivateAccess through reflection. |
||
Issue descriptionTo call hidden methods on the WebView super class there exist some classes in android.webkit that call WebView.super.foo(). The support library that can't call hidden methods directly will have to use reflection to call those methods, but you can't call a super method through reflection in Java. It is not obvious how this can be solved - if there are no methods on WebView or its super classes for which we need to call both the super class method, and the WebView APK implementation, then we just won't run into this problem (as long as we make sure we never add a method for which we have to call both the super class implementation and the WebView APK implementation).
,
Aug 9 2017
Out of the calls we make into WebView.super, the following are hidden (this is easy to test by creating your own class Foo overriding WebView, and copy-pasting WebView.PrivateAccess into that class, replacing WebView.super calls with Foo.super). performAccessibilityActionInternal setFrame startActivityForResult onDrawVerticalScrollBar
,
Aug 9 2017
WebView.PrivateAccess.super_performAccessibilityAction calls WebView.super.performAccessibilityActionInternal. WebView.PrivateAccess.super_performAccessibilityAction is called from WebViewChromium.performAccessibilityAction if mAwContents.supportsAccessibilityAction is false (otherwise we call mAwContents.performAccessibilityAction). Currently AwContents.performAccessibilityAction always returns false, but there is a TODO from dmazzoni there to implement that method in WebContentsAccessibility. setFrame is only called directly from WebView.setFrame: WebView.setFrame -> WebViewProvider.ViewDelegate.setFrame -> WebViewChromium.setFrame -> WebView.PrivateAccess.super_setFrame -> WebView.super.setFrame this is a bit ugly, but I don't think there's anything we can do about this for existing Android versions - for P+ we could just have WebView.setFrame directly call WebView.super.setFrame. WebViewChromium.InternalAccessAdapter.super_startActivityForResult actually falls back to using reflection to call WebView.startActivityForResult for Android versions before N (exclusive). Note that this works because WebView itself doesn't override startActivityForResult to call into the WebView APK (that would cause an inf loop). So, as long as we never implement startActivityForResult in the WebView class, we could use reflection here. onDrawVerticalScrollBar is called in a similar way to setFrame, calling from WebView, through the WebViewProvider.ViewDelegate.
,
Aug 9 2017
It looks like we could use a Java class called MethodHandle to invoke a super class method: https://docs.oracle.com/javase/7/docs/api/java/lang/invoke/MethodHandle.html MethodHandle handle = MethodHandles.lookup().findSpecial(clazz, methodName, MethodType, callingClass); handle.invoke(supportLibraryWebView); I'll try this to ensure it works.
,
Aug 9 2017
And it turns out MethodHandle was added in API level 26 :/
,
Aug 9 2017
There's more I think. Eg onDetachedFromWindowInternal calls super as well (though not from glue or chromium code)
,
Aug 9 2017
Darn, ye you're right, it's just not called from WebView.PrivateAccess (which is where I've been looking)
,
Apr 9 2018
This is not an issue atm since we use none of the super calls. |
||
►
Sign in to add a comment |
||
Comment 1 by gsennton@chromium.org
, Aug 9 2017