WebView file:///android_res/ assumes the R class is <packagename>.R but it isn't always |
|||||||
Issue descriptionWebView's internal redirection for file:///android_res/ URLs relies on being able to find the application's R class using reflection. We take the app's package name and add ".R" to do this. However, it's not actually guaranteed to be the case that the application's main R class has that classname; it was very rare for someone to override this in the past and so nobody noticed, but now Gradle (used by Android Studio) has a supported feature that causes the package name to not match the R class *much* more often: http://tools.android.com/tech-docs/new-build-system/applicationid-vs-packagename See discussion on AOSP bugtracker here for more details: https://code.google.com/p/android/issues/detail?id=154653 While we can't completely fix this without adding an API for apps to use to specify where their R class is located (unlikely to be worth it), we probably could guess slightly better: if there's no R class to be found under the package name, strip off one component of the package name from the right end and try again. This will work for cases where people have used Gradle's applicationIdSuffix feature to append a suffix to the normal package name. It still won't work when the applicationId is completely different to the package name, but I can't think of a sane way to deal with that.
,
Apr 4 2016
Does Resource.getIdentifier actually work in this case? I'm not 100% sure it does. I had a look at the implementation, but am not sure whether this works - it's not obvious to me where the name of the ResTable in libandroidfw comes from for a given APK, and it seems at least possible that the name comes from the package name of the APK, which will mean it would fail in exactly the same way as the reflection here, so someone would at least need to test whether that really works. Also, it seems like a risky change from a backward compatibility point of view - I'm not sure there's *any* resource ID we could try to look up that would be guaranteed to come from the right package. (I don't think anything stops you from using a system resource as your icon, for example). This reflection-based R class lookup is how this has always worked in WebView (including pre-chromium), and it's sadly quite possible that apps are depending on this exact behaviour. You're right that there isn't technically guaranteed to be an R class at all thanks to obfuscation, but because WebView has always done this, any app that's using file:///android_res has already had to make sure that its R class does, in fact, exist and have the right name. Apps could, in theory, even be providing a *fake* R class that has perfectly valid IDs in it but isn't the real R class built by aapt at compile time, and so switching to directly querying the resources would actually *break* such an application :/ So.. it's maybe worth considering, but we'd need to see a prototype that actually demonstrably worked and then think about whether it's too much of a compatibility risk. The advantage of doing the relatively dumb logic I proposed of just going "up" the package hierarchy is that it won't break any case that's currently working.
,
Apr 5 2016
Ah, right. Hadn't checked that this is how it's always been. That surely speaks for not fiddling with it for all the reasons you mention. As you say, developers should have had to ensure the R class being available when using file://android_res so perhaps this falls back to developers also ensuring that it is the case even when using the package name renaming feature? One way of doing that could I think be to use the --extra-packages flag of aapt to get an R.java also in the resulting package: aapt ... --rename-manifest-package <new.package.name> --extra-packages <new.package.name>
,
Apr 5 2016
Yeah, we should probably follow up with the android tools team about this incompatibility and see if they may want to fix it on their end..
,
May 31 2016
Filed a tools bug about this here: https://code.google.com/p/android/issues/detail?id=211768 Hopefully we can come up with a way to make more cases work, or at least document the incompatibility.
,
Jun 13 2016
Sounds like no change planned in webview?
,
Jun 14 2016
I think it's reasonable to implement the simple workaround I proposed in the original report - if the R class isn't found, go "up" one package and try again, until we find it (or run out of packages). This would solve the issue for the specific case of an app that uses gradle's applicationIdSuffix feature to append ".beta" or similar to the package name, which is likely to be the common case where this fails.
,
Jun 20 2016
https://codereview.chromium.org/2075753002/
,
Jun 21 2016
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/3730ff3155bc7c214865a01e0bfbe7221eac3e62 commit 3730ff3155bc7c214865a01e0bfbe7221eac3e62 Author: boliu <boliu@chromium.org> Date: Tue Jun 21 14:25:19 2016 aw: Try strip out last component of app name for android_res Gradle allows the R class of the app to differ from the application name. This CL specifically handles the case where the R class is the application name with suffixes added. Eg: app: com.example.app R class: com.example.app.free.R BUG= 599869 Review-Url: https://codereview.chromium.org/2075753002 Cr-Commit-Position: refs/heads/master@{#400985} [modify] https://crrev.com/3730ff3155bc7c214865a01e0bfbe7221eac3e62/android_webview/java/src/org/chromium/android_webview/AndroidProtocolHandler.java
,
Jun 21 2016
,
Feb 28 2018
Looks like this issue can be reopened. There's a regression caused by this change https://chromium.googlesource.com/chromium/src.git/+/95d6e720c235f105aa3182e2a1b2f826cfaa483f%5E%21/#F1 The getClazz method in AndroidProtocolHandler.java is now always using the same package name instead of taking it as an argument. Hence the striped package name is never used and hence the resource fails to load if the applicationId is different from the package in which the R class is located.
,
Feb 28 2018
Oops, well-spotted. We don't have a regression test for this, unfortunately :/
,
Mar 1 2018
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/308cf1dcc54eddb8aa3370ee364c1b738712c819 commit 308cf1dcc54eddb8aa3370ee364c1b738712c819 Author: Torne (Richard Coles) <torne@google.com> Date: Thu Mar 01 01:16:32 2018 Fix broken R class searching in file:///android_res/ The removal of GetApplicationContext accidentally removed the parameter used to try shorter versions of the package name if the R class isn't found in the original package name, reintroducing crbug.com/599869 that this logic was written to fix. Put the package name parameter back so that stripping off elements of the package name actually has an effect. Bug: 599869 Change-Id: Iad5e0174052b1362c8fe7e86089655e3fd60b847 Reviewed-on: https://chromium-review.googlesource.com/941591 Reviewed-by: Bo <boliu@chromium.org> Commit-Queue: Richard Coles <torne@chromium.org> Cr-Commit-Position: refs/heads/master@{#539967} [modify] https://crrev.com/308cf1dcc54eddb8aa3370ee364c1b738712c819/android_webview/java/src/org/chromium/android_webview/AndroidProtocolHandler.java
,
Mar 1 2018
Not going to merge this back to 65 since we broke this in 59 and nobody noticed until now; it'll be in 66.
,
Mar 1 2018
|
|||||||
►
Sign in to add a comment |
|||||||
Comment 1 by sberg...@opera.com
, Apr 4 2016