This commit is contained in:
Carsten "Tomcat" Book 2015-10-06 12:21:45 +02:00
Родитель 448b7e50a9 71e22d0c44
Коммит f21f41d902
126 изменённых файлов: 876 добавлений и 419 удалений

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

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Bug 1182727 - Changed toolchain, needs clobber again :(
Bug 1210755 - Android build: Switch to Android 6.0 SDK / API 23

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1f226126dcba8af16c8db08556130b0bb04bb8d3"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="60cdaa3d3424db3432dc903e7f9c6c8fa099c06d"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1f226126dcba8af16c8db08556130b0bb04bb8d3"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="60cdaa3d3424db3432dc903e7f9c6c8fa099c06d"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>

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

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1f226126dcba8af16c8db08556130b0bb04bb8d3"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="60cdaa3d3424db3432dc903e7f9c6c8fa099c06d"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="27eb2f04e149fc2c9976d881b1b5984bbe7ee089"/>

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

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1f226126dcba8af16c8db08556130b0bb04bb8d3"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="60cdaa3d3424db3432dc903e7f9c6c8fa099c06d"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="31a7849fe9a8b743d6f5e5facc212f0ef9d57499"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1f226126dcba8af16c8db08556130b0bb04bb8d3"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="60cdaa3d3424db3432dc903e7f9c6c8fa099c06d"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1f226126dcba8af16c8db08556130b0bb04bb8d3"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="60cdaa3d3424db3432dc903e7f9c6c8fa099c06d"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

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

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1f226126dcba8af16c8db08556130b0bb04bb8d3"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="60cdaa3d3424db3432dc903e7f9c6c8fa099c06d"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="27eb2f04e149fc2c9976d881b1b5984bbe7ee089"/>

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1f226126dcba8af16c8db08556130b0bb04bb8d3"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="60cdaa3d3424db3432dc903e7f9c6c8fa099c06d"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>

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

@ -1,9 +1,9 @@
{
"git": {
"git_revision": "1f226126dcba8af16c8db08556130b0bb04bb8d3",
"git_revision": "60cdaa3d3424db3432dc903e7f9c6c8fa099c06d",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
"revision": "44cf4f0a2b14c88e117d9c8cf76779d0a7c26999",
"revision": "1de2dfa13b0b91c293111198011353c7bb86242d",
"repo_path": "integration/gaia-central"
}

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1f226126dcba8af16c8db08556130b0bb04bb8d3"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="60cdaa3d3424db3432dc903e7f9c6c8fa099c06d"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>

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

@ -18,7 +18,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1f226126dcba8af16c8db08556130b0bb04bb8d3"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="60cdaa3d3424db3432dc903e7f9c6c8fa099c06d"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="31a7849fe9a8b743d6f5e5facc212f0ef9d57499"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1f226126dcba8af16c8db08556130b0bb04bb8d3"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="60cdaa3d3424db3432dc903e7f9c6c8fa099c06d"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>

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

@ -713,7 +713,6 @@
<image id="default-notification-icon" class="notification-anchor-icon" role="button"/>
<image id="identity-notification-icon" class="notification-anchor-icon" role="button"/>
<image id="geo-notification-icon" class="notification-anchor-icon" role="button"/>
<image id="push-notification-icon" class="notification-anchor-icon" role="button"/>
<image id="addons-notification-icon" class="notification-anchor-icon" role="button"/>
<image id="indexedDB-notification-icon" class="notification-anchor-icon" role="button"/>
<image id="login-fill-notification-icon" class="notification-anchor-icon" role="button"/>

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

@ -6,6 +6,7 @@
position="after_start"
hidden="true"
orient="vertical"
noautofocus="true"
role="alert"/>
<popupnotification id="webRTC-shareDevices-notification" hidden="true">

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

@ -0,0 +1,7 @@
[DEFAULT]
support-files =
file_dom_notifications.html
[browser_notification_open_settings.js]
[browser_notification_tab_switching.js]
skip-if = buildapp == 'mulet' || e10s # Bug 1100662 - content access causing uncaught exception - Error: cannot ipc non-cpow object at chrome://mochitests/content/browser/browser/base/content/test/general/browser_notification_tab_switching.js:32 (or in RemoteAddonsChild.jsm)

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

@ -0,0 +1,18 @@
"use strict";
add_task(function* test_settingsOpen() {
info("Opening a dummy tab so openPreferences=>switchToTabHavingURI doesn't use the blank tab.");
yield BrowserTestUtils.withNewTab({
gBrowser,
url: "about:robots"
}, function* dummyTabTask(aBrowser) {
let tabPromise = BrowserTestUtils.waitForNewTab(gBrowser, "about:preferences#content");
info("simulate a notifications-open-settings notification");
let uri = NetUtil.newURI("https://example.com");
let principal = Services.scriptSecurityManager.createCodebasePrincipal(uri, {});
Services.obs.notifyObservers(principal, "notifications-open-settings", null);
let tab = yield tabPromise;
ok(tab, "The notification settings tab opened");
BrowserTestUtils.removeTab(tab);
});
});

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

@ -6,7 +6,7 @@
var tab;
var notification;
var notificationURL = "http://example.org/browser/browser/base/content/test/general/file_dom_notifications.html";
var notificationURL = "http://example.org/browser/browser/base/content/test/alerts/file_dom_notifications.html";
var newWindowOpenedFromTab;
function test () {
@ -58,7 +58,7 @@ function onAlertShowing() {
info("Notification alert showing");
notification.removeEventListener("show", onAlertShowing);
let alertWindow = findChromeWindowByURI("chrome://global/content/alerts/alert.xul");
let alertWindow = Services.wm.getMostRecentWindow("alert:alert");
if (!alertWindow) {
todo(false, "Notifications don't use XUL windows on all platforms.");
notification.close();

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

@ -1,5 +1,6 @@
<html>
<head>
<meta charset="utf-8">
<script>
"use strict";

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

@ -62,7 +62,6 @@ support-files =
file_bug970276_favicon1.ico
file_bug970276_favicon2.ico
file_documentnavigation_frameset.html
file_dom_notifications.html
file_double_close_tab.html
file_favicon_change.html
file_favicon_change_not_in_document.html
@ -338,8 +337,6 @@ skip-if = os != "win" # The Fitts Law menu button is only supported on Windows (
skip-if = e10s # Bug 1100664 - test directly access content docShells (TypeError: gBrowser.docShell is null)
[browser_mixedcontent_securityflags.js]
tags = mcb
[browser_notification_tab_switching.js]
skip-if = buildapp == 'mulet' || e10s # Bug 1100662 - content access causing uncaught exception - Error: cannot ipc non-cpow object at chrome://mochitests/content/browser/browser/base/content/test/general/browser_notification_tab_switching.js:32 (or in RemoteAddonsChild.jsm)
[browser_offlineQuotaNotification.js]
skip-if = buildapp == 'mulet' || e10s # Bug 1093603 - test breaks with PopupNotifications.panel.firstElementChild is null
[browser_overflowScroll.js]

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

@ -59,16 +59,6 @@ function whenDelayedStartupFinished(aWindow, aCallback) {
}, "browser-delayed-startup-finished", false);
}
function findChromeWindowByURI(aURI) {
let windows = Services.wm.getEnumerator(null);
while (windows.hasMoreElements()) {
let win = windows.getNext();
if (win.location.href == aURI)
return win;
}
return null;
}
function updateTabContextMenu(tab) {
let menu = document.getElementById("tabContextMenu");
if (!tab)

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

@ -15,6 +15,7 @@ MOCHITEST_CHROME_MANIFESTS += [
]
BROWSER_CHROME_MANIFESTS += [
'content/test/alerts/browser.ini',
'content/test/chat/browser.ini',
'content/test/general/browser.ini',
'content/test/newtab/browser.ini',

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

@ -147,7 +147,8 @@ loop.store.ConversationAppStore = (function() {
this._dispatcher.dispatch(new loop.shared.actions.HangupCall());
break;
case "room":
if (this._activeRoomStore.getStoreState().used) {
if (this._activeRoomStore.getStoreState().used &&
!this._storeState.showFeedbackForm) {
this._dispatcher.dispatch(new loop.shared.actions.LeaveRoom());
} else {
loop.shared.mixins.WindowCloseMixin.closeWindow();

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

@ -404,6 +404,8 @@ loop.conversationViews = (function(mozL10n) {
case FAILURE_DETAILS.TOS_FAILURE:
return mozL10n.get("tos_failure_message",
{ clientShortname: mozL10n.get("clientShortname2") });
case FAILURE_DETAILS.ICE_FAILED:
return mozL10n.get("ice_failure_message");
default:
return mozL10n.get("generic_failure_message");
}

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

@ -404,6 +404,8 @@ loop.conversationViews = (function(mozL10n) {
case FAILURE_DETAILS.TOS_FAILURE:
return mozL10n.get("tos_failure_message",
{ clientShortname: mozL10n.get("clientShortname2") });
case FAILURE_DETAILS.ICE_FAILED:
return mozL10n.get("ice_failure_message");
default:
return mozL10n.get("generic_failure_message");
}

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

@ -8,6 +8,7 @@ loop.roomViews = (function(mozL10n) {
var ROOM_STATES = loop.store.ROOM_STATES;
var SCREEN_SHARE_STATES = loop.shared.utils.SCREEN_SHARE_STATES;
var FAILURE_DETAILS = loop.shared.utils.FAILURE_DETAILS;
var sharedActions = loop.shared.actions;
var sharedMixins = loop.shared.mixins;
var sharedUtils = loop.shared.utils;
@ -99,6 +100,14 @@ loop.roomViews = (function(mozL10n) {
{ id: "feedback" },
{ id: "help" }
];
var btnTitle;
if (this.props.failureReason === FAILURE_DETAILS.ICE_FAILED) {
btnTitle = mozL10n.get("retry_call_button");
} else {
btnTitle = mozL10n.get("rejoin_button");
}
return (
React.createElement("div", {className: "room-failure"},
React.createElement(loop.conversationViews.FailureInfoView, {
@ -106,7 +115,7 @@ loop.roomViews = (function(mozL10n) {
React.createElement("div", {className: "btn-group call-action-group"},
React.createElement("button", {className: "btn btn-info btn-rejoin",
onClick: this.handleRejoinCall},
mozL10n.get("rejoin_button")
btnTitle
)
),
React.createElement(loop.shared.views.SettingsControlButton, {

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

@ -8,6 +8,7 @@ loop.roomViews = (function(mozL10n) {
var ROOM_STATES = loop.store.ROOM_STATES;
var SCREEN_SHARE_STATES = loop.shared.utils.SCREEN_SHARE_STATES;
var FAILURE_DETAILS = loop.shared.utils.FAILURE_DETAILS;
var sharedActions = loop.shared.actions;
var sharedMixins = loop.shared.mixins;
var sharedUtils = loop.shared.utils;
@ -99,6 +100,14 @@ loop.roomViews = (function(mozL10n) {
{ id: "feedback" },
{ id: "help" }
];
var btnTitle;
if (this.props.failureReason === FAILURE_DETAILS.ICE_FAILED) {
btnTitle = mozL10n.get("retry_call_button");
} else {
btnTitle = mozL10n.get("rejoin_button");
}
return (
<div className="room-failure">
<loop.conversationViews.FailureInfoView
@ -106,7 +115,7 @@ loop.roomViews = (function(mozL10n) {
<div className="btn-group call-action-group">
<button className="btn btn-info btn-rejoin"
onClick={this.handleRejoinCall}>
{mozL10n.get("rejoin_button")}
{btnTitle}
</button>
</div>
<loop.shared.views.SettingsControlButton

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

@ -928,6 +928,13 @@ loop.OTSdkDriver = (function() {
_onOTException: function(event) {
switch (event.code) {
case OT.ExceptionCodes.PUBLISHER_ICE_WORKFLOW_FAILED:
case OT.ExceptionCodes.SUBSCRIBER_ICE_WORKFLOW_FAILED:
this.dispatcher.dispatch(new sharedActions.ConnectionFailure({
reason: FAILURE_DETAILS.ICE_FAILED
}));
this._notifyMetricsEvent("sdk.exception." + event.code);
break;
case OT.ExceptionCodes.UNABLE_TO_PUBLISH:
if (event.message === "GetUserMedia") {
// We free up the publisher here in case the store wants to try

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

@ -84,7 +84,8 @@ var inChrome = typeof Components != "undefined" && "utils" in Components;
// TOS_FAILURE reflects the sdk error code 1026:
// https://tokbox.com/developer/sdks/js/reference/ExceptionEvent.html
TOS_FAILURE: "reason-tos-failure",
UNKNOWN: "reason-unknown"
UNKNOWN: "reason-unknown",
ICE_FAILED: "reason-ice-failed"
};
var ROOM_INFO_FAILURES = {

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

@ -158,6 +158,8 @@ loop.standaloneRoomViews = (function(mozL10n) {
case FAILURE_DETAILS.TOS_FAILURE:
return mozL10n.get("tos_failure_message",
{ clientShortname: mozL10n.get("clientShortname2") });
case FAILURE_DETAILS.ICE_FAILED:
return mozL10n.get("rooms_ice_failure_message");
default:
return mozL10n.get("status_error");
}

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

@ -158,6 +158,8 @@ loop.standaloneRoomViews = (function(mozL10n) {
case FAILURE_DETAILS.TOS_FAILURE:
return mozL10n.get("tos_failure_message",
{ clientShortname: mozL10n.get("clientShortname2") });
case FAILURE_DETAILS.ICE_FAILED:
return mozL10n.get("rooms_ice_failure_message");
default:
return mozL10n.get("status_error");
}

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

@ -72,6 +72,7 @@ rooms_unavailable_notification_message=Sorry, you cannot join this conversation.
rooms_media_denied_message=We could not get access to your microphone or camera. Please reload the page to try again.
room_information_failure_not_available=No information about this conversation is available. Please request a new link from the person who sent it to you.
room_information_failure_unsupported_browser=Your browser cannot access any information about this conversation. Please make sure you're using the latest version.
rooms_ice_failure_message=Connection failed. Your firewall may be blocking calls.
## LOCALIZATION_NOTE(rooms_read_while_wait_offer): This string is followed by a
# tile/offer image and title that are provided by a separate service that has

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

@ -250,6 +250,19 @@ describe("loop.store.ConversationAppStore", function () {
sinon.assert.notCalled(loop.shared.mixins.WindowCloseMixin.closeWindow);
});
it("should close the window when a room was used and it showed feedback", function() {
store.setStoreState({
showFeedbackForm: true,
windowType: "room"
});
roomUsed = true;
store.LoopHangupNowHandler();
sinon.assert.notCalled(dispatcher.dispatch);
sinon.assert.calledOnce(loop.shared.mixins.WindowCloseMixin.closeWindow);
});
it("should close the window when a room was not used", function() {
store.setStoreState({ windowType: "room" });

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

@ -351,6 +351,16 @@ describe("loop.conversationViews", function () {
expect(extraFailureMessage.textContent).eql("Fake failure message");
});
it("should display an ICE failure message", function() {
view = mountTestComponent({
failureReason: FAILURE_DETAILS.ICE_FAILED
});
var message = view.getDOMNode().querySelector(".failure-info-message");
expect(message.textContent).eql("ice_failure_message");
});
});
describe("DirectCallFailureView", function() {

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

@ -142,7 +142,7 @@ describe("loop.roomViews", function () {
function mountTestComponent(props) {
props = _.extend({
dispatcher: dispatcher,
failureReason: FAILURE_DETAILS.UNKNOWN,
failureReason: props && props.failureReason || FAILURE_DETAILS.UNKNOWN,
mozLoop: fakeMozLoop
});
return TestUtils.renderIntoDocument(
@ -177,6 +177,16 @@ describe("loop.roomViews", function () {
new sharedActions.JoinRoom());
});
it("should render retry button when an ice failure is dispatched", function() {
view = mountTestComponent({
failureReason: FAILURE_DETAILS.ICE_FAILED
});
var retryBtn = view.getDOMNode().querySelector(".btn-rejoin");
expect(retryBtn.textContent).eql("retry_call_button");
});
it("should play a failure sound, once", function() {
view = mountTestComponent();

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

@ -1661,6 +1661,51 @@ describe("loop.OTSdkDriver", function () {
}));
});
});
describe("ICE failed", function() {
it("should dispatch a ConnectionFailure action (Publisher)", function() {
sdk.trigger("exception", {
code: OT.ExceptionCodes.PUBLISHER_ICE_WORKFLOW_FAILED,
message: "ICE failed"
});
sinon.assert.calledTwice(dispatcher.dispatch);
sinon.assert.calledWithExactly(dispatcher.dispatch,
new sharedActions.ConnectionFailure({
reason: FAILURE_DETAILS.ICE_FAILED
}));
});
it("should dispatch a ConnectionFailure action (Subscriber)", function() {
sdk.trigger("exception", {
code: OT.ExceptionCodes.SUBSCRIBER_ICE_WORKFLOW_FAILED,
message: "ICE failed"
});
sinon.assert.calledTwice(dispatcher.dispatch);
sinon.assert.calledWithExactly(dispatcher.dispatch,
new sharedActions.ConnectionFailure({
reason: FAILURE_DETAILS.ICE_FAILED
}));
});
it("should notify metrics", function() {
sdk.trigger("exception", {
code: OT.ExceptionCodes.PUBLISHER_ICE_WORKFLOW_FAILED,
message: "ICE failed"
});
sinon.assert.calledTwice(dispatcher.dispatch);
sinon.assert.calledWithExactly(dispatcher.dispatch,
new sharedActions.ConnectionStatus({
event: "sdk.exception." + OT.ExceptionCodes.PUBLISHER_ICE_WORKFLOW_FAILED,
state: "starting",
connections: 0,
sendStreams: 0,
recvStreams: 0
}));
});
});
});
});

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

@ -652,6 +652,17 @@ describe("loop.standaloneRoomViews", function() {
TestUtils.findRenderedComponentWithType(view,
loop.standaloneRoomViews.StandaloneRoomFailureView);
});
it("should display ICE failure message", function() {
activeRoomStore.setStoreState({
roomState: ROOM_STATES.FAILED,
failureReason: FAILURE_DETAILS.ICE_FAILED
});
var ice_failed_message = view.getDOMNode().querySelector(".failed-room-message").textContent;
expect(ice_failed_message).eql("rooms_ice_failure_message");
expect(view.getDOMNode().querySelector(".btn-info")).not.eql(null);
});
});
describe("Join button", function() {

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

@ -276,6 +276,9 @@ BrowserGlue.prototype = {
// nsIObserver implementation
observe: function BG_observe(subject, topic, data) {
switch (topic) {
case "notifications-open-settings":
this._openPreferences("content");
break;
case "prefservice:after-app-defaults":
this._onAppDefaults();
break;
@ -591,6 +594,7 @@ BrowserGlue.prototype = {
// initialization (called on application startup)
_init: function BG__init() {
let os = Services.obs;
os.addObserver(this, "notifications-open-settings", false);
os.addObserver(this, "prefservice:after-app-defaults", false);
os.addObserver(this, "final-ui-startup", false);
os.addObserver(this, "browser-delayed-startup-finished", false);
@ -639,6 +643,7 @@ BrowserGlue.prototype = {
// cleanup (called on application shutdown)
_dispose: function BG__dispose() {
let os = Services.obs;
os.removeObserver(this, "notifications-open-settings");
os.removeObserver(this, "prefservice:after-app-defaults");
os.removeObserver(this, "final-ui-startup");
os.removeObserver(this, "sessionstore-windows-restored");
@ -2361,6 +2366,19 @@ BrowserGlue.prototype = {
}
}),
/**
* Open preferences even if there are no open windows.
*/
_openPreferences(...args) {
if (Services.appShell.hiddenDOMWindow.openPreferences) {
Services.appShell.hiddenDOMWindow.openPreferences(...args);
return;
}
let chromeWindow = RecentWindow.getMostRecentBrowserWindow();
chromeWindow.openPreferences(...args);
},
#ifdef MOZ_SERVICES_SYNC
/**
* Called as an observer when Sync's "display URI" notification is fired.
@ -2534,38 +2552,6 @@ ContentPermissionPrompt.prototype = {
mainAction, secondaryActions, aOptions);
},
_promptPush : function(aRequest) {
var message = gBrowserBundle.GetStringFromName("push.enablePush2");
var actions = [
{
stringId: "push.alwaysAllow",
action: Ci.nsIPermissionManager.ALLOW_ACTION,
expireType: null,
callback: function() {}
},
{
stringId: "push.allowForSession",
action: Ci.nsIPermissionManager.ALLOW_ACTION,
expireType: Ci.nsIPermissionManager.EXPIRE_SESSION,
callback: function() {}
},
{
stringId: "push.alwaysBlock",
action: Ci.nsIPermissionManager.DENY_ACTION,
expireType: null,
callback: function() {}
}]
var options = {
learnMoreURL: Services.urlFormatter.formatURLPref("browser.push.warning.infoURL"),
};
this._showPrompt(aRequest, message, "push", actions, "push",
"push-notification-icon", options);
},
_promptGeo : function(aRequest) {
var secHistogram = Services.telemetry.getHistogramById("SECURITY_UI");
@ -2620,12 +2606,6 @@ ContentPermissionPrompt.prototype = {
var message = gBrowserBundle.GetStringFromName("webNotifications.showFromSite2");
var actions = [
{
stringId: "webNotifications.showForSession",
action: Ci.nsIPermissionManager.ALLOW_ACTION,
expireType: Ci.nsIPermissionManager.EXPIRE_SESSION,
callback: function() {},
},
{
stringId: "webNotifications.alwaysShow",
action: Ci.nsIPermissionManager.ALLOW_ACTION,
@ -2640,9 +2620,13 @@ ContentPermissionPrompt.prototype = {
},
];
var options = {
learnMoreURL: Services.urlFormatter.formatURLPref("browser.push.warning.infoURL"),
};
this._showPrompt(aRequest, message, "desktop-notification", actions,
"web-notifications",
"web-notifications-notification-icon", null);
"web-notifications-notification-icon", options);
},
_promptPointerLock: function CPP_promtPointerLock(aRequest, autoAllow) {
@ -2713,7 +2697,6 @@ ContentPermissionPrompt.prototype = {
const kFeatureKeys = { "geolocation" : "geo",
"desktop-notification" : "desktop-notification",
"pointerLock" : "pointerLock",
"push" : "push"
};
// Make sure that we support the request.
@ -2764,9 +2747,6 @@ ContentPermissionPrompt.prototype = {
case "pointerLock":
this._promptPointerLock(request, autoAllow);
break;
case "push":
this._promptPush(request);
break;
}
},

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

@ -46,7 +46,7 @@ var gVisitStmt = gPlacesDatabase.createAsyncStatement(
* Permission types that should be tested with testExactPermission, as opposed
* to testPermission. This is based on what consumers use to test these permissions.
*/
var TEST_EXACT_PERM_TYPES = ["geo", "camera", "microphone"];
var TEST_EXACT_PERM_TYPES = ["geo", "camera", "microphone", "desktop-notification"];
/**
* Site object represents a single site, uniquely identified by a principal.
@ -321,16 +321,9 @@ var PermissionDefaults = {
Services.prefs.setBoolPref("dom.disable_open_during_load", value);
},
get push() {
if (!Services.prefs.getBoolPref("dom.push.enabled")) {
return this.DENY;
}
get ["desktop-notification"]() {
return this.UNKNOWN;
},
set push(aValue) {
let value = (aValue != this.DENY);
Services.prefs.setBoolPref("dom.push.enabled", value);
},
get camera() {
return this.UNKNOWN;
},
@ -384,17 +377,18 @@ var AboutPermissions = {
* Potential future additions: "sts/use", "sts/subd"
*/
_supportedPermissions: ["password", "cookie", "geo", "indexedDB", "popup",
"camera", "microphone", "push"],
"camera", "microphone", "desktop-notification"],
/**
* Permissions that don't have a global "Allow" option.
*/
_noGlobalAllow: ["geo", "indexedDB", "camera", "microphone", "push"],
_noGlobalAllow: ["geo", "indexedDB", "camera", "microphone",
"desktop-notification"],
/**
* Permissions that don't have a global "Deny" option.
*/
_noGlobalDeny: ["camera", "microphone"],
_noGlobalDeny: ["camera", "microphone", "desktop-notification"],
_stringBundle: Services.strings.
createBundle("chrome://browser/locale/preferences/aboutPermissions.properties"),

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

@ -239,21 +239,21 @@
</vbox>
</hbox>
<!-- Push Notifications -->
<hbox id="push-pref-item"
<!-- Notifications -->
<hbox id="desktop-notification-pref-item"
class="pref-item" align="top">
<image class="pref-icon" type="push"/>
<image class="pref-icon" type="desktop-notification"/>
<vbox>
<label class="pref-title" value="&push.label;"/>
<label class="pref-title" value="&desktop-notification.label;"/>
<hbox align="center">
<menulist id="push-menulist"
<menulist id="desktop-notification-menulist"
class="pref-menulist"
type="push"
type="desktop-notification"
oncommand="AboutPermissions.onPermissionCommand(event);">
<menupopup>
<menuitem id="push-0" value="0" label="&permission.alwaysAsk;"/>
<menuitem id="push-1" value="1" label="&permission.allow;"/>
<menuitem id="push-2" value="2" label="&permission.block;"/>
<menuitem id="desktop-notification-0" value="0" label="&permission.alwaysAsk;"/>
<menuitem id="desktop-notification-1" value="1" label="&permission.allow;"/>
<menuitem id="desktop-notification-2" value="2" label="&permission.block;"/>
</menupopup>
</menulist>
</hbox>

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

@ -28,7 +28,7 @@ const TEST_PERMS = {
"password": PERM_ALLOW,
"cookie": PERM_ALLOW,
"geo": PERM_UNKNOWN,
"push": PERM_DENY,
"desktop-notification": PERM_UNKNOWN,
"indexedDB": PERM_UNKNOWN,
"popup": PERM_DENY,
"camera": PERM_UNKNOWN,

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

@ -119,9 +119,6 @@
<field name="FormHistory" readonly="true">
(Components.utils.import("resource://gre/modules/FormHistory.jsm", {})).FormHistory;
</field>
<field name="PlacesUtils" readonly="true">
(Components.utils.import("resource://gre/modules/PlacesUtils.jsm", {})).PlacesUtils;
</field>
<property name="engines" readonly="true">
<getter><![CDATA[
@ -1445,7 +1442,7 @@
button.id = "searchbar-engine-one-off-item-" + currentEngine.name.replace(/ /g, '-');
let uri = "chrome://browser/skin/search-engine-placeholder.png";
if (currentEngine.iconURI)
uri = PlacesUtils.getImageURLForResolution(window, currentEngine.iconURI.spec);
uri = currentEngine.iconURI.spec;
button.setAttribute("image", uri);
button.setAttribute("tooltiptext", currentEngine.name);
button.engine = currentEngine;

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

@ -375,23 +375,12 @@ geolocation.neverShareLocation.accesskey=N
geolocation.shareWithSite2=Would you like to share your location with this site?
geolocation.shareWithFile2=Would you like to share your location with this file?
webNotifications.showForSession=Show for this session
webNotifications.showForSession.accesskey=s
webNotifications.alwaysShow=Always Show Notifications
webNotifications.alwaysShow.accesskey=A
webNotifications.neverShow=Always Block Notifications
webNotifications.neverShow.accesskey=N
webNotifications.showFromSite2=Would you like to show notifications from this site?
# Push Notifications
push.allowForSession=Allow for Session
push.allowForSession.accesskey=S
push.alwaysAllow=Always Allow Push Notifications
push.alwaysAllow.accesskey=A
push.alwaysBlock=Always Block Push Notifications
push.alwaysBlock.accesskey=B
push.enablePush2=Would you like to allow Push Notifications for this site?
# Pointer lock UI
pointerLock.allow2=Hide pointer

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

@ -298,6 +298,7 @@ cannot_start_call_session_not_ready=Can't start call, session is not ready.
network_disconnected=The network connection terminated abruptly.
connection_error_see_console_notification=Call failed; see console for details.
no_media_failure_message=No camera or microphone found.
ice_failure_message=Connection failed. Your firewall may be blocking calls.
## LOCALIZATION NOTE (legal_text_and_links3): In this item, don't translate the
## parts between {{..}} because these will be replaced with links with the labels

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

@ -41,7 +41,7 @@
<!ENTITY popup.label "Open Pop-up Windows">
<!ENTITY push.label "Receive Push Notifications">
<!ENTITY desktop-notification.label "Show Notifications">
<!ENTITY camera.label "Use the Camera">
<!ENTITY microphone.label "Use the Microphone">

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

@ -17,4 +17,3 @@ permission.popup.label = Open Pop-up Windows
permission.geo.label = Access Your Location
permission.indexedDB.label = Maintain Offline Storage
permission.pointerLock.label = Hide the Mouse Pointer
permission.push.label = Receive Push Notifications

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

@ -161,7 +161,9 @@ var gPermissionObject = {
}
},
"desktop-notification": {},
"desktop-notification": {
exactHostMatch: true
},
"camera": {},
"microphone": {},
@ -188,9 +190,5 @@ var gPermissionObject = {
"pointerLock": {
exactHostMatch: true
},
"push": {
exactHostMatch: true
}
};

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

@ -8,7 +8,6 @@ Components.utils.import("resource:///modules/SitePermissions.jsm");
add_task(function* testPermissionsListing() {
Assert.deepEqual(SitePermissions.listPermissions().sort(),
["camera","cookie","desktop-notification","geo","image",
"indexedDB","install","microphone","pointerLock","popup",
"push"],
"indexedDB","install","microphone","pointerLock","popup"],
"Correct list of all permissions");
});

Двоичные данные
browser/themes/linux/Push-16.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 606 B

Двоичные данные
browser/themes/linux/Push-64.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 7.9 KiB

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

@ -23,8 +23,6 @@ browser.jar:
skin/classic/browser/content-contextmenu.svg
skin/classic/browser/Geolocation-16.png
skin/classic/browser/Geolocation-64.png
skin/classic/browser/Push-16.png
skin/classic/browser/Push-64.png
skin/classic/browser/Info.png
skin/classic/browser/menuPanel.png
skin/classic/browser/menuPanel@2x.png
@ -38,8 +36,6 @@ browser.jar:
skin/classic/browser/menuPanel-small@2x.png
skin/classic/browser/monitor.png
skin/classic/browser/monitor_16-10.png
skin/classic/browser/notification-16.png
skin/classic/browser/notification-64.png
* skin/classic/browser/pageInfo.css
skin/classic/browser/pageInfo.png
skin/classic/browser/page-livemarks.png

Двоичные данные
browser/themes/linux/notification-16.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 610 B

Двоичные данные
browser/themes/linux/notification-64.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 3.3 KiB

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

@ -94,8 +94,8 @@
.pref-icon[type="geo"] {
list-style-image: url(chrome://browser/skin/Geolocation-64.png);
}
.pref-icon[type="push"] {
list-style-image: url(chrome://browser/skin/Push-64.png);
.pref-icon[type="desktop-notification"] {
list-style-image: url(chrome://browser/skin/web-notifications-icon.svg);
}
.pref-icon[type="indexedDB"] {
list-style-image: url(chrome://global/skin/icons/question-64.png);

Двоичные данные
browser/themes/osx/Push-16.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 312 B

Двоичные данные
browser/themes/osx/Push-16@2x.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 666 B

Двоичные данные
browser/themes/osx/Push-64.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 8.3 KiB

Двоичные данные
browser/themes/osx/Push-64@2x.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 26 KiB

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

@ -25,10 +25,6 @@ browser.jar:
skin/classic/browser/Geolocation-16@2x.png
skin/classic/browser/Geolocation-64.png
skin/classic/browser/Geolocation-64@2x.png
skin/classic/browser/Push-16.png
skin/classic/browser/Push-16@2x.png
skin/classic/browser/Push-64.png
skin/classic/browser/Push-64@2x.png
skin/classic/browser/Info.png
skin/classic/browser/keyhole-circle.png
skin/classic/browser/keyhole-circle@2x.png
@ -36,10 +32,6 @@ browser.jar:
skin/classic/browser/subtle-pattern.png
skin/classic/browser/menu-back.png
skin/classic/browser/menu-forward.png
skin/classic/browser/notification-16.png
skin/classic/browser/notification-16@2x.png
skin/classic/browser/notification-64.png
skin/classic/browser/notification-64@2x.png
skin/classic/browser/menuPanel.png
skin/classic/browser/menuPanel@2x.png
skin/classic/browser/menuPanel-customize.png

Двоичные данные
browser/themes/osx/notification-16.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 610 B

Двоичные данные
browser/themes/osx/notification-16@2x.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.2 KiB

Двоичные данные
browser/themes/osx/notification-64.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 3.3 KiB

Двоичные данные
browser/themes/osx/notification-64@2x.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 7.2 KiB

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

@ -104,8 +104,8 @@
.pref-icon[type="geo"] {
list-style-image: url(chrome://browser/skin/Geolocation-64.png);
}
.pref-icon[type="push"] {
list-style-image: url(chrome://browser/skin/Push-64.png);
.pref-icon[type="desktop-notification"] {
list-style-image: url(chrome://browser/skin/web-notifications-icon.svg);
}
.pref-icon[type="indexedDB"] {
list-style-image: url(chrome://global/skin/icons/question-64.png);

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

@ -127,6 +127,8 @@
skin/classic/browser/notification-pluginAlert@2x.png (../shared/plugins/notification-pluginAlert@2x.png)
skin/classic/browser/notification-pluginBlocked.png (../shared/plugins/notification-pluginBlocked.png)
skin/classic/browser/notification-pluginBlocked@2x.png (../shared/plugins/notification-pluginBlocked@2x.png)
skin/classic/browser/web-notifications-icon.svg (../shared/web-notifications-icon.svg)
skin/classic/browser/web-notifications-tray.svg (../shared/web-notifications-tray.svg)
skin/classic/browser/webRTC-shareDevice-16.png (../shared/webrtc/webRTC-shareDevice-16.png)
skin/classic/browser/webRTC-shareDevice-16@2x.png (../shared/webrtc/webRTC-shareDevice-16@2x.png)
skin/classic/browser/webRTC-shareDevice-64.png (../shared/webrtc/webRTC-shareDevice-64.png)

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

@ -14,10 +14,6 @@
list-style-image: url(chrome://browser/skin/Geolocation-64.png);
}
.popup-notification-icon[popupid="push"] {
list-style-image: url(chrome://browser/skin/Push-64.png);
}
.popup-notification-icon[popupid="xpinstall-disabled"],
.popup-notification-icon[popupid="addon-install-blocked"],
.popup-notification-icon[popupid="addon-install-origin-blocked"] {
@ -53,7 +49,7 @@
}
.popup-notification-icon[popupid="web-notifications"] {
list-style-image: url(chrome://browser/skin/notification-64.png);
list-style-image: url(chrome://browser/skin/web-notifications-icon.svg);
}
.popup-notification-icon[popupid="indexedDB-permissions-prompt"],
@ -142,10 +138,6 @@
list-style-image: url(chrome://browser/skin/Geolocation-16.png);
}
#push-notification-icon {
list-style-image: url(chrome://browser/skin/Push-16.png);
}
#addons-notification-icon {
list-style-image: url(chrome://browser/skin/addons/addon-install-anchor.svg#default);
}
@ -254,7 +246,18 @@
.web-notifications-notification-icon,
#web-notifications-notification-icon {
list-style-image: url(chrome://browser/skin/notification-16.png);
list-style-image: url(chrome://browser/skin/web-notifications-tray.svg);
-moz-image-region: rect(0, 16px, 16px, 0);
}
.web-notifications-notification-icon:hover,
#web-notifications-notification-icon:hover {
-moz-image-region: rect(0, 32px, 16px, 16px);
}
.web-notifications-notification-icon:hover:active,
#web-notifications-notification-icon:hover:active {
-moz-image-region: rect(0, 48px, 16px, 32px);
}
.pointerLock-notification-icon,
@ -369,10 +372,6 @@
list-style-image: url(chrome://browser/skin/Geolocation-16@2x.png);
}
#push-notification-icon {
list-style-image: url(chrome://browser/skin/Push-16@2x.png);
}
.indexedDB-notification-icon,
#indexedDB-notification-icon {
list-style-image: url(chrome://global/skin/icons/question-32.png);
@ -412,11 +411,6 @@
-moz-image-region: rect(0, 96px, 32px, 64px);
}
.web-notifications-notification-icon,
#web-notifications-notification-icon {
list-style-image: url(chrome://browser/skin/notification-16@2x.png);
}
.pointerLock-notification-icon,
#pointerLock-notification-icon {
list-style-image: url(chrome://browser/skin/pointerLock-16@2x.png);
@ -438,14 +432,6 @@
list-style-image: url(chrome://browser/skin/Geolocation-64@2x.png);
}
.popup-notification-icon[popupid="push"] {
list-style-image: url(chrome://browser/skin/Push-64@2x.png);
}
.popup-notification-icon[popupid="web-notifications"] {
list-style-image: url(chrome://browser/skin/notification-64@2x.png);
}
.popup-notification-icon[popupid="pointerLock"] {
list-style-image: url(chrome://browser/skin/pointerLock-64@2x.png);
}

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

@ -84,7 +84,7 @@
list-style-image: url("chrome://browser/skin/social/chat-icons.svg#minimize-hover");
}
:hover,:hover:active) {
.chat-minimize-button:hover:active {
list-style-image: url("chrome://browser/skin/social/chat-icons.svg#minimize-active");
}

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

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid" width="64" height="64" viewBox="0 0 64 64">
<defs>
<style>
.icon {
fill: #a6a6a6;
fill-rule: evenodd;
}
</style>
</defs>
<path d="M57,48 L46,48 L46,60.016 L32.482,48 L7,48 C5.343,48 4,46.657 4,45 L4,11.031 C4,9.374 5.343,8.031 7,8.031 L57,8.031 C58.657,8.031 60,9.374 60,11.031 L60,45 C60,46.657 58.657,48 57,48 ZM36,16.031 C36,14.927 35.105,14.031 34,14.031 L30,14.031 C28.895,14.031 28,14.927 28,16.031 L28,30.031 C28,31.136 28.895,32.031 30,32.031 L34,32.031 C35.105,32.031 36,31.136 36,30.031 L36,16.031 ZM36,37.5 C36,36.672 35.328,36 34.5,36 L29.5,36 C28.672,36 28,36.672 28,37.5 L28,40.5 C28,41.328 28.672,42 29.5,42 L34.5,42 C35.328,42 36,41.328 36,40.5 L36,37.5 Z" class="icon"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 1.0 KiB

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

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="48" height="16" viewBox="0 0 96 32">
<defs>
<style>
.style-icon-notification {
fill: #666666;
}
.style-icon-notification.hover {
fill: #808080;
}
.style-icon-notification.active {
fill: #4d4d4d;
}
</style>
<path id="shape-notifcations-push" d="M27,23.969 L24,23.969 L24,29.977 L17.241,23.969 L5,23.969 C3.343,23.969 2,22.626 2,20.969 L2,6.969 C2,5.312 3.343,3.969 5,3.969 L27,3.969 C28.657,3.969 30,5.312 30,6.969 L30,20.969 C30,22.626 28.657,23.969 27,23.969 ZM18,8.969 C18,7.864 17.105,6.969 16,6.969 C14.895,6.969 14,7.864 14,8.969 L14,13.969 C14,15.073 14.895,15.969 16,15.969 C17.105,15.969 18,15.073 18,13.969 L18,8.969 ZM16.5,17.969 L15.5,17.969 C14.672,17.969 14,18.640 14,19.469 C14,20.297 14.672,20.969 15.5,20.969 L16.5,20.969 C17.328,20.969 18,20.297 18,19.469 C18,18.640 17.328,17.969 16.5,17.969 Z"/>
</defs>
<use xlink:href="#shape-notifcations-push" class="style-icon-notification"/>
<use xlink:href="#shape-notifcations-push" transform="translate(32)" class="style-icon-notification hover"/>
<use xlink:href="#shape-notifcations-push" transform="translate(64)" class="style-icon-notification active"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 1.5 KiB

Двоичные данные
browser/themes/windows/Push-16.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 704 B

Двоичные данные
browser/themes/windows/Push-64.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 8.2 KiB

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

@ -25,8 +25,6 @@ browser.jar:
skin/classic/browser/content-contextmenu.svg
skin/classic/browser/Geolocation-16.png
skin/classic/browser/Geolocation-64.png
skin/classic/browser/Push-16.png
skin/classic/browser/Push-64.png
skin/classic/browser/Info.png
skin/classic/browser/Info-XP.png
skin/classic/browser/keyhole-forward-mask.svg
@ -53,8 +51,6 @@ browser.jar:
skin/classic/browser/menuPanel-small-aero@2x.png
skin/classic/browser/monitor.png
skin/classic/browser/monitor_16-10.png
skin/classic/browser/notification-16.png
skin/classic/browser/notification-64.png
skin/classic/browser/pageInfo.css
skin/classic/browser/pageInfo.png
skin/classic/browser/pageInfo-XP.png

Двоичные данные
browser/themes/windows/notification-16.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 514 B

Двоичные данные
browser/themes/windows/notification-64.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 3.2 KiB

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

@ -98,8 +98,8 @@
.pref-icon[type="geo"] {
list-style-image: url(chrome://browser/skin/Geolocation-64.png);
}
.pref-icon[type="push"] {
list-style-image: url(chrome://browser/skin/Push-64.png);
.pref-icon[type="desktop-notification"] {
list-style-image: url(chrome://browser/skin/web-notifications-icon.svg);
}
.pref-icon[type="indexedDB"] {
list-style-image: url(chrome://global/skin/icons/question-64.png);

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

@ -295,8 +295,9 @@ AC_DEFUN([MOZ_ANDROID_GOOGLE_PLAY_SERVICES],
if test -n "$MOZ_NATIVE_DEVICES" ; then
AC_SUBST(MOZ_NATIVE_DEVICES)
MOZ_ANDROID_AAR(play-services-base, 7.8.0, google, com/google/android/gms)
MOZ_ANDROID_AAR(play-services-cast, 7.8.0, google, com/google/android/gms)
MOZ_ANDROID_AAR(play-services-base, 8.1.0, google, com/google/android/gms)
MOZ_ANDROID_AAR(play-services-basement, 8.1.0, google, com/google/android/gms)
MOZ_ANDROID_AAR(play-services-cast, 8.1.0, google, com/google/android/gms)
MOZ_ANDROID_AAR(mediarouter-v7, 22.2.1, android, com/android/support, REQUIRED_INTERNAL_IMPL)
fi

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

@ -4067,7 +4067,7 @@ if test -z "$gonkdir" ; then
;;
esac
MOZ_ANDROID_SDK(22, 22.0.1)
MOZ_ANDROID_SDK(23, 23.0.1)
;;
esac
fi

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

@ -10,7 +10,7 @@ const {Connection} = require("devtools/shared/client/connection-manager");
const {RuntimeTypes} = require("devtools/client/webide/modules/runtimes");
const Strings = Services.strings.createBundle("chrome://browser/locale/devtools/webide.properties");
const UNRESTRICTED_HELP_URL = "https://developer.mozilla.org/docs/Tools/WebIDE#Unrestricted_app_debugging_%28including_certified_apps.2C_main_process.2C_etc.%29";
const UNRESTRICTED_HELP_URL = "https://developer.mozilla.org/docs/Tools/WebIDE/Running_and_debugging_apps#Unrestricted_app_debugging_%28including_certified_apps_main_process_etc.%29";
window.addEventListener("load", function onLoad() {
window.removeEventListener("load", onLoad);

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

@ -1161,6 +1161,15 @@ NotificationObserver::Observe(nsISupports* aSubject, const char* aTopic,
}
permissionManager->RemoveFromPrincipal(mPrincipal, "desktop-notification");
return NS_OK;
} else if (!strcmp("alertsettingscallback", aTopic)) {
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (!obs) {
return NS_ERROR_FAILURE;
}
// Notify other observers so they can show settings UI.
obs->NotifyObservers(mPrincipal, "notifications-open-settings", nullptr);
return NS_OK;
}
return mObserver->Observe(aSubject, aTopic, aData);
@ -1630,9 +1639,9 @@ Notification::GetPermissionInternal(nsIPrincipal* aPrincipal,
nsCOMPtr<nsIPermissionManager> permissionManager =
services::GetPermissionManager();
permissionManager->TestPermissionFromPrincipal(aPrincipal,
"desktop-notification",
&permission);
permissionManager->TestExactPermissionFromPrincipal(aPrincipal,
"desktop-notification",
&permission);
// Convert the result to one of the enum types.
switch (permission) {

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

@ -12,7 +12,8 @@ namespace dom {
const char* kPermissionTypes[] = {
"geo",
"desktop-notification",
"push",
// Alias `push` to `desktop-notification`.
"desktop-notification",
"midi"
};

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

@ -23,7 +23,7 @@ SimpleTest.waitForExplicitFinish();
const PERMISSIONS = [
{ name: 'geolocation', perm: 'geo' },
{ name: 'notifications', perm: 'desktop-notification' },
{ name: 'push', perm: 'push' },
{ name: 'push', perm: 'desktop-notification' },
];
const UNSUPPORTED_PERMISSIONS = [

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

@ -67,13 +67,13 @@ Push.prototype = {
askPermission: function (aAllowCallback, aCancelCallback) {
debug("askPermission");
let principal = this._window.document.nodePrincipal;
let type = "push";
let permValue =
Services.perms.testExactPermissionFromPrincipal(principal, type);
let permValue = Services.perms.testExactPermissionFromPrincipal(
this._principal,
"desktop-notification"
);
if (permValue == Ci.nsIPermissionManager.ALLOW_ACTION) {
aAllowCallback();
aAllowCallback();
return;
}
@ -83,8 +83,8 @@ Push.prototype = {
}
// Create an array with a single nsIContentPermissionType element.
type = {
type: "push",
let type = {
type: "desktop-notification",
access: null,
options: [],
QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionType])
@ -95,7 +95,7 @@ Push.prototype = {
// create a nsIContentPermissionRequest
let request = {
types: typeArray,
principal: principal,
principal: this._principal,
QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionRequest]),
allow: function() {
let histogram = Services.telemetry.getHistogramById("PUSH_API_PERMISSION_GRANTED");
@ -182,11 +182,8 @@ Push.prototype = {
let permission = Ci.nsIPermissionManager.DENY_ACTION;
try {
let permissionManager = Cc["@mozilla.org/permissionmanager;1"]
.getService(Ci.nsIPermissionManager);
permission =
permissionManager.testExactPermissionFromPrincipal(this._principal,
"push");
permission = Services.perms.testExactPermissionFromPrincipal(
this._principal, "desktop-notification");
} catch(e) {
reject();
return;

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

@ -592,7 +592,7 @@ public:
uint32_t permission = nsIPermissionManager::DENY_ACTION;
nsresult rv = permManager->TestExactPermissionFromPrincipal(
principal,
"push",
"desktop-notification",
&permission);
if (NS_WARN_IF(NS_FAILED(rv)) || permission != nsIPermissionManager::ALLOW_ACTION) {
@ -732,28 +732,20 @@ public:
mozilla::services::GetPermissionManager();
nsresult rv = NS_ERROR_FAILURE;
PushPermissionState state = PushPermissionState::Denied;
PushPermissionState state = PushPermissionState::Prompt;
if (permManager) {
uint32_t permission = nsIPermissionManager::DENY_ACTION;
uint32_t permission = nsIPermissionManager::UNKNOWN_ACTION;
rv = permManager->TestExactPermissionFromPrincipal(
mProxy->GetWorkerPrivate()->GetPrincipal(),
"push",
"desktop-notification",
&permission);
if (NS_SUCCEEDED(rv)) {
switch (permission) {
case nsIPermissionManager::ALLOW_ACTION:
state = PushPermissionState::Granted;
break;
case nsIPermissionManager::DENY_ACTION:
state = PushPermissionState::Denied;
break;
case nsIPermissionManager::PROMPT_ACTION:
state = PushPermissionState::Prompt;
break;
default:
MOZ_CRASH("Unexpected case!");
if (permission == nsIPermissionManager::ALLOW_ACTION) {
state = PushPermissionState::Granted;
} else if (permission == nsIPermissionManager::DENY_ACTION) {
state = PushPermissionState::Denied;
}
}
}

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

@ -160,21 +160,13 @@ PushRecord.prototype = {
return false;
},
/**
* Returns the push permission state for the principal associated with
* this registration.
*/
pushPermission() {
return Services.perms.testExactPermissionFromPrincipal(
this.principal, "push");
},
/**
* Indicates whether the registration can deliver push messages to its
* associated service worker.
*/
hasPermission() {
let permission = this.pushPermission();
let permission = Services.perms.testExactPermissionFromPrincipal(
this.principal, "desktop-notification");
return permission == Ci.nsIPermissionManager.ALLOW_ACTION;
},

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

@ -179,7 +179,7 @@ http://creativecommons.org/licenses/publicdomain/
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true]
]}, runTest);
SpecialPowers.addPermission('push', true, document);
SpecialPowers.addPermission("desktop-notification", true, document);
SimpleTest.waitForExplicitFinish();
</script>
</body>

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

@ -65,7 +65,7 @@ http://creativecommons.org/licenses/publicdomain/
}).then(SimpleTest.finish);
}
SpecialPowers.addPermission('push', false, document);
SpecialPowers.addPermission("desktop-notification", false, document);
SpecialPowers.pushPrefEnv({"set": [
["dom.push.enabled", true],
["dom.serviceWorkers.exemptFromPerDomainMax", true],

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

@ -125,7 +125,7 @@ http://creativecommons.org/licenses/publicdomain/
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true]
]}, runTest);
SpecialPowers.addPermission('push', true, document);
SpecialPowers.addPermission("desktop-notification", true, document);
SimpleTest.waitForExplicitFinish();
</script>
</body>

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

@ -119,7 +119,7 @@ http://creativecommons.org/licenses/publicdomain/
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true]
]}, runTest);
SpecialPowers.addPermission('push', true, document);
SpecialPowers.addPermission("desktop-notification", true, document);
SimpleTest.waitForExplicitFinish();
</script>
</body>

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

@ -107,7 +107,7 @@ var defaultServerURL = SpecialPowers.getCharPref("dom.push.serverURL");
["dom.serviceWorkers.testing.enabled", true],
["dom.push.serverURL", "wss://something.org"]
]}, runTest);
SpecialPowers.addPermission('push', true, document);
SpecialPowers.addPermission("desktop-notification", true, document);
SimpleTest.waitForExplicitFinish();
</script>
</body>

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

@ -71,13 +71,33 @@ http://creativecommons.org/licenses/publicdomain/
}
function checkPermissionState(swr) {
return swr.pushManager.permissionState().then(function(state) {
ok(state === "denied", "permissionState() should resolve to denied.");
return swr;
}).catch(function(e) {
ok(false, "permissionState() should resolve to denied.");
return swr;
});
var permissionManager = SpecialPowers.Ci.nsIPermissionManager;
var tests = [{
action: permissionManager.ALLOW_ACTION,
state: "granted",
}, {
action: permissionManager.DENY_ACTION,
state: "denied",
}, {
action: permissionManager.PROMPT_ACTION,
state: "prompt",
}, {
action: permissionManager.UNKNOWN_ACTION,
state: "prompt",
}];
return tests.reduce((promise, test) => {
return promise.then(function() {
if (test.action == permissionManager.UNKNOWN_ACTION) {
SpecialPowers.removePermission("desktop-notification", document);
} else {
SpecialPowers.addPermission("desktop-notification",
test.action, document);
}
return swr.pushManager.permissionState().then(state => {
is(state, test.state, JSON.stringify(test));
});
});
}, Promise.resolve());
}
function runTest() {
@ -91,7 +111,7 @@ http://creativecommons.org/licenses/publicdomain/
}).then(SimpleTest.finish);
}
SpecialPowers.addPermission('push', false, document);
SpecialPowers.addPermission("desktop-notification", false, document);
SpecialPowers.pushPrefEnv({"set": [
["dom.push.enabled", true],
["dom.serviceWorkers.exemptFromPerDomainMax", true],

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

@ -131,7 +131,7 @@ http://creativecommons.org/licenses/publicdomain/
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true]
]}, runTest);
SpecialPowers.addPermission('push', true, document);
SpecialPowers.addPermission("desktop-notification", true, document);
SimpleTest.waitForExplicitFinish();
</script>
</body>

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

@ -293,7 +293,7 @@ http://creativecommons.org/licenses/publicdomain/
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true]
]}, runTest);
SpecialPowers.addPermission('push', true, document);
SpecialPowers.addPermission("desktop-notification", true, document);
SimpleTest.waitForExplicitFinish();
</script>
</body>

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

@ -85,7 +85,7 @@ http://creativecommons.org/licenses/publicdomain/
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true]
]}, runTest);
SpecialPowers.addPermission('push', true, document);
SpecialPowers.addPermission("desktop-notification", true, document);
SimpleTest.waitForExplicitFinish();
</script>
</body>

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

@ -98,7 +98,7 @@ this.RequestSyncService = {
// operation is completed.
this.dbTxn("readonly", function(aStore) {
aStore.openCursor().onsuccess = function(event) {
aStore.openCursor().onsuccess = event => {
let cursor = event.target.result;
if (cursor) {
this.addRegistration(cursor.value, cursor.continue);

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

@ -66,6 +66,7 @@ JAVA_CLASSPATH += \
ifdef MOZ_NATIVE_DEVICES
JAVA_CLASSPATH += \
$(ANDROID_PLAY_SERVICES_BASE_AAR_LIB) \
$(ANDROID_PLAY_SERVICES_BASEMENT_AAR_LIB) \
$(ANDROID_PLAY_SERVICES_CAST_AAR_LIB) \
$(ANDROID_MEDIAROUTER_V7_AAR_LIB) \
$(ANDROID_MEDIAROUTER_V7_AAR_INTERNAL_LIB) \
@ -86,6 +87,7 @@ java_bundled_libs := \
ifdef MOZ_NATIVE_DEVICES
java_bundled_libs += \
$(ANDROID_PLAY_SERVICES_BASE_AAR_LIB) \
$(ANDROID_PLAY_SERVICES_BASEMENT_AAR_LIB) \
$(ANDROID_PLAY_SERVICES_CAST_AAR_LIB) \
$(ANDROID_MEDIAROUTER_V7_AAR_LIB) \
$(ANDROID_MEDIAROUTER_V7_AAR_INTERNAL_LIB) \
@ -372,6 +374,7 @@ generated/android/support/v7/appcompat/R.java: .aapt.deps ;
generated/android/support/v7/mediarouter/R.java: .aapt.deps ;
generated/android/support/v7/recyclerview/R.java: .aapt.deps ;
generated/com/google/android/gms/R.java: .aapt.deps ;
generated/com/google/android/gms/base/R.java: .aapt.deps ;
generated/com/google/android/gms/cast/R.java: .aapt.deps ;
gecko.ap_: .aapt.deps ;

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

@ -14,6 +14,7 @@ import java.util.Locale;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.annotation.RobocopTarget;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.GeckoAppShell;
@ -25,6 +26,7 @@ import org.mozilla.gecko.Tab;
import org.mozilla.gecko.Tabs;
import org.mozilla.gecko.Telemetry;
import org.mozilla.gecko.TelemetryContract;
import org.mozilla.gecko.db.BrowserContract;
import org.mozilla.gecko.db.BrowserContract.History;
import org.mozilla.gecko.db.BrowserContract.URLColumns;
import org.mozilla.gecko.home.HomePager.OnUrlOpenListener;
@ -35,6 +37,7 @@ import org.mozilla.gecko.util.StringUtils;
import org.mozilla.gecko.util.ThreadUtils;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
@ -94,6 +97,7 @@ public class BrowserSearch extends HomeFragment
// AsyncTask loader ID for suggestion query
private static final int LOADER_ID_SUGGESTION = 1;
private static final int LOADER_ID_SAVED_SUGGESTION = 2;
// Timeout for the suggestion client to respond
private static final int SUGGESTION_TIMEOUT = 3000;
@ -137,6 +141,9 @@ public class BrowserSearch extends HomeFragment
// Access to this member must only occur from the UI thread.
private List<SearchEngine> mSearchEngines;
// Search history suggestions
private ArrayList<String> mSearchHistorySuggestions;
// Track the locale that was last in use when we filled mSearchEngines.
// Access to this member must only occur from the UI thread.
private Locale mLastLocale;
@ -148,7 +155,8 @@ public class BrowserSearch extends HomeFragment
private CursorLoaderCallbacks mCursorLoaderCallbacks;
// Callbacks used for the search suggestion loader
private SuggestionLoaderCallbacks mSuggestionLoaderCallbacks;
private SearchEngineSuggestionLoaderCallbacks mSearchEngineSuggestionLoaderCallbacks;
private SearchHistorySuggestionLoaderCallbacks mSearchHistorySuggestionLoaderCallback;
// Autocomplete handler used when filtering results
private AutocompleteHandler mAutocompleteHandler;
@ -220,6 +228,7 @@ public class BrowserSearch extends HomeFragment
super.onCreate(savedInstanceState);
mSearchEngines = new ArrayList<SearchEngine>();
mSearchHistorySuggestions = new ArrayList<>();
}
@Override
@ -355,7 +364,8 @@ public class BrowserSearch extends HomeFragment
mList.setAdapter(mAdapter);
// Only create an instance when we need it
mSuggestionLoaderCallbacks = null;
mSearchEngineSuggestionLoaderCallbacks = null;
mSearchHistorySuggestionLoaderCallback = null;
// Create callbacks before the initial loader is started
mCursorLoaderCallbacks = new CursorLoaderCallbacks();
@ -519,11 +529,20 @@ public class BrowserSearch extends HomeFragment
return;
}
if (mSuggestionLoaderCallbacks == null) {
mSuggestionLoaderCallbacks = new SuggestionLoaderCallbacks();
// Suggestions from search engine
if (mSearchEngineSuggestionLoaderCallbacks == null) {
mSearchEngineSuggestionLoaderCallbacks = new SearchEngineSuggestionLoaderCallbacks();
}
getLoaderManager().restartLoader(LOADER_ID_SUGGESTION, null, mSearchEngineSuggestionLoaderCallbacks);
getLoaderManager().restartLoader(LOADER_ID_SUGGESTION, null, mSuggestionLoaderCallbacks);
// Start search history suggestions query only in nightly. Bug 1201325
if (AppConstants.NIGHTLY_BUILD) {
// Saved suggestions
if (mSearchHistorySuggestionLoaderCallback == null) {
mSearchHistorySuggestionLoaderCallback = new SearchHistorySuggestionLoaderCallbacks();
}
getLoaderManager().restartLoader(LOADER_ID_SAVED_SUGGESTION, null, mSearchHistorySuggestionLoaderCallback);
}
}
private void setSuggestions(ArrayList<String> suggestions) {
@ -533,6 +552,13 @@ public class BrowserSearch extends HomeFragment
mAdapter.notifyDataSetChanged();
}
private void setSavedSuggestions(ArrayList<String> savedSuggestions) {
ThreadUtils.assertOnUiThread();
mSearchHistorySuggestions = savedSuggestions;
mAdapter.notifyDataSetChanged();
}
private void setSearchEngines(JSONObject data) {
ThreadUtils.assertOnUiThread();
@ -788,22 +814,15 @@ public class BrowserSearch extends HomeFragment
}
}
private static class SuggestionAsyncLoader extends AsyncTaskLoader<ArrayList<String>> {
private final SuggestClient mSuggestClient;
private final String mSearchTerm;
abstract private static class SuggestionAsyncLoader extends AsyncTaskLoader<ArrayList<String>> {
protected final String mSearchTerm;
private ArrayList<String> mSuggestions;
public SuggestionAsyncLoader(Context context, SuggestClient suggestClient, String searchTerm) {
public SuggestionAsyncLoader(Context context, String searchTerm) {
super(context);
mSuggestClient = suggestClient;
mSearchTerm = searchTerm;
}
@Override
public ArrayList<String> loadInBackground() {
return mSuggestClient.query(mSearchTerm);
}
@Override
public void deliverResult(ArrayList<String> suggestions) {
mSuggestions = suggestions;
@ -838,6 +857,58 @@ public class BrowserSearch extends HomeFragment
}
}
private static class SearchEngineSuggestionAsyncLoader extends SuggestionAsyncLoader {
private final SuggestClient mSuggestClient;
public SearchEngineSuggestionAsyncLoader(Context context, SuggestClient suggestClient, String searchTerm) {
super(context, searchTerm);
mSuggestClient = suggestClient;
}
@Override
public ArrayList<String> loadInBackground() {
return mSuggestClient.query(mSearchTerm);
}
}
private static class SearchHistorySuggestionAsyncLoader extends SuggestionAsyncLoader {
public SearchHistorySuggestionAsyncLoader(Context context, String searchTerm) {
super(context, searchTerm);
}
@Override
public ArrayList<String> loadInBackground() {
final ContentResolver cr = getContext().getContentResolver();
String[] columns = new String[] { BrowserContract.SearchHistory.QUERY };
String actualQuery = BrowserContract.SearchHistory.QUERY + " LIKE ?";
String[] queryArgs = new String[] { '%' + mSearchTerm + '%' };
final int maxSavedSuggestions = getContext().getResources().getInteger(R.integer.max_saved_suggestions);
final String sortOrderAndLimit = BrowserContract.SearchHistory.DATE +" DESC LIMIT " + maxSavedSuggestions;
final Cursor result = cr.query(BrowserContract.SearchHistory.CONTENT_URI, columns, actualQuery, queryArgs, sortOrderAndLimit);
if (result == null) {
return new ArrayList<>();
}
final ArrayList<String> savedSuggestions = new ArrayList<>();
try {
if (result.moveToFirst()) {
final int searchColumn = result.getColumnIndexOrThrow(BrowserContract.SearchHistory.QUERY);
do {
final String savedSearch = result.getString(searchColumn);
savedSuggestions.add(savedSearch);
} while (result.moveToNext());
}
} finally {
result.close();
}
return savedSuggestions;
}
}
private class SearchAdapter extends MultiTypeCursorAdapter {
private static final int ROW_SEARCH = 0;
private static final int ROW_STANDARD = 1;
@ -915,8 +986,9 @@ public class BrowserSearch extends HomeFragment
row.setSearchTerm(mSearchTerm);
final SearchEngine engine = mSearchEngines.get(position);
final boolean animate = (mAnimateSuggestions && engine.hasSuggestions());
row.updateSuggestions(mSuggestionsEnabled, engine, mSearchTerm, animate);
final boolean haveSuggestions = (engine.hasSuggestions() || !mSearchHistorySuggestions.isEmpty());
final boolean animate = (mAnimateSuggestions && haveSuggestions);
row.updateSuggestions(mSuggestionsEnabled, engine, mSearchHistorySuggestions, animate);
if (animate) {
// Only animate suggestions the first time they are shown
mAnimateSuggestions = false;
@ -955,13 +1027,13 @@ public class BrowserSearch extends HomeFragment
}
}
private class SuggestionLoaderCallbacks implements LoaderCallbacks<ArrayList<String>> {
private class SearchEngineSuggestionLoaderCallbacks implements LoaderCallbacks<ArrayList<String>> {
@Override
public Loader<ArrayList<String>> onCreateLoader(int id, Bundle args) {
// mSuggestClient is set to null in onDestroyView(), so using it
// safely here relies on the fact that onCreateLoader() is called
// synchronously in restartLoader().
return new SuggestionAsyncLoader(getActivity(), mSuggestClient, mSearchTerm);
return new SearchEngineSuggestionAsyncLoader(getActivity(), mSuggestClient, mSearchTerm);
}
@Override
@ -975,6 +1047,26 @@ public class BrowserSearch extends HomeFragment
}
}
private class SearchHistorySuggestionLoaderCallbacks implements LoaderCallbacks<ArrayList<String>> {
@Override
public Loader<ArrayList<String>> onCreateLoader(int id, Bundle args) {
// mSuggestClient is set to null in onDestroyView(), so using it
// safely here relies on the fact that onCreateLoader() is called
// synchronously in restartLoader().
return new SearchHistorySuggestionAsyncLoader(getActivity(), mSearchTerm);
}
@Override
public void onLoadFinished(Loader<ArrayList<String>> loader, ArrayList<String> suggestions) {
setSavedSuggestions(suggestions);
}
@Override
public void onLoaderReset(Loader<ArrayList<String>> loader) {
setSavedSuggestions(new ArrayList<String>());
}
}
private static class ListSelectionListener implements View.OnFocusChangeListener,
AdapterView.OnItemSelectedListener {
private SearchEngineRow mSelectedEngineRow;

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

@ -6,7 +6,6 @@
package org.mozilla.gecko.home;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.db.BrowserContract.SearchHistory;
import org.mozilla.gecko.GeckoSharedPrefs;
import org.mozilla.gecko.R;
import org.mozilla.gecko.Telemetry;
@ -22,8 +21,6 @@ import org.mozilla.gecko.widget.AnimatedHeightLayout;
import org.mozilla.gecko.widget.FaviconView;
import org.mozilla.gecko.widget.FlowLayout;
import android.database.Cursor;
import android.content.ContentResolver;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.drawable.Drawable;
@ -37,6 +34,7 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.EnumSet;
import java.util.List;
class SearchEngineRow extends AnimatedHeightLayout {
// Duration for fade-in animation
@ -242,55 +240,26 @@ class SearchEngineRow extends AnimatedHeightLayout {
/**
* Displays search suggestions from previous searches.
*
* @param c The Cursor to iterate over for saved search suggestion to display
* @param savedSuggestions The List to iterate over for saved search suggestions to display
* @param suggestionCounter global index of where to start adding suggestion "buttons" in the search engine row
* @param animate whether or not to animate suggestions for visual polish
* @param recycledSuggestionCount How many suggestion "button" views we could recycle from previous calls
*/
private void updateFromSavedSearches(Cursor c, boolean animate, int suggestionCounter, int recycledSuggestionCount) {
if (c == null) {
private void updateFromSavedSearches(List<String> savedSuggestions, boolean animate, int suggestionCounter, int recycledSuggestionCount) {
if (savedSuggestions == null || savedSuggestions.isEmpty()) {
return;
}
try {
if (c.moveToFirst()) {
final int searchColumn = c.getColumnIndexOrThrow(SearchHistory.QUERY);
final int historyStartIndex = suggestionCounter;
do {
final String savedSearch = c.getString(searchColumn);
// suggestionCounter counts all suggestions (from history and the search engine)
// but we want the relative position of the history item in telemetry
String telemetryTag = "history." + (suggestionCounter - historyStartIndex);
bindSuggestionView(savedSearch, animate, recycledSuggestionCount, suggestionCounter, true, telemetryTag);
++suggestionCounter;
} while (c.moveToNext());
}
} finally {
c.close();
final int historyStartIndex = suggestionCounter;
for (String suggestion : savedSuggestions) {
String telemetryTag = "history." + (suggestionCounter - historyStartIndex);
bindSuggestionView(suggestion, animate, recycledSuggestionCount, suggestionCounter, true, telemetryTag);
++suggestionCounter;
}
hideRecycledSuggestions(suggestionCounter, recycledSuggestionCount);
}
/**
* Gets matching suggestions from search history.
*
* @param searchTerm the string with which to look for matches in the saved searches
* @return matching prior searches that contain searchTerm
*/
private Cursor getSavedSearches(String searchTerm) {
if (!AppConstants.NIGHTLY_BUILD) {
return null;
}
final ContentResolver cr = getContext().getContentResolver();
String[] columns = new String[] { SearchHistory.QUERY };
String actualQuery = SearchHistory.QUERY + " LIKE ?";
String[] queryArgs = new String[] { '%' + searchTerm + '%' };
String sortOrderAndLimit = SearchHistory.DATE +" DESC LIMIT " + mMaxSavedSuggestions;
return cr.query(SearchHistory.CONTENT_URI, columns, actualQuery, queryArgs, sortOrderAndLimit);
}
/**
* Displays suggestions supplied by the search engine, relative to number of suggestions from search history.
*
@ -341,10 +310,10 @@ class SearchEngineRow extends AnimatedHeightLayout {
*
* @param searchSuggestionsEnabled whether or not suggestions from the default search engine are enabled
* @param searchEngine the search engine to use throughout the SearchEngineRow class
* @param searchTerm the text from the url to get suggestions on
* @param searchHistorySuggestions search history suggestions
* @param animate whether or not to use animations
**/
public void updateSuggestions(boolean searchSuggestionsEnabled, SearchEngine searchEngine, String searchTerm, boolean animate) {
public void updateSuggestions(boolean searchSuggestionsEnabled, SearchEngine searchEngine, List<String> searchHistorySuggestions, boolean animate) {
mSearchEngine = searchEngine;
// Set the search engine icon (e.g., Google) for the row.
mIconView.updateAndScaleImage(mSearchEngine.getIcon(), mSearchEngine.getEngineIdentifier());
@ -363,25 +332,12 @@ class SearchEngineRow extends AnimatedHeightLayout {
final boolean savedSearchesEnabled = prefs.getBoolean(GeckoPreferences.PREFS_HISTORY_SAVED_SEARCH, true);
if (searchSuggestionsEnabled && savedSearchesEnabled) {
final Cursor c = getSavedSearches(searchTerm);
try {
final int savedSearchCount = (c != null) ? c.getCount() : 0;
final int suggestionViewCount = updateFromSearchEngine(animate, recycledSuggestionCount, savedSearchCount);
updateFromSavedSearches(c, animate, suggestionViewCount, recycledSuggestionCount);
} finally {
if (c != null) {
c.close();
}
}
final int savedSearchCount = (searchHistorySuggestions != null) ? searchHistorySuggestions.size() : 0;
final int suggestionViewCount = updateFromSearchEngine(animate, recycledSuggestionCount, savedSearchCount);
updateFromSavedSearches(searchHistorySuggestions, animate, suggestionViewCount, recycledSuggestionCount);
} else if (savedSearchesEnabled) {
final Cursor c = getSavedSearches(searchTerm);
try {
updateFromSavedSearches(c, animate, 0, recycledSuggestionCount);
} finally {
if (c != null) {
c.close();
}
}
updateFromSavedSearches(searchHistorySuggestions, animate, 0, recycledSuggestionCount);
} else if (searchSuggestionsEnabled) {
updateFromSearchEngine(animate, recycledSuggestionCount, 0);
}

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

@ -225,6 +225,10 @@
<!ENTITY pref_donottrack_title "Do not track">
<!ENTITY pref_donottrack_summary "&brandShortName; will tell sites that you do not want to be tracked">
<!ENTITY pref_tracking_protection_enabled "Enabled">
<!ENTITY pref_tracking_protection_enabled_pb "Enabled in Private Browsing">
<!ENTITY pref_tracking_protection_disabled "Disabled">
<!ENTITY tracking_protection_prompt_title "Now with Tracking Protection">
<!ENTITY tracking_protection_prompt_text "Actively block tracking elements so you don\'t have to worry.">
<!ENTITY tracking_protection_prompt_tip_text "Visit Privacy settings to learn more">

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

@ -654,6 +654,7 @@ moz_native_devices_jars = [
CONFIG['ANDROID_MEDIAROUTER_V7_AAR_LIB'],
CONFIG['ANDROID_MEDIAROUTER_V7_AAR_INTERNAL_LIB'],
CONFIG['ANDROID_PLAY_SERVICES_BASE_AAR_LIB'],
CONFIG['ANDROID_PLAY_SERVICES_BASEMENT_AAR_LIB'],
CONFIG['ANDROID_PLAY_SERVICES_CAST_AAR_LIB'],
]
moz_native_devices_sources = [
@ -672,8 +673,13 @@ if CONFIG['MOZ_NATIVE_DEVICES']:
resjar.generated_sources += ['android/support/v7/mediarouter/R.java']
if CONFIG['ANDROID_PLAY_SERVICES_BASE_AAR']:
ANDROID_EXTRA_PACKAGES += ['com.google.android.gms']
ANDROID_EXTRA_PACKAGES += ['com.google.android.gms.base']
ANDROID_EXTRA_RES_DIRS += ['%' + CONFIG['ANDROID_PLAY_SERVICES_BASE_AAR_RES']]
resjar.generated_sources += ['com/google/android/gms/base/R.java']
if CONFIG['ANDROID_PLAY_SERVICES_BASEMENT_AAR']:
ANDROID_EXTRA_PACKAGES += ['com.google.android.gms']
ANDROID_EXTRA_RES_DIRS += ['%' + CONFIG['ANDROID_PLAY_SERVICES_BASEMENT_AAR_RES']]
resjar.generated_sources += ['com/google/android/gms/R.java']
if CONFIG['ANDROID_PLAY_SERVICES_CAST_AAR']:

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

@ -128,6 +128,8 @@ OnSharedPreferenceChangeListener
private static final String PREFS_DEVTOOLS_REMOTE_WIFI_ENABLED = "devtools.remote.wifi.enabled";
private static final String PREFS_DISPLAY_TITLEBAR_MODE = "browser.chrome.titlebarMode";
private static final String PREFS_SYNC = NON_PREF_PREFIX + "sync";
private static final String PREFS_TRACKING_PROTECTION = "privacy.trackingprotection.state";
private static final String PREFS_TRACKING_PROTECTION_PB = "privacy.trackingprotection.pbmode.enabled";
public static final String PREFS_OPEN_URLS_IN_PRIVATE = NON_PREF_PREFIX + "openExternalURLsPrivately";
public static final String PREFS_VOICE_INPUT_ENABLED = NON_PREF_PREFIX + "voice_input_enabled";
public static final String PREFS_QRCODE_ENABLED = NON_PREF_PREFIX + "qrcode_enabled";
@ -772,6 +774,20 @@ OnSharedPreferenceChangeListener
i--;
continue;
}
} else if (PREFS_TRACKING_PROTECTION.equals(key)) {
// Remove UI for global TP pref in non-Nightly builds.
if (!AppConstants.NIGHTLY_BUILD) {
preferences.removePreference(pref);
i--;
continue;
}
} else if (PREFS_TRACKING_PROTECTION_PB.equals(key)) {
// Remove UI for private-browsing-only TP pref in Nightly builds.
if (AppConstants.NIGHTLY_BUILD) {
preferences.removePreference(pref);
i--;
continue;
}
} else if (PREFS_TELEMETRY_ENABLED.equals(key)) {
if (!AppConstants.MOZ_TELEMETRY_REPORTING) {
preferences.removePreference(pref);

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше