mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 03:45:46 +00:00
Merge mozilla-central to autoland. a=merge CLOSED TREE
This commit is contained in:
commit
e5bdfc5b27
@ -719,8 +719,6 @@ pref("plugin.default.state", 1);
|
||||
// Plugins bundled in XPIs are enabled by default.
|
||||
pref("plugin.defaultXpi.state", 2);
|
||||
|
||||
// Java is Click-to-Activate by default on all channels.
|
||||
pref("plugin.state.java", 1);
|
||||
|
||||
// Flash is Click-to-Activate by default on all channels.
|
||||
pref("plugin.state.flash", 1);
|
||||
|
@ -1,6 +1,6 @@
|
||||
const PREF_MULTISELECT_TABS = "browser.tabs.multiselect";
|
||||
|
||||
async function triggerClickOn(target, options) {
|
||||
function triggerClickOn(target, options) {
|
||||
let promise = BrowserTestUtils.waitForEvent(target, "click");
|
||||
if (AppConstants.platform == "macosx") {
|
||||
options = { metaKey: options.ctrlKey };
|
||||
@ -10,7 +10,7 @@ async function triggerClickOn(target, options) {
|
||||
}
|
||||
|
||||
async function addTab() {
|
||||
const tab = BrowserTestUtils.addTab(gBrowser, "http://mochi.test:8888/");
|
||||
const tab = BrowserTestUtils.addTab(gBrowser, "http://mochi.test:8888/", {skipAnimation: true});
|
||||
const browser = gBrowser.getBrowserForTab(tab);
|
||||
await BrowserTestUtils.browserLoaded(browser);
|
||||
return tab;
|
||||
@ -22,7 +22,13 @@ add_task(async function clickWithoutPrefSet() {
|
||||
|
||||
isnot(gBrowser.selectedTab, tab, "Tab doesn't have focus");
|
||||
|
||||
await triggerClickOn(tab, { ctrlKey: true });
|
||||
// We make sure that the tab-switch is completely done before executing checks
|
||||
await BrowserTestUtils.switchTab(gBrowser, () => {
|
||||
triggerClickOn(tab, { ctrlKey: true });
|
||||
});
|
||||
|
||||
await TestUtils.waitForCondition(() => gBrowser.selectedTab == tab,
|
||||
"Wait for the selectedTab getter to update");
|
||||
|
||||
ok(!tab.multiselected && !mSelectedTabs.has(tab),
|
||||
"Multi-select tab doesn't work when multi-select pref is not set");
|
||||
|
@ -1843,7 +1843,7 @@ BrowserGlue.prototype = {
|
||||
_migrateUI: function BG__migrateUI() {
|
||||
// Use an increasing number to keep track of the current migration state.
|
||||
// Completely unrelated to the current Firefox release number.
|
||||
const UI_VERSION = 68;
|
||||
const UI_VERSION = 69;
|
||||
const BROWSER_DOCURL = "chrome://browser/content/browser.xul";
|
||||
|
||||
let currentUIVersion;
|
||||
@ -2205,6 +2205,17 @@ BrowserGlue.prototype = {
|
||||
"kinto.sqlite"), {ignoreAbsent: true});
|
||||
}
|
||||
|
||||
if (currentUIVersion < 69) {
|
||||
// Clear old social prefs from profile (bug 1460675)
|
||||
let socialPrefs = Services.prefs.getBranch("social.");
|
||||
if (socialPrefs) {
|
||||
let socialPrefsArray = socialPrefs.getChildList("");
|
||||
for (let item of socialPrefsArray) {
|
||||
Services.prefs.clearUserPref("social." + item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update the migration version.
|
||||
Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
|
||||
},
|
||||
|
@ -0,0 +1,23 @@
|
||||
const UI_VERSION = 69;
|
||||
const TOPIC_BROWSERGLUE_TEST = "browser-glue-test";
|
||||
const TOPICDATA_BROWSERGLUE_TEST = "force-ui-migration";
|
||||
|
||||
var gBrowserGlue = Cc["@mozilla.org/browser/browserglue;1"]
|
||||
.getService(Ci.nsIObserver);
|
||||
|
||||
Services.prefs.setIntPref("browser.migration.version", UI_VERSION - 1);
|
||||
|
||||
add_task(async function test_check_cleanup_social_prefs() {
|
||||
Services.prefs.setStringPref("social.manifest.example-com", "example.com");
|
||||
|
||||
// Simulate a migration.
|
||||
gBrowserGlue.observe(null, TOPIC_BROWSERGLUE_TEST, TOPICDATA_BROWSERGLUE_TEST);
|
||||
|
||||
Assert.ok(!Services.prefs.prefHasUserValue("social.manifest.example-com"),
|
||||
"should have cleared old social preference 'social.manifest.example-com'");
|
||||
});
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("browser.migration.version");
|
||||
Services.prefs.clearUserPref("social.manifest.example-com");
|
||||
});
|
@ -9,4 +9,5 @@ support-files =
|
||||
[test_browserGlue_migration_loop_cleanup.js]
|
||||
[test_distribution.js]
|
||||
[test_distribution_cachedexistence.js]
|
||||
[test_browserGlue_migration_social_cleanup.js]
|
||||
[test_browserGlue_pingcentre.js]
|
||||
|
@ -615,31 +615,6 @@ Navigator::GetDoNotTrack(nsAString &aResult)
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Navigator::JavaEnabled(CallerType aCallerType, ErrorResult& aRv)
|
||||
{
|
||||
Telemetry::AutoTimer<Telemetry::CHECK_JAVA_ENABLED> telemetryTimer;
|
||||
|
||||
// Return true if we have a handler for the java mime
|
||||
nsAutoString javaMIME;
|
||||
Preferences::GetString("plugin.java.mime", javaMIME);
|
||||
NS_ENSURE_TRUE(!javaMIME.IsEmpty(), false);
|
||||
|
||||
if (!mMimeTypes) {
|
||||
if (!mWindow) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return false;
|
||||
}
|
||||
mMimeTypes = new nsMimeTypeArray(mWindow);
|
||||
}
|
||||
|
||||
RefreshMIMEArray();
|
||||
|
||||
nsMimeType *mimeType = mMimeTypes->NamedItem(javaMIME, aCallerType);
|
||||
|
||||
return mimeType && mimeType->GetEnabledPlugin();
|
||||
}
|
||||
|
||||
uint64_t
|
||||
Navigator::HardwareConcurrency()
|
||||
{
|
||||
|
@ -158,7 +158,10 @@ public:
|
||||
bool CookieEnabled();
|
||||
void GetBuildID(nsAString& aBuildID, CallerType aCallerType,
|
||||
ErrorResult& aRv) const;
|
||||
bool JavaEnabled(CallerType aCallerType, ErrorResult& aRv);
|
||||
bool JavaEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
uint64_t HardwareConcurrency();
|
||||
bool TaintEnabled()
|
||||
{
|
||||
|
@ -42,7 +42,10 @@ public:
|
||||
StructuredCloneHolderBase(StructuredCloneScope aScope = StructuredCloneScope::SameProcessSameThread);
|
||||
virtual ~StructuredCloneHolderBase();
|
||||
|
||||
StructuredCloneHolderBase(StructuredCloneHolderBase&& aOther) = default;
|
||||
// Note, it is unsafe to Move() a StructuredCloneHolderBase since a raw
|
||||
// this pointer is passed to mBuffer as a callback closure. That must
|
||||
// be fixed if you want to implement a move constructor here.
|
||||
StructuredCloneHolderBase(StructuredCloneHolderBase&& aOther) = delete;
|
||||
|
||||
// These methods should be implemented in order to clone data.
|
||||
// Read more documentation in js/public/StructuredClone.h.
|
||||
@ -173,7 +176,7 @@ public:
|
||||
StructuredCloneScope aStructuredCloneScope);
|
||||
virtual ~StructuredCloneHolder();
|
||||
|
||||
StructuredCloneHolder(StructuredCloneHolder&& aOther) = default;
|
||||
StructuredCloneHolder(StructuredCloneHolder&& aOther) = delete;
|
||||
|
||||
// Normally you should just use Write() and Read().
|
||||
|
||||
|
@ -46,3 +46,4 @@ DEPRECATED_OPERATION(OrientationEvent)
|
||||
DEPRECATED_OPERATION(ProximityEvent)
|
||||
DEPRECATED_OPERATION(AmbientLightEvent)
|
||||
DEPRECATED_OPERATION(IDBOpenDBOptions_StorageType)
|
||||
DEPRECATED_OPERATION(DOMAttrModifiedEvent)
|
||||
|
@ -326,6 +326,9 @@ EventListenerManager::AddEventListenerInternal(
|
||||
nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
|
||||
if (doc) {
|
||||
doc->WarnOnceAbout(nsIDocument::eMutationEvent);
|
||||
if (aEventMessage == eLegacyAttrModified) {
|
||||
doc->WarnOnceAbout(nsIDocument::eDOMAttrModifiedEvent);
|
||||
}
|
||||
}
|
||||
// If aEventMessage is eLegacySubtreeModified, we need to listen all
|
||||
// mutations. nsContentUtils::HasMutationListeners relies on this.
|
||||
|
@ -103,17 +103,17 @@ static NPNetscapeFuncs sBrowserFuncs = {
|
||||
_geturl,
|
||||
_posturl,
|
||||
_requestread,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr, // _newstream, unimplemented
|
||||
nullptr, // _write, unimplemented
|
||||
nullptr, // _destroystream, unimplemented
|
||||
_status,
|
||||
_useragent,
|
||||
_memalloc,
|
||||
_memfree,
|
||||
_memflush,
|
||||
_reloadplugins,
|
||||
_getJavaEnv,
|
||||
_getJavaPeer,
|
||||
nullptr, // _getJavaEnv, unimplemented
|
||||
nullptr, // _getJavaPeer, unimplemented
|
||||
_geturlnotify,
|
||||
_posturlnotify,
|
||||
_getvalue,
|
||||
@ -1702,14 +1702,6 @@ _requestread(NPStream *pstream, NPByteRange *rangeList)
|
||||
return NPERR_STREAM_NOT_SEEKABLE;
|
||||
}
|
||||
|
||||
// Deprecated, only stubbed out
|
||||
void* /* OJI type: JRIEnv* */
|
||||
_getJavaEnv()
|
||||
{
|
||||
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_GetJavaEnv\n"));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char *
|
||||
_useragent(NPP npp)
|
||||
{
|
||||
@ -1743,14 +1735,6 @@ _memalloc (uint32_t size)
|
||||
return moz_xmalloc(size);
|
||||
}
|
||||
|
||||
// Deprecated, only stubbed out
|
||||
void* /* OJI type: jref */
|
||||
_getJavaPeer(NPP npp)
|
||||
{
|
||||
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_GetJavaPeer: npp=%p\n", (void*)npp));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
_pushpopupsenabledstate(NPP npp, NPBool enabled)
|
||||
{
|
||||
|
@ -279,13 +279,6 @@ _useragent(NPP npp);
|
||||
void*
|
||||
_memalloc (uint32_t size);
|
||||
|
||||
// Deprecated entry points for the old Java plugin.
|
||||
void* /* OJI type: JRIEnv* */
|
||||
_getJavaEnv();
|
||||
|
||||
void* /* OJI type: jref */
|
||||
_getJavaPeer(NPP npp);
|
||||
|
||||
void
|
||||
_urlredirectresponse(NPP instance, void* notifyData, NPBool allow);
|
||||
|
||||
|
@ -59,7 +59,6 @@ nsNPAPIPluginInstance::nsNPAPIPluginInstance()
|
||||
#ifdef XP_MACOSX
|
||||
, mCurrentPluginEvent(nullptr)
|
||||
#endif
|
||||
, mHaveJavaC2PJSObjectQuirk(false)
|
||||
, mCachedParamLength(0)
|
||||
, mCachedParamNames(nullptr)
|
||||
, mCachedParamValues(nullptr)
|
||||
|
@ -298,9 +298,6 @@ private:
|
||||
// This is only valid when the plugin is actually stopped!
|
||||
mozilla::TimeStamp mStopTime;
|
||||
|
||||
// is this instance Java and affected by bug 750480?
|
||||
bool mHaveJavaC2PJSObjectQuirk;
|
||||
|
||||
static uint32_t gInUnsafePluginCalls;
|
||||
|
||||
// The arrays can only be released when the plugin instance is destroyed,
|
||||
|
@ -875,14 +875,6 @@ _useragent(NPP aNPP);
|
||||
static void*
|
||||
_memalloc (uint32_t size);
|
||||
|
||||
// Deprecated entry points for the old Java plugin.
|
||||
static void* /* OJI type: JRIEnv* */
|
||||
_getjavaenv(void);
|
||||
|
||||
// Deprecated entry points for the old Java plugin.
|
||||
static void* /* OJI type: jref */
|
||||
_getjavapeer(NPP aNPP);
|
||||
|
||||
static bool
|
||||
_invoke(NPP aNPP, NPObject* npobj, NPIdentifier method, const NPVariant *args,
|
||||
uint32_t argCount, NPVariant *result);
|
||||
@ -978,17 +970,17 @@ const NPNetscapeFuncs PluginModuleChild::sBrowserFuncs = {
|
||||
mozilla::plugins::child::_geturl,
|
||||
mozilla::plugins::child::_posturl,
|
||||
mozilla::plugins::child::_requestread,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr, // _newstream, unimplemented
|
||||
nullptr, // _write, unimplemented
|
||||
nullptr, // _destroystream, unimplemented
|
||||
mozilla::plugins::child::_status,
|
||||
mozilla::plugins::child::_useragent,
|
||||
mozilla::plugins::child::_memalloc,
|
||||
mozilla::plugins::child::_memfree,
|
||||
mozilla::plugins::child::_memflush,
|
||||
mozilla::plugins::child::_reloadplugins,
|
||||
mozilla::plugins::child::_getjavaenv,
|
||||
mozilla::plugins::child::_getjavapeer,
|
||||
nullptr, // _getjavaenv, unimplemented
|
||||
nullptr, // _getjavapeer, unimplemented
|
||||
mozilla::plugins::child::_geturlnotify,
|
||||
mozilla::plugins::child::_posturlnotify,
|
||||
mozilla::plugins::child::_getvalue,
|
||||
@ -1304,21 +1296,6 @@ _memalloc(uint32_t aSize)
|
||||
return moz_xmalloc(aSize);
|
||||
}
|
||||
|
||||
// Deprecated entry points for the old Java plugin.
|
||||
void* /* OJI type: JRIEnv* */
|
||||
_getjavaenv(void)
|
||||
{
|
||||
PLUGIN_LOG_DEBUG_FUNCTION;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* /* OJI type: jref */
|
||||
_getjavapeer(NPP aNPP)
|
||||
{
|
||||
PLUGIN_LOG_DEBUG_FUNCTION;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
_invoke(NPP aNPP,
|
||||
NPObject* aNPObj,
|
||||
|
@ -135,7 +135,6 @@ static bool setPluginWantsAllStreams(NPObject* npobj, const NPVariant* args, uin
|
||||
static bool crashPlugin(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||
static bool crashOnDestroy(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||
static bool getObjectValue(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||
static bool getJavaCodebase(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||
static bool checkObjectValue(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||
static bool enableFPExceptions(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||
static bool hangPlugin(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||
@ -207,7 +206,6 @@ static const NPUTF8* sPluginMethodIdentifierNames[] = {
|
||||
"crash",
|
||||
"crashOnDestroy",
|
||||
"getObjectValue",
|
||||
"getJavaCodebase",
|
||||
"checkObjectValue",
|
||||
"enableFPExceptions",
|
||||
"hang",
|
||||
@ -280,7 +278,6 @@ static const ScriptableFunction sPluginMethodFunctions[] = {
|
||||
crashPlugin,
|
||||
crashOnDestroy,
|
||||
getObjectValue,
|
||||
getJavaCodebase,
|
||||
checkObjectValue,
|
||||
enableFPExceptions,
|
||||
hangPlugin,
|
||||
@ -882,11 +879,6 @@ NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char*
|
||||
if (strcmp(argn[i], "bugmode") == 0) {
|
||||
instanceData->bugMode = atoi(argv[i]);
|
||||
}
|
||||
// Try to emulate java's codebase handling: Use the last seen codebase
|
||||
// value, regardless of whether it is in attributes or params.
|
||||
if (strcasecmp(argn[i], "codebase") == 0) {
|
||||
instanceData->javaCodebase = argv[i];
|
||||
}
|
||||
|
||||
// Bug 1307694 - There are two flash parameters that are order dependent for
|
||||
// scaling/sizing the plugin. If they ever change from what is expected, it
|
||||
@ -2724,20 +2716,6 @@ static const NPClass kTestSharedNPClass = {
|
||||
// Everything else is nullptr
|
||||
};
|
||||
|
||||
static bool getJavaCodebase(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
|
||||
{
|
||||
if (argCount != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NPP npp = static_cast<TestNPObject*>(npobj)->npp;
|
||||
InstanceData* id = static_cast<InstanceData*>(npp->pdata);
|
||||
|
||||
char *outval = NPN_StrDup(id->javaCodebase.c_str());
|
||||
STRINGZ_TO_NPVARIANT(outval, *result);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool getObjectValue(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
|
||||
{
|
||||
NPP npp = static_cast<TestNPObject*>(npobj)->npp;
|
||||
|
@ -141,7 +141,6 @@ typedef struct InstanceData {
|
||||
bool wantsAllStreams;
|
||||
int32_t mouseUpEventCount;
|
||||
int32_t bugMode;
|
||||
std::string javaCodebase;
|
||||
AsyncDrawing asyncDrawing;
|
||||
NPAsyncSurface *frontBuffer;
|
||||
NPAsyncSurface *backBuffer;
|
||||
|
@ -521,17 +521,17 @@ public:
|
||||
};
|
||||
|
||||
class SendMessageEventRunnable final : public ExtendableEventWorkerRunnable
|
||||
, public StructuredCloneHolder
|
||||
{
|
||||
StructuredCloneHolder mData;
|
||||
const ClientInfoAndState mClientInfoAndState;
|
||||
|
||||
public:
|
||||
SendMessageEventRunnable(WorkerPrivate* aWorkerPrivate,
|
||||
KeepAliveToken* aKeepAliveToken,
|
||||
StructuredCloneHolder&& aData,
|
||||
const ClientInfoAndState& aClientInfoAndState)
|
||||
: ExtendableEventWorkerRunnable(aWorkerPrivate, aKeepAliveToken)
|
||||
, mData(Move(aData))
|
||||
, StructuredCloneHolder(CloningSupported, TransferringSupported,
|
||||
JS::StructuredCloneScope::SameProcessDifferentThread)
|
||||
, mClientInfoAndState(aClientInfoAndState)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
@ -543,13 +543,13 @@ public:
|
||||
JS::Rooted<JS::Value> messageData(aCx);
|
||||
nsCOMPtr<nsIGlobalObject> sgo = aWorkerPrivate->GlobalScope();
|
||||
ErrorResult rv;
|
||||
mData.Read(sgo, aCx, &messageData, rv);
|
||||
Read(sgo, aCx, &messageData, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Sequence<OwningNonNull<MessagePort>> ports;
|
||||
if (!mData.TakeTransferredPortsAsSequence(ports)) {
|
||||
if (!TakeTransferredPortsAsSequence(ports)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -640,17 +640,6 @@ ServiceWorkerPrivate::SendMessageEvent(ipc::StructuredCloneData&& aData,
|
||||
JS::Rooted<JS::Value> transferable(cx);
|
||||
transferable.setObject(*array);
|
||||
|
||||
StructuredCloneHolder holder(StructuredCloneHolder::CloningSupported,
|
||||
StructuredCloneHolder::TransferringSupported,
|
||||
JS::StructuredCloneScope::DifferentProcess);
|
||||
holder.Write(cx, messageData, transferable, JS::CloneDataPolicy(), rv);
|
||||
if (rv.Failed()) {
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
// Now that the re-packing is complete, send a runnable to the service worker
|
||||
// thread.
|
||||
|
||||
rv = SpawnWorkerIfNeeded(MessageEvent);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
return rv.StealNSResult();
|
||||
@ -658,8 +647,13 @@ ServiceWorkerPrivate::SendMessageEvent(ipc::StructuredCloneData&& aData,
|
||||
|
||||
RefPtr<KeepAliveToken> token = CreateEventKeepAliveToken();
|
||||
RefPtr<SendMessageEventRunnable> runnable =
|
||||
new SendMessageEventRunnable(mWorkerPrivate, token, Move(holder),
|
||||
aClientInfoAndState);
|
||||
new SendMessageEventRunnable(mWorkerPrivate, token, aClientInfoAndState);
|
||||
|
||||
runnable->Write(cx, messageData, transferable, JS::CloneDataPolicy(), rv);
|
||||
if (rv.Failed()) {
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
if (!runnable->Dispatch()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -186,7 +186,7 @@ partial interface Navigator {
|
||||
readonly attribute DOMString buildID;
|
||||
|
||||
// WebKit/Blink/Trident/Presto support this.
|
||||
[Throws, NeedsCallerType]
|
||||
[Affects=Nothing, DependsOn=Nothing]
|
||||
boolean javaEnabled();
|
||||
|
||||
/**
|
||||
|
@ -119,6 +119,7 @@ public:
|
||||
EndTransactionFlags aFlags = END_DEFAULT) = 0;
|
||||
virtual void UpdateRenderBounds(const gfx::IntRect& aRect) {}
|
||||
virtual void SetDiagnosticTypes(DiagnosticTypes aDiagnostics) {}
|
||||
virtual void InvalidateAll() = 0;
|
||||
|
||||
virtual HostLayerManager* AsHostLayerManager() override {
|
||||
return this;
|
||||
@ -406,6 +407,10 @@ public:
|
||||
mCompositor->SetDiagnosticTypes(aDiagnostics);
|
||||
}
|
||||
|
||||
virtual void InvalidateAll() override {
|
||||
AddInvalidRegion(nsIntRegion(mRenderBounds));
|
||||
}
|
||||
|
||||
void ForcePresent() override { mCompositor->ForcePresent(); }
|
||||
|
||||
private:
|
||||
|
@ -642,9 +642,8 @@ CompositorBridgeParent::RecvNotifyRegionInvalidated(const nsIntRegion& aRegion)
|
||||
void
|
||||
CompositorBridgeParent::Invalidate()
|
||||
{
|
||||
if (mLayerManager && mLayerManager->GetRoot()) {
|
||||
mLayerManager->AddInvalidRegion(
|
||||
mLayerManager->GetRoot()->GetLocalVisibleRegion().ToUnknownRegion().GetBounds());
|
||||
if (mLayerManager) {
|
||||
mLayerManager->InvalidateAll();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,6 +69,10 @@ public:
|
||||
void NotifyShadowTreeTransaction() override;
|
||||
void UpdateRenderBounds(const gfx::IntRect& aRect) override;
|
||||
|
||||
void InvalidateAll() override {
|
||||
AddInvalidRegion(nsIntRegion(mRenderBounds));
|
||||
}
|
||||
|
||||
LayerManagerMLGPU* AsLayerManagerMLGPU() override {
|
||||
return this;
|
||||
}
|
||||
|
@ -201,12 +201,6 @@ opt = args.jemalloc
|
||||
if opt is not None:
|
||||
CONFIGURE_ARGS += (" --enable-jemalloc" if opt else " --disable-jemalloc")
|
||||
|
||||
# Any jobs that wish to produce additional output can save them into the upload
|
||||
# directory if there is such a thing, falling back to OBJDIR.
|
||||
env.setdefault('MOZ_UPLOAD_DIR', OBJDIR)
|
||||
ensure_dir_exists(env['MOZ_UPLOAD_DIR'], clobber=False, creation_marker_filename=None)
|
||||
info("MOZ_UPLOAD_DIR = {}".format(env['MOZ_UPLOAD_DIR']))
|
||||
|
||||
# Some of the variants request a particular word size (eg ARM simulators).
|
||||
word_bits = variant.get('bits')
|
||||
|
||||
@ -314,6 +308,12 @@ timer.start()
|
||||
ensure_dir_exists(OBJDIR, clobber=not args.dep and not args.nobuild)
|
||||
ensure_dir_exists(OUTDIR, clobber=not args.keep)
|
||||
|
||||
# Any jobs that wish to produce additional output can save them into the upload
|
||||
# directory if there is such a thing, falling back to OBJDIR.
|
||||
env.setdefault('MOZ_UPLOAD_DIR', OBJDIR)
|
||||
ensure_dir_exists(env['MOZ_UPLOAD_DIR'], clobber=False, creation_marker_filename=None)
|
||||
info("MOZ_UPLOAD_DIR = {}".format(env['MOZ_UPLOAD_DIR']))
|
||||
|
||||
|
||||
def run_command(command, check=False, **kwargs):
|
||||
kwargs.setdefault('cwd', OBJDIR)
|
||||
|
@ -0,0 +1,15 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/ */
|
||||
|
||||
var BUGNUMBER = '523401';
|
||||
var summary = 'numeric literal followed by an identifier';
|
||||
|
||||
var array = new Array();
|
||||
assertThrowsInstanceOf(() => eval("array[0for]"), SyntaxError);
|
||||
assertThrowsInstanceOf(() => eval("array[1yield]"), SyntaxError);
|
||||
assertThrowsInstanceOf(() => eval("array[2in []]"), SyntaxError); // "2 in []" is valid.
|
||||
reportCompare(array[2 in []], undefined);
|
||||
reportCompare(2 in [], false);
|
||||
assertThrowsInstanceOf(() => eval("array[3in]"), SyntaxError);
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(0, 0);
|
0
js/src/tests/non262/literals/numeric/shell.js
Normal file
0
js/src/tests/non262/literals/numeric/shell.js
Normal file
0
js/src/tests/non262/literals/shell.js
Normal file
0
js/src/tests/non262/literals/shell.js
Normal file
@ -557,8 +557,188 @@ var XPCOMUtils = {
|
||||
writable: false
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Defines a proxy which acts as a lazy object getter that can be passed
|
||||
* around as a reference, and will only be evaluated when something in
|
||||
* that object gets accessed.
|
||||
*
|
||||
* The evaluation can be triggered by a function call, by getting or
|
||||
* setting a property, calling this as a constructor, or enumerating
|
||||
* the properties of this object (e.g. during an iteration).
|
||||
*
|
||||
* Please note that, even after evaluated, the object given to you
|
||||
* remains being the proxy object (which forwards everything to the
|
||||
* real object). This is important to correctly use these objects
|
||||
* in pairs of add+remove listeners, for example.
|
||||
* If your use case requires access to the direct object, you can
|
||||
* get it through the untrap callback.
|
||||
*
|
||||
* @param aObject
|
||||
* The object to define the lazy getter on.
|
||||
*
|
||||
* You can pass null to aObject if you just want to get this
|
||||
* proxy through the return value.
|
||||
*
|
||||
* @param aName
|
||||
* The name of the getter to define on aObject.
|
||||
*
|
||||
* @param aInitFuncOrResource
|
||||
* A function or a module that defines what this object actually
|
||||
* should be when it gets evaluated. This will only ever be called once.
|
||||
*
|
||||
* Short-hand: If you pass a string to this parameter, it will be treated
|
||||
* as the URI of a module to be imported, and aName will be used as
|
||||
* the symbol to retrieve from the module.
|
||||
*
|
||||
* @param aStubProperties
|
||||
* In this parameter, you can provide an object which contains
|
||||
* properties from the original object that, when accessed, will still
|
||||
* prevent the entire object from being evaluated.
|
||||
*
|
||||
* These can be copies or simplified versions of the original properties.
|
||||
*
|
||||
* One example is to provide an alternative QueryInterface implementation
|
||||
* to avoid the entire object from being evaluated when it's added as an
|
||||
* observer (as addObserver calls object.QueryInterface(Ci.nsIObserver)).
|
||||
*
|
||||
* Once the object has been evaluated, the properties from the real
|
||||
* object will be used instead of the ones provided here.
|
||||
*
|
||||
* @param aUntrapCallback
|
||||
* A function that gets called once when the object has just been evaluated.
|
||||
* You can use this to do some work (e.g. setting properties) that you need
|
||||
* to do on this object but that can wait until it gets evaluated.
|
||||
*
|
||||
* Another use case for this is to use during code development to log when
|
||||
* this object gets evaluated, to make sure you're not accidentally triggering
|
||||
* it earlier than expected.
|
||||
*/
|
||||
defineLazyProxy: function XPCOMUtils__defineLazyProxy(aObject, aName, aInitFuncOrResource,
|
||||
aStubProperties, aUntrapCallback) {
|
||||
let initFunc = aInitFuncOrResource;
|
||||
|
||||
if (typeof(aInitFuncOrResource) == "string") {
|
||||
initFunc = function () {
|
||||
let tmp = {};
|
||||
ChromeUtils.import(aInitFuncOrResource, tmp);
|
||||
return tmp[aName];
|
||||
};
|
||||
}
|
||||
|
||||
let handler = new LazyProxyHandler(aName, initFunc,
|
||||
aStubProperties, aUntrapCallback);
|
||||
|
||||
/*
|
||||
* We cannot simply create a lazy getter for the underlying
|
||||
* object and pass it as the target of the proxy, because
|
||||
* just passing it in `new Proxy` means it would get
|
||||
* evaluated. Becase of this, a full handler needs to be
|
||||
* implemented (the LazyProxyHandler).
|
||||
*
|
||||
* So, an empty object is used as the target, and the handler
|
||||
* replaces it on every call with the real object.
|
||||
*/
|
||||
let proxy = new Proxy({}, handler);
|
||||
|
||||
if (aObject) {
|
||||
Object.defineProperty(aObject, aName, {
|
||||
value: proxy,
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
});
|
||||
}
|
||||
|
||||
return proxy;
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* LazyProxyHandler
|
||||
* This class implements the handler used
|
||||
* in the proxy from defineLazyProxy.
|
||||
*
|
||||
* This handler forwards all calls to an underlying object,
|
||||
* stored as `this.realObject`, which is obtained as the returned
|
||||
* value from aInitFunc, which will be called on the first time
|
||||
* time that it needs to be used (with an exception in the get() trap
|
||||
* for the properties provided in the `aStubProperties` parameter).
|
||||
*/
|
||||
|
||||
class LazyProxyHandler {
|
||||
constructor(aName, aInitFunc, aStubProperties, aUntrapCallback) {
|
||||
this.pending = true;
|
||||
this.name = aName;
|
||||
this.initFuncOrResource = aInitFunc;
|
||||
this.stubProperties = aStubProperties;
|
||||
this.untrapCallback = aUntrapCallback;
|
||||
}
|
||||
|
||||
getObject() {
|
||||
if (this.pending) {
|
||||
this.realObject = this.initFuncOrResource.call(null);
|
||||
|
||||
if (this.untrapCallback) {
|
||||
this.untrapCallback.call(null, this.realObject);
|
||||
this.untrapCallback = null;
|
||||
}
|
||||
|
||||
this.pending = false;
|
||||
this.stubProperties = null;
|
||||
}
|
||||
return this.realObject;
|
||||
}
|
||||
|
||||
getPrototypeOf(target) {
|
||||
return Reflect.getPrototypeOf(this.getObject());
|
||||
}
|
||||
|
||||
setPrototypeOf(target, prototype) {
|
||||
return Reflect.setPrototypeOf(this.getObject(), prototype);
|
||||
}
|
||||
|
||||
isExtensible(target) {
|
||||
return Reflect.isExtensible(this.getObject());
|
||||
}
|
||||
|
||||
preventExtensions(target) {
|
||||
return Reflect.preventExtensions(this.getObject());
|
||||
}
|
||||
|
||||
getOwnPropertyDescriptor(target, prop) {
|
||||
return Reflect.getOwnPropertyDescriptor(this.getObject(), prop);
|
||||
}
|
||||
|
||||
defineProperty(target, prop, descriptor) {
|
||||
return Reflect.defineProperty(this.getObject(), prop, descriptor);
|
||||
}
|
||||
|
||||
has(target, prop) {
|
||||
return Reflect.has(this.getObject(), prop);
|
||||
}
|
||||
|
||||
get(target, prop, receiver) {
|
||||
if (this.pending &&
|
||||
this.stubProperties &&
|
||||
Object.prototype.hasOwnProperty.call(this.stubProperties, prop)) {
|
||||
return this.stubProperties[prop];
|
||||
}
|
||||
return Reflect.get(this.getObject(), prop, receiver);
|
||||
}
|
||||
|
||||
set(target, prop, value, receiver) {
|
||||
return Reflect.set(this.getObject(), prop, value, receiver);
|
||||
}
|
||||
|
||||
deleteProperty(target, prop) {
|
||||
return Reflect.deleteProperty(this.getObject(), prop);
|
||||
}
|
||||
|
||||
ownKeys(target) {
|
||||
return Reflect.ownKeys(this.getObject());
|
||||
}
|
||||
}
|
||||
|
||||
var XPCU_lazyPreferenceObserverQI = ChromeUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]);
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "Services",
|
||||
|
113
js/xpconnect/tests/unit/test_lazyproxy.js
Normal file
113
js/xpconnect/tests/unit/test_lazyproxy.js
Normal file
@ -0,0 +1,113 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* This file tests the method defineLazyProxy from XPCOMUtils.jsm.
|
||||
*/
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
add_task(function test_lazy_proxy() {
|
||||
let tmp = {};
|
||||
let realObject = {
|
||||
"prop1": "value1",
|
||||
"prop2": "value2",
|
||||
};
|
||||
|
||||
let evaluated = false;
|
||||
let untrapCalled = false;
|
||||
|
||||
let lazyProxy = XPCOMUtils.defineLazyProxy(
|
||||
tmp,
|
||||
"myLazyProxy",
|
||||
|
||||
// Initiliazer function
|
||||
function init() {
|
||||
evaluated = true;
|
||||
return realObject;
|
||||
},
|
||||
|
||||
// Stub properties
|
||||
{
|
||||
"prop1": "stub"
|
||||
},
|
||||
|
||||
// Untrap callback
|
||||
function untrapCallback(obj) {
|
||||
Assert.equal(obj, realObject, "The underlying object can be obtained in the untrap callback");
|
||||
untrapCalled = true;
|
||||
}
|
||||
);
|
||||
|
||||
// Check that the proxy returned and the one
|
||||
// defined in tmp are the same.
|
||||
//
|
||||
// Note: Assert.strictEqual can't be used here
|
||||
// because it wants to stringify the two objects
|
||||
// compared, which defeats the lazy proxy.
|
||||
Assert.ok(lazyProxy === tmp.myLazyProxy, "Return value and object defined are the same");
|
||||
|
||||
Assert.ok(Cu.isProxy(lazyProxy), "Returned value is in fact a proxy");
|
||||
|
||||
// Check that just using the proxy above didn't
|
||||
// trigger the lazy getter evaluation.
|
||||
Assert.ok(!evaluated, "The lazy proxy hasn't been evaluated yet");
|
||||
Assert.ok(!untrapCalled, "The untrap callback hasn't been called yet");
|
||||
|
||||
// Accessing a stubbed property returns the stub
|
||||
// value and doesn't trigger evaluation.
|
||||
Assert.equal(lazyProxy.prop1, "stub", "Accessing a stubbed property returns the stubbed value");
|
||||
|
||||
Assert.ok(!evaluated, "The access to the stubbed property above didn't evaluate the lazy proxy");
|
||||
Assert.ok(!untrapCalled, "The untrap callback hasn't been called yet");
|
||||
|
||||
// Now the access to another property will trigger
|
||||
// the evaluation, as expected.
|
||||
Assert.equal(lazyProxy.prop2, "value2", "Property access is correctly forwarded to the underlying object");
|
||||
|
||||
Assert.ok(evaluated, "Accessing a non-stubbed property triggered the proxy evaluation");
|
||||
Assert.ok(untrapCalled, "The untrap callback was called");
|
||||
|
||||
// The value of prop1 is now the real value and not the stub value.
|
||||
Assert.equal(lazyProxy.prop1, "value1", "The value of prop1 is now the real value and not the stub one");
|
||||
});
|
||||
|
||||
add_task(function test_module_version() {
|
||||
// Test that passing a string instead of an initialization function
|
||||
// makes this behave like a lazy module getter.
|
||||
const NET_UTIL_URI = "resource://gre/modules/NetUtil.jsm";
|
||||
let underlyingObject;
|
||||
|
||||
Cu.unload(NET_UTIL_URI);
|
||||
|
||||
let lazyProxy = XPCOMUtils.defineLazyProxy(
|
||||
null,
|
||||
"NetUtil",
|
||||
NET_UTIL_URI,
|
||||
null, /* no stubs */
|
||||
function untrapCallback(object) {
|
||||
underlyingObject = object;
|
||||
}
|
||||
);
|
||||
|
||||
Assert.ok(!Cu.isModuleLoaded(NET_UTIL_URI), "The NetUtil module was not loaded by the lazy proxy definition");
|
||||
|
||||
// Access the object, which will evaluate the proxy.
|
||||
lazyProxy.foo = "bar";
|
||||
|
||||
// Module was loaded.
|
||||
Assert.ok(Cu.isModuleLoaded(NET_UTIL_URI), "The NetUtil module was loaded");
|
||||
|
||||
let { NetUtil } = ChromeUtils.import(NET_UTIL_URI, {});
|
||||
|
||||
// Avoids a gigantic stringification in the logs.
|
||||
Assert.ok(NetUtil === underlyingObject, "The module loaded is the same as the one directly obtained by ChromeUtils.import");
|
||||
|
||||
// Proxy correctly passed the setter to the underlying object.
|
||||
Assert.equal(NetUtil.foo, "bar", "Proxy correctly passed the setter to the underlying object");
|
||||
|
||||
delete lazyProxy.foo;
|
||||
|
||||
// Proxy correctly passed the delete operation to the underlying object.
|
||||
Assert.ok(!NetUtil.hasOwnProperty("foo"), "Proxy correctly passed the delete operation to the underlying object");
|
||||
});
|
@ -93,6 +93,7 @@ head = head_ongc.js
|
||||
[test_recursive_import.js]
|
||||
[test_xpcomutils.js]
|
||||
[test_unload.js]
|
||||
[test_lazyproxy.js]
|
||||
[test_attributes.js]
|
||||
[test_params.js]
|
||||
[test_tearoffs.js]
|
||||
|
@ -10197,10 +10197,10 @@ PaintTelemetry::AutoRecordPaint::~AutoRecordPaint()
|
||||
uint32_t amount = static_cast<int32_t>((aDurationMs / totalMs) * 100.0);
|
||||
Telemetry::Accumulate(Telemetry::CONTENT_LARGE_PAINT_PHASE_WEIGHT, aKey, amount);
|
||||
};
|
||||
auto recordSmall = [=](const nsString& aKey, double aDurationMs) -> void {
|
||||
auto recordSmall = [=](const nsCString& aKey, double aDurationMs) -> void {
|
||||
MOZ_ASSERT(aDurationMs <= totalMs);
|
||||
uint32_t amount = static_cast<int32_t>((aDurationMs / totalMs) * 100.0);
|
||||
Telemetry::ScalarAdd(Telemetry::ScalarID::GFX_SMALL_PAINT_PHASE_WEIGHT, aKey, amount);
|
||||
Telemetry::Accumulate(Telemetry::CONTENT_SMALL_PAINT_PHASE_WEIGHT, aKey, amount);
|
||||
};
|
||||
|
||||
double dlMs = sMetrics[Metric::DisplayList];
|
||||
@ -10214,9 +10214,9 @@ PaintTelemetry::AutoRecordPaint::~AutoRecordPaint()
|
||||
recordLarge(NS_LITERAL_CSTRING("flb"), flbMs);
|
||||
recordLarge(NS_LITERAL_CSTRING("r"), rMs);
|
||||
} else {
|
||||
recordSmall(NS_LITERAL_STRING("dl"), dlMs);
|
||||
recordSmall(NS_LITERAL_STRING("flb"), flbMs);
|
||||
recordSmall(NS_LITERAL_STRING("r"), rMs);
|
||||
recordSmall(NS_LITERAL_CSTRING("dl"), dlMs);
|
||||
recordSmall(NS_LITERAL_CSTRING("flb"), flbMs);
|
||||
recordSmall(NS_LITERAL_CSTRING("r"), rMs);
|
||||
}
|
||||
}
|
||||
|
||||
|
147
mfbt/Maybe.h
147
mfbt/Maybe.h
@ -315,11 +315,7 @@ public:
|
||||
bool isNothing() const { return !mIsSome; }
|
||||
|
||||
/* Returns the contents of this Maybe<T> by value. Unsafe unless |isSome()|. */
|
||||
T value() const
|
||||
{
|
||||
MOZ_ASSERT(mIsSome);
|
||||
return ref();
|
||||
}
|
||||
T value() const;
|
||||
|
||||
/*
|
||||
* Returns the contents of this Maybe<T> by value. If |isNothing()|, returns
|
||||
@ -348,17 +344,8 @@ public:
|
||||
}
|
||||
|
||||
/* Returns the contents of this Maybe<T> by pointer. Unsafe unless |isSome()|. */
|
||||
T* ptr()
|
||||
{
|
||||
MOZ_ASSERT(mIsSome);
|
||||
return &ref();
|
||||
}
|
||||
|
||||
const T* ptr() const
|
||||
{
|
||||
MOZ_ASSERT(mIsSome);
|
||||
return &ref();
|
||||
}
|
||||
T* ptr();
|
||||
const T* ptr() const;
|
||||
|
||||
/*
|
||||
* Returns the contents of this Maybe<T> by pointer. If |isNothing()|,
|
||||
@ -402,30 +389,12 @@ public:
|
||||
return aFunc();
|
||||
}
|
||||
|
||||
T* operator->()
|
||||
{
|
||||
MOZ_ASSERT(mIsSome);
|
||||
return ptr();
|
||||
}
|
||||
|
||||
const T* operator->() const
|
||||
{
|
||||
MOZ_ASSERT(mIsSome);
|
||||
return ptr();
|
||||
}
|
||||
T* operator->();
|
||||
const T* operator->() const;
|
||||
|
||||
/* Returns the contents of this Maybe<T> by ref. Unsafe unless |isSome()|. */
|
||||
T& ref()
|
||||
{
|
||||
MOZ_ASSERT(mIsSome);
|
||||
return *static_cast<T*>(data());
|
||||
}
|
||||
|
||||
const T& ref() const
|
||||
{
|
||||
MOZ_ASSERT(mIsSome);
|
||||
return *static_cast<const T*>(data());
|
||||
}
|
||||
T& ref();
|
||||
const T& ref() const;
|
||||
|
||||
/*
|
||||
* Returns the contents of this Maybe<T> by ref. If |isNothing()|, returns
|
||||
@ -469,17 +438,8 @@ public:
|
||||
return aFunc();
|
||||
}
|
||||
|
||||
T& operator*()
|
||||
{
|
||||
MOZ_ASSERT(mIsSome);
|
||||
return ref();
|
||||
}
|
||||
|
||||
const T& operator*() const
|
||||
{
|
||||
MOZ_ASSERT(mIsSome);
|
||||
return ref();
|
||||
}
|
||||
T& operator*();
|
||||
const T& operator*() const;
|
||||
|
||||
/* If |isSome()|, runs the provided function or functor on the contents of
|
||||
* this Maybe. */
|
||||
@ -544,12 +504,7 @@ public:
|
||||
* arguments to |emplace()| are the parameters to T's constructor.
|
||||
*/
|
||||
template<typename... Args>
|
||||
void emplace(Args&&... aArgs)
|
||||
{
|
||||
MOZ_ASSERT(!mIsSome);
|
||||
::new (KnownNotNull, data()) T(Forward<Args>(aArgs)...);
|
||||
mIsSome = true;
|
||||
}
|
||||
void emplace(Args&&... aArgs);
|
||||
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& aStream, const Maybe<T>& aMaybe)
|
||||
@ -563,6 +518,88 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
T
|
||||
Maybe<T>::value() const
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(mIsSome);
|
||||
return ref();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T*
|
||||
Maybe<T>::ptr()
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(mIsSome);
|
||||
return &ref();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const T*
|
||||
Maybe<T>::ptr() const
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(mIsSome);
|
||||
return &ref();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T*
|
||||
Maybe<T>::operator->()
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(mIsSome);
|
||||
return ptr();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const T*
|
||||
Maybe<T>::operator->() const
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(mIsSome);
|
||||
return ptr();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T&
|
||||
Maybe<T>::ref()
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(mIsSome);
|
||||
return *static_cast<T*>(data());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const T&
|
||||
Maybe<T>::ref() const
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(mIsSome);
|
||||
return *static_cast<const T*>(data());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T&
|
||||
Maybe<T>::operator*()
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(mIsSome);
|
||||
return ref();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const T&
|
||||
Maybe<T>::operator*() const
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(mIsSome);
|
||||
return ref();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename... Args>
|
||||
void
|
||||
Maybe<T>::emplace(Args&&... aArgs)
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(!mIsSome);
|
||||
::new (KnownNotNull, data()) T(Forward<Args>(aArgs)...);
|
||||
mIsSome = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Some() creates a Maybe<T> value containing the provided T value. If T has a
|
||||
* move constructor, it's used to make this as efficient as possible.
|
||||
|
@ -396,6 +396,9 @@ class NavigationDelegateTest : BaseSessionTest() {
|
||||
|
||||
@WithDevToolsAPI
|
||||
@Test fun onNewSession_calledForTargetBlankLink() {
|
||||
// Disable popup blocker.
|
||||
sessionRule.setPrefsUntilTestEnd(mapOf("dom.disable_open_during_load" to false))
|
||||
|
||||
sessionRule.session.loadTestPath(NEW_SESSION_HTML_PATH)
|
||||
sessionRule.session.waitForPageStop()
|
||||
|
||||
@ -433,6 +436,9 @@ class NavigationDelegateTest : BaseSessionTest() {
|
||||
|
||||
@WithDevToolsAPI
|
||||
@Test fun onNewSession_childShouldLoad() {
|
||||
// Disable popup blocker.
|
||||
sessionRule.setPrefsUntilTestEnd(mapOf("dom.disable_open_during_load" to false))
|
||||
|
||||
sessionRule.session.loadTestPath(NEW_SESSION_HTML_PATH)
|
||||
sessionRule.session.waitForPageStop()
|
||||
|
||||
@ -455,6 +461,9 @@ class NavigationDelegateTest : BaseSessionTest() {
|
||||
|
||||
@WithDevToolsAPI
|
||||
@Test fun onNewSession_setWindowOpener() {
|
||||
// Disable popup blocker.
|
||||
sessionRule.setPrefsUntilTestEnd(mapOf("dom.disable_open_during_load" to false))
|
||||
|
||||
sessionRule.session.loadTestPath(NEW_SESSION_HTML_PATH)
|
||||
sessionRule.session.waitForPageStop()
|
||||
|
||||
@ -469,6 +478,9 @@ class NavigationDelegateTest : BaseSessionTest() {
|
||||
|
||||
@WithDevToolsAPI
|
||||
@Test fun onNewSession_supportNoOpener() {
|
||||
// Disable popup blocker.
|
||||
sessionRule.setPrefsUntilTestEnd(mapOf("dom.disable_open_during_load" to false))
|
||||
|
||||
sessionRule.session.loadTestPath(NEW_SESSION_HTML_PATH)
|
||||
sessionRule.session.waitForPageStop()
|
||||
|
||||
@ -482,6 +494,9 @@ class NavigationDelegateTest : BaseSessionTest() {
|
||||
|
||||
@WithDevToolsAPI
|
||||
@Test fun onNewSession_notCalledForHandledLoads() {
|
||||
// Disable popup blocker.
|
||||
sessionRule.setPrefsUntilTestEnd(mapOf("dom.disable_open_during_load" to false))
|
||||
|
||||
sessionRule.session.loadTestPath(NEW_SESSION_HTML_PATH)
|
||||
sessionRule.session.waitForPageStop()
|
||||
|
||||
@ -514,6 +529,9 @@ class NavigationDelegateTest : BaseSessionTest() {
|
||||
@WithDevToolsAPI
|
||||
@Test(expected = IllegalArgumentException::class)
|
||||
fun onNewSession_doesNotAllowOpened() {
|
||||
// Disable popup blocker.
|
||||
sessionRule.setPrefsUntilTestEnd(mapOf("dom.disable_open_during_load" to false))
|
||||
|
||||
sessionRule.session.loadTestPath(NEW_SESSION_HTML_PATH)
|
||||
sessionRule.session.waitForPageStop()
|
||||
|
||||
|
@ -3103,11 +3103,6 @@ pref("plugins.navigator.hidden_ctp_plugin", "");
|
||||
// The default value for nsIPluginTag.enabledState (STATE_ENABLED = 2)
|
||||
pref("plugin.default.state", 2);
|
||||
|
||||
// The MIME type that should bind to legacy java-specific invocations like
|
||||
// <applet> and <object data="java:foo">. Setting this to a non-java MIME type
|
||||
// is undefined behavior.
|
||||
pref("plugin.java.mime", "application/x-java-vm");
|
||||
|
||||
// How long in minutes we will allow a plugin to work after the user has chosen
|
||||
// to allow it "now"
|
||||
pref("plugin.sessionPermissionNow.intervalInMinutes", 60);
|
||||
|
@ -154,6 +154,11 @@ public:
|
||||
return !!::FlushInstructionCache(::GetCurrentProcess(), nullptr, 0);
|
||||
}
|
||||
|
||||
static DWORD GetTrampWriteProtFlags()
|
||||
{
|
||||
return PAGE_EXECUTE_READWRITE;
|
||||
}
|
||||
|
||||
protected:
|
||||
uint8_t* GetLocalView() const
|
||||
{
|
||||
@ -370,6 +375,11 @@ public:
|
||||
return !!::FlushInstructionCache(mProcess, nullptr, 0);
|
||||
}
|
||||
|
||||
static DWORD GetTrampWriteProtFlags()
|
||||
{
|
||||
return PAGE_READWRITE;
|
||||
}
|
||||
|
||||
protected:
|
||||
uint8_t* GetLocalView() const
|
||||
{
|
||||
|
@ -30,7 +30,7 @@ public:
|
||||
, mMaxOffset(aChunkSize)
|
||||
, mAccumulatedStatus(true)
|
||||
{
|
||||
::VirtualProtect(aLocalBase, aChunkSize, PAGE_EXECUTE_READWRITE,
|
||||
::VirtualProtect(aLocalBase, aChunkSize, MMPolicy::GetTrampWriteProtFlags(),
|
||||
&mPrevLocalProt);
|
||||
}
|
||||
|
||||
|
@ -2706,32 +2706,6 @@ NS_LinkRedirectChannels(uint32_t channelId,
|
||||
_result);
|
||||
}
|
||||
|
||||
#define NS_FAKE_SCHEME "http://"
|
||||
#define NS_FAKE_TLD ".invalid"
|
||||
nsresult NS_MakeRandomInvalidURLString(nsCString &result)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIUUIDGenerator> uuidgen =
|
||||
do_GetService("@mozilla.org/uuid-generator;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsID idee;
|
||||
rv = uuidgen->GenerateUUIDInPlace(&idee);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
char chars[NSID_LENGTH];
|
||||
idee.ToProvidedString(chars);
|
||||
|
||||
result.AssignLiteral(NS_FAKE_SCHEME);
|
||||
// Strip off the '{' and '}' at the beginning and end of the UUID
|
||||
result.Append(chars + 1, NSID_LENGTH - 3);
|
||||
result.AppendLiteral(NS_FAKE_TLD);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
#undef NS_FAKE_SCHEME
|
||||
#undef NS_FAKE_TLD
|
||||
|
||||
nsresult NS_MaybeOpenChannelUsingOpen2(nsIChannel* aChannel,
|
||||
nsIInputStream **aStream)
|
||||
{
|
||||
@ -2752,64 +2726,6 @@ nsresult NS_MaybeOpenChannelUsingAsyncOpen2(nsIChannel* aChannel,
|
||||
return aChannel->AsyncOpen(aListener, nullptr);
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_CheckIsJavaCompatibleURLString(nsCString &urlString, bool *result)
|
||||
{
|
||||
*result = false; // Default to "no"
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsIURLParser> urlParser =
|
||||
do_GetService(NS_STDURLPARSER_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv) || !urlParser)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
bool compatible = true;
|
||||
uint32_t schemePos = 0;
|
||||
int32_t schemeLen = 0;
|
||||
urlParser->ParseURL(urlString.get(), -1, &schemePos, &schemeLen,
|
||||
nullptr, nullptr, nullptr, nullptr);
|
||||
if (schemeLen != -1) {
|
||||
nsCString scheme;
|
||||
scheme.Assign(urlString.get() + schemePos, schemeLen);
|
||||
// By default Java only understands a small number of URL schemes, and of
|
||||
// these only some can legitimately represent a browser page's "origin"
|
||||
// (and be something we can legitimately expect Java to handle ... or not
|
||||
// to mishandle).
|
||||
//
|
||||
// Besides those listed below, the OJI plugin understands the "jar",
|
||||
// "mailto", "netdoc", "javascript" and "rmi" schemes, and Java Plugin2
|
||||
// also understands the "about" scheme. We actually pass "about" URLs
|
||||
// to Java ("about:blank" when processing a javascript: URL (one that
|
||||
// calls Java) from the location bar of a blank page, and (in FF4 and up)
|
||||
// "about:home" when processing a javascript: URL from the home page).
|
||||
// And Java doesn't appear to mishandle them (for example it doesn't allow
|
||||
// connections to "about" URLs). But it doesn't make any sense to do
|
||||
// same-origin checks on "about" URLs, so we don't include them in our
|
||||
// scheme whitelist.
|
||||
//
|
||||
// The OJI plugin doesn't understand "chrome" URLs (only Java Plugin2
|
||||
// does) -- so we mustn't pass them to the OJI plugin. But we do need to
|
||||
// pass "chrome" URLs to Java Plugin2: Java Plugin2 grants additional
|
||||
// privileges to chrome "origins", and some extensions take advantage of
|
||||
// this. For more information see bug 620773.
|
||||
//
|
||||
// As of FF4, we no longer support the OJI plugin.
|
||||
if (PL_strcasecmp(scheme.get(), "http") &&
|
||||
PL_strcasecmp(scheme.get(), "https") &&
|
||||
PL_strcasecmp(scheme.get(), "file") &&
|
||||
PL_strcasecmp(scheme.get(), "ftp") &&
|
||||
PL_strcasecmp(scheme.get(), "gopher") &&
|
||||
PL_strcasecmp(scheme.get(), "chrome"))
|
||||
compatible = false;
|
||||
} else {
|
||||
compatible = false;
|
||||
}
|
||||
|
||||
*result = compatible;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/** Given the first (disposition) token from a Content-Disposition header,
|
||||
* tell whether it indicates the content is inline or attachment
|
||||
* @param aDispToken the disposition token from the content-disposition header
|
||||
|
@ -849,12 +849,6 @@ nsresult NS_LinkRedirectChannels(uint32_t channelId,
|
||||
nsIParentChannel *parentChannel,
|
||||
nsIChannel **_result);
|
||||
|
||||
/**
|
||||
* Helper function to create a random URL string that's properly formed
|
||||
* but guaranteed to be invalid.
|
||||
*/
|
||||
nsresult NS_MakeRandomInvalidURLString(nsCString &result);
|
||||
|
||||
/**
|
||||
* Helper function which checks whether the channel can be
|
||||
* openend using Open2() or has to fall back to opening
|
||||
@ -871,15 +865,6 @@ nsresult NS_MaybeOpenChannelUsingOpen2(nsIChannel* aChannel,
|
||||
nsresult NS_MaybeOpenChannelUsingAsyncOpen2(nsIChannel* aChannel,
|
||||
nsIStreamListener *aListener);
|
||||
|
||||
/**
|
||||
* Helper function to determine whether urlString is Java-compatible --
|
||||
* whether it can be passed to the Java URL(String) constructor without the
|
||||
* latter throwing a MalformedURLException, or without Java otherwise
|
||||
* mishandling it. This function (in effect) implements a scheme whitelist
|
||||
* for Java.
|
||||
*/
|
||||
nsresult NS_CheckIsJavaCompatibleURLString(nsCString& urlString, bool *result);
|
||||
|
||||
/** Given the first (disposition) token from a Content-Disposition header,
|
||||
* tell whether it indicates the content is inline or attachment
|
||||
* @param aDispToken the disposition token from the content-disposition header
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "nsIFile.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsURLHelper.h"
|
||||
#include "nsEscape.h"
|
||||
|
||||
@ -306,8 +307,11 @@ SubstitutingProtocolHandler::SetSubstitution(const nsACString& root, nsIURI *bas
|
||||
}
|
||||
|
||||
nsresult
|
||||
SubstitutingProtocolHandler::SetSubstitutionWithFlags(const nsACString& root, nsIURI *baseURI, uint32_t flags)
|
||||
SubstitutingProtocolHandler::SetSubstitutionWithFlags(const nsACString& origRoot, nsIURI *baseURI, uint32_t flags)
|
||||
{
|
||||
nsAutoCString root;
|
||||
ToLowerCase(origRoot, root);
|
||||
|
||||
if (!baseURI) {
|
||||
mSubstitutions.Remove(root);
|
||||
NotifyObservers(root, baseURI);
|
||||
@ -349,10 +353,13 @@ SubstitutingProtocolHandler::SetSubstitutionWithFlags(const nsACString& root, ns
|
||||
}
|
||||
|
||||
nsresult
|
||||
SubstitutingProtocolHandler::GetSubstitution(const nsACString& root, nsIURI **result)
|
||||
SubstitutingProtocolHandler::GetSubstitution(const nsACString& origRoot, nsIURI **result)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(result);
|
||||
|
||||
nsAutoCString root;
|
||||
ToLowerCase(origRoot, root);
|
||||
|
||||
SubstitutionEntry entry;
|
||||
if (mSubstitutions.Get(root, &entry)) {
|
||||
nsCOMPtr<nsIURI> baseURI = entry.baseURI;
|
||||
@ -367,6 +374,12 @@ SubstitutingProtocolHandler::GetSubstitution(const nsACString& root, nsIURI **re
|
||||
nsresult
|
||||
SubstitutingProtocolHandler::GetSubstitutionFlags(const nsACString& root, uint32_t* flags)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
nsAutoCString lcRoot;
|
||||
ToLowerCase(root, lcRoot);
|
||||
MOZ_ASSERT(root.Equals(lcRoot), "GetSubstitutionFlags should never receive mixed-case root name");
|
||||
#endif
|
||||
|
||||
*flags = 0;
|
||||
SubstitutionEntry entry;
|
||||
if (mSubstitutions.Get(root, &entry)) {
|
||||
@ -379,9 +392,13 @@ SubstitutingProtocolHandler::GetSubstitutionFlags(const nsACString& root, uint32
|
||||
}
|
||||
|
||||
nsresult
|
||||
SubstitutingProtocolHandler::HasSubstitution(const nsACString& root, bool *result)
|
||||
SubstitutingProtocolHandler::HasSubstitution(const nsACString& origRoot, bool *result)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(result);
|
||||
|
||||
nsAutoCString root;
|
||||
ToLowerCase(origRoot, root);
|
||||
|
||||
*result = HasSubstitution(root);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -25,8 +25,8 @@ interface nsISubstitutingProtocolHandler : nsIProtocolHandler
|
||||
*
|
||||
* A null baseURI removes the specified substitution.
|
||||
*
|
||||
* A root key should always be lowercase; however, this may not be
|
||||
* enforced.
|
||||
* The root key will be converted to lower-case to conform to
|
||||
* case-insensitive URI hostname matching behavior.
|
||||
*/
|
||||
[must_use] void setSubstitution(in ACString root, in nsIURI baseURI);
|
||||
|
||||
|
41
netwerk/test/unit/test_substituting_protocol_handler.js
Normal file
41
netwerk/test/unit/test_substituting_protocol_handler.js
Normal file
@ -0,0 +1,41 @@
|
||||
"use strict";
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
add_task(async function test_case_insensitive_substitutions() {
|
||||
let resProto = Services.io.getProtocolHandler("resource")
|
||||
.QueryInterface(Ci.nsISubstitutingProtocolHandler);
|
||||
|
||||
let uri = Services.io.newFileURI(do_get_file("data"));
|
||||
|
||||
resProto.setSubstitution("FooBar", uri);
|
||||
resProto.setSubstitutionWithFlags("BarBaz", uri, 0);
|
||||
|
||||
equal(resProto.resolveURI(Services.io.newURI("resource://foobar/")),
|
||||
uri.spec, "Got correct resolved URI for setSubstitution");
|
||||
|
||||
equal(resProto.resolveURI(Services.io.newURI("resource://foobar/")),
|
||||
uri.spec, "Got correct resolved URI for setSubstitutionWithFlags");
|
||||
|
||||
ok(resProto.hasSubstitution("foobar"), "hasSubstitution works with all-lower-case root");
|
||||
ok(resProto.hasSubstitution("FooBar"), "hasSubstitution works with mixed-case root");
|
||||
|
||||
equal(resProto.getSubstitution("foobar").spec, uri.spec,
|
||||
"getSubstitution works with all-lower-case root");
|
||||
equal(resProto.getSubstitution("FooBar").spec, uri.spec,
|
||||
"getSubstitution works with mixed-case root");
|
||||
|
||||
resProto.setSubstitution("foobar", null);
|
||||
resProto.setSubstitution("barbaz", null);
|
||||
|
||||
Assert.throws(() => resProto.resolveURI(Services.io.newURI("resource://foobar/")),
|
||||
e => e.result == Cr.NS_ERROR_NOT_AVAILABLE,
|
||||
"Correctly unregistered case-insensitive substitution in setSubstitution");
|
||||
Assert.throws(() => resProto.resolveURI(Services.io.newURI("resource://barbaz/")),
|
||||
e => e.result == Cr.NS_ERROR_NOT_AVAILABLE,
|
||||
"Correctly unregistered case-insensitive substitution in setSubstitutionWithFlags");
|
||||
|
||||
Assert.throws(() => resProto.getSubstitution("foobar"),
|
||||
e => e.result == Cr.NS_ERROR_NOT_AVAILABLE,
|
||||
"foobar substitution has been removed");
|
||||
});
|
@ -421,3 +421,4 @@ run-sequentially = node server exceptions dont replay well
|
||||
# http2-using tests require node available
|
||||
skip-if = os == "android"
|
||||
[test_ioservice.js]
|
||||
[test_substituting_protocol_handler.js]
|
||||
|
@ -6,7 +6,7 @@ loader: taskgraph.loader.transform:loader
|
||||
|
||||
transforms:
|
||||
- taskgraph.transforms.release_deps:transforms
|
||||
- taskgraph.transforms.beetmover_cdns:transforms
|
||||
- taskgraph.transforms.beetmover_push_to_release:transforms
|
||||
- taskgraph.transforms.task:transforms
|
||||
|
||||
kind-dependencies:
|
||||
@ -17,20 +17,20 @@ job-defaults:
|
||||
shipping-phase: push
|
||||
|
||||
jobs:
|
||||
fennec-push-to-cdns:
|
||||
name: fennec_push_to_cdns
|
||||
fennec-push-to-release:
|
||||
name: fennec_push_to_release
|
||||
product: fennec
|
||||
shipping-product: fennec
|
||||
treeherder-platform: Android/opt
|
||||
treeherder-platform: fennec-release/opt
|
||||
|
||||
devedition-push-to-cdns:
|
||||
name: devedition_push_to_cdns
|
||||
devedition-push-to-release:
|
||||
name: devedition_push_to_release
|
||||
product: devedition
|
||||
shipping-product: devedition
|
||||
treeherder-platform: Linux64-devedition/opt
|
||||
treeherder-platform: devedition-release/opt
|
||||
|
||||
firefox-push-to-cdns:
|
||||
name: firefox_push_to_cdns
|
||||
firefox-push-to-release:
|
||||
name: firefox_push_to_release
|
||||
product: firefox
|
||||
shipping-product: firefox
|
||||
treeherder-platform: Linux64/opt
|
||||
treeherder-platform: firefox-release/opt
|
@ -5,7 +5,7 @@
|
||||
loader: taskgraph.loader.transform:loader
|
||||
|
||||
kind-dependencies:
|
||||
- beetmover-cdns
|
||||
- release-beetmover-push-to-release
|
||||
|
||||
transforms:
|
||||
- taskgraph.transforms.release_deps:transforms
|
||||
|
@ -10,7 +10,7 @@ transforms:
|
||||
- taskgraph.transforms.task:transforms
|
||||
|
||||
kind-dependencies:
|
||||
- beetmover-cdns
|
||||
- release-beetmover-push-to-release
|
||||
|
||||
job-defaults:
|
||||
name: notify-release-drivers-push
|
||||
|
@ -10,7 +10,7 @@ transforms:
|
||||
- taskgraph.transforms.task:transforms
|
||||
|
||||
kind-dependencies:
|
||||
- beetmover-cdns
|
||||
- release-beetmover-push-to-release
|
||||
|
||||
job-defaults:
|
||||
description: Release Promotion version bump/tag
|
||||
|
@ -195,10 +195,11 @@ Beetmover-repackage is beetmover but for tasks that need an intermediate step
|
||||
between signing and packaging, such as OSX. For more details see the definitions
|
||||
of the Beetmover kind above and the repackage kind below.
|
||||
|
||||
beetmover-cdns
|
||||
-------------------
|
||||
release-beetmover-push-to-release
|
||||
---------------------------------
|
||||
|
||||
Beetmover-cdns publishes promoted releases to CDNs. This is part of release promotion.
|
||||
Beetmover-cdns publishes promoted releases from the candidates directory to the
|
||||
release directory. This is part of release promotion.
|
||||
|
||||
beetmover-source
|
||||
-------------------
|
||||
|
@ -356,6 +356,9 @@ def release_promotion_action(parameters, graph_config, input, task_group_id, tas
|
||||
parameters['release_enable_partners'] = release_enable_partners
|
||||
parameters['release_partners'] = input.get('release_partners')
|
||||
parameters['release_enable_emefree'] = release_enable_emefree
|
||||
# When doing staging releases on try, we still want to re-use tasks from
|
||||
# previous graphs.
|
||||
parameters['optimize_target_tasks'] = True
|
||||
|
||||
partner_config = input.get('release_partner_config')
|
||||
if not partner_config and (release_enable_emefree or release_enable_partners):
|
||||
|
@ -2,7 +2,7 @@
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
"""
|
||||
Transform the beetmover-cdns task into a task description.
|
||||
Transform the beetmover-push-to-release task into a task description.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
@ -30,7 +30,7 @@ taskref_or_string = Any(
|
||||
basestring,
|
||||
{Required('task-reference'): basestring})
|
||||
|
||||
beetmover_cdns_description_schema = Schema({
|
||||
beetmover_push_to_release_description_schema = Schema({
|
||||
Required('name'): basestring,
|
||||
Required('product'): basestring,
|
||||
Required('treeherder-platform'): basestring,
|
||||
@ -52,13 +52,13 @@ def validate(config, jobs):
|
||||
for job in jobs:
|
||||
label = job['name']
|
||||
validate_schema(
|
||||
beetmover_cdns_description_schema, job,
|
||||
"In cdns-signing ({!r} kind) task for {!r}:".format(config.kind, label))
|
||||
beetmover_push_to_release_description_schema, job,
|
||||
"In beetmover-push-to-release ({!r} kind) task for {!r}:".format(config.kind, label))
|
||||
yield job
|
||||
|
||||
|
||||
@transforms.add
|
||||
def make_beetmover_cdns_description(config, jobs):
|
||||
def make_beetmover_push_to_release_description(config, jobs):
|
||||
for job in jobs:
|
||||
treeherder = job.get('treeherder', {})
|
||||
treeherder.setdefault('symbol', 'Rel(BM-C)')
|
||||
@ -68,7 +68,7 @@ def make_beetmover_cdns_description(config, jobs):
|
||||
|
||||
label = job['name']
|
||||
description = (
|
||||
"Beetmover push to cdns for '{product}'".format(
|
||||
"Beetmover push to release for '{product}'".format(
|
||||
product=job['product']
|
||||
)
|
||||
)
|
||||
@ -96,10 +96,10 @@ def make_beetmover_cdns_description(config, jobs):
|
||||
|
||||
|
||||
@transforms.add
|
||||
def make_beetmover_cdns_worker(config, jobs):
|
||||
def make_beetmover_push_to_release_worker(config, jobs):
|
||||
for job in jobs:
|
||||
worker = {
|
||||
'implementation': 'beetmover-cdns',
|
||||
'implementation': 'beetmover-push-to-release',
|
||||
'product': job['product'],
|
||||
}
|
||||
job["worker"] = worker
|
@ -13,6 +13,7 @@ from taskgraph.util.schema import validate_schema, Schema
|
||||
from taskgraph.util.scriptworker import (
|
||||
get_signing_cert_scope,
|
||||
get_worker_type_for_scope,
|
||||
add_scope_prefix,
|
||||
)
|
||||
from taskgraph.transforms.task import task_description_schema
|
||||
from voluptuous import Any, Required, Optional
|
||||
@ -98,7 +99,7 @@ def make_checksums_signing_description(config, jobs):
|
||||
'max-run-time': 3600},
|
||||
'scopes': [
|
||||
signing_cert_scope,
|
||||
"project:releng:signing:format:gpg"
|
||||
add_scope_prefix(config, 'signing:format:gpg'),
|
||||
],
|
||||
'dependencies': dependencies,
|
||||
'attributes': attributes,
|
||||
|
@ -13,6 +13,7 @@ from taskgraph.util.schema import validate_schema, Schema
|
||||
from taskgraph.util.scriptworker import (
|
||||
get_signing_cert_scope,
|
||||
get_worker_type_for_scope,
|
||||
add_scope_prefix,
|
||||
)
|
||||
from taskgraph.util.taskcluster import get_artifact_path
|
||||
from taskgraph.transforms.task import task_description_schema
|
||||
@ -88,7 +89,7 @@ def make_release_generate_checksums_signing_description(config, jobs):
|
||||
'max-run-time': 3600},
|
||||
'scopes': [
|
||||
signing_cert_scope,
|
||||
"project:releng:signing:format:gpg"
|
||||
add_scope_prefix(config, 'signing:format:gpg'),
|
||||
],
|
||||
'dependencies': dependencies,
|
||||
'attributes': attributes,
|
||||
|
@ -13,6 +13,7 @@ from taskgraph.util.schema import validate_schema, Schema
|
||||
from taskgraph.util.scriptworker import (
|
||||
get_signing_cert_scope,
|
||||
get_worker_type_for_scope,
|
||||
add_scope_prefix,
|
||||
)
|
||||
from taskgraph.transforms.task import task_description_schema
|
||||
from voluptuous import Any, Required, Optional
|
||||
@ -88,7 +89,7 @@ def make_checksums_signing_description(config, jobs):
|
||||
'max-run-time': 3600},
|
||||
'scopes': [
|
||||
signing_cert_scope,
|
||||
"project:releng:signing:format:gpg"
|
||||
add_scope_prefix(config, 'signing:format:gpg'),
|
||||
],
|
||||
'dependencies': dependencies,
|
||||
'attributes': attributes,
|
||||
|
@ -465,7 +465,7 @@ task_description_schema = Schema({
|
||||
Required('locale'): basestring,
|
||||
}],
|
||||
}, {
|
||||
Required('implementation'): 'beetmover-cdns',
|
||||
Required('implementation'): 'beetmover-push-to-release',
|
||||
|
||||
# the maximum time to run, in seconds
|
||||
Required('max-run-time'): int,
|
||||
@ -998,8 +998,8 @@ def build_beetmover_payload(config, task, task_def):
|
||||
task_def['payload'].update(release_config)
|
||||
|
||||
|
||||
@payload_builder('beetmover-cdns')
|
||||
def build_beetmover_cdns_payload(config, task, task_def):
|
||||
@payload_builder('beetmover-push-to-release')
|
||||
def build_beetmover_push_to_release_payload(config, task, task_def):
|
||||
worker = task['worker']
|
||||
release_config = get_release_config(config)
|
||||
|
||||
@ -1219,7 +1219,7 @@ def set_defaults(config, tasks):
|
||||
worker.setdefault('max-run-time', 600)
|
||||
elif worker['implementation'] == 'beetmover':
|
||||
worker.setdefault('max-run-time', 600)
|
||||
elif worker['implementation'] == 'beetmover-cdns':
|
||||
elif worker['implementation'] == 'beetmover-push-to-release':
|
||||
worker.setdefault('max-run-time', 600)
|
||||
elif worker['implementation'] == 'push-apk':
|
||||
worker.setdefault('commit', False)
|
||||
|
@ -3988,14 +3988,6 @@
|
||||
"n_buckets": 10,
|
||||
"description": "Time spent scanning filesystem for plugins (ms)"
|
||||
},
|
||||
"CHECK_JAVA_ENABLED": {
|
||||
"record_in_processes": ["main", "content"],
|
||||
"expires_in_version": "default",
|
||||
"kind": "exponential",
|
||||
"high": 3000,
|
||||
"n_buckets": 10,
|
||||
"description": "Time spent checking if Java is enabled (ms)"
|
||||
},
|
||||
"PLUGIN_HANG_UI_USER_RESPONSE": {
|
||||
"record_in_processes": ["main", "content"],
|
||||
"expires_in_version": "never",
|
||||
@ -12987,6 +12979,17 @@
|
||||
"n_buckets": 10,
|
||||
"description": "Percentage of time taken by phases in expensive content paints."
|
||||
},
|
||||
"CONTENT_SMALL_PAINT_PHASE_WEIGHT": {
|
||||
"record_in_processes": ["main", "content"],
|
||||
"alert_emails": ["mwoodrow@mozilla.com","gfx-telemetry-alerts@mozilla.com"],
|
||||
"bug_numbers": [1430897],
|
||||
"expires_in_version": "66",
|
||||
"keyed": true,
|
||||
"kind": "linear",
|
||||
"high": 100,
|
||||
"n_buckets": 10,
|
||||
"description": "Percentage of time taken by phases in normal content paints."
|
||||
},
|
||||
"NARRATE_CONTENT_BY_LANGUAGE_2": {
|
||||
"record_in_processes": ["main", "content"],
|
||||
"alert_emails": ["eisaacson@mozilla.com"],
|
||||
|
@ -1318,24 +1318,6 @@ gfx.omtp:
|
||||
record_in_processes:
|
||||
- 'content'
|
||||
|
||||
gfx:
|
||||
small_paint_phase_weight:
|
||||
bug_numbers:
|
||||
- 1430897
|
||||
description: >
|
||||
Time that is spent in each phase of painting, as a percentage of
|
||||
paint time. See also CONTENT_LARGE_PAINT_PHASE_WEIGHT in Histograms.json.
|
||||
Keys are r (rasterization), dl (display list construction), and flb
|
||||
(FrameLayerBuilder).
|
||||
keyed: true
|
||||
kind: uint
|
||||
expires: "66"
|
||||
notification_emails:
|
||||
- gfx-telemetry-alerts@mozilla.com
|
||||
- mwoodrow@mozilla.com
|
||||
record_in_processes:
|
||||
- 'content'
|
||||
|
||||
# The following section contains the form autofill related scalars.
|
||||
formautofill:
|
||||
availability:
|
||||
|
@ -94,7 +94,6 @@
|
||||
"CHARSET_OVERRIDE_SITUATION",
|
||||
"CHARSET_OVERRIDE_USED",
|
||||
"CHECK_ADDONS_MODIFIED_MS",
|
||||
"CHECK_JAVA_ENABLED",
|
||||
"COMPONENTS_SHIM_ACCESSED_BY_CONTENT",
|
||||
"COMPOSITE_FRAME_ROUNDTRIP_TIME",
|
||||
"COMPOSITE_TIME",
|
||||
@ -601,7 +600,6 @@
|
||||
"CHARSET_OVERRIDE_SITUATION",
|
||||
"CHARSET_OVERRIDE_USED",
|
||||
"CHECK_ADDONS_MODIFIED_MS",
|
||||
"CHECK_JAVA_ENABLED",
|
||||
"COMPONENTS_SHIM_ACCESSED_BY_CONTENT",
|
||||
"COMPOSITE_FRAME_ROUNDTRIP_TIME",
|
||||
"COMPOSITE_TIME",
|
||||
@ -1435,7 +1433,6 @@
|
||||
"PDF_VIEWER_TIME_TO_VIEW_MS",
|
||||
"SSL_OCSP_MAY_FETCH",
|
||||
"MOZ_SQLITE_OTHER_READ_B",
|
||||
"CHECK_JAVA_ENABLED",
|
||||
"TRANSLATION_OPPORTUNITIES",
|
||||
"NEWTAB_PAGE_BLOCKED_SITES_COUNT",
|
||||
"FX_SESSION_RESTORE_NUMBER_OF_TABS_RESTORED",
|
||||
|
@ -2471,6 +2471,7 @@ this.XPIDatabaseReconcile = {
|
||||
let isDetectedInstall = isNewInstall && !aNewAddon;
|
||||
|
||||
// Load the manifest if necessary and sanity check the add-on ID
|
||||
let unsigned;
|
||||
try {
|
||||
if (!aNewAddon) {
|
||||
// Load the manifest from the add-on.
|
||||
@ -2482,6 +2483,11 @@ this.XPIDatabaseReconcile = {
|
||||
throw new Error("Invalid addon ID: expected addon ID " + aId +
|
||||
", found " + aNewAddon.id + " in manifest");
|
||||
}
|
||||
|
||||
unsigned = XPIDatabase.mustSign(aNewAddon.type) && !aNewAddon.isCorrectlySigned;
|
||||
if (unsigned) {
|
||||
throw Error(`Extension ${aNewAddon.id} is not correctly signed`);
|
||||
}
|
||||
} catch (e) {
|
||||
logger.warn("addMetadata: Add-on " + aId + " is invalid", e);
|
||||
|
||||
@ -2491,6 +2497,8 @@ this.XPIDatabaseReconcile = {
|
||||
logger.warn("Not uninstalling invalid item because it is a proxy file");
|
||||
else if (aInstallLocation.locked)
|
||||
logger.warn("Could not uninstall invalid item from locked install location");
|
||||
else if (unsigned && !isNewInstall)
|
||||
logger.warn("Not uninstalling existing unsigned add-on");
|
||||
else
|
||||
aInstallLocation.uninstallAddon(aId);
|
||||
return null;
|
||||
|
@ -1 +0,0 @@
|
||||
ChromeUtils.import("resource://xpcshell-data/BootstrapMonitor.jsm").monitor(this);
|
@ -23,7 +23,5 @@ add_task(async function() {
|
||||
await XPIProvider.verifySignatures();
|
||||
|
||||
let addon = await AddonManager.getAddonByID(ID);
|
||||
Assert.equal(addon.signedState, AddonManager.SIGNEDSTATE_MISSING);
|
||||
Assert.ok(!addon.isActive);
|
||||
Assert.ok(addon.appDisabled);
|
||||
Assert.equal(addon, null, "Unsigned extensions should not be installed at startup");
|
||||
});
|
||||
|
@ -76,6 +76,10 @@ function promiseWriteRelativePointer(aId, aName) {
|
||||
add_task(async function setup() {
|
||||
ok(TEST_UNPACKED, "Pointer files only work with unpacked directories");
|
||||
|
||||
// Unpacked extensions are never signed, so this can only run with
|
||||
// signature checks disabled.
|
||||
Services.prefs.setBoolPref(PREF_XPI_SIGNATURES_REQUIRED, false);
|
||||
|
||||
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1");
|
||||
});
|
||||
|
||||
|
@ -73,6 +73,10 @@ profileDir.append("extensions");
|
||||
function run_test() {
|
||||
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "2", "2");
|
||||
|
||||
// Unpacked extensions are never signed, so this can only run with
|
||||
// signature checks disabled.
|
||||
Services.prefs.setBoolPref(PREF_XPI_SIGNATURES_REQUIRED, false);
|
||||
|
||||
add_task(run_proxy_tests);
|
||||
|
||||
if (gHaveSymlinks)
|
||||
|
@ -8,6 +8,8 @@ createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "42");
|
||||
|
||||
BootstrapMonitor.init();
|
||||
|
||||
const BOOTSTRAP_JS = `ChromeUtils.import("resource://xpcshell-data/BootstrapMonitor.jsm").monitor(this);`;
|
||||
|
||||
// Ensure that a proxy file to an add-on with a valid manifest works.
|
||||
add_task(async function() {
|
||||
Services.prefs.setBoolPref(PREF_XPI_SIGNATURES_REQUIRED, false);
|
||||
@ -15,23 +17,20 @@ add_task(async function() {
|
||||
await promiseStartupManager();
|
||||
|
||||
let tempdir = gTmpD.clone();
|
||||
await promiseWriteInstallRDFToDir({
|
||||
let unpackedAddon = await promiseWriteInstallRDFToDir({
|
||||
id: ID,
|
||||
version: "1.0",
|
||||
bootstrap: true,
|
||||
unpack: true,
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "1",
|
||||
maxVersion: "1"
|
||||
}],
|
||||
}],
|
||||
name: "Test Bootstrap 1 (proxy)",
|
||||
}, tempdir, ID, "bootstrap.js");
|
||||
|
||||
let unpackedAddon = tempdir.clone();
|
||||
unpackedAddon.append(ID);
|
||||
do_get_file("data/test_proxy/bootstrap.js")
|
||||
.copyTo(unpackedAddon, "bootstrap.js");
|
||||
}, tempdir, ID, {
|
||||
"bootstrap.js": BOOTSTRAP_JS,
|
||||
});
|
||||
|
||||
// create proxy file in profile/extensions dir
|
||||
let extensionsDir = gProfD.clone();
|
||||
@ -40,23 +39,30 @@ add_task(async function() {
|
||||
|
||||
await promiseRestartManager();
|
||||
|
||||
BootstrapMonitor.checkAddonInstalled(ID, "1.0");
|
||||
BootstrapMonitor.checkAddonStarted(ID, "1.0");
|
||||
|
||||
let addon = await promiseAddonByID(ID);
|
||||
|
||||
Assert.notEqual(addon, null);
|
||||
Assert.equal(addon.version, "1.0");
|
||||
Assert.equal(addon.name, "Test Bootstrap 1 (proxy)");
|
||||
Assert.ok(addon.isCompatible);
|
||||
Assert.ok(!addon.appDisabled);
|
||||
Assert.ok(addon.isActive);
|
||||
Assert.equal(addon.type, "extension");
|
||||
Assert.equal(addon.signedState, mozinfo.addon_signing ? AddonManager.SIGNEDSTATE_UNKNOWN : AddonManager.SIGNEDSTATE_NOT_REQUIRED);
|
||||
if (AppConstants.MOZ_REQUIRE_SIGNING) {
|
||||
BootstrapMonitor.checkAddonNotInstalled(ID, "1.0");
|
||||
BootstrapMonitor.checkAddonNotStarted(ID, "1.0");
|
||||
|
||||
Assert.ok(proxyFile.exists());
|
||||
Assert.equal(addon, null);
|
||||
} else {
|
||||
BootstrapMonitor.checkAddonInstalled(ID, "1.0");
|
||||
BootstrapMonitor.checkAddonStarted(ID, "1.0");
|
||||
|
||||
addon.uninstall();
|
||||
Assert.notEqual(addon, null);
|
||||
Assert.equal(addon.version, "1.0");
|
||||
Assert.equal(addon.name, "Test Bootstrap 1 (proxy)");
|
||||
Assert.ok(addon.isCompatible);
|
||||
Assert.ok(!addon.appDisabled);
|
||||
Assert.ok(addon.isActive);
|
||||
Assert.equal(addon.type, "extension");
|
||||
Assert.equal(addon.signedState, mozinfo.addon_signing ? AddonManager.SIGNEDSTATE_UNKNOWN : AddonManager.SIGNEDSTATE_NOT_REQUIRED);
|
||||
|
||||
Assert.ok(proxyFile.exists());
|
||||
|
||||
addon.uninstall();
|
||||
}
|
||||
unpackedAddon.remove(true);
|
||||
|
||||
await promiseRestartManager();
|
||||
@ -69,23 +75,20 @@ add_task(async function() {
|
||||
let tempdir = gTmpD.clone();
|
||||
|
||||
// use a mismatched ID to make this install.rdf invalid
|
||||
await promiseWriteInstallRDFToDir({
|
||||
let unpackedAddon = await promiseWriteInstallRDFToDir({
|
||||
id: "bad-proxy1@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
bootstrap: true,
|
||||
unpack: true,
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "1",
|
||||
maxVersion: "1"
|
||||
}],
|
||||
}],
|
||||
name: "Test Bootstrap 1 (proxy)",
|
||||
}, tempdir, ID, "bootstrap.js");
|
||||
|
||||
let unpackedAddon = tempdir.clone();
|
||||
unpackedAddon.append(ID);
|
||||
do_get_file("data/test_proxy/bootstrap.js")
|
||||
.copyTo(unpackedAddon, "bootstrap.js");
|
||||
}, tempdir, ID, {
|
||||
"bootstrap.js": BOOTSTRAP_JS,
|
||||
});
|
||||
|
||||
// create proxy file in profile/extensions dir
|
||||
let extensionsDir = gProfD.clone();
|
||||
|
@ -90,68 +90,6 @@ function verify_no_change([startFile, startState], [endFile, endState]) {
|
||||
});
|
||||
}
|
||||
|
||||
function verify_enables([startFile, startState], [endFile, endState]) {
|
||||
add_task(async function() {
|
||||
info("A switch from " + startFile + " to " + endFile + " should enable the add-on.");
|
||||
|
||||
// Install the first add-on
|
||||
await manuallyInstall(do_get_file(DATA + startFile), profileDir, ID);
|
||||
await promiseStartupManager();
|
||||
|
||||
let addon = await promiseAddonByID(ID);
|
||||
Assert.notEqual(addon, null);
|
||||
Assert.ok(!addon.isActive);
|
||||
Assert.equal(addon.pendingOperations, AddonManager.PENDING_NONE);
|
||||
Assert.equal(addon.signedState, startState);
|
||||
|
||||
// Swap in the files from the next add-on
|
||||
manuallyUninstall(profileDir, ID);
|
||||
await manuallyInstall(do_get_file(DATA + endFile), profileDir, ID);
|
||||
|
||||
let needsRestart = hasFlag(addon.operationsRequiringRestart, AddonManager.OP_NEEDS_RESTART_ENABLE);
|
||||
info(needsRestart);
|
||||
|
||||
let events = {};
|
||||
if (!needsRestart) {
|
||||
events[ID] = [
|
||||
["onPropertyChanged", ["appDisabled"]],
|
||||
["onEnabling", false],
|
||||
"onEnabled"
|
||||
];
|
||||
} else {
|
||||
events[ID] = [
|
||||
["onPropertyChanged", ["appDisabled"]],
|
||||
"onEnabling"
|
||||
];
|
||||
}
|
||||
|
||||
if (startState != endState)
|
||||
events[ID].unshift(["onPropertyChanged", ["signedState"]]);
|
||||
|
||||
prepare_test(events);
|
||||
|
||||
// Trigger the check
|
||||
let changes = await verifySignatures();
|
||||
Assert.equal(changes.enabled.length, 1);
|
||||
Assert.equal(changes.enabled[0], ID);
|
||||
Assert.equal(changes.disabled.length, 0);
|
||||
|
||||
Assert.ok(!addon.appDisabled);
|
||||
if (needsRestart)
|
||||
Assert.notEqual(addon.pendingOperations, AddonManager.PENDING_NONE);
|
||||
else
|
||||
Assert.ok(addon.isActive);
|
||||
Assert.equal(addon.signedState, endState);
|
||||
|
||||
ensure_test_completed();
|
||||
|
||||
// Remove the add-on and restart to let it go away
|
||||
manuallyUninstall(profileDir, ID);
|
||||
await promiseRestartManager();
|
||||
await promiseShutdownManager();
|
||||
});
|
||||
}
|
||||
|
||||
function verify_disables([startFile, startState], [endFile, endState]) {
|
||||
add_task(async function() {
|
||||
info("A switch from " + startFile + " to " + endFile + " should disable the add-on.");
|
||||
@ -219,20 +157,8 @@ for (let start of GOOD) {
|
||||
}
|
||||
}
|
||||
|
||||
for (let start of BAD) {
|
||||
for (let end of GOOD) {
|
||||
verify_enables(start, end);
|
||||
}
|
||||
}
|
||||
|
||||
for (let start of GOOD) {
|
||||
for (let end of GOOD.filter(f => f != start)) {
|
||||
verify_no_change(start, end);
|
||||
}
|
||||
}
|
||||
|
||||
for (let start of BAD) {
|
||||
for (let end of BAD.filter(f => f != start)) {
|
||||
verify_no_change(start, end);
|
||||
}
|
||||
}
|
||||
|
@ -172,6 +172,14 @@ add_task(async function() {
|
||||
|
||||
let target;
|
||||
if (!packed) {
|
||||
// Unpacked extensions don't support signing, which means that
|
||||
// our mock signing service is not able to give them a
|
||||
// privileged signed state, and we can't install them on release
|
||||
// builds.
|
||||
if (!AppConstants.MOZ_ALLOW_LEGACY_EXTENSIONS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
target = tempdir.clone();
|
||||
target.append(ID);
|
||||
|
||||
@ -362,6 +370,11 @@ add_task(async function test_samefile() {
|
||||
// Install a temporary add-on over the top of an existing add-on.
|
||||
// Uninstall it and make sure the existing add-on comes back.
|
||||
add_task(async function() {
|
||||
// We can't install unpacked add-ons on release builds. See above.
|
||||
if (!AppConstants.MOZ_ALLOW_LEGACY_EXTENSIONS) {
|
||||
return;
|
||||
}
|
||||
|
||||
await promiseInstallAllFiles([do_get_addon("test_bootstrap1_1")], true);
|
||||
|
||||
BootstrapMonitor.checkAddonInstalled(ID, "1.0");
|
||||
@ -464,6 +477,11 @@ add_task(async function() {
|
||||
// Install a temporary add-on as a version upgrade over the top of an
|
||||
// existing temporary add-on.
|
||||
add_task(async function() {
|
||||
// We can't install unpacked add-ons on release builds. See above.
|
||||
if (!AppConstants.MOZ_ALLOW_LEGACY_EXTENSIONS) {
|
||||
return;
|
||||
}
|
||||
|
||||
const tempdir = gTmpD.clone();
|
||||
|
||||
await promiseWriteInstallRDFToDir(sampleRDFManifest, tempdir, "bootstrap1@tests.mozilla.org", "bootstrap.js");
|
||||
@ -515,6 +533,11 @@ add_task(async function() {
|
||||
// Install a temporary add-on as a version downgrade over the top of an
|
||||
// existing temporary add-on.
|
||||
add_task(async function() {
|
||||
// We can't install unpacked add-ons on release builds. See above.
|
||||
if (!AppConstants.MOZ_ALLOW_LEGACY_EXTENSIONS) {
|
||||
return;
|
||||
}
|
||||
|
||||
const tempdir = gTmpD.clone();
|
||||
|
||||
await promiseWriteInstallRDFToDir(sampleRDFManifest, tempdir, "bootstrap1@tests.mozilla.org", "bootstrap.js");
|
||||
@ -564,6 +587,11 @@ add_task(async function() {
|
||||
// Installing a temporary add-on over an existing add-on with the same
|
||||
// version number should be installed as an upgrade.
|
||||
add_task(async function() {
|
||||
// We can't install unpacked add-ons on release builds. See above.
|
||||
if (!AppConstants.MOZ_ALLOW_LEGACY_EXTENSIONS) {
|
||||
return;
|
||||
}
|
||||
|
||||
const tempdir = gTmpD.clone();
|
||||
|
||||
await promiseWriteInstallRDFToDir(sampleRDFManifest, tempdir, "bootstrap1@tests.mozilla.org", "bootstrap.js");
|
||||
@ -621,6 +649,11 @@ add_task(async function() {
|
||||
// Install a temporary add-on over the top of an existing disabled add-on.
|
||||
// After restart, the existing add-on should continue to be installed and disabled.
|
||||
add_task(async function() {
|
||||
// We can't install unpacked add-ons on release builds. See above.
|
||||
if (!AppConstants.MOZ_ALLOW_LEGACY_EXTENSIONS) {
|
||||
return;
|
||||
}
|
||||
|
||||
await promiseInstallAllFiles([do_get_addon("test_bootstrap1_1")], true);
|
||||
|
||||
BootstrapMonitor.checkAddonInstalled(ID, "1.0");
|
||||
|
@ -10,3 +10,4 @@ tags = addons
|
||||
tags = webextensions
|
||||
|
||||
[test_filepointer.js]
|
||||
skip-if = !allow_legacy_extensions || require_signing
|
||||
|
Loading…
Reference in New Issue
Block a user