mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-27 21:00:50 +00:00
merge m-c to fx-team
This commit is contained in:
commit
19c35e17d3
@ -203,7 +203,7 @@ pref("app.update.incompatible.mode", 0);
|
||||
// .. etc ..
|
||||
//
|
||||
pref("extensions.update.enabled", true);
|
||||
pref("extensions.update.url", "https://versioncheck.addons.mozilla.org/update/VersionCheck.php?reqVersion=%REQ_VERSION%&id=%ITEM_ID%&version=%ITEM_VERSION%&maxAppVersion=%ITEM_MAXAPPVERSION%&status=%ITEM_STATUS%&appID=%APP_ID%&appVersion=%APP_VERSION%&appOS=%APP_OS%&appABI=%APP_ABI%&locale=%APP_LOCALE%¤tAppVersion=%CURRENT_APP_VERSION%&updateType=%UPDATE_TYPE%");
|
||||
pref("extensions.update.url", "https://versioncheck.addons.mozilla.org/update/VersionCheck.php?reqVersion=%REQ_VERSION%&id=%ITEM_ID%&version=%ITEM_VERSION%&maxAppVersion=%ITEM_MAXAPPVERSION%&status=%ITEM_STATUS%&appID=%APP_ID%&appVersion=%APP_VERSION%&appOS=%APP_OS%&appABI=%APP_ABI%&locale=%APP_LOCALE%¤tAppVersion=%CURRENT_APP_VERSION%&updateType=%UPDATE_TYPE%&compatMode=%COMPATIBILITY_MODE%");
|
||||
pref("extensions.update.interval", 86400); // Check for updates to Extensions and
|
||||
// Themes every day
|
||||
// Non-symmetric (not shared by extensions) extension-specific [update] preferences
|
||||
|
@ -208,6 +208,7 @@ let TabView = {
|
||||
this._iframe = document.createElement("iframe");
|
||||
this._iframe.id = "tab-view";
|
||||
this._iframe.setAttribute("transparent", "true");
|
||||
this._iframe.setAttribute("tooltip", "tab-view-tooltip");
|
||||
this._iframe.flex = 1;
|
||||
|
||||
let self = this;
|
||||
@ -235,6 +236,12 @@ let TabView = {
|
||||
|
||||
this._iframe.setAttribute("src", "chrome://browser/content/tabview.html");
|
||||
this._deck.appendChild(this._iframe);
|
||||
|
||||
// ___ create tooltip
|
||||
let tooltip = document.createElement("tooltip");
|
||||
tooltip.id = "tab-view-tooltip";
|
||||
tooltip.setAttribute("onpopupshowing", "return TabView.fillInTooltip(document.tooltipNode);");
|
||||
document.getElementById("mainPopupSet").appendChild(tooltip);
|
||||
},
|
||||
|
||||
// ----------
|
||||
@ -353,8 +360,10 @@ let TabView = {
|
||||
if (!tabItem)
|
||||
return;
|
||||
|
||||
// Switch to the new tab
|
||||
window.gBrowser.selectedTab = tabItem.tab;
|
||||
if (gBrowser.selectedTab.pinned)
|
||||
groupItems.updateActiveGroupItemAndTabBar(tabItem, {dontSetActiveTabInGroup: true});
|
||||
else
|
||||
gBrowser.selectedTab = tabItem.tab;
|
||||
});
|
||||
}
|
||||
}, true);
|
||||
@ -440,5 +449,29 @@ let TabView = {
|
||||
// show banner
|
||||
this._window.UI.notifySessionRestoreEnabled();
|
||||
}
|
||||
},
|
||||
|
||||
// ----------
|
||||
// Function: fillInTooltip
|
||||
// Fills in the tooltip text.
|
||||
fillInTooltip: function fillInTooltip(tipElement) {
|
||||
let retVal = false;
|
||||
let titleText = null;
|
||||
let direction = tipElement.ownerDocument.dir;
|
||||
|
||||
while (!titleText && tipElement) {
|
||||
if (tipElement.nodeType == Node.ELEMENT_NODE)
|
||||
titleText = tipElement.getAttribute("title");
|
||||
tipElement = tipElement.parentNode;
|
||||
}
|
||||
let tipNode = document.getElementById("tab-view-tooltip");
|
||||
tipNode.style.direction = direction;
|
||||
|
||||
if (titleText) {
|
||||
tipNode.setAttribute("label", titleText);
|
||||
retVal = true;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
};
|
||||
|
@ -148,6 +148,7 @@ function GroupItem(listOfEls, options) {
|
||||
.click(function() {
|
||||
self.closeAll();
|
||||
})
|
||||
.attr("title", tabviewString("groupItem.closeGroup"))
|
||||
.appendTo($container);
|
||||
|
||||
// ___ Title
|
||||
@ -198,7 +199,8 @@ function GroupItem(listOfEls, options) {
|
||||
e.stopPropagation();
|
||||
})
|
||||
.keypress(handleKeyPress)
|
||||
.keyup(handleKeyUp);
|
||||
.keyup(handleKeyUp)
|
||||
.attr("title", tabviewString("groupItem.defaultName"));
|
||||
|
||||
this.$titleShield
|
||||
.mousedown(function(e) {
|
||||
@ -212,7 +214,8 @@ function GroupItem(listOfEls, options) {
|
||||
|
||||
if (!self.isDragging)
|
||||
self.focusTitle();
|
||||
});
|
||||
})
|
||||
.attr("title", tabviewString("groupItem.defaultName"));
|
||||
|
||||
if (options.focusTitle)
|
||||
this.focusTitle();
|
||||
@ -904,6 +907,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||
.appendTo(this.$undoContainer);
|
||||
let undoClose = iQ("<span/>")
|
||||
.addClass("close")
|
||||
.attr("title", tabviewString("groupItem.discardClosedGroup"))
|
||||
.appendTo(this.$undoContainer);
|
||||
|
||||
this.$undoContainer.css({
|
||||
@ -1143,7 +1147,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||
|
||||
let closed = options.dontClose ? false : this.closeIfEmpty();
|
||||
if (closed ||
|
||||
(this._children.length == 0 && !gBrowser.selectedTab.pinned &&
|
||||
(this._children.length == 0 && !gBrowser._numPinnedTabs &&
|
||||
!item.isDragging)) {
|
||||
this._makeLastActiveGroupItemActive();
|
||||
} else if (!options.dontArrange) {
|
||||
@ -2230,29 +2234,31 @@ let GroupItems = {
|
||||
}
|
||||
|
||||
toClose.forEach(function(groupItem) {
|
||||
// All remaining children in to-be-closed groups are re-used by
|
||||
// session restore. Reconnect them so that they're put into their
|
||||
// right groups.
|
||||
let children = groupItem.getChildren().concat();
|
||||
|
||||
children.forEach(function (tabItem) {
|
||||
if (tabItem.parent && tabItem.parent.hidden)
|
||||
// all tabs still existing in closed groups will be moved to new
|
||||
// groups. prepare them to be reconnected later.
|
||||
groupItem.getChildren().forEach(function (tabItem) {
|
||||
if (tabItem.parent.hidden)
|
||||
iQ(tabItem.container).show();
|
||||
|
||||
tabItem._reconnected = false;
|
||||
|
||||
// sanity check the tab's groupID
|
||||
let tabData = Storage.getTabData(tabItem.tab);
|
||||
let parentGroup = GroupItems.groupItem(tabData.groupID);
|
||||
|
||||
// correct the tab's groupID if necessary
|
||||
if (!parentGroup || -1 < toClose.indexOf(parentGroup)) {
|
||||
tabData.groupID = activeGroupId || Object.keys(groupItemData)[0];
|
||||
Storage.saveTab(tabItem.tab, tabData);
|
||||
if (tabData) {
|
||||
let parentGroup = GroupItems.groupItem(tabData.groupID);
|
||||
|
||||
// the tab's group id could be invalid or point to a non-existing
|
||||
// group. correct it by assigning the active group id or the first
|
||||
// group of the just restored session.
|
||||
if (!parentGroup || -1 < toClose.indexOf(parentGroup)) {
|
||||
tabData.groupID = activeGroupId || Object.keys(groupItemData)[0];
|
||||
Storage.saveTab(tabItem.tab, tabData);
|
||||
}
|
||||
}
|
||||
|
||||
tabItem._reconnected = false;
|
||||
tabItem._reconnect();
|
||||
});
|
||||
|
||||
// this closes the group but not its children
|
||||
groupItem.close({immediately: true});
|
||||
});
|
||||
}
|
||||
@ -2466,10 +2472,14 @@ let GroupItems = {
|
||||
// ----------
|
||||
// Function: updateActiveGroupItemAndTabBar
|
||||
// Sets active TabItem and GroupItem, and updates tab bar appropriately.
|
||||
updateActiveGroupItemAndTabBar: function GroupItems_updateActiveGroupItemAndTabBar(tabItem) {
|
||||
// Parameters:
|
||||
// tabItem - the tab item
|
||||
// options - is passed to UI.setActive() directly
|
||||
updateActiveGroupItemAndTabBar:
|
||||
function GroupItems_updateActiveGroupItemAndTabBar(tabItem, options) {
|
||||
Utils.assertThrow(tabItem && tabItem.isATabItem, "tabItem must be a TabItem");
|
||||
|
||||
UI.setActive(tabItem);
|
||||
UI.setActive(tabItem, options);
|
||||
this._updateTabBar();
|
||||
},
|
||||
|
||||
|
@ -431,13 +431,15 @@ let Search = {
|
||||
|
||||
iQ("#searchbox").keyup(function Search_init_box_keyup() {
|
||||
self.perform();
|
||||
});
|
||||
})
|
||||
.attr("title", tabviewString("button.searchTabs"));
|
||||
|
||||
iQ("#searchbutton").mousedown(function Search_init_button_mousedown() {
|
||||
self._initiatedBy = "buttonclick";
|
||||
self.ensureShown();
|
||||
self.switchToInMode();
|
||||
});
|
||||
})
|
||||
.attr("title", tabviewString("button.searchTabs"));
|
||||
|
||||
window.addEventListener("focus", function Search_init_window_focus() {
|
||||
if (self.isEnabled()) {
|
||||
|
@ -148,6 +148,8 @@ function TabItem(tab, options) {
|
||||
|
||||
this.droppable(true);
|
||||
|
||||
this.$close.attr("title", tabbrowserString("tabs.closeTab"));
|
||||
|
||||
TabItems.register(this);
|
||||
|
||||
// ___ reconnect to data from Storage
|
||||
@ -204,7 +206,15 @@ TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||
this._cachedImageData = imageData;
|
||||
this.$cachedThumb.attr("src", this._cachedImageData).show();
|
||||
this.$canvas.css({opacity: 0});
|
||||
this.$tabTitle.text(tabData.title ? tabData.title : "");
|
||||
let label = "";
|
||||
let title;
|
||||
if (tabData.title) {
|
||||
label = tabData.title;
|
||||
title = label + "\n" + tabData.url;
|
||||
} else {
|
||||
title = tabData.url;
|
||||
}
|
||||
this.$tabTitle.text(label).attr("title", title);
|
||||
|
||||
this._sendToSubscribers("showingCachedData");
|
||||
},
|
||||
@ -1003,10 +1013,10 @@ let TabItems = {
|
||||
// ___ URL
|
||||
let tabUrl = tab.linkedBrowser.currentURI.spec;
|
||||
if (tabUrl != tabItem.url) {
|
||||
let oldURL = tabItem.url;
|
||||
tabItem.url = tabUrl;
|
||||
tabItem.save();
|
||||
}
|
||||
tabItem.$container.attr("title", label + "\n" + tabUrl);
|
||||
|
||||
// ___ Make sure the tab is complete and ready for updating.
|
||||
if (!this.isComplete(tab) && (!options || !options.force)) {
|
||||
|
@ -13,8 +13,13 @@ XPCOMUtils.defineLazyGetter(this, "tabviewBundle", function() {
|
||||
return Services.strings.
|
||||
createBundle("chrome://browser/locale/tabview.properties");
|
||||
});
|
||||
XPCOMUtils.defineLazyGetter(this, "tabbrowserBundle", function() {
|
||||
return Services.strings.
|
||||
createBundle("chrome://browser/locale/tabbrowser.properties");
|
||||
});
|
||||
|
||||
function tabviewString(name) tabviewBundle.GetStringFromName('tabview.' + name);
|
||||
function tabbrowserString(name) tabbrowserBundle.GetStringFromName(name);
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "gPrefBranch", function() {
|
||||
return Services.prefs.getBranch("browser.panorama.");
|
||||
|
@ -87,8 +87,9 @@ _BROWSER_FILES = \
|
||||
browser_tabview_bug606905.js \
|
||||
browser_tabview_bug607108.js \
|
||||
browser_tabview_bug608037.js \
|
||||
browser_tabview_bug608184.js \
|
||||
browser_tabview_bug608153.js \
|
||||
browser_tabview_bug608158.js \
|
||||
browser_tabview_bug608184.js \
|
||||
browser_tabview_bug608405.js \
|
||||
browser_tabview_bug610208.js \
|
||||
browser_tabview_bug610242.js \
|
||||
@ -165,6 +166,8 @@ _BROWSER_FILES = \
|
||||
browser_tabview_bug686654.js \
|
||||
browser_tabview_bug697390.js \
|
||||
browser_tabview_bug705621.js \
|
||||
browser_tabview_bug706430.js \
|
||||
browser_tabview_bug706736.js \
|
||||
browser_tabview_click_group.js \
|
||||
browser_tabview_dragdrop.js \
|
||||
browser_tabview_exit_button.js \
|
||||
|
48
browser/components/tabview/test/browser_tabview_bug608153.js
Normal file
48
browser/components/tabview/test/browser_tabview_bug608153.js
Normal file
@ -0,0 +1,48 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
let pinnedTab = gBrowser.addTab();
|
||||
gBrowser.pinTab(pinnedTab);
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gBrowser.unpinTab(pinnedTab);
|
||||
while (gBrowser.tabs[1])
|
||||
gBrowser.removeTab(gBrowser.tabs[1]);
|
||||
hideTabView();
|
||||
});
|
||||
|
||||
showTabView(function() {
|
||||
let cw = TabView.getContentWindow();
|
||||
let groupItemOne = cw.GroupItems.groupItems[0];
|
||||
let groupItemTwo = createGroupItemWithBlankTabs(window, 250, 250, 40, 1);
|
||||
|
||||
is(cw.GroupItems.groupItems.length, 2, "Two group items");
|
||||
|
||||
hideTabView(function() {
|
||||
gBrowser.selectedTab = pinnedTab;
|
||||
is(cw.GroupItems.getActiveGroupItem(), groupItemTwo, "Group two is active");
|
||||
is(gBrowser.selectedTab, pinnedTab, "Selected tab is the pinned tab");
|
||||
|
||||
goToNextGroup();
|
||||
is(cw.GroupItems.getActiveGroupItem(), groupItemOne, "Group one is active");
|
||||
is(gBrowser.selectedTab, pinnedTab, "Selected tab is the pinned tab");
|
||||
|
||||
finish();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function goToNextGroup() {
|
||||
let utils =
|
||||
QueryInterface(Ci.nsIInterfaceRequestor).
|
||||
getInterface(Ci.nsIDOMWindowUtils);
|
||||
|
||||
const masks = Ci.nsIDOMNSEvent;
|
||||
let mval = 0;
|
||||
mval |= masks.CONTROL_MASK;
|
||||
|
||||
utils.sendKeyEvent("keypress", 0, 96, mval);
|
||||
}
|
@ -15,7 +15,7 @@ function test() {
|
||||
is(groupItemOne.getChildren().length, 1, "Group one has 1 tab item");
|
||||
|
||||
let groupItemTwo = createGroupItemWithBlankTabs(win, 300, 300, 40, 1);
|
||||
is(groupItemTwo.getChildren().length, 1, "Group two has 2 tab items");
|
||||
is(groupItemTwo.getChildren().length, 1, "Group two has 1 tab item");
|
||||
|
||||
whenTabViewIsHidden(function() {
|
||||
executeSoon(function() {
|
||||
|
65
browser/components/tabview/test/browser_tabview_bug706430.js
Normal file
65
browser/components/tabview/test/browser_tabview_bug706430.js
Normal file
@ -0,0 +1,65 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
let state1 = {
|
||||
windows: [{
|
||||
tabs: [{
|
||||
entries: [{ url: "about:blank#1" }],
|
||||
hidden: true,
|
||||
extData: {"tabview-tab": '{"url":"about:blank#1","groupID":1,"bounds":{"left":120,"top":20,"width":20,"height":20}}'}
|
||||
},{
|
||||
entries: [{ url: "about:blank#2" }],
|
||||
hidden: false,
|
||||
extData: {"tabview-tab": '{"url":"about:blank#2","groupID":2,"bounds":{"left":20,"top":20,"width":20,"height":20}}'},
|
||||
}],
|
||||
selected: 2,
|
||||
extData: {
|
||||
"tabview-groups": '{"nextID":3,"activeGroupId":2, "totalNumber":2}',
|
||||
"tabview-group":
|
||||
'{"1":{"bounds":{"left":15,"top":5,"width":280,"height":232},"id":1},' +
|
||||
'"2":{"bounds":{"left":309,"top":5,"width":267,"height":226},"id":2}}'
|
||||
}
|
||||
}]
|
||||
};
|
||||
|
||||
let state2 = {
|
||||
windows: [{
|
||||
tabs: [{entries: [{ url: "about:blank#1" }], hidden: true},
|
||||
{entries: [{ url: "about:blank#2" }], hidden: false}],
|
||||
selected: 2
|
||||
}]
|
||||
};
|
||||
|
||||
let ss = Cc["@mozilla.org/browser/sessionstore;1"]
|
||||
.getService(Ci.nsISessionStore);
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
newWindowWithState(state1, function (win) {
|
||||
registerCleanupFunction(function () win.close());
|
||||
|
||||
showTabView(function () {
|
||||
let cw = win.TabView.getContentWindow();
|
||||
let [group1, group2] = cw.GroupItems.groupItems;
|
||||
let [tab1, tab2] = win.gBrowser.tabs;
|
||||
|
||||
checkUrl(group1.getChild(0), "about:blank#1", "tab1 is in first group");
|
||||
checkUrl(group2.getChild(0), "about:blank#2", "tab2 is in second group");
|
||||
|
||||
whenWindowStateReady(win, function () {
|
||||
let groups = cw.GroupItems.groupItems;
|
||||
is(groups.length, 1, "one groupItem");
|
||||
is(groups[0].getChildren().length, 2, "single groupItem has two children");
|
||||
|
||||
finish();
|
||||
});
|
||||
|
||||
ss.setWindowState(win, JSON.stringify(state2), true);
|
||||
}, win);
|
||||
});
|
||||
}
|
||||
|
||||
function checkUrl(aTabItem, aUrl, aMsg) {
|
||||
is(aTabItem.tab.linkedBrowser.currentURI.spec, aUrl, aMsg);
|
||||
}
|
40
browser/components/tabview/test/browser_tabview_bug706736.js
Normal file
40
browser/components/tabview/test/browser_tabview_bug706736.js
Normal file
@ -0,0 +1,40 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
newWindowWithTabView(function(win) {
|
||||
registerCleanupFunction(function() {
|
||||
win.close();
|
||||
});
|
||||
|
||||
let cw = win.TabView.getContentWindow();
|
||||
|
||||
let groupItemOne = cw.GroupItems.groupItems[0];
|
||||
is(groupItemOne.getChildren().length, 1, "Group one has 1 tab item");
|
||||
|
||||
let groupItemTwo = createGroupItemWithBlankTabs(win, 300, 300, 40, 1);
|
||||
is(groupItemTwo.getChildren().length, 1, "Group two has 1 tab items");
|
||||
|
||||
whenTabViewIsHidden(function() {
|
||||
win.gBrowser.removeTab(win.gBrowser.selectedTab);
|
||||
executeSoon(function() {
|
||||
win.undoCloseTab();
|
||||
|
||||
groupItemTwo.addSubscriber("childAdded", function onChildAdded(data) {
|
||||
groupItemTwo.removeSubscriber("childAdded", onChildAdded);
|
||||
|
||||
is(groupItemOne.getChildren().length, 1, "Group one still has 1 tab item");
|
||||
is(groupItemTwo.getChildren().length, 1, "Group two still has 1 tab item");
|
||||
});
|
||||
|
||||
finish();
|
||||
});
|
||||
}, win);
|
||||
groupItemTwo.getChild(0).zoomIn();
|
||||
}, function(win) {
|
||||
let newTab = win.gBrowser.addTab();
|
||||
win.gBrowser.pinTab(newTab);
|
||||
});
|
||||
}
|
@ -195,7 +195,8 @@ let UI = {
|
||||
iQ("#exit-button").click(function() {
|
||||
self.exit();
|
||||
self.blurAll();
|
||||
});
|
||||
})
|
||||
.attr("title", tabviewString("button.exitTabGroups"));
|
||||
|
||||
// When you click on the background/empty part of TabView,
|
||||
// we create a new groupItem.
|
||||
@ -465,7 +466,8 @@ let UI = {
|
||||
if (item.isATabItem) {
|
||||
if (item.parent)
|
||||
GroupItems.setActiveGroupItem(item.parent);
|
||||
this._setActiveTab(item);
|
||||
if (!options || !options.dontSetActiveTabInGroup)
|
||||
this._setActiveTab(item);
|
||||
} else {
|
||||
GroupItems.setActiveGroupItem(item);
|
||||
if (!options || !options.dontSetActiveTabInGroup) {
|
||||
|
@ -1,4 +1,8 @@
|
||||
tabview.groupItem.defaultName=Name this tab group…
|
||||
tabview.button.searchTabs=Search tab groups
|
||||
tabview.button.exitTabGroups=Exit tab groups
|
||||
tabview.groupItem.defaultName=Name this tab group
|
||||
tabview.groupItem.closeGroup=Close group
|
||||
tabview.groupItem.undoCloseGroup=Undo Close Group
|
||||
tabview.groupItem.discardClosedGroup=Discard closed group
|
||||
tabview.search.otherWindowTabs=Tabs from other windows
|
||||
tabview.notification.sessionStore=Tabs and groups will automatically be restored the next time you start %S.
|
||||
|
@ -21,6 +21,7 @@
|
||||
#
|
||||
# Contributor(s):
|
||||
# Dave Townsend <dtownsend@oxymoronical.com>
|
||||
# Blair McBride <bmcbride@mozilla.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@ -50,8 +51,11 @@ const PREF_EM_LAST_PLATFORM_VERSION = "extensions.lastPlatformVersion";
|
||||
const PREF_EM_AUTOUPDATE_DEFAULT = "extensions.update.autoUpdateDefault";
|
||||
const PREF_EM_STRICT_COMPATIBILITY = "extensions.strictCompatibility";
|
||||
|
||||
// Note: This has to be kept in sync with the same constant in AddonRepository.jsm
|
||||
const STRICT_COMPATIBILITY_DEFAULT = true;
|
||||
|
||||
const TOOLKIT_ID = "toolkit@mozilla.org";
|
||||
|
||||
const VALID_TYPES_REGEXP = /^[\w\-]+$/;
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
@ -235,6 +239,67 @@ AddonScreenshot.prototype = {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This represents a compatibility override for an addon.
|
||||
*
|
||||
* @param aType
|
||||
* Overrride type - "compatible" or "incompatible"
|
||||
* @param aMinVersion
|
||||
* Minimum version of the addon to match
|
||||
* @param aMaxVersion
|
||||
* Maximum version of the addon to match
|
||||
* @param aAppID
|
||||
* Application ID used to match appMinVersion and appMaxVersion
|
||||
* @param aAppMinVersion
|
||||
* Minimum version of the application to match
|
||||
* @param aAppMaxVersion
|
||||
* Maximum version of the application to match
|
||||
*/
|
||||
function AddonCompatibilityOverride(aType, aMinVersion, aMaxVersion, aAppID,
|
||||
aAppMinVersion, aAppMaxVersion) {
|
||||
this.type = aType;
|
||||
this.minVersion = aMinVersion;
|
||||
this.maxVersion = aMaxVersion;
|
||||
this.appID = aAppID;
|
||||
this.appMinVersion = aAppMinVersion;
|
||||
this.appMaxVersion = aAppMaxVersion;
|
||||
}
|
||||
|
||||
AddonCompatibilityOverride.prototype = {
|
||||
/**
|
||||
* Type of override - "incompatible" or "compatible".
|
||||
* Only "incompatible" is supported for now.
|
||||
*/
|
||||
type: null,
|
||||
|
||||
/**
|
||||
* Min version of the addon to match.
|
||||
*/
|
||||
minVersion: null,
|
||||
|
||||
/**
|
||||
* Max version of the addon to match.
|
||||
*/
|
||||
maxVersion: null,
|
||||
|
||||
/**
|
||||
* Application ID to match.
|
||||
*/
|
||||
appID: null,
|
||||
|
||||
/**
|
||||
* Min version of the application to match.
|
||||
*/
|
||||
appMinVersion: null,
|
||||
|
||||
/**
|
||||
* Max version of the application to match.
|
||||
*/
|
||||
appMaxVersion: null
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A type of add-on, used by the UI to determine how to display different types
|
||||
* of add-ons.
|
||||
@ -552,11 +617,14 @@ var AddonManagerInternal = {
|
||||
return;
|
||||
|
||||
Services.obs.notifyObservers(null, "addons-background-update-start", null);
|
||||
let pendingUpdates = 1;
|
||||
let pendingUpdates = 0;
|
||||
|
||||
function notifyComplete() {
|
||||
if (--pendingUpdates == 0)
|
||||
Services.obs.notifyObservers(null, "addons-background-update-complete", null);
|
||||
if (--pendingUpdates == 0) {
|
||||
Services.obs.notifyObservers(null,
|
||||
"addons-background-update-complete",
|
||||
null);
|
||||
}
|
||||
}
|
||||
|
||||
let scope = {};
|
||||
@ -565,30 +633,34 @@ var AddonManagerInternal = {
|
||||
scope.LightweightThemeManager.updateCurrentTheme();
|
||||
|
||||
this.getAllAddons(function getAddonsCallback(aAddons) {
|
||||
pendingUpdates++;
|
||||
// Repopulate repository cache first, to ensure compatibility overrides
|
||||
// are up to date before checking for addon updates.
|
||||
var ids = [a.id for each (a in aAddons)];
|
||||
scope.AddonRepository.repopulateCache(ids, notifyComplete);
|
||||
scope.AddonRepository.repopulateCache(ids, function BUC_repopulateCacheCallback() {
|
||||
AddonManagerInternal.updateAddonRepositoryData(function BUC_updateAddonCallback() {
|
||||
|
||||
pendingUpdates += aAddons.length;
|
||||
pendingUpdates += aAddons.length;
|
||||
|
||||
aAddons.forEach(function BUC_forEachCallback(aAddon) {
|
||||
// Check all add-ons for updates so that any compatibility updates will
|
||||
// be applied
|
||||
aAddon.findUpdates({
|
||||
onUpdateAvailable: function BUC_onUpdateAvailable(aAddon, aInstall) {
|
||||
// Start installing updates when the add-on can be updated and
|
||||
// background updates should be applied.
|
||||
if (aAddon.permissions & AddonManager.PERM_CAN_UPGRADE &&
|
||||
AddonManager.shouldAutoUpdate(aAddon)) {
|
||||
aInstall.install();
|
||||
}
|
||||
},
|
||||
|
||||
onUpdateFinished: notifyComplete
|
||||
}, AddonManager.UPDATE_WHEN_PERIODIC_UPDATE);
|
||||
aAddons.forEach(function BUC_forEachCallback(aAddon) {
|
||||
// Check all add-ons for updates so that any compatibility updates will
|
||||
// be applied
|
||||
aAddon.findUpdates({
|
||||
onUpdateAvailable: function BUC_onUpdateAvailable(aAddon, aInstall) {
|
||||
// Start installing updates when the add-on can be updated and
|
||||
// background updates should be applied.
|
||||
if (aAddon.permissions & AddonManager.PERM_CAN_UPGRADE &&
|
||||
AddonManager.shouldAutoUpdate(aAddon)) {
|
||||
aInstall.install();
|
||||
}
|
||||
},
|
||||
|
||||
onUpdateFinished: notifyComplete
|
||||
}, AddonManager.UPDATE_WHEN_PERIODIC_UPDATE);
|
||||
});
|
||||
|
||||
notifyComplete();
|
||||
});
|
||||
});
|
||||
|
||||
notifyComplete();
|
||||
});
|
||||
},
|
||||
|
||||
@ -715,7 +787,31 @@ var AddonManagerInternal = {
|
||||
callProvider(provider, "updateAddonAppDisabledStates");
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Notifies all providers that the repository has updated its data for
|
||||
* installed add-ons.
|
||||
*
|
||||
* @param aCallback
|
||||
* Function to call when operation is complete.
|
||||
*/
|
||||
updateAddonRepositoryData: function AMI_updateAddonRepositoryData(aCallback) {
|
||||
if (!aCallback)
|
||||
throw Components.Exception("Must specify aCallback",
|
||||
Cr.NS_ERROR_INVALID_ARG);
|
||||
|
||||
new AsyncObjectCaller(this.providers, "updateAddonRepositoryData", {
|
||||
nextObject: function(aCaller, aProvider) {
|
||||
callProvider(aProvider,
|
||||
"updateAddonRepositoryData",
|
||||
null,
|
||||
aCaller.callNext.bind(aCaller));
|
||||
},
|
||||
noMoreObjects: function(aCaller) {
|
||||
safeCall(aCallback);
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Asynchronously gets an AddonInstall for a URL.
|
||||
*
|
||||
@ -1225,6 +1321,8 @@ var AddonManagerPrivate = {
|
||||
|
||||
AddonScreenshot: AddonScreenshot,
|
||||
|
||||
AddonCompatibilityOverride: AddonCompatibilityOverride,
|
||||
|
||||
AddonType: AddonType
|
||||
};
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
# Contributor(s):
|
||||
# Dave Townsend <dtownsend@oxymoronical.com>
|
||||
# Ben Parr <bparr@bparr.com>
|
||||
# Blair McBride <bmcbride@mozilla.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@ -74,6 +75,10 @@ XPCOMUtils.defineLazyGetter(this, "PREF_CHECK_COMPATIBILITY", function () {
|
||||
#endif
|
||||
});
|
||||
|
||||
const PREF_EM_STRICT_COMPATIBILITY = "extensions.strictCompatibility";
|
||||
// Note: This has to be kept in sync with the same constant in AddonManager.jsm
|
||||
const STRICT_COMPATIBILITY_DEFAULT = true;
|
||||
|
||||
const XMLURI_PARSE_ERROR = "http://www.mozilla.org/newlayout/xml/parsererror.xml";
|
||||
|
||||
const API_VERSION = "1.5";
|
||||
@ -81,7 +86,9 @@ const DEFAULT_CACHE_TYPES = "extension,theme,locale,dictionary";
|
||||
|
||||
const KEY_PROFILEDIR = "ProfD";
|
||||
const FILE_DATABASE = "addons.sqlite";
|
||||
const DB_SCHEMA = 2;
|
||||
const DB_SCHEMA = 3;
|
||||
|
||||
const TOOLKIT_ID = "toolkit@mozilla.org";
|
||||
|
||||
["LOG", "WARN", "ERROR"].forEach(function(aName) {
|
||||
this.__defineGetter__(aName, function() {
|
||||
@ -356,6 +363,12 @@ AddonSearchResult.prototype = {
|
||||
*/
|
||||
isPlatformCompatible: true,
|
||||
|
||||
/**
|
||||
* Array of AddonCompatibilityOverride objects, that describe overrides for
|
||||
* compatibility with an application versions.
|
||||
**/
|
||||
compatibilityOverrides: null,
|
||||
|
||||
/**
|
||||
* True if the add-on has a secure means of updating
|
||||
*/
|
||||
@ -609,8 +622,8 @@ var AddonRepository = {
|
||||
getAddonsToCache(aIds, function(aAddons) {
|
||||
// Completely remove cache if there are no add-ons to cache
|
||||
if (aAddons.length == 0) {
|
||||
this._addons = null;
|
||||
this._pendingCallbacks = null;
|
||||
self._addons = null;
|
||||
self._pendingCallbacks = null;
|
||||
AddonDatabase.delete(aCallback);
|
||||
return;
|
||||
}
|
||||
@ -744,12 +757,12 @@ var AddonRepository = {
|
||||
let url = this._formatURLPref(PREF_GETADDONS_BYIDS, params);
|
||||
|
||||
let self = this;
|
||||
function handleResults(aElements, aTotalResults) {
|
||||
function handleResults(aElements, aTotalResults, aCompatData) {
|
||||
// Don't use this._parseAddons() so that, for example,
|
||||
// incompatible add-ons are not filtered out
|
||||
let results = [];
|
||||
for (let i = 0; i < aElements.length && results.length < self._maxResults; i++) {
|
||||
let result = self._parseAddon(aElements[i]);
|
||||
let result = self._parseAddon(aElements[i], null, aCompatData);
|
||||
if (result == null)
|
||||
continue;
|
||||
|
||||
@ -763,6 +776,24 @@ var AddonRepository = {
|
||||
ids.splice(idIndex, 1);
|
||||
}
|
||||
|
||||
// Include any compatibility overrides for addons not hosted by the
|
||||
// remote repository.
|
||||
for each (let addonCompat in aCompatData) {
|
||||
if (addonCompat.hosted)
|
||||
continue;
|
||||
|
||||
let addon = new AddonSearchResult(addonCompat.id);
|
||||
// Compatibility overrides can only be for extensions.
|
||||
addon.type = "extension";
|
||||
addon.compatibilityOverrides = addonCompat.compatRanges;
|
||||
let result = {
|
||||
addon: addon,
|
||||
xpiURL: null,
|
||||
xpiHash: null
|
||||
};
|
||||
results.push(result);
|
||||
}
|
||||
|
||||
// aTotalResults irrelevant
|
||||
self._reportSuccess(results, -1);
|
||||
}
|
||||
@ -865,6 +896,14 @@ var AddonRepository = {
|
||||
return (elementsList.length == 1) ? elementsList[0] : null;
|
||||
},
|
||||
|
||||
// Get direct descendant by unique tag name.
|
||||
// Returns null if not unique tag name.
|
||||
_getUniqueDirectDescendant: function(aElement, aTagName) {
|
||||
let elementsList = Array.filter(aElement.children,
|
||||
function(aChild) aChild.tagName == aTagName);
|
||||
return (elementsList.length == 1) ? elementsList[0] : null;
|
||||
},
|
||||
|
||||
// Parse out trimmed text content. Returns null if text content empty.
|
||||
_getTextContent: function(aElement) {
|
||||
let textContent = aElement.textContent.trim();
|
||||
@ -878,6 +917,14 @@ var AddonRepository = {
|
||||
return (descendant != null) ? this._getTextContent(descendant) : null;
|
||||
},
|
||||
|
||||
// Parse out trimmed text content of a direct descendant with the specified
|
||||
// tag name.
|
||||
// Returns null if the parsing unsuccessful.
|
||||
_getDirectDescendantTextContent: function(aElement, aTagName) {
|
||||
let descendant = this._getUniqueDirectDescendant(aElement, aTagName);
|
||||
return (descendant != null) ? this._getTextContent(descendant) : null;
|
||||
},
|
||||
|
||||
/*
|
||||
* Creates an AddonSearchResult by parsing an <addon> element
|
||||
*
|
||||
@ -885,10 +932,13 @@ var AddonRepository = {
|
||||
* The <addon> element to parse
|
||||
* @param aSkip
|
||||
* Object containing ids and sourceURIs of add-ons to skip.
|
||||
* @param aCompatData
|
||||
* Array of parsed addon_compatibility elements to accosiate with the
|
||||
* resulting AddonSearchResult. Optional.
|
||||
* @return Result object containing the parsed AddonSearchResult, xpiURL and
|
||||
* xpiHash if the parsing was successful. Otherwise returns null.
|
||||
*/
|
||||
_parseAddon: function(aElement, aSkip) {
|
||||
_parseAddon: function(aElement, aSkip, aCompatData) {
|
||||
let skipIDs = (aSkip && aSkip.ids) ? aSkip.ids : [];
|
||||
let skipSourceURIs = (aSkip && aSkip.sourceURIs) ? aSkip.sourceURIs : [];
|
||||
|
||||
@ -903,6 +953,9 @@ var AddonRepository = {
|
||||
xpiHash: null
|
||||
};
|
||||
|
||||
if (aCompatData && guid in aCompatData)
|
||||
addon.compatibilityOverrides = aCompatData[guid].compatRanges;
|
||||
|
||||
let self = this;
|
||||
for (let node = aElement.firstChild; node; node = node.nextSibling) {
|
||||
if (!(node instanceof Ci.nsIDOMElement))
|
||||
@ -1095,6 +1148,11 @@ var AddonRepository = {
|
||||
checkCompatibility = Services.prefs.getBoolPref(PREF_CHECK_COMPATIBILITY);
|
||||
} catch(e) { }
|
||||
|
||||
let strictCompatibility = STRICT_COMPATIBILITY_DEFAULT;
|
||||
try {
|
||||
strictCompatibility = Services.prefs.getBoolPref(PREF_EM_STRICT_COMPATIBILITY);
|
||||
} catch (e) {}
|
||||
|
||||
function isSameApplication(aAppNode) {
|
||||
return self._getTextContent(aAppNode) == Services.appinfo.ID;
|
||||
}
|
||||
@ -1119,7 +1177,8 @@ var AddonRepository = {
|
||||
|
||||
let currentVersion = Services.appinfo.version;
|
||||
return (Services.vc.compare(minVersion, currentVersion) <= 0 &&
|
||||
Services.vc.compare(currentVersion, maxVersion) <= 0);
|
||||
((!strictCompatibility) ||
|
||||
Services.vc.compare(currentVersion, maxVersion) <= 0));
|
||||
});
|
||||
|
||||
// Ignore add-ons not compatible with this Application
|
||||
@ -1131,7 +1190,9 @@ var AddonRepository = {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add-on meets all requirements, so parse out data
|
||||
// Add-on meets all requirements, so parse out data.
|
||||
// Don't pass in compatiblity override data, because that's only returned
|
||||
// in GUID searches, which don't use _parseAddons().
|
||||
let result = this._parseAddon(element, aSkip);
|
||||
if (result == null)
|
||||
continue;
|
||||
@ -1186,6 +1247,83 @@ var AddonRepository = {
|
||||
});
|
||||
},
|
||||
|
||||
// Parses addon_compatibility nodes, that describe compatibility overrides.
|
||||
_parseAddonCompatElement: function(aResultObj, aElement) {
|
||||
let guid = this._getDescendantTextContent(aElement, "guid");
|
||||
if (!guid)
|
||||
return;
|
||||
|
||||
let compat = {id: guid};
|
||||
compat.hosted = aElement.getAttribute("hosted") != "false";
|
||||
|
||||
function findMatchingAppRange(aNodes) {
|
||||
let toolkitAppRange = null;
|
||||
for (let i = 0; i < aNodes.length; i++) {
|
||||
let node = aNodes[i];
|
||||
let appID = this._getDescendantTextContent(node, "appID");
|
||||
if (appID != Services.appinfo.ID && appID != TOOLKIT_ID)
|
||||
continue;
|
||||
|
||||
let minVersion = this._getDescendantTextContent(node, "min_version");
|
||||
let maxVersion = this._getDescendantTextContent(node, "max_version");
|
||||
if (minVersion == null || maxVersion == null)
|
||||
continue;
|
||||
|
||||
let appRange = { appID: appID,
|
||||
appMinVersion: minVersion,
|
||||
appMaxVersion: maxVersion };
|
||||
|
||||
// Only use Toolkit app ranges if no ranges match the application ID.
|
||||
if (appID == TOOLKIT_ID)
|
||||
toolkitAppRange = appRange;
|
||||
else
|
||||
return appRange;
|
||||
}
|
||||
return toolkitAppRange;
|
||||
}
|
||||
|
||||
function parseRangeNode(aNode) {
|
||||
let type = aNode.getAttribute("type");
|
||||
// Only "incompatible" (blacklisting) is supported for now.
|
||||
if (type != "incompatible")
|
||||
return null;
|
||||
|
||||
let override = new AddonManagerPrivate.AddonCompatibilityOverride(type);
|
||||
|
||||
override.minVersion = this._getDirectDescendantTextContent(aNode, "min_version");
|
||||
override.maxVersion = this._getDirectDescendantTextContent(aNode, "max_version");
|
||||
|
||||
if (!override.minVersion || !override.maxVersion)
|
||||
return null;
|
||||
|
||||
let appRanges = aNode.querySelectorAll("compatible_applications > application");
|
||||
let appRange = findMatchingAppRange.bind(this)(appRanges);
|
||||
if (!appRange)
|
||||
return null;
|
||||
|
||||
override.appID = appRange.appID;
|
||||
override.appMinVersion = appRange.appMinVersion;
|
||||
override.appMaxVersion = appRange.appMaxVersion;
|
||||
|
||||
return override;
|
||||
}
|
||||
|
||||
let rangeNodes = aElement.querySelectorAll("version_ranges > version_range");
|
||||
compat.compatRanges = Array.map(rangeNodes, parseRangeNode.bind(this))
|
||||
.filter(function(aItem) !!aItem);
|
||||
if (compat.compatRanges.length == 0)
|
||||
return;
|
||||
|
||||
aResultObj[compat.id] = compat;
|
||||
},
|
||||
|
||||
// Parses addon_compatibility elements.
|
||||
_parseAddonCompatData: function(aElements) {
|
||||
let compatData = {};
|
||||
Array.forEach(aElements, this._parseAddonCompatElement.bind(this, compatData));
|
||||
return compatData;
|
||||
},
|
||||
|
||||
// Begins a new search if one isn't currently executing
|
||||
_beginSearch: function(aURI, aMaxResults, aCallback, aHandleResults) {
|
||||
if (this._searching || aURI == null || aMaxResults <= 0) {
|
||||
@ -1227,7 +1365,10 @@ var AddonRepository = {
|
||||
if (parsedTotalResults >= totalResults)
|
||||
totalResults = parsedTotalResults;
|
||||
|
||||
aHandleResults(elements, totalResults);
|
||||
let compatElements = documentElement.getElementsByTagName("addon_compatibility");
|
||||
let compatData = self._parseAddonCompatData(compatElements);
|
||||
|
||||
aHandleResults(elements, totalResults, compatData);
|
||||
}, false);
|
||||
this._request.send(null);
|
||||
},
|
||||
@ -1271,7 +1412,33 @@ var AddonRepository = {
|
||||
});
|
||||
|
||||
return Services.urlFormatter.formatURL(url);
|
||||
},
|
||||
|
||||
// Find a AddonCompatibilityOverride that matches a given aAddonVersion and
|
||||
// application/platform version.
|
||||
findMatchingCompatOverride: function AR_findMatchingCompatOverride(aAddonVersion,
|
||||
aCompatOverrides,
|
||||
aAppVersion,
|
||||
aPlatformVersion) {
|
||||
for (let i = 0; i < aCompatOverrides.length; i++) {
|
||||
let override = aCompatOverrides[i];
|
||||
|
||||
let appVersion = null;
|
||||
if (override.appID == TOOLKIT_ID)
|
||||
appVersion = aPlatformVersion || Services.appinfo.platformVersion;
|
||||
else
|
||||
appVersion = aAppVersion || Services.appinfo.version;
|
||||
|
||||
if (Services.vc.compare(override.minVersion, aAddonVersion) <= 0 &&
|
||||
Services.vc.compare(aAddonVersion, override.maxVersion) <= 0 &&
|
||||
Services.vc.compare(override.appMinVersion, appVersion) <= 0 &&
|
||||
Services.vc.compare(appVersion, override.appMaxVersion) <= 0) {
|
||||
return override;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
AddonRepository.initialize();
|
||||
|
||||
@ -1300,6 +1467,11 @@ var AddonDatabase = {
|
||||
"thumbnailURL, thumbnailWidth, thumbnailHeight, caption " +
|
||||
"FROM screenshot ORDER BY addon_internal_id, num",
|
||||
|
||||
getAllCompatOverrides: "SELECT addon_internal_id, type, minVersion, " +
|
||||
"maxVersion, appID, appMinVersion, appMaxVersion " +
|
||||
"FROM compatibility_override " +
|
||||
"ORDER BY addon_internal_id, num",
|
||||
|
||||
insertAddon: "INSERT INTO addon VALUES (NULL, :id, :type, :name, :version, " +
|
||||
":creator, :creatorURL, :description, :fullDescription, " +
|
||||
":developerComments, :eula, :iconURL, :homepageURL, :supportURL, " +
|
||||
@ -1319,6 +1491,11 @@ var AddonDatabase = {
|
||||
":num, :url, :width, :height, :thumbnailURL, " +
|
||||
":thumbnailWidth, :thumbnailHeight, :caption)",
|
||||
|
||||
insertCompatibilityOverride: "INSERT INTO compatibility_override VALUES " +
|
||||
"(:addon_internal_id, :num, :type, " +
|
||||
":minVersion, :maxVersion, :appID, " +
|
||||
":appMinVersion, :appMaxVersion)",
|
||||
|
||||
emptyAddon: "DELETE FROM addon"
|
||||
},
|
||||
|
||||
@ -1384,29 +1561,42 @@ var AddonDatabase = {
|
||||
if (dbMissing)
|
||||
this._createSchema();
|
||||
|
||||
switch (this.connection.schemaVersion) {
|
||||
case 0:
|
||||
this._createSchema();
|
||||
break;
|
||||
case 1:
|
||||
try {
|
||||
try {
|
||||
switch (this.connection.schemaVersion) {
|
||||
case 0:
|
||||
LOG("Recreating database schema");
|
||||
this._createSchema();
|
||||
break;
|
||||
case 1:
|
||||
LOG("Upgrading database schema");
|
||||
this.connection.executeSimpleSQL("ALTER TABLE screenshot ADD COLUMN width INTEGER");
|
||||
this.connection.executeSimpleSQL("ALTER TABLE screenshot ADD COLUMN height INTEGER");
|
||||
this.connection.executeSimpleSQL("ALTER TABLE screenshot ADD COLUMN thumbnailWidth INTEGER");
|
||||
this.connection.executeSimpleSQL("ALTER TABLE screenshot ADD COLUMN thumbnailHeight INTEGER");
|
||||
this._createIndices();
|
||||
this.connection.schemaVersion = DB_SCHEMA;
|
||||
} catch (e) {
|
||||
ERROR("Failed to create database schema", e);
|
||||
this.logSQLError(this.connection.lastError, this.connection.lastErrorString);
|
||||
this.connection.rollbackTransaction();
|
||||
case 2:
|
||||
this.connection.createTable("compatibility_override",
|
||||
"addon_internal_id INTEGER, " +
|
||||
"num INTEGER, " +
|
||||
"type TEXT, " +
|
||||
"minVersion TEXT, " +
|
||||
"maxVersion TEXT, " +
|
||||
"appID TEXT, " +
|
||||
"appMinVersion TEXT, " +
|
||||
"appMaxVersion TEXT, " +
|
||||
"PRIMARY KEY (addon_internal_id, num)");
|
||||
this._createIndices();
|
||||
this._createTriggers();
|
||||
this.connection.schemaVersion = DB_SCHEMA;
|
||||
case 3:
|
||||
break;
|
||||
default:
|
||||
return tryAgain();
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
break;
|
||||
default:
|
||||
return tryAgain();
|
||||
}
|
||||
} catch (e) {
|
||||
ERROR("Failed to create database schema", e);
|
||||
this.logSQLError(this.connection.lastError, this.connection.lastErrorString);
|
||||
this.connection.rollbackTransaction();
|
||||
return tryAgain();
|
||||
}
|
||||
|
||||
return this.connection;
|
||||
@ -1595,6 +1785,38 @@ var AddonDatabase = {
|
||||
return;
|
||||
}
|
||||
|
||||
getAllCompatOverrides();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getAllCompatOverrides() {
|
||||
self.getAsyncStatement("getAllCompatOverrides").executeAsync({
|
||||
handleResult: function(aResults) {
|
||||
let row = null;
|
||||
while (row = aResults.getNextRow()) {
|
||||
let addon_internal_id = row.getResultByName("addon_internal_id");
|
||||
if (!(addon_internal_id in addons)) {
|
||||
WARN("Found a compatibility override not linked to an add-on in database");
|
||||
continue;
|
||||
}
|
||||
|
||||
let addon = addons[addon_internal_id];
|
||||
if (!addon.compatibilityOverrides)
|
||||
addon.compatibilityOverrides = [];
|
||||
addon.compatibilityOverrides.push(self._makeCompatOverrideFromAsyncRow(row));
|
||||
}
|
||||
},
|
||||
|
||||
handleError: self.asyncErrorLogger,
|
||||
|
||||
handleCompletion: function(aReason) {
|
||||
if (aReason != Ci.mozIStorageStatementCallback.REASON_FINISHED) {
|
||||
ERROR("Error retrieving compatibility overrides from database. Returning empty results");
|
||||
aCallback({});
|
||||
return;
|
||||
}
|
||||
|
||||
let returnedAddons = {};
|
||||
for each (let addon in addons)
|
||||
returnedAddons[addon.id] = addon;
|
||||
@ -1677,8 +1899,9 @@ var AddonDatabase = {
|
||||
let internal_id = null;
|
||||
this.connection.beginTransaction();
|
||||
|
||||
// Simultaneously insert the developers and screenshots of the add-on
|
||||
function insertDevelopersAndScreenshots() {
|
||||
// Simultaneously insert the developers, screenshots, and compatibility
|
||||
// overrides of the add-on.
|
||||
function insertAdditionalData() {
|
||||
let stmts = [];
|
||||
|
||||
// Initialize statement and parameters for inserting an array
|
||||
@ -1696,11 +1919,15 @@ var AddonDatabase = {
|
||||
stmts.push(stmt);
|
||||
}
|
||||
|
||||
// Initialize statements to insert developers and screenshots
|
||||
// Initialize statements to insert developers, screenshots, and
|
||||
// compatibility overrides
|
||||
initializeArrayInsert("insertDeveloper", aAddon.developers,
|
||||
self._addDeveloperParams);
|
||||
initializeArrayInsert("insertScreenshot", aAddon.screenshots,
|
||||
self._addScreenshotParams);
|
||||
initializeArrayInsert("insertCompatibilityOverride",
|
||||
aAddon.compatibilityOverrides,
|
||||
self._addCompatOverrideParams);
|
||||
|
||||
// Immediately call callback if nothing to insert
|
||||
if (stmts.length == 0) {
|
||||
@ -1714,7 +1941,7 @@ var AddonDatabase = {
|
||||
handleError: self.asyncErrorLogger,
|
||||
handleCompletion: function(aReason) {
|
||||
if (aReason != Ci.mozIStorageStatementCallback.REASON_FINISHED) {
|
||||
ERROR("Error inserting developers and screenshots into database. Attempting to continue");
|
||||
ERROR("Error inserting additional addon metadata into database. Attempting to continue");
|
||||
self.connection.rollbackTransaction();
|
||||
}
|
||||
else {
|
||||
@ -1740,7 +1967,7 @@ var AddonDatabase = {
|
||||
}
|
||||
|
||||
internal_id = self.connection.lastInsertRowID;
|
||||
insertDevelopersAndScreenshots();
|
||||
insertAdditionalData();
|
||||
}
|
||||
});
|
||||
},
|
||||
@ -1826,6 +2053,35 @@ var AddonDatabase = {
|
||||
aParams.addParams(bp);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add compatibility override parameters to the specified
|
||||
* mozIStorageBindingParamsArray.
|
||||
*
|
||||
* @param aParams
|
||||
* The mozIStorageBindingParamsArray to add the parameters to
|
||||
* @param aInternalID
|
||||
* The internal_id of the add-on that this override is for
|
||||
* @param aOverride
|
||||
* The override to make the parameters from
|
||||
* @param aIndex
|
||||
* The index of this override
|
||||
*/
|
||||
_addCompatOverrideParams: function AD_addCompatOverrideParams(aParams,
|
||||
aInternalID,
|
||||
aOverride,
|
||||
aIndex) {
|
||||
let bp = aParams.newBindingParams();
|
||||
bp.bindByName("addon_internal_id", aInternalID);
|
||||
bp.bindByName("num", aIndex);
|
||||
bp.bindByName("type", aOverride.type);
|
||||
bp.bindByName("minVersion", aOverride.minVersion);
|
||||
bp.bindByName("maxVersion", aOverride.maxVersion);
|
||||
bp.bindByName("appID", aOverride.appID);
|
||||
bp.bindByName("appMinVersion", aOverride.appMinVersion);
|
||||
bp.bindByName("appMaxVersion", aOverride.appMaxVersion);
|
||||
aParams.addParams(bp);
|
||||
},
|
||||
|
||||
/**
|
||||
* Make add-on from an asynchronous row
|
||||
* Note: This add-on will be lacking both developers and screenshots
|
||||
@ -1894,6 +2150,28 @@ var AddonDatabase = {
|
||||
thumbnailWidth, thumbnailHeight, caption);
|
||||
},
|
||||
|
||||
/**
|
||||
* Make a CompatibilityOverride from an asynchronous row
|
||||
*
|
||||
* @param aRow
|
||||
* The asynchronous row to use
|
||||
* @return The created CompatibilityOverride
|
||||
*/
|
||||
_makeCompatOverrideFromAsyncRow: function AD_makeCompatOverrideFromAsyncRow(aRow) {
|
||||
let type = aRow.getResultByName("type");
|
||||
let minVersion = aRow.getResultByName("minVersion");
|
||||
let maxVersion = aRow.getResultByName("maxVersion");
|
||||
let appID = aRow.getResultByName("appID");
|
||||
let appMinVersion = aRow.getResultByName("appMinVersion");
|
||||
let appMaxVersion = aRow.getResultByName("appMaxVersion");
|
||||
return new AddonManagerPrivate.AddonCompatibilityOverride(type,
|
||||
minVersion,
|
||||
maxVersion,
|
||||
appID,
|
||||
appMinVersion,
|
||||
appMaxVersion);
|
||||
},
|
||||
|
||||
/**
|
||||
* Synchronously creates the schema in the database.
|
||||
*/
|
||||
@ -1950,13 +2228,19 @@ var AddonDatabase = {
|
||||
"caption TEXT, " +
|
||||
"PRIMARY KEY (addon_internal_id, num)");
|
||||
|
||||
this._createIndices();
|
||||
this.connection.createTable("compatibility_override",
|
||||
"addon_internal_id INTEGER, " +
|
||||
"num INTEGER, " +
|
||||
"type TEXT, " +
|
||||
"minVersion TEXT, " +
|
||||
"maxVersion TEXT, " +
|
||||
"appID TEXT, " +
|
||||
"appMinVersion TEXT, " +
|
||||
"appMaxVersion TEXT, " +
|
||||
"PRIMARY KEY (addon_internal_id, num)");
|
||||
|
||||
this.connection.executeSimpleSQL("CREATE TRIGGER delete_addon AFTER DELETE " +
|
||||
"ON addon BEGIN " +
|
||||
"DELETE FROM developer WHERE addon_internal_id=old.internal_id; " +
|
||||
"DELETE FROM screenshot WHERE addon_internal_id=old.internal_id; " +
|
||||
"END");
|
||||
this._createIndices();
|
||||
this._createTriggers();
|
||||
|
||||
this.connection.schemaVersion = DB_SCHEMA;
|
||||
this.connection.commitTransaction();
|
||||
@ -1968,6 +2252,19 @@ var AddonDatabase = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Synchronously creates the triggers in the database.
|
||||
*/
|
||||
_createTriggers: function AD__createTriggers() {
|
||||
this.connection.executeSimpleSQL("DROP TRIGGER IF EXISTS delete_addon");
|
||||
this.connection.executeSimpleSQL("CREATE TRIGGER delete_addon AFTER DELETE " +
|
||||
"ON addon BEGIN " +
|
||||
"DELETE FROM developer WHERE addon_internal_id=old.internal_id; " +
|
||||
"DELETE FROM screenshot WHERE addon_internal_id=old.internal_id; " +
|
||||
"DELETE FROM compatibility_override WHERE addon_internal_id=old.internal_id; " +
|
||||
"END");
|
||||
},
|
||||
|
||||
/**
|
||||
* Synchronously creates the indices in the database.
|
||||
*/
|
||||
@ -1976,5 +2273,7 @@ var AddonDatabase = {
|
||||
"ON developer (addon_internal_id)");
|
||||
this.connection.executeSimpleSQL("CREATE INDEX IF NOT EXISTS screenshot_idx " +
|
||||
"ON screenshot (addon_internal_id)");
|
||||
this.connection.executeSimpleSQL("CREATE INDEX IF NOT EXISTS compatibility_override_idx " +
|
||||
"ON compatibility_override (addon_internal_id)");
|
||||
}
|
||||
};
|
||||
|
@ -21,6 +21,7 @@
|
||||
#
|
||||
# Contributor(s):
|
||||
# Dave Townsend <dtownsend@oxymoronical.com>
|
||||
# Blair McBride <bmcbride@mozilla.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@ -61,6 +62,7 @@ const XMLURI_PARSE_ERROR = "http://www.mozilla.org/newlayout/xml/parsererror.
|
||||
const PREF_UPDATE_REQUIREBUILTINCERTS = "extensions.update.requireBuiltInCerts";
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
Components.utils.import("resource://gre/modules/AddonRepository.jsm");
|
||||
// shared code for suppressing bad cert dialogs
|
||||
Components.utils.import("resource://gre/modules/CertUtils.jsm");
|
||||
|
||||
@ -393,6 +395,7 @@ function parseRDFManifest(aId, aType, aUpdateKey, aRequest) {
|
||||
updateURL: getProperty(ds, targetApp, "updateLink"),
|
||||
updateHash: getProperty(ds, targetApp, "updateHash"),
|
||||
updateInfoURL: getProperty(ds, targetApp, "updateInfoURL"),
|
||||
strictCompatibility: getProperty(ds, targetApp, "strictCompatibility") == "true",
|
||||
targetApplications: [appEntry]
|
||||
};
|
||||
|
||||
@ -594,19 +597,39 @@ UpdateParser.prototype = {
|
||||
* The application version to use
|
||||
* @param aPlatformVersion
|
||||
* The platform version to use
|
||||
* @param aIgnoreMaxVersion
|
||||
* Ignore maxVersion when testing if an update matches. Optional.
|
||||
* @param aIgnoreStrictCompat
|
||||
* Ignore strictCompatibility when testing if an update matches. Optional.
|
||||
* @param aCompatOverrides
|
||||
* AddonCompatibilityOverride objects to match against. Optional.
|
||||
* @return true if the update is compatible with the application/platform
|
||||
*/
|
||||
function matchesVersions(aUpdate, aAppVersion, aPlatformVersion) {
|
||||
function matchesVersions(aUpdate, aAppVersion, aPlatformVersion,
|
||||
aIgnoreMaxVersion, aIgnoreStrictCompat,
|
||||
aCompatOverrides) {
|
||||
if (aCompatOverrides) {
|
||||
let override = AddonRepository.findMatchingCompatOverride(aUpdate.version,
|
||||
aCompatOverrides,
|
||||
aAppVersion,
|
||||
aPlatformVersion);
|
||||
if (override && override.type == "incompatible")
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aUpdate.strictCompatibility && !aIgnoreStrictCompat)
|
||||
aIgnoreMaxVersion = false;
|
||||
|
||||
let result = false;
|
||||
for (let i = 0; i < aUpdate.targetApplications.length; i++) {
|
||||
let app = aUpdate.targetApplications[i];
|
||||
if (app.id == Services.appinfo.ID) {
|
||||
return (Services.vc.compare(aAppVersion, app.minVersion) >= 0) &&
|
||||
(Services.vc.compare(aAppVersion, app.maxVersion) <= 0);
|
||||
(aIgnoreMaxVersion || (Services.vc.compare(aAppVersion, app.maxVersion) <= 0));
|
||||
}
|
||||
if (app.id == TOOLKIT_ID) {
|
||||
result = (Services.vc.compare(aPlatformVersion, app.minVersion) >= 0) &&
|
||||
(Services.vc.compare(aPlatformVersion, app.maxVersion) <= 0);
|
||||
(aIgnoreMaxVersion || (Services.vc.compare(aPlatformVersion, app.maxVersion) <= 0));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@ -640,12 +663,18 @@ var AddonUpdateChecker = {
|
||||
* The version of the application or null to use the current version
|
||||
* @param aPlatformVersion
|
||||
* The version of the platform or null to use the current version
|
||||
* @param aIgnoreMaxVersion
|
||||
* Ignore maxVersion when testing if an update matches. Optional.
|
||||
* @param aIgnoreStrictCompat
|
||||
* Ignore strictCompatibility when testing if an update matches. Optional.
|
||||
* @return an update object if one matches or null if not
|
||||
*/
|
||||
getCompatibilityUpdate: function AUC_getCompatibilityUpdate(aUpdates, aVersion,
|
||||
aIgnoreCompatibility,
|
||||
aAppVersion,
|
||||
aPlatformVersion) {
|
||||
aPlatformVersion,
|
||||
aIgnoreMaxVersion,
|
||||
aIgnoreStrictCompat) {
|
||||
if (!aAppVersion)
|
||||
aAppVersion = Services.appinfo.version;
|
||||
if (!aPlatformVersion)
|
||||
@ -660,7 +689,8 @@ var AddonUpdateChecker = {
|
||||
return aUpdates[i];
|
||||
}
|
||||
}
|
||||
else if (matchesVersions(aUpdates[i], aAppVersion, aPlatformVersion)) {
|
||||
else if (matchesVersions(aUpdates[i], aAppVersion, aPlatformVersion,
|
||||
aIgnoreMaxVersion, aIgnoreStrictCompat)) {
|
||||
return aUpdates[i];
|
||||
}
|
||||
}
|
||||
@ -677,11 +707,20 @@ var AddonUpdateChecker = {
|
||||
* The version of the application or null to use the current version
|
||||
* @param aPlatformVersion
|
||||
* The version of the platform or null to use the current version
|
||||
* @param aIgnoreMaxVersion
|
||||
* When determining compatible updates, ignore maxVersion. Optional.
|
||||
* @param aIgnoreMaxVersion
|
||||
* When determining compatible updates, ignore strictCompatibility. Optional.
|
||||
* @param aCompatOverrides
|
||||
* Array of AddonCompatibilityOverride to take into account. Optional.
|
||||
* @return an update object if one matches or null if not
|
||||
*/
|
||||
getNewestCompatibleUpdate: function AUC_getNewestCompatibleUpdate(aUpdates,
|
||||
aAppVersion,
|
||||
aPlatformVersion) {
|
||||
aPlatformVersion,
|
||||
aIgnoreMaxVersion,
|
||||
aIgnoreStrictCompat,
|
||||
aCompatOverrides) {
|
||||
if (!aAppVersion)
|
||||
aAppVersion = Services.appinfo.version;
|
||||
if (!aPlatformVersion)
|
||||
@ -699,8 +738,11 @@ var AddonUpdateChecker = {
|
||||
if (state != Ci.nsIBlocklistService.STATE_NOT_BLOCKED)
|
||||
continue;
|
||||
if ((newest == null || (Services.vc.compare(newest.version, aUpdates[i].version) < 0)) &&
|
||||
matchesVersions(aUpdates[i], aAppVersion, aPlatformVersion))
|
||||
matchesVersions(aUpdates[i], aAppVersion, aPlatformVersion,
|
||||
aIgnoreMaxVersion, aIgnoreStrictCompat,
|
||||
aCompatOverrides)) {
|
||||
newest = aUpdates[i];
|
||||
}
|
||||
}
|
||||
return newest;
|
||||
},
|
||||
|
@ -1174,6 +1174,13 @@ function escapeAddonURI(aAddon, aUri, aUpdateType, aAppVersion)
|
||||
maxVersion = "";
|
||||
uri = uri.replace(/%ITEM_MAXAPPVERSION%/g, maxVersion);
|
||||
|
||||
let compatMode = "normal";
|
||||
if (!XPIProvider.checkCompatibility)
|
||||
compatMode = "ignore";
|
||||
else if (AddonManager.strictCompatibility)
|
||||
compatMode = "strict";
|
||||
uri = uri.replace(/%COMPATIBILITY_MODE%/g, compatMode);
|
||||
|
||||
// Replace custom parameters (names of custom parameters must have at
|
||||
// least 3 characters to prevent lookups for something like %D0%C8)
|
||||
var catMan = null;
|
||||
@ -3346,6 +3353,36 @@ var XPIProvider = {
|
||||
}, this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the repositoryAddon property for all add-ons.
|
||||
*
|
||||
* @param aCallback
|
||||
* Function to call when operation is complete.
|
||||
*/
|
||||
updateAddonRepositoryData: function XPI_updateAddonRepositoryData(aCallback) {
|
||||
let self = this;
|
||||
XPIDatabase.getVisibleAddons(null, function UARD_getVisibleAddonsCallback(aAddons) {
|
||||
let pending = aAddons.length;
|
||||
function notifyComplete() {
|
||||
if (--pending == 0)
|
||||
aCallback();
|
||||
}
|
||||
|
||||
aAddons.forEach(function UARD_forEachCallback(aAddon) {
|
||||
AddonRepository.getCachedAddonByID(aAddon.id,
|
||||
function UARD_getCachedAddonCallback(aRepoAddon) {
|
||||
if (aRepoAddon) {
|
||||
aAddon._repositoryAddon = aRepoAddon;
|
||||
aAddon.compatibilityOverrides = aRepoAddon.compatibilityOverrides;
|
||||
self.updateAddonDisabledState(aAddon);
|
||||
}
|
||||
|
||||
notifyComplete();
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* When the previously selected theme is removed this method will be called
|
||||
* to enable the default theme.
|
||||
@ -4052,6 +4089,9 @@ AsyncAddonListCallback.prototype = {
|
||||
XPIDatabase.makeAddonFromRowAsync(row, function(aAddon) {
|
||||
function completeAddon(aRepositoryAddon) {
|
||||
aAddon._repositoryAddon = aRepositoryAddon;
|
||||
aAddon.compatibilityOverrides = aRepositoryAddon ?
|
||||
aRepositoryAddon.compatibilityOverrides :
|
||||
null;
|
||||
self.addons.push(aAddon);
|
||||
if (self.complete && self.addons.length == self.count)
|
||||
self.callback(self.addons);
|
||||
@ -6152,6 +6192,7 @@ AddonInstall.prototype = {
|
||||
AddonRepository.getCachedAddonByID(aAddon.id, function(aRepoAddon) {
|
||||
if (aRepoAddon) {
|
||||
aAddon._repositoryAddon = aRepoAddon;
|
||||
aAddon.compatibilityOverrides = aRepoAddon.compatibilityOverrides;
|
||||
aCallback();
|
||||
return;
|
||||
}
|
||||
@ -6160,6 +6201,9 @@ AddonInstall.prototype = {
|
||||
AddonRepository.cacheAddons([aAddon.id], function() {
|
||||
AddonRepository.getCachedAddonByID(aAddon.id, function(aRepoAddon) {
|
||||
aAddon._repositoryAddon = aRepoAddon;
|
||||
aAddon.compatibilityOverrides = aRepoAddon ?
|
||||
aRepoAddon.compatibilityOverrides :
|
||||
null;
|
||||
aCallback();
|
||||
});
|
||||
});
|
||||
@ -6970,10 +7014,24 @@ UpdateChecker.prototype = {
|
||||
onUpdateCheckComplete: function UC_onUpdateCheckComplete(aUpdates) {
|
||||
let AUC = AddonUpdateChecker;
|
||||
|
||||
let ignoreMaxVersion = false;
|
||||
let ignoreStrictCompat = false;
|
||||
if (!XPIProvider.checkCompatibility) {
|
||||
ignoreMaxVersion = true;
|
||||
ignoreStrictCompat = true;
|
||||
} else if (this.addon.type == "extension" &&
|
||||
!AddonManager.strictCompatibility &&
|
||||
!this.addon.strictCompatibility &&
|
||||
!this.addon.hasBinaryComponents) {
|
||||
ignoreMaxVersion = true;
|
||||
}
|
||||
|
||||
// Always apply any compatibility update for the current version
|
||||
let compatUpdate = AUC.getCompatibilityUpdate(aUpdates, this.addon.version,
|
||||
this.syncCompatibility);
|
||||
|
||||
this.syncCompatibility,
|
||||
null, null,
|
||||
ignoreMaxVersion,
|
||||
ignoreStrictCompat);
|
||||
// Apply the compatibility update to the database
|
||||
if (compatUpdate)
|
||||
this.addon.applyCompatibilityUpdate(compatUpdate, this.syncCompatibility);
|
||||
@ -6987,7 +7045,9 @@ UpdateChecker.prototype = {
|
||||
Services.vc.compare(this.platformVersion, Services.appinfo.platformVersion) != 0)) {
|
||||
compatUpdate = AUC.getCompatibilityUpdate(aUpdates, this.addon.version,
|
||||
false, this.appVersion,
|
||||
this.platformVersion);
|
||||
this.platformVersion,
|
||||
ignoreMaxVersion,
|
||||
ignoreStrictCompat);
|
||||
}
|
||||
|
||||
if (compatUpdate)
|
||||
@ -7007,9 +7067,16 @@ UpdateChecker.prototype = {
|
||||
AddonManager.UPDATE_STATUS_NO_ERROR);
|
||||
}
|
||||
|
||||
let compatOverrides = AddonManager.strictCompatibility ?
|
||||
null :
|
||||
this.addon.compatibilityOverrides;
|
||||
|
||||
let update = AUC.getNewestCompatibleUpdate(aUpdates,
|
||||
this.appVersion,
|
||||
this.platformVersion);
|
||||
this.platformVersion,
|
||||
ignoreMaxVersion,
|
||||
ignoreStrictCompat,
|
||||
compatOverrides);
|
||||
|
||||
if (update && Services.vc.compare(this.addon.version, update.version) < 0) {
|
||||
for (let i = 0; i < XPIProvider.installs.length; i++) {
|
||||
@ -7149,6 +7216,17 @@ AddonInternal.prototype = {
|
||||
if (this.type == "extension" && !AddonManager.strictCompatibility &&
|
||||
!this.strictCompatibility && !this.hasBinaryComponents) {
|
||||
|
||||
// The repository can specify compatibility overrides.
|
||||
// Note: For now, only blacklisting is supported by overrides.
|
||||
if (this._repositoryAddon &&
|
||||
this._repositoryAddon.compatibilityOverrides) {
|
||||
let overrides = this._repositoryAddon.compatibilityOverrides;
|
||||
let override = AddonRepository.findMatchingCompatOverride(this.version,
|
||||
overrides);
|
||||
if (override && override.type == "incompatible")
|
||||
return false;
|
||||
}
|
||||
|
||||
// Extremely old extensions should not be compatible by default.
|
||||
let minCompatVersion;
|
||||
if (app.id == Services.appinfo.ID)
|
||||
@ -7252,7 +7330,7 @@ AddonInternal.prototype = {
|
||||
importMetadata: function(aObj) {
|
||||
["targetApplications", "userDisabled", "softDisabled", "existingAddonID",
|
||||
"sourceURI", "releaseNotesURI", "installDate", "updateDate",
|
||||
"applyBackgroundUpdates"].forEach(function(aProp) {
|
||||
"applyBackgroundUpdates", "compatibilityOverrides"].forEach(function(aProp) {
|
||||
if (!(aProp in aObj))
|
||||
return;
|
||||
|
||||
@ -7368,7 +7446,7 @@ function AddonWrapper(aAddon) {
|
||||
["id", "syncGUID", "version", "type", "isCompatible", "isPlatformCompatible",
|
||||
"providesUpdatesSecurely", "blocklistState", "blocklistURL", "appDisabled",
|
||||
"softDisabled", "skinnable", "size", "foreignInstall", "hasBinaryComponents",
|
||||
"strictCompatibility"].forEach(function(aProp) {
|
||||
"strictCompatibility", "compatibilityOverrides"].forEach(function(aProp) {
|
||||
this.__defineGetter__(aProp, function() aAddon[aProp]);
|
||||
}, this);
|
||||
|
||||
|
@ -39,6 +39,7 @@ function test() {
|
||||
requestLongerTimeout(2);
|
||||
// Turn on searching for this test
|
||||
Services.prefs.setIntPref(PREF_SEARCH_MAXRESULTS, 15);
|
||||
Services.prefs.setBoolPref(PREF_STRICT_COMPAT, true);
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
@ -621,6 +622,28 @@ add_test(function() {
|
||||
});
|
||||
});
|
||||
|
||||
// Tests that compatible-by-default addons are shown if strict compatibility checking is disabled
|
||||
add_test(function() {
|
||||
restart_manager(gManagerWindow, null, function(aWindow) {
|
||||
gManagerWindow = aWindow;
|
||||
gCategoryUtilities = new CategoryUtilities(gManagerWindow);
|
||||
|
||||
Services.prefs.setBoolPref(PREF_STRICT_COMPAT, false);
|
||||
search("incompatible", false, function() {
|
||||
var item = get_addon_item("remote5");
|
||||
is_element_visible(item, "Incompatible addon should be visible");
|
||||
isnot(item.getAttribute("notification"), "warning", "Compatibility warning should not be shown");
|
||||
|
||||
var item = get_addon_item("remote6");
|
||||
is(item, null, "Addon incompatible with the product should not be visible");
|
||||
|
||||
Services.prefs.setBoolPref(PREF_STRICT_COMPAT, true);
|
||||
run_next_test();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// Tests that restarting the manager doesn't change search results
|
||||
add_test(function() {
|
||||
restart_manager(gManagerWindow, null, function(aWindow) {
|
||||
|
@ -122,8 +122,6 @@ function setupUI(aFailDownloads, aFailInstalls, aCallback) {
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
requestLongerTimeout(100);
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
|
@ -115,5 +115,68 @@
|
||||
</preview>
|
||||
</previews>
|
||||
</addon>
|
||||
|
||||
<addon_compatibility hosted="true" id="123">
|
||||
<guid>test_AddonRepository_1@tests.mozilla.org</guid>
|
||||
<name>PASS</name>
|
||||
<version_ranges>
|
||||
<!-- Will be included -->
|
||||
<version_range type="incompatible">
|
||||
<min_version>0.1</min_version>
|
||||
<max_version>0.2</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>XPCShell</name>
|
||||
<application_id>666</application_id>
|
||||
<min_version>3.0</min_version>
|
||||
<max_version>4.0</max_version>
|
||||
<appID>xpcshell@tests.mozilla.org</appID>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
<!-- Will be included -->
|
||||
<version_range type="incompatible">
|
||||
<min_version>0.2</min_version>
|
||||
<max_version>0.3</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>XPCShell</name>
|
||||
<application_id>666</application_id>
|
||||
<min_version>5.0</min_version>
|
||||
<max_version>6.0</max_version>
|
||||
<appID>xpcshell@tests.mozilla.org</appID>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
<!-- Won't be included - invalid type attribute -->
|
||||
<version_range type="unknown">
|
||||
<min_version>9</min_version>
|
||||
<max_version>10</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>XPCShell</name>
|
||||
<application_id>666</application_id>
|
||||
<min_version>10.0</min_version>
|
||||
<max_version>11.0</max_version>
|
||||
<appID>xpcshell@tests.mozilla.org</appID>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
<!-- Won't be included - no matching appID -->
|
||||
<version_range type="incompatible">
|
||||
<min_version>0.2</min_version>
|
||||
<max_version>0.3</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>Unknown App</name>
|
||||
<application_id>123</application_id>
|
||||
<min_version>1.0</min_version>
|
||||
<max_version>999.0</max_version>
|
||||
<appID>unknown-app@tests.mozilla.org</appID>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
</version_ranges>
|
||||
</addon_compatibility>
|
||||
</searchresults>
|
||||
|
||||
|
@ -62,6 +62,69 @@
|
||||
<install size="5555">http://localhost:4444/addons/test_AddonRepository_2.xpi</install>
|
||||
</addon>
|
||||
|
||||
<addon_compatibility hosted="true" id="123">
|
||||
<guid>test1@tests.mozilla.org</guid>
|
||||
<name>PASS</name>
|
||||
<version_ranges>
|
||||
<!-- Will be included -->
|
||||
<version_range type="incompatible">
|
||||
<min_version>0.1</min_version>
|
||||
<max_version>0.2</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>XPCShell</name>
|
||||
<application_id>666</application_id>
|
||||
<min_version>3.0</min_version>
|
||||
<max_version>4.0</max_version>
|
||||
<appID>xpcshell@tests.mozilla.org</appID>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
<!-- Will be included -->
|
||||
<version_range type="incompatible">
|
||||
<min_version>0.2</min_version>
|
||||
<max_version>0.3</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>XPCShell</name>
|
||||
<application_id>666</application_id>
|
||||
<min_version>5.0</min_version>
|
||||
<max_version>6.0</max_version>
|
||||
<appID>xpcshell@tests.mozilla.org</appID>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
<!-- Won't be included - invalid type attribute -->
|
||||
<version_range type="unknown">
|
||||
<min_version>9</min_version>
|
||||
<max_version>10</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>XPCShell</name>
|
||||
<application_id>666</application_id>
|
||||
<min_version>10.0</min_version>
|
||||
<max_version>11.0</max_version>
|
||||
<appID>xpcshell@tests.mozilla.org</appID>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
<!-- Won't be included - no matching appID -->
|
||||
<version_range type="incompatible">
|
||||
<min_version>0.2</min_version>
|
||||
<max_version>0.3</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>Unknown App</name>
|
||||
<application_id>123</application_id>
|
||||
<min_version>1.0</min_version>
|
||||
<max_version>999.0</max_version>
|
||||
<appID>unknown-app@tests.mozilla.org</appID>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
</version_ranges>
|
||||
</addon_compatibility>
|
||||
|
||||
<!-- Fails because guid matches previously successful result -->
|
||||
<addon>
|
||||
<name>FAIL</name>
|
||||
|
@ -0,0 +1,228 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<searchresults total_results="9">
|
||||
<addon>
|
||||
<name>Test addon 2</name>
|
||||
<type id="1">Extension</type>
|
||||
<guid>addon2@tests.mozilla.org</guid>
|
||||
<version>1.0</version>
|
||||
</addon>
|
||||
|
||||
<addon>
|
||||
<name>Test addon 3</name>
|
||||
<type id="1">Extension</type>
|
||||
<guid>addon3@tests.mozilla.org</guid>
|
||||
<version>1.0</version>
|
||||
</addon>
|
||||
<addon_compatibility hosted="true">
|
||||
<name>Test addon 3</name>
|
||||
<guid>addon3@tests.mozilla.org</guid>
|
||||
<version_ranges>
|
||||
<version_range type="incompatible">
|
||||
<min_version>0.9</min_version>
|
||||
<max_version>1.0</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>XPCShell</name>
|
||||
<appID>xpcshell@tests.mozilla.org</appID>
|
||||
<min_version>1</min_version>
|
||||
<max_version>2</max_version>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
</version_ranges>
|
||||
</addon_compatibility>
|
||||
|
||||
<addon>
|
||||
<name>Test addon 4</name>
|
||||
<type id="1">Extension</type>
|
||||
<guid>addon4@tests.mozilla.org</guid>
|
||||
<version>1.0</version>
|
||||
</addon>
|
||||
<addon_compatibility hosted="true">
|
||||
<name>Test addon 4</name>
|
||||
<guid>addon4@tests.mozilla.org</guid>
|
||||
<version_ranges>
|
||||
<version_range type="incompatible">
|
||||
<min_version>0.9</min_version>
|
||||
<max_version>1.0</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>XPCShell</name>
|
||||
<appID>xpcshell@tests.mozilla.org</appID>
|
||||
<min_version>1</min_version>
|
||||
<max_version>2</max_version>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
</version_ranges>
|
||||
</addon_compatibility>
|
||||
|
||||
<addon>
|
||||
<name>Test addon 5</name>
|
||||
<type id="1">Extension</type>
|
||||
<guid>addon5@tests.mozilla.org</guid>
|
||||
<version>1.0</version>
|
||||
</addon>
|
||||
<addon_compatibility hosted="true">
|
||||
<name>Test addon 5</name>
|
||||
<guid>addon5@tests.mozilla.org</guid>
|
||||
<version_ranges>
|
||||
<version_range type="incompatible">
|
||||
<min_version>0.9</min_version>
|
||||
<max_version>1.0</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>Unknown App</name>
|
||||
<appID>unknown-app@tests.mozilla.org</appID>
|
||||
<min_version>1</min_version>
|
||||
<max_version>2</max_version>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
</version_ranges>
|
||||
</addon_compatibility>
|
||||
|
||||
<addon>
|
||||
<name>Test addon 6</name>
|
||||
<type id="1">Extension</type>
|
||||
<guid>addon6@tests.mozilla.org</guid>
|
||||
<version>1.0</version>
|
||||
</addon>
|
||||
<addon_compatibility hosted="true">
|
||||
<name>Test addon 6</name>
|
||||
<guid>addon6@tests.mozilla.org</guid>
|
||||
<version_ranges>
|
||||
<version_range type="incompatible">
|
||||
<min_version>0.5</min_version>
|
||||
<max_version>0.9</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>XPCShell</name>
|
||||
<appID>xpcshell@tests.mozilla.org</appID>
|
||||
<min_version>1</min_version>
|
||||
<max_version>2</max_version>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
</version_ranges>
|
||||
</addon_compatibility>
|
||||
|
||||
<addon>
|
||||
<name>Test addon 7</name>
|
||||
<type id="1">Extension</type>
|
||||
<guid>addon7@tests.mozilla.org</guid>
|
||||
<version>1.0</version>
|
||||
</addon>
|
||||
<addon_compatibility hosted="true">
|
||||
<name>Test addon 7</name>
|
||||
<guid>addon7@tests.mozilla.org</guid>
|
||||
<version_ranges>
|
||||
<version_range type="incompatible">
|
||||
<min_version>0.5</min_version>
|
||||
<max_version>1.0</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>XPCShell</name>
|
||||
<appID>xpcshell@tests.mozilla.org</appID>
|
||||
<min_version>0.1</min_version>
|
||||
<max_version>0.9</max_version>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
</version_ranges>
|
||||
</addon_compatibility>
|
||||
|
||||
<addon>
|
||||
<name>Test addon 8</name>
|
||||
<type id="1">Extension</type>
|
||||
<guid>addon8@tests.mozilla.org</guid>
|
||||
<version>1.0</version>
|
||||
</addon>
|
||||
<addon_compatibility hosted="true">
|
||||
<name>Test addon 8</name>
|
||||
<guid>addon8@tests.mozilla.org</guid>
|
||||
<version_ranges>
|
||||
<version_range type="incompatible">
|
||||
<min_version>6</min_version>
|
||||
<max_version>6.2</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>XPCShell</name>
|
||||
<appID>xpcshell@tests.mozilla.org</appID>
|
||||
<min_version>0.9</min_version>
|
||||
<max_version>9</max_version>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
<version_range type="incompatible">
|
||||
<min_version>0.5</min_version>
|
||||
<max_version>1.0</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>XPCShell</name>
|
||||
<appID>xpcshell@tests.mozilla.org</appID>
|
||||
<min_version>0.1</min_version>
|
||||
<max_version>9</max_version>
|
||||
</application>
|
||||
<application>
|
||||
<name>Unknown app</name>
|
||||
<appID>unknown-app@tests.mozilla.org</appID>
|
||||
<min_version>0.1</min_version>
|
||||
<max_version>9</max_version>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
<version_range type="incompatible">
|
||||
<min_version>0.1</min_version>
|
||||
<max_version>0.2</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>XPCShell</name>
|
||||
<appID>xpcshell@tests.mozilla.org</appID>
|
||||
<min_version>0.1</min_version>
|
||||
<max_version>0.9</max_version>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
</version_ranges>
|
||||
</addon_compatibility>
|
||||
|
||||
<addon_compatibility hosted="false">
|
||||
<name>Test addon 9</name>
|
||||
<guid>addon9@tests.mozilla.org</guid>
|
||||
<version_ranges>
|
||||
<version_range type="incompatible">
|
||||
<min_version>0.5</min_version>
|
||||
<max_version>1.0</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>XPCShell</name>
|
||||
<appID>xpcshell@tests.mozilla.org</appID>
|
||||
<min_version>1</min_version>
|
||||
<max_version>2</max_version>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
</version_ranges>
|
||||
</addon_compatibility>
|
||||
|
||||
<addon_compatibility hosted="false">
|
||||
<name>Test addon 10</name>
|
||||
<guid>addon10@tests.mozilla.org</guid>
|
||||
<version_ranges>
|
||||
<version_range type="compatible">
|
||||
<min_version>0.5</min_version>
|
||||
<max_version>1.0</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>XPCShell</name>
|
||||
<appID>xpcshell@tests.mozilla.org</appID>
|
||||
<min_version>1</min_version>
|
||||
<max_version>2</max_version>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
</version_ranges>
|
||||
</addon_compatibility>
|
||||
|
||||
</searchresults>
|
@ -144,4 +144,107 @@
|
||||
</Seq>
|
||||
</em:updates>
|
||||
</Description>
|
||||
|
||||
<Description about="urn:mozilla:extension:addon9@tests.mozilla.org">
|
||||
<em:updates>
|
||||
<Seq>
|
||||
<li>
|
||||
<Description>
|
||||
<em:version>2.0</em:version>
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>xpcshell@tests.mozilla.org</em:id>
|
||||
<em:minVersion>1</em:minVersion>
|
||||
<em:maxVersion>1</em:maxVersion>
|
||||
<em:updateLink>http://localhost:4444/addons/test_update9_2.xpi</em:updateLink>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
</Description>
|
||||
</li>
|
||||
<!-- Incompatible when strict compatibility is enabled -->
|
||||
<li>
|
||||
<Description>
|
||||
<em:version>3.0</em:version>
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>xpcshell@tests.mozilla.org</em:id>
|
||||
<em:minVersion>0.9</em:minVersion>
|
||||
<em:maxVersion>0.9</em:maxVersion>
|
||||
<em:updateLink>http://localhost:4444/addons/test_update9_3.xpi</em:updateLink>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
</Description>
|
||||
</li>
|
||||
<!-- Incompatible due to compatibility override -->
|
||||
<li>
|
||||
<Description>
|
||||
<em:version>4.0</em:version>
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>xpcshell@tests.mozilla.org</em:id>
|
||||
<em:minVersion>0.9</em:minVersion>
|
||||
<em:maxVersion>0.9</em:maxVersion>
|
||||
<em:updateLink>http://localhost:4444/addons/test_update9_4.xpi</em:updateLink>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
</Description>
|
||||
</li>
|
||||
<!-- Addon for future version of app -->
|
||||
<li>
|
||||
<Description>
|
||||
<em:version>5.0</em:version>
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>xpcshell@tests.mozilla.org</em:id>
|
||||
<em:minVersion>5</em:minVersion>
|
||||
<em:maxVersion>6</em:maxVersion>
|
||||
<em:updateLink>http://localhost:4444/addons/test_update9_5.xpi</em:updateLink>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
</Description>
|
||||
</li>
|
||||
</Seq>
|
||||
</em:updates>
|
||||
</Description>
|
||||
|
||||
<Description about="urn:mozilla:extension:addon10@tests.mozilla.org">
|
||||
<em:updates>
|
||||
<Seq>
|
||||
<li>
|
||||
<Description>
|
||||
<em:version>1.0</em:version>
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>xpcshell@tests.mozilla.org</em:id>
|
||||
<em:minVersion>0.1</em:minVersion>
|
||||
<em:maxVersion>0.4</em:maxVersion>
|
||||
<em:updateLink>http://localhost:4444/addons/test_update10.xpi</em:updateLink>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
</Description>
|
||||
</li>
|
||||
</Seq>
|
||||
</em:updates>
|
||||
</Description>
|
||||
|
||||
<Description about="urn:mozilla:extension:addon11@tests.mozilla.org">
|
||||
<em:updates>
|
||||
<Seq>
|
||||
<li>
|
||||
<Description>
|
||||
<em:version>2.0</em:version>
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>xpcshell@tests.mozilla.org</em:id>
|
||||
<em:minVersion>0.1</em:minVersion>
|
||||
<em:maxVersion>0.2</em:maxVersion>
|
||||
<em:strictCompatibility>true</em:strictCompatibility>
|
||||
<em:updateLink>http://localhost:4444/addons/test_update11.xpi</em:updateLink>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
</Description>
|
||||
</li>
|
||||
</Seq>
|
||||
</em:updates>
|
||||
</Description>
|
||||
</RDF>
|
||||
|
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<searchresults total_results="11">
|
||||
<addon>
|
||||
<name>Test Addon 9</name>
|
||||
<type id="1">Extension</type>
|
||||
<guid>addon9@tests.mozilla.org</guid>
|
||||
</addon>
|
||||
<addon_compatibility hosted="true">
|
||||
<guid>addon9@tests.mozilla.org</guid>
|
||||
<name>Test Addon 9</name>
|
||||
<version_ranges>
|
||||
<version_range type="incompatible">
|
||||
<min_version>4</min_version>
|
||||
<max_version>4</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>XPCShell</name>
|
||||
<min_version>1</min_version>
|
||||
<max_version>1</max_version>
|
||||
<appID>xpcshell@tests.mozilla.org</appID>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
</version_ranges>
|
||||
</addon_compatibility>
|
||||
</searchresults>
|
@ -296,4 +296,124 @@
|
||||
<RDF:Description about="urn:mozilla:extension:test_bug378216_15@tests.mozilla.org">
|
||||
<em:updates>Foo</em:updates>
|
||||
</RDF:Description>
|
||||
|
||||
<!-- Various updates available - one is not compatible, but compatibility checking is disabled -->
|
||||
<Description about="urn:mozilla:extension:ignore-compat@tests.mozilla.org">
|
||||
<em:updates>
|
||||
<Seq>
|
||||
<li>
|
||||
<Description>
|
||||
<em:version>1.0</em:version>
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>xpcshell@tests.mozilla.org</em:id>
|
||||
<em:minVersion>0.1</em:minVersion>
|
||||
<em:maxVersion>0.2</em:maxVersion>
|
||||
<em:updateLink>https://localhost:4444/addons/test1.xpi</em:updateLink>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
</Description>
|
||||
</li>
|
||||
<li>
|
||||
<Description>
|
||||
<em:version>2.0</em:version>
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>xpcshell@tests.mozilla.org</em:id>
|
||||
<em:minVersion>0.5</em:minVersion>
|
||||
<em:maxVersion>0.6</em:maxVersion>
|
||||
<em:updateLink>https://localhost:4444/addons/test2.xpi</em:updateLink>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
</Description>
|
||||
</li>
|
||||
<!-- Update for future app versions - should never be compatible -->
|
||||
<li>
|
||||
<Description>
|
||||
<em:version>3.0</em:version>
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>xpcshell@tests.mozilla.org</em:id>
|
||||
<em:minVersion>2</em:minVersion>
|
||||
<em:maxVersion>3</em:maxVersion>
|
||||
<em:updateLink>https://localhost:4444/addons/test3.xpi</em:updateLink>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
</Description>
|
||||
</li>
|
||||
</Seq>
|
||||
</em:updates>
|
||||
</Description>
|
||||
|
||||
<!-- Various updates available - one is not compatible, but compatibility checking is disabled -->
|
||||
<Description about="urn:mozilla:extension:compat-override@tests.mozilla.org">
|
||||
<em:updates>
|
||||
<Seq>
|
||||
<!-- Has compatibility override, but it doesn't match this app version -->
|
||||
<li>
|
||||
<Description>
|
||||
<em:version>1.0</em:version>
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>xpcshell@tests.mozilla.org</em:id>
|
||||
<em:minVersion>0.1</em:minVersion>
|
||||
<em:maxVersion>0.2</em:maxVersion>
|
||||
<em:updateLink>https://localhost:4444/addons/test1.xpi</em:updateLink>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
</Description>
|
||||
</li>
|
||||
<!-- Has compatibility override, so is incompaible -->
|
||||
<li>
|
||||
<Description>
|
||||
<em:version>2.0</em:version>
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>xpcshell@tests.mozilla.org</em:id>
|
||||
<em:minVersion>0.5</em:minVersion>
|
||||
<em:maxVersion>0.6</em:maxVersion>
|
||||
<em:updateLink>https://localhost:4444/addons/test2.xpi</em:updateLink>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
</Description>
|
||||
</li>
|
||||
<!-- Update for future app versions - should never be compatible -->
|
||||
<li>
|
||||
<Description>
|
||||
<em:version>3.0</em:version>
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>xpcshell@tests.mozilla.org</em:id>
|
||||
<em:minVersion>2</em:minVersion>
|
||||
<em:maxVersion>3</em:maxVersion>
|
||||
<em:updateLink>https://localhost:4444/addons/test3.xpi</em:updateLink>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
</Description>
|
||||
</li>
|
||||
</Seq>
|
||||
</em:updates>
|
||||
</Description>
|
||||
|
||||
<!-- Opt-in to strict compatibility checking -->
|
||||
<Description about="urn:mozilla:extension:compat-strict-optin@tests.mozilla.org">
|
||||
<em:updates>
|
||||
<Seq>
|
||||
<li>
|
||||
<Description>
|
||||
<em:version>1.0</em:version>
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>xpcshell@tests.mozilla.org</em:id>
|
||||
<em:minVersion>0.1</em:minVersion>
|
||||
<em:maxVersion>0.2</em:maxVersion>
|
||||
<em:strictCompatibility>true</em:strictCompatibility>
|
||||
<em:updateLink>https://localhost:4444/addons/test1.xpi</em:updateLink>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
</Description>
|
||||
</li>
|
||||
</Seq>
|
||||
</em:updates>
|
||||
</Description>
|
||||
</RDF>
|
||||
|
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
|
||||
<Description about="urn:mozilla:extension:compatmode-ignore@tests.mozilla.org">
|
||||
<em:updates>
|
||||
<Seq>
|
||||
<li>
|
||||
<Description>
|
||||
<em:version>2.0</em:version>
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>xpcshell@tests.mozilla.org</em:id>
|
||||
<em:minVersion>1</em:minVersion>
|
||||
<em:maxVersion>2</em:maxVersion>
|
||||
<em:updateLink>https://localhost:4444/addons/test1.xpi</em:updateLink>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
</Description>
|
||||
</li>
|
||||
</Seq>
|
||||
</em:updates>
|
||||
</Description>
|
||||
</RDF>
|
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
|
||||
<Description about="urn:mozilla:extension:compatmode-normal@tests.mozilla.org">
|
||||
<em:updates>
|
||||
<Seq>
|
||||
<li>
|
||||
<Description>
|
||||
<em:version>2.0</em:version>
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>xpcshell@tests.mozilla.org</em:id>
|
||||
<em:minVersion>1</em:minVersion>
|
||||
<em:maxVersion>2</em:maxVersion>
|
||||
<em:updateLink>https://localhost:4444/addons/test1.xpi</em:updateLink>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
</Description>
|
||||
</li>
|
||||
</Seq>
|
||||
</em:updates>
|
||||
</Description>
|
||||
</RDF>
|
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
|
||||
<Description about="urn:mozilla:extension:compatmode-strict@tests.mozilla.org">
|
||||
<em:updates>
|
||||
<Seq>
|
||||
<li>
|
||||
<Description>
|
||||
<em:version>2.0</em:version>
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>xpcshell@tests.mozilla.org</em:id>
|
||||
<em:minVersion>1</em:minVersion>
|
||||
<em:maxVersion>2</em:maxVersion>
|
||||
<em:updateLink>https://localhost:4444/addons/test1.xpi</em:updateLink>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
</Description>
|
||||
</li>
|
||||
</Seq>
|
||||
</em:updates>
|
||||
</Description>
|
||||
</RDF>
|
@ -244,6 +244,12 @@ function do_check_addon(aActualAddon, aExpectedAddon, aProperties) {
|
||||
do_check_eq(actualValue.getTime(), expectedValue.getTime());
|
||||
break;
|
||||
|
||||
case "compatibilityOverrides":
|
||||
do_check_eq(actualValue.length, expectedValue.length);
|
||||
for (let i = 0; i < actualValue.length; i++)
|
||||
do_check_compatibilityoverride(actualValue[i], expectedValue[i]);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (actualValue !== expectedValue)
|
||||
do_throw("Failed for " + aProperty + " for add-on " + aExpectedAddon.id +
|
||||
@ -285,6 +291,24 @@ function do_check_screenshot(aActual, aExpected) {
|
||||
do_check_eq(aActual.caption, aExpected.caption);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the actual compatibility override is the same as the expected
|
||||
* compatibility override.
|
||||
*
|
||||
* @param aAction
|
||||
* The actual compatibility override to check.
|
||||
* @param aExpected
|
||||
* The expected compatibility override to check against.
|
||||
*/
|
||||
function do_check_compatibilityoverride(aActual, aExpected) {
|
||||
do_check_eq(aActual.type, aExpected.type);
|
||||
do_check_eq(aActual.minVersion, aExpected.minVersion);
|
||||
do_check_eq(aActual.maxVersion, aExpected.maxVersion);
|
||||
do_check_eq(aActual.appID, aExpected.appID);
|
||||
do_check_eq(aActual.appMinVersion, aExpected.appMinVersion);
|
||||
do_check_eq(aActual.appMaxVersion, aExpected.appMaxVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts up the add-on manager as if it was started by the application.
|
||||
*
|
||||
|
@ -36,7 +36,8 @@ var ADDON_PROPERTIES = ["id", "type", "version", "creator", "developers",
|
||||
"averageRating", "reviewCount", "reviewURL",
|
||||
"totalDownloads", "weeklyDownloads", "dailyUsers",
|
||||
"sourceURI", "repositoryStatus", "size", "updateDate",
|
||||
"purchaseURL", "purchaseAmount", "purchaseDisplayAmount"];
|
||||
"purchaseURL", "purchaseAmount", "purchaseDisplayAmount",
|
||||
"compatibilityOverrides"];
|
||||
|
||||
// Results of getAddonsByIDs
|
||||
var GET_RESULTS = [{
|
||||
@ -82,7 +83,22 @@ var GET_RESULTS = [{
|
||||
sourceURI: BASE_URL + INSTALL_URL2,
|
||||
repositoryStatus: 8,
|
||||
size: 5555,
|
||||
updateDate: new Date(1265033045000)
|
||||
updateDate: new Date(1265033045000),
|
||||
compatibilityOverrides: [{
|
||||
type: "incompatible",
|
||||
minVersion: 0.1,
|
||||
maxVersion: 0.2,
|
||||
appID: "xpcshell@tests.mozilla.org",
|
||||
appMinVersion: 3.0,
|
||||
appMaxVersion: 4.0
|
||||
}, {
|
||||
type: "incompatible",
|
||||
minVersion: 0.2,
|
||||
maxVersion: 0.3,
|
||||
appID: "xpcshell@tests.mozilla.org",
|
||||
appMinVersion: 5.0,
|
||||
appMaxVersion: 6.0
|
||||
}]
|
||||
}, {
|
||||
id: "test_AddonRepository_1@tests.mozilla.org",
|
||||
version: "1.4",
|
||||
@ -176,7 +192,8 @@ var SEARCH_RESULTS = [{
|
||||
sourceURI: BASE_URL + "/test3.xpi",
|
||||
repositoryStatus: 8,
|
||||
size: 5555,
|
||||
updateDate: new Date(1265033045000)
|
||||
updateDate: new Date(1265033045000),
|
||||
|
||||
}, {
|
||||
id: "purchase1@tests.mozilla.org",
|
||||
type: "extension",
|
||||
|
@ -39,7 +39,8 @@ const ADDON_PROPERTIES = ["id", "type", "name", "version", "creator",
|
||||
"optionsURL", "aboutURL", "contributionURL",
|
||||
"contributionAmount", "averageRating", "reviewCount",
|
||||
"reviewURL", "totalDownloads", "weeklyDownloads",
|
||||
"dailyUsers", "sourceURI", "repositoryStatus"];
|
||||
"dailyUsers", "sourceURI", "repositoryStatus",
|
||||
"compatibilityOverrides"];
|
||||
|
||||
// The size and updateDate properties are annoying to test for XPI add-ons.
|
||||
// However, since we only care about whether the repository value vs. the
|
||||
@ -90,7 +91,22 @@ const REPOSITORY_ADDONS = [{
|
||||
weeklyDownloads: 3331,
|
||||
dailyUsers: 4441,
|
||||
sourceURI: BASE_URL + "/repo/1/install.xpi",
|
||||
repositoryStatus: 4
|
||||
repositoryStatus: 4,
|
||||
compatibilityOverrides: [{
|
||||
type: "incompatible",
|
||||
minVersion: 0.1,
|
||||
maxVersion: 0.2,
|
||||
appID: "xpcshell@tests.mozilla.org",
|
||||
appMinVersion: 3.0,
|
||||
appMaxVersion: 4.0
|
||||
}, {
|
||||
type: "incompatible",
|
||||
minVersion: 0.2,
|
||||
maxVersion: 0.3,
|
||||
appID: "xpcshell@tests.mozilla.org",
|
||||
appMinVersion: 5.0,
|
||||
appMaxVersion: 6.0
|
||||
}]
|
||||
}, {
|
||||
id: ADDON_IDS[1],
|
||||
type: "theme",
|
||||
@ -222,7 +238,22 @@ const WITH_CACHE = [{
|
||||
weeklyDownloads: 3331,
|
||||
dailyUsers: 4441,
|
||||
sourceURI: NetUtil.newURI(ADDON_FILES[0]).spec,
|
||||
repositoryStatus: 4
|
||||
repositoryStatus: 4,
|
||||
compatibilityOverrides: [{
|
||||
type: "incompatible",
|
||||
minVersion: 0.1,
|
||||
maxVersion: 0.2,
|
||||
appID: "xpcshell@tests.mozilla.org",
|
||||
appMinVersion: 3.0,
|
||||
appMaxVersion: 4.0
|
||||
}, {
|
||||
type: "incompatible",
|
||||
minVersion: 0.2,
|
||||
maxVersion: 0.3,
|
||||
appID: "xpcshell@tests.mozilla.org",
|
||||
appMinVersion: 5.0,
|
||||
appMaxVersion: 6.0
|
||||
}]
|
||||
}, {
|
||||
id: ADDON_IDS[1],
|
||||
type: "theme",
|
||||
@ -319,7 +350,22 @@ const WITH_EXTENSION_CACHE = [{
|
||||
weeklyDownloads: 3331,
|
||||
dailyUsers: 4441,
|
||||
sourceURI: NetUtil.newURI(ADDON_FILES[0]).spec,
|
||||
repositoryStatus: 4
|
||||
repositoryStatus: 4,
|
||||
compatibilityOverrides: [{
|
||||
type: "incompatible",
|
||||
minVersion: 0.1,
|
||||
maxVersion: 0.2,
|
||||
appID: "xpcshell@tests.mozilla.org",
|
||||
appMinVersion: 3.0,
|
||||
appMaxVersion: 4.0
|
||||
}, {
|
||||
type: "incompatible",
|
||||
minVersion: 0.2,
|
||||
maxVersion: 0.3,
|
||||
appID: "xpcshell@tests.mozilla.org",
|
||||
appMinVersion: 5.0,
|
||||
appMaxVersion: 6.0
|
||||
}]
|
||||
}, {
|
||||
id: ADDON_IDS[1],
|
||||
type: "theme",
|
||||
|
275
toolkit/mozapps/extensions/test/xpcshell/test_compatoverrides.js
Normal file
275
toolkit/mozapps/extensions/test/xpcshell/test_compatoverrides.js
Normal file
@ -0,0 +1,275 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests compatibility overrides, for when strict compatibility checking is
|
||||
// disabled. See bug 693906.
|
||||
|
||||
|
||||
const PREF_GETADDONS_CACHE_ENABLED = "extensions.getAddons.cache.enabled";
|
||||
const PREF_GETADDONS_BYIDS = "extensions.getAddons.get.url";
|
||||
|
||||
const PORT = 4444;
|
||||
const BASE_URL = "http://localhost:" + PORT;
|
||||
const DEFAULT_URL = "about:blank";
|
||||
const REQ_URL = "/data.xml";
|
||||
|
||||
Services.prefs.setBoolPref(PREF_EM_STRICT_COMPATIBILITY, false);
|
||||
Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, true);
|
||||
Services.prefs.setCharPref(PREF_GETADDONS_BYIDS,
|
||||
BASE_URL + REQ_URL);
|
||||
|
||||
do_load_httpd_js();
|
||||
var gServer;
|
||||
|
||||
|
||||
// Not hosted, no overrides
|
||||
var addon1 = {
|
||||
id: "addon1@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
name: "Test addon 1",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "1",
|
||||
maxVersion: "1"
|
||||
}]
|
||||
};
|
||||
|
||||
// Hosted, no overrides
|
||||
var addon2 = {
|
||||
id: "addon2@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
name: "Test addon 2",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "1",
|
||||
maxVersion: "1"
|
||||
}]
|
||||
};
|
||||
|
||||
// Hosted, matching override
|
||||
var addon3 = {
|
||||
id: "addon3@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
name: "Test addon 3",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "1",
|
||||
maxVersion: "1"
|
||||
}]
|
||||
};
|
||||
|
||||
// Hosted, matching override, wouldn't be compatible if strict chekcing is enabled
|
||||
var addon4 = {
|
||||
id: "addon4@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
name: "Test addon 4",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "0.1",
|
||||
maxVersion: "0.2"
|
||||
}]
|
||||
};
|
||||
|
||||
// Hosted, app ID doesn't match in override
|
||||
var addon5 = {
|
||||
id: "addon5@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
name: "Test addon 5",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "1",
|
||||
maxVersion: "1"
|
||||
}]
|
||||
};
|
||||
|
||||
// Hosted, addon version range doesn't match in override
|
||||
var addon6 = {
|
||||
id: "addon6@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
name: "Test addon 6",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "1",
|
||||
maxVersion: "1"
|
||||
}]
|
||||
};
|
||||
|
||||
// Hosted, app version range doesn't match in override
|
||||
var addon7 = {
|
||||
id: "addon7@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
name: "Test addon 7",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "1",
|
||||
maxVersion: "1"
|
||||
}]
|
||||
};
|
||||
|
||||
// Hosted, multiple overrides
|
||||
var addon8 = {
|
||||
id: "addon8@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
name: "Test addon 8",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "1",
|
||||
maxVersion: "1"
|
||||
}]
|
||||
};
|
||||
|
||||
// Not hosted, matching override
|
||||
var addon9 = {
|
||||
id: "addon9@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
name: "Test addon 9",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "1",
|
||||
maxVersion: "1"
|
||||
}]
|
||||
};
|
||||
|
||||
// Not hosted, override is of unsupported type (compatible)
|
||||
var addon10 = {
|
||||
id: "addon10@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
name: "Test addon 10",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "1",
|
||||
maxVersion: "1"
|
||||
}]
|
||||
};
|
||||
|
||||
|
||||
const profileDir = gProfD.clone();
|
||||
profileDir.append("extensions");
|
||||
|
||||
|
||||
/*
|
||||
* Trigger an AddonManager background update check
|
||||
*
|
||||
* @param aCallback
|
||||
* Callback to call once the background update is complete
|
||||
*/
|
||||
function trigger_background_update(aCallback) {
|
||||
Services.obs.addObserver({
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
Services.obs.removeObserver(this, "addons-background-update-complete");
|
||||
aCallback();
|
||||
}
|
||||
}, "addons-background-update-complete", false);
|
||||
|
||||
gInternalManager.notify(null);
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
do_test_pending();
|
||||
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "2");
|
||||
|
||||
writeInstallRDFForExtension(addon1, profileDir);
|
||||
writeInstallRDFForExtension(addon2, profileDir);
|
||||
writeInstallRDFForExtension(addon3, profileDir);
|
||||
writeInstallRDFForExtension(addon4, profileDir);
|
||||
writeInstallRDFForExtension(addon5, profileDir);
|
||||
writeInstallRDFForExtension(addon6, profileDir);
|
||||
writeInstallRDFForExtension(addon7, profileDir);
|
||||
writeInstallRDFForExtension(addon8, profileDir);
|
||||
writeInstallRDFForExtension(addon9, profileDir);
|
||||
writeInstallRDFForExtension(addon10, profileDir);
|
||||
|
||||
gServer = new nsHttpServer();
|
||||
gServer.registerFile(REQ_URL, do_get_file("data/test_compatoverrides.xml"));
|
||||
gServer.start(PORT);
|
||||
|
||||
startupManager();
|
||||
|
||||
trigger_background_update(run_test_1);
|
||||
}
|
||||
|
||||
function end_test() {
|
||||
gServer.stop(do_test_finished);
|
||||
}
|
||||
|
||||
function check_compat_status(aCallback) {
|
||||
AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
|
||||
"addon2@tests.mozilla.org",
|
||||
"addon3@tests.mozilla.org",
|
||||
"addon4@tests.mozilla.org",
|
||||
"addon5@tests.mozilla.org",
|
||||
"addon6@tests.mozilla.org",
|
||||
"addon7@tests.mozilla.org",
|
||||
"addon8@tests.mozilla.org",
|
||||
"addon9@tests.mozilla.org",
|
||||
"addon10@tests.mozilla.org"],
|
||||
function([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10]) {
|
||||
|
||||
do_check_neq(a1, null);
|
||||
do_check_eq(a1.compatibilityOverrides, null);
|
||||
do_check_true(a1.isCompatible);
|
||||
do_check_false(a1.appDisabled);
|
||||
|
||||
do_check_neq(a2, null);
|
||||
do_check_eq(a2.compatibilityOverrides, null);
|
||||
do_check_true(a2.isCompatible);
|
||||
do_check_false(a2.appDisabled);
|
||||
|
||||
do_check_neq(a3, null);
|
||||
do_check_neq(a3.compatibilityOverrides, null);
|
||||
do_check_eq(a3.compatibilityOverrides.length, 1);
|
||||
do_check_false(a3.isCompatible);
|
||||
do_check_true(a3.appDisabled);
|
||||
|
||||
do_check_neq(a4, null);
|
||||
do_check_neq(a4.compatibilityOverrides, null);
|
||||
do_check_eq(a4.compatibilityOverrides.length, 1);
|
||||
do_check_false(a4.isCompatible);
|
||||
do_check_true(a4.appDisabled);
|
||||
|
||||
do_check_neq(a5, null);
|
||||
do_check_eq(a5.compatibilityOverrides, null);
|
||||
do_check_true(a5.isCompatible);
|
||||
do_check_false(a5.appDisabled);
|
||||
|
||||
do_check_neq(a6, null);
|
||||
do_check_neq(a6.compatibilityOverrides, null);
|
||||
do_check_eq(a6.compatibilityOverrides.length, 1);
|
||||
do_check_true(a6.isCompatible);
|
||||
do_check_false(a6.appDisabled);
|
||||
|
||||
do_check_neq(a7, null);
|
||||
do_check_neq(a7.compatibilityOverrides, null);
|
||||
do_check_eq(a7.compatibilityOverrides.length, 1);
|
||||
do_check_true(a7.isCompatible);
|
||||
do_check_false(a7.appDisabled);
|
||||
|
||||
do_check_neq(a8, null);
|
||||
do_check_neq(a8.compatibilityOverrides, null);
|
||||
do_check_eq(a8.compatibilityOverrides.length, 3);
|
||||
do_check_false(a8.isCompatible);
|
||||
do_check_true(a8.appDisabled);
|
||||
|
||||
do_check_neq(a9, null);
|
||||
do_check_neq(a9.compatibilityOverrides, null);
|
||||
do_check_eq(a9.compatibilityOverrides.length, 1);
|
||||
do_check_false(a9.isCompatible);
|
||||
do_check_true(a9.appDisabled);
|
||||
|
||||
do_check_neq(a10, null);
|
||||
do_check_eq(a10.compatibilityOverrides, null);
|
||||
do_check_true(a10.isCompatible);
|
||||
do_check_false(a10.appDisabled);
|
||||
|
||||
aCallback();
|
||||
});
|
||||
}
|
||||
|
||||
function run_test_1() {
|
||||
check_compat_status(run_test_2);
|
||||
}
|
||||
|
||||
function run_test_2() {
|
||||
restartManager();
|
||||
check_compat_status(end_test);
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
const EXPECTED_SCHEMA_VERSION = 2;
|
||||
const EXPECTED_SCHEMA_VERSION = 3;
|
||||
let dbfile;
|
||||
|
||||
function run_test() {
|
||||
@ -88,6 +88,24 @@ function run_test() {
|
||||
do_check_eq(db.schemaVersion, EXPECTED_SCHEMA_VERSION);
|
||||
do_check_true(db.indexExists("developer_idx"));
|
||||
do_check_true(db.indexExists("screenshot_idx"));
|
||||
do_check_true(db.indexExists("compatibility_override_idx"));
|
||||
do_check_true(db.tableExists("compatibility_override"));
|
||||
|
||||
// Check the trigger is working
|
||||
db.executeSimpleSQL("INSERT INTO addon (id, type, name) VALUES('test_addon', 'extension', 'Test Addon')");
|
||||
let internalID = db.lastInsertRowID;
|
||||
db.executeSimpleSQL("INSERT INTO compatibility_override (addon_internal_id, num, type) VALUES('" + internalID + "', '1', 'incompatible')");
|
||||
|
||||
let stmt = db.createStatement("SELECT COUNT(*) AS count FROM compatibility_override");
|
||||
stmt.executeStep();
|
||||
do_check_eq(stmt.row.count, 1);
|
||||
stmt.reset();
|
||||
|
||||
db.executeSimpleSQL("DELETE FROM addon");
|
||||
stmt.executeStep();
|
||||
do_check_eq(stmt.row.count, 0);
|
||||
stmt.finalize();
|
||||
|
||||
db.close();
|
||||
run_test_2();
|
||||
}
|
||||
|
@ -6,6 +6,8 @@
|
||||
|
||||
const PREF_MATCH_OS_LOCALE = "intl.locale.matchOS";
|
||||
const PREF_SELECTED_LOCALE = "general.useragent.locale";
|
||||
const PREF_GETADDONS_BYIDS = "extensions.getAddons.get.url";
|
||||
const PREF_GETADDONS_CACHE_ENABLED = "extensions.getAddons.cache.enabled";
|
||||
|
||||
// The test extension uses an insecure update url.
|
||||
Services.prefs.setBoolPref(PREF_EM_CHECK_UPDATE_SECURITY, false);
|
||||
@ -771,9 +773,10 @@ function run_test_12() {
|
||||
});
|
||||
}
|
||||
|
||||
// Tests that no compatibility update is passed to the listener when there is
|
||||
// Tests that a compatibility update is passed to the listener when there is
|
||||
// compatibility info for the current version of the app but not for the
|
||||
// version of the app that the caller requested an update check for.
|
||||
// version of the app that the caller requested an update check for, when
|
||||
// strict compatibility checking is disabled.
|
||||
function run_test_13() {
|
||||
// Not initially compatible but the update check will make it compatible
|
||||
writeInstallRDFForExtension({
|
||||
@ -798,8 +801,8 @@ function run_test_13() {
|
||||
|
||||
a7.findUpdates({
|
||||
sawUpdate: false,
|
||||
onCompatibilityUpdateAvailable: function(addon) {
|
||||
do_throw("Should have not have seen compatibility information");
|
||||
onNoCompatibilityUpdateAvailable: function(addon) {
|
||||
do_throw("Should have seen compatibility information");
|
||||
},
|
||||
|
||||
onUpdateAvailable: function(addon, install) {
|
||||
@ -1052,7 +1055,7 @@ function run_test_16() {
|
||||
a2.uninstall();
|
||||
restartManager();
|
||||
|
||||
end_test();
|
||||
run_test_17();
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -1064,3 +1067,106 @@ function run_test_16() {
|
||||
aInstall.install();
|
||||
}, "application/x-xpinstall");
|
||||
}
|
||||
|
||||
// Test that the update check correctly observes the
|
||||
// extensions.strictCompatibility pref and compatibility overrides.
|
||||
function run_test_17() {
|
||||
writeInstallRDFForExtension({
|
||||
id: "addon9@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
updateURL: "http://localhost:4444/data/test_update.rdf",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "0.1",
|
||||
maxVersion: "0.2"
|
||||
}],
|
||||
name: "Test Addon 9",
|
||||
}, profileDir);
|
||||
restartManager();
|
||||
|
||||
AddonManager.addInstallListener({
|
||||
onNewInstall: function(aInstall) {
|
||||
if (aInstall.existingAddon.id != "addon9@tests.mozilla.org")
|
||||
do_throw("Saw unexpected onNewInstall for " + aInstall.existingAddon.id);
|
||||
do_check_eq(aInstall.version, "3.0");
|
||||
},
|
||||
onDownloadFailed: function(aInstall) {
|
||||
do_execute_soon(run_test_18);
|
||||
}
|
||||
});
|
||||
|
||||
Services.prefs.setCharPref(PREF_GETADDONS_BYIDS, "http://localhost:4444/data/test_update.xml");
|
||||
Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, true);
|
||||
// Fake a timer event
|
||||
gInternalManager.notify(null);
|
||||
}
|
||||
|
||||
// Tests that compatibility updates are applied to addons when the updated
|
||||
// compatibility data wouldn't match with strict compatibility enabled.
|
||||
function run_test_18() {
|
||||
writeInstallRDFForExtension({
|
||||
id: "addon10@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
updateURL: "http://localhost:4444/data/test_update.rdf",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "0.1",
|
||||
maxVersion: "0.2"
|
||||
}],
|
||||
name: "Test Addon 10",
|
||||
}, profileDir);
|
||||
restartManager();
|
||||
|
||||
AddonManager.getAddonByID("addon10@tests.mozilla.org", function(a10) {
|
||||
do_check_neq(a10, null);
|
||||
|
||||
a10.findUpdates({
|
||||
onNoCompatibilityUpdateAvailable: function() {
|
||||
do_throw("Should have seen compatibility information");
|
||||
},
|
||||
|
||||
onUpdateAvailable: function() {
|
||||
do_throw("Should not have seen an available update");
|
||||
},
|
||||
|
||||
onUpdateFinished: function() {
|
||||
run_test_19();
|
||||
}
|
||||
}, AddonManager.UPDATE_WHEN_USER_REQUESTED);
|
||||
});
|
||||
}
|
||||
|
||||
// Test that the update check correctly observes when an addon opts-in to
|
||||
// strict compatibility checking.
|
||||
function run_test_19() {
|
||||
writeInstallRDFForExtension({
|
||||
id: "addon11@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
updateURL: "http://localhost:4444/data/test_update.rdf",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "0.1",
|
||||
maxVersion: "0.2"
|
||||
}],
|
||||
name: "Test Addon 11",
|
||||
}, profileDir);
|
||||
restartManager();
|
||||
|
||||
AddonManager.getAddonByID("addon11@tests.mozilla.org", function(a11) {
|
||||
do_check_neq(a11, null);
|
||||
|
||||
a11.findUpdates({
|
||||
onCompatibilityUpdateAvailable: function() {
|
||||
do_throw("Should have not have seen compatibility information");
|
||||
},
|
||||
|
||||
onUpdateAvailable: function() {
|
||||
do_throw("Should not have seen an available update");
|
||||
},
|
||||
|
||||
onUpdateFinished: function() {
|
||||
end_test();
|
||||
}
|
||||
}, AddonManager.UPDATE_WHEN_USER_REQUESTED);
|
||||
});
|
||||
}
|
||||
|
@ -0,0 +1,198 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// This verifies that add-on update check correctly fills in the
|
||||
// %COMPATIBILITY_MODE% token in the update URL.
|
||||
|
||||
|
||||
// The test extension uses an insecure update url.
|
||||
Services.prefs.setBoolPref(PREF_EM_CHECK_UPDATE_SECURITY, false);
|
||||
|
||||
do_load_httpd_js();
|
||||
var testserver;
|
||||
const profileDir = gProfD.clone();
|
||||
profileDir.append("extensions");
|
||||
|
||||
var COMPATIBILITY_PREF;
|
||||
|
||||
function run_test() {
|
||||
do_test_pending();
|
||||
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
|
||||
|
||||
var channel = "default";
|
||||
try {
|
||||
channel = Services.prefs.getCharPref("app.update.channel");
|
||||
} catch (e) { }
|
||||
if (channel != "aurora" &&
|
||||
channel != "beta" &&
|
||||
channel != "release") {
|
||||
var version = "nightly";
|
||||
} else {
|
||||
version = Services.appinfo.version.replace(/^([^\.]+\.[0-9]+[a-z]*).*/gi, "$1");
|
||||
}
|
||||
COMPATIBILITY_PREF = "extensions.checkCompatibility." + version;
|
||||
|
||||
// Create and configure the HTTP server.
|
||||
testserver = new nsHttpServer();
|
||||
testserver.registerDirectory("/data/", do_get_file("data"));
|
||||
testserver.registerDirectory("/addons/", do_get_file("addons"));
|
||||
testserver.start(4444);
|
||||
|
||||
writeInstallRDFForExtension({
|
||||
id: "compatmode-normal@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
updateURL: "http://localhost:4444/data/test_updatecompatmode_%COMPATIBILITY_MODE%.rdf",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "1",
|
||||
maxVersion: "1"
|
||||
}],
|
||||
name: "Test Addon - normal"
|
||||
}, profileDir);
|
||||
|
||||
writeInstallRDFForExtension({
|
||||
id: "compatmode-strict@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
updateURL: "http://localhost:4444/data/test_updatecompatmode_%COMPATIBILITY_MODE%.rdf",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "1",
|
||||
maxVersion: "1"
|
||||
}],
|
||||
name: "Test Addon - strict"
|
||||
}, profileDir);
|
||||
|
||||
writeInstallRDFForExtension({
|
||||
id: "compatmode-strict-optin@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
updateURL: "http://localhost:4444/data/test_updatecompatmode_%COMPATIBILITY_MODE%.rdf",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "1",
|
||||
maxVersion: "1"
|
||||
}],
|
||||
name: "Test Addon - strict opt-in",
|
||||
strictCompatibility: true
|
||||
}, profileDir);
|
||||
|
||||
writeInstallRDFForExtension({
|
||||
id: "compatmode-ignore@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
updateURL: "http://localhost:4444/data/test_updatecompatmode_%COMPATIBILITY_MODE%.rdf",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "1",
|
||||
maxVersion: "1"
|
||||
}],
|
||||
name: "Test Addon - ignore",
|
||||
}, profileDir);
|
||||
|
||||
startupManager();
|
||||
run_test_1();
|
||||
}
|
||||
|
||||
function end_test() {
|
||||
testserver.stop(do_test_finished);
|
||||
}
|
||||
|
||||
|
||||
// Strict compatibility checking disabled.
|
||||
function run_test_1() {
|
||||
do_print("Testing with strict compatibility checking disabled");
|
||||
Services.prefs.setBoolPref(PREF_EM_STRICT_COMPATIBILITY, false);
|
||||
AddonManager.getAddonByID("compatmode-normal@tests.mozilla.org", function(addon) {
|
||||
do_check_neq(addon, null);
|
||||
addon.findUpdates({
|
||||
onCompatibilityUpdateAvailable: function() {
|
||||
do_throw("Should have not have seen compatibility information");
|
||||
},
|
||||
|
||||
onNoUpdateAvailable: function() {
|
||||
do_throw("Should have seen an available update");
|
||||
},
|
||||
|
||||
onUpdateAvailable: function(addon, install) {
|
||||
do_check_eq(install.version, "2.0")
|
||||
},
|
||||
|
||||
onUpdateFinished: function() {
|
||||
run_test_2();
|
||||
}
|
||||
}, AddonManager.UPDATE_WHEN_USER_REQUESTED);
|
||||
});
|
||||
}
|
||||
|
||||
// Strict compatibility checking enabled.
|
||||
function run_test_2() {
|
||||
do_print("Testing with strict compatibility checking enabled");
|
||||
Services.prefs.setBoolPref(PREF_EM_STRICT_COMPATIBILITY, true);
|
||||
AddonManager.getAddonByID("compatmode-strict@tests.mozilla.org", function(addon) {
|
||||
do_check_neq(addon, null);
|
||||
addon.findUpdates({
|
||||
onCompatibilityUpdateAvailable: function() {
|
||||
do_throw("Should have not have seen compatibility information");
|
||||
},
|
||||
|
||||
onNoUpdateAvailable: function() {
|
||||
do_throw("Should have seen an available update");
|
||||
},
|
||||
|
||||
onUpdateAvailable: function(addon, install) {
|
||||
do_check_eq(install.version, "2.0")
|
||||
},
|
||||
|
||||
onUpdateFinished: function() {
|
||||
run_test_3();
|
||||
}
|
||||
}, AddonManager.UPDATE_WHEN_USER_REQUESTED);
|
||||
});
|
||||
}
|
||||
|
||||
// Strict compatibility checking opt-in.
|
||||
function run_test_3() {
|
||||
do_print("Testing with strict compatibility disabled, but addon opt-in");
|
||||
Services.prefs.setBoolPref(PREF_EM_STRICT_COMPATIBILITY, false);
|
||||
AddonManager.getAddonByID("compatmode-strict-optin@tests.mozilla.org", function(addon) {
|
||||
do_check_neq(addon, null);
|
||||
addon.findUpdates({
|
||||
onCompatibilityUpdateAvailable: function() {
|
||||
do_throw("Should have not have seen compatibility information");
|
||||
},
|
||||
|
||||
onUpdateAvailable: function(addon, install) {
|
||||
do_throw("Should not have seen an available update");
|
||||
},
|
||||
|
||||
onUpdateFinished: function() {
|
||||
run_test_4();
|
||||
}
|
||||
}, AddonManager.UPDATE_WHEN_USER_REQUESTED);
|
||||
});
|
||||
}
|
||||
|
||||
// Compatibility checking disabled.
|
||||
function run_test_4() {
|
||||
do_print("Testing with all compatibility checking disabled");
|
||||
Services.prefs.setBoolPref(COMPATIBILITY_PREF, false);
|
||||
AddonManager.getAddonByID("compatmode-ignore@tests.mozilla.org", function(addon) {
|
||||
do_check_neq(addon, null);
|
||||
addon.findUpdates({
|
||||
onCompatibilityUpdateAvailable: function() {
|
||||
do_throw("Should have not have seen compatibility information");
|
||||
},
|
||||
|
||||
onNoUpdateAvailable: function() {
|
||||
do_throw("Should have seen an available update");
|
||||
},
|
||||
|
||||
onUpdateAvailable: function(addon, install) {
|
||||
do_check_eq(install.version, "2.0")
|
||||
},
|
||||
|
||||
onUpdateFinished: function() {
|
||||
end_test();
|
||||
}
|
||||
}, AddonManager.UPDATE_WHEN_USER_REQUESTED);
|
||||
});
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// This verifies that add-on update checks work correctly when compatibility
|
||||
// check is disabled.
|
||||
|
||||
|
||||
const PREF_GETADDONS_BYIDS = "extensions.getAddons.get.url";
|
||||
const PREF_GETADDONS_CACHE_ENABLED = "extensions.getAddons.cache.enabled";
|
||||
|
||||
// The test extension uses an insecure update url.
|
||||
Services.prefs.setBoolPref(PREF_EM_CHECK_UPDATE_SECURITY, false);
|
||||
|
||||
do_load_httpd_js();
|
||||
var testserver;
|
||||
const profileDir = gProfD.clone();
|
||||
profileDir.append("extensions");
|
||||
|
||||
|
||||
function run_test() {
|
||||
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
|
||||
|
||||
// Create and configure the HTTP server.
|
||||
testserver = new nsHttpServer();
|
||||
testserver.registerDirectory("/data/", do_get_file("data"));
|
||||
testserver.registerDirectory("/addons/", do_get_file("addons"));
|
||||
testserver.start(4444);
|
||||
|
||||
run_test_1();
|
||||
}
|
||||
|
||||
// Test that the update check correctly observes the
|
||||
// extensions.strictCompatibility pref and compatibility overrides.
|
||||
function run_test_1() {
|
||||
writeInstallRDFForExtension({
|
||||
id: "addon9@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
updateURL: "http://localhost:4444/data/test_update.rdf",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "0.1",
|
||||
maxVersion: "0.2"
|
||||
}],
|
||||
name: "Test Addon 9",
|
||||
}, profileDir);
|
||||
restartManager();
|
||||
|
||||
AddonManager.addInstallListener({
|
||||
onNewInstall: function(aInstall) {
|
||||
if (aInstall.existingAddon.id != "addon9@tests.mozilla.org")
|
||||
do_throw("Saw unexpected onNewInstall for " + aInstall.existingAddon.id);
|
||||
do_check_eq(aInstall.version, "4.0");
|
||||
},
|
||||
onDownloadFailed: function(aInstall) {
|
||||
do_execute_soon(run_test_2);
|
||||
}
|
||||
});
|
||||
|
||||
Services.prefs.setCharPref(PREF_GETADDONS_BYIDS, "http://localhost:4444/data/test_update.xml");
|
||||
Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, true);
|
||||
// Fake a timer event
|
||||
gInternalManager.notify(null);
|
||||
}
|
||||
|
||||
// Test that the update check correctly observes when an addon opts-in to
|
||||
// strict compatibility checking.
|
||||
function run_test_2() {
|
||||
writeInstallRDFForExtension({
|
||||
id: "addon11@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
updateURL: "http://localhost:4444/data/test_update.rdf",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "0.1",
|
||||
maxVersion: "0.2"
|
||||
}],
|
||||
name: "Test Addon 11",
|
||||
}, profileDir);
|
||||
restartManager();
|
||||
|
||||
AddonManager.getAddonByID("addon11@tests.mozilla.org", function(a11) {
|
||||
do_check_neq(a11, null);
|
||||
|
||||
a11.findUpdates({
|
||||
onCompatibilityUpdateAvailable: function() {
|
||||
do_throw("Should have not have seen compatibility information");
|
||||
},
|
||||
|
||||
onNoUpdateAvailable: function() {
|
||||
do_throw("Should have seen an available update");
|
||||
},
|
||||
|
||||
onUpdateFinished: function() {
|
||||
end_test();
|
||||
}
|
||||
}, AddonManager.UPDATE_WHEN_USER_REQUESTED);
|
||||
});
|
||||
}
|
@ -6,6 +6,8 @@
|
||||
|
||||
const PREF_MATCH_OS_LOCALE = "intl.locale.matchOS";
|
||||
const PREF_SELECTED_LOCALE = "general.useragent.locale";
|
||||
const PREF_GETADDONS_BYIDS = "extensions.getAddons.get.url";
|
||||
const PREF_GETADDONS_CACHE_ENABLED = "extensions.getAddons.cache.enabled";
|
||||
|
||||
// The test extension uses an insecure update url.
|
||||
Services.prefs.setBoolPref("extensions.checkUpdateSecurity", false);
|
||||
@ -1016,6 +1018,75 @@ function check_test_15(aInstall) {
|
||||
|
||||
restartManager();
|
||||
|
||||
end_test();
|
||||
run_test_16();
|
||||
});
|
||||
}
|
||||
|
||||
// Test that the update check correctly observes the
|
||||
// extensions.strictCompatibility pref and compatibility overrides.
|
||||
function run_test_16() {
|
||||
writeInstallRDFForExtension({
|
||||
id: "addon9@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
updateURL: "http://localhost:4444/data/test_update.rdf",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "0.1",
|
||||
maxVersion: "0.2"
|
||||
}],
|
||||
name: "Test Addon 9",
|
||||
}, profileDir);
|
||||
restartManager();
|
||||
|
||||
AddonManager.addInstallListener({
|
||||
onNewInstall: function(aInstall) {
|
||||
if (aInstall.existingAddon.id != "addon9@tests.mozilla.org")
|
||||
do_throw("Saw unexpected onNewInstall for " + aInstall.existingAddon.id);
|
||||
do_check_eq(aInstall.version, "2.0");
|
||||
},
|
||||
onDownloadFailed: function(aInstall) {
|
||||
do_execute_soon(run_test_17);
|
||||
}
|
||||
});
|
||||
|
||||
Services.prefs.setCharPref(PREF_GETADDONS_BYIDS, "http://localhost:4444/data/test_update.xml");
|
||||
Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, true);
|
||||
// Fake a timer event
|
||||
gInternalManager.notify(null);
|
||||
}
|
||||
|
||||
// Test that the update check correctly observes when an addon opts-in to
|
||||
// strict compatibility checking.
|
||||
function run_test_17() {
|
||||
|
||||
writeInstallRDFForExtension({
|
||||
id: "addon11@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
updateURL: "http://localhost:4444/data/test_update.rdf",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "0.1",
|
||||
maxVersion: "0.2"
|
||||
}],
|
||||
name: "Test Addon 11",
|
||||
}, profileDir);
|
||||
restartManager();
|
||||
|
||||
AddonManager.getAddonByID("addon11@tests.mozilla.org", function(a11) {
|
||||
do_check_neq(a11, null);
|
||||
|
||||
a11.findUpdates({
|
||||
onCompatibilityUpdateAvailable: function() {
|
||||
do_throw("Should have not have seen compatibility information");
|
||||
},
|
||||
|
||||
onUpdateAvailable: function() {
|
||||
do_throw("Should not have seen an available update");
|
||||
},
|
||||
|
||||
onUpdateFinished: function() {
|
||||
end_test();
|
||||
}
|
||||
}, AddonManager.UPDATE_WHEN_USER_REQUESTED);
|
||||
});
|
||||
}
|
||||
|
@ -6,6 +6,18 @@
|
||||
|
||||
Components.utils.import("resource://gre/modules/AddonUpdateChecker.jsm");
|
||||
|
||||
|
||||
var channel = "default";
|
||||
try {
|
||||
channel = Services.prefs.getCharPref("app.update.channel");
|
||||
} catch (e) { }
|
||||
if (channel != "aurora" && channel != "beta" && channel != "release")
|
||||
var version = "nightly";
|
||||
else
|
||||
version = Services.appinfo.version.replace(/^([^\.]+\.[0-9]+[a-z]*).*/gi, "$1");
|
||||
const COMPATIBILITY_PREF = "extensions.checkCompatibility." + version;
|
||||
|
||||
|
||||
do_load_httpd_js();
|
||||
var testserver;
|
||||
|
||||
@ -226,7 +238,87 @@ function run_test_11() {
|
||||
|
||||
onUpdateCheckError: function(status) {
|
||||
do_check_eq(status, AddonUpdateChecker.ERROR_PARSE_ERROR);
|
||||
end_test();
|
||||
run_test_12();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function run_test_12() {
|
||||
AddonUpdateChecker.checkForUpdates("ignore-compat@tests.mozilla.org",
|
||||
"extension", null,
|
||||
"http://localhost:4444/data/test_updatecheck.rdf", {
|
||||
onUpdateCheckComplete: function(updates) {
|
||||
do_check_eq(updates.length, 3);
|
||||
let update = AddonUpdateChecker.getNewestCompatibleUpdate(updates,
|
||||
null,
|
||||
null,
|
||||
true);
|
||||
do_check_neq(update, null);
|
||||
do_check_eq(update.version, 2);
|
||||
run_test_13();
|
||||
},
|
||||
|
||||
onUpdateCheckError: function(status) {
|
||||
do_throw("Update check failed with status " + status);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function run_test_13() {
|
||||
AddonUpdateChecker.checkForUpdates("compat-override@tests.mozilla.org",
|
||||
"extension", null,
|
||||
"http://localhost:4444/data/test_updatecheck.rdf", {
|
||||
onUpdateCheckComplete: function(updates) {
|
||||
do_check_eq(updates.length, 3);
|
||||
let overrides = [{
|
||||
type: "incompatible",
|
||||
minVersion: 1,
|
||||
maxVersion: 2,
|
||||
appID: "xpcshell@tests.mozilla.org",
|
||||
appMinVersion: 0.1,
|
||||
appMaxVersion: 0.2
|
||||
}, {
|
||||
type: "incompatible",
|
||||
minVersion: 2,
|
||||
maxVersion: 2,
|
||||
appID: "xpcshell@tests.mozilla.org",
|
||||
appMinVersion: 1,
|
||||
appMaxVersion: 2
|
||||
}];
|
||||
let update = AddonUpdateChecker.getNewestCompatibleUpdate(updates,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
overrides);
|
||||
do_check_neq(update, null);
|
||||
do_check_eq(update.version, 1);
|
||||
run_test_14();
|
||||
},
|
||||
|
||||
onUpdateCheckError: function(status) {
|
||||
do_throw("Update check failed with status " + status);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function run_test_14() {
|
||||
AddonUpdateChecker.checkForUpdates("compat-strict-optin@tests.mozilla.org",
|
||||
"extension", null,
|
||||
"http://localhost:4444/data/test_updatecheck.rdf", {
|
||||
onUpdateCheckComplete: function(updates) {
|
||||
do_check_eq(updates.length, 1);
|
||||
let update = AddonUpdateChecker.getNewestCompatibleUpdate(updates,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false);
|
||||
do_check_eq(update, null);
|
||||
end_test();
|
||||
},
|
||||
|
||||
onUpdateCheckError: function(status) {
|
||||
do_throw("Update check failed with status " + status);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -127,6 +127,7 @@ fail-if = os == "android"
|
||||
[test_cacheflush.js]
|
||||
[test_checkcompatibility.js]
|
||||
[test_ChromeManifestParser.js]
|
||||
[test_compatoverrides.js]
|
||||
[test_corrupt.js]
|
||||
[test_corrupt_strictcompat.js]
|
||||
[test_dictionary.js]
|
||||
@ -198,12 +199,16 @@ skip-if = os == "android"
|
||||
[test_update_strictcompat.js]
|
||||
# Bug 676992: test consistently hangs on Android
|
||||
skip-if = os == "android"
|
||||
[test_update_ignorecompat.js]
|
||||
# Bug 676992: test consistently hangs on Android
|
||||
skip-if = os == "android"
|
||||
[test_updatecheck.js]
|
||||
# Bug 676992: test consistently hangs on Android
|
||||
skip-if = os == "android"
|
||||
[test_updateid.js]
|
||||
# Bug 676992: test consistently hangs on Android
|
||||
skip-if = os == "android"
|
||||
[test_update_compatmode.js]
|
||||
[test_upgrade.js]
|
||||
# Bug 676992: test consistently hangs on Android
|
||||
skip-if = os == "android"
|
||||
|
Loading…
x
Reference in New Issue
Block a user