Merge m-c to inbound.

This commit is contained in:
Ryan VanderMeulen 2014-04-22 13:07:17 -07:00
commit 4fbf07a98b
82 changed files with 1596 additions and 580 deletions

View File

@ -49,7 +49,7 @@ pref("network.protocol-handler.warn-external.vnd.youtube", false);
// By default, all protocol handlers are exposed. This means that the browser
// will response to openURL commands for all URL types. It will also try to open
// link clicks inside the browser before failing over to the system handlers.
pref("network.protocol-handler.expose.rtsp", false);
pref("network.protocol-handler.expose.rtsp", true);
/* http prefs */
pref("network.http.pipelining", true);

View File

@ -19,11 +19,11 @@
<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="f0463704888881b8ed1619e8d4b0d851b0e0311b"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0a4d2dea25a7162ee43db3a0db817798b70e7521"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="55bcc2d7e44dc805c24b57d1e783fc26e8a2ee86"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="52720b94a4f709d5f96c23b2d63c398e7002ecb9"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="0292e64ef8451df104dcf9ac3b2c6749b81684dd"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="85f9690323b235f4dcf2901ea2240d3c60fc22a0"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
<!-- Stock Android things -->

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f0463704888881b8ed1619e8d4b0d851b0e0311b"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="0a4d2dea25a7162ee43db3a0db817798b70e7521"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
@ -128,7 +128,7 @@
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="3a9a17613cc685aa232432566ad6cc607eab4ec1"/>
<project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="09485b73629856b21b2ed6073e327ab0e69a1189"/>
<project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="7d33aaf740bbf6c7c6e9c34a92b371eda311b66b"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="8afce6d5d48b71b6e7cb917179fb6147fb747521"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="9a00b3db898a83ef0766baa93e935e525572899e"/>
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="72e3a520e3c700839f07ba0113fd527b923c3330"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="baaf899afb158b9530690002f3656e958e3eb047"/>

View File

@ -12,10 +12,10 @@
<!--original fetch url was https://git.mozilla.org/releases-->
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
<!-- B2G specific things. -->
<project name="platform_build" path="build" remote="b2g" revision="52c909ccead537f8f9dbf634f3e6639078a8b0bd">
<project name="platform_build" path="build" remote="b2g" revision="65fba428f8d76336b33ddd9e15900357953600ba">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f0463704888881b8ed1619e8d4b0d851b0e0311b"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="0a4d2dea25a7162ee43db3a0db817798b70e7521"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
@ -119,15 +119,15 @@
<project name="platform/system/netd" path="system/netd" revision="36704b0da24debcab8090156568ac236315036bb"/>
<project name="platform/system/security" path="system/security" revision="583374f69f531ba68fc3dcbff1f74893d2a96406"/>
<project name="platform/system/vold" path="system/vold" revision="d4455b8cf361f8353e8aebac15ffd64b4aedd2b9"/>
<project name="platform_frameworks_av" path="frameworks/av" remote="b2g" revision="ee814270f52127febfcf29bacf9f1b327d7c4c29"/>
<project name="platform_system_core" path="system/core" remote="b2g" revision="9395eb5aa885cf6d305a202de6e9694a58a89717"/>
<default remote="caf" revision="refs/tags/android-4.4.2_r1" sync-j="4"/>
<!-- Emulator specific things -->
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="72ffdf71c68a96309212eb13d63560d66db14c9e"/>
<project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="a706bf388e30ec1f5273cf72cd0156e429f23fac"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="0909f27aaa6bf55314edddb48bb1cd6296a2d55c"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="3ef6c54fd5bba6fbd4c11f3870ab3aa32693f0da"/>
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="694cecf256122d0cb3b6a1a4efb4b5c7401db223"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="e5dba2723b3e417b107cf9546fb8e10b98e977ae"/>
<project name="platform_frameworks_av" path="frameworks/av" remote="b2g" revision="ee814270f52127febfcf29bacf9f1b327d7c4c29"/>
<project name="platform_system_core" path="system/core" remote="b2g" revision="9395eb5aa885cf6d305a202de6e9694a58a89717"/>
<project name="platform/development" path="development" revision="5968ff4e13e0d696ad8d972281fc27ae5a12829b"/>
<project name="android-sdk" path="sdk" remote="b2g" revision="0951179277915335251c5e11d242e4e1a8c2236f"/>
</manifest>

View File

@ -19,11 +19,11 @@
<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="f0463704888881b8ed1619e8d4b0d851b0e0311b"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0a4d2dea25a7162ee43db3a0db817798b70e7521"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="55bcc2d7e44dc805c24b57d1e783fc26e8a2ee86"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="52720b94a4f709d5f96c23b2d63c398e7002ecb9"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="0292e64ef8451df104dcf9ac3b2c6749b81684dd"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="85f9690323b235f4dcf2901ea2240d3c60fc22a0"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
<!-- Stock Android things -->

View File

@ -18,7 +18,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f0463704888881b8ed1619e8d4b0d851b0e0311b"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="0a4d2dea25a7162ee43db3a0db817798b70e7521"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>

View File

@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
"revision": "3f54f719dc145f1544db67881a48819559ecb71b",
"revision": "b209dbf62facaae103d9a577ef885d429a431d6c",
"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="f0463704888881b8ed1619e8d4b0d851b0e0311b"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0a4d2dea25a7162ee43db3a0db817798b70e7521"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>

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="f0463704888881b8ed1619e8d4b0d851b0e0311b"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0a4d2dea25a7162ee43db3a0db817798b70e7521"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>

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="f0463704888881b8ed1619e8d4b0d851b0e0311b"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0a4d2dea25a7162ee43db3a0db817798b70e7521"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>

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="f0463704888881b8ed1619e8d4b0d851b0e0311b"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0a4d2dea25a7162ee43db3a0db817798b70e7521"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f0463704888881b8ed1619e8d4b0d851b0e0311b"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="0a4d2dea25a7162ee43db3a0db817798b70e7521"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>

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="f0463704888881b8ed1619e8d4b0d851b0e0311b"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0a4d2dea25a7162ee43db3a0db817798b70e7521"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>

View File

@ -663,13 +663,7 @@ pref("plugins.click_to_play", true);
pref("plugins.hideMissingPluginsNotification", false);
#ifdef RELEASE_BUILD
// For now, plugins other than Java and Flash are enabled in beta/release
// and click-to-activate in earlier channels.
pref("plugin.default.state", 2);
#else
pref("plugin.default.state", 1);
#endif
// Plugins bundled in XPIs are enabled by default.
pref("plugin.defaultXpi.state", 2);
@ -679,6 +673,124 @@ pref("plugin.defaultXpi.state", 2);
pref("plugin.state.flash", 2);
pref("plugin.state.java", 1);
// Whitelist Requests
// Unity player, bug 979849
#ifdef XP_WIN
pref("plugin.state.npunity3d", 2);
#endif
#ifdef XP_MACOSX
pref("plugin.state.unity web player", 2);
#endif
// Cisco Jabber SDK, bug 980133
#ifdef XP_WIN
pref("plugin.state.npciscowebcommunicator", 2);
#endif
#ifdef XP_MACOSX
pref("plugin.state.ciscowebcommunicator", 2);
#endif
// McAfee Security Scanner detection plugin, bug 980772
#ifdef XP_WIN
pref("plugin.state.npmcafeemss", 2);
#endif
// Cisco VGConnect for directv.com, bug 981403
#ifdef XP_WIN
pref("plugin.state.npplayerplugin", 2);
#endif
#ifdef XP_MACOSX
pref("plugin.state.playerplugin", 2);
#endif
// Cisco Jabber Client, bug 981905
#ifdef XP_WIN
pref("plugin.state.npchip", 2);
#endif
#ifdef XP_MACOSX
pref("plugin.state.cisco jabber guest plug-in", 2);
#endif
// Estonian ID-card plugin, bug 982045
#ifdef XP_WIN
pref("plugin.state.npesteid-firefox-plugin", 2);
#endif
#ifdef XP_MACOSX
pref("plugin.state.esteidfirefoxplugin", 2);
#endif
#ifdef UNIX_BUT_NOT_MAC
pref("plugin.state.npesteid-firefox-plugin", 2);
#endif
// coupons.com, bug 984441
#ifdef XP_WIN
pref("plugin.state.npmozcouponprinter", 2);
#endif
#ifdef XP_MACOSX
pref("plugin.state.couponprinter-firefox_v", 2);
#endif
// Nexus Personal BankID, bug 987056
pref("plugin.state.npbispbrowser", 2);
// Gradecam, bug 988119
#ifdef XP_WIN
pref("plugin.state.npgcplugin", 2);
#endif
#ifdef XP_MACOSX
pref("plugin.state.gcplugin", 2);
#endif
// Smart Card Plugin, bug 988781
#ifdef XP_WIN
pref("plugin.state.npwebcard", 2);
#endif
// Cisco WebEx, bug 989096
#ifdef XP_WIN
pref("plugin.state.npatgpc", 2);
#endif
#ifdef XP_MACOSX
pref("plugin.state.webex", 2);
#endif
#ifdef UNIX_BUT_NOT_MAC
pref("plugin.state.npatgpc", 2);
#endif
// Skype, bug 990067
#ifdef XP_WIN
pref("plugin.state.npskypewebplugin", 2);
#endif
#ifdef XP_MACOSX
pref("plugin.state.skypewebplugin", 2);
#endif
// Facebook video calling, bug 990068
#ifdef XP_WIN
pref("plugin.state.npfacebookvideocalling", 2);
#endif
#ifdef XP_MACOSX
pref("plugin.state.facebookvideocalling", 2);
#endif
// MS Office Lync plugin, bug 990069
#ifdef XP_WIN
pref("plugin.state.npmeetingjoinpluginoc", 2);
#endif
#ifdef XP_MACOSX
pref("plugin.state.lwaplugin", 2);
#endif
// VidyoWeb, bug 990286
#ifdef XP_WIN
pref("plugin.state.npvidyoweb", 2);
#endif
#ifdef XP_MACOSX
pref("plugin.state.npvidyoweb", 2);
pref("plugin.state.vidyoweb", 2);
#endif
// display door hanger if flash not installed
pref("plugins.notifyMissingFlash", true);
@ -1286,7 +1398,7 @@ pref("devtools.eyedropper.zoom", 6);
// - keymap: which keymap to use (can be 'default', 'emacs' or 'vim')
// - autoclosebrackets: whether to permit automatic bracket/quote closing.
// - detectindentation: whether to detect the indentation from the file
pref("devtools.editor.tabsize", 4);
pref("devtools.editor.tabsize", 2);
pref("devtools.editor.expandtab", true);
pref("devtools.editor.keymap", "default");
pref("devtools.editor.autoclosebrackets", true);

View File

@ -122,36 +122,25 @@ tabbrowser {
visibility: hidden;
}
.tab-background,
.tab-close-button,
.tab-label {
.tab-background {
/* Explicitly set the visibility to override the value (collapsed)
* we inherit from #TabsToolbar[collapsed] upon opening a browser window. */
visibility: visible;
}
.tab-close-button[fadein],
.tab-background[fadein] {
/* This transition is only wanted for opening tabs. */
transition: visibility 0ms 25ms;
}
.tab-close-button:not([fadein]),
.tab-background:not([fadein]) {
visibility: hidden;
}
.tab-close-button[fadein],
.tab-label[fadein] {
/* This transition is only wanted for opening tabs. */
transition: opacity 70ms 230ms,
visibility 0ms 230ms;
}
.tab-close-button:not([fadein]),
.tab-label:not([fadein]) {
visibility: collapse;
opacity: .6;
}
.tab-label:not([fadein]),
.tab-throbber:not([fadein]),
.tab-icon-image:not([fadein]) {
display: none;

View File

@ -27,6 +27,6 @@ add_task(function() {
is(newWinBookmarksToolbarPlaceholder.getAttribute("wrap"), "true",
"Button in new window should have 'wrap' attribute");
yield newWin.PanelUI.hide();
newWin.close();
yield promiseWindowClosed(newWin);
CustomizableUI.reset();
});

View File

@ -133,7 +133,6 @@ PlacesController.prototype = {
case "cmd_paste":
case "cmd_delete":
case "placesCmd_delete":
case "placesCmd_moveBookmarks":
case "cmd_paste":
case "placesCmd_paste":
case "placesCmd_new:folder":

View File

@ -23,27 +23,38 @@ var gMoveBookmarksDialog = {
},
onOK: function MBD_onOK(aEvent) {
var selectedNode = this.foldersTree.selectedNode;
NS_ASSERT(selectedNode,
"selectedNode must be set in a single-selection tree with initial selection set");
var selectedFolderID = PlacesUtils.getConcreteItemId(selectedNode);
let selectedNode = this.foldersTree.selectedNode;
let selectedFolderId = PlacesUtils.getConcreteItemId(selectedNode);
var transactions = [];
for (var i=0; i < this._nodes.length; i++) {
// Nothing to do if the node is already under the selected folder
if (this._nodes[i].parent.itemId == selectedFolderID)
continue;
if (!PlacesUIUtils.useAsyncTransactions) {
let transactions = [];
for (var i=0; i < this._nodes.length; i++) {
// Nothing to do if the node is already under the selected folder
if (this._nodes[i].parent.itemId == selectedFolderId)
continue;
let txn = new PlacesMoveItemTransaction(this._nodes[i].itemId,
selectedFolderID,
PlacesUtils.bookmarks.DEFAULT_INDEX);
transactions.push(txn);
let txn = new PlacesMoveItemTransaction(this._nodes[i].itemId,
selectedFolderId,
PlacesUtils.bookmarks.DEFAULT_INDEX);
transactions.push(txn);
}
if (transactions.length != 0) {
let txn = new PlacesAggregatedTransaction("Move Items", transactions);
PlacesUtils.transactionManager.doTransaction(txn);
}
return;
}
if (transactions.length != 0) {
let txn = new PlacesAggregatedTransaction("Move Items", transactions);
PlacesUtils.transactionManager.doTransaction(txn);
}
PlacesTransactions.transact(function* () {
let newParentGUID = yield PlacesUtils.promiseItemGUID(selectedFolderId);
for (let node of this._nodes) {
// Nothing to do if the node is already under the selected folder.
if (node.parent.itemId == selectedFolderId)
continue;
yield PlacesTransactions.MoveItem({ GUID: node.bookmarkGuid
, newParentGUID: newParentGUID });
}
}.bind(this)).then(null, Components.utils.reportError);
},
newFolder: function MBD_newFolder() {

View File

@ -52,7 +52,7 @@ function test(){
}
function testSourceIsUgly() {
ok(!gEditor.getText().contains("\n "),
ok(!gEditor.getText().contains("\n "),
"The source shouldn't be pretty printed yet.");
}
@ -93,7 +93,7 @@ function testAutoPrettyPrintOff(){
}
function testSourceIsPretty() {
ok(gEditor.getText().contains("\n "),
ok(gEditor.getText().contains("\n "),
"The source should be pretty printed.")
}

View File

@ -63,7 +63,7 @@ function test(){
}
function testSourceIsUgly() {
ok(!gEditor.getText().contains("\n "),
ok(!gEditor.getText().contains("\n "),
"The source shouldn't be pretty printed yet.");
}
@ -96,7 +96,7 @@ function disableAutoPrettyPrint(){
}
function testSourceIsPretty() {
ok(gEditor.getText().contains("\n "),
ok(gEditor.getText().contains("\n "),
"The source should be pretty printed.")
}

View File

@ -38,7 +38,7 @@ function test() {
}
function testSourceIsUgly() {
ok(!gEditor.getText().contains("\n "),
ok(!gEditor.getText().contains("\n "),
"The source shouldn't be pretty printed yet.");
}
@ -52,7 +52,7 @@ function testProgressBarShown() {
}
function testSourceIsPretty() {
ok(gEditor.getText().contains("\n "),
ok(gEditor.getText().contains("\n "),
"The source should be pretty printed.")
}
@ -66,7 +66,7 @@ function testSourceIsStillPretty() {
const { source } = gSources.selectedItem.attachment;
gDebugger.DebuggerController.SourceScripts.getText(source).then(([, text]) => {
ok(text.contains("\n "),
ok(text.contains("\n "),
"Subsequent calls to getText return the pretty printed source.");
deferred.resolve();
});

View File

@ -43,7 +43,7 @@ function selectContextMenuItem() {
}
function testSourceIsPretty() {
ok(gEditor.getText().contains("\n "),
ok(gEditor.getText().contains("\n "),
"The source should be pretty printed.")
}

View File

@ -37,7 +37,7 @@ function test() {
}
function testSourceIsUgly() {
ok(!gEditor.getText().contains("\n "),
ok(!gEditor.getText().contains("\n "),
"The source shouldn't be pretty printed yet.");
}
@ -46,7 +46,7 @@ function clickPrettyPrintButton() {
}
function testSourceIsPretty() {
ok(gEditor.getText().contains("\n "),
ok(gEditor.getText().contains("\n "),
"The source should be pretty printed.")
}

View File

@ -41,7 +41,7 @@ function test() {
}
function testSourceIsUgly() {
ok(!gEditor.getText().contains("\n "),
ok(!gEditor.getText().contains("\n "),
"The source shouldn't be pretty printed yet.");
}
@ -55,7 +55,7 @@ function testProgressBarShown() {
}
function testSourceIsPretty() {
ok(gEditor.getText().contains("\n "),
ok(gEditor.getText().contains("\n "),
"The source should be pretty printed.")
}
@ -69,7 +69,7 @@ function testSourceIsStillPretty() {
const { source } = gSources.selectedItem.attachment;
gDebugger.DebuggerController.SourceScripts.getText(source).then(([, text]) => {
ok(text.contains("\n "),
ok(text.contains("\n "),
"Subsequent calls to getText return the pretty printed source.");
deferred.resolve();
});

View File

@ -28,7 +28,6 @@ support-files =
# [browser_inspector_bug_831693_searchbox_panel_navigation.js]
# Disabled for too many intermittent failures (bug 851349)
[browser_inspector_bug_840156_destroy_after_navigation.js]
[browser_inspector_changes.js]
[browser_inspector_cmd_inspect.js]
[browser_inspector_dead_node_exception.js]
[browser_inspector_destroyselection.js]

View File

@ -1,156 +0,0 @@
/* -*- Mode: Javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=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/. */
let doc;
let testDiv;
function test() {
let inspector;
function createDocument()
{
doc.body.innerHTML = '<div id="testdiv">Test div!</div>';
doc.title = "Inspector Change Test";
openInspector(runInspectorTests);
}
function getInspectorRuleProp(aName)
{
let ruleview = inspector.sidebar.getWindowForTab("ruleview").ruleview.view;
let inlineStyles = ruleview._elementStyle.rules[0];
for (let key in inlineStyles.textProps) {
let prop = inlineStyles.textProps[key];
if (prop.name == aName) {
return prop;
}
}
return null;
}
function runInspectorTests(aInspector)
{
inspector = aInspector;
waitForView("computedview", () => {
info("Computed View ready");
inspector.sidebar.select("computedview");
testDiv = doc.getElementById("testdiv");
testDiv.style.fontSize = "10px";
// Start up the style inspector panel...
inspector.once("computed-view-refreshed", () => {
executeSoon(computedStylePanelTests);
});
inspector.selection.setNode(testDiv);
});
}
function computedStylePanelTests()
{
let computedview = inspector.sidebar.getWindowForTab("computedview").computedview;
ok(computedview, "Style Panel has a cssHtmlTree");
let fontSize = getComputedPropertyValue("font-size");
is(fontSize, "10px", "Style inspector should be showing the correct font size.");
testDiv.style.cssText = "font-size: 15px; color: red;";
// Wait until layout-change fires from mutation to skip earlier refresh event
inspector.once("layout-change", () => {
inspector.once("computed-view-refreshed", () => {
executeSoon(computedStylePanelAfterChange);
});
});
}
function computedStylePanelAfterChange()
{
let fontSize = getComputedPropertyValue("font-size");
is(fontSize, "15px", "Style inspector should be showing the new font size.");
let color = getComputedPropertyValue("color");
is(color, "#F00", "Style inspector should be showing the new color.");
computedStylePanelNotActive();
}
function computedStylePanelNotActive()
{
// Tests changes made while the style panel is not active.
inspector.sidebar.select("ruleview");
testDiv.style.cssText = "font-size: 20px; color: blue; text-align: center";
inspector.once("computed-view-refreshed", () => {
executeSoon(computedStylePanelAfterSwitch);
});
}
function computedStylePanelAfterSwitch()
{
let fontSize = getComputedPropertyValue("font-size");
is(fontSize, "20px", "Style inspector should be showing the new font size.");
let color = getComputedPropertyValue("color");
is(color, "#00F", "Style inspector should be showing the new color.");
let textAlign = getComputedPropertyValue("text-align");
is(textAlign, "center", "Style inspector should be showing the new text align.");
rulePanelTests();
}
function rulePanelTests()
{
inspector.sidebar.select("ruleview");
let ruleview = inspector.sidebar.getWindowForTab("ruleview").ruleview;
ok(ruleview, "Style Panel has a ruleview");
let propView = getInspectorRuleProp("text-align");
is(propView.value, "center", "Style inspector should be showing the new text align.");
testDiv.style.cssText = "font-size: 3em; color: lightgoldenrodyellow; text-align: right; text-transform: uppercase";
inspector.once("rule-view-refreshed", () => {
executeSoon(rulePanelAfterChange);
});
}
function rulePanelAfterChange()
{
let propView = getInspectorRuleProp("text-align");
is(propView.value, "right", "Style inspector should be showing the new text align.");
let propView = getInspectorRuleProp("color");
is(propView.value, "lightgoldenrodyellow", "Style inspector should be showing the new color.")
let propView = getInspectorRuleProp("font-size");
is(propView.value, "3em", "Style inspector should be showing the new font size.");
let propView = getInspectorRuleProp("text-transform");
is(propView.value, "uppercase", "Style inspector should be showing the new text transform.");
finishTest();
}
function finishTest()
{
gBrowser.removeCurrentTab();
finish();
}
waitForExplicitFinish();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function() {
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
doc = content.document;
waitForFocus(createDocument, content);
}, true);
content.location = "data:text/html;charset=utf-8,browser_inspector_changes.js";
}

View File

@ -169,7 +169,25 @@ function onEditorKeypress({ ed, Editor }, event) {
return;
}
if ((event.ctrlKey || event.metaKey) && event.keyCode == event.DOM_VK_SPACE) {
// When Ctrl/Cmd + Space is pressed, two simultaneous keypresses are emitted
// first one for just the Ctrl/Cmd and second one for combo. The first one
// leave the private.doNotAutocomplete as true, so we have to make it false
private.doNotAutocomplete = false;
return;
}
if (event.ctrlKey || event.metaKey || event.altKey) {
private.doNotAutocomplete = true;
private.popup.hidePopup();
return;
}
switch (event.keyCode) {
case event.DOM_VK_RETURN:
private.doNotAutocomplete = true;
break;
case event.DOM_VK_ESCAPE:
if (private.popup.isOpen)
event.preventDefault();

View File

@ -62,26 +62,26 @@ function test() {
waitForExplicitFinish();
setup((ed, win) => {
is(ed.getOption("indentUnit"), 4,
"4 spaces before code added");
is(ed.getOption("indentUnit"), 2,
"2 spaces before code added");
is(ed.getOption("indentWithTabs"), false,
"spaces is default");
ed.setText(TWO_SPACES_CODE);
is(ed.getOption("indentUnit"), 2,
"2 spaces detected in 2 space code");
is(ed.getOption("indentWithTabs"), false,
"spaces detected in 2 space code");
ed.setText(FOUR_SPACES_CODE);
is(ed.getOption("indentUnit"), 4,
"4 spaces detected in 4 space code");
is(ed.getOption("indentWithTabs"), false,
"spaces detected in 4 space code");
ed.setText(TWO_SPACES_CODE);
is(ed.getOption("indentUnit"), 2,
"2 spaces detected in 2 space code");
is(ed.getOption("indentWithTabs"), false,
"spaces detected in 2 space code");
ed.setText(TABS_CODE);
is(ed.getOption("indentUnit"), 4,
"4 space indentation unit");
is(ed.getOption("indentUnit"), 2,
"2 space indentation unit");
is(ed.getOption("indentWithTabs"), true,
"tabs detected in majority tabs code");

View File

@ -31,6 +31,8 @@ support-files =
[browser_computedview_media-queries.js]
[browser_computedview_no-results-placeholder.js]
[browser_computedview_original-source-link.js]
[browser_computedview_refresh-on-style-change_01.js]
[browser_computedview_refresh-on-style-change_02.js]
[browser_computedview_search-filter.js]
[browser_computedview_select-and-copy-styles.js]
[browser_computedview_style-editor-link.js]
@ -77,6 +79,7 @@ skip-if = os == "win" && debug # bug 963492
[browser_ruleview_pseudo-element.js]
[browser_ruleview_refresh-on-attribute-change_01.js]
[browser_ruleview_refresh-on-attribute-change_02.js]
[browser_ruleview_refresh-on-style-change.js]
[browser_ruleview_select-and-copy-styles.js]
[browser_ruleview_style-editor-link.js]
[browser_ruleview_urls-clickable.js]

View File

@ -0,0 +1,35 @@
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test that the computed view refreshes when the current node has its style
// changed
const TESTCASE_URI = 'data:text/html;charset=utf-8,' +
'<div id="testdiv" style="font-size:10px;">Test div!</div>';
let test = asyncTest(function*() {
yield addTab(TESTCASE_URI);
info("Getting the test node");
let div = getNode("#testdiv");
info("Opening the computed view and selecting the test node");
let {toolbox, inspector, view} = yield openComputedView();
yield selectNode(div, inspector);
let fontSize = getComputedViewPropertyValue(view, "font-size");
is(fontSize, "10px", "The computed view shows the right font-size");
info("Changing the node's style and waiting for the update");
let onUpdated = inspector.once("computed-view-refreshed");
div.style.cssText = "font-size: 15px; color: red;";
yield onUpdated;
fontSize = getComputedViewPropertyValue(view, "font-size");
is(fontSize, "15px", "The computed view shows the updated font-size");
let color = getComputedViewPropertyValue(view, "color");
is(color, "#F00", "The computed view also shows the color now");
});

View File

@ -0,0 +1,40 @@
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test that the computed view refreshes when the current node has its style
// changed, even if the view is not the active one
const TESTCASE_URI = 'data:text/html;charset=utf-8,' +
'<div id="testdiv" style="font-size:10px;">Test div!</div>';
let test = asyncTest(function*() {
yield addTab(TESTCASE_URI);
info("Getting the test node");
let div = getNode("#testdiv");
info("Opening the computed view and selecting the test node");
let {toolbox, inspector, view} = yield openComputedView();
yield selectNode(div, inspector);
let fontSize = getComputedViewPropertyValue(view, "font-size");
is(fontSize, "10px", "The computed view shows the right font-size");
info("Now switching to the rule view");
yield openRuleView();
info("Changing the node's style and waiting for the update");
let onUpdated = inspector.once("computed-view-refreshed");
div.style.cssText = "font-size: 20px; color: blue; text-align: center";
yield onUpdated;
fontSize = getComputedViewPropertyValue(view, "font-size");
is(fontSize, "20px", "The computed view shows the updated font-size");
let color = getComputedViewPropertyValue(view, "color");
is(color, "#00F", "The computed view also shows the color now");
let textAlign = getComputedViewPropertyValue(view, "text-align");
is(textAlign, "center", "The computed view also shows the text-align now");
});

View File

@ -0,0 +1,41 @@
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test that the rule view refreshes when the current node has its style
// changed
const TESTCASE_URI = 'data:text/html;charset=utf-8,' +
'<div id="testdiv" style="font-size:10px;">Test div!</div>';
let test = asyncTest(function*() {
yield addTab(TESTCASE_URI);
Services.prefs.setCharPref("devtools.defaultColorUnit", "name");
info("Getting the test node");
let div = getNode("#testdiv");
info("Opening the rule view and selecting the test node");
let {toolbox, inspector, view} = yield openRuleView();
yield selectNode(div, inspector);
let fontSize = getRuleViewPropertyValue(view, "element", "font-size");
is(fontSize, "10px", "The rule view shows the right font-size");
info("Changing the node's style and waiting for the update");
let onUpdated = inspector.once("rule-view-refreshed");
div.style.cssText = "font-size: 3em; color: lightgoldenrodyellow; text-align: right; text-transform: uppercase";
yield onUpdated;
let textAlign = getRuleViewPropertyValue(view, "element", "text-align");
is(textAlign, "right", "The rule view shows the new text align.");
let color = getRuleViewPropertyValue(view, "element", "color");
is(color, "lightgoldenrodyellow", "The rule view shows the new color.")
let fontSize = getRuleViewPropertyValue(view, "element", "font-size");
is(fontSize, "3em", "The rule view shows the new font size.");
let textTransform = getRuleViewPropertyValue(view, "element", "text-transform");
is(textTransform, "uppercase", "The rule view shows the new text transform.");
});

View File

@ -34,9 +34,14 @@ registerCleanupFunction(() => {
}
});
// Uncomment to log events
// Services.prefs.setBoolPref("devtools.dump.emit", true);
// Clean-up all prefs that might have been changed during a test run
// (safer here because if the test fails, then the pref is never reverted)
registerCleanupFunction(() => {
Services.prefs.clearUserPref("devtools.dump.emit");
Services.prefs.clearUserPref("devtools.defaultColorUnit");
});
/**
@ -477,7 +482,7 @@ function hasSideBarTab(inspector, id) {
function getRuleViewRule(view, selectorText) {
let rule;
for (let r of view.doc.querySelectorAll(".ruleview-rule")) {
let selector = r.querySelector(".ruleview-selector-matched");
let selector = r.querySelector(".ruleview-selector, .ruleview-selector-matched");
if (selector && selector.textContent === selectorText) {
rule = r;
break;
@ -515,6 +520,20 @@ function getRuleViewProperty(view, selectorText, propertyName) {
return prop;
}
/**
* Get the text value of the property corresponding to a given selector and name
* in the rule-view
* @param {CssRuleView} view The instance of the rule-view panel
* @param {String} selectorText The selector in the rule-view to look for the
* property in
* @param {String} propertyName The name of the property
* @return {String} The property value
*/
function getRuleViewPropertyValue(view, selectorText, propertyName) {
return getRuleViewProperty(view, selectorText, propertyName)
.valueSpan.textContent;
}
/**
* Simulate a color change in a given color picker tooltip, and optionally wait
* for a given element in the page to have its style changed as a result
@ -655,6 +674,18 @@ function getComputedViewProperty(view, name) {
return prop;
}
/**
* Get the text value of the property corresponding to a given name in the
* computed-view
* @param {CssHtmlTree} view The instance of the computed view panel
* @param {String} name The name of the property to retrieve
* @return {String} The property value
*/
function getComputedViewPropertyValue(view, selectorText, propertyName) {
return getComputedViewProperty(view, selectorText, propertyName)
.valueSpan.textContent;
}
/**
* Expand a given property, given its index in the current property list of
* the computed view

View File

@ -51,17 +51,20 @@
padding-bottom: 1px;
}
#nav-bar {
background-image: linear-gradient(@toolbarHighlight@, rgba(255,255,255,0));
box-shadow: 0 1px 0 @toolbarHighlight@ inset;
#TabsToolbar:not([collapsed="true"]) + #nav-bar {
margin-top: -@tabToolbarNavbarOverlap@; /* Move up into the TabsToolbar */
padding-top: 2px;
padding-bottom: 2px;
/* Position the toolbar above the bottom of background tabs */
position: relative;
z-index: 1;
}
#nav-bar {
background-image: linear-gradient(@toolbarHighlight@, rgba(255,255,255,0));
box-shadow: 0 1px 0 @toolbarHighlight@ inset;
padding-top: 2px;
padding-bottom: 2px;
}
#nav-bar-overflow-button {
-moz-image-region: rect(-5px, 12px, 11px, -4px);
}

View File

@ -109,6 +109,13 @@ toolbarseparator {
background: url(chrome://browser/skin/Toolbar-background-noise.png) hsl(0,0%,83%);
}
#TabsToolbar:not([collapsed="true"]) + #nav-bar {
margin-top: -@tabToolbarNavbarOverlap@; /* Move up into the TabsToolbar */
/* Position the toolbar above the bottom of background tabs */
position: relative;
z-index: 1;
}
#nav-bar {
-moz-appearance: none;
background: url(chrome://browser/skin/Toolbar-background-noise.png),
@ -124,10 +131,6 @@ toolbarseparator {
background-position: 0 1px, 0 0;
box-shadow: inset 0 1px 0 hsla(0,0%,100%,.4);
margin-top: -@tabToolbarNavbarOverlap@;
/* Position the toolbar above the bottom of background tabs */
position: relative;
z-index: 1;
}
@media (min-resolution: 2dppx) {

View File

@ -99,6 +99,10 @@
background-position: top 5px left 4px;
}
.subviewbutton[checked="true"]:-moz-locale-dir(rtl) {
background-position: top 5px right 4px;
}
.subviewbutton:not(:-moz-any([image],[targetURI],.cui-withicon, .bookmark-item)) > .menu-iconic-left {
display: none;
}

View File

@ -1068,6 +1068,10 @@ toolbaritem[overflowedItem=true],
background: url("chrome://global/skin/menu/shared-menu-check.png") center left 7px / 11px 11px no-repeat transparent;
}
.subviewbutton[checked="true"]:-moz-locale-dir(rtl) {
background-position: center right 7px;
}
.subviewbutton > .menu-iconic-left {
-moz-appearance: none;
-moz-margin-end: 3px;

View File

@ -283,15 +283,18 @@
}
}
#nav-bar {
background-image: linear-gradient(@toolbarHighlight@, rgba(255,255,255,0));
box-shadow: 0 1px 0 @toolbarHighlight@ inset;
#TabsToolbar:not([collapsed="true"]) + #nav-bar {
margin-top: -@tabToolbarNavbarOverlap@; /* Move up into the TabsToolbar */
/* Position the toolbar above the bottom of background tabs */
position: relative;
z-index: 1;
}
#nav-bar {
background-image: linear-gradient(@toolbarHighlight@, rgba(255,255,255,0));
box-shadow: 0 1px 0 @toolbarHighlight@ inset;
}
#personal-bookmarks {
min-height: 24px;
}

View File

@ -430,6 +430,11 @@ DecoderTraits::CanHandleMediaType(const char* aMIMEType,
if (MediaDecoder::IsMediaPluginsEnabled() &&
GetMediaPluginHost()->FindDecoder(nsDependentCString(aMIMEType), &codecList))
result = CANPLAY_MAYBE;
#endif
#ifdef NECKO_PROTOCOL_rtsp
if (IsRtspSupportedType(nsDependentCString(aMIMEType))) {
result = CANPLAY_MAYBE;
}
#endif
if (result == CANPLAY_NO || !aHaveRequestedCodecs || !codecList) {
return result;
@ -664,6 +669,9 @@ bool DecoderTraits::IsSupportedInVideoDocument(const nsACString& aType)
#endif
#ifdef MOZ_APPLEMEDIA
IsAppleMediaSupportedType(aType) ||
#endif
#ifdef NECKO_PROTOCOL_rtsp
IsRtspSupportedType(aType) ||
#endif
false;
}

View File

@ -1552,6 +1552,11 @@ MediaCache::ReleaseStream(MediaCacheStream* aStream)
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
CACHE_LOG(PR_LOG_DEBUG, ("Stream %p closed", aStream));
mStreams.RemoveElement(aStream);
// Update MediaCache again for |mStreams| is changed.
// We need to re-run Update() to ensure streams reading from the same resource
// as the removed stream get a chance to continue reading.
gMediaCache->QueueUpdate();
}
void

View File

@ -15,6 +15,10 @@
#include "nsIScriptSecurityManager.h"
#include "nsIStreamingProtocolService.h"
#include "nsServiceManagerUtils.h"
#ifdef NECKO_PROTOCOL_rtsp
#include "mozilla/net/RtspChannelChild.h"
#endif
using namespace mozilla::net;
#ifdef PR_LOGGING
PRLogModuleInfo* gRtspMediaResourceLog;
@ -37,9 +41,9 @@ namespace mozilla {
* Even though the ring buffer is divided into fixed size slots, it still can
* store the data which size is larger than one slot size.
* */
#define BUFFER_SLOT_NUM 512
#define BUFFER_SLOT_NUM 8192
#define BUFFER_SLOT_DEFAULT_SIZE 256
#define BUFFER_SLOT_MAX_SIZE 8192
#define BUFFER_SLOT_MAX_SIZE 512
#define BUFFER_SLOT_INVALID -1
#define BUFFER_SLOT_EMPTY 0
@ -354,21 +358,21 @@ RtspMediaResource::RtspMediaResource(MediaDecoder* aDecoder,
, mIsConnected(false)
, mRealTime(false)
{
nsCOMPtr<nsIStreamingProtocolControllerService> mediaControllerService =
do_GetService(MEDIASTREAMCONTROLLERSERVICE_CONTRACTID);
MOZ_ASSERT(mediaControllerService);
if (mediaControllerService) {
mediaControllerService->Create(mChannel,
getter_AddRefs(mMediaStreamController));
MOZ_ASSERT(mMediaStreamController);
mListener = new Listener(this);
mMediaStreamController->AsyncOpen(mListener);
}
#ifndef NECKO_PROTOCOL_rtsp
MOZ_CRASH("Should not be called except for B2G platform");
#else
MOZ_ASSERT(aChannel);
mMediaStreamController =
static_cast<RtspChannelChild*>(aChannel)->GetController();
MOZ_ASSERT(mMediaStreamController);
mListener = new Listener(this);
mMediaStreamController->AsyncOpen(mListener);
#ifdef PR_LOGGING
if (!gRtspMediaResourceLog) {
gRtspMediaResourceLog = PR_NewLogModule("RtspMediaResource");
}
#endif
#endif
}
RtspMediaResource::~RtspMediaResource()
@ -634,6 +638,9 @@ RtspMediaResource::OnDisconnected(uint8_t aTrackIdx, nsresult aReason)
void RtspMediaResource::Suspend(bool aCloseImmediately)
{
NS_ASSERTION(NS_IsMainThread(), "Don't call on non-main thread");
if (NS_WARN_IF(!mDecoder)) {
return;
}
MediaDecoderOwner* owner = mDecoder->GetMediaOwner();
NS_ENSURE_TRUE_VOID(owner);
@ -647,6 +654,9 @@ void RtspMediaResource::Suspend(bool aCloseImmediately)
void RtspMediaResource::Resume()
{
NS_ASSERTION(NS_IsMainThread(), "Don't call on non-main thread");
if (NS_WARN_IF(!mDecoder)) {
return;
}
MediaDecoderOwner* owner = mDecoder->GetMediaOwner();
NS_ENSURE_TRUE_VOID(owner);

View File

@ -175,6 +175,7 @@ LOCAL_INCLUDES += [
'/content/base/src',
'/layout/generic',
'/layout/xul',
'/netwerk/base/src',
]
if CONFIG['MOZ_DIRECTSHOW']:

View File

@ -47,6 +47,10 @@ PRLogModuleInfo* gAudioOffloadPlayerLog;
#define AUDIO_OFFLOAD_LOG(type, msg)
#endif
// maximum time in paused state when offloading audio decompression.
// When elapsed, the AudioSink is destroyed to allow the audio DSP to power down.
static const uint64_t OFFLOAD_PAUSE_MAX_MSECS = 60000ll;
AudioOffloadPlayer::AudioOffloadPlayer(MediaOmxDecoder* aObserver) :
mObserver(aObserver),
mInputBuffer(nullptr),
@ -78,9 +82,7 @@ AudioOffloadPlayer::AudioOffloadPlayer(MediaOmxDecoder* aObserver) :
AudioOffloadPlayer::~AudioOffloadPlayer()
{
if (mStarted) {
Reset();
}
Reset();
AudioSystem::releaseAudioSessionId(mSessionId);
}
@ -109,12 +111,6 @@ status_t AudioOffloadPlayer::Start(bool aSourceAlreadyStarted)
}
}
MediaSource::ReadOptions options;
if (mSeeking) {
options.setSeekTo(mSeekTimeUs);
mSeeking = false;
}
sp<MetaData> format = mSource->getFormat();
const char* mime;
int avgBitRate = -1;
@ -177,21 +173,24 @@ status_t AudioOffloadPlayer::Start(bool aSourceAlreadyStarted)
return err;
}
void AudioOffloadPlayer::ChangeState(MediaDecoder::PlayState aState)
status_t AudioOffloadPlayer::ChangeState(MediaDecoder::PlayState aState)
{
MOZ_ASSERT(NS_IsMainThread());
mPlayState = aState;
switch (mPlayState) {
case MediaDecoder::PLAY_STATE_PLAYING:
Play();
case MediaDecoder::PLAY_STATE_PLAYING: {
status_t err = Play();
if (err != OK) {
return err;
}
StartTimeUpdate();
break;
} break;
case MediaDecoder::PLAY_STATE_SEEKING: {
int64_t seekTimeUs
= mObserver->GetSeekTime();
SeekTo(seekTimeUs);
SeekTo(seekTimeUs, true);
mObserver->ResetSeekTime();
} break;
@ -209,33 +208,70 @@ void AudioOffloadPlayer::ChangeState(MediaDecoder::PlayState aState)
default:
break;
}
return OK;
}
static void ResetCallback(nsITimer* aTimer, void* aClosure)
{
AudioOffloadPlayer* player = static_cast<AudioOffloadPlayer*>(aClosure);
if (player) {
player->Reset();
}
}
void AudioOffloadPlayer::Pause(bool aPlayPendingSamples)
{
MOZ_ASSERT(NS_IsMainThread());
CHECK(mStarted);
CHECK(mAudioSink.get());
if (aPlayPendingSamples) {
mAudioSink->Stop();
} else {
mAudioSink->Pause();
if (mStarted) {
CHECK(mAudioSink.get());
if (aPlayPendingSamples) {
mAudioSink->Stop();
} else {
mAudioSink->Pause();
}
mPlaying = false;
}
mPlaying = false;
if (mResetTimer) {
return;
}
mResetTimer = do_CreateInstance("@mozilla.org/timer;1");
mResetTimer->InitWithFuncCallback(ResetCallback,
this,
OFFLOAD_PAUSE_MAX_MSECS,
nsITimer::TYPE_ONE_SHOT);
}
status_t AudioOffloadPlayer::Play()
{
MOZ_ASSERT(NS_IsMainThread());
CHECK(mStarted);
CHECK(mAudioSink.get());
if (mResetTimer) {
mResetTimer->Cancel();
mResetTimer = nullptr;
}
status_t err = OK;
err = mAudioSink->Start();
if (err == OK) {
mPlaying = true;
if (!mStarted) {
// Last pause timed out and offloaded audio sink was reset. Start it again
err = Start(false);
if (err != OK) {
return err;
}
// Seek to last play position only when there was no seek during last pause
if (!mSeeking) {
SeekTo(mPositionTimeMediaUs);
}
}
if (!mPlaying) {
CHECK(mAudioSink.get());
err = mAudioSink->Start();
if (err == OK) {
mPlaying = true;
}
}
return err;
@ -243,7 +279,10 @@ status_t AudioOffloadPlayer::Play()
void AudioOffloadPlayer::Reset()
{
CHECK(mStarted);
if (!mStarted) {
return;
}
CHECK(mAudioSink.get());
AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("reset: mPlaying=%d mReachedEOS=%d",
@ -273,19 +312,18 @@ void AudioOffloadPlayer::Reset()
mInputBuffer->release();
mInputBuffer = nullptr;
}
mSource->stop();
IPCThreadState::self()->flushCommands();
StopTimeUpdate();
mSeeking = false;
mSeekTimeUs = 0;
mReachedEOS = false;
mStarted = false;
mPlaying = false;
mStartPosUs = 0;
}
status_t AudioOffloadPlayer::SeekTo(int64_t aTimeUs)
status_t AudioOffloadPlayer::SeekTo(int64_t aTimeUs, bool aDispatchSeekEvents)
{
MOZ_ASSERT(NS_IsMainThread());
CHECK(mAudioSink.get());
@ -299,26 +337,33 @@ status_t AudioOffloadPlayer::SeekTo(int64_t aTimeUs)
mPositionTimeMediaUs = -1;
mSeekTimeUs = aTimeUs;
mStartPosUs = aTimeUs;
mDispatchSeekEvents = aDispatchSeekEvents;
nsCOMPtr<nsIRunnable> nsEvent = NS_NewRunnableMethod(mObserver,
&MediaDecoder::SeekingStarted);
NS_DispatchToMainThread(nsEvent, NS_DISPATCH_NORMAL);
if (mDispatchSeekEvents) {
nsCOMPtr<nsIRunnable> nsEvent = NS_NewRunnableMethod(mObserver,
&MediaDecoder::SeekingStarted);
NS_DispatchToMainThread(nsEvent, NS_DISPATCH_NORMAL);
}
if (mPlaying) {
mAudioSink->Pause();
}
mAudioSink->Flush();
if (mPlaying) {
mAudioSink->Flush();
mAudioSink->Start();
} else {
mSeekDuringPause = true;
AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("Fake seek complete during pause"));
nsCOMPtr<nsIRunnable> nsEvent = NS_NewRunnableMethod(mObserver,
&MediaDecoder::SeekingStopped);
NS_DispatchToMainThread(nsEvent, NS_DISPATCH_NORMAL);
if (mStarted) {
mAudioSink->Flush();
}
if (mDispatchSeekEvents) {
mDispatchSeekEvents = false;
AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("Fake seek complete during pause"));
nsCOMPtr<nsIRunnable> nsEvent = NS_NewRunnableMethod(mObserver,
&MediaDecoder::SeekingStopped);
NS_DispatchToMainThread(nsEvent, NS_DISPATCH_NORMAL);
}
}
return OK;
@ -339,6 +384,9 @@ int64_t AudioOffloadPlayer::GetMediaTimeUs()
if (mSeeking) {
return mSeekTimeUs;
}
if (!mStarted) {
return mPositionTimeMediaUs;
}
playPosition = GetOutputPlayPositionUs_l();
if (!mReachedEOS) {
@ -427,8 +475,6 @@ size_t AudioOffloadPlayer::FillBuffer(void* aData, size_t aSize)
return 0;
}
bool postSeekComplete = false;
size_t sizeDone = 0;
size_t sizeRemaining = aSize;
while (sizeRemaining > 0) {
@ -446,9 +492,7 @@ size_t AudioOffloadPlayer::FillBuffer(void* aData, size_t aSize)
mInputBuffer->release();
mInputBuffer = nullptr;
}
mSeeking = false;
postSeekComplete = true;
}
}
@ -491,31 +535,31 @@ size_t AudioOffloadPlayer::FillBuffer(void* aData, size_t aSize)
kKeyTime, &mPositionTimeMediaUs));
}
// need to adjust the mStartPosUs for offload decoding since parser
// might not be able to get the exact seek time requested.
if (refreshSeekTime) {
if (postSeekComplete) {
if (!mSeekDuringPause) {
AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("FillBuffer posting SEEK_COMPLETE"));
nsCOMPtr<nsIRunnable> nsEvent = NS_NewRunnableMethod(mObserver,
&MediaDecoder::SeekingStopped);
NS_DispatchToMainThread(nsEvent, NS_DISPATCH_NORMAL);
} else {
// Callback is already called for seek during pause. Just reset the
// flag
AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("Not posting seek complete as its"
" already faked"));
mSeekDuringPause = false;
}
if (mDispatchSeekEvents && !mSeekDuringPause) {
mDispatchSeekEvents = false;
AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("FillBuffer posting SEEK_COMPLETE"));
nsCOMPtr<nsIRunnable> nsEvent = NS_NewRunnableMethod(mObserver,
&MediaDecoder::SeekingStopped);
NS_DispatchToMainThread(nsEvent, NS_DISPATCH_NORMAL);
NotifyPositionChanged();
postSeekComplete = false;
} else if (mSeekDuringPause) {
// Callback is already called for seek during pause. Just reset the
// flag
AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("Not posting seek complete as its"
" already faked"));
mSeekDuringPause = false;
}
NotifyPositionChanged();
// need to adjust the mStartPosUs for offload decoding since parser
// might not be able to get the exact seek time requested.
mStartPosUs = mPositionTimeMediaUs;
AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("Adjust seek time to: %.2f",
mStartPosUs / 1E6));
// clear seek time with mLock locked and once we have valid
// mPositionTimeMediaUs
// before clearing mSeekTimeUs check if a new seek request has been

View File

@ -86,7 +86,7 @@ public:
// To update progress bar when the element is visible
void SetElementVisibility(bool aIsVisible);
void ChangeState(MediaDecoder::PlayState aState);
status_t ChangeState(MediaDecoder::PlayState aState);
void SetVolume(double aVolume);
@ -97,6 +97,9 @@ public:
void TimeUpdate();
// Close the audio sink, stop time updates, frees the input buffers
void Reset();
private:
// Set when audio source is started and audioSink is initialized
// Used only in main thread
@ -122,6 +125,12 @@ private:
// mLock
bool mSeekDuringPause;
// Seek can be triggered internally or by MediaDecoder. This bool is to
// to track seek triggered by MediaDecoder so that we can send back
// SeekingStarted and SeekingStopped events.
// Used in main thread and offload callback thread, protected by Mutex mLock
bool mDispatchSeekEvents;
// Set when the HTML Audio Element is visible to the user.
// Used only in main thread
bool mIsElementVisible;
@ -164,7 +173,7 @@ private:
android::sp<MediaSource> mSource;
// Audio sink wrapper to access offloaded audio tracks
// Used in main thread and offload callback thread, access is protected by
// Used in main thread and offload callback thread
// Race conditions are protected in underlying Android::AudioTrack class
android::sp<AudioSink> mAudioSink;
@ -175,10 +184,17 @@ private:
MediaOmxDecoder* mObserver;
TimeStamp mLastFireUpdateTime;
// Timer to trigger position changed events
nsCOMPtr<nsITimer> mTimeUpdateTimer;
// Timer to reset AudioSink when audio is paused for OFFLOAD_PAUSE_MAX_USECS.
// It is triggered in Pause() and canceled when there is a Play() within
// OFFLOAD_PAUSE_MAX_USECS. Used only from main thread so no lock is needed.
nsCOMPtr<nsITimer> mResetTimer;
int64_t GetMediaTimeUs();
// Provide the playback position in microseconds from total number of
// frames played by audio track
int64_t GetOutputPlayPositionUs_l() const;
@ -198,16 +214,14 @@ private:
bool IsSeeking();
// Set mSeekTime to the given position and restart the sink. Actual seek
// happens in FillBuffer(). To MediaDecoder, send SeekingStarted event always
// and SeekingStopped event when the play state is paused.
// happens in FillBuffer(). If aDispatchSeekEvents is true, send
// SeekingStarted event always and SeekingStopped event when the play state is
// paused to MediaDecoder.
// When decoding and playing happens separately, if there is a seek during
// pause, we can decode and keep data ready.
// In case of offload player, no way to seek during pause. So just fake that
// seek is done.
status_t SeekTo(int64_t aTimeUs);
// Close the audio sink, stop time updates, frees the input buffers
void Reset();
status_t SeekTo(int64_t aTimeUs, bool aDispatchSeekEvents = false);
// Start/Resume the audio sink so that callback will start being called to get
// compressed data

View File

@ -49,7 +49,10 @@ public:
return android::NO_INIT;
}
virtual void ChangeState(MediaDecoder::PlayState aState) {}
virtual status_t ChangeState(MediaDecoder::PlayState aState)
{
return android::NO_INIT;
}
virtual void SetVolume(double aVolume) {}

View File

@ -65,7 +65,6 @@ void MediaOmxDecoder::MetadataLoaded(int aChannels,
MediaDecoder::MetadataLoaded(aChannels, aRate, aHasAudio, aHasVideo, aTags);
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
if (!mCanOffloadAudio || mFallbackToStateMachine || mOutputStreams.Length() ||
mInitialPlaybackRate != 1.0) {
DECODER_LOG(PR_LOG_DEBUG, ("In %s Offload Audio check failed",
@ -95,7 +94,6 @@ void MediaOmxDecoder::PauseStateMachine()
MOZ_ASSERT(NS_IsMainThread());
GetReentrantMonitor().AssertCurrentThreadIn();
DECODER_LOG(PR_LOG_DEBUG, ("%s", __PRETTY_FUNCTION__));
if (!mDecoderStateMachine) {
return;
}
@ -106,7 +104,7 @@ void MediaOmxDecoder::PauseStateMachine()
void MediaOmxDecoder::ResumeStateMachine()
{
MOZ_ASSERT(NS_IsMainThread());
GetReentrantMonitor().AssertCurrentThreadIn();
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
DECODER_LOG(PR_LOG_DEBUG, ("%s current time %f", __PRETTY_FUNCTION__,
mCurrentTime));
@ -130,7 +128,6 @@ void MediaOmxDecoder::AudioOffloadTearDown()
DECODER_LOG(PR_LOG_DEBUG, ("%s", __PRETTY_FUNCTION__));
{
// Audio offload player sent tear down event. Fallback to state machine
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
ResumeStateMachine();
}
}
@ -143,7 +140,6 @@ void MediaOmxDecoder::AddOutputStream(ProcessedMediaStream* aStream,
if (mAudioOffloadPlayer) {
// Offload player cannot handle MediaStream. Fallback
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
ResumeStateMachine();
}
@ -158,7 +154,6 @@ void MediaOmxDecoder::SetPlaybackRate(double aPlaybackRate)
if (mAudioOffloadPlayer &&
((aPlaybackRate != 0.0) || (aPlaybackRate != 1.0))) {
// Offload player cannot handle playback rate other than 1/0. Fallback
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
ResumeStateMachine();
}
@ -168,21 +163,22 @@ void MediaOmxDecoder::SetPlaybackRate(double aPlaybackRate)
void MediaOmxDecoder::ChangeState(PlayState aState)
{
MOZ_ASSERT(NS_IsMainThread());
// Keep MediaDecoder state in sync with MediaElement irrespective of offload
// playback so it will continue to work in normal mode when offloading fails
// in between
MediaDecoder::ChangeState(aState);
if (mAudioOffloadPlayer) {
mAudioOffloadPlayer->ChangeState(aState);
status_t err = mAudioOffloadPlayer->ChangeState(aState);
if (err != OK) {
ResumeStateMachine();
}
}
}
void MediaOmxDecoder::ApplyStateToStateMachine(PlayState aState)
{
MOZ_ASSERT(NS_IsMainThread());
// During offload playback, state machine should be in dormant state.
// ApplyStateToStateMachine() can change state machine state to
// something else or reset the seek time. So don't call this when audio is

View File

@ -538,8 +538,17 @@ nsDOMWindowUtils::SetResolution(float aXResolution, float aYResolution)
}
nsIPresShell* presShell = GetPresShell();
return presShell ? presShell->SetResolution(aXResolution, aYResolution)
: NS_ERROR_FAILURE;
if (!presShell) {
return NS_ERROR_FAILURE;
}
nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
if (sf) {
sf->SetResolution(gfxSize(aXResolution, aYResolution));
presShell->SetResolution(aXResolution, aYResolution);
}
return NS_OK;
}
NS_IMETHODIMP
@ -550,13 +559,21 @@ nsDOMWindowUtils::GetResolution(float* aXResolution, float* aYResolution)
}
nsIPresShell* presShell = GetPresShell();
if (!presShell) {
return NS_ERROR_FAILURE;
}
if (presShell) {
nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
if (sf) {
const gfxSize& res = sf->GetResolution();
*aXResolution = res.width;
*aYResolution = res.height;
} else {
*aXResolution = presShell->GetXResolution();
*aYResolution = presShell->GetYResolution();
return NS_OK;
}
return NS_ERROR_FAILURE;
return NS_OK;
}
NS_IMETHODIMP

View File

@ -999,15 +999,6 @@ BluetoothHfpManager::SendResponse(bthf_at_response_t aResponseCode)
void
BluetoothHfpManager::UpdatePhoneCIND(uint32_t aCallIndex, bool aSend)
{
// Update callsetup state
uint16_t callState = mCurrentCallArray[aCallIndex].mState;
if (callState == nsITelephonyProvider::CALL_STATE_CONNECTED ||
callState == nsITelephonyProvider::CALL_STATE_HELD) {
mCallSetupState = nsITelephonyProvider::CALL_STATE_DISCONNECTED;
} else {
mCallSetupState = callState;
}
NS_ENSURE_TRUE_VOID(sBluetoothHfpInterface);
int numActive = GetNumberOfCalls(nsITelephonyProvider::CALL_STATE_CONNECTED);
@ -1016,8 +1007,8 @@ BluetoothHfpManager::UpdatePhoneCIND(uint32_t aCallIndex, bool aSend)
nsAutoCString number = NS_ConvertUTF16toUTF8(mCurrentCallArray[aCallIndex].mNumber);
bthf_call_addrtype_t type = mCurrentCallArray[aCallIndex].mType;
BT_LOGR("[%d] state %d => BTHF: active[%d] held[%d] state[%d]",
aCallIndex, callState, numActive, numHeld, bthfCallState);
BT_LOGR("[%d] state %d => BTHF: active[%d] held[%d] state[%d]", aCallIndex,
mCurrentCallArray[aCallIndex].mState, numActive, numHeld, bthfCallState);
NS_ENSURE_TRUE_VOID(BT_STATUS_SUCCESS ==
sBluetoothHfpInterface->phone_state_change(
@ -1124,6 +1115,22 @@ BluetoothHfpManager::HandleCallStateChanged(uint32_t aCallIndex,
mCurrentCallArray[aCallIndex].mType = BTHF_CALL_ADDRTYPE_INTERNATIONAL;
}
bool isSetupCall = (aCallState == nsITelephonyProvider::CALL_STATE_INCOMING ||
aCallState == nsITelephonyProvider::CALL_STATE_ALERTING ||
aCallState == nsITelephonyProvider::CALL_STATE_DIALING);
bool hasSetupCall = (FindFirstCall(nsITelephonyProvider::CALL_STATE_INCOMING) ||
FindFirstCall(nsITelephonyProvider::CALL_STATE_ALERTING) ||
FindFirstCall(nsITelephonyProvider::CALL_STATE_DIALING));
// Update callsetup state when
// 1) this call is in call setup
// 2) all calls in the call array including this call are not in call setup
if (isSetupCall) {
mCallSetupState = aCallState;
} else if (!hasSetupCall) {
mCallSetupState = nsITelephonyProvider::CALL_STATE_DISCONNECTED;
}
UpdatePhoneCIND(aCallIndex, aSend);
switch (aCallState) {

View File

@ -1162,6 +1162,74 @@ AppendDeviceName(BluetoothSignal& aSignal)
unused << handler.forget(); // picked up by callback handler
}
class SetPairingConfirmationTask : public Task
{
public:
SetPairingConfirmationTask(const nsAString& aDeviceAddress,
bool aConfirm,
BluetoothReplyRunnable* aRunnable)
: mDeviceAddress(aDeviceAddress)
, mConfirm(aConfirm)
, mRunnable(aRunnable)
{
MOZ_ASSERT(!mDeviceAddress.IsEmpty());
}
void Run() MOZ_OVERRIDE
{
MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
MOZ_ASSERT(sDBusConnection);
nsAutoString errorStr;
BluetoothValue v = true;
DBusMessage *msg;
if (!sPairingReqTable->Get(mDeviceAddress, &msg) && mRunnable) {
BT_WARNING("%s: Couldn't get original request message.", __FUNCTION__);
errorStr.AssignLiteral("Couldn't get original request message.");
DispatchBluetoothReply(mRunnable, v, errorStr);
return;
}
DBusMessage *reply;
if (mConfirm) {
reply = dbus_message_new_method_return(msg);
} else {
reply = dbus_message_new_error(msg, "org.bluez.Error.Rejected",
"User rejected confirmation");
}
if (!reply) {
BT_WARNING("%s: Memory can't be allocated for the message.", __FUNCTION__);
dbus_message_unref(msg);
errorStr.AssignLiteral("Memory can't be allocated for the message.");
if (mRunnable) {
DispatchBluetoothReply(mRunnable, v, errorStr);
}
return;
}
bool result = sDBusConnection->Send(reply);
if (!result) {
errorStr.AssignLiteral("Can't send message!");
}
dbus_message_unref(msg);
dbus_message_unref(reply);
sPairingReqTable->Remove(mDeviceAddress);
if (mRunnable) {
DispatchBluetoothReply(mRunnable, v, errorStr);
}
}
private:
nsString mDeviceAddress;
bool mConfirm;
nsRefPtr<BluetoothReplyRunnable> mRunnable;
};
static DBusHandlerResult
AgentEventFilter(DBusConnection *conn, DBusMessage *msg, void *data)
{
@ -1331,7 +1399,25 @@ AgentEventFilter(DBusConnection *conn, DBusMessage *msg, void *data)
dbus_connection_send(conn, reply, nullptr);
dbus_message_unref(reply);
// Do not send an notification to upper layer, too annoying.
// Do not send a notification to upper layer, too annoying.
return DBUS_HANDLER_RESULT_HANDLED;
} else if (dbus_message_is_method_call(msg, DBUS_AGENT_IFACE, "RequestPairingConsent")) {
// Directly SetPairingconfirmation for RequestPairingConsent here
if (!dbus_message_get_args(msg, nullptr,
DBUS_TYPE_OBJECT_PATH, &objectPath,
DBUS_TYPE_INVALID)) {
errorStr.AssignLiteral("Invalid arguments: RequestPairingConsent()");
goto handle_error;
}
nsString address = GetAddressFromObjectPath(NS_ConvertUTF8toUTF16(objectPath));
sPairingReqTable->Put(address, msg);
Task* task = new SetPairingConfirmationTask(address, true, nullptr);
DispatchToDBusThread(task);
// Increase dbus message reference counts, it will be decreased in
// SetPairingConfirmationTask
dbus_message_ref(msg);
// Do not send a notification to upper layer
return DBUS_HANDLER_RESULT_HANDLED;
} else {
#ifdef DEBUG
@ -3182,68 +3268,6 @@ BluetoothDBusService::SetPasskeyInternal(const nsAString& aDeviceAddress,
return true;
}
class SetPairingConfirmationTask : public Task
{
public:
SetPairingConfirmationTask(const nsAString& aDeviceAddress,
bool aConfirm,
BluetoothReplyRunnable* aRunnable)
: mDeviceAddress(aDeviceAddress)
, mConfirm(aConfirm)
, mRunnable(aRunnable)
{
MOZ_ASSERT(!mDeviceAddress.IsEmpty());
MOZ_ASSERT(mRunnable);
}
void Run() MOZ_OVERRIDE
{
MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
MOZ_ASSERT(sDBusConnection);
nsAutoString errorStr;
BluetoothValue v = true;
DBusMessage *msg;
if (!sPairingReqTable->Get(mDeviceAddress, &msg)) {
BT_WARNING("%s: Couldn't get original request message.", __FUNCTION__);
errorStr.AssignLiteral("Couldn't get original request message.");
DispatchBluetoothReply(mRunnable, v, errorStr);
return;
}
DBusMessage *reply;
if (mConfirm) {
reply = dbus_message_new_method_return(msg);
} else {
reply = dbus_message_new_error(msg, "org.bluez.Error.Rejected",
"User rejected confirmation");
}
if (!reply) {
BT_WARNING("%s: Memory can't be allocated for the message.", __FUNCTION__);
dbus_message_unref(msg);
errorStr.AssignLiteral("Memory can't be allocated for the message.");
DispatchBluetoothReply(mRunnable, v, errorStr);
return;
}
bool result = sDBusConnection->Send(reply);
if (!result) {
errorStr.AssignLiteral("Can't send message!");
}
dbus_message_unref(msg);
dbus_message_unref(reply);
sPairingReqTable->Remove(mDeviceAddress);
DispatchBluetoothReply(mRunnable, v, errorStr);
}
private:
nsString mDeviceAddress;
bool mConfirm;
nsRefPtr<BluetoothReplyRunnable> mRunnable;
};
bool
BluetoothDBusService::SetPairingConfirmationInternal(

View File

@ -51,6 +51,7 @@
#include <cutils/properties.h>
#include <system/audio.h>
#define RES_720P (720 * 1280)
namespace android {
GonkRecorder::GonkRecorder()
@ -370,6 +371,11 @@ status_t GonkRecorder::setParamMaxFileSizeBytes(int64_t bytes) {
RE_LOGW("Target file size (%lld bytes) is too small to be respected", bytes);
}
if (bytes >= 0xffffffffLL) {
RE_LOGW("Target file size (%lld bytes) too large to be respected, clipping to 4GB", bytes);
bytes = 0xffffffffLL;
}
mMaxFileSizeBytes = bytes;
return OK;
}
@ -656,6 +662,13 @@ status_t GonkRecorder::setClientName(const String16& clientName) {
}
status_t GonkRecorder::prepare() {
if (mVideoSource != VIDEO_SOURCE_LIST_END && mVideoEncoder != VIDEO_ENCODER_LIST_END &&
mVideoHeight && mVideoWidth && // Video recording
(mVideoHeight * mVideoWidth >= RES_720P)) {
// TODO: Above check needs to be updated when mMaxFileDurationUs is set from camera app
RE_LOGV("Video is high resolution so setting 64-bit file offsets");
setParam64BitFileOffset(true);
}
return OK;
}

View File

@ -30,14 +30,6 @@ using namespace mozilla::dom;
using mozilla::ErrorResult;
using mozilla::dom::telephony::kOutgoingPlaceholderCallIndex;
namespace {
typedef nsAutoTArray<Telephony*, 2> TelephonyList;
TelephonyList* gTelephonyList;
} // anonymous namespace
class Telephony::Listener : public nsITelephonyListener
{
Telephony* mTelephony;
@ -121,26 +113,11 @@ public:
Telephony::Telephony(nsPIDOMWindow* aOwner)
: DOMEventTargetHelper(aOwner), mActiveCall(nullptr), mEnumerated(false)
{
if (!gTelephonyList) {
gTelephonyList = new TelephonyList();
}
gTelephonyList->AppendElement(this);
}
Telephony::~Telephony()
{
Shutdown();
NS_ASSERTION(gTelephonyList, "This should never be null!");
NS_ASSERTION(gTelephonyList->Contains(this), "Should be in the list!");
if (gTelephonyList->Length() == 1) {
delete gTelephonyList;
gTelephonyList = nullptr;
} else {
gTelephonyList->RemoveElement(this);
}
}
void

View File

@ -787,7 +787,8 @@ TelephonyProvider.prototype = {
aCall.isSwitchable,
aCall.isMergeable]);
} else {
this.notifyCallError(aClientId, aCall.callIndex, aCall.failCause);
this._notifyAllListeners("notifyError",
[aClientId, aCall.callIndex, aCall.failCause]);
}
delete this._currentCalls[aClientId][aCall.callIndex];
@ -796,13 +797,6 @@ TelephonyProvider.prototype = {
}
},
/**
* Handle call error.
*/
notifyCallError: function(aClientId, aCallIndex, aErrorMsg) {
this._notifyAllListeners("notifyError", [aClientId, aCallIndex, aErrorMsg]);
},
/**
* Handle an incoming call.
*

View File

@ -10,14 +10,11 @@
"@mozilla.org/telephony/gonktelephonyprovider;1"
%}
[scriptable, uuid(5fdd720f-fbe8-46f5-b671-3bf3360013dd)]
[scriptable, uuid(9d884482-90fc-4050-a4b1-1a370afe7a35)]
interface nsIGonkTelephonyProvider : nsITelephonyProvider
{
void notifyCallDisconnected(in unsigned long clientId, in jsval call);
void notifyCallError(in unsigned long clientId, in long callIndex,
in AString error);
void notifyCallRing();
void notifyCallStateChanged(in unsigned long clientId, in jsval call,

View File

@ -12,6 +12,7 @@
#define nsPresState_h_
#include "nsPoint.h"
#include "gfxPoint.h"
#include "nsAutoPtr.h"
class nsPresState
@ -20,6 +21,7 @@ public:
nsPresState()
: mContentData(nullptr)
, mScrollState(0, 0)
, mResolution(1.0, 1.0)
, mDisabledSet(false)
, mDisabled(false)
{}
@ -29,18 +31,28 @@ public:
mScrollState = aState;
}
nsPoint GetScrollState()
nsPoint GetScrollState() const
{
return mScrollState;
}
void SetResolution(const gfxSize& aSize)
{
mResolution = aSize;
}
gfxSize GetResolution() const
{
return mResolution;
}
void ClearNonScrollState()
{
mContentData = nullptr;
mDisabledSet = false;
}
bool GetDisabled()
bool GetDisabled() const
{
return mDisabled;
}
@ -51,12 +63,12 @@ public:
mDisabledSet = true;
}
bool IsDisabledSet()
bool IsDisabledSet() const
{
return mDisabledSet;
}
nsISupports* GetStateProperty()
nsISupports* GetStateProperty() const
{
return mContentData;
}
@ -70,6 +82,7 @@ public:
protected:
nsCOMPtr<nsISupports> mContentData;
nsPoint mScrollState;
gfxSize mResolution;
bool mDisabledSet;
bool mDisabled;
};

View File

@ -1600,6 +1600,7 @@ ScrollFrameHelper::ScrollFrameHelper(nsContainerFrame* aOuter,
, mScrollPosAtLastPaint(0, 0)
, mRestorePos(-1, -1)
, mLastPos(-1, -1)
, mResolution(1.0, 1.0)
, mScrollPosForLayerPixelAlignment(-1, -1)
, mLastUpdateImagesPos(-1, -1)
, mNeverHasVerticalScrollbar(false)
@ -2786,6 +2787,18 @@ ScrollFrameHelper::GetScrollPositionClampingScrollPortSize() const
return mScrollPort.Size();
}
gfxSize
ScrollFrameHelper::GetResolution() const
{
return mResolution;
}
void
ScrollFrameHelper::SetResolution(const gfxSize& aResolution)
{
mResolution = aResolution;
}
static void
AdjustForWholeDelta(int32_t aDelta, nscoord* aCoord)
{
@ -4486,7 +4499,7 @@ ScrollFrameHelper::GetCoordAttribute(nsIFrame* aBox, nsIAtom* aAtom,
}
nsPresState*
ScrollFrameHelper::SaveState()
ScrollFrameHelper::SaveState() const
{
nsIScrollbarMediator* mediator = do_QueryFrame(GetScrolledFrame());
if (mediator) {
@ -4511,6 +4524,7 @@ ScrollFrameHelper::SaveState()
pt = mRestorePos;
}
state->SetScrollState(pt);
state->SetResolution(mResolution);
return state;
}
@ -4520,6 +4534,11 @@ ScrollFrameHelper::RestoreState(nsPresState* aState)
mRestorePos = aState->GetScrollState();
mDidHistoryRestore = true;
mLastPos = mScrolledFrame ? GetLogicalScrollPosition() : nsPoint(0,0);
mResolution = aState->GetResolution();
if (mIsRoot) {
mOuter->PresContext()->PresShell()->SetResolution(mResolution.width, mResolution.height);
}
}
void

View File

@ -163,6 +163,9 @@ public:
// Get the scroll range assuming the scrollport has size (aWidth, aHeight).
nsRect GetScrollRange(nscoord aWidth, nscoord aHeight) const;
nsSize GetScrollPositionClampingScrollPortSize() const;
gfxSize GetResolution() const;
void SetResolution(const gfxSize& aResolution);
protected:
nsRect GetScrollRangeForClamping() const;
@ -207,7 +210,7 @@ public:
nsSize GetLineScrollAmount() const;
nsSize GetPageScrollAmount() const;
nsPresState* SaveState();
nsPresState* SaveState() const;
void RestoreState(nsPresState* aState);
nsIFrame* GetScrolledFrame() const { return mScrolledFrame; }
@ -348,6 +351,9 @@ public:
// other than trying to restore mRestorePos.
nsPoint mLastPos;
// The current resolution derived from the zoom level and device pixel ratio.
gfxSize mResolution;
nsExpirationState mActivityExpirationState;
nsCOMPtr<nsITimer> mScrollActivityTimer;
@ -577,6 +583,12 @@ public:
virtual nsSize GetScrollPositionClampingScrollPortSize() const MOZ_OVERRIDE {
return mHelper.GetScrollPositionClampingScrollPortSize();
}
virtual gfxSize GetResolution() const MOZ_OVERRIDE {
return mHelper.GetResolution();
}
virtual void SetResolution(const gfxSize& aResolution) MOZ_OVERRIDE {
return mHelper.SetResolution(aResolution);
}
virtual nsSize GetLineScrollAmount() const MOZ_OVERRIDE {
return mHelper.GetLineScrollAmount();
}
@ -887,6 +899,12 @@ public:
virtual nsSize GetScrollPositionClampingScrollPortSize() const MOZ_OVERRIDE {
return mHelper.GetScrollPositionClampingScrollPortSize();
}
virtual gfxSize GetResolution() const MOZ_OVERRIDE {
return mHelper.GetResolution();
}
virtual void SetResolution(const gfxSize& aResolution) MOZ_OVERRIDE {
return mHelper.SetResolution(aResolution);
}
virtual nsSize GetLineScrollAmount() const MOZ_OVERRIDE {
return mHelper.GetLineScrollAmount();
}

View File

@ -134,7 +134,14 @@ public:
* position.
*/
virtual nsSize GetScrollPositionClampingScrollPortSize() const = 0;
/**
* Get the element resolution.
*/
virtual gfxSize GetResolution() const = 0;
/**
* Set the element resolution.
*/
virtual void SetResolution(const gfxSize& aResolution) = 0;
/**
* Return how much we would try to scroll by in each direction if
* asked to scroll by one "line" vertically and horizontally.

View File

@ -83,7 +83,7 @@ public class HomeProvider extends SQLiteBridgeContentProvider {
private Cursor queryFakeItems(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
JSONArray items = null;
try {
final String jsonString = RawResource.get(getContext(), R.raw.fake_home_items);
final String jsonString = RawResource.getAsString(getContext(), R.raw.fake_home_items);
items = new JSONArray(jsonString);
} catch (IOException e) {
Log.e(LOGTAG, "Error getting fake home items", e);

View File

@ -86,6 +86,13 @@ public class ToolbarComponent extends BaseComponent {
return (ImageButton) getToolbarView().findViewById(R.id.forward);
}
/**
* Returns the View for the edit cancel button in the browser toolbar.
*/
private ImageButton getEditCancelButton() {
return (ImageButton) getToolbarView().findViewById(R.id.edit_cancel);
}
private CharSequence getTitle() {
return getTitleHelper(true);
}
@ -145,14 +152,19 @@ public class ToolbarComponent extends BaseComponent {
public ToolbarComponent dismissEditingMode() {
assertIsEditing();
if (getUrlEditText().isInputMethodTarget()) {
// Drop the soft keyboard.
// TODO: Solo.hideSoftKeyboard() does not clear focus, causing unexpected
// behavior, but we may want to use it over goBack().
mSolo.goBack();
}
// Cancel Button not implemeneted in tablet.
if (DeviceHelper.isTablet()) {
if (getUrlEditText().isInputMethodTarget()) {
// Drop the soft keyboard.
// TODO: Solo.hideSoftKeyboard() does not clear focus, causing unexpected
// behavior, but we may want to use it over goBack().
mSolo.goBack();
}
mSolo.goBack();
mSolo.goBack();
} else {
mSolo.clickOnView(getEditCancelButton());
}
waitForNotEditing();

View File

@ -12,8 +12,17 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
/**
* {@code RawResource} provides API to load raw resources in different
* forms. For now, we only load them as strings. We're using raw resources
* as localizable 'assets' as opposed to a string that can be directly
* translatable e.g. JSON file vs string.
*
* This is just a utility class to avoid code duplication for the different
* cases where need to read such assets.
*/
public final class RawResource {
public static String get(Context context, int id) throws IOException {
public static String getAsString(Context context, int id) throws IOException {
InputStreamReader reader = null;
try {

View File

@ -2882,6 +2882,7 @@ function Tab(aURL, aParams) {
this.lastTouchedAt = Date.now();
this._zoom = 1.0;
this._drawZoom = 1.0;
this._restoreZoom = false;
this._fixedMarginLeft = 0;
this._fixedMarginTop = 0;
this._fixedMarginRight = 0;
@ -3486,6 +3487,7 @@ Tab.prototype = {
let win = this.browser.contentWindow;
win.scrollTo(x, y);
this.saveSessionZoom(aViewport.zoom);
this.userScrollPos.x = win.scrollX;
this.userScrollPos.y = win.scrollY;
@ -3535,12 +3537,13 @@ Tab.prototype = {
getViewport: function() {
let screenW = gScreenWidth - gViewportMargins.left - gViewportMargins.right;
let screenH = gScreenHeight - gViewportMargins.top - gViewportMargins.bottom;
let zoom = this.restoredSessionZoom() || this._zoom;
let viewport = {
width: screenW,
height: screenH,
cssWidth: screenW / this._zoom,
cssHeight: screenH / this._zoom,
cssWidth: screenW / zoom,
cssHeight: screenH / zoom,
pageLeft: 0,
pageTop: 0,
pageRight: screenW,
@ -3548,13 +3551,13 @@ Tab.prototype = {
// We make up matching css page dimensions
cssPageLeft: 0,
cssPageTop: 0,
cssPageRight: screenW / this._zoom,
cssPageBottom: screenH / this._zoom,
cssPageRight: screenW / zoom,
cssPageBottom: screenH / zoom,
fixedMarginLeft: this._fixedMarginLeft,
fixedMarginTop: this._fixedMarginTop,
fixedMarginRight: this._fixedMarginRight,
fixedMarginBottom: this._fixedMarginBottom,
zoom: this._zoom,
zoom: zoom,
};
// Set the viewport offset to current scroll offset
@ -4186,6 +4189,9 @@ Tab.prototype = {
tabID: this.id,
};
// Restore zoom only when moving in session history, not for new page loads.
this._restoreZoom = aMessage != "New";
if (aParams) {
if ("url" in aParams)
message.url = aParams.url;
@ -4198,6 +4204,22 @@ Tab.prototype = {
sendMessageToJava(message);
},
saveSessionZoom: function(aZoom) {
let cwu = this.browser.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
cwu.setResolution(aZoom / window.devicePixelRatio, aZoom / window.devicePixelRatio);
},
restoredSessionZoom: function() {
if (!this._restoreZoom) {
return null;
}
let cwu = this.browser.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
let res = {x: {}, y: {}};
cwu.getResolution(res.x, res.y);
return res.x.value * window.devicePixelRatio;
},
OnHistoryNewEntry: function(aUri) {
this._sendHistoryEvent("New", { url: aUri.spec });
},
@ -4322,8 +4344,11 @@ Tab.prototype = {
// In all of these cases, we maintain how much actual content is visible
// within the screen width. Note that "actual content" may be different
// with respect to CSS pixels because of the CSS viewport size changing.
let zoomScale = (screenW * oldBrowserWidth) / (aOldScreenWidth * viewportW);
let zoom = (aInitialLoad && metadata.defaultZoom) ? metadata.defaultZoom : this.clampZoom(this._zoom * zoomScale);
let zoom = this.restoredSessionZoom() || metadata.defaultZoom;
if (!zoom || !aInitialLoad) {
let zoomScale = (screenW * oldBrowserWidth) / (aOldScreenWidth * viewportW);
zoom = this.clampZoom(this._zoom * zoomScale);
}
this.setResolution(zoom, false);
this.setScrollClampingSize(zoom);
@ -4459,7 +4484,8 @@ Tab.prototype = {
// and zoom when calculating the new ones, so we need to reset these
// things here before calling updateMetadata.
this.setBrowserSize(kDefaultCSSViewportWidth, kDefaultCSSViewportHeight);
this.setResolution(gScreenWidth / this.browserWidth, false);
let zoom = this.restoredSessionZoom() || gScreenWidth / this.browserWidth;
this.setResolution(zoom, true);
ViewportHandler.updateMetadata(this, true);
// Note that if we draw without a display-port, things can go wrong. By the

View File

@ -13,6 +13,7 @@ jar.sources += [
'src/tests/BrowserTestCase.java',
'src/tests/TestGeckoSharedPrefs.java',
'src/tests/TestJarReader.java',
'src/tests/TestRawResource.java',
'src/tests/TestTopSitesCursorWrapper.java',
]
jar.generated_sources = [] # None yet -- try to keep it this way.

View File

@ -0,0 +1,67 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
package org.mozilla.gecko.browser.tests;
import android.content.Context;
import android.content.res.Resources;
import android.test.mock.MockContext;
import android.test.mock.MockResources;
import android.util.TypedValue;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.IOException;
import org.mozilla.gecko.util.RawResource;
/**
* Tests whether RawResource.getAsString() produces the right String
* result after reading the returned raw resource's InputStream.
*/
public class TestRawResource extends BrowserTestCase {
private static final int RAW_RESOURCE_ID = 1;
private static final String RAW_CONTENTS = "RAW";
private static class TestContext extends MockContext {
private final Resources resources;
public TestContext() {
resources = new TestResources();
}
@Override
public Resources getResources() {
return resources;
}
}
/**
* Browser instrumentation tests can't have access to test-only
* resources (bug 994135) yet so we mock the access to resources
* for now.
*/
private static class TestResources extends MockResources {
@Override
public InputStream openRawResource(int id) {
if (id == RAW_RESOURCE_ID) {
return new ByteArrayInputStream(RAW_CONTENTS.getBytes());
}
return null;
}
}
public void testGet() {
Context context = new TestContext();
String result;
try {
result = RawResource.getAsString(context, RAW_RESOURCE_ID);
} catch (IOException e) {
result = null;
}
assertEquals(RAW_CONTENTS, result);
}
}

View File

@ -7,6 +7,7 @@
include protocol PHttpChannel;
include protocol PFTPChannel;
include protocol PRtspChannel;
include URIParams;
include InputStreamParams;
@ -89,5 +90,15 @@ union ChannelDiverterArgs
PFTPChannel;
};
//-----------------------------------------------------------------------------
// RTSP IPDL structs
//-----------------------------------------------------------------------------
struct RtspChannelConnectArgs
{
URIParams uri;
uint32_t channelId;
};
} // namespace ipc
} // namespace mozilla

View File

@ -22,6 +22,7 @@
#include "mozilla/dom/network/UDPSocketChild.h"
#ifdef NECKO_PROTOCOL_rtsp
#include "mozilla/net/RtspControllerChild.h"
#include "mozilla/net/RtspChannelChild.h"
#endif
#include "SerializedLoadContext.h"
@ -181,6 +182,23 @@ NeckoChild::DeallocPRtspControllerChild(PRtspControllerChild* child)
return true;
}
PRtspChannelChild*
NeckoChild::AllocPRtspChannelChild(const RtspChannelConnectArgs& aArgs)
{
NS_NOTREACHED("AllocPRtspController should not be called");
return nullptr;
}
bool
NeckoChild::DeallocPRtspChannelChild(PRtspChannelChild* child)
{
#ifdef NECKO_PROTOCOL_rtsp
RtspChannelChild* p = static_cast<RtspChannelChild*>(child);
p->ReleaseIPDLReference();
#endif
return true;
}
PTCPSocketChild*
NeckoChild::AllocPTCPSocketChild()
{

View File

@ -62,6 +62,10 @@ protected:
virtual bool DeallocPRemoteOpenFileChild(PRemoteOpenFileChild*) MOZ_OVERRIDE;
virtual PRtspControllerChild* AllocPRtspControllerChild() MOZ_OVERRIDE;
virtual bool DeallocPRtspControllerChild(PRtspControllerChild*) MOZ_OVERRIDE;
virtual PRtspChannelChild*
AllocPRtspChannelChild(const RtspChannelConnectArgs& aArgs)
MOZ_OVERRIDE;
virtual bool DeallocPRtspChannelChild(PRtspChannelChild*) MOZ_OVERRIDE;
virtual PChannelDiverterChild*
AllocPChannelDiverterChild(const ChannelDiverterArgs& channel) MOZ_OVERRIDE;
virtual bool

View File

@ -15,6 +15,7 @@
#include "mozilla/net/WebSocketChannelParent.h"
#ifdef NECKO_PROTOCOL_rtsp
#include "mozilla/net/RtspControllerParent.h"
#include "mozilla/net/RtspChannelParent.h"
#endif
#include "mozilla/net/DNSRequestParent.h"
#include "mozilla/net/RemoteOpenFileParent.h"
@ -336,6 +337,42 @@ NeckoParent::DeallocPRtspControllerParent(PRtspControllerParent* actor)
return true;
}
PRtspChannelParent*
NeckoParent::AllocPRtspChannelParent(const RtspChannelConnectArgs& aArgs)
{
#ifdef NECKO_PROTOCOL_rtsp
nsCOMPtr<nsIURI> uri = DeserializeURI(aArgs.uri());
RtspChannelParent *p = new RtspChannelParent(uri);
p->AddRef();
return p;
#else
return nullptr;
#endif
}
bool
NeckoParent::RecvPRtspChannelConstructor(
PRtspChannelParent* aActor,
const RtspChannelConnectArgs& aConnectArgs)
{
#ifdef NECKO_PROTOCOL_rtsp
RtspChannelParent* p = static_cast<RtspChannelParent*>(aActor);
return p->Init(aConnectArgs);
#else
return nullptr;
#endif
}
bool
NeckoParent::DeallocPRtspChannelParent(PRtspChannelParent* actor)
{
#ifdef NECKO_PROTOCOL_rtsp
RtspChannelParent* p = static_cast<RtspChannelParent*>(actor);
p->Release();
#endif
return true;
}
PTCPSocketParent*
NeckoParent::AllocPTCPSocketParent()
{

View File

@ -144,6 +144,15 @@ protected:
virtual PRtspControllerParent* AllocPRtspControllerParent() MOZ_OVERRIDE;
virtual bool DeallocPRtspControllerParent(PRtspControllerParent*) MOZ_OVERRIDE;
virtual PRtspChannelParent*
AllocPRtspChannelParent(const RtspChannelConnectArgs& aArgs)
MOZ_OVERRIDE;
virtual bool
RecvPRtspChannelConstructor(PRtspChannelParent* aActor,
const RtspChannelConnectArgs& aArgs)
MOZ_OVERRIDE;
virtual bool DeallocPRtspChannelParent(PRtspChannelParent*) MOZ_OVERRIDE;
virtual PChannelDiverterParent*
AllocPChannelDiverterParent(const ChannelDiverterArgs& channel) MOZ_OVERRIDE;
virtual bool

View File

@ -22,6 +22,7 @@ include protocol PBlob; //FIXME: bug #792908
include protocol PFileDescriptorSet;
include protocol PRtspController;
include protocol PRtspChannel;
include URIParams;
include InputStreamParams;
include NeckoChannelParams;
@ -47,6 +48,7 @@ sync protocol PNecko
manages PDNSRequest;
manages PRemoteOpenFile;
manages PRtspController;
manages PRtspChannel;
manages PChannelDiverter;
parent:
@ -71,6 +73,7 @@ parent:
HTMLDNSPrefetch(nsString hostname, uint16_t flags);
CancelHTMLDNSPrefetch(nsString hostname, uint16_t flags, nsresult reason);
PRtspController();
PRtspChannel(RtspChannelConnectArgs args);
PChannelDiverter(ChannelDiverterArgs channel);
both:

View File

@ -0,0 +1,25 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et tw=80 ft=cpp : */
/* 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 protocol PNecko;
include URIParams;
namespace mozilla {
namespace net {
async protocol PRtspChannel
{
manager PNecko;
parent:
// Note: channels are opened during construction, so no open method here:
// see PNecko.ipdl
__delete__();
};
} // namespace net
} // namespace mozilla

View File

@ -34,6 +34,7 @@ IPDL_SOURCES = [
'PChannelDiverter.ipdl',
'PNecko.ipdl',
'PRemoteOpenFile.ipdl',
'PRtspChannel.ipdl',
'PRtspController.ipdl',
]

View File

@ -5,42 +5,72 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RtspChannelChild.h"
#include "nsIURI.h"
#include "nsAutoPtr.h"
#include "nsStandardURL.h"
#include "mozilla/ipc/URIUtils.h"
using namespace mozilla::ipc;
namespace mozilla {
namespace net {
NS_IMPL_ISUPPORTS_INHERITED1(RtspChannelChild,
nsBaseChannel,
nsIChannel)
//-----------------------------------------------------------------------------
// RtspChannelChild::nsIChannel
// RtspChannelChild
//-----------------------------------------------------------------------------
NS_IMETHODIMP
RtspChannelChild::AsyncOpen(nsIStreamListener *aListener, nsISupports *aContext)
RtspChannelChild::RtspChannelChild(nsIURI *aUri)
: mIPCOpen(false)
, mCanceled(false)
{
MOZ_ASSERT(aListener);
nsCOMPtr<nsIURI> uri = nsBaseChannel::URI();
NS_ENSURE_TRUE(uri, NS_ERROR_ILLEGAL_VALUE);
nsAutoCString uriSpec;
uri->GetSpec(uriSpec);
mListener = aListener;
mListenerContext = aContext;
// Call OnStartRequest directly. mListener is expected to create/load an
// RtspMediaResource which will create an RtspMediaController. This controller
// manages the control and data streams to and from the network.
mListener->OnStartRequest(this, aContext);
return NS_OK;
nsBaseChannel::SetURI(aUri);
}
RtspChannelChild::~RtspChannelChild()
{
}
nsIStreamingProtocolController*
RtspChannelChild::GetController()
{
return mMediaStreamController;
}
void
RtspChannelChild::ReleaseController()
{
if (mMediaStreamController) {
mMediaStreamController = nullptr;
}
}
//-----------------------------------------------------------------------------
// IPDL
//-----------------------------------------------------------------------------
void
RtspChannelChild::AddIPDLReference()
{
NS_ABORT_IF_FALSE(!mIPCOpen,
"Attempt to retain more than one IPDL reference");
mIPCOpen = true;
AddRef();
}
void
RtspChannelChild::ReleaseIPDLReference()
{
NS_ABORT_IF_FALSE(mIPCOpen, "Attempt to release nonexistent IPDL reference");
mIPCOpen = false;
Release();
}
//-----------------------------------------------------------------------------
// nsISupports
//-----------------------------------------------------------------------------
NS_IMPL_ISUPPORTS_INHERITED2(RtspChannelChild,
nsBaseChannel,
nsIChannel,
nsIChildChannel)
//-----------------------------------------------------------------------------
// nsBaseChannel::nsIChannel
//-----------------------------------------------------------------------------
NS_IMETHODIMP
RtspChannelChild::GetContentType(nsACString& aContentType)
{
@ -48,15 +78,194 @@ RtspChannelChild::GetContentType(nsACString& aContentType)
return NS_OK;
}
NS_IMETHODIMP
RtspChannelChild::Init(nsIURI* aUri)
class CallListenerOnStartRequestEvent : public nsRunnable
{
MOZ_ASSERT(aUri);
public:
CallListenerOnStartRequestEvent(nsIStreamListener *aListener,
nsIRequest *aRequest, nsISupports *aContext)
: mListener(aListener)
, mRequest(aRequest)
, mContext(aContext)
{
MOZ_RELEASE_ASSERT(aListener);
}
NS_IMETHOD Run()
{
MOZ_ASSERT(NS_IsMainThread());
mListener->OnStartRequest(mRequest, mContext);
return NS_OK;
}
private:
nsRefPtr<nsIStreamListener> mListener;
nsRefPtr<nsIRequest> mRequest;
nsRefPtr<nsISupports> mContext;
};
NS_IMETHODIMP
RtspChannelChild::AsyncOpen(nsIStreamListener *aListener, nsISupports *aContext)
{
// Precondition checks.
MOZ_ASSERT(aListener);
nsCOMPtr<nsIURI> uri = nsBaseChannel::URI();
NS_ENSURE_TRUE(uri, NS_ERROR_ILLEGAL_VALUE);
// Create RtspController.
nsCOMPtr<nsIStreamingProtocolControllerService> mediaControllerService =
do_GetService(MEDIASTREAMCONTROLLERSERVICE_CONTRACTID);
MOZ_RELEASE_ASSERT(mediaControllerService,
"Cannot proceed if media controller service is unavailable!");
mediaControllerService->Create(this, getter_AddRefs(mMediaStreamController));
MOZ_ASSERT(mMediaStreamController);
// Add ourselves to the load group.
if (mLoadGroup) {
mLoadGroup->AddRequest(this, nullptr);
}
// Dispatch mListener's OnStartRequest directly. mListener is expected to
// create an RtspMediaResource and use the RtspController we just created to
// manage the control and data streams to and from the network.
mListener = aListener;
mListenerContext = aContext;
NS_DispatchToMainThread(
new CallListenerOnStartRequestEvent(mListener, this, mListenerContext));
nsBaseChannel::Init();
nsBaseChannel::SetURI(aUri);
return NS_OK;
}
} // namespace mozilla::net
//-----------------------------------------------------------------------------
// nsBaseChannel::nsIStreamListener::nsIRequestObserver
//-----------------------------------------------------------------------------
NS_IMETHODIMP
RtspChannelChild::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
{
MOZ_CRASH("Should never be called");
}
NS_IMETHODIMP
RtspChannelChild::OnStopRequest(nsIRequest *aRequest, nsISupports *aContext,
nsresult aStatusCode)
{
MOZ_CRASH("Should never be called");
}
//-----------------------------------------------------------------------------
// nsBaseChannel::nsIStreamListener
//-----------------------------------------------------------------------------
NS_IMETHODIMP
RtspChannelChild::OnDataAvailable(nsIRequest *aRequest,
nsISupports *aContext,
nsIInputStream *aInputStream,
uint64_t aOffset,
uint32_t aCount)
{
MOZ_CRASH("Should never be called");
}
//-----------------------------------------------------------------------------
// nsBaseChannel::nsIChannel::nsIRequest
//-----------------------------------------------------------------------------
class CallListenerOnStopRequestEvent : public nsRunnable
{
public:
CallListenerOnStopRequestEvent(nsIStreamListener *aListener,
nsIRequest *aRequest,
nsISupports *aContext, nsresult aStatus)
: mListener(aListener)
, mRequest(aRequest)
, mContext(aContext)
, mStatus(aStatus)
{
MOZ_RELEASE_ASSERT(aListener);
}
NS_IMETHOD Run()
{
MOZ_ASSERT(NS_IsMainThread());
mListener->OnStopRequest(mRequest, mContext, mStatus);
return NS_OK;
}
private:
nsRefPtr<nsIStreamListener> mListener;
nsRefPtr<nsIRequest> mRequest;
nsRefPtr<nsISupports> mContext;
nsresult mStatus;
};
NS_IMETHODIMP
RtspChannelChild::Cancel(nsresult status)
{
if (mCanceled) {
return NS_OK;
}
mCanceled = true;
// Stop RtspController.
if (mMediaStreamController) {
mMediaStreamController->Stop();
}
// Call mListener's OnStopRequest to do clean up.
NS_DispatchToMainThread(
new CallListenerOnStopRequestEvent(mListener, this,
mListenerContext, status));
mListener = nullptr;
mListenerContext = nullptr;
// Remove ourselves from the load group.
if (mLoadGroup) {
mLoadGroup->RemoveRequest(this, nullptr, status);
}
return NS_OK;
}
NS_IMETHODIMP
RtspChannelChild::Suspend()
{
MOZ_CRASH("Should never be called");
}
NS_IMETHODIMP
RtspChannelChild::Resume()
{
MOZ_CRASH("Should never be called");
}
//-----------------------------------------------------------------------------
// nsBaseChannel
//-----------------------------------------------------------------------------
NS_IMETHODIMP
RtspChannelChild::OpenContentStream(bool aAsync,
nsIInputStream **aStream,
nsIChannel **aChannel)
{
MOZ_CRASH("Should never be called");
}
//-----------------------------------------------------------------------------
// nsIChildChannel
//-----------------------------------------------------------------------------
NS_IMETHODIMP
RtspChannelChild::ConnectParent(uint32_t id)
{
// Create RtspChannelParent for redirection.
AddIPDLReference();
RtspChannelConnectArgs connectArgs;
SerializeURI(nsBaseChannel::URI(), connectArgs.uri());
connectArgs.channelId() = id;
if (!gNeckoChild->SendPRtspChannelConstructor(this, connectArgs)) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
NS_IMETHODIMP
RtspChannelChild::CompleteRedirectSetup(nsIStreamListener *aListener,
nsISupports *aContext)
{
return AsyncOpen(aListener, aContext);
}
} // namespace net
} // namespace mozilla

View File

@ -7,69 +7,82 @@
#ifndef RtspChannelChild_h
#define RtspChannelChild_h
#include "mozilla/net/PRtspChannelChild.h"
#include "mozilla/net/NeckoChild.h"
#include "nsBaseChannel.h"
#include "nsIChildChannel.h"
#include "nsIStreamingProtocolController.h"
#include "nsIStreamingProtocolService.h"
namespace mozilla {
namespace net {
//-----------------------------------------------------------------------------
// RtspChannelChild is a dummy channel used to aid MediaResource creation in
// HTMLMediaElement. Actual network control and data flows are managed by an
// RtspController object created and owned by RtspMediaResource.
// Therefore, when RtspChannelChild::AsyncOpen is called, mListener->OnStartRequest
// will be called immediately. It is expected that an RtspMediaResource object
// will be created in that calling context or after; the RtspController object
// will be created internally by RtspMediaResource."
// HTMLMediaElement. Network control and data flows are managed by an
// RtspController object, which is created by us and manipulated by
// RtspMediaResource. This object is also responsible for inter-process
// communication with the parent process.
// When RtspChannelChild::AsyncOpen is called, it should create an
// RtspController object, dispatch an OnStartRequest and immediately return.
// We expect an RtspMediaResource object will be created in the calling context
// and it will use the RtpController we create.
class RtspChannelChild : public nsBaseChannel
class RtspChannelChild : public PRtspChannelChild
, public nsBaseChannel
, public nsIChildChannel
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSICHILDCHANNEL
RtspChannelChild() { }
RtspChannelChild(nsIURI *aUri);
~RtspChannelChild();
~RtspChannelChild() { }
// Overrides nsBaseChannel::AsyncOpen and call listener's OnStartRequest immediately.
NS_IMETHOD AsyncOpen(nsIStreamListener *listener,
nsISupports *aContext) MOZ_OVERRIDE MOZ_FINAL;
// Set Rtsp URL.
NS_IMETHOD Init(nsIURI* uri);
// Overrides nsBaseChannel::GetContentType, return streaming protocol type "RTSP".
// nsBaseChannel::nsIChannel
NS_IMETHOD GetContentType(nsACString & aContentType) MOZ_OVERRIDE MOZ_FINAL;
NS_IMETHOD AsyncOpen(nsIStreamListener *listener, nsISupports *aContext)
MOZ_OVERRIDE MOZ_FINAL;
NS_IMETHOD OpenContentStream(bool aAsync,
nsIInputStream **aStream,
nsIChannel **aChannel) MOZ_OVERRIDE MOZ_FINAL
{
return NS_ERROR_NOT_IMPLEMENTED;
}
// nsIRequestObserver
NS_IMETHOD OnStartRequest(nsIRequest *aRequest,
nsISupports *aContext) MOZ_OVERRIDE MOZ_FINAL
{
return NS_ERROR_NOT_IMPLEMENTED;
}
// nsBaseChannel::nsIStreamListener::nsIRequestObserver
NS_IMETHOD OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
MOZ_OVERRIDE MOZ_FINAL;
NS_IMETHOD OnStopRequest(nsIRequest *aRequest,
nsISupports *aContext,
nsresult aStatusCode) MOZ_OVERRIDE MOZ_FINAL
{
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult aStatusCode) MOZ_OVERRIDE MOZ_FINAL;
// nsIStreamListener
// nsBaseChannel::nsIStreamListener
NS_IMETHOD OnDataAvailable(nsIRequest *aRequest,
nsISupports *aContext,
nsIInputStream *aInputStream,
uint64_t aOffset,
uint32_t aCount) MOZ_OVERRIDE MOZ_FINAL
{
return NS_ERROR_NOT_IMPLEMENTED;
}
uint32_t aCount) MOZ_OVERRIDE MOZ_FINAL;
// nsBaseChannel::nsIChannel::nsIRequest
NS_IMETHOD Cancel(nsresult status) MOZ_OVERRIDE MOZ_FINAL;
NS_IMETHOD Suspend() MOZ_OVERRIDE MOZ_FINAL;
NS_IMETHOD Resume() MOZ_OVERRIDE MOZ_FINAL;
// nsBaseChannel
NS_IMETHOD OpenContentStream(bool aAsync,
nsIInputStream **aStream,
nsIChannel **aChannel) MOZ_OVERRIDE MOZ_FINAL;
// IPDL
void AddIPDLReference();
void ReleaseIPDLReference();
// RtspChannelChild
nsIStreamingProtocolController* GetController();
void ReleaseController();
private:
bool mIPCOpen;
bool mCanceled;
nsCOMPtr<nsIStreamingProtocolController> mMediaStreamController;
};
}
} // namespace mozilla::net
} // namespace net
} // namespace mozilla
#endif // RtspChannelChild_h

View File

@ -0,0 +1,159 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et 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 "RtspChannelParent.h"
using namespace mozilla::ipc;
namespace mozilla {
namespace net {
//-----------------------------------------------------------------------------
// RtspChannelParent
//-----------------------------------------------------------------------------
RtspChannelParent::RtspChannelParent(nsIURI *aUri)
: mIPCClosed(false)
{
nsBaseChannel::SetURI(aUri);
}
RtspChannelParent::~RtspChannelParent()
{
}
void
RtspChannelParent::ActorDestroy(ActorDestroyReason why)
{
mIPCClosed = true;
}
//-----------------------------------------------------------------------------
// nsISupports
//-----------------------------------------------------------------------------
NS_IMPL_ISUPPORTS_INHERITED1(RtspChannelParent,
nsBaseChannel,
nsIParentChannel)
//-----------------------------------------------------------------------------
// RtspChannelParent methods
//-----------------------------------------------------------------------------
bool
RtspChannelParent::Init(const RtspChannelConnectArgs& aArgs)
{
return ConnectChannel(aArgs.channelId());
}
bool
RtspChannelParent::ConnectChannel(const uint32_t& channelId)
{
nsresult rv;
nsCOMPtr<nsIChannel> channel;
rv = NS_LinkRedirectChannels(channelId, this, getter_AddRefs(channel));
return true;
}
//-----------------------------------------------------------------------------
// nsBaseChannel::nsIChannel
//-----------------------------------------------------------------------------
NS_IMETHODIMP
RtspChannelParent::GetContentType(nsACString& aContentType)
{
aContentType.AssignLiteral("RTSP");
return NS_OK;
}
NS_IMETHODIMP
RtspChannelParent::AsyncOpen(nsIStreamListener *aListener, nsISupports *aContext)
{
return NS_OK;
}
//-----------------------------------------------------------------------------
// nsBaseChannel::nsIStreamListener::nsIRequestObserver
//-----------------------------------------------------------------------------
NS_IMETHODIMP
RtspChannelParent::OnStartRequest(nsIRequest *aRequest,
nsISupports *aContext)
{
MOZ_CRASH("Should never be called");
}
NS_IMETHODIMP
RtspChannelParent::OnStopRequest(nsIRequest *aRequest,
nsISupports *aContext,
nsresult aStatusCode)
{
MOZ_CRASH("Should never be called");
}
//-----------------------------------------------------------------------------
// nsBaseChannel::nsIStreamListener
//-----------------------------------------------------------------------------
NS_IMETHODIMP
RtspChannelParent::OnDataAvailable(nsIRequest *aRequest,
nsISupports *aContext,
nsIInputStream *aInputStream,
uint64_t aOffset,
uint32_t aCount)
{
MOZ_CRASH("Should never be called");
}
//-----------------------------------------------------------------------------
// nsBaseChannel::nsIChannel::nsIRequeset
//-----------------------------------------------------------------------------
NS_IMETHODIMP
RtspChannelParent::Cancel(nsresult status)
{
// FIXME: This method will be called by
// nsXMLHttpRequest::CloseRequestWithError while closing the browser app.
// However, the root cause is RtspChannelParent will be created by
// nsXMLHttpRequest::Open when we navigate away from an RTSP web page.
// We should find out why it happens and decide how to fix it.
return NS_OK;
}
NS_IMETHODIMP
RtspChannelParent::Suspend()
{
MOZ_CRASH("Should never be called");
}
NS_IMETHODIMP
RtspChannelParent::Resume()
{
MOZ_CRASH("Should never be called");
}
//-----------------------------------------------------------------------------
// nsBaseChannel
//-----------------------------------------------------------------------------
NS_IMETHODIMP
RtspChannelParent::OpenContentStream(bool aAsync,
nsIInputStream **aStream,
nsIChannel **aChannel)
{
MOZ_CRASH("Should never be called");
}
//-----------------------------------------------------------------------------
// nsIParentChannel
//-----------------------------------------------------------------------------
NS_IMETHODIMP
RtspChannelParent::SetParentListener(HttpChannelParentListener *aListener)
{
return NS_OK;
}
NS_IMETHODIMP
RtspChannelParent::Delete()
{
return NS_OK;
}
} // namespace net
} // namespace mozilla

View File

@ -0,0 +1,84 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et 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 RtspChannelParent_h
#define RtspChannelParent_h
#include "mozilla/net/PRtspChannelParent.h"
#include "mozilla/net/NeckoParent.h"
#include "nsBaseChannel.h"
#include "nsIParentChannel.h"
namespace mozilla {
namespace net {
//-----------------------------------------------------------------------------
// Note: RtspChannel doesn't transport streams as normal channel does.
// (See RtspChannelChild.h for detail).
// The reason for the existence of RtspChannelParent is to support HTTP->RTSP
// redirection.
// When redirection happens, two instances of RtspChannelParent will be created:
// - One will be created when HTTP creates the new channel for redirects, and
// will be registered as an nsIChannel.
// - The other will be created via IPDL by RtspChannelChild, and will be
// registered as an nsIParentChannel.
class RtspChannelParent : public PRtspChannelParent
, public nsBaseChannel
, public nsIParentChannel
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIPARENTCHANNEL
RtspChannelParent(nsIURI *aUri);
~RtspChannelParent();
// nsBaseChannel::nsIChannel
NS_IMETHOD GetContentType(nsACString & aContentType) MOZ_OVERRIDE MOZ_FINAL;
NS_IMETHOD AsyncOpen(nsIStreamListener *listener,
nsISupports *aContext) MOZ_OVERRIDE MOZ_FINAL;
// nsBaseChannel::nsIStreamListener::nsIRequestObserver
NS_IMETHOD OnStartRequest(nsIRequest *aRequest,
nsISupports *aContext) MOZ_OVERRIDE MOZ_FINAL;
NS_IMETHOD OnStopRequest(nsIRequest *aRequest,
nsISupports *aContext,
nsresult aStatusCode) MOZ_OVERRIDE MOZ_FINAL;
// nsBaseChannel::nsIStreamListener
NS_IMETHOD OnDataAvailable(nsIRequest *aRequest,
nsISupports *aContext,
nsIInputStream *aInputStream,
uint64_t aOffset,
uint32_t aCount) MOZ_OVERRIDE MOZ_FINAL;
// nsBaseChannel::nsIChannel::nsIRequest
NS_IMETHOD Cancel(nsresult status) MOZ_OVERRIDE MOZ_FINAL;
NS_IMETHOD Suspend() MOZ_OVERRIDE MOZ_FINAL;
NS_IMETHOD Resume() MOZ_OVERRIDE MOZ_FINAL;
// nsBaseChannel
NS_IMETHOD OpenContentStream(bool aAsync,
nsIInputStream **aStream,
nsIChannel **aChannel) MOZ_OVERRIDE MOZ_FINAL;
// RtspChannelParent
bool Init(const RtspChannelConnectArgs& aArgs);
protected:
// Used to connect redirected-to channel in parent with just created
// ChildChannel. Used during HTTP->RTSP redirection.
bool ConnectChannel(const uint32_t& channelId);
private:
bool mIPCClosed;
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
};
} // namespace net
} // namespace mozilla
#endif // RtspChannelParent_h

View File

@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RtspChannelChild.h"
#include "RtspChannelParent.h"
#include "RtspHandler.h"
#include "nsILoadGroup.h"
#include "nsIInterfaceRequestor.h"
@ -68,15 +69,19 @@ NS_IMETHODIMP
RtspHandler::NewChannel(nsIURI *aURI, nsIChannel **aResult)
{
bool isRtsp = false;
nsRefPtr<RtspChannelChild> rtspChannel;
nsRefPtr<nsBaseChannel> rtspChannel;
nsresult rv = aURI->SchemeIs("rtsp", &isRtsp);
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(isRtsp, NS_ERROR_UNEXPECTED);
rtspChannel = new RtspChannelChild();
if (IsNeckoChild()) {
rtspChannel = new RtspChannelChild(aURI);
} else {
rtspChannel = new RtspChannelParent(aURI);
}
rv = rtspChannel->Init(aURI);
rv = rtspChannel->Init();
NS_ENSURE_SUCCESS(rv, rv);
rtspChannel.forget(aResult);

View File

@ -78,6 +78,12 @@ RtspControllerChild::~RtspControllerChild()
LOG(("RtspControllerChild::~RtspControllerChild()"));
}
void
RtspControllerChild::ReleaseChannel()
{
static_cast<RtspChannelChild*>(mChannel.get())->ReleaseController();
}
bool
RtspControllerChild::OKToSendIPC()
{
@ -174,6 +180,7 @@ RtspControllerChild::RecvOnDisconnected(
if (mListener) {
mListener->OnDisconnected(index, reason);
}
ReleaseChannel();
return true;
}
@ -185,6 +192,7 @@ RtspControllerChild::RecvAsyncOpenFailed(const nsresult& reason)
if (mListener) {
mListener->OnDisconnected(0, NS_ERROR_CONNECTION_REFUSED);
}
ReleaseChannel();
return true;
}

View File

@ -13,6 +13,7 @@
#include "nsCOMPtr.h"
#include "nsString.h"
#include "nsTArray.h"
#include "mozilla/net/RtspChannelChild.h"
namespace mozilla {
namespace net {
@ -70,6 +71,8 @@ class RtspControllerChild : public nsIStreamingProtocolController
uint32_t mTotalTracks;
// Current suspension depth for this channel object
uint32_t mSuspendCount;
// Detach channel-controller relationship.
void ReleaseChannel();
};
} // namespace net
} // namespace mozilla

View File

@ -10,6 +10,7 @@ EXPORTS.mozilla.net += [
'controller/RtspMetaData.h',
'rtsp/RTSPSource.h',
'RtspChannelChild.h',
'RtspChannelParent.h',
'RtspHandler.h',
]
@ -20,6 +21,7 @@ SOURCES += [
'controller/RtspControllerParent.cpp',
'controller/RtspMetaData.cpp',
'RtspChannelChild.cpp',
'RtspChannelParent.cpp',
'RtspHandler.cpp',
]

View File

@ -351,16 +351,20 @@ let PlacesTransactions = {
* are not protected from consumers who use the raw places APIs directly.
*/
transact: function (aToTransact) {
let generatorMode = typeof(aToTransact) == "function";
if (generatorMode) {
if (!aToTransact.isGenerator())
let isGeneratorObj =
o => Object.prototype.toString.call(o) == "[object Generator]";
let generator = null;
if (typeof(aToTransact) == "function") {
generator = aToTransact();
if (!isGeneratorObj(generator))
throw new Error("aToTransact is not a generator function");
}
else {
if (!TransactionsHistory.isProxifiedTransactionObject(aToTransact))
throw new Error("aToTransact is not a valid transaction object");
if (executedTransactions.has(aToTransact))
throw new Error("Transactions objects may not be recycled.");
else if (!TransactionsHistory.isProxifiedTransactionObject(aToTransact)) {
throw new Error("aToTransact is not a valid transaction object");
}
else if (executedTransactions.has(aToTransact)) {
throw new Error("Transactions objects may not be recycled.");
}
return Serialize(function* () {
@ -387,7 +391,7 @@ let PlacesTransactions = {
let next = error ?
aGenerator.throw(sendValue) : aGenerator.next(sendValue);
sendValue = next.value;
if (Object.prototype.toString.call(sendValue) == "[object Generator]") {
if (isGeneratorObj(sendValue)) {
sendValue = yield transactBatch(sendValue);
}
else if (typeof(sendValue) == "object" && sendValue) {
@ -410,8 +414,8 @@ let PlacesTransactions = {
return sendValue;
}
if (generatorMode)
return yield transactBatch(aToTransact());
if (generator)
return yield transactBatch(generator);
else
return yield transactOneTransaction(aToTransact);
}.bind(this));
@ -887,9 +891,10 @@ PT.NewLivemark.prototype = Object.seal({
/**
* Transaction for moving an item.
*
* Required Input Properties: GUID, newParentGUID, newIndex.
* Required Input Properties: GUID, newParentGUID.
* Optional Input Properties newIndex.
*/
PT.MoveItem = DefineTransaction(["GUID", "newParentGUID", "newIndex"]);
PT.MoveItem = DefineTransaction(["GUID", "newParentGUID"], ["newIndex"]);
PT.MoveItem.prototype = Object.seal({
execute: function* (aGUID, aNewParentGUID, aNewIndex) {
let itemId = yield PlacesUtils.promiseItemId(aGUID),

View File

@ -454,8 +454,7 @@ add_task(function* test_move_items_to_folder() {
ensureUndoState([[bkm_b_txn, bkm_a_txn, folder_a_txn]], 0);
let moveTxn = PT.MoveItem({ GUID: bkm_a_info.GUID
, newParentGUID: folder_a_info.GUID
, newIndex: bmsvc.DEFAULT_INDEX });
, newParentGUID: folder_a_info.GUID });
yield PT.transact(moveTxn);
let ensureDo = () => {

View File

@ -13,7 +13,7 @@ toolkit.jar:
skin/classic/mozapps/downloads/unknownContentType.css (downloads/unknownContentType.css)
skin/classic/mozapps/extensions/about.css (extensions/about.css)
skin/classic/mozapps/extensions/blocklist.css (extensions/blocklist.css)
skin/classic/mozapps/extensions/extensions.css (extensions/extensions.css)
* skin/classic/mozapps/extensions/extensions.css (extensions/extensions.css)
* skin/classic/mozapps/extensions/selectAddons.css (extensions/selectAddons.css)
skin/classic/mozapps/extensions/update.css (extensions/update.css)
skin/classic/mozapps/extensions/extensions.svg (extensions/extensions.svg)