Bug 1501108 - [1.7] Add GeckoView Session Context ID support. r=snorp,baku,mayhemer

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Eugen Sawin 2019-07-21 17:18:37 +00:00
Родитель 85846573be
Коммит 532f60a55d
10 изменённых файлов: 114 добавлений и 3 удалений

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

@ -158,6 +158,15 @@ void OriginAttributes::CreateSuffix(nsACString& aStr) const {
sanitizedFirstPartyDomain);
}
if (!mGeckoViewSessionContextId.IsEmpty()) {
nsAutoString sanitizedGeckoViewUserContextId(mGeckoViewSessionContextId);
sanitizedGeckoViewUserContextId.ReplaceChar(
dom::quota::QuotaManager::kReplaceChars, '+');
params.Set(NS_LITERAL_STRING("geckoViewUserContextId"),
sanitizedGeckoViewUserContextId);
}
aStr.Truncate();
params.Serialize(value);
@ -243,6 +252,13 @@ class MOZ_STACK_CLASS PopulateFromSuffixIterator final
return true;
}
if (aName.EqualsLiteral("geckoViewUserContextId")) {
MOZ_RELEASE_ASSERT(
mOriginAttributes->mGeckoViewSessionContextId.IsEmpty());
mOriginAttributes->mGeckoViewSessionContextId.Assign(aValue);
return true;
}
// No other attributes are supported.
return false;
}

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

@ -48,7 +48,8 @@ class OriginAttributes : public dom::OriginAttributesDictionary {
return mInIsolatedMozBrowser == aOther.mInIsolatedMozBrowser &&
mUserContextId == aOther.mUserContextId &&
mPrivateBrowsingId == aOther.mPrivateBrowsingId &&
mFirstPartyDomain == aOther.mFirstPartyDomain;
mFirstPartyDomain == aOther.mFirstPartyDomain &&
mGeckoViewSessionContextId == aOther.mGeckoViewSessionContextId;
}
bool operator!=(const OriginAttributes& aOther) const {
@ -58,7 +59,8 @@ class OriginAttributes : public dom::OriginAttributesDictionary {
MOZ_MUST_USE bool EqualsIgnoringFPD(const OriginAttributes& aOther) const {
return mInIsolatedMozBrowser == aOther.mInIsolatedMozBrowser &&
mUserContextId == aOther.mUserContextId &&
mPrivateBrowsingId == aOther.mPrivateBrowsingId;
mPrivateBrowsingId == aOther.mPrivateBrowsingId &&
mGeckoViewSessionContextId == aOther.mGeckoViewSessionContextId;
}
// Serializes/Deserializes non-default values into the suffix format, i.e.
@ -146,6 +148,12 @@ class OriginAttributesPattern : public dom::OriginAttributesPatternDictionary {
return false;
}
if (mGeckoViewSessionContextId.WasPassed() &&
mGeckoViewSessionContextId.Value() !=
aAttrs.mGeckoViewSessionContextId) {
return false;
}
return true;
}
@ -172,6 +180,13 @@ class OriginAttributesPattern : public dom::OriginAttributesPatternDictionary {
return false;
}
if (mGeckoViewSessionContextId.WasPassed() &&
aOther.mGeckoViewSessionContextId.WasPassed() &&
mGeckoViewSessionContextId.Value() !=
aOther.mGeckoViewSessionContextId.Value()) {
return false;
}
return true;
}
};

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

@ -547,12 +547,14 @@ dictionary OriginAttributesDictionary {
boolean inIsolatedMozBrowser = false;
unsigned long privateBrowsingId = 0;
DOMString firstPartyDomain = "";
DOMString geckoViewSessionContextId = "";
};
dictionary OriginAttributesPatternDictionary {
unsigned long userContextId;
boolean inIsolatedMozBrowser;
unsigned long privateBrowsingId;
DOMString firstPartyDomain;
DOMString geckoViewSessionContextId;
};
dictionary CompileScriptOptionsDictionary {

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

@ -37,6 +37,7 @@ struct ParamTraits<mozilla::OriginAttributesPattern> {
WriteParam(aMsg, aParam.mInIsolatedMozBrowser);
WriteParam(aMsg, aParam.mPrivateBrowsingId);
WriteParam(aMsg, aParam.mUserContextId);
WriteParam(aMsg, aParam.mGeckoViewSessionContextId);
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
@ -44,7 +45,8 @@ struct ParamTraits<mozilla::OriginAttributesPattern> {
return ReadParam(aMsg, aIter, &aResult->mFirstPartyDomain) &&
ReadParam(aMsg, aIter, &aResult->mInIsolatedMozBrowser) &&
ReadParam(aMsg, aIter, &aResult->mPrivateBrowsingId) &&
ReadParam(aMsg, aIter, &aResult->mUserContextId);
ReadParam(aMsg, aIter, &aResult->mUserContextId) &&
ReadParam(aMsg, aIter, &aResult->mGeckoViewSessionContextId);
}
};

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

@ -797,6 +797,7 @@ package org.mozilla.geckoview {
ctor public GeckoSessionSettings(@NonNull GeckoSessionSettings);
method public boolean getAllowJavascript();
method @Nullable public String getChromeUri();
method @Nullable public String getContextId();
method public int getDisplayMode();
method public boolean getFullAccessibilityTree();
method public int getScreenId();
@ -834,6 +835,7 @@ package org.mozilla.geckoview {
method @NonNull public GeckoSessionSettings.Builder allowJavascript(boolean);
method @NonNull public GeckoSessionSettings build();
method @NonNull public GeckoSessionSettings.Builder chromeUri(@NonNull String);
method @NonNull public GeckoSessionSettings.Builder contextId(@Nullable String);
method @NonNull public GeckoSessionSettings.Builder displayMode(int);
method @NonNull public GeckoSessionSettings.Builder fullAccessibilityTree(boolean);
method @NonNull public GeckoSessionSettings.Builder screenId(int);

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

@ -79,6 +79,22 @@ public final class GeckoSessionSettings implements Parcelable {
return this;
}
/**
* Set the session context ID for this instance.
* Setting a context ID partitions the cookie jars based on the provided
* IDs. This isolates the browser storage like cookies and localStorage
* between sessions, only sessions that share the same ID share storage
* data.
*
* @param value The custom context ID.
* The default ID is null, which removes isolation for this
* instance.
*/
public @NonNull Builder contextId(final @Nullable String value) {
mSettings.setContextId(value);
return this;
}
/**
* Set whether multi-process support should be enabled.
*
@ -213,6 +229,7 @@ public final class GeckoSessionSettings implements Parcelable {
* width of 980 CSS px.
*/
public static final int VIEWPORT_MODE_MOBILE = 0;
/**
* All pages will be rendered using the special desktop mode viewport, which has a width of
* 980 CSS px, regardless of whether the page has a &lt;meta&gt; viewport tag specified or not.
@ -314,6 +331,12 @@ public final class GeckoSessionSettings implements Parcelable {
private static final Key<Boolean> FULL_ACCESSIBILITY_TREE =
new Key<Boolean>("fullAccessibilityTree", /* initOnly */ false, /* values */ null);
/**
* Key to specify the session context ID.
*/
private static final Key<String> CONTEXT_ID =
new Key<String>("sessionContextId", /* initOnly */ true, /* values */ null);
private final GeckoSession mSession;
private final GeckoBundle mBundle;
@ -347,6 +370,7 @@ public final class GeckoSessionSettings implements Parcelable {
mBundle.putString(USER_AGENT_OVERRIDE.name, null);
mBundle.putInt(VIEWPORT_MODE.name, VIEWPORT_MODE_MOBILE);
mBundle.putInt(DISPLAY_MODE.name, DISPLAY_MODE_BROWSER);
mBundle.putString(CONTEXT_ID.name, null);
}
/**
@ -439,6 +463,15 @@ public final class GeckoSessionSettings implements Parcelable {
return getBoolean(USE_PRIVATE_MODE);
}
/**
* The context ID for this session.
*
* @return The context ID for this session.
*/
public @Nullable String getContextId() {
return getString(CONTEXT_ID);
}
/**
* Whether multiprocess is enabled.
*
@ -597,6 +630,10 @@ public final class GeckoSessionSettings implements Parcelable {
setString(USER_AGENT_OVERRIDE, value);
}
private void setContextId(final @Nullable String value) {
setString(CONTEXT_ID, value);
}
private void setString(final Key<String> key, final String value) {
synchronized (mBundle) {
if (valueChangedLocked(key, value)) {

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

@ -17,6 +17,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
E10SUtils: "resource://gre/modules/E10SUtils.jsm",
LoadURIDelegate: "resource://gre/modules/LoadURIDelegate.jsm",
Services: "resource://gre/modules/Services.jsm",
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm",
});
XPCOMUtils.defineLazyGetter(this, "ReferrerInfo", () =>
@ -58,6 +59,8 @@ class GeckoViewNavigation extends GeckoViewModule {
}
onInit() {
debug`onInit`;
this.registerListener([
"GeckoView:GoBack",
"GeckoView:GoForward",
@ -69,6 +72,17 @@ class GeckoViewNavigation extends GeckoViewModule {
this.messageManager.addMessageListener("Browser:LoadURI", this);
this._initialAboutBlank = true;
debug`sessionContextId=${this.settings.sessionContextId}`;
if (this.settings.sessionContextId !== null) {
this.browser.webNavigation.setOriginAttributesBeforeLoading({
geckoViewSessionContextId: this.settings.sessionContextId,
privateBrowsingId: PrivateBrowsingUtils.isBrowserPrivate(this.browser)
? 1
: 0,
});
}
}
// Bundle event handler.

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

@ -43,6 +43,7 @@ class GeckoViewSettings extends GeckoViewModule {
debug`onInit`;
this._userAgentMode = USER_AGENT_MODE_MOBILE;
this._userAgentOverride = null;
this._sessionContextId = null;
// Required for safe browsing and tracking protection.
this.registerListener(["GeckoView:GetUserAgent"]);
@ -65,6 +66,7 @@ class GeckoViewSettings extends GeckoViewModule {
this.displayMode = settings.displayMode;
this.userAgentMode = settings.userAgentMode;
this.userAgentOverride = settings.userAgentOverride;
this.sessionContextId = settings.sessionContextId;
}
get useMultiprocess() {
@ -110,6 +112,14 @@ class GeckoViewSettings extends GeckoViewModule {
set displayMode(aMode) {
this.window.docShell.displayMode = aMode;
}
set sessionContextId(aAttribute) {
this._sessionContextId = aAttribute;
}
get sessionContextId() {
return this._sessionContextId;
}
}
const { debug, warn } = GeckoViewSettings.initLogging("GeckoViewSettings"); // eslint-disable-line no-unused-vars

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

@ -125,4 +125,13 @@ const GeckoViewStorageController = {
aCallback.onSuccess();
});
},
clearSessionContextData(aContextId) {
const pattern = { geckoViewSessionContextId: aContextId };
debug`clearSessionContextData ${pattern}`;
Services.clearData.deleteDataFromOriginAttributesPattern(pattern);
// Call QMS explicitly to work around bug 1537882.
Services.qms.clearStoragesForOriginAttributesPattern(
JSON.stringify(pattern));
},
};

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

@ -2911,6 +2911,10 @@ already_AddRefed<nsILoadInfo> HttpBaseChannel::CloneLoadInfoForRedirect(
MOZ_ASSERT(
docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId,
"docshell and necko should have the same privateBrowsingId attribute.");
MOZ_ASSERT(docShellAttrs.mGeckoViewSessionContextId ==
attrs.mGeckoViewSessionContextId,
"docshell and necko should have the same "
"geckoViewSessionContextId attribute");
attrs = docShellAttrs;
attrs.SetFirstPartyDomain(true, newURI);