Merge m-c to f-t

This commit is contained in:
Phil Ringnalda 2015-01-31 09:15:02 -08:00
commit 1411df5edb
251 changed files with 5439 additions and 3291 deletions

View File

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Bug 1109248 - This needed a CLOBBER on Windows and OSX.
Bug 870366 - Blacklisting PREF_JS_EXPORTS in Makefile.ins (because of 852814)

View File

@ -15,6 +15,9 @@ namespace a11y {
bool
DocAccessibleParent::RecvShowEvent(const ShowEventData& aData)
{
if (mShutdown)
return true;
if (aData.NewTree().IsEmpty()) {
NS_ERROR("no children being added");
return false;
@ -95,6 +98,9 @@ DocAccessibleParent::AddSubtree(ProxyAccessible* aParent,
bool
DocAccessibleParent::RecvHideEvent(const uint64_t& aRootID)
{
if (mShutdown)
return true;
ProxyEntry* rootEntry = mAccessibles.GetEntry(aRootID);
if (!rootEntry) {
NS_ERROR("invalid root being removed!");
@ -151,17 +157,21 @@ PLDHashOperator
DocAccessibleParent::ShutdownAccessibles(ProxyEntry* entry, void*)
{
ProxyDestroyed(entry->mProxy);
return PL_DHASH_NEXT;
return PL_DHASH_REMOVE;
}
void
DocAccessibleParent::Destroy()
{
MOZ_ASSERT(mChildDocs.IsEmpty(),
"why weren't the child docs destroyed already?");
NS_ASSERTION(mChildDocs.IsEmpty(),
"why weren't the child docs destroyed already?");
MOZ_ASSERT(!mShutdown);
mShutdown = true;
uint32_t childDocCount = mChildDocs.Length();
for (uint32_t i = childDocCount - 1; i < childDocCount; i--)
mChildDocs[i]->Destroy();
mAccessibles.EnumerateEntries(ShutdownAccessibles, nullptr);
ProxyDestroyed(this);
mParentDoc ? mParentDoc->RemoveChildDoc(this)

View File

@ -15,7 +15,7 @@ namespace a11y {
void
ProxyAccessible::Shutdown()
{
MOZ_ASSERT(!mOuterDoc);
NS_ASSERTION(!mOuterDoc, "Why do we still have a child doc?");
// XXX Ideally this wouldn't be necessary, but it seems OuterDoc accessibles
// can be destroyed before the doc they own.

View File

@ -5,8 +5,6 @@
USE_RCS_MK := 1
include $(topsrcdir)/config/makefiles/rcs.mk
PREF_JS_EXPORTS = $(srcdir)/b2g.js
UA_UPDATE_FILE = ua-update.json
$(UA_UPDATE_FILE): % : %.in

View File

@ -76,3 +76,8 @@ if CONFIG['OS_ARCH'] == 'WINNT':
]
FAIL_ON_WARNINGS = True
JS_PREFERENCE_FILES += [
'b2g.js',
]

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e06971db7acf7a35c32eb74d675a4e12e288e6be">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="45475198737a504d81932a9c90002902054fce23"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ab69ae06a7f2b54e60ab63b1b44c8d19d5d20d94"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="45475198737a504d81932a9c90002902054fce23"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="ab69ae06a7f2b54e60ab63b1b44c8d19d5d20d94"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="eb1795a9002eb142ac58c8d68f8f4ba094af07ca"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="45475198737a504d81932a9c90002902054fce23"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ab69ae06a7f2b54e60ab63b1b44c8d19d5d20d94"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="5d482e320548e7ef0a44f62fd7ad51778cca4b3a"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e06971db7acf7a35c32eb74d675a4e12e288e6be">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="45475198737a504d81932a9c90002902054fce23"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ab69ae06a7f2b54e60ab63b1b44c8d19d5d20d94"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="45475198737a504d81932a9c90002902054fce23"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="ab69ae06a7f2b54e60ab63b1b44c8d19d5d20d94"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="eb1795a9002eb142ac58c8d68f8f4ba094af07ca"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e06971db7acf7a35c32eb74d675a4e12e288e6be">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="45475198737a504d81932a9c90002902054fce23"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ab69ae06a7f2b54e60ab63b1b44c8d19d5d20d94"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="45475198737a504d81932a9c90002902054fce23"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ab69ae06a7f2b54e60ab63b1b44c8d19d5d20d94"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="5d482e320548e7ef0a44f62fd7ad51778cca4b3a"/>

View File

@ -1,9 +1,9 @@
{
"git": {
"git_revision": "45475198737a504d81932a9c90002902054fce23",
"git_revision": "ab69ae06a7f2b54e60ab63b1b44c8d19d5d20d94",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
"revision": "419454c1e3ab5e54dec3745e21e7352eeb24accf",
"revision": "3dc35073ce80056af02c7869ad97079e6f612714",
"repo_path": "integration/gaia-central"
}

View File

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="45475198737a504d81932a9c90002902054fce23"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="ab69ae06a7f2b54e60ab63b1b44c8d19d5d20d94"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>

View File

@ -15,7 +15,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="45475198737a504d81932a9c90002902054fce23"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="b33a1afb538e8c7e12f6fb792c454da34f9f5b76"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="45475198737a504d81932a9c90002902054fce23"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ab69ae06a7f2b54e60ab63b1b44c8d19d5d20d94"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="5d482e320548e7ef0a44f62fd7ad51778cca4b3a"/>

View File

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="45475198737a504d81932a9c90002902054fce23"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="b33a1afb538e8c7e12f6fb792c454da34f9f5b76"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -1,5 +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/.
PREF_JS_EXPORTS += $(topsrcdir)/b2g/app/b2g.js

View File

@ -4,3 +4,8 @@
DIST_SUBDIR = 'browser'
export('DIST_SUBDIR')
JS_PREFERENCE_FILES += [
'/b2g/app/b2g.js',
]

View File

@ -25,7 +25,10 @@ RETRIEVE_WINDOWS_INSTALLER = 1
MOZ_LANGPACK_EID=langpack-$(AB_CD)@b2g.mozilla.org
PREF_JS_EXPORTS = $(call MERGE_FILE,b2g-l10n.js)
L10N_PREF_JS_EXPORTS = $(call MERGE_FILE,b2g-l10n.js)
L10N_PREF_JS_EXPORTS_PATH = $(FINAL_TARGET)/$(PREF_DIR)
L10N_PREF_JS_EXPORTS_FLAGS = $(PREF_PPFLAGS) --silence-missing-directive-warnings
PP_TARGETS += L10N_PREF_JS_EXPORTS
ifneq (,$(filter cocoa,$(MOZ_WIDGET_TOOLKIT)))
MOZ_PKG_MAC_DSSTORE=$(_ABS_DIST)/branding/dsstore

View File

@ -4,9 +4,6 @@
dist_dest = $(DIST)/$(MOZ_MACBUNDLE_NAME)
PREF_JS_EXPORTS = $(srcdir)/profile/firefox.js \
$(NULL)
# hardcode en-US for the moment
AB_CD = en-US
@ -18,10 +15,6 @@ DEFINES += \
-DPBMODE_ICO='"$(DIST)/branding/pbmode.ico"' \
$(NULL)
ifdef LIBXUL_SDK #{
PREF_JS_EXPORTS += $(srcdir)/profile/channel-prefs.js
endif #} LIBXUL_SDK
# Build a binary bootstrapping with XRE_main
ifndef MOZ_WINCONSOLE

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1421170069000">
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1422484744000">
<emItems>
<emItem blockID="i58" id="webmaster@buzzzzvideos.info">
<versionRange minVersion="0" maxVersion="*">
@ -953,6 +953,12 @@
</versionRange>
<prefs>
</prefs>
</emItem>
<emItem blockID="i822" id="{6af08a71-380e-42dd-9312-0111d2bc0630}">
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
<prefs>
</prefs>
</emItem>
<emItem blockID="i490" id="now.msn.com@services.mozilla.org">
<versionRange minVersion="0" maxVersion="*" severity="3">
@ -2792,6 +2798,18 @@
<match name="filename" exp="(NPSWF32.*\.dll)|(Flash\ Player\.plugin)" /> <versionRange minVersion="14.0" maxVersion="15.0.0.242" severity="0" vulnerabilitystatus="1"></versionRange>
<infoURL>https://get.adobe.com/flashplayer/</infoURL>
</pluginItem>
<pluginItem blockID="p824">
<match name="filename" exp="(NPSWF32.*\.dll)|(Flash\ Player\.plugin)" /> <versionRange minVersion="13.0.0.259" maxVersion="13.0.0.263" severity="0" vulnerabilitystatus="1"></versionRange>
<infoURL>https://get.adobe.com/flashplayer/</infoURL>
</pluginItem>
<pluginItem os="Linux" blockID="p826">
<match name="filename" exp="libflashplayer\.so" /> <versionRange minVersion="11.2.202.425" maxVersion="11.2.202.439" severity="0" vulnerabilitystatus="1"></versionRange>
<infoURL>https://get.adobe.com/flashplayer/</infoURL>
</pluginItem>
<pluginItem blockID="p828">
<match name="filename" exp="(NPSWF32.*\.dll)|(Flash\ Player\.plugin)" /> <versionRange minVersion="15.0.0.243" maxVersion="16.0.0.287" severity="0" vulnerabilitystatus="1"></versionRange>
<infoURL>https://get.adobe.com/flashplayer/</infoURL>
</pluginItem>
</pluginItems>
<gfxItems>

View File

@ -11,6 +11,15 @@ if CONFIG['OS_ARCH'] == 'WINNT' and (CONFIG['MOZ_METRO'] or CONFIG['MOZ_ASAN']):
else:
GeckoProgram(CONFIG['MOZ_APP_NAME'], msvcrt='static')
JS_PREFERENCE_FILES += [
'profile/firefox.js',
]
if CONFIG['LIBXUL_SDK']:
PREF_JS_EXPORTS += [
'profile/channel-prefs.js',
]
SOURCES += [
'nsBrowserApp.cpp',
]

View File

@ -4,8 +4,6 @@
include $(topsrcdir)/config/config.mk
PREF_JS_EXPORTS = $(srcdir)/pref/firefox-branding.js
# On Windows only do this step for browser, skip for metro.
ifeq ($(MOZ_WIDGET_TOOLKIT) $(DIST_SUBDIR),windows browser)
BRANDING_FILES := \

View File

@ -8,3 +8,8 @@ DIRS += ['content', 'locales']
DIST_SUBDIR = 'browser'
export('DIST_SUBDIR')
JS_PREFERENCE_FILES += [
'pref/firefox-branding.js',
]

View File

@ -4,8 +4,6 @@
include $(topsrcdir)/config/config.mk
PREF_JS_EXPORTS = $(srcdir)/pref/firefox-branding.js
# On Windows only do this step for browser, skip for metro.
ifeq ($(MOZ_WIDGET_TOOLKIT) $(DIST_SUBDIR),windows browser)
BRANDING_FILES := \

View File

@ -8,3 +8,8 @@ DIRS += ['content', 'locales']
DIST_SUBDIR = 'browser'
export('DIST_SUBDIR')
JS_PREFERENCE_FILES += [
'pref/firefox-branding.js',
]

View File

@ -4,8 +4,6 @@
include $(topsrcdir)/config/config.mk
PREF_JS_EXPORTS = $(srcdir)/pref/firefox-branding.js
# On Windows only do this step for browser, skip for metro.
ifeq ($(MOZ_WIDGET_TOOLKIT) $(DIST_SUBDIR),windows browser)
BRANDING_FILES := \

View File

@ -8,3 +8,8 @@ DIRS += ['content', 'locales']
DIST_SUBDIR = 'browser'
export('DIST_SUBDIR')
JS_PREFERENCE_FILES += [
'pref/firefox-branding.js',
]

View File

@ -4,8 +4,6 @@
include $(topsrcdir)/config/config.mk
PREF_JS_EXPORTS = $(srcdir)/pref/firefox-branding.js
# On Windows only do this step for browser, skip for metro.
ifeq ($(MOZ_WIDGET_TOOLKIT) $(DIST_SUBDIR),windows browser)
BRANDING_FILES := \

View File

@ -8,3 +8,8 @@ DIRS += ['content', 'locales']
DIST_SUBDIR = 'browser'
export('DIST_SUBDIR')
JS_PREFERENCE_FILES += [
'pref/firefox-branding.js',
]

View File

@ -1,5 +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/.
PREF_JS_EXPORTS = $(srcdir)/webide-prefs.js

View File

@ -23,3 +23,8 @@ EXTRA_JS_MODULES.devtools.webide += [
'modules/tab-store.js',
'modules/utils.js'
]
JS_PREFERENCE_FILES += [
'webide-prefs.js',
]

View File

@ -44,7 +44,10 @@ RETRIEVE_WINDOWS_INSTALLER = 1
MOZ_LANGPACK_EID=langpack-$(AB_CD)@firefox.mozilla.org
PREF_JS_EXPORTS = $(call MERGE_FILE,firefox-l10n.js)
L10N_PREF_JS_EXPORTS = $(call MERGE_FILE,firefox-l10n.js)
L10N_PREF_JS_EXPORTS_PATH = $(FINAL_TARGET)/$(PREF_DIR)
L10N_PREF_JS_EXPORTS_FLAGS = $(PREF_PPFLAGS) --silence-missing-directive-warnings
PP_TARGETS += L10N_PREF_JS_EXPORTS
ifneq (,$(filter cocoa,$(MOZ_WIDGET_TOOLKIT)))
MOZ_PKG_MAC_DSSTORE=$(_ABS_DIST)/branding/dsstore

View File

@ -11,8 +11,11 @@ include $(topsrcdir)/config/config.mk
# l10s prefs file
# copying firefox-l10n.js over from LOCALE_SRCDIR or browser
PREF_JS_EXPORTS = $(firstword $(wildcard $(LOCALE_SRCDIR)/firefox-l10n.js) \
$(topsrcdir)/$(relativesrcdir)/en-US/firefox-l10n.js )
L10N_PREF_JS_EXPORTS = $(firstword $(wildcard $(LOCALE_SRCDIR)/firefox-l10n.js) \
$(srcdir)/en-US/firefox-l10n.js )
L10N_PREF_JS_EXPORTS_PATH = $(FINAL_TARGET)/$(PREF_DIR)
L10N_PREF_JS_EXPORTS_FLAGS = $(PREF_PPFLAGS) --silence-missing-directive-warnings
PP_TARGETS += L10N_PREF_JS_EXPORTS
include $(topsrcdir)/config/rules.mk

View File

@ -1,7 +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/.
include $(topsrcdir)/config/config.mk
PREF_JS_EXPORTS = $(srcdir)/metro.js

View File

@ -4,3 +4,7 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
JS_PREFERENCE_FILES += [
'metro.js',
]

View File

@ -116,7 +116,6 @@ nsNullPrincipal::Init(uint32_t aAppId, bool aInMozBrowser)
}
mURI = new nsNullPrincipalURI(str);
NS_ENSURE_TRUE(mURI, NS_ERROR_OUT_OF_MEMORY);
return NS_OK;
}

View File

@ -986,8 +986,6 @@ nsScriptSecurityManager::CreateCodebasePrincipal(nsIURI* aURI, uint32_t aAppId,
}
nsRefPtr<nsPrincipal> codebase = new nsPrincipal();
if (!codebase)
return NS_ERROR_OUT_OF_MEMORY;
nsresult rv = codebase->Init(aURI, aAppId, aInMozBrowser);
if (NS_FAILED(rv))
@ -1269,7 +1267,6 @@ nsresult nsScriptSecurityManager::Init()
// Create our system principal singleton
nsRefPtr<nsSystemPrincipal> system = new nsSystemPrincipal();
NS_ENSURE_TRUE(system, NS_ERROR_OUT_OF_MEMORY);
mSystemPrincipal = system;

View File

@ -90,6 +90,7 @@ _MOZBUILD_EXTERNAL_VARIABLES := \
NO_DIST_INSTALL \
OS_LIBS \
PARALLEL_DIRS \
PREF_JS_EXPORTS \
PROGRAM \
PYTHON_UNIT_TESTS \
RESOURCE_FILES \

View File

@ -524,6 +524,12 @@ this.PermissionsTable = { geolocation: {
trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"requestsync-manager": {
app: DENY_ACTION,
trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
}
};

View File

@ -626,7 +626,7 @@ File::Constructor(const GlobalObject& aGlobal,
const ChromeFilePropertyBag& aBag,
ErrorResult& aRv)
{
if (!nsContentUtils::IsCallerChrome()) {
if (!nsContentUtils::ThreadsafeIsCallerChrome()) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
@ -648,6 +648,7 @@ File::Constructor(const GlobalObject& aGlobal,
const ChromeFilePropertyBag& aBag,
ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread());
if (!nsContentUtils::IsCallerChrome()) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
@ -672,7 +673,7 @@ File::Constructor(const GlobalObject& aGlobal,
const ChromeFilePropertyBag& aBag,
ErrorResult& aRv)
{
if (!nsContentUtils::IsCallerChrome()) {
if (!nsContentUtils::ThreadsafeIsCallerChrome()) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}

View File

@ -112,6 +112,13 @@ GetObjectLog()
#define LOG(args) PR_LOG(GetObjectLog(), PR_LOG_DEBUG, args)
#define LOG_ENABLED() PR_LOG_TEST(GetObjectLog(), PR_LOG_DEBUG)
static bool
IsJavaMIME(const nsACString & aMIMEType)
{
return
nsPluginHost::GetSpecialType(aMIMEType) == nsPluginHost::eSpecialType_Java;
}
static bool
InActiveDocument(nsIContent *aContent)
{
@ -992,7 +999,7 @@ nsObjectLoadingContent::BuildParametersArray()
mCachedAttributes.AppendElement(param);
}
bool isJava = nsPluginHost::IsJavaMIMEType(mContentType.get());
bool isJava = IsJavaMIME(mContentType);
nsCString codebase;
if (isJava) {
@ -1584,8 +1591,8 @@ nsObjectLoadingContent::UpdateObjectParameters(bool aJavaURI)
if (aJavaURI || thisContent->NodeInfo()->Equals(nsGkAtoms::applet)) {
nsAdoptingCString javaMIME = Preferences::GetCString(kPrefJavaMIME);
newMime = javaMIME;
NS_ASSERTION(nsPluginHost::IsJavaMIMEType(newMime.get()),
"plugin.mime.java should be recognized by IsJavaMIMEType");
NS_ASSERTION(IsJavaMIME(newMime),
"plugin.mime.java should be recognized as java");
isJava = true;
} else {
nsAutoString rawTypeAttr;
@ -1593,7 +1600,7 @@ nsObjectLoadingContent::UpdateObjectParameters(bool aJavaURI)
if (!rawTypeAttr.IsEmpty()) {
typeAttr = rawTypeAttr;
CopyUTF16toUTF8(rawTypeAttr, newMime);
isJava = nsPluginHost::IsJavaMIMEType(newMime.get());
isJava = IsJavaMIME(newMime);
}
}
@ -1607,8 +1614,8 @@ nsObjectLoadingContent::UpdateObjectParameters(bool aJavaURI)
if (!classIDAttr.IsEmpty()) {
// Our classid support is limited to 'java:' ids
nsAdoptingCString javaMIME = Preferences::GetCString(kPrefJavaMIME);
NS_ASSERTION(nsPluginHost::IsJavaMIMEType(javaMIME.get()),
"plugin.mime.java should be recognized by IsJavaMIMEType");
NS_ASSERTION(IsJavaMIME(javaMIME),
"plugin.mime.java should be recognized as java");
if (StringBeginsWith(classIDAttr, NS_LITERAL_STRING("java:")) &&
PluginExistsForType(javaMIME)) {
newMime = javaMIME;
@ -1720,7 +1727,7 @@ nsObjectLoadingContent::UpdateObjectParameters(bool aJavaURI)
(caps & eAllowPluginSkipChannel) &&
IsPluginEnabledByExtension(newURI, newMime)) {
LOG(("OBJLC [%p]: Using extension as type hint (%s)", this, newMime.get()));
if (!isJava && nsPluginHost::IsJavaMIMEType(newMime.get())) {
if (!isJava && IsJavaMIME(newMime)) {
return UpdateObjectParameters(true);
}
}
@ -1836,7 +1843,7 @@ nsObjectLoadingContent::UpdateObjectParameters(bool aJavaURI)
}
} else {
newMime = channelType;
if (nsPluginHost::IsJavaMIMEType(newMime.get())) {
if (IsJavaMIME(newMime)) {
// Java does not load with a channel, and being java retroactively
// changes how we may have interpreted the codebase to construct this
// URI above. Because the behavior here is more or less undefined, play
@ -2107,7 +2114,7 @@ nsObjectLoadingContent::LoadObject(bool aNotify,
if (mType != eType_Null) {
bool allowLoad = true;
if (nsPluginHost::IsJavaMIMEType(mContentType.get())) {
if (IsJavaMIME(mContentType)) {
allowLoad = CheckJavaCodebase();
}
int16_t contentPolicy = nsIContentPolicy::ACCEPT;
@ -3017,7 +3024,8 @@ nsObjectLoadingContent::StopPluginInstance()
if (inst) {
const char* mime = nullptr;
if (NS_SUCCEEDED(inst->GetMIMEType(&mime)) && mime) {
if (strcmp(mime, "audio/x-pn-realaudio-plugin") == 0) {
if (nsPluginHost::GetSpecialType(nsDependentCString(mime)) ==
nsPluginHost::eSpecialType_RealPlayer) {
delayedStop = true;
}
}

View File

@ -2726,6 +2726,10 @@ UnwrapArgImpl(JS::Handle<JSObject*> src,
const nsIID &iid,
void **ppArg)
{
if (!NS_IsMainThread()) {
return NS_ERROR_NOT_AVAILABLE;
}
nsISupports *iface = xpc::UnwrapReflectorToISupports(src);
if (iface) {
if (NS_FAILED(iface->QueryInterface(iid, ppArg))) {

View File

@ -633,6 +633,10 @@ DOMInterfaces = {
'headerFile': 'nsIMediaList.h',
},
'MediaKeyStatusMap' : {
'implicitJSContext': [ 'size', 'get', 'has' ]
},
'MediaStream': {
'headerFile': 'DOMMediaStream.h',
'nativeType': 'mozilla::DOMMediaStream'

View File

@ -57,3 +57,4 @@ skip-if = debug == false
skip-if = debug == false
[test_promise_rejections_from_jsimplemented.html]
skip-if = debug == false
[test_worker_UnwrapArg.html]

View File

@ -0,0 +1,58 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1127206
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1127206</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript">
/** Test for Bug 1127206 **/
SimpleTest.waitForExplicitFinish();
var blob = new Blob([
`try { new File({}); }
catch (e) {
postMessage("throwing on random object");
}
try { new File(new Blob(["abc"])); }
catch (e) {
postMessage("throwing on Blob");
}
try { new File("abc"); }
catch (e) {
postMessage("throwing on string");
}
postMessage('finishTest')`]);
var url = URL.createObjectURL(blob);
var w = new Worker(url);
var expectedResults = [
"throwing on random object",
"throwing on Blob",
"throwing on string",
];
var curIndex = 0;
w.onmessage = function(e) {
if (curIndex == expectedResults.length) {
is(e.data, "finishTest", "What message is this?");
SimpleTest.finish();
} else {
is(e.data, expectedResults[curIndex],
"Message " + (curIndex+1) + " should be correct");
++curIndex;
}
}
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1127206">Mozilla Bug 1127206</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
</html>

View File

@ -314,6 +314,17 @@ ContentEventHandler::GetNativeTextLength(nsIContent* aContent,
return GetTextLength(aContent, LINE_BREAK_TYPE_NATIVE, aMaxLength);
}
static inline uint32_t
GetBRLength(LineBreakType aLineBreakType)
{
#if defined(XP_WIN)
// Length of \r\n
return (aLineBreakType == LINE_BREAK_TYPE_NATIVE) ? 2 : 1;
#else
return 1;
#endif
}
/* static */ uint32_t
ContentEventHandler::GetTextLength(nsIContent* aContent,
LineBreakType aLineBreakType,
@ -344,12 +355,7 @@ ContentEventHandler::GetTextLength(nsIContent* aContent,
uint32_t length = std::min(text->GetLength(), aMaxLength);
return length + textLengthDifference;
} else if (IsContentBR(aContent)) {
#if defined(XP_WIN)
// Length of \r\n
return (aLineBreakType == LINE_BREAK_TYPE_NATIVE) ? 2 : 1;
#else
return 1;
#endif
return GetBRLength(aLineBreakType);
}
return 0;
}
@ -393,7 +399,6 @@ static nsresult GenerateFlatTextContent(nsRange* aRange,
return NS_OK;
}
nsAutoString tmpStr;
for (; !iter->IsDone(); iter->Next()) {
nsINode* node = iter->GetCurrentNode();
if (!node) {
@ -423,6 +428,171 @@ static nsresult GenerateFlatTextContent(nsRange* aRange,
return NS_OK;
}
static FontRange*
AppendFontRange(nsTArray<FontRange>& aFontRanges, uint32_t aBaseOffset)
{
FontRange* fontRange = aFontRanges.AppendElement();
fontRange->mStartOffset = aBaseOffset;
return fontRange;
}
/* static */ uint32_t
ContentEventHandler::GetTextLengthInRange(nsIContent* aContent,
uint32_t aXPStartOffset,
uint32_t aXPEndOffset,
LineBreakType aLineBreakType)
{
return aLineBreakType == LINE_BREAK_TYPE_NATIVE ?
GetNativeTextLength(aContent, aXPStartOffset, aXPEndOffset) :
aXPEndOffset - aXPStartOffset;
}
/* static */ void
ContentEventHandler::AppendFontRanges(FontRangeArray& aFontRanges,
nsIContent* aContent,
int32_t aBaseOffset,
int32_t aXPStartOffset,
int32_t aXPEndOffset,
LineBreakType aLineBreakType)
{
nsIFrame* frame = aContent->GetPrimaryFrame();
if (!frame) {
// It is a non-rendered content, create an empty range for it.
AppendFontRange(aFontRanges, aBaseOffset);
return;
}
int32_t baseOffset = aBaseOffset;
nsTextFrame* curr = do_QueryFrame(frame);
MOZ_ASSERT(curr, "Not a text frame");
while (curr) {
int32_t frameXPStart = std::max(curr->GetContentOffset(), aXPStartOffset);
int32_t frameXPEnd = std::min(curr->GetContentEnd(), aXPEndOffset);
if (frameXPStart >= frameXPEnd) {
curr = static_cast<nsTextFrame*>(curr->GetNextContinuation());
continue;
}
gfxSkipCharsIterator iter = curr->EnsureTextRun(nsTextFrame::eInflated);
gfxTextRun* textRun = curr->GetTextRun(nsTextFrame::eInflated);
nsTextFrame* next = nullptr;
if (frameXPEnd < aXPEndOffset) {
next = static_cast<nsTextFrame*>(curr->GetNextContinuation());
while (next && next->GetTextRun(nsTextFrame::eInflated) == textRun) {
frameXPEnd = std::min(next->GetContentEnd(), aXPEndOffset);
next = frameXPEnd < aXPEndOffset ?
static_cast<nsTextFrame*>(next->GetNextContinuation()) : nullptr;
}
}
uint32_t skipStart = iter.ConvertOriginalToSkipped(frameXPStart);
uint32_t skipEnd = iter.ConvertOriginalToSkipped(frameXPEnd);
gfxTextRun::GlyphRunIterator runIter(
textRun, skipStart, skipEnd - skipStart);
int32_t lastXPEndOffset = frameXPStart;
while (runIter.NextRun()) {
gfxFont* font = runIter.GetGlyphRun()->mFont.get();
int32_t startXPOffset =
iter.ConvertSkippedToOriginal(runIter.GetStringStart());
// It is possible that the first glyph run has exceeded the frame,
// because the whole frame is filled by skipped chars.
if (startXPOffset >= frameXPEnd) {
break;
}
if (startXPOffset > lastXPEndOffset) {
// Create range for skipped leading chars.
AppendFontRange(aFontRanges, baseOffset);
baseOffset += GetTextLengthInRange(
aContent, lastXPEndOffset, startXPOffset, aLineBreakType);
lastXPEndOffset = startXPOffset;
}
FontRange* fontRange = AppendFontRange(aFontRanges, baseOffset);
fontRange->mFontName = font->GetName();
fontRange->mFontSize = font->GetAdjustedSize();
// The converted original offset may exceed the range,
// hence we need to clamp it.
int32_t endXPOffset =
iter.ConvertSkippedToOriginal(runIter.GetStringEnd());
endXPOffset = std::min(frameXPEnd, endXPOffset);
baseOffset += GetTextLengthInRange(aContent, startXPOffset, endXPOffset,
aLineBreakType);
lastXPEndOffset = endXPOffset;
}
if (lastXPEndOffset < frameXPEnd) {
// Create range for skipped trailing chars. It also handles case
// that the whole frame contains only skipped chars.
AppendFontRange(aFontRanges, baseOffset);
baseOffset += GetTextLengthInRange(
aContent, lastXPEndOffset, frameXPEnd, aLineBreakType);
}
curr = next;
}
}
/* static */ nsresult
ContentEventHandler::GenerateFlatFontRanges(nsRange* aRange,
FontRangeArray& aFontRanges,
uint32_t& aLength,
LineBreakType aLineBreakType)
{
MOZ_ASSERT(aFontRanges.IsEmpty(), "aRanges must be empty array");
nsINode* startNode = aRange->GetStartParent();
nsINode* endNode = aRange->GetEndParent();
if (NS_WARN_IF(!startNode || !endNode)) {
return NS_ERROR_FAILURE;
}
// baseOffset is the flattened offset of each content node.
int32_t baseOffset = 0;
nsCOMPtr<nsIContentIterator> iter = NS_NewContentIterator();
for (iter->Init(aRange); !iter->IsDone(); iter->Next()) {
nsINode* node = iter->GetCurrentNode();
if (NS_WARN_IF(!node)) {
break;
}
if (!node->IsContent()) {
continue;
}
nsIContent* content = node->AsContent();
if (content->IsNodeOfType(nsINode::eTEXT)) {
int32_t startOffset = content != startNode ? 0 : aRange->StartOffset();
int32_t endOffset = content != endNode ?
content->TextLength() : aRange->EndOffset();
AppendFontRanges(aFontRanges, content, baseOffset,
startOffset, endOffset, aLineBreakType);
baseOffset += GetTextLengthInRange(content, startOffset, endOffset,
aLineBreakType);
} else if (IsContentBR(content)) {
if (aFontRanges.IsEmpty()) {
MOZ_ASSERT(baseOffset == 0);
FontRange* fontRange = AppendFontRange(aFontRanges, baseOffset);
nsIFrame* frame = content->GetPrimaryFrame();
if (frame) {
const nsFont& font = frame->GetParent()->StyleFont()->mFont;
const FontFamilyList& fontList = font.fontlist;
const FontFamilyName& fontName = fontList.IsEmpty() ?
FontFamilyName(fontList.GetDefaultFontType()) :
fontList.GetFontlist()[0];
fontName.AppendToString(fontRange->mFontName, false);
fontRange->mFontSize =
frame->PresContext()->AppUnitsToDevPixels(font.size);
}
}
baseOffset += GetBRLength(aLineBreakType);
}
}
aLength = baseOffset;
return NS_OK;
}
nsresult
ContentEventHandler::ExpandToClusterBoundary(nsIContent* aContent,
bool aForward,
@ -697,6 +867,18 @@ ContentEventHandler::OnQueryTextContent(WidgetQueryContentEvent* aEvent)
rv = GenerateFlatTextContent(range, aEvent->mReply.mString, lineBreakType);
NS_ENSURE_SUCCESS(rv, rv);
if (aEvent->mWithFontRanges) {
uint32_t fontRangeLength;
rv = GenerateFlatFontRanges(range, aEvent->mReply.mFontRanges,
fontRangeLength, lineBreakType);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
MOZ_ASSERT(fontRangeLength == aEvent->mReply.mString.Length(),
"Font ranges doesn't match the string");
}
aEvent->mSucceeded = true;
return NS_OK;

View File

@ -94,6 +94,12 @@ public:
// Get the native text length of a content node excluding any children
static uint32_t GetNativeTextLength(nsIContent* aContent,
uint32_t aMaxLength = UINT32_MAX);
// Get the text length of a given range of a content node in
// the given line break type.
static uint32_t GetTextLengthInRange(nsIContent* aContent,
uint32_t aXPStartOffset,
uint32_t aXPEndOffset,
LineBreakType aLineBreakType);
protected:
static uint32_t GetTextLength(nsIContent* aContent,
LineBreakType aLineBreakType,
@ -129,6 +135,18 @@ protected:
// true, it is expanded to forward.
nsresult ExpandToClusterBoundary(nsIContent* aContent, bool aForward,
uint32_t* aXPOffset);
typedef nsTArray<mozilla::FontRange> FontRangeArray;
static void AppendFontRanges(FontRangeArray& aFontRanges,
nsIContent* aContent,
int32_t aBaseOffset,
int32_t aXPStartOffset,
int32_t aXPEndOffset,
LineBreakType aLineBreakType);
static nsresult GenerateFlatFontRanges(nsRange* aRange,
FontRangeArray& aFontRanges,
uint32_t& aLength,
LineBreakType aLineBreakType);
};
} // namespace mozilla

View File

@ -1889,7 +1889,6 @@ HTMLMediaElement::CaptureStreamInternal(bool aFinishWhenEnded)
// back into the output stream.
out->mStream->GetStream()->ChangeExplicitBlockerCount(1);
if (mDecoder) {
mDecoder->SetAudioCaptured(true);
mDecoder->AddOutputStream(
out->mStream->GetStream()->AsProcessedStream(), aFinishWhenEnded);
}
@ -2705,7 +2704,6 @@ nsresult HTMLMediaElement::FinishDecoderSetup(MediaDecoder* aDecoder,
// available immediately.
mDecoder->SetResource(aStream);
mDecoder->SetAudioChannel(mAudioChannel);
mDecoder->SetAudioCaptured(mAudioCaptured);
mDecoder->SetVolume(mMuted ? 0.0 : mVolume);
mDecoder->SetPreservesPitch(mPreservesPitch);
mDecoder->SetPlaybackRate(mPlaybackRate);

View File

@ -98,7 +98,7 @@ TimeRanges::GetEndTime()
}
void
TimeRanges::Normalize(double aError)
TimeRanges::Normalize(double aTolerance)
{
if (mRanges.Length() >= 2) {
nsAutoTArray<TimeRange,4> normalized;
@ -112,7 +112,7 @@ TimeRanges::Normalize(double aError)
current.mEnd >= mRanges[i].mEnd) {
continue;
}
if (current.mEnd + aError >= mRanges[i].mStart) {
if (current.mEnd + aTolerance >= mRanges[i].mStart) {
current.mEnd = mRanges[i].mEnd;
} else {
normalized.AppendElement(current);
@ -127,10 +127,10 @@ TimeRanges::Normalize(double aError)
}
void
TimeRanges::Union(const TimeRanges* aOtherRanges, double aError)
TimeRanges::Union(const TimeRanges* aOtherRanges, double aTolerance)
{
mRanges.AppendElements(aOtherRanges->mRanges);
Normalize(aError);
Normalize(aTolerance);
}
void
@ -156,10 +156,10 @@ TimeRanges::Intersection(const TimeRanges* aOtherRanges)
}
TimeRanges::index_type
TimeRanges::Find(double aTime, double aError /* = 0 */)
TimeRanges::Find(double aTime, double aTolerance /* = 0 */)
{
for (index_type i = 0; i < mRanges.Length(); ++i) {
if (aTime < mRanges[i].mEnd && (aTime + aError) >= mRanges[i].mStart) {
if (aTime < mRanges[i].mEnd && (aTime + aTolerance) >= mRanges[i].mStart) {
return i;
}
}

View File

@ -42,10 +42,10 @@ public:
double GetEndTime();
// See http://www.whatwg.org/html/#normalized-timeranges-object
void Normalize(double aError = 0.0);
void Normalize(double aTolerance = 0.0);
// Mutate this TimeRange to be the union of this and aOtherRanges.
void Union(const TimeRanges* aOtherRanges, double aError);
void Union(const TimeRanges* aOtherRanges, double aTolerance);
// Mutate this TimeRange to be the intersection of this and aOtherRanges.
void Intersection(const TimeRanges* aOtherRanges);
@ -91,7 +91,7 @@ public:
typedef nsTArray<TimeRange>::index_type index_type;
static const index_type NoIndex = index_type(-1);
index_type Find(double aTime, double aError = 0);
index_type Find(double aTime, double aTolerance = 0);
bool Contains(double aStart, double aEnd) {
index_type target = Find(aStart);

View File

@ -312,7 +312,7 @@ function StkSetupEventListMessage(aStkSetupEventListCmd) {
}
StkSetupEventListMessage.prototype = Object.create(StkCommandMessage.prototype);
function StkMenuCmd(aCommandDetails) {
function StkSetUpMenuCmd(aCommandDetails) {
// Call |StkProactiveCommand| constructor.
StkProactiveCommand.call(this, aCommandDetails);
@ -340,10 +340,10 @@ function StkMenuCmd(aCommandDetails) {
this.isHelpAvailable = !!(options.isHelpAvailable);
}
StkMenuCmd.prototype = Object.create(StkProactiveCommand.prototype, {
StkSetUpMenuCmd.prototype = Object.create(StkProactiveCommand.prototype, {
QueryInterface: {
value: XPCOMUtils.generateQI([Ci.nsIStkProactiveCmd,
Ci.nsIStkMenuCmd])
Ci.nsIStkSetUpMenuCmd])
},
// Cache items for getItems()
@ -352,7 +352,7 @@ StkMenuCmd.prototype = Object.create(StkProactiveCommand.prototype, {
// Cache items for getNextActionList()
nextActionList: { value: null, writable: true },
// nsIStkMenuCmd
// nsIStkSetUpMenuCmd
title: { value: null, writable: true },
getItems: {
@ -393,12 +393,12 @@ StkMenuCmd.prototype = Object.create(StkProactiveCommand.prototype, {
isHelpAvailable: { value: false, writable: true }
});
function StkMenuMessage(aStkMenuCmd) {
function StkSetUpMenuMessage(aStkSetUpMenuCmd) {
// Call |StkCommandMessage| constructor.
StkCommandMessage.call(this, aStkMenuCmd);
StkCommandMessage.call(this, aStkSetUpMenuCmd);
this.options = {
items: aStkMenuCmd.getItems().map(function(aStkItem) {
items: aStkSetUpMenuCmd.getItems().map(function(aStkItem) {
if (!aStkItem) {
return null;
}
@ -414,70 +414,50 @@ function StkMenuMessage(aStkMenuCmd) {
return item;
}),
isHelpAvailable: aStkMenuCmd.isHelpAvailable
isHelpAvailable: aStkSetUpMenuCmd.isHelpAvailable
};
if (aStkMenuCmd.title) {
this.options.title = aStkMenuCmd.title;
if (aStkSetUpMenuCmd.title) {
this.options.title = aStkSetUpMenuCmd.title;
}
let nextActionList = aStkMenuCmd.getNextActionList();
let nextActionList = aStkSetUpMenuCmd.getNextActionList();
if (nextActionList && nextActionList.length > 0) {
this.options.nextActionList = nextActionList;
}
if (aStkMenuCmd.iconInfo) {
appendIconInfo(this.options, aStkMenuCmd.iconInfo);
if (aStkSetUpMenuCmd.iconInfo) {
appendIconInfo(this.options, aStkSetUpMenuCmd.iconInfo);
}
}
StkMenuMessage.prototype = Object.create(StkCommandMessage.prototype);
StkSetUpMenuMessage.prototype = Object.create(StkCommandMessage.prototype);
function StkSetUpMenuCmd(aCommandDetails) {
// Call |StkMenuCmd| constructor.
StkMenuCmd.call(this, aCommandDetails);
function StkSelectItemCmd(aCommandDetails) {
// Call |StkSetUpMenuCmd| constructor.
StkSetUpMenuCmd.call(this, aCommandDetails);
let options = aCommandDetails.options;
this.presentationType = options.presentationType;
}
StkSetUpMenuCmd.prototype = Object.create(StkMenuCmd.prototype, {
QueryInterface: {
value: XPCOMUtils.generateQI([Ci.nsIStkProactiveCmd,
Ci.nsIStkMenuCmd,
Ci.nsIStkSetUpMenuCmd])
},
// nsIStkSetUpMenuCmd
presentationType: { value: 0, writable: true }
});
function StkSetUpMenuMessage(aStkSetUpMenuCmd) {
// Call |StkMenuMessage| constructor.
StkMenuMessage.call(this, aStkSetUpMenuCmd);
this.options.presentationType = aStkSetUpMenuCmd.presentationType;
}
StkSetUpMenuMessage.prototype = Object.create(StkMenuMessage.prototype);
function StkSelectItemCmd(aCommandDetails) {
// Call |StkMenuCmd| constructor.
StkMenuCmd.call(this, aCommandDetails);
let options = aCommandDetails.options;
if (options.defaultItem !== undefined &&
options.defaultItem !== null) {
this.defaultItem = options.defaultItem;
}
}
StkSelectItemCmd.prototype = Object.create(StkMenuCmd.prototype, {
StkSelectItemCmd.prototype = Object.create(StkSetUpMenuCmd.prototype, {
QueryInterface: {
value: XPCOMUtils.generateQI([Ci.nsIStkProactiveCmd,
Ci.nsIStkMenuCmd,
Ci.nsIStkSetUpMenuCmd,
Ci.nsIStkSelectItemCmd])
},
// nsIStkSelectItemCmd
presentationType: {
value: 0,
writable: true
},
defaultItem: {
value: Ci.nsIStkSelectItemCmd.DEFAULT_ITEM_INVALID,
writable: true
@ -485,14 +465,16 @@ StkSelectItemCmd.prototype = Object.create(StkMenuCmd.prototype, {
});
function StkSelectItemMessage(aStkSelectItemCmd) {
// Call |StkMenuMessage| constructor.
StkMenuMessage.call(this, aStkSelectItemCmd);
// Call |StkSetUpMenuMessage| constructor.
StkSetUpMenuMessage.call(this, aStkSelectItemCmd);
this.options.presentationType = aStkSelectItemCmd.presentationType;
if (aStkSelectItemCmd.defaultItem !== Ci.nsIStkSelectItemCmd.DEFAULT_ITEM_INVALID) {
this.options.defaultItem = aStkSelectItemCmd.defaultItem;
}
}
StkSelectItemMessage.prototype = Object.create(StkMenuMessage.prototype);
StkSelectItemMessage.prototype = Object.create(StkSetUpMenuMessage.prototype);
function StkTextMessageCmd(aCommandDetails) {
// Call |StkProactiveCommand| constructor.

View File

@ -240,10 +240,10 @@ interface nsIStkSetupEventListCmd : nsIStkProactiveCmd
};
/**
* The base interface of nsIStkSetUpMenuCmd and nsIStkSelectItemCmd.
* This interface is to be applied by STK_CMD_SET_UP_MENU.
*/
[scriptable, uuid(298bf414-6a1f-11e4-9045-3b3fd28e7f6a)]
interface nsIStkMenuCmd : nsIStkProactiveCmd
[scriptable, uuid(d7a66664-a602-11e4-9cc7-c7ce5fdade7d)]
interface nsIStkSetUpMenuCmd : nsIStkProactiveCmd
{
/**
* (Optional for STK_CMD_SELECT_ITEM)
@ -304,29 +304,22 @@ interface nsIStkMenuCmd : nsIStkProactiveCmd
};
/**
* This interface is to be applied by STK_CMD_SET_UP_MENU.
* This interface is to be applied by STK_CMD_SELECT_ITEM.
*/
[scriptable, uuid(d3ddb1f0-631c-11e4-aac3-4beb03196b7b)]
interface nsIStkSetUpMenuCmd : nsIStkMenuCmd
[scriptable, uuid(eb71f0fa-a602-11e4-926f-a3814461d218)]
interface nsIStkSelectItemCmd : nsIStkSetUpMenuCmd
{
/**
* Presentation type, one of PRESENTATION_TYPE_*.
*
* @See TS 11.14, clause 12.6, Command Qualifier: Select Item
*/
const short PRESENTATION_TYPE_NOT_SPECIFIED = 0x00;
const short PRESENTATION_TYPE_DATA_VALUES = 0x01;
const short PRESENTATION_TYPE_NAVIGATION_OPTIONS = 0x03;
const unsigned short PRESENTATION_TYPE_NOT_SPECIFIED = 0x00;
const unsigned short PRESENTATION_TYPE_DATA_VALUES = 0x01;
const unsigned short PRESENTATION_TYPE_NAVIGATION_OPTIONS = 0x03;
readonly attribute unsigned short presentationType;
};
/**
* This interface is to be applied by STK_CMD_SELECT_ITEM.
*/
[scriptable, uuid(816dc186-631b-11e4-864f-b37f7b54a1b8)]
interface nsIStkSelectItemCmd : nsIStkMenuCmd
{
const unsigned short DEFAULT_ITEM_INVALID = 0xFFFF;
/**

View File

@ -217,6 +217,7 @@ function testSelectItem(aCommand, aExpect) {
is(aCommand.typeOfCommand, MozIccManager.STK_CMD_SELECT_ITEM, "typeOfCommand");
is(aCommand.commandQualifier, aExpect.commandQualifier, "commandQualifier");
is(aCommand.options.title, aExpect.title, "options.title");
is(aCommand.options.presentationType, aCommand.commandQualifier & 0x03, "presentationType");
for (let index in aExpect.items) {
let item = aCommand.options.items[index];

View File

@ -158,6 +158,8 @@ function testSetupMenu(aCommand, aExpect) {
is(aCommand.typeOfCommand, MozIccManager.STK_CMD_SET_UP_MENU, "typeOfCommand");
is(aCommand.commandQualifier, aExpect.commandQualifier, "commandQualifier");
is(aCommand.options.title, aExpect.title, "options.title");
// To ensure that 'presentationType' will only be available in SELECT_ITEM.
is(aCommand.options.presentationType, undefined, "presentationType");
for (let index in aExpect.items) {
let item = aCommand.options.items[index];

View File

@ -2496,7 +2496,10 @@ ContentChild::RecvGetProfile(nsCString* aProfile)
bool
ContentChild::RecvLoadPluginResult(const uint32_t& aPluginId, const bool& aResult)
{
bool finalResult = aResult && SendConnectPluginBridge(aPluginId);
nsresult rv;
bool finalResult = aResult &&
SendConnectPluginBridge(aPluginId, &rv) &&
NS_SUCCEEDED(rv);
plugins::PluginModuleContentParent::OnLoadPluginResult(aPluginId,
finalResult);
return true;

View File

@ -979,15 +979,17 @@ static nsIDocShell* GetOpenerDocShellHelper(Element* aFrameElement)
}
bool
ContentParent::RecvLoadPlugin(const uint32_t& aPluginId)
ContentParent::RecvLoadPlugin(const uint32_t& aPluginId, nsresult* aRv)
{
return mozilla::plugins::SetupBridge(aPluginId, this);
*aRv = NS_OK;
return mozilla::plugins::SetupBridge(aPluginId, this, false, aRv);
}
bool
ContentParent::RecvConnectPluginBridge(const uint32_t& aPluginId)
ContentParent::RecvConnectPluginBridge(const uint32_t& aPluginId, nsresult* aRv)
{
return mozilla::plugins::SetupBridge(aPluginId, this, true);
*aRv = NS_OK;
return mozilla::plugins::SetupBridge(aPluginId, this, true, aRv);
}
bool

View File

@ -153,8 +153,8 @@ public:
TabId* aTabId) MOZ_OVERRIDE;
virtual bool RecvBridgeToChildProcess(const ContentParentId& aCpId) MOZ_OVERRIDE;
virtual bool RecvLoadPlugin(const uint32_t& aPluginId) MOZ_OVERRIDE;
virtual bool RecvConnectPluginBridge(const uint32_t& aPluginId) MOZ_OVERRIDE;
virtual bool RecvLoadPlugin(const uint32_t& aPluginId, nsresult* aRv) MOZ_OVERRIDE;
virtual bool RecvConnectPluginBridge(const uint32_t& aPluginId, nsresult* aRv) MOZ_OVERRIDE;
virtual bool RecvFindPlugins(const uint32_t& aPluginEpoch,
nsTArray<PluginTag>* aPlugins,
uint32_t* aNewPluginEpoch) MOZ_OVERRIDE;

View File

@ -594,7 +594,7 @@ parent:
* process. We use intr semantics here to ensure that the PluginModuleParent
* allocation message is dispatched before LoadPlugin returns.
*/
sync LoadPlugin(uint32_t pluginId);
sync LoadPlugin(uint32_t pluginId) returns (nsresult rv);
/**
* This call is used by asynchronous plugin instantiation to notify the
@ -602,7 +602,7 @@ parent:
* the specified plugin id. When this call returns, the requested bridge
* connection has been made.
*/
sync ConnectPluginBridge(uint32_t aPluginId);
sync ConnectPluginBridge(uint32_t aPluginId) returns (nsresult rv);
/**
* This call returns the set of plugins loaded in the chrome

View File

@ -2126,6 +2126,7 @@ TabParent::RecvGetDefaultScale(double* aValue)
bool
TabParent::RecvGetWidgetNativeData(WindowsHandle* aValue)
{
*aValue = 0;
nsCOMPtr<nsIContent> content = do_QueryInterface(mFrameElement);
if (content) {
nsIPresShell* shell = content->OwnerDoc()->GetShell();
@ -2136,11 +2137,10 @@ TabParent::RecvGetWidgetNativeData(WindowsHandle* aValue)
if (widget) {
*aValue = reinterpret_cast<WindowsHandle>(
widget->GetNativeData(NS_NATIVE_SHAREABLE_WINDOW));
return true;
}
}
}
return false;
return true;
}
bool

View File

@ -263,15 +263,6 @@ void MediaDecoder::SetVolume(double aVolume)
}
}
void MediaDecoder::SetAudioCaptured(bool aCaptured)
{
MOZ_ASSERT(NS_IsMainThread());
mInitialAudioCaptured = aCaptured;
if (mDecoderStateMachine) {
mDecoderStateMachine->SetAudioCaptured(aCaptured);
}
}
void MediaDecoder::ConnectDecodedStreamToOutputStream(OutputStreamData* aStream)
{
NS_ASSERTION(!aStream->mPort, "Already connected?");
@ -360,13 +351,6 @@ MediaDecoder::DecodedStreamGraphListener::NotifyEvent(MediaStreamGraph* aGraph,
}
}
void MediaDecoder::RecreateDecodedStreamIfNecessary(int64_t aStartTimeUSecs)
{
if (mInitialAudioCaptured) {
RecreateDecodedStream(aStartTimeUSecs);
}
}
void MediaDecoder::DestroyDecodedStream()
{
MOZ_ASSERT(NS_IsMainThread());
@ -470,9 +454,13 @@ void MediaDecoder::AddOutputStream(ProcessedMediaStream* aStream,
{
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
if (!mDecodedStream) {
RecreateDecodedStream(mDecoderStateMachine ?
int64_t(mDecoderStateMachine->GetCurrentTime()*USECS_PER_S) : 0);
if (mDecoderStateMachine) {
mDecoderStateMachine->SetAudioCaptured();
}
if (!GetDecodedStream()) {
int64_t t = mDecoderStateMachine ?
mDecoderStateMachine->GetCurrentTimeUs() : 0;
RecreateDecodedStream(t);
}
OutputStreamData* os = mOutputStreams.AppendElement();
os->Init(aStream, aFinishWhenEnded);
@ -672,7 +660,9 @@ void MediaDecoder::SetStateMachineParameters()
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
mDecoderStateMachine->SetDuration(mDuration);
mDecoderStateMachine->SetVolume(mInitialVolume);
mDecoderStateMachine->SetAudioCaptured(mInitialAudioCaptured);
if (GetDecodedStream()) {
mDecoderStateMachine->SetAudioCaptured();
}
SetPlaybackRate(mInitialPlaybackRate);
mDecoderStateMachine->SetPreservesPitch(mInitialPreservesPitch);
if (mMinimizePreroll) {

View File

@ -374,9 +374,6 @@ public:
virtual void Pause();
// Adjust the speed of the playback, optionally with pitch correction,
virtual void SetVolume(double aVolume);
// Sets whether audio is being captured. If it is, we won't play any
// of our audio.
virtual void SetAudioCaptured(bool aCaptured);
virtual void NotifyWaitingForResourcesStatusChanged() MOZ_OVERRIDE;
@ -857,9 +854,6 @@ public:
// The decoder monitor must be held.
bool IsLogicallyPlaying();
// Re-create a decoded stream if audio being captured
void RecreateDecodedStreamIfNecessary(int64_t aStartTimeUSecs);
#ifdef MOZ_EME
// This takes the decoder monitor.
virtual nsresult SetCDMProxy(CDMProxy* aProxy) MOZ_OVERRIDE;
@ -1068,9 +1062,6 @@ protected:
// only.
int64_t mDuration;
// True when playback should start with audio captured (not playing).
bool mInitialAudioCaptured;
// True if the media is seekable (i.e. supports random access).
bool mMediaSeekable;

View File

@ -1387,11 +1387,11 @@ void MediaDecoderStateMachine::SetVolume(double volume)
}
}
void MediaDecoderStateMachine::SetAudioCaptured(bool aCaptured)
void MediaDecoderStateMachine::SetAudioCaptured()
{
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
if (!mAudioCaptured && aCaptured && !mStopAudioThread) {
AssertCurrentThreadInMonitor();
if (!mAudioCaptured && !mStopAudioThread) {
// Make sure the state machine runs as soon as possible. That will
// stop the audio sink.
// If mStopAudioThread is true then we're already stopping the audio sink
@ -1405,7 +1405,7 @@ void MediaDecoderStateMachine::SetAudioCaptured(bool aCaptured)
ResyncAudioClock();
}
}
mAudioCaptured = aCaptured;
mAudioCaptured = true;
}
double MediaDecoderStateMachine::GetCurrentTime() const
@ -1418,6 +1418,16 @@ double MediaDecoderStateMachine::GetCurrentTime() const
return static_cast<double>(mCurrentFrameTime) / static_cast<double>(USECS_PER_S);
}
int64_t MediaDecoderStateMachine::GetCurrentTimeUs() const
{
NS_ASSERTION(NS_IsMainThread() ||
OnStateMachineThread() ||
OnDecodeThread(),
"Should be on main, decode, or state machine thread.");
return mCurrentFrameTime;
}
bool MediaDecoderStateMachine::IsRealTime() const {
return mScheduler->IsRealTime();
}
@ -1782,7 +1792,9 @@ MediaDecoderStateMachine::StartSeek(const SeekTarget& aTarget)
DECODER_LOG("Changed state to SEEKING (to %lld)", mSeekTarget.mTime);
SetState(DECODER_STATE_SEEKING);
mDecoder->RecreateDecodedStreamIfNecessary(seekTime - mStartTime);
if (mAudioCaptured) {
mDecoder->RecreateDecodedStream(seekTime - mStartTime);
}
ScheduleStateMachine();
}

View File

@ -155,7 +155,7 @@ public:
// Set the audio volume. The decoder monitor must be obtained before
// calling this.
void SetVolume(double aVolume);
void SetAudioCaptured(bool aCapture);
void SetAudioCaptured();
// Check if the decoder needs to become dormant state.
bool IsDormantNeeded();
@ -241,6 +241,7 @@ public:
// Called from the main thread to get the current frame time. The decoder
// monitor must be obtained before calling this.
double GetCurrentTime() const;
int64_t GetCurrentTimeUs() const;
// Clear the flag indicating that a playback position change event
// is currently queued. This is called from the main thread and must

View File

@ -267,35 +267,18 @@ CDMCallbackProxy::SessionError(const nsCString& aSessionId,
}
void
CDMCallbackProxy::KeyIdUsable(const nsCString& aSessionId,
const nsTArray<uint8_t>& aKeyId)
CDMCallbackProxy::KeyStatusChanged(const nsCString& aSessionId,
const nsTArray<uint8_t>& aKeyId,
GMPMediaKeyStatus aStatus)
{
MOZ_ASSERT(mProxy->IsOnGMPThread());
bool keysChange = false;
{
CDMCaps::AutoLock caps(mProxy->Capabilites());
keysChange = caps.SetKeyUsable(aKeyId, NS_ConvertUTF8toUTF16(aSessionId));
}
if (keysChange) {
nsRefPtr<nsIRunnable> task;
task = NS_NewRunnableMethodWithArg<nsString>(mProxy,
&CDMProxy::OnKeysChange,
NS_ConvertUTF8toUTF16(aSessionId));
NS_DispatchToMainThread(task);
}
}
void
CDMCallbackProxy::KeyIdNotUsable(const nsCString& aSessionId,
const nsTArray<uint8_t>& aKeyId)
{
MOZ_ASSERT(mProxy->IsOnGMPThread());
bool keysChange = false;
{
CDMCaps::AutoLock caps(mProxy->Capabilites());
keysChange = caps.SetKeyUnusable(aKeyId, NS_ConvertUTF8toUTF16(aSessionId));
keysChange = caps.SetKeyStatus(aKeyId,
NS_ConvertUTF8toUTF16(aSessionId),
aStatus);
}
if (keysChange) {
nsRefPtr<nsIRunnable> task;

View File

@ -43,11 +43,9 @@ public:
uint32_t aSystemCode,
const nsCString& aMessage) MOZ_OVERRIDE;
virtual void KeyIdUsable(const nsCString& aSessionId,
const nsTArray<uint8_t>& aKeyId) MOZ_OVERRIDE;
virtual void KeyIdNotUsable(const nsCString& aSessionId,
const nsTArray<uint8_t>& aKeyId) MOZ_OVERRIDE;
virtual void KeyStatusChanged(const nsCString& aSessionId,
const nsTArray<uint8_t>& aKeyId,
GMPMediaKeyStatus aStatus) MOZ_OVERRIDE;
virtual void SetCaps(uint64_t aCaps) MOZ_OVERRIDE;

View File

@ -5,7 +5,6 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "CDMCaps.h"
#include "gmp-decryption.h"
#include "EMELog.h"
#include "nsThreadUtils.h"
#include "SamplesWaitingForKey.h"
@ -80,9 +79,9 @@ bool
CDMCaps::AutoLock::IsKeyUsable(const CencKeyId& aKeyId)
{
mData.mMonitor.AssertCurrentThreadOwns();
const auto& keys = mData.mUsableKeyIds;
const auto& keys = mData.mKeyStatuses;
for (size_t i = 0; i < keys.Length(); i++) {
if (keys[i].mId == aKeyId) {
if (keys[i].mId == aKeyId && keys[i].mStatus == kGMPUsable) {
return true;
}
}
@ -90,15 +89,32 @@ CDMCaps::AutoLock::IsKeyUsable(const CencKeyId& aKeyId)
}
bool
CDMCaps::AutoLock::SetKeyUsable(const CencKeyId& aKeyId,
const nsString& aSessionId)
CDMCaps::AutoLock::SetKeyStatus(const CencKeyId& aKeyId,
const nsString& aSessionId,
GMPMediaKeyStatus aStatus)
{
mData.mMonitor.AssertCurrentThreadOwns();
UsableKey key(aKeyId, aSessionId);
if (mData.mUsableKeyIds.Contains(key)) {
return false;
KeyStatus key(aKeyId, aSessionId, aStatus);
auto index = mData.mKeyStatuses.IndexOf(key);
if (aStatus == kGMPUnknown) {
// Return true if the element is found to notify key changes.
return mData.mKeyStatuses.RemoveElement(key);
}
mData.mUsableKeyIds.AppendElement(key);
if (index != mData.mKeyStatuses.NoIndex) {
if (mData.mKeyStatuses[index].mStatus == aStatus) {
return false;
}
mData.mKeyStatuses[index].mStatus = aStatus;
} else {
mData.mKeyStatuses.AppendElement(key);
}
if (aStatus != kGMPUsable) {
return true;
}
auto& waiters = mData.mWaitForKeys;
size_t i = 0;
while (i < waiters.Length()) {
@ -113,26 +129,6 @@ CDMCaps::AutoLock::SetKeyUsable(const CencKeyId& aKeyId,
return true;
}
bool
CDMCaps::AutoLock::SetKeyUnusable(const CencKeyId& aKeyId,
const nsString& aSessionId)
{
mData.mMonitor.AssertCurrentThreadOwns();
UsableKey key(aKeyId, aSessionId);
if (!mData.mUsableKeyIds.Contains(key)) {
return false;
}
auto& keys = mData.mUsableKeyIds;
for (size_t i = 0; i < keys.Length(); i++) {
if (keys[i].mId == aKeyId &&
keys[i].mSessionId == aSessionId) {
keys.RemoveElementAt(i);
break;
}
}
return true;
}
void
CDMCaps::AutoLock::NotifyWhenKeyIdUsable(const CencKeyId& aKey,
SamplesWaitingForKey* aListener)
@ -175,15 +171,15 @@ CDMCaps::AutoLock::CanDecryptVideo()
}
void
CDMCaps::AutoLock::GetUsableKeysForSession(const nsAString& aSessionId,
nsTArray<CencKeyId>& aOutKeyIds)
CDMCaps::AutoLock::GetKeyStatusesForSession(const nsAString& aSessionId,
nsTArray<KeyStatus>& aOutKeyStatuses)
{
for (size_t i = 0; i < mData.mUsableKeyIds.Length(); i++) {
const auto& key = mData.mUsableKeyIds[i];
for (size_t i = 0; i < mData.mKeyStatuses.Length(); i++) {
const auto& key = mData.mKeyStatuses[i];
if (key.mSessionId.Equals(aSessionId)) {
aOutKeyIds.AppendElement(key.mId);
aOutKeyStatuses.AppendElement(key);
}
}
}
} // namespace mozilla
} // namespace mozilla

View File

@ -14,6 +14,7 @@
#include "nsTArray.h"
#include "mozilla/Attributes.h"
#include "SamplesWaitingForKey.h"
#include "gmp-decryption.h"
namespace mozilla {
@ -24,6 +25,29 @@ public:
CDMCaps();
~CDMCaps();
struct KeyStatus {
KeyStatus(const CencKeyId& aId,
const nsString& aSessionId,
GMPMediaKeyStatus aStatus)
: mId(aId)
, mSessionId(aSessionId)
, mStatus(aStatus)
{}
KeyStatus(const KeyStatus& aOther)
: mId(aOther.mId)
, mSessionId(aOther.mSessionId)
, mStatus(aOther.mStatus)
{}
bool operator==(const KeyStatus& aOther) const {
return mId == aOther.mId &&
mSessionId == aOther.mSessionId;
};
CencKeyId mId;
nsString mSessionId;
GMPMediaKeyStatus mStatus;
};
// Locks the CDMCaps. It must be locked to access its shared state.
// Threadsafe when locked.
class MOZ_STACK_CLASS AutoLock {
@ -37,16 +61,12 @@ public:
bool IsKeyUsable(const CencKeyId& aKeyId);
// Returns true if setting this key usable results in the usable keys
// changing for this session, i.e. the key was not previously marked usable.
bool SetKeyUsable(const CencKeyId& aKeyId, const nsString& aSessionId);
// Returns true if key status changed,
// i.e. the key status changed from usable to expired.
bool SetKeyStatus(const CencKeyId& aKeyId, const nsString& aSessionId, GMPMediaKeyStatus aStatus);
// Returns true if setting this key unusable results in the usable keys
// changing for this session, i.e. the key was previously marked usable.
bool SetKeyUnusable(const CencKeyId& aKeyId, const nsString& aSessionId);
void GetUsableKeysForSession(const nsAString& aSessionId,
nsTArray<CencKeyId>& aOutKeyIds);
void GetKeyStatusesForSession(const nsAString& aSessionId,
nsTArray<KeyStatus>& aOutKeyStatuses);
// Sets the capabilities of the CDM. aCaps is the logical OR of the
// GMP_EME_CAP_* flags from gmp-decryption.h.
@ -85,25 +105,7 @@ private:
Monitor mMonitor;
struct UsableKey {
UsableKey(const CencKeyId& aId,
const nsString& aSessionId)
: mId(aId)
, mSessionId(aSessionId)
{}
UsableKey(const UsableKey& aOther)
: mId(aOther.mId)
, mSessionId(aOther.mSessionId)
{}
bool operator==(const UsableKey& aOther) const {
return mId == aOther.mId &&
mSessionId == aOther.mSessionId;
};
CencKeyId mId;
nsString mSessionId;
};
nsTArray<UsableKey> mUsableKeyIds;
nsTArray<KeyStatus> mKeyStatuses;
nsTArray<WaitForKeys> mWaitForKeys;

View File

@ -9,6 +9,7 @@
#include "mozilla/dom/MediaKeyError.h"
#include "mozilla/dom/MediaKeyMessageEvent.h"
#include "mozilla/dom/MediaEncryptedEvent.h"
#include "mozilla/dom/MediaKeyStatusMap.h"
#include "nsCycleCollectionParticipant.h"
#include "mozilla/CDMProxy.h"
#include "mozilla/AsyncEventDispatcher.h"
@ -22,6 +23,7 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED(MediaKeySession,
DOMEventTargetHelper,
mMediaKeyError,
mKeys,
mKeyStatusMap,
mClosed)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MediaKeySession)
@ -46,6 +48,7 @@ MediaKeySession::MediaKeySession(nsPIDOMWindow* aParent,
, mToken(sMediaKeySessionNum++)
, mIsClosed(false)
, mUninitialized(true)
, mKeyStatusMap(new MediaKeyStatusMap(aParent))
{
MOZ_ASSERT(aParent);
mClosed = mKeys->MakePromise(aRv);
@ -106,6 +109,30 @@ MediaKeySession::Closed() const
return mClosed;
}
void
MediaKeySession::UpdateKeyStatusMap()
{
MOZ_ASSERT(!IsClosed());
if (!mKeys->GetCDMProxy()) {
return;
}
nsTArray<CDMCaps::KeyStatus> keyStatuses;
{
CDMCaps::AutoLock caps(mKeys->GetCDMProxy()->Capabilites());
caps.GetKeyStatusesForSession(mSessionId, keyStatuses);
}
mKeyStatusMap->Update(keyStatuses);
}
MediaKeyStatusMap*
MediaKeySession::KeyStatuses() const
{
return mKeyStatusMap;
}
already_AddRefed<Promise>
MediaKeySession::GenerateRequest(const nsAString& aInitDataType,
const ArrayBufferViewOrArrayBuffer& aInitData,
@ -248,34 +275,6 @@ MediaKeySession::Remove(ErrorResult& aRv)
return promise.forget();
}
already_AddRefed<Promise>
MediaKeySession::GetUsableKeyIds(ErrorResult& aRv)
{
nsRefPtr<Promise> promise(mKeys->MakePromise(aRv));
if (aRv.Failed()) {
return nullptr;
}
if (IsClosed() || !mKeys->GetCDMProxy()) {
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
return promise.forget();
}
nsTArray<CencKeyId> keyIds;
{
CDMCaps::AutoLock caps(mKeys->GetCDMProxy()->Capabilites());
caps.GetUsableKeysForSession(mSessionId, keyIds);
}
nsTArray<TypedArrayCreator<ArrayBuffer>> array;
for (size_t i = 0; i < keyIds.Length(); i++) {
array.AppendElement(keyIds[i]);
}
promise->MaybeResolve(array);
return promise.forget();
}
void
MediaKeySession::DispatchKeyMessage(MediaKeyMessageType aMessageType,
const nsTArray<uint8_t>& aMessage)
@ -302,6 +301,9 @@ MediaKeySession::DispatchKeysChange()
if (IsClosed()) {
return;
}
UpdateKeyStatusMap();
nsRefPtr<AsyncEventDispatcher> asyncDispatcher =
new AsyncEventDispatcher(this, NS_LITERAL_STRING("keyschange"), false);
asyncDispatcher->PostDOMEvent();

View File

@ -30,6 +30,7 @@ namespace dom {
class ArrayBufferViewOrArrayBuffer;
class MediaKeyError;
class MediaKeyStatusMap;
class MediaKeySession MOZ_FINAL : public DOMEventTargetHelper
{
@ -51,6 +52,8 @@ public:
// Mark this as resultNotAddRefed to return raw pointers
MediaKeyError* GetError() const;
MediaKeyStatusMap* KeyStatuses() const;
void GetKeySystem(nsString& aRetval) const;
void GetSessionId(nsString& aRetval) const;
@ -78,8 +81,6 @@ public:
already_AddRefed<Promise> Remove(ErrorResult& aRv);
already_AddRefed<Promise> GetUsableKeyIds(ErrorResult& aRv);
void DispatchKeyMessage(MediaKeyMessageType aMessageType,
const nsTArray<uint8_t>& aMessage);
@ -97,6 +98,8 @@ public:
private:
~MediaKeySession();
void UpdateKeyStatusMap();
nsRefPtr<Promise> mClosed;
nsRefPtr<MediaKeyError> mMediaKeyError;
@ -107,6 +110,7 @@ private:
const uint32_t mToken;
bool mIsClosed;
bool mUninitialized;
nsRefPtr<MediaKeyStatusMap> mKeyStatusMap;
};
} // namespace dom

View File

@ -0,0 +1,245 @@
/* -*- 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/. */
#include "nsPIDOMWindow.h"
#include "mozilla/dom/MediaKeyStatusMap.h"
#include "mozilla/dom/UnionTypes.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTING_ADDREF(MediaKeyStatusMap)
NS_IMPL_CYCLE_COLLECTING_RELEASE(MediaKeyStatusMap)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MediaKeyStatusMap)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION_CLASS(MediaKeyStatusMap)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(MediaKeyStatusMap)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
tmp->mMap = nullptr;
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(MediaKeyStatusMap)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(MediaKeyStatusMap)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mMap)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
MediaKeyStatusMap::MediaKeyStatusMap(nsPIDOMWindow* aParent)
: mParent(aParent)
, mUpdateError(NS_OK)
{
AutoJSAPI jsapi;
if (NS_WARN_IF(!jsapi.Init(aParent))) {
mUpdateError = NS_ERROR_FAILURE;
return;
}
JSContext* cx = jsapi.cx();
mMap = JS::NewMapObject(cx);
if (NS_WARN_IF(!mMap)) {
mUpdateError = NS_ERROR_FAILURE;
}
}
MediaKeyStatusMap::~MediaKeyStatusMap()
{
}
JSObject*
MediaKeyStatusMap::WrapObject(JSContext* aCx)
{
return MediaKeyStatusMapBinding::Wrap(aCx, this);
}
nsPIDOMWindow*
MediaKeyStatusMap::GetParentObject() const
{
return mParent;
}
MediaKeyStatus
MediaKeyStatusMap::Get(JSContext* aCx,
const ArrayBufferViewOrArrayBuffer& aKey,
ErrorResult& aRv) const
{
if (NS_FAILED(mUpdateError)) {
aRv.Throw(mUpdateError);
return MediaKeyStatus::Internal_error;
}
JS::Rooted<JSObject*> map(aCx, mMap);
JS::Rooted<JS::Value> key(aCx);
JS::Rooted<JS::Value> val(aCx);
if (!aKey.ToJSVal(aCx, map, &key) ||
!JS::MapGet(aCx, map, key, &val)) {
aRv.Throw(NS_ERROR_FAILURE);
return MediaKeyStatus::Internal_error;
}
bool ok;
int index = FindEnumStringIndex<true>(
aCx, val, MediaKeyStatusValues::strings,
"MediaKeyStatus", "Invalid MediaKeyStatus value", &ok);
return ok ? static_cast<MediaKeyStatus>(index) :
MediaKeyStatus::Internal_error;
}
bool
MediaKeyStatusMap::Has(JSContext* aCx,
const ArrayBufferViewOrArrayBuffer& aKey,
ErrorResult& aRv) const
{
if (NS_FAILED(mUpdateError)) {
aRv.Throw(mUpdateError);
return false;
}
JS::Rooted<JSObject*> map(aCx, mMap);
JS::Rooted<JS::Value> key(aCx);
bool result = false;
if (!aKey.ToJSVal(aCx, map, &key) ||
!JS::MapHas(aCx, map, key, &result)) {
aRv.Throw(NS_ERROR_FAILURE);
}
return result;
}
template<decltype(JS::MapKeys) Method>
static void CallMapMethod(JSContext* aCx,
const JS::Heap<JSObject*>& aMap,
JS::MutableHandle<JSObject*> aResult,
ErrorResult& aRv,
nsresult aUpdateError)
{
if (NS_FAILED(aUpdateError)) {
aRv.Throw(aUpdateError);
return;
}
JS::Rooted<JSObject*> map(aCx, aMap);
JS::Rooted<JS::Value> result(aCx);
if (!Method(aCx, map, &result)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
aResult.set(&result.toObject());
}
void
MediaKeyStatusMap::Keys(JSContext* aCx,
JS::MutableHandle<JSObject*> aResult,
ErrorResult& aRv) const
{
CallMapMethod<JS::MapKeys>(aCx, mMap, aResult, aRv, mUpdateError);
}
void
MediaKeyStatusMap::Values(JSContext* aCx,
JS::MutableHandle<JSObject*> aResult,
ErrorResult& aRv) const
{
CallMapMethod<JS::MapValues>(aCx, mMap, aResult, aRv, mUpdateError);
}
void
MediaKeyStatusMap::Entries(JSContext* aCx,
JS::MutableHandle<JSObject*> aResult,
ErrorResult& aRv) const
{
CallMapMethod<JS::MapEntries>(aCx, mMap, aResult, aRv, mUpdateError);
}
uint32_t
MediaKeyStatusMap::GetSize(JSContext* aCx, ErrorResult& aRv) const
{
if (NS_FAILED(mUpdateError)) {
aRv.Throw(mUpdateError);
return 0;
}
JS::Rooted<JSObject*> map(aCx, mMap);
return JS::MapSize(aCx, map);
}
static MediaKeyStatus
ToMediaKeyStatus(GMPMediaKeyStatus aStatus) {
switch (aStatus) {
case kGMPUsable: return MediaKeyStatus::Usable;
case kGMPExpired: return MediaKeyStatus::Expired;
case kGMPOutputNotAllowed: return MediaKeyStatus::Output_not_allowed;
default: return MediaKeyStatus::Internal_error;
}
}
static bool
ToJSString(JSContext* aCx, GMPMediaKeyStatus aStatus,
JS::MutableHandle<JS::Value> aResult)
{
auto val = uint32_t(ToMediaKeyStatus(aStatus));
MOZ_ASSERT(val < ArrayLength(MediaKeyStatusValues::strings));
JSString* str = JS_NewStringCopyN(aCx,
MediaKeyStatusValues::strings[val].value,
MediaKeyStatusValues::strings[val].length);
if (!str) {
return false;
}
aResult.setString(str);
return true;
}
nsresult
MediaKeyStatusMap::UpdateInternal(const nsTArray<CDMCaps::KeyStatus>& keys)
{
AutoJSAPI jsapi;
if (!mMap || NS_WARN_IF(!jsapi.Init(mParent))) {
return NS_ERROR_FAILURE;
}
jsapi.TakeOwnershipOfErrorReporting();
JSContext* cx = jsapi.cx();
JS::Rooted<JSObject*> map(cx, mMap);
if (!JS::MapClear(cx, map)) {
return NS_ERROR_FAILURE;
}
for (size_t i = 0; i < keys.Length(); i++) {
const auto& ks = keys[i];
JS::Rooted<JS::Value> key(cx);
JS::Rooted<JS::Value> val(cx);
if (!ToJSValue(cx, TypedArrayCreator<ArrayBuffer>(ks.mId), &key) ||
!ToJSString(cx, ks.mStatus, &val) ||
!JS::MapSet(cx, map, key, val)) {
return NS_ERROR_OUT_OF_MEMORY;
}
}
return NS_OK;
}
void
MediaKeyStatusMap::Update(const nsTArray<CDMCaps::KeyStatus>& keys)
{
// Since we can't leave the map in a partial update state, we need
// to remember the error and throw it next time the interface methods
// are called.
mUpdateError = UpdateInternal(keys);
}
} // namespace dom
} // namespace mozilla

View File

@ -0,0 +1,78 @@
/* -*- 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_dom_MediaKeyStatuses_h
#define mozilla_dom_MediaKeyStatuses_h
#include "mozilla/ErrorResult.h"
#include "mozilla/Attributes.h"
#include "nsCycleCollectionParticipant.h"
#include "nsWrapperCache.h"
#include "mozilla/dom/TypedArray.h"
#include "mozilla/dom/MediaKeyStatusMapBinding.h"
#include "mozilla/CDMCaps.h"
class nsPIDOMWindow;
class ArrayBufferViewOrArrayBuffer;
namespace mozilla {
namespace dom {
class MediaKeyStatusMap MOZ_FINAL : public nsISupports,
public nsWrapperCache
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MediaKeyStatusMap)
public:
explicit MediaKeyStatusMap(nsPIDOMWindow* aParent);
protected:
~MediaKeyStatusMap();
public:
nsPIDOMWindow* GetParentObject() const;
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
MediaKeyStatus Get(JSContext* aCx,
const ArrayBufferViewOrArrayBuffer& aKey,
ErrorResult& aRv) const;
bool Has(JSContext* aCx,
const ArrayBufferViewOrArrayBuffer& aKey,
ErrorResult& aRv) const;
void Keys(JSContext* aCx,
JS::MutableHandle<JSObject*> aResult,
ErrorResult& aRv) const;
void Values(JSContext* aCx,
JS::MutableHandle<JSObject*> aResult,
ErrorResult& aRv) const;
void Entries(JSContext* aCx,
JS::MutableHandle<JSObject*> aResult,
ErrorResult& aRv) const;
uint32_t GetSize(JSContext* aCx, ErrorResult& aRv) const;
void Update(const nsTArray<CDMCaps::KeyStatus>& keys);
private:
nsresult UpdateInternal(const nsTArray<CDMCaps::KeyStatus>& keys);
nsCOMPtr<nsPIDOMWindow> mParent;
JS::Heap<JSObject*> mMap;
nsresult mUpdateError;
};
} // namespace dom
} // namespace mozilla
#endif

View File

@ -10,6 +10,7 @@ EXPORTS.mozilla.dom += [
'MediaKeyMessageEvent.h',
'MediaKeys.h',
'MediaKeySession.h',
'MediaKeyStatusMap.h',
'MediaKeySystemAccess.h',
]
@ -30,6 +31,7 @@ UNIFIED_SOURCES += [
'MediaKeyMessageEvent.cpp',
'MediaKeys.cpp',
'MediaKeySession.cpp',
'MediaKeyStatusMap.cpp',
'MediaKeySystemAccess.cpp',
]

View File

@ -1,5 +1,5 @@
Name: fake
Description: Fake GMP Plugin
Version: 1.0
APIs: encode-video[h264], decode-video[h264], eme-decrypt-v4[fake]
APIs: encode-video[h264], decode-video[h264], eme-decrypt-v5[fake]
Libraries: dxva2.dll

View File

@ -126,27 +126,17 @@ GMPDecryptorChild::SessionError(const char* aSessionId,
}
void
GMPDecryptorChild::KeyIdUsable(const char* aSessionId,
uint32_t aSessionIdLength,
const uint8_t* aKeyId,
uint32_t aKeyIdLength)
GMPDecryptorChild::KeyStatusChanged(const char* aSessionId,
uint32_t aSessionIdLength,
const uint8_t* aKeyId,
uint32_t aKeyIdLength,
GMPMediaKeyStatus aStatus)
{
nsAutoTArray<uint8_t, 16> kid;
kid.AppendElements(aKeyId, aKeyIdLength);
CALL_ON_GMP_THREAD(SendKeyIdUsable,
nsAutoCString(aSessionId, aSessionIdLength), kid);
}
void
GMPDecryptorChild::KeyIdNotUsable(const char* aSessionId,
uint32_t aSessionIdLength,
const uint8_t* aKeyId,
uint32_t aKeyIdLength)
{
nsAutoTArray<uint8_t, 16> kid;
kid.AppendElements(aKeyId, aKeyIdLength);
CALL_ON_GMP_THREAD(SendKeyIdNotUsable,
nsAutoCString(aSessionId, aSessionIdLength), kid);
CALL_ON_GMP_THREAD(SendKeyStatusChanged,
nsAutoCString(aSessionId, aSessionIdLength), kid,
aStatus);
}
void

View File

@ -63,15 +63,11 @@ public:
const char* aMessage,
uint32_t aMessageLength) MOZ_OVERRIDE;
virtual void KeyIdUsable(const char* aSessionId,
uint32_t aSessionIdLength,
const uint8_t* aKeyId,
uint32_t aKeyIdLength) MOZ_OVERRIDE;
virtual void KeyIdNotUsable(const char* aSessionId,
uint32_t aSessionIdLength,
const uint8_t* aKeyId,
uint32_t aKeyIdLength) MOZ_OVERRIDE;
virtual void KeyStatusChanged(const char* aSessionId,
uint32_t aSessionIdLength,
const uint8_t* aKeyId,
uint32_t aKeyIdLength,
GMPMediaKeyStatus aStatus) MOZ_OVERRIDE;
virtual void SetCapabilities(uint64_t aCaps) MOZ_OVERRIDE;

View File

@ -265,26 +265,15 @@ GMPDecryptorParent::RecvSessionError(const nsCString& aSessionId,
}
bool
GMPDecryptorParent::RecvKeyIdUsable(const nsCString& aSessionId,
InfallibleTArray<uint8_t>&& aKeyId)
GMPDecryptorParent::RecvKeyStatusChanged(const nsCString& aSessionId,
InfallibleTArray<uint8_t>&& aKeyId,
const GMPMediaKeyStatus& aStatus)
{
if (!mIsOpen) {
NS_WARNING("Trying to use a dead GMP decrypter!");
return false;
}
mCallback->KeyIdUsable(aSessionId, aKeyId);
return true;
}
bool
GMPDecryptorParent::RecvKeyIdNotUsable(const nsCString& aSessionId,
InfallibleTArray<uint8_t>&& aKeyId)
{
if (!mIsOpen) {
NS_WARNING("Trying to use a dead GMP decrypter!");
return false;
}
mCallback->KeyIdNotUsable(aSessionId, aKeyId);
mCallback->KeyStatusChanged(aSessionId, aKeyId, aStatus);
return true;
}

View File

@ -91,11 +91,9 @@ private:
const uint32_t& aSystemCode,
const nsCString& aMessage) MOZ_OVERRIDE;
virtual bool RecvKeyIdUsable(const nsCString& aSessionId,
InfallibleTArray<uint8_t>&& aKeyId) MOZ_OVERRIDE;
virtual bool RecvKeyIdNotUsable(const nsCString& aSessionId,
InfallibleTArray<uint8_t>&& aKeyId) MOZ_OVERRIDE;
virtual bool RecvKeyStatusChanged(const nsCString& aSessionId,
InfallibleTArray<uint8_t>&& aKeyId,
const GMPMediaKeyStatus& aStatus) MOZ_OVERRIDE;
virtual bool RecvDecrypted(const uint32_t& aId,
const GMPErr& aErr,

View File

@ -44,11 +44,9 @@ public:
uint32_t aSystemCode,
const nsCString& aMessage) = 0;
virtual void KeyIdUsable(const nsCString& aSessionId,
const nsTArray<uint8_t>& aKeyId) = 0;
virtual void KeyIdNotUsable(const nsCString& aSessionId,
const nsTArray<uint8_t>& aKeyId) = 0;
virtual void KeyStatusChanged(const nsCString& aSessionId,
const nsTArray<uint8_t>& aKeyId,
GMPMediaKeyStatus aStatus) = 0;
virtual void SetCaps(uint64_t aCaps) = 0;

View File

@ -60,6 +60,13 @@ struct ParamTraits<GMPSessionMessageType>
kGMPMessageInvalid>
{};
template <>
struct ParamTraits<GMPMediaKeyStatus>
: public ContiguousEnumSerializer<GMPMediaKeyStatus,
kGMPUsable,
kGMPMediaKeyStatusInvalid>
{};
template <>
struct ParamTraits<GMPSessionType>
: public ContiguousEnumSerializer<GMPSessionType,

View File

@ -7,6 +7,7 @@ include protocol PGMP;
include GMPTypes;
using GMPSessionMessageType from "gmp-decryption.h";
using GMPMediaKeyStatus from "gmp-decryption.h";
using GMPSessionType from "gmp-decryption.h";
using GMPDOMException from "gmp-decryption.h";
using GMPErr from "gmp-errors.h";
@ -77,12 +78,11 @@ parent:
uint32_t aSystemCode,
nsCString aMessage);
KeyIdUsable(nsCString aSessionId, uint8_t[] aKey);
KeyStatusChanged(nsCString aSessionId, uint8_t[] aKey,
GMPMediaKeyStatus aStatus);
SetCaps(uint64_t aCaps);
KeyIdNotUsable(nsCString aSessionId,uint8_t[] aKey);
Decrypted(uint32_t aId, GMPErr aResult, uint8_t[] aBuffer);
};

View File

@ -76,6 +76,14 @@ enum GMPSessionMessageType {
kGMPMessageInvalid = 4 // Must always be last.
};
enum GMPMediaKeyStatus {
kGMPUsable = 0,
kGMPExpired = 1,
kGMPOutputNotAllowed = 2,
kGMPUnknown = 3,
kGMPMediaKeyStatusInvalid = 4 // Must always be last.
};
// Time in milliseconds, as offset from epoch, 1 Jan 1970.
typedef int64_t GMPTimestamp;
@ -173,20 +181,14 @@ public:
const char* aMessage,
uint32_t aMessageLength) = 0;
// Marks a key as usable. Gecko will not call into the CDM to decrypt
// Notifies the status of a key. Gecko will not call into the CDM to decrypt
// or decode content encrypted with a key unless the CDM has marked it
// usable first. So a CDM *MUST* mark its usable keys as usable!
virtual void KeyIdUsable(const char* aSessionId,
uint32_t aSessionIdLength,
const uint8_t* aKeyId,
uint32_t aKeyIdLength) = 0;
// Marks a key as no longer usable.
// Note: Keys are assumed to be not usable when a session is closed or removed.
virtual void KeyIdNotUsable(const char* aSessionId,
uint32_t aSessionIdLength,
const uint8_t* aKeyId,
uint32_t aKeyIdLength) = 0;
virtual void KeyStatusChanged(const char* aSessionId,
uint32_t aSessionIdLength,
const uint8_t* aKeyId,
uint32_t aKeyIdLength,
GMPMediaKeyStatus aStatus) = 0;
// The CDM must report its capabilites of this CDM. aCaps should be a
// logical OR of the GMP_EME_CAP_* flags. The CDM *MUST* call this
@ -220,7 +222,7 @@ enum GMPSessionType {
kGMPSessionInvalid = 2 // Must always be last.
};
#define GMP_API_DECRYPTOR "eme-decrypt-v4"
#define GMP_API_DECRYPTOR "eme-decrypt-v5"
// API exposed by plugin library to manage decryption sessions.
// When the Host requests this by calling GMPGetAPIFunc().

View File

@ -1116,10 +1116,9 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
nsresult aException,
uint32_t aSystemCode,
const nsCString& aMessage) MOZ_OVERRIDE {}
virtual void KeyIdUsable(const nsCString& aSessionId,
const nsTArray<uint8_t>& aKeyId) MOZ_OVERRIDE { }
virtual void KeyIdNotUsable(const nsCString& aSessionId,
const nsTArray<uint8_t>& aKeyId) MOZ_OVERRIDE {}
virtual void KeyStatusChanged(const nsCString& aSessionId,
const nsTArray<uint8_t>& aKeyId,
GMPMediaKeyStatus aStatus) MOZ_OVERRIDE { }
virtual void SetCaps(uint64_t aCaps) MOZ_OVERRIDE {}
virtual void Decrypted(uint32_t aId,
GMPErr aResult,

View File

@ -341,19 +341,14 @@ MediaSource::Enabled(JSContext* cx, JSObject* aGlobal)
}
// We want to restrict to YouTube only.
// We define that as the origin being https://*.youtube.com.
// We also support https://*.youtube-nocookie.com.
// We define that as the origin being *.youtube.com.
// We also support *.youtube-nocookie.com
nsIPrincipal* principal = nsContentUtils::ObjectPrincipal(global);
nsCOMPtr<nsIURI> uri;
if (NS_FAILED(principal->GetURI(getter_AddRefs(uri))) || !uri) {
return false;
}
bool isHttps = false;
if (NS_FAILED(uri->SchemeIs("https", &isHttps)) || !isHttps) {
return false;
}
nsCOMPtr<nsIEffectiveTLDService> tldServ =
do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
NS_ENSURE_TRUE(tldServ, false);

View File

@ -225,10 +225,8 @@ MediaSourceReader::OnAudioNotDecoded(NotDecodedReason aReason)
AdjustEndTime(&mLastAudioTime, mAudioReader);
}
// See if we can find a different reader that can pick up where we left off. We use the
// EOS_FUZZ_US to allow for the fact that our end time can be inaccurate due to bug
// 1065207.
if (SwitchAudioReader(mLastAudioTime, EOS_FUZZ_US) == READER_NEW) {
// See if we can find a different reader that can pick up where we left off.
if (SwitchAudioReader(mLastAudioTime) == READER_NEW) {
mAudioSeekRequest.Begin(mAudioReader->Seek(mLastAudioTime, 0)
->RefableThen(GetTaskQueue(), __func__, this,
&MediaSourceReader::CompleteAudioSeekAndDoRequest,
@ -337,10 +335,8 @@ MediaSourceReader::OnVideoNotDecoded(NotDecodedReason aReason)
AdjustEndTime(&mLastVideoTime, mVideoReader);
}
// See if we can find a different reader that can pick up where we left off. We use the
// EOS_FUZZ_US to allow for the fact that our end time can be inaccurate due to bug
// 1065207.
if (SwitchVideoReader(mLastVideoTime, EOS_FUZZ_US) == READER_NEW) {
// See if we can find a different reader that can pick up where we left off.
if (SwitchVideoReader(mLastVideoTime) == READER_NEW) {
mVideoSeekRequest.Begin(mVideoReader->Seek(mLastVideoTime, 0)
->RefableThen(GetTaskQueue(), __func__, this,
&MediaSourceReader::CompleteVideoSeekAndDoRequest,
@ -437,7 +433,7 @@ MediaSourceReader::BreakCycles()
already_AddRefed<MediaDecoderReader>
MediaSourceReader::SelectReader(int64_t aTarget,
int64_t aError,
int64_t aTolerance,
const nsTArray<nsRefPtr<SourceBufferDecoder>>& aTrackDecoders)
{
mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
@ -450,7 +446,7 @@ MediaSourceReader::SelectReader(int64_t aTarget,
nsRefPtr<dom::TimeRanges> ranges = new dom::TimeRanges();
aTrackDecoders[i]->GetBuffered(ranges);
if (ranges->Find(double(aTarget) / USECS_PER_S,
double(aError) / USECS_PER_S) == dom::TimeRanges::NoIndex) {
double(aTolerance) / USECS_PER_S) == dom::TimeRanges::NoIndex) {
MSE_DEBUGV("MediaSourceReader(%p)::SelectReader(%lld) newReader=%p target not in ranges=%s",
this, aTarget, newReader.get(), DumpTimeRanges(ranges).get());
continue;
@ -472,14 +468,21 @@ MediaSourceReader::HaveData(int64_t aTarget, MediaData::Type aType)
}
MediaSourceReader::SwitchReaderResult
MediaSourceReader::SwitchAudioReader(int64_t aTarget, int64_t aError)
MediaSourceReader::SwitchAudioReader(int64_t aTarget)
{
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
// XXX: Can't handle adding an audio track after ReadMetadata.
if (!mAudioTrack) {
return READER_ERROR;
}
nsRefPtr<MediaDecoderReader> newReader = SelectReader(aTarget, aError, mAudioTrack->Decoders());
// We first search without the tolerance and then search with it, so that, in
// the case of perfectly-aligned data, we don't prematurely jump to a new
// reader and skip the last few samples of the current one.
nsRefPtr<MediaDecoderReader> newReader = SelectReader(aTarget, /* aTolerance = */ 0, mAudioTrack->Decoders());
if (!newReader) {
newReader = SelectReader(aTarget, EOS_FUZZ_US, mAudioTrack->Decoders());
}
if (newReader && newReader != mAudioReader) {
mAudioReader->SetIdle();
mAudioReader = newReader;
@ -490,14 +493,21 @@ MediaSourceReader::SwitchAudioReader(int64_t aTarget, int64_t aError)
}
MediaSourceReader::SwitchReaderResult
MediaSourceReader::SwitchVideoReader(int64_t aTarget, int64_t aError)
MediaSourceReader::SwitchVideoReader(int64_t aTarget)
{
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
// XXX: Can't handle adding a video track after ReadMetadata.
if (!mVideoTrack) {
return READER_ERROR;
}
nsRefPtr<MediaDecoderReader> newReader = SelectReader(aTarget, aError, mVideoTrack->Decoders());
// We first search without the tolerance and then search with it, so that, in
// the case of perfectly-aligned data, we don't prematurely jump to a new
// reader and skip the last few samples of the current one.
nsRefPtr<MediaDecoderReader> newReader = SelectReader(aTarget, /* aTolerance = */ 0, mVideoTrack->Decoders());
if (!newReader) {
newReader = SelectReader(aTarget, EOS_FUZZ_US, mVideoTrack->Decoders());
}
if (newReader && newReader != mVideoReader) {
mVideoReader->SetIdle();
mVideoReader = newReader;
@ -632,10 +642,10 @@ bool
MediaSourceReader::TrackBuffersContainTime(int64_t aTime)
{
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
if (mAudioTrack && !mAudioTrack->ContainsTime(aTime)) {
if (mAudioTrack && !mAudioTrack->ContainsTime(aTime, EOS_FUZZ_US)) {
return false;
}
if (mVideoTrack && !mVideoTrack->ContainsTime(aTime)) {
if (mVideoTrack && !mVideoTrack->ContainsTime(aTime, EOS_FUZZ_US)) {
return false;
}
return true;

View File

@ -155,15 +155,16 @@ public:
private:
// Switch the current audio/video reader to the reader that
// contains aTarget (or up to aError after target). Both
// aTarget and aError are in microseconds.
// contains aTarget (or up to aTolerance after target). Both
// aTarget and aTolerance are in microseconds.
enum SwitchReaderResult {
READER_ERROR = -1,
READER_EXISTING = 0,
READER_NEW = 1,
};
SwitchReaderResult SwitchAudioReader(int64_t aTarget, int64_t aError = 0);
SwitchReaderResult SwitchVideoReader(int64_t aTarget, int64_t aError = 0);
SwitchReaderResult SwitchAudioReader(int64_t aTarget);
SwitchReaderResult SwitchVideoReader(int64_t aTarget);
void DoAudioRequest();
void DoVideoRequest();
@ -199,7 +200,7 @@ private:
// Return a reader from the set available in aTrackDecoders that has data
// available in the range requested by aTarget.
already_AddRefed<MediaDecoderReader> SelectReader(int64_t aTarget,
int64_t aError,
int64_t aTolerance,
const nsTArray<nsRefPtr<SourceBufferDecoder>>& aTrackDecoders);
bool HaveData(int64_t aTarget, MediaData::Type aType);

View File

@ -584,13 +584,14 @@ TrackBuffer::IsReady()
}
bool
TrackBuffer::ContainsTime(int64_t aTime)
TrackBuffer::ContainsTime(int64_t aTime, int64_t aTolerance)
{
ReentrantMonitorAutoEnter mon(mParentDecoder->GetReentrantMonitor());
for (uint32_t i = 0; i < mInitializedDecoders.Length(); ++i) {
nsRefPtr<dom::TimeRanges> r = new dom::TimeRanges();
mInitializedDecoders[i]->GetBuffered(r);
if (r->Find(double(aTime) / USECS_PER_S) != dom::TimeRanges::NoIndex) {
if (r->Find(double(aTime) / USECS_PER_S,
double(aTolerance) / USECS_PER_S) != dom::TimeRanges::NoIndex) {
return true;
}
}

View File

@ -76,7 +76,7 @@ public:
// Returns true if any of the decoders managed by this track buffer
// contain aTime in their buffered ranges.
bool ContainsTime(int64_t aTime);
bool ContainsTime(int64_t aTime, int64_t aTolerance);
void BreakCycles();

View File

@ -31,14 +31,17 @@ function UsableKeyIdsMatch(usableKeyIds, expectedKeyIds) {
function AwaitAllKeysUsable(session, keys, token) {
return new Promise(function(resolve, reject) {
function listener(event) {
session.getUsableKeyIds().then(function(usableKeyIds) {
var u = UsableKeyIdsMatch(usableKeyIds, keys);
if (UsableKeyIdsMatch(usableKeyIds, keys)) {
Log(token, "resolving AwaitAllKeysUsable promise");
session.removeEventListener("keyschange", listener);
resolve();
}
}, bail(token + " failed to get usableKeyIds"));
var map = session.keyStatuses;
var usableKeyIds = [];
for (var [key, val] of map.entries()) {
is(val, "usable", token + ": key status should be usable");
usableKeyIds.push(key);
}
if (UsableKeyIdsMatch(usableKeyIds, keys)) {
Log(token, "resolving AwaitAllKeysUsable promise");
session.removeEventListener("keyschange", listener);
resolve();
}
}
session.addEventListener("keyschange", listener);
});
@ -47,12 +50,11 @@ function AwaitAllKeysUsable(session, keys, token) {
function AwaitAllKeysNotUsable(session, token) {
return new Promise(function(resolve, reject) {
function listener(event) {
session.getUsableKeyIds().then(function(usableKeyIds) {
if (usableKeyIds.length == 0) {
session.removeEventListener("keyschange", listener);
resolve();
}
}, bail(token + " failed to get usableKeyIds"));
var map = session.keyStatuses;
if (map.size == 0) {
session.removeEventListener("keyschange", listener);
resolve();
}
}
session.addEventListener("keyschange", listener);
});

View File

@ -22,13 +22,14 @@ function KeysChangeFunc(session, keys, token) {
return function(ev) {
var session = ev.target;
session.gotKeysChanged = true;
session.getUsableKeyIds().then(function(keyIds) {
for (var k = 0; k < keyIds.length; k++) {
var kid = Base64ToHex(window.btoa(ArrayBufferToString(keyIds[k])));
ok(kid in session.keyIdsReceived, TimeStamp(token) + " session.keyIdsReceived contained " + kid + " as expected.");
session.keyIdsReceived[kid] = true;
}
}, bail("Failed to get keyIds"));
var map = session.keyStatuses;
for (var [key, val] of map.entries()) {
is(val, "usable", token + ": key status should be usable");
var kid = Base64ToHex(window.btoa(ArrayBufferToString(key)));
ok(kid in session.keyIdsReceived, TimeStamp(token) + " session.keyIdsReceived contained " + kid + " as expected.");
session.keyIdsReceived[kid] = true;
}
}
}

View File

@ -43,20 +43,29 @@ skip-if = (toolkit == 'gonk' && debug) # debug-only failure, turned an intermitt
[test_getUserMedia_constraints.html]
skip-if = toolkit == 'gonk' || toolkit == 'android' # Bug 907352, backwards-compatible behavior on mobile only
[test_getUserMedia_constraints_mobile.html]
skip-if = toolkit != 'gonk' && toolkit != 'android' # Bug 907352, backwards-compatible behavior on mobile only
skip-if = toolkit != 'android' # Bug 1063290, intermittent timeout # Bug 907352, backwards-compatible behavior on mobile only
[test_getUserMedia_callbacks.html]
skip-if = toolkit == 'gonk' # Bug 1063290, intermittent timeout
[test_getUserMedia_gumWithinGum.html]
skip-if = toolkit == 'gonk' # Bug 1063290, intermittent timeout
[test_getUserMedia_playAudioTwice.html]
skip-if = toolkit == 'gonk' # Bug 1063290, intermittent timeout
[test_getUserMedia_playVideoAudioTwice.html]
skip-if = (toolkit == 'gonk' && debug) # debug-only failure; bug 926558
skip-if = toolkit == 'gonk' # Bug 1063290, intermittent timeout # bug 926558, debug-only failure
[test_getUserMedia_playVideoTwice.html]
skip-if = toolkit == 'gonk' # Bug 1063290, intermittent timeout
[test_getUserMedia_stopAudioStream.html]
skip-if = toolkit == 'gonk' # Bug 1063290, intermittent timeout
[test_getUserMedia_stopAudioStreamWithFollowupAudio.html]
skip-if = toolkit == 'gonk' # Bug 1063290, intermittent timeout
[test_getUserMedia_stopVideoAudioStream.html]
skip-if = (toolkit == 'gonk' && debug) # debug-only failure
skip-if = toolkit == 'gonk' # Bug 1063290, intermittent timeout # bug 926558, debug-only failure
[test_getUserMedia_stopVideoAudioStreamWithFollowupVideoAudio.html]
skip-if = toolkit == 'gonk' # Bug 1063290, intermittent timeout
[test_getUserMedia_stopVideoStream.html]
skip-if = toolkit == 'gonk' # Bug 1063290, intermittent timeout
[test_getUserMedia_stopVideoStreamWithFollowupVideo.html]
skip-if = toolkit == 'gonk' # Bug 1063290, intermittent timeout
[test_getUserMedia_peerIdentity.html]
skip-if = toolkit == 'gonk' # b2g(Bug 1021776, too --ing slow on b2g)
[test_peerConnection_addCandidateInHaveLocalOffer.html]

View File

@ -200,6 +200,16 @@ MediaEngineGonkVideoSource::Start(SourceMediaStream* aStream, TrackID aID)
return NS_ERROR_FAILURE;
}
nsTArray<nsString> focusModes;
mCameraControl->Get(CAMERA_PARAM_SUPPORTED_FOCUSMODES, focusModes);
for (nsTArray<nsString>::index_type i = 0; i < focusModes.Length(); ++i) {
if (focusModes[i].EqualsASCII("continuous-video")) {
mCameraControl->Set(CAMERA_PARAM_FOCUSMODE, focusModes[i]);
mCameraControl->ResumeContinuousFocus();
break;
}
}
if (NS_FAILED(InitDirectMediaBuffer())) {
return NS_ERROR_FAILURE;
}
@ -424,15 +434,6 @@ MediaEngineGonkVideoSource::StartImpl(webrtc::CaptureCapability aCapability) {
mCameraControl->Start(&config);
mCameraControl->Set(CAMERA_PARAM_PICTURE_SIZE, config.mPreviewSize);
nsTArray<nsString> focusModes;
mCameraControl->Get(CAMERA_PARAM_SUPPORTED_FOCUSMODES, focusModes);
for (nsTArray<nsString>::index_type i = 0; i < focusModes.Length(); ++i) {
if (focusModes[i].EqualsASCII("continuous-video")) {
mCameraControl->Set(CAMERA_PARAM_FOCUSMODE, focusModes[i]);
break;
}
}
hal::RegisterScreenConfigurationObserver(this);
}

View File

@ -535,8 +535,10 @@ nsresult nsNPAPIPluginInstance::SetWindow(NPWindow* window)
#if MOZ_WIDGET_GTK
// bug 108347, flash plugin on linux doesn't like window->width <=
// 0, but Java needs wants this call.
if (!nsPluginHost::IsJavaMIMEType(mMIMEType) && window->type == NPWindowTypeWindow &&
(window->width <= 0 || window->height <= 0)) {
if (window && window->type == NPWindowTypeWindow &&
(window->width <= 0 || window->height <= 0) &&
(nsPluginHost::GetSpecialType(nsDependentCString(mMIMEType)) !=
nsPluginHost::eSpecialType_Java)) {
return NS_OK;
}
#endif
@ -749,8 +751,8 @@ NPError nsNPAPIPluginInstance::SetWindowless(bool aWindowless)
// property. (Last tested version: sl 4.0).
// Changes to this code should be matched with changes in
// PluginInstanceChild::InitQuirksMode.
NS_NAMED_LITERAL_CSTRING(silverlight, "application/x-silverlight");
if (!PL_strncasecmp(mMIMEType, silverlight.get(), silverlight.Length())) {
if (nsPluginHost::GetSpecialType(nsDependentCString(mMIMEType)) ==
nsPluginHost::eSpecialType_Silverlight) {
mTransparent = true;
}
}

View File

@ -1652,19 +1652,43 @@ nsPluginHost::SiteHasData(nsIPluginTag* plugin, const nsACString& domain,
return NS_OK;
}
bool nsPluginHost::IsJavaMIMEType(const char* aType)
nsPluginHost::SpecialType
nsPluginHost::GetSpecialType(const nsACString & aMIMEType)
{
if (aMIMEType.LowerCaseEqualsASCII("application/x-shockwave-flash") ||
aMIMEType.LowerCaseEqualsASCII("application/futuresplash")) {
return eSpecialType_Flash;
}
if (aMIMEType.LowerCaseEqualsASCII("application/x-silverlight") ||
aMIMEType.LowerCaseEqualsASCII("application/x-silverlight-2")) {
return eSpecialType_Silverlight;
}
if (aMIMEType.LowerCaseEqualsASCII("audio/x-pn-realaudio-plugin")) {
NS_WARNING("You are loading RealPlayer");
return eSpecialType_RealPlayer;
}
if (aMIMEType.LowerCaseEqualsASCII("application/pdf")) {
return eSpecialType_PDF;
}
// Java registers variants of its MIME with parameters, e.g.
// application/x-java-vm;version=1.3
const nsACString &noParam = Substring(aMIMEType, 0, aMIMEType.FindChar(';'));
// The java mime pref may well not be one of these,
// e.g. application/x-java-test used in the test suite
nsAdoptingCString javaMIME = Preferences::GetCString(kPrefJavaMIME);
return aType &&
(javaMIME.EqualsIgnoreCase(aType) ||
(0 == PL_strncasecmp(aType, "application/x-java-vm",
sizeof("application/x-java-vm") - 1)) ||
(0 == PL_strncasecmp(aType, "application/x-java-applet",
sizeof("application/x-java-applet") - 1)) ||
(0 == PL_strncasecmp(aType, "application/x-java-bean",
sizeof("application/x-java-bean") - 1)));
if ((!javaMIME.IsEmpty() && noParam.LowerCaseEqualsASCII(javaMIME)) ||
noParam.LowerCaseEqualsASCII("application/x-java-vm") ||
noParam.LowerCaseEqualsASCII("application/x-java-applet") ||
noParam.LowerCaseEqualsASCII("application/x-java-bean")) {
return eSpecialType_Java;
}
return eSpecialType_None;
}
// Check whether or not a tag is a live, valid tag, and that it's loaded.

View File

@ -171,9 +171,20 @@ public:
// Always returns true if plugin.allowed_types is not set
static bool IsTypeWhitelisted(const char *aType);
// checks whether aTag is a "java" plugin tag (a tag for a plugin
// that does Java)
static bool IsJavaMIMEType(const char *aType);
// checks whether aType is a type we recognize for potential special handling
enum SpecialType { eSpecialType_None,
// Informs some decisions about OOP and quirks
eSpecialType_Flash,
// Binds to the <applet> tag, has various special
// rules around opening channels, codebase, ...
eSpecialType_Java,
// Some IPC quirks
eSpecialType_Silverlight,
// Native widget quirks
eSpecialType_PDF,
// Native widget quirks
eSpecialType_RealPlayer };
static SpecialType GetSpecialType(const nsACString & aMIMEType);
static nsresult PostPluginUnloadEvent(PRLibrary* aLibrary);

View File

@ -1096,10 +1096,10 @@ void nsPluginInstanceOwner::AddToCARefreshTimer() {
// Flash invokes InvalidateRect for us.
const char* mime = nullptr;
if (NS_SUCCEEDED(mInstance->GetMIMEType(&mime)) && mime) {
if (strcmp(mime, "application/x-shockwave-flash") == 0) {
return;
}
if (NS_SUCCEEDED(mInstance->GetMIMEType(&mime)) && mime &&
nsPluginHost::GetSpecialType(nsDependentCString(mime)) ==
nsPluginHost::eSpecialType_Flash) {
return;
}
if (!sCARefreshListeners) {

View File

@ -97,16 +97,8 @@ void PluginWindowEvent::Init(const PluginWindowWeakRef &ref, HWND aWnd,
* nsPluginNativeWindow Windows specific class declaration
*/
typedef enum {
nsPluginType_Unknown = 0,
nsPluginType_Flash,
nsPluginType_Real,
nsPluginType_PDF,
nsPluginType_Other
} nsPluginType;
class nsPluginNativeWindowWin : public nsPluginNativeWindow {
public:
public:
nsPluginNativeWindowWin();
virtual ~nsPluginNativeWindowWin();
@ -135,7 +127,7 @@ private:
HWND mParentWnd;
LONG_PTR mParentProc;
public:
nsPluginType mPluginType;
nsPluginHost::SpecialType mPluginType;
};
static bool sInMessageDispatch = false;
@ -162,7 +154,7 @@ static bool ProcessFlashMessageDelayed(nsPluginNativeWindowWin * aWin, nsNPAPIPl
nsCOMPtr<nsIRunnable> pwe = aWin->GetPluginWindowEvent(hWnd, msg, wParam, lParam);
if (pwe) {
NS_DispatchToCurrentThread(pwe);
return true;
return true;
}
return false;
}
@ -183,7 +175,7 @@ private:
NS_IMETHODIMP nsDelayedPopupsEnabledEvent::Run()
{
mInst->PushPopupsEnabledState(false);
return NS_OK;
return NS_OK;
}
static LRESULT CALLBACK PluginWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
@ -213,7 +205,7 @@ static LRESULT CALLBACK PluginWndProcInternal(HWND hWnd, UINT msg, WPARAM wParam
// Real may go into a state where it recursivly dispatches the same event
// when subclassed. If this is Real, lets examine the event and drop it
// on the floor if we get into this recursive situation. See bug 192914.
if (win->mPluginType == nsPluginType_Real) {
if (win->mPluginType == nsPluginHost::eSpecialType_RealPlayer) {
if (sInMessageDispatch && msg == sLastMsg)
return true;
// Cache the last message sent
@ -263,7 +255,7 @@ static LRESULT CALLBACK PluginWndProcInternal(HWND hWnd, UINT msg, WPARAM wParam
case WM_MOUSEACTIVATE: {
// If a child window of this plug-in is already focused,
// don't focus the parent to avoid focus dance. We'll
// don't focus the parent to avoid focus dance. We'll
// receive a follow up WM_SETFOCUS which will notify
// the appropriate window anyway.
HWND focusedWnd = ::GetFocus();
@ -291,7 +283,7 @@ static LRESULT CALLBACK PluginWndProcInternal(HWND hWnd, UINT msg, WPARAM wParam
case WM_KILLFOCUS: {
// RealPlayer can crash, don't process the message for those,
// see bug 328675.
if (win->mPluginType == nsPluginType_Real && msg == sLastMsg)
if (win->mPluginType == nsPluginHost::eSpecialType_RealPlayer && msg == sLastMsg)
return TRUE;
// Make sure setfocus and killfocus get through to the widget procedure
// even if they are eaten by the plugin. Also make sure we aren't calling
@ -309,7 +301,7 @@ static LRESULT CALLBACK PluginWndProcInternal(HWND hWnd, UINT msg, WPARAM wParam
// Macromedia Flash plugin may flood the message queue with some special messages
// (WM_USER+1) causing 100% CPU consumption and GUI freeze, see mozilla bug 132759;
// we can prevent this from happening by delaying the processing such messages;
if (win->mPluginType == nsPluginType_Flash) {
if (win->mPluginType == nsPluginHost::eSpecialType_Flash) {
if (ProcessFlashMessageDelayed(win, inst, hWnd, msg, wParam, lParam))
return TRUE;
}
@ -403,7 +395,7 @@ SetWindowLongHookCheck(HWND hWnd,
{
nsPluginNativeWindowWin * win =
(nsPluginNativeWindowWin *)GetProp(hWnd, NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION);
if (!win || (win && win->mPluginType != nsPluginType_Flash) ||
if (!win || (win && win->mPluginType != nsPluginHost::eSpecialType_Flash) ||
(nIndex == GWLP_WNDPROC &&
newLong == reinterpret_cast<LONG_PTR>(PluginWndProc)))
return true;
@ -425,7 +417,7 @@ SetWindowLongAHook(HWND hWnd,
if (SetWindowLongHookCheck(hWnd, nIndex, newLong))
return sUser32SetWindowLongAHookStub(hWnd, nIndex, newLong);
// Set flash's new subclass to get the result.
// Set flash's new subclass to get the result.
LONG_PTR proc = sUser32SetWindowLongAHookStub(hWnd, nIndex, newLong);
// We already checked this in SetWindowLongHookCheck
@ -454,14 +446,14 @@ SetWindowLongWHook(HWND hWnd,
if (SetWindowLongHookCheck(hWnd, nIndex, newLong))
return sUser32SetWindowLongWHookStub(hWnd, nIndex, newLong);
// Set flash's new subclass to get the result.
// Set flash's new subclass to get the result.
LONG_PTR proc = sUser32SetWindowLongWHookStub(hWnd, nIndex, newLong);
// We already checked this in SetWindowLongHookCheck
nsPluginNativeWindowWin * win =
(nsPluginNativeWindowWin *)GetProp(hWnd, NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION);
// Hook our subclass back up, just like we do on setwindow.
// Hook our subclass back up, just like we do on setwindow.
win->SetPrevWindowProc(
reinterpret_cast<WNDPROC>(sUser32SetWindowLongWHookStub(hWnd, nIndex,
reinterpret_cast<LONG_PTR>(PluginWndProc))));
@ -499,15 +491,15 @@ HookSetWindowLongPtr()
nsPluginNativeWindowWin::nsPluginNativeWindowWin() : nsPluginNativeWindow()
{
// initialize the struct fields
window = nullptr;
x = 0;
y = 0;
width = 0;
height = 0;
window = nullptr;
x = 0;
y = 0;
width = 0;
height = 0;
mPrevWinProc = nullptr;
mPluginWinProc = nullptr;
mPluginType = nsPluginType_Unknown;
mPluginType = nsPluginHost::eSpecialType_None;
mParentWnd = nullptr;
mParentProc = 0;
@ -555,10 +547,10 @@ NS_IMETHODIMP PluginWindowEvent::Run()
else {
// Currently not used, but added so that processing events here
// is more generic.
::CallWindowProc(win->GetWindowProc(),
hWnd,
GetMsg(),
GetWParam(),
::CallWindowProc(win->GetWindowProc(),
hWnd,
GetMsg(),
GetWParam(),
GetLParam());
}
@ -566,7 +558,7 @@ NS_IMETHODIMP PluginWindowEvent::Run()
return NS_OK;
}
PluginWindowEvent *
PluginWindowEvent *
nsPluginNativeWindowWin::GetPluginWindowEvent(HWND aWnd, UINT aMsg, WPARAM aWParam, LPARAM aLParam)
{
if (!mWeakRef) {
@ -580,7 +572,7 @@ nsPluginNativeWindowWin::GetPluginWindowEvent(HWND aWnd, UINT aMsg, WPARAM aWPar
// We have the ability to alloc if needed in case in the future some plugin
// should post multiple PostMessages. However, this could lead to many
// alloc's per second which could become a performance issue. See bug 169247.
if (!mCachedPluginWindowEvent)
if (!mCachedPluginWindowEvent)
{
event = new PluginWindowEvent();
if (!event) return nullptr;
@ -615,18 +607,10 @@ nsresult nsPluginNativeWindowWin::CallSetWindow(nsRefPtr<nsNPAPIPluginInstance>
}
// check plugin mime type and cache it if it will need special treatment later
if (mPluginType == nsPluginType_Unknown) {
if (mPluginType == nsPluginHost::eSpecialType_None) {
const char* mimetype = nullptr;
aPluginInstance->GetMIMEType(&mimetype);
if (mimetype) {
if (!strcmp(mimetype, "application/x-shockwave-flash"))
mPluginType = nsPluginType_Flash;
else if (!strcmp(mimetype, "audio/x-pn-realaudio-plugin"))
mPluginType = nsPluginType_Real;
else if (!strcmp(mimetype, "application/pdf"))
mPluginType = nsPluginType_PDF;
else
mPluginType = nsPluginType_Other;
if (NS_SUCCEEDED(aPluginInstance->GetMIMEType(&mimetype)) && mimetype) {
mPluginType = nsPluginHost::GetSpecialType(nsDependentCString(mimetype));
}
}
@ -649,7 +633,7 @@ nsresult nsPluginNativeWindowWin::CallSetWindow(nsRefPtr<nsNPAPIPluginInstance>
// PDF plugin v7.0.9, v8.1.3, and v9.0 subclass parent window, bug 531551
// V8.2.2 and V9.1 don't have such problem.
if (mPluginType == nsPluginType_PDF) {
if (mPluginType == nsPluginHost::eSpecialType_PDF) {
HWND parent = ::GetParent((HWND)window);
if (mParentWnd != parent) {
NS_ASSERTION(!mParentWnd, "Plugin's parent window changed");
@ -663,7 +647,7 @@ nsresult nsPluginNativeWindowWin::CallSetWindow(nsRefPtr<nsNPAPIPluginInstance>
SubclassAndAssociateWindow();
if (window && mPluginType == nsPluginType_Flash &&
if (window && mPluginType == nsPluginHost::eSpecialType_Flash &&
!GetPropW((HWND)window, L"PluginInstanceParentProperty")) {
HookSetWindowLongPtr();
}
@ -714,7 +698,7 @@ nsresult nsPluginNativeWindowWin::SubclassAndAssociateWindow()
DebugOnly<nsPluginNativeWindowWin *> win = (nsPluginNativeWindowWin *)::GetProp(hWnd, NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION);
NS_ASSERTION(!win || (win == this), "plugin window already has property and this is not us");
if (!::SetProp(hWnd, NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION, (HANDLE)this))
return NS_ERROR_FAILURE;
@ -741,7 +725,7 @@ nsresult nsPluginNativeWindowWin::UndoSubclassAndAssociateWindow()
SetWindowLongPtr(hWnd, GWL_STYLE, style);
}
if (mPluginType == nsPluginType_PDF && mParentWnd) {
if (mPluginType == nsPluginHost::eSpecialType_Flash && mParentWnd) {
::SetWindowLongPtr(mParentWnd, GWLP_WNDPROC, mParentProc);
mParentWnd = nullptr;
mParentProc = 0;

View File

@ -195,10 +195,16 @@ void nsPluginTag::InitMime(const char* const* aMimeTypes,
}
// Look for certain special plugins.
if (nsPluginHost::IsJavaMIMEType(mimeType.get())) {
mIsJavaPlugin = true;
} else if (mimeType.EqualsLiteral("application/x-shockwave-flash")) {
mIsFlashPlugin = true;
switch (nsPluginHost::GetSpecialType(mimeType)) {
case nsPluginHost::eSpecialType_Java:
mIsJavaPlugin = true;
break;
case nsPluginHost::eSpecialType_Flash:
mIsFlashPlugin = true;
break;
case nsPluginHost::eSpecialType_None:
default:
break;
}
// Fill in our MIME type array.

View File

@ -17,7 +17,7 @@ namespace plugins {
bool
SetupBridge(uint32_t aPluginId, dom::ContentParent* aContentParent,
bool aForceBridgeNow = false);
bool aForceBridgeNow, nsresult* rv);
bool
FindPluginsForContent(uint32_t aPluginEpoch,

Some files were not shown because too many files have changed in this diff Show More