Bug 1522137 - Move resource://android handler to C++. r=mayhemer

This is needed to make the handler to avoid race conditions where some code
tries to access a resource://android URI before the handler has been
registered.

Depends on D18739

Differential Revision: https://phabricator.services.mozilla.com/D18740

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Agi Sferro 2019-02-25 15:38:21 +00:00
Родитель 31607a16bb
Коммит 3ba359e0a9
4 изменённых файлов: 50 добавлений и 38 удалений

Просмотреть файл

@ -20,27 +20,9 @@ function BrowserCLH() {
}
BrowserCLH.prototype = {
/**
* Register resource://android as the APK root.
*
* Consumers can access Android assets using resource://android/assets/FILENAME.
*/
setResourceSubstitutions: function() {
let registry = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIChromeRegistry);
// Like jar:jar:file:///data/app/org.mozilla.fennec-2.apk!/assets/omni.ja!/chrome/chrome/content/aboutHome.xhtml
let url = registry.convertChromeURL(Services.io.newURI("chrome://browser/content/aboutHome.xhtml")).spec;
// Like jar:file:///data/app/org.mozilla.fennec-2.apk!/
url = url.substring(4, url.indexOf("!/") + 2);
let protocolHandler = Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler);
protocolHandler.setSubstitution("android", Services.io.newURI(url));
},
observe: function(subject, topic, data) {
switch (topic) {
case "app-startup": {
this.setResourceSubstitutions();
Services.obs.addObserver(this, "chrome-document-interactive");
Services.obs.addObserver(this, "content-document-interactive");

Просмотреть файл

@ -25,22 +25,6 @@ GeckoViewStartup.prototype = {
QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),
/**
* Register resource://android as the APK root.
*
* Consumers can access Android assets using resource://android/assets/FILENAME.
*/
setResourceSubstitutions: function() {
let registry = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIChromeRegistry);
// Like jar:jar:file:///data/app/org.mozilla.geckoview.test.apk!/assets/omni.ja!/chrome/geckoview/content/geckoview.js
let url = registry.convertChromeURL(Services.io.newURI("chrome://geckoview/content/geckoview.js")).spec;
// Like jar:file:///data/app/org.mozilla.geckoview.test.apk!/
url = url.substring(4, url.indexOf("!/") + 2);
let protocolHandler = Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler);
protocolHandler.setSubstitution("android", Services.io.newURI(url));
},
/* ---------- nsIObserver ---------- */
observe: function(aSubject, aTopic, aData) {
debug `observe: ${aTopic}`;
@ -84,9 +68,6 @@ GeckoViewStartup.prototype = {
if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_DEFAULT) {
ActorManagerParent.flush();
// Parent process only.
this.setResourceSubstitutions();
Services.mm.loadFrameScript(
"chrome://geckoview/content/GeckoViewPromptChild.js", true);

Просмотреть файл

@ -23,6 +23,7 @@ using mozilla::dom::ContentParent;
#define kAPP "app"
#define kGRE "gre"
#define kAndroid "android"
nsresult nsResProtocolHandler::Init() {
nsresult rv;
@ -40,6 +41,10 @@ nsresult nsResProtocolHandler::Init() {
mAppURI = mGREURI;
}
#ifdef ANDROID
rv = GetApkURI(mApkURI);
#endif
// XXXbsmedberg Neil wants a resource://pchrome/ for the profile chrome dir...
// but once I finish multiple chrome registration I'm not sure that it is
// needed
@ -50,6 +55,35 @@ nsresult nsResProtocolHandler::Init() {
return rv;
}
#ifdef ANDROID
nsresult nsResProtocolHandler::GetApkURI(nsACString& aResult) {
nsCString::const_iterator start, iter;
mGREURI.BeginReading(start);
mGREURI.EndReading(iter);
nsCString::const_iterator start_iter = start;
// This is like jar:jar:file://path/to/apk/base.apk!/path/to/omni.ja!/
bool found = FindInReadable(NS_LITERAL_CSTRING("!/"), start_iter, iter);
NS_ENSURE_TRUE(found, NS_ERROR_UNEXPECTED);
// like jar:jar:file://path/to/apk/base.apk!/
const nsDependentCSubstring& withoutPath = Substring(start, iter);
NS_ENSURE_TRUE(withoutPath.Length() >= 4, NS_ERROR_UNEXPECTED);
// Let's make sure we're removing what we expect to remove
NS_ENSURE_TRUE(Substring(withoutPath, 0, 4).EqualsLiteral("jar:"),
NS_ERROR_UNEXPECTED);
// like jar:file://path/to/apk/base.apk!/
aResult = ToNewCString(Substring(withoutPath, 4));
// Remove the trailing /
NS_ENSURE_TRUE(aResult.Length() >= 1, NS_ERROR_UNEXPECTED);
aResult.Truncate(aResult.Length() - 1);
return NS_OK;
}
#endif
//----------------------------------------------------------------------------
// nsResProtocolHandler::nsISupports
//----------------------------------------------------------------------------
@ -98,6 +132,10 @@ bool nsResProtocolHandler::ResolveSpecialCases(const nsACString& aHost,
aResult.Assign(mAppURI);
} else if (aHost.Equals(kGRE)) {
aResult.Assign(mGREURI);
#ifdef ANDROID
} else if (aHost.Equals(kAndroid)) {
aResult.Assign(mApkURI);
#endif
} else {
return false;
}
@ -110,6 +148,7 @@ nsresult nsResProtocolHandler::SetSubstitution(const nsACString& aRoot,
MOZ_ASSERT(!aRoot.EqualsLiteral(""));
MOZ_ASSERT(!aRoot.EqualsLiteral(kAPP));
MOZ_ASSERT(!aRoot.EqualsLiteral(kGRE));
MOZ_ASSERT(!aRoot.EqualsLiteral(kAndroid));
return SubstitutingProtocolHandler::SetSubstitution(aRoot, aBaseURI);
}
@ -119,13 +158,18 @@ nsresult nsResProtocolHandler::SetSubstitutionWithFlags(const nsACString& aRoot,
MOZ_ASSERT(!aRoot.EqualsLiteral(""));
MOZ_ASSERT(!aRoot.EqualsLiteral(kAPP));
MOZ_ASSERT(!aRoot.EqualsLiteral(kGRE));
MOZ_ASSERT(!aRoot.EqualsLiteral(kAndroid));
return SubstitutingProtocolHandler::SetSubstitutionWithFlags(aRoot, aBaseURI,
aFlags);
}
nsresult nsResProtocolHandler::HasSubstitution(const nsACString& aRoot,
bool* aResult) {
if (aRoot.EqualsLiteral(kAPP) || aRoot.EqualsLiteral(kGRE)) {
if (aRoot.EqualsLiteral(kAPP) || aRoot.EqualsLiteral(kGRE)
#ifdef ANDROID
|| aRoot.EqualsLiteral(kAndroid)
#endif
) {
*aResult = true;
return NS_OK;
}

Просмотреть файл

@ -73,6 +73,11 @@ class nsResProtocolHandler final
private:
nsCString mAppURI;
nsCString mGREURI;
#ifdef ANDROID
// Used for resource://android URIs
nsCString mApkURI;
nsresult GetApkURI(nsACString& aResult);
#endif
};
#endif /* nsResProtocolHandler_h___ */