зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to inbound. a=merge
This commit is contained in:
Коммит
d9f7626454
|
@ -64,10 +64,8 @@ XPCOMUtils.defineLazyServiceGetter(Services, 'captivePortalDetector',
|
||||||
'@mozilla.org/toolkit/captive-detector;1',
|
'@mozilla.org/toolkit/captive-detector;1',
|
||||||
'nsICaptivePortalDetector');
|
'nsICaptivePortalDetector');
|
||||||
|
|
||||||
if (AppConstants.MOZ_SAFE_BROWSING) {
|
XPCOMUtils.defineLazyModuleGetter(this, "SafeBrowsing",
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "SafeBrowsing",
|
"resource://gre/modules/SafeBrowsing.jsm");
|
||||||
"resource://gre/modules/SafeBrowsing.jsm");
|
|
||||||
}
|
|
||||||
|
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "SafeMode",
|
XPCOMUtils.defineLazyModuleGetter(this, "SafeMode",
|
||||||
"resource://gre/modules/SafeMode.jsm");
|
"resource://gre/modules/SafeMode.jsm");
|
||||||
|
@ -434,11 +432,9 @@ var shell = {
|
||||||
ppmm.addMessageListener("mail-handler", this);
|
ppmm.addMessageListener("mail-handler", this);
|
||||||
ppmm.addMessageListener("file-picker", this);
|
ppmm.addMessageListener("file-picker", this);
|
||||||
|
|
||||||
if (AppConstants.MOZ_SAFE_BROWSING) {
|
setTimeout(function() {
|
||||||
setTimeout(function() {
|
SafeBrowsing.init();
|
||||||
SafeBrowsing.init();
|
}, 5000);
|
||||||
}, 5000);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
stop: function shell_stop() {
|
stop: function shell_stop() {
|
||||||
|
|
|
@ -17,8 +17,6 @@ MOZ_BRANDING_DIRECTORY=b2g/branding/unofficial
|
||||||
MOZ_OFFICIAL_BRANDING_DIRECTORY=b2g/branding/official
|
MOZ_OFFICIAL_BRANDING_DIRECTORY=b2g/branding/official
|
||||||
# MOZ_APP_DISPLAYNAME is set by branding/configure.sh
|
# MOZ_APP_DISPLAYNAME is set by branding/configure.sh
|
||||||
|
|
||||||
MOZ_SAFE_BROWSING=1
|
|
||||||
|
|
||||||
MOZ_NO_SMART_CARDS=1
|
MOZ_NO_SMART_CARDS=1
|
||||||
MOZ_APP_STATIC_INI=1
|
MOZ_APP_STATIC_INI=1
|
||||||
MOZ_NO_EV_CERTS=1
|
MOZ_NO_EV_CERTS=1
|
||||||
|
|
|
@ -24,7 +24,6 @@ MOZ_BRANDING_DIRECTORY=b2g/branding/unofficial
|
||||||
MOZ_OFFICIAL_BRANDING_DIRECTORY=b2g/branding/official
|
MOZ_OFFICIAL_BRANDING_DIRECTORY=b2g/branding/official
|
||||||
# MOZ_APP_DISPLAYNAME is set by branding/configure.sh
|
# MOZ_APP_DISPLAYNAME is set by branding/configure.sh
|
||||||
|
|
||||||
MOZ_SAFE_BROWSING=1
|
|
||||||
MOZ_CAPTIVEDETECT=1
|
MOZ_CAPTIVEDETECT=1
|
||||||
|
|
||||||
MOZ_NO_SMART_CARDS=1
|
MOZ_NO_SMART_CARDS=1
|
||||||
|
|
|
@ -13,10 +13,8 @@
|
||||||
%customizeToolbarDTD;
|
%customizeToolbarDTD;
|
||||||
<!ENTITY % placesDTD SYSTEM "chrome://browser/locale/places/places.dtd">
|
<!ENTITY % placesDTD SYSTEM "chrome://browser/locale/places/places.dtd">
|
||||||
%placesDTD;
|
%placesDTD;
|
||||||
#ifdef MOZ_SAFE_BROWSING
|
|
||||||
<!ENTITY % safebrowsingDTD SYSTEM "chrome://browser/locale/safebrowsing/phishing-afterload-warning-message.dtd">
|
<!ENTITY % safebrowsingDTD SYSTEM "chrome://browser/locale/safebrowsing/phishing-afterload-warning-message.dtd">
|
||||||
%safebrowsingDTD;
|
%safebrowsingDTD;
|
||||||
#endif
|
|
||||||
<!ENTITY % aboutHomeDTD SYSTEM "chrome://browser/locale/aboutHome.dtd">
|
<!ENTITY % aboutHomeDTD SYSTEM "chrome://browser/locale/aboutHome.dtd">
|
||||||
%aboutHomeDTD;
|
%aboutHomeDTD;
|
||||||
<!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd">
|
<!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd">
|
||||||
|
|
|
@ -2,9 +2,6 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
// Note: this file is not shipped (through jar.mn)
|
|
||||||
// if MOZ_SAFE_BROWSING is not defined.
|
|
||||||
|
|
||||||
var gSafeBrowsing = {
|
var gSafeBrowsing = {
|
||||||
|
|
||||||
setReportPhishingMenu: function() {
|
setReportPhishingMenu: function() {
|
||||||
|
|
|
@ -763,7 +763,7 @@ html|*#fullscreen-exit-button {
|
||||||
-moz-user-focus: normal;
|
-moz-user-focus: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
.blocked-permission-icon:not([showing]),
|
#blocked-permissions-container > .blocked-permission-icon:not([showing]),
|
||||||
.notification-anchor-icon:not([showing]) {
|
.notification-anchor-icon:not([showing]) {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,10 +57,8 @@ Cu.import("resource://gre/modules/NotificationDB.jsm");
|
||||||
["webrtcUI", "resource:///modules/webrtcUI.jsm", ]
|
["webrtcUI", "resource:///modules/webrtcUI.jsm", ]
|
||||||
].forEach(([name, resource]) => XPCOMUtils.defineLazyModuleGetter(this, name, resource));
|
].forEach(([name, resource]) => XPCOMUtils.defineLazyModuleGetter(this, name, resource));
|
||||||
|
|
||||||
if (AppConstants.MOZ_SAFE_BROWSING) {
|
XPCOMUtils.defineLazyModuleGetter(this, "SafeBrowsing",
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "SafeBrowsing",
|
"resource://gre/modules/SafeBrowsing.jsm");
|
||||||
"resource://gre/modules/SafeBrowsing.jsm");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (AppConstants.MOZ_CRASHREPORTER) {
|
if (AppConstants.MOZ_CRASHREPORTER) {
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "PluginCrashReporter",
|
XPCOMUtils.defineLazyModuleGetter(this, "PluginCrashReporter",
|
||||||
|
@ -1146,10 +1144,8 @@ var gBrowserInit = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AppConstants.MOZ_SAFE_BROWSING) {
|
// Bug 778855 - Perf regression if we do this here. To be addressed in bug 779008.
|
||||||
// Bug 778855 - Perf regression if we do this here. To be addressed in bug 779008.
|
setTimeout(function() { SafeBrowsing.init(); }, 2000);
|
||||||
setTimeout(function() { SafeBrowsing.init(); }, 2000);
|
|
||||||
}
|
|
||||||
|
|
||||||
Services.obs.addObserver(gIdentityHandler, "perm-changed", false);
|
Services.obs.addObserver(gIdentityHandler, "perm-changed", false);
|
||||||
Services.obs.addObserver(gSessionHistoryObserver, "browser:purge-session-history", false);
|
Services.obs.addObserver(gSessionHistoryObserver, "browser:purge-session-history", false);
|
||||||
|
@ -7377,7 +7373,7 @@ var gIdentityHandler = {
|
||||||
let img = document.createElement("image");
|
let img = document.createElement("image");
|
||||||
let classes = "identity-popup-permission-icon " + aPermission.id + "-icon";
|
let classes = "identity-popup-permission-icon " + aPermission.id + "-icon";
|
||||||
if (aPermission.state == SitePermissions.BLOCK)
|
if (aPermission.state == SitePermissions.BLOCK)
|
||||||
classes += " blocked";
|
classes += " blocked-permission-icon";
|
||||||
if (aPermission.inUse)
|
if (aPermission.inUse)
|
||||||
classes += " in-use";
|
classes += " in-use";
|
||||||
img.setAttribute("class", classes);
|
img.setAttribute("class", classes);
|
||||||
|
|
|
@ -23,9 +23,7 @@
|
||||||
<script type="application/javascript" src="chrome://browser/content/browser-places.js"/>
|
<script type="application/javascript" src="chrome://browser/content/browser-places.js"/>
|
||||||
<script type="application/javascript" src="chrome://browser/content/browser-plugins.js"/>
|
<script type="application/javascript" src="chrome://browser/content/browser-plugins.js"/>
|
||||||
<script type="application/javascript" src="chrome://browser/content/browser-refreshblocker.js"/>
|
<script type="application/javascript" src="chrome://browser/content/browser-refreshblocker.js"/>
|
||||||
#ifdef MOZ_SAFE_BROWSING
|
|
||||||
<script type="application/javascript" src="chrome://browser/content/browser-safebrowsing.js"/>
|
<script type="application/javascript" src="chrome://browser/content/browser-safebrowsing.js"/>
|
||||||
#endif
|
|
||||||
<script type="application/javascript" src="chrome://browser/content/browser-sidebar.js"/>
|
<script type="application/javascript" src="chrome://browser/content/browser-sidebar.js"/>
|
||||||
<script type="application/javascript" src="chrome://browser/content/browser-social.js"/>
|
<script type="application/javascript" src="chrome://browser/content/browser-social.js"/>
|
||||||
<script type="application/javascript" src="chrome://browser/content/browser-syncui.js"/>
|
<script type="application/javascript" src="chrome://browser/content/browser-syncui.js"/>
|
||||||
|
|
|
@ -695,8 +695,11 @@ nsContextMenu.prototype = {
|
||||||
this.target.getRequest(Ci.nsIImageLoadingContent.CURRENT_REQUEST);
|
this.target.getRequest(Ci.nsIImageLoadingContent.CURRENT_REQUEST);
|
||||||
if (request && (request.imageStatus & request.STATUS_SIZE_AVAILABLE))
|
if (request && (request.imageStatus & request.STATUS_SIZE_AVAILABLE))
|
||||||
this.onLoadedImage = true;
|
this.onLoadedImage = true;
|
||||||
if (request && (request.imageStatus & request.STATUS_LOAD_COMPLETE))
|
if (request &&
|
||||||
|
(request.imageStatus & request.STATUS_LOAD_COMPLETE) &&
|
||||||
|
!(request.imageStatus & request.STATUS_ERROR)) {
|
||||||
this.onCompletedImage = true;
|
this.onCompletedImage = true;
|
||||||
|
}
|
||||||
|
|
||||||
this.mediaURL = this.target.currentURI.spec;
|
this.mediaURL = this.target.currentURI.spec;
|
||||||
|
|
||||||
|
|
|
@ -742,8 +742,9 @@ function openTourPage()
|
||||||
function buildHelpMenu()
|
function buildHelpMenu()
|
||||||
{
|
{
|
||||||
// Enable/disable the "Report Web Forgery" menu item.
|
// Enable/disable the "Report Web Forgery" menu item.
|
||||||
if (typeof gSafeBrowsing != "undefined" && AppConstants.MOZ_SAFE_BROWSING)
|
if (typeof gSafeBrowsing != "undefined") {
|
||||||
gSafeBrowsing.setReportPhishingMenu();
|
gSafeBrowsing.setReportPhishingMenu();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isElementVisible(aElement)
|
function isElementVisible(aElement)
|
||||||
|
|
|
@ -87,9 +87,7 @@ browser.jar:
|
||||||
content/browser/browser-places.js (content/browser-places.js)
|
content/browser/browser-places.js (content/browser-places.js)
|
||||||
content/browser/browser-plugins.js (content/browser-plugins.js)
|
content/browser/browser-plugins.js (content/browser-plugins.js)
|
||||||
content/browser/browser-refreshblocker.js (content/browser-refreshblocker.js)
|
content/browser/browser-refreshblocker.js (content/browser-refreshblocker.js)
|
||||||
#ifdef MOZ_SAFE_BROWSING
|
|
||||||
content/browser/browser-safebrowsing.js (content/browser-safebrowsing.js)
|
content/browser/browser-safebrowsing.js (content/browser-safebrowsing.js)
|
||||||
#endif
|
|
||||||
content/browser/browser-sidebar.js (content/browser-sidebar.js)
|
content/browser/browser-sidebar.js (content/browser-sidebar.js)
|
||||||
content/browser/browser-social.js (content/browser-social.js)
|
content/browser/browser-social.js (content/browser-social.js)
|
||||||
content/browser/browser-syncui.js (content/browser-syncui.js)
|
content/browser/browser-syncui.js (content/browser-syncui.js)
|
||||||
|
@ -191,10 +189,8 @@ browser.jar:
|
||||||
# the following files are browser-specific overrides
|
# the following files are browser-specific overrides
|
||||||
* content/browser/license.html (/toolkit/content/license.html)
|
* content/browser/license.html (/toolkit/content/license.html)
|
||||||
% override chrome://global/content/license.html chrome://browser/content/license.html
|
% override chrome://global/content/license.html chrome://browser/content/license.html
|
||||||
#ifdef MOZ_SAFE_BROWSING
|
|
||||||
content/browser/report-phishing-overlay.xul (content/report-phishing-overlay.xul)
|
content/browser/report-phishing-overlay.xul (content/report-phishing-overlay.xul)
|
||||||
content/browser/blockedSite.xhtml (content/blockedSite.xhtml)
|
content/browser/blockedSite.xhtml (content/blockedSite.xhtml)
|
||||||
% overlay chrome://browser/content/browser.xul chrome://browser/content/report-phishing-overlay.xul
|
% overlay chrome://browser/content/browser.xul chrome://browser/content/report-phishing-overlay.xul
|
||||||
#endif
|
|
||||||
|
|
||||||
% override chrome://global/content/netError.xhtml chrome://browser/content/aboutNetError.xhtml
|
% override chrome://global/content/netError.xhtml chrome://browser/content/aboutNetError.xhtml
|
||||||
|
|
|
@ -35,13 +35,11 @@ struct RedirEntry {
|
||||||
URI_SAFE_FOR_UNTRUSTED_CONTENT.
|
URI_SAFE_FOR_UNTRUSTED_CONTENT.
|
||||||
*/
|
*/
|
||||||
static RedirEntry kRedirMap[] = {
|
static RedirEntry kRedirMap[] = {
|
||||||
#ifdef MOZ_SAFE_BROWSING
|
|
||||||
{ "blocked", "chrome://browser/content/blockedSite.xhtml",
|
{ "blocked", "chrome://browser/content/blockedSite.xhtml",
|
||||||
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
|
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
|
||||||
nsIAboutModule::URI_CAN_LOAD_IN_CHILD |
|
nsIAboutModule::URI_CAN_LOAD_IN_CHILD |
|
||||||
nsIAboutModule::ALLOW_SCRIPT |
|
nsIAboutModule::ALLOW_SCRIPT |
|
||||||
nsIAboutModule::HIDE_FROM_ABOUTABOUT },
|
nsIAboutModule::HIDE_FROM_ABOUTABOUT },
|
||||||
#endif
|
|
||||||
{ "certerror", "chrome://browser/content/aboutNetError.xhtml",
|
{ "certerror", "chrome://browser/content/aboutNetError.xhtml",
|
||||||
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
|
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
|
||||||
nsIAboutModule::URI_CAN_LOAD_IN_CHILD |
|
nsIAboutModule::URI_CAN_LOAD_IN_CHILD |
|
||||||
|
|
|
@ -85,9 +85,7 @@ static const mozilla::Module::ContractIDEntry kBrowserContracts[] = {
|
||||||
{ NS_SHELLSERVICE_CONTRACTID, &kNS_SHELLSERVICE_CID },
|
{ NS_SHELLSERVICE_CONTRACTID, &kNS_SHELLSERVICE_CID },
|
||||||
#endif
|
#endif
|
||||||
{ NS_FEEDSNIFFER_CONTRACTID, &kNS_FEEDSNIFFER_CID },
|
{ NS_FEEDSNIFFER_CONTRACTID, &kNS_FEEDSNIFFER_CID },
|
||||||
#ifdef MOZ_SAFE_BROWSING
|
|
||||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "blocked", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "blocked", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
||||||
#endif
|
|
||||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "certerror", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "certerror", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
||||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "socialerror", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "socialerror", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
||||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "providerdirectory", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "providerdirectory", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
||||||
|
|
|
@ -50,6 +50,7 @@ EXTRA_JS_MODULES += [
|
||||||
]
|
]
|
||||||
|
|
||||||
BROWSER_CHROME_MANIFESTS += [
|
BROWSER_CHROME_MANIFESTS += [
|
||||||
|
'safebrowsing/content/test/browser.ini',
|
||||||
'tests/browser/browser.ini'
|
'tests/browser/browser.ini'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -57,9 +58,6 @@ XPCSHELL_TESTS_MANIFESTS += [
|
||||||
'tests/unit/xpcshell.ini'
|
'tests/unit/xpcshell.ini'
|
||||||
]
|
]
|
||||||
|
|
||||||
if CONFIG['MOZ_SAFE_BROWSING']:
|
|
||||||
BROWSER_CHROME_MANIFESTS += ['safebrowsing/content/test/browser.ini']
|
|
||||||
|
|
||||||
with Files('safebrowsing/*'):
|
with Files('safebrowsing/*'):
|
||||||
BUG_COMPONENT = ('Toolkit', 'Phishing Protection')
|
BUG_COMPONENT = ('Toolkit', 'Phishing Protection')
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,6 @@ fi
|
||||||
# Enable building ./signmar and running libmar signature tests
|
# Enable building ./signmar and running libmar signature tests
|
||||||
MOZ_ENABLE_SIGNMAR=1
|
MOZ_ENABLE_SIGNMAR=1
|
||||||
|
|
||||||
MOZ_SAFE_BROWSING=1
|
|
||||||
MOZ_APP_VERSION=$FIREFOX_VERSION
|
MOZ_APP_VERSION=$FIREFOX_VERSION
|
||||||
MOZ_APP_VERSION_DISPLAY=$FIREFOX_VERSION_DISPLAY
|
MOZ_APP_VERSION_DISPLAY=$FIREFOX_VERSION_DISPLAY
|
||||||
MOZ_EXTENSIONS_DEFAULT=" gio"
|
MOZ_EXTENSIONS_DEFAULT=" gio"
|
||||||
|
|
|
@ -596,13 +596,11 @@
|
||||||
@RESPATH@/modules/*
|
@RESPATH@/modules/*
|
||||||
|
|
||||||
; Safe Browsing
|
; Safe Browsing
|
||||||
#ifdef MOZ_URL_CLASSIFIER
|
|
||||||
@RESPATH@/components/nsURLClassifier.manifest
|
@RESPATH@/components/nsURLClassifier.manifest
|
||||||
@RESPATH@/components/nsUrlClassifierHashCompleter.js
|
@RESPATH@/components/nsUrlClassifierHashCompleter.js
|
||||||
@RESPATH@/components/nsUrlClassifierListManager.js
|
@RESPATH@/components/nsUrlClassifierListManager.js
|
||||||
@RESPATH@/components/nsUrlClassifierLib.js
|
@RESPATH@/components/nsUrlClassifierLib.js
|
||||||
@RESPATH@/components/url-classifier.xpt
|
@RESPATH@/components/url-classifier.xpt
|
||||||
#endif
|
|
||||||
|
|
||||||
; Private Browsing
|
; Private Browsing
|
||||||
@RESPATH@/components/privatebrowsing.xpt
|
@RESPATH@/components/privatebrowsing.xpt
|
||||||
|
|
|
@ -53,10 +53,8 @@
|
||||||
locale/browser/places/bookmarkProperties.properties (%chrome/browser/places/bookmarkProperties.properties)
|
locale/browser/places/bookmarkProperties.properties (%chrome/browser/places/bookmarkProperties.properties)
|
||||||
locale/browser/preferences/selectBookmark.dtd (%chrome/browser/preferences/selectBookmark.dtd)
|
locale/browser/preferences/selectBookmark.dtd (%chrome/browser/preferences/selectBookmark.dtd)
|
||||||
locale/browser/places/moveBookmarks.dtd (%chrome/browser/places/moveBookmarks.dtd)
|
locale/browser/places/moveBookmarks.dtd (%chrome/browser/places/moveBookmarks.dtd)
|
||||||
#ifdef MOZ_SAFE_BROWSING
|
|
||||||
locale/browser/safebrowsing/phishing-afterload-warning-message.dtd (%chrome/browser/safebrowsing/phishing-afterload-warning-message.dtd)
|
locale/browser/safebrowsing/phishing-afterload-warning-message.dtd (%chrome/browser/safebrowsing/phishing-afterload-warning-message.dtd)
|
||||||
locale/browser/safebrowsing/report-phishing.dtd (%chrome/browser/safebrowsing/report-phishing.dtd)
|
locale/browser/safebrowsing/report-phishing.dtd (%chrome/browser/safebrowsing/report-phishing.dtd)
|
||||||
#endif
|
|
||||||
locale/browser/feeds/subscribe.dtd (%chrome/browser/feeds/subscribe.dtd)
|
locale/browser/feeds/subscribe.dtd (%chrome/browser/feeds/subscribe.dtd)
|
||||||
locale/browser/feeds/subscribe.properties (%chrome/browser/feeds/subscribe.properties)
|
locale/browser/feeds/subscribe.properties (%chrome/browser/feeds/subscribe.properties)
|
||||||
locale/browser/migration/migration.dtd (%chrome/browser/migration/migration.dtd)
|
locale/browser/migration/migration.dtd (%chrome/browser/migration/migration.dtd)
|
||||||
|
|
|
@ -221,8 +221,8 @@ fi
|
||||||
])
|
])
|
||||||
|
|
||||||
dnl Configure an Android SDK.
|
dnl Configure an Android SDK.
|
||||||
dnl Arg 1: target SDK version, like 22.
|
dnl Arg 1: target SDK version, like 23.
|
||||||
dnl Arg 2: build tools version, like 22.0.1.
|
dnl Arg 2: list of build-tools versions, like "23.0.3 23.0.1".
|
||||||
AC_DEFUN([MOZ_ANDROID_SDK],
|
AC_DEFUN([MOZ_ANDROID_SDK],
|
||||||
[
|
[
|
||||||
|
|
||||||
|
@ -254,12 +254,21 @@ case "$target" in
|
||||||
fi
|
fi
|
||||||
AC_MSG_RESULT([$android_sdk])
|
AC_MSG_RESULT([$android_sdk])
|
||||||
|
|
||||||
android_build_tools="$android_sdk_root"/build-tools/$2
|
AC_MSG_CHECKING([for Android build-tools])
|
||||||
AC_MSG_CHECKING([for Android build-tools version $2])
|
android_build_tools_base="$android_sdk_root"/build-tools
|
||||||
if test -d "$android_build_tools" -a -f "$android_build_tools/aapt"; then
|
android_build_tools_version=""
|
||||||
AC_MSG_RESULT([$android_build_tools])
|
versions=($2)
|
||||||
else
|
for version in $versions; do
|
||||||
AC_MSG_ERROR([You must install the Android build-tools version $2. Try |mach bootstrap|. (Looked for $android_build_tools)])
|
android_build_tools="$android_build_tools_base"/$version
|
||||||
|
if test -d "$android_build_tools" -a -f "$android_build_tools/aapt"; then
|
||||||
|
android_build_tools_version=$version
|
||||||
|
AC_MSG_RESULT([$android_build_tools])
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if test "$android_build_tools_version" == ""; then
|
||||||
|
version=$(echo $versions | cut -d" " -f1)
|
||||||
|
AC_MSG_ERROR([You must install the Android build-tools version $version. Try |mach bootstrap|. (Looked for "$android_build_tools_base"/$version)])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
MOZ_PATH_PROG(ZIPALIGN, zipalign, :, [$android_build_tools])
|
MOZ_PATH_PROG(ZIPALIGN, zipalign, :, [$android_build_tools])
|
||||||
|
@ -309,7 +318,7 @@ case "$target" in
|
||||||
ANDROID_SDK="${android_sdk}"
|
ANDROID_SDK="${android_sdk}"
|
||||||
ANDROID_SDK_ROOT="${android_sdk_root}"
|
ANDROID_SDK_ROOT="${android_sdk_root}"
|
||||||
ANDROID_TOOLS="${android_tools}"
|
ANDROID_TOOLS="${android_tools}"
|
||||||
ANDROID_BUILD_TOOLS_VERSION="$2"
|
ANDROID_BUILD_TOOLS_VERSION="$android_build_tools_version"
|
||||||
AC_DEFINE_UNQUOTED(ANDROID_TARGET_SDK,$ANDROID_TARGET_SDK)
|
AC_DEFINE_UNQUOTED(ANDROID_TARGET_SDK,$ANDROID_TARGET_SDK)
|
||||||
AC_SUBST(ANDROID_TARGET_SDK)
|
AC_SUBST(ANDROID_TARGET_SDK)
|
||||||
AC_SUBST(ANDROID_SDK_ROOT)
|
AC_SUBST(ANDROID_SDK_ROOT)
|
||||||
|
|
|
@ -13,4 +13,7 @@ DevToolsModules(
|
||||||
'panel.js'
|
'panel.js'
|
||||||
)
|
)
|
||||||
|
|
||||||
BROWSER_CHROME_MANIFESTS += ['test/mochitest/browser.ini']
|
BROWSER_CHROME_MANIFESTS += [
|
||||||
|
'new/test/mochitest/browser.ini',
|
||||||
|
'test/mochitest/browser.ini'
|
||||||
|
]
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
[DEFAULT]
|
||||||
|
tags = devtools
|
||||||
|
subsuite = devtools
|
||||||
|
|
||||||
|
[browser_dbg_stub.js]
|
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
add_task(function*() {
|
||||||
|
ok(true,
|
||||||
|
"This is a stub so that we can run the new debugger tests " +
|
||||||
|
"by copying them in here. This will go away once we land " +
|
||||||
|
"the initial suite of new tests");
|
||||||
|
});
|
|
@ -182,14 +182,28 @@ Tools.jsdebugger = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (Services.prefs.getBoolPref("devtools.debugger.new-debugger-frontend")) {
|
function switchDebugger() {
|
||||||
const NewDebuggerPanel = require("devtools/client/debugger/new/panel").DebuggerPanel;
|
if (Services.prefs.getBoolPref("devtools.debugger.new-debugger-frontend")) {
|
||||||
|
const NewDebuggerPanel = require("devtools/client/debugger/new/panel").DebuggerPanel;
|
||||||
|
|
||||||
Tools.jsdebugger.url = "chrome://devtools/content/debugger/new/index.html";
|
Tools.jsdebugger.url = "chrome://devtools/content/debugger/new/index.html";
|
||||||
Tools.jsdebugger.build = function (iframeWindow, toolbox) {
|
Tools.jsdebugger.build = function (iframeWindow, toolbox) {
|
||||||
return new NewDebuggerPanel(iframeWindow, toolbox);
|
return new NewDebuggerPanel(iframeWindow, toolbox);
|
||||||
};
|
};
|
||||||
|
} else {
|
||||||
|
Tools.jsdebugger.url = "chrome://devtools/content/debugger/debugger.xul";
|
||||||
|
Tools.jsdebugger.build = function (iframeWindow, toolbox) {
|
||||||
|
return new DebuggerPanel(iframeWindow, toolbox);
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
switchDebugger();
|
||||||
|
|
||||||
|
Services.prefs.addObserver(
|
||||||
|
"devtools.debugger.new-debugger-frontend",
|
||||||
|
{ observe: switchDebugger },
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
Tools.styleEditor = {
|
Tools.styleEditor = {
|
||||||
id: "styleeditor",
|
id: "styleeditor",
|
||||||
|
|
|
@ -176,7 +176,8 @@ module.exports = createClass({
|
||||||
if (functionDisplayName) {
|
if (functionDisplayName) {
|
||||||
elements.push(
|
elements.push(
|
||||||
dom.span({ className: "frame-link-function-display-name" },
|
dom.span({ className: "frame-link-function-display-name" },
|
||||||
functionDisplayName)
|
functionDisplayName),
|
||||||
|
" "
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -236,7 +237,7 @@ module.exports = createClass({
|
||||||
elements.push(sourceEl);
|
elements.push(sourceEl);
|
||||||
|
|
||||||
if (showHost && host) {
|
if (showHost && host) {
|
||||||
elements.push(dom.span({ className: "frame-link-host" }, host));
|
elements.push(" ", dom.span({ className: "frame-link-host" }, host));
|
||||||
}
|
}
|
||||||
|
|
||||||
return dom.span(attributes, ...elements);
|
return dom.span(attributes, ...elements);
|
||||||
|
|
|
@ -42,12 +42,12 @@ const StackTrace = createClass({
|
||||||
let frames = [];
|
let frames = [];
|
||||||
stacktrace.forEach(s => {
|
stacktrace.forEach(s => {
|
||||||
if (s.asyncCause) {
|
if (s.asyncCause) {
|
||||||
frames.push(AsyncFrame({
|
frames.push("\t", AsyncFrame({
|
||||||
asyncCause: s.asyncCause
|
asyncCause: s.asyncCause
|
||||||
}));
|
}), "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
frames.push(Frame({
|
frames.push("\t", Frame({
|
||||||
frame: {
|
frame: {
|
||||||
functionDisplayName: s.functionName,
|
functionDisplayName: s.functionName,
|
||||||
source: s.filename.split(" -> ").pop(),
|
source: s.filename.split(" -> ").pop(),
|
||||||
|
@ -58,7 +58,7 @@ const StackTrace = createClass({
|
||||||
showAnonymousFunctionName: true,
|
showAnonymousFunctionName: true,
|
||||||
showFullSourceUrl: true,
|
showFullSourceUrl: true,
|
||||||
onClick: onViewSourceInDebugger
|
onClick: onViewSourceInDebugger
|
||||||
}));
|
}), "\n");
|
||||||
});
|
});
|
||||||
|
|
||||||
return dom.div({ className: "stack-trace" }, frames);
|
return dom.div({ className: "stack-trace" }, frames);
|
||||||
|
|
|
@ -45,7 +45,9 @@ window.onload = function() {
|
||||||
let traceEl = trace.getDOMNode();
|
let traceEl = trace.getDOMNode();
|
||||||
ok(traceEl, "Rendered StackTrace has an element");
|
ok(traceEl, "Rendered StackTrace has an element");
|
||||||
|
|
||||||
let frameEls = traceEl.childNodes;
|
// Get the child nodes and filter out the text-only whitespace ones
|
||||||
|
let frameEls = Array.from(traceEl.childNodes)
|
||||||
|
.filter(n => n.className.includes("frame"));
|
||||||
ok(frameEls, "Rendered StackTrace has frames");
|
ok(frameEls, "Rendered StackTrace has frames");
|
||||||
is(frameEls.length, 3, "StackTrace has 3 frames");
|
is(frameEls.length, 3, "StackTrace has 3 frames");
|
||||||
|
|
||||||
|
@ -76,6 +78,14 @@ window.onload = function() {
|
||||||
shouldLink: true,
|
shouldLink: true,
|
||||||
tooltip: "View source in Debugger → http://myfile.com/loadee.js:10",
|
tooltip: "View source in Debugger → http://myfile.com/loadee.js:10",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Check the tabs and newlines in the stack trace textContent
|
||||||
|
let traceText = traceEl.textContent;
|
||||||
|
let traceLines = traceText.split("\n");
|
||||||
|
ok(traceLines.length > 0, "There are newlines in the stack trace text");
|
||||||
|
is(traceLines.pop(), "", "There is a newline at the end of the stack trace text");
|
||||||
|
is(traceLines.length, 3, "The stack trace text has 3 lines");
|
||||||
|
ok(traceLines.every(l => l[0] == "\t"), "Every stack trace line starts with tab");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -935,8 +935,6 @@ Messages.Simple.prototype = extend(Messages.BaseMessage.prototype, {
|
||||||
|
|
||||||
this.element.appendChild(body);
|
this.element.appendChild(body);
|
||||||
|
|
||||||
this.element.appendChild(this.document.createTextNode("\n"));
|
|
||||||
|
|
||||||
this.element.clipboardText = this.element.textContent;
|
this.element.clipboardText = this.element.textContent;
|
||||||
|
|
||||||
if (this.private) {
|
if (this.private) {
|
||||||
|
@ -993,12 +991,16 @@ Messages.Simple.prototype = extend(Messages.BaseMessage.prototype, {
|
||||||
let location = this._renderLocation();
|
let location = this._renderLocation();
|
||||||
|
|
||||||
if (repeatNode) {
|
if (repeatNode) {
|
||||||
|
bodyFlex.appendChild(this.document.createTextNode(" "));
|
||||||
bodyFlex.appendChild(repeatNode);
|
bodyFlex.appendChild(repeatNode);
|
||||||
}
|
}
|
||||||
if (location) {
|
if (location) {
|
||||||
|
bodyFlex.appendChild(this.document.createTextNode(" "));
|
||||||
bodyFlex.appendChild(location);
|
bodyFlex.appendChild(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bodyFlex.appendChild(this.document.createTextNode("\n"));
|
||||||
|
|
||||||
if (this.stack) {
|
if (this.stack) {
|
||||||
this._attachment = new Widgets.Stacktrace(this, this.stack).render().element;
|
this._attachment = new Widgets.Stacktrace(this, this.stack).render().element;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,67 +3,95 @@
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
/* globals goDoCommand */
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// Test copying of the entire console message when right-clicked
|
// Test copying of the entire console message when right-clicked
|
||||||
// with no other text selected. See Bug 1100562.
|
// with no other text selected. See Bug 1100562.
|
||||||
|
|
||||||
function test() {
|
add_task(function* () {
|
||||||
let hud;
|
let hud;
|
||||||
let outputNode;
|
let outputNode;
|
||||||
let contextMenu;
|
let contextMenu;
|
||||||
|
|
||||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/test/test-console.html";
|
||||||
"test/test-console.html";
|
|
||||||
|
|
||||||
Task.spawn(runner).then(finishTest);
|
const { tab, browser } = yield loadTab(TEST_URI);
|
||||||
|
hud = yield openConsole(tab);
|
||||||
|
outputNode = hud.outputNode;
|
||||||
|
contextMenu = hud.iframeWindow.document.getElementById("output-contextmenu");
|
||||||
|
|
||||||
function* runner() {
|
registerCleanupFunction(() => {
|
||||||
const {tab} = yield loadTab(TEST_URI);
|
hud = outputNode = contextMenu = null;
|
||||||
hud = yield openConsole(tab);
|
});
|
||||||
outputNode = hud.outputNode;
|
|
||||||
contextMenu = hud.iframeWindow.document.getElementById("output-contextmenu");
|
|
||||||
|
|
||||||
registerCleanupFunction(() => {
|
hud.jsterm.clearOutput();
|
||||||
hud = outputNode = contextMenu = null;
|
|
||||||
});
|
|
||||||
|
|
||||||
hud.jsterm.clearOutput();
|
yield ContentTask.spawn(browser, {}, function* () {
|
||||||
content.console.log("bug 1100562");
|
let button = content.document.getElementById("testTrace");
|
||||||
|
button.click();
|
||||||
|
});
|
||||||
|
|
||||||
let [results] = yield waitForMessages({
|
let results = yield waitForMessages({
|
||||||
webconsole: hud,
|
webconsole: hud,
|
||||||
messages: [{
|
messages: [
|
||||||
|
{
|
||||||
text: "bug 1100562",
|
text: "bug 1100562",
|
||||||
category: CATEGORY_WEBDEV,
|
category: CATEGORY_WEBDEV,
|
||||||
severity: SEVERITY_LOG,
|
severity: SEVERITY_LOG,
|
||||||
}]
|
lines: 1,
|
||||||
});
|
},
|
||||||
|
{
|
||||||
|
name: "console.trace output",
|
||||||
|
consoleTrace: true,
|
||||||
|
lines: 3,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
outputNode.focus();
|
outputNode.focus();
|
||||||
let message = [...results.matched][0];
|
|
||||||
|
|
||||||
yield waitForContextMenu(contextMenu, message, copyFromPopup,
|
for (let result of results) {
|
||||||
testContextMenuCopy);
|
let message = [...result.matched][0];
|
||||||
|
|
||||||
function copyFromPopup() {
|
yield waitForContextMenu(contextMenu, message, () => {
|
||||||
let copyItem = contextMenu.querySelector("#cMenu_copy");
|
let copyItem = contextMenu.querySelector("#cMenu_copy");
|
||||||
copyItem.doCommand();
|
copyItem.doCommand();
|
||||||
|
|
||||||
let controller = top.document.commandDispatcher
|
let controller = top.document.commandDispatcher
|
||||||
.getControllerForCommand("cmd_copy");
|
.getControllerForCommand("cmd_copy");
|
||||||
is(controller.isCommandEnabled("cmd_copy"), true, "cmd_copy is enabled");
|
is(controller.isCommandEnabled("cmd_copy"), true, "cmd_copy is enabled");
|
||||||
}
|
});
|
||||||
|
|
||||||
function testContextMenuCopy() {
|
let clipboardText;
|
||||||
waitForClipboard((str) => {
|
|
||||||
return message.textContent.trim() == str.trim();
|
|
||||||
}, () => {
|
|
||||||
goDoCommand("cmd_copy");
|
|
||||||
}, () => {}, () => {}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
yield closeConsole(tab);
|
yield waitForClipboardPromise(
|
||||||
|
() => goDoCommand("cmd_copy"),
|
||||||
|
(str) => {
|
||||||
|
clipboardText = str;
|
||||||
|
return message.textContent == clipboardText;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(clipboardText, "Clipboard text was found and saved");
|
||||||
|
|
||||||
|
let lines = clipboardText.split("\n");
|
||||||
|
ok(lines.length > 0, "There is at least one newline in the message");
|
||||||
|
is(lines.pop(), "", "There is a newline at the end");
|
||||||
|
is(lines.length, result.lines, `There are ${result.lines} lines in the message`);
|
||||||
|
|
||||||
|
// Test the first line for "timestamp message repeat file:line"
|
||||||
|
let firstLine = lines.shift();
|
||||||
|
ok(/^[\d:.]+ .+ \d+ .+:\d+$/.test(firstLine),
|
||||||
|
"The message's first line has the right format");
|
||||||
|
|
||||||
|
// Test the remaining lines (stack trace) for "TABfunctionName sourceURL:line:col"
|
||||||
|
for (let line of lines) {
|
||||||
|
ok(/^\t.+ .+:\d+:\d+$/.test(line), "The stack trace line has the right format");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
yield closeConsole(tab);
|
||||||
|
yield finishTest();
|
||||||
|
});
|
||||||
|
|
|
@ -13,6 +13,12 @@
|
||||||
console.log(str);
|
console.log(str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testTrace() {
|
||||||
|
console.log("bug 1100562");
|
||||||
|
console.trace();
|
||||||
|
}
|
||||||
|
|
||||||
console.info("INLINE SCRIPT:");
|
console.info("INLINE SCRIPT:");
|
||||||
test();
|
test();
|
||||||
console.warn("I'm warning you, he will eat up all yr bacon.");
|
console.warn("I'm warning you, he will eat up all yr bacon.");
|
||||||
|
@ -22,6 +28,7 @@
|
||||||
<body>
|
<body>
|
||||||
<h1 id="header">Heads Up Display Demo</h1>
|
<h1 id="header">Heads Up Display Demo</h1>
|
||||||
<button onclick="test();">Log stuff about Dolske</button>
|
<button onclick="test();">Log stuff about Dolske</button>
|
||||||
|
<button id="testTrace" onclick="testTrace();">Log stuff with stacktrace</button>
|
||||||
<div id="myDiv"></div>
|
<div id="myDiv"></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -6,6 +6,24 @@
|
||||||
const parsePropertiesFile = require("devtools/shared/node-properties/node-properties");
|
const parsePropertiesFile = require("devtools/shared/node-properties/node-properties");
|
||||||
const { sprintf } = require("devtools/shared/sprintfjs/sprintf");
|
const { sprintf } = require("devtools/shared/sprintfjs/sprintf");
|
||||||
|
|
||||||
|
const propertiesMap = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Memoized getter for properties files that ensures a given url is only required and
|
||||||
|
* parsed once.
|
||||||
|
*
|
||||||
|
* @param {String} url
|
||||||
|
* The URL of the properties file to parse.
|
||||||
|
* @return {Object} parsed properties mapped in an object.
|
||||||
|
*/
|
||||||
|
function getProperties(url) {
|
||||||
|
if (!propertiesMap[url]) {
|
||||||
|
propertiesMap[url] = parsePropertiesFile(require(`raw!${url}`));
|
||||||
|
}
|
||||||
|
|
||||||
|
return propertiesMap[url];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Localization convenience methods.
|
* Localization convenience methods.
|
||||||
*
|
*
|
||||||
|
@ -17,14 +35,6 @@ function LocalizationHelper(stringBundleName) {
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalizationHelper.prototype = {
|
LocalizationHelper.prototype = {
|
||||||
get properties() {
|
|
||||||
if (!this._properties) {
|
|
||||||
this._properties = parsePropertiesFile(require(`raw!${this.stringBundleName}`));
|
|
||||||
}
|
|
||||||
|
|
||||||
return this._properties;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* L10N shortcut function.
|
* L10N shortcut function.
|
||||||
*
|
*
|
||||||
|
@ -32,8 +42,9 @@ LocalizationHelper.prototype = {
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
getStr: function (name) {
|
getStr: function (name) {
|
||||||
if (name in this.properties) {
|
let properties = getProperties(this.stringBundleName);
|
||||||
return this.properties[name];
|
if (name in properties) {
|
||||||
|
return properties[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error("No localization found for [" + name + "]");
|
throw new Error("No localization found for [" + name + "]");
|
||||||
|
@ -103,6 +114,63 @@ LocalizationHelper.prototype = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function getPropertiesForNode(node) {
|
||||||
|
let bundleEl = node.closest("[data-localization-bundle]");
|
||||||
|
if (!bundleEl) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
let propertiesUrl = bundleEl.getAttribute("data-localization-bundle");
|
||||||
|
return getProperties(propertiesUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translate existing markup annotated with data-localization attributes.
|
||||||
|
*
|
||||||
|
* How to use data-localization in markup:
|
||||||
|
*
|
||||||
|
* <div data-localization="content=myContent;title=myTitle"/>
|
||||||
|
*
|
||||||
|
* The data-localization attribute identifies an element as being localizable.
|
||||||
|
* The content of the attribute is semi-colon separated list of descriptors.
|
||||||
|
* - "title=myTitle" means the "title" attribute should be replaced with the localized
|
||||||
|
* string corresponding to the key "myTitle".
|
||||||
|
* - "content=myContent" means the text content of the node should be replaced by the
|
||||||
|
* string corresponding to "myContent"
|
||||||
|
*
|
||||||
|
* How to define the localization bundle in markup:
|
||||||
|
*
|
||||||
|
* <div data-localization-bundle="url/to/my.properties">
|
||||||
|
* [...]
|
||||||
|
* <div data-localization="content=myContent;title=myTitle"/>
|
||||||
|
*
|
||||||
|
* Set the data-localization-bundle on an ancestor of the nodes that should be localized.
|
||||||
|
*
|
||||||
|
* @param {Element} root
|
||||||
|
* The root node to use for the localization
|
||||||
|
*/
|
||||||
|
function localizeMarkup(root) {
|
||||||
|
let elements = root.querySelectorAll("[data-localization]");
|
||||||
|
for (let element of elements) {
|
||||||
|
let properties = getPropertiesForNode(element);
|
||||||
|
if (!properties) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let attributes = element.getAttribute("data-localization").split(";");
|
||||||
|
for (let attribute of attributes) {
|
||||||
|
let [name, value] = attribute.trim().split("=");
|
||||||
|
if (name === "content") {
|
||||||
|
element.textContent = properties[value];
|
||||||
|
} else {
|
||||||
|
element.setAttribute(name, properties[value]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
element.removeAttribute("data-localization");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const sharedL10N = new LocalizationHelper("devtools-shared/locale/shared.properties");
|
const sharedL10N = new LocalizationHelper("devtools-shared/locale/shared.properties");
|
||||||
const ELLIPSIS = sharedL10N.getStr("ellipsis");
|
const ELLIPSIS = sharedL10N.getStr("ellipsis");
|
||||||
|
|
||||||
|
@ -140,5 +208,6 @@ function MultiLocalizationHelper(...stringBundleNames) {
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.LocalizationHelper = LocalizationHelper;
|
exports.LocalizationHelper = LocalizationHelper;
|
||||||
|
exports.localizeMarkup = localizeMarkup;
|
||||||
exports.MultiLocalizationHelper = MultiLocalizationHelper;
|
exports.MultiLocalizationHelper = MultiLocalizationHelper;
|
||||||
exports.ELLIPSIS = ELLIPSIS;
|
exports.ELLIPSIS = ELLIPSIS;
|
||||||
|
|
|
@ -5,3 +5,4 @@ support-files =
|
||||||
../../../server/tests/browser/head.js
|
../../../server/tests/browser/head.js
|
||||||
|
|
||||||
[browser_async_storage.js]
|
[browser_async_storage.js]
|
||||||
|
[browser_l10n_localizeMarkup.js]
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// Tests that the markup localization works properly.
|
||||||
|
|
||||||
|
const { localizeMarkup, LocalizationHelper } = require("devtools/shared/l10n");
|
||||||
|
|
||||||
|
add_task(function* () {
|
||||||
|
info("Check that the strings used for this test are still valid");
|
||||||
|
let INSPECTOR_L10N = new LocalizationHelper("devtools/locale/inspector.properties");
|
||||||
|
let TOOLBOX_L10N = new LocalizationHelper("devtools/locale/toolbox.properties");
|
||||||
|
let str1 = INSPECTOR_L10N.getStr("inspector.label");
|
||||||
|
let str2 = INSPECTOR_L10N.getStr("inspector.commandkey");
|
||||||
|
let str3 = TOOLBOX_L10N.getStr("toolbox.defaultTitle");
|
||||||
|
ok(str1 && str2 && str3, "If this failed, strings should be updated in the test");
|
||||||
|
|
||||||
|
info("Create the test markup");
|
||||||
|
let div = document.createElement("div");
|
||||||
|
div.innerHTML =
|
||||||
|
`<div data-localization-bundle="devtools/locale/inspector.properties">
|
||||||
|
<div id="d0" data-localization="content=inspector.someInvalidKey"></div>
|
||||||
|
<div id="d1" data-localization="content=inspector.label">Text will disappear</div>
|
||||||
|
<div id="d2" data-localization="content=inspector.label;title=inspector.commandkey">
|
||||||
|
</div>
|
||||||
|
<!-- keep the following data-localization on two separate lines -->
|
||||||
|
<div id="d3" data-localization="content=inspector.label;
|
||||||
|
title=inspector.commandkey"></div>
|
||||||
|
<div id="d4" data-localization="aria-label=inspector.label">Some content</div>
|
||||||
|
<div data-localization-bundle="devtools/locale/toolbox.properties">
|
||||||
|
<div id="d5" data-localization="content=toolbox.defaultTitle"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
info("Use localization helper to localize the test markup");
|
||||||
|
localizeMarkup(div);
|
||||||
|
|
||||||
|
let div1 = div.querySelector("#d1");
|
||||||
|
let div2 = div.querySelector("#d2");
|
||||||
|
let div3 = div.querySelector("#d3");
|
||||||
|
let div4 = div.querySelector("#d4");
|
||||||
|
let div5 = div.querySelector("#d5");
|
||||||
|
|
||||||
|
is(div1.innerHTML, str1, "The content of #d1 is localized");
|
||||||
|
is(div2.innerHTML, str1, "The content of #d2 is localized");
|
||||||
|
is(div2.getAttribute("title"), str2, "The title of #d2 is localized");
|
||||||
|
is(div3.innerHTML, str1, "The content of #d3 is localized");
|
||||||
|
is(div3.getAttribute("title"), str2, "The title of #d3 is localized");
|
||||||
|
is(div4.innerHTML, "Some content", "The content of #d4 is not replaced");
|
||||||
|
is(div4.getAttribute("aria-label"), str1, "The aria-label of #d4 is localized");
|
||||||
|
is(div5.innerHTML, str3, "The content of #d5 is localized with another bundle");
|
||||||
|
});
|
|
@ -143,10 +143,14 @@ AnimationEffectReadOnly::GetComputedTimingAt(
|
||||||
StickyTimeDuration activeTime;
|
StickyTimeDuration activeTime;
|
||||||
|
|
||||||
StickyTimeDuration beforeActiveBoundary =
|
StickyTimeDuration beforeActiveBoundary =
|
||||||
std::min(StickyTimeDuration(aTiming.mDelay), result.mEndTime);
|
std::max(std::min(StickyTimeDuration(aTiming.mDelay), result.mEndTime),
|
||||||
|
zeroDuration);
|
||||||
|
|
||||||
StickyTimeDuration activeAfterBoundary =
|
StickyTimeDuration activeAfterBoundary =
|
||||||
std::min(StickyTimeDuration(aTiming.mDelay + result.mActiveDuration),
|
std::max(std::min(StickyTimeDuration(aTiming.mDelay +
|
||||||
result.mEndTime);
|
result.mActiveDuration),
|
||||||
|
result.mEndTime),
|
||||||
|
zeroDuration);
|
||||||
|
|
||||||
if (localTime > activeAfterBoundary ||
|
if (localTime > activeAfterBoundary ||
|
||||||
(aPlaybackRate >= 0 && localTime == activeAfterBoundary)) {
|
(aPlaybackRate >= 0 && localTime == activeAfterBoundary)) {
|
||||||
|
@ -155,9 +159,10 @@ AnimationEffectReadOnly::GetComputedTimingAt(
|
||||||
// The animation isn't active or filling at this time.
|
// The animation isn't active or filling at this time.
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
activeTime = std::max(std::min(result.mActiveDuration,
|
activeTime =
|
||||||
result.mActiveDuration + aTiming.mEndDelay),
|
std::max(std::min(StickyTimeDuration(localTime - aTiming.mDelay),
|
||||||
zeroDuration);
|
result.mActiveDuration),
|
||||||
|
zeroDuration);
|
||||||
} else if (localTime < beforeActiveBoundary ||
|
} else if (localTime < beforeActiveBoundary ||
|
||||||
(aPlaybackRate < 0 && localTime == beforeActiveBoundary)) {
|
(aPlaybackRate < 0 && localTime == beforeActiveBoundary)) {
|
||||||
result.mPhase = ComputedTiming::AnimationPhase::Before;
|
result.mPhase = ComputedTiming::AnimationPhase::Before;
|
||||||
|
@ -165,7 +170,8 @@ AnimationEffectReadOnly::GetComputedTimingAt(
|
||||||
// The animation isn't active or filling at this time.
|
// The animation isn't active or filling at this time.
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
// activeTime is zero
|
activeTime = std::max(StickyTimeDuration(localTime - aTiming.mDelay),
|
||||||
|
zeroDuration);
|
||||||
} else {
|
} else {
|
||||||
MOZ_ASSERT(result.mActiveDuration != zeroDuration,
|
MOZ_ASSERT(result.mActiveDuration != zeroDuration,
|
||||||
"How can we be in the middle of a zero-duration interval?");
|
"How can we be in the middle of a zero-duration interval?");
|
||||||
|
|
|
@ -114,7 +114,8 @@ struct TimingParams
|
||||||
|
|
||||||
StickyTimeDuration EndTime() const
|
StickyTimeDuration EndTime() const
|
||||||
{
|
{
|
||||||
return mDelay + ActiveDuration() + mEndDelay;
|
return std::max(mDelay + ActiveDuration() + mEndDelay,
|
||||||
|
StickyTimeDuration());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const TimingParams& aOther) const;
|
bool operator==(const TimingParams& aOther) const;
|
||||||
|
|
|
@ -192,7 +192,7 @@ test(function(t) {
|
||||||
// undefined value.
|
// undefined value.
|
||||||
var div = addDiv(t, {style: 'animation: moveAnimation 10s -100s forwards'});
|
var div = addDiv(t, {style: 'animation: moveAnimation 10s -100s forwards'});
|
||||||
var effect = div.getAnimations()[0].effect;
|
var effect = div.getAnimations()[0].effect;
|
||||||
assert_equals(effect.getComputedTiming().endTime, -90 * MS_PER_SEC,
|
assert_equals(effect.getComputedTiming().endTime, 0,
|
||||||
'Initial value of endTime');
|
'Initial value of endTime');
|
||||||
}, 'endTime of an animation that finishes before its startTime');
|
}, 'endTime of an animation that finishes before its startTime');
|
||||||
|
|
||||||
|
|
|
@ -279,7 +279,7 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This listener observes the first video frame to arrive with a non-empty size,
|
* This listener observes the first video frame to arrive with a non-empty size,
|
||||||
* and calls HTMLMediaElement::ReceivedMediaStreamInitialSize() with that size.
|
* and calls HTMLMediaElement::UpdateInitialMediaSize() with that size.
|
||||||
*/
|
*/
|
||||||
class HTMLMediaElement::StreamSizeListener : public DirectMediaStreamTrackListener {
|
class HTMLMediaElement::StreamSizeListener : public DirectMediaStreamTrackListener {
|
||||||
public:
|
public:
|
||||||
|
@ -287,13 +287,17 @@ public:
|
||||||
mElement(aElement),
|
mElement(aElement),
|
||||||
mInitialSizeFound(false)
|
mInitialSizeFound(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void Forget() { mElement = nullptr; }
|
void Forget() { mElement = nullptr; }
|
||||||
|
|
||||||
void ReceivedSize(gfx::IntSize aSize)
|
void ReceivedSize(gfx::IntSize aSize)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
if (!mElement) {
|
if (!mElement) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<HTMLMediaElement> deathGrip = mElement;
|
RefPtr<HTMLMediaElement> deathGrip = mElement;
|
||||||
mElement->UpdateInitialMediaSize(aSize);
|
mElement->UpdateInitialMediaSize(aSize);
|
||||||
}
|
}
|
||||||
|
@ -302,18 +306,27 @@ public:
|
||||||
StreamTime aTrackOffset,
|
StreamTime aTrackOffset,
|
||||||
const MediaSegment& aMedia) override
|
const MediaSegment& aMedia) override
|
||||||
{
|
{
|
||||||
if (mInitialSizeFound || aMedia.GetType() != MediaSegment::VIDEO) {
|
if (mInitialSizeFound) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (aMedia.GetType() != MediaSegment::VIDEO) {
|
||||||
|
MOZ_ASSERT(false, "Should only lock on to a video track");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const VideoSegment& video = static_cast<const VideoSegment&>(aMedia);
|
const VideoSegment& video = static_cast<const VideoSegment&>(aMedia);
|
||||||
for (VideoSegment::ConstChunkIterator c(video); !c.IsEnded(); c.Next()) {
|
for (VideoSegment::ConstChunkIterator c(video); !c.IsEnded(); c.Next()) {
|
||||||
if (c->mFrame.GetIntrinsicSize() != gfx::IntSize(0,0)) {
|
if (c->mFrame.GetIntrinsicSize() != gfx::IntSize(0,0)) {
|
||||||
mInitialSizeFound = true;
|
mInitialSizeFound = true;
|
||||||
nsCOMPtr<nsIRunnable> event =
|
nsCOMPtr<nsIRunnable> event =
|
||||||
NewRunnableMethod<gfx::IntSize>(
|
NewRunnableMethod<gfx::IntSize>(this, &StreamSizeListener::ReceivedSize,
|
||||||
this, &StreamSizeListener::ReceivedSize,
|
c->mFrame.GetIntrinsicSize());
|
||||||
c->mFrame.GetIntrinsicSize());
|
// This is fine to dispatch straight to main thread (instead of via
|
||||||
aGraph->DispatchToMainThreadAfterStreamStateUpdate(event.forget());
|
// ...AfterStreamUpdate()) since it reflects state of the element,
|
||||||
|
// not the stream. Events reflecting stream or track state should be
|
||||||
|
// dispatched so their order is preserved.
|
||||||
|
NS_DispatchToMainThread(event.forget());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -323,7 +336,9 @@ private:
|
||||||
// These fields may only be accessed on the main thread
|
// These fields may only be accessed on the main thread
|
||||||
HTMLMediaElement* mElement;
|
HTMLMediaElement* mElement;
|
||||||
|
|
||||||
// These fields may only be accessed on the MSG thread
|
// These fields may only be accessed on the MSG's appending thread.
|
||||||
|
// (this is a direct listener so we get called by whoever is producing
|
||||||
|
// this track's data)
|
||||||
bool mInitialSizeFound;
|
bool mInitialSizeFound;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2575,16 +2590,21 @@ HTMLMediaElement::CaptureStreamInternal(bool aFinishWhenEnded,
|
||||||
mAudioCaptured = true;
|
mAudioCaptured = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mDecoder) {
|
||||||
|
out->mCapturingDecoder = true;
|
||||||
|
mDecoder->AddOutputStream(out->mStream->GetInputStream()->AsProcessedStream(),
|
||||||
|
aFinishWhenEnded);
|
||||||
|
} else if (mSrcStream) {
|
||||||
|
out->mCapturingMediaStream = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (mReadyState == HAVE_NOTHING) {
|
if (mReadyState == HAVE_NOTHING) {
|
||||||
// Do not expose the tracks directly before we have metadata.
|
// Do not expose the tracks until we have metadata.
|
||||||
RefPtr<DOMMediaStream> result = out->mStream;
|
RefPtr<DOMMediaStream> result = out->mStream;
|
||||||
return result.forget();
|
return result.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mDecoder) {
|
if (mDecoder) {
|
||||||
out->mCapturingDecoder = true;
|
|
||||||
mDecoder->AddOutputStream(out->mStream->GetInputStream()->AsProcessedStream(),
|
|
||||||
aFinishWhenEnded);
|
|
||||||
if (HasAudio()) {
|
if (HasAudio()) {
|
||||||
TrackID audioTrackId = mMediaInfo.mAudio.mTrackId;
|
TrackID audioTrackId = mMediaInfo.mAudio.mTrackId;
|
||||||
RefPtr<MediaStreamTrackSource> trackSource =
|
RefPtr<MediaStreamTrackSource> trackSource =
|
||||||
|
@ -2610,22 +2630,6 @@ HTMLMediaElement::CaptureStreamInternal(bool aFinishWhenEnded,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mSrcStream) {
|
if (mSrcStream) {
|
||||||
out->mCapturingMediaStream = true;
|
|
||||||
MediaStream* inputStream = out->mStream->GetInputStream();
|
|
||||||
if (!inputStream) {
|
|
||||||
NS_ERROR("No input stream");
|
|
||||||
RefPtr<DOMMediaStream> result = out->mStream;
|
|
||||||
return result.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
ProcessedMediaStream* processedInputStream =
|
|
||||||
inputStream->AsProcessedStream();
|
|
||||||
if (!processedInputStream) {
|
|
||||||
NS_ERROR("Input stream not a ProcessedMediaStream");
|
|
||||||
RefPtr<DOMMediaStream> result = out->mStream;
|
|
||||||
return result.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < AudioTracks()->Length(); ++i) {
|
for (size_t i = 0; i < AudioTracks()->Length(); ++i) {
|
||||||
AudioTrack* t = (*AudioTracks())[i];
|
AudioTrack* t = (*AudioTracks())[i];
|
||||||
if (t->Enabled()) {
|
if (t->Enabled()) {
|
||||||
|
|
|
@ -2554,7 +2554,7 @@ TabParent::GetAuthPrompt(uint32_t aPromptReason, const nsIID& iid,
|
||||||
nsCOMPtr<nsILoginManagerPrompter> prompter = do_QueryInterface(prompt);
|
nsCOMPtr<nsILoginManagerPrompter> prompter = do_QueryInterface(prompt);
|
||||||
if (prompter) {
|
if (prompter) {
|
||||||
nsCOMPtr<nsIDOMElement> browser = do_QueryInterface(mFrameElement);
|
nsCOMPtr<nsIDOMElement> browser = do_QueryInterface(mFrameElement);
|
||||||
prompter->SetE10sData(browser, nullptr);
|
prompter->SetBrowser(browser);
|
||||||
}
|
}
|
||||||
|
|
||||||
*aResult = prompt.forget().take();
|
*aResult = prompt.forget().take();
|
||||||
|
|
|
@ -242,7 +242,6 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
|
||||||
mQuickBuffering(false),
|
mQuickBuffering(false),
|
||||||
mMinimizePreroll(false),
|
mMinimizePreroll(false),
|
||||||
mDecodeThreadWaiting(false),
|
mDecodeThreadWaiting(false),
|
||||||
mDecodingFirstFrame(true),
|
|
||||||
mSentLoadedMetadataEvent(false),
|
mSentLoadedMetadataEvent(false),
|
||||||
mSentFirstFrameLoadedEvent(false),
|
mSentFirstFrameLoadedEvent(false),
|
||||||
mSentPlaybackEndedEvent(false),
|
mSentPlaybackEndedEvent(false),
|
||||||
|
@ -488,7 +487,7 @@ MediaDecoderStateMachine::NeedToDecodeVideo()
|
||||||
IsVideoDecoding(), mMinimizePreroll, HaveEnoughDecodedVideo());
|
IsVideoDecoding(), mMinimizePreroll, HaveEnoughDecodedVideo());
|
||||||
return IsVideoDecoding() &&
|
return IsVideoDecoding() &&
|
||||||
mState != DECODER_STATE_SEEKING &&
|
mState != DECODER_STATE_SEEKING &&
|
||||||
((IsDecodingFirstFrame() && VideoQueue().GetSize() == 0) ||
|
((!mSentFirstFrameLoadedEvent && VideoQueue().GetSize() == 0) ||
|
||||||
(!mMinimizePreroll && !HaveEnoughDecodedVideo()));
|
(!mMinimizePreroll && !HaveEnoughDecodedVideo()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -496,7 +495,8 @@ bool
|
||||||
MediaDecoderStateMachine::NeedToSkipToNextKeyframe()
|
MediaDecoderStateMachine::NeedToSkipToNextKeyframe()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
MOZ_ASSERT(OnTaskQueue());
|
||||||
if (IsDecodingFirstFrame()) {
|
// Don't skip when we're still decoding first frames.
|
||||||
|
if (!mSentFirstFrameLoadedEvent) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(mState == DECODER_STATE_DECODING ||
|
MOZ_ASSERT(mState == DECODER_STATE_DECODING ||
|
||||||
|
@ -557,7 +557,7 @@ MediaDecoderStateMachine::NeedToDecodeAudio()
|
||||||
|
|
||||||
return IsAudioDecoding() &&
|
return IsAudioDecoding() &&
|
||||||
mState != DECODER_STATE_SEEKING &&
|
mState != DECODER_STATE_SEEKING &&
|
||||||
((IsDecodingFirstFrame() && AudioQueue().GetSize() == 0) ||
|
((!mSentFirstFrameLoadedEvent && AudioQueue().GetSize() == 0) ||
|
||||||
(!mMinimizePreroll && !HaveEnoughDecodedAudio()));
|
(!mMinimizePreroll && !HaveEnoughDecodedAudio()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -733,7 +733,7 @@ bool
|
||||||
MediaDecoderStateMachine::MaybeFinishDecodeFirstFrame()
|
MediaDecoderStateMachine::MaybeFinishDecodeFirstFrame()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
MOZ_ASSERT(OnTaskQueue());
|
||||||
if (!IsDecodingFirstFrame() ||
|
if (mSentFirstFrameLoadedEvent ||
|
||||||
(IsAudioDecoding() && AudioQueue().GetSize() == 0) ||
|
(IsAudioDecoding() && AudioQueue().GetSize() == 0) ||
|
||||||
(IsVideoDecoding() && VideoQueue().GetSize() == 0)) {
|
(IsVideoDecoding() && VideoQueue().GetSize() == 0)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -790,7 +790,7 @@ MediaDecoderStateMachine::OnVideoDecoded(MediaData* aVideoSample,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
TimeDuration decodeTime = TimeStamp::Now() - aDecodeStartTime;
|
TimeDuration decodeTime = TimeStamp::Now() - aDecodeStartTime;
|
||||||
if (!IsDecodingFirstFrame() &&
|
if (mSentFirstFrameLoadedEvent &&
|
||||||
THRESHOLD_FACTOR * DurationToUsecs(decodeTime) > mLowAudioThresholdUsecs &&
|
THRESHOLD_FACTOR * DurationToUsecs(decodeTime) > mLowAudioThresholdUsecs &&
|
||||||
!HasLowUndecodedData())
|
!HasLowUndecodedData())
|
||||||
{
|
{
|
||||||
|
@ -1077,7 +1077,6 @@ MediaDecoderStateMachine::EnterState(State aState)
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
MOZ_ASSERT(OnTaskQueue());
|
||||||
switch (aState) {
|
switch (aState) {
|
||||||
case DECODER_STATE_DECODING_METADATA:
|
case DECODER_STATE_DECODING_METADATA:
|
||||||
mDecodingFirstFrame = true;
|
|
||||||
ReadMetadata();
|
ReadMetadata();
|
||||||
break;
|
break;
|
||||||
case DECODER_STATE_DORMANT:
|
case DECODER_STATE_DORMANT:
|
||||||
|
@ -1260,19 +1259,11 @@ MediaDecoderStateMachine::StartDecoding()
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
MOZ_ASSERT(OnTaskQueue());
|
||||||
MOZ_ASSERT(mState == DECODER_STATE_DECODING);
|
MOZ_ASSERT(mState == DECODER_STATE_DECODING);
|
||||||
|
|
||||||
if (mDecodingFirstFrame && mSentFirstFrameLoadedEvent) {
|
// Handle the pending seek now if we've decoded first frames. Otherwise it
|
||||||
// We're resuming from dormant state, so we don't need to request
|
// will be handled after decoding first frames.
|
||||||
// the first samples in order to determine the media start time,
|
if (mSentFirstFrameLoadedEvent && mQueuedSeek.Exists()) {
|
||||||
// we have the start time from last time we loaded.
|
InitiateSeek(Move(mQueuedSeek));
|
||||||
// FinishDecodeFirstFrame will be launched upon completion of the seek when
|
return;
|
||||||
// we have data ready to play.
|
|
||||||
MOZ_ASSERT(mQueuedSeek.Exists() && mSentFirstFrameLoadedEvent,
|
|
||||||
"Return from dormant must have queued seek");
|
|
||||||
|
|
||||||
if (mQueuedSeek.Exists()) {
|
|
||||||
InitiateSeek(Move(mQueuedSeek));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CheckIfDecodeComplete()) {
|
if (CheckIfDecodeComplete()) {
|
||||||
|
@ -1511,8 +1502,12 @@ MediaDecoderStateMachine::Seek(SeekTarget aTarget)
|
||||||
MOZ_ASSERT(mState > DECODER_STATE_DECODING_METADATA,
|
MOZ_ASSERT(mState > DECODER_STATE_DECODING_METADATA,
|
||||||
"We should have got duration already");
|
"We should have got duration already");
|
||||||
|
|
||||||
if (mState < DECODER_STATE_DECODING ||
|
// Can't seek until the start time is known.
|
||||||
(IsDecodingFirstFrame() && !mReader->ForceZeroStartTime())) {
|
bool hasStartTime = mSentFirstFrameLoadedEvent || mReader->ForceZeroStartTime();
|
||||||
|
// Can't seek when state is WAIT_FOR_CDM or DORMANT.
|
||||||
|
bool stateAllowed = mState >= DECODER_STATE_DECODING;
|
||||||
|
|
||||||
|
if (!stateAllowed || !hasStartTime) {
|
||||||
DECODER_LOG("Seek() Not Enough Data to continue at this stage, queuing seek");
|
DECODER_LOG("Seek() Not Enough Data to continue at this stage, queuing seek");
|
||||||
mQueuedSeek.RejectIfExists(__func__);
|
mQueuedSeek.RejectIfExists(__func__);
|
||||||
mQueuedSeek.mTarget = aTarget;
|
mQueuedSeek.mTarget = aTarget;
|
||||||
|
@ -1906,8 +1901,8 @@ bool MediaDecoderStateMachine::HasLowUndecodedData()
|
||||||
bool MediaDecoderStateMachine::HasLowUndecodedData(int64_t aUsecs)
|
bool MediaDecoderStateMachine::HasLowUndecodedData(int64_t aUsecs)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
MOZ_ASSERT(OnTaskQueue());
|
||||||
NS_ASSERTION(mState >= DECODER_STATE_DECODING && !IsDecodingFirstFrame(),
|
MOZ_ASSERT(mState >= DECODER_STATE_DECODING && mSentFirstFrameLoadedEvent,
|
||||||
"Must have loaded first frame for mBuffered to be valid");
|
"Must have loaded first frame for mBuffered to be valid");
|
||||||
|
|
||||||
// If we don't have a duration, mBuffered is probably not going to have
|
// If we don't have a duration, mBuffered is probably not going to have
|
||||||
// a useful buffered range. Return false here so that we don't get stuck in
|
// a useful buffered range. Return false here so that we don't get stuck in
|
||||||
|
@ -2074,12 +2069,6 @@ MediaDecoderStateMachine::EnqueueFirstFrameLoadedEvent()
|
||||||
[]() { MOZ_CRASH("Should not reach"); }));
|
[]() { MOZ_CRASH("Should not reach"); }));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
MediaDecoderStateMachine::IsDecodingFirstFrame()
|
|
||||||
{
|
|
||||||
return mState == DECODER_STATE_DECODING && mDecodingFirstFrame;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MediaDecoderStateMachine::FinishDecodeFirstFrame()
|
MediaDecoderStateMachine::FinishDecodeFirstFrame()
|
||||||
{
|
{
|
||||||
|
@ -2106,9 +2095,8 @@ MediaDecoderStateMachine::FinishDecodeFirstFrame()
|
||||||
// If we didn't have duration and/or start time before, we should now.
|
// If we didn't have duration and/or start time before, we should now.
|
||||||
EnqueueLoadedMetadataEvent();
|
EnqueueLoadedMetadataEvent();
|
||||||
}
|
}
|
||||||
EnqueueFirstFrameLoadedEvent();
|
|
||||||
|
|
||||||
mDecodingFirstFrame = false;
|
EnqueueFirstFrameLoadedEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -2173,9 +2161,11 @@ MediaDecoderStateMachine::SeekCompleted()
|
||||||
// SeekTask::Discard() will ask MediaDecoderReaderWrapper to discard media
|
// SeekTask::Discard() will ask MediaDecoderReaderWrapper to discard media
|
||||||
// data requests.
|
// data requests.
|
||||||
|
|
||||||
if (mDecodingFirstFrame) {
|
// Notify FirstFrameLoaded now if we haven't since we've decoded some data
|
||||||
// We were resuming from dormant, or initiated a seek early.
|
// for readyState to transition to HAVE_CURRENT_DATA and fire 'loadeddata'.
|
||||||
// We can fire loadeddata now.
|
if (!mSentFirstFrameLoadedEvent) {
|
||||||
|
// Only MSE can start seeking before finishing decoding first frames.
|
||||||
|
MOZ_ASSERT(mReader->ForceZeroStartTime());
|
||||||
FinishDecodeFirstFrame();
|
FinishDecodeFirstFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2273,9 +2263,8 @@ nsresult MediaDecoderStateMachine::RunStateMachine()
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
case DECODER_STATE_DECODING: {
|
case DECODER_STATE_DECODING: {
|
||||||
if (IsDecodingFirstFrame()) {
|
// Can't start playback until having decoded first frames.
|
||||||
// We haven't completed decoding our first frames, we can't start
|
if (!mSentFirstFrameLoadedEvent) {
|
||||||
// playback yet.
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
if (mPlayState != MediaDecoder::PLAY_STATE_PLAYING && IsPlaying())
|
if (mPlayState != MediaDecoder::PLAY_STATE_PLAYING && IsPlaying())
|
||||||
|
@ -2492,7 +2481,7 @@ void MediaDecoderStateMachine::UpdateNextFrameStatus()
|
||||||
|
|
||||||
MediaDecoderOwner::NextFrameStatus status;
|
MediaDecoderOwner::NextFrameStatus status;
|
||||||
const char* statusString;
|
const char* statusString;
|
||||||
if (mState <= DECODER_STATE_WAIT_FOR_CDM || IsDecodingFirstFrame()) {
|
if (mState < DECODER_STATE_DECODING || !mSentFirstFrameLoadedEvent) {
|
||||||
status = MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE;
|
status = MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE;
|
||||||
statusString = "NEXT_FRAME_UNAVAILABLE";
|
statusString = "NEXT_FRAME_UNAVAILABLE";
|
||||||
} else if (IsBuffering()) {
|
} else if (IsBuffering()) {
|
||||||
|
@ -2830,12 +2819,12 @@ MediaDecoderStateMachine::DumpDebugInfo()
|
||||||
mMediaSink->DumpDebugInfo();
|
mMediaSink->DumpDebugInfo();
|
||||||
DUMP_LOG(
|
DUMP_LOG(
|
||||||
"GetMediaTime=%lld GetClock=%lld mMediaSink=%p "
|
"GetMediaTime=%lld GetClock=%lld mMediaSink=%p "
|
||||||
"mState=%s mPlayState=%d mDecodingFirstFrame=%d IsPlaying=%d "
|
"mState=%s mPlayState=%d mSentFirstFrameLoadedEvent=%d IsPlaying=%d "
|
||||||
"mAudioStatus=%s mVideoStatus=%s mDecodedAudioEndTime=%lld mDecodedVideoEndTime=%lld "
|
"mAudioStatus=%s mVideoStatus=%s mDecodedAudioEndTime=%lld mDecodedVideoEndTime=%lld "
|
||||||
"mIsAudioPrerolling=%d mIsVideoPrerolling=%d "
|
"mIsAudioPrerolling=%d mIsVideoPrerolling=%d "
|
||||||
"mAudioCompleted=%d mVideoCompleted=%d",
|
"mAudioCompleted=%d mVideoCompleted=%d",
|
||||||
GetMediaTime(), mMediaSink->IsStarted() ? GetClock() : -1, mMediaSink.get(),
|
GetMediaTime(), mMediaSink->IsStarted() ? GetClock() : -1, mMediaSink.get(),
|
||||||
ToStateStr(), mPlayState.Ref(), mDecodingFirstFrame, IsPlaying(),
|
ToStateStr(), mPlayState.Ref(), mSentFirstFrameLoadedEvent, IsPlaying(),
|
||||||
AudioRequestStatus(), VideoRequestStatus(), mDecodedAudioEndTime, mDecodedVideoEndTime,
|
AudioRequestStatus(), VideoRequestStatus(), mDecodedAudioEndTime, mDecodedVideoEndTime,
|
||||||
mIsAudioPrerolling, mIsVideoPrerolling, mAudioCompleted.Ref(), mVideoCompleted.Ref());
|
mIsAudioPrerolling, mIsVideoPrerolling, mAudioCompleted.Ref(), mVideoCompleted.Ref());
|
||||||
});
|
});
|
||||||
|
|
|
@ -567,8 +567,7 @@ protected:
|
||||||
// If there are any queued seek, will change state to DECODER_STATE_SEEKING
|
// If there are any queued seek, will change state to DECODER_STATE_SEEKING
|
||||||
// and return true.
|
// and return true.
|
||||||
bool MaybeFinishDecodeFirstFrame();
|
bool MaybeFinishDecodeFirstFrame();
|
||||||
// Return true if we are currently decoding the first frames.
|
|
||||||
bool IsDecodingFirstFrame();
|
|
||||||
void FinishDecodeFirstFrame();
|
void FinishDecodeFirstFrame();
|
||||||
|
|
||||||
// Completes the seek operation, moves onto the next appropriate state.
|
// Completes the seek operation, moves onto the next appropriate state.
|
||||||
|
@ -885,18 +884,14 @@ private:
|
||||||
// Track our request to update the buffered ranges
|
// Track our request to update the buffered ranges
|
||||||
MozPromiseRequestHolder<MediaDecoderReader::BufferedUpdatePromise> mBufferedUpdateRequest;
|
MozPromiseRequestHolder<MediaDecoderReader::BufferedUpdatePromise> mBufferedUpdateRequest;
|
||||||
|
|
||||||
// True if we need to call FinishDecodeFirstFrame() upon frame decoding
|
|
||||||
// succeeding.
|
|
||||||
bool mDecodingFirstFrame;
|
|
||||||
|
|
||||||
// True if we are back from DECODER_STATE_DORMANT state and
|
// True if we are back from DECODER_STATE_DORMANT state and
|
||||||
// LoadedMetadataEvent was already sent.
|
// LoadedMetadataEvent was already sent.
|
||||||
bool mSentLoadedMetadataEvent;
|
bool mSentLoadedMetadataEvent;
|
||||||
// True if we are back from DECODER_STATE_DORMANT state and
|
|
||||||
// FirstFrameLoadedEvent was already sent, then we can skip
|
// True if we've decoded first frames (thus having the start time) and
|
||||||
// SetStartTime because the mStartTime already set before. Also we don't need
|
// notified the FirstFrameLoaded event. Note we can't initiate seek until the
|
||||||
// to decode any audio/video since the MediaDecoder will trigger a seek
|
// start time is known which happens when the first frames are decoded or we
|
||||||
// operation soon.
|
// are playing an MSE stream (the start time is always assumed 0).
|
||||||
bool mSentFirstFrameLoadedEvent;
|
bool mSentFirstFrameLoadedEvent;
|
||||||
|
|
||||||
bool mSentPlaybackEndedEvent;
|
bool mSentPlaybackEndedEvent;
|
||||||
|
|
|
@ -62,9 +62,9 @@ MediaFormatReader::MediaFormatReader(AbstractMediaDecoder* aDecoder,
|
||||||
VideoFrameContainer* aVideoFrameContainer,
|
VideoFrameContainer* aVideoFrameContainer,
|
||||||
layers::LayersBackend aLayersBackend)
|
layers::LayersBackend aLayersBackend)
|
||||||
: MediaDecoderReader(aDecoder)
|
: MediaDecoderReader(aDecoder)
|
||||||
, mAudio(this, MediaData::AUDIO_DATA, Preferences::GetUint("media.audio-decode-ahead", 2),
|
, mAudio(this, MediaData::AUDIO_DATA,
|
||||||
Preferences::GetUint("media.audio-max-decode-error", 3))
|
Preferences::GetUint("media.audio-max-decode-error", 3))
|
||||||
, mVideo(this, MediaData::VIDEO_DATA, Preferences::GetUint("media.video-decode-ahead", 2),
|
, mVideo(this, MediaData::VIDEO_DATA,
|
||||||
Preferences::GetUint("media.video-max-decode-error", 2))
|
Preferences::GetUint("media.video-max-decode-error", 2))
|
||||||
, mDemuxer(aDemuxer)
|
, mDemuxer(aDemuxer)
|
||||||
, mDemuxerInitDone(false)
|
, mDemuxerInitDone(false)
|
||||||
|
@ -562,7 +562,7 @@ MediaFormatReader::RequestVideoData(bool aSkipToNextKeyframe,
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<MediaDataPromise> p = mVideo.EnsurePromise(__func__);
|
RefPtr<MediaDataPromise> p = mVideo.EnsurePromise(__func__);
|
||||||
NotifyDecodingRequested(TrackInfo::kVideoTrack);
|
ScheduleUpdate(TrackInfo::kVideoTrack);
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
@ -606,7 +606,6 @@ MediaFormatReader::OnDemuxFailed(TrackType aTrack, DemuxerFailureReason aFailure
|
||||||
void
|
void
|
||||||
MediaFormatReader::DoDemuxVideo()
|
MediaFormatReader::DoDemuxVideo()
|
||||||
{
|
{
|
||||||
// TODO Use DecodeAhead value rather than 1.
|
|
||||||
mVideo.mDemuxRequest.Begin(mVideo.mTrackDemuxer->GetSamples(1)
|
mVideo.mDemuxRequest.Begin(mVideo.mTrackDemuxer->GetSamples(1)
|
||||||
->Then(OwnerThread(), __func__, this,
|
->Then(OwnerThread(), __func__, this,
|
||||||
&MediaFormatReader::OnVideoDemuxCompleted,
|
&MediaFormatReader::OnVideoDemuxCompleted,
|
||||||
|
@ -657,7 +656,7 @@ MediaFormatReader::RequestAudioData()
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<MediaDataPromise> p = mAudio.EnsurePromise(__func__);
|
RefPtr<MediaDataPromise> p = mAudio.EnsurePromise(__func__);
|
||||||
NotifyDecodingRequested(TrackInfo::kAudioTrack);
|
ScheduleUpdate(TrackInfo::kAudioTrack);
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
@ -665,7 +664,6 @@ MediaFormatReader::RequestAudioData()
|
||||||
void
|
void
|
||||||
MediaFormatReader::DoDemuxAudio()
|
MediaFormatReader::DoDemuxAudio()
|
||||||
{
|
{
|
||||||
// TODO Use DecodeAhead value rather than 1.
|
|
||||||
mAudio.mDemuxRequest.Begin(mAudio.mTrackDemuxer->GetSamples(1)
|
mAudio.mDemuxRequest.Begin(mAudio.mTrackDemuxer->GetSamples(1)
|
||||||
->Then(OwnerThread(), __func__, this,
|
->Then(OwnerThread(), __func__, this,
|
||||||
&MediaFormatReader::OnAudioDemuxCompleted,
|
&MediaFormatReader::OnAudioDemuxCompleted,
|
||||||
|
@ -706,7 +704,7 @@ MediaFormatReader::NotifyInputExhausted(TrackType aTrack)
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
MOZ_ASSERT(OnTaskQueue());
|
||||||
LOGV("Decoder has requested more %s data", TrackTypeToStr(aTrack));
|
LOGV("Decoder has requested more %s data", TrackTypeToStr(aTrack));
|
||||||
auto& decoder = GetDecoderData(aTrack);
|
auto& decoder = GetDecoderData(aTrack);
|
||||||
decoder.mInputExhausted = true;
|
decoder.mDecodePending = false;
|
||||||
ScheduleUpdate(aTrack);
|
ScheduleUpdate(aTrack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -755,33 +753,21 @@ MediaFormatReader::NotifyEndOfStream(TrackType aTrack)
|
||||||
ScheduleUpdate(aTrack);
|
ScheduleUpdate(aTrack);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
MediaFormatReader::NotifyDecodingRequested(TrackType aTrack)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
|
||||||
auto& decoder = GetDecoderData(aTrack);
|
|
||||||
decoder.mDecodingRequested = true;
|
|
||||||
ScheduleUpdate(aTrack);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
MediaFormatReader::NeedInput(DecoderData& aDecoder)
|
MediaFormatReader::NeedInput(DecoderData& aDecoder)
|
||||||
{
|
{
|
||||||
// We try to keep a few more compressed samples input than decoded samples
|
// To account for H.264 streams which may require a longer
|
||||||
// have been output, provided the state machine has requested we send it a
|
// run of input than we input, decoders fire an "input exhausted" callback.
|
||||||
// decoded sample. To account for H.264 streams which may require a longer
|
// The decoder will not be fed a new raw sample until InputExhausted
|
||||||
// run of input than we input, decoders fire an "input exhausted" callback,
|
// has been called.
|
||||||
// which overrides our "few more samples" threshold.
|
|
||||||
return
|
return
|
||||||
|
(aDecoder.HasPromise() || aDecoder.mTimeThreshold.isSome()) &&
|
||||||
!aDecoder.HasPendingDrain() &&
|
!aDecoder.HasPendingDrain() &&
|
||||||
!aDecoder.HasFatalError() &&
|
!aDecoder.HasFatalError() &&
|
||||||
aDecoder.mDecodingRequested &&
|
|
||||||
!aDecoder.mDemuxRequest.Exists() &&
|
!aDecoder.mDemuxRequest.Exists() &&
|
||||||
|
!aDecoder.mOutput.Length() &&
|
||||||
!aDecoder.HasInternalSeekPending() &&
|
!aDecoder.HasInternalSeekPending() &&
|
||||||
aDecoder.mOutput.Length() <= aDecoder.mDecodeAhead &&
|
!aDecoder.mDecodePending;
|
||||||
(aDecoder.mInputExhausted || !aDecoder.mQueuedSamples.IsEmpty() ||
|
|
||||||
aDecoder.mTimeThreshold.isSome() ||
|
|
||||||
aDecoder.mNumSamplesInput - aDecoder.mNumSamplesOutput <= aDecoder.mDecodeAhead);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -932,6 +918,7 @@ MediaFormatReader::DecodeDemuxedSamples(TrackType aTrack,
|
||||||
LOG("Unable to pass frame to decoder");
|
LOG("Unable to pass frame to decoder");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
decoder.mDecodePending = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1007,7 +994,7 @@ MediaFormatReader::HandleDemuxedSamples(TrackType aTrack,
|
||||||
decoder.ShutdownDecoder();
|
decoder.ShutdownDecoder();
|
||||||
if (sample->mKeyframe) {
|
if (sample->mKeyframe) {
|
||||||
decoder.mQueuedSamples.AppendElements(Move(samples));
|
decoder.mQueuedSamples.AppendElements(Move(samples));
|
||||||
NotifyDecodingRequested(aTrack);
|
ScheduleUpdate(aTrack);
|
||||||
} else {
|
} else {
|
||||||
TimeInterval time =
|
TimeInterval time =
|
||||||
TimeInterval(TimeUnit::FromMicroseconds(sample->mTime),
|
TimeInterval(TimeUnit::FromMicroseconds(sample->mTime),
|
||||||
|
@ -1045,9 +1032,6 @@ MediaFormatReader::HandleDemuxedSamples(TrackType aTrack,
|
||||||
}
|
}
|
||||||
samplesPending = true;
|
samplesPending = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have serviced the decoder's request for more data.
|
|
||||||
decoder.mInputExhausted = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1071,7 +1055,7 @@ MediaFormatReader::InternalSeek(TrackType aTrack, const InternalSeekTarget& aTar
|
||||||
"Seek promise must be disconnected when timethreshold is reset");
|
"Seek promise must be disconnected when timethreshold is reset");
|
||||||
decoder.mTimeThreshold.ref().mHasSeeked = true;
|
decoder.mTimeThreshold.ref().mHasSeeked = true;
|
||||||
self->SetVideoDecodeThreshold();
|
self->SetVideoDecodeThreshold();
|
||||||
self->NotifyDecodingRequested(aTrack);
|
self->ScheduleUpdate(aTrack);
|
||||||
},
|
},
|
||||||
[self, aTrack] (DemuxerFailureReason aResult) {
|
[self, aTrack] (DemuxerFailureReason aResult) {
|
||||||
auto& decoder = self->GetDecoderData(aTrack);
|
auto& decoder = self->GetDecoderData(aTrack);
|
||||||
|
@ -1275,6 +1259,7 @@ MediaFormatReader::Update(TrackType aTrack)
|
||||||
|
|
||||||
if (decoder.mError &&
|
if (decoder.mError &&
|
||||||
decoder.mError.ref() == MediaDataDecoderError::DECODE_ERROR) {
|
decoder.mError.ref() == MediaDataDecoderError::DECODE_ERROR) {
|
||||||
|
decoder.mDecodePending = false;
|
||||||
decoder.mError.reset();
|
decoder.mError.reset();
|
||||||
if (++decoder.mNumOfConsecutiveError > decoder.mMaxConsecutiveError) {
|
if (++decoder.mNumOfConsecutiveError > decoder.mMaxConsecutiveError) {
|
||||||
NotifyError(aTrack);
|
NotifyError(aTrack);
|
||||||
|
@ -1292,11 +1277,11 @@ MediaFormatReader::Update(TrackType aTrack)
|
||||||
|
|
||||||
bool needInput = NeedInput(decoder);
|
bool needInput = NeedInput(decoder);
|
||||||
|
|
||||||
LOGV("Update(%s) ni=%d no=%d ie=%d, in:%llu out:%llu qs=%u pending:%u waiting:%d ahead:%d sid:%u",
|
LOGV("Update(%s) ni=%d no=%d ie=%d, in:%llu out:%llu qs=%u pending:%u waiting:%d promise:%d sid:%u",
|
||||||
TrackTypeToStr(aTrack), needInput, needOutput, decoder.mInputExhausted,
|
TrackTypeToStr(aTrack), needInput, needOutput, decoder.mDecodePending,
|
||||||
decoder.mNumSamplesInput, decoder.mNumSamplesOutput,
|
decoder.mNumSamplesInput, decoder.mNumSamplesOutput,
|
||||||
uint32_t(size_t(decoder.mSizeOfQueue)), uint32_t(decoder.mOutput.Length()),
|
uint32_t(size_t(decoder.mSizeOfQueue)), uint32_t(decoder.mOutput.Length()),
|
||||||
decoder.mWaitingForData, !decoder.HasPromise(), decoder.mLastStreamSourceID);
|
decoder.mWaitingForData, decoder.HasPromise(), decoder.mLastStreamSourceID);
|
||||||
|
|
||||||
if (decoder.mWaitingForData &&
|
if (decoder.mWaitingForData &&
|
||||||
(!decoder.mTimeThreshold || decoder.mTimeThreshold.ref().mWaiting)) {
|
(!decoder.mTimeThreshold || decoder.mTimeThreshold.ref().mWaiting)) {
|
||||||
|
@ -1577,7 +1562,7 @@ MediaFormatReader::OnVideoSkipCompleted(uint32_t aSkipped)
|
||||||
|
|
||||||
VideoSkipReset(aSkipped);
|
VideoSkipReset(aSkipped);
|
||||||
|
|
||||||
NotifyDecodingRequested(TrackInfo::kVideoTrack);
|
ScheduleUpdate(TrackInfo::kVideoTrack);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1595,7 +1580,7 @@ MediaFormatReader::OnVideoSkipFailed(MediaTrackDemuxer::SkipFailureHolder aFailu
|
||||||
DropDecodedSamples(TrackInfo::kVideoTrack);
|
DropDecodedSamples(TrackInfo::kVideoTrack);
|
||||||
// We can't complete the skip operation, will just service a video frame
|
// We can't complete the skip operation, will just service a video frame
|
||||||
// normally.
|
// normally.
|
||||||
NotifyDecodingRequested(TrackInfo::kVideoTrack);
|
ScheduleUpdate(TrackInfo::kVideoTrack);
|
||||||
break;
|
break;
|
||||||
case DemuxerFailureReason::CANCELED: MOZ_FALLTHROUGH;
|
case DemuxerFailureReason::CANCELED: MOZ_FALLTHROUGH;
|
||||||
case DemuxerFailureReason::SHUTDOWN:
|
case DemuxerFailureReason::SHUTDOWN:
|
||||||
|
@ -2013,12 +1998,11 @@ MediaFormatReader::GetMozDebugReaderData(nsAString& aString)
|
||||||
result += nsPrintfCString("audio frames decoded: %lld\n",
|
result += nsPrintfCString("audio frames decoded: %lld\n",
|
||||||
mAudio.mNumSamplesOutputTotal);
|
mAudio.mNumSamplesOutputTotal);
|
||||||
if (HasAudio()) {
|
if (HasAudio()) {
|
||||||
result += nsPrintfCString("audio state: ni=%d no=%d ie=%d demuxr:%d demuxq:%d decoder:%d tt:%f tths:%d in:%llu out:%llu qs=%u pending:%u waiting:%d sid:%u\n",
|
result += nsPrintfCString("audio state: ni=%d no=%d ie=%d demuxr:%d demuxq:%d tt:%f tths:%d in:%llu out:%llu qs=%u pending:%u waiting:%d sid:%u\n",
|
||||||
NeedInput(mAudio), mAudio.HasPromise(),
|
NeedInput(mAudio), mAudio.HasPromise(),
|
||||||
mAudio.mInputExhausted,
|
mAudio.mDecodePending,
|
||||||
mAudio.mDemuxRequest.Exists(),
|
mAudio.mDemuxRequest.Exists(),
|
||||||
int(mAudio.mQueuedSamples.Length()),
|
int(mAudio.mQueuedSamples.Length()),
|
||||||
mAudio.mDecodingRequested,
|
|
||||||
mAudio.mTimeThreshold
|
mAudio.mTimeThreshold
|
||||||
? mAudio.mTimeThreshold.ref().Time().ToSeconds()
|
? mAudio.mTimeThreshold.ref().Time().ToSeconds()
|
||||||
: -1.0,
|
: -1.0,
|
||||||
|
@ -2037,12 +2021,11 @@ MediaFormatReader::GetMozDebugReaderData(nsAString& aString)
|
||||||
mVideo.mNumSamplesOutputTotal,
|
mVideo.mNumSamplesOutputTotal,
|
||||||
mVideo.mNumSamplesSkippedTotal);
|
mVideo.mNumSamplesSkippedTotal);
|
||||||
if (HasVideo()) {
|
if (HasVideo()) {
|
||||||
result += nsPrintfCString("video state: ni=%d no=%d ie=%d demuxr:%d demuxq:%d decoder:%d tt:%f tths:%d in:%llu out:%llu qs=%u pending:%u waiting:%d sid:%u\n",
|
result += nsPrintfCString("video state: ni=%d no=%d ie=%d demuxr:%d demuxq:%d tt:%f tths:%d in:%llu out:%llu qs=%u pending:%u waiting:%d sid:%u\n",
|
||||||
NeedInput(mVideo), mVideo.HasPromise(),
|
NeedInput(mVideo), mVideo.HasPromise(),
|
||||||
mVideo.mInputExhausted,
|
mVideo.mDecodePending,
|
||||||
mVideo.mDemuxRequest.Exists(),
|
mVideo.mDemuxRequest.Exists(),
|
||||||
int(mVideo.mQueuedSamples.Length()),
|
int(mVideo.mQueuedSamples.Length()),
|
||||||
mVideo.mDecodingRequested,
|
|
||||||
mVideo.mTimeThreshold
|
mVideo.mTimeThreshold
|
||||||
? mVideo.mTimeThreshold.ref().Time().ToSeconds()
|
? mVideo.mTimeThreshold.ref().Time().ToSeconds()
|
||||||
: -1.0,
|
: -1.0,
|
||||||
|
@ -2080,7 +2063,7 @@ MediaFormatReader::SetBlankDecode(TrackType aTrack, bool aIsBlankDecode)
|
||||||
decoder.mIsBlankDecode = aIsBlankDecode;
|
decoder.mIsBlankDecode = aIsBlankDecode;
|
||||||
decoder.Flush();
|
decoder.Flush();
|
||||||
decoder.ShutdownDecoder();
|
decoder.ShutdownDecoder();
|
||||||
NotifyDecodingRequested(TrackInfo::kVideoTrack); // Calls ScheduleUpdate().
|
ScheduleUpdate(TrackInfo::kVideoTrack);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,7 +169,6 @@ private:
|
||||||
void NotifyError(TrackType aTrack, MediaDataDecoderError aError = MediaDataDecoderError::FATAL_ERROR);
|
void NotifyError(TrackType aTrack, MediaDataDecoderError aError = MediaDataDecoderError::FATAL_ERROR);
|
||||||
void NotifyWaitingForData(TrackType aTrack);
|
void NotifyWaitingForData(TrackType aTrack);
|
||||||
void NotifyEndOfStream(TrackType aTrack);
|
void NotifyEndOfStream(TrackType aTrack);
|
||||||
void NotifyDecodingRequested(TrackType aTrack);
|
|
||||||
|
|
||||||
void ExtractCryptoInitData(nsTArray<uint8_t>& aInitData);
|
void ExtractCryptoInitData(nsTArray<uint8_t>& aInitData);
|
||||||
|
|
||||||
|
@ -231,21 +230,18 @@ private:
|
||||||
struct DecoderData {
|
struct DecoderData {
|
||||||
DecoderData(MediaFormatReader* aOwner,
|
DecoderData(MediaFormatReader* aOwner,
|
||||||
MediaData::Type aType,
|
MediaData::Type aType,
|
||||||
uint32_t aDecodeAhead,
|
|
||||||
uint32_t aNumOfMaxError)
|
uint32_t aNumOfMaxError)
|
||||||
: mOwner(aOwner)
|
: mOwner(aOwner)
|
||||||
, mType(aType)
|
, mType(aType)
|
||||||
, mMonitor("DecoderData")
|
, mMonitor("DecoderData")
|
||||||
, mDescription("shutdown")
|
, mDescription("shutdown")
|
||||||
, mDecodeAhead(aDecodeAhead)
|
|
||||||
, mUpdateScheduled(false)
|
, mUpdateScheduled(false)
|
||||||
, mDemuxEOS(false)
|
, mDemuxEOS(false)
|
||||||
, mWaitingForData(false)
|
, mWaitingForData(false)
|
||||||
, mReceivedNewData(false)
|
, mReceivedNewData(false)
|
||||||
, mDecoderInitialized(false)
|
, mDecoderInitialized(false)
|
||||||
, mDecodingRequested(false)
|
|
||||||
, mOutputRequested(false)
|
, mOutputRequested(false)
|
||||||
, mInputExhausted(false)
|
, mDecodePending(false)
|
||||||
, mNeedDraining(false)
|
, mNeedDraining(false)
|
||||||
, mDraining(false)
|
, mDraining(false)
|
||||||
, mDrainComplete(false)
|
, mDrainComplete(false)
|
||||||
|
@ -288,7 +284,6 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only accessed from reader's task queue.
|
// Only accessed from reader's task queue.
|
||||||
uint32_t mDecodeAhead;
|
|
||||||
bool mUpdateScheduled;
|
bool mUpdateScheduled;
|
||||||
bool mDemuxEOS;
|
bool mDemuxEOS;
|
||||||
bool mWaitingForData;
|
bool mWaitingForData;
|
||||||
|
@ -312,11 +307,14 @@ private:
|
||||||
MozPromiseRequestHolder<MediaDataDecoder::InitPromise> mInitPromise;
|
MozPromiseRequestHolder<MediaDataDecoder::InitPromise> mInitPromise;
|
||||||
// False when decoder is created. True when decoder Init() promise is resolved.
|
// False when decoder is created. True when decoder Init() promise is resolved.
|
||||||
bool mDecoderInitialized;
|
bool mDecoderInitialized;
|
||||||
// Set when decoding can proceed. It is reset when a decoding promise is
|
|
||||||
// rejected or prior a seek operation.
|
|
||||||
bool mDecodingRequested;
|
|
||||||
bool mOutputRequested;
|
bool mOutputRequested;
|
||||||
bool mInputExhausted;
|
// Set to true once the MediaDataDecoder has been fed a compressed sample.
|
||||||
|
// No more sample will be passed to the decoder while true.
|
||||||
|
// mDecodePending is reset when:
|
||||||
|
// 1- The decoder returns a sample
|
||||||
|
// 2- The decoder calls InputExhausted
|
||||||
|
// 3- The decoder is Flushed or Reset.
|
||||||
|
bool mDecodePending;
|
||||||
bool mNeedDraining;
|
bool mNeedDraining;
|
||||||
bool mDraining;
|
bool mDraining;
|
||||||
bool mDrainComplete;
|
bool mDrainComplete;
|
||||||
|
@ -376,9 +374,8 @@ private:
|
||||||
if (mDecoder) {
|
if (mDecoder) {
|
||||||
mDecoder->Flush();
|
mDecoder->Flush();
|
||||||
}
|
}
|
||||||
mDecodingRequested = false;
|
|
||||||
mOutputRequested = false;
|
mOutputRequested = false;
|
||||||
mInputExhausted = false;
|
mDecodePending = false;
|
||||||
mOutput.Clear();
|
mOutput.Clear();
|
||||||
mNumSamplesInput = 0;
|
mNumSamplesInput = 0;
|
||||||
mNumSamplesOutput = 0;
|
mNumSamplesOutput = 0;
|
||||||
|
@ -397,10 +394,9 @@ private:
|
||||||
mDemuxEOS = false;
|
mDemuxEOS = false;
|
||||||
mWaitingForData = false;
|
mWaitingForData = false;
|
||||||
mQueuedSamples.Clear();
|
mQueuedSamples.Clear();
|
||||||
mDecodingRequested = false;
|
|
||||||
mOutputRequested = false;
|
mOutputRequested = false;
|
||||||
mInputExhausted = false;
|
|
||||||
mNeedDraining = false;
|
mNeedDraining = false;
|
||||||
|
mDecodePending = false;
|
||||||
mDraining = false;
|
mDraining = false;
|
||||||
mDrainComplete = false;
|
mDrainComplete = false;
|
||||||
mTimeThreshold.reset();
|
mTimeThreshold.reset();
|
||||||
|
@ -441,9 +437,8 @@ private:
|
||||||
public:
|
public:
|
||||||
DecoderDataWithPromise(MediaFormatReader* aOwner,
|
DecoderDataWithPromise(MediaFormatReader* aOwner,
|
||||||
MediaData::Type aType,
|
MediaData::Type aType,
|
||||||
uint32_t aDecodeAhead,
|
|
||||||
uint32_t aNumOfMaxError)
|
uint32_t aNumOfMaxError)
|
||||||
: DecoderData(aOwner, aType, aDecodeAhead, aNumOfMaxError)
|
: DecoderData(aOwner, aType, aNumOfMaxError)
|
||||||
, mHasPromise(false)
|
, mHasPromise(false)
|
||||||
|
|
||||||
{}
|
{}
|
||||||
|
@ -472,7 +467,6 @@ private:
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(mOwner->OnTaskQueue());
|
MOZ_ASSERT(mOwner->OnTaskQueue());
|
||||||
mPromise.Reject(aReason, aMethodName);
|
mPromise.Reject(aReason, aMethodName);
|
||||||
mDecodingRequested = false;
|
|
||||||
mHasPromise = false;
|
mHasPromise = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1077,6 +1077,25 @@ MediaStreamGraph::NotifyOutputData(AudioDataValue* aBuffer, size_t aFrames,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MediaStreamGraph::AssertOnGraphThreadOrNotRunning() const
|
||||||
|
{
|
||||||
|
// either we're on the right thread (and calling CurrentDriver() is safe),
|
||||||
|
// or we're going to assert anyways, so don't cross-check CurrentDriver
|
||||||
|
#ifdef DEBUG
|
||||||
|
MediaStreamGraphImpl const * graph =
|
||||||
|
static_cast<MediaStreamGraphImpl const *>(this);
|
||||||
|
// if all the safety checks fail, assert we own the monitor
|
||||||
|
if (!graph->mDriver->OnThread()) {
|
||||||
|
if (!(graph->mDetectedNotRunning &&
|
||||||
|
graph->mLifecycleState > MediaStreamGraphImpl::LIFECYCLE_RUNNING &&
|
||||||
|
NS_IsMainThread())) {
|
||||||
|
graph->mMonitor.AssertCurrentThreadOwns();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
MediaStreamGraphImpl::ShouldUpdateMainThread()
|
MediaStreamGraphImpl::ShouldUpdateMainThread()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1353,6 +1353,7 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual void DispatchToMainThreadAfterStreamStateUpdate(already_AddRefed<nsIRunnable> aRunnable)
|
virtual void DispatchToMainThreadAfterStreamStateUpdate(already_AddRefed<nsIRunnable> aRunnable)
|
||||||
{
|
{
|
||||||
|
AssertOnGraphThreadOrNotRunning();
|
||||||
*mPendingUpdateRunnables.AppendElement() = aRunnable;
|
*mPendingUpdateRunnables.AppendElement() = aRunnable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1374,6 +1375,8 @@ public:
|
||||||
void NotifyOutputData(AudioDataValue* aBuffer, size_t aFrames,
|
void NotifyOutputData(AudioDataValue* aBuffer, size_t aFrames,
|
||||||
TrackRate aRate, uint32_t aChannels);
|
TrackRate aRate, uint32_t aChannels);
|
||||||
|
|
||||||
|
void AssertOnGraphThreadOrNotRunning() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit MediaStreamGraph(TrackRate aSampleRate)
|
explicit MediaStreamGraph(TrackRate aSampleRate)
|
||||||
: mSampleRate(aSampleRate)
|
: mSampleRate(aSampleRate)
|
||||||
|
|
|
@ -202,24 +202,8 @@ public:
|
||||||
nsISupports* aData,
|
nsISupports* aData,
|
||||||
const nsTArray<AudioNodeSizes>& aAudioStreamSizes);
|
const nsTArray<AudioNodeSizes>& aAudioStreamSizes);
|
||||||
|
|
||||||
// The following methods run on the graph thread (or possibly the main thread if
|
// The following methods run on the graph thread (or possibly the main thread
|
||||||
// mLifecycleState > LIFECYCLE_RUNNING)
|
// if mLifecycleState > LIFECYCLE_RUNNING)
|
||||||
void AssertOnGraphThreadOrNotRunning() const
|
|
||||||
{
|
|
||||||
// either we're on the right thread (and calling CurrentDriver() is safe),
|
|
||||||
// or we're going to assert anyways, so don't cross-check CurrentDriver
|
|
||||||
#ifdef DEBUG
|
|
||||||
// if all the safety checks fail, assert we own the monitor
|
|
||||||
if (!mDriver->OnThread()) {
|
|
||||||
if (!(mDetectedNotRunning &&
|
|
||||||
mLifecycleState > LIFECYCLE_RUNNING &&
|
|
||||||
NS_IsMainThread())) {
|
|
||||||
mMonitor.AssertCurrentThreadOwns();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void CollectSizesForMemoryReport(
|
void CollectSizesForMemoryReport(
|
||||||
already_AddRefed<nsIHandleReportCallback> aHandleReport,
|
already_AddRefed<nsIHandleReportCallback> aHandleReport,
|
||||||
already_AddRefed<nsISupports> aHandlerData);
|
already_AddRefed<nsISupports> aHandlerData);
|
||||||
|
|
|
@ -132,7 +132,7 @@ FlacFrameParser::DecodeHeaderBlock(const uint8_t* aPacket, size_t aLength)
|
||||||
if (numChannels > FLAC_MAX_CHANNELS) {
|
if (numChannels > FLAC_MAX_CHANNELS) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
uint32_t bps = ((blob >> 38) & BITMASK(5)) + 1;
|
uint32_t bps = ((blob >> 36) & BITMASK(5)) + 1;
|
||||||
if (bps > 24) {
|
if (bps > 24) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -175,6 +175,9 @@ public:
|
||||||
|
|
||||||
// Denotes that the last input sample has been inserted into the decoder,
|
// Denotes that the last input sample has been inserted into the decoder,
|
||||||
// and no more output can be produced unless more input is sent.
|
// and no more output can be produced unless more input is sent.
|
||||||
|
// A frame decoding session is completed once InputExhausted has been called.
|
||||||
|
// MediaDataDecoder::Input will not be called again until InputExhausted has
|
||||||
|
// been called.
|
||||||
virtual void InputExhausted() = 0;
|
virtual void InputExhausted() = 0;
|
||||||
|
|
||||||
virtual void DrainComplete() = 0;
|
virtual void DrainComplete() = 0;
|
||||||
|
|
|
@ -96,11 +96,7 @@ private:
|
||||||
while (mReorderQueue.Length() > mMaxRefFrames) {
|
while (mReorderQueue.Length() > mMaxRefFrames) {
|
||||||
mCallback->Output(mReorderQueue.Pop().get());
|
mCallback->Output(mReorderQueue.Pop().get());
|
||||||
}
|
}
|
||||||
|
mCallback->InputExhausted();
|
||||||
if (mReorderQueue.Length() <= mMaxRefFrames) {
|
|
||||||
mCallback->InputExhausted();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -163,12 +163,9 @@ OpusDataDecoder::ProcessDecode(MediaRawData* aSample)
|
||||||
mCallback->Error(MediaDataDecoderError::DECODE_ERROR);
|
mCallback->Error(MediaDataDecoderError::DECODE_ERROR);
|
||||||
break;
|
break;
|
||||||
case DecodeError::DECODE_SUCCESS:
|
case DecodeError::DECODE_SUCCESS:
|
||||||
|
mCallback->InputExhausted();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mTaskQueue->IsEmpty()) {
|
|
||||||
mCallback->InputExhausted();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OpusDataDecoder::DecodeError
|
OpusDataDecoder::DecodeError
|
||||||
|
|
|
@ -202,7 +202,7 @@ TheoraDecoder::ProcessDecode(MediaRawData* aSample)
|
||||||
}
|
}
|
||||||
if (DoDecode(aSample) == -1) {
|
if (DoDecode(aSample) == -1) {
|
||||||
mCallback->Error(MediaDataDecoderError::DECODE_ERROR);
|
mCallback->Error(MediaDataDecoderError::DECODE_ERROR);
|
||||||
} else if (mTaskQueue->IsEmpty()) {
|
} else {
|
||||||
mCallback->InputExhausted();
|
mCallback->InputExhausted();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -192,7 +192,7 @@ VPXDecoder::ProcessDecode(MediaRawData* aSample)
|
||||||
}
|
}
|
||||||
if (DoDecode(aSample) == -1) {
|
if (DoDecode(aSample) == -1) {
|
||||||
mCallback->Error(MediaDataDecoderError::DECODE_ERROR);
|
mCallback->Error(MediaDataDecoderError::DECODE_ERROR);
|
||||||
} else if (mTaskQueue->IsEmpty()) {
|
} else {
|
||||||
mCallback->InputExhausted();
|
mCallback->InputExhausted();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,7 +143,7 @@ VorbisDataDecoder::ProcessDecode(MediaRawData* aSample)
|
||||||
}
|
}
|
||||||
if (DoDecode(aSample) == -1) {
|
if (DoDecode(aSample) == -1) {
|
||||||
mCallback->Error(MediaDataDecoderError::DECODE_ERROR);
|
mCallback->Error(MediaDataDecoderError::DECODE_ERROR);
|
||||||
} else if (mTaskQueue->IsEmpty()) {
|
} else {
|
||||||
mCallback->InputExhausted();
|
mCallback->InputExhausted();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,8 @@ WaveDataDecoder::Input(MediaRawData* aSample)
|
||||||
{
|
{
|
||||||
if (!DoDecode(aSample)) {
|
if (!DoDecode(aSample)) {
|
||||||
mCallback->Error(MediaDataDecoderError::DECODE_ERROR);
|
mCallback->Error(MediaDataDecoderError::DECODE_ERROR);
|
||||||
|
} else {
|
||||||
|
mCallback->InputExhausted();
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,10 +215,7 @@ AppleATDecoder::SubmitSample(MediaRawData* aSample)
|
||||||
}
|
}
|
||||||
mQueuedSamples.Clear();
|
mQueuedSamples.Clear();
|
||||||
}
|
}
|
||||||
|
mCallback->InputExhausted();
|
||||||
if (mTaskQueue->IsEmpty()) {
|
|
||||||
mCallback->InputExhausted();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
|
|
@ -34,11 +34,9 @@ AppleVTDecoder::AppleVTDecoder(const VideoInfo& aConfig,
|
||||||
, mPictureHeight(aConfig.mImage.height)
|
, mPictureHeight(aConfig.mImage.height)
|
||||||
, mDisplayWidth(aConfig.mDisplay.width)
|
, mDisplayWidth(aConfig.mDisplay.width)
|
||||||
, mDisplayHeight(aConfig.mDisplay.height)
|
, mDisplayHeight(aConfig.mDisplay.height)
|
||||||
, mQueuedSamples(0)
|
|
||||||
, mTaskQueue(aTaskQueue)
|
, mTaskQueue(aTaskQueue)
|
||||||
, mMaxRefFrames(mp4_demuxer::H264::ComputeMaxRefFrames(aConfig.mExtraData))
|
, mMaxRefFrames(mp4_demuxer::H264::ComputeMaxRefFrames(aConfig.mExtraData))
|
||||||
, mImageContainer(aImageContainer)
|
, mImageContainer(aImageContainer)
|
||||||
, mInputIncoming(0)
|
|
||||||
, mIsShutDown(false)
|
, mIsShutDown(false)
|
||||||
#ifdef MOZ_WIDGET_UIKIT
|
#ifdef MOZ_WIDGET_UIKIT
|
||||||
, mUseSoftwareImages(true)
|
, mUseSoftwareImages(true)
|
||||||
|
@ -88,8 +86,6 @@ AppleVTDecoder::Input(MediaRawData* aSample)
|
||||||
aSample->mKeyframe ? " keyframe" : "",
|
aSample->mKeyframe ? " keyframe" : "",
|
||||||
aSample->Size());
|
aSample->Size());
|
||||||
|
|
||||||
mInputIncoming++;
|
|
||||||
|
|
||||||
mTaskQueue->Dispatch(NewRunnableMethod<RefPtr<MediaRawData>>(
|
mTaskQueue->Dispatch(NewRunnableMethod<RefPtr<MediaRawData>>(
|
||||||
this, &AppleVTDecoder::ProcessDecode, aSample));
|
this, &AppleVTDecoder::ProcessDecode, aSample));
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -104,8 +100,6 @@ AppleVTDecoder::Flush()
|
||||||
NewRunnableMethod(this, &AppleVTDecoder::ProcessFlush);
|
NewRunnableMethod(this, &AppleVTDecoder::ProcessFlush);
|
||||||
SyncRunnable::DispatchToThread(mTaskQueue, runnable);
|
SyncRunnable::DispatchToThread(mTaskQueue, runnable);
|
||||||
mIsFlushing = false;
|
mIsFlushing = false;
|
||||||
// All ProcessDecode() tasks should be done.
|
|
||||||
MOZ_ASSERT(mInputIncoming == 0);
|
|
||||||
|
|
||||||
mSeekTargetThreshold.reset();
|
mSeekTargetThreshold.reset();
|
||||||
|
|
||||||
|
@ -142,18 +136,11 @@ AppleVTDecoder::ProcessDecode(MediaRawData* aSample)
|
||||||
{
|
{
|
||||||
AssertOnTaskQueueThread();
|
AssertOnTaskQueueThread();
|
||||||
|
|
||||||
mInputIncoming--;
|
|
||||||
|
|
||||||
if (mIsFlushing) {
|
if (mIsFlushing) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto rv = DoDecode(aSample);
|
auto rv = DoDecode(aSample);
|
||||||
// Ask for more data.
|
|
||||||
if (NS_SUCCEEDED(rv) && !mInputIncoming && mQueuedSamples <= mMaxRefFrames) {
|
|
||||||
LOG("%s task queue empty; requesting more data", GetDescriptionName());
|
|
||||||
mCallback->InputExhausted();
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -213,7 +200,6 @@ AppleVTDecoder::DrainReorderedFrames()
|
||||||
while (!mReorderQueue.IsEmpty()) {
|
while (!mReorderQueue.IsEmpty()) {
|
||||||
mCallback->Output(mReorderQueue.Pop().get());
|
mCallback->Output(mReorderQueue.Pop().get());
|
||||||
}
|
}
|
||||||
mQueuedSamples = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -223,7 +209,6 @@ AppleVTDecoder::ClearReorderedFrames()
|
||||||
while (!mReorderQueue.IsEmpty()) {
|
while (!mReorderQueue.IsEmpty()) {
|
||||||
mReorderQueue.Pop();
|
mReorderQueue.Pop();
|
||||||
}
|
}
|
||||||
mQueuedSamples = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -288,16 +273,10 @@ AppleVTDecoder::OutputFrame(CVPixelBufferRef aImage,
|
||||||
aFrameRef.is_sync_point ? " keyframe" : ""
|
aFrameRef.is_sync_point ? " keyframe" : ""
|
||||||
);
|
);
|
||||||
|
|
||||||
if (mQueuedSamples > mMaxRefFrames) {
|
|
||||||
// We had stopped requesting more input because we had received too much at
|
|
||||||
// the time. We can ask for more once again.
|
|
||||||
mCallback->InputExhausted();
|
|
||||||
}
|
|
||||||
MOZ_ASSERT(mQueuedSamples);
|
|
||||||
mQueuedSamples--;
|
|
||||||
|
|
||||||
if (!aImage) {
|
if (!aImage) {
|
||||||
// Image was dropped by decoder.
|
// Image was dropped by decoder or none return yet.
|
||||||
|
// We need more input to continue.
|
||||||
|
mCallback->InputExhausted();
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,9 +389,10 @@ AppleVTDecoder::OutputFrame(CVPixelBufferRef aImage,
|
||||||
// in composition order.
|
// in composition order.
|
||||||
MonitorAutoLock mon(mMonitor);
|
MonitorAutoLock mon(mMonitor);
|
||||||
mReorderQueue.Push(data);
|
mReorderQueue.Push(data);
|
||||||
while (mReorderQueue.Length() > mMaxRefFrames) {
|
if (mReorderQueue.Length() > mMaxRefFrames) {
|
||||||
mCallback->Output(mReorderQueue.Pop().get());
|
mCallback->Output(mReorderQueue.Pop().get());
|
||||||
}
|
}
|
||||||
|
mCallback->InputExhausted();
|
||||||
LOG("%llu decoded frames queued",
|
LOG("%llu decoded frames queued",
|
||||||
static_cast<unsigned long long>(mReorderQueue.Length()));
|
static_cast<unsigned long long>(mReorderQueue.Length()));
|
||||||
|
|
||||||
|
@ -480,8 +460,6 @@ AppleVTDecoder::DoDecode(MediaRawData* aSample)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
mQueuedSamples++;
|
|
||||||
|
|
||||||
VTDecodeFrameFlags decodeFlags =
|
VTDecodeFrameFlags decodeFlags =
|
||||||
kVTDecodeFrame_EnableAsynchronousDecompression;
|
kVTDecodeFrame_EnableAsynchronousDecompression;
|
||||||
rv = VTDecompressionSessionDecodeFrame(mSession,
|
rv = VTDecompressionSessionDecodeFrame(mSession,
|
||||||
|
|
|
@ -90,11 +90,6 @@ private:
|
||||||
const uint32_t mDisplayWidth;
|
const uint32_t mDisplayWidth;
|
||||||
const uint32_t mDisplayHeight;
|
const uint32_t mDisplayHeight;
|
||||||
|
|
||||||
// Number of times a sample was queued via Input(). Will be decreased upon
|
|
||||||
// the decoder's callback being invoked.
|
|
||||||
// This is used to calculate how many frames has been buffered by the decoder.
|
|
||||||
Atomic<uint32_t> mQueuedSamples;
|
|
||||||
|
|
||||||
// Method to set up the decompression session.
|
// Method to set up the decompression session.
|
||||||
nsresult InitializeSession();
|
nsresult InitializeSession();
|
||||||
nsresult WaitForAsynchronousFrames();
|
nsresult WaitForAsynchronousFrames();
|
||||||
|
@ -106,9 +101,6 @@ private:
|
||||||
const RefPtr<TaskQueue> mTaskQueue;
|
const RefPtr<TaskQueue> mTaskQueue;
|
||||||
const uint32_t mMaxRefFrames;
|
const uint32_t mMaxRefFrames;
|
||||||
const RefPtr<layers::ImageContainer> mImageContainer;
|
const RefPtr<layers::ImageContainer> mImageContainer;
|
||||||
// Increased when Input is called, and decreased when ProcessFrame runs.
|
|
||||||
// Reaching 0 indicates that there's no pending Input.
|
|
||||||
Atomic<uint32_t> mInputIncoming;
|
|
||||||
Atomic<bool> mIsShutDown;
|
Atomic<bool> mIsShutDown;
|
||||||
const bool mUseSoftwareImages;
|
const bool mUseSoftwareImages;
|
||||||
|
|
||||||
|
|
|
@ -133,6 +133,7 @@ FFmpegAudioDecoder<LIBAV_VER>::DoDecode(MediaRawData* aSample)
|
||||||
|
|
||||||
int64_t samplePosition = aSample->mOffset;
|
int64_t samplePosition = aSample->mOffset;
|
||||||
media::TimeUnit pts = media::TimeUnit::FromMicroseconds(aSample->mTime);
|
media::TimeUnit pts = media::TimeUnit::FromMicroseconds(aSample->mTime);
|
||||||
|
bool didOutput = false;
|
||||||
|
|
||||||
while (packet.size > 0) {
|
while (packet.size > 0) {
|
||||||
int decoded;
|
int decoded;
|
||||||
|
@ -181,6 +182,7 @@ FFmpegAudioDecoder<LIBAV_VER>::DoDecode(MediaRawData* aSample)
|
||||||
numChannels,
|
numChannels,
|
||||||
samplingRate);
|
samplingRate);
|
||||||
mCallback->Output(data);
|
mCallback->Output(data);
|
||||||
|
didOutput = true;
|
||||||
pts += duration;
|
pts += duration;
|
||||||
if (!pts.IsValid()) {
|
if (!pts.IsValid()) {
|
||||||
NS_WARNING("Invalid count of accumulated audio samples");
|
NS_WARNING("Invalid count of accumulated audio samples");
|
||||||
|
@ -192,7 +194,7 @@ FFmpegAudioDecoder<LIBAV_VER>::DoDecode(MediaRawData* aSample)
|
||||||
samplePosition += bytesConsumed;
|
samplePosition += bytesConsumed;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DecodeResult::DECODE_FRAME;
|
return didOutput ? DecodeResult::DECODE_FRAME : DecodeResult::DECODE_NO_FRAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -117,10 +117,12 @@ FFmpegDataDecoder<LIBAV_VER>::ProcessDecode(MediaRawData* aSample)
|
||||||
case DecodeResult::FATAL_ERROR:
|
case DecodeResult::FATAL_ERROR:
|
||||||
mCallback->Error(MediaDataDecoderError::FATAL_ERROR);
|
mCallback->Error(MediaDataDecoderError::FATAL_ERROR);
|
||||||
break;
|
break;
|
||||||
|
case DecodeResult::DECODE_NO_FRAME:
|
||||||
|
case DecodeResult::DECODE_FRAME:
|
||||||
|
mCallback->InputExhausted();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (mTaskQueue->IsEmpty()) {
|
break;
|
||||||
mCallback->InputExhausted();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -149,9 +149,7 @@ WMFMediaDataDecoder::ProcessOutput()
|
||||||
mCallback->Output(output);
|
mCallback->Output(output);
|
||||||
}
|
}
|
||||||
if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
|
if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
|
||||||
if (mTaskQueue->IsEmpty()) {
|
mCallback->InputExhausted();
|
||||||
mCallback->InputExhausted();
|
|
||||||
}
|
|
||||||
} else if (FAILED(hr)) {
|
} else if (FAILED(hr)) {
|
||||||
NS_WARNING("WMFMediaDataDecoder failed to output data");
|
NS_WARNING("WMFMediaDataDecoder failed to output data");
|
||||||
mCallback->Error(MediaDataDecoderError::DECODE_ERROR);
|
mCallback->Error(MediaDataDecoderError::DECODE_ERROR);
|
||||||
|
|
|
@ -15,9 +15,16 @@ from external_media_tests.utils import verbose_until
|
||||||
|
|
||||||
class YouTubePuppeteer(VideoPuppeteer):
|
class YouTubePuppeteer(VideoPuppeteer):
|
||||||
"""
|
"""
|
||||||
Wrapper around a YouTube #movie_player element.
|
Wrapper around a YouTube .html5-video-player element.
|
||||||
|
|
||||||
Partial reference: https://developers.google.com/youtube/js_api_reference.
|
Can be used with youtube videos or youtube videos at embedded URLS. E.g.
|
||||||
|
both https://www.youtube.com/watch?v=AbAACm1IQE0 and
|
||||||
|
https://www.youtube.com/embed/AbAACm1IQE0 should work.
|
||||||
|
|
||||||
|
Using an embedded video has the advantage of not auto-playing more videos
|
||||||
|
while a test is running.
|
||||||
|
|
||||||
|
Partial reference: https://developers.google.com/youtube/iframe_api_reference.
|
||||||
This reference is useful for site-specific features such as interacting
|
This reference is useful for site-specific features such as interacting
|
||||||
with ads, or accessing YouTube's debug data.
|
with ads, or accessing YouTube's debug data.
|
||||||
"""
|
"""
|
||||||
|
@ -37,14 +44,16 @@ class YouTubePuppeteer(VideoPuppeteer):
|
||||||
self.player = None
|
self.player = None
|
||||||
super(YouTubePuppeteer,
|
super(YouTubePuppeteer,
|
||||||
self).__init__(marionette, url,
|
self).__init__(marionette, url,
|
||||||
video_selector='#movie_player video',
|
video_selector='.html5-video-player video',
|
||||||
**kwargs)
|
**kwargs)
|
||||||
wait = Wait(self.marionette, timeout=30)
|
wait = Wait(self.marionette, timeout=30)
|
||||||
with self.marionette.using_context(Marionette.CONTEXT_CONTENT):
|
with self.marionette.using_context(Marionette.CONTEXT_CONTENT):
|
||||||
verbose_until(wait, self,
|
verbose_until(wait, self,
|
||||||
expected.element_present(By.ID, 'movie_player'))
|
expected.element_present(By.CLASS_NAME,
|
||||||
self.player = self.marionette.find_element(By.ID, 'movie_player')
|
'html5-video-player'))
|
||||||
self.marionette.execute_script("log('#movie_player "
|
self.player = self.marionette.find_element(By.CLASS_NAME,
|
||||||
|
'html5-video-player')
|
||||||
|
self.marionette.execute_script("log('.html5-video-player "
|
||||||
"element obtained');")
|
"element obtained');")
|
||||||
# When an ad is playing, self.player_duration indicates the duration
|
# When an ad is playing, self.player_duration indicates the duration
|
||||||
# of the spliced-in ad stream, not the duration of the main video, so
|
# of the spliced-in ad stream, not the duration of the main video, so
|
||||||
|
@ -117,7 +126,7 @@ class YouTubePuppeteer(VideoPuppeteer):
|
||||||
def execute_yt_script(self, script):
|
def execute_yt_script(self, script):
|
||||||
"""
|
"""
|
||||||
Execute JS script in content context with access to video element and
|
Execute JS script in content context with access to video element and
|
||||||
YouTube #movie_player element.
|
YouTube .html5-video-player element.
|
||||||
|
|
||||||
:param script: script to be executed.
|
:param script: script to be executed.
|
||||||
|
|
||||||
|
@ -131,7 +140,7 @@ class YouTubePuppeteer(VideoPuppeteer):
|
||||||
@property
|
@property
|
||||||
def playback_quality(self):
|
def playback_quality(self):
|
||||||
"""
|
"""
|
||||||
Please see https://developers.google.com/youtube/js_api_reference#Playback_quality
|
Please see https://developers.google.com/youtube/iframe_api_reference#Playback_quality
|
||||||
for valid values.
|
for valid values.
|
||||||
|
|
||||||
:return: A string with a valid value returned via YouTube.
|
:return: A string with a valid value returned via YouTube.
|
||||||
|
@ -176,7 +185,7 @@ class YouTubePuppeteer(VideoPuppeteer):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
:return: The YouTube state of the video. See
|
:return: The YouTube state of the video. See
|
||||||
https://developers.google.com/youtube/js_api_reference#getPlayerState
|
https://developers.google.com/youtube/iframe_api_reference#getPlayerState
|
||||||
for valid values.
|
for valid values.
|
||||||
"""
|
"""
|
||||||
state = self.execute_yt_script('return arguments[1].'
|
state = self.execute_yt_script('return arguments[1].'
|
||||||
|
@ -188,7 +197,7 @@ class YouTubePuppeteer(VideoPuppeteer):
|
||||||
"""
|
"""
|
||||||
This and the following properties are based on the
|
This and the following properties are based on the
|
||||||
player.getPlayerState() call
|
player.getPlayerState() call
|
||||||
(https://developers.google.com/youtube/js_api_reference#Playback_status)
|
(https://developers.google.com/youtube/iframe_api_reference#Playback_status)
|
||||||
|
|
||||||
:return: True if the video has not yet started.
|
:return: True if the video has not yet started.
|
||||||
"""
|
"""
|
||||||
|
@ -240,7 +249,7 @@ class YouTubePuppeteer(VideoPuppeteer):
|
||||||
Get state of current ad.
|
Get state of current ad.
|
||||||
|
|
||||||
:return: Returns one of the constants listed in
|
:return: Returns one of the constants listed in
|
||||||
https://developers.google.com/youtube/js_api_reference#Playback_status
|
https://developers.google.com/youtube/iframe_api_reference#Playback_status
|
||||||
for an ad.
|
for an ad.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -350,7 +359,7 @@ class YouTubePuppeteer(VideoPuppeteer):
|
||||||
# no ad playing
|
# no ad playing
|
||||||
return False
|
return False
|
||||||
if self.ad_skippable:
|
if self.ad_skippable:
|
||||||
selector = '#movie_player .videoAdUiSkipContainer'
|
selector = '.html5-video-player .videoAdUiSkipContainer'
|
||||||
wait = Wait(self.marionette, timeout=30)
|
wait = Wait(self.marionette, timeout=30)
|
||||||
try:
|
try:
|
||||||
with self.marionette.using_context(Marionette.CONTEXT_CONTENT):
|
with self.marionette.using_context(Marionette.CONTEXT_CONTENT):
|
||||||
|
@ -378,7 +387,7 @@ class YouTubePuppeteer(VideoPuppeteer):
|
||||||
if (self.ad_playing and self.video_src.startswith('mediasource') and
|
if (self.ad_playing and self.video_src.startswith('mediasource') and
|
||||||
self.duration):
|
self.duration):
|
||||||
return self.duration
|
return self.duration
|
||||||
selector = '#movie_player .videoAdUiAttribution'
|
selector = '.html5-media-player .videoAdUiAttribution'
|
||||||
wait = Wait(self.marionette, timeout=5)
|
wait = Wait(self.marionette, timeout=5)
|
||||||
try:
|
try:
|
||||||
with self.marionette.using_context(Marionette.CONTEXT_CONTENT):
|
with self.marionette.using_context(Marionette.CONTEXT_CONTENT):
|
||||||
|
@ -464,7 +473,7 @@ class YouTubePuppeteer(VideoPuppeteer):
|
||||||
player_state = self._yt_player_state_name[self.player_state]
|
player_state = self._yt_player_state_name[self.player_state]
|
||||||
ad_state = self._yt_player_state_name[self.ad_state]
|
ad_state = self._yt_player_state_name[self.ad_state]
|
||||||
messages += [
|
messages += [
|
||||||
'#movie_player: {',
|
'.html5-media-player: {',
|
||||||
'\tvideo id: {0},'.format(self.movie_id),
|
'\tvideo id: {0},'.format(self.movie_id),
|
||||||
'\tvideo_title: {0}'.format(self.movie_title),
|
'\tvideo_title: {0}'.format(self.movie_title),
|
||||||
'\tcurrent_state: {0},'.format(player_state),
|
'\tcurrent_state: {0},'.format(player_state),
|
||||||
|
@ -475,7 +484,7 @@ class YouTubePuppeteer(VideoPuppeteer):
|
||||||
'}'
|
'}'
|
||||||
]
|
]
|
||||||
else:
|
else:
|
||||||
messages += ['\t#movie_player: None']
|
messages += ['\t.html5-media-player: None']
|
||||||
return '\n'.join(messages)
|
return '\n'.join(messages)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
# short videos; no ads; max 5 minutes
|
# short videos; no ads; embedded; max 5 minutes
|
||||||
# 0:12
|
# 0:12
|
||||||
[https://youtu.be/AbAACm1IQE0]
|
[https://youtube.com/embed/AbAACm1IQE0?autoplay=1]
|
||||||
# 2:18
|
# 2:18
|
||||||
[https://www.youtube.com/watch?v=yOQQCoxs8-k]
|
[https://youtube.com/embed/yOQQCoxs8-k?autoplay=1]
|
||||||
# 0:08
|
# 0:08
|
||||||
[https://www.youtube.com/watch?v=1visYpIREUM]
|
[https://youtube.com/embed/1visYpIREUM?autoplay=1]
|
||||||
# 2:09
|
# 2:09
|
||||||
[https://www.youtube.com/watch?v=rjmuKV9BTkE]
|
[https://youtube.com/embed/rjmuKV9BTkE?autoplay=1]
|
||||||
|
|
|
@ -1,14 +1,5 @@
|
||||||
# all long videos; < 12 hours total
|
# a couple of very long videos, < 12 hours total
|
||||||
# 2:18:00
|
# 6:00:00 - can't embed due to copyright
|
||||||
[http://youtu.be/FLX64H5FYa8]
|
[https://www.youtube.com/watch?v=5N8sUccRiTA]
|
||||||
# 1:00:00
|
# 2:09:00
|
||||||
[https://www.youtube.com/watch?v=AYYDshv8C4g]
|
[https://www.youtube.com/embed/b6q5N16dje4?autoplay=1]
|
||||||
# 1:10:00
|
|
||||||
[https://www.youtube.com/watch?v=V0Vy4kYAPDk]
|
|
||||||
# 1:47:00
|
|
||||||
[https://www.youtube.com/watch?v=bFtGE2C7Pxs]
|
|
||||||
|
|
||||||
|
|
||||||
# shutdownhang | WaitForSingleObjectEx | WaitForSingleObject | PR_Wait | nsThread::ProcessNextEvent(bool, bool*) | NS_ProcessNextEvent(nsIThread*, bool) | mozilla::MediaShutdownManager::Shutdown()
|
|
||||||
# 1:43:00
|
|
||||||
[https://www.youtube.com/watch?v=BXMtXpmpXPU]
|
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
# a couple of very long videos, < 12 hours total
|
|
||||||
# 6:00:00
|
|
||||||
[https://www.youtube.com/watch?v=5N8sUccRiTA]
|
|
||||||
# 2:27:00
|
|
||||||
[https://www.youtube.com/watch?v=NAVrm3wjzq8]
|
|
||||||
# 58:50
|
|
||||||
[https://www.youtube.com/watch?v=uP1BBw3IYco]
|
|
||||||
# 2:09:00
|
|
||||||
[https://www.youtube.com/watch?v=b6q5N16dje4]
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# It appears these are not currently used by tests. They are left here as they
|
||||||
|
# reference failure scenarios. If tese are fixed that can be removed.
|
||||||
|
|
||||||
# videos from crashes, < 12 hours
|
# videos from crashes, < 12 hours
|
||||||
|
|
||||||
# hang | NtUserMessageCall | SendMessageW
|
# hang | NtUserMessageCall | SendMessageW
|
|
@ -1,3 +1,6 @@
|
||||||
|
# It appears these are not currently used by tests. They are left here as they
|
||||||
|
# reference failure scenarios. If tese are fixed that can be removed.
|
||||||
|
|
||||||
# Total time: about 12-13 hours + unskippable ads
|
# Total time: about 12-13 hours + unskippable ads
|
||||||
#Request url: https://crash-stats.mozilla.com/api/SuperSearchUnredacted/?product=Firefox&url=%24https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D&url=%21~list&url=%21~index&_results_number=50&platform=Windows&version=37.0&date=%3E2015-03-26
|
#Request url: https://crash-stats.mozilla.com/api/SuperSearchUnredacted/?product=Firefox&url=%24https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D&url=%21~list&url=%21~index&_results_number=50&platform=Windows&version=37.0&date=%3E2015-03-26
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
# very long test; 96-100 hours?
|
|
||||||
# 00:3:26
|
|
||||||
[https://www.youtube.com/watch?v=7RMQksXpQSk]
|
|
||||||
# nyan cat 10 hours
|
|
||||||
[http://youtu.be/9bZkp7q19f0]
|
|
||||||
# 4:54:00
|
|
||||||
[https://www.youtube.com/watch?v=jWlKjw3LBDk]
|
|
||||||
# 3:00:01
|
|
||||||
[https://www.youtube.com/watch?v=ub9JUDS_6i8]
|
|
||||||
# 10 hours rick roll
|
|
||||||
[https://www.youtube.com/watch?v=BROWqjuTM0g]
|
|
||||||
# 24 hours
|
|
||||||
[https://www.youtube.com/watch?v=FvHiLLkPhQE]
|
|
||||||
# 2 hours
|
|
||||||
[https://www.youtube.com/watch?v=VmOuW5zTt9w
|
|
|
@ -1,18 +1,18 @@
|
||||||
# mix of shorter/longer videos with/without ads, < 60 min
|
# mix of shorter/longer videos with/without ads, < 60 min
|
||||||
# 4:59
|
# 4:59 - can't embed
|
||||||
[http://youtu.be/pWI8RB2dmfU]
|
[https://www.youtube.com/watch?v=pWI8RB2dmfU]
|
||||||
# 0:46 ad at start
|
# 0:46 ad at start
|
||||||
[http://youtu.be/6SFp1z7uA6g]
|
[https://www.youtube.com/embed/6SFp1z7uA6g?autoplay=1]
|
||||||
# 0:58 ad at start
|
# 0:58 ad at start
|
||||||
[http://youtu.be/Aebs62bX0dA]
|
[https://www.youtube.com/embed/Aebs62bX0dA?autoplay=1]
|
||||||
# 1:43 ad
|
# 1:43 ad
|
||||||
[https://www.youtube.com/watch?v=l5ODwR6FPRQ]
|
[https://www.youtube.com/embed/l5ODwR6FPRQ?autoplay=1]
|
||||||
# 8:00 ad
|
# 8:00 ad - can't embed
|
||||||
[https://www.youtube.com/watch?v=KlyXNRrsk4A]
|
[https://www.youtube.com/watch?v=KlyXNRrsk4A]
|
||||||
# video with ad in beginning and in the middle 20:00
|
# video with ad in beginning and in the middle 20:00
|
||||||
# https://bugzilla.mozilla.org/show_bug.cgi?id=1176815
|
# https://bugzilla.mozilla.org/show_bug.cgi?id=1176815
|
||||||
[https://www.youtube.com/watch?v=cht9Xq9suGg]
|
[https://www.youtube.com/embed/cht9Xq9suGg?autoplay=1]
|
||||||
# 1:35 ad
|
# 1:35 ad
|
||||||
[https://www.youtube.com/watch?v=orybDrUj4vA]
|
[https://www.youtube.com/embed/orybDrUj4vA?autoplay=1]
|
||||||
# 3:02 - ad
|
# 3:02 ad
|
||||||
[https://youtu.be/tDDVAErOI5U]
|
[https://www.youtube.com/embed/tDDVAErOI5U?autoplay=1]
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
# a few longer videos, < 60 min total
|
|
||||||
# 0:30:00 no ad
|
|
||||||
[https://www.youtube.com/watch?v=-qXxNPvqHtQ]
|
|
||||||
# 0:20:00
|
|
||||||
[http://youtu.be/Fu2DcHzokew]
|
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
# a few longer videos, < 120 min total
|
|
||||||
# video with ad in the middle
|
|
||||||
# 21:00
|
|
||||||
[https://www.youtube.com/watch?v=cht9Xq9suGg]
|
|
||||||
# 16:00
|
|
||||||
[https://www.youtube.com/watch?v=6Lm9EHhbJAY]
|
|
||||||
# 20:00
|
|
||||||
[https://www.youtube.com/watch?v=8XQ1onjXJK0]
|
|
||||||
# 59:06
|
|
||||||
[https://www.youtube.com/watch?v=kmpiY5kssU4]
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
# 00:12
|
|
||||||
[https://youtu.be/AbAACm1IQE0]
|
|
||||||
# longer video with ads; < 15 min total
|
|
||||||
# 13:40
|
|
||||||
[https://www.youtube.com/watch?v=87uo2TPrsl8]
|
|
|
@ -1,5 +0,0 @@
|
||||||
# 1-2 longer videos with ads; < 15 minutes total
|
|
||||||
[https://www.youtube.com/watch?v=v678Em6qyzk]
|
|
||||||
[https://www.youtube.com/watch?v=l8XOZJkozfI]
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# It appears these are not currently used by tests. They are left here as they
|
||||||
|
# reference failure scenarios. If tese are fixed that can be removed.
|
||||||
|
|
||||||
# crash-data videos, < 15 minutes total
|
# crash-data videos, < 15 minutes total
|
||||||
|
|
||||||
# hang | NtUserMessageCall | SendMessageW
|
# hang | NtUserMessageCall | SendMessageW
|
|
@ -46,6 +46,7 @@
|
||||||
#if defined(MOZ_X11)
|
#if defined(MOZ_X11)
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
|
#include "X11UndefineNone.h"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -2610,7 +2610,7 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent)
|
||||||
#ifdef MOZ_WIDGET_GTK
|
#ifdef MOZ_WIDGET_GTK
|
||||||
Window root = GDK_ROOT_WINDOW();
|
Window root = GDK_ROOT_WINDOW();
|
||||||
#else
|
#else
|
||||||
Window root = None; // Could XQueryTree, but this is not important.
|
Window root = X11None; // Could XQueryTree, but this is not important.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch (anEvent.mMessage) {
|
switch (anEvent.mMessage) {
|
||||||
|
@ -2628,7 +2628,7 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent)
|
||||||
event.y_root = rootPoint.y;
|
event.y_root = rootPoint.y;
|
||||||
event.state = XInputEventState(mouseEvent);
|
event.state = XInputEventState(mouseEvent);
|
||||||
// information lost
|
// information lost
|
||||||
event.subwindow = None;
|
event.subwindow = X11None;
|
||||||
event.mode = -1;
|
event.mode = -1;
|
||||||
event.detail = NotifyDetailNone;
|
event.detail = NotifyDetailNone;
|
||||||
event.same_screen = True;
|
event.same_screen = True;
|
||||||
|
@ -2647,7 +2647,7 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent)
|
||||||
event.y_root = rootPoint.y;
|
event.y_root = rootPoint.y;
|
||||||
event.state = XInputEventState(mouseEvent);
|
event.state = XInputEventState(mouseEvent);
|
||||||
// information lost
|
// information lost
|
||||||
event.subwindow = None;
|
event.subwindow = X11None;
|
||||||
event.is_hint = NotifyNormal;
|
event.is_hint = NotifyNormal;
|
||||||
event.same_screen = True;
|
event.same_screen = True;
|
||||||
}
|
}
|
||||||
|
@ -2678,7 +2678,7 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// information lost:
|
// information lost:
|
||||||
event.subwindow = None;
|
event.subwindow = X11None;
|
||||||
event.same_screen = True;
|
event.same_screen = True;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2722,7 +2722,7 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent)
|
||||||
|
|
||||||
// Information that could be obtained from pluginEvent but we may not
|
// Information that could be obtained from pluginEvent but we may not
|
||||||
// want to promise to provide:
|
// want to promise to provide:
|
||||||
event.subwindow = None;
|
event.subwindow = X11None;
|
||||||
event.x = 0;
|
event.x = 0;
|
||||||
event.y = 0;
|
event.y = 0;
|
||||||
event.x_root = -1;
|
event.x_root = -1;
|
||||||
|
@ -2764,7 +2764,7 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent)
|
||||||
XAnyEvent& event = pluginEvent.xany;
|
XAnyEvent& event = pluginEvent.xany;
|
||||||
event.display = widget ?
|
event.display = widget ?
|
||||||
static_cast<Display*>(widget->GetNativeData(NS_NATIVE_DISPLAY)) : nullptr;
|
static_cast<Display*>(widget->GetNativeData(NS_NATIVE_DISPLAY)) : nullptr;
|
||||||
event.window = None; // not a real window
|
event.window = X11None; // not a real window
|
||||||
// information lost:
|
// information lost:
|
||||||
event.serial = 0;
|
event.serial = 0;
|
||||||
event.send_event = False;
|
event.send_event = False;
|
||||||
|
|
|
@ -217,7 +217,7 @@ nsresult nsPluginNativeWindowGtk::CreateXEmbedWindow(bool aEnableXtFocus) {
|
||||||
GdkVisual* gdkVisual = gdk_drawable_get_visual(gdkWindow);
|
GdkVisual* gdkVisual = gdk_drawable_get_visual(gdkWindow);
|
||||||
mWsInfo.depth = gdkVisual->depth;
|
mWsInfo.depth = gdkVisual->depth;
|
||||||
#else
|
#else
|
||||||
mWsInfo.colormap = None;
|
mWsInfo.colormap = X11None;
|
||||||
GdkVisual* gdkVisual = gdk_window_get_visual(gdkWindow);
|
GdkVisual* gdkVisual = gdk_window_get_visual(gdkWindow);
|
||||||
mWsInfo.depth = gdk_visual_get_depth(gdkVisual);
|
mWsInfo.depth = gdk_visual_get_depth(gdkVisual);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1282,7 +1282,7 @@ PluginInstanceChild::AnswerNPP_SetWindow(const NPRemoteWindow& aWindow)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aWindow.visualID != None
|
if (aWindow.visualID != X11None
|
||||||
&& gtk_check_version(2, 12, 10) != nullptr) { // older
|
&& gtk_check_version(2, 12, 10) != nullptr) { // older
|
||||||
// Workaround for a bug in Gtk+ (prior to 2.12.10) where deleting
|
// Workaround for a bug in Gtk+ (prior to 2.12.10) where deleting
|
||||||
// a foreign GdkColormap will also free the XColormap.
|
// a foreign GdkColormap will also free the XColormap.
|
||||||
|
|
|
@ -81,7 +81,7 @@ pluginInstanceInit(InstanceData* instanceData)
|
||||||
|
|
||||||
instanceData->platformData->display = nullptr;
|
instanceData->platformData->display = nullptr;
|
||||||
instanceData->platformData->visual = nullptr;
|
instanceData->platformData->visual = nullptr;
|
||||||
instanceData->platformData->colormap = None;
|
instanceData->platformData->colormap = X11None;
|
||||||
instanceData->platformData->plug = nullptr;
|
instanceData->platformData->plug = nullptr;
|
||||||
|
|
||||||
return NPERR_NO_ERROR;
|
return NPERR_NO_ERROR;
|
||||||
|
@ -97,7 +97,7 @@ pluginInstanceShutdown(InstanceData* instanceData)
|
||||||
if (instanceData->hasWidget) {
|
if (instanceData->hasWidget) {
|
||||||
Window window = reinterpret_cast<XID>(instanceData->window.window);
|
Window window = reinterpret_cast<XID>(instanceData->window.window);
|
||||||
|
|
||||||
if (window != None) {
|
if (window != X11None) {
|
||||||
// This window XID should still be valid.
|
// This window XID should still be valid.
|
||||||
// See bug 429604 and bug 454756.
|
// See bug 429604 and bug 454756.
|
||||||
XWindowAttributes attributes;
|
XWindowAttributes attributes;
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#ifdef MOZ_X11
|
#ifdef MOZ_X11
|
||||||
#include <X11/extensions/Xrender.h>
|
#include <X11/extensions/Xrender.h>
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
|
#include "X11UndefineNone.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct _cairo;
|
struct _cairo;
|
||||||
|
@ -87,7 +88,7 @@ public:
|
||||||
BorrowedXlibDrawable()
|
BorrowedXlibDrawable()
|
||||||
: mDT(nullptr),
|
: mDT(nullptr),
|
||||||
mDisplay(nullptr),
|
mDisplay(nullptr),
|
||||||
mDrawable(None),
|
mDrawable(X11None),
|
||||||
mScreen(nullptr),
|
mScreen(nullptr),
|
||||||
mVisual(nullptr),
|
mVisual(nullptr),
|
||||||
mXRenderFormat(nullptr)
|
mXRenderFormat(nullptr)
|
||||||
|
@ -96,7 +97,7 @@ public:
|
||||||
explicit BorrowedXlibDrawable(DrawTarget *aDT)
|
explicit BorrowedXlibDrawable(DrawTarget *aDT)
|
||||||
: mDT(nullptr),
|
: mDT(nullptr),
|
||||||
mDisplay(nullptr),
|
mDisplay(nullptr),
|
||||||
mDrawable(None),
|
mDrawable(X11None),
|
||||||
mScreen(nullptr),
|
mScreen(nullptr),
|
||||||
mVisual(nullptr),
|
mVisual(nullptr),
|
||||||
mXRenderFormat(nullptr)
|
mXRenderFormat(nullptr)
|
||||||
|
|
|
@ -2163,7 +2163,7 @@ DrawTargetCairo::Draw3DTransformedSurface(SourceSurface* aSurface, const Matrix4
|
||||||
0, nullptr);
|
0, nullptr);
|
||||||
|
|
||||||
XRenderComposite(display, PictOpSrc,
|
XRenderComposite(display, PictOpSrc,
|
||||||
srcPict, None, dstPict,
|
srcPict, X11None, dstPict,
|
||||||
0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0,
|
||||||
xformBounds.width, xformBounds.height);
|
xformBounds.width, xformBounds.height);
|
||||||
|
|
||||||
|
@ -2313,7 +2313,7 @@ BorrowedXlibDrawable::Init(DrawTarget* aDT)
|
||||||
MOZ_ASSERT(aDT, "Caller should check for nullptr");
|
MOZ_ASSERT(aDT, "Caller should check for nullptr");
|
||||||
MOZ_ASSERT(!mDT, "Can't initialize twice!");
|
MOZ_ASSERT(!mDT, "Can't initialize twice!");
|
||||||
mDT = aDT;
|
mDT = aDT;
|
||||||
mDrawable = None;
|
mDrawable = X11None;
|
||||||
|
|
||||||
#ifdef CAIRO_HAS_XLIB_SURFACE
|
#ifdef CAIRO_HAS_XLIB_SURFACE
|
||||||
if (aDT->GetBackendType() != BackendType::CAIRO ||
|
if (aDT->GetBackendType() != BackendType::CAIRO ||
|
||||||
|
@ -2356,7 +2356,7 @@ BorrowedXlibDrawable::Finish()
|
||||||
cairo_surface_t* surf = cairo_get_group_target(cairoDT->mContext);
|
cairo_surface_t* surf = cairo_get_group_target(cairoDT->mContext);
|
||||||
cairo_surface_mark_dirty(surf);
|
cairo_surface_mark_dirty(surf);
|
||||||
if (mDrawable) {
|
if (mDrawable) {
|
||||||
mDrawable = None;
|
mDrawable = X11None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
|
#include "X11UndefineNone.h"
|
||||||
|
|
||||||
#include "mozilla/MathAlgorithms.h"
|
#include "mozilla/MathAlgorithms.h"
|
||||||
#include "mozilla/StaticPtr.h"
|
#include "mozilla/StaticPtr.h"
|
||||||
|
@ -308,13 +309,13 @@ GLXPixmap
|
||||||
GLXLibrary::CreatePixmap(gfxASurface* aSurface)
|
GLXLibrary::CreatePixmap(gfxASurface* aSurface)
|
||||||
{
|
{
|
||||||
if (!SupportsTextureFromPixmap(aSurface)) {
|
if (!SupportsTextureFromPixmap(aSurface)) {
|
||||||
return None;
|
return X11None;
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxXlibSurface* xs = static_cast<gfxXlibSurface*>(aSurface);
|
gfxXlibSurface* xs = static_cast<gfxXlibSurface*>(aSurface);
|
||||||
const XRenderPictFormat* format = xs->XRenderFormat();
|
const XRenderPictFormat* format = xs->XRenderFormat();
|
||||||
if (!format || format->type != PictTypeDirect) {
|
if (!format || format->type != PictTypeDirect) {
|
||||||
return None;
|
return X11None;
|
||||||
}
|
}
|
||||||
const XRenderDirectFormat& direct = format->direct;
|
const XRenderDirectFormat& direct = format->direct;
|
||||||
int alphaSize = FloorLog2(direct.alphaMask + 1);
|
int alphaSize = FloorLog2(direct.alphaMask + 1);
|
||||||
|
@ -327,7 +328,7 @@ GLXLibrary::CreatePixmap(gfxASurface* aSurface)
|
||||||
(alphaSize ? LOCAL_GLX_BIND_TO_TEXTURE_RGBA_EXT
|
(alphaSize ? LOCAL_GLX_BIND_TO_TEXTURE_RGBA_EXT
|
||||||
: LOCAL_GLX_BIND_TO_TEXTURE_RGB_EXT), True,
|
: LOCAL_GLX_BIND_TO_TEXTURE_RGB_EXT), True,
|
||||||
LOCAL_GLX_RENDER_TYPE, LOCAL_GLX_RGBA_BIT,
|
LOCAL_GLX_RENDER_TYPE, LOCAL_GLX_RGBA_BIT,
|
||||||
None };
|
X11None };
|
||||||
|
|
||||||
int numConfigs = 0;
|
int numConfigs = 0;
|
||||||
Display* display = xs->XDisplay();
|
Display* display = xs->XDisplay();
|
||||||
|
@ -351,7 +352,7 @@ GLXLibrary::CreatePixmap(gfxASurface* aSurface)
|
||||||
~(redMask | greenMask | blueMask) != -1UL << format->depth;
|
~(redMask | greenMask | blueMask) != -1UL << format->depth;
|
||||||
|
|
||||||
for (int i = 0; i < numConfigs; i++) {
|
for (int i = 0; i < numConfigs; i++) {
|
||||||
int id = None;
|
int id = X11None;
|
||||||
sGLXLibrary.xGetFBConfigAttrib(display, cfgs[i], LOCAL_GLX_VISUAL_ID, &id);
|
sGLXLibrary.xGetFBConfigAttrib(display, cfgs[i], LOCAL_GLX_VISUAL_ID, &id);
|
||||||
Visual* visual;
|
Visual* visual;
|
||||||
int depth;
|
int depth;
|
||||||
|
@ -424,14 +425,14 @@ GLXLibrary::CreatePixmap(gfxASurface* aSurface)
|
||||||
// caller should deal with this situation.
|
// caller should deal with this situation.
|
||||||
NS_WARN_IF_FALSE(format->depth == 8,
|
NS_WARN_IF_FALSE(format->depth == 8,
|
||||||
"[GLX] Couldn't find a FBConfig matching Pixmap format");
|
"[GLX] Couldn't find a FBConfig matching Pixmap format");
|
||||||
return None;
|
return X11None;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pixmapAttribs[] = { LOCAL_GLX_TEXTURE_TARGET_EXT, LOCAL_GLX_TEXTURE_2D_EXT,
|
int pixmapAttribs[] = { LOCAL_GLX_TEXTURE_TARGET_EXT, LOCAL_GLX_TEXTURE_2D_EXT,
|
||||||
LOCAL_GLX_TEXTURE_FORMAT_EXT,
|
LOCAL_GLX_TEXTURE_FORMAT_EXT,
|
||||||
(alphaSize ? LOCAL_GLX_TEXTURE_FORMAT_RGBA_EXT
|
(alphaSize ? LOCAL_GLX_TEXTURE_FORMAT_RGBA_EXT
|
||||||
: LOCAL_GLX_TEXTURE_FORMAT_RGB_EXT),
|
: LOCAL_GLX_TEXTURE_FORMAT_RGB_EXT),
|
||||||
None};
|
X11None};
|
||||||
|
|
||||||
GLXPixmap glxpixmap = xCreatePixmap(display,
|
GLXPixmap glxpixmap = xCreatePixmap(display,
|
||||||
cfgs[matchIndex],
|
cfgs[matchIndex],
|
||||||
|
@ -900,7 +901,7 @@ GLContextGLX::~GLContextGLX()
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
bool success =
|
bool success =
|
||||||
#endif
|
#endif
|
||||||
mGLX->xMakeCurrent(mDisplay, None, nullptr);
|
mGLX->xMakeCurrent(mDisplay, X11None, nullptr);
|
||||||
MOZ_ASSERT(success,
|
MOZ_ASSERT(success,
|
||||||
"glXMakeCurrent failed to release GL context before we call "
|
"glXMakeCurrent failed to release GL context before we call "
|
||||||
"glXDestroyContext!");
|
"glXDestroyContext!");
|
||||||
|
@ -1242,7 +1243,7 @@ GLContextGLX::FindFBConfigForWindow(Display* display, int screen, Window window,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (int i = 0; i < numConfigs; i++) {
|
for (int i = 0; i < numConfigs; i++) {
|
||||||
int visid = None;
|
int visid = X11None;
|
||||||
sGLXLibrary.xGetFBConfigAttrib(display, cfgs[i], LOCAL_GLX_VISUAL_ID, &visid);
|
sGLXLibrary.xGetFBConfigAttrib(display, cfgs[i], LOCAL_GLX_VISUAL_ID, &visid);
|
||||||
if (!visid) {
|
if (!visid) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <X11/extensions/Xrender.h> // for XRenderPictFormat, etc
|
#include <X11/extensions/Xrender.h> // for XRenderPictFormat, etc
|
||||||
#include <X11/extensions/render.h> // for PictFormat
|
#include <X11/extensions/render.h> // for PictFormat
|
||||||
#include "cairo-xlib.h"
|
#include "cairo-xlib.h"
|
||||||
|
#include "X11UndefineNone.h"
|
||||||
#include <stdint.h> // for uint32_t
|
#include <stdint.h> // for uint32_t
|
||||||
#include "GLDefs.h" // for GLenum
|
#include "GLDefs.h" // for GLenum
|
||||||
#include "gfxPlatform.h" // for gfxPlatform
|
#include "gfxPlatform.h" // for gfxPlatform
|
||||||
|
@ -65,7 +66,7 @@ SurfaceDescriptorX11::SurfaceDescriptorX11(gfxXlibSurface* aSurf,
|
||||||
bool aForwardGLX)
|
bool aForwardGLX)
|
||||||
: mId(aSurf->XDrawable())
|
: mId(aSurf->XDrawable())
|
||||||
, mSize(aSurf->GetSize())
|
, mSize(aSurf->GetSize())
|
||||||
, mGLXPixmap(None)
|
, mGLXPixmap(X11None)
|
||||||
{
|
{
|
||||||
const XRenderPictFormat *pictFormat = aSurf->XRenderFormat();
|
const XRenderPictFormat *pictFormat = aSurf->XRenderFormat();
|
||||||
if (pictFormat) {
|
if (pictFormat) {
|
||||||
|
@ -86,7 +87,7 @@ SurfaceDescriptorX11::SurfaceDescriptorX11(Drawable aDrawable, XID aFormatID,
|
||||||
: mId(aDrawable)
|
: mId(aDrawable)
|
||||||
, mFormat(aFormatID)
|
, mFormat(aFormatID)
|
||||||
, mSize(aSize)
|
, mSize(aSize)
|
||||||
, mGLXPixmap(None)
|
, mGLXPixmap(X11None)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
already_AddRefed<gfxXlibSurface>
|
already_AddRefed<gfxXlibSurface>
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
#ifndef MOZILLA_GFX_X11UNDEFINENONE_H_
|
||||||
|
#define MOZILLA_GFX_X11UNDEFINENONE_H_
|
||||||
|
|
||||||
|
// The header <X11/X.h> defines "None" as a macro that expands to "0L".
|
||||||
|
// This is terrible because many enumerations have an enumerator named "None".
|
||||||
|
// To work around this, we undefine the macro "None", and define a replacement
|
||||||
|
// macro named "X11None".
|
||||||
|
// Include this header after including X11 headers, where necessary.
|
||||||
|
#ifdef None
|
||||||
|
# undef None
|
||||||
|
# define X11None 0L
|
||||||
|
// <X11/X.h> also defines "RevertToNone" as a macro that expands to "(int)None".
|
||||||
|
// Since we are undefining "None", that stops working. To keep it working,
|
||||||
|
// we undefine "RevertToNone" and redefine it in terms of "X11None".
|
||||||
|
# ifdef RevertToNone
|
||||||
|
# undef RevertToNone
|
||||||
|
# define RevertToNone (int)X11None
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* MOZILLA_GFX_X11UNDEFINENONE_H_ */
|
|
@ -29,7 +29,7 @@ FindVisualAndDepth(Display* aDisplay, VisualID aVisualID,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_ASSERTION(aVisualID == None, "VisualID not on Screen.");
|
NS_ASSERTION(aVisualID == X11None, "VisualID not on Screen.");
|
||||||
*aVisual = nullptr;
|
*aVisual = nullptr;
|
||||||
*aDepth = 0;
|
*aDepth = 0;
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#if defined(MOZ_WIDGET_GTK)
|
#if defined(MOZ_WIDGET_GTK)
|
||||||
# include <gdk/gdk.h>
|
# include <gdk/gdk.h>
|
||||||
# include <gdk/gdkx.h>
|
# include <gdk/gdkx.h>
|
||||||
|
# include "X11UndefineNone.h"
|
||||||
#else
|
#else
|
||||||
# error Unknown toolkit
|
# error Unknown toolkit
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -39,6 +39,7 @@ EXPORTS += [
|
||||||
'nsTransform2D.h',
|
'nsTransform2D.h',
|
||||||
'PingPongRegion.h',
|
'PingPongRegion.h',
|
||||||
'RegionBuilder.h',
|
'RegionBuilder.h',
|
||||||
|
'X11UndefineNone.h'
|
||||||
]
|
]
|
||||||
|
|
||||||
EXPORTS.mozilla += [
|
EXPORTS.mozilla += [
|
||||||
|
|
|
@ -25,7 +25,7 @@ using namespace mozilla::gfx;
|
||||||
gfxXlibSurface::gfxXlibSurface(Display *dpy, Drawable drawable, Visual *visual)
|
gfxXlibSurface::gfxXlibSurface(Display *dpy, Drawable drawable, Visual *visual)
|
||||||
: mPixmapTaken(false), mDisplay(dpy), mDrawable(drawable)
|
: mPixmapTaken(false), mDisplay(dpy), mDrawable(drawable)
|
||||||
#if defined(GL_PROVIDER_GLX)
|
#if defined(GL_PROVIDER_GLX)
|
||||||
, mGLXPixmap(None)
|
, mGLXPixmap(X11None)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
const gfx::IntSize size = DoSizeQuery();
|
const gfx::IntSize size = DoSizeQuery();
|
||||||
|
@ -36,7 +36,7 @@ gfxXlibSurface::gfxXlibSurface(Display *dpy, Drawable drawable, Visual *visual)
|
||||||
gfxXlibSurface::gfxXlibSurface(Display *dpy, Drawable drawable, Visual *visual, const gfx::IntSize& size)
|
gfxXlibSurface::gfxXlibSurface(Display *dpy, Drawable drawable, Visual *visual, const gfx::IntSize& size)
|
||||||
: mPixmapTaken(false), mDisplay(dpy), mDrawable(drawable)
|
: mPixmapTaken(false), mDisplay(dpy), mDrawable(drawable)
|
||||||
#if defined(GL_PROVIDER_GLX)
|
#if defined(GL_PROVIDER_GLX)
|
||||||
, mGLXPixmap(None)
|
, mGLXPixmap(X11None)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
NS_ASSERTION(Factory::CheckSurfaceSize(size, XLIB_IMAGE_SIDE_SIZE_LIMIT),
|
NS_ASSERTION(Factory::CheckSurfaceSize(size, XLIB_IMAGE_SIDE_SIZE_LIMIT),
|
||||||
|
@ -51,7 +51,7 @@ gfxXlibSurface::gfxXlibSurface(Screen *screen, Drawable drawable, XRenderPictFor
|
||||||
: mPixmapTaken(false), mDisplay(DisplayOfScreen(screen)),
|
: mPixmapTaken(false), mDisplay(DisplayOfScreen(screen)),
|
||||||
mDrawable(drawable)
|
mDrawable(drawable)
|
||||||
#if defined(GL_PROVIDER_GLX)
|
#if defined(GL_PROVIDER_GLX)
|
||||||
, mGLXPixmap(None)
|
, mGLXPixmap(X11None)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
NS_ASSERTION(Factory::CheckSurfaceSize(size, XLIB_IMAGE_SIDE_SIZE_LIMIT),
|
NS_ASSERTION(Factory::CheckSurfaceSize(size, XLIB_IMAGE_SIDE_SIZE_LIMIT),
|
||||||
|
@ -67,7 +67,7 @@ gfxXlibSurface::gfxXlibSurface(Screen *screen, Drawable drawable, XRenderPictFor
|
||||||
gfxXlibSurface::gfxXlibSurface(cairo_surface_t *csurf)
|
gfxXlibSurface::gfxXlibSurface(cairo_surface_t *csurf)
|
||||||
: mPixmapTaken(false)
|
: mPixmapTaken(false)
|
||||||
#if defined(GL_PROVIDER_GLX)
|
#if defined(GL_PROVIDER_GLX)
|
||||||
, mGLXPixmap(None)
|
, mGLXPixmap(X11None)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
NS_PRECONDITION(cairo_surface_status(csurf) == 0,
|
NS_PRECONDITION(cairo_surface_status(csurf) == 0,
|
||||||
|
@ -97,9 +97,9 @@ CreatePixmap(Screen *screen, const gfx::IntSize& size, unsigned int depth,
|
||||||
Drawable relatedDrawable)
|
Drawable relatedDrawable)
|
||||||
{
|
{
|
||||||
if (!Factory::CheckSurfaceSize(size, XLIB_IMAGE_SIDE_SIZE_LIMIT))
|
if (!Factory::CheckSurfaceSize(size, XLIB_IMAGE_SIDE_SIZE_LIMIT))
|
||||||
return None;
|
return X11None;
|
||||||
|
|
||||||
if (relatedDrawable == None) {
|
if (relatedDrawable == X11None) {
|
||||||
relatedDrawable = RootWindowOfScreen(screen);
|
relatedDrawable = RootWindowOfScreen(screen);
|
||||||
}
|
}
|
||||||
Display *dpy = DisplayOfScreen(screen);
|
Display *dpy = DisplayOfScreen(screen);
|
||||||
|
@ -274,7 +274,7 @@ gfxXlibSurface::Finish()
|
||||||
#if defined(GL_PROVIDER_GLX)
|
#if defined(GL_PROVIDER_GLX)
|
||||||
if (mPixmapTaken && mGLXPixmap) {
|
if (mPixmapTaken && mGLXPixmap) {
|
||||||
gl::sGLXLibrary.DestroyPixmap(mDisplay, mGLXPixmap);
|
gl::sGLXLibrary.DestroyPixmap(mDisplay, mGLXPixmap);
|
||||||
mGLXPixmap = None;
|
mGLXPixmap = X11None;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
gfxASurface::Finish();
|
gfxASurface::Finish();
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include <X11/extensions/Xrender.h>
|
#include <X11/extensions/Xrender.h>
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
|
#include "X11UndefineNone.h"
|
||||||
|
|
||||||
#if defined(GL_PROVIDER_GLX)
|
#if defined(GL_PROVIDER_GLX)
|
||||||
#include "GLXLibrary.h"
|
#include "GLXLibrary.h"
|
||||||
|
@ -46,13 +47,13 @@ public:
|
||||||
// |screen| (if specified).
|
// |screen| (if specified).
|
||||||
static already_AddRefed<gfxXlibSurface>
|
static already_AddRefed<gfxXlibSurface>
|
||||||
Create(Screen *screen, Visual *visual, const mozilla::gfx::IntSize& size,
|
Create(Screen *screen, Visual *visual, const mozilla::gfx::IntSize& size,
|
||||||
Drawable relatedDrawable = None);
|
Drawable relatedDrawable = X11None);
|
||||||
static cairo_surface_t *
|
static cairo_surface_t *
|
||||||
CreateCairoSurface(Screen *screen, Visual *visual, const mozilla::gfx::IntSize& size,
|
CreateCairoSurface(Screen *screen, Visual *visual, const mozilla::gfx::IntSize& size,
|
||||||
Drawable relatedDrawable = None);
|
Drawable relatedDrawable = X11None);
|
||||||
static already_AddRefed<gfxXlibSurface>
|
static already_AddRefed<gfxXlibSurface>
|
||||||
Create(Screen* screen, XRenderPictFormat *format, const mozilla::gfx::IntSize& size,
|
Create(Screen* screen, XRenderPictFormat *format, const mozilla::gfx::IntSize& size,
|
||||||
Drawable relatedDrawable = None);
|
Drawable relatedDrawable = X11None);
|
||||||
|
|
||||||
virtual ~gfxXlibSurface();
|
virtual ~gfxXlibSurface();
|
||||||
|
|
||||||
|
|
|
@ -482,7 +482,9 @@ void
|
||||||
ServoStyleSet::StyleNewSubtree(nsIContent* aContent)
|
ServoStyleSet::StyleNewSubtree(nsIContent* aContent)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aContent->IsDirtyForServo());
|
MOZ_ASSERT(aContent->IsDirtyForServo());
|
||||||
Servo_RestyleSubtree(aContent, mRawSet.get());
|
if (aContent->IsElement() || aContent->IsNodeOfType(nsINode::eTEXT)) {
|
||||||
|
Servo_RestyleSubtree(aContent, mRawSet.get());
|
||||||
|
}
|
||||||
ClearDirtyBits(aContent);
|
ClearDirtyBits(aContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -763,7 +763,7 @@ class IceTestPeer : public sigslot::has_slots<> {
|
||||||
remote->GetCandidates(i);
|
remote->GetCandidates(i);
|
||||||
|
|
||||||
for (size_t j=0; j<candidates.size(); ++j) {
|
for (size_t j=0; j<candidates.size(); ++j) {
|
||||||
std::cerr << name_ << " Candidate: " + candidates[j] << std::endl;
|
std::cerr << name_ << " Adding remote candidate: " + candidates[j] << std::endl;
|
||||||
}
|
}
|
||||||
res = aStream->ParseAttributes(candidates);
|
res = aStream->ParseAttributes(candidates);
|
||||||
ASSERT_TRUE(NS_SUCCEEDED(res));
|
ASSERT_TRUE(NS_SUCCEEDED(res));
|
||||||
|
|
|
@ -181,7 +181,8 @@ int nr_ice_candidate_pair_unfreeze(nr_ice_peer_ctx *pctx, nr_ice_cand_pair *pair
|
||||||
static void nr_ice_candidate_pair_stun_cb(NR_SOCKET s, int how, void *cb_arg)
|
static void nr_ice_candidate_pair_stun_cb(NR_SOCKET s, int how, void *cb_arg)
|
||||||
{
|
{
|
||||||
int r,_status;
|
int r,_status;
|
||||||
nr_ice_cand_pair *pair=cb_arg,*orig_pair;
|
nr_ice_cand_pair *pair=cb_arg;
|
||||||
|
nr_ice_cand_pair *actual_pair=0;
|
||||||
nr_ice_candidate *cand=0;
|
nr_ice_candidate *cand=0;
|
||||||
nr_stun_message *sres;
|
nr_stun_message *sres;
|
||||||
nr_transport_addr *request_src;
|
nr_transport_addr *request_src;
|
||||||
|
@ -256,14 +257,17 @@ static void nr_ice_candidate_pair_stun_cb(NR_SOCKET s, int how, void *cb_arg)
|
||||||
|
|
||||||
cand=TAILQ_FIRST(&pair->local->component->candidates);
|
cand=TAILQ_FIRST(&pair->local->component->candidates);
|
||||||
while(cand){
|
while(cand){
|
||||||
if(!nr_transport_addr_cmp(&cand->addr,&pair->stun_client->results.ice_binding_response.mapped_addr,NR_TRANSPORT_ADDR_CMP_MODE_ALL))
|
if(!nr_transport_addr_cmp(&cand->addr,&pair->stun_client->results.ice_binding_response.mapped_addr,NR_TRANSPORT_ADDR_CMP_MODE_ALL)) {
|
||||||
|
r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s): found pre-existing local candidate of type %d for mapped address %s", pair->pctx->label,cand->type,cand->addr.as_string);
|
||||||
|
assert(cand->type != HOST);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
cand=TAILQ_NEXT(cand,entry_comp);
|
cand=TAILQ_NEXT(cand,entry_comp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* OK, nothing found, must be peer reflexive */
|
|
||||||
if(!cand) {
|
if(!cand) {
|
||||||
|
/* OK, nothing found, must be a new peer reflexive */
|
||||||
if (pair->pctx->ctx->flags & NR_ICE_CTX_FLAGS_RELAY_ONLY) {
|
if (pair->pctx->ctx->flags & NR_ICE_CTX_FLAGS_RELAY_ONLY) {
|
||||||
/* Any STUN response with a reflexive address in it is unwanted
|
/* Any STUN response with a reflexive address in it is unwanted
|
||||||
when we'll send on relay only. Bail since cand is used below. */
|
when we'll send on relay only. Bail since cand is used below. */
|
||||||
|
@ -277,27 +281,31 @@ static void nr_ice_candidate_pair_stun_cb(NR_SOCKET s, int how, void *cb_arg)
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
cand->state=NR_ICE_CAND_STATE_INITIALIZED;
|
cand->state=NR_ICE_CAND_STATE_INITIALIZED;
|
||||||
TAILQ_INSERT_TAIL(&pair->local->component->candidates,cand,entry_comp);
|
TAILQ_INSERT_TAIL(&pair->local->component->candidates,cand,entry_comp);
|
||||||
|
} else {
|
||||||
|
/* Check if we have a pair for this candidate already. */
|
||||||
|
if(r=nr_ice_media_stream_find_pair(pair->remote->stream, cand, pair->remote, &actual_pair)) {
|
||||||
|
r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s): no pair exists for %s and %s", pair->pctx->label,cand->addr.as_string, pair->remote->addr.as_string);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Note: we stomp the existing pair! */
|
if(!actual_pair) {
|
||||||
orig_pair=pair;
|
if(r=nr_ice_candidate_pair_create(pair->pctx,cand,pair->remote, &actual_pair))
|
||||||
if(r=nr_ice_candidate_pair_create(pair->pctx,cand,pair->remote,
|
ABORT(r);
|
||||||
&pair))
|
|
||||||
ABORT(r);
|
|
||||||
|
|
||||||
nr_ice_candidate_pair_set_state(pair->pctx,pair,NR_ICE_PAIR_STATE_SUCCEEDED);
|
if(r=nr_ice_component_insert_pair(actual_pair->remote->component,actual_pair))
|
||||||
|
ABORT(r);
|
||||||
|
|
||||||
if(r=nr_ice_component_insert_pair(pair->remote->component,pair))
|
/* If the original pair was nominated, make us nominated too. */
|
||||||
ABORT(r);
|
if(pair->peer_nominated)
|
||||||
|
actual_pair->peer_nominated=1;
|
||||||
|
|
||||||
/* If the original pair was nominated, make us nominated,
|
/* Now mark the orig pair failed */
|
||||||
since we replace him*/
|
nr_ice_candidate_pair_set_state(pair->pctx,pair,NR_ICE_PAIR_STATE_FAILED);
|
||||||
if(orig_pair->peer_nominated)
|
}
|
||||||
pair->peer_nominated=1;
|
|
||||||
|
|
||||||
|
assert(actual_pair);
|
||||||
/* Now mark the orig pair failed */
|
nr_ice_candidate_pair_set_state(actual_pair->pctx,actual_pair,NR_ICE_PAIR_STATE_SUCCEEDED);
|
||||||
nr_ice_candidate_pair_set_state(orig_pair->pctx,orig_pair,NR_ICE_PAIR_STATE_FAILED);
|
pair=actual_pair;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -913,3 +913,21 @@ void nr_ice_media_stream_role_change(nr_ice_media_stream *stream)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int nr_ice_media_stream_find_pair(nr_ice_media_stream *str, nr_ice_candidate *lcand, nr_ice_candidate *rcand, nr_ice_cand_pair **pair)
|
||||||
|
{
|
||||||
|
nr_ice_cand_pair_head *head = &str->check_list;
|
||||||
|
nr_ice_cand_pair *c1;
|
||||||
|
|
||||||
|
c1=TAILQ_FIRST(head);
|
||||||
|
while(c1){
|
||||||
|
if(c1->local == lcand &&
|
||||||
|
c1->remote == rcand) {
|
||||||
|
*pair=c1;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
c1=TAILQ_NEXT(c1,check_queue_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(R_NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
|
@ -92,6 +92,7 @@ int nr_ice_media_stream_get_best_candidate(nr_ice_media_stream *str, int compone
|
||||||
int nr_ice_media_stream_send(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, int component, UCHAR *data, int len);
|
int nr_ice_media_stream_send(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, int component, UCHAR *data, int len);
|
||||||
int nr_ice_media_stream_get_active(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, int component, nr_ice_candidate **local, nr_ice_candidate **remote);
|
int nr_ice_media_stream_get_active(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, int component, nr_ice_candidate **local, nr_ice_candidate **remote);
|
||||||
int nr_ice_media_stream_find_component(nr_ice_media_stream *str, int comp_id, nr_ice_component **compp);
|
int nr_ice_media_stream_find_component(nr_ice_media_stream *str, int comp_id, nr_ice_component **compp);
|
||||||
|
int nr_ice_media_stream_find_pair(nr_ice_media_stream *str, nr_ice_candidate *local, nr_ice_candidate *remote, nr_ice_cand_pair **pair);
|
||||||
int nr_ice_media_stream_addrs(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, int component, nr_transport_addr *local, nr_transport_addr *remote);
|
int nr_ice_media_stream_addrs(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, int component, nr_transport_addr *local, nr_transport_addr *remote);
|
||||||
int
|
int
|
||||||
nr_ice_peer_ctx_parse_media_stream_attribute(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream, char *attr);
|
nr_ice_peer_ctx_parse_media_stream_attribute(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream, char *attr);
|
||||||
|
|
|
@ -12,7 +12,6 @@ import org.mozilla.gecko.util.GeckoEventListener;
|
||||||
import org.mozilla.gecko.util.JSONUtils;
|
import org.mozilla.gecko.util.JSONUtils;
|
||||||
import org.mozilla.gecko.util.NativeEventListener;
|
import org.mozilla.gecko.util.NativeEventListener;
|
||||||
import org.mozilla.gecko.util.NativeJSObject;
|
import org.mozilla.gecko.util.NativeJSObject;
|
||||||
import org.mozilla.gecko.util.WebActivityMapper;
|
|
||||||
import org.mozilla.gecko.widget.ExternalIntentDuringPrivateBrowsingPromptFragment;
|
import org.mozilla.gecko.widget.ExternalIntentDuringPrivateBrowsingPromptFragment;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
|
@ -48,7 +47,6 @@ public final class IntentHelper implements GeckoEventListener,
|
||||||
"Intent:GetHandlers",
|
"Intent:GetHandlers",
|
||||||
"Intent:Open",
|
"Intent:Open",
|
||||||
"Intent:OpenForResult",
|
"Intent:OpenForResult",
|
||||||
"WebActivity:Open"
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final String[] NATIVE_EVENTS = {
|
private static final String[] NATIVE_EVENTS = {
|
||||||
|
@ -416,8 +414,6 @@ public final class IntentHelper implements GeckoEventListener,
|
||||||
open(message);
|
open(message);
|
||||||
} else if (event.equals("Intent:OpenForResult")) {
|
} else if (event.equals("Intent:OpenForResult")) {
|
||||||
openForResult(message);
|
openForResult(message);
|
||||||
} else if (event.equals("WebActivity:Open")) {
|
|
||||||
openWebActivity(message);
|
|
||||||
}
|
}
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
Log.e(LOGTAG, "Exception handling message \"" + event + "\":", e);
|
Log.e(LOGTAG, "Exception handling message \"" + event + "\":", e);
|
||||||
|
@ -572,11 +568,6 @@ public final class IntentHelper implements GeckoEventListener,
|
||||||
return UNKNOWN_PROTOCOL_URI_PREFIX + encodedUri;
|
return UNKNOWN_PROTOCOL_URI_PREFIX + encodedUri;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void openWebActivity(JSONObject message) throws JSONException {
|
|
||||||
final Intent intent = WebActivityMapper.getIntentForWebActivity(message.getJSONObject("activity"));
|
|
||||||
ActivityHandlerHelper.startIntentForActivity(activity, intent, new ResultHandler(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class ResultHandler implements ActivityResultHandler {
|
private static class ResultHandler implements ActivityResultHandler {
|
||||||
private final JSONObject message;
|
private final JSONObject message;
|
||||||
|
|
||||||
|
|
|
@ -139,7 +139,6 @@ gujar.sources += [geckoview_source_dir + 'java/org/mozilla/gecko/' + x for x in
|
||||||
'util/UIAsyncTask.java',
|
'util/UIAsyncTask.java',
|
||||||
'util/UUIDUtil.java',
|
'util/UUIDUtil.java',
|
||||||
'util/WeakReferenceHandler.java',
|
'util/WeakReferenceHandler.java',
|
||||||
'util/WebActivityMapper.java',
|
|
||||||
'util/WindowUtils.java',
|
'util/WindowUtils.java',
|
||||||
]]
|
]]
|
||||||
gujar.extra_jars = [
|
gujar.extra_jars = [
|
||||||
|
|
|
@ -57,10 +57,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "LoginManagerParent",
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "Task", "resource://gre/modules/Task.jsm");
|
XPCOMUtils.defineLazyModuleGetter(this, "Task", "resource://gre/modules/Task.jsm");
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm");
|
XPCOMUtils.defineLazyModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm");
|
||||||
|
|
||||||
if (AppConstants.MOZ_SAFE_BROWSING) {
|
XPCOMUtils.defineLazyModuleGetter(this, "SafeBrowsing",
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "SafeBrowsing",
|
"resource://gre/modules/SafeBrowsing.jsm");
|
||||||
"resource://gre/modules/SafeBrowsing.jsm");
|
|
||||||
}
|
|
||||||
|
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "BrowserUtils",
|
XPCOMUtils.defineLazyModuleGetter(this, "BrowserUtils",
|
||||||
"resource://gre/modules/BrowserUtils.jsm");
|
"resource://gre/modules/BrowserUtils.jsm");
|
||||||
|
@ -549,10 +547,8 @@ var BrowserApp = {
|
||||||
InitLater(() => Services.search.init(), Services, "search");
|
InitLater(() => Services.search.init(), Services, "search");
|
||||||
InitLater(() => DownloadNotifications.init(), window, "DownloadNotifications");
|
InitLater(() => DownloadNotifications.init(), window, "DownloadNotifications");
|
||||||
|
|
||||||
if (AppConstants.MOZ_SAFE_BROWSING) {
|
// Bug 778855 - Perf regression if we do this here. To be addressed in bug 779008.
|
||||||
// Bug 778855 - Perf regression if we do this here. To be addressed in bug 779008.
|
InitLater(() => SafeBrowsing.init(), window, "SafeBrowsing");
|
||||||
InitLater(() => SafeBrowsing.init(), window, "SafeBrowsing");
|
|
||||||
}
|
|
||||||
|
|
||||||
InitLater(() => Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager));
|
InitLater(() => Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager));
|
||||||
InitLater(() => LoginManagerParent.init(), window, "LoginManagerParent");
|
InitLater(() => LoginManagerParent.init(), window, "LoginManagerParent");
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
/* 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/. */
|
|
||||||
|
|
||||||
"use strict"
|
|
||||||
|
|
||||||
const Cc = Components.classes;
|
|
||||||
const Ci = Components.interfaces;
|
|
||||||
const Cu = Components.utils;
|
|
||||||
|
|
||||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
|
||||||
Cu.import("resource://gre/modules/Messaging.jsm");
|
|
||||||
|
|
||||||
function ActivitiesGlue() { }
|
|
||||||
|
|
||||||
ActivitiesGlue.prototype = {
|
|
||||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIActivityUIGlue]),
|
|
||||||
classID: Components.ID("{e4deb5f6-d5e3-4fce-bc53-901dd9951c48}"),
|
|
||||||
|
|
||||||
// Ignore aActivities results on Android, go straight to Android intents.
|
|
||||||
chooseActivity: function ap_chooseActivity(aOptions, aActivities, aCallback) {
|
|
||||||
Messaging.sendRequestForResult({
|
|
||||||
type: "WebActivity:Open",
|
|
||||||
activity: { name: aOptions.name, data: aOptions.data }
|
|
||||||
}).then((result) => {
|
|
||||||
aCallback.handleEvent(Ci.nsIActivityUIGlueCallback.NATIVE_ACTIVITY, result);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ActivitiesGlue]);
|
|
|
@ -105,18 +105,23 @@ LoginManagerPrompter.prototype = {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
init : function (aWindow, aFactory) {
|
init : function (aWindow, aFactory) {
|
||||||
this._window = aWindow;
|
this._chromeWindow = this._getChromeWindow(aWindow).wrappedJSObject;
|
||||||
this._factory = aFactory || null;
|
this._factory = aFactory || null;
|
||||||
|
this._browser = null;
|
||||||
|
|
||||||
var prefBranch = Services.prefs.getBranch("signon.");
|
var prefBranch = Services.prefs.getBranch("signon.");
|
||||||
this._debug = prefBranch.getBoolPref("debug");
|
this._debug = prefBranch.getBoolPref("debug");
|
||||||
this.log("===== initialized =====");
|
this.log("===== initialized =====");
|
||||||
},
|
},
|
||||||
|
|
||||||
setE10sData : function (aBrowser, aOpener) {
|
set browser(aBrowser) {
|
||||||
throw new Error("This should be filled in when Android is multiprocess");
|
this._browser = aBrowser;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// setting this attribute is ignored because Android does not consider
|
||||||
|
// opener windows when displaying login notifications
|
||||||
|
set opener(aOpener) { },
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* promptToSavePassword
|
* promptToSavePassword
|
||||||
*
|
*
|
||||||
|
@ -140,10 +145,7 @@ LoginManagerPrompter.prototype = {
|
||||||
* Password string used in creating a doorhanger action
|
* Password string used in creating a doorhanger action
|
||||||
*/
|
*/
|
||||||
_showLoginNotification : function (aBody, aButtons, aUsername, aPassword) {
|
_showLoginNotification : function (aBody, aButtons, aUsername, aPassword) {
|
||||||
let notifyWin = this._window.top;
|
let tabID = this._chromeWindow.BrowserApp.getTabForBrowser(this._browser).id;
|
||||||
let chromeWin = this._getChromeWindow(notifyWin).wrappedJSObject;
|
|
||||||
let browser = chromeWin.BrowserApp.getBrowserForWindow(notifyWin);
|
|
||||||
let tabID = chromeWin.BrowserApp.getTabForBrowser(browser).id;
|
|
||||||
|
|
||||||
let actionText = {
|
let actionText = {
|
||||||
text: aUsername,
|
text: aUsername,
|
||||||
|
@ -334,6 +336,8 @@ LoginManagerPrompter.prototype = {
|
||||||
* Given a content DOM window, returns the chrome window it's in.
|
* Given a content DOM window, returns the chrome window it's in.
|
||||||
*/
|
*/
|
||||||
_getChromeWindow: function (aWindow) {
|
_getChromeWindow: function (aWindow) {
|
||||||
|
if (aWindow instanceof Ci.nsIDOMChromeWindow)
|
||||||
|
return aWindow;
|
||||||
var chromeWin = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
var chromeWin = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||||
.getInterface(Ci.nsIWebNavigation)
|
.getInterface(Ci.nsIWebNavigation)
|
||||||
.QueryInterface(Ci.nsIDocShell)
|
.QueryInterface(Ci.nsIDocShell)
|
||||||
|
@ -350,8 +354,7 @@ LoginManagerPrompter.prototype = {
|
||||||
_getNativeWindow : function () {
|
_getNativeWindow : function () {
|
||||||
let nativeWindow = null;
|
let nativeWindow = null;
|
||||||
try {
|
try {
|
||||||
let notifyWin = this._window.top;
|
let chromeWin = this._chromeWindow;
|
||||||
let chromeWin = this._getChromeWindow(notifyWin).wrappedJSObject;
|
|
||||||
if (chromeWin.NativeWindow) {
|
if (chromeWin.NativeWindow) {
|
||||||
nativeWindow = chromeWin.NativeWindow;
|
nativeWindow = chromeWin.NativeWindow;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -14,9 +14,7 @@ contract @mozilla.org/network/protocol/about;1?what=privatebrowsing {322ba47e-70
|
||||||
#ifdef MOZ_SERVICES_HEALTHREPORT
|
#ifdef MOZ_SERVICES_HEALTHREPORT
|
||||||
contract @mozilla.org/network/protocol/about;1?what=healthreport {322ba47e-7047-4f71-aebf-cb7d69325cd9}
|
contract @mozilla.org/network/protocol/about;1?what=healthreport {322ba47e-7047-4f71-aebf-cb7d69325cd9}
|
||||||
#endif
|
#endif
|
||||||
#ifdef MOZ_SAFE_BROWSING
|
|
||||||
contract @mozilla.org/network/protocol/about;1?what=blocked {322ba47e-7047-4f71-aebf-cb7d69325cd9}
|
contract @mozilla.org/network/protocol/about;1?what=blocked {322ba47e-7047-4f71-aebf-cb7d69325cd9}
|
||||||
#endif
|
|
||||||
contract @mozilla.org/network/protocol/about;1?what=accounts {322ba47e-7047-4f71-aebf-cb7d69325cd9}
|
contract @mozilla.org/network/protocol/about;1?what=accounts {322ba47e-7047-4f71-aebf-cb7d69325cd9}
|
||||||
contract @mozilla.org/network/protocol/about;1?what=logins {322ba47e-7047-4f71-aebf-cb7d69325cd9}
|
contract @mozilla.org/network/protocol/about;1?what=logins {322ba47e-7047-4f71-aebf-cb7d69325cd9}
|
||||||
|
|
||||||
|
@ -117,10 +115,6 @@ category update-timer Snippets @mozilla.org/snippets;1,getService,snippets-updat
|
||||||
component {430b987f-bb9f-46a3-99a5-241749220b29} ColorPicker.js
|
component {430b987f-bb9f-46a3-99a5-241749220b29} ColorPicker.js
|
||||||
contract @mozilla.org/colorpicker;1 {430b987f-bb9f-46a3-99a5-241749220b29}
|
contract @mozilla.org/colorpicker;1 {430b987f-bb9f-46a3-99a5-241749220b29}
|
||||||
|
|
||||||
# AndroidActivitiesGlue.js
|
|
||||||
component {e4deb5f6-d5e3-4fce-bc53-901dd9951c48} AndroidActivitiesGlue.js
|
|
||||||
contract @mozilla.org/dom/activities/ui-glue;1 {e4deb5f6-d5e3-4fce-bc53-901dd9951c48}
|
|
||||||
|
|
||||||
# PersistentNotificationHandler.js
|
# PersistentNotificationHandler.js
|
||||||
component {75390fe7-f8a3-423a-b3b1-258d7eabed40} PersistentNotificationHandler.js
|
component {75390fe7-f8a3-423a-b3b1-258d7eabed40} PersistentNotificationHandler.js
|
||||||
contract @mozilla.org/persistent-notification-handler;1 {75390fe7-f8a3-423a-b3b1-258d7eabed40}
|
contract @mozilla.org/persistent-notification-handler;1 {75390fe7-f8a3-423a-b3b1-258d7eabed40}
|
||||||
|
|
|
@ -18,7 +18,7 @@ let dataURI = "iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAC4klEQVRYhdWXLWzbQ
|
||||||
let image = atob(dataURI);
|
let image = atob(dataURI);
|
||||||
const IMAGE_ARRAYBUFFER = Uint8Array.from(image, byte => byte.charCodeAt(0)).buffer;
|
const IMAGE_ARRAYBUFFER = Uint8Array.from(image, byte => byte.charCodeAt(0)).buffer;
|
||||||
|
|
||||||
function backgroundScript() {
|
function background() {
|
||||||
browser.test.assertTrue("pageAction" in browser, "Namespace 'pageAction' exists in browser");
|
browser.test.assertTrue("pageAction" in browser, "Namespace 'pageAction' exists in browser");
|
||||||
browser.test.assertTrue("show" in browser.pageAction, "API method 'show' exists in browser.pageAction");
|
browser.test.assertTrue("show" in browser.pageAction, "API method 'show' exists in browser.pageAction");
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ function backgroundScript() {
|
||||||
|
|
||||||
add_task(function* test_contentscript() {
|
add_task(function* test_contentscript() {
|
||||||
let extension = ExtensionTestUtils.loadExtension({
|
let extension = ExtensionTestUtils.loadExtension({
|
||||||
background: "(" + backgroundScript.toString() + ")()",
|
background,
|
||||||
manifest: {
|
manifest: {
|
||||||
"name": "PageAction Extension",
|
"name": "PageAction Extension",
|
||||||
"page_action": {
|
"page_action": {
|
||||||
|
|
|
@ -21,7 +21,7 @@ let image = atob(dataURI);
|
||||||
const IMAGE_ARRAYBUFFER = Uint8Array.from(image, byte => byte.charCodeAt(0)).buffer;
|
const IMAGE_ARRAYBUFFER = Uint8Array.from(image, byte => byte.charCodeAt(0)).buffer;
|
||||||
|
|
||||||
add_task(function* test_contentscript() {
|
add_task(function* test_contentscript() {
|
||||||
function backgroundScript() {
|
function background() {
|
||||||
// TODO: Use the Tabs API to obtain the tab ids for showing pageActions.
|
// TODO: Use the Tabs API to obtain the tab ids for showing pageActions.
|
||||||
let tabId = 1;
|
let tabId = 1;
|
||||||
let onClickedListenerEnabled = false;
|
let onClickedListenerEnabled = false;
|
||||||
|
@ -71,7 +71,7 @@ add_task(function* test_contentscript() {
|
||||||
}
|
}
|
||||||
|
|
||||||
let extension = ExtensionTestUtils.loadExtension({
|
let extension = ExtensionTestUtils.loadExtension({
|
||||||
background: `(${backgroundScript}())`,
|
background,
|
||||||
manifest: {
|
manifest: {
|
||||||
"name": "PageAction Extension",
|
"name": "PageAction Extension",
|
||||||
"page_action": {
|
"page_action": {
|
||||||
|
@ -83,11 +83,11 @@ add_task(function* test_contentscript() {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
files: {
|
files: {
|
||||||
"default.html": `<html><head><meta charset="utf-8"><script src="popup.js"></${"script"}></head></html>`,
|
"default.html": `<html><head><meta charset="utf-8"><script src="popup.js"><\/script></head></html>`,
|
||||||
"extension.png": IMAGE_ARRAYBUFFER,
|
"extension.png": IMAGE_ARRAYBUFFER,
|
||||||
"a.html": `<html><head><meta charset="utf-8"><script src="popup.js"></${"script"}></head></html>`,
|
"a.html": `<html><head><meta charset="utf-8"><script src="popup.js"><\/script></head></html>`,
|
||||||
"b.html": `<html><head><meta charset="utf-8"><script src="popup.js"></${"script"}></head></html>`,
|
"b.html": `<html><head><meta charset="utf-8"><script src="popup.js"><\/script></head></html>`,
|
||||||
"popup.js": `(${popupScript})()`,
|
"popup.js": popupScript,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,6 @@ XPIDL_MODULE = 'MobileComponents'
|
||||||
EXTRA_COMPONENTS += [
|
EXTRA_COMPONENTS += [
|
||||||
'AboutRedirector.js',
|
'AboutRedirector.js',
|
||||||
'AddonUpdateService.js',
|
'AddonUpdateService.js',
|
||||||
'AndroidActivitiesGlue.js',
|
|
||||||
'BlocklistPrompt.js',
|
'BlocklistPrompt.js',
|
||||||
'BrowserCLH.js',
|
'BrowserCLH.js',
|
||||||
'ColorPicker.js',
|
'ColorPicker.js',
|
||||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче