Closed
Bug 948465
Opened 11 years ago
Closed 10 years ago
[GeckoView] Allow loading from assets/ via URL, e.g. file://android_asset/
Categories
(Firefox for Android Graveyard :: General, defect)
Tracking
(Not tracked)
RESOLVED
FIXED
Firefox 34
People
(Reporter: BenB, Assigned: nalexander)
References
Details
(Keywords: dev-doc-needed)
Attachments
(3 files)
3.72 KB,
patch
|
mfinkle
:
review+
|
Details | Diff | Splinter Review |
3.08 KB,
patch
|
mfinkle
:
review+
|
Details | Diff | Splinter Review |
5.69 KB,
patch
|
Details | Diff | Splinter Review |
Reproduction:
1. Embed GeckoView in your Android app
2. Place assets/myapp/index.html in your app's source, and build
3. Load URI "file://android_asset/myapp/index.html" into the GeckoView browser.
Actual result:
File not found
Expected result:
The file from assets/ is being loaded.
Relative URLs from there on also work.
Why:
WebView supports this, and it's highly useful for very common usecases where you want to ship part of your Android app as webapp, and bundle your runtime (GeckoView) and your app (HTML+JS, in assets).
Related bugs:
Bug 948325 is more generic and powerful, but requires custom code from the embedder. I think we need both that bug and this one.
Bug 880107 - GeckoView tracker
Reporter | ||
Comment 1•11 years ago
|
||
Until we have this, this can be achieved in the embedding app with:
URI apkURI = (new File(MyActivity.this.getPackageResourcePath())).toURI();
String assetsURL = "jar:" + apkURI + "!/assets/";
String myURL = assetsURL + "test.html";
But the fact that it's so easy also means that it should be easy to implement within GeckoView. file://android_asset/ is well-documented for WebView, and that would be the first thing developers would try.
Comment 2•11 years ago
|
||
(In reply to Ben Bucksch (:BenB) from comment #1)
> Until we have this, this can be achieved in the embedding app with:
>
> URI apkURI = (new File(MyActivity.this.getPackageResourcePath())).toURI();
> String assetsURL = "jar:" + apkURI + "!/assets/";
> String myURL = assetsURL + "test.html";
>
> But the fact that it's so easy also means that it should be easy to
> implement within GeckoView. file://android_asset/ is well-documented for
> WebView, and that would be the first thing developers would try.
So we could add some code to our loadUrl API to replace "file://android_asset/" with "jar:" + apkURI + "!/assets/" ?
Reporter | ||
Comment 3•11 years ago
|
||
I think this would fail this part:
> Expected result: ...
> Relative URLs from there on also work.
So, I would have to be deeper, in the URL resolver. I think this bug and bug 948325 could be implemented in the same code place.
Reporter | ||
Comment 4•11 years ago
|
||
In other words: If myapp/test.html loads <script src="test.js" />, it needs to resolve to "file://android_asset/myapp/test.js", which then loads file <apk>/assets/myapp/test.js.
Comment 5•11 years ago
|
||
(In reply to Ben Bucksch (:BenB) from comment #4)
> In other words: If myapp/test.html loads <script src="test.js" />, it needs
> to resolve to "file://android_asset/myapp/test.js", which then loads file
> <apk>/assets/myapp/test.js.
Right
Android impl notes:
http://androidxref.com/4.4_r1/xref/frameworks/base/core/java/android/webkit/URLUtil.java#35
Reporter | ||
Comment 6•11 years ago
|
||
Actually..., I'm wrong. If you just replace the file:// URL with "jar:" in loadURI, then of course relative URL would resolve to "jar:", too. The app would see a difference when checking window.location, but it should work. For me, that's good enough. I'd personally place it deeper. Up to you to decide.
Assignee | ||
Comment 7•11 years ago
|
||
So, I dug into this over the weekend. It's not that hard to arrange in Gecko itself for resource://android_asset/foo to load assets/foo. It is a little tricky, because the correct resource substitution needs the current APK path, which changes over time (updates, for example, bump the APK path).
I followed BenB, with:
+ printWriter.println("resource android_asset jar:file://" + apkPath + "!/assets/");
The trick is to load this *really* early in the registration process. Ideally, we want it as part of the chrome.manifest in omni.ja, but I wasn't able to figure out how to get that. (The reason I want it early is to override GRE module loads, but I haven't figure out how to do this yet.)
I did manage to dynamically write an appOmni.ja and arrange for it to be installed via -appomni. This works, but it's using a big hammer for a small feature. (appomni is a *really* valuable extension point in future; we shouldn't camp it without good reason.)
Assignee | ||
Comment 8•11 years ago
|
||
> The trick is to load this *really* early in the registration process.
> Ideally, we want it as part of the chrome.manifest in omni.ja, but I wasn't
> able to figure out how to get that. (The reason I want it early is to
> override GRE module loads, but I haven't figure out how to do this yet.)
I haven't tried this, but it might be possible to include a static link to a chrome.manifest in omni.ja, and then to write that chrome.manifest dynamically with the appropriate resource override.
Or we might be able to call nsIResProtocolHandler's setSubstitution around the same time as omni.ja's chrome.manifest is registered.
Reporter | ||
Comment 9•11 years ago
|
||
Nick, personally, I think we should go the the 3-liner Java code I posted above.
As far as "early": If you want to do advanced stuff like replacing certain Gecko DLLs/so with your own, then I think it's fair to say you have to do extra work. Once you figured out a good way, you can document this on the wiki.
I think the common usecase here is to load HTML assets, or data that the app needs. Most GeckoView users will need this.
Maybe even JSMs or extra JS components or similar.
Blocks: 888391
Assignee | ||
Comment 10•10 years ago
|
||
Consumers can access Android assets (and resources) by using
resource://android/assets/FILENAME.
The resource substitution is registered at app-startup time so that the
substitution is in place before any add-on has started up: as documented
at [1], "[an] add-on will not receive xpcom-startup or app-startup
notifications".
[1] https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Guide/Receiving_startup_notifications
Attachment #8460637 -
Flags: review?(mark.finkle)
Assignee | ||
Comment 11•10 years ago
|
||
I have not yet verified that this does the right thing for GeckoView
embedders, but I have a hard time imagining it doesn't, since we hook
into the XPCOM start-up process very early.
Attachment #8460640 -
Flags: review?(mark.finkle)
Assignee | ||
Comment 12•10 years ago
|
||
Assignee | ||
Updated•10 years ago
|
OS: Linux → Android
Hardware: x86_64 → All
Assignee | ||
Updated•10 years ago
|
Assignee: nobody → nalexander
Keywords: dev-doc-needed
Assignee | ||
Comment 13•10 years ago
|
||
This packs example.{html,js} into the APK assets/. The following loads
an example.html that loads a relative example.js; if everything works,
you should get a red body background:
adb shell am start -a android.intent.action.VIEW -n org.mozilla.fennec_nalexander/.App -d resource://android/assets/example.html
Comment 14•10 years ago
|
||
Comment on attachment 8460637 [details] [diff] [review]
Part 1: Register resource://android/ point to Fennec APK root. r=mfinkle
>diff --git a/mobile/android/components/BrowserCLH.js b/mobile/android/components/BrowserCLH.js
>+ setResourceSubstitutions: function () {
>+ let registry = Cc['@mozilla.org/chrome/chrome-registry;1'].getService(Ci["nsIChromeRegistry"]);
nit: use " not '
>+ let protocolHandler = Services.io
>+ .getProtocolHandler("resource")
>+ .QueryInterface(Ci.nsIResProtocolHandler);
nit: it's ok for this to be one line
Attachment #8460637 -
Flags: review?(mark.finkle) → review+
Updated•10 years ago
|
Attachment #8460640 -
Flags: review?(mark.finkle) → review+
Assignee | ||
Comment 15•10 years ago
|
||
https://hg.mozilla.org/integration/fx-team/rev/f9e3fc8632a3
https://hg.mozilla.org/integration/fx-team/rev/99151ee98fd4
Status: NEW → ASSIGNED
Comment 16•10 years ago
|
||
https://hg.mozilla.org/mozilla-central/rev/f9e3fc8632a3
https://hg.mozilla.org/mozilla-central/rev/99151ee98fd4
Status: ASSIGNED → RESOLVED
Closed: 10 years ago
Resolution: --- → FIXED
Target Milestone: --- → Firefox 34
Updated•4 years ago
|
Product: Firefox for Android → Firefox for Android Graveyard
You need to log in
before you can comment on or make changes to this bug.
Description
•