From 0eea64518b73849db223d7e3da9288acddcb38db Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Thu, 6 Feb 2020 16:03:39 -0500 Subject: Issue mcp-graveyard/UXP#1390 - Get rid of the Presentation API --- dom/base/Navigator.cpp | 22 - dom/base/Navigator.h | 4 - dom/ipc/ContentChild.cpp | 45 - dom/ipc/ContentChild.h | 11 - dom/ipc/ContentParent.cpp | 23 - dom/ipc/ContentParent.h | 6 - dom/ipc/PContent.ipdl | 16 - dom/moz.build | 2 - dom/presentation/AvailabilityCollection.cpp | 99 -- dom/presentation/AvailabilityCollection.h | 45 - .../ControllerConnectionCollection.cpp | 116 -- dom/presentation/ControllerConnectionCollection.h | 49 - .../DCPresentationChannelDescription.cpp | 46 - .../DCPresentationChannelDescription.h | 37 - dom/presentation/Presentation.cpp | 182 --- dom/presentation/Presentation.h | 70 - dom/presentation/PresentationAvailability.cpp | 206 --- dom/presentation/PresentationAvailability.h | 74 - dom/presentation/PresentationCallbacks.cpp | 282 ---- dom/presentation/PresentationCallbacks.h | 85 - dom/presentation/PresentationConnection.cpp | 763 --------- dom/presentation/PresentationConnection.h | 128 -- dom/presentation/PresentationConnectionList.cpp | 125 -- dom/presentation/PresentationConnectionList.h | 57 - .../PresentationDataChannelSessionTransport.js | 378 ----- ...resentationDataChannelSessionTransport.manifest | 6 - dom/presentation/PresentationDeviceInfoManager.js | 119 -- dom/presentation/PresentationDeviceInfoManager.jsm | 104 -- .../PresentationDeviceInfoManager.manifest | 3 - dom/presentation/PresentationDeviceManager.cpp | 336 ---- dom/presentation/PresentationDeviceManager.h | 54 - dom/presentation/PresentationLog.h | 26 - dom/presentation/PresentationNetworkHelper.js | 28 - .../PresentationNetworkHelper.manifest | 3 - dom/presentation/PresentationReceiver.cpp | 179 --- dom/presentation/PresentationReceiver.h | 71 - dom/presentation/PresentationRequest.cpp | 563 ------- dom/presentation/PresentationRequest.h | 84 - dom/presentation/PresentationService.cpp | 1188 -------------- dom/presentation/PresentationService.h | 68 - dom/presentation/PresentationServiceBase.h | 401 ----- dom/presentation/PresentationSessionInfo.cpp | 1617 -------------------- dom/presentation/PresentationSessionInfo.h | 304 ---- dom/presentation/PresentationSessionRequest.cpp | 72 - dom/presentation/PresentationSessionRequest.h | 41 - .../PresentationTCPSessionTransport.cpp | 589 ------- dom/presentation/PresentationTCPSessionTransport.h | 110 -- dom/presentation/PresentationTerminateRequest.cpp | 73 - dom/presentation/PresentationTerminateRequest.h | 41 - .../PresentationTransportBuilderConstructor.cpp | 85 - .../PresentationTransportBuilderConstructor.h | 48 - dom/presentation/interfaces/moz.build | 30 - .../interfaces/nsIPresentationControlChannel.idl | 139 -- .../interfaces/nsIPresentationControlService.idl | 156 -- .../interfaces/nsIPresentationDevice.idl | 43 - .../interfaces/nsIPresentationDeviceManager.idl | 51 - .../interfaces/nsIPresentationDevicePrompt.idl | 58 - .../interfaces/nsIPresentationDeviceProvider.idl | 75 - .../interfaces/nsIPresentationListener.idl | 50 - .../interfaces/nsIPresentationLocalDevice.idl | 17 - .../interfaces/nsIPresentationNetworkHelper.idl | 36 - .../interfaces/nsIPresentationRequestUIGlue.idl | 29 - .../interfaces/nsIPresentationService.idl | 275 ---- .../interfaces/nsIPresentationSessionRequest.idl | 35 - .../interfaces/nsIPresentationSessionTransport.idl | 69 - .../nsIPresentationSessionTransportBuilder.idl | 80 - .../interfaces/nsIPresentationTerminateRequest.idl | 33 - dom/presentation/ipc/PPresentation.ipdl | 112 -- dom/presentation/ipc/PPresentationBuilder.ipdl | 34 - dom/presentation/ipc/PPresentationRequest.ipdl | 22 - dom/presentation/ipc/PresentationBuilderChild.cpp | 184 --- dom/presentation/ipc/PresentationBuilderChild.h | 48 - dom/presentation/ipc/PresentationBuilderParent.cpp | 267 ---- dom/presentation/ipc/PresentationBuilderParent.h | 52 - dom/presentation/ipc/PresentationChild.cpp | 198 --- dom/presentation/ipc/PresentationChild.h | 101 -- .../ipc/PresentationContentSessionInfo.cpp | 109 -- .../ipc/PresentationContentSessionInfo.h | 62 - dom/presentation/ipc/PresentationIPCService.cpp | 538 ------- dom/presentation/ipc/PresentationIPCService.h | 75 - dom/presentation/ipc/PresentationParent.cpp | 553 ------- dom/presentation/ipc/PresentationParent.h | 137 -- dom/presentation/moz.build | 89 -- .../provider/AndroidCastDeviceProvider.js | 461 ------ .../provider/AndroidCastDeviceProvider.manifest | 4 - .../provider/BuiltinProviders.manifest | 2 - .../provider/ControllerStateMachine.jsm | 240 --- .../provider/DeviceProviderHelpers.cpp | 57 - dom/presentation/provider/DeviceProviderHelpers.h | 30 - .../provider/DisplayDeviceProvider.cpp | 580 ------- dom/presentation/provider/DisplayDeviceProvider.h | 136 -- .../provider/LegacyMDNSDeviceProvider.cpp | 774 ---------- .../provider/LegacyMDNSDeviceProvider.h | 191 --- .../provider/LegacyPresentationControlService.js | 488 ------ dom/presentation/provider/LegacyProviders.manifest | 2 - .../provider/MulticastDNSDeviceProvider.cpp | 1249 --------------- .../provider/MulticastDNSDeviceProvider.h | 225 --- .../provider/PresentationControlService.js | 960 ------------ .../provider/PresentationDeviceProviderModule.cpp | 87 -- dom/presentation/provider/ReceiverStateMachine.jsm | 238 --- dom/presentation/provider/StateMachineHelper.jsm | 39 - dom/presentation/provider/moz.build | 40 - dom/presentation/provider/nsTCPDeviceInfo.h | 77 - .../PresentationDeviceInfoChromeScript.js | 150 -- .../mochitest/PresentationSessionChromeScript.js | 470 ------ .../PresentationSessionChromeScript1UA.js | 366 ----- .../mochitest/PresentationSessionFrameScript.js | 258 ---- dom/presentation/tests/mochitest/chrome.ini | 14 - .../mochitest/file_presentation_1ua_receiver.html | 220 --- .../mochitest/file_presentation_1ua_wentaway.html | 95 -- .../file_presentation_mixed_security_contexts.html | 159 -- .../mochitest/file_presentation_non_receiver.html | 41 - ...ile_presentation_non_receiver_inner_iframe.html | 26 - .../mochitest/file_presentation_receiver.html | 140 -- ...presentation_receiver_auxiliary_navigation.html | 60 - ...tation_receiver_establish_connection_error.html | 79 - .../file_presentation_receiver_inner_iframe.html | 26 - .../mochitest/file_presentation_reconnect.html | 102 -- .../file_presentation_sandboxed_presentation.html | 114 -- .../mochitest/file_presentation_terminate.html | 104 -- ...ation_terminate_establish_connection_error.html | 114 -- .../file_presentation_unknown_content_type.test | 1 - ...presentation_unknown_content_type.test^headers^ | 1 - dom/presentation/tests/mochitest/mochitest.ini | 77 - .../test_presentation_1ua_connection_wentaway.js | 175 --- ...resentation_1ua_connection_wentaway_inproc.html | 18 - ...t_presentation_1ua_connection_wentaway_oop.html | 18 - .../test_presentation_1ua_sender_and_receiver.js | 370 ----- ...resentation_1ua_sender_and_receiver_inproc.html | 18 - ...t_presentation_1ua_sender_and_receiver_oop.html | 18 - .../mochitest/test_presentation_availability.html | 236 --- ..._presentation_datachannel_sessiontransport.html | 245 --- .../mochitest/test_presentation_dc_receiver.html | 141 -- .../test_presentation_dc_receiver_oop.html | 213 --- .../mochitest/test_presentation_dc_sender.html | 291 ---- .../mochitest/test_presentation_device_info.html | 144 -- .../test_presentation_device_info_permission.html | 35 - .../test_presentation_mixed_security_contexts.html | 81 - ...t_presentation_receiver_auxiliary_navigation.js | 77 - ...ation_receiver_auxiliary_navigation_inproc.html | 18 - ...entation_receiver_auxiliary_navigation_oop.html | 18 - .../mochitest/test_presentation_reconnect.html | 379 ----- .../test_presentation_sandboxed_presentation.html | 75 - ...t_presentation_sender_on_terminate_request.html | 187 --- .../test_presentation_sender_startWithDevice.html | 173 --- .../mochitest/test_presentation_tcp_receiver.html | 137 -- ...on_tcp_receiver_establish_connection_error.html | 110 -- ..._tcp_receiver_establish_connection_timeout.html | 81 - ...er_establish_connection_unknown_content_type.js | 88 -- ...ish_connection_unknown_content_type_inproc.html | 16 - ...ablish_connection_unknown_content_type_oop.html | 16 - .../test_presentation_tcp_receiver_oop.html | 178 --- .../mochitest/test_presentation_tcp_sender.html | 260 ---- ...st_presentation_tcp_sender_default_request.html | 151 -- .../test_presentation_tcp_sender_disconnect.html | 160 -- ...tion_tcp_sender_establish_connection_error.html | 514 ------- .../tests/mochitest/test_presentation_terminate.js | 243 --- ...ntation_terminate_establish_connection_error.js | 197 --- ...erminate_establish_connection_error_inproc.html | 18 - ...n_terminate_establish_connection_error_oop.html | 18 - .../test_presentation_terminate_inproc.html | 18 - .../mochitest/test_presentation_terminate_oop.html | 18 - .../xpcshell/test_multicast_dns_device_provider.js | 1318 ---------------- .../xpcshell/test_presentation_device_manager.js | 244 --- .../test_presentation_session_transport.js | 198 --- .../xpcshell/test_presentation_state_machine.js | 236 --- .../tests/xpcshell/test_tcp_control_channel.js | 398 ----- dom/presentation/tests/xpcshell/xpcshell.ini | 9 - dom/webidl/Navigator.webidl | 5 - dom/webidl/Presentation.webidl | 30 - dom/webidl/PresentationAvailability.webidl | 22 - dom/webidl/PresentationConnection.webidl | 96 -- .../PresentationConnectionAvailableEvent.webidl | 22 - dom/webidl/PresentationConnectionCloseEvent.webidl | 41 - dom/webidl/PresentationConnectionList.webidl | 25 - dom/webidl/PresentationDeviceInfoManager.webidl | 26 - dom/webidl/PresentationReceiver.webidl | 18 - dom/webidl/PresentationRequest.webidl | 86 -- dom/webidl/moz.build | 9 - 179 files changed, 29274 deletions(-) delete mode 100644 dom/presentation/AvailabilityCollection.cpp delete mode 100644 dom/presentation/AvailabilityCollection.h delete mode 100644 dom/presentation/ControllerConnectionCollection.cpp delete mode 100644 dom/presentation/ControllerConnectionCollection.h delete mode 100644 dom/presentation/DCPresentationChannelDescription.cpp delete mode 100644 dom/presentation/DCPresentationChannelDescription.h delete mode 100644 dom/presentation/Presentation.cpp delete mode 100644 dom/presentation/Presentation.h delete mode 100644 dom/presentation/PresentationAvailability.cpp delete mode 100644 dom/presentation/PresentationAvailability.h delete mode 100644 dom/presentation/PresentationCallbacks.cpp delete mode 100644 dom/presentation/PresentationCallbacks.h delete mode 100644 dom/presentation/PresentationConnection.cpp delete mode 100644 dom/presentation/PresentationConnection.h delete mode 100644 dom/presentation/PresentationConnectionList.cpp delete mode 100644 dom/presentation/PresentationConnectionList.h delete mode 100644 dom/presentation/PresentationDataChannelSessionTransport.js delete mode 100644 dom/presentation/PresentationDataChannelSessionTransport.manifest delete mode 100644 dom/presentation/PresentationDeviceInfoManager.js delete mode 100644 dom/presentation/PresentationDeviceInfoManager.jsm delete mode 100644 dom/presentation/PresentationDeviceInfoManager.manifest delete mode 100644 dom/presentation/PresentationDeviceManager.cpp delete mode 100644 dom/presentation/PresentationDeviceManager.h delete mode 100644 dom/presentation/PresentationLog.h delete mode 100644 dom/presentation/PresentationNetworkHelper.js delete mode 100644 dom/presentation/PresentationNetworkHelper.manifest delete mode 100644 dom/presentation/PresentationReceiver.cpp delete mode 100644 dom/presentation/PresentationReceiver.h delete mode 100644 dom/presentation/PresentationRequest.cpp delete mode 100644 dom/presentation/PresentationRequest.h delete mode 100644 dom/presentation/PresentationService.cpp delete mode 100644 dom/presentation/PresentationService.h delete mode 100644 dom/presentation/PresentationServiceBase.h delete mode 100644 dom/presentation/PresentationSessionInfo.cpp delete mode 100644 dom/presentation/PresentationSessionInfo.h delete mode 100644 dom/presentation/PresentationSessionRequest.cpp delete mode 100644 dom/presentation/PresentationSessionRequest.h delete mode 100644 dom/presentation/PresentationTCPSessionTransport.cpp delete mode 100644 dom/presentation/PresentationTCPSessionTransport.h delete mode 100644 dom/presentation/PresentationTerminateRequest.cpp delete mode 100644 dom/presentation/PresentationTerminateRequest.h delete mode 100644 dom/presentation/PresentationTransportBuilderConstructor.cpp delete mode 100644 dom/presentation/PresentationTransportBuilderConstructor.h delete mode 100644 dom/presentation/interfaces/moz.build delete mode 100644 dom/presentation/interfaces/nsIPresentationControlChannel.idl delete mode 100644 dom/presentation/interfaces/nsIPresentationControlService.idl delete mode 100644 dom/presentation/interfaces/nsIPresentationDevice.idl delete mode 100644 dom/presentation/interfaces/nsIPresentationDeviceManager.idl delete mode 100644 dom/presentation/interfaces/nsIPresentationDevicePrompt.idl delete mode 100644 dom/presentation/interfaces/nsIPresentationDeviceProvider.idl delete mode 100644 dom/presentation/interfaces/nsIPresentationListener.idl delete mode 100644 dom/presentation/interfaces/nsIPresentationLocalDevice.idl delete mode 100644 dom/presentation/interfaces/nsIPresentationNetworkHelper.idl delete mode 100644 dom/presentation/interfaces/nsIPresentationRequestUIGlue.idl delete mode 100644 dom/presentation/interfaces/nsIPresentationService.idl delete mode 100644 dom/presentation/interfaces/nsIPresentationSessionRequest.idl delete mode 100644 dom/presentation/interfaces/nsIPresentationSessionTransport.idl delete mode 100644 dom/presentation/interfaces/nsIPresentationSessionTransportBuilder.idl delete mode 100644 dom/presentation/interfaces/nsIPresentationTerminateRequest.idl delete mode 100644 dom/presentation/ipc/PPresentation.ipdl delete mode 100644 dom/presentation/ipc/PPresentationBuilder.ipdl delete mode 100644 dom/presentation/ipc/PPresentationRequest.ipdl delete mode 100644 dom/presentation/ipc/PresentationBuilderChild.cpp delete mode 100644 dom/presentation/ipc/PresentationBuilderChild.h delete mode 100644 dom/presentation/ipc/PresentationBuilderParent.cpp delete mode 100644 dom/presentation/ipc/PresentationBuilderParent.h delete mode 100644 dom/presentation/ipc/PresentationChild.cpp delete mode 100644 dom/presentation/ipc/PresentationChild.h delete mode 100644 dom/presentation/ipc/PresentationContentSessionInfo.cpp delete mode 100644 dom/presentation/ipc/PresentationContentSessionInfo.h delete mode 100644 dom/presentation/ipc/PresentationIPCService.cpp delete mode 100644 dom/presentation/ipc/PresentationIPCService.h delete mode 100644 dom/presentation/ipc/PresentationParent.cpp delete mode 100644 dom/presentation/ipc/PresentationParent.h delete mode 100644 dom/presentation/moz.build delete mode 100644 dom/presentation/provider/AndroidCastDeviceProvider.js delete mode 100644 dom/presentation/provider/AndroidCastDeviceProvider.manifest delete mode 100644 dom/presentation/provider/BuiltinProviders.manifest delete mode 100644 dom/presentation/provider/ControllerStateMachine.jsm delete mode 100644 dom/presentation/provider/DeviceProviderHelpers.cpp delete mode 100644 dom/presentation/provider/DeviceProviderHelpers.h delete mode 100644 dom/presentation/provider/DisplayDeviceProvider.cpp delete mode 100644 dom/presentation/provider/DisplayDeviceProvider.h delete mode 100644 dom/presentation/provider/LegacyMDNSDeviceProvider.cpp delete mode 100644 dom/presentation/provider/LegacyMDNSDeviceProvider.h delete mode 100644 dom/presentation/provider/LegacyPresentationControlService.js delete mode 100644 dom/presentation/provider/LegacyProviders.manifest delete mode 100644 dom/presentation/provider/MulticastDNSDeviceProvider.cpp delete mode 100644 dom/presentation/provider/MulticastDNSDeviceProvider.h delete mode 100644 dom/presentation/provider/PresentationControlService.js delete mode 100644 dom/presentation/provider/PresentationDeviceProviderModule.cpp delete mode 100644 dom/presentation/provider/ReceiverStateMachine.jsm delete mode 100644 dom/presentation/provider/StateMachineHelper.jsm delete mode 100644 dom/presentation/provider/moz.build delete mode 100644 dom/presentation/provider/nsTCPDeviceInfo.h delete mode 100644 dom/presentation/tests/mochitest/PresentationDeviceInfoChromeScript.js delete mode 100644 dom/presentation/tests/mochitest/PresentationSessionChromeScript.js delete mode 100644 dom/presentation/tests/mochitest/PresentationSessionChromeScript1UA.js delete mode 100644 dom/presentation/tests/mochitest/PresentationSessionFrameScript.js delete mode 100644 dom/presentation/tests/mochitest/chrome.ini delete mode 100644 dom/presentation/tests/mochitest/file_presentation_1ua_receiver.html delete mode 100644 dom/presentation/tests/mochitest/file_presentation_1ua_wentaway.html delete mode 100644 dom/presentation/tests/mochitest/file_presentation_mixed_security_contexts.html delete mode 100644 dom/presentation/tests/mochitest/file_presentation_non_receiver.html delete mode 100644 dom/presentation/tests/mochitest/file_presentation_non_receiver_inner_iframe.html delete mode 100644 dom/presentation/tests/mochitest/file_presentation_receiver.html delete mode 100644 dom/presentation/tests/mochitest/file_presentation_receiver_auxiliary_navigation.html delete mode 100644 dom/presentation/tests/mochitest/file_presentation_receiver_establish_connection_error.html delete mode 100644 dom/presentation/tests/mochitest/file_presentation_receiver_inner_iframe.html delete mode 100644 dom/presentation/tests/mochitest/file_presentation_reconnect.html delete mode 100644 dom/presentation/tests/mochitest/file_presentation_sandboxed_presentation.html delete mode 100644 dom/presentation/tests/mochitest/file_presentation_terminate.html delete mode 100644 dom/presentation/tests/mochitest/file_presentation_terminate_establish_connection_error.html delete mode 100644 dom/presentation/tests/mochitest/file_presentation_unknown_content_type.test delete mode 100644 dom/presentation/tests/mochitest/file_presentation_unknown_content_type.test^headers^ delete mode 100644 dom/presentation/tests/mochitest/mochitest.ini delete mode 100644 dom/presentation/tests/mochitest/test_presentation_1ua_connection_wentaway.js delete mode 100644 dom/presentation/tests/mochitest/test_presentation_1ua_connection_wentaway_inproc.html delete mode 100644 dom/presentation/tests/mochitest/test_presentation_1ua_connection_wentaway_oop.html delete mode 100644 dom/presentation/tests/mochitest/test_presentation_1ua_sender_and_receiver.js delete mode 100644 dom/presentation/tests/mochitest/test_presentation_1ua_sender_and_receiver_inproc.html delete mode 100644 dom/presentation/tests/mochitest/test_presentation_1ua_sender_and_receiver_oop.html delete mode 100644 dom/presentation/tests/mochitest/test_presentation_availability.html delete mode 100644 dom/presentation/tests/mochitest/test_presentation_datachannel_sessiontransport.html delete mode 100644 dom/presentation/tests/mochitest/test_presentation_dc_receiver.html delete mode 100644 dom/presentation/tests/mochitest/test_presentation_dc_receiver_oop.html delete mode 100644 dom/presentation/tests/mochitest/test_presentation_dc_sender.html delete mode 100644 dom/presentation/tests/mochitest/test_presentation_device_info.html delete mode 100644 dom/presentation/tests/mochitest/test_presentation_device_info_permission.html delete mode 100644 dom/presentation/tests/mochitest/test_presentation_mixed_security_contexts.html delete mode 100644 dom/presentation/tests/mochitest/test_presentation_receiver_auxiliary_navigation.js delete mode 100644 dom/presentation/tests/mochitest/test_presentation_receiver_auxiliary_navigation_inproc.html delete mode 100644 dom/presentation/tests/mochitest/test_presentation_receiver_auxiliary_navigation_oop.html delete mode 100644 dom/presentation/tests/mochitest/test_presentation_reconnect.html delete mode 100644 dom/presentation/tests/mochitest/test_presentation_sandboxed_presentation.html delete mode 100644 dom/presentation/tests/mochitest/test_presentation_sender_on_terminate_request.html delete mode 100644 dom/presentation/tests/mochitest/test_presentation_sender_startWithDevice.html delete mode 100644 dom/presentation/tests/mochitest/test_presentation_tcp_receiver.html delete mode 100644 dom/presentation/tests/mochitest/test_presentation_tcp_receiver_establish_connection_error.html delete mode 100644 dom/presentation/tests/mochitest/test_presentation_tcp_receiver_establish_connection_timeout.html delete mode 100644 dom/presentation/tests/mochitest/test_presentation_tcp_receiver_establish_connection_unknown_content_type.js delete mode 100644 dom/presentation/tests/mochitest/test_presentation_tcp_receiver_establish_connection_unknown_content_type_inproc.html delete mode 100644 dom/presentation/tests/mochitest/test_presentation_tcp_receiver_establish_connection_unknown_content_type_oop.html delete mode 100644 dom/presentation/tests/mochitest/test_presentation_tcp_receiver_oop.html delete mode 100644 dom/presentation/tests/mochitest/test_presentation_tcp_sender.html delete mode 100644 dom/presentation/tests/mochitest/test_presentation_tcp_sender_default_request.html delete mode 100644 dom/presentation/tests/mochitest/test_presentation_tcp_sender_disconnect.html delete mode 100644 dom/presentation/tests/mochitest/test_presentation_tcp_sender_establish_connection_error.html delete mode 100644 dom/presentation/tests/mochitest/test_presentation_terminate.js delete mode 100644 dom/presentation/tests/mochitest/test_presentation_terminate_establish_connection_error.js delete mode 100644 dom/presentation/tests/mochitest/test_presentation_terminate_establish_connection_error_inproc.html delete mode 100644 dom/presentation/tests/mochitest/test_presentation_terminate_establish_connection_error_oop.html delete mode 100644 dom/presentation/tests/mochitest/test_presentation_terminate_inproc.html delete mode 100644 dom/presentation/tests/mochitest/test_presentation_terminate_oop.html delete mode 100644 dom/presentation/tests/xpcshell/test_multicast_dns_device_provider.js delete mode 100644 dom/presentation/tests/xpcshell/test_presentation_device_manager.js delete mode 100644 dom/presentation/tests/xpcshell/test_presentation_session_transport.js delete mode 100644 dom/presentation/tests/xpcshell/test_presentation_state_machine.js delete mode 100644 dom/presentation/tests/xpcshell/test_tcp_control_channel.js delete mode 100644 dom/presentation/tests/xpcshell/xpcshell.ini delete mode 100644 dom/webidl/Presentation.webidl delete mode 100644 dom/webidl/PresentationAvailability.webidl delete mode 100644 dom/webidl/PresentationConnection.webidl delete mode 100644 dom/webidl/PresentationConnectionAvailableEvent.webidl delete mode 100644 dom/webidl/PresentationConnectionCloseEvent.webidl delete mode 100644 dom/webidl/PresentationConnectionList.webidl delete mode 100644 dom/webidl/PresentationDeviceInfoManager.webidl delete mode 100644 dom/webidl/PresentationReceiver.webidl delete mode 100644 dom/webidl/PresentationRequest.webidl (limited to 'dom') diff --git a/dom/base/Navigator.cpp b/dom/base/Navigator.cpp index fdf151b6c4..1433f32571 100644 --- a/dom/base/Navigator.cpp +++ b/dom/base/Navigator.cpp @@ -40,7 +40,6 @@ #include "mozilla/dom/FlyWebPublishedServer.h" #include "mozilla/dom/FlyWebService.h" #include "mozilla/dom/Permissions.h" -#include "mozilla/dom/Presentation.h" #include "mozilla/dom/ServiceWorkerContainer.h" #include "mozilla/dom/StorageManager.h" #include "mozilla/dom/TCPSocket.h" @@ -67,8 +66,6 @@ #include "nsIAppsService.h" #include "mozIApplication.h" #include "WidgetUtils.h" -#include "nsIPresentationService.h" - #include "mozilla/dom/MediaDevices.h" #include "MediaManager.h" @@ -218,7 +215,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Navigator) #ifdef MOZ_EME NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMediaKeySystemAccessManager) #endif - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPresentation) #ifdef MOZ_GAMEPAD NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGamepadServiceTest) #endif @@ -284,10 +280,6 @@ Navigator::Invalidate() mTimeManager = nullptr; } - if (mPresentation) { - mPresentation = nullptr; - } - mServiceWorkerContainer = nullptr; #ifdef MOZ_EME @@ -1931,19 +1923,5 @@ Navigator::RequestMediaKeySystemAccess(const nsAString& aKeySystem, } #endif -Presentation* -Navigator::GetPresentation(ErrorResult& aRv) -{ - if (!mPresentation) { - if (!mWindow) { - aRv.Throw(NS_ERROR_UNEXPECTED); - return nullptr; - } - mPresentation = Presentation::Create(mWindow); - } - - return mPresentation; -} - } // namespace dom } // namespace mozilla diff --git a/dom/base/Navigator.h b/dom/base/Navigator.h index 91b7fc15ce..c681797fb6 100644 --- a/dom/base/Navigator.h +++ b/dom/base/Navigator.h @@ -74,7 +74,6 @@ class Connection; } // namespace network class PowerManager; -class Presentation; class LegacyMozTCPSocket; class StorageManager; @@ -210,8 +209,6 @@ public: system::AudioChannelManager* GetMozAudioChannelManager(ErrorResult& aRv); #endif // MOZ_AUDIO_CHANNEL_MANAGER - Presentation* GetPresentation(ErrorResult& aRv); - bool SendBeacon(const nsAString& aUrl, const Nullable& aData, ErrorResult& aRv); @@ -288,7 +285,6 @@ private: RefPtr mTimeManager; RefPtr mServiceWorkerContainer; nsCOMPtr mWindow; - RefPtr mPresentation; #ifdef MOZ_GAMEPAD RefPtr mGamepadServiceTest; #endif diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index fdf0fcf3eb..41856eef8e 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -150,8 +150,6 @@ #endif #include "mozilla/dom/File.h" -#include "mozilla/dom/PPresentationChild.h" -#include "mozilla/dom/PresentationIPCService.h" #include "mozilla/ipc/InputStreamUtils.h" #ifdef MOZ_WEBSPEECH @@ -1417,20 +1415,6 @@ ContentChild::SendPBlobConstructor(PBlobChild* aActor, return PContentChild::SendPBlobConstructor(aActor, aParams); } -PPresentationChild* -ContentChild::AllocPPresentationChild() -{ - MOZ_CRASH("We should never be manually allocating PPresentationChild actors"); - return nullptr; -} - -bool -ContentChild::DeallocPPresentationChild(PPresentationChild* aActor) -{ - delete aActor; - return true; -} - PFlyWebPublishedServerChild* ContentChild::AllocPFlyWebPublishedServerChild(const nsString& name, const FlyWebPublishOptions& params) @@ -1447,35 +1431,6 @@ ContentChild::DeallocPFlyWebPublishedServerChild(PFlyWebPublishedServerChild* aA return true; } -bool -ContentChild::RecvNotifyPresentationReceiverLaunched(PBrowserChild* aIframe, - const nsString& aSessionId) -{ - nsCOMPtr docShell = - do_GetInterface(static_cast(aIframe)->WebNavigation()); - NS_WARNING_ASSERTION(docShell, "WebNavigation failed"); - - nsCOMPtr service = - do_GetService(PRESENTATION_SERVICE_CONTRACTID); - NS_WARNING_ASSERTION(service, "presentation service is missing"); - - Unused << NS_WARN_IF(NS_FAILED(static_cast(service.get())->MonitorResponderLoading(aSessionId, docShell))); - - return true; -} - -bool -ContentChild::RecvNotifyPresentationReceiverCleanUp(const nsString& aSessionId) -{ - nsCOMPtr service = - do_GetService(PRESENTATION_SERVICE_CONTRACTID); - NS_WARNING_ASSERTION(service, "presentation service is missing"); - - Unused << NS_WARN_IF(NS_FAILED(service->UntrackSessionInfo(aSessionId, nsIPresentationService::ROLE_RECEIVER))); - - return true; -} - bool ContentChild::RecvNotifyEmptyHTTPCache() { diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h index 4c8f15cc05..403328a212 100644 --- a/dom/ipc/ContentChild.h +++ b/dom/ipc/ContentChild.h @@ -297,23 +297,12 @@ public: virtual bool DeallocPStorageChild(PStorageChild* aActor) override; - virtual PPresentationChild* AllocPPresentationChild() override; - - virtual bool DeallocPPresentationChild(PPresentationChild* aActor) override; - virtual PFlyWebPublishedServerChild* AllocPFlyWebPublishedServerChild(const nsString& name, const FlyWebPublishOptions& params) override; virtual bool DeallocPFlyWebPublishedServerChild(PFlyWebPublishedServerChild* aActor) override; - virtual bool - RecvNotifyPresentationReceiverLaunched(PBrowserChild* aIframe, - const nsString& aSessionId) override; - - virtual bool - RecvNotifyPresentationReceiverCleanUp(const nsString& aSessionId) override; - virtual bool RecvNotifyEmptyHTTPCache() override; virtual PSpeechSynthesisChild* AllocPSpeechSynthesisChild() override; diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 97e3a48808..026346b773 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -51,8 +51,6 @@ #include "mozilla/dom/ServiceWorkerRegistrar.h" #include "mozilla/dom/power/PowerManagerService.h" #include "mozilla/dom/Permissions.h" -#include "mozilla/dom/PresentationParent.h" -#include "mozilla/dom/PPresentationParent.h" #include "mozilla/dom/PushNotifier.h" #include "mozilla/dom/FlyWebPublishedServerIPC.h" #include "mozilla/dom/quota/QuotaManagerService.h" @@ -3106,27 +3104,6 @@ ContentParent::DeallocPStorageParent(PStorageParent* aActor) return true; } -PPresentationParent* -ContentParent::AllocPPresentationParent() -{ - RefPtr actor = new PresentationParent(); - return actor.forget().take(); -} - -bool -ContentParent::DeallocPPresentationParent(PPresentationParent* aActor) -{ - RefPtr actor = - dont_AddRef(static_cast(aActor)); - return true; -} - -bool -ContentParent::RecvPPresentationConstructor(PPresentationParent* aActor) -{ - return static_cast(aActor)->Init(mChildID); -} - PFlyWebPublishedServerParent* ContentParent::AllocPFlyWebPublishedServerParent(const nsString& name, const FlyWebPublishOptions& params) diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index 26b5c44acc..a4ddb9c64c 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -800,12 +800,6 @@ private: virtual bool DeallocPStorageParent(PStorageParent* aActor) override; - virtual PPresentationParent* AllocPPresentationParent() override; - - virtual bool DeallocPPresentationParent(PPresentationParent* aActor) override; - - virtual bool RecvPPresentationConstructor(PPresentationParent* aActor) override; - virtual PFlyWebPublishedServerParent* AllocPFlyWebPublishedServerParent(const nsString& name, const FlyWebPublishOptions& params) override; diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index e8fb25aecc..9ed8363d70 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -43,7 +43,6 @@ include protocol PJavaScript; include protocol PRemoteSpellcheckEngine; include protocol PWebBrowserPersistDocument; include protocol PWebrtcGlobal; -include protocol PPresentation; include protocol PVideoDecoderManager; include protocol PFlyWebPublishedServer; include DOMTypes; @@ -260,7 +259,6 @@ nested(upto inside_cpow) sync protocol PContent manages PRemoteSpellcheckEngine; manages PWebBrowserPersistDocument; manages PWebrtcGlobal; - manages PPresentation; manages PFlyWebPublishedServer; both: @@ -480,18 +478,6 @@ child: */ async UpdateWindow(uintptr_t aChildId); - /** - * Notify the child that presentation receiver has been launched with the - * correspondent iframe. - */ - async NotifyPresentationReceiverLaunched(PBrowser aIframe, nsString aSessionId); - - /** - * Notify the child that the info about a presentation receiver needs to be - * cleaned up. - */ - async NotifyPresentationReceiverCleanUp(nsString aSessionId); - /** * Notify the child that cache is emptied. */ @@ -682,8 +668,6 @@ parent: async PWebrtcGlobal(); - async PPresentation(); - async PFlyWebPublishedServer(nsString name, FlyWebPublishOptions params); // Services remoting diff --git a/dom/moz.build b/dom/moz.build index 54dc0510e7..731c9af722 100644 --- a/dom/moz.build +++ b/dom/moz.build @@ -107,8 +107,6 @@ if CONFIG['OS_ARCH'] == 'WINNT': if CONFIG['MOZ_SECUREELEMENT']: DIRS += ['secureelement'] -DIRS += ['presentation'] - TEST_DIRS += [ 'tests', 'imptests', diff --git a/dom/presentation/AvailabilityCollection.cpp b/dom/presentation/AvailabilityCollection.cpp deleted file mode 100644 index 73752c7505..0000000000 --- a/dom/presentation/AvailabilityCollection.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* 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 "AvailabilityCollection.h" - -#include "mozilla/ClearOnShutdown.h" -#include "PresentationAvailability.h" - -namespace mozilla { -namespace dom { - -/* static */ -StaticAutoPtr -AvailabilityCollection::sSingleton; -static bool gOnceAliveNowDead = false; - -/* static */ AvailabilityCollection* -AvailabilityCollection::GetSingleton() -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (!sSingleton && !gOnceAliveNowDead) { - sSingleton = new AvailabilityCollection(); - ClearOnShutdown(&sSingleton); - } - - return sSingleton; -} - -AvailabilityCollection::AvailabilityCollection() -{ - MOZ_COUNT_CTOR(AvailabilityCollection); -} - -AvailabilityCollection::~AvailabilityCollection() -{ - MOZ_COUNT_DTOR(AvailabilityCollection); - gOnceAliveNowDead = true; -} - -void -AvailabilityCollection::Add(PresentationAvailability* aAvailability) -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (!aAvailability) { - return; - } - - WeakPtr availability = aAvailability; - if (mAvailabilities.Contains(aAvailability)) { - return; - } - - mAvailabilities.AppendElement(aAvailability); -} - -void -AvailabilityCollection::Remove(PresentationAvailability* aAvailability) -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (!aAvailability) { - return; - } - - WeakPtr availability = aAvailability; - mAvailabilities.RemoveElement(availability); -} - -already_AddRefed -AvailabilityCollection::Find(const uint64_t aWindowId, const nsTArray& aUrls) -{ - MOZ_ASSERT(NS_IsMainThread()); - - // Loop backwards to allow removing elements in the loop. - for (int i = mAvailabilities.Length() - 1; i >= 0; --i) { - WeakPtr availability = mAvailabilities[i]; - if (!availability) { - // The availability object was destroyed. Remove it from the list. - mAvailabilities.RemoveElementAt(i); - continue; - } - - if (availability->Equals(aWindowId, aUrls)) { - RefPtr matchedAvailability = availability.get(); - return matchedAvailability.forget(); - } - } - - - return nullptr; -} - -} // namespace dom -} // namespace mozilla diff --git a/dom/presentation/AvailabilityCollection.h b/dom/presentation/AvailabilityCollection.h deleted file mode 100644 index d2faae4c29..0000000000 --- a/dom/presentation/AvailabilityCollection.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_dom_AvailabilityCollection_h -#define mozilla_dom_AvailabilityCollection_h - -#include "mozilla/StaticPtr.h" -#include "mozilla/WeakPtr.h" -#include "nsString.h" -#include "nsTArray.h" - -namespace mozilla { -namespace dom { - -class PresentationAvailability; - -class AvailabilityCollection final -{ -public: - static AvailabilityCollection* GetSingleton(); - - void Add(PresentationAvailability* aAvailability); - - void Remove(PresentationAvailability* aAvailability); - - already_AddRefed - Find(const uint64_t aWindowId, const nsTArray& aUrls); - -private: - friend class StaticAutoPtr; - - AvailabilityCollection(); - virtual ~AvailabilityCollection(); - - static StaticAutoPtr sSingleton; - nsTArray> mAvailabilities; -}; - -} // namespace dom -} // namespace mozilla - -#endif // mozilla_dom_AvailabilityCollection_h diff --git a/dom/presentation/ControllerConnectionCollection.cpp b/dom/presentation/ControllerConnectionCollection.cpp deleted file mode 100644 index 7d3ffe6845..0000000000 --- a/dom/presentation/ControllerConnectionCollection.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* 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 "ControllerConnectionCollection.h" - -#include "mozilla/ClearOnShutdown.h" -#include "nsIPresentationService.h" -#include "PresentationConnection.h" - -namespace mozilla { -namespace dom { - -/* static */ -StaticAutoPtr -ControllerConnectionCollection::sSingleton; - -/* static */ ControllerConnectionCollection* -ControllerConnectionCollection::GetSingleton() -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (!sSingleton) { - sSingleton = new ControllerConnectionCollection(); - ClearOnShutdown(&sSingleton); - } - - return sSingleton; -} - -ControllerConnectionCollection::ControllerConnectionCollection() -{ - MOZ_COUNT_CTOR(ControllerConnectionCollection); -} - -ControllerConnectionCollection::~ControllerConnectionCollection() -{ - MOZ_COUNT_DTOR(ControllerConnectionCollection); -} - -void -ControllerConnectionCollection::AddConnection( - PresentationConnection* aConnection, - const uint8_t aRole) -{ - MOZ_ASSERT(NS_IsMainThread()); - if (aRole != nsIPresentationService::ROLE_CONTROLLER) { - MOZ_ASSERT(false, "This is allowed only to be called at controller side."); - return; - } - - if (!aConnection) { - return; - } - - WeakPtr connection = aConnection; - if (mConnections.Contains(connection)) { - return; - } - - mConnections.AppendElement(connection); -} - -void -ControllerConnectionCollection::RemoveConnection( - PresentationConnection* aConnection, - const uint8_t aRole) -{ - MOZ_ASSERT(NS_IsMainThread()); - if (aRole != nsIPresentationService::ROLE_CONTROLLER) { - MOZ_ASSERT(false, "This is allowed only to be called at controller side."); - return; - } - - if (!aConnection) { - return; - } - - WeakPtr connection = aConnection; - mConnections.RemoveElement(connection); -} - -already_AddRefed -ControllerConnectionCollection::FindConnection( - uint64_t aWindowId, - const nsAString& aId, - const uint8_t aRole) -{ - MOZ_ASSERT(NS_IsMainThread()); - if (aRole != nsIPresentationService::ROLE_CONTROLLER) { - MOZ_ASSERT(false, "This is allowed only to be called at controller side."); - return nullptr; - } - - // Loop backwards to allow removing elements in the loop. - for (int i = mConnections.Length() - 1; i >= 0; --i) { - WeakPtr connection = mConnections[i]; - if (!connection) { - // The connection was destroyed. Remove it from the list. - mConnections.RemoveElementAt(i); - continue; - } - - if (connection->Equals(aWindowId, aId)) { - RefPtr matchedConnection = connection.get(); - return matchedConnection.forget(); - } - } - - return nullptr; -} - -} // namespace dom -} // namespace mozilla diff --git a/dom/presentation/ControllerConnectionCollection.h b/dom/presentation/ControllerConnectionCollection.h deleted file mode 100644 index c5300fe309..0000000000 --- a/dom/presentation/ControllerConnectionCollection.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_dom_ControllerConnectionCollection_h -#define mozilla_dom_ControllerConnectionCollection_h - -#include "mozilla/StaticPtr.h" -#include "mozilla/WeakPtr.h" -#include "nsString.h" -#include "nsTArray.h" - -namespace mozilla { -namespace dom { - -class PresentationConnection; - -class ControllerConnectionCollection final -{ -public: - static ControllerConnectionCollection* GetSingleton(); - - void AddConnection(PresentationConnection* aConnection, - const uint8_t aRole); - - void RemoveConnection(PresentationConnection* aConnection, - const uint8_t aRole); - - already_AddRefed - FindConnection(uint64_t aWindowId, - const nsAString& aId, - const uint8_t aRole); - -private: - friend class StaticAutoPtr; - - ControllerConnectionCollection(); - virtual ~ControllerConnectionCollection(); - - static StaticAutoPtr sSingleton; - nsTArray> mConnections; -}; - -} // namespace dom -} // namespace mozilla - -#endif // mozilla_dom_ControllerConnectionCollection_h diff --git a/dom/presentation/DCPresentationChannelDescription.cpp b/dom/presentation/DCPresentationChannelDescription.cpp deleted file mode 100644 index a904dfe3f4..0000000000 --- a/dom/presentation/DCPresentationChannelDescription.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* 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 "DCPresentationChannelDescription.h" - -namespace mozilla { -namespace dom { - -NS_IMPL_ISUPPORTS(DCPresentationChannelDescription, - nsIPresentationChannelDescription) - -NS_IMETHODIMP -DCPresentationChannelDescription::GetType(uint8_t* aRetVal) -{ - if (NS_WARN_IF(!aRetVal)) { - return NS_ERROR_INVALID_POINTER; - } - - *aRetVal = nsIPresentationChannelDescription::TYPE_DATACHANNEL; - return NS_OK; -} - -NS_IMETHODIMP -DCPresentationChannelDescription::GetTcpAddress(nsIArray** aRetVal) -{ - return NS_ERROR_FAILURE; -} - -NS_IMETHODIMP -DCPresentationChannelDescription::GetTcpPort(uint16_t* aRetVal) -{ - return NS_ERROR_FAILURE; -} - -NS_IMETHODIMP -DCPresentationChannelDescription::GetDataChannelSDP(nsAString& aDataChannelSDP) -{ - aDataChannelSDP = mSDP; - return NS_OK; -} - -} // namespace dom -} // namespace mozilla diff --git a/dom/presentation/DCPresentationChannelDescription.h b/dom/presentation/DCPresentationChannelDescription.h deleted file mode 100644 index 63a058f9a9..0000000000 --- a/dom/presentation/DCPresentationChannelDescription.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_dom_DCPresentationChannelDescription_h -#define mozilla_dom_DCPresentationChannelDescription_h - -#include "nsIPresentationControlChannel.h" -#include "nsString.h" - -namespace mozilla { -namespace dom { - -// PresentationChannelDescription for Data Channel -class DCPresentationChannelDescription final : public nsIPresentationChannelDescription -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIPRESENTATIONCHANNELDESCRIPTION - - explicit DCPresentationChannelDescription(const nsAString& aSDP) - : mSDP(aSDP) - { - } - -private: - virtual ~DCPresentationChannelDescription() = default; - - nsString mSDP; -}; - -} // namespace dom -} // namespace mozilla - -#endif // mozilla_dom_DCPresentationChannelDescription_h diff --git a/dom/presentation/Presentation.cpp b/dom/presentation/Presentation.cpp deleted file mode 100644 index 07ca12f26d..0000000000 --- a/dom/presentation/Presentation.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* 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 "Presentation.h" - -#include - -#include "mozilla/dom/PresentationBinding.h" -#include "mozilla/dom/Promise.h" -#include "nsContentUtils.h" -#include "nsCycleCollectionParticipant.h" -#include "nsIDocShell.h" -#include "nsIPresentationService.h" -#include "nsIScriptSecurityManager.h" -#include "nsJSUtils.h" -#include "nsNetUtil.h" -#include "nsPIDOMWindow.h" -#include "nsSandboxFlags.h" -#include "nsServiceManagerUtils.h" -#include "PresentationReceiver.h" - -namespace mozilla { -namespace dom { - -NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Presentation, - mWindow, - mDefaultRequest, mReceiver) - -NS_IMPL_CYCLE_COLLECTING_ADDREF(Presentation) -NS_IMPL_CYCLE_COLLECTING_RELEASE(Presentation) - -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Presentation) - NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY - NS_INTERFACE_MAP_ENTRY(nsISupports) -NS_INTERFACE_MAP_END - -/* static */ already_AddRefed -Presentation::Create(nsPIDOMWindowInner* aWindow) -{ - RefPtr presentation = new Presentation(aWindow); - return presentation.forget(); -} - -Presentation::Presentation(nsPIDOMWindowInner* aWindow) - : mWindow(aWindow) -{ -} - -Presentation::~Presentation() -{ -} - -/* virtual */ JSObject* -Presentation::WrapObject(JSContext* aCx, - JS::Handle aGivenProto) -{ - return PresentationBinding::Wrap(aCx, this, aGivenProto); -} - -void -Presentation::SetDefaultRequest(PresentationRequest* aRequest) -{ - nsCOMPtr doc = mWindow ? mWindow->GetExtantDoc() : nullptr; - if (NS_WARN_IF(!doc)) { - return; - } - - if (doc->GetSandboxFlags() & SANDBOXED_PRESENTATION) { - return; - } - - mDefaultRequest = aRequest; -} - -already_AddRefed -Presentation::GetDefaultRequest() const -{ - RefPtr request = mDefaultRequest; - return request.forget(); -} - -already_AddRefed -Presentation::GetReceiver() -{ - // return the same receiver if already created - if (mReceiver) { - RefPtr receiver = mReceiver; - return receiver.forget(); - } - - if (!HasReceiverSupport() || !IsInPresentedContent()) { - return nullptr; - } - - mReceiver = PresentationReceiver::Create(mWindow); - if (NS_WARN_IF(!mReceiver)) { - MOZ_ASSERT(mReceiver); - return nullptr; - } - - RefPtr receiver = mReceiver; - return receiver.forget(); -} - -void -Presentation::SetStartSessionUnsettled(bool aIsUnsettled) -{ - mStartSessionUnsettled = aIsUnsettled; -} - -bool -Presentation::IsStartSessionUnsettled() const -{ - return mStartSessionUnsettled; -} - -bool -Presentation::HasReceiverSupport() const -{ - if (!mWindow) { - return false; - } - - // Grant access to browser receiving pages and their same-origin iframes. (App - // pages should be controlled by "presentation" permission in app manifests.) - nsCOMPtr docShell = mWindow->GetDocShell(); - if (!docShell) { - return false; - } - - if (!Preferences::GetBool("dom.presentation.testing.simulate-receiver") && - !docShell->GetIsInMozBrowserOrApp() && - !docShell->GetIsTopLevelContentDocShell()) { - return false; - } - - nsAutoString presentationURL; - nsContentUtils::GetPresentationURL(docShell, presentationURL); - - if (presentationURL.IsEmpty()) { - return false; - } - - nsCOMPtr securityManager = - nsContentUtils::GetSecurityManager(); - if (!securityManager) { - return false; - } - - nsCOMPtr presentationURI; - nsresult rv = NS_NewURI(getter_AddRefs(presentationURI), presentationURL); - if (NS_FAILED(rv)) { - return false; - } - - nsCOMPtr docURI = mWindow->GetDocumentURI(); - return NS_SUCCEEDED(securityManager->CheckSameOriginURI(presentationURI, - docURI, - false)); -} - -bool -Presentation::IsInPresentedContent() const -{ - if (!mWindow) { - return false; - } - - nsCOMPtr docShell = mWindow->GetDocShell(); - MOZ_ASSERT(docShell); - - nsAutoString presentationURL; - nsContentUtils::GetPresentationURL(docShell, presentationURL); - - return !presentationURL.IsEmpty(); -} - -} // namespace dom -} // namespace mozilla diff --git a/dom/presentation/Presentation.h b/dom/presentation/Presentation.h deleted file mode 100644 index 08d0003b33..0000000000 --- a/dom/presentation/Presentation.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_dom_Presentation_h -#define mozilla_dom_Presentation_h - -#include "nsCOMPtr.h" -#include "nsCycleCollectionParticipant.h" -#include "nsISupportsImpl.h" -#include "nsWrapperCache.h" - -class nsPIDOMWindowInner; - -namespace mozilla { -namespace dom { - -class Promise; -class PresentationReceiver; -class PresentationRequest; - -class Presentation final : public nsISupports - , public nsWrapperCache -{ -public: - NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Presentation) - - static already_AddRefed Create(nsPIDOMWindowInner* aWindow); - - virtual JSObject* WrapObject(JSContext* aCx, - JS::Handle aGivenProto) override; - - nsPIDOMWindowInner* GetParentObject() const - { - return mWindow; - } - - // WebIDL (public APIs) - void SetDefaultRequest(PresentationRequest* aRequest); - - already_AddRefed GetDefaultRequest() const; - - already_AddRefed GetReceiver(); - - // For bookkeeping unsettled start session request - void SetStartSessionUnsettled(bool aIsUnsettled); - bool IsStartSessionUnsettled() const; - -private: - explicit Presentation(nsPIDOMWindowInner* aWindow); - - virtual ~Presentation(); - - bool HasReceiverSupport() const; - - bool IsInPresentedContent() const; - - RefPtr mDefaultRequest; - RefPtr mReceiver; - nsCOMPtr mWindow; - bool mStartSessionUnsettled = false; -}; - -} // namespace dom -} // namespace mozilla - -#endif // mozilla_dom_Presentation_h diff --git a/dom/presentation/PresentationAvailability.cpp b/dom/presentation/PresentationAvailability.cpp deleted file mode 100644 index 93f27dfbfc..0000000000 --- a/dom/presentation/PresentationAvailability.cpp +++ /dev/null @@ -1,206 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* 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 "PresentationAvailability.h" - -#include "mozilla/dom/PresentationAvailabilityBinding.h" -#include "mozilla/dom/Promise.h" -#include "mozilla/Unused.h" -#include "nsCycleCollectionParticipant.h" -#include "nsIPresentationDeviceManager.h" -#include "nsIPresentationService.h" -#include "nsServiceManagerUtils.h" -#include "PresentationLog.h" - -using namespace mozilla; -using namespace mozilla::dom; - -NS_IMPL_CYCLE_COLLECTION_CLASS(PresentationAvailability) - -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(PresentationAvailability, DOMEventTargetHelper) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPromises) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END - -NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(PresentationAvailability, DOMEventTargetHelper) - NS_IMPL_CYCLE_COLLECTION_UNLINK(mPromises); - tmp->Shutdown(); -NS_IMPL_CYCLE_COLLECTION_UNLINK_END - -NS_IMPL_ADDREF_INHERITED(PresentationAvailability, DOMEventTargetHelper) -NS_IMPL_RELEASE_INHERITED(PresentationAvailability, DOMEventTargetHelper) - -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(PresentationAvailability) - NS_INTERFACE_MAP_ENTRY(nsIPresentationAvailabilityListener) -NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper) - -/* static */ already_AddRefed -PresentationAvailability::Create(nsPIDOMWindowInner* aWindow, - const nsTArray& aUrls, - RefPtr& aPromise) -{ - RefPtr availability = - new PresentationAvailability(aWindow, aUrls); - return NS_WARN_IF(!availability->Init(aPromise)) ? nullptr - : availability.forget(); -} - -PresentationAvailability::PresentationAvailability(nsPIDOMWindowInner* aWindow, - const nsTArray& aUrls) - : DOMEventTargetHelper(aWindow) - , mIsAvailable(false) - , mUrls(aUrls) -{ - for (uint32_t i = 0; i < mUrls.Length(); ++i) { - mAvailabilityOfUrl.AppendElement(false); - } -} - -PresentationAvailability::~PresentationAvailability() -{ - Shutdown(); -} - -bool -PresentationAvailability::Init(RefPtr& aPromise) -{ - nsCOMPtr service = - do_GetService(PRESENTATION_SERVICE_CONTRACTID); - if (NS_WARN_IF(!service)) { - return false; - } - - nsresult rv = service->RegisterAvailabilityListener(mUrls, this); - if (NS_WARN_IF(NS_FAILED(rv))) { - // If the user agent is unable to monitor available device, - // Resolve promise with |value| set to false. - mIsAvailable = false; - aPromise->MaybeResolve(this); - return true; - } - - EnqueuePromise(aPromise); - - AvailabilityCollection* collection = AvailabilityCollection::GetSingleton(); - if (collection) { - collection->Add(this); - } - - return true; -} - -void PresentationAvailability::Shutdown() -{ - AvailabilityCollection* collection = AvailabilityCollection::GetSingleton(); - if (collection ) { - collection->Remove(this); - } - - nsCOMPtr service = - do_GetService(PRESENTATION_SERVICE_CONTRACTID); - if (NS_WARN_IF(!service)) { - return; - } - - Unused << - NS_WARN_IF(NS_FAILED(service->UnregisterAvailabilityListener(mUrls, - this))); -} - -/* virtual */ void -PresentationAvailability::DisconnectFromOwner() -{ - Shutdown(); - DOMEventTargetHelper::DisconnectFromOwner(); -} - -/* virtual */ JSObject* -PresentationAvailability::WrapObject(JSContext* aCx, - JS::Handle aGivenProto) -{ - return PresentationAvailabilityBinding::Wrap(aCx, this, aGivenProto); -} - -bool -PresentationAvailability::Equals(const uint64_t aWindowID, - const nsTArray& aUrls) const -{ - if (GetOwner() && GetOwner()->WindowID() == aWindowID && - mUrls.Length() == aUrls.Length()) { - for (const auto& url : aUrls) { - if (!mUrls.Contains(url)) { - return false; - } - } - return true; - } - - return false; -} - -bool -PresentationAvailability::IsCachedValueReady() -{ - // All pending promises will be solved when cached value is ready and - // no promise should be enqueued afterward. - return mPromises.IsEmpty(); -} - -void -PresentationAvailability::EnqueuePromise(RefPtr& aPromise) -{ - mPromises.AppendElement(aPromise); -} - -bool -PresentationAvailability::Value() const -{ - return mIsAvailable; -} - -NS_IMETHODIMP -PresentationAvailability::NotifyAvailableChange(const nsTArray& aAvailabilityUrls, - bool aIsAvailable) -{ - bool available = false; - for (uint32_t i = 0; i < mUrls.Length(); ++i) { - if (aAvailabilityUrls.Contains(mUrls[i])) { - mAvailabilityOfUrl[i] = aIsAvailable; - } - available |= mAvailabilityOfUrl[i]; - } - - return NS_DispatchToCurrentThread(NewRunnableMethod - (this, - &PresentationAvailability::UpdateAvailabilityAndDispatchEvent, - available)); -} - -void -PresentationAvailability::UpdateAvailabilityAndDispatchEvent(bool aIsAvailable) -{ - PRES_DEBUG("%s\n", __func__); - bool isChanged = (aIsAvailable != mIsAvailable); - - mIsAvailable = aIsAvailable; - - if (!mPromises.IsEmpty()) { - // Use the first availability change notification to resolve promise. - do { - nsTArray> promises = Move(mPromises); - for (auto& promise : promises) { - promise->MaybeResolve(this); - } - // more promises may have been added to mPromises, at least in theory - } while (!mPromises.IsEmpty()); - - return; - } - - if (isChanged) { - Unused << - NS_WARN_IF(NS_FAILED(DispatchTrustedEvent(NS_LITERAL_STRING("change")))); - } -} diff --git a/dom/presentation/PresentationAvailability.h b/dom/presentation/PresentationAvailability.h deleted file mode 100644 index edfae2c02b..0000000000 --- a/dom/presentation/PresentationAvailability.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_dom_PresentationAvailability_h -#define mozilla_dom_PresentationAvailability_h - -#include "mozilla/DOMEventTargetHelper.h" -#include "nsIPresentationListener.h" -#include "nsTArray.h" - -namespace mozilla { -namespace dom { - -class Promise; - -class PresentationAvailability final : public DOMEventTargetHelper - , public nsIPresentationAvailabilityListener - , public SupportsWeakPtr -{ -public: - NS_DECL_ISUPPORTS_INHERITED - NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(PresentationAvailability, - DOMEventTargetHelper) - NS_DECL_NSIPRESENTATIONAVAILABILITYLISTENER - MOZ_DECLARE_WEAKREFERENCE_TYPENAME(PresentationAvailability) - - static already_AddRefed - Create(nsPIDOMWindowInner* aWindow, - const nsTArray& aUrls, - RefPtr& aPromise); - - virtual void DisconnectFromOwner() override; - - virtual JSObject* WrapObject(JSContext* aCx, - JS::Handle aGivenProto) override; - - bool Equals(const uint64_t aWindowID, const nsTArray& aUrls) const; - - bool IsCachedValueReady(); - - void EnqueuePromise(RefPtr& aPromise); - - // WebIDL (public APIs) - bool Value() const; - - IMPL_EVENT_HANDLER(change); - -private: - explicit PresentationAvailability(nsPIDOMWindowInner* aWindow, - const nsTArray& aUrls); - - virtual ~PresentationAvailability(); - - bool Init(RefPtr& aPromise); - - void Shutdown(); - - void UpdateAvailabilityAndDispatchEvent(bool aIsAvailable); - - bool mIsAvailable; - - nsTArray> mPromises; - - nsTArray mUrls; - nsTArray mAvailabilityOfUrl; -}; - -} // namespace dom -} // namespace mozilla - -#endif // mozilla_dom_PresentationAvailability_h diff --git a/dom/presentation/PresentationCallbacks.cpp b/dom/presentation/PresentationCallbacks.cpp deleted file mode 100644 index fd0ffee31c..0000000000 --- a/dom/presentation/PresentationCallbacks.cpp +++ /dev/null @@ -1,282 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* 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 "mozilla/dom/Promise.h" -#include "nsIDocShell.h" -#include "nsIInterfaceRequestorUtils.h" -#include "nsIPresentationService.h" -#include "nsIWebProgress.h" -#include "nsServiceManagerUtils.h" -#include "nsThreadUtils.h" -#include "PresentationCallbacks.h" -#include "PresentationRequest.h" -#include "PresentationConnection.h" -#include "PresentationTransportBuilderConstructor.h" - -using namespace mozilla; -using namespace mozilla::dom; - -/* - * Implementation of PresentationRequesterCallback - */ - -NS_IMPL_ISUPPORTS(PresentationRequesterCallback, nsIPresentationServiceCallback) - -PresentationRequesterCallback::PresentationRequesterCallback(PresentationRequest* aRequest, - const nsAString& aSessionId, - Promise* aPromise) - : mRequest(aRequest) - , mSessionId(aSessionId) - , mPromise(aPromise) -{ - MOZ_ASSERT(mRequest); - MOZ_ASSERT(mPromise); - MOZ_ASSERT(!mSessionId.IsEmpty()); -} - -PresentationRequesterCallback::~PresentationRequesterCallback() -{ -} - -// nsIPresentationServiceCallback -NS_IMETHODIMP -PresentationRequesterCallback::NotifySuccess(const nsAString& aUrl) -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (aUrl.IsEmpty()) { - return NotifyError(NS_ERROR_DOM_OPERATION_ERR); - } - - RefPtr connection = - PresentationConnection::Create(mRequest->GetOwner(), mSessionId, aUrl, - nsIPresentationService::ROLE_CONTROLLER); - if (NS_WARN_IF(!connection)) { - return NotifyError(NS_ERROR_DOM_OPERATION_ERR); - } - - mRequest->NotifyPromiseSettled(); - mPromise->MaybeResolve(connection); - - return mRequest->DispatchConnectionAvailableEvent(connection); -} - -NS_IMETHODIMP -PresentationRequesterCallback::NotifyError(nsresult aError) -{ - MOZ_ASSERT(NS_IsMainThread()); - - mRequest->NotifyPromiseSettled(); - mPromise->MaybeReject(aError); - return NS_OK; -} - -/* - * Implementation of PresentationRequesterCallback - */ - -NS_IMPL_ISUPPORTS_INHERITED0(PresentationReconnectCallback, - PresentationRequesterCallback) - -PresentationReconnectCallback::PresentationReconnectCallback( - PresentationRequest* aRequest, - const nsAString& aSessionId, - Promise* aPromise, - PresentationConnection* aConnection) - : PresentationRequesterCallback(aRequest, aSessionId, aPromise) - , mConnection(aConnection) -{ -} - -PresentationReconnectCallback::~PresentationReconnectCallback() -{ -} - -NS_IMETHODIMP -PresentationReconnectCallback::NotifySuccess(const nsAString& aUrl) -{ - MOZ_ASSERT(NS_IsMainThread()); - - nsCOMPtr service = - do_GetService(PRESENTATION_SERVICE_CONTRACTID); - if (NS_WARN_IF(!service)) { - return NS_ERROR_NOT_AVAILABLE; - } - - nsresult rv = NS_OK; - // We found a matched connection with the same window ID, URL, and - // the session ID. Resolve the promise with this connection and dispatch - // the event. - if (mConnection) { - mConnection->NotifyStateChange( - mSessionId, - nsIPresentationSessionListener::STATE_CONNECTING, - NS_OK); - mPromise->MaybeResolve(mConnection); - rv = mRequest->DispatchConnectionAvailableEvent(mConnection); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - } else { - // Use |PresentationRequesterCallback::NotifySuccess| to create a new - // connection since we don't find one that can be reused. - rv = PresentationRequesterCallback::NotifySuccess(aUrl); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - rv = service->UpdateWindowIdBySessionId(mSessionId, - nsIPresentationService::ROLE_CONTROLLER, - mRequest->GetOwner()->WindowID()); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - } - - nsString sessionId = nsString(mSessionId); - return NS_DispatchToMainThread( - NS_NewRunnableFunction([sessionId, service]() -> void { - service->BuildTransport(sessionId, - nsIPresentationService::ROLE_CONTROLLER); - })); -} - -NS_IMETHODIMP -PresentationReconnectCallback::NotifyError(nsresult aError) -{ - if (mConnection) { - mConnection->NotifyStateChange( - mSessionId, - nsIPresentationSessionListener::STATE_CLOSED, - aError); - } - return PresentationRequesterCallback::NotifyError(aError); -} - -NS_IMPL_ISUPPORTS(PresentationResponderLoadingCallback, - nsIWebProgressListener, - nsISupportsWeakReference) - -PresentationResponderLoadingCallback::PresentationResponderLoadingCallback(const nsAString& aSessionId) - : mSessionId(aSessionId) -{ -} - -PresentationResponderLoadingCallback::~PresentationResponderLoadingCallback() -{ - if (mProgress) { - mProgress->RemoveProgressListener(this); - mProgress = nullptr; - } -} - -nsresult -PresentationResponderLoadingCallback::Init(nsIDocShell* aDocShell) -{ - mProgress = do_GetInterface(aDocShell); - if (NS_WARN_IF(!mProgress)) { - return NS_ERROR_NOT_AVAILABLE; - } - - uint32_t busyFlags = nsIDocShell::BUSY_FLAGS_NONE; - nsresult rv = aDocShell->GetBusyFlags(&busyFlags); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - if ((busyFlags == nsIDocShell::BUSY_FLAGS_NONE) || - (busyFlags & nsIDocShell::BUSY_FLAGS_PAGE_LOADING)) { - // The docshell has finished loading or is receiving data (|STATE_TRANSFERRING| - // has already been fired), so the page is ready for presentation use. - return NotifyReceiverReady(/* isLoading = */ true); - } - - // Start to listen to document state change event |STATE_TRANSFERRING|. - return mProgress->AddProgressListener(this, nsIWebProgress::NOTIFY_STATE_DOCUMENT); -} - -nsresult -PresentationResponderLoadingCallback::NotifyReceiverReady(bool aIsLoading) -{ - nsCOMPtr window = do_GetInterface(mProgress); - if (NS_WARN_IF(!window || !window->GetCurrentInnerWindow())) { - return NS_ERROR_NOT_AVAILABLE; - } - uint64_t windowId = window->GetCurrentInnerWindow()->WindowID(); - - nsCOMPtr service = - do_GetService(PRESENTATION_SERVICE_CONTRACTID); - if (NS_WARN_IF(!service)) { - return NS_ERROR_NOT_AVAILABLE; - } - - nsCOMPtr constructor = - PresentationTransportBuilderConstructor::Create(); - return service->NotifyReceiverReady(mSessionId, - windowId,aIsLoading, - constructor); -} - -// nsIWebProgressListener -NS_IMETHODIMP -PresentationResponderLoadingCallback::OnStateChange(nsIWebProgress* aWebProgress, - nsIRequest* aRequest, - uint32_t aStateFlags, - nsresult aStatus) -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (aStateFlags & (nsIWebProgressListener::STATE_TRANSFERRING | - nsIWebProgressListener::STATE_STOP)) { - mProgress->RemoveProgressListener(this); - - bool isLoading = aStateFlags & nsIWebProgressListener::STATE_TRANSFERRING; - return NotifyReceiverReady(isLoading); - } - - return NS_OK; -} - -NS_IMETHODIMP -PresentationResponderLoadingCallback::OnProgressChange(nsIWebProgress* aWebProgress, - nsIRequest* aRequest, - int32_t aCurSelfProgress, - int32_t aMaxSelfProgress, - int32_t aCurTotalProgress, - int32_t aMaxTotalProgress) -{ - // Do nothing. - return NS_OK; -} - -NS_IMETHODIMP -PresentationResponderLoadingCallback::OnLocationChange(nsIWebProgress* aWebProgress, - nsIRequest* aRequest, - nsIURI* aURI, - uint32_t aFlags) -{ - // Do nothing. - return NS_OK; -} - -NS_IMETHODIMP -PresentationResponderLoadingCallback::OnStatusChange(nsIWebProgress* aWebProgress, - nsIRequest* aRequest, - nsresult aStatus, - const char16_t* aMessage) -{ - // Do nothing. - return NS_OK; -} - -NS_IMETHODIMP -PresentationResponderLoadingCallback::OnSecurityChange(nsIWebProgress* aWebProgress, - nsIRequest* aRequest, - uint32_t state) -{ - // Do nothing. - return NS_OK; -} diff --git a/dom/presentation/PresentationCallbacks.h b/dom/presentation/PresentationCallbacks.h deleted file mode 100644 index e493b05108..0000000000 --- a/dom/presentation/PresentationCallbacks.h +++ /dev/null @@ -1,85 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_dom_PresentationCallbacks_h -#define mozilla_dom_PresentationCallbacks_h - -#include "mozilla/RefPtr.h" -#include "nsCOMPtr.h" -#include "nsIPresentationService.h" -#include "nsIWebProgressListener.h" -#include "nsString.h" -#include "nsWeakReference.h" - -class nsIDocShell; -class nsIWebProgress; - -namespace mozilla { -namespace dom { - -class PresentationConnection; -class PresentationRequest; -class Promise; - -class PresentationRequesterCallback : public nsIPresentationServiceCallback -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIPRESENTATIONSERVICECALLBACK - - PresentationRequesterCallback(PresentationRequest* aRequest, - const nsAString& aSessionId, - Promise* aPromise); - -protected: - virtual ~PresentationRequesterCallback(); - - RefPtr mRequest; - nsString mSessionId; - RefPtr mPromise; -}; - -class PresentationReconnectCallback final : public PresentationRequesterCallback -{ -public: - NS_DECL_ISUPPORTS_INHERITED - NS_DECL_NSIPRESENTATIONSERVICECALLBACK - - PresentationReconnectCallback(PresentationRequest* aRequest, - const nsAString& aSessionId, - Promise* aPromise, - PresentationConnection* aConnection); - -private: - virtual ~PresentationReconnectCallback(); - - RefPtr mConnection; -}; - -class PresentationResponderLoadingCallback final : public nsIWebProgressListener - , public nsSupportsWeakReference -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIWEBPROGRESSLISTENER - - explicit PresentationResponderLoadingCallback(const nsAString& aSessionId); - - nsresult Init(nsIDocShell* aDocShell); - -private: - ~PresentationResponderLoadingCallback(); - - nsresult NotifyReceiverReady(bool aIsLoading); - - nsString mSessionId; - nsCOMPtr mProgress; -}; - -} // namespace dom -} // namespace mozilla - -#endif // mozilla_dom_PresentationCallbacks_h diff --git a/dom/presentation/PresentationConnection.cpp b/dom/presentation/PresentationConnection.cpp deleted file mode 100644 index e9c4a71ca2..0000000000 --- a/dom/presentation/PresentationConnection.cpp +++ /dev/null @@ -1,763 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* 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 "PresentationConnection.h" - -#include "ControllerConnectionCollection.h" -#include "mozilla/AsyncEventDispatcher.h" -#include "mozilla/dom/DOMException.h" -#include "mozilla/dom/File.h" -#include "mozilla/dom/MessageEvent.h" -#include "mozilla/dom/MessageEventBinding.h" -#include "mozilla/dom/PresentationConnectionCloseEvent.h" -#include "mozilla/ErrorNames.h" -#include "mozilla/DebugOnly.h" -#include "nsContentUtils.h" -#include "nsCycleCollectionParticipant.h" -#include "nsIPresentationService.h" -#include "nsServiceManagerUtils.h" -#include "nsStringStream.h" -#include "PresentationConnectionList.h" -#include "PresentationLog.h" - -using namespace mozilla; -using namespace mozilla::dom; - -NS_IMPL_CYCLE_COLLECTION_CLASS(PresentationConnection) - -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(PresentationConnection, DOMEventTargetHelper) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwningConnectionList) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END - -NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(PresentationConnection, DOMEventTargetHelper) - tmp->Shutdown(); - NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwningConnectionList) -NS_IMPL_CYCLE_COLLECTION_UNLINK_END - -NS_IMPL_ADDREF_INHERITED(PresentationConnection, DOMEventTargetHelper) -NS_IMPL_RELEASE_INHERITED(PresentationConnection, DOMEventTargetHelper) - -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(PresentationConnection) - NS_INTERFACE_MAP_ENTRY(nsIPresentationSessionListener) - NS_INTERFACE_MAP_ENTRY(nsIRequest) -NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper) - -PresentationConnection::PresentationConnection(nsPIDOMWindowInner* aWindow, - const nsAString& aId, - const nsAString& aUrl, - const uint8_t aRole, - PresentationConnectionList* aList) - : DOMEventTargetHelper(aWindow) - , mId(aId) - , mUrl(aUrl) - , mState(PresentationConnectionState::Connecting) - , mOwningConnectionList(aList) - , mBinaryType(PresentationConnectionBinaryType::Arraybuffer) -{ - MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER || - aRole == nsIPresentationService::ROLE_RECEIVER); - mRole = aRole; -} - -/* virtual */ PresentationConnection::~PresentationConnection() -{ -} - -/* static */ already_AddRefed -PresentationConnection::Create(nsPIDOMWindowInner* aWindow, - const nsAString& aId, - const nsAString& aUrl, - const uint8_t aRole, - PresentationConnectionList* aList) -{ - MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER || - aRole == nsIPresentationService::ROLE_RECEIVER); - RefPtr connection = - new PresentationConnection(aWindow, aId, aUrl, aRole, aList); - if (NS_WARN_IF(!connection->Init())) { - return nullptr; - } - - if (aRole == nsIPresentationService::ROLE_CONTROLLER) { - ControllerConnectionCollection::GetSingleton()->AddConnection(connection, - aRole); - } - - return connection.forget(); -} - -bool -PresentationConnection::Init() -{ - if (NS_WARN_IF(mId.IsEmpty())) { - return false; - } - - nsCOMPtr service = - do_GetService(PRESENTATION_SERVICE_CONTRACTID); - if(NS_WARN_IF(!service)) { - return false; - } - - nsresult rv = service->RegisterSessionListener(mId, mRole, this); - if(NS_WARN_IF(NS_FAILED(rv))) { - return false; - } - - rv = AddIntoLoadGroup(); - if(NS_WARN_IF(NS_FAILED(rv))) { - return false; - } - - return true; -} - -void -PresentationConnection::Shutdown() -{ - PRES_DEBUG("connection shutdown:id[%s], role[%d]\n", - NS_ConvertUTF16toUTF8(mId).get(), mRole); - - nsCOMPtr service = - do_GetService(PRESENTATION_SERVICE_CONTRACTID); - if (NS_WARN_IF(!service)) { - return; - } - - DebugOnly rv = service->UnregisterSessionListener(mId, mRole); - NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "UnregisterSessionListener failed"); - - DebugOnly rv2 = RemoveFromLoadGroup(); - NS_WARNING_ASSERTION(NS_SUCCEEDED(rv2), "RemoveFromLoadGroup failed"); - - if (mRole == nsIPresentationService::ROLE_CONTROLLER) { - ControllerConnectionCollection::GetSingleton()->RemoveConnection(this, - mRole); - } -} - -/* virtual */ void -PresentationConnection::DisconnectFromOwner() -{ - Unused << NS_WARN_IF(NS_FAILED(ProcessConnectionWentAway())); - DOMEventTargetHelper::DisconnectFromOwner(); -} - -/* virtual */ JSObject* -PresentationConnection::WrapObject(JSContext* aCx, - JS::Handle aGivenProto) -{ - return PresentationConnectionBinding::Wrap(aCx, this, aGivenProto); -} - -void -PresentationConnection::GetId(nsAString& aId) const -{ - aId = mId; -} - -void -PresentationConnection::GetUrl(nsAString& aUrl) const -{ - aUrl = mUrl; -} - -PresentationConnectionState -PresentationConnection::State() const -{ - return mState; -} - -PresentationConnectionBinaryType -PresentationConnection::BinaryType() const -{ - return mBinaryType; -} - -void -PresentationConnection::SetBinaryType(PresentationConnectionBinaryType aType) -{ - mBinaryType = aType; -} - -void -PresentationConnection::Send(const nsAString& aData, - ErrorResult& aRv) -{ - // Sending is not allowed if the session is not connected. - if (NS_WARN_IF(mState != PresentationConnectionState::Connected)) { - aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); - return; - } - - nsCOMPtr service = - do_GetService(PRESENTATION_SERVICE_CONTRACTID); - if(NS_WARN_IF(!service)) { - AsyncCloseConnectionWithErrorMsg( - NS_LITERAL_STRING("Unable to send message due to an internal error.")); - return; - } - - nsresult rv = service->SendSessionMessage(mId, mRole, aData); - if(NS_WARN_IF(NS_FAILED(rv))) { - const uint32_t kMaxMessageLength = 256; - nsAutoString data(Substring(aData, 0, kMaxMessageLength)); - - AsyncCloseConnectionWithErrorMsg( - NS_LITERAL_STRING("Unable to send message: \"") + data + - NS_LITERAL_STRING("\"")); - } -} - -void -PresentationConnection::Send(Blob& aData, - ErrorResult& aRv) -{ - if (NS_WARN_IF(mState != PresentationConnectionState::Connected)) { - aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); - return; - } - - nsCOMPtr service = - do_GetService(PRESENTATION_SERVICE_CONTRACTID); - if(NS_WARN_IF(!service)) { - AsyncCloseConnectionWithErrorMsg( - NS_LITERAL_STRING("Unable to send message due to an internal error.")); - return; - } - - nsresult rv = service->SendSessionBlob(mId, mRole, &aData); - if(NS_WARN_IF(NS_FAILED(rv))) { - AsyncCloseConnectionWithErrorMsg( - NS_LITERAL_STRING("Unable to send binary message for Blob message.")); - } -} - -void -PresentationConnection::Send(const ArrayBuffer& aData, - ErrorResult& aRv) -{ - if (NS_WARN_IF(mState != PresentationConnectionState::Connected)) { - aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); - return; - } - - nsCOMPtr service = - do_GetService(PRESENTATION_SERVICE_CONTRACTID); - if(NS_WARN_IF(!service)) { - AsyncCloseConnectionWithErrorMsg( - NS_LITERAL_STRING("Unable to send message due to an internal error.")); - return; - } - - aData.ComputeLengthAndData(); - - static_assert(sizeof(*aData.Data()) == 1, "byte-sized data required"); - - uint32_t length = aData.Length(); - char* data = reinterpret_cast(aData.Data()); - nsDependentCSubstring msgString(data, length); - - nsresult rv = service->SendSessionBinaryMsg(mId, mRole, msgString); - if(NS_WARN_IF(NS_FAILED(rv))) { - AsyncCloseConnectionWithErrorMsg( - NS_LITERAL_STRING("Unable to send binary message for ArrayBuffer message.")); - } -} - -void -PresentationConnection::Send(const ArrayBufferView& aData, - ErrorResult& aRv) -{ - if (NS_WARN_IF(mState != PresentationConnectionState::Connected)) { - aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); - return; - } - - nsCOMPtr service = - do_GetService(PRESENTATION_SERVICE_CONTRACTID); - if(NS_WARN_IF(!service)) { - AsyncCloseConnectionWithErrorMsg( - NS_LITERAL_STRING("Unable to send message due to an internal error.")); - return; - } - - aData.ComputeLengthAndData(); - - static_assert(sizeof(*aData.Data()) == 1, "byte-sized data required"); - - uint32_t length = aData.Length(); - char* data = reinterpret_cast(aData.Data()); - nsDependentCSubstring msgString(data, length); - - nsresult rv = service->SendSessionBinaryMsg(mId, mRole, msgString); - if(NS_WARN_IF(NS_FAILED(rv))) { - AsyncCloseConnectionWithErrorMsg( - NS_LITERAL_STRING("Unable to send binary message for ArrayBufferView message.")); - } -} - -void -PresentationConnection::Close(ErrorResult& aRv) -{ - // It only works when the state is CONNECTED or CONNECTING. - if (NS_WARN_IF(mState != PresentationConnectionState::Connected && - mState != PresentationConnectionState::Connecting)) { - return; - } - - nsCOMPtr service = - do_GetService(PRESENTATION_SERVICE_CONTRACTID); - if(NS_WARN_IF(!service)) { - aRv.Throw(NS_ERROR_DOM_OPERATION_ERR); - return; - } - - Unused << NS_WARN_IF(NS_FAILED( - service->CloseSession(mId, - mRole, - nsIPresentationService::CLOSED_REASON_CLOSED))); -} - -void -PresentationConnection::Terminate(ErrorResult& aRv) -{ - // It only works when the state is CONNECTED. - if (NS_WARN_IF(mState != PresentationConnectionState::Connected)) { - return; - } - - nsCOMPtr service = - do_GetService(PRESENTATION_SERVICE_CONTRACTID); - if(NS_WARN_IF(!service)) { - aRv.Throw(NS_ERROR_DOM_OPERATION_ERR); - return; - } - - Unused << NS_WARN_IF(NS_FAILED(service->TerminateSession(mId, mRole))); -} - -bool -PresentationConnection::Equals(uint64_t aWindowId, - const nsAString& aId) -{ - return GetOwner() && - aWindowId == GetOwner()->WindowID() && - mId.Equals(aId); -} - -NS_IMETHODIMP -PresentationConnection::NotifyStateChange(const nsAString& aSessionId, - uint16_t aState, - nsresult aReason) -{ - PRES_DEBUG("connection state change:id[%s], state[%x], reason[%x], role[%d]\n", - NS_ConvertUTF16toUTF8(aSessionId).get(), aState, - aReason, mRole); - - if (!aSessionId.Equals(mId)) { - return NS_ERROR_INVALID_ARG; - } - - // A terminated connection should always remain in terminated. - if (mState == PresentationConnectionState::Terminated) { - return NS_OK; - } - - PresentationConnectionState state; - switch (aState) { - case nsIPresentationSessionListener::STATE_CONNECTING: - state = PresentationConnectionState::Connecting; - break; - case nsIPresentationSessionListener::STATE_CONNECTED: - state = PresentationConnectionState::Connected; - break; - case nsIPresentationSessionListener::STATE_CLOSED: - state = PresentationConnectionState::Closed; - break; - case nsIPresentationSessionListener::STATE_TERMINATED: - state = PresentationConnectionState::Terminated; - break; - default: - NS_WARNING("Unknown presentation session state."); - return NS_ERROR_INVALID_ARG; - } - - if (mState == state) { - return NS_OK; - } - mState = state; - - nsresult rv = ProcessStateChanged(aReason); - if(NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - if (mOwningConnectionList) { - mOwningConnectionList->NotifyStateChange(aSessionId, this); - } - - return NS_OK; -} - -nsresult -PresentationConnection::ProcessStateChanged(nsresult aReason) -{ - switch (mState) { - case PresentationConnectionState::Connecting: - return NS_OK; - case PresentationConnectionState::Connected: { - RefPtr asyncDispatcher = - new AsyncEventDispatcher(this, NS_LITERAL_STRING("connect"), false); - return asyncDispatcher->PostDOMEvent(); - } - case PresentationConnectionState::Closed: { - PresentationConnectionClosedReason reason = - PresentationConnectionClosedReason::Closed; - - nsString errorMsg; - if (NS_FAILED(aReason)) { - reason = PresentationConnectionClosedReason::Error; - nsCString name, message; - - // If aReason is not a DOM error, use error name as message. - if (NS_FAILED(NS_GetNameAndMessageForDOMNSResult(aReason, - name, - message))) { - mozilla::GetErrorName(aReason, message); - message.InsertLiteral("Internal error: ", 0); - } - CopyUTF8toUTF16(message, errorMsg); - } - - Unused << - NS_WARN_IF(NS_FAILED(DispatchConnectionCloseEvent(reason, errorMsg))); - - return RemoveFromLoadGroup(); - } - case PresentationConnectionState::Terminated: { - // Ensure onterminate event is fired. - RefPtr asyncDispatcher = - new AsyncEventDispatcher(this, NS_LITERAL_STRING("terminate"), false); - Unused << NS_WARN_IF(NS_FAILED(asyncDispatcher->PostDOMEvent())); - - nsCOMPtr service = - do_GetService(PRESENTATION_SERVICE_CONTRACTID); - if (NS_WARN_IF(!service)) { - return NS_ERROR_NOT_AVAILABLE; - } - - nsresult rv = service->UnregisterSessionListener(mId, mRole); - if(NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - return RemoveFromLoadGroup(); - } - default: - MOZ_CRASH("Unknown presentation session state."); - return NS_ERROR_INVALID_ARG; - } -} - -NS_IMETHODIMP -PresentationConnection::NotifyMessage(const nsAString& aSessionId, - const nsACString& aData, - bool aIsBinary) -{ - PRES_DEBUG("connection %s:id[%s], data[%s], role[%d]\n", __func__, - NS_ConvertUTF16toUTF8(aSessionId).get(), - nsPromiseFlatCString(aData).get(), mRole); - - if (!aSessionId.Equals(mId)) { - return NS_ERROR_INVALID_ARG; - } - - // No message should be expected when the session is not connected. - if (NS_WARN_IF(mState != PresentationConnectionState::Connected)) { - return NS_ERROR_DOM_INVALID_STATE_ERR; - } - - if (NS_WARN_IF(NS_FAILED(DoReceiveMessage(aData, aIsBinary)))) { - AsyncCloseConnectionWithErrorMsg( - NS_LITERAL_STRING("Unable to receive a message.")); - return NS_ERROR_FAILURE; - } - - return NS_OK; -} - -nsresult -PresentationConnection::DoReceiveMessage(const nsACString& aData, bool aIsBinary) -{ - // Transform the data. - AutoJSAPI jsapi; - if (!jsapi.Init(GetOwner())) { - return NS_ERROR_FAILURE; - } - JSContext* cx = jsapi.cx(); - JS::Rooted jsData(cx); - - nsresult rv; - if (aIsBinary) { - if (mBinaryType == PresentationConnectionBinaryType::Blob) { - RefPtr blob = - Blob::CreateStringBlob(GetOwner(), aData, EmptyString()); - MOZ_ASSERT(blob); - - if (!ToJSValue(cx, blob, &jsData)) { - return NS_ERROR_FAILURE; - } - } else if (mBinaryType == PresentationConnectionBinaryType::Arraybuffer) { - JS::Rooted arrayBuf(cx); - rv = nsContentUtils::CreateArrayBuffer(cx, aData, arrayBuf.address()); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - jsData.setObject(*arrayBuf); - } else { - NS_RUNTIMEABORT("Unknown binary type!"); - return NS_ERROR_UNEXPECTED; - } - } else { - NS_ConvertUTF8toUTF16 utf16Data(aData); - if(NS_WARN_IF(!ToJSValue(cx, utf16Data, &jsData))) { - return NS_ERROR_FAILURE; - } - } - - return DispatchMessageEvent(jsData); -} - -nsresult -PresentationConnection::DispatchConnectionCloseEvent( - PresentationConnectionClosedReason aReason, - const nsAString& aMessage, - bool aDispatchNow) -{ - if (mState != PresentationConnectionState::Closed) { - MOZ_ASSERT(false, "The connection state should be closed."); - return NS_ERROR_FAILURE; - } - - PresentationConnectionCloseEventInit init; - init.mReason = aReason; - init.mMessage = aMessage; - - RefPtr closedEvent = - PresentationConnectionCloseEvent::Constructor(this, - NS_LITERAL_STRING("close"), - init); - closedEvent->SetTrusted(true); - - if (aDispatchNow) { - bool ignore; - return DOMEventTargetHelper::DispatchEvent(closedEvent, &ignore); - } - - RefPtr asyncDispatcher = - new AsyncEventDispatcher(this, static_cast(closedEvent)); - return asyncDispatcher->PostDOMEvent(); -} - -nsresult -PresentationConnection::DispatchMessageEvent(JS::Handle aData) -{ - nsCOMPtr global = do_QueryInterface(GetOwner()); - if (NS_WARN_IF(!global)) { - return NS_ERROR_NOT_AVAILABLE; - } - - // Get the origin. - nsAutoString origin; - nsresult rv = nsContentUtils::GetUTFOrigin(global->PrincipalOrNull(), origin); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - RefPtr messageEvent = new MessageEvent(this, nullptr, nullptr); - - messageEvent->InitMessageEvent(nullptr, - NS_LITERAL_STRING("message"), - false, false, aData, origin, - EmptyString(), nullptr, - Sequence>()); - messageEvent->SetTrusted(true); - - RefPtr asyncDispatcher = - new AsyncEventDispatcher(this, static_cast(messageEvent)); - return asyncDispatcher->PostDOMEvent(); -} - -nsresult -PresentationConnection::ProcessConnectionWentAway() -{ - if (mState != PresentationConnectionState::Connected && - mState != PresentationConnectionState::Connecting) { - // If the state is not connected or connecting, do not need to - // close the session. - return NS_OK; - } - - mState = PresentationConnectionState::Terminated; - - nsCOMPtr service = - do_GetService(PRESENTATION_SERVICE_CONTRACTID); - if (NS_WARN_IF(!service)) { - return NS_ERROR_NOT_AVAILABLE; - } - - return service->CloseSession( - mId, mRole, nsIPresentationService::CLOSED_REASON_WENTAWAY); -} - -NS_IMETHODIMP -PresentationConnection::GetName(nsACString &aResult) -{ - aResult.AssignLiteral("about:presentation-connection"); - return NS_OK; -} - -NS_IMETHODIMP -PresentationConnection::IsPending(bool* aRetval) -{ - *aRetval = true; - return NS_OK; -} - -NS_IMETHODIMP -PresentationConnection::GetStatus(nsresult* aStatus) -{ - *aStatus = NS_OK; - return NS_OK; -} - -NS_IMETHODIMP -PresentationConnection::Cancel(nsresult aStatus) -{ - nsCOMPtr event = - NewRunnableMethod(this, &PresentationConnection::ProcessConnectionWentAway); - return NS_DispatchToCurrentThread(event); -} -NS_IMETHODIMP -PresentationConnection::Suspend(void) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} -NS_IMETHODIMP -PresentationConnection::Resume(void) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -PresentationConnection::GetLoadGroup(nsILoadGroup** aLoadGroup) -{ - *aLoadGroup = nullptr; - - nsCOMPtr doc = GetOwner() ? GetOwner()->GetExtantDoc() : nullptr; - if (!doc) { - return NS_ERROR_FAILURE; - } - - *aLoadGroup = doc->GetDocumentLoadGroup().take(); - return NS_OK; -} - -NS_IMETHODIMP -PresentationConnection::SetLoadGroup(nsILoadGroup * aLoadGroup) -{ - return NS_ERROR_UNEXPECTED; -} - -NS_IMETHODIMP -PresentationConnection::GetLoadFlags(nsLoadFlags* aLoadFlags) -{ - *aLoadFlags = nsIRequest::LOAD_BACKGROUND; - return NS_OK; -} - -NS_IMETHODIMP -PresentationConnection::SetLoadFlags(nsLoadFlags aLoadFlags) -{ - return NS_OK; -} - -nsresult -PresentationConnection::AddIntoLoadGroup() -{ - // Avoid adding to loadgroup multiple times - if (mWeakLoadGroup) { - return NS_OK; - } - - nsCOMPtr loadGroup; - nsresult rv = GetLoadGroup(getter_AddRefs(loadGroup)); - if(NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - rv = loadGroup->AddRequest(this, nullptr); - if(NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - mWeakLoadGroup = do_GetWeakReference(loadGroup); - return NS_OK; -} - -nsresult -PresentationConnection::RemoveFromLoadGroup() -{ - if (!mWeakLoadGroup) { - return NS_OK; - } - - nsCOMPtr loadGroup = do_QueryReferent(mWeakLoadGroup); - if (loadGroup) { - mWeakLoadGroup = nullptr; - return loadGroup->RemoveRequest(this, nullptr, NS_OK); - } - - return NS_OK; -} - -void -PresentationConnection::AsyncCloseConnectionWithErrorMsg(const nsAString& aMessage) -{ - if (mState == PresentationConnectionState::Terminated) { - return; - } - - nsString message = nsString(aMessage); - RefPtr self = this; - nsCOMPtr r = - NS_NewRunnableFunction([self, message]() -> void { - // Set |mState| to |PresentationConnectionState::Closed| here to avoid - // calling |ProcessStateChanged|. - self->mState = PresentationConnectionState::Closed; - - // Make sure dispatching the event and closing the connection are invoked - // at the same time by setting |aDispatchNow| to true. - Unused << NS_WARN_IF(NS_FAILED( - self->DispatchConnectionCloseEvent(PresentationConnectionClosedReason::Error, - message, - true))); - - nsCOMPtr service = - do_GetService(PRESENTATION_SERVICE_CONTRACTID); - if(NS_WARN_IF(!service)) { - return; - } - - Unused << NS_WARN_IF(NS_FAILED( - service->CloseSession(self->mId, - self->mRole, - nsIPresentationService::CLOSED_REASON_ERROR))); - }); - - Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(r))); -} diff --git a/dom/presentation/PresentationConnection.h b/dom/presentation/PresentationConnection.h deleted file mode 100644 index cecf6c3462..0000000000 --- a/dom/presentation/PresentationConnection.h +++ /dev/null @@ -1,128 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_dom_PresentationConnection_h -#define mozilla_dom_PresentationConnection_h - -#include "mozilla/DOMEventTargetHelper.h" -#include "mozilla/dom/TypedArray.h" -#include "mozilla/WeakPtr.h" -#include "mozilla/dom/PresentationConnectionBinding.h" -#include "mozilla/dom/PresentationConnectionCloseEventBinding.h" -#include "nsIPresentationListener.h" -#include "nsIRequest.h" -#include "nsWeakReference.h" - -namespace mozilla { -namespace dom { - -class Blob; -class PresentationConnectionList; - -class PresentationConnection final : public DOMEventTargetHelper - , public nsIPresentationSessionListener - , public nsIRequest - , public SupportsWeakPtr -{ -public: - NS_DECL_ISUPPORTS_INHERITED - NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(PresentationConnection, - DOMEventTargetHelper) - NS_DECL_NSIPRESENTATIONSESSIONLISTENER - NS_DECL_NSIREQUEST - MOZ_DECLARE_WEAKREFERENCE_TYPENAME(PresentationConnection) - - static already_AddRefed - Create(nsPIDOMWindowInner* aWindow, - const nsAString& aId, - const nsAString& aUrl, - const uint8_t aRole, - PresentationConnectionList* aList = nullptr); - - virtual void DisconnectFromOwner() override; - - virtual JSObject* WrapObject(JSContext* aCx, - JS::Handle aGivenProto) override; - - // WebIDL (public APIs) - void GetId(nsAString& aId) const; - - void GetUrl(nsAString& aUrl) const; - - PresentationConnectionState State() const; - - PresentationConnectionBinaryType BinaryType() const; - - void SetBinaryType(PresentationConnectionBinaryType aType); - - void Send(const nsAString& aData, - ErrorResult& aRv); - - void Send(Blob& aData, - ErrorResult& aRv); - - void Send(const ArrayBuffer& aData, - ErrorResult& aRv); - - void Send(const ArrayBufferView& aData, - ErrorResult& aRv); - - void Close(ErrorResult& aRv); - - void Terminate(ErrorResult& aRv); - - bool - Equals(uint64_t aWindowId, const nsAString& aId); - - IMPL_EVENT_HANDLER(connect); - IMPL_EVENT_HANDLER(close); - IMPL_EVENT_HANDLER(terminate); - IMPL_EVENT_HANDLER(message); - -private: - PresentationConnection(nsPIDOMWindowInner* aWindow, - const nsAString& aId, - const nsAString& aUrl, - const uint8_t aRole, - PresentationConnectionList* aList); - - ~PresentationConnection(); - - bool Init(); - - void Shutdown(); - - nsresult ProcessStateChanged(nsresult aReason); - - nsresult DispatchConnectionCloseEvent(PresentationConnectionClosedReason aReason, - const nsAString& aMessage, - bool aDispatchNow = false); - - nsresult DispatchMessageEvent(JS::Handle aData); - - nsresult ProcessConnectionWentAway(); - - nsresult AddIntoLoadGroup(); - - nsresult RemoveFromLoadGroup(); - - void AsyncCloseConnectionWithErrorMsg(const nsAString& aMessage); - - nsresult DoReceiveMessage(const nsACString& aData, bool aIsBinary); - - nsString mId; - nsString mUrl; - uint8_t mRole; - PresentationConnectionState mState; - RefPtr mOwningConnectionList; - nsWeakPtr mWeakLoadGroup; - PresentationConnectionBinaryType mBinaryType; -}; - -} // namespace dom -} // namespace mozilla - -#endif // mozilla_dom_PresentationConnection_h diff --git a/dom/presentation/PresentationConnectionList.cpp b/dom/presentation/PresentationConnectionList.cpp deleted file mode 100644 index 0e0e7696cb..0000000000 --- a/dom/presentation/PresentationConnectionList.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* 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 "PresentationConnectionList.h" - -#include "mozilla/AsyncEventDispatcher.h" -#include "mozilla/dom/PresentationConnectionAvailableEvent.h" -#include "mozilla/dom/PresentationConnectionListBinding.h" -#include "mozilla/dom/Promise.h" -#include "PresentationConnection.h" - -namespace mozilla { -namespace dom { - -NS_IMPL_CYCLE_COLLECTION_INHERITED(PresentationConnectionList, DOMEventTargetHelper, - mGetConnectionListPromise, - mConnections) - -NS_IMPL_ADDREF_INHERITED(PresentationConnectionList, DOMEventTargetHelper) -NS_IMPL_RELEASE_INHERITED(PresentationConnectionList, DOMEventTargetHelper) - -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(PresentationConnectionList) -NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper) - -PresentationConnectionList::PresentationConnectionList(nsPIDOMWindowInner* aWindow, - Promise* aPromise) - : DOMEventTargetHelper(aWindow) - , mGetConnectionListPromise(aPromise) -{ - MOZ_ASSERT(aWindow); - MOZ_ASSERT(aPromise); -} - -/* virtual */ JSObject* -PresentationConnectionList::WrapObject(JSContext* aCx, - JS::Handle aGivenProto) -{ - return PresentationConnectionListBinding::Wrap(aCx, this, aGivenProto); -} - -void -PresentationConnectionList::GetConnections( - nsTArray>& aConnections) const -{ - aConnections = mConnections; -} - -nsresult -PresentationConnectionList::DispatchConnectionAvailableEvent( - PresentationConnection* aConnection) -{ - PresentationConnectionAvailableEventInit init; - init.mConnection = aConnection; - - RefPtr event = - PresentationConnectionAvailableEvent::Constructor( - this, - NS_LITERAL_STRING("connectionavailable"), - init); - - if (NS_WARN_IF(!event)) { - return NS_ERROR_FAILURE; - } - event->SetTrusted(true); - - RefPtr asyncDispatcher = - new AsyncEventDispatcher(this, event); - return asyncDispatcher->PostDOMEvent(); -} - -PresentationConnectionList::ConnectionArrayIndex -PresentationConnectionList::FindConnectionById( - const nsAString& aId) -{ - for (ConnectionArrayIndex i = 0; i < mConnections.Length(); i++) { - nsAutoString id; - mConnections[i]->GetId(id); - if (id == nsAutoString(aId)) { - return i; - } - } - - return mConnections.NoIndex; -} - -void -PresentationConnectionList::NotifyStateChange(const nsAString& aSessionId, - PresentationConnection* aConnection) -{ - if (!aConnection) { - MOZ_ASSERT(false, "PresentationConnection can not be null."); - return; - } - - bool connectionFound = - FindConnectionById(aSessionId) != mConnections.NoIndex ? true : false; - - PresentationConnectionListBinding::ClearCachedConnectionsValue(this); - switch (aConnection->State()) { - case PresentationConnectionState::Connected: - if (!connectionFound) { - mConnections.AppendElement(aConnection); - if (mGetConnectionListPromise) { - mGetConnectionListPromise->MaybeResolve(this); - mGetConnectionListPromise = nullptr; - return; - } - } - DispatchConnectionAvailableEvent(aConnection); - break; - case PresentationConnectionState::Terminated: - if (connectionFound) { - mConnections.RemoveElement(aConnection); - } - break; - default: - break; - } -} - -} // namespace dom -} // namespace mozilla diff --git a/dom/presentation/PresentationConnectionList.h b/dom/presentation/PresentationConnectionList.h deleted file mode 100644 index b430219ce7..0000000000 --- a/dom/presentation/PresentationConnectionList.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_dom_PresentationConnectionList_h -#define mozilla_dom_PresentationConnectionList_h - -#include "mozilla/DOMEventTargetHelper.h" -#include "nsTArray.h" - -namespace mozilla { -namespace dom { - -class PresentationConnection; -class Promise; - -class PresentationConnectionList final : public DOMEventTargetHelper -{ -public: - NS_DECL_ISUPPORTS_INHERITED - NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(PresentationConnectionList, - DOMEventTargetHelper) - - PresentationConnectionList(nsPIDOMWindowInner* aWindow, - Promise* aPromise); - - virtual JSObject* WrapObject(JSContext* aCx, - JS::Handle aGivenProto) override; - - void GetConnections(nsTArray>& aConnections) const; - - void NotifyStateChange(const nsAString& aSessionId, PresentationConnection* aConnection); - - IMPL_EVENT_HANDLER(connectionavailable); - -private: - virtual ~PresentationConnectionList() = default; - - nsresult DispatchConnectionAvailableEvent(PresentationConnection* aConnection); - - typedef nsTArray> ConnectionArray; - typedef ConnectionArray::index_type ConnectionArrayIndex; - - ConnectionArrayIndex FindConnectionById(const nsAString& aId); - - RefPtr mGetConnectionListPromise; - - // This array stores only non-terminsted connections. - ConnectionArray mConnections; -}; - -} // namespace dom -} // namespace mozilla - -#endif // mozilla_dom_PresentationConnectionList_h diff --git a/dom/presentation/PresentationDataChannelSessionTransport.js b/dom/presentation/PresentationDataChannelSessionTransport.js deleted file mode 100644 index 9af6213cb0..0000000000 --- a/dom/presentation/PresentationDataChannelSessionTransport.js +++ /dev/null @@ -1,378 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this file, -* You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); - -// Bug 1228209 - plan to remove this eventually -function log(aMsg) { - //dump("-*- PresentationDataChannelSessionTransport.js : " + aMsg + "\n"); -} - -const PRESENTATIONTRANSPORT_CID = Components.ID("{dd2bbf2f-3399-4389-8f5f-d382afb8b2d6}"); -const PRESENTATIONTRANSPORT_CONTRACTID = "mozilla.org/presentation/datachanneltransport;1"; - -const PRESENTATIONTRANSPORTBUILDER_CID = Components.ID("{215b2f62-46e2-4004-a3d1-6858e56c20f3}"); -const PRESENTATIONTRANSPORTBUILDER_CONTRACTID = "mozilla.org/presentation/datachanneltransportbuilder;1"; - -function PresentationDataChannelDescription(aDataChannelSDP) { - this._dataChannelSDP = JSON.stringify(aDataChannelSDP); -} - -PresentationDataChannelDescription.prototype = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationChannelDescription]), - get type() { - return Ci.nsIPresentationChannelDescription.TYPE_DATACHANNEL; - }, - get tcpAddress() { - return null; - }, - get tcpPort() { - return null; - }, - get dataChannelSDP() { - return this._dataChannelSDP; - } -}; - -function PresentationTransportBuilder() { - log("PresentationTransportBuilder construct"); - this._isControlChannelNeeded = true; -} - -PresentationTransportBuilder.prototype = { - classID: PRESENTATIONTRANSPORTBUILDER_CID, - contractID: PRESENTATIONTRANSPORTBUILDER_CONTRACTID, - QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationSessionTransportBuilder, - Ci.nsIPresentationDataChannelSessionTransportBuilder, - Ci.nsITimerCallback]), - - buildDataChannelTransport: function(aRole, aWindow, aListener) { - if (!aRole || !aWindow || !aListener) { - log("buildDataChannelTransport with illegal parameters"); - throw Cr.NS_ERROR_ILLEGAL_VALUE; - } - - if (this._window) { - log("buildDataChannelTransport has started."); - throw Cr.NS_ERROR_UNEXPECTED; - } - - log("buildDataChannelTransport with role " + aRole); - this._role = aRole; - this._window = aWindow; - this._listener = aListener.QueryInterface(Ci.nsIPresentationSessionTransportBuilderListener); - - // TODO bug 1227053 set iceServers from |nsIPresentationDevice| - this._peerConnection = new this._window.RTCPeerConnection(); - - // |this._listener == null| will throw since the control channel is - // abnormally closed. - this._peerConnection.onicecandidate = aEvent => aEvent.candidate && - this._listener.sendIceCandidate(JSON.stringify(aEvent.candidate)); - - this._peerConnection.onnegotiationneeded = () => { - log("onnegotiationneeded with role " + this._role); - if (!this._peerConnection) { - log("ignoring negotiationneeded without PeerConnection"); - return; - } - this._peerConnection.createOffer() - .then(aOffer => this._peerConnection.setLocalDescription(aOffer)) - .then(() => this._listener - .sendOffer(new PresentationDataChannelDescription(this._peerConnection.localDescription))) - .catch(e => this._reportError(e)); - } - - switch (this._role) { - case Ci.nsIPresentationService.ROLE_CONTROLLER: - this._dataChannel = this._peerConnection.createDataChannel("presentationAPI"); - this._setDataChannel(); - break; - - case Ci.nsIPresentationService.ROLE_RECEIVER: - this._peerConnection.ondatachannel = aEvent => { - this._dataChannel = aEvent.channel; - // Ensure the binaryType of dataChannel is blob. - this._dataChannel.binaryType = "blob"; - this._setDataChannel(); - } - break; - default: - throw Cr.NS_ERROR_ILLEGAL_VALUE; - } - - // TODO bug 1228235 we should have a way to let device providers customize - // the time-out duration. - let timeout = Services.prefs.getIntPref("presentation.receiver.loading.timeout", 10000); - - // The timer is to check if the negotiation finishes on time. - this._timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - this._timer.initWithCallback(this, timeout, this._timer.TYPE_ONE_SHOT); - }, - - notify: function() { - if (!this._sessionTransport) { - this._cleanup(Cr.NS_ERROR_NET_TIMEOUT); - } - }, - - _reportError: function(aError) { - log("report Error " + aError.name + ":" + aError.message); - this._cleanup(Cr.NS_ERROR_FAILURE); - }, - - _setDataChannel: function() { - this._dataChannel.onopen = () => { - log("data channel is open, notify the listener, role " + this._role); - - // Handoff the ownership of _peerConnection and _dataChannel to - // _sessionTransport - this._sessionTransport = new PresentationTransport(); - this._sessionTransport.init(this._peerConnection, this._dataChannel, this._window); - this._peerConnection.onicecandidate = null; - this._peerConnection.onnegotiationneeded = null; - this._peerConnection = this._dataChannel = null; - - this._listener.onSessionTransport(this._sessionTransport); - this._sessionTransport.callback.notifyTransportReady(); - - this._cleanup(Cr.NS_OK); - }; - - this._dataChannel.onerror = aError => { - log("data channel onerror " + aError.name + ":" + aError.message); - this._cleanup(Cr.NS_ERROR_FAILURE); - } - }, - - _cleanup: function(aReason) { - if (aReason != Cr.NS_OK) { - this._listener.onError(aReason); - } - - if (this._dataChannel) { - this._dataChannel.close(); - this._dataChannel = null; - } - - if (this._peerConnection) { - this._peerConnection.close(); - this._peerConnection = null; - } - - this._role = null; - this._window = null; - - this._listener = null; - this._sessionTransport = null; - - if (this._timer) { - this._timer.cancel(); - this._timer = null; - } - }, - - // nsIPresentationControlChannelListener - onOffer: function(aOffer) { - if (this._role !== Ci.nsIPresentationService.ROLE_RECEIVER || - this._sessionTransport) { - log("onOffer status error"); - this._cleanup(Cr.NS_ERROR_FAILURE); - } - - log("onOffer: " + aOffer.dataChannelSDP + " with role " + this._role); - - let offer = new this._window - .RTCSessionDescription(JSON.parse(aOffer.dataChannelSDP)); - - this._peerConnection.setRemoteDescription(offer) - .then(() => this._peerConnection.signalingState == "stable" || - this._peerConnection.createAnswer()) - .then(aAnswer => this._peerConnection.setLocalDescription(aAnswer)) - .then(() => { - this._isControlChannelNeeded = false; - this._listener - .sendAnswer(new PresentationDataChannelDescription(this._peerConnection.localDescription)) - }).catch(e => this._reportError(e)); - }, - - onAnswer: function(aAnswer) { - if (this._role !== Ci.nsIPresentationService.ROLE_CONTROLLER || - this._sessionTransport) { - log("onAnswer status error"); - this._cleanup(Cr.NS_ERROR_FAILURE); - } - - log("onAnswer: " + aAnswer.dataChannelSDP + " with role " + this._role); - - let answer = new this._window - .RTCSessionDescription(JSON.parse(aAnswer.dataChannelSDP)); - - this._peerConnection.setRemoteDescription(answer).catch(e => this._reportError(e)); - this._isControlChannelNeeded = false; - }, - - onIceCandidate: function(aCandidate) { - log("onIceCandidate: " + aCandidate + " with role " + this._role); - if (!this._window || !this._peerConnection) { - log("ignoring ICE candidate after connection"); - return; - } - let candidate = new this._window.RTCIceCandidate(JSON.parse(aCandidate)); - this._peerConnection.addIceCandidate(candidate).catch(e => this._reportError(e)); - }, - - notifyDisconnected: function(aReason) { - log("notifyDisconnected reason: " + aReason); - - if (aReason != Cr.NS_OK) { - this._cleanup(aReason); - } else if (this._isControlChannelNeeded) { - this._cleanup(Cr.NS_ERROR_FAILURE); - } - }, -}; - -function PresentationTransport() { - this._messageQueue = []; - this._closeReason = Cr.NS_OK; -} - -PresentationTransport.prototype = { - classID: PRESENTATIONTRANSPORT_CID, - contractID: PRESENTATIONTRANSPORT_CONTRACTID, - QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationSessionTransport]), - - init: function(aPeerConnection, aDataChannel, aWindow) { - log("initWithDataChannel"); - this._enableDataNotification = false; - this._dataChannel = aDataChannel; - this._peerConnection = aPeerConnection; - this._window = aWindow; - - this._dataChannel.onopen = () => { - log("data channel reopen. Should never touch here"); - }; - - this._dataChannel.onclose = () => { - log("data channel onclose"); - if (this._callback) { - this._callback.notifyTransportClosed(this._closeReason); - } - this._cleanup(); - } - - this._dataChannel.onmessage = aEvent => { - log("data channel onmessage " + aEvent.data); - - if (!this._enableDataNotification || !this._callback) { - log("queue message"); - this._messageQueue.push(aEvent.data); - return; - } - this._doNotifyData(aEvent.data); - }; - - this._dataChannel.onerror = aError => { - log("data channel onerror " + aError.name + ":" + aError.message); - if (this._callback) { - this._callback.notifyTransportClosed(Cr.NS_ERROR_FAILURE); - } - this._cleanup(); - } - }, - - // nsIPresentationTransport - get selfAddress() { - throw NS_ERROR_NOT_AVAILABLE; - }, - - get callback() { - return this._callback; - }, - - set callback(aCallback) { - this._callback = aCallback; - }, - - send: function(aData) { - log("send " + aData); - this._dataChannel.send(aData); - }, - - sendBinaryMsg: function(aData) { - log("sendBinaryMsg"); - - let array = new Uint8Array(aData.length); - for (let i = 0; i < aData.length; i++) { - array[i] = aData.charCodeAt(i); - } - - this._dataChannel.send(array); - }, - - sendBlob: function(aBlob) { - log("sendBlob"); - - this._dataChannel.send(aBlob); - }, - - enableDataNotification: function() { - log("enableDataNotification"); - if (this._enableDataNotification) { - return; - } - - if (!this._callback) { - throw NS_ERROR_NOT_AVAILABLE; - } - - this._enableDataNotification = true; - - this._messageQueue.forEach(aData => this._doNotifyData(aData)); - this._messageQueue = []; - }, - - close: function(aReason) { - this._closeReason = aReason; - - this._dataChannel.close(); - }, - - _cleanup: function() { - this._dataChannel = null; - - if (this._peerConnection) { - this._peerConnection.close(); - this._peerConnection = null; - } - this._callback = null; - this._messageQueue = []; - this._window = null; - }, - - _doNotifyData: function(aData) { - if (!this._callback) { - throw NS_ERROR_NOT_AVAILABLE; - } - - if (aData instanceof this._window.Blob) { - let reader = new this._window.FileReader(); - reader.addEventListener("load", (aEvent) => { - this._callback.notifyData(aEvent.target.result, true); - }); - reader.readAsBinaryString(aData); - } else { - this._callback.notifyData(aData, false); - } - }, -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PresentationTransportBuilder, - PresentationTransport]); diff --git a/dom/presentation/PresentationDataChannelSessionTransport.manifest b/dom/presentation/PresentationDataChannelSessionTransport.manifest deleted file mode 100644 index 6838f675fa..0000000000 --- a/dom/presentation/PresentationDataChannelSessionTransport.manifest +++ /dev/null @@ -1,6 +0,0 @@ -# PresentationDataChannelSessionTransport.js -component {dd2bbf2f-3399-4389-8f5f-d382afb8b2d6} PresentationDataChannelSessionTransport.js -contract @mozilla.org/presentation/datachanneltransport;1 {dd2bbf2f-3399-4389-8f5f-d382afb8b2d6} - -component {215b2f62-46e2-4004-a3d1-6858e56c20f3} PresentationDataChannelSessionTransport.js -contract @mozilla.org/presentation/datachanneltransportbuilder;1 {215b2f62-46e2-4004-a3d1-6858e56c20f3} diff --git a/dom/presentation/PresentationDeviceInfoManager.js b/dom/presentation/PresentationDeviceInfoManager.js deleted file mode 100644 index 29e7d370ce..0000000000 --- a/dom/presentation/PresentationDeviceInfoManager.js +++ /dev/null @@ -1,119 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this file, -* You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu} = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/DOMRequestHelper.jsm"); - -function log(aMsg) { - //dump("-*- PresentationDeviceInfoManager.js : " + aMsg + "\n"); -} - -const PRESENTATIONDEVICEINFOMANAGER_CID = Components.ID("{1bd66bef-f643-4be3-b690-0c656353eafd}"); -const PRESENTATIONDEVICEINFOMANAGER_CONTRACTID = "@mozilla.org/presentation-device/deviceInfo;1"; - -XPCOMUtils.defineLazyServiceGetter(this, "cpmm", - "@mozilla.org/childprocessmessagemanager;1", - "nsIMessageSender"); - -function PresentationDeviceInfoManager() {} - -PresentationDeviceInfoManager.prototype = { - __proto__: DOMRequestIpcHelper.prototype, - - classID: PRESENTATIONDEVICEINFOMANAGER_CID, - contractID: PRESENTATIONDEVICEINFOMANAGER_CONTRACTID, - QueryInterface: XPCOMUtils.generateQI([Ci.nsISupportsWeakReference, - Ci.nsIObserver, - Ci.nsIDOMGlobalPropertyInitializer]), - - receiveMessage: function(aMsg) { - if (!aMsg || !aMsg.data) { - return; - } - - let data = aMsg.data; - - log("receive aMsg: " + aMsg.name); - switch (aMsg.name) { - case "PresentationDeviceInfoManager:OnDeviceChange": { - let detail = { - detail: { - type: data.type, - deviceInfo: data.deviceInfo, - } - }; - let event = new this._window.CustomEvent("devicechange", Cu.cloneInto(detail, this._window)); - this.__DOM_IMPL__.dispatchEvent(event); - break; - } - case "PresentationDeviceInfoManager:GetAll:Result:Ok": { - let resolver = this.takePromiseResolver(data.requestId); - - if (!resolver) { - return; - } - - resolver.resolve(Cu.cloneInto(data.devices, this._window)); - break; - } - case "PresentationDeviceInfoManager:GetAll:Result:Error": { - let resolver = this.takePromiseResolver(data.requestId); - - if (!resolver) { - return; - } - - resolver.reject(data.error); - break; - } - } - }, - - init: function(aWin) { - log("init"); - this.initDOMRequestHelper(aWin, [ - {name: "PresentationDeviceInfoManager:OnDeviceChange", weakRef: true}, - {name: "PresentationDeviceInfoManager:GetAll:Result:Ok", weakRef: true}, - {name: "PresentationDeviceInfoManager:GetAll:Result:Error", weakRef: true}, - ]); - }, - - uninit: function() { - log("uninit"); - let self = this; - - this.forEachPromiseResolver(function(aKey) { - self.takePromiseResolver(aKey).reject("PresentationDeviceInfoManager got destroyed"); - }); - }, - - get ondevicechange() { - return this.__DOM_IMPL__.getEventHandler("ondevicechange"); - }, - - set ondevicechange(aHandler) { - this.__DOM_IMPL__.setEventHandler("ondevicechange", aHandler); - }, - - getAll: function() { - log("getAll"); - let self = this; - return this.createPromiseWithId(function(aResolverId) { - cpmm.sendAsyncMessage("PresentationDeviceInfoManager:GetAll", { - requestId: aResolverId, - }); - }); - }, - - forceDiscovery: function() { - cpmm.sendAsyncMessage("PresentationDeviceInfoManager:ForceDiscovery"); - }, -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PresentationDeviceInfoManager]); diff --git a/dom/presentation/PresentationDeviceInfoManager.jsm b/dom/presentation/PresentationDeviceInfoManager.jsm deleted file mode 100644 index 205982b9c0..0000000000 --- a/dom/presentation/PresentationDeviceInfoManager.jsm +++ /dev/null @@ -1,104 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- / -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu} = Components; - -this.EXPORTED_SYMBOLS = ["PresentationDeviceInfoService"]; - -function log(aMsg) { - //dump("PresentationDeviceInfoManager.jsm: " + aMsg + "\n"); -} - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); - -XPCOMUtils.defineLazyServiceGetter(this, "presentationDeviceManager", - "@mozilla.org/presentation-device/manager;1", - "nsIPresentationDeviceManager"); - -XPCOMUtils.defineLazyServiceGetter(this, "ppmm", - "@mozilla.org/parentprocessmessagemanager;1", - "nsIMessageBroadcaster"); - -this.PresentationDeviceInfoService = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIMessageListener, - Ci.nsIObserver]), - - init: function() { - log("init"); - ppmm.addMessageListener("PresentationDeviceInfoManager:GetAll", this); - ppmm.addMessageListener("PresentationDeviceInfoManager:ForceDiscovery", this); - Services.obs.addObserver(this, "presentation-device-change", false); - }, - - getAll: function(aData, aMm) { - log("getAll"); - let deviceArray = presentationDeviceManager.getAvailableDevices().QueryInterface(Ci.nsIArray); - if (!deviceArray) { - aData.error = "DataError"; - aMm.sendAsyncMessage("PresentationDeviceInfoManager:GetAll:Result:Error", aData); - return; - } - - aData.devices = []; - for (let i = 0; i < deviceArray.length; i++) { - let device = deviceArray.queryElementAt(i, Ci.nsIPresentationDevice); - aData.devices.push({ - id: device.id, - name: device.name, - type: device.type, - }); - } - aMm.sendAsyncMessage("PresentationDeviceInfoManager:GetAll:Result:Ok", aData); - }, - - forceDiscovery: function() { - log("forceDiscovery"); - presentationDeviceManager.forceDiscovery(); - }, - - observe: function(aSubject, aTopic, aData) { - log("observe: " + aTopic); - - let device = aSubject.QueryInterface(Ci.nsIPresentationDevice); - let data = { - type: aData, - deviceInfo: { - id: device.id, - name: device.name, - type: device.type, - }, - }; - ppmm.broadcastAsyncMessage("PresentationDeviceInfoManager:OnDeviceChange", data); - }, - - receiveMessage: function(aMessage) { - if (!aMessage.target.assertPermission("presentation-device-manage")) { - debug("receive message " + aMessage.name + - " from a content process with no 'presentation-device-manage' privileges."); - return null; - } - - let msg = aMessage.data || {}; - let mm = aMessage.target; - - log("receiveMessage: " + aMessage.name); - switch (aMessage.name) { - case "PresentationDeviceInfoManager:GetAll": { - this.getAll(msg, mm); - break; - } - case "PresentationDeviceInfoManager:ForceDiscovery": { - this.forceDiscovery(); - break; - } - } - }, -}; - -this.PresentationDeviceInfoService.init(); diff --git a/dom/presentation/PresentationDeviceInfoManager.manifest b/dom/presentation/PresentationDeviceInfoManager.manifest deleted file mode 100644 index ae50b8e6a8..0000000000 --- a/dom/presentation/PresentationDeviceInfoManager.manifest +++ /dev/null @@ -1,3 +0,0 @@ -# PresentationDeviceInfoManager.js -component {1bd66bef-f643-4be3-b690-0c656353eafd} PresentationDeviceInfoManager.js -contract @mozilla.org/presentation-device/deviceInfo;1 {1bd66bef-f643-4be3-b690-0c656353eafd} diff --git a/dom/presentation/PresentationDeviceManager.cpp b/dom/presentation/PresentationDeviceManager.cpp deleted file mode 100644 index 7e5a4700c8..0000000000 --- a/dom/presentation/PresentationDeviceManager.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "PresentationDeviceManager.h" - -#include "mozilla/Services.h" -#include "MainThreadUtils.h" -#include "nsArrayUtils.h" -#include "nsCategoryCache.h" -#include "nsCOMPtr.h" -#include "nsIMutableArray.h" -#include "nsIObserverService.h" -#include "nsXULAppAPI.h" -#include "PresentationSessionRequest.h" -#include "PresentationTerminateRequest.h" - -namespace mozilla { -namespace dom { - -NS_IMPL_ISUPPORTS(PresentationDeviceManager, - nsIPresentationDeviceManager, - nsIPresentationDeviceListener, - nsIObserver, - nsISupportsWeakReference) - -PresentationDeviceManager::PresentationDeviceManager() -{ -} - -PresentationDeviceManager::~PresentationDeviceManager() -{ - UnloadDeviceProviders(); - mDevices.Clear(); -} - -void -PresentationDeviceManager::Init() -{ - nsCOMPtr obs = mozilla::services::GetObserverService(); - if (obs) { - obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false); - } - - LoadDeviceProviders(); -} - -void -PresentationDeviceManager::Shutdown() -{ - nsCOMPtr obs = mozilla::services::GetObserverService(); - if (obs) { - obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID); - } - - UnloadDeviceProviders(); -} - -void -PresentationDeviceManager::LoadDeviceProviders() -{ - MOZ_ASSERT(mProviders.IsEmpty()); - - nsCategoryCache providerCache(PRESENTATION_DEVICE_PROVIDER_CATEGORY); - providerCache.GetEntries(mProviders); - - for (uint32_t i = 0; i < mProviders.Length(); ++i) { - mProviders[i]->SetListener(this); - } -} - -void -PresentationDeviceManager::UnloadDeviceProviders() -{ - for (uint32_t i = 0; i < mProviders.Length(); ++i) { - mProviders[i]->SetListener(nullptr); - } - - mProviders.Clear(); -} - -void -PresentationDeviceManager::NotifyDeviceChange(nsIPresentationDevice* aDevice, - const char16_t* aType) -{ - nsCOMPtr obs = services::GetObserverService(); - if (obs) { - obs->NotifyObservers(aDevice, - PRESENTATION_DEVICE_CHANGE_TOPIC, - aType); - } -} - -// nsIPresentationDeviceManager -NS_IMETHODIMP -PresentationDeviceManager::ForceDiscovery() -{ - MOZ_ASSERT(NS_IsMainThread()); - - for (uint32_t i = 0; i < mProviders.Length(); ++i) { - mProviders[i]->ForceDiscovery(); - } - - return NS_OK; -} - -NS_IMETHODIMP -PresentationDeviceManager::AddDeviceProvider(nsIPresentationDeviceProvider* aProvider) -{ - NS_ENSURE_ARG(aProvider); - MOZ_ASSERT(NS_IsMainThread()); - - if (NS_WARN_IF(mProviders.Contains(aProvider))) { - return NS_OK; - } - - mProviders.AppendElement(aProvider); - aProvider->SetListener(this); - - return NS_OK; -} - -NS_IMETHODIMP -PresentationDeviceManager::RemoveDeviceProvider(nsIPresentationDeviceProvider* aProvider) -{ - NS_ENSURE_ARG(aProvider); - MOZ_ASSERT(NS_IsMainThread()); - - if (NS_WARN_IF(!mProviders.RemoveElement(aProvider))) { - return NS_ERROR_FAILURE; - } - - aProvider->SetListener(nullptr); - - return NS_OK; -} - -NS_IMETHODIMP -PresentationDeviceManager::GetDeviceAvailable(bool* aRetVal) -{ - NS_ENSURE_ARG_POINTER(aRetVal); - MOZ_ASSERT(NS_IsMainThread()); - - *aRetVal = !mDevices.IsEmpty(); - - return NS_OK; -} - -NS_IMETHODIMP -PresentationDeviceManager::GetAvailableDevices(nsIArray* aPresentationUrls, nsIArray** aRetVal) -{ - NS_ENSURE_ARG_POINTER(aRetVal); - MOZ_ASSERT(NS_IsMainThread()); - - // Bug 1194049: some providers may discontinue discovery after timeout. - // Call |ForceDiscovery()| here to make sure device lists are updated. - NS_DispatchToMainThread( - NewRunnableMethod(this, &PresentationDeviceManager::ForceDiscovery)); - - nsTArray presentationUrls; - if (aPresentationUrls) { - uint32_t length; - nsresult rv = aPresentationUrls->GetLength(&length); - if (NS_SUCCEEDED(rv)) { - for (uint32_t i = 0; i < length; ++i) { - nsCOMPtr isupportStr = - do_QueryElementAt(aPresentationUrls, i); - - nsAutoString presentationUrl; - rv = isupportStr->GetData(presentationUrl); - if (NS_WARN_IF(NS_FAILED(rv))) { - continue; - } - - presentationUrls.AppendElement(presentationUrl); - } - } - } - - nsCOMPtr devices = do_CreateInstance(NS_ARRAY_CONTRACTID); - for (uint32_t i = 0; i < mDevices.Length(); ++i) { - if (presentationUrls.IsEmpty()) { - devices->AppendElement(mDevices[i], false); - continue; - } - - for (uint32_t j = 0; j < presentationUrls.Length(); ++j) { - bool isSupported; - if (NS_SUCCEEDED(mDevices[i]->IsRequestedUrlSupported(presentationUrls[j], - &isSupported)) && - isSupported) { - devices->AppendElement(mDevices[i], false); - break; - } - } - } - - devices.forget(aRetVal); - - return NS_OK; -} - -// nsIPresentationDeviceListener -NS_IMETHODIMP -PresentationDeviceManager::AddDevice(nsIPresentationDevice* aDevice) -{ - NS_ENSURE_ARG(aDevice); - MOZ_ASSERT(NS_IsMainThread()); - - if (NS_WARN_IF(mDevices.Contains(aDevice))) { - return NS_ERROR_FAILURE; - } - - mDevices.AppendElement(aDevice); - - NotifyDeviceChange(aDevice, u"add"); - - return NS_OK; -} - -NS_IMETHODIMP -PresentationDeviceManager::RemoveDevice(nsIPresentationDevice* aDevice) -{ - NS_ENSURE_ARG(aDevice); - MOZ_ASSERT(NS_IsMainThread()); - - int32_t index = mDevices.IndexOf(aDevice); - if (NS_WARN_IF(index < 0)) { - return NS_ERROR_FAILURE; - } - - mDevices.RemoveElementAt(index); - - NotifyDeviceChange(aDevice, u"remove"); - - return NS_OK; -} - -NS_IMETHODIMP -PresentationDeviceManager::UpdateDevice(nsIPresentationDevice* aDevice) -{ - NS_ENSURE_ARG(aDevice); - MOZ_ASSERT(NS_IsMainThread()); - - if (NS_WARN_IF(!mDevices.Contains(aDevice))) { - return NS_ERROR_FAILURE; - } - - NotifyDeviceChange(aDevice, u"update"); - - return NS_OK; -} - -NS_IMETHODIMP -PresentationDeviceManager::OnSessionRequest(nsIPresentationDevice* aDevice, - const nsAString& aUrl, - const nsAString& aPresentationId, - nsIPresentationControlChannel* aControlChannel) -{ - NS_ENSURE_ARG(aDevice); - NS_ENSURE_ARG(aControlChannel); - - nsCOMPtr obs = services::GetObserverService(); - NS_ENSURE_TRUE(obs, NS_ERROR_FAILURE); - - RefPtr request = - new PresentationSessionRequest(aDevice, aUrl, aPresentationId, aControlChannel); - obs->NotifyObservers(request, - PRESENTATION_SESSION_REQUEST_TOPIC, - nullptr); - - return NS_OK; -} - -NS_IMETHODIMP -PresentationDeviceManager::OnTerminateRequest(nsIPresentationDevice* aDevice, - const nsAString& aPresentationId, - nsIPresentationControlChannel* aControlChannel, - bool aIsFromReceiver) -{ - NS_ENSURE_ARG(aDevice); - NS_ENSURE_ARG(aControlChannel); - - nsCOMPtr obs = services::GetObserverService(); - NS_ENSURE_TRUE(obs, NS_ERROR_FAILURE); - - RefPtr request = - new PresentationTerminateRequest(aDevice, aPresentationId, - aControlChannel, aIsFromReceiver); - obs->NotifyObservers(request, - PRESENTATION_TERMINATE_REQUEST_TOPIC, - nullptr); - - return NS_OK; -} - -NS_IMETHODIMP -PresentationDeviceManager::OnReconnectRequest(nsIPresentationDevice* aDevice, - const nsAString& aUrl, - const nsAString& aPresentationId, - nsIPresentationControlChannel* aControlChannel) -{ - NS_ENSURE_ARG(aDevice); - NS_ENSURE_ARG(aControlChannel); - - nsCOMPtr obs = services::GetObserverService(); - NS_ENSURE_TRUE(obs, NS_ERROR_FAILURE); - - RefPtr request = - new PresentationSessionRequest(aDevice, aUrl, aPresentationId, aControlChannel); - obs->NotifyObservers(request, - PRESENTATION_RECONNECT_REQUEST_TOPIC, - nullptr); - - return NS_OK; -} - -// nsIObserver -NS_IMETHODIMP -PresentationDeviceManager::Observe(nsISupports *aSubject, - const char *aTopic, - const char16_t *aData) -{ - if (!strcmp(aTopic, "profile-after-change")) { - Init(); - } else if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) { - Shutdown(); - } - - return NS_OK; -} - -} // namespace dom -} // namespace mozilla diff --git a/dom/presentation/PresentationDeviceManager.h b/dom/presentation/PresentationDeviceManager.h deleted file mode 100644 index f854ee8834..0000000000 --- a/dom/presentation/PresentationDeviceManager.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_dom_PresentationDeviceManager_h__ -#define mozilla_dom_PresentationDeviceManager_h__ - -#include "nsIObserver.h" -#include "nsIPresentationDevice.h" -#include "nsIPresentationDeviceManager.h" -#include "nsIPresentationDeviceProvider.h" -#include "nsCOMArray.h" -#include "nsWeakReference.h" - -namespace mozilla { -namespace dom { - -class PresentationDeviceManager final : public nsIPresentationDeviceManager - , public nsIPresentationDeviceListener - , public nsIObserver - , public nsSupportsWeakReference -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIPRESENTATIONDEVICEMANAGER - NS_DECL_NSIPRESENTATIONDEVICELISTENER - NS_DECL_NSIOBSERVER - - PresentationDeviceManager(); - -private: - virtual ~PresentationDeviceManager(); - - void Init(); - - void Shutdown(); - - void LoadDeviceProviders(); - - void UnloadDeviceProviders(); - - void NotifyDeviceChange(nsIPresentationDevice* aDevice, - const char16_t* aType); - - nsCOMArray mProviders; - nsCOMArray mDevices; -}; - -} // namespace dom -} // namespace mozilla - -#endif /* mozilla_dom_PresentationDeviceManager_h__ */ diff --git a/dom/presentation/PresentationLog.h b/dom/presentation/PresentationLog.h deleted file mode 100644 index 96af0c1249..0000000000 --- a/dom/presentation/PresentationLog.h +++ /dev/null @@ -1,26 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_dom_PresentationLog_h -#define mozilla_dom_PresentationLog_h - -/* - * MOZ_LOG=Presentation:5 - * For detail, see PresentationService.cpp - */ -namespace mozilla { -namespace dom { -extern mozilla::LazyLogModule gPresentationLog; -} -} - -#undef PRES_ERROR -#define PRES_ERROR(...) MOZ_LOG(mozilla::dom::gPresentationLog, mozilla::LogLevel::Error, (__VA_ARGS__)) - -#undef PRES_DEBUG -#define PRES_DEBUG(...) MOZ_LOG(mozilla::dom::gPresentationLog, mozilla::LogLevel::Debug, (__VA_ARGS__)) - -#endif // mozilla_dom_PresentationLog_h diff --git a/dom/presentation/PresentationNetworkHelper.js b/dom/presentation/PresentationNetworkHelper.js deleted file mode 100644 index 9b6458dafa..0000000000 --- a/dom/presentation/PresentationNetworkHelper.js +++ /dev/null @@ -1,28 +0,0 @@ -// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*- -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const { classes: Cc, interfaces: Ci, utils: Cu } = Components; - -Cu.import("resource://gre/modules/Messaging.jsm"); -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -const NETWORKHELPER_CID = Components.ID("{5fb96caa-6d49-4f6b-9a4b-65dd0d51f92d}"); - -function PresentationNetworkHelper() {} - -PresentationNetworkHelper.prototype = { - classID: NETWORKHELPER_CID, - QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationNetworkHelper]), - - getWifiIPAddress: function(aListener) { - Messaging.sendRequestForResult({type: "Wifi:GetIPAddress"}) - .then(result => aListener.onGetWifiIPAddress(result), - err => aListener.onError(err)); - } -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PresentationNetworkHelper]); diff --git a/dom/presentation/PresentationNetworkHelper.manifest b/dom/presentation/PresentationNetworkHelper.manifest deleted file mode 100644 index a061cef08f..0000000000 --- a/dom/presentation/PresentationNetworkHelper.manifest +++ /dev/null @@ -1,3 +0,0 @@ -# PresentationNetworkHelper.js -component {5fb96caa-6d49-4f6b-9a4b-65dd0d51f92d} PresentationNetworkHelper.js -contract @mozilla.org/presentation-device/networkHelper;1 {5fb96caa-6d49-4f6b-9a4b-65dd0d51f92d} diff --git a/dom/presentation/PresentationReceiver.cpp b/dom/presentation/PresentationReceiver.cpp deleted file mode 100644 index bc1776b456..0000000000 --- a/dom/presentation/PresentationReceiver.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* 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 "PresentationReceiver.h" - -#include "mozilla/dom/PresentationReceiverBinding.h" -#include "mozilla/dom/Promise.h" -#include "nsContentUtils.h" -#include "nsIPresentationService.h" -#include "nsPIDOMWindow.h" -#include "nsServiceManagerUtils.h" -#include "nsThreadUtils.h" -#include "PresentationConnection.h" -#include "PresentationConnectionList.h" -#include "PresentationLog.h" - -namespace mozilla { -namespace dom { - -NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(PresentationReceiver, - mOwner, - mGetConnectionListPromise, - mConnectionList) - -NS_IMPL_CYCLE_COLLECTING_ADDREF(PresentationReceiver) -NS_IMPL_CYCLE_COLLECTING_RELEASE(PresentationReceiver) - -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PresentationReceiver) - NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY - NS_INTERFACE_MAP_ENTRY(nsIPresentationRespondingListener) - NS_INTERFACE_MAP_ENTRY(nsISupports) -NS_INTERFACE_MAP_END - -/* static */ already_AddRefed -PresentationReceiver::Create(nsPIDOMWindowInner* aWindow) -{ - RefPtr receiver = new PresentationReceiver(aWindow); - return NS_WARN_IF(!receiver->Init()) ? nullptr : receiver.forget(); -} - -PresentationReceiver::PresentationReceiver(nsPIDOMWindowInner* aWindow) - : mOwner(aWindow) -{ - MOZ_ASSERT(aWindow); -} - -PresentationReceiver::~PresentationReceiver() -{ - Shutdown(); -} - -bool -PresentationReceiver::Init() -{ - if (NS_WARN_IF(!mOwner)) { - return false; - } - mWindowId = mOwner->WindowID(); - - nsCOMPtr docShell = mOwner->GetDocShell(); - MOZ_ASSERT(docShell); - - nsContentUtils::GetPresentationURL(docShell, mUrl); - return !mUrl.IsEmpty(); -} - -void PresentationReceiver::Shutdown() -{ - PRES_DEBUG("receiver shutdown:windowId[%d]\n", mWindowId); - - // Unregister listener for incoming sessions. - nsCOMPtr service = - do_GetService(PRESENTATION_SERVICE_CONTRACTID); - if (NS_WARN_IF(!service)) { - return; - } - - Unused << - NS_WARN_IF(NS_FAILED(service->UnregisterRespondingListener(mWindowId))); -} - -/* virtual */ JSObject* -PresentationReceiver::WrapObject(JSContext* aCx, - JS::Handle aGivenProto) -{ - return PresentationReceiverBinding::Wrap(aCx, this, aGivenProto); -} - -NS_IMETHODIMP -PresentationReceiver::NotifySessionConnect(uint64_t aWindowId, - const nsAString& aSessionId) -{ - PRES_DEBUG("receiver session connect:id[%s], windowId[%x]\n", - NS_ConvertUTF16toUTF8(aSessionId).get(), aWindowId); - - if (NS_WARN_IF(!mOwner)) { - return NS_ERROR_FAILURE; - } - - if (NS_WARN_IF(aWindowId != mWindowId)) { - return NS_ERROR_INVALID_ARG; - } - - if (NS_WARN_IF(!mConnectionList)) { - return NS_ERROR_FAILURE; - } - - RefPtr connection = - PresentationConnection::Create(mOwner, aSessionId, mUrl, - nsIPresentationService::ROLE_RECEIVER, - mConnectionList); - if (NS_WARN_IF(!connection)) { - return NS_ERROR_NOT_AVAILABLE; - } - - return NS_OK; -} - -already_AddRefed -PresentationReceiver::GetConnectionList(ErrorResult& aRv) -{ - nsCOMPtr global = do_QueryInterface(mOwner); - if (NS_WARN_IF(!global)) { - aRv.Throw(NS_ERROR_UNEXPECTED); - return nullptr; - } - - if (!mGetConnectionListPromise) { - mGetConnectionListPromise = Promise::Create(global, aRv); - if (NS_WARN_IF(aRv.Failed())) { - return nullptr; - } - - RefPtr self = this; - nsresult rv = - NS_DispatchToMainThread(NS_NewRunnableFunction([self] () -> void { - self->CreateConnectionList(); - })); - if (NS_FAILED(rv)) { - aRv.Throw(rv); - return nullptr; - } - } - - RefPtr promise = mGetConnectionListPromise; - return promise.forget(); -} - -void -PresentationReceiver::CreateConnectionList() -{ - MOZ_ASSERT(mGetConnectionListPromise); - - if (mConnectionList) { - return; - } - - mConnectionList = new PresentationConnectionList(mOwner, - mGetConnectionListPromise); - - // Register listener for incoming sessions. - nsCOMPtr service = - do_GetService(PRESENTATION_SERVICE_CONTRACTID); - if (NS_WARN_IF(!service)) { - mGetConnectionListPromise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR); - return; - } - - nsresult rv = service->RegisterRespondingListener(mWindowId, this); - if (NS_WARN_IF(NS_FAILED(rv))) { - mGetConnectionListPromise->MaybeReject(rv); - } -} - -} // namespace dom -} // namespace mozilla diff --git a/dom/presentation/PresentationReceiver.h b/dom/presentation/PresentationReceiver.h deleted file mode 100644 index ee72f587bc..0000000000 --- a/dom/presentation/PresentationReceiver.h +++ /dev/null @@ -1,71 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_dom_PresentationReceiver_h -#define mozilla_dom_PresentationReceiver_h - -#include "mozilla/ErrorResult.h" -#include "nsCOMPtr.h" -#include "nsCycleCollectionParticipant.h" -#include "nsIPresentationListener.h" -#include "nsWrapperCache.h" -#include "nsString.h" - -class nsPIDOMWindowInner; - -namespace mozilla { -namespace dom { - -class PresentationConnection; -class PresentationConnectionList; -class Promise; - -class PresentationReceiver final : public nsIPresentationRespondingListener - , public nsWrapperCache -{ -public: - NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(PresentationReceiver) - NS_DECL_NSIPRESENTATIONRESPONDINGLISTENER - - static already_AddRefed Create(nsPIDOMWindowInner* aWindow); - - virtual JSObject* WrapObject(JSContext* aCx, - JS::Handle aGivenProto) override; - - nsPIDOMWindowInner* GetParentObject() const - { - return mOwner; - } - - // WebIDL (public APIs) - already_AddRefed GetConnectionList(ErrorResult& aRv); - -private: - explicit PresentationReceiver(nsPIDOMWindowInner* aWindow); - - virtual ~PresentationReceiver(); - - MOZ_IS_CLASS_INIT bool Init(); - - void Shutdown(); - - void CreateConnectionList(); - - // Store the inner window ID for |UnregisterRespondingListener| call in - // |Shutdown| since the inner window may not exist at that moment. - uint64_t mWindowId; - - nsCOMPtr mOwner; - nsString mUrl; - RefPtr mGetConnectionListPromise; - RefPtr mConnectionList; -}; - -} // namespace dom -} // namespace mozilla - -#endif // mozilla_dom_PresentationReceiver_h diff --git a/dom/presentation/PresentationRequest.cpp b/dom/presentation/PresentationRequest.cpp deleted file mode 100644 index 221684e531..0000000000 --- a/dom/presentation/PresentationRequest.cpp +++ /dev/null @@ -1,563 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* 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 "PresentationRequest.h" - -#include "AvailabilityCollection.h" -#include "ControllerConnectionCollection.h" -#include "mozilla/BasePrincipal.h" -#include "mozilla/dom/Navigator.h" -#include "mozilla/dom/PresentationRequestBinding.h" -#include "mozilla/dom/PresentationConnectionAvailableEvent.h" -#include "mozilla/dom/Promise.h" -#include "mozilla/Move.h" -#include "mozIThirdPartyUtil.h" -#include "nsContentSecurityManager.h" -#include "nsCycleCollectionParticipant.h" -#include "nsGlobalWindow.h" -#include "nsIDocument.h" -#include "nsIPresentationService.h" -#include "nsIURI.h" -#include "nsIUUIDGenerator.h" -#include "nsNetUtil.h" -#include "nsSandboxFlags.h" -#include "nsServiceManagerUtils.h" -#include "Presentation.h" -#include "PresentationAvailability.h" -#include "PresentationCallbacks.h" -#include "PresentationLog.h" -#include "PresentationTransportBuilderConstructor.h" - -using namespace mozilla; -using namespace mozilla::dom; - -NS_IMPL_ADDREF_INHERITED(PresentationRequest, DOMEventTargetHelper) -NS_IMPL_RELEASE_INHERITED(PresentationRequest, DOMEventTargetHelper) - -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(PresentationRequest) -NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper) - -static nsresult -GetAbsoluteURL(const nsAString& aUrl, - nsIURI* aBaseUri, - nsIDocument* aDocument, - nsAString& aAbsoluteUrl) -{ - nsCOMPtr uri; - nsresult rv = NS_NewURI(getter_AddRefs(uri), - aUrl, - aDocument ? aDocument->GetDocumentCharacterSet().get() - : nullptr, - aBaseUri); - - if (NS_FAILED(rv)) { - return rv; - } - - nsAutoCString spec; - uri->GetSpec(spec); - - aAbsoluteUrl = NS_ConvertUTF8toUTF16(spec); - - return NS_OK; -} - -/* static */ already_AddRefed -PresentationRequest::Constructor(const GlobalObject& aGlobal, - const nsAString& aUrl, - ErrorResult& aRv) -{ - Sequence urls; - urls.AppendElement(aUrl, fallible); - return Constructor(aGlobal, urls, aRv); -} - -/* static */ already_AddRefed -PresentationRequest::Constructor(const GlobalObject& aGlobal, - const Sequence& aUrls, - ErrorResult& aRv) -{ - nsCOMPtr window = do_QueryInterface(aGlobal.GetAsSupports()); - if (!window) { - aRv.Throw(NS_ERROR_UNEXPECTED); - return nullptr; - } - - if (aUrls.IsEmpty()) { - aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); - return nullptr; - } - - // Resolve relative URL to absolute URL - nsCOMPtr baseUri = window->GetDocBaseURI(); - nsTArray urls; - for (const auto& url : aUrls) { - nsAutoString absoluteUrl; - nsresult rv = - GetAbsoluteURL(url, baseUri, window->GetExtantDoc(), absoluteUrl); - if (NS_WARN_IF(NS_FAILED(rv))) { - aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR); - return nullptr; - } - - urls.AppendElement(absoluteUrl); - } - - RefPtr request = - new PresentationRequest(window, Move(urls)); - return NS_WARN_IF(!request->Init()) ? nullptr : request.forget(); -} - -PresentationRequest::PresentationRequest(nsPIDOMWindowInner* aWindow, - nsTArray&& aUrls) - : DOMEventTargetHelper(aWindow) - , mUrls(Move(aUrls)) -{ -} - -PresentationRequest::~PresentationRequest() -{ -} - -bool -PresentationRequest::Init() -{ - return true; -} - -/* virtual */ JSObject* -PresentationRequest::WrapObject(JSContext* aCx, - JS::Handle aGivenProto) -{ - return PresentationRequestBinding::Wrap(aCx, this, aGivenProto); -} - -already_AddRefed -PresentationRequest::Start(ErrorResult& aRv) -{ - return StartWithDevice(NullString(), aRv); -} - -already_AddRefed -PresentationRequest::StartWithDevice(const nsAString& aDeviceId, - ErrorResult& aRv) -{ - nsCOMPtr global = do_QueryInterface(GetOwner()); - if (NS_WARN_IF(!global)) { - aRv.Throw(NS_ERROR_UNEXPECTED); - return nullptr; - } - - // Get the origin. - nsAutoString origin; - nsresult rv = nsContentUtils::GetUTFOrigin(global->PrincipalOrNull(), origin); - if (NS_WARN_IF(NS_FAILED(rv))) { - aRv.Throw(rv); - return nullptr; - } - - nsCOMPtr doc = GetOwner()->GetExtantDoc(); - if (NS_WARN_IF(!doc)) { - aRv.Throw(NS_ERROR_FAILURE); - return nullptr; - } - - RefPtr promise = Promise::Create(global, aRv); - if (NS_WARN_IF(aRv.Failed())) { - return nullptr; - } - - if (IsProhibitMixedSecurityContexts(doc) && - !IsAllURLAuthenticated()) { - promise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR); - return promise.forget(); - } - - if (doc->GetSandboxFlags() & SANDBOXED_PRESENTATION) { - promise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR); - return promise.forget(); - } - - RefPtr navigator = - nsGlobalWindow::Cast(GetOwner())->GetNavigator(aRv); - if (NS_WARN_IF(aRv.Failed())) { - return nullptr; - } - - RefPtr presentation = navigator->GetPresentation(aRv); - if (NS_WARN_IF(aRv.Failed())) { - return nullptr; - } - - if (presentation->IsStartSessionUnsettled()) { - promise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR); - return promise.forget(); - } - - // Generate a session ID. - nsCOMPtr uuidgen = - do_GetService("@mozilla.org/uuid-generator;1"); - if(NS_WARN_IF(!uuidgen)) { - promise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR); - return promise.forget(); - } - - nsID uuid; - uuidgen->GenerateUUIDInPlace(&uuid); - char buffer[NSID_LENGTH]; - uuid.ToProvidedString(buffer); - nsAutoString id; - CopyASCIItoUTF16(buffer, id); - - nsCOMPtr service = - do_GetService(PRESENTATION_SERVICE_CONTRACTID); - if(NS_WARN_IF(!service)) { - promise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR); - return promise.forget(); - } - - presentation->SetStartSessionUnsettled(true); - - // Get xul:browser element in parent process or nsWindowRoot object in child - // process. If it's in child process, the corresponding xul:browser element - // will be obtained at PresentationRequestParent::DoRequest in its parent - // process. - nsCOMPtr handler = - do_QueryInterface(GetOwner()->GetChromeEventHandler()); - nsCOMPtr principal = doc->NodePrincipal(); - nsCOMPtr callback = - new PresentationRequesterCallback(this, id, promise); - nsCOMPtr constructor = - PresentationTransportBuilderConstructor::Create(); - rv = service->StartSession(mUrls, - id, - origin, - aDeviceId, - GetOwner()->WindowID(), - handler, - principal, - callback, - constructor); - if (NS_WARN_IF(NS_FAILED(rv))) { - promise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR); - NotifyPromiseSettled(); - } - - return promise.forget(); -} - -already_AddRefed -PresentationRequest::Reconnect(const nsAString& aPresentationId, - ErrorResult& aRv) -{ - nsCOMPtr global = do_QueryInterface(GetOwner()); - if (NS_WARN_IF(!global)) { - aRv.Throw(NS_ERROR_UNEXPECTED); - return nullptr; - } - - nsCOMPtr doc = GetOwner()->GetExtantDoc(); - if (NS_WARN_IF(!doc)) { - aRv.Throw(NS_ERROR_FAILURE); - return nullptr; - } - - RefPtr promise = Promise::Create(global, aRv); - if (NS_WARN_IF(aRv.Failed())) { - return nullptr; - } - - if (IsProhibitMixedSecurityContexts(doc) && - !IsAllURLAuthenticated()) { - promise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR); - return promise.forget(); - } - - if (doc->GetSandboxFlags() & SANDBOXED_PRESENTATION) { - promise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR); - return promise.forget(); - } - - nsString presentationId = nsString(aPresentationId); - nsCOMPtr r = - NewRunnableMethod>( - this, - &PresentationRequest::FindOrCreatePresentationConnection, - presentationId, - promise); - - if (NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(r)))) { - promise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR); - } - - return promise.forget(); -} - -void -PresentationRequest::FindOrCreatePresentationConnection( - const nsAString& aPresentationId, - Promise* aPromise) -{ - MOZ_ASSERT(aPromise); - - if (NS_WARN_IF(!GetOwner())) { - aPromise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR); - return; - } - - RefPtr connection = - ControllerConnectionCollection::GetSingleton()->FindConnection( - GetOwner()->WindowID(), - aPresentationId, - nsIPresentationService::ROLE_CONTROLLER); - - if (connection) { - nsAutoString url; - connection->GetUrl(url); - if (mUrls.Contains(url)) { - switch (connection->State()) { - case PresentationConnectionState::Closed: - // We found the matched connection. - break; - case PresentationConnectionState::Connecting: - case PresentationConnectionState::Connected: - aPromise->MaybeResolve(connection); - return; - case PresentationConnectionState::Terminated: - // A terminated connection cannot be reused. - connection = nullptr; - break; - default: - MOZ_CRASH("Unknown presentation session state."); - return; - } - } else { - connection = nullptr; - } - } - - nsCOMPtr service = - do_GetService(PRESENTATION_SERVICE_CONTRACTID); - if(NS_WARN_IF(!service)) { - aPromise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR); - return; - } - - nsCOMPtr callback = - new PresentationReconnectCallback(this, - aPresentationId, - aPromise, - connection); - - nsresult rv = - service->ReconnectSession(mUrls, - aPresentationId, - nsIPresentationService::ROLE_CONTROLLER, - callback); - if (NS_WARN_IF(NS_FAILED(rv))) { - aPromise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR); - } -} - -already_AddRefed -PresentationRequest::GetAvailability(ErrorResult& aRv) -{ - PRES_DEBUG("%s\n", __func__); - nsCOMPtr global = do_QueryInterface(GetOwner()); - if (NS_WARN_IF(!global)) { - aRv.Throw(NS_ERROR_UNEXPECTED); - return nullptr; - } - - nsCOMPtr doc = GetOwner()->GetExtantDoc(); - if (NS_WARN_IF(!doc)) { - aRv.Throw(NS_ERROR_FAILURE); - return nullptr; - } - - RefPtr promise = Promise::Create(global, aRv); - if (NS_WARN_IF(aRv.Failed())) { - return nullptr; - } - - if (IsProhibitMixedSecurityContexts(doc) && - !IsAllURLAuthenticated()) { - promise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR); - return promise.forget(); - } - - if (doc->GetSandboxFlags() & SANDBOXED_PRESENTATION) { - promise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR); - return promise.forget(); - } - - FindOrCreatePresentationAvailability(promise); - - return promise.forget(); -} - -void -PresentationRequest::FindOrCreatePresentationAvailability(RefPtr& aPromise) -{ - MOZ_ASSERT(aPromise); - - if (NS_WARN_IF(!GetOwner())) { - aPromise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR); - return; - } - - AvailabilityCollection* collection = AvailabilityCollection::GetSingleton(); - if (NS_WARN_IF(!collection)) { - aPromise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR); - return; - } - - RefPtr availability = - collection->Find(GetOwner()->WindowID(), mUrls); - - if (!availability) { - availability = PresentationAvailability::Create(GetOwner(), mUrls, aPromise); - } else { - PRES_DEBUG(">resolve with same object\n"); - - // Fetching cached available devices is asynchronous in our implementation, - // we need to ensure the promise is resolved in order. - if (availability->IsCachedValueReady()) { - aPromise->MaybeResolve(availability); - return; - } - - availability->EnqueuePromise(aPromise); - } - - if (!availability) { - aPromise->MaybeReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR); - return; - } -} - -nsresult -PresentationRequest::DispatchConnectionAvailableEvent(PresentationConnection* aConnection) -{ - PresentationConnectionAvailableEventInit init; - init.mConnection = aConnection; - - RefPtr event = - PresentationConnectionAvailableEvent::Constructor(this, - NS_LITERAL_STRING("connectionavailable"), - init); - if (NS_WARN_IF(!event)) { - return NS_ERROR_FAILURE; - } - event->SetTrusted(true); - - RefPtr asyncDispatcher = - new AsyncEventDispatcher(this, event); - return asyncDispatcher->PostDOMEvent(); -} - -void -PresentationRequest::NotifyPromiseSettled() -{ - PRES_DEBUG("%s\n", __func__); - - if (!GetOwner()) { - return; - } - - ErrorResult rv; - RefPtr navigator = - nsGlobalWindow::Cast(GetOwner())->GetNavigator(rv); - if (!navigator) { - return; - } - - RefPtr presentation = navigator->GetPresentation(rv); - - if (presentation) { - presentation->SetStartSessionUnsettled(false); - } -} - -bool -PresentationRequest::IsProhibitMixedSecurityContexts(nsIDocument* aDocument) -{ - MOZ_ASSERT(aDocument); - - if (nsContentUtils::IsChromeDoc(aDocument)) { - return true; - } - - nsCOMPtr doc = aDocument; - while (doc && !nsContentUtils::IsChromeDoc(doc)) { - if (nsContentUtils::HttpsStateIsModern(doc)) { - return true; - } - - doc = doc->GetParentDocument(); - } - - return false; -} - -bool -PresentationRequest::IsPrioriAuthenticatedURL(const nsAString& aUrl) -{ - nsCOMPtr uri; - if (NS_FAILED(NS_NewURI(getter_AddRefs(uri), aUrl))) { - return false; - } - - nsAutoCString scheme; - nsresult rv = uri->GetScheme(scheme); - if (NS_WARN_IF(NS_FAILED(rv))) { - return false; - } - - if (scheme.EqualsLiteral("data")) { - return true; - } - - nsAutoCString uriSpec; - rv = uri->GetSpec(uriSpec); - if (NS_WARN_IF(NS_FAILED(rv))) { - return false; - } - - if (uriSpec.EqualsLiteral("about:blank") || - uriSpec.EqualsLiteral("about:srcdoc")) { - return true; - } - - PrincipalOriginAttributes attrs; - nsCOMPtr principal = - BasePrincipal::CreateCodebasePrincipal(uri, attrs); - if (NS_WARN_IF(!principal)) { - return false; - } - - nsCOMPtr csm = - do_GetService(NS_CONTENTSECURITYMANAGER_CONTRACTID); - if (NS_WARN_IF(!csm)) { - return false; - } - - bool isTrustworthyOrigin = false; - csm->IsOriginPotentiallyTrustworthy(principal, &isTrustworthyOrigin); - return isTrustworthyOrigin; -} - -bool -PresentationRequest::IsAllURLAuthenticated() -{ - for (const auto& url : mUrls) { - if (!IsPrioriAuthenticatedURL(url)) { - return false; - } - } - - return true; -} diff --git a/dom/presentation/PresentationRequest.h b/dom/presentation/PresentationRequest.h deleted file mode 100644 index ce82f2b447..0000000000 --- a/dom/presentation/PresentationRequest.h +++ /dev/null @@ -1,84 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_dom_PresentationRequest_h -#define mozilla_dom_PresentationRequest_h - -#include "mozilla/dom/BindingDeclarations.h" -#include "mozilla/DOMEventTargetHelper.h" - -class nsIDocument; - -namespace mozilla { -namespace dom { - -class Promise; -class PresentationAvailability; -class PresentationConnection; - -class PresentationRequest final : public DOMEventTargetHelper -{ -public: - NS_DECL_ISUPPORTS_INHERITED - - static already_AddRefed Constructor( - const GlobalObject& aGlobal, - const nsAString& aUrl, - ErrorResult& aRv); - - static already_AddRefed Constructor( - const GlobalObject& aGlobal, - const Sequence& aUrls, - ErrorResult& aRv); - - virtual JSObject* WrapObject(JSContext* aCx, - JS::Handle aGivenProto) override; - - // WebIDL (public APIs) - already_AddRefed Start(ErrorResult& aRv); - - already_AddRefed StartWithDevice(const nsAString& aDeviceId, - ErrorResult& aRv); - - already_AddRefed Reconnect(const nsAString& aPresentationId, - ErrorResult& aRv); - - already_AddRefed GetAvailability(ErrorResult& aRv); - - IMPL_EVENT_HANDLER(connectionavailable); - - nsresult DispatchConnectionAvailableEvent(PresentationConnection* aConnection); - - void NotifyPromiseSettled(); - -private: - PresentationRequest(nsPIDOMWindowInner* aWindow, - nsTArray&& aUrls); - - ~PresentationRequest(); - - bool Init(); - - void FindOrCreatePresentationConnection(const nsAString& aPresentationId, - Promise* aPromise); - - void FindOrCreatePresentationAvailability(RefPtr& aPromise); - - // Implement https://w3c.github.io/webappsec-mixed-content/#categorize-settings-object - bool IsProhibitMixedSecurityContexts(nsIDocument* aDocument); - - // Implement https://w3c.github.io/webappsec-mixed-content/#a-priori-authenticated-url - bool IsPrioriAuthenticatedURL(const nsAString& aUrl); - - bool IsAllURLAuthenticated(); - - nsTArray mUrls; -}; - -} // namespace dom -} // namespace mozilla - -#endif // mozilla_dom_PresentationRequest_h diff --git a/dom/presentation/PresentationService.cpp b/dom/presentation/PresentationService.cpp deleted file mode 100644 index bc525cdb8c..0000000000 --- a/dom/presentation/PresentationService.cpp +++ /dev/null @@ -1,1188 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=2 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "PresentationService.h" - -#include "ipc/PresentationIPCService.h" -#include "mozilla/Services.h" -#include "nsGlobalWindow.h" -#include "nsIMutableArray.h" -#include "nsIObserverService.h" -#include "nsIPresentationControlChannel.h" -#include "nsIPresentationDeviceManager.h" -#include "nsIPresentationDevicePrompt.h" -#include "nsIPresentationListener.h" -#include "nsIPresentationRequestUIGlue.h" -#include "nsIPresentationSessionRequest.h" -#include "nsIPresentationTerminateRequest.h" -#include "nsISupportsPrimitives.h" -#include "nsNetUtil.h" -#include "nsServiceManagerUtils.h" -#include "nsThreadUtils.h" -#include "nsXPCOMCID.h" -#include "nsXULAppAPI.h" -#include "PresentationLog.h" - -namespace mozilla { -namespace dom { - -static bool -IsSameDevice(nsIPresentationDevice* aDevice, nsIPresentationDevice* aDeviceAnother) { - if (!aDevice || !aDeviceAnother) { - return false; - } - - nsAutoCString deviceId; - aDevice->GetId(deviceId); - nsAutoCString anotherId; - aDeviceAnother->GetId(anotherId); - if (!deviceId.Equals(anotherId)) { - return false; - } - - nsAutoCString deviceType; - aDevice->GetType(deviceType); - nsAutoCString anotherType; - aDeviceAnother->GetType(anotherType); - if (!deviceType.Equals(anotherType)) { - return false; - } - - return true; -} - -static nsresult -ConvertURLArrayHelper(const nsTArray& aUrls, nsIArray** aResult) -{ - if (!aResult) { - return NS_ERROR_INVALID_POINTER; - } - - *aResult = nullptr; - - nsresult rv; - nsCOMPtr urls = - do_CreateInstance(NS_ARRAY_CONTRACTID, &rv); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - for (const auto& url : aUrls) { - nsCOMPtr isupportsString = - do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - rv = isupportsString->SetData(url); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - rv = urls->AppendElement(isupportsString, false); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - } - - urls.forget(aResult); - return NS_OK; -} - -/* - * Implementation of PresentationDeviceRequest - */ - -class PresentationDeviceRequest final : public nsIPresentationDeviceRequest -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIPRESENTATIONDEVICEREQUEST - - PresentationDeviceRequest( - const nsTArray& aUrls, - const nsAString& aId, - const nsAString& aOrigin, - uint64_t aWindowId, - nsIDOMEventTarget* aEventTarget, - nsIPrincipal* aPrincipal, - nsIPresentationServiceCallback* aCallback, - nsIPresentationTransportBuilderConstructor* aBuilderConstructor); - -private: - virtual ~PresentationDeviceRequest() = default; - nsresult CreateSessionInfo(nsIPresentationDevice* aDevice, - const nsAString& aSelectedRequestUrl); - - nsTArray mRequestUrls; - nsString mId; - nsString mOrigin; - uint64_t mWindowId; - nsWeakPtr mChromeEventHandler; - nsCOMPtr mPrincipal; - nsCOMPtr mCallback; - nsCOMPtr mBuilderConstructor; -}; - -LazyLogModule gPresentationLog("Presentation"); - -NS_IMPL_ISUPPORTS(PresentationDeviceRequest, nsIPresentationDeviceRequest) - -PresentationDeviceRequest::PresentationDeviceRequest( - const nsTArray& aUrls, - const nsAString& aId, - const nsAString& aOrigin, - uint64_t aWindowId, - nsIDOMEventTarget* aEventTarget, - nsIPrincipal* aPrincipal, - nsIPresentationServiceCallback* aCallback, - nsIPresentationTransportBuilderConstructor* aBuilderConstructor) - : mRequestUrls(aUrls) - , mId(aId) - , mOrigin(aOrigin) - , mWindowId(aWindowId) - , mChromeEventHandler(do_GetWeakReference(aEventTarget)) - , mPrincipal(aPrincipal) - , mCallback(aCallback) - , mBuilderConstructor(aBuilderConstructor) -{ - MOZ_ASSERT(!mRequestUrls.IsEmpty()); - MOZ_ASSERT(!mId.IsEmpty()); - MOZ_ASSERT(!mOrigin.IsEmpty()); - MOZ_ASSERT(mCallback); - MOZ_ASSERT(mBuilderConstructor); -} - -NS_IMETHODIMP -PresentationDeviceRequest::GetOrigin(nsAString& aOrigin) -{ - aOrigin = mOrigin; - return NS_OK; -} - -NS_IMETHODIMP -PresentationDeviceRequest::GetRequestURLs(nsIArray** aUrls) -{ - return ConvertURLArrayHelper(mRequestUrls, aUrls); -} - -NS_IMETHODIMP -PresentationDeviceRequest::GetChromeEventHandler(nsIDOMEventTarget** aChromeEventHandler) -{ - nsCOMPtr handler(do_QueryReferent(mChromeEventHandler)); - handler.forget(aChromeEventHandler); - return NS_OK; -} - -NS_IMETHODIMP -PresentationDeviceRequest::GetPrincipal(nsIPrincipal** aPrincipal) -{ - nsCOMPtr principal(mPrincipal); - principal.forget(aPrincipal); - return NS_OK; -} - -NS_IMETHODIMP -PresentationDeviceRequest::Select(nsIPresentationDevice* aDevice) -{ - MOZ_ASSERT(NS_IsMainThread()); - if (NS_WARN_IF(!aDevice)) { - MOZ_ASSERT(false, "|aDevice| should noe be null."); - mCallback->NotifyError(NS_ERROR_DOM_OPERATION_ERR); - return NS_ERROR_INVALID_ARG; - } - - // Select the most suitable URL for starting the presentation. - nsAutoString selectedRequestUrl; - for (const auto& url : mRequestUrls) { - bool isSupported; - if (NS_SUCCEEDED(aDevice->IsRequestedUrlSupported(url, &isSupported)) && - isSupported) { - selectedRequestUrl.Assign(url); - break; - } - } - - if (selectedRequestUrl.IsEmpty()) { - return mCallback->NotifyError(NS_ERROR_DOM_NOT_FOUND_ERR); - } - - if (NS_WARN_IF(NS_FAILED(CreateSessionInfo(aDevice, selectedRequestUrl)))) { - return mCallback->NotifyError(NS_ERROR_DOM_OPERATION_ERR); - } - - return mCallback->NotifySuccess(selectedRequestUrl); -} - -nsresult -PresentationDeviceRequest::CreateSessionInfo( - nsIPresentationDevice* aDevice, - const nsAString& aSelectedRequestUrl) -{ - nsCOMPtr service = - do_GetService(PRESENTATION_SERVICE_CONTRACTID); - if (NS_WARN_IF(!service)) { - return NS_ERROR_NOT_AVAILABLE; - } - - // Create the controlling session info - RefPtr info = - static_cast(service.get())-> - CreateControllingSessionInfo(aSelectedRequestUrl, mId, mWindowId); - if (NS_WARN_IF(!info)) { - return NS_ERROR_NOT_AVAILABLE; - } - info->SetDevice(aDevice); - - // Establish a control channel. If we failed to do so, the callback is called - // with an error message. - nsCOMPtr ctrlChannel; - nsresult rv = aDevice->EstablishControlChannel(getter_AddRefs(ctrlChannel)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return info->ReplyError(NS_ERROR_DOM_OPERATION_ERR); - } - - // Initialize the session info with the control channel. - rv = info->Init(ctrlChannel); - if (NS_WARN_IF(NS_FAILED(rv))) { - return info->ReplyError(NS_ERROR_DOM_OPERATION_ERR); - } - - info->SetTransportBuilderConstructor(mBuilderConstructor); - return NS_OK; -} - -NS_IMETHODIMP -PresentationDeviceRequest::Cancel(nsresult aReason) -{ - return mCallback->NotifyError(aReason); -} - -/* - * Implementation of PresentationService - */ - -NS_IMPL_ISUPPORTS(PresentationService, - nsIPresentationService, - nsIObserver) - -PresentationService::PresentationService() -{ -} - -PresentationService::~PresentationService() -{ - HandleShutdown(); -} - -bool -PresentationService::Init() -{ - MOZ_ASSERT(NS_IsMainThread()); - - nsCOMPtr obs = services::GetObserverService(); - if (NS_WARN_IF(!obs)) { - return false; - } - - nsresult rv = obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false); - if (NS_WARN_IF(NS_FAILED(rv))) { - return false; - } - rv = obs->AddObserver(this, PRESENTATION_DEVICE_CHANGE_TOPIC, false); - if (NS_WARN_IF(NS_FAILED(rv))) { - return false; - } - rv = obs->AddObserver(this, PRESENTATION_SESSION_REQUEST_TOPIC, false); - if (NS_WARN_IF(NS_FAILED(rv))) { - return false; - } - rv = obs->AddObserver(this, PRESENTATION_TERMINATE_REQUEST_TOPIC, false); - if (NS_WARN_IF(NS_FAILED(rv))) { - return false; - } - rv = obs->AddObserver(this, PRESENTATION_RECONNECT_REQUEST_TOPIC, false); - if (NS_WARN_IF(NS_FAILED(rv))) { - return false; - } - - return !NS_WARN_IF(NS_FAILED(rv)); -} - -NS_IMETHODIMP -PresentationService::Observe(nsISupports* aSubject, - const char* aTopic, - const char16_t* aData) -{ - if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) { - HandleShutdown(); - return NS_OK; - } else if (!strcmp(aTopic, PRESENTATION_DEVICE_CHANGE_TOPIC)) { - // Ignore the "update" case here, since we only care about the arrival and - // removal of the device. - if (!NS_strcmp(aData, u"add")) { - nsCOMPtr device = do_QueryInterface(aSubject); - if (NS_WARN_IF(!device)) { - return NS_ERROR_FAILURE; - } - - return HandleDeviceAdded(device); - } else if(!NS_strcmp(aData, u"remove")) { - return HandleDeviceRemoved(); - } - - return NS_OK; - } else if (!strcmp(aTopic, PRESENTATION_SESSION_REQUEST_TOPIC)) { - nsCOMPtr request(do_QueryInterface(aSubject)); - if (NS_WARN_IF(!request)) { - return NS_ERROR_FAILURE; - } - - return HandleSessionRequest(request); - } else if (!strcmp(aTopic, PRESENTATION_TERMINATE_REQUEST_TOPIC)) { - nsCOMPtr request(do_QueryInterface(aSubject)); - if (NS_WARN_IF(!request)) { - return NS_ERROR_FAILURE; - } - - return HandleTerminateRequest(request); - } else if (!strcmp(aTopic, PRESENTATION_RECONNECT_REQUEST_TOPIC)) { - nsCOMPtr request(do_QueryInterface(aSubject)); - if (NS_WARN_IF(!request)) { - return NS_ERROR_FAILURE; - } - - return HandleReconnectRequest(request); - } else if (!strcmp(aTopic, "profile-after-change")) { - // It's expected since we add and entry to |kLayoutCategories| in - // |nsLayoutModule.cpp| to launch this service earlier. - return NS_OK; - } - - MOZ_ASSERT(false, "Unexpected topic for PresentationService"); - return NS_ERROR_UNEXPECTED; -} - -void -PresentationService::HandleShutdown() -{ - MOZ_ASSERT(NS_IsMainThread()); - - Shutdown(); - - mAvailabilityManager.Clear(); - mSessionInfoAtController.Clear(); - mSessionInfoAtReceiver.Clear(); - - nsCOMPtr obs = services::GetObserverService(); - if (obs) { - obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID); - obs->RemoveObserver(this, PRESENTATION_DEVICE_CHANGE_TOPIC); - obs->RemoveObserver(this, PRESENTATION_SESSION_REQUEST_TOPIC); - obs->RemoveObserver(this, PRESENTATION_TERMINATE_REQUEST_TOPIC); - obs->RemoveObserver(this, PRESENTATION_RECONNECT_REQUEST_TOPIC); - } -} - -nsresult -PresentationService::HandleDeviceAdded(nsIPresentationDevice* aDevice) -{ - PRES_DEBUG("%s\n", __func__); - if (!aDevice) { - MOZ_ASSERT(false, "aDevice shoud no be null."); - return NS_ERROR_INVALID_ARG; - } - - // Query for only unavailable URLs while device added. - nsTArray unavailableUrls; - mAvailabilityManager.GetAvailbilityUrlByAvailability(unavailableUrls, false); - - nsTArray supportedAvailabilityUrl; - for (const auto& url : unavailableUrls) { - bool isSupported; - if (NS_SUCCEEDED(aDevice->IsRequestedUrlSupported(url, &isSupported)) && - isSupported) { - supportedAvailabilityUrl.AppendElement(url); - } - } - - if (!supportedAvailabilityUrl.IsEmpty()) { - return mAvailabilityManager.DoNotifyAvailableChange(supportedAvailabilityUrl, - true); - } - - return NS_OK; -} - -nsresult -PresentationService::HandleDeviceRemoved() -{ - PRES_DEBUG("%s\n", __func__); - - // Query for only available URLs while device removed. - nsTArray availabilityUrls; - mAvailabilityManager.GetAvailbilityUrlByAvailability(availabilityUrls, true); - - return UpdateAvailabilityUrlChange(availabilityUrls); -} - -nsresult -PresentationService::UpdateAvailabilityUrlChange( - const nsTArray& aAvailabilityUrls) -{ - nsCOMPtr deviceManager = - do_GetService(PRESENTATION_DEVICE_MANAGER_CONTRACTID); - if (NS_WARN_IF(!deviceManager)) { - return NS_ERROR_NOT_AVAILABLE; - } - - nsCOMPtr devices; - nsresult rv = deviceManager->GetAvailableDevices(nullptr, - getter_AddRefs(devices)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - uint32_t numOfDevices; - devices->GetLength(&numOfDevices); - - nsTArray supportedAvailabilityUrl; - for (const auto& url : aAvailabilityUrls) { - for (uint32_t i = 0; i < numOfDevices; ++i) { - nsCOMPtr device = do_QueryElementAt(devices, i); - if (device) { - bool isSupported; - if (NS_SUCCEEDED(device->IsRequestedUrlSupported(url, &isSupported)) && - isSupported) { - supportedAvailabilityUrl.AppendElement(url); - break; - } - } - } - } - - if (supportedAvailabilityUrl.IsEmpty()) { - return mAvailabilityManager.DoNotifyAvailableChange(aAvailabilityUrls, - false); - } - - return mAvailabilityManager.DoNotifyAvailableChange(supportedAvailabilityUrl, - true); -} - -nsresult -PresentationService::HandleSessionRequest(nsIPresentationSessionRequest* aRequest) -{ - nsCOMPtr ctrlChannel; - nsresult rv = aRequest->GetControlChannel(getter_AddRefs(ctrlChannel)); - if (NS_WARN_IF(NS_FAILED(rv) || !ctrlChannel)) { - return rv; - } - - nsAutoString url; - rv = aRequest->GetUrl(url); - if (NS_WARN_IF(NS_FAILED(rv))) { - ctrlChannel->Disconnect(rv); - return rv; - } - - nsAutoString sessionId; - rv = aRequest->GetPresentationId(sessionId); - if (NS_WARN_IF(NS_FAILED(rv))) { - ctrlChannel->Disconnect(rv); - return rv; - } - - nsCOMPtr device; - rv = aRequest->GetDevice(getter_AddRefs(device)); - if (NS_WARN_IF(NS_FAILED(rv))) { - ctrlChannel->Disconnect(rv); - return rv; - } - - // Create or reuse session info. - RefPtr info = - GetSessionInfo(sessionId, nsIPresentationService::ROLE_RECEIVER); - - // This is the case for reconnecting a session. - // Update the control channel and device of the session info. - // Call |NotifyResponderReady| to indicate the receiver page is already there. - if (info) { - PRES_DEBUG("handle reconnection:id[%s]\n", - NS_ConvertUTF16toUTF8(sessionId).get()); - - info->SetControlChannel(ctrlChannel); - info->SetDevice(device); - return static_cast( - info.get())->DoReconnect(); - } - - // This is the case for a new session. - PRES_DEBUG("handle new session:url[%d], id[%s]\n", - NS_ConvertUTF16toUTF8(url).get(), - NS_ConvertUTF16toUTF8(sessionId).get()); - - info = new PresentationPresentingInfo(url, sessionId, device); - rv = info->Init(ctrlChannel); - if (NS_WARN_IF(NS_FAILED(rv))) { - ctrlChannel->Disconnect(rv); - return rv; - } - - mSessionInfoAtReceiver.Put(sessionId, info); - - // Notify the receiver to launch. - nsCOMPtr glue = - do_CreateInstance(PRESENTATION_REQUEST_UI_GLUE_CONTRACTID); - if (NS_WARN_IF(!glue)) { - ctrlChannel->Disconnect(NS_ERROR_DOM_OPERATION_ERR); - return info->ReplyError(NS_ERROR_DOM_OPERATION_ERR); - } - nsCOMPtr promise; - rv = glue->SendRequest(url, sessionId, device, getter_AddRefs(promise)); - if (NS_WARN_IF(NS_FAILED(rv))) { - ctrlChannel->Disconnect(rv); - return info->ReplyError(NS_ERROR_DOM_OPERATION_ERR); - } - nsCOMPtr realPromise = do_QueryInterface(promise); - static_cast(info.get())->SetPromise(realPromise); - - return NS_OK; -} - -nsresult -PresentationService::HandleTerminateRequest(nsIPresentationTerminateRequest* aRequest) -{ - nsCOMPtr ctrlChannel; - nsresult rv = aRequest->GetControlChannel(getter_AddRefs(ctrlChannel)); - if (NS_WARN_IF(NS_FAILED(rv) || !ctrlChannel)) { - return rv; - } - - nsAutoString sessionId; - rv = aRequest->GetPresentationId(sessionId); - if (NS_WARN_IF(NS_FAILED(rv))) { - ctrlChannel->Disconnect(rv); - return rv; - } - - nsCOMPtr device; - rv = aRequest->GetDevice(getter_AddRefs(device)); - if (NS_WARN_IF(NS_FAILED(rv))) { - ctrlChannel->Disconnect(rv); - return rv; - } - - bool isFromReceiver; - rv = aRequest->GetIsFromReceiver(&isFromReceiver); - if (NS_WARN_IF(NS_FAILED(rv))) { - ctrlChannel->Disconnect(rv); - return rv; - } - - RefPtr info; - if (!isFromReceiver) { - info = GetSessionInfo(sessionId, nsIPresentationService::ROLE_RECEIVER); - } else { - info = GetSessionInfo(sessionId, nsIPresentationService::ROLE_CONTROLLER); - } - if (NS_WARN_IF(!info)) { - // Cannot terminate non-existed session. - ctrlChannel->Disconnect(NS_ERROR_DOM_OPERATION_ERR); - return NS_ERROR_DOM_ABORT_ERR; - } - - // Check if terminate request comes from known device. - RefPtr knownDevice = info->GetDevice(); - if (NS_WARN_IF(!IsSameDevice(device, knownDevice))) { - ctrlChannel->Disconnect(NS_ERROR_DOM_OPERATION_ERR); - return NS_ERROR_DOM_ABORT_ERR; - } - - PRES_DEBUG("handle termination:id[%s], receiver[%d]\n", __func__, - sessionId.get(), isFromReceiver); - - return info->OnTerminate(ctrlChannel); -} - -nsresult -PresentationService::HandleReconnectRequest(nsIPresentationSessionRequest* aRequest) -{ - nsCOMPtr ctrlChannel; - nsresult rv = aRequest->GetControlChannel(getter_AddRefs(ctrlChannel)); - if (NS_WARN_IF(NS_FAILED(rv) || !ctrlChannel)) { - return rv; - } - - nsAutoString sessionId; - rv = aRequest->GetPresentationId(sessionId); - if (NS_WARN_IF(NS_FAILED(rv))) { - ctrlChannel->Disconnect(rv); - return rv; - } - - uint64_t windowId; - rv = GetWindowIdBySessionIdInternal(sessionId, - nsIPresentationService::ROLE_RECEIVER, - &windowId); - if (NS_WARN_IF(NS_FAILED(rv))) { - ctrlChannel->Disconnect(rv); - return rv; - } - - RefPtr info = - GetSessionInfo(sessionId, nsIPresentationService::ROLE_RECEIVER); - if (NS_WARN_IF(!info)) { - // Cannot reconnect non-existed session - ctrlChannel->Disconnect(NS_ERROR_DOM_OPERATION_ERR); - return NS_ERROR_DOM_ABORT_ERR; - } - - nsAutoString url; - rv = aRequest->GetUrl(url); - if (NS_WARN_IF(NS_FAILED(rv))) { - ctrlChannel->Disconnect(rv); - return rv; - } - - // Make sure the url is the same as the previous one. - if (NS_WARN_IF(!info->GetUrl().Equals(url))) { - ctrlChannel->Disconnect(rv); - return rv; - } - - return HandleSessionRequest(aRequest); -} - -NS_IMETHODIMP -PresentationService::StartSession( - const nsTArray& aUrls, - const nsAString& aSessionId, - const nsAString& aOrigin, - const nsAString& aDeviceId, - uint64_t aWindowId, - nsIDOMEventTarget* aEventTarget, - nsIPrincipal* aPrincipal, - nsIPresentationServiceCallback* aCallback, - nsIPresentationTransportBuilderConstructor* aBuilderConstructor) -{ - PRES_DEBUG("%s:id[%s]\n", __func__, NS_ConvertUTF16toUTF8(aSessionId).get()); - - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(aCallback); - MOZ_ASSERT(!aSessionId.IsEmpty()); - MOZ_ASSERT(!aUrls.IsEmpty()); - - nsCOMPtr request = - new PresentationDeviceRequest(aUrls, - aSessionId, - aOrigin, - aWindowId, - aEventTarget, - aPrincipal, - aCallback, - aBuilderConstructor); - - if (aDeviceId.IsVoid()) { - // Pop up a prompt and ask user to select a device. - nsCOMPtr prompt = - do_GetService(PRESENTATION_DEVICE_PROMPT_CONTRACTID); - if (NS_WARN_IF(!prompt)) { - return aCallback->NotifyError(NS_ERROR_DOM_INVALID_ACCESS_ERR); - } - - nsresult rv = prompt->PromptDeviceSelection(request); - if (NS_WARN_IF(NS_FAILED(rv))) { - return aCallback->NotifyError(NS_ERROR_DOM_OPERATION_ERR); - } - - return NS_OK; - } - - // Find the designated device from available device list. - nsCOMPtr deviceManager = - do_GetService(PRESENTATION_DEVICE_MANAGER_CONTRACTID); - if (NS_WARN_IF(!deviceManager)) { - return aCallback->NotifyError(NS_ERROR_DOM_OPERATION_ERR); - } - - nsCOMPtr presentationUrls; - if (NS_WARN_IF(NS_FAILED( - ConvertURLArrayHelper(aUrls, getter_AddRefs(presentationUrls))))) { - return aCallback->NotifyError(NS_ERROR_DOM_OPERATION_ERR); - } - - nsCOMPtr devices; - nsresult rv = deviceManager->GetAvailableDevices(presentationUrls, getter_AddRefs(devices)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return aCallback->NotifyError(NS_ERROR_DOM_OPERATION_ERR); - } - - nsCOMPtr enumerator; - rv = devices->Enumerate(getter_AddRefs(enumerator)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return aCallback->NotifyError(NS_ERROR_DOM_OPERATION_ERR); - } - - NS_ConvertUTF16toUTF8 utf8DeviceId(aDeviceId); - bool hasMore; - while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMore)) && hasMore) { - nsCOMPtr isupports; - rv = enumerator->GetNext(getter_AddRefs(isupports)); - - nsCOMPtr device(do_QueryInterface(isupports)); - MOZ_ASSERT(device); - - nsAutoCString id; - if (NS_SUCCEEDED(device->GetId(id)) && id.Equals(utf8DeviceId)) { - request->Select(device); - return NS_OK; - } - } - - // Reject if designated device is not available. - return aCallback->NotifyError(NS_ERROR_DOM_NOT_FOUND_ERR); -} - -already_AddRefed -PresentationService::CreateControllingSessionInfo(const nsAString& aUrl, - const nsAString& aSessionId, - uint64_t aWindowId) -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (aSessionId.IsEmpty()) { - return nullptr; - } - - RefPtr info = - new PresentationControllingInfo(aUrl, aSessionId); - - mSessionInfoAtController.Put(aSessionId, info); - AddRespondingSessionId(aWindowId, - aSessionId, - nsIPresentationService::ROLE_CONTROLLER); - return info.forget(); -} - -NS_IMETHODIMP -PresentationService::SendSessionMessage(const nsAString& aSessionId, - uint8_t aRole, - const nsAString& aData) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(!aData.IsEmpty()); - MOZ_ASSERT(!aSessionId.IsEmpty()); - MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER || - aRole == nsIPresentationService::ROLE_RECEIVER); - - RefPtr info = GetSessionInfo(aSessionId, aRole); - if (NS_WARN_IF(!info)) { - return NS_ERROR_NOT_AVAILABLE; - } - - return info->Send(aData); -} - -NS_IMETHODIMP -PresentationService::SendSessionBinaryMsg(const nsAString& aSessionId, - uint8_t aRole, - const nsACString &aData) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(!aData.IsEmpty()); - MOZ_ASSERT(!aSessionId.IsEmpty()); - MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER || - aRole == nsIPresentationService::ROLE_RECEIVER); - - RefPtr info = GetSessionInfo(aSessionId, aRole); - if (NS_WARN_IF(!info)) { - return NS_ERROR_NOT_AVAILABLE; - } - - return info->SendBinaryMsg(aData); -} - -NS_IMETHODIMP -PresentationService::SendSessionBlob(const nsAString& aSessionId, - uint8_t aRole, - nsIDOMBlob* aBlob) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(!aSessionId.IsEmpty()); - MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER || - aRole == nsIPresentationService::ROLE_RECEIVER); - MOZ_ASSERT(aBlob); - - RefPtr info = GetSessionInfo(aSessionId, aRole); - if (NS_WARN_IF(!info)) { - return NS_ERROR_NOT_AVAILABLE; - } - - return info->SendBlob(aBlob); -} - -NS_IMETHODIMP -PresentationService::CloseSession(const nsAString& aSessionId, - uint8_t aRole, - uint8_t aClosedReason) -{ - PRES_DEBUG("%s:id[%s], reason[%x], role[%d]\n", __func__, - NS_ConvertUTF16toUTF8(aSessionId).get(), aClosedReason, aRole); - - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(!aSessionId.IsEmpty()); - MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER || - aRole == nsIPresentationService::ROLE_RECEIVER); - - RefPtr info = GetSessionInfo(aSessionId, aRole); - if (NS_WARN_IF(!info)) { - return NS_ERROR_NOT_AVAILABLE; - } - - if (aClosedReason == nsIPresentationService::CLOSED_REASON_WENTAWAY) { - // Remove nsIPresentationSessionListener since we don't want to dispatch - // PresentationConnectionCloseEvent if the page is went away. - info->SetListener(nullptr); - } - - return info->Close(NS_OK, nsIPresentationSessionListener::STATE_CLOSED); -} - -NS_IMETHODIMP -PresentationService::TerminateSession(const nsAString& aSessionId, - uint8_t aRole) -{ - PRES_DEBUG("%s:id[%s], role[%d]\n", __func__, - NS_ConvertUTF16toUTF8(aSessionId).get(), aRole); - - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(!aSessionId.IsEmpty()); - MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER || - aRole == nsIPresentationService::ROLE_RECEIVER); - - RefPtr info = GetSessionInfo(aSessionId, aRole); - if (NS_WARN_IF(!info)) { - return NS_ERROR_NOT_AVAILABLE; - } - - return info->Close(NS_OK, nsIPresentationSessionListener::STATE_TERMINATED); -} - -NS_IMETHODIMP -PresentationService::ReconnectSession(const nsTArray& aUrls, - const nsAString& aSessionId, - uint8_t aRole, - nsIPresentationServiceCallback* aCallback) -{ - PRES_DEBUG("%s:id[%s]\n", __func__, NS_ConvertUTF16toUTF8(aSessionId).get()); - - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(!aSessionId.IsEmpty()); - MOZ_ASSERT(aCallback); - MOZ_ASSERT(!aUrls.IsEmpty()); - - if (aRole != nsIPresentationService::ROLE_CONTROLLER) { - MOZ_ASSERT(false, "Only controller can call ReconnectSession."); - return NS_ERROR_INVALID_ARG; - } - - if (NS_WARN_IF(!aCallback)) { - return NS_ERROR_INVALID_ARG; - } - - RefPtr info = GetSessionInfo(aSessionId, aRole); - if (NS_WARN_IF(!info)) { - return aCallback->NotifyError(NS_ERROR_DOM_NOT_FOUND_ERR); - } - - if (NS_WARN_IF(!aUrls.Contains(info->GetUrl()))) { - return aCallback->NotifyError(NS_ERROR_DOM_NOT_FOUND_ERR); - } - - return static_cast(info.get())->Reconnect(aCallback); -} - -NS_IMETHODIMP -PresentationService::BuildTransport(const nsAString& aSessionId, - uint8_t aRole) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(!aSessionId.IsEmpty()); - - if (aRole != nsIPresentationService::ROLE_CONTROLLER) { - MOZ_ASSERT(false, "Only controller can call BuildTransport."); - return NS_ERROR_INVALID_ARG; - } - - RefPtr info = GetSessionInfo(aSessionId, aRole); - if (NS_WARN_IF(!info)) { - return NS_ERROR_NOT_AVAILABLE; - } - - return static_cast(info.get())->BuildTransport(); -} - -NS_IMETHODIMP -PresentationService::RegisterAvailabilityListener( - const nsTArray& aAvailabilityUrls, - nsIPresentationAvailabilityListener* aListener) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(!aAvailabilityUrls.IsEmpty()); - MOZ_ASSERT(aListener); - - mAvailabilityManager.AddAvailabilityListener(aAvailabilityUrls, aListener); - return UpdateAvailabilityUrlChange(aAvailabilityUrls); -} - -NS_IMETHODIMP -PresentationService::UnregisterAvailabilityListener( - const nsTArray& aAvailabilityUrls, - nsIPresentationAvailabilityListener* aListener) -{ - MOZ_ASSERT(NS_IsMainThread()); - - mAvailabilityManager.RemoveAvailabilityListener(aAvailabilityUrls, aListener); - return NS_OK; -} - -NS_IMETHODIMP -PresentationService::RegisterSessionListener(const nsAString& aSessionId, - uint8_t aRole, - nsIPresentationSessionListener* aListener) -{ - PRES_DEBUG("%s:id[%s], role[%d]\n", __func__, - NS_ConvertUTF16toUTF8(aSessionId).get(), aRole); - - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(aListener); - MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER || - aRole == nsIPresentationService::ROLE_RECEIVER); - - RefPtr info = GetSessionInfo(aSessionId, aRole); - if (NS_WARN_IF(!info)) { - // Notify the listener of TERMINATED since no correspondent session info is - // available possibly due to establishment failure. This would be useful at - // the receiver side, since a presentation session is created at beginning - // and here is the place to realize the underlying establishment fails. - nsresult rv = aListener->NotifyStateChange(aSessionId, - nsIPresentationSessionListener::STATE_TERMINATED, - NS_ERROR_NOT_AVAILABLE); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - return NS_ERROR_NOT_AVAILABLE; - } - - return info->SetListener(aListener); -} - -NS_IMETHODIMP -PresentationService::UnregisterSessionListener(const nsAString& aSessionId, - uint8_t aRole) -{ - PRES_DEBUG("%s:id[%s], role[%d]\n", __func__, - NS_ConvertUTF16toUTF8(aSessionId).get(), aRole); - - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER || - aRole == nsIPresentationService::ROLE_RECEIVER); - - RefPtr info = GetSessionInfo(aSessionId, aRole); - if (info) { - // When content side decide not handling this session anymore, simply - // close the connection. Session info is kept for reconnection. - Unused << NS_WARN_IF(NS_FAILED(info->Close(NS_OK, nsIPresentationSessionListener::STATE_CLOSED))); - return info->SetListener(nullptr); - } - return NS_OK; -} - -NS_IMETHODIMP -PresentationService::RegisterRespondingListener( - uint64_t aWindowId, - nsIPresentationRespondingListener* aListener) -{ - PRES_DEBUG("%s:windowId[%lld]\n", __func__, aWindowId); - - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(aListener); - - nsCOMPtr listener; - if (mRespondingListeners.Get(aWindowId, getter_AddRefs(listener))) { - return (listener == aListener) ? NS_OK : NS_ERROR_DOM_INVALID_STATE_ERR; - } - - nsTArray sessionIdArray; - nsresult rv = mReceiverSessionIdManager.GetSessionIds(aWindowId, - sessionIdArray); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - for (const auto& id : sessionIdArray) { - aListener->NotifySessionConnect(aWindowId, id); - } - - mRespondingListeners.Put(aWindowId, aListener); - return NS_OK; -} - -NS_IMETHODIMP -PresentationService::UnregisterRespondingListener(uint64_t aWindowId) -{ - PRES_DEBUG("%s:windowId[%lld]\n", __func__, aWindowId); - - MOZ_ASSERT(NS_IsMainThread()); - - mRespondingListeners.Remove(aWindowId); - return NS_OK; -} - -NS_IMETHODIMP -PresentationService::NotifyReceiverReady( - const nsAString& aSessionId, - uint64_t aWindowId, - bool aIsLoading, - nsIPresentationTransportBuilderConstructor* aBuilderConstructor) -{ - PRES_DEBUG("%s:id[%s], windowId[%lld], loading[%d]\n", __func__, - NS_ConvertUTF16toUTF8(aSessionId).get(), aWindowId, aIsLoading); - - RefPtr info = - GetSessionInfo(aSessionId, nsIPresentationService::ROLE_RECEIVER); - if (NS_WARN_IF(!info)) { - return NS_ERROR_NOT_AVAILABLE; - } - - AddRespondingSessionId(aWindowId, - aSessionId, - nsIPresentationService::ROLE_RECEIVER); - - if (!aIsLoading) { - return static_cast( - info.get())->NotifyResponderFailure(); - } - - nsCOMPtr listener; - if (mRespondingListeners.Get(aWindowId, getter_AddRefs(listener))) { - nsresult rv = listener->NotifySessionConnect(aWindowId, aSessionId); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - } - - info->SetTransportBuilderConstructor(aBuilderConstructor); - return static_cast(info.get())->NotifyResponderReady(); -} - -nsresult -PresentationService::NotifyTransportClosed(const nsAString& aSessionId, - uint8_t aRole, - nsresult aReason) -{ - PRES_DEBUG("%s:id[%s], reason[%x], role[%d]\n", __func__, - NS_ConvertUTF16toUTF8(aSessionId).get(), aReason, aRole); - - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(!aSessionId.IsEmpty()); - MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER || - aRole == nsIPresentationService::ROLE_RECEIVER); - - RefPtr info = GetSessionInfo(aSessionId, aRole); - if (NS_WARN_IF(!info)) { - return NS_ERROR_NOT_AVAILABLE; - } - - return info->NotifyTransportClosed(aReason); -} - -NS_IMETHODIMP -PresentationService::UntrackSessionInfo(const nsAString& aSessionId, - uint8_t aRole) -{ - PRES_DEBUG("%s:id[%s], role[%d]\n", __func__, - NS_ConvertUTF16toUTF8(aSessionId).get(), aRole); - - MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER || - aRole == nsIPresentationService::ROLE_RECEIVER); - // Remove the session info. - if (nsIPresentationService::ROLE_CONTROLLER == aRole) { - mSessionInfoAtController.Remove(aSessionId); - } else { - // Terminate receiver page. - uint64_t windowId; - nsresult rv = GetWindowIdBySessionIdInternal(aSessionId, aRole, &windowId); - if (NS_SUCCEEDED(rv)) { - NS_DispatchToMainThread(NS_NewRunnableFunction([windowId]() -> void { - PRES_DEBUG("Attempt to close window[%d]\n", windowId); - - if (auto* window = nsGlobalWindow::GetInnerWindowWithId(windowId)) { - window->Close(); - } - })); - } - - mSessionInfoAtReceiver.Remove(aSessionId); - } - - // Remove the in-process responding info if there's still any. - RemoveRespondingSessionId(aSessionId, aRole); - - return NS_OK; -} - -NS_IMETHODIMP -PresentationService::GetWindowIdBySessionId(const nsAString& aSessionId, - uint8_t aRole, - uint64_t* aWindowId) -{ - return GetWindowIdBySessionIdInternal(aSessionId, aRole, aWindowId); -} - -NS_IMETHODIMP -PresentationService::UpdateWindowIdBySessionId(const nsAString& aSessionId, - uint8_t aRole, - const uint64_t aWindowId) -{ - return UpdateWindowIdBySessionIdInternal(aSessionId, aRole, aWindowId); -} - -bool -PresentationService::IsSessionAccessible(const nsAString& aSessionId, - const uint8_t aRole, - base::ProcessId aProcessId) -{ - MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER || - aRole == nsIPresentationService::ROLE_RECEIVER); - RefPtr info = GetSessionInfo(aSessionId, aRole); - if (NS_WARN_IF(!info)) { - return false; - } - return info->IsAccessible(aProcessId); -} - -} // namespace dom -} // namespace mozilla - -already_AddRefed -NS_CreatePresentationService() -{ - MOZ_ASSERT(NS_IsMainThread()); - - nsCOMPtr service; - if (XRE_GetProcessType() == GeckoProcessType_Content) { - service = new mozilla::dom::PresentationIPCService(); - } else { - service = new PresentationService(); - if (NS_WARN_IF(!static_cast(service.get())->Init())) { - return nullptr; - } - } - - return service.forget(); -} diff --git a/dom/presentation/PresentationService.h b/dom/presentation/PresentationService.h deleted file mode 100644 index b2d39e6915..0000000000 --- a/dom/presentation/PresentationService.h +++ /dev/null @@ -1,68 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_dom_PresentationService_h -#define mozilla_dom_PresentationService_h - -#include "nsCOMPtr.h" -#include "nsIObserver.h" -#include "PresentationServiceBase.h" -#include "PresentationSessionInfo.h" - -class nsIPresentationSessionRequest; -class nsIPresentationTerminateRequest; -class nsIURI; -class nsIPresentationSessionTransportBuilder; - -namespace mozilla { -namespace dom { - -class PresentationDeviceRequest; -class PresentationRespondingInfo; - -class PresentationService final - : public nsIPresentationService - , public nsIObserver - , public PresentationServiceBase -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIOBSERVER - NS_DECL_NSIPRESENTATIONSERVICE - - PresentationService(); - bool Init(); - - bool IsSessionAccessible(const nsAString& aSessionId, - const uint8_t aRole, - base::ProcessId aProcessId); - -private: - friend class PresentationDeviceRequest; - - virtual ~PresentationService(); - void HandleShutdown(); - nsresult HandleDeviceAdded(nsIPresentationDevice* aDevice); - nsresult HandleDeviceRemoved(); - nsresult HandleSessionRequest(nsIPresentationSessionRequest* aRequest); - nsresult HandleTerminateRequest(nsIPresentationTerminateRequest* aRequest); - nsresult HandleReconnectRequest(nsIPresentationSessionRequest* aRequest); - - // This is meant to be called by PresentationDeviceRequest. - already_AddRefed - CreateControllingSessionInfo(const nsAString& aUrl, - const nsAString& aSessionId, - uint64_t aWindowId); - - // Emumerate all devices to get the availability of each input Urls. - nsresult UpdateAvailabilityUrlChange( - const nsTArray& aAvailabilityUrls); -}; - -} // namespace dom -} // namespace mozilla - -#endif // mozilla_dom_PresentationService_h diff --git a/dom/presentation/PresentationServiceBase.h b/dom/presentation/PresentationServiceBase.h deleted file mode 100644 index 227e954306..0000000000 --- a/dom/presentation/PresentationServiceBase.h +++ /dev/null @@ -1,401 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set sw=2 ts=8 et 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/. */ - -#ifndef mozilla_dom_PresentationServiceBase_h -#define mozilla_dom_PresentationServiceBase_h - -#include "mozilla/Unused.h" -#include "nsClassHashtable.h" -#include "nsCOMArray.h" -#include "nsIPresentationListener.h" -#include "nsIPresentationService.h" -#include "nsRefPtrHashtable.h" -#include "nsString.h" -#include "nsTArray.h" - -namespace mozilla { -namespace dom { - -template -class PresentationServiceBase -{ -public: - PresentationServiceBase() = default; - - already_AddRefed - GetSessionInfo(const nsAString& aSessionId, const uint8_t aRole) - { - MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER || - aRole == nsIPresentationService::ROLE_RECEIVER); - - RefPtr info; - if (aRole == nsIPresentationService::ROLE_CONTROLLER) { - return mSessionInfoAtController.Get(aSessionId, getter_AddRefs(info)) ? - info.forget() : nullptr; - } else { - return mSessionInfoAtReceiver.Get(aSessionId, getter_AddRefs(info)) ? - info.forget() : nullptr; - } - } - -protected: - class SessionIdManager final - { - public: - explicit SessionIdManager() - { - MOZ_COUNT_CTOR(SessionIdManager); - } - - ~SessionIdManager() - { - MOZ_COUNT_DTOR(SessionIdManager); - } - - nsresult GetWindowId(const nsAString& aSessionId, uint64_t* aWindowId) - { - MOZ_ASSERT(NS_IsMainThread()); - - if (mRespondingWindowIds.Get(aSessionId, aWindowId)) { - return NS_OK; - } - return NS_ERROR_NOT_AVAILABLE; - } - - nsresult GetSessionIds(uint64_t aWindowId, nsTArray& aSessionIds) - { - MOZ_ASSERT(NS_IsMainThread()); - - nsTArray* sessionIdArray; - if (!mRespondingSessionIds.Get(aWindowId, &sessionIdArray)) { - return NS_ERROR_INVALID_ARG; - } - - aSessionIds.Assign(*sessionIdArray); - return NS_OK; - } - - void AddSessionId(uint64_t aWindowId, const nsAString& aSessionId) - { - MOZ_ASSERT(NS_IsMainThread()); - - if (NS_WARN_IF(aWindowId == 0)) { - return; - } - - nsTArray* sessionIdArray; - if (!mRespondingSessionIds.Get(aWindowId, &sessionIdArray)) { - sessionIdArray = new nsTArray(); - mRespondingSessionIds.Put(aWindowId, sessionIdArray); - } - - sessionIdArray->AppendElement(nsString(aSessionId)); - mRespondingWindowIds.Put(aSessionId, aWindowId); - } - - void RemoveSessionId(const nsAString& aSessionId) - { - MOZ_ASSERT(NS_IsMainThread()); - - uint64_t windowId = 0; - if (mRespondingWindowIds.Get(aSessionId, &windowId)) { - mRespondingWindowIds.Remove(aSessionId); - nsTArray* sessionIdArray; - if (mRespondingSessionIds.Get(windowId, &sessionIdArray)) { - sessionIdArray->RemoveElement(nsString(aSessionId)); - if (sessionIdArray->IsEmpty()) { - mRespondingSessionIds.Remove(windowId); - } - } - } - } - - nsresult UpdateWindowId(const nsAString& aSessionId, const uint64_t aWindowId) - { - MOZ_ASSERT(NS_IsMainThread()); - - RemoveSessionId(aSessionId); - AddSessionId(aWindowId, aSessionId); - return NS_OK; - } - - void Clear() - { - mRespondingSessionIds.Clear(); - mRespondingWindowIds.Clear(); - } - - private: - nsClassHashtable> mRespondingSessionIds; - nsDataHashtable mRespondingWindowIds; - }; - - class AvailabilityManager final - { - public: - explicit AvailabilityManager() - { - MOZ_COUNT_CTOR(AvailabilityManager); - } - - ~AvailabilityManager() - { - MOZ_COUNT_DTOR(AvailabilityManager); - } - - void AddAvailabilityListener( - const nsTArray& aAvailabilityUrls, - nsIPresentationAvailabilityListener* aListener) - { - nsTArray dummy; - AddAvailabilityListener(aAvailabilityUrls, aListener, dummy); - } - - void AddAvailabilityListener( - const nsTArray& aAvailabilityUrls, - nsIPresentationAvailabilityListener* aListener, - nsTArray& aAddedUrls) - { - if (!aListener) { - MOZ_ASSERT(false, "aListener should not be null."); - return; - } - - if (aAvailabilityUrls.IsEmpty()) { - MOZ_ASSERT(false, "aAvailabilityUrls should not be empty."); - return; - } - - aAddedUrls.Clear(); - nsTArray knownAvailableUrls; - for (const auto& url : aAvailabilityUrls) { - AvailabilityEntry* entry; - if (!mAvailabilityUrlTable.Get(url, &entry)) { - entry = new AvailabilityEntry(); - mAvailabilityUrlTable.Put(url, entry); - aAddedUrls.AppendElement(url); - } - if (!entry->mListeners.Contains(aListener)) { - entry->mListeners.AppendElement(aListener); - } - if (entry->mAvailable) { - knownAvailableUrls.AppendElement(url); - } - } - - if (!knownAvailableUrls.IsEmpty()) { - Unused << - NS_WARN_IF( - NS_FAILED(aListener->NotifyAvailableChange(knownAvailableUrls, - true))); - } else { - // If we can't find any known available url and there is no newly - // added url, we still need to notify the listener of the result. - // So, the promise returned by |getAvailability| can be resolved. - if (aAddedUrls.IsEmpty()) { - Unused << - NS_WARN_IF( - NS_FAILED(aListener->NotifyAvailableChange(aAvailabilityUrls, - false))); - } - } - } - - void RemoveAvailabilityListener( - const nsTArray& aAvailabilityUrls, - nsIPresentationAvailabilityListener* aListener) - { - nsTArray dummy; - RemoveAvailabilityListener(aAvailabilityUrls, aListener, dummy); - } - - void RemoveAvailabilityListener( - const nsTArray& aAvailabilityUrls, - nsIPresentationAvailabilityListener* aListener, - nsTArray& aRemovedUrls) - { - if (!aListener) { - MOZ_ASSERT(false, "aListener should not be null."); - return; - } - - if (aAvailabilityUrls.IsEmpty()) { - MOZ_ASSERT(false, "aAvailabilityUrls should not be empty."); - return; - } - - aRemovedUrls.Clear(); - for (const auto& url : aAvailabilityUrls) { - AvailabilityEntry* entry; - if (mAvailabilityUrlTable.Get(url, &entry)) { - entry->mListeners.RemoveElement(aListener); - if (entry->mListeners.IsEmpty()) { - mAvailabilityUrlTable.Remove(url); - aRemovedUrls.AppendElement(url); - } - } - } - } - - nsresult DoNotifyAvailableChange(const nsTArray& aAvailabilityUrls, - bool aAvailable) - { - typedef nsClassHashtable> ListenerToUrlsMap; - ListenerToUrlsMap availabilityListenerTable; - // Create a mapping from nsIPresentationAvailabilityListener to - // availabilityUrls. - for (auto it = mAvailabilityUrlTable.ConstIter(); !it.Done(); it.Next()) { - if (aAvailabilityUrls.Contains(it.Key())) { - AvailabilityEntry* entry = it.UserData(); - entry->mAvailable = aAvailable; - - for (uint32_t i = 0; i < entry->mListeners.Length(); ++i) { - nsIPresentationAvailabilityListener* listener = - entry->mListeners.ObjectAt(i); - nsTArray* urlArray; - if (!availabilityListenerTable.Get(listener, &urlArray)) { - urlArray = new nsTArray(); - availabilityListenerTable.Put(listener, urlArray); - } - urlArray->AppendElement(it.Key()); - } - } - } - - for (auto it = availabilityListenerTable.Iter(); !it.Done(); it.Next()) { - auto listener = - static_cast(it.Key()); - - Unused << - NS_WARN_IF(NS_FAILED(listener->NotifyAvailableChange(*it.UserData(), - aAvailable))); - } - return NS_OK; - } - - void GetAvailbilityUrlByAvailability(nsTArray& aOutArray, - bool aAvailable) - { - aOutArray.Clear(); - - for (auto it = mAvailabilityUrlTable.ConstIter(); !it.Done(); it.Next()) { - if (it.UserData()->mAvailable == aAvailable) { - aOutArray.AppendElement(it.Key()); - } - } - } - - void Clear() - { - mAvailabilityUrlTable.Clear(); - } - - private: - struct AvailabilityEntry - { - explicit AvailabilityEntry() - : mAvailable(false) - {} - - bool mAvailable; - nsCOMArray mListeners; - }; - - nsClassHashtable mAvailabilityUrlTable; - }; - - virtual ~PresentationServiceBase() = default; - - void Shutdown() - { - mRespondingListeners.Clear(); - mControllerSessionIdManager.Clear(); - mReceiverSessionIdManager.Clear(); - } - - nsresult GetWindowIdBySessionIdInternal(const nsAString& aSessionId, - uint8_t aRole, - uint64_t* aWindowId) - { - MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER || - aRole == nsIPresentationService::ROLE_RECEIVER); - - if (NS_WARN_IF(!aWindowId)) { - return NS_ERROR_INVALID_POINTER; - } - - if (aRole == nsIPresentationService::ROLE_CONTROLLER) { - return mControllerSessionIdManager.GetWindowId(aSessionId, aWindowId); - } - - return mReceiverSessionIdManager.GetWindowId(aSessionId, aWindowId); - } - - void AddRespondingSessionId(uint64_t aWindowId, - const nsAString& aSessionId, - uint8_t aRole) - { - MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER || - aRole == nsIPresentationService::ROLE_RECEIVER); - - if (aRole == nsIPresentationService::ROLE_CONTROLLER) { - mControllerSessionIdManager.AddSessionId(aWindowId, aSessionId); - } else { - mReceiverSessionIdManager.AddSessionId(aWindowId, aSessionId); - } - } - - void RemoveRespondingSessionId(const nsAString& aSessionId, - uint8_t aRole) - { - MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER || - aRole == nsIPresentationService::ROLE_RECEIVER); - - if (aRole == nsIPresentationService::ROLE_CONTROLLER) { - mControllerSessionIdManager.RemoveSessionId(aSessionId); - } else { - mReceiverSessionIdManager.RemoveSessionId(aSessionId); - } - } - - nsresult UpdateWindowIdBySessionIdInternal(const nsAString& aSessionId, - uint8_t aRole, - const uint64_t aWindowId) - { - MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER || - aRole == nsIPresentationService::ROLE_RECEIVER); - - if (aRole == nsIPresentationService::ROLE_CONTROLLER) { - return mControllerSessionIdManager.UpdateWindowId(aSessionId, aWindowId); - } - - return mReceiverSessionIdManager.UpdateWindowId(aSessionId, aWindowId); - } - - // Store the responding listener based on the window ID of the (in-process or - // OOP) receiver page. - nsRefPtrHashtable - mRespondingListeners; - - // Store the mapping between the window ID of the in-process and OOP page and the ID - // of the responding session. It's used for both controller and receiver page - // to retrieve the correspondent session ID. Besides, also keep the mapping - // between the responding session ID and the window ID to help look up the - // window ID. - SessionIdManager mControllerSessionIdManager; - SessionIdManager mReceiverSessionIdManager; - - nsRefPtrHashtable mSessionInfoAtController; - nsRefPtrHashtable mSessionInfoAtReceiver; - - AvailabilityManager mAvailabilityManager; -}; - -} // namespace dom -} // namespace mozilla - -#endif // mozilla_dom_PresentationServiceBase_h diff --git a/dom/presentation/PresentationSessionInfo.cpp b/dom/presentation/PresentationSessionInfo.cpp deleted file mode 100644 index 1dd92ab69d..0000000000 --- a/dom/presentation/PresentationSessionInfo.cpp +++ /dev/null @@ -1,1617 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* 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 "mozilla/dom/ContentParent.h" -#include "mozilla/dom/HTMLIFrameElementBinding.h" -#include "mozilla/dom/TabParent.h" -#include "mozilla/Function.h" -#include "mozilla/Logging.h" -#include "mozilla/Move.h" -#include "mozilla/Preferences.h" -#include "mozilla/Services.h" -#include "nsContentUtils.h" -#include "nsGlobalWindow.h" -#include "nsIDocShell.h" -#include "nsFrameLoader.h" -#include "nsIMutableArray.h" -#include "nsINetAddr.h" -#include "nsISocketTransport.h" -#include "nsISupportsPrimitives.h" -#include "nsNetCID.h" -#include "nsServiceManagerUtils.h" -#include "nsThreadUtils.h" -#include "PresentationLog.h" -#include "PresentationService.h" -#include "PresentationSessionInfo.h" - -#ifdef MOZ_WIDGET_ANDROID -#include "nsIPresentationNetworkHelper.h" -#endif // MOZ_WIDGET_ANDROID - -using namespace mozilla; -using namespace mozilla::dom; -using namespace mozilla::services; - -/* - * Implementation of PresentationChannelDescription - */ - -namespace mozilla { -namespace dom { - -#ifdef MOZ_WIDGET_ANDROID - -namespace { - -class PresentationNetworkHelper final : public nsIPresentationNetworkHelperListener -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIPRESENTATIONNETWORKHELPERLISTENER - - using Function = nsresult(PresentationControllingInfo::*)(const nsACString&); - - explicit PresentationNetworkHelper(PresentationControllingInfo* aInfo, - const Function& aFunc); - - nsresult GetWifiIPAddress(); - -private: - ~PresentationNetworkHelper() = default; - - RefPtr mInfo; - Function mFunc; -}; - -NS_IMPL_ISUPPORTS(PresentationNetworkHelper, - nsIPresentationNetworkHelperListener) - -PresentationNetworkHelper::PresentationNetworkHelper(PresentationControllingInfo* aInfo, - const Function& aFunc) - : mInfo(aInfo) - , mFunc(aFunc) -{ - MOZ_ASSERT(aInfo); - MOZ_ASSERT(aFunc); -} - -nsresult -PresentationNetworkHelper::GetWifiIPAddress() -{ - nsresult rv; - - nsCOMPtr networkHelper = - do_GetService(PRESENTATION_NETWORK_HELPER_CONTRACTID, &rv); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - return networkHelper->GetWifiIPAddress(this); -} - -NS_IMETHODIMP -PresentationNetworkHelper::OnError(const nsACString & aReason) -{ - PRES_ERROR("PresentationNetworkHelper::OnError: %s", - nsPromiseFlatCString(aReason).get()); - return NS_OK; -} - -NS_IMETHODIMP -PresentationNetworkHelper::OnGetWifiIPAddress(const nsACString& aIPAddress) -{ - MOZ_ASSERT(mInfo); - MOZ_ASSERT(mFunc); - - NS_DispatchToMainThread( - NewRunnableMethod(mInfo, - mFunc, - aIPAddress)); - return NS_OK; -} - -} // anonymous namespace - -#endif // MOZ_WIDGET_ANDROID - -class TCPPresentationChannelDescription final : public nsIPresentationChannelDescription -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIPRESENTATIONCHANNELDESCRIPTION - - TCPPresentationChannelDescription(const nsACString& aAddress, - uint16_t aPort) - : mAddress(aAddress) - , mPort(aPort) - { - } - -private: - ~TCPPresentationChannelDescription() {} - - nsCString mAddress; - uint16_t mPort; -}; - -} // namespace dom -} // namespace mozilla - -NS_IMPL_ISUPPORTS(TCPPresentationChannelDescription, nsIPresentationChannelDescription) - -NS_IMETHODIMP -TCPPresentationChannelDescription::GetType(uint8_t* aRetVal) -{ - if (NS_WARN_IF(!aRetVal)) { - return NS_ERROR_INVALID_POINTER; - } - - *aRetVal = nsIPresentationChannelDescription::TYPE_TCP; - return NS_OK; -} - -NS_IMETHODIMP -TCPPresentationChannelDescription::GetTcpAddress(nsIArray** aRetVal) -{ - if (NS_WARN_IF(!aRetVal)) { - return NS_ERROR_INVALID_POINTER; - } - - nsCOMPtr array = do_CreateInstance(NS_ARRAY_CONTRACTID); - if (NS_WARN_IF(!array)) { - return NS_ERROR_OUT_OF_MEMORY; - } - - // TODO bug 1228504 Take all IP addresses in PresentationChannelDescription - // into account. And at the first stage Presentation API is only exposed on - // Firefox OS where the first IP appears enough for most scenarios. - nsCOMPtr address = do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID); - if (NS_WARN_IF(!address)) { - return NS_ERROR_OUT_OF_MEMORY; - } - address->SetData(mAddress); - - array->AppendElement(address, false); - array.forget(aRetVal); - - return NS_OK; -} - -NS_IMETHODIMP -TCPPresentationChannelDescription::GetTcpPort(uint16_t* aRetVal) -{ - if (NS_WARN_IF(!aRetVal)) { - return NS_ERROR_INVALID_POINTER; - } - - *aRetVal = mPort; - return NS_OK; -} - -NS_IMETHODIMP -TCPPresentationChannelDescription::GetDataChannelSDP(nsAString& aDataChannelSDP) -{ - aDataChannelSDP.Truncate(); - return NS_OK; -} - -/* - * Implementation of PresentationSessionInfo - */ - -NS_IMPL_ISUPPORTS(PresentationSessionInfo, - nsIPresentationSessionTransportCallback, - nsIPresentationControlChannelListener, - nsIPresentationSessionTransportBuilderListener); - -/* virtual */ nsresult -PresentationSessionInfo::Init(nsIPresentationControlChannel* aControlChannel) -{ - SetControlChannel(aControlChannel); - return NS_OK; -} - -/* virtual */ void -PresentationSessionInfo::Shutdown(nsresult aReason) -{ - PRES_DEBUG("%s:id[%s], reason[%x], role[%d]\n", __func__, - NS_ConvertUTF16toUTF8(mSessionId).get(), aReason, mRole); - - NS_WARNING_ASSERTION(NS_SUCCEEDED(aReason), "bad reason"); - - // Close the control channel if any. - if (mControlChannel) { - Unused << NS_WARN_IF(NS_FAILED(mControlChannel->Disconnect(aReason))); - } - - // Close the data transport channel if any. - if (mTransport) { - // |mIsTransportReady| will be unset once |NotifyTransportClosed| is called. - Unused << NS_WARN_IF(NS_FAILED(mTransport->Close(aReason))); - } - - mIsResponderReady = false; - mIsOnTerminating = false; - - ResetBuilder(); -} - -nsresult -PresentationSessionInfo::SetListener(nsIPresentationSessionListener* aListener) -{ - mListener = aListener; - - if (mListener) { - // Enable data notification for the transport channel if it's available. - if (mTransport) { - nsresult rv = mTransport->EnableDataNotification(); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - } - - // The transport might become ready, or might become un-ready again, before - // the listener has registered. So notify the listener of the state change. - return mListener->NotifyStateChange(mSessionId, mState, mReason); - } - - return NS_OK; -} - -nsresult -PresentationSessionInfo::Send(const nsAString& aData) -{ - if (NS_WARN_IF(!IsSessionReady())) { - return NS_ERROR_DOM_INVALID_STATE_ERR; - } - - if (NS_WARN_IF(!mTransport)) { - return NS_ERROR_NOT_AVAILABLE; - } - - return mTransport->Send(aData); -} - -nsresult -PresentationSessionInfo::SendBinaryMsg(const nsACString& aData) -{ - if (NS_WARN_IF(!IsSessionReady())) { - return NS_ERROR_DOM_INVALID_STATE_ERR; - } - - if (NS_WARN_IF(!mTransport)) { - return NS_ERROR_NOT_AVAILABLE; - } - - return mTransport->SendBinaryMsg(aData); -} - -nsresult -PresentationSessionInfo::SendBlob(nsIDOMBlob* aBlob) -{ - if (NS_WARN_IF(!IsSessionReady())) { - return NS_ERROR_DOM_INVALID_STATE_ERR; - } - - if (NS_WARN_IF(!mTransport)) { - return NS_ERROR_NOT_AVAILABLE; - } - - return mTransport->SendBlob(aBlob); -} - -nsresult -PresentationSessionInfo::Close(nsresult aReason, - uint32_t aState) -{ - // Do nothing if session is already terminated. - if (nsIPresentationSessionListener::STATE_TERMINATED == mState) { - return NS_OK; - } - - SetStateWithReason(aState, aReason); - - switch (aState) { - case nsIPresentationSessionListener::STATE_CLOSED: { - Shutdown(aReason); - break; - } - case nsIPresentationSessionListener::STATE_TERMINATED: { - if (!mControlChannel) { - nsCOMPtr ctrlChannel; - nsresult rv = mDevice->EstablishControlChannel(getter_AddRefs(ctrlChannel)); - if (NS_FAILED(rv)) { - Shutdown(rv); - return rv; - } - - SetControlChannel(ctrlChannel); - return rv; - } - - ContinueTermination(); - return NS_OK; - } - } - - return NS_OK; -} - -nsresult -PresentationSessionInfo::OnTerminate(nsIPresentationControlChannel* aControlChannel) -{ - mIsOnTerminating = true; // Mark for terminating transport channel - SetStateWithReason(nsIPresentationSessionListener::STATE_TERMINATED, NS_OK); - SetControlChannel(aControlChannel); - - return NS_OK; -} - -nsresult -PresentationSessionInfo::ReplySuccess() -{ - SetStateWithReason(nsIPresentationSessionListener::STATE_CONNECTED, NS_OK); - return NS_OK; -} - -nsresult -PresentationSessionInfo::ReplyError(nsresult aError) -{ - Shutdown(aError); - - // Remove itself since it never succeeds. - return UntrackFromService(); -} - -/* virtual */ nsresult -PresentationSessionInfo::UntrackFromService() -{ - nsCOMPtr service = - do_GetService(PRESENTATION_SERVICE_CONTRACTID); - if (NS_WARN_IF(!service)) { - return NS_ERROR_NOT_AVAILABLE; - } - static_cast(service.get())->UntrackSessionInfo(mSessionId, mRole); - - return NS_OK; -} - -nsPIDOMWindowInner* -PresentationSessionInfo::GetWindow() -{ - nsCOMPtr service = - do_GetService(PRESENTATION_SERVICE_CONTRACTID); - if (NS_WARN_IF(!service)) { - return nullptr; - } - uint64_t windowId = 0; - if (NS_WARN_IF(NS_FAILED(service->GetWindowIdBySessionId(mSessionId, - mRole, - &windowId)))) { - return nullptr; - } - - auto window = nsGlobalWindow::GetInnerWindowWithId(windowId); - if (!window) { - return nullptr; - } - - return window->AsInner(); -} - -/* virtual */ bool -PresentationSessionInfo::IsAccessible(base::ProcessId aProcessId) -{ - // No restriction by default. - return true; -} - -void -PresentationSessionInfo::ContinueTermination() -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(mControlChannel); - - if (NS_WARN_IF(NS_FAILED(mControlChannel->Terminate(mSessionId))) - || mIsOnTerminating) { - Shutdown(NS_OK); - } -} - -// nsIPresentationSessionTransportCallback -NS_IMETHODIMP -PresentationSessionInfo::NotifyTransportReady() -{ - PRES_DEBUG("%s:id[%s], role[%d], state[%d]\n", __func__, - NS_ConvertUTF16toUTF8(mSessionId).get(), mRole, mState); - - MOZ_ASSERT(NS_IsMainThread()); - - if (mState != nsIPresentationSessionListener::STATE_CONNECTING && - mState != nsIPresentationSessionListener::STATE_CONNECTED) { - return NS_OK; - } - - mIsTransportReady = true; - - // Established RTCDataChannel implies responder is ready. - if (mTransportType == nsIPresentationChannelDescription::TYPE_DATACHANNEL) { - mIsResponderReady = true; - } - - // At sender side, session might not be ready at this point (waiting for - // receiver's answer). Yet at receiver side, session must be ready at this - // point since the data transport channel is created after the receiver page - // is ready for presentation use. - if (IsSessionReady()) { - return ReplySuccess(); - } - - return NS_OK; -} - -NS_IMETHODIMP -PresentationSessionInfo::NotifyTransportClosed(nsresult aReason) -{ - PRES_DEBUG("%s:id[%s], reason[%x], role[%d]\n", __func__, - NS_ConvertUTF16toUTF8(mSessionId).get(), aReason, mRole); - - MOZ_ASSERT(NS_IsMainThread()); - - // Nullify |mTransport| here so it won't try to re-close |mTransport| in - // potential subsequent |Shutdown| calls. - mTransport = nullptr; - - if (NS_WARN_IF(!IsSessionReady() && - mState == nsIPresentationSessionListener::STATE_CONNECTING)) { - // It happens before the session is ready. Reply the callback. - return ReplyError(NS_ERROR_DOM_OPERATION_ERR); - } - - // Unset |mIsTransportReady| here so it won't affect |IsSessionReady()| above. - mIsTransportReady = false; - - if (mState == nsIPresentationSessionListener::STATE_CONNECTED) { - // The transport channel is closed unexpectedly (not caused by a |Close| call). - SetStateWithReason(nsIPresentationSessionListener::STATE_CLOSED, aReason); - } - - Shutdown(aReason); - - if (mState == nsIPresentationSessionListener::STATE_TERMINATED) { - // Directly untrack the session info from the service. - return UntrackFromService(); - } - - return NS_OK; -} - -NS_IMETHODIMP -PresentationSessionInfo::NotifyData(const nsACString& aData, bool aIsBinary) -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (NS_WARN_IF(!IsSessionReady())) { - return NS_ERROR_DOM_INVALID_STATE_ERR; - } - - if (NS_WARN_IF(!mListener)) { - return NS_ERROR_NOT_AVAILABLE; - } - - return mListener->NotifyMessage(mSessionId, aData, aIsBinary); -} - -// nsIPresentationSessionTransportBuilderListener -NS_IMETHODIMP -PresentationSessionInfo::OnSessionTransport(nsIPresentationSessionTransport* aTransport) -{ - PRES_DEBUG("%s:id[%s], role[%d], state[%d]\n", __func__, - NS_ConvertUTF16toUTF8(mSessionId).get(), mRole, mState); - - ResetBuilder(); - - if (mState != nsIPresentationSessionListener::STATE_CONNECTING) { - return NS_ERROR_FAILURE; - } - - if (NS_WARN_IF(!aTransport)) { - return NS_ERROR_INVALID_ARG; - } - - mTransport = aTransport; - - nsresult rv = mTransport->SetCallback(this); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - if (mListener) { - mTransport->EnableDataNotification(); - } - - return NS_OK; -} - -NS_IMETHODIMP -PresentationSessionInfo::OnError(nsresult aReason) -{ - PRES_DEBUG("%s:id[%s], reason[%x], role[%d]\n", __func__, - NS_ConvertUTF16toUTF8(mSessionId).get(), aReason, mRole); - - ResetBuilder(); - return ReplyError(aReason); -} - -NS_IMETHODIMP -PresentationSessionInfo::SendOffer(nsIPresentationChannelDescription* aOffer) -{ - return mControlChannel->SendOffer(aOffer); -} - -NS_IMETHODIMP -PresentationSessionInfo::SendAnswer(nsIPresentationChannelDescription* aAnswer) -{ - return mControlChannel->SendAnswer(aAnswer); -} - -NS_IMETHODIMP -PresentationSessionInfo::SendIceCandidate(const nsAString& candidate) -{ - return mControlChannel->SendIceCandidate(candidate); -} - -NS_IMETHODIMP -PresentationSessionInfo::Close(nsresult reason) -{ - return mControlChannel->Disconnect(reason); -} - -/** - * Implementation of PresentationControllingInfo - * - * During presentation session establishment, the sender expects the following - * after trying to establish the control channel: (The order between step 3 and - * 4 is not guaranteed.) - * 1. |Init| is called to open a socket |mServerSocket| for data transport - * channel. - * 2. |NotifyConnected| of |nsIPresentationControlChannelListener| is called to - * indicate the control channel is ready to use. Then send the offer to the - * receiver via the control channel. - * 3.1 |OnSocketAccepted| of |nsIServerSocketListener| is called to indicate the - * data transport channel is connected. Then initialize |mTransport|. - * 3.2 |NotifyTransportReady| of |nsIPresentationSessionTransportCallback| is - * called. - * 4. |OnAnswer| of |nsIPresentationControlChannelListener| is called to - * indicate the receiver is ready. Close the control channel since it's no - * longer needed. - * 5. Once both step 3 and 4 are done, the presentation session is ready to use. - * So notify the listener of CONNECTED state. - */ - -NS_IMPL_ISUPPORTS_INHERITED(PresentationControllingInfo, - PresentationSessionInfo, - nsIServerSocketListener) - -nsresult -PresentationControllingInfo::Init(nsIPresentationControlChannel* aControlChannel) -{ - PresentationSessionInfo::Init(aControlChannel); - - // Initialize |mServerSocket| for bootstrapping the data transport channel and - // use |this| as the listener. - mServerSocket = do_CreateInstance(NS_SERVERSOCKET_CONTRACTID); - if (NS_WARN_IF(!mServerSocket)) { - return ReplyError(NS_ERROR_DOM_OPERATION_ERR); - } - - nsresult rv = mServerSocket->Init(-1, false, -1); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - rv = mServerSocket->AsyncListen(this); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - int32_t port; - rv = mServerSocket->GetPort(&port); - if (!NS_WARN_IF(NS_FAILED(rv))) { - PRES_DEBUG("%s:ServerSocket created.port[%d]\n",__func__, port); - } - - return NS_OK; -} - -void -PresentationControllingInfo::Shutdown(nsresult aReason) -{ - PresentationSessionInfo::Shutdown(aReason); - - // Close the server socket if any. - if (mServerSocket) { - Unused << NS_WARN_IF(NS_FAILED(mServerSocket->Close())); - mServerSocket = nullptr; - } -} - -nsresult -PresentationControllingInfo::GetAddress() -{ -#if defined(MOZ_WIDGET_ANDROID) - RefPtr networkHelper = - new PresentationNetworkHelper(this, - &PresentationControllingInfo::OnGetAddress); - nsresult rv = networkHelper->GetWifiIPAddress(); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - -#else - nsCOMPtr networkInfo = do_GetService(NETWORKINFOSERVICE_CONTRACT_ID); - MOZ_ASSERT(networkInfo); - - nsresult rv = networkInfo->ListNetworkAddresses(this); - - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } -#endif - - return NS_OK; -} - -nsresult -PresentationControllingInfo::OnGetAddress(const nsACString& aAddress) -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (NS_WARN_IF(!mServerSocket)) { - return NS_ERROR_FAILURE; - } - if (NS_WARN_IF(!mControlChannel)) { - return NS_ERROR_FAILURE; - } - - // Prepare and send the offer. - int32_t port; - nsresult rv = mServerSocket->GetPort(&port); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - RefPtr description = - new TCPPresentationChannelDescription(aAddress, static_cast(port)); - return mControlChannel->SendOffer(description); -} - -// nsIPresentationControlChannelListener -NS_IMETHODIMP -PresentationControllingInfo::OnIceCandidate(const nsAString& aCandidate) -{ - if (mTransportType != nsIPresentationChannelDescription::TYPE_DATACHANNEL) { - return NS_ERROR_FAILURE; - } - - nsCOMPtr - builder = do_QueryInterface(mBuilder); - - if (NS_WARN_IF(!builder)) { - return NS_ERROR_FAILURE; - } - - return builder->OnIceCandidate(aCandidate); -} - -NS_IMETHODIMP -PresentationControllingInfo::OnOffer(nsIPresentationChannelDescription* aDescription) -{ - MOZ_ASSERT(false, "Sender side should not receive offer."); - return NS_ERROR_FAILURE; -} - -NS_IMETHODIMP -PresentationControllingInfo::OnAnswer(nsIPresentationChannelDescription* aDescription) -{ - if (mTransportType == nsIPresentationChannelDescription::TYPE_DATACHANNEL) { - nsCOMPtr - builder = do_QueryInterface(mBuilder); - - if (NS_WARN_IF(!builder)) { - return NS_ERROR_FAILURE; - } - - return builder->OnAnswer(aDescription); - } - - mIsResponderReady = true; - - // Close the control channel since it's no longer needed. - nsresult rv = mControlChannel->Disconnect(NS_OK); - if (NS_WARN_IF(NS_FAILED(rv))) { - return ReplyError(NS_ERROR_DOM_OPERATION_ERR); - } - - // Session might not be ready at this moment (waiting for the establishment of - // the data transport channel). - if (IsSessionReady()){ - return ReplySuccess(); - } - - return NS_OK; -} - -NS_IMETHODIMP -PresentationControllingInfo::NotifyConnected() -{ - PRES_DEBUG("%s:id[%s], role[%d]\n", __func__, - NS_ConvertUTF16toUTF8(mSessionId).get(), mRole); - - MOZ_ASSERT(NS_IsMainThread()); - - switch (mState) { - case nsIPresentationSessionListener::STATE_CONNECTING: { - if (mIsReconnecting) { - return ContinueReconnect(); - } - - nsresult rv = mControlChannel->Launch(GetSessionId(), GetUrl()); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - Unused << NS_WARN_IF(NS_FAILED(BuildTransport())); - break; - } - case nsIPresentationSessionListener::STATE_TERMINATED: { - ContinueTermination(); - break; - } - default: - break; - } - - return NS_OK; -} - -NS_IMETHODIMP -PresentationControllingInfo::NotifyReconnected() -{ - PRES_DEBUG("%s:id[%s], role[%d]\n", __func__, - NS_ConvertUTF16toUTF8(mSessionId).get(), mRole); - - MOZ_ASSERT(NS_IsMainThread()); - - if (NS_WARN_IF(mState != nsIPresentationSessionListener::STATE_CONNECTING)) { - return NS_ERROR_FAILURE; - } - - return NotifyReconnectResult(NS_OK); -} - -nsresult -PresentationControllingInfo::BuildTransport() -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (mState != nsIPresentationSessionListener::STATE_CONNECTING) { - return NS_OK; - } - - if (NS_WARN_IF(!mBuilderConstructor)) { - return NS_ERROR_NOT_AVAILABLE; - } - - if (!Preferences::GetBool("dom.presentation.session_transport.data_channel.enable")) { - // Build TCP session transport - return GetAddress(); - } - /** - * Generally transport is maintained by the chrome process. However, data - * channel should be live with the DOM , which implies RTCDataChannel in an OOP - * page should be establish in the content process. - * - * |mBuilderConstructor| is responsible for creating a builder, which is for - * building a data channel transport. - * - * In the OOP case, |mBuilderConstructor| would create a builder which is - * an object of |PresentationBuilderParent|. So, |BuildDataChannelTransport| - * triggers an IPC call to make content process establish a RTCDataChannel - * transport. - */ - - mTransportType = nsIPresentationChannelDescription::TYPE_DATACHANNEL; - if (NS_WARN_IF(NS_FAILED( - mBuilderConstructor->CreateTransportBuilder(mTransportType, - getter_AddRefs(mBuilder))))) { - return NS_ERROR_NOT_AVAILABLE; - } - - nsCOMPtr - dataChannelBuilder(do_QueryInterface(mBuilder)); - if (NS_WARN_IF(!dataChannelBuilder)) { - return NS_ERROR_NOT_AVAILABLE; - } - - // OOP window would be set from content process - nsPIDOMWindowInner* window = GetWindow(); - - nsresult rv = dataChannelBuilder-> - BuildDataChannelTransport(nsIPresentationService::ROLE_CONTROLLER, - window, - this); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - return NS_OK; -} - -NS_IMETHODIMP -PresentationControllingInfo::NotifyDisconnected(nsresult aReason) -{ - PRES_DEBUG("%s:id[%s], reason[%x], role[%d]\n", __func__, - NS_ConvertUTF16toUTF8(mSessionId).get(), aReason, mRole); - - MOZ_ASSERT(NS_IsMainThread()); - - if (mTransportType == nsIPresentationChannelDescription::TYPE_DATACHANNEL) { - nsCOMPtr - builder = do_QueryInterface(mBuilder); - if (builder) { - Unused << NS_WARN_IF(NS_FAILED(builder->NotifyDisconnected(aReason))); - } - } - - // Unset control channel here so it won't try to re-close it in potential - // subsequent |Shutdown| calls. - SetControlChannel(nullptr); - - if (NS_WARN_IF(NS_FAILED(aReason) || !mIsResponderReady)) { - // The presentation session instance may already exist. - // Change the state to CLOSED if it is not terminated. - if (nsIPresentationSessionListener::STATE_TERMINATED != mState) { - SetStateWithReason(nsIPresentationSessionListener::STATE_CLOSED, aReason); - } - - // If |aReason| is NS_OK, it implies that the user closes the connection - // before becomming connected. No need to call |ReplyError| in this case. - if (NS_FAILED(aReason)) { - if (mIsReconnecting) { - NotifyReconnectResult(NS_ERROR_DOM_OPERATION_ERR); - } - // Reply error for an abnormal close. - return ReplyError(NS_ERROR_DOM_OPERATION_ERR); - } - Shutdown(aReason); - } - - // This is the case for reconnecting a connection which is in - // connecting state and |mTransport| is not ready. - if (mDoReconnectAfterClose && !mTransport) { - mDoReconnectAfterClose = false; - return Reconnect(mReconnectCallback); - } - - return NS_OK; -} - -// nsIServerSocketListener -NS_IMETHODIMP -PresentationControllingInfo::OnSocketAccepted(nsIServerSocket* aServerSocket, - nsISocketTransport* aTransport) -{ - int32_t port; - nsresult rv = aTransport->GetPort(&port); - if (!NS_WARN_IF(NS_FAILED(rv))) { - PRES_DEBUG("%s:receive from port[%d]\n",__func__, port); - } - - MOZ_ASSERT(NS_IsMainThread()); - - if (NS_WARN_IF(!mBuilderConstructor)) { - return ReplyError(NS_ERROR_DOM_OPERATION_ERR); - } - - // Initialize session transport builder and use |this| as the callback. - nsCOMPtr builder; - if (NS_SUCCEEDED(mBuilderConstructor->CreateTransportBuilder( - nsIPresentationChannelDescription::TYPE_TCP, - getter_AddRefs(mBuilder)))) { - builder = do_QueryInterface(mBuilder); - } - - if (NS_WARN_IF(!builder)) { - return ReplyError(NS_ERROR_DOM_OPERATION_ERR); - } - - mTransportType = nsIPresentationChannelDescription::TYPE_TCP; - return builder->BuildTCPSenderTransport(aTransport, this); -} - -NS_IMETHODIMP -PresentationControllingInfo::OnStopListening(nsIServerSocket* aServerSocket, - nsresult aStatus) -{ - PRES_DEBUG("controller %s:status[%x]\n",__func__, aStatus); - - MOZ_ASSERT(NS_IsMainThread()); - - if (aStatus == NS_BINDING_ABORTED) { // The server socket was manually closed. - return NS_OK; - } - - Shutdown(aStatus); - - if (NS_WARN_IF(!IsSessionReady())) { - // It happens before the session is ready. Reply the callback. - return ReplyError(NS_ERROR_DOM_OPERATION_ERR); - } - - // It happens after the session is ready. Change the state to CLOSED. - SetStateWithReason(nsIPresentationSessionListener::STATE_CLOSED, aStatus); - - return NS_OK; -} - -/** - * The steps to reconnect a session are summarized below: - * 1. Change |mState| to CONNECTING. - * 2. Check whether |mControlChannel| is existed or not. Usually we have to - * create a new control cahnnel. - * 3.1 |mControlChannel| is null, which means we have to create a new one. - * |EstablishControlChannel| is called to create a new control channel. - * At this point, |mControlChannel| is not able to use yet. Set - * |mIsReconnecting| to true and wait until |NotifyConnected|. - * 3.2 |mControlChannel| is not null and is avaliable. - * We can just call |ContinueReconnect| to send reconnect command. - * 4. |NotifyReconnected| of |nsIPresentationControlChannelListener| is called - * to indicate the receiver is ready for reconnecting. - * 5. Once both step 3 and 4 are done, the rest is to build a new data - * transport channel by following the same steps as starting a - * new session. - */ - -nsresult -PresentationControllingInfo::Reconnect(nsIPresentationServiceCallback* aCallback) -{ - PRES_DEBUG("%s:id[%s], role[%d], state[%d]\n", __func__, - NS_ConvertUTF16toUTF8(mSessionId).get(), mRole, mState); - - if (!aCallback) { - return NS_ERROR_INVALID_ARG; - } - - mReconnectCallback = aCallback; - - if (NS_WARN_IF(mState == nsIPresentationSessionListener::STATE_TERMINATED)) { - return NotifyReconnectResult(NS_ERROR_DOM_INVALID_STATE_ERR); - } - - // If |mState| is not CLOSED, we have to close the connection before - // reconnecting. The process to reconnect will be continued after - // |NotifyDisconnected| or |NotifyTransportClosed| is invoked. - if (mState == nsIPresentationSessionListener::STATE_CONNECTING || - mState == nsIPresentationSessionListener::STATE_CONNECTED) { - mDoReconnectAfterClose = true; - return Close(NS_OK, nsIPresentationSessionListener::STATE_CLOSED); - } - - // Make sure |mState| is closed at this point. - MOZ_ASSERT(mState == nsIPresentationSessionListener::STATE_CLOSED); - - mState = nsIPresentationSessionListener::STATE_CONNECTING; - mIsReconnecting = true; - - nsresult rv = NS_OK; - if (!mControlChannel) { - nsCOMPtr ctrlChannel; - rv = mDevice->EstablishControlChannel(getter_AddRefs(ctrlChannel)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return NotifyReconnectResult(NS_ERROR_DOM_OPERATION_ERR); - } - - rv = Init(ctrlChannel); - if (NS_WARN_IF(NS_FAILED(rv))) { - return NotifyReconnectResult(NS_ERROR_DOM_OPERATION_ERR); - } - } else { - return ContinueReconnect(); - } - - return NS_OK; -} - -nsresult -PresentationControllingInfo::ContinueReconnect() -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(mControlChannel); - - mIsReconnecting = false; - if (NS_WARN_IF(NS_FAILED(mControlChannel->Reconnect(mSessionId, GetUrl())))) { - return NotifyReconnectResult(NS_ERROR_DOM_OPERATION_ERR); - } - - return NS_OK; -} - -// nsIListNetworkAddressesListener -NS_IMETHODIMP -PresentationControllingInfo::OnListedNetworkAddresses(const char** aAddressArray, - uint32_t aAddressArraySize) -{ - if (!aAddressArraySize) { - return OnListNetworkAddressesFailed(); - } - - // TODO bug 1228504 Take all IP addresses in PresentationChannelDescription - // into account. And at the first stage Presentation API is only exposed on - // Firefox OS where the first IP appears enough for most scenarios. - - nsAutoCString ip; - ip.Assign(aAddressArray[0]); - - // On Firefox desktop, the IP address is retrieved from a callback function. - // To make consistent code sequence, following function call is dispatched - // into main thread instead of calling it directly. - NS_DispatchToMainThread( - NewRunnableMethod( - this, - &PresentationControllingInfo::OnGetAddress, - ip)); - - return NS_OK; -} - -NS_IMETHODIMP -PresentationControllingInfo::OnListNetworkAddressesFailed() -{ - PRES_ERROR("PresentationControllingInfo:OnListNetworkAddressesFailed"); - - // In 1-UA case, transport channel can still be established - // on loopback interface even if no network address available. - NS_DispatchToMainThread( - NewRunnableMethod( - this, - &PresentationControllingInfo::OnGetAddress, - "127.0.0.1")); - - return NS_OK; -} - -nsresult -PresentationControllingInfo::NotifyReconnectResult(nsresult aStatus) -{ - if (!mReconnectCallback) { - MOZ_ASSERT(false, "mReconnectCallback can not be null here."); - return NS_ERROR_FAILURE; - } - - mIsReconnecting = false; - nsCOMPtr callback = - mReconnectCallback.forget(); - if (NS_FAILED(aStatus)) { - return callback->NotifyError(aStatus); - } - - return callback->NotifySuccess(GetUrl()); -} - -// nsIPresentationSessionTransportCallback -NS_IMETHODIMP -PresentationControllingInfo::NotifyTransportReady() -{ - return PresentationSessionInfo::NotifyTransportReady(); -} - -NS_IMETHODIMP -PresentationControllingInfo::NotifyTransportClosed(nsresult aReason) -{ - if (!mDoReconnectAfterClose) { - return PresentationSessionInfo::NotifyTransportClosed(aReason);; - } - - MOZ_ASSERT(mState == nsIPresentationSessionListener::STATE_CLOSED); - - mTransport = nullptr; - mIsTransportReady = false; - mDoReconnectAfterClose = false; - return Reconnect(mReconnectCallback); -} - -NS_IMETHODIMP -PresentationControllingInfo::NotifyData(const nsACString& aData, bool aIsBinary) -{ - return PresentationSessionInfo::NotifyData(aData, aIsBinary); -} - -/** - * Implementation of PresentationPresentingInfo - * - * During presentation session establishment, the receiver expects the following - * after trying to launch the app by notifying "presentation-launch-receiver": - * (The order between step 2 and 3 is not guaranteed.) - * 1. |Observe| of |nsIObserver| is called with "presentation-receiver-launched". - * Then start listen to document |STATE_TRANSFERRING| event. - * 2. |NotifyResponderReady| is called to indicate the receiver page is ready - * for presentation use. - * 3. |OnOffer| of |nsIPresentationControlChannelListener| is called. - * 4. Once both step 2 and 3 are done, establish the data transport channel and - * send the answer. (The control channel will be closed by the sender once it - * receives the answer.) - * 5. |NotifyTransportReady| of |nsIPresentationSessionTransportCallback| is - * called. The presentation session is ready to use, so notify the listener - * of CONNECTED state. - */ - -NS_IMPL_ISUPPORTS_INHERITED(PresentationPresentingInfo, - PresentationSessionInfo, - nsITimerCallback) - -nsresult -PresentationPresentingInfo::Init(nsIPresentationControlChannel* aControlChannel) -{ - PresentationSessionInfo::Init(aControlChannel); - - // Add a timer to prevent waiting indefinitely in case the receiver page fails - // to become ready. - nsresult rv; - int32_t timeout = - Preferences::GetInt("presentation.receiver.loading.timeout", 10000); - mTimer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - rv = mTimer->InitWithCallback(this, timeout, nsITimer::TYPE_ONE_SHOT); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - return NS_OK; -} - -void -PresentationPresentingInfo::Shutdown(nsresult aReason) -{ - PresentationSessionInfo::Shutdown(aReason); - - if (mTimer) { - mTimer->Cancel(); - } - - mLoadingCallback = nullptr; - mRequesterDescription = nullptr; - mPendingCandidates.Clear(); - mPromise = nullptr; - mHasFlushPendingEvents = false; -} - -// nsIPresentationSessionTransportBuilderListener -NS_IMETHODIMP -PresentationPresentingInfo::OnSessionTransport(nsIPresentationSessionTransport* aTransport) -{ - nsresult rv = PresentationSessionInfo::OnSessionTransport(aTransport); - - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - // The session transport is managed by content process - if (NS_WARN_IF(!aTransport)) { - return NS_ERROR_INVALID_ARG; - } - - // send answer for TCP session transport - if (mTransportType == nsIPresentationChannelDescription::TYPE_TCP) { - // Prepare and send the answer. - // In the current implementation of |PresentationSessionTransport|, - // |GetSelfAddress| cannot return the real info when it's initialized via - // |buildTCPReceiverTransport|. Yet this deficiency only affects the channel - // description for the answer, which is not actually checked at requester side. - nsCOMPtr selfAddr; - rv = mTransport->GetSelfAddress(getter_AddRefs(selfAddr)); - NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "GetSelfAddress failed"); - - nsCString address; - uint16_t port = 0; - if (NS_SUCCEEDED(rv)) { - selfAddr->GetAddress(address); - selfAddr->GetPort(&port); - } - nsCOMPtr description = - new TCPPresentationChannelDescription(address, port); - - return mControlChannel->SendAnswer(description); - } - - return NS_OK; -} - -// Delegate the pending offer and ICE candidates to builder. -NS_IMETHODIMP -PresentationPresentingInfo::FlushPendingEvents(nsIPresentationDataChannelSessionTransportBuilder* builder) -{ - if (NS_WARN_IF(!builder)) { - return NS_ERROR_FAILURE; - } - - mHasFlushPendingEvents = true; - - if (mRequesterDescription) { - builder->OnOffer(mRequesterDescription); - } - mRequesterDescription = nullptr; - - for (size_t i = 0; i < mPendingCandidates.Length(); ++i) { - builder->OnIceCandidate(mPendingCandidates[i]); - } - mPendingCandidates.Clear(); - return NS_OK; -} - -nsresult -PresentationPresentingInfo::InitTransportAndSendAnswer() -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(mState == nsIPresentationSessionListener::STATE_CONNECTING); - - uint8_t type = 0; - nsresult rv = mRequesterDescription->GetType(&type); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - if (NS_WARN_IF(!mBuilderConstructor)) { - return ReplyError(NS_ERROR_DOM_OPERATION_ERR); - } - - if (NS_WARN_IF(NS_FAILED( - mBuilderConstructor->CreateTransportBuilder(type, - getter_AddRefs(mBuilder))))) { - return NS_ERROR_NOT_AVAILABLE; - } - - if (type == nsIPresentationChannelDescription::TYPE_TCP) { - // Establish a data transport channel |mTransport| to the sender and use - // |this| as the callback. - nsCOMPtr builder = - do_QueryInterface(mBuilder); - if (NS_WARN_IF(!builder)) { - return NS_ERROR_NOT_AVAILABLE; - } - - mTransportType = nsIPresentationChannelDescription::TYPE_TCP; - return builder->BuildTCPReceiverTransport(mRequesterDescription, this); - } - - if (type == nsIPresentationChannelDescription::TYPE_DATACHANNEL) { - if (!Preferences::GetBool("dom.presentation.session_transport.data_channel.enable")) { - return NS_ERROR_NOT_IMPLEMENTED; - } - /** - * Generally transport is maintained by the chrome process. However, data - * channel should be live with the DOM , which implies RTCDataChannel in an OOP - * page should be establish in the content process. - * - * |mBuilderConstructor| is responsible for creating a builder, which is for - * building a data channel transport. - * - * In the OOP case, |mBuilderConstructor| would create a builder which is - * an object of |PresentationBuilderParent|. So, |BuildDataChannelTransport| - * triggers an IPC call to make content process establish a RTCDataChannel - * transport. - */ - - mTransportType = nsIPresentationChannelDescription::TYPE_DATACHANNEL; - - nsCOMPtr dataChannelBuilder = - do_QueryInterface(mBuilder); - if (NS_WARN_IF(!dataChannelBuilder)) { - return NS_ERROR_NOT_AVAILABLE; - } - - nsPIDOMWindowInner* window = GetWindow(); - - rv = dataChannelBuilder-> - BuildDataChannelTransport(nsIPresentationService::ROLE_RECEIVER, - window, - this); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - rv = FlushPendingEvents(dataChannelBuilder); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - return NS_OK; - } - - MOZ_ASSERT(false, "Unknown nsIPresentationChannelDescription type!"); - return NS_ERROR_UNEXPECTED; -} - -nsresult -PresentationPresentingInfo::UntrackFromService() -{ - // Remove the OOP responding info (if it has never been used). - if (mContentParent) { - Unused << NS_WARN_IF(!static_cast(mContentParent.get())->SendNotifyPresentationReceiverCleanUp(mSessionId)); - } - - // Receiver device might need clean up after session termination. - if (mDevice) { - mDevice->Disconnect(); - } - mDevice = nullptr; - - // Remove the session info (and the in-process responding info if there's any). - nsCOMPtr service = - do_GetService(PRESENTATION_SERVICE_CONTRACTID); - if (NS_WARN_IF(!service)) { - return NS_ERROR_NOT_AVAILABLE; - } - static_cast(service.get())->UntrackSessionInfo(mSessionId, mRole); - - return NS_OK; -} - -bool -PresentationPresentingInfo::IsAccessible(base::ProcessId aProcessId) -{ - // Only the specific content process should access the responder info. - return (mContentParent) ? - aProcessId == static_cast(mContentParent.get())->OtherPid() : - false; -} - -nsresult -PresentationPresentingInfo::NotifyResponderReady() -{ - PRES_DEBUG("%s:id[%s], role[%d], state[%d]\n", __func__, - NS_ConvertUTF16toUTF8(mSessionId).get(), mRole, mState); - - if (mTimer) { - mTimer->Cancel(); - mTimer = nullptr; - } - - mIsResponderReady = true; - - // Initialize |mTransport| and send the answer to the sender if sender's - // description is already offered. - if (mRequesterDescription) { - nsresult rv = InitTransportAndSendAnswer(); - if (NS_WARN_IF(NS_FAILED(rv))) { - return ReplyError(NS_ERROR_DOM_OPERATION_ERR); - } - } - - return NS_OK; -} - -nsresult -PresentationPresentingInfo::NotifyResponderFailure() -{ - PRES_DEBUG("%s:id[%s], role[%d]\n", __func__, - NS_ConvertUTF16toUTF8(mSessionId).get(), mRole); - - if (mTimer) { - mTimer->Cancel(); - mTimer = nullptr; - } - - return ReplyError(NS_ERROR_DOM_OPERATION_ERR); -} - -nsresult -PresentationPresentingInfo::DoReconnect() -{ - PRES_DEBUG("%s:id[%s], role[%d]\n", __func__, - NS_ConvertUTF16toUTF8(mSessionId).get(), mRole); - - MOZ_ASSERT(mState == nsIPresentationSessionListener::STATE_CLOSED); - - SetStateWithReason(nsIPresentationSessionListener::STATE_CONNECTING, NS_OK); - - return NotifyResponderReady(); -} - -// nsIPresentationControlChannelListener -NS_IMETHODIMP -PresentationPresentingInfo::OnOffer(nsIPresentationChannelDescription* aDescription) -{ - if (NS_WARN_IF(mHasFlushPendingEvents)) { - return ReplyError(NS_ERROR_DOM_OPERATION_ERR); - } - - if (NS_WARN_IF(!aDescription)) { - return ReplyError(NS_ERROR_DOM_OPERATION_ERR); - } - - mRequesterDescription = aDescription; - - // Initialize |mTransport| and send the answer to the sender if the receiver - // page is ready for presentation use. - if (mIsResponderReady) { - nsresult rv = InitTransportAndSendAnswer(); - if (NS_WARN_IF(NS_FAILED(rv))) { - return ReplyError(NS_ERROR_DOM_OPERATION_ERR); - } - } - - return NS_OK; -} - -NS_IMETHODIMP -PresentationPresentingInfo::OnAnswer(nsIPresentationChannelDescription* aDescription) -{ - MOZ_ASSERT(false, "Receiver side should not receive answer."); - return NS_ERROR_FAILURE; -} - -NS_IMETHODIMP -PresentationPresentingInfo::OnIceCandidate(const nsAString& aCandidate) -{ - if (!mBuilder && !mHasFlushPendingEvents) { - mPendingCandidates.AppendElement(nsString(aCandidate)); - return NS_OK; - } - - if (NS_WARN_IF(!mBuilder && mHasFlushPendingEvents)) { - return NS_ERROR_FAILURE; - } - - nsCOMPtr - builder = do_QueryInterface(mBuilder); - - return builder->OnIceCandidate(aCandidate); -} - -NS_IMETHODIMP -PresentationPresentingInfo::NotifyConnected() -{ - PRES_DEBUG("%s:id[%s], role[%d]\n", __func__, - NS_ConvertUTF16toUTF8(mSessionId).get(), mRole); - - if (nsIPresentationSessionListener::STATE_TERMINATED == mState) { - ContinueTermination(); - } - - return NS_OK; -} - -NS_IMETHODIMP -PresentationPresentingInfo::NotifyReconnected() -{ - MOZ_ASSERT(false, "NotifyReconnected should not be called at receiver side."); - return NS_OK; -} - -NS_IMETHODIMP -PresentationPresentingInfo::NotifyDisconnected(nsresult aReason) -{ - PRES_DEBUG("%s:id[%s], reason[%x], role[%d]\n", __func__, - NS_ConvertUTF16toUTF8(mSessionId).get(), aReason, mRole); - - MOZ_ASSERT(NS_IsMainThread()); - - if (mTransportType == nsIPresentationChannelDescription::TYPE_DATACHANNEL) { - nsCOMPtr - builder = do_QueryInterface(mBuilder); - if (builder) { - Unused << NS_WARN_IF(NS_FAILED(builder->NotifyDisconnected(aReason))); - } - } - - // Unset control channel here so it won't try to re-close it in potential - // subsequent |Shutdown| calls. - SetControlChannel(nullptr); - - if (NS_WARN_IF(NS_FAILED(aReason))) { - // The presentation session instance may already exist. - // Change the state to TERMINATED since it never succeeds. - SetStateWithReason(nsIPresentationSessionListener::STATE_TERMINATED, aReason); - - // Reply error for an abnormal close. - return ReplyError(NS_ERROR_DOM_OPERATION_ERR); - } - - return NS_OK; -} - -// nsITimerCallback -NS_IMETHODIMP -PresentationPresentingInfo::Notify(nsITimer* aTimer) -{ - MOZ_ASSERT(NS_IsMainThread()); - NS_WARNING("The receiver page fails to become ready before timeout."); - - mTimer = nullptr; - return ReplyError(NS_ERROR_DOM_TIMEOUT_ERR); -} - -// PromiseNativeHandler -void -PresentationPresentingInfo::ResolvedCallback(JSContext* aCx, - JS::Handle aValue) -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (NS_WARN_IF(!aValue.isObject())) { - ReplyError(NS_ERROR_DOM_OPERATION_ERR); - return; - } - - JS::Rooted obj(aCx, &aValue.toObject()); - if (NS_WARN_IF(!obj)) { - ReplyError(NS_ERROR_DOM_OPERATION_ERR); - return; - } - - // Start to listen to document state change event |STATE_TRANSFERRING|. - // Use Element to support both HTMLIFrameElement and nsXULElement. - Element* frame = nullptr; - nsresult rv = UNWRAP_OBJECT(Element, &obj, frame); - if (NS_WARN_IF(!frame)) { - ReplyError(NS_ERROR_DOM_OPERATION_ERR); - return; - } - - nsCOMPtr owner = do_QueryInterface((nsIFrameLoaderOwner*) frame); - if (NS_WARN_IF(!owner)) { - ReplyError(NS_ERROR_DOM_OPERATION_ERR); - return; - } - - nsCOMPtr frameLoader = owner->GetFrameLoader(); - if (NS_WARN_IF(!frameLoader)) { - ReplyError(NS_ERROR_DOM_OPERATION_ERR); - return; - } - - RefPtr tabParent = TabParent::GetFrom(frameLoader); - if (tabParent) { - // OOP frame - // Notify the content process that a receiver page has launched, so it can - // start monitoring the loading progress. - mContentParent = tabParent->Manager(); - Unused << NS_WARN_IF(!static_cast(mContentParent.get())->SendNotifyPresentationReceiverLaunched(tabParent, mSessionId)); - } else { - // In-process frame - nsCOMPtr docShell; - rv = frameLoader->GetDocShell(getter_AddRefs(docShell)); - if (NS_WARN_IF(NS_FAILED(rv))) { - ReplyError(NS_ERROR_DOM_OPERATION_ERR); - return; - } - - // Keep an eye on the loading progress of the receiver page. - mLoadingCallback = new PresentationResponderLoadingCallback(mSessionId); - rv = mLoadingCallback->Init(docShell); - if (NS_WARN_IF(NS_FAILED(rv))) { - ReplyError(NS_ERROR_DOM_OPERATION_ERR); - return; - } - } -} - -void -PresentationPresentingInfo::RejectedCallback(JSContext* aCx, - JS::Handle aValue) -{ - MOZ_ASSERT(NS_IsMainThread()); - NS_WARNING("Launching the receiver page has been rejected."); - - if (mTimer) { - mTimer->Cancel(); - mTimer = nullptr; - } - - ReplyError(NS_ERROR_DOM_OPERATION_ERR); -} diff --git a/dom/presentation/PresentationSessionInfo.h b/dom/presentation/PresentationSessionInfo.h deleted file mode 100644 index 6338d3c32a..0000000000 --- a/dom/presentation/PresentationSessionInfo.h +++ /dev/null @@ -1,304 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_dom_PresentationSessionInfo_h -#define mozilla_dom_PresentationSessionInfo_h - -#include "base/process.h" -#include "mozilla/dom/nsIContentParent.h" -#include "mozilla/dom/Promise.h" -#include "mozilla/dom/PromiseNativeHandler.h" -#include "mozilla/DebugOnly.h" -#include "mozilla/RefPtr.h" -#include "nsCOMPtr.h" -#include "nsINetworkInfoService.h" -#include "nsIPresentationControlChannel.h" -#include "nsIPresentationDevice.h" -#include "nsIPresentationListener.h" -#include "nsIPresentationService.h" -#include "nsIPresentationSessionTransport.h" -#include "nsIPresentationSessionTransportBuilder.h" -#include "nsIServerSocket.h" -#include "nsITimer.h" -#include "nsString.h" -#include "PresentationCallbacks.h" - -namespace mozilla { -namespace dom { - -class PresentationSessionInfo : public nsIPresentationSessionTransportCallback - , public nsIPresentationControlChannelListener - , public nsIPresentationSessionTransportBuilderListener -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIPRESENTATIONSESSIONTRANSPORTCALLBACK - NS_DECL_NSIPRESENTATIONSESSIONTRANSPORTBUILDERLISTENER - - PresentationSessionInfo(const nsAString& aUrl, - const nsAString& aSessionId, - const uint8_t aRole) - : mUrl(aUrl) - , mSessionId(aSessionId) - , mIsResponderReady(false) - , mIsTransportReady(false) - , mState(nsIPresentationSessionListener::STATE_CONNECTING) - , mReason(NS_OK) - { - MOZ_ASSERT(!mUrl.IsEmpty()); - MOZ_ASSERT(!mSessionId.IsEmpty()); - MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER || - aRole == nsIPresentationService::ROLE_RECEIVER); - mRole = aRole; - } - - virtual nsresult Init(nsIPresentationControlChannel* aControlChannel); - - const nsAString& GetUrl() const - { - return mUrl; - } - - const nsAString& GetSessionId() const - { - return mSessionId; - } - - uint8_t GetRole() const - { - return mRole; - } - - nsresult SetListener(nsIPresentationSessionListener* aListener); - - void SetDevice(nsIPresentationDevice* aDevice) - { - mDevice = aDevice; - } - - already_AddRefed GetDevice() const - { - nsCOMPtr device = mDevice; - return device.forget(); - } - - void SetControlChannel(nsIPresentationControlChannel* aControlChannel) - { - if (mControlChannel) { - mControlChannel->SetListener(nullptr); - } - - mControlChannel = aControlChannel; - if (mControlChannel) { - mControlChannel->SetListener(this); - } - } - - nsresult Send(const nsAString& aData); - - nsresult SendBinaryMsg(const nsACString& aData); - - nsresult SendBlob(nsIDOMBlob* aBlob); - - nsresult Close(nsresult aReason, - uint32_t aState); - - nsresult OnTerminate(nsIPresentationControlChannel* aControlChannel); - - nsresult ReplyError(nsresult aReason); - - virtual bool IsAccessible(base::ProcessId aProcessId); - - void SetTransportBuilderConstructor( - nsIPresentationTransportBuilderConstructor* aBuilderConstructor) - { - mBuilderConstructor = aBuilderConstructor; - } - -protected: - virtual ~PresentationSessionInfo() - { - Shutdown(NS_OK); - } - - virtual void Shutdown(nsresult aReason); - - nsresult ReplySuccess(); - - bool IsSessionReady() - { - return mIsResponderReady && mIsTransportReady; - } - - virtual nsresult UntrackFromService(); - - void SetStateWithReason(uint32_t aState, nsresult aReason) - { - if (mState == aState) { - return; - } - - mState = aState; - mReason = aReason; - - // Notify session state change. - if (mListener) { - DebugOnly rv = - mListener->NotifyStateChange(mSessionId, mState, aReason); - NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "NotifyStateChanged"); - } - } - - void ContinueTermination(); - - void ResetBuilder() - { - mBuilder = nullptr; - } - - // Should be nsIPresentationChannelDescription::TYPE_TCP/TYPE_DATACHANNEL - uint8_t mTransportType = 0; - - nsPIDOMWindowInner* GetWindow(); - - nsString mUrl; - nsString mSessionId; - // mRole should be nsIPresentationService::ROLE_CONTROLLER - // or nsIPresentationService::ROLE_RECEIVER. - uint8_t mRole; - bool mIsResponderReady; - bool mIsTransportReady; - bool mIsOnTerminating = false; - uint32_t mState; // CONNECTED, CLOSED, TERMINATED - nsresult mReason; - nsCOMPtr mListener; - nsCOMPtr mDevice; - nsCOMPtr mTransport; - nsCOMPtr mControlChannel; - nsCOMPtr mBuilder; - nsCOMPtr mBuilderConstructor; -}; - -// Session info with controlling browsing context (sender side) behaviors. -class PresentationControllingInfo final : public PresentationSessionInfo - , public nsIServerSocketListener - , public nsIListNetworkAddressesListener -{ -public: - NS_DECL_ISUPPORTS_INHERITED - NS_DECL_NSIPRESENTATIONCONTROLCHANNELLISTENER - NS_DECL_NSISERVERSOCKETLISTENER - NS_DECL_NSILISTNETWORKADDRESSESLISTENER - NS_DECL_NSIPRESENTATIONSESSIONTRANSPORTCALLBACK - - PresentationControllingInfo(const nsAString& aUrl, - const nsAString& aSessionId) - : PresentationSessionInfo(aUrl, - aSessionId, - nsIPresentationService::ROLE_CONTROLLER) - {} - - nsresult Init(nsIPresentationControlChannel* aControlChannel) override; - - nsresult Reconnect(nsIPresentationServiceCallback* aCallback); - - nsresult BuildTransport(); - -private: - ~PresentationControllingInfo() - { - Shutdown(NS_OK); - } - - void Shutdown(nsresult aReason) override; - - nsresult GetAddress(); - - nsresult OnGetAddress(const nsACString& aAddress); - - nsresult ContinueReconnect(); - - nsresult NotifyReconnectResult(nsresult aStatus); - - nsCOMPtr mServerSocket; - nsCOMPtr mReconnectCallback; - bool mIsReconnecting = false; - bool mDoReconnectAfterClose = false; -}; - -// Session info with presenting browsing context (receiver side) behaviors. -class PresentationPresentingInfo final : public PresentationSessionInfo - , public PromiseNativeHandler - , public nsITimerCallback -{ -public: - NS_DECL_ISUPPORTS_INHERITED - NS_DECL_NSIPRESENTATIONCONTROLCHANNELLISTENER - NS_DECL_NSITIMERCALLBACK - - PresentationPresentingInfo(const nsAString& aUrl, - const nsAString& aSessionId, - nsIPresentationDevice* aDevice) - : PresentationSessionInfo(aUrl, - aSessionId, - nsIPresentationService::ROLE_RECEIVER) - { - MOZ_ASSERT(aDevice); - SetDevice(aDevice); - } - - nsresult Init(nsIPresentationControlChannel* aControlChannel) override; - - nsresult NotifyResponderReady(); - nsresult NotifyResponderFailure(); - - NS_IMETHODIMP OnSessionTransport(nsIPresentationSessionTransport* transport) override; - - void ResolvedCallback(JSContext* aCx, JS::Handle aValue) override; - - void RejectedCallback(JSContext* aCx, JS::Handle aValue) override; - - void SetPromise(Promise* aPromise) - { - mPromise = aPromise; - mPromise->AppendNativeHandler(this); - } - - bool IsAccessible(base::ProcessId aProcessId) override; - - nsresult DoReconnect(); - -private: - ~PresentationPresentingInfo() - { - Shutdown(NS_OK); - } - - void Shutdown(nsresult aReason) override; - - nsresult InitTransportAndSendAnswer(); - - nsresult UntrackFromService() override; - - NS_IMETHODIMP - FlushPendingEvents(nsIPresentationDataChannelSessionTransportBuilder* builder); - - bool mHasFlushPendingEvents = false; - RefPtr mLoadingCallback; - nsCOMPtr mTimer; - nsCOMPtr mRequesterDescription; - nsTArray mPendingCandidates; - RefPtr mPromise; - - // The content parent communicating with the content process which the OOP - // receiver page belongs to. - nsCOMPtr mContentParent; -}; - -} // namespace dom -} // namespace mozilla - -#endif // mozilla_dom_PresentationSessionInfo_h diff --git a/dom/presentation/PresentationSessionRequest.cpp b/dom/presentation/PresentationSessionRequest.cpp deleted file mode 100644 index 219fbd6a45..0000000000 --- a/dom/presentation/PresentationSessionRequest.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "PresentationSessionRequest.h" -#include "nsIPresentationControlChannel.h" -#include "nsIPresentationDevice.h" - -namespace mozilla { -namespace dom { - -NS_IMPL_ISUPPORTS(PresentationSessionRequest, nsIPresentationSessionRequest) - -PresentationSessionRequest::PresentationSessionRequest(nsIPresentationDevice* aDevice, - const nsAString& aUrl, - const nsAString& aPresentationId, - nsIPresentationControlChannel* aControlChannel) - : mUrl(aUrl) - , mPresentationId(aPresentationId) - , mDevice(aDevice) - , mControlChannel(aControlChannel) -{ -} - -PresentationSessionRequest::~PresentationSessionRequest() -{ -} - -// nsIPresentationSessionRequest - -NS_IMETHODIMP -PresentationSessionRequest::GetDevice(nsIPresentationDevice** aRetVal) -{ - NS_ENSURE_ARG_POINTER(aRetVal); - - nsCOMPtr device = mDevice; - device.forget(aRetVal); - - return NS_OK; -} - -NS_IMETHODIMP -PresentationSessionRequest::GetUrl(nsAString& aRetVal) -{ - aRetVal = mUrl; - - return NS_OK; -} - -NS_IMETHODIMP -PresentationSessionRequest::GetPresentationId(nsAString& aRetVal) -{ - aRetVal = mPresentationId; - - return NS_OK; -} - -NS_IMETHODIMP -PresentationSessionRequest::GetControlChannel(nsIPresentationControlChannel** aRetVal) -{ - NS_ENSURE_ARG_POINTER(aRetVal); - - nsCOMPtr controlChannel = mControlChannel; - controlChannel.forget(aRetVal); - - return NS_OK; -} - -} // namespace dom -} // namespace mozilla diff --git a/dom/presentation/PresentationSessionRequest.h b/dom/presentation/PresentationSessionRequest.h deleted file mode 100644 index c56502d77d..0000000000 --- a/dom/presentation/PresentationSessionRequest.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_dom_PresentationSessionRequest_h__ -#define mozilla_dom_PresentationSessionRequest_h__ - -#include "nsIPresentationSessionRequest.h" -#include "nsCOMPtr.h" -#include "nsString.h" - -namespace mozilla { -namespace dom { - -class PresentationSessionRequest final : public nsIPresentationSessionRequest -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIPRESENTATIONSESSIONREQUEST - - PresentationSessionRequest(nsIPresentationDevice* aDevice, - const nsAString& aUrl, - const nsAString& aPresentationId, - nsIPresentationControlChannel* aControlChannel); - -private: - virtual ~PresentationSessionRequest(); - - nsString mUrl; - nsString mPresentationId; - nsCOMPtr mDevice; - nsCOMPtr mControlChannel; -}; - -} // namespace dom -} // namespace mozilla - -#endif /* mozilla_dom_PresentationSessionRequest_h__ */ - diff --git a/dom/presentation/PresentationTCPSessionTransport.cpp b/dom/presentation/PresentationTCPSessionTransport.cpp deleted file mode 100644 index 1ccb8b43c6..0000000000 --- a/dom/presentation/PresentationTCPSessionTransport.cpp +++ /dev/null @@ -1,589 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* 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 "nsArrayUtils.h" -#include "nsIAsyncStreamCopier.h" -#include "nsIInputStreamPump.h" -#include "nsIMultiplexInputStream.h" -#include "nsIMutableArray.h" -#include "nsIOutputStream.h" -#include "nsIPresentationControlChannel.h" -#include "nsIScriptableInputStream.h" -#include "nsISocketTransport.h" -#include "nsISocketTransportService.h" -#include "nsISupportsPrimitives.h" -#include "nsNetUtil.h" -#include "nsQueryObject.h" -#include "nsServiceManagerUtils.h" -#include "nsStreamUtils.h" -#include "nsThreadUtils.h" -#include "PresentationLog.h" -#include "PresentationTCPSessionTransport.h" - -#define BUFFER_SIZE 65536 - -using namespace mozilla; -using namespace mozilla::dom; - -class CopierCallbacks final : public nsIRequestObserver -{ -public: - explicit CopierCallbacks(PresentationTCPSessionTransport* aTransport) - : mOwner(aTransport) - {} - - NS_DECL_ISUPPORTS - NS_DECL_NSIREQUESTOBSERVER -private: - ~CopierCallbacks() {} - - RefPtr mOwner; -}; - -NS_IMPL_ISUPPORTS(CopierCallbacks, nsIRequestObserver) - -NS_IMETHODIMP -CopierCallbacks::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext) -{ - return NS_OK; -} - -NS_IMETHODIMP -CopierCallbacks::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext, nsresult aStatus) -{ - mOwner->NotifyCopyComplete(aStatus); - return NS_OK; -} - -NS_IMPL_CYCLE_COLLECTION(PresentationTCPSessionTransport, mTransport, - mSocketInputStream, mSocketOutputStream, - mInputStreamPump, mInputStreamScriptable, - mMultiplexStream, mMultiplexStreamCopier, mCallback) - -NS_IMPL_CYCLE_COLLECTING_ADDREF(PresentationTCPSessionTransport) -NS_IMPL_CYCLE_COLLECTING_RELEASE(PresentationTCPSessionTransport) - -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PresentationTCPSessionTransport) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPresentationSessionTransport) - NS_INTERFACE_MAP_ENTRY(nsIInputStreamCallback) - NS_INTERFACE_MAP_ENTRY(nsIPresentationSessionTransport) - NS_INTERFACE_MAP_ENTRY(nsIPresentationSessionTransportBuilder) - NS_INTERFACE_MAP_ENTRY(nsIPresentationTCPSessionTransportBuilder) - NS_INTERFACE_MAP_ENTRY(nsIRequestObserver) - NS_INTERFACE_MAP_ENTRY(nsIStreamListener) - NS_INTERFACE_MAP_ENTRY(nsITransportEventSink) -NS_INTERFACE_MAP_END - -PresentationTCPSessionTransport::PresentationTCPSessionTransport() - : mReadyState(ReadyState::CLOSED) - , mAsyncCopierActive(false) - , mCloseStatus(NS_OK) - , mDataNotificationEnabled(false) -{ -} - -PresentationTCPSessionTransport::~PresentationTCPSessionTransport() -{ -} - -NS_IMETHODIMP -PresentationTCPSessionTransport::BuildTCPSenderTransport(nsISocketTransport* aTransport, - nsIPresentationSessionTransportBuilderListener* aListener) -{ - if (NS_WARN_IF(!aTransport)) { - return NS_ERROR_INVALID_ARG; - } - mTransport = aTransport; - - if (NS_WARN_IF(!aListener)) { - return NS_ERROR_INVALID_ARG; - } - mListener = aListener; - - nsresult rv = CreateStream(); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - mRole = nsIPresentationService::ROLE_CONTROLLER; - - nsCOMPtr sessionTransport = do_QueryObject(this); - nsCOMPtr onSessionTransportRunnable = - NewRunnableMethod - (mListener, - &nsIPresentationSessionTransportBuilderListener::OnSessionTransport, - sessionTransport); - - NS_DispatchToCurrentThread(onSessionTransportRunnable.forget()); - - nsCOMPtr setReadyStateRunnable = - NewRunnableMethod(this, - &PresentationTCPSessionTransport::SetReadyState, - ReadyState::OPEN); - return NS_DispatchToCurrentThread(setReadyStateRunnable.forget()); -} - -NS_IMETHODIMP -PresentationTCPSessionTransport::BuildTCPReceiverTransport(nsIPresentationChannelDescription* aDescription, - nsIPresentationSessionTransportBuilderListener* aListener) -{ - if (NS_WARN_IF(!aDescription)) { - return NS_ERROR_INVALID_ARG; - } - - if (NS_WARN_IF(!aListener)) { - return NS_ERROR_INVALID_ARG; - } - mListener = aListener; - - uint16_t serverPort; - nsresult rv = aDescription->GetTcpPort(&serverPort); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - nsCOMPtr serverHosts; - rv = aDescription->GetTcpAddress(getter_AddRefs(serverHosts)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - // TODO bug 1228504 Take all IP addresses in PresentationChannelDescription - // into account. And at the first stage Presentation API is only exposed on - // Firefox OS where the first IP appears enough for most scenarios. - nsCOMPtr supportStr = do_QueryElementAt(serverHosts, 0); - if (NS_WARN_IF(!supportStr)) { - return NS_ERROR_INVALID_ARG; - } - - nsAutoCString serverHost; - supportStr->GetData(serverHost); - if (serverHost.IsEmpty()) { - return NS_ERROR_INVALID_ARG; - } - - PRES_DEBUG("%s:ServerHost[%s],ServerPort[%d]\n", __func__, serverHost.get(), serverPort); - - SetReadyState(ReadyState::CONNECTING); - - nsCOMPtr sts = - do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID); - if (NS_WARN_IF(!sts)) { - return NS_ERROR_NOT_AVAILABLE; - } - rv = sts->CreateTransport(nullptr, 0, serverHost, serverPort, nullptr, - getter_AddRefs(mTransport)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - nsCOMPtr mainThread; - NS_GetMainThread(getter_AddRefs(mainThread)); - - mTransport->SetEventSink(this, mainThread); - - rv = CreateStream(); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - mRole = nsIPresentationService::ROLE_RECEIVER; - - nsCOMPtr sessionTransport = do_QueryObject(this); - nsCOMPtr runnable = - NewRunnableMethod - (mListener, - &nsIPresentationSessionTransportBuilderListener::OnSessionTransport, - sessionTransport); - return NS_DispatchToCurrentThread(runnable.forget()); -} - -nsresult -PresentationTCPSessionTransport::CreateStream() -{ - nsresult rv = mTransport->OpenInputStream(0, 0, 0, getter_AddRefs(mSocketInputStream)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - rv = mTransport->OpenOutputStream(nsITransport::OPEN_UNBUFFERED, 0, 0, getter_AddRefs(mSocketOutputStream)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - // If the other side is not listening, we will get an |onInputStreamReady| - // callback where |available| raises to indicate the connection was refused. - nsCOMPtr asyncStream = do_QueryInterface(mSocketInputStream); - if (NS_WARN_IF(!asyncStream)) { - return NS_ERROR_NOT_AVAILABLE; - } - - nsCOMPtr mainThread; - NS_GetMainThread(getter_AddRefs(mainThread)); - - rv = asyncStream->AsyncWait(this, nsIAsyncInputStream::WAIT_CLOSURE_ONLY, 0, mainThread); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - mInputStreamScriptable = do_CreateInstance("@mozilla.org/scriptableinputstream;1", &rv); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - rv = mInputStreamScriptable->Init(mSocketInputStream); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - mMultiplexStream = do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1", &rv); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - mMultiplexStreamCopier = do_CreateInstance("@mozilla.org/network/async-stream-copier;1", &rv); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - nsCOMPtr sts = - do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID); - if (NS_WARN_IF(!sts)) { - return NS_ERROR_NOT_AVAILABLE; - } - - nsCOMPtr target = do_QueryInterface(sts); - rv = mMultiplexStreamCopier->Init(mMultiplexStream, - mSocketOutputStream, - target, - true, /* source buffered */ - false, /* sink buffered */ - BUFFER_SIZE, - false, /* close source */ - false); /* close sink */ - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - return NS_OK; -} - -nsresult -PresentationTCPSessionTransport::CreateInputStreamPump() -{ - if (NS_WARN_IF(mInputStreamPump)) { - return NS_OK; - } - - nsresult rv; - mInputStreamPump = do_CreateInstance(NS_INPUTSTREAMPUMP_CONTRACTID, &rv); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - rv = mInputStreamPump->Init(mSocketInputStream, -1, -1, 0, 0, false); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - rv = mInputStreamPump->AsyncRead(this, nullptr); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - return NS_OK; -} - -NS_IMETHODIMP -PresentationTCPSessionTransport::EnableDataNotification() -{ - if (NS_WARN_IF(!mCallback)) { - return NS_ERROR_DOM_INVALID_STATE_ERR; - } - - if (mDataNotificationEnabled) { - return NS_OK; - } - - mDataNotificationEnabled = true; - - if (IsReadyToNotifyData()) { - return CreateInputStreamPump(); - } - - return NS_OK; -} - -// nsIPresentationSessionTransportBuilderListener -NS_IMETHODIMP -PresentationTCPSessionTransport::GetCallback(nsIPresentationSessionTransportCallback** aCallback) -{ - nsCOMPtr callback = mCallback; - callback.forget(aCallback); - return NS_OK; -} - -NS_IMETHODIMP -PresentationTCPSessionTransport::SetCallback(nsIPresentationSessionTransportCallback* aCallback) -{ - mCallback = aCallback; - - if (!!mCallback && ReadyState::OPEN == mReadyState) { - // Notify the transport channel is ready. - Unused << NS_WARN_IF(NS_FAILED(mCallback->NotifyTransportReady())); - } - - return NS_OK; -} - -NS_IMETHODIMP -PresentationTCPSessionTransport::GetSelfAddress(nsINetAddr** aSelfAddress) -{ - if (NS_WARN_IF(!mTransport)) { - return NS_ERROR_DOM_INVALID_STATE_ERR; - } - - return mTransport->GetScriptableSelfAddr(aSelfAddress); -} - -void -PresentationTCPSessionTransport::EnsureCopying() -{ - if (mAsyncCopierActive) { - return; - } - - mAsyncCopierActive = true; - RefPtr callbacks = new CopierCallbacks(this); - Unused << NS_WARN_IF(NS_FAILED(mMultiplexStreamCopier->AsyncCopy(callbacks, nullptr))); -} - -void -PresentationTCPSessionTransport::NotifyCopyComplete(nsresult aStatus) -{ - mAsyncCopierActive = false; - mMultiplexStream->RemoveStream(0); - if (NS_WARN_IF(NS_FAILED(aStatus))) { - if (mReadyState != ReadyState::CLOSED) { - mCloseStatus = aStatus; - SetReadyState(ReadyState::CLOSED); - } - return; - } - - uint32_t count; - nsresult rv = mMultiplexStream->GetCount(&count); - if (NS_WARN_IF(NS_FAILED(rv))) { - return; - } - - if (count) { - EnsureCopying(); - return; - } - - if (mReadyState == ReadyState::CLOSING) { - mSocketOutputStream->Close(); - mCloseStatus = NS_OK; - SetReadyState(ReadyState::CLOSED); - } -} - -NS_IMETHODIMP -PresentationTCPSessionTransport::Send(const nsAString& aData) -{ - if (NS_WARN_IF(mReadyState != ReadyState::OPEN)) { - return NS_ERROR_DOM_INVALID_STATE_ERR; - } - - nsresult rv; - nsCOMPtr stream = - do_CreateInstance(NS_STRINGINPUTSTREAM_CONTRACTID, &rv); - if(NS_WARN_IF(NS_FAILED(rv))) { - return NS_ERROR_DOM_INVALID_STATE_ERR; - } - - NS_ConvertUTF16toUTF8 msgString(aData); - rv = stream->SetData(msgString.BeginReading(), msgString.Length()); - if(NS_WARN_IF(NS_FAILED(rv))) { - return NS_ERROR_DOM_INVALID_STATE_ERR; - } - - mMultiplexStream->AppendStream(stream); - - EnsureCopying(); - - return NS_OK; -} - -NS_IMETHODIMP -PresentationTCPSessionTransport::SendBinaryMsg(const nsACString& aData) -{ - return NS_ERROR_DOM_NOT_SUPPORTED_ERR; -} - -NS_IMETHODIMP -PresentationTCPSessionTransport::SendBlob(nsIDOMBlob* aBlob) -{ - return NS_ERROR_DOM_NOT_SUPPORTED_ERR; -} - -NS_IMETHODIMP -PresentationTCPSessionTransport::Close(nsresult aReason) -{ - PRES_DEBUG("%s:reason[%x]\n", __func__, aReason); - - if (mReadyState == ReadyState::CLOSED || mReadyState == ReadyState::CLOSING) { - return NS_OK; - } - - mCloseStatus = aReason; - SetReadyState(ReadyState::CLOSING); - - uint32_t count = 0; - mMultiplexStream->GetCount(&count); - if (!count) { - mSocketOutputStream->Close(); - } - - mSocketInputStream->Close(); - mDataNotificationEnabled = false; - - mListener = nullptr; - - return NS_OK; -} - -void -PresentationTCPSessionTransport::SetReadyState(ReadyState aReadyState) -{ - mReadyState = aReadyState; - - if (mReadyState == ReadyState::OPEN) { - if (IsReadyToNotifyData()) { - CreateInputStreamPump(); - } - - if (NS_WARN_IF(!mCallback)) { - return; - } - - // Notify the transport channel is ready. - Unused << NS_WARN_IF(NS_FAILED(mCallback->NotifyTransportReady())); - } else if (mReadyState == ReadyState::CLOSED && mCallback) { - if (NS_WARN_IF(!mCallback)) { - return; - } - - // Notify the transport channel has been shut down. - Unused << - NS_WARN_IF(NS_FAILED(mCallback->NotifyTransportClosed(mCloseStatus))); - mCallback = nullptr; - } -} - -// nsITransportEventSink -NS_IMETHODIMP -PresentationTCPSessionTransport::OnTransportStatus(nsITransport* aTransport, - nsresult aStatus, - int64_t aProgress, - int64_t aProgressMax) -{ - PRES_DEBUG("%s:aStatus[%x]\n", __func__, aStatus); - - MOZ_ASSERT(NS_IsMainThread()); - - if (aStatus != NS_NET_STATUS_CONNECTED_TO) { - return NS_OK; - } - - SetReadyState(ReadyState::OPEN); - - return NS_OK; -} - -// nsIInputStreamCallback -NS_IMETHODIMP -PresentationTCPSessionTransport::OnInputStreamReady(nsIAsyncInputStream* aStream) -{ - MOZ_ASSERT(NS_IsMainThread()); - - // Only used for detecting if the connection was refused. - uint64_t dummy; - nsresult rv = aStream->Available(&dummy); - if (NS_WARN_IF(NS_FAILED(rv))) { - if (mReadyState != ReadyState::CLOSED) { - mCloseStatus = NS_ERROR_CONNECTION_REFUSED; - SetReadyState(ReadyState::CLOSED); - } - } - - return NS_OK; -} - -// nsIRequestObserver -NS_IMETHODIMP -PresentationTCPSessionTransport::OnStartRequest(nsIRequest* aRequest, - nsISupports* aContext) -{ - // Do nothing. - return NS_OK; -} - -NS_IMETHODIMP -PresentationTCPSessionTransport::OnStopRequest(nsIRequest* aRequest, - nsISupports* aContext, - nsresult aStatusCode) -{ - PRES_DEBUG("%s:aStatusCode[%x]\n", __func__, aStatusCode); - - MOZ_ASSERT(NS_IsMainThread()); - - uint32_t count; - nsresult rv = mMultiplexStream->GetCount(&count); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - mInputStreamPump = nullptr; - - if (count != 0 && NS_SUCCEEDED(aStatusCode)) { - // If we have some buffered output still, and status is not an error, the - // other side has done a half-close, but we don't want to be in the close - // state until we are done sending everything that was buffered. We also - // don't want to call |NotifyTransportClosed| yet. - return NS_OK; - } - - // We call this even if there is no error. - if (mReadyState != ReadyState::CLOSED) { - mCloseStatus = aStatusCode; - SetReadyState(ReadyState::CLOSED); - } - return NS_OK; -} - -// nsIStreamListener -NS_IMETHODIMP -PresentationTCPSessionTransport::OnDataAvailable(nsIRequest* aRequest, - nsISupports* aContext, - nsIInputStream* aStream, - uint64_t aOffset, - uint32_t aCount) -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (NS_WARN_IF(!mCallback)) { - return NS_ERROR_NOT_AVAILABLE; - } - - nsCString data; - nsresult rv = mInputStreamScriptable->ReadBytes(aCount, data); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - // Pass the incoming data to the listener. - return mCallback->NotifyData(data, false); -} diff --git a/dom/presentation/PresentationTCPSessionTransport.h b/dom/presentation/PresentationTCPSessionTransport.h deleted file mode 100644 index f36b371a4b..0000000000 --- a/dom/presentation/PresentationTCPSessionTransport.h +++ /dev/null @@ -1,110 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_dom_PresentationSessionTransport_h -#define mozilla_dom_PresentationSessionTransport_h - -#include "mozilla/RefPtr.h" -#include "nsCOMPtr.h" -#include "nsIAsyncInputStream.h" -#include "nsIPresentationSessionTransport.h" -#include "nsIPresentationSessionTransportBuilder.h" -#include "nsIStreamListener.h" -#include "nsISupportsImpl.h" -#include "nsITransport.h" - -class nsISocketTransport; -class nsIInputStreamPump; -class nsIScriptableInputStream; -class nsIMultiplexInputStream; -class nsIAsyncStreamCopier; -class nsIInputStream; - -namespace mozilla { -namespace dom { - -/* - * App-to-App transport channel for the presentation session. It's usually - * initialized with an |InitWithSocketTransport| call if at the presenting sender - * side; whereas it's initialized with an |InitWithChannelDescription| if at the - * presenting receiver side. The lifetime is managed in either - * |PresentationControllingInfo| (sender side) or |PresentationPresentingInfo| - * (receiver side) in PresentationSessionInfo.cpp. - */ -class PresentationTCPSessionTransport final : public nsIPresentationSessionTransport - , public nsIPresentationTCPSessionTransportBuilder - , public nsITransportEventSink - , public nsIInputStreamCallback - , public nsIStreamListener -{ -public: - NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(PresentationTCPSessionTransport, - nsIPresentationSessionTransport) - - NS_DECL_NSIPRESENTATIONSESSIONTRANSPORT - NS_DECL_NSIPRESENTATIONSESSIONTRANSPORTBUILDER - NS_DECL_NSIPRESENTATIONTCPSESSIONTRANSPORTBUILDER - NS_DECL_NSITRANSPORTEVENTSINK - NS_DECL_NSIINPUTSTREAMCALLBACK - NS_DECL_NSIREQUESTOBSERVER - NS_DECL_NSISTREAMLISTENER - - PresentationTCPSessionTransport(); - - void NotifyCopyComplete(nsresult aStatus); - -private: - ~PresentationTCPSessionTransport(); - - nsresult CreateStream(); - - nsresult CreateInputStreamPump(); - - void EnsureCopying(); - - enum class ReadyState { - CONNECTING, - OPEN, - CLOSING, - CLOSED - }; - - void SetReadyState(ReadyState aReadyState); - - bool IsReadyToNotifyData() - { - return mDataNotificationEnabled && mReadyState == ReadyState::OPEN; - } - - ReadyState mReadyState; - bool mAsyncCopierActive; - nsresult mCloseStatus; - bool mDataNotificationEnabled; - - uint8_t mRole = 0; - - // Raw socket streams - nsCOMPtr mTransport; - nsCOMPtr mSocketInputStream; - nsCOMPtr mSocketOutputStream; - - // Input stream machinery - nsCOMPtr mInputStreamPump; - nsCOMPtr mInputStreamScriptable; - - // Output stream machinery - nsCOMPtr mMultiplexStream; - nsCOMPtr mMultiplexStreamCopier; - - nsCOMPtr mCallback; - nsCOMPtr mListener; -}; - -} // namespace dom -} // namespace mozilla - -#endif // mozilla_dom_PresentationSessionTransport_h diff --git a/dom/presentation/PresentationTerminateRequest.cpp b/dom/presentation/PresentationTerminateRequest.cpp deleted file mode 100644 index 61fd8403f4..0000000000 --- a/dom/presentation/PresentationTerminateRequest.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "PresentationTerminateRequest.h" -#include "nsIPresentationControlChannel.h" -#include "nsIPresentationDevice.h" - -namespace mozilla { -namespace dom { - -NS_IMPL_ISUPPORTS(PresentationTerminateRequest, nsIPresentationTerminateRequest) - -PresentationTerminateRequest::PresentationTerminateRequest( - nsIPresentationDevice* aDevice, - const nsAString& aPresentationId, - nsIPresentationControlChannel* aControlChannel, - bool aIsFromReceiver) - : mPresentationId(aPresentationId) - , mDevice(aDevice) - , mControlChannel(aControlChannel) - , mIsFromReceiver(aIsFromReceiver) -{ -} - -PresentationTerminateRequest::~PresentationTerminateRequest() -{ -} - -// nsIPresentationTerminateRequest -NS_IMETHODIMP -PresentationTerminateRequest::GetDevice(nsIPresentationDevice** aRetVal) -{ - NS_ENSURE_ARG_POINTER(aRetVal); - - nsCOMPtr device = mDevice; - device.forget(aRetVal); - - return NS_OK; -} - -NS_IMETHODIMP -PresentationTerminateRequest::GetPresentationId(nsAString& aRetVal) -{ - aRetVal = mPresentationId; - - return NS_OK; -} - -NS_IMETHODIMP -PresentationTerminateRequest::GetControlChannel( - nsIPresentationControlChannel** aRetVal) -{ - NS_ENSURE_ARG_POINTER(aRetVal); - - nsCOMPtr controlChannel = mControlChannel; - controlChannel.forget(aRetVal); - - return NS_OK; -} - -NS_IMETHODIMP -PresentationTerminateRequest::GetIsFromReceiver(bool* aRetVal) -{ - *aRetVal = mIsFromReceiver; - - return NS_OK; -} - -} // namespace dom -} // namespace mozilla diff --git a/dom/presentation/PresentationTerminateRequest.h b/dom/presentation/PresentationTerminateRequest.h deleted file mode 100644 index ca3563f8df..0000000000 --- a/dom/presentation/PresentationTerminateRequest.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_dom_PresentationTerminateRequest_h__ -#define mozilla_dom_PresentationTerminateRequest_h__ - -#include "nsIPresentationTerminateRequest.h" -#include "nsCOMPtr.h" -#include "nsString.h" - -namespace mozilla { -namespace dom { - -class PresentationTerminateRequest final : public nsIPresentationTerminateRequest -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIPRESENTATIONTERMINATEREQUEST - - PresentationTerminateRequest(nsIPresentationDevice* aDevice, - const nsAString& aPresentationId, - nsIPresentationControlChannel* aControlChannel, - bool aIsFromReceiver); - -private: - virtual ~PresentationTerminateRequest(); - - nsString mPresentationId; - nsCOMPtr mDevice; - nsCOMPtr mControlChannel; - bool mIsFromReceiver; -}; - -} // namespace dom -} // namespace mozilla - -#endif /* mozilla_dom_PresentationTerminateRequest_h__ */ - diff --git a/dom/presentation/PresentationTransportBuilderConstructor.cpp b/dom/presentation/PresentationTransportBuilderConstructor.cpp deleted file mode 100644 index 98177958d1..0000000000 --- a/dom/presentation/PresentationTransportBuilderConstructor.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "PresentationTransportBuilderConstructor.h" - -#include "nsComponentManagerUtils.h" -#include "nsIPresentationControlChannel.h" -#include "nsIPresentationSessionTransport.h" -#include "nsXULAppAPI.h" - -namespace mozilla { -namespace dom { - -NS_IMPL_ISUPPORTS(DummyPresentationTransportBuilderConstructor, - nsIPresentationTransportBuilderConstructor) - -NS_IMETHODIMP -DummyPresentationTransportBuilderConstructor::CreateTransportBuilder( - uint8_t aType, - nsIPresentationSessionTransportBuilder** aRetval) -{ - MOZ_ASSERT(false, "Unexpected to be invoked."); - return NS_OK; -} - -NS_IMPL_ISUPPORTS_INHERITED0(PresentationTransportBuilderConstructor, - DummyPresentationTransportBuilderConstructor) - -/* static */ already_AddRefed -PresentationTransportBuilderConstructor::Create() -{ - nsCOMPtr constructor; - if (XRE_IsContentProcess()) { - constructor = new DummyPresentationTransportBuilderConstructor(); - } else { - constructor = new PresentationTransportBuilderConstructor(); - } - - return constructor.forget(); -} - -NS_IMETHODIMP -PresentationTransportBuilderConstructor::CreateTransportBuilder( - uint8_t aType, - nsIPresentationSessionTransportBuilder** aRetval) -{ - if (NS_WARN_IF(!aRetval)) { - return NS_ERROR_INVALID_ARG; - } - - *aRetval = nullptr; - - if (NS_WARN_IF(aType != nsIPresentationChannelDescription::TYPE_TCP && - aType != nsIPresentationChannelDescription::TYPE_DATACHANNEL)) { - return NS_ERROR_INVALID_ARG; - } - - if (XRE_IsContentProcess()) { - MOZ_ASSERT(false, - "CreateTransportBuilder can only be invoked in parent process."); - return NS_ERROR_FAILURE; - } - - nsCOMPtr builder; - if (aType == nsIPresentationChannelDescription::TYPE_TCP) { - builder = - do_CreateInstance(PRESENTATION_TCP_SESSION_TRANSPORT_CONTRACTID); - } else { - builder = - do_CreateInstance("@mozilla.org/presentation/datachanneltransportbuilder;1"); - } - - if (NS_WARN_IF(!builder)) { - return NS_ERROR_DOM_OPERATION_ERR; - } - - builder.forget(aRetval); - return NS_OK; -} - -} // namespace dom -} // namespace mozilla diff --git a/dom/presentation/PresentationTransportBuilderConstructor.h b/dom/presentation/PresentationTransportBuilderConstructor.h deleted file mode 100644 index 4250d61baa..0000000000 --- a/dom/presentation/PresentationTransportBuilderConstructor.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_dom_PresentationTransportBuilderConstructor_h -#define mozilla_dom_PresentationTransportBuilderConstructor_h - -#include "nsCOMPtr.h" -#include "nsIPresentationSessionTransportBuilder.h" -#include "nsISupportsImpl.h" - -namespace mozilla { -namespace dom { - -class DummyPresentationTransportBuilderConstructor : - public nsIPresentationTransportBuilderConstructor -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIPRESENTATIONTRANSPORTBUILDERCONSTRUCTOR - - DummyPresentationTransportBuilderConstructor() = default; - -protected: - virtual ~DummyPresentationTransportBuilderConstructor() = default; -}; - -class PresentationTransportBuilderConstructor final : - public DummyPresentationTransportBuilderConstructor -{ -public: - NS_DECL_ISUPPORTS_INHERITED - NS_DECL_NSIPRESENTATIONTRANSPORTBUILDERCONSTRUCTOR - - static already_AddRefed - Create(); - -private: - PresentationTransportBuilderConstructor() = default; - virtual ~PresentationTransportBuilderConstructor() = default; -}; - -} // namespace dom -} // namespace mozilla - -#endif // mozilla_dom_PresentationTransportBuilderConstructor_h diff --git a/dom/presentation/interfaces/moz.build b/dom/presentation/interfaces/moz.build deleted file mode 100644 index 935e390003..0000000000 --- a/dom/presentation/interfaces/moz.build +++ /dev/null @@ -1,30 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -XPIDL_SOURCES += [ - 'nsIPresentationControlChannel.idl', - 'nsIPresentationControlService.idl', - 'nsIPresentationDevice.idl', - 'nsIPresentationDeviceManager.idl', - 'nsIPresentationDevicePrompt.idl', - 'nsIPresentationDeviceProvider.idl', - 'nsIPresentationListener.idl', - 'nsIPresentationLocalDevice.idl', - 'nsIPresentationRequestUIGlue.idl', - 'nsIPresentationService.idl', - 'nsIPresentationSessionRequest.idl', - 'nsIPresentationSessionTransport.idl', - 'nsIPresentationSessionTransportBuilder.idl', - 'nsIPresentationTerminateRequest.idl', -] - -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android': - XPIDL_SOURCES += [ - 'nsIPresentationNetworkHelper.idl', - ] - -XPIDL_MODULE = 'dom_presentation' - diff --git a/dom/presentation/interfaces/nsIPresentationControlChannel.idl b/dom/presentation/interfaces/nsIPresentationControlChannel.idl deleted file mode 100644 index 669e4088ee..0000000000 --- a/dom/presentation/interfaces/nsIPresentationControlChannel.idl +++ /dev/null @@ -1,139 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsISupports.idl" - -interface nsIArray; -interface nsIInputStream; - -[scriptable, uuid(ae318e05-2a4e-4f85-95c0-e8b191ad812c)] -interface nsIPresentationChannelDescription: nsISupports -{ - const unsigned short TYPE_TCP = 1; - const unsigned short TYPE_DATACHANNEL = 2; - - // Type of transport channel. - readonly attribute uint8_t type; - - // Addresses for TCP channel (as a list of nsISupportsCString). - // Should only be used while type == TYPE_TCP. - readonly attribute nsIArray tcpAddress; - - // Port number for TCP channel. - // Should only be used while type == TYPE_TCP. - readonly attribute uint16_t tcpPort; - - // SDP for Data Channel. - // Should only be used while type == TYPE_DATACHANNEL. - readonly attribute DOMString dataChannelSDP; -}; - -/* - * The callbacks for events on control channel. - */ -[scriptable, uuid(96dd548f-7d0f-43c1-b1ad-28e666cf1e82)] -interface nsIPresentationControlChannelListener: nsISupports -{ - /* - * Callback for receiving offer from remote endpoint. - * @param offer The received offer. - */ - void onOffer(in nsIPresentationChannelDescription offer); - - /* - * Callback for receiving answer from remote endpoint. - * @param answer The received answer. - */ - void onAnswer(in nsIPresentationChannelDescription answer); - - /* - * Callback for receiving ICE candidate from remote endpoint. - * @param answer The received answer. - */ - void onIceCandidate(in DOMString candidate); - - /* - * The callback for notifying channel connected. This should be async called - * after nsIPresentationDevice::establishControlChannel. - */ - void notifyConnected(); - - /* - * The callback for notifying channel disconnected. - * @param reason The reason of channel close, NS_OK represents normal close. - */ - void notifyDisconnected(in nsresult reason); - - /* - * The callback for notifying the reconnect command is acknowledged. - */ - void notifyReconnected(); -}; - -/* - * The control channel for establishing RTCPeerConnection for a presentation - * session. SDP Offer/Answer will be exchanged through this interface. The - * control channel should be in-order. - */ -[scriptable, uuid(e60e208c-a9f5-4bc6-9a3e-47f3e4ae9c57)] -interface nsIPresentationControlChannel: nsISupports -{ - // The listener for handling events of this control channel. - // All the events should be pending until listener is assigned. - attribute nsIPresentationControlChannelListener listener; - - /* - * Send offer to remote endpoint. |onOffer| should be invoked on remote - * endpoint. - * @param offer The offer to send. - * @throws NS_ERROR_FAILURE on failure - */ - void sendOffer(in nsIPresentationChannelDescription offer); - - /* - * Send answer to remote endpoint. |onAnswer| should be invoked on remote - * endpoint. - * @param answer The answer to send. - * @throws NS_ERROR_FAILURE on failure - */ - void sendAnswer(in nsIPresentationChannelDescription answer); - - /* - * Send ICE candidate to remote endpoint. |onIceCandidate| should be invoked - * on remote endpoint. - * @param candidate The candidate to send - * @throws NS_ERROR_FAILURE on failure - */ - void sendIceCandidate(in DOMString candidate); - - /* - * Launch a presentation on remote endpoint. - * @param presentationId The Id for representing this session. - * @param url The URL requested to open by remote device. - * @throws NS_ERROR_FAILURE on failure - */ - void launch(in DOMString presentationId, in DOMString url); - - /* - * Terminate a presentation on remote endpoint. - * @param presentationId The Id for representing this session. - * @throws NS_ERROR_FAILURE on failure - */ - void terminate(in DOMString presentationId); - - /* - * Disconnect the control channel. - * @param reason The reason of disconnecting channel; NS_OK represents normal. - */ - void disconnect(in nsresult reason); - - /* - * Reconnect a presentation on remote endpoint. - * Note that only controller is allowed to reconnect a session. - * @param presentationId The Id for representing this session. - * @param url The URL requested to open by remote device. - * @throws NS_ERROR_FAILURE on failure - */ - void reconnect(in DOMString presentationId, in DOMString url); -}; diff --git a/dom/presentation/interfaces/nsIPresentationControlService.idl b/dom/presentation/interfaces/nsIPresentationControlService.idl deleted file mode 100644 index d4b967b003..0000000000 --- a/dom/presentation/interfaces/nsIPresentationControlService.idl +++ /dev/null @@ -1,156 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsISupports.idl" - -interface nsIPresentationControlChannel; - -%{C++ -#define PRESENTATION_CONTROL_SERVICE_CONTACT_ID \ - "@mozilla.org/presentation/control-service;1" -%} - -/* - * The device information required for establishing control channel. - */ -[scriptable, uuid(296fd171-e4d0-4de0-99ff-ad8ed52ddef3)] -interface nsITCPDeviceInfo: nsISupports -{ - readonly attribute AUTF8String id; - readonly attribute AUTF8String address; - readonly attribute uint16_t port; - // SHA-256 fingerprint of server certificate. Empty string represents - // server doesn't support TLS or not available. - readonly attribute AUTF8String certFingerprint; -}; - -[scriptable, uuid(09bddfaf-fcc2-4dc9-b33e-a509a1c2fb6d)] -interface nsIPresentationControlServerListener: nsISupports -{ - /** - * Callback while the server is ready or restarted. - * @param aPort - * The port of the server socket. - * @param aCertFingerprint - * The SHA-256 fingerprint of TLS server certificate. - * Empty string represents server started without encryption. - */ - void onServerReady(in uint16_t aPort, in AUTF8String aCertFingerprint); - - /** - * Callback while the server is stopped or fails to start. - * @param aResult - * The error cause of server stopped or the reason of - * start failure. - * NS_OK means the server is stopped by close. - */ - void onServerStopped(in nsresult aResult); - - /** - * Callback while the remote host is requesting to start a presentation session. - * @param aDeviceInfo The device information related to the remote host. - * @param aUrl The URL requested to open by remote device. - * @param aPresentationId The Id for representing this session. - * @param aControlChannel The control channel for this session. - */ - void onSessionRequest(in nsITCPDeviceInfo aDeviceInfo, - in DOMString aUrl, - in DOMString aPresentationId, - in nsIPresentationControlChannel aControlChannel); - - /** - * Callback while the remote host is requesting to terminate a presentation session. - * @param aDeviceInfo The device information related to the remote host. - * @param aPresentationId The Id for representing this session. - * @param aControlChannel The control channel for this session. - * @param aIsFromReceiver true if termination is initiated by receiver. - */ - void onTerminateRequest(in nsITCPDeviceInfo aDeviceInfo, - in DOMString aPresentationId, - in nsIPresentationControlChannel aControlChannel, - in boolean aIsFromReceiver); - - /** - * Callback while the remote host is requesting to reconnect a presentation session. - * @param aDeviceInfo The device information related to the remote host. - * @param aUrl The URL requested to open by remote device. - * @param aPresentationId The Id for representing this session. - * @param aControlChannel The control channel for this session. - */ - void onReconnectRequest(in nsITCPDeviceInfo aDeviceInfo, - in DOMString url, - in DOMString aPresentationId, - in nsIPresentationControlChannel aControlChannel); -}; - -/** - * Presentation control service which can be used for both presentation - * control client and server. - */ -[scriptable, uuid(55d6b605-2389-4aae-a8fe-60d4440540ea)] -interface nsIPresentationControlService: nsISupports -{ - /** - * This method initializes server socket. Caller should set listener and - * monitor onServerReady event to get the correct server info. - * @param aEncrypted - * True for using TLS control channel. - * @param aPort - * The port of the server socket. Pass 0 or opt-out to indicate no - * preference, and a port will be selected automatically. - * @throws NS_ERROR_FAILURE if the server socket has been inited or the - * server socket can not be inited. - */ - void startServer(in boolean aEncrypted, [optional] in uint16_t aPort); - - /** - * Request connection to designated remote presentation control receiver. - * @param aDeviceInfo - * The remtoe device info for establish connection. - * @returns The control channel for this session. - * @throws NS_ERROR_FAILURE if the Id hasn't been inited. - */ - nsIPresentationControlChannel connect(in nsITCPDeviceInfo aDeviceInfo); - - /** - * Check the compatibility to remote presentation control server. - * @param aVersion - * The version of remote server. - */ - boolean isCompatibleServer(in uint32_t aVersion); - - /** - * Close server socket and call |listener.onClose(NS_OK)| - */ - void close(); - - /** - * Get the listen port of the TCP socket, valid after the server is ready. - * 0 indicates the server socket is not ready or is closed. - */ - readonly attribute uint16_t port; - - /** - * The protocol version implemented by this server. - */ - readonly attribute uint32_t version; - - /** - * The id of the TCP presentation server. |requestSession| won't - * work until the |id| is set. - */ - attribute AUTF8String id; - - /** - * The fingerprint of the TLS server certificate. - * Empty string indicates the server is not ready or not encrypted. - */ - attribute AUTF8String certFingerprint; - - /** - * The listener for handling events of this presentation control server. - * Listener must be provided before invoke |startServer| and |close|. - */ - attribute nsIPresentationControlServerListener listener; -}; diff --git a/dom/presentation/interfaces/nsIPresentationDevice.idl b/dom/presentation/interfaces/nsIPresentationDevice.idl deleted file mode 100644 index 63e4a52ef6..0000000000 --- a/dom/presentation/interfaces/nsIPresentationDevice.idl +++ /dev/null @@ -1,43 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsISupports.idl" - -interface nsIPresentationControlChannel; - -/* - * Remote device. - */ -[scriptable, uuid(b1e0a7af-5936-4066-8f2e-f789fb9a7e8f)] -interface nsIPresentationDevice : nsISupports -{ - // The unique Id for the device. UUID is recommanded. - readonly attribute AUTF8String id; - - // The human-readable name of this device. - readonly attribute AUTF8String name; - - // TODO expose more info in order to fulfill UX spec - // The category of this device, could be "wifi", "bluetooth", "hdmi", etc. - readonly attribute AUTF8String type; - - /* - * Establish a control channel to this device. - * @returns The control channel for this session. - * @throws NS_ERROR_FAILURE if the establishment fails - */ - nsIPresentationControlChannel establishControlChannel(); - - // Do something when presentation session is disconnected. - void disconnect(); - - /* - * Query if requested presentation URL is supported. - * @params requestedUrl the designated URL for a presentation request. - * @returns true if designated URL is supported. - */ - boolean isRequestedUrlSupported(in DOMString requestedUrl); -}; - - diff --git a/dom/presentation/interfaces/nsIPresentationDeviceManager.idl b/dom/presentation/interfaces/nsIPresentationDeviceManager.idl deleted file mode 100644 index adff9fc09e..0000000000 --- a/dom/presentation/interfaces/nsIPresentationDeviceManager.idl +++ /dev/null @@ -1,51 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsISupports.idl" - -interface nsIArray; -interface nsIPresentationDeviceProvider; - -%{C++ -#define PRESENTATION_DEVICE_MANAGER_CONTRACTID "@mozilla.org/presentation-device/manager;1" -#define PRESENTATION_DEVICE_CHANGE_TOPIC "presentation-device-change" -%} - -/* - * Manager for the device availability. User can observe "presentation-device-change" - * for any update of the available devices. - */ -[scriptable, uuid(beb61db5-3d5f-454f-a15a-dbfa0337c569)] -interface nsIPresentationDeviceManager : nsISupports -{ - // true if there is any device available. - readonly attribute boolean deviceAvailable; - - /* - * Register a device provider manually. - * @param provider The device provider to add. - */ - void addDeviceProvider(in nsIPresentationDeviceProvider provider); - - /* - * Unregister a device provider manually. - * @param provider The device provider to remove. - */ - void removeDeviceProvider(in nsIPresentationDeviceProvider provider); - - /* - * Force all registered device providers to update device information. - */ - void forceDiscovery(); - - /* - * Retrieve all available devices or all available devices that supports - * designated presentation URLs, return a list of nsIPresentationDevice. - * The returned list is a cached device list and could be out-of-date. - * Observe device change events to get following updates. - * @param presentationUrls the target presentation URLs for device filtering - */ - nsIArray getAvailableDevices([optional] in nsIArray presentationUrls); -}; - diff --git a/dom/presentation/interfaces/nsIPresentationDevicePrompt.idl b/dom/presentation/interfaces/nsIPresentationDevicePrompt.idl deleted file mode 100644 index 2900eb59cb..0000000000 --- a/dom/presentation/interfaces/nsIPresentationDevicePrompt.idl +++ /dev/null @@ -1,58 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsISupports.idl" - -interface nsIArray; -interface nsIDOMEventTarget; -interface nsIPresentationDevice; -interface nsIPrincipal; - -%{C++ -#define PRESENTATION_DEVICE_PROMPT_CONTRACTID "@mozilla.org/presentation-device/prompt;1" -%} - -/* - * The information and callbacks for device selection - */ -[scriptable, uuid(b2aa7f6a-9448-446a-bba4-9c29638b0ed4)] -interface nsIPresentationDeviceRequest : nsISupports -{ - // The origin which initiate the request. - readonly attribute DOMString origin; - - // The array of candidate URLs. - readonly attribute nsIArray requestURLs; - - // The XUL browser element that the request was originated in. - readonly attribute nsIDOMEventTarget chromeEventHandler; - - // The principal of the request. - readonly attribute nsIPrincipal principal; - - /* - * Callback after selecting a device - * @param device The selected device. - */ - void select(in nsIPresentationDevice device); - - /* - * Callback after selection failed or canceled by user. - * @param reason The error cause for canceling this request. - */ - void cancel(in nsresult reason); -}; - -/* - * UI prompt for device selection. - */ -[scriptable, uuid(ac1a7e44-de86-454f-a9f1-276de2539831)] -interface nsIPresentationDevicePrompt : nsISupports -{ - /* - * Request a device selection. - * @param request The information and callbacks of this selection request. - */ - void promptDeviceSelection(in nsIPresentationDeviceRequest request); -}; diff --git a/dom/presentation/interfaces/nsIPresentationDeviceProvider.idl b/dom/presentation/interfaces/nsIPresentationDeviceProvider.idl deleted file mode 100644 index b2c5e530cd..0000000000 --- a/dom/presentation/interfaces/nsIPresentationDeviceProvider.idl +++ /dev/null @@ -1,75 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsISupports.idl" - -interface nsIPresentationDevice; -interface nsIPresentationControlChannel; - -%{C++ -#define PRESENTATION_DEVICE_PROVIDER_CATEGORY "presentation-device-provider" -%} - -/* - * The callbacks for any device updates and session request. - */ -[scriptable, uuid(46fd372b-2e40-4179-9b36-0478d141e440)] -interface nsIPresentationDeviceListener: nsISupports -{ - void addDevice(in nsIPresentationDevice device); - void removeDevice(in nsIPresentationDevice device); - void updateDevice(in nsIPresentationDevice device); - - /* - * Callback while the remote device is requesting to start a presentation session. - * @param device The remote device that sent session request. - * @param url The URL requested to open by remote device. - * @param presentationId The Id for representing this session. - * @param controlChannel The control channel for this session. - */ - void onSessionRequest(in nsIPresentationDevice device, - in DOMString url, - in DOMString presentationId, - in nsIPresentationControlChannel controlChannel); - - /* - * Callback while the remote device is requesting to terminate a presentation session. - * @param device The remote device that sent session request. - * @param presentationId The Id for representing this session. - * @param controlChannel The control channel for this session. - * @param aIsFromReceiver true if termination is initiated by receiver. - */ - void onTerminateRequest(in nsIPresentationDevice device, - in DOMString presentationId, - in nsIPresentationControlChannel controlChannel, - in boolean aIsFromReceiver); - - /* - * Callback while the remote device is requesting to reconnect a presentation session. - * @param device The remote device that sent session request. - * @param aUrl The URL requested to open by remote device. - * @param presentationId The Id for representing this session. - * @param controlChannel The control channel for this session. - */ - void onReconnectRequest(in nsIPresentationDevice device, - in DOMString url, - in DOMString presentationId, - in nsIPresentationControlChannel controlChannel); -}; - -/* - * Device provider for any device protocol, can be registered as default - * providers by adding its contractID to category "presentation-device-provider". - */ -[scriptable, uuid(3db2578a-0f50-44ad-b01b-28427b71b7bf)] -interface nsIPresentationDeviceProvider: nsISupports -{ - // The listener for handling any device update. - attribute nsIPresentationDeviceListener listener; - - /* - * Force to update device information. - */ - void forceDiscovery(); -}; diff --git a/dom/presentation/interfaces/nsIPresentationListener.idl b/dom/presentation/interfaces/nsIPresentationListener.idl deleted file mode 100644 index 546c2fd4bf..0000000000 --- a/dom/presentation/interfaces/nsIPresentationListener.idl +++ /dev/null @@ -1,50 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsISupports.idl" - -[ref] native URLArrayRef(const nsTArray); - -[uuid(0105f837-4279-4715-9d5b-2dc3f8b65353)] -interface nsIPresentationAvailabilityListener : nsISupports -{ - /* - * Called when device availability changes. - */ - [noscript] void notifyAvailableChange(in URLArrayRef urls, - in bool available); -}; - -[scriptable, uuid(7dd48df8-8f8c-48c7-ac37-7b9fd1acf2f8)] -interface nsIPresentationSessionListener : nsISupports -{ - const unsigned short STATE_CONNECTING = 0; - const unsigned short STATE_CONNECTED = 1; - const unsigned short STATE_CLOSED = 2; - const unsigned short STATE_TERMINATED = 3; - - /* - * Called when session state changes. - */ - void notifyStateChange(in DOMString sessionId, - in unsigned short state, - in nsresult reason); - - /* - * Called when receive messages. - */ - void notifyMessage(in DOMString sessionId, - in ACString data, - in boolean isBinary); -}; - -[scriptable, uuid(27f101d7-9ed1-429e-b4f8-43b00e8e111c)] -interface nsIPresentationRespondingListener : nsISupports -{ - /* - * Called when an incoming session connects. - */ - void notifySessionConnect(in unsigned long long windowId, - in DOMString sessionId); -}; diff --git a/dom/presentation/interfaces/nsIPresentationLocalDevice.idl b/dom/presentation/interfaces/nsIPresentationLocalDevice.idl deleted file mode 100644 index 80e3b4041f..0000000000 --- a/dom/presentation/interfaces/nsIPresentationLocalDevice.idl +++ /dev/null @@ -1,17 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsIPresentationDevice.idl" - -/* - * Local device. - * This device is used for 1-UA use case. The result for display is rendered by - * this host device. - */ -[scriptable, uuid(dd239720-cab6-4fb5-9025-cba23f1bbc2d)] -interface nsIPresentationLocalDevice : nsIPresentationDevice -{ - // (1-UA only) The property is used to get the window ID of 1-UA device. - readonly attribute AUTF8String windowId; -}; diff --git a/dom/presentation/interfaces/nsIPresentationNetworkHelper.idl b/dom/presentation/interfaces/nsIPresentationNetworkHelper.idl deleted file mode 100644 index 514075dfab..0000000000 --- a/dom/presentation/interfaces/nsIPresentationNetworkHelper.idl +++ /dev/null @@ -1,36 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsISupports.idl" - -%{C++ -#define PRESENTATION_NETWORK_HELPER_CONTRACTID \ - "@mozilla.org/presentation-device/networkHelper;1" -%} - -[scriptable, uuid(0a7e134f-ff80-4e73-91e6-12b3134fe568)] -interface nsIPresentationNetworkHelperListener : nsISupports -{ - /** - * Called when error occurs. - * @param aReason error message. - */ - void onError(in AUTF8String aReason); - - /** - * Called when get Wi-Fi IP address. - * @param aIPAddress the IP address of Wi-Fi interface. - */ - void onGetWifiIPAddress(in AUTF8String aIPAddress); -}; - -[scriptable, uuid(650dc16b-3d9c-49a6-9037-1d6f2d18c90c)] -interface nsIPresentationNetworkHelper : nsISupports -{ - /** - * Get IP address of Wi-Fi interface. - * @param aListener the callback interface. - */ - void getWifiIPAddress(in nsIPresentationNetworkHelperListener aListener); -}; diff --git a/dom/presentation/interfaces/nsIPresentationRequestUIGlue.idl b/dom/presentation/interfaces/nsIPresentationRequestUIGlue.idl deleted file mode 100644 index dab1991e4d..0000000000 --- a/dom/presentation/interfaces/nsIPresentationRequestUIGlue.idl +++ /dev/null @@ -1,29 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsISupports.idl" - -interface nsIPresentationDevice; - -%{C++ -#define PRESENTATION_REQUEST_UI_GLUE_CONTRACTID \ - "@mozilla.org/presentation/requestuiglue;1" -%} - -[scriptable, uuid(faa45119-6fb5-496c-aa4c-f740177a38b5)] -interface nsIPresentationRequestUIGlue : nsISupports -{ - /* - * This method is called to open the responding app/page when - * a presentation request comes in at receiver side. - * - * @param url The url of the request. - * @param sessionId The session ID of the request. - * - * @return A promise that resolves to the opening frame. - */ - nsISupports sendRequest(in DOMString url, - in DOMString sessionId, - in nsIPresentationDevice device); -}; diff --git a/dom/presentation/interfaces/nsIPresentationService.idl b/dom/presentation/interfaces/nsIPresentationService.idl deleted file mode 100644 index c3c15bb9fe..0000000000 --- a/dom/presentation/interfaces/nsIPresentationService.idl +++ /dev/null @@ -1,275 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsISupports.idl" - -interface nsIDOMBlob; -interface nsIDOMEventTarget; -interface nsIInputStream; -interface nsIPresentationAvailabilityListener; -interface nsIPresentationRespondingListener; -interface nsIPresentationSessionListener; -interface nsIPresentationTransportBuilderConstructor; -interface nsIPrincipal; - -%{C++ -#define PRESENTATION_SERVICE_CID \ - { 0x1d9bb10c, 0xc0ab, 0x4fe8, \ - { 0x9e, 0x4f, 0x40, 0x58, 0xb8, 0x51, 0x98, 0x32 } } -#define PRESENTATION_SERVICE_CONTRACTID \ - "@mozilla.org/presentation/presentationservice;1" - -#include "nsTArray.h" - -class nsString; -%} - -[ref] native URLArrayRef(const nsTArray); - -[scriptable, uuid(12073206-0065-4b10-9488-a6eb9b23e65b)] -interface nsIPresentationServiceCallback : nsISupports -{ - /* - * Called when the operation succeeds. - * - * @param url: the selected request url used to start or reconnect a session. - */ - void notifySuccess(in DOMString url); - - /* - * Called when the operation fails. - * - * @param error: error message. - */ - void notifyError(in nsresult error); -}; - -[scriptable, uuid(de42b741-5619-4650-b961-c2cebb572c95)] -interface nsIPresentationService : nsISupports -{ - const unsigned short ROLE_CONTROLLER = 0x1; - const unsigned short ROLE_RECEIVER = 0x2; - - const unsigned short CLOSED_REASON_ERROR = 0x1; - const unsigned short CLOSED_REASON_CLOSED = 0x2; - const unsigned short CLOSED_REASON_WENTAWAY = 0x3; - - /* - * Start a new presentation session and display a prompt box which asks users - * to select a device. - * - * @param urls: The candidate Urls of presenting page. Only one url would be used. - * @param sessionId: An ID to identify presentation session. - * @param origin: The url of requesting page. - * @param deviceId: The specified device of handling this request, null string - * for prompt device selection dialog. - * @param windowId: The inner window ID associated with the presentation - * session. (0 implies no window ID since no actual window - * uses 0 as its ID. Generally it's the case the window is - * located in different process from this service) - * @param eventTarget: The chrome event handler, in particular XUL browser - * element in parent process, that the request was - * originated in. - * @param principal: The principal that initiated the session. - * @param callback: Invoke the callback when the operation is completed. - * NotifySuccess() is called with |id| if a session is - * established successfully with the selected device. - * Otherwise, NotifyError() is called with a error message. - * @param constructor: The constructor for creating a transport builder. - */ - [noscript] void startSession(in URLArrayRef urls, - in DOMString sessionId, - in DOMString origin, - in DOMString deviceId, - in unsigned long long windowId, - in nsIDOMEventTarget eventTarget, - in nsIPrincipal principal, - in nsIPresentationServiceCallback callback, - in nsIPresentationTransportBuilderConstructor constructor); - - /* - * Send the message to the session. - * - * @param sessionId: An ID to identify presentation session. - * @param role: Identify the function called by controller or receiver. - * @param data: the message being sent out. - */ - void sendSessionMessage(in DOMString sessionId, - in uint8_t role, - in DOMString data); - - /* - * Send the binary message to the session. - * - * @param sessionId: An ID to identify presentation session. - * @param role: Identify the function called by controller or receiver. - * @param data: the message being sent out. - */ - void sendSessionBinaryMsg(in DOMString sessionId, - in uint8_t role, - in ACString data); - - /* - * Send the blob to the session. - * - * @param sessionId: An ID to identify presentation session. - * @param role: Identify the function called by controller or receiver. - * @param blob: The input blob to be sent. - */ - void sendSessionBlob(in DOMString sessionId, - in uint8_t role, - in nsIDOMBlob blob); - - /* - * Close the session. - * - * @param sessionId: An ID to identify presentation session. - * @param role: Identify the function called by controller or receiver. - */ - void closeSession(in DOMString sessionId, - in uint8_t role, - in uint8_t closedReason); - - /* - * Terminate the session. - * - * @param sessionId: An ID to identify presentation session. - * @param role: Identify the function called by controller or receiver. - */ - void terminateSession(in DOMString sessionId, - in uint8_t role); - - /* - * Reconnect the session. - * - * @param url: The request Urls. - * @param sessionId: An ID to identify presentation session. - * @param role: Identify the function called by controller or receiver. - * @param callback: NotifySuccess() is called when a control channel - * is opened successfully. - * Otherwise, NotifyError() is called with a error message. - */ - [noscript] void reconnectSession(in URLArrayRef urls, - in DOMString sessionId, - in uint8_t role, - in nsIPresentationServiceCallback callback); - - /* - * Register an availability listener. Must be called from the main thread. - * - * @param availabilityUrls: The Urls that this listener is interested in. - * @param listener: The listener to register. - */ - [noscript] void registerAvailabilityListener( - in URLArrayRef availabilityUrls, - in nsIPresentationAvailabilityListener listener); - - /* - * Unregister an availability listener. Must be called from the main thread. - * - * @param availabilityUrls: The Urls that are registered before. - * @param listener: The listener to unregister. - */ - [noscript] void unregisterAvailabilityListener( - in URLArrayRef availabilityUrls, - in nsIPresentationAvailabilityListener listener); - - /* - * Register a session listener. Must be called from the main thread. - * - * @param sessionId: An ID to identify presentation session. - * @param role: Identify the function called by controller or receiver. - * @param listener: The listener to register. - */ - void registerSessionListener(in DOMString sessionId, - in uint8_t role, - in nsIPresentationSessionListener listener); - - /* - * Unregister a session listener. Must be called from the main thread. - * - * @param sessionId: An ID to identify presentation session. - * @param role: Identify the function called by controller or receiver. - */ - void unregisterSessionListener(in DOMString sessionId, - in uint8_t role); - - /* - * Register a responding listener. Must be called from the main thread. - * - * @param windowId: The window ID associated with the listener. - * @param listener: The listener to register. - */ - void registerRespondingListener(in unsigned long long windowId, - in nsIPresentationRespondingListener listener); - - /* - * Unregister a responding listener. Must be called from the main thread. - * @param windowId: The window ID associated with the listener. - */ - void unregisterRespondingListener(in unsigned long long windowId); - - /* - * Notify the receiver page is ready for presentation use. - * - * @param sessionId An ID to identify presentation session. - * @param windowId The inner window ID associated with the presentation - * session. - * @param isLoading true if receiver page is loading successfully. - * @param constructor: The constructor for creating a transport builder. - */ - void notifyReceiverReady(in DOMString sessionId, - in unsigned long long windowId, - in boolean isLoading, - in nsIPresentationTransportBuilderConstructor constructor); - - /* - * Notify the transport is closed - * - * @param sessionId: An ID to identify presentation session. - * @param role: Identify the function called by controller or receiver. - * @param reason: the error message. NS_OK indicates it is closed normally. - */ - void NotifyTransportClosed(in DOMString sessionId, - in uint8_t role, - in nsresult reason); - - /* - * Untrack the relevant info about the presentation session if there's any. - * - * @param sessionId: An ID to identify presentation session. - * @param role: Identify the function called by controller or receiver. - */ - void untrackSessionInfo(in DOMString sessionId, in uint8_t role); - - /* - * The windowId for building RTCDataChannel session transport - * - * @param sessionId: An ID to identify presentation session. - * @param role: Identify the function called by controller or receiver. - */ - unsigned long long getWindowIdBySessionId(in DOMString sessionId, - in uint8_t role); - - /* - * Update the mapping of the session ID and window ID. - * - * @param sessionId: An ID to identify presentation session. - * @param role: Identify the function called by controller or receiver. - * @param windowId: The inner window ID associated with the presentation - * session. - */ - void updateWindowIdBySessionId(in DOMString sessionId, - in uint8_t role, - in unsigned long long windowId); - - /* - * To build the session transport. - * NOTE: This function should be only called at controller side. - * - * @param sessionId: An ID to identify presentation session. - * @param role: Identify the function called by controller or receiver. - */ - void buildTransport(in DOMString sessionId, in uint8_t role); -}; diff --git a/dom/presentation/interfaces/nsIPresentationSessionRequest.idl b/dom/presentation/interfaces/nsIPresentationSessionRequest.idl deleted file mode 100644 index 45a0e314cb..0000000000 --- a/dom/presentation/interfaces/nsIPresentationSessionRequest.idl +++ /dev/null @@ -1,35 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsISupports.idl" - -interface nsIPresentationDevice; -interface nsIPresentationControlChannel; - -%{C++ -#define PRESENTATION_SESSION_REQUEST_TOPIC "presentation-session-request" -#define PRESENTATION_RECONNECT_REQUEST_TOPIC "presentation-reconnect-request" -%} - -/* - * The event of a device requesting for starting or reconnecting - * a presentation session. User can monitor the session request - * on every device by observing "presentation-sesion-request" for a - * new session and "presentation-reconnect-request" for reconnecting. - */ -[scriptable, uuid(d808a084-d0f8-455a-a8df-5879e05a755b)] -interface nsIPresentationSessionRequest: nsISupports -{ - // The device which requesting the presentation session. - readonly attribute nsIPresentationDevice device; - - // The URL requested to open by remote device. - readonly attribute DOMString url; - - // The Id for representing this session. - readonly attribute DOMString presentationId; - - // The control channel for this session. - readonly attribute nsIPresentationControlChannel controlChannel; -}; diff --git a/dom/presentation/interfaces/nsIPresentationSessionTransport.idl b/dom/presentation/interfaces/nsIPresentationSessionTransport.idl deleted file mode 100644 index a0b5617d7d..0000000000 --- a/dom/presentation/interfaces/nsIPresentationSessionTransport.idl +++ /dev/null @@ -1,69 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsISupports.idl" - -interface nsIDOMBlob; -interface nsIInputStream; -interface nsINetAddr; - -%{C++ -#define PRESENTATION_TCP_SESSION_TRANSPORT_CONTRACTID \ - "@mozilla.org/presentation/presentationtcpsessiontransport;1" -%} - -/* - * The callback for session transport events. - */ -[scriptable, uuid(9f158786-41a6-4a10-b29b-9497f25d4b67)] -interface nsIPresentationSessionTransportCallback : nsISupports -{ - void notifyTransportReady(); - void notifyTransportClosed(in nsresult reason); - void notifyData(in ACString data, in boolean isBinary); -}; - -/* - * App-to-App transport channel for the presentation session. - */ -[scriptable, uuid(670b7e1b-65be-42b6-a596-be571907fa18)] -interface nsIPresentationSessionTransport : nsISupports -{ - // Should be set once the underlying session transport is built - attribute nsIPresentationSessionTransportCallback callback; - - // valid for TCP session transport - readonly attribute nsINetAddr selfAddress; - - /* - * Enable the notification for incoming data. |notifyData| of - * |nsIPresentationSessionTransportCallback| can start getting invoked. - * Should set callback before |enableDataNotification| is called. - */ - void enableDataNotification(); - - /* - * Send message to the remote endpoint. - * @param data The message to send. - */ - void send(in DOMString data); - - /* - * Send the binary message to the remote endpoint. - * @param data: the message being sent out. - */ - void sendBinaryMsg(in ACString data); - - /* - * Send the blob to the remote endpoint. - * @param blob: The input blob to be sent. - */ - void sendBlob(in nsIDOMBlob blob); - - /* - * Close this session transport. - * @param reason The reason for closing this session transport. - */ - void close(in nsresult reason); -}; diff --git a/dom/presentation/interfaces/nsIPresentationSessionTransportBuilder.idl b/dom/presentation/interfaces/nsIPresentationSessionTransportBuilder.idl deleted file mode 100644 index 969f37d713..0000000000 --- a/dom/presentation/interfaces/nsIPresentationSessionTransportBuilder.idl +++ /dev/null @@ -1,80 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsISupports.idl" - -interface nsIPresentationChannelDescription; -interface nsISocketTransport; -interface mozIDOMWindow; -interface nsIPresentationControlChannel; -interface nsIPresentationSessionTransport; - -[scriptable, uuid(673f6de1-e253-41b8-9be8-b7ff161fa8dc)] -interface nsIPresentationSessionTransportBuilderListener : nsISupports -{ - // Should set |transport.callback| in |onSessionTransport|. - void onSessionTransport(in nsIPresentationSessionTransport transport); - void onError(in nsresult reason); - - void sendOffer(in nsIPresentationChannelDescription offer); - void sendAnswer(in nsIPresentationChannelDescription answer); - void sendIceCandidate(in DOMString candidate); - void close(in nsresult reason); -}; - -[scriptable, uuid(2fdbe67d-80f9-48dc-8237-5bef8fa19801)] -interface nsIPresentationSessionTransportBuilder : nsISupports -{ -}; - -/** - * The constructor for creating a transport builder. - */ -[scriptable, uuid(706482b2-1b51-4bed-a21d-785a9cfcfac7)] -interface nsIPresentationTransportBuilderConstructor : nsISupports -{ - nsIPresentationSessionTransportBuilder createTransportBuilder(in uint8_t type); -}; - -/** - * Builder for TCP session transport - */ -[scriptable, uuid(cde36d6e-f471-4262-a70d-f932a26b21d9)] -interface nsIPresentationTCPSessionTransportBuilder : nsIPresentationSessionTransportBuilder -{ - /** - * The following creation functions will trigger |listener.onSessionTransport| - * if the session transport is successfully built, |listener.onError| if some - * error occurs during building session transport. - */ - void buildTCPSenderTransport(in nsISocketTransport aTransport, - in nsIPresentationSessionTransportBuilderListener aListener); - - void buildTCPReceiverTransport(in nsIPresentationChannelDescription aDescription, - in nsIPresentationSessionTransportBuilderListener aListener); -}; - -/** - * Builder for WebRTC data channel session transport - */ -[scriptable, uuid(8131c4e0-3a8c-4bc1-a92a-8431473d2fe8)] -interface nsIPresentationDataChannelSessionTransportBuilder : nsIPresentationSessionTransportBuilder -{ - /** - * The following creation function will trigger |listener.onSessionTransport| - * if the session transport is successfully built, |listener.onError| if some - * error occurs during creating session transport. The |notifyConnected| of - * |aControlChannel| should be called before calling - * |buildDataChannelTransport|. - */ - void buildDataChannelTransport(in uint8_t aRole, - in mozIDOMWindow aWindow, - in nsIPresentationSessionTransportBuilderListener aListener); - - // Bug 1275150 - Merge TCP builder with the following APIs - void onOffer(in nsIPresentationChannelDescription offer); - void onAnswer(in nsIPresentationChannelDescription answer); - void onIceCandidate(in DOMString candidate); - void notifyDisconnected(in nsresult reason); -}; diff --git a/dom/presentation/interfaces/nsIPresentationTerminateRequest.idl b/dom/presentation/interfaces/nsIPresentationTerminateRequest.idl deleted file mode 100644 index a9f86fa0d9..0000000000 --- a/dom/presentation/interfaces/nsIPresentationTerminateRequest.idl +++ /dev/null @@ -1,33 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsISupports.idl" - -interface nsIPresentationDevice; -interface nsIPresentationControlChannel; - -%{C++ -#define PRESENTATION_TERMINATE_REQUEST_TOPIC "presentation-terminate-request" -%} - -/* - * The event of a device requesting for terminating a presentation session. User can - * monitor the terminate request on every device by observing "presentation-terminate-request". - */ -[scriptable, uuid(3ddbf3a4-53ee-4b70-9bbc-58ac90dce6b5)] -interface nsIPresentationTerminateRequest: nsISupports -{ - // The device which requesting to terminate presentation session. - readonly attribute nsIPresentationDevice device; - - // The Id for representing this session. - readonly attribute DOMString presentationId; - - // The control channel for this session. - // Should only use this channel to complete session termination. - readonly attribute nsIPresentationControlChannel controlChannel; - - // True if termination is initiated by receiver. - readonly attribute boolean isFromReceiver; -}; diff --git a/dom/presentation/ipc/PPresentation.ipdl b/dom/presentation/ipc/PPresentation.ipdl deleted file mode 100644 index e0f4d28884..0000000000 --- a/dom/presentation/ipc/PPresentation.ipdl +++ /dev/null @@ -1,112 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set sw=2 ts=8 et 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 PContent; -include protocol PPresentationRequest; -include protocol PPresentationBuilder; - -include InputStreamParams; - -using class IPC::Principal from "mozilla/dom/PermissionMessageUtils.h"; -using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h"; - -namespace mozilla { -namespace dom { - -struct StartSessionRequest -{ - nsString[] urls; - nsString sessionId; - nsString origin; - nsString deviceId; - uint64_t windowId; - TabId tabId; - Principal principal; -}; - -struct SendSessionMessageRequest -{ - nsString sessionId; - uint8_t role; - nsString data; -}; - -struct CloseSessionRequest -{ - nsString sessionId; - uint8_t role; - uint8_t closedReason; -}; - -struct TerminateSessionRequest -{ - nsString sessionId; - uint8_t role; -}; - -struct ReconnectSessionRequest -{ - nsString[] urls; - nsString sessionId; - uint8_t role; -}; - -struct BuildTransportRequest -{ - nsString sessionId; - uint8_t role; -}; - -union PresentationIPCRequest -{ - StartSessionRequest; - SendSessionMessageRequest; - CloseSessionRequest; - TerminateSessionRequest; - ReconnectSessionRequest; - BuildTransportRequest; -}; - -sync protocol PPresentation -{ - manager PContent; - manages PPresentationBuilder; - manages PPresentationRequest; - -child: - async NotifyAvailableChange(nsString[] aAvailabilityUrls, - bool aAvailable); - async NotifySessionStateChange(nsString aSessionId, - uint16_t aState, - nsresult aReason); - async NotifyMessage(nsString aSessionId, nsCString aData, bool aIsBinary); - async NotifySessionConnect(uint64_t aWindowId, nsString aSessionId); - async NotifyCloseSessionTransport(nsString aSessionId, - uint8_t aRole, - nsresult aReason); - - async PPresentationBuilder(nsString aSessionId, uint8_t aRole); - -parent: - async __delete__(); - - async RegisterAvailabilityHandler(nsString[] aAvailabilityUrls); - async UnregisterAvailabilityHandler(nsString[] aAvailabilityUrls); - - async RegisterSessionHandler(nsString aSessionId, uint8_t aRole); - async UnregisterSessionHandler(nsString aSessionId, uint8_t aRole); - - async RegisterRespondingHandler(uint64_t aWindowId); - async UnregisterRespondingHandler(uint64_t aWindowId); - - async PPresentationRequest(PresentationIPCRequest aRequest); - - async NotifyReceiverReady(nsString aSessionId, uint64_t aWindowId, bool aIsLoading); - async NotifyTransportClosed(nsString aSessionId, uint8_t aRole, nsresult aReason); -}; - -} // namespace dom -} // namespace mozilla diff --git a/dom/presentation/ipc/PPresentationBuilder.ipdl b/dom/presentation/ipc/PPresentationBuilder.ipdl deleted file mode 100644 index e32b02e8f3..0000000000 --- a/dom/presentation/ipc/PPresentationBuilder.ipdl +++ /dev/null @@ -1,34 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* 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/. */ - -include protocol PPresentation; - -namespace mozilla { -namespace dom { - -async protocol PPresentationBuilder -{ - manager PPresentation; - -parent: - async SendOffer(nsString aSDP); - async SendAnswer(nsString aSDP); - async SendIceCandidate(nsString aCandidate); - async Close(nsresult aReason); - - async OnSessionTransport(); - async OnSessionTransportError(nsresult aReason); - -child: - async OnOffer(nsString aSDP); - async OnAnswer(nsString aSDP); - async OnIceCandidate(nsString aCandidate); - - async __delete__(); -}; - -} // namespace dom -} // namespace mozilla diff --git a/dom/presentation/ipc/PPresentationRequest.ipdl b/dom/presentation/ipc/PPresentationRequest.ipdl deleted file mode 100644 index fa99dfcabb..0000000000 --- a/dom/presentation/ipc/PPresentationRequest.ipdl +++ /dev/null @@ -1,22 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* 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/. */ - -include protocol PPresentation; - -namespace mozilla { -namespace dom { - -sync protocol PPresentationRequest -{ - manager PPresentation; - -child: - async __delete__(nsresult result); - async NotifyRequestUrlSelected(nsString aUrl); -}; - -} // namespace dom -} // namespace mozilla diff --git a/dom/presentation/ipc/PresentationBuilderChild.cpp b/dom/presentation/ipc/PresentationBuilderChild.cpp deleted file mode 100644 index 387332e9e4..0000000000 --- a/dom/presentation/ipc/PresentationBuilderChild.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* 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/. */ - -#include "DCPresentationChannelDescription.h" -#include "nsComponentManagerUtils.h" -#include "nsGlobalWindow.h" -#include "PresentationBuilderChild.h" -#include "PresentationIPCService.h" -#include "nsServiceManagerUtils.h" -#include "mozilla/Unused.h" - -namespace mozilla { -namespace dom { - -NS_IMPL_ISUPPORTS(PresentationBuilderChild, - nsIPresentationSessionTransportBuilderListener) - -PresentationBuilderChild::PresentationBuilderChild(const nsString& aSessionId, - uint8_t aRole) - : mSessionId(aSessionId) - , mRole(aRole) -{ -} - -nsresult PresentationBuilderChild::Init() -{ - mBuilder = do_CreateInstance("@mozilla.org/presentation/datachanneltransportbuilder;1"); - if (NS_WARN_IF(!mBuilder)) { - return NS_ERROR_NOT_AVAILABLE; - } - - uint64_t windowId = 0; - - nsCOMPtr service = - do_GetService(PRESENTATION_SERVICE_CONTRACTID); - if (NS_WARN_IF(!service)) { - return NS_ERROR_NOT_AVAILABLE; - } - - if (NS_WARN_IF(NS_FAILED(service->GetWindowIdBySessionId( - mSessionId, - mRole, - &windowId)))) { - return NS_ERROR_NOT_AVAILABLE; - } - - nsPIDOMWindowInner* window = nsGlobalWindow::GetInnerWindowWithId(windowId)->AsInner(); - if (NS_WARN_IF(!window)) { - return NS_ERROR_NOT_AVAILABLE; - } - - return mBuilder->BuildDataChannelTransport(mRole, window, this); -} - -void -PresentationBuilderChild::ActorDestroy(ActorDestroyReason aWhy) -{ - mBuilder = nullptr; - mActorDestroyed = true; -} - -bool -PresentationBuilderChild::RecvOnOffer(const nsString& aSDP) -{ - if (NS_WARN_IF(!mBuilder)) { - return false; - } - RefPtr description = - new DCPresentationChannelDescription(aSDP); - - if (NS_WARN_IF(NS_FAILED(mBuilder->OnOffer(description)))) { - return false; - } - return true; -} - -bool -PresentationBuilderChild::RecvOnAnswer(const nsString& aSDP) -{ - if (NS_WARN_IF(!mBuilder)) { - return false; - } - RefPtr description = - new DCPresentationChannelDescription(aSDP); - - if (NS_WARN_IF(NS_FAILED(mBuilder->OnAnswer(description)))) { - return false; - } - return true; -} - -bool -PresentationBuilderChild::RecvOnIceCandidate(const nsString& aCandidate) -{ - if (NS_WARN_IF(mBuilder && NS_FAILED(mBuilder->OnIceCandidate(aCandidate)))) { - return false; - } - return true; -} - -// nsPresentationSessionTransportBuilderListener -NS_IMETHODIMP -PresentationBuilderChild::OnSessionTransport(nsIPresentationSessionTransport* aTransport) -{ - if (NS_WARN_IF(mActorDestroyed || !SendOnSessionTransport())){ - return NS_ERROR_FAILURE; - } - - nsCOMPtr service = - do_GetService(PRESENTATION_SERVICE_CONTRACTID); - NS_WARNING_ASSERTION(service, "no presentation service"); - if (service) { - Unused << NS_WARN_IF(NS_FAILED(static_cast(service.get())-> - NotifySessionTransport(mSessionId, mRole, aTransport))); - } - mBuilder = nullptr; - return NS_OK; -} - -NS_IMETHODIMP -PresentationBuilderChild::OnError(nsresult reason) -{ - mBuilder = nullptr; - - if (NS_WARN_IF(mActorDestroyed || !SendOnSessionTransportError(reason))){ - return NS_ERROR_FAILURE; - } - return NS_OK; -} - -NS_IMETHODIMP -PresentationBuilderChild::SendOffer(nsIPresentationChannelDescription* aOffer) -{ - nsAutoString SDP; - nsresult rv = aOffer->GetDataChannelSDP(SDP); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - if (NS_WARN_IF(mActorDestroyed || !SendSendOffer(SDP))){ - return NS_ERROR_FAILURE; - } - return NS_OK; -} - -NS_IMETHODIMP -PresentationBuilderChild::SendAnswer(nsIPresentationChannelDescription* aAnswer) -{ - nsAutoString SDP; - nsresult rv = aAnswer->GetDataChannelSDP(SDP); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - if (NS_WARN_IF(mActorDestroyed || !SendSendAnswer(SDP))){ - return NS_ERROR_FAILURE; - } - return NS_OK; -} - -NS_IMETHODIMP -PresentationBuilderChild::SendIceCandidate(const nsAString& candidate) -{ - if (NS_WARN_IF(mActorDestroyed || !SendSendIceCandidate(nsString(candidate)))) { - return NS_ERROR_FAILURE; - } - return NS_OK; -} - -NS_IMETHODIMP -PresentationBuilderChild::Close(nsresult reason) -{ - if (NS_WARN_IF(mActorDestroyed || !SendClose(reason))) { - return NS_ERROR_FAILURE; - } - return NS_OK; -} - -} // namespace dom -} // namespace mozilla - diff --git a/dom/presentation/ipc/PresentationBuilderChild.h b/dom/presentation/ipc/PresentationBuilderChild.h deleted file mode 100644 index 5ada53ab7e..0000000000 --- a/dom/presentation/ipc/PresentationBuilderChild.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* 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/. */ - -#ifndef mozilla_dom_PresentationBuilderChild_h -#define mozilla_dom_PresentationBuilderChild_h - -#include "mozilla/dom/PPresentationBuilderChild.h" -#include "nsIPresentationSessionTransportBuilder.h" - -namespace mozilla { -namespace dom { - -class PresentationBuilderChild final: public PPresentationBuilderChild - , public nsIPresentationSessionTransportBuilderListener -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIPRESENTATIONSESSIONTRANSPORTBUILDERLISTENER - - explicit PresentationBuilderChild(const nsString& aSessionId, - uint8_t aRole); - - nsresult Init(); - - virtual void ActorDestroy(ActorDestroyReason aWhy) override; - - virtual bool RecvOnOffer(const nsString& aSDP) override; - - virtual bool RecvOnAnswer(const nsString& aSDP) override; - - virtual bool RecvOnIceCandidate(const nsString& aCandidate) override; - -private: - virtual ~PresentationBuilderChild() = default; - - nsString mSessionId; - uint8_t mRole; - bool mActorDestroyed = false; - nsCOMPtr mBuilder; -}; - -} // namespace dom -} // namespace mozilla - -#endif // mozilla_dom_PresentationBuilderChild_h diff --git a/dom/presentation/ipc/PresentationBuilderParent.cpp b/dom/presentation/ipc/PresentationBuilderParent.cpp deleted file mode 100644 index dc784b13c4..0000000000 --- a/dom/presentation/ipc/PresentationBuilderParent.cpp +++ /dev/null @@ -1,267 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* 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/. */ - -#include "DCPresentationChannelDescription.h" -#include "PresentationBuilderParent.h" -#include "PresentationSessionInfo.h" - -namespace mozilla { -namespace dom { - -namespace { - -class PresentationSessionTransportIPC final : - public nsIPresentationSessionTransport -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIPRESENTATIONSESSIONTRANSPORT - - PresentationSessionTransportIPC(PresentationParent* aParent, - const nsAString& aSessionId, - uint8_t aRole) - : mParent(aParent) - , mSessionId(aSessionId) - , mRole(aRole) - { - MOZ_ASSERT(mParent); - } - -private: - virtual ~PresentationSessionTransportIPC() = default; - - RefPtr mParent; - nsString mSessionId; - uint8_t mRole; -}; - -NS_IMPL_ISUPPORTS(PresentationSessionTransportIPC, - nsIPresentationSessionTransport) - -NS_IMETHODIMP -PresentationSessionTransportIPC::GetCallback( - nsIPresentationSessionTransportCallback** aCallback) -{ - return NS_OK; -} - -NS_IMETHODIMP -PresentationSessionTransportIPC::SetCallback( - nsIPresentationSessionTransportCallback* aCallback) -{ - if (aCallback) { - aCallback->NotifyTransportReady(); - } - return NS_OK; -} - -NS_IMETHODIMP -PresentationSessionTransportIPC::GetSelfAddress(nsINetAddr** aSelfAddress) -{ - MOZ_ASSERT(false, "Not expected."); - return NS_ERROR_FAILURE; -} - -NS_IMETHODIMP -PresentationSessionTransportIPC::EnableDataNotification() -{ - return NS_OK; -} - -NS_IMETHODIMP -PresentationSessionTransportIPC::Send(const nsAString& aData) -{ - return NS_OK; -} - -NS_IMETHODIMP -PresentationSessionTransportIPC::SendBinaryMsg(const nsACString& aData) -{ - return NS_OK; -} - -NS_IMETHODIMP -PresentationSessionTransportIPC::SendBlob(nsIDOMBlob* aBlob) -{ - return NS_OK; -} - -NS_IMETHODIMP -PresentationSessionTransportIPC::Close(nsresult aReason) -{ - if (NS_WARN_IF(!mParent->SendNotifyCloseSessionTransport(mSessionId, - mRole, - aReason))) { - return NS_ERROR_FAILURE; - } - - return NS_OK; -} - -} // anonymous namespace - -NS_IMPL_ISUPPORTS(PresentationBuilderParent, - nsIPresentationSessionTransportBuilder, - nsIPresentationDataChannelSessionTransportBuilder) - -PresentationBuilderParent::PresentationBuilderParent(PresentationParent* aParent) - : mParent(aParent) -{ - MOZ_COUNT_CTOR(PresentationBuilderParent); -} - -PresentationBuilderParent::~PresentationBuilderParent() -{ - MOZ_COUNT_DTOR(PresentationBuilderParent); - - if (mNeedDestroyActor) { - Unused << NS_WARN_IF(!Send__delete__(this)); - } -} - -NS_IMETHODIMP -PresentationBuilderParent::BuildDataChannelTransport( - uint8_t aRole, - mozIDOMWindow* aWindow, /* unused */ - nsIPresentationSessionTransportBuilderListener* aListener) -{ - mBuilderListener = aListener; - - RefPtr info = static_cast(aListener); - nsAutoString sessionId(info->GetSessionId()); - if (NS_WARN_IF(!mParent->SendPPresentationBuilderConstructor(this, - sessionId, - aRole))) { - return NS_ERROR_FAILURE; - } - mIPCSessionTransport = new PresentationSessionTransportIPC(mParent, - sessionId, - aRole); - mNeedDestroyActor = true; - mParent = nullptr; - return NS_OK; -} - -NS_IMETHODIMP -PresentationBuilderParent::OnIceCandidate(const nsAString& aCandidate) -{ - if (NS_WARN_IF(!SendOnIceCandidate(nsString(aCandidate)))){ - return NS_ERROR_FAILURE; - } - return NS_OK; -} - -NS_IMETHODIMP -PresentationBuilderParent::OnOffer(nsIPresentationChannelDescription* aDescription) -{ - nsAutoString SDP; - nsresult rv = aDescription->GetDataChannelSDP(SDP); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - if (NS_WARN_IF(!SendOnOffer(SDP))){ - return NS_ERROR_FAILURE; - } - return NS_OK; -} - -NS_IMETHODIMP -PresentationBuilderParent::OnAnswer(nsIPresentationChannelDescription* aDescription) -{ - nsAutoString SDP; - nsresult rv = aDescription->GetDataChannelSDP(SDP); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - if (NS_WARN_IF(!SendOnAnswer(SDP))){ - return NS_ERROR_FAILURE; - } - return NS_OK; -} - -NS_IMETHODIMP -PresentationBuilderParent::NotifyDisconnected(nsresult aReason) -{ - return NS_OK; -} - -void -PresentationBuilderParent::ActorDestroy(ActorDestroyReason aWhy) -{ - mNeedDestroyActor = false; - mParent = nullptr; - mBuilderListener = nullptr; -} - -bool -PresentationBuilderParent::RecvSendOffer(const nsString& aSDP) -{ - RefPtr description = - new DCPresentationChannelDescription(aSDP); - if (NS_WARN_IF(!mBuilderListener || - NS_FAILED(mBuilderListener->SendOffer(description)))) { - return false; - } - return true; -} - -bool -PresentationBuilderParent::RecvSendAnswer(const nsString& aSDP) -{ - RefPtr description = - new DCPresentationChannelDescription(aSDP); - if (NS_WARN_IF(!mBuilderListener || - NS_FAILED(mBuilderListener->SendAnswer(description)))) { - return false; - } - return true; -} - -bool -PresentationBuilderParent::RecvSendIceCandidate(const nsString& aCandidate) -{ - if (NS_WARN_IF(!mBuilderListener || - NS_FAILED(mBuilderListener->SendIceCandidate(aCandidate)))) { - return false; - } - return true; -} - -bool -PresentationBuilderParent::RecvClose(const nsresult& aReason) -{ - if (NS_WARN_IF(!mBuilderListener || - NS_FAILED(mBuilderListener->Close(aReason)))) { - return false; - } - return true; -} - -// Delegate to nsIPresentationSessionTransportBuilderListener -bool -PresentationBuilderParent::RecvOnSessionTransport() -{ - RefPtr kungFuDeathGrip = this; - Unused << - NS_WARN_IF(!mBuilderListener || - NS_FAILED(mBuilderListener->OnSessionTransport(mIPCSessionTransport))); - return true; -} - -bool -PresentationBuilderParent::RecvOnSessionTransportError(const nsresult& aReason) -{ - if (NS_WARN_IF(!mBuilderListener || - NS_FAILED(mBuilderListener->OnError(aReason)))) { - return false; - } - return true; -} - -} // namespace dom -} // namespace mozilla diff --git a/dom/presentation/ipc/PresentationBuilderParent.h b/dom/presentation/ipc/PresentationBuilderParent.h deleted file mode 100644 index 7fd211ce52..0000000000 --- a/dom/presentation/ipc/PresentationBuilderParent.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* 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/. */ - -#ifndef mozilla_dom_PresentationBuilderParent_h__ -#define mozilla_dom_PresentationBuilderParent_h__ - -#include "mozilla/dom/PPresentationBuilderParent.h" -#include "PresentationParent.h" -#include "nsIPresentationSessionTransportBuilder.h" - -namespace mozilla { -namespace dom { - -class PresentationBuilderParent final: public PPresentationBuilderParent - , public nsIPresentationDataChannelSessionTransportBuilder -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIPRESENTATIONSESSIONTRANSPORTBUILDER - NS_DECL_NSIPRESENTATIONDATACHANNELSESSIONTRANSPORTBUILDER - - explicit PresentationBuilderParent(PresentationParent* aParent); - - virtual bool RecvSendOffer(const nsString& aSDP) override; - - virtual bool RecvSendAnswer(const nsString& aSDP) override; - - virtual bool RecvSendIceCandidate(const nsString& aCandidate) override; - - virtual bool RecvClose(const nsresult& aReason) override; - - virtual void ActorDestroy(ActorDestroyReason aWhy) override; - - virtual bool RecvOnSessionTransport() override; - - virtual bool RecvOnSessionTransportError(const nsresult& aReason) override; - -private: - virtual ~PresentationBuilderParent(); - bool mNeedDestroyActor = false; - RefPtr mParent; - nsCOMPtr mBuilderListener; - nsCOMPtr mIPCSessionTransport; -}; - -} // namespace dom -} // namespace mozilla - -#endif // mozilla_dom_PresentationBuilderParent_h__ diff --git a/dom/presentation/ipc/PresentationChild.cpp b/dom/presentation/ipc/PresentationChild.cpp deleted file mode 100644 index d24ba9e8cd..0000000000 --- a/dom/presentation/ipc/PresentationChild.cpp +++ /dev/null @@ -1,198 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* 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/. */ - -#include "DCPresentationChannelDescription.h" -#include "mozilla/StaticPtr.h" -#include "PresentationBuilderChild.h" -#include "PresentationChild.h" -#include "PresentationIPCService.h" -#include "nsThreadUtils.h" - -using namespace mozilla; -using namespace mozilla::dom; - -/* - * Implementation of PresentationChild - */ - -PresentationChild::PresentationChild(PresentationIPCService* aService) - : mActorDestroyed(false) - , mService(aService) -{ - MOZ_ASSERT(mService); - - MOZ_COUNT_CTOR(PresentationChild); -} - -PresentationChild::~PresentationChild() -{ - MOZ_COUNT_DTOR(PresentationChild); - - if (!mActorDestroyed) { - Send__delete__(this); - } - mService = nullptr; -} - -void -PresentationChild::ActorDestroy(ActorDestroyReason aWhy) -{ - mActorDestroyed = true; - mService->NotifyPresentationChildDestroyed(); - mService = nullptr; -} - -PPresentationRequestChild* -PresentationChild::AllocPPresentationRequestChild(const PresentationIPCRequest& aRequest) -{ - NS_NOTREACHED("We should never be manually allocating PPresentationRequestChild actors"); - return nullptr; -} - -bool -PresentationChild::DeallocPPresentationRequestChild(PPresentationRequestChild* aActor) -{ - delete aActor; - return true; -} - -bool PresentationChild::RecvPPresentationBuilderConstructor( - PPresentationBuilderChild* aActor, - const nsString& aSessionId, - const uint8_t& aRole) -{ - // Child will build the session transport - PresentationBuilderChild* actor = static_cast(aActor); - return NS_WARN_IF(NS_FAILED(actor->Init())) ? false : true; -} - -PPresentationBuilderChild* -PresentationChild::AllocPPresentationBuilderChild(const nsString& aSessionId, - const uint8_t& aRole) -{ - RefPtr actor - = new PresentationBuilderChild(aSessionId, aRole); - - return actor.forget().take(); -} - -bool -PresentationChild::DeallocPPresentationBuilderChild(PPresentationBuilderChild* aActor) -{ - RefPtr actor = - dont_AddRef(static_cast(aActor)); - return true; -} - - -bool -PresentationChild::RecvNotifyAvailableChange( - nsTArray&& aAvailabilityUrls, - const bool& aAvailable) -{ - if (mService) { - Unused << - NS_WARN_IF(NS_FAILED(mService->NotifyAvailableChange(aAvailabilityUrls, - aAvailable))); - } - return true; -} - -bool -PresentationChild::RecvNotifySessionStateChange(const nsString& aSessionId, - const uint16_t& aState, - const nsresult& aReason) -{ - if (mService) { - Unused << NS_WARN_IF(NS_FAILED(mService->NotifySessionStateChange(aSessionId, - aState, - aReason))); - } - return true; -} - -bool -PresentationChild::RecvNotifyMessage(const nsString& aSessionId, - const nsCString& aData, - const bool& aIsBinary) -{ - if (mService) { - Unused << NS_WARN_IF(NS_FAILED(mService->NotifyMessage(aSessionId, - aData, - aIsBinary))); - } - return true; -} - -bool -PresentationChild::RecvNotifySessionConnect(const uint64_t& aWindowId, - const nsString& aSessionId) -{ - if (mService) { - Unused << NS_WARN_IF(NS_FAILED(mService->NotifySessionConnect(aWindowId, aSessionId))); - } - return true; -} - -bool -PresentationChild::RecvNotifyCloseSessionTransport(const nsString& aSessionId, - const uint8_t& aRole, - const nsresult& aReason) -{ - if (mService) { - Unused << NS_WARN_IF(NS_FAILED( - mService->CloseContentSessionTransport(aSessionId, aRole, aReason))); - } - return true; -} - -/* - * Implementation of PresentationRequestChild - */ - -PresentationRequestChild::PresentationRequestChild(nsIPresentationServiceCallback* aCallback) - : mActorDestroyed(false) - , mCallback(aCallback) -{ - MOZ_COUNT_CTOR(PresentationRequestChild); -} - -PresentationRequestChild::~PresentationRequestChild() -{ - MOZ_COUNT_DTOR(PresentationRequestChild); - - mCallback = nullptr; -} - -void -PresentationRequestChild::ActorDestroy(ActorDestroyReason aWhy) -{ - mActorDestroyed = true; - mCallback = nullptr; -} - -bool -PresentationRequestChild::Recv__delete__(const nsresult& aResult) -{ - if (mActorDestroyed) { - return true; - } - - if (mCallback) { - if (NS_FAILED(aResult)) { - Unused << NS_WARN_IF(NS_FAILED(mCallback->NotifyError(aResult))); - } - } - - return true; -} - -bool -PresentationRequestChild::RecvNotifyRequestUrlSelected(const nsString& aUrl) -{ - Unused << NS_WARN_IF(NS_FAILED(mCallback->NotifySuccess(aUrl))); - return true; -} diff --git a/dom/presentation/ipc/PresentationChild.h b/dom/presentation/ipc/PresentationChild.h deleted file mode 100644 index 1c625b8ceb..0000000000 --- a/dom/presentation/ipc/PresentationChild.h +++ /dev/null @@ -1,101 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* 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/. */ - -#ifndef mozilla_dom_PresentationChild_h -#define mozilla_dom_PresentationChild_h - -#include "mozilla/dom/PPresentationBuilderChild.h" -#include "mozilla/dom/PPresentationChild.h" -#include "mozilla/dom/PPresentationRequestChild.h" - -class nsIPresentationServiceCallback; - -namespace mozilla { -namespace dom { - -class PresentationIPCService; - -class PresentationChild final : public PPresentationChild -{ -public: - explicit PresentationChild(PresentationIPCService* aService); - - virtual void - ActorDestroy(ActorDestroyReason aWhy) override; - - virtual PPresentationRequestChild* - AllocPPresentationRequestChild(const PresentationIPCRequest& aRequest) override; - - virtual bool - DeallocPPresentationRequestChild(PPresentationRequestChild* aActor) override; - - bool RecvPPresentationBuilderConstructor(PPresentationBuilderChild* aActor, - const nsString& aSessionId, - const uint8_t& aRole) override; - - virtual PPresentationBuilderChild* - AllocPPresentationBuilderChild(const nsString& aSessionId, const uint8_t& aRole) override; - - virtual bool - DeallocPPresentationBuilderChild(PPresentationBuilderChild* aActor) override; - - virtual bool - RecvNotifyAvailableChange(nsTArray&& aAvailabilityUrls, - const bool& aAvailable) override; - - virtual bool - RecvNotifySessionStateChange(const nsString& aSessionId, - const uint16_t& aState, - const nsresult& aReason) override; - - virtual bool - RecvNotifyMessage(const nsString& aSessionId, - const nsCString& aData, - const bool& aIsBinary) override; - - virtual bool - RecvNotifySessionConnect(const uint64_t& aWindowId, - const nsString& aSessionId) override; - - virtual bool - RecvNotifyCloseSessionTransport(const nsString& aSessionId, - const uint8_t& aRole, - const nsresult& aReason) override; - -private: - virtual ~PresentationChild(); - - bool mActorDestroyed = false; - RefPtr mService; -}; - -class PresentationRequestChild final : public PPresentationRequestChild -{ - friend class PresentationChild; - -public: - explicit PresentationRequestChild(nsIPresentationServiceCallback* aCallback); - - virtual void - ActorDestroy(ActorDestroyReason aWhy) override; - - virtual bool - Recv__delete__(const nsresult& aResult) override; - - virtual bool - RecvNotifyRequestUrlSelected(const nsString& aUrl) override; - -private: - virtual ~PresentationRequestChild(); - - bool mActorDestroyed = false; - nsCOMPtr mCallback; -}; - -} // namespace dom -} // namespace mozilla - -#endif // mozilla_dom_PresentationChild_h diff --git a/dom/presentation/ipc/PresentationContentSessionInfo.cpp b/dom/presentation/ipc/PresentationContentSessionInfo.cpp deleted file mode 100644 index 071ea924f3..0000000000 --- a/dom/presentation/ipc/PresentationContentSessionInfo.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* 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 "nsServiceManagerUtils.h" -#include "PresentationContentSessionInfo.h" -#include "PresentationIPCService.h" - -namespace mozilla { -namespace dom { - -NS_IMPL_ISUPPORTS(PresentationContentSessionInfo, - nsIPresentationSessionTransportCallback); - -nsresult -PresentationContentSessionInfo::Init() { - if (NS_WARN_IF(NS_FAILED(mTransport->SetCallback(this)))) { - return NS_ERROR_NOT_AVAILABLE; - } - if (NS_WARN_IF(NS_FAILED(mTransport->EnableDataNotification()))) { - return NS_ERROR_NOT_AVAILABLE; - } - return NS_OK; -} - -nsresult -PresentationContentSessionInfo::Send(const nsAString& aData) -{ - if (!mTransport) { - return NS_ERROR_NOT_AVAILABLE; - } - - return mTransport->Send(aData); -} - -nsresult -PresentationContentSessionInfo::SendBinaryMsg(const nsACString& aData) -{ - if (NS_WARN_IF(!mTransport)) { - return NS_ERROR_NOT_AVAILABLE; - } - - return mTransport->SendBinaryMsg(aData); -} - -nsresult -PresentationContentSessionInfo::SendBlob(nsIDOMBlob* aBlob) -{ - if (NS_WARN_IF(!mTransport)) { - return NS_ERROR_NOT_AVAILABLE; - } - - return mTransport->SendBlob(aBlob); -} - -nsresult -PresentationContentSessionInfo::Close(nsresult aReason) -{ - if (!mTransport) { - return NS_ERROR_NOT_AVAILABLE; - } - - return mTransport->Close(aReason); -} - -// nsIPresentationSessionTransportCallback -NS_IMETHODIMP -PresentationContentSessionInfo::NotifyTransportReady() -{ - // do nothing since |onSessionTransport| implies this - return NS_OK; -} - -NS_IMETHODIMP -PresentationContentSessionInfo::NotifyTransportClosed(nsresult aReason) -{ - MOZ_ASSERT(NS_IsMainThread()); - - // Nullify |mTransport| here so it won't try to re-close |mTransport| in - // potential subsequent |Shutdown| calls. - mTransport = nullptr; - nsCOMPtr service = - do_GetService(PRESENTATION_SERVICE_CONTRACTID); - if (NS_WARN_IF(!service)) { - return NS_ERROR_NOT_AVAILABLE; - } - return static_cast(service.get())-> - NotifyTransportClosed(mSessionId, mRole, aReason); -} - -NS_IMETHODIMP -PresentationContentSessionInfo::NotifyData(const nsACString& aData, - bool aIsBinary) -{ - MOZ_ASSERT(NS_IsMainThread()); - - nsCOMPtr service = - do_GetService(PRESENTATION_SERVICE_CONTRACTID); - if (NS_WARN_IF(!service)) { - return NS_ERROR_NOT_AVAILABLE; - } - return static_cast(service.get())-> - NotifyMessage(mSessionId, aData, aIsBinary); -} - -} // namespace dom -} // namespace mozilla diff --git a/dom/presentation/ipc/PresentationContentSessionInfo.h b/dom/presentation/ipc/PresentationContentSessionInfo.h deleted file mode 100644 index 447485dbd1..0000000000 --- a/dom/presentation/ipc/PresentationContentSessionInfo.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_dom_PresentationContentSessionInfo_h -#define mozilla_dom_PresentationContentSessionInfo_h - -#include "nsCOMPtr.h" -#include "nsIPresentationSessionTransport.h" - -namespace mozilla { -namespace dom { - -/** - * PresentationContentSessionInfo manages nsIPresentationSessionTransport and - * delegates the callbacks to PresentationIPCService. Only lives in content - * process. - */ -class PresentationContentSessionInfo final : public nsIPresentationSessionTransportCallback -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIPRESENTATIONSESSIONTRANSPORTCALLBACK - - PresentationContentSessionInfo(const nsAString& aSessionId, - uint8_t aRole, - nsIPresentationSessionTransport* aTransport) - : mSessionId(aSessionId) - , mRole(aRole) - , mTransport(aTransport) - { - MOZ_ASSERT(XRE_IsContentProcess()); - MOZ_ASSERT(!aSessionId.IsEmpty()); - MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER || - aRole == nsIPresentationService::ROLE_RECEIVER); - MOZ_ASSERT(aTransport); - } - - nsresult Init(); - - nsresult Send(const nsAString& aData); - - nsresult SendBinaryMsg(const nsACString& aData); - - nsresult SendBlob(nsIDOMBlob* aBlob); - - nsresult Close(nsresult aReason); - -private: - virtual ~PresentationContentSessionInfo() {} - - nsString mSessionId; - uint8_t mRole; - nsCOMPtr mTransport; -}; - -} // namespace dom -} // namespace mozilla - -#endif // mozilla_dom_PresentationContentSessionInfo_h diff --git a/dom/presentation/ipc/PresentationIPCService.cpp b/dom/presentation/ipc/PresentationIPCService.cpp deleted file mode 100644 index 8c85b239d4..0000000000 --- a/dom/presentation/ipc/PresentationIPCService.cpp +++ /dev/null @@ -1,538 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set sw=2 ts=8 et 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 "mozilla/dom/ContentChild.h" -#include "mozilla/dom/PermissionMessageUtils.h" -#include "mozilla/dom/PPresentation.h" -#include "mozilla/dom/TabParent.h" -#include "mozilla/ipc/InputStreamUtils.h" -#include "mozilla/ipc/URIUtils.h" -#include "nsGlobalWindow.h" -#include "nsIPresentationListener.h" -#include "PresentationCallbacks.h" -#include "PresentationChild.h" -#include "PresentationContentSessionInfo.h" -#include "PresentationIPCService.h" -#include "PresentationLog.h" - -using namespace mozilla; -using namespace mozilla::dom; -using namespace mozilla::ipc; - -namespace { - -PresentationChild* sPresentationChild; - -} // anonymous - -NS_IMPL_ISUPPORTS(PresentationIPCService, - nsIPresentationService, - nsIPresentationAvailabilityListener) - -PresentationIPCService::PresentationIPCService() -{ - ContentChild* contentChild = ContentChild::GetSingleton(); - if (NS_WARN_IF(!contentChild)) { - return; - } - sPresentationChild = new PresentationChild(this); - Unused << - NS_WARN_IF(!contentChild->SendPPresentationConstructor(sPresentationChild)); -} - -/* virtual */ -PresentationIPCService::~PresentationIPCService() -{ - Shutdown(); - - mSessionListeners.Clear(); - mSessionInfoAtController.Clear(); - mSessionInfoAtReceiver.Clear(); - sPresentationChild = nullptr; -} - -NS_IMETHODIMP -PresentationIPCService::StartSession( - const nsTArray& aUrls, - const nsAString& aSessionId, - const nsAString& aOrigin, - const nsAString& aDeviceId, - uint64_t aWindowId, - nsIDOMEventTarget* aEventTarget, - nsIPrincipal* aPrincipal, - nsIPresentationServiceCallback* aCallback, - nsIPresentationTransportBuilderConstructor* aBuilderConstructor) -{ - if (aWindowId != 0) { - AddRespondingSessionId(aWindowId, - aSessionId, - nsIPresentationService::ROLE_CONTROLLER); - } - - nsPIDOMWindowInner* window = - nsGlobalWindow::GetInnerWindowWithId(aWindowId)->AsInner(); - TabId tabId = TabParent::GetTabIdFrom(window->GetDocShell()); - - return SendRequest(aCallback, StartSessionRequest(aUrls, - nsString(aSessionId), - nsString(aOrigin), - nsString(aDeviceId), - aWindowId, - tabId, - IPC::Principal(aPrincipal))); -} - -NS_IMETHODIMP -PresentationIPCService::SendSessionMessage(const nsAString& aSessionId, - uint8_t aRole, - const nsAString& aData) -{ - MOZ_ASSERT(!aSessionId.IsEmpty()); - MOZ_ASSERT(!aData.IsEmpty()); - - RefPtr info = - GetSessionInfo(aSessionId, aRole); - // data channel session transport is maintained by content process - if (info) { - return info->Send(aData); - } - - return SendRequest(nullptr, SendSessionMessageRequest(nsString(aSessionId), - aRole, - nsString(aData))); -} - -NS_IMETHODIMP -PresentationIPCService::SendSessionBinaryMsg(const nsAString& aSessionId, - uint8_t aRole, - const nsACString &aData) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(!aData.IsEmpty()); - MOZ_ASSERT(!aSessionId.IsEmpty()); - MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER || - aRole == nsIPresentationService::ROLE_RECEIVER); - - RefPtr info = - GetSessionInfo(aSessionId, aRole); - // data channel session transport is maintained by content process - if (info) { - return info->SendBinaryMsg(aData); - } - - return NS_ERROR_NOT_AVAILABLE; -} - -NS_IMETHODIMP -PresentationIPCService::SendSessionBlob(const nsAString& aSessionId, - uint8_t aRole, - nsIDOMBlob* aBlob) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(!aSessionId.IsEmpty()); - MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER || - aRole == nsIPresentationService::ROLE_RECEIVER); - MOZ_ASSERT(aBlob); - - RefPtr info = - GetSessionInfo(aSessionId, aRole); - // data channel session transport is maintained by content process - if (info) { - return info->SendBlob(aBlob); - } - - return NS_ERROR_NOT_AVAILABLE; -} - -NS_IMETHODIMP -PresentationIPCService::CloseSession(const nsAString& aSessionId, - uint8_t aRole, - uint8_t aClosedReason) -{ - MOZ_ASSERT(!aSessionId.IsEmpty()); - - nsresult rv = SendRequest(nullptr, CloseSessionRequest(nsString(aSessionId), - aRole, - aClosedReason)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - RefPtr info = - GetSessionInfo(aSessionId, aRole); - if (info) { - return info->Close(NS_OK); - } - - return NS_OK; -} - -NS_IMETHODIMP -PresentationIPCService::TerminateSession(const nsAString& aSessionId, - uint8_t aRole) -{ - MOZ_ASSERT(!aSessionId.IsEmpty()); - - nsresult rv = SendRequest(nullptr, TerminateSessionRequest(nsString(aSessionId), aRole)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - RefPtr info = - GetSessionInfo(aSessionId, aRole); - if (info) { - return info->Close(NS_OK); - } - - return NS_OK; -} - -NS_IMETHODIMP -PresentationIPCService::ReconnectSession(const nsTArray& aUrls, - const nsAString& aSessionId, - uint8_t aRole, - nsIPresentationServiceCallback* aCallback) -{ - MOZ_ASSERT(!aSessionId.IsEmpty()); - - if (aRole != nsIPresentationService::ROLE_CONTROLLER) { - MOZ_ASSERT(false, "Only controller can call ReconnectSession."); - return NS_ERROR_INVALID_ARG; - } - - return SendRequest(aCallback, ReconnectSessionRequest(aUrls, - nsString(aSessionId), - aRole)); -} - -NS_IMETHODIMP -PresentationIPCService::BuildTransport(const nsAString& aSessionId, - uint8_t aRole) -{ - MOZ_ASSERT(!aSessionId.IsEmpty()); - - if (aRole != nsIPresentationService::ROLE_CONTROLLER) { - MOZ_ASSERT(false, "Only controller can call ReconnectSession."); - return NS_ERROR_INVALID_ARG; - } - - return SendRequest(nullptr, BuildTransportRequest(nsString(aSessionId), - aRole)); -} - -nsresult -PresentationIPCService::SendRequest(nsIPresentationServiceCallback* aCallback, - const PresentationIPCRequest& aRequest) -{ - if (sPresentationChild) { - PresentationRequestChild* actor = new PresentationRequestChild(aCallback); - Unused << NS_WARN_IF(!sPresentationChild->SendPPresentationRequestConstructor(actor, aRequest)); - } - return NS_OK; -} - -NS_IMETHODIMP -PresentationIPCService::RegisterAvailabilityListener( - const nsTArray& aAvailabilityUrls, - nsIPresentationAvailabilityListener* aListener) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(!aAvailabilityUrls.IsEmpty()); - MOZ_ASSERT(aListener); - - nsTArray addedUrls; - mAvailabilityManager.AddAvailabilityListener(aAvailabilityUrls, - aListener, - addedUrls); - - if (sPresentationChild && !addedUrls.IsEmpty()) { - Unused << - NS_WARN_IF( - !sPresentationChild->SendRegisterAvailabilityHandler(addedUrls)); - } - return NS_OK; -} - -NS_IMETHODIMP -PresentationIPCService::UnregisterAvailabilityListener( - const nsTArray& aAvailabilityUrls, - nsIPresentationAvailabilityListener* aListener) -{ - MOZ_ASSERT(NS_IsMainThread()); - - nsTArray removedUrls; - mAvailabilityManager.RemoveAvailabilityListener(aAvailabilityUrls, - aListener, - removedUrls); - - if (sPresentationChild && !removedUrls.IsEmpty()) { - Unused << - NS_WARN_IF( - !sPresentationChild->SendUnregisterAvailabilityHandler(removedUrls)); - } - return NS_OK; -} - -NS_IMETHODIMP -PresentationIPCService::RegisterSessionListener(const nsAString& aSessionId, - uint8_t aRole, - nsIPresentationSessionListener* aListener) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(aListener); - - nsCOMPtr listener; - if (mSessionListeners.Get(aSessionId, getter_AddRefs(listener))) { - mSessionListeners.Put(aSessionId, aListener); - return NS_OK; - } - - mSessionListeners.Put(aSessionId, aListener); - if (sPresentationChild) { - Unused << - NS_WARN_IF(!sPresentationChild->SendRegisterSessionHandler( - nsString(aSessionId), aRole)); - } - return NS_OK; -} - -NS_IMETHODIMP -PresentationIPCService::UnregisterSessionListener(const nsAString& aSessionId, - uint8_t aRole) -{ - MOZ_ASSERT(NS_IsMainThread()); - - UntrackSessionInfo(aSessionId, aRole); - - mSessionListeners.Remove(aSessionId); - if (sPresentationChild) { - Unused << - NS_WARN_IF(!sPresentationChild->SendUnregisterSessionHandler( - nsString(aSessionId), aRole)); - } - return NS_OK; -} - -NS_IMETHODIMP -PresentationIPCService::RegisterRespondingListener(uint64_t aWindowId, - nsIPresentationRespondingListener* aListener) -{ - MOZ_ASSERT(NS_IsMainThread()); - - mRespondingListeners.Put(aWindowId, aListener); - if (sPresentationChild) { - Unused << - NS_WARN_IF(!sPresentationChild->SendRegisterRespondingHandler(aWindowId)); - } - return NS_OK; -} - -NS_IMETHODIMP -PresentationIPCService::UnregisterRespondingListener(uint64_t aWindowId) -{ - MOZ_ASSERT(NS_IsMainThread()); - - mRespondingListeners.Remove(aWindowId); - if (sPresentationChild) { - Unused << - NS_WARN_IF(!sPresentationChild->SendUnregisterRespondingHandler( - aWindowId)); - } - return NS_OK; -} - -nsresult -PresentationIPCService::NotifySessionTransport(const nsString& aSessionId, - const uint8_t& aRole, - nsIPresentationSessionTransport* aTransport) -{ - RefPtr info = - new PresentationContentSessionInfo(aSessionId, aRole, aTransport); - - if (NS_WARN_IF(NS_FAILED(info->Init()))) { - return NS_ERROR_NOT_AVAILABLE; - } - - if (aRole == nsIPresentationService::ROLE_CONTROLLER) { - mSessionInfoAtController.Put(aSessionId, info); - } else { - mSessionInfoAtReceiver.Put(aSessionId, info); - } - return NS_OK; -} - -NS_IMETHODIMP -PresentationIPCService::GetWindowIdBySessionId(const nsAString& aSessionId, - uint8_t aRole, - uint64_t* aWindowId) -{ - return GetWindowIdBySessionIdInternal(aSessionId, aRole, aWindowId); -} - -NS_IMETHODIMP -PresentationIPCService::UpdateWindowIdBySessionId(const nsAString& aSessionId, - uint8_t aRole, - const uint64_t aWindowId) -{ - return UpdateWindowIdBySessionIdInternal(aSessionId, aRole, aWindowId); -} - -nsresult -PresentationIPCService::NotifySessionStateChange(const nsAString& aSessionId, - uint16_t aState, - nsresult aReason) -{ - nsCOMPtr listener; - if (NS_WARN_IF(!mSessionListeners.Get(aSessionId, getter_AddRefs(listener)))) { - return NS_OK; - } - - return listener->NotifyStateChange(aSessionId, aState, aReason); -} - -// Only used for OOP RTCDataChannel session transport case. -nsresult -PresentationIPCService::NotifyMessage(const nsAString& aSessionId, - const nsACString& aData, - const bool& aIsBinary) -{ - nsCOMPtr listener; - if (NS_WARN_IF(!mSessionListeners.Get(aSessionId, getter_AddRefs(listener)))) { - return NS_OK; - } - - return listener->NotifyMessage(aSessionId, aData, aIsBinary); -} - -// Only used for OOP RTCDataChannel session transport case. -nsresult -PresentationIPCService::NotifyTransportClosed(const nsAString& aSessionId, - uint8_t aRole, - nsresult aReason) -{ - RefPtr info = - GetSessionInfo(aSessionId, aRole); - if (NS_WARN_IF(!info)) { - return NS_ERROR_NOT_AVAILABLE; - } - Unused << NS_WARN_IF(!sPresentationChild->SendNotifyTransportClosed(nsString(aSessionId), aRole, aReason)); - return NS_OK; -} - -nsresult -PresentationIPCService::NotifySessionConnect(uint64_t aWindowId, - const nsAString& aSessionId) -{ - nsCOMPtr listener; - if (NS_WARN_IF(!mRespondingListeners.Get(aWindowId, getter_AddRefs(listener)))) { - return NS_OK; - } - - return listener->NotifySessionConnect(aWindowId, aSessionId); -} - -NS_IMETHODIMP -PresentationIPCService::NotifyAvailableChange( - const nsTArray& aAvailabilityUrls, - bool aAvailable) -{ - return mAvailabilityManager.DoNotifyAvailableChange(aAvailabilityUrls, - aAvailable); -} - -NS_IMETHODIMP -PresentationIPCService::NotifyReceiverReady( - const nsAString& aSessionId, - uint64_t aWindowId, - bool aIsLoading, - nsIPresentationTransportBuilderConstructor* aBuilderConstructor) -{ - MOZ_ASSERT(NS_IsMainThread()); - - // No actual window uses 0 as its ID. - if (NS_WARN_IF(aWindowId == 0)) { - return NS_ERROR_NOT_AVAILABLE; - } - - // Track the responding info for an OOP receiver page. - AddRespondingSessionId(aWindowId, - aSessionId, - nsIPresentationService::ROLE_RECEIVER); - - Unused << NS_WARN_IF(!sPresentationChild->SendNotifyReceiverReady(nsString(aSessionId), - aWindowId, - aIsLoading)); - - // Release mCallback after using aSessionId - // because aSessionId is held by mCallback. - mCallback = nullptr; - return NS_OK; -} - -NS_IMETHODIMP -PresentationIPCService::UntrackSessionInfo(const nsAString& aSessionId, - uint8_t aRole) -{ - PRES_DEBUG("content %s:id[%s], role[%d]\n", __func__, - NS_ConvertUTF16toUTF8(aSessionId).get(), aRole); - - if (nsIPresentationService::ROLE_RECEIVER == aRole) { - // Terminate receiver page. - uint64_t windowId; - if (NS_SUCCEEDED(GetWindowIdBySessionIdInternal(aSessionId, - aRole, - &windowId))) { - NS_DispatchToMainThread(NS_NewRunnableFunction([windowId]() -> void { - PRES_DEBUG("Attempt to close window[%d]\n", windowId); - - if (auto* window = nsGlobalWindow::GetInnerWindowWithId(windowId)) { - window->Close(); - } - })); - } - } - - // Remove the OOP responding info (if it has never been used). - RemoveRespondingSessionId(aSessionId, aRole); - - if (nsIPresentationService::ROLE_CONTROLLER == aRole) { - mSessionInfoAtController.Remove(aSessionId); - } else { - mSessionInfoAtReceiver.Remove(aSessionId); - } - - return NS_OK; -} - -void -PresentationIPCService::NotifyPresentationChildDestroyed() -{ - sPresentationChild = nullptr; -} - -nsresult -PresentationIPCService::MonitorResponderLoading(const nsAString& aSessionId, - nsIDocShell* aDocShell) -{ - MOZ_ASSERT(NS_IsMainThread()); - - mCallback = new PresentationResponderLoadingCallback(aSessionId); - return mCallback->Init(aDocShell); -} - -nsresult -PresentationIPCService::CloseContentSessionTransport(const nsString& aSessionId, - uint8_t aRole, - nsresult aReason) -{ - RefPtr info = - GetSessionInfo(aSessionId, aRole); - if (NS_WARN_IF(!info)) { - return NS_ERROR_NOT_AVAILABLE; - } - - return info->Close(aReason); -} diff --git a/dom/presentation/ipc/PresentationIPCService.h b/dom/presentation/ipc/PresentationIPCService.h deleted file mode 100644 index 5eab7e68a7..0000000000 --- a/dom/presentation/ipc/PresentationIPCService.h +++ /dev/null @@ -1,75 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set sw=2 ts=8 et 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/. */ - -#ifndef mozilla_dom_PresentationIPCService_h -#define mozilla_dom_PresentationIPCService_h - -#include "mozilla/dom/PresentationServiceBase.h" -#include "nsIPresentationListener.h" -#include "nsIPresentationSessionTransport.h" -#include "nsIPresentationService.h" - -class nsIDocShell; - -namespace mozilla { -namespace dom { - -class PresentationIPCRequest; -class PresentationContentSessionInfo; -class PresentationResponderLoadingCallback; - -class PresentationIPCService final - : public nsIPresentationAvailabilityListener - , public nsIPresentationService - , public PresentationServiceBase -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIPRESENTATIONAVAILABILITYLISTENER - NS_DECL_NSIPRESENTATIONSERVICE - - PresentationIPCService(); - - nsresult NotifySessionStateChange(const nsAString& aSessionId, - uint16_t aState, - nsresult aReason); - - nsresult NotifyMessage(const nsAString& aSessionId, - const nsACString& aData, - const bool& aIsBinary); - - nsresult NotifySessionConnect(uint64_t aWindowId, - const nsAString& aSessionId); - - void NotifyPresentationChildDestroyed(); - - nsresult MonitorResponderLoading(const nsAString& aSessionId, - nsIDocShell* aDocShell); - - nsresult NotifySessionTransport(const nsString& aSessionId, - const uint8_t& aRole, - nsIPresentationSessionTransport* transport); - - nsresult CloseContentSessionTransport(const nsString& aSessionId, - uint8_t aRole, - nsresult aReason); - -private: - virtual ~PresentationIPCService(); - nsresult SendRequest(nsIPresentationServiceCallback* aCallback, - const PresentationIPCRequest& aRequest); - - nsRefPtrHashtable mSessionListeners; - nsRefPtrHashtable mRespondingListeners; - RefPtr mCallback; -}; - -} // namespace dom -} // namespace mozilla - -#endif // mozilla_dom_PresentationIPCService_h diff --git a/dom/presentation/ipc/PresentationParent.cpp b/dom/presentation/ipc/PresentationParent.cpp deleted file mode 100644 index 02f60500a9..0000000000 --- a/dom/presentation/ipc/PresentationParent.cpp +++ /dev/null @@ -1,553 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* 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/. */ - -#include "DCPresentationChannelDescription.h" -#include "mozilla/dom/ContentProcessManager.h" -#include "mozilla/ipc/InputStreamUtils.h" -#include "mozilla/Unused.h" -#include "nsIPresentationDeviceManager.h" -#include "nsIPresentationSessionTransport.h" -#include "nsIPresentationSessionTransportBuilder.h" -#include "nsServiceManagerUtils.h" -#include "PresentationBuilderParent.h" -#include "PresentationParent.h" -#include "PresentationService.h" -#include "PresentationSessionInfo.h" - -namespace mozilla { -namespace dom { - -namespace { - -class PresentationTransportBuilderConstructorIPC final : - public nsIPresentationTransportBuilderConstructor -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIPRESENTATIONTRANSPORTBUILDERCONSTRUCTOR - - explicit PresentationTransportBuilderConstructorIPC(PresentationParent* aParent) - : mParent(aParent) - { - } - -private: - virtual ~PresentationTransportBuilderConstructorIPC() = default; - - RefPtr mParent; -}; - -NS_IMPL_ISUPPORTS(PresentationTransportBuilderConstructorIPC, - nsIPresentationTransportBuilderConstructor) - -NS_IMETHODIMP -PresentationTransportBuilderConstructorIPC::CreateTransportBuilder( - uint8_t aType, - nsIPresentationSessionTransportBuilder** aRetval) -{ - if (NS_WARN_IF(!aRetval)) { - return NS_ERROR_INVALID_ARG; - } - - *aRetval = nullptr; - - if (NS_WARN_IF(aType != nsIPresentationChannelDescription::TYPE_TCP && - aType != nsIPresentationChannelDescription::TYPE_DATACHANNEL)) { - return NS_ERROR_INVALID_ARG; - } - - if (XRE_IsContentProcess()) { - MOZ_ASSERT(false, - "CreateTransportBuilder can only be invoked in parent process."); - return NS_ERROR_FAILURE; - } - - nsCOMPtr builder; - if (aType == nsIPresentationChannelDescription::TYPE_TCP) { - builder = do_CreateInstance(PRESENTATION_TCP_SESSION_TRANSPORT_CONTRACTID); - } else { - builder = new PresentationBuilderParent(mParent); - } - - if (NS_WARN_IF(!builder)) { - return NS_ERROR_DOM_OPERATION_ERR; - } - - builder.forget(aRetval); - return NS_OK; -} - -} // anonymous namespace - -/* - * Implementation of PresentationParent - */ - -NS_IMPL_ISUPPORTS(PresentationParent, - nsIPresentationAvailabilityListener, - nsIPresentationSessionListener, - nsIPresentationRespondingListener) - -PresentationParent::PresentationParent() -{ - MOZ_COUNT_CTOR(PresentationParent); -} - -/* virtual */ PresentationParent::~PresentationParent() -{ - MOZ_COUNT_DTOR(PresentationParent); -} - -bool -PresentationParent::Init(ContentParentId aContentParentId) -{ - MOZ_ASSERT(!mService); - mService = do_GetService(PRESENTATION_SERVICE_CONTRACTID); - mChildId = aContentParentId; - return NS_WARN_IF(!mService) ? false : true; -} - -void -PresentationParent::ActorDestroy(ActorDestroyReason aWhy) -{ - mActorDestroyed = true; - - for (uint32_t i = 0; i < mSessionIdsAtController.Length(); i++) { - Unused << NS_WARN_IF(NS_FAILED(mService-> - UnregisterSessionListener(mSessionIdsAtController[i], - nsIPresentationService::ROLE_CONTROLLER))); - } - mSessionIdsAtController.Clear(); - - for (uint32_t i = 0; i < mSessionIdsAtReceiver.Length(); i++) { - Unused << NS_WARN_IF(NS_FAILED(mService-> - UnregisterSessionListener(mSessionIdsAtReceiver[i], nsIPresentationService::ROLE_RECEIVER))); - } - mSessionIdsAtReceiver.Clear(); - - for (uint32_t i = 0; i < mWindowIds.Length(); i++) { - Unused << NS_WARN_IF(NS_FAILED(mService-> - UnregisterRespondingListener(mWindowIds[i]))); - } - mWindowIds.Clear(); - - if (!mContentAvailabilityUrls.IsEmpty()) { - mService->UnregisterAvailabilityListener(mContentAvailabilityUrls, this); - } - mService = nullptr; -} - -bool -PresentationParent::RecvPPresentationRequestConstructor( - PPresentationRequestParent* aActor, - const PresentationIPCRequest& aRequest) -{ - PresentationRequestParent* actor = static_cast(aActor); - - nsresult rv = NS_ERROR_FAILURE; - switch (aRequest.type()) { - case PresentationIPCRequest::TStartSessionRequest: - rv = actor->DoRequest(aRequest.get_StartSessionRequest()); - break; - case PresentationIPCRequest::TSendSessionMessageRequest: - rv = actor->DoRequest(aRequest.get_SendSessionMessageRequest()); - break; - case PresentationIPCRequest::TCloseSessionRequest: - rv = actor->DoRequest(aRequest.get_CloseSessionRequest()); - break; - case PresentationIPCRequest::TTerminateSessionRequest: - rv = actor->DoRequest(aRequest.get_TerminateSessionRequest()); - break; - case PresentationIPCRequest::TReconnectSessionRequest: - rv = actor->DoRequest(aRequest.get_ReconnectSessionRequest()); - break; - case PresentationIPCRequest::TBuildTransportRequest: - rv = actor->DoRequest(aRequest.get_BuildTransportRequest()); - break; - default: - MOZ_CRASH("Unknown PresentationIPCRequest type"); - } - - return NS_WARN_IF(NS_FAILED(rv)) ? false : true; -} - -PPresentationRequestParent* -PresentationParent::AllocPPresentationRequestParent( - const PresentationIPCRequest& aRequest) -{ - MOZ_ASSERT(mService); - RefPtr actor = new PresentationRequestParent(mService, mChildId); - return actor.forget().take(); -} - -bool -PresentationParent::DeallocPPresentationRequestParent( - PPresentationRequestParent* aActor) -{ - RefPtr actor = - dont_AddRef(static_cast(aActor)); - return true; -} - -PPresentationBuilderParent* -PresentationParent::AllocPPresentationBuilderParent(const nsString& aSessionId, - const uint8_t& aRole) -{ - NS_NOTREACHED("We should never be manually allocating AllocPPresentationBuilderParent actors"); - return nullptr; -} - -bool -PresentationParent::DeallocPPresentationBuilderParent( - PPresentationBuilderParent* aActor) -{ - return true; -} - -bool -PresentationParent::Recv__delete__() -{ - return true; -} - -bool -PresentationParent::RecvRegisterAvailabilityHandler( - nsTArray&& aAvailabilityUrls) -{ - MOZ_ASSERT(mService); - - Unused << NS_WARN_IF(NS_FAILED(mService->RegisterAvailabilityListener( - aAvailabilityUrls, - this))); - mContentAvailabilityUrls.AppendElements(aAvailabilityUrls); - return true; -} - -bool -PresentationParent::RecvUnregisterAvailabilityHandler( - nsTArray&& aAvailabilityUrls) -{ - MOZ_ASSERT(mService); - - Unused << NS_WARN_IF(NS_FAILED(mService->UnregisterAvailabilityListener( - aAvailabilityUrls, - this))); - for (const auto& url : aAvailabilityUrls) { - mContentAvailabilityUrls.RemoveElement(url); - } - return true; -} - -/* virtual */ bool -PresentationParent::RecvRegisterSessionHandler(const nsString& aSessionId, - const uint8_t& aRole) -{ - MOZ_ASSERT(mService); - - // Validate the accessibility (primarily for receiver side) so that a - // compromised child process can't fake the ID. - if (NS_WARN_IF(!static_cast(mService.get())-> - IsSessionAccessible(aSessionId, aRole, OtherPid()))) { - return true; - } - - if (nsIPresentationService::ROLE_CONTROLLER == aRole) { - mSessionIdsAtController.AppendElement(aSessionId); - } else { - mSessionIdsAtReceiver.AppendElement(aSessionId); - } - Unused << NS_WARN_IF(NS_FAILED(mService->RegisterSessionListener(aSessionId, aRole, this))); - return true; -} - -/* virtual */ bool -PresentationParent::RecvUnregisterSessionHandler(const nsString& aSessionId, - const uint8_t& aRole) -{ - MOZ_ASSERT(mService); - if (nsIPresentationService::ROLE_CONTROLLER == aRole) { - mSessionIdsAtController.RemoveElement(aSessionId); - } else { - mSessionIdsAtReceiver.RemoveElement(aSessionId); - } - Unused << NS_WARN_IF(NS_FAILED(mService->UnregisterSessionListener(aSessionId, aRole))); - return true; -} - -/* virtual */ bool -PresentationParent::RecvRegisterRespondingHandler(const uint64_t& aWindowId) -{ - MOZ_ASSERT(mService); - - mWindowIds.AppendElement(aWindowId); - Unused << NS_WARN_IF(NS_FAILED(mService->RegisterRespondingListener(aWindowId, this))); - return true; -} - -/* virtual */ bool -PresentationParent::RecvUnregisterRespondingHandler(const uint64_t& aWindowId) -{ - MOZ_ASSERT(mService); - mWindowIds.RemoveElement(aWindowId); - Unused << NS_WARN_IF(NS_FAILED(mService->UnregisterRespondingListener(aWindowId))); - return true; -} - -NS_IMETHODIMP -PresentationParent::NotifyAvailableChange(const nsTArray& aAvailabilityUrls, - bool aAvailable) -{ - if (NS_WARN_IF(mActorDestroyed || - !SendNotifyAvailableChange(aAvailabilityUrls, - aAvailable))) { - return NS_ERROR_FAILURE; - } - return NS_OK; -} - -NS_IMETHODIMP -PresentationParent::NotifyStateChange(const nsAString& aSessionId, - uint16_t aState, - nsresult aReason) -{ - if (NS_WARN_IF(mActorDestroyed || - !SendNotifySessionStateChange(nsString(aSessionId), - aState, - aReason))) { - return NS_ERROR_FAILURE; - } - return NS_OK; -} - -NS_IMETHODIMP -PresentationParent::NotifyMessage(const nsAString& aSessionId, - const nsACString& aData, - bool aIsBinary) -{ - if (NS_WARN_IF(mActorDestroyed || - !SendNotifyMessage(nsString(aSessionId), - nsCString(aData), - aIsBinary))) { - return NS_ERROR_FAILURE; - } - return NS_OK; -} - -NS_IMETHODIMP -PresentationParent::NotifySessionConnect(uint64_t aWindowId, - const nsAString& aSessionId) -{ - if (NS_WARN_IF(mActorDestroyed || - !SendNotifySessionConnect(aWindowId, nsString(aSessionId)))) { - return NS_ERROR_FAILURE; - } - return NS_OK; -} - -bool -PresentationParent::RecvNotifyReceiverReady(const nsString& aSessionId, - const uint64_t& aWindowId, - const bool& aIsLoading) -{ - MOZ_ASSERT(mService); - - nsCOMPtr constructor = - new PresentationTransportBuilderConstructorIPC(this); - Unused << NS_WARN_IF(NS_FAILED(mService->NotifyReceiverReady(aSessionId, - aWindowId, - aIsLoading, - constructor))); - return true; -} - -bool -PresentationParent::RecvNotifyTransportClosed(const nsString& aSessionId, - const uint8_t& aRole, - const nsresult& aReason) -{ - MOZ_ASSERT(mService); - - Unused << NS_WARN_IF(NS_FAILED(mService->NotifyTransportClosed(aSessionId, aRole, aReason))); - return true; -} - -/* - * Implementation of PresentationRequestParent - */ - -NS_IMPL_ISUPPORTS(PresentationRequestParent, nsIPresentationServiceCallback) - -PresentationRequestParent::PresentationRequestParent(nsIPresentationService* aService, - ContentParentId aContentParentId) - : mService(aService) - , mChildId(aContentParentId) -{ - MOZ_COUNT_CTOR(PresentationRequestParent); -} - -PresentationRequestParent::~PresentationRequestParent() -{ - MOZ_COUNT_DTOR(PresentationRequestParent); -} - -void -PresentationRequestParent::ActorDestroy(ActorDestroyReason aWhy) -{ - mActorDestroyed = true; - mService = nullptr; -} - -nsresult -PresentationRequestParent::DoRequest(const StartSessionRequest& aRequest) -{ - MOZ_ASSERT(mService); - - mSessionId = aRequest.sessionId(); - - nsCOMPtr eventTarget; - ContentProcessManager* cpm = ContentProcessManager::GetSingleton(); - RefPtr tp = - cpm->GetTopLevelTabParentByProcessAndTabId(mChildId, aRequest.tabId()); - if (tp) { - eventTarget = do_QueryInterface(tp->GetOwnerElement()); - } - - RefPtr parent = static_cast(Manager()); - nsCOMPtr constructor = - new PresentationTransportBuilderConstructorIPC(parent); - return mService->StartSession(aRequest.urls(), aRequest.sessionId(), - aRequest.origin(), aRequest.deviceId(), - aRequest.windowId(), eventTarget, - aRequest.principal(), this, constructor); -} - -nsresult -PresentationRequestParent::DoRequest(const SendSessionMessageRequest& aRequest) -{ - MOZ_ASSERT(mService); - - // Validate the accessibility (primarily for receiver side) so that a - // compromised child process can't fake the ID. - if (NS_WARN_IF(!static_cast(mService.get())-> - IsSessionAccessible(aRequest.sessionId(), aRequest.role(), OtherPid()))) { - return SendResponse(NS_ERROR_DOM_SECURITY_ERR); - } - - nsresult rv = mService->SendSessionMessage(aRequest.sessionId(), - aRequest.role(), - aRequest.data()); - if (NS_WARN_IF(NS_FAILED(rv))) { - return SendResponse(rv); - } - return SendResponse(NS_OK); -} - -nsresult -PresentationRequestParent::DoRequest(const CloseSessionRequest& aRequest) -{ - MOZ_ASSERT(mService); - - // Validate the accessibility (primarily for receiver side) so that a - // compromised child process can't fake the ID. - if (NS_WARN_IF(!static_cast(mService.get())-> - IsSessionAccessible(aRequest.sessionId(), aRequest.role(), OtherPid()))) { - return SendResponse(NS_ERROR_DOM_SECURITY_ERR); - } - - nsresult rv = mService->CloseSession(aRequest.sessionId(), - aRequest.role(), - aRequest.closedReason()); - if (NS_WARN_IF(NS_FAILED(rv))) { - return SendResponse(rv); - } - return SendResponse(NS_OK); -} - -nsresult -PresentationRequestParent::DoRequest(const TerminateSessionRequest& aRequest) -{ - MOZ_ASSERT(mService); - - // Validate the accessibility (primarily for receiver side) so that a - // compromised child process can't fake the ID. - if (NS_WARN_IF(!static_cast(mService.get())-> - IsSessionAccessible(aRequest.sessionId(), aRequest.role(), OtherPid()))) { - return SendResponse(NS_ERROR_DOM_SECURITY_ERR); - } - - nsresult rv = mService->TerminateSession(aRequest.sessionId(), aRequest.role()); - if (NS_WARN_IF(NS_FAILED(rv))) { - return SendResponse(rv); - } - return SendResponse(NS_OK); -} - -nsresult -PresentationRequestParent::DoRequest(const ReconnectSessionRequest& aRequest) -{ - MOZ_ASSERT(mService); - - // Validate the accessibility (primarily for receiver side) so that a - // compromised child process can't fake the ID. - if (NS_WARN_IF(!static_cast(mService.get())-> - IsSessionAccessible(aRequest.sessionId(), aRequest.role(), OtherPid()))) { - - // NOTE: Return NS_ERROR_DOM_NOT_FOUND_ERR here to match the spec. - // https://w3c.github.io/presentation-api/#reconnecting-to-a-presentation - return SendResponse(NS_ERROR_DOM_NOT_FOUND_ERR); - } - - mSessionId = aRequest.sessionId(); - return mService->ReconnectSession(aRequest.urls(), - aRequest.sessionId(), - aRequest.role(), - this); -} - -nsresult -PresentationRequestParent::DoRequest(const BuildTransportRequest& aRequest) -{ - MOZ_ASSERT(mService); - - // Validate the accessibility (primarily for receiver side) so that a - // compromised child process can't fake the ID. - if (NS_WARN_IF(!static_cast(mService.get())-> - IsSessionAccessible(aRequest.sessionId(), aRequest.role(), OtherPid()))) { - return SendResponse(NS_ERROR_DOM_SECURITY_ERR); - } - - nsresult rv = mService->BuildTransport(aRequest.sessionId(), aRequest.role()); - if (NS_WARN_IF(NS_FAILED(rv))) { - return SendResponse(rv); - } - return SendResponse(NS_OK); -} - -NS_IMETHODIMP -PresentationRequestParent::NotifySuccess(const nsAString& aUrl) -{ - Unused << SendNotifyRequestUrlSelected(nsString(aUrl)); - return SendResponse(NS_OK); -} - -NS_IMETHODIMP -PresentationRequestParent::NotifyError(nsresult aError) -{ - return SendResponse(aError); -} - -nsresult -PresentationRequestParent::SendResponse(nsresult aResult) -{ - if (NS_WARN_IF(mActorDestroyed || !Send__delete__(this, aResult))) { - return NS_ERROR_FAILURE; - } - - return NS_OK; -} - -} // namespace dom -} // namespace mozilla diff --git a/dom/presentation/ipc/PresentationParent.h b/dom/presentation/ipc/PresentationParent.h deleted file mode 100644 index b038aa2163..0000000000 --- a/dom/presentation/ipc/PresentationParent.h +++ /dev/null @@ -1,137 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* 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/. */ - -#ifndef mozilla_dom_PresentationParent_h__ -#define mozilla_dom_PresentationParent_h__ - -#include "mozilla/dom/ipc/IdType.h" -#include "mozilla/dom/PPresentationBuilderParent.h" -#include "mozilla/dom/PPresentationParent.h" -#include "mozilla/dom/PPresentationRequestParent.h" -#include "nsIPresentationListener.h" -#include "nsIPresentationService.h" -#include "nsIPresentationSessionTransportBuilder.h" - -namespace mozilla { -namespace dom { - -class PresentationParent final : public PPresentationParent - , public nsIPresentationAvailabilityListener - , public nsIPresentationSessionListener - , public nsIPresentationRespondingListener -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIPRESENTATIONAVAILABILITYLISTENER - NS_DECL_NSIPRESENTATIONSESSIONLISTENER - NS_DECL_NSIPRESENTATIONRESPONDINGLISTENER - - PresentationParent(); - - bool Init(ContentParentId aContentParentId); - - bool RegisterTransportBuilder(const nsString& aSessionId, const uint8_t& aRole); - - virtual void ActorDestroy(ActorDestroyReason aWhy) override; - - virtual bool - RecvPPresentationRequestConstructor(PPresentationRequestParent* aActor, - const PresentationIPCRequest& aRequest) override; - - virtual PPresentationRequestParent* - AllocPPresentationRequestParent(const PresentationIPCRequest& aRequest) override; - - virtual bool - DeallocPPresentationRequestParent(PPresentationRequestParent* aActor) override; - - virtual PPresentationBuilderParent* - AllocPPresentationBuilderParent(const nsString& aSessionId, - const uint8_t& aRole) override; - - virtual bool - DeallocPPresentationBuilderParent( - PPresentationBuilderParent* aActor) override; - - virtual bool Recv__delete__() override; - - virtual bool RecvRegisterAvailabilityHandler( - nsTArray&& aAvailabilityUrls) override; - - virtual bool RecvUnregisterAvailabilityHandler( - nsTArray&& aAvailabilityUrls) override; - - virtual bool RecvRegisterSessionHandler(const nsString& aSessionId, - const uint8_t& aRole) override; - - virtual bool RecvUnregisterSessionHandler(const nsString& aSessionId, - const uint8_t& aRole) override; - - virtual bool RecvRegisterRespondingHandler(const uint64_t& aWindowId) override; - - virtual bool RecvUnregisterRespondingHandler(const uint64_t& aWindowId) override; - - virtual bool RecvNotifyReceiverReady(const nsString& aSessionId, - const uint64_t& aWindowId, - const bool& aIsLoading) override; - - virtual bool RecvNotifyTransportClosed(const nsString& aSessionId, - const uint8_t& aRole, - const nsresult& aReason) override; - -private: - virtual ~PresentationParent(); - - bool mActorDestroyed = false; - nsCOMPtr mService; - nsTArray mSessionIdsAtController; - nsTArray mSessionIdsAtReceiver; - nsTArray mWindowIds; - ContentParentId mChildId; - nsTArray mContentAvailabilityUrls; -}; - -class PresentationRequestParent final : public PPresentationRequestParent - , public nsIPresentationServiceCallback -{ - friend class PresentationParent; - -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIPRESENTATIONSERVICECALLBACK - - explicit PresentationRequestParent(nsIPresentationService* aService, - ContentParentId aContentParentId); - - virtual void ActorDestroy(ActorDestroyReason aWhy) override; - -private: - virtual ~PresentationRequestParent(); - - nsresult SendResponse(nsresult aResult); - - nsresult DoRequest(const StartSessionRequest& aRequest); - - nsresult DoRequest(const SendSessionMessageRequest& aRequest); - - nsresult DoRequest(const CloseSessionRequest& aRequest); - - nsresult DoRequest(const TerminateSessionRequest& aRequest); - - nsresult DoRequest(const ReconnectSessionRequest& aRequest); - - nsresult DoRequest(const BuildTransportRequest& aRequest); - - bool mActorDestroyed = false; - bool mNeedRegisterBuilder = false; - nsString mSessionId; - nsCOMPtr mService; - ContentParentId mChildId; -}; - -} // namespace dom -} // namespace mozilla - -#endif // mozilla_dom_PresentationParent_h__ diff --git a/dom/presentation/moz.build b/dom/presentation/moz.build deleted file mode 100644 index a7058382f6..0000000000 --- a/dom/presentation/moz.build +++ /dev/null @@ -1,89 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -DIRS += ['interfaces', 'provider'] - -XPCSHELL_TESTS_MANIFESTS += ['tests/xpcshell/xpcshell.ini'] -MOCHITEST_MANIFESTS += ['tests/mochitest/mochitest.ini'] -MOCHITEST_CHROME_MANIFESTS += ['tests/mochitest/chrome.ini'] - -EXPORTS.mozilla.dom += [ - 'DCPresentationChannelDescription.h', - 'ipc/PresentationBuilderChild.h', - 'ipc/PresentationBuilderParent.h', - 'ipc/PresentationChild.h', - 'ipc/PresentationIPCService.h', - 'ipc/PresentationParent.h', - 'Presentation.h', - 'PresentationAvailability.h', - 'PresentationCallbacks.h', - 'PresentationConnection.h', - 'PresentationConnectionList.h', - 'PresentationDeviceManager.h', - 'PresentationReceiver.h', - 'PresentationRequest.h', - 'PresentationService.h', - 'PresentationServiceBase.h', - 'PresentationSessionInfo.h', - 'PresentationTCPSessionTransport.h', -] - -UNIFIED_SOURCES += [ - 'AvailabilityCollection.cpp', - 'ControllerConnectionCollection.cpp', - 'DCPresentationChannelDescription.cpp', - 'ipc/PresentationBuilderChild.cpp', - 'ipc/PresentationBuilderParent.cpp', - 'ipc/PresentationChild.cpp', - 'ipc/PresentationContentSessionInfo.cpp', - 'ipc/PresentationIPCService.cpp', - 'ipc/PresentationParent.cpp', - 'Presentation.cpp', - 'PresentationAvailability.cpp', - 'PresentationCallbacks.cpp', - 'PresentationConnection.cpp', - 'PresentationConnectionList.cpp', - 'PresentationDeviceManager.cpp', - 'PresentationReceiver.cpp', - 'PresentationRequest.cpp', - 'PresentationService.cpp', - 'PresentationSessionInfo.cpp', - 'PresentationSessionRequest.cpp', - 'PresentationTCPSessionTransport.cpp', - 'PresentationTerminateRequest.cpp', - 'PresentationTransportBuilderConstructor.cpp' -] - -EXTRA_COMPONENTS += [ - 'PresentationDataChannelSessionTransport.js', - 'PresentationDataChannelSessionTransport.manifest', - 'PresentationDeviceInfoManager.js', - 'PresentationDeviceInfoManager.manifest', -] - -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android': - EXTRA_COMPONENTS += [ - 'PresentationNetworkHelper.js', - 'PresentationNetworkHelper.manifest', - ] - -EXTRA_JS_MODULES += [ - 'PresentationDeviceInfoManager.jsm', -] - -IPDL_SOURCES += [ - 'ipc/PPresentation.ipdl', - 'ipc/PPresentationBuilder.ipdl', - 'ipc/PPresentationRequest.ipdl' -] - -LOCAL_INCLUDES += [ - '../base' -] - -include('/ipc/chromium/chromium-config.mozbuild') - -FINAL_LIBRARY = 'xul' diff --git a/dom/presentation/provider/AndroidCastDeviceProvider.js b/dom/presentation/provider/AndroidCastDeviceProvider.js deleted file mode 100644 index cf555f77b2..0000000000 --- a/dom/presentation/provider/AndroidCastDeviceProvider.js +++ /dev/null @@ -1,461 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -/* jshint esnext:true, globalstrict:true, moz:true, undef:true, unused:true */ -/* globals Components, dump */ -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -// globals XPCOMUtils -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -// globals Services -Cu.import("resource://gre/modules/Services.jsm"); -// globals Messaging -Cu.import("resource://gre/modules/Messaging.jsm"); - -function log(str) { - // dump("-*- AndroidCastDeviceProvider -*-: " + str + "\n"); -} - -// Helper function: transfer nsIPresentationChannelDescription to json -function descriptionToString(aDescription) { - let json = {}; - json.type = aDescription.type; - switch(aDescription.type) { - case Ci.nsIPresentationChannelDescription.TYPE_TCP: - let addresses = aDescription.tcpAddress.QueryInterface(Ci.nsIArray); - json.tcpAddress = []; - for (let idx = 0; idx < addresses.length; idx++) { - let address = addresses.queryElementAt(idx, Ci.nsISupportsCString); - json.tcpAddress.push(address.data); - } - json.tcpPort = aDescription.tcpPort; - break; - case Ci.nsIPresentationChannelDescription.TYPE_DATACHANNEL: - json.dataChannelSDP = aDescription.dataChannelSDP; - break; - } - return JSON.stringify(json); -} - -const TOPIC_ANDROID_CAST_DEVICE_SYNCDEVICE = "AndroidCastDevice:SyncDevice"; -const TOPIC_ANDROID_CAST_DEVICE_ADDED = "AndroidCastDevice:Added"; -const TOPIC_ANDROID_CAST_DEVICE_REMOVED = "AndroidCastDevice:Removed"; -const TOPIC_ANDROID_CAST_DEVICE_START = "AndroidCastDevice:Start"; -const TOPIC_ANDROID_CAST_DEVICE_STOP = "AndroidCastDevice:Stop"; -const TOPIC_PRESENTATION_VIEW_READY = "presentation-view-ready"; - -function LocalControlChannel(aProvider, aDeviceId, aRole) { - log("LocalControlChannel - create new LocalControlChannel for : " - + aRole); - this._provider = aProvider; - this._deviceId = aDeviceId; - this._role = aRole; -} - -LocalControlChannel.prototype = { - _listener: null, - _provider: null, - _deviceId: null, - _role: null, - _isOnTerminating: false, - _isOnDisconnecting: false, - _pendingConnected: false, - _pendingDisconnect: null, - _pendingOffer: null, - _pendingCandidate: null, - /* For the controller, it would be the control channel of the receiver. - * For the receiver, it would be the control channel of the controller. */ - _correspondingControlChannel: null, - - set correspondingControlChannel(aCorrespondingControlChannel) { - this._correspondingControlChannel = aCorrespondingControlChannel; - }, - - get correspondingControlChannel() { - return this._correspondingControlChannel; - }, - - notifyConnected: function LCC_notifyConnected() { - this._pendingDisconnect = null; - - if (!this._listener) { - this._pendingConnected = true; - } else { - this._listener.notifyConnected(); - } - }, - - onOffer: function LCC_onOffer(aOffer) { - if (this._role == Ci.nsIPresentationService.ROLE_CONTROLLER) { - log("LocalControlChannel - onOffer of controller should not be called."); - return; - } - if (!this._listener) { - this._pendingOffer = aOffer; - } else { - this._listener.onOffer(aOffer); - } - }, - - onAnswer: function LCC_onAnswer(aAnswer) { - if (this._role == Ci.nsIPresentationService.ROLE_RECEIVER) { - log("LocalControlChannel - onAnswer of receiver should not be called."); - return; - } - this._listener.onAnswer(aAnswer); - }, - - notifyIceCandidate: function LCC_notifyIceCandidate(aCandidate) { - if (!this._listener) { - this._pendingCandidate = aCandidate; - } else { - this._listener.onIceCandidate(aCandidate); - } - }, - - // nsIPresentationControlChannel - get listener() { - return this._listener; - }, - - set listener(aListener) { - this._listener = aListener; - - if (!this._listener) { - return; - } - - if (this._pendingConnected) { - this.notifyConnected(); - this._pendingConnected = false; - } - - if (this._pendingOffer) { - this.onOffer(this._pendingOffer); - this._pendingOffer = null; - } - - if (this._pendingCandidate) { - this.notifyIceCandidate(this._pendingCandidate); - this._pendingCandidate = null; - } - - if (this._pendingDisconnect != null) { - this.disconnect(this._pendingDisconnect); - this._pendingDisconnect = null; - } - }, - - sendOffer: function LCC_sendOffer(aOffer) { - if (this._role == Ci.nsIPresentationService.ROLE_RECEIVER) { - log("LocalControlChannel - sendOffer of receiver should not be called."); - return; - } - log("LocalControlChannel - sendOffer aOffer=" + descriptionToString(aOffer)); - this._correspondingControlChannel.onOffer(aOffer); - }, - - sendAnswer: function LCC_sendAnswer(aAnswer) { - if (this._role == Ci.nsIPresentationService.ROLE_CONTROLLER) { - log("LocalControlChannel - sendAnswer of controller should not be called."); - return; - } - log("LocalControlChannel - sendAnswer aAnswer=" + descriptionToString(aAnswer)); - this._correspondingControlChannel.onAnswer(aAnswer); - }, - - sendIceCandidate: function LCC_sendIceCandidate(aCandidate) { - log("LocalControlChannel - sendAnswer aCandidate=" + aCandidate); - this._correspondingControlChannel.notifyIceCandidate(aCandidate); - }, - - launch: function LCC_launch(aPresentationId, aUrl) { - log("LocalControlChannel - launch aPresentationId=" - + aPresentationId + " aUrl=" + aUrl); - // Create control channel for receiver directly. - let controlChannel = new LocalControlChannel(this._provider, - this._deviceId, - Ci.nsIPresentationService.ROLE_RECEIVER); - - // Set up the corresponding control channels for both controller and receiver. - this._correspondingControlChannel = controlChannel; - controlChannel._correspondingControlChannel = this; - - this._provider.onSessionRequest(this._deviceId, - aUrl, - aPresentationId, - controlChannel); - controlChannel.notifyConnected(); - }, - - terminate: function LCC_terminate(aPresentationId) { - log("LocalControlChannel - terminate aPresentationId=" - + aPresentationId); - - if (this._isOnTerminating) { - return; - } - - // Create control channel for corresponding role directly. - let correspondingRole = this._role == Ci.nsIPresentationService.ROLE_CONTROLLER - ? Ci.nsIPresentationService.ROLE_RECEIVER - : Ci.nsIPresentationService.ROLE_CONTROLLER; - let controlChannel = new LocalControlChannel(this._provider, - this._deviceId, - correspondingRole); - // Prevent the termination recursion. - controlChannel._isOnTerminating = true; - - // Set up the corresponding control channels for both controller and receiver. - this._correspondingControlChannel = controlChannel; - controlChannel._correspondingControlChannel = this; - - this._provider.onTerminateRequest(this._deviceId, - aPresentationId, - controlChannel, - this._role == Ci.nsIPresentationService.ROLE_RECEIVER); - controlChannel.notifyConnected(); - }, - - disconnect: function LCC_disconnect(aReason) { - log("LocalControlChannel - disconnect aReason=" + aReason); - - if (this._isOnDisconnecting) { - return; - } - - this._pendingOffer = null; - this._pendingCandidate = null; - this._pendingConnected = false; - - // this._pendingDisconnect is a nsresult. - // If it is null, it means no pending disconnect. - // If it is NS_OK, it means this control channel is disconnected normally. - // If it is other nsresult value, it means this control channel is - // disconnected abnormally. - - // Remote endpoint closes the control channel with abnormal reason. - if (aReason == Cr.NS_OK && - this._pendingDisconnect != null && - this._pendingDisconnect != Cr.NS_OK) { - aReason = this._pendingDisconnect; - } - - if (!this._listener) { - this._pendingDisconnect = aReason; - return; - } - - this._isOnDisconnecting = true; - this._correspondingControlChannel.disconnect(aReason); - this._listener.notifyDisconnected(aReason); - }, - - reconnect: function LCC_reconnect(aPresentationId, aUrl) { - log("1-UA on Android doesn't support reconnect."); - throw Cr.NS_ERROR_FAILURE; - }, - - classID: Components.ID("{c9be9450-e5c7-4294-a287-376971b017fd}"), - QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlChannel]), -}; - -function ChromecastRemoteDisplayDevice(aProvider, aId, aName, aRole) { - this._provider = aProvider; - this._id = aId; - this._name = aName; - this._role = aRole; -} - -ChromecastRemoteDisplayDevice.prototype = { - _id: null, - _name: null, - _role: null, - _provider: null, - _ctrlChannel: null, - - update: function CRDD_update(aName) { - this._name = aName || this._name; - }, - - // nsIPresentationDevice - get id() { return this._id; }, - - get name() { return this._name; }, - - get type() { return "chromecast"; }, - - establishControlChannel: function CRDD_establishControlChannel() { - this._ctrlChannel = new LocalControlChannel(this._provider, - this._id, - this._role); - - if (this._role == Ci.nsIPresentationService.ROLE_CONTROLLER) { - // Only connect to Chromecast for controller. - // Monitor the receiver being ready. - Services.obs.addObserver(this, TOPIC_PRESENTATION_VIEW_READY, true); - - // Launch Chromecast service in Android. - Messaging.sendRequestForResult({ - type: TOPIC_ANDROID_CAST_DEVICE_START, - id: this.id - }).then(result => { - log("Chromecast is connected."); - }).catch(error => { - log("Can not connect to Chromecast."); - // If Chromecast can not be launched, remove the observer. - Services.obs.removeObserver(this, TOPIC_PRESENTATION_VIEW_READY); - this._ctrlChannel.disconnect(Cr.NS_ERROR_FAILURE); - }); - } else { - // If establishControlChannel called from the receiver, we don't need to - // wait the 'presentation-view-ready' event. - this._ctrlChannel.notifyConnected(); - } - - return this._ctrlChannel; - }, - - disconnect: function CRDD_disconnect() { - // Disconnect from Chromecast. - Messaging.sendRequestForResult({ - type: TOPIC_ANDROID_CAST_DEVICE_STOP, - id: this.id - }); - }, - - isRequestedUrlSupported: function CRDD_isRequestedUrlSupported(aUrl) { - let url = Cc["@mozilla.org/network/io-service;1"] - .getService(Ci.nsIIOService) - .newURI(aUrl, null, null); - return url.scheme == "http" || url.scheme == "https"; - }, - - // nsIPresentationLocalDevice - get windowId() { return this._id; }, - - // nsIObserver - observe: function CRDD_observe(aSubject, aTopic, aData) { - if (aTopic == TOPIC_PRESENTATION_VIEW_READY) { - log("ChromecastRemoteDisplayDevice - observe: aTopic=" - + aTopic + " data=" + aData); - if (this.windowId === aData) { - Services.obs.removeObserver(this, TOPIC_PRESENTATION_VIEW_READY); - this._ctrlChannel.notifyConnected(); - } - } - }, - - QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDevice, - Ci.nsIPresentationLocalDevice, - Ci.nsISupportsWeakReference, - Ci.nsIObserver]), -}; - -function AndroidCastDeviceProvider() { -} - -AndroidCastDeviceProvider.prototype = { - _listener: null, - _deviceList: new Map(), - - onSessionRequest: function APDP_onSessionRequest(aDeviceId, - aUrl, - aPresentationId, - aControlChannel) { - log("AndroidCastDeviceProvider - onSessionRequest" - + " aDeviceId=" + aDeviceId); - let device = this._deviceList.get(aDeviceId); - let receiverDevice = new ChromecastRemoteDisplayDevice(this, - device.id, - device.name, - Ci.nsIPresentationService.ROLE_RECEIVER); - this._listener.onSessionRequest(receiverDevice, - aUrl, - aPresentationId, - aControlChannel); - }, - - onTerminateRequest: function APDP_onTerminateRequest(aDeviceId, - aPresentationId, - aControlChannel, - aIsFromReceiver) { - log("AndroidCastDeviceProvider - onTerminateRequest" - + " aDeviceId=" + aDeviceId - + " aPresentationId=" + aPresentationId - + " aIsFromReceiver=" + aIsFromReceiver); - let device = this._deviceList.get(aDeviceId); - this._listener.onTerminateRequest(device, - aPresentationId, - aControlChannel, - aIsFromReceiver); - }, - - // nsIPresentationDeviceProvider - set listener(aListener) { - this._listener = aListener; - - // When unload this provider. - if (!this._listener) { - // remove observer - Services.obs.removeObserver(this, TOPIC_ANDROID_CAST_DEVICE_ADDED); - Services.obs.removeObserver(this, TOPIC_ANDROID_CAST_DEVICE_REMOVED); - return; - } - - // Sync all device already found by Android. - Services.obs.notifyObservers(null, TOPIC_ANDROID_CAST_DEVICE_SYNCDEVICE, ""); - // Observer registration - Services.obs.addObserver(this, TOPIC_ANDROID_CAST_DEVICE_ADDED, false); - Services.obs.addObserver(this, TOPIC_ANDROID_CAST_DEVICE_REMOVED, false); - }, - - get listener() { - return this._listener; - }, - - forceDiscovery: function APDP_forceDiscovery() { - // There is no API to do force discovery in Android SDK. - }, - - // nsIObserver - observe: function APDP_observe(aSubject, aTopic, aData) { - switch (aTopic) { - case TOPIC_ANDROID_CAST_DEVICE_ADDED: { - let deviceInfo = JSON.parse(aData); - let deviceId = deviceInfo.uuid; - - if (!this._deviceList.has(deviceId)) { - let device = new ChromecastRemoteDisplayDevice(this, - deviceInfo.uuid, - deviceInfo.friendlyName, - Ci.nsIPresentationService.ROLE_CONTROLLER); - this._deviceList.set(device.id, device); - this._listener.addDevice(device); - } else { - let device = this._deviceList.get(deviceId); - device.update(deviceInfo.friendlyName); - this._listener.updateDevice(device); - } - break; - } - case TOPIC_ANDROID_CAST_DEVICE_REMOVED: { - let deviceId = aData; - let device = this._deviceList.get(deviceId); - this._listener.removeDevice(device); - this._deviceList.delete(deviceId); - break; - } - } - }, - - classID: Components.ID("{7394f24c-dbc3-48c8-8a47-cd10169b7c6b}"), - QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, - Ci.nsIPresentationDeviceProvider]), -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([AndroidCastDeviceProvider]); diff --git a/dom/presentation/provider/AndroidCastDeviceProvider.manifest b/dom/presentation/provider/AndroidCastDeviceProvider.manifest deleted file mode 100644 index db2aa101b6..0000000000 --- a/dom/presentation/provider/AndroidCastDeviceProvider.manifest +++ /dev/null @@ -1,4 +0,0 @@ -# AndroidCastDeviceProvider.js -component {7394f24c-dbc3-48c8-8a47-cd10169b7c6b} AndroidCastDeviceProvider.js -contract @mozilla.org/presentation-device/android-cast-device-provider;1 {7394f24c-dbc3-48c8-8a47-cd10169b7c6b} -category presentation-device-provider AndroidCastDeviceProvider @mozilla.org/presentation-device/android-cast-device-provider;1 diff --git a/dom/presentation/provider/BuiltinProviders.manifest b/dom/presentation/provider/BuiltinProviders.manifest deleted file mode 100644 index 0ba7bcaa70..0000000000 --- a/dom/presentation/provider/BuiltinProviders.manifest +++ /dev/null @@ -1,2 +0,0 @@ -component {f4079b8b-ede5-4b90-a112-5b415a931deb} PresentationControlService.js -contract @mozilla.org/presentation/control-service;1 {f4079b8b-ede5-4b90-a112-5b415a931deb} diff --git a/dom/presentation/provider/ControllerStateMachine.jsm b/dom/presentation/provider/ControllerStateMachine.jsm deleted file mode 100644 index b568a8e9af..0000000000 --- a/dom/presentation/provider/ControllerStateMachine.jsm +++ /dev/null @@ -1,240 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -/* jshint esnext:true, globalstrict:true, moz:true, undef:true, unused:true */ -/* globals Components, dump */ - -"use strict"; - -this.EXPORTED_SYMBOLS = ["ControllerStateMachine"]; // jshint ignore:line - -const { utils: Cu } = Components; - -/* globals State, CommandType */ -Cu.import("resource://gre/modules/presentation/StateMachineHelper.jsm"); - -const DEBUG = false; -function debug(str) { - dump("-*- ControllerStateMachine: " + str + "\n"); -} - -var handlers = [ - function _initHandler(stateMachine, command) { - // shouldn't receive any command at init state. - DEBUG && debug("unexpected command: " + JSON.stringify(command)); // jshint ignore:line - }, - function _connectingHandler(stateMachine, command) { - switch (command.type) { - case CommandType.CONNECT_ACK: - stateMachine.state = State.CONNECTED; - stateMachine._notifyDeviceConnected(); - break; - case CommandType.DISCONNECT: - stateMachine.state = State.CLOSED; - stateMachine._notifyDisconnected(command.reason); - break; - default: - debug("unexpected command: " + JSON.stringify(command)); - // ignore unexpected command. - break; - } - }, - function _connectedHandler(stateMachine, command) { - switch (command.type) { - case CommandType.DISCONNECT: - stateMachine.state = State.CLOSED; - stateMachine._notifyDisconnected(command.reason); - break; - case CommandType.LAUNCH_ACK: - stateMachine._notifyLaunch(command.presentationId); - break; - case CommandType.TERMINATE: - stateMachine._notifyTerminate(command.presentationId); - break; - case CommandType.TERMINATE_ACK: - stateMachine._notifyTerminate(command.presentationId); - break; - case CommandType.ANSWER: - case CommandType.ICE_CANDIDATE: - stateMachine._notifyChannelDescriptor(command); - break; - case CommandType.RECONNECT_ACK: - stateMachine._notifyReconnect(command.presentationId); - break; - default: - debug("unexpected command: " + JSON.stringify(command)); - // ignore unexpected command. - break; - } - }, - function _closingHandler(stateMachine, command) { - switch (command.type) { - case CommandType.DISCONNECT: - stateMachine.state = State.CLOSED; - stateMachine._notifyDisconnected(command.reason); - break; - default: - debug("unexpected command: " + JSON.stringify(command)); - // ignore unexpected command. - break; - } - }, - function _closedHandler(stateMachine, command) { - // ignore every command in closed state. - DEBUG && debug("unexpected command: " + JSON.stringify(command)); // jshint ignore:line - }, -]; - -function ControllerStateMachine(channel, deviceId) { - this.state = State.INIT; - this._channel = channel; - this._deviceId = deviceId; -} - -ControllerStateMachine.prototype = { - launch: function _launch(presentationId, url) { - if (this.state === State.CONNECTED) { - this._sendCommand({ - type: CommandType.LAUNCH, - presentationId: presentationId, - url: url, - }); - } - }, - - terminate: function _terminate(presentationId) { - if (this.state === State.CONNECTED) { - this._sendCommand({ - type: CommandType.TERMINATE, - presentationId: presentationId, - }); - } - }, - - terminateAck: function _terminateAck(presentationId) { - if (this.state === State.CONNECTED) { - this._sendCommand({ - type: CommandType.TERMINATE_ACK, - presentationId: presentationId, - }); - } - }, - - reconnect: function _reconnect(presentationId, url) { - if (this.state === State.CONNECTED) { - this._sendCommand({ - type: CommandType.RECONNECT, - presentationId: presentationId, - url: url, - }); - } - }, - - sendOffer: function _sendOffer(offer) { - if (this.state === State.CONNECTED) { - this._sendCommand({ - type: CommandType.OFFER, - offer: offer, - }); - } - }, - - sendAnswer: function _sendAnswer() { - // answer can only be sent by presenting UA. - debug("controller shouldn't generate answer"); - }, - - updateIceCandidate: function _updateIceCandidate(candidate) { - if (this.state === State.CONNECTED) { - this._sendCommand({ - type: CommandType.ICE_CANDIDATE, - candidate: candidate, - }); - } - }, - - onCommand: function _onCommand(command) { - handlers[this.state](this, command); - }, - - onChannelReady: function _onChannelReady() { - if (this.state === State.INIT) { - this._sendCommand({ - type: CommandType.CONNECT, - deviceId: this._deviceId - }); - this.state = State.CONNECTING; - } - }, - - onChannelClosed: function _onChannelClose(reason, isByRemote) { - switch (this.state) { - case State.CONNECTED: - if (isByRemote) { - this.state = State.CLOSED; - this._notifyDisconnected(reason); - } else { - this._sendCommand({ - type: CommandType.DISCONNECT, - reason: reason - }); - this.state = State.CLOSING; - this._closeReason = reason; - } - break; - case State.CLOSING: - if (isByRemote) { - this.state = State.CLOSED; - if (this._closeReason) { - reason = this._closeReason; - delete this._closeReason; - } - this._notifyDisconnected(reason); - } - break; - default: - DEBUG && debug("unexpected channel close: " + reason + ", " + isByRemote); // jshint ignore:line - break; - } - }, - - _sendCommand: function _sendCommand(command) { - this._channel.sendCommand(command); - }, - - _notifyDeviceConnected: function _notifyDeviceConnected() { - //XXX trigger following command - this._channel.notifyDeviceConnected(); - }, - - _notifyDisconnected: function _notifyDisconnected(reason) { - this._channel.notifyDisconnected(reason); - }, - - _notifyLaunch: function _notifyLaunch(presentationId) { - this._channel.notifyLaunch(presentationId); - }, - - _notifyTerminate: function _notifyTerminate(presentationId) { - this._channel.notifyTerminate(presentationId); - }, - - _notifyReconnect: function _notifyReconnect(presentationId) { - this._channel.notifyReconnect(presentationId); - }, - - _notifyChannelDescriptor: function _notifyChannelDescriptor(command) { - switch (command.type) { - case CommandType.ANSWER: - this._channel.notifyAnswer(command.answer); - break; - case CommandType.ICE_CANDIDATE: - this._channel.notifyIceCandidate(command.candidate); - break; - } - }, -}; - -this.ControllerStateMachine = ControllerStateMachine; // jshint ignore:line diff --git a/dom/presentation/provider/DeviceProviderHelpers.cpp b/dom/presentation/provider/DeviceProviderHelpers.cpp deleted file mode 100644 index 00b2c12f19..0000000000 --- a/dom/presentation/provider/DeviceProviderHelpers.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- Mode: C++; 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/. */ - -#include "DeviceProviderHelpers.h" - -#include "nsCOMPtr.h" -#include "nsIURI.h" -#include "nsNetUtil.h" - -namespace mozilla { -namespace dom { -namespace presentation { - -static const char* const kFxTVPresentationAppUrls[] = { - "app://fling-player.gaiamobile.org/index.html", - "app://notification-receiver.gaiamobile.org/index.html", - nullptr -}; - -/* static */ bool -DeviceProviderHelpers::IsCommonlySupportedScheme(const nsAString& aUrl) -{ - nsCOMPtr uri; - nsresult rv = NS_NewURI(getter_AddRefs(uri), aUrl); - if (NS_FAILED(rv) || !uri) { - return false; - } - - nsAutoCString scheme; - uri->GetScheme(scheme); - if (scheme.LowerCaseEqualsLiteral("http") || - scheme.LowerCaseEqualsLiteral("https")) { - return true; - } - - return false; -} - -/* static */ bool -DeviceProviderHelpers::IsFxTVSupportedAppUrl(const nsAString& aUrl) -{ - // Check if matched with any presentation Apps on TV. - for (uint32_t i = 0; kFxTVPresentationAppUrls[i]; i++) { - if (aUrl.EqualsASCII(kFxTVPresentationAppUrls[i])) { - return true; - } - } - - return false; -} - -} // namespace presentation -} // namespace dom -} // namespace mozilla diff --git a/dom/presentation/provider/DeviceProviderHelpers.h b/dom/presentation/provider/DeviceProviderHelpers.h deleted file mode 100644 index 4bde09bed8..0000000000 --- a/dom/presentation/provider/DeviceProviderHelpers.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- Mode: C++; 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/. */ - -#ifndef mozilla_dom_presentation_DeviceProviderHelpers_h -#define mozilla_dom_presentation_DeviceProviderHelpers_h - -#include "nsString.h" - -namespace mozilla { -namespace dom { -namespace presentation { - -class DeviceProviderHelpers final -{ -public: - static bool IsCommonlySupportedScheme(const nsAString& aUrl); - static bool IsFxTVSupportedAppUrl(const nsAString& aUrl); - -private: - DeviceProviderHelpers() = delete; -}; - -} // namespace presentation -} // namespace dom -} // namespace mozilla - -#endif // mozilla_dom_presentation_DeviceProviderHelpers_h diff --git a/dom/presentation/provider/DisplayDeviceProvider.cpp b/dom/presentation/provider/DisplayDeviceProvider.cpp deleted file mode 100644 index 3f88aba5e3..0000000000 --- a/dom/presentation/provider/DisplayDeviceProvider.cpp +++ /dev/null @@ -1,580 +0,0 @@ -/* -*- Mode: C++; 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/. */ - -#include "DisplayDeviceProvider.h" - -#include "DeviceProviderHelpers.h" -#include "mozilla/Logging.h" -#include "mozilla/Preferences.h" -#include "mozilla/Services.h" -#include "mozilla/Unused.h" -#include "nsIObserverService.h" -#include "nsIServiceManager.h" -#include "nsIWindowWatcher.h" -#include "nsNetUtil.h" -#include "nsPIDOMWindow.h" -#include "nsSimpleURI.h" -#include "nsTCPDeviceInfo.h" -#include "nsThreadUtils.h" - -static mozilla::LazyLogModule gDisplayDeviceProviderLog("DisplayDeviceProvider"); - -#define LOG(format) MOZ_LOG(gDisplayDeviceProviderLog, mozilla::LogLevel::Debug, format) - -#define DISPLAY_CHANGED_NOTIFICATION "display-changed" -#define DEFAULT_CHROME_FEATURES_PREF "toolkit.defaultChromeFeatures" -#define CHROME_REMOTE_URL_PREF "b2g.multiscreen.chrome_remote_url" -#define PREF_PRESENTATION_DISCOVERABLE_RETRY_MS "dom.presentation.discoverable.retry_ms" - -namespace mozilla { -namespace dom { -namespace presentation { - -/** - * This wrapper is used to break circular-reference problem. - */ -class DisplayDeviceProviderWrappedListener final - : public nsIPresentationControlServerListener -{ -public: - NS_DECL_ISUPPORTS - NS_FORWARD_SAFE_NSIPRESENTATIONCONTROLSERVERLISTENER(mListener) - - explicit DisplayDeviceProviderWrappedListener() = default; - - nsresult SetListener(DisplayDeviceProvider* aListener) - { - mListener = aListener; - return NS_OK; - } - -private: - virtual ~DisplayDeviceProviderWrappedListener() = default; - - DisplayDeviceProvider* mListener = nullptr; -}; - -NS_IMPL_ISUPPORTS(DisplayDeviceProviderWrappedListener, - nsIPresentationControlServerListener) - -NS_IMPL_ISUPPORTS(DisplayDeviceProvider::HDMIDisplayDevice, - nsIPresentationDevice, - nsIPresentationLocalDevice) - -// nsIPresentationDevice -NS_IMETHODIMP -DisplayDeviceProvider::HDMIDisplayDevice::GetId(nsACString& aId) -{ - aId = mWindowId; - return NS_OK; -} - -NS_IMETHODIMP -DisplayDeviceProvider::HDMIDisplayDevice::GetName(nsACString& aName) -{ - aName = mName; - return NS_OK; -} - -NS_IMETHODIMP -DisplayDeviceProvider::HDMIDisplayDevice::GetType(nsACString& aType) -{ - aType = mType; - return NS_OK; -} - -NS_IMETHODIMP -DisplayDeviceProvider::HDMIDisplayDevice::GetWindowId(nsACString& aWindowId) -{ - aWindowId = mWindowId; - return NS_OK; -} - -NS_IMETHODIMP -DisplayDeviceProvider::HDMIDisplayDevice - ::EstablishControlChannel(nsIPresentationControlChannel** aControlChannel) -{ - nsresult rv = OpenTopLevelWindow(); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - RefPtr provider = mProvider.get(); - if (NS_WARN_IF(!provider)) { - return NS_ERROR_FAILURE; - } - return provider->Connect(this, aControlChannel); -} - -NS_IMETHODIMP -DisplayDeviceProvider::HDMIDisplayDevice::Disconnect() -{ - nsresult rv = CloseTopLevelWindow(); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - return NS_OK;; -} - -NS_IMETHODIMP -DisplayDeviceProvider::HDMIDisplayDevice::IsRequestedUrlSupported( - const nsAString& aRequestedUrl, - bool* aRetVal) -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (!aRetVal) { - return NS_ERROR_INVALID_POINTER; - } - - // 1-UA device only supports HTTP/HTTPS hosted receiver page. - *aRetVal = DeviceProviderHelpers::IsCommonlySupportedScheme(aRequestedUrl); - - return NS_OK; -} - -nsresult -DisplayDeviceProvider::HDMIDisplayDevice::OpenTopLevelWindow() -{ - MOZ_ASSERT(!mWindow); - - nsresult rv; - nsAutoCString flags(Preferences::GetCString(DEFAULT_CHROME_FEATURES_PREF)); - if (flags.IsEmpty()) { - return NS_ERROR_NOT_AVAILABLE; - } - flags.AppendLiteral(",mozDisplayId="); - flags.AppendInt(mScreenId); - - nsAutoCString remoteShellURLString(Preferences::GetCString(CHROME_REMOTE_URL_PREF)); - remoteShellURLString.AppendLiteral("#"); - remoteShellURLString.Append(mWindowId); - - // URI validation - nsCOMPtr remoteShellURL; - rv = NS_NewURI(getter_AddRefs(remoteShellURL), remoteShellURLString); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - rv = remoteShellURL->GetSpec(remoteShellURLString); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - nsCOMPtr ww = do_GetService(NS_WINDOWWATCHER_CONTRACTID); - MOZ_ASSERT(ww); - - rv = ww->OpenWindow(nullptr, - remoteShellURLString.get(), - "_blank", - flags.get(), - nullptr, - getter_AddRefs(mWindow)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - return NS_OK; -} - -nsresult -DisplayDeviceProvider::HDMIDisplayDevice::CloseTopLevelWindow() -{ - MOZ_ASSERT(mWindow); - - nsCOMPtr piWindow = nsPIDOMWindowOuter::From(mWindow); - nsresult rv = piWindow->Close(); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - return NS_OK; -} - -NS_IMPL_ISUPPORTS(DisplayDeviceProvider, - nsIObserver, - nsIPresentationDeviceProvider, - nsIPresentationControlServerListener) - -DisplayDeviceProvider::~DisplayDeviceProvider() -{ - Uninit(); -} - -nsresult -DisplayDeviceProvider::Init() -{ - // Provider must be initialized only once. - if (mInitialized) { - return NS_OK; - } - - nsresult rv; - - mServerRetryMs = Preferences::GetUint(PREF_PRESENTATION_DISCOVERABLE_RETRY_MS); - mServerRetryTimer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - nsCOMPtr obs = mozilla::services::GetObserverService(); - MOZ_ASSERT(obs); - - obs->AddObserver(this, DISPLAY_CHANGED_NOTIFICATION, false); - - mDevice = new HDMIDisplayDevice(this); - - mWrappedListener = new DisplayDeviceProviderWrappedListener(); - rv = mWrappedListener->SetListener(this); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - mPresentationService = do_CreateInstance(PRESENTATION_CONTROL_SERVICE_CONTACT_ID, - &rv); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - rv = StartTCPService(); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - mInitialized = true; - return NS_OK; -} - -nsresult -DisplayDeviceProvider::Uninit() -{ - // Provider must be deleted only once. - if (!mInitialized) { - return NS_OK; - } - - nsCOMPtr obs = mozilla::services::GetObserverService(); - if (obs) { - obs->RemoveObserver(this, DISPLAY_CHANGED_NOTIFICATION); - } - - // Remove device from device manager when the provider is uninit - RemoveExternalScreen(); - - AbortServerRetry(); - - mInitialized = false; - mWrappedListener->SetListener(nullptr); - return NS_OK; -} - -nsresult -DisplayDeviceProvider::StartTCPService() -{ - MOZ_ASSERT(NS_IsMainThread()); - - nsresult rv; - rv = mPresentationService->SetId(NS_LITERAL_CSTRING("DisplayDeviceProvider")); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - uint16_t servicePort; - rv = mPresentationService->GetPort(&servicePort); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - /* - * If |servicePort| is non-zero, it means PresentationServer is running. - * Otherwise, we should make it start serving. - */ - if (servicePort) { - mPort = servicePort; - return NS_OK; - } - - rv = mPresentationService->SetListener(mWrappedListener); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - AbortServerRetry(); - - // 1-UA doesn't need encryption. - rv = mPresentationService->StartServer(/* aEncrypted = */ false, - /* aPort = */ 0); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - return NS_OK; -} - -void -DisplayDeviceProvider::AbortServerRetry() -{ - if (mIsServerRetrying) { - mIsServerRetrying = false; - mServerRetryTimer->Cancel(); - } -} - -nsresult -DisplayDeviceProvider::AddExternalScreen() -{ - MOZ_ASSERT(mDeviceListener); - - nsresult rv; - nsCOMPtr listener; - rv = GetListener(getter_AddRefs(listener)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - rv = listener->AddDevice(mDevice); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - return NS_OK; -} - -nsresult -DisplayDeviceProvider::RemoveExternalScreen() -{ - MOZ_ASSERT(mDeviceListener); - - nsresult rv; - nsCOMPtr listener; - rv = GetListener(getter_AddRefs(listener)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - rv = listener->RemoveDevice(mDevice); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - mDevice->Disconnect(); - return NS_OK; -} - -// nsIPresentationDeviceProvider -NS_IMETHODIMP -DisplayDeviceProvider::GetListener(nsIPresentationDeviceListener** aListener) -{ - if (NS_WARN_IF(!aListener)) { - return NS_ERROR_INVALID_POINTER; - } - - nsresult rv; - nsCOMPtr listener = - do_QueryReferent(mDeviceListener, &rv); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - listener.forget(aListener); - - return NS_OK; -} - -NS_IMETHODIMP -DisplayDeviceProvider::SetListener(nsIPresentationDeviceListener* aListener) -{ - mDeviceListener = do_GetWeakReference(aListener); - nsresult rv = mDeviceListener ? Init() : Uninit(); - if(NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - return NS_OK; -} - -NS_IMETHODIMP -DisplayDeviceProvider::ForceDiscovery() -{ - return NS_OK; -} - -// nsIPresentationControlServerListener -NS_IMETHODIMP -DisplayDeviceProvider::OnServerReady(uint16_t aPort, - const nsACString& aCertFingerprint) -{ - MOZ_ASSERT(NS_IsMainThread()); - mPort = aPort; - - return NS_OK; -} - -NS_IMETHODIMP -DisplayDeviceProvider::OnServerStopped(nsresult aResult) -{ - MOZ_ASSERT(NS_IsMainThread()); - - // Try restart server if it is stopped abnormally. - if (NS_FAILED(aResult)) { - mIsServerRetrying = true; - mServerRetryTimer->Init(this, mServerRetryMs, nsITimer::TYPE_ONE_SHOT); - } - - return NS_OK; -} - -NS_IMETHODIMP -DisplayDeviceProvider::OnSessionRequest(nsITCPDeviceInfo* aDeviceInfo, - const nsAString& aUrl, - const nsAString& aPresentationId, - nsIPresentationControlChannel* aControlChannel) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(aDeviceInfo); - MOZ_ASSERT(aControlChannel); - - nsresult rv; - - nsCOMPtr listener; - rv = GetListener(getter_AddRefs(listener)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - MOZ_ASSERT(!listener); - - rv = listener->OnSessionRequest(mDevice, - aUrl, - aPresentationId, - aControlChannel); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - return NS_OK; -} - -NS_IMETHODIMP -DisplayDeviceProvider::OnTerminateRequest(nsITCPDeviceInfo* aDeviceInfo, - const nsAString& aPresentationId, - nsIPresentationControlChannel* aControlChannel, - bool aIsFromReceiver) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(aDeviceInfo); - MOZ_ASSERT(aControlChannel); - - nsresult rv; - - nsCOMPtr listener; - rv = GetListener(getter_AddRefs(listener)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - MOZ_ASSERT(!listener); - - rv = listener->OnTerminateRequest(mDevice, - aPresentationId, - aControlChannel, - aIsFromReceiver); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - return NS_OK; -} - -NS_IMETHODIMP -DisplayDeviceProvider::OnReconnectRequest(nsITCPDeviceInfo* aDeviceInfo, - const nsAString& aUrl, - const nsAString& aPresentationId, - nsIPresentationControlChannel* aControlChannel) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(aDeviceInfo); - MOZ_ASSERT(aControlChannel); - - nsresult rv; - - nsCOMPtr listener; - rv = GetListener(getter_AddRefs(listener)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - MOZ_ASSERT(!listener); - - rv = listener->OnReconnectRequest(mDevice, - aUrl, - aPresentationId, - aControlChannel); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - return NS_OK; -} - -// nsIObserver -NS_IMETHODIMP -DisplayDeviceProvider::Observe(nsISupports* aSubject, - const char* aTopic, - const char16_t* aData) -{ - if (!strcmp(aTopic, DISPLAY_CHANGED_NOTIFICATION)) { - nsCOMPtr displayInfo = do_QueryInterface(aSubject); - MOZ_ASSERT(displayInfo); - - int32_t type; - bool isConnected; - displayInfo->GetConnected(&isConnected); - // XXX The ID is as same as the type of display. - // See Bug 1138287 and nsScreenManagerGonk::AddScreen() for more detail. - displayInfo->GetId(&type); - - if (type == DisplayType::DISPLAY_EXTERNAL) { - nsresult rv = isConnected ? AddExternalScreen() : RemoveExternalScreen(); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - } - } else if (!strcmp(aTopic, NS_TIMER_CALLBACK_TOPIC)) { - nsCOMPtr timer = do_QueryInterface(aSubject); - if (!timer) { - return NS_ERROR_UNEXPECTED; - } - - if (timer == mServerRetryTimer) { - mIsServerRetrying = false; - StartTCPService(); - } - } - - return NS_OK; -} - -nsresult -DisplayDeviceProvider::Connect(HDMIDisplayDevice* aDevice, - nsIPresentationControlChannel** aControlChannel) -{ - MOZ_ASSERT(aDevice); - MOZ_ASSERT(mPresentationService); - NS_ENSURE_ARG_POINTER(aControlChannel); - *aControlChannel = nullptr; - - nsCOMPtr deviceInfo = new TCPDeviceInfo(aDevice->Id(), - aDevice->Address(), - mPort, - EmptyCString()); - - return mPresentationService->Connect(deviceInfo, aControlChannel); -} - -} // namespace presentation -} // namespace dom -} // namespace mozilla diff --git a/dom/presentation/provider/DisplayDeviceProvider.h b/dom/presentation/provider/DisplayDeviceProvider.h deleted file mode 100644 index ebd5db3943..0000000000 --- a/dom/presentation/provider/DisplayDeviceProvider.h +++ /dev/null @@ -1,136 +0,0 @@ -/* -*- Mode: C++; 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/. */ - -#ifndef mozilla_dom_presentation_provider_DisplayDeviceProvider_h -#define mozilla_dom_presentation_provider_DisplayDeviceProvider_h - -#include "mozilla/RefPtr.h" -#include "mozilla/WeakPtr.h" -#include "nsCOMPtr.h" -#include "nsIDOMWindow.h" -#include "nsIDisplayInfo.h" -#include "nsIObserver.h" -#include "nsIPresentationDeviceProvider.h" -#include "nsIPresentationLocalDevice.h" -#include "nsIPresentationControlService.h" -#include "nsITimer.h" -#include "nsIWindowWatcher.h" -#include "nsString.h" -#include "nsTArray.h" -#include "nsWeakReference.h" - -namespace mozilla { -namespace dom { -namespace presentation { - -// Consistent definition with the definition in -// widget/gonk/libdisplay/GonkDisplay.h. -enum DisplayType { - DISPLAY_PRIMARY, - DISPLAY_EXTERNAL, - DISPLAY_VIRTUAL, - NUM_DISPLAY_TYPES -}; - -class DisplayDeviceProviderWrappedListener; - -class DisplayDeviceProvider final : public nsIObserver - , public nsIPresentationDeviceProvider - , public nsIPresentationControlServerListener - , public SupportsWeakPtr -{ -private: - class HDMIDisplayDevice final : public nsIPresentationLocalDevice - { - public: - NS_DECL_ISUPPORTS - NS_DECL_NSIPRESENTATIONDEVICE - NS_DECL_NSIPRESENTATIONLOCALDEVICE - - // mScreenId is as same as the definition of display type. - explicit HDMIDisplayDevice(DisplayDeviceProvider* aProvider) - : mScreenId(DisplayType::DISPLAY_EXTERNAL) - , mName("HDMI") - , mType("external") - , mWindowId("hdmi") - , mAddress("127.0.0.1") - , mProvider(aProvider) - {} - - nsresult OpenTopLevelWindow(); - nsresult CloseTopLevelWindow(); - - const nsCString& Id() const { return mWindowId; } - const nsCString& Address() const { return mAddress; } - - private: - virtual ~HDMIDisplayDevice() = default; - - // Due to the limitation of nsWinodw, mScreenId must be an integer. - // And mScreenId is also align to the display type defined in - // widget/gonk/libdisplay/GonkDisplay.h. - // HDMI display is DisplayType::DISPLAY_EXTERNAL. - uint32_t mScreenId; - nsCString mName; - nsCString mType; - nsCString mWindowId; - nsCString mAddress; - - nsCOMPtr mWindow; - // weak pointer - // Provider hold a strong pointer to the device. Use weak pointer to prevent - // the reference cycle. - WeakPtr mProvider; - }; - -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIOBSERVER - NS_DECL_NSIPRESENTATIONDEVICEPROVIDER - NS_DECL_NSIPRESENTATIONCONTROLSERVERLISTENER - // For using WeakPtr when MOZ_REFCOUNTED_LEAK_CHECKING defined - MOZ_DECLARE_WEAKREFERENCE_TYPENAME(DisplayDeviceProvider) - - nsresult Connect(HDMIDisplayDevice* aDevice, - nsIPresentationControlChannel** aControlChannel); -private: - virtual ~DisplayDeviceProvider(); - - nsresult Init(); - nsresult Uninit(); - - nsresult AddExternalScreen(); - nsresult RemoveExternalScreen(); - - nsresult StartTCPService(); - - void AbortServerRetry(); - - // Now support HDMI display only and there should be only one HDMI display. - nsCOMPtr mDevice = nullptr; - // weak pointer - // PresentationDeviceManager (mDeviceListener) hold strong pointer to - // DisplayDeviceProvider. Use nsWeakPtr to avoid reference cycle. - nsWeakPtr mDeviceListener = nullptr; - nsCOMPtr mPresentationService; - // Used to prevent reference cycle between DisplayDeviceProvider and - // TCPPresentationServer. - RefPtr mWrappedListener; - - bool mInitialized = false; - uint16_t mPort; - - bool mIsServerRetrying = false; - uint32_t mServerRetryMs; - nsCOMPtr mServerRetryTimer; -}; - -} // mozilla -} // dom -} // presentation - -#endif // mozilla_dom_presentation_provider_DisplayDeviceProvider_h - diff --git a/dom/presentation/provider/LegacyMDNSDeviceProvider.cpp b/dom/presentation/provider/LegacyMDNSDeviceProvider.cpp deleted file mode 100644 index 54849c9e37..0000000000 --- a/dom/presentation/provider/LegacyMDNSDeviceProvider.cpp +++ /dev/null @@ -1,774 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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 "LegacyMDNSDeviceProvider.h" - -#include "DeviceProviderHelpers.h" -#include "MainThreadUtils.h" -#include "mozilla/Logging.h" -#include "mozilla/Preferences.h" -#include "mozilla/Services.h" -#include "mozilla/Unused.h" -#include "nsComponentManagerUtils.h" -#include "nsIObserverService.h" -#include "nsIWritablePropertyBag2.h" -#include "nsServiceManagerUtils.h" -#include "nsTCPDeviceInfo.h" -#include "nsThreadUtils.h" -#include "nsIPropertyBag2.h" - -#define PREF_PRESENTATION_DISCOVERY_LEGACY "dom.presentation.discovery.legacy.enabled" -#define PREF_PRESENTATION_DISCOVERY_TIMEOUT_MS "dom.presentation.discovery.timeout_ms" -#define PREF_PRESENTATION_DEVICE_NAME "dom.presentation.device.name" - -#define LEGACY_SERVICE_TYPE "_mozilla_papi._tcp" - -#define LEGACY_PRESENTATION_CONTROL_SERVICE_CONTACT_ID "@mozilla.org/presentation/legacy-control-service;1" - -static mozilla::LazyLogModule sLegacyMDNSProviderLogModule("LegacyMDNSDeviceProvider"); - -#undef LOG_I -#define LOG_I(...) MOZ_LOG(sLegacyMDNSProviderLogModule, mozilla::LogLevel::Debug, (__VA_ARGS__)) -#undef LOG_E -#define LOG_E(...) MOZ_LOG(sLegacyMDNSProviderLogModule, mozilla::LogLevel::Error, (__VA_ARGS__)) - -namespace mozilla { -namespace dom { -namespace presentation { -namespace legacy { - -static const char* kObservedPrefs[] = { - PREF_PRESENTATION_DISCOVERY_LEGACY, - PREF_PRESENTATION_DISCOVERY_TIMEOUT_MS, - PREF_PRESENTATION_DEVICE_NAME, - nullptr -}; - -namespace { - -static void -GetAndroidDeviceName(nsACString& aRetVal) -{ - nsCOMPtr infoService = do_GetService("@mozilla.org/system-info;1"); - MOZ_ASSERT(infoService, "Could not find a system info service"); - - Unused << NS_WARN_IF(NS_FAILED(infoService->GetPropertyAsACString( - NS_LITERAL_STRING("device"), aRetVal))); -} - -} //anonymous namespace - -/** - * This wrapper is used to break circular-reference problem. - */ -class DNSServiceWrappedListener final - : public nsIDNSServiceDiscoveryListener - , public nsIDNSServiceResolveListener -{ -public: - NS_DECL_ISUPPORTS - NS_FORWARD_SAFE_NSIDNSSERVICEDISCOVERYLISTENER(mListener) - NS_FORWARD_SAFE_NSIDNSSERVICERESOLVELISTENER(mListener) - - explicit DNSServiceWrappedListener() = default; - - nsresult SetListener(LegacyMDNSDeviceProvider* aListener) - { - mListener = aListener; - return NS_OK; - } - -private: - virtual ~DNSServiceWrappedListener() = default; - - LegacyMDNSDeviceProvider* mListener = nullptr; -}; - -NS_IMPL_ISUPPORTS(DNSServiceWrappedListener, - nsIDNSServiceDiscoveryListener, - nsIDNSServiceResolveListener) - -NS_IMPL_ISUPPORTS(LegacyMDNSDeviceProvider, - nsIPresentationDeviceProvider, - nsIDNSServiceDiscoveryListener, - nsIDNSServiceResolveListener, - nsIObserver) - -LegacyMDNSDeviceProvider::~LegacyMDNSDeviceProvider() -{ - Uninit(); -} - -nsresult -LegacyMDNSDeviceProvider::Init() -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (mInitialized) { - return NS_OK; - } - - nsresult rv; - - mMulticastDNS = do_GetService(DNSSERVICEDISCOVERY_CONTRACT_ID, &rv); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - mWrappedListener = new DNSServiceWrappedListener(); - if (NS_WARN_IF(NS_FAILED(rv = mWrappedListener->SetListener(this)))) { - return rv; - } - - mPresentationService = do_CreateInstance(LEGACY_PRESENTATION_CONTROL_SERVICE_CONTACT_ID, &rv); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - mDiscoveryTimer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - Preferences::AddStrongObservers(this, kObservedPrefs); - - mDiscoveryEnabled = Preferences::GetBool(PREF_PRESENTATION_DISCOVERY_LEGACY); - mDiscoveryTimeoutMs = Preferences::GetUint(PREF_PRESENTATION_DISCOVERY_TIMEOUT_MS); - mServiceName = Preferences::GetCString(PREF_PRESENTATION_DEVICE_NAME); - - // FIXME: Bug 1185806 - Provide a common device name setting. - if (mServiceName.IsEmpty()) { - GetAndroidDeviceName(mServiceName); - Unused << Preferences::SetCString(PREF_PRESENTATION_DEVICE_NAME, mServiceName); - } - - Unused << mPresentationService->SetId(mServiceName); - - if (mDiscoveryEnabled && NS_WARN_IF(NS_FAILED(rv = ForceDiscovery()))) { - return rv; - } - - mInitialized = true; - return NS_OK; -} - -nsresult -LegacyMDNSDeviceProvider::Uninit() -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (!mInitialized) { - return NS_OK; - } - - ClearDevices(); - - Preferences::RemoveObservers(this, kObservedPrefs); - - StopDiscovery(NS_OK); - - mMulticastDNS = nullptr; - - if (mWrappedListener) { - mWrappedListener->SetListener(nullptr); - mWrappedListener = nullptr; - } - - mInitialized = false; - return NS_OK; -} - -nsresult -LegacyMDNSDeviceProvider::StopDiscovery(nsresult aReason) -{ - LOG_I("StopDiscovery (0x%08x)", aReason); - - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(mDiscoveryTimer); - - Unused << mDiscoveryTimer->Cancel(); - - if (mDiscoveryRequest) { - mDiscoveryRequest->Cancel(aReason); - mDiscoveryRequest = nullptr; - } - - return NS_OK; -} - -nsresult -LegacyMDNSDeviceProvider::Connect(Device* aDevice, - nsIPresentationControlChannel** aRetVal) -{ - MOZ_ASSERT(aDevice); - MOZ_ASSERT(mPresentationService); - - RefPtr deviceInfo = new TCPDeviceInfo(aDevice->Id(), - aDevice->Address(), - aDevice->Port(), - EmptyCString()); - - return mPresentationService->Connect(deviceInfo, aRetVal); -} - -nsresult -LegacyMDNSDeviceProvider::AddDevice(const nsACString& aId, - const nsACString& aServiceName, - const nsACString& aServiceType, - const nsACString& aAddress, - const uint16_t aPort) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(mPresentationService); - - RefPtr device = new Device(aId, /* ID */ - aServiceName, - aServiceType, - aAddress, - aPort, - DeviceState::eActive, - this); - - nsCOMPtr listener; - if (NS_SUCCEEDED(GetListener(getter_AddRefs(listener))) && listener) { - Unused << listener->AddDevice(device); - } - - mDevices.AppendElement(device); - - return NS_OK; -} - -nsresult -LegacyMDNSDeviceProvider::UpdateDevice(const uint32_t aIndex, - const nsACString& aServiceName, - const nsACString& aServiceType, - const nsACString& aAddress, - const uint16_t aPort) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(mPresentationService); - - if (NS_WARN_IF(aIndex >= mDevices.Length())) { - return NS_ERROR_INVALID_ARG; - } - - RefPtr device = mDevices[aIndex]; - device->Update(aServiceName, aServiceType, aAddress, aPort); - device->ChangeState(DeviceState::eActive); - - nsCOMPtr listener; - if (NS_SUCCEEDED(GetListener(getter_AddRefs(listener))) && listener) { - Unused << listener->UpdateDevice(device); - } - - return NS_OK; -} - -nsresult -LegacyMDNSDeviceProvider::RemoveDevice(const uint32_t aIndex) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(mPresentationService); - - if (NS_WARN_IF(aIndex >= mDevices.Length())) { - return NS_ERROR_INVALID_ARG; - } - - RefPtr device = mDevices[aIndex]; - - LOG_I("RemoveDevice: %s", device->Id().get()); - mDevices.RemoveElementAt(aIndex); - - nsCOMPtr listener; - if (NS_SUCCEEDED(GetListener(getter_AddRefs(listener))) && listener) { - Unused << listener->RemoveDevice(device); - } - - return NS_OK; -} - -bool -LegacyMDNSDeviceProvider::FindDeviceById(const nsACString& aId, - uint32_t& aIndex) -{ - MOZ_ASSERT(NS_IsMainThread()); - - RefPtr device = new Device(aId, - /* aName = */ EmptyCString(), - /* aType = */ EmptyCString(), - /* aHost = */ EmptyCString(), - /* aPort = */ 0, - /* aState = */ DeviceState::eUnknown, - /* aProvider = */ nullptr); - size_t index = mDevices.IndexOf(device, 0, DeviceIdComparator()); - - if (index == mDevices.NoIndex) { - return false; - } - - aIndex = index; - return true; -} - -bool -LegacyMDNSDeviceProvider::FindDeviceByAddress(const nsACString& aAddress, - uint32_t& aIndex) -{ - MOZ_ASSERT(NS_IsMainThread()); - - RefPtr device = new Device(/* aId = */ EmptyCString(), - /* aName = */ EmptyCString(), - /* aType = */ EmptyCString(), - aAddress, - /* aPort = */ 0, - /* aState = */ DeviceState::eUnknown, - /* aProvider = */ nullptr); - size_t index = mDevices.IndexOf(device, 0, DeviceAddressComparator()); - - if (index == mDevices.NoIndex) { - return false; - } - - aIndex = index; - return true; -} - -void -LegacyMDNSDeviceProvider::MarkAllDevicesUnknown() -{ - MOZ_ASSERT(NS_IsMainThread()); - - for (auto& device : mDevices) { - device->ChangeState(DeviceState::eUnknown); - } -} - -void -LegacyMDNSDeviceProvider::ClearUnknownDevices() -{ - MOZ_ASSERT(NS_IsMainThread()); - - size_t i = mDevices.Length(); - while (i > 0) { - --i; - if (mDevices[i]->State() == DeviceState::eUnknown) { - Unused << NS_WARN_IF(NS_FAILED(RemoveDevice(i))); - } - } -} - -void -LegacyMDNSDeviceProvider::ClearDevices() -{ - MOZ_ASSERT(NS_IsMainThread()); - - size_t i = mDevices.Length(); - while (i > 0) { - --i; - Unused << NS_WARN_IF(NS_FAILED(RemoveDevice(i))); - } -} - -// nsIPresentationDeviceProvider -NS_IMETHODIMP -LegacyMDNSDeviceProvider::GetListener(nsIPresentationDeviceListener** aListener) -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (NS_WARN_IF(!aListener)) { - return NS_ERROR_INVALID_POINTER; - } - - nsresult rv; - nsCOMPtr listener = - do_QueryReferent(mDeviceListener, &rv); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - listener.forget(aListener); - - return NS_OK; -} - -NS_IMETHODIMP -LegacyMDNSDeviceProvider::SetListener(nsIPresentationDeviceListener* aListener) -{ - MOZ_ASSERT(NS_IsMainThread()); - - mDeviceListener = do_GetWeakReference(aListener); - - nsresult rv; - if (mDeviceListener) { - if (NS_WARN_IF(NS_FAILED(rv = Init()))) { - return rv; - } - } else { - if (NS_WARN_IF(NS_FAILED(rv = Uninit()))) { - return rv; - } - } - - return NS_OK; -} - -NS_IMETHODIMP -LegacyMDNSDeviceProvider::ForceDiscovery() -{ - LOG_I("ForceDiscovery (%d)", mDiscoveryEnabled); - MOZ_ASSERT(NS_IsMainThread()); - - if (!mDiscoveryEnabled) { - return NS_OK; - } - - MOZ_ASSERT(mDiscoveryTimer); - MOZ_ASSERT(mMulticastDNS); - - // if it's already discovering, extend existing discovery timeout. - nsresult rv; - if (mIsDiscovering) { - Unused << mDiscoveryTimer->Cancel(); - - if (NS_WARN_IF(NS_FAILED( rv = mDiscoveryTimer->Init(this, - mDiscoveryTimeoutMs, - nsITimer::TYPE_ONE_SHOT)))) { - return rv; - } - return NS_OK; - } - - StopDiscovery(NS_OK); - - if (NS_WARN_IF(NS_FAILED(rv = mMulticastDNS->StartDiscovery( - NS_LITERAL_CSTRING(LEGACY_SERVICE_TYPE), - mWrappedListener, - getter_AddRefs(mDiscoveryRequest))))) { - return rv; - } - - return NS_OK; -} - -// nsIDNSServiceDiscoveryListener -NS_IMETHODIMP -LegacyMDNSDeviceProvider::OnDiscoveryStarted(const nsACString& aServiceType) -{ - LOG_I("OnDiscoveryStarted"); - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(mDiscoveryTimer); - - MarkAllDevicesUnknown(); - - nsresult rv; - if (NS_WARN_IF(NS_FAILED(rv = mDiscoveryTimer->Init(this, - mDiscoveryTimeoutMs, - nsITimer::TYPE_ONE_SHOT)))) { - return rv; - } - - mIsDiscovering = true; - - return NS_OK; -} - -NS_IMETHODIMP -LegacyMDNSDeviceProvider::OnDiscoveryStopped(const nsACString& aServiceType) -{ - LOG_I("OnDiscoveryStopped"); - MOZ_ASSERT(NS_IsMainThread()); - - ClearUnknownDevices(); - - mIsDiscovering = false; - - return NS_OK; -} - -NS_IMETHODIMP -LegacyMDNSDeviceProvider::OnServiceFound(nsIDNSServiceInfo* aServiceInfo) -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (NS_WARN_IF(!aServiceInfo)) { - return NS_ERROR_INVALID_ARG; - } - - nsresult rv ; - - nsAutoCString serviceName; - if (NS_WARN_IF(NS_FAILED(rv = aServiceInfo->GetServiceName(serviceName)))) { - return rv; - } - - LOG_I("OnServiceFound: %s", serviceName.get()); - - if (mMulticastDNS) { - if (NS_WARN_IF(NS_FAILED(rv = mMulticastDNS->ResolveService( - aServiceInfo, mWrappedListener)))) { - return rv; - } - } - - return NS_OK; -} - -NS_IMETHODIMP -LegacyMDNSDeviceProvider::OnServiceLost(nsIDNSServiceInfo* aServiceInfo) -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (NS_WARN_IF(!aServiceInfo)) { - return NS_ERROR_INVALID_ARG; - } - - nsresult rv; - - nsAutoCString serviceName; - if (NS_WARN_IF(NS_FAILED(rv = aServiceInfo->GetServiceName(serviceName)))) { - return rv; - } - - LOG_I("OnServiceLost: %s", serviceName.get()); - - nsAutoCString host; - if (NS_WARN_IF(NS_FAILED(rv = aServiceInfo->GetHost(host)))) { - return rv; - } - - uint32_t index; - if (!FindDeviceById(host, index)) { - // given device was not found - return NS_OK; - } - - if (NS_WARN_IF(NS_FAILED(rv = RemoveDevice(index)))) { - return rv; - } - - return NS_OK; -} - -NS_IMETHODIMP -LegacyMDNSDeviceProvider::OnStartDiscoveryFailed(const nsACString& aServiceType, - int32_t aErrorCode) -{ - LOG_E("OnStartDiscoveryFailed: %d", aErrorCode); - MOZ_ASSERT(NS_IsMainThread()); - - return NS_OK; -} - -NS_IMETHODIMP -LegacyMDNSDeviceProvider::OnStopDiscoveryFailed(const nsACString& aServiceType, - int32_t aErrorCode) -{ - LOG_E("OnStopDiscoveryFailed: %d", aErrorCode); - MOZ_ASSERT(NS_IsMainThread()); - - return NS_OK; -} - -// nsIDNSServiceResolveListener -NS_IMETHODIMP -LegacyMDNSDeviceProvider::OnServiceResolved(nsIDNSServiceInfo* aServiceInfo) -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (NS_WARN_IF(!aServiceInfo)) { - return NS_ERROR_INVALID_ARG; - } - - nsresult rv; - - nsAutoCString serviceName; - if (NS_WARN_IF(NS_FAILED(rv = aServiceInfo->GetServiceName(serviceName)))) { - return rv; - } - - LOG_I("OnServiceResolved: %s", serviceName.get()); - - nsAutoCString host; - if (NS_WARN_IF(NS_FAILED(rv = aServiceInfo->GetHost(host)))) { - return rv; - } - - nsAutoCString address; - if (NS_WARN_IF(NS_FAILED(rv = aServiceInfo->GetAddress(address)))) { - return rv; - } - - uint16_t port; - if (NS_WARN_IF(NS_FAILED(rv = aServiceInfo->GetPort(&port)))) { - return rv; - } - - nsAutoCString serviceType; - if (NS_WARN_IF(NS_FAILED(rv = aServiceInfo->GetServiceType(serviceType)))) { - return rv; - } - - uint32_t index; - if (FindDeviceById(host, index)) { - return UpdateDevice(index, - serviceName, - serviceType, - address, - port); - } else { - return AddDevice(host, - serviceName, - serviceType, - address, - port); - } - - return NS_OK; -} - -NS_IMETHODIMP -LegacyMDNSDeviceProvider::OnResolveFailed(nsIDNSServiceInfo* aServiceInfo, - int32_t aErrorCode) -{ - LOG_E("OnResolveFailed: %d", aErrorCode); - MOZ_ASSERT(NS_IsMainThread()); - - return NS_OK; -} - -// nsIObserver -NS_IMETHODIMP -LegacyMDNSDeviceProvider::Observe(nsISupports* aSubject, - const char* aTopic, - const char16_t* aData) -{ - MOZ_ASSERT(NS_IsMainThread()); - - NS_ConvertUTF16toUTF8 data(aData); - LOG_I("Observe: topic = %s, data = %s", aTopic, data.get()); - - if (!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) { - if (data.EqualsLiteral(PREF_PRESENTATION_DISCOVERY_LEGACY)) { - OnDiscoveryChanged(Preferences::GetBool(PREF_PRESENTATION_DISCOVERY_LEGACY)); - } else if (data.EqualsLiteral(PREF_PRESENTATION_DISCOVERY_TIMEOUT_MS)) { - OnDiscoveryTimeoutChanged(Preferences::GetUint(PREF_PRESENTATION_DISCOVERY_TIMEOUT_MS)); - } else if (data.EqualsLiteral(PREF_PRESENTATION_DEVICE_NAME)) { - nsAdoptingCString newServiceName = Preferences::GetCString(PREF_PRESENTATION_DEVICE_NAME); - if (!mServiceName.Equals(newServiceName)) { - OnServiceNameChanged(newServiceName); - } - } - } else if (!strcmp(aTopic, NS_TIMER_CALLBACK_TOPIC)) { - StopDiscovery(NS_OK); - } - - return NS_OK; -} - -nsresult -LegacyMDNSDeviceProvider::OnDiscoveryChanged(bool aEnabled) -{ - LOG_I("DiscoveryEnabled = %d\n", aEnabled); - MOZ_ASSERT(NS_IsMainThread()); - - mDiscoveryEnabled = aEnabled; - - if (mDiscoveryEnabled) { - return ForceDiscovery(); - } - - return StopDiscovery(NS_OK); -} - -nsresult -LegacyMDNSDeviceProvider::OnDiscoveryTimeoutChanged(uint32_t aTimeoutMs) -{ - LOG_I("OnDiscoveryTimeoutChanged = %d\n", aTimeoutMs); - MOZ_ASSERT(NS_IsMainThread()); - - mDiscoveryTimeoutMs = aTimeoutMs; - - return NS_OK; -} - -nsresult -LegacyMDNSDeviceProvider::OnServiceNameChanged(const nsACString& aServiceName) -{ - LOG_I("serviceName = %s\n", PromiseFlatCString(aServiceName).get()); - MOZ_ASSERT(NS_IsMainThread()); - - mServiceName = aServiceName; - mPresentationService->SetId(mServiceName); - - return NS_OK; -} - -// LegacyMDNSDeviceProvider::Device -NS_IMPL_ISUPPORTS(LegacyMDNSDeviceProvider::Device, - nsIPresentationDevice) - -// nsIPresentationDevice -NS_IMETHODIMP -LegacyMDNSDeviceProvider::Device::GetId(nsACString& aId) -{ - aId = mId; - - return NS_OK; -} - -NS_IMETHODIMP -LegacyMDNSDeviceProvider::Device::GetName(nsACString& aName) -{ - aName = mName; - - return NS_OK; -} - -NS_IMETHODIMP -LegacyMDNSDeviceProvider::Device::GetType(nsACString& aType) -{ - aType = mType; - - return NS_OK; -} - -NS_IMETHODIMP -LegacyMDNSDeviceProvider::Device::EstablishControlChannel( - nsIPresentationControlChannel** aRetVal) -{ - if (!mProvider) { - return NS_ERROR_FAILURE; - } - - return mProvider->Connect(this, aRetVal); -} - -NS_IMETHODIMP -LegacyMDNSDeviceProvider::Device::Disconnect() -{ - // No need to do anything when disconnect. - return NS_OK; -} - -NS_IMETHODIMP -LegacyMDNSDeviceProvider::Device::IsRequestedUrlSupported( - const nsAString& aRequestedUrl, - bool* aRetVal) -{ - if (!aRetVal) { - return NS_ERROR_INVALID_POINTER; - } - - // Legacy TV 2.5 device only support a fixed set of presentation Apps. - *aRetVal = DeviceProviderHelpers::IsFxTVSupportedAppUrl(aRequestedUrl); - - return NS_OK; -} - -} // namespace legacy -} // namespace presentation -} // namespace dom -} // namespace mozilla diff --git a/dom/presentation/provider/LegacyMDNSDeviceProvider.h b/dom/presentation/provider/LegacyMDNSDeviceProvider.h deleted file mode 100644 index 33ba877d33..0000000000 --- a/dom/presentation/provider/LegacyMDNSDeviceProvider.h +++ /dev/null @@ -1,191 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_dom_presentation_provider_LegacyMDNSDeviceProvider_h -#define mozilla_dom_presentation_provider_LegacyMDNSDeviceProvider_h - -#include "mozilla/RefPtr.h" -#include "nsCOMPtr.h" -#include "nsICancelable.h" -#include "nsIDNSServiceDiscovery.h" -#include "nsIObserver.h" -#include "nsIPresentationDevice.h" -#include "nsIPresentationDeviceProvider.h" -#include "nsIPresentationControlService.h" -#include "nsITimer.h" -#include "nsString.h" -#include "nsTArray.h" -#include "nsWeakPtr.h" - -namespace mozilla { -namespace dom { -namespace presentation { -namespace legacy { - -class DNSServiceWrappedListener; -class MulticastDNSService; - -class LegacyMDNSDeviceProvider final - : public nsIPresentationDeviceProvider - , public nsIDNSServiceDiscoveryListener - , public nsIDNSServiceResolveListener - , public nsIObserver -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIPRESENTATIONDEVICEPROVIDER - NS_DECL_NSIDNSSERVICEDISCOVERYLISTENER - NS_DECL_NSIDNSSERVICERESOLVELISTENER - NS_DECL_NSIOBSERVER - - explicit LegacyMDNSDeviceProvider() = default; - nsresult Init(); - nsresult Uninit(); - -private: - enum class DeviceState : uint32_t { - eUnknown, - eActive - }; - - class Device final : public nsIPresentationDevice - { - public: - NS_DECL_ISUPPORTS - NS_DECL_NSIPRESENTATIONDEVICE - - explicit Device(const nsACString& aId, - const nsACString& aName, - const nsACString& aType, - const nsACString& aAddress, - const uint16_t aPort, - DeviceState aState, - LegacyMDNSDeviceProvider* aProvider) - : mId(aId) - , mName(aName) - , mType(aType) - , mAddress(aAddress) - , mPort(aPort) - , mState(aState) - , mProvider(aProvider) - { - } - - const nsCString& Id() const - { - return mId; - } - - const nsCString& Address() const - { - return mAddress; - } - - uint16_t Port() const - { - return mPort; - } - - DeviceState State() const - { - return mState; - } - - void ChangeState(DeviceState aState) - { - mState = aState; - } - - void Update(const nsACString& aName, - const nsACString& aType, - const nsACString& aAddress, - const uint16_t aPort) - { - mName = aName; - mType = aType; - mAddress = aAddress; - mPort = aPort; - } - - private: - virtual ~Device() = default; - - nsCString mId; - nsCString mName; - nsCString mType; - nsCString mAddress; - uint16_t mPort; - DeviceState mState; - LegacyMDNSDeviceProvider* mProvider; - }; - - struct DeviceIdComparator { - bool Equals(const RefPtr& aA, const RefPtr& aB) const { - return aA->Id() == aB->Id(); - } - }; - - struct DeviceAddressComparator { - bool Equals(const RefPtr& aA, const RefPtr& aB) const { - return aA->Address() == aB->Address(); - } - }; - - virtual ~LegacyMDNSDeviceProvider(); - nsresult StopDiscovery(nsresult aReason); - nsresult Connect(Device* aDevice, - nsIPresentationControlChannel** aRetVal); - - // device manipulation - nsresult AddDevice(const nsACString& aId, - const nsACString& aServiceName, - const nsACString& aServiceType, - const nsACString& aAddress, - const uint16_t aPort); - nsresult UpdateDevice(const uint32_t aIndex, - const nsACString& aServiceName, - const nsACString& aServiceType, - const nsACString& aAddress, - const uint16_t aPort); - nsresult RemoveDevice(const uint32_t aIndex); - bool FindDeviceById(const nsACString& aId, - uint32_t& aIndex); - - bool FindDeviceByAddress(const nsACString& aAddress, - uint32_t& aIndex); - - void MarkAllDevicesUnknown(); - void ClearUnknownDevices(); - void ClearDevices(); - - // preferences - nsresult OnDiscoveryChanged(bool aEnabled); - nsresult OnDiscoveryTimeoutChanged(uint32_t aTimeoutMs); - nsresult OnServiceNameChanged(const nsACString& aServiceName); - - bool mInitialized = false; - nsWeakPtr mDeviceListener; - nsCOMPtr mPresentationService; - nsCOMPtr mMulticastDNS; - RefPtr mWrappedListener; - - nsCOMPtr mDiscoveryRequest; - - nsTArray> mDevices; - - bool mDiscoveryEnabled = false; - bool mIsDiscovering = false; - uint32_t mDiscoveryTimeoutMs; - nsCOMPtr mDiscoveryTimer; - - nsCString mServiceName; -}; - -} // namespace legacy -} // namespace presentation -} // namespace dom -} // namespace mozilla - -#endif // mozilla_dom_presentation_provider_LegacyMDNSDeviceProvider_h diff --git a/dom/presentation/provider/LegacyPresentationControlService.js b/dom/presentation/provider/LegacyPresentationControlService.js deleted file mode 100644 index b27177b635..0000000000 --- a/dom/presentation/provider/LegacyPresentationControlService.js +++ /dev/null @@ -1,488 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -/* jshint esnext:true, globalstrict:true, moz:true, undef:true, unused:true */ -/* globals Components, dump */ -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -/* globals XPCOMUtils */ -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -/* globals Services */ -Cu.import("resource://gre/modules/Services.jsm"); -/* globals NetUtil */ -Cu.import("resource://gre/modules/NetUtil.jsm"); - -const DEBUG = Services.prefs.getBoolPref("dom.presentation.tcp_server.debug"); -function log(aMsg) { - dump("-*- LegacyPresentationControlService.js: " + aMsg + "\n"); -} - -function LegacyPresentationControlService() { - DEBUG && log("LegacyPresentationControlService - ctor"); //jshint ignore:line - this._id = null; -} - -LegacyPresentationControlService.prototype = { - startServer: function() { - DEBUG && log("LegacyPresentationControlService - doesn't support receiver mode"); //jshint ignore:line - throw Cr.NS_ERROR_NOT_IMPLEMENTED; - }, - - get id() { - return this._id; - }, - - set id(aId) { - this._id = aId; - }, - - get port() { - return 0; - }, - - get version() { - return 0; - }, - - set listener(aListener) { //jshint ignore:line - DEBUG && log("LegacyPresentationControlService - doesn't support receiver mode"); //jshint ignore:line - throw Cr.NS_ERROR_NOT_IMPLEMENTED; - }, - - get listener() { - return null; - }, - - connect: function(aDeviceInfo) { - if (!this.id) { - DEBUG && log("LegacyPresentationControlService - Id has not initialized; requestSession fails"); //jshint ignore:line - return null; - } - DEBUG && log("LegacyPresentationControlService - requestSession to " + aDeviceInfo.id); //jshint ignore:line - - let sts = Cc["@mozilla.org/network/socket-transport-service;1"] - .getService(Ci.nsISocketTransportService); - - let socketTransport; - try { - socketTransport = sts.createTransport(null, - 0, - aDeviceInfo.address, - aDeviceInfo.port, - null); - } catch (e) { - DEBUG && log("LegacyPresentationControlService - createTransport throws: " + e); //jshint ignore:line - // Pop the exception to |TCPDevice.establishControlChannel| - throw Cr.NS_ERROR_FAILURE; - } - return new LegacyTCPControlChannel(this.id, - socketTransport, - aDeviceInfo); - }, - - close: function() { - DEBUG && log("LegacyPresentationControlService - close"); //jshint ignore:line - }, - - classID: Components.ID("{b21816fe-8aff-4811-86d2-85a7444c557e}"), - QueryInterface : XPCOMUtils.generateQI([Ci.nsIPresentationControlService]), -}; - -function ChannelDescription(aInit) { - this._type = aInit.type; - switch (this._type) { - case Ci.nsIPresentationChannelDescription.TYPE_TCP: - this._tcpAddresses = Cc["@mozilla.org/array;1"] - .createInstance(Ci.nsIMutableArray); - for (let address of aInit.tcpAddress) { - let wrapper = Cc["@mozilla.org/supports-cstring;1"] - .createInstance(Ci.nsISupportsCString); - wrapper.data = address; - this._tcpAddresses.appendElement(wrapper, false); - } - - this._tcpPort = aInit.tcpPort; - break; - case Ci.nsIPresentationChannelDescription.TYPE_DATACHANNEL: - this._dataChannelSDP = aInit.dataChannelSDP; - break; - } -} - -ChannelDescription.prototype = { - _type: 0, - _tcpAddresses: null, - _tcpPort: 0, - _dataChannelSDP: "", - - get type() { - return this._type; - }, - - get tcpAddress() { - return this._tcpAddresses; - }, - - get tcpPort() { - return this._tcpPort; - }, - - get dataChannelSDP() { - return this._dataChannelSDP; - }, - - classID: Components.ID("{d69fc81c-4f40-47a3-97e6-b4cf5db2294e}"), - QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationChannelDescription]), -}; - -// Helper function: transfer nsIPresentationChannelDescription to json -function discriptionAsJson(aDescription) { - let json = {}; - json.type = aDescription.type; - switch(aDescription.type) { - case Ci.nsIPresentationChannelDescription.TYPE_TCP: - let addresses = aDescription.tcpAddress.QueryInterface(Ci.nsIArray); - json.tcpAddress = []; - for (let idx = 0; idx < addresses.length; idx++) { - let address = addresses.queryElementAt(idx, Ci.nsISupportsCString); - json.tcpAddress.push(address.data); - } - json.tcpPort = aDescription.tcpPort; - break; - case Ci.nsIPresentationChannelDescription.TYPE_DATACHANNEL: - json.dataChannelSDP = aDescription.dataChannelSDP; - break; - } - return json; -} - -function LegacyTCPControlChannel(id, - transport, - deviceInfo) { - DEBUG && log("create LegacyTCPControlChannel"); //jshint ignore:line - this._deviceInfo = deviceInfo; - this._transport = transport; - - this._id = id; - - let currentThread = Services.tm.currentThread; - transport.setEventSink(this, currentThread); - - this._input = this._transport.openInputStream(0, 0, 0) - .QueryInterface(Ci.nsIAsyncInputStream); - this._input.asyncWait(this.QueryInterface(Ci.nsIStreamListener), - Ci.nsIAsyncInputStream.WAIT_CLOSURE_ONLY, - 0, - currentThread); - - this._output = this._transport - .openOutputStream(Ci.nsITransport.OPEN_UNBUFFERED, 0, 0); -} - -LegacyTCPControlChannel.prototype = { - _connected: false, - _pendingOpen: false, - _pendingAnswer: null, - _pendingClose: null, - _pendingCloseReason: null, - - _sendMessage: function(aJSONData, aOnThrow) { - if (!aOnThrow) { - aOnThrow = function(e) {throw e.result;}; - } - - if (!aJSONData) { - aOnThrow(); - return; - } - - if (!this._connected) { - DEBUG && log("LegacyTCPControlChannel - send" + aJSONData.type + " fails"); //jshint ignore:line - throw Cr.NS_ERROR_FAILURE; - } - - try { - this._send(aJSONData); - } catch (e) { - aOnThrow(e); - } - }, - - _sendInit: function() { - let msg = { - type: "requestSession:Init", - presentationId: this._presentationId, - url: this._url, - id: this._id, - }; - - this._sendMessage(msg, function(e) { - this.disconnect(); - this._notifyDisconnected(e.result); - }); - }, - - launch: function(aPresentationId, aUrl) { - this._presentationId = aPresentationId; - this._url = aUrl; - - this._sendInit(); - }, - - terminate: function() { - // Legacy protocol doesn't support extra terminate protocol. - // Trigger error handling for browser to shutdown all the resource locally. - throw Cr.NS_ERROR_NOT_IMPLEMENTED; - }, - - sendOffer: function(aOffer) { - let msg = { - type: "requestSession:Offer", - presentationId: this._presentationId, - offer: discriptionAsJson(aOffer), - }; - this._sendMessage(msg); - }, - - sendAnswer: function(aAnswer) { //jshint ignore:line - throw Cr.NS_ERROR_NOT_IMPLEMENTED; - }, - - sendIceCandidate: function(aCandidate) { - let msg = { - type: "requestSession:IceCandidate", - presentationId: this._presentationId, - iceCandidate: aCandidate, - }; - this._sendMessage(msg); - }, - // may throw an exception - _send: function(aMsg) { - DEBUG && log("LegacyTCPControlChannel - Send: " + JSON.stringify(aMsg, null, 2)); //jshint ignore:line - - /** - * XXX In TCP streaming, it is possible that more than one message in one - * TCP packet. We use line delimited JSON to identify where one JSON encoded - * object ends and the next begins. Therefore, we do not allow newline - * characters whithin the whole message, and add a newline at the end. - * Please see the parser code in |onDataAvailable|. - */ - let message = JSON.stringify(aMsg).replace(["\n"], "") + "\n"; - try { - this._output.write(message, message.length); - } catch(e) { - DEBUG && log("LegacyTCPControlChannel - Failed to send message: " + e.name); //jshint ignore:line - throw e; - } - }, - - // nsIAsyncInputStream (Triggered by nsIInputStream.asyncWait) - // Only used for detecting connection refused - onInputStreamReady: function(aStream) { - try { - aStream.available(); - } catch (e) { - DEBUG && log("LegacyTCPControlChannel - onInputStreamReady error: " + e.name); //jshint ignore:line - // NS_ERROR_CONNECTION_REFUSED - this._listener.notifyDisconnected(e.result); - } - }, - - // nsITransportEventSink (Triggered by nsISocketTransport.setEventSink) - onTransportStatus: function(aTransport, aStatus, aProg, aProgMax) { //jshint ignore:line - DEBUG && log("LegacyTCPControlChannel - onTransportStatus: " - + aStatus.toString(16)); //jshint ignore:line - if (aStatus === Ci.nsISocketTransport.STATUS_CONNECTED_TO) { - this._connected = true; - - if (!this._pump) { - this._createInputStreamPump(); - } - - this._notifyConnected(); - } - }, - - // nsIRequestObserver (Triggered by nsIInputStreamPump.asyncRead) - onStartRequest: function() { - DEBUG && log("LegacyTCPControlChannel - onStartRequest"); //jshint ignore:line - }, - - // nsIRequestObserver (Triggered by nsIInputStreamPump.asyncRead) - onStopRequest: function(aRequest, aContext, aStatus) { - DEBUG && log("LegacyTCPControlChannel - onStopRequest: " + aStatus); //jshint ignore:line - this.disconnect(aStatus); - this._notifyDisconnected(aStatus); - }, - - // nsIStreamListener (Triggered by nsIInputStreamPump.asyncRead) - onDataAvailable: function(aRequest, aContext, aInputStream, aOffset, aCount) { //jshint ignore:line - let data = NetUtil.readInputStreamToString(aInputStream, - aInputStream.available()); - DEBUG && log("LegacyTCPControlChannel - onDataAvailable: " + data); //jshint ignore:line - - // Parser of line delimited JSON. Please see |_send| for more informaiton. - let jsonArray = data.split("\n"); - jsonArray.pop(); - for (let json of jsonArray) { - let msg; - try { - msg = JSON.parse(json); - } catch (e) { - DEBUG && log("LegacyTCPSignalingChannel - error in parsing json: " + e); //jshint ignore:line - } - - this._handleMessage(msg); - } - }, - - _createInputStreamPump: function() { - DEBUG && log("LegacyTCPControlChannel - create pump"); //jshint ignore:line - this._pump = Cc["@mozilla.org/network/input-stream-pump;1"]. - createInstance(Ci.nsIInputStreamPump); - this._pump.init(this._input, -1, -1, 0, 0, false); - this._pump.asyncRead(this, null); - }, - - // Handle command from remote side - _handleMessage: function(aMsg) { - DEBUG && log("LegacyTCPControlChannel - handleMessage from " - + JSON.stringify(this._deviceInfo) + ": " + JSON.stringify(aMsg)); //jshint ignore:line - switch (aMsg.type) { - case "requestSession:Answer": { - this._onAnswer(aMsg.answer); - break; - } - case "requestSession:IceCandidate": { - this._listener.onIceCandidate(aMsg.iceCandidate); - break; - } - case "requestSession:CloseReason": { - this._pendingCloseReason = aMsg.reason; - break; - } - } - }, - - get listener() { - return this._listener; - }, - - set listener(aListener) { - DEBUG && log("LegacyTCPControlChannel - set listener: " + aListener); //jshint ignore:line - if (!aListener) { - this._listener = null; - return; - } - - this._listener = aListener; - if (this._pendingOpen) { - this._pendingOpen = false; - DEBUG && log("LegacyTCPControlChannel - notify pending opened"); //jshint ignore:line - this._listener.notifyConnected(); - } - - if (this._pendingAnswer) { - let answer = this._pendingAnswer; - DEBUG && log("LegacyTCPControlChannel - notify pending answer: " + - JSON.stringify(answer)); // jshint ignore:line - this._listener.onAnswer(new ChannelDescription(answer)); - this._pendingAnswer = null; - } - - if (this._pendingClose) { - DEBUG && log("LegacyTCPControlChannel - notify pending closed"); //jshint ignore:line - this._notifyDisconnected(this._pendingCloseReason); - this._pendingClose = null; - } - }, - - /** - * These functions are designed to handle the interaction with listener - * appropriately. |_FUNC| is to handle |this._listener.FUNC|. - */ - _onAnswer: function(aAnswer) { - if (!this._connected) { - return; - } - if (!this._listener) { - this._pendingAnswer = aAnswer; - return; - } - DEBUG && log("LegacyTCPControlChannel - notify answer: " + JSON.stringify(aAnswer)); //jshint ignore:line - this._listener.onAnswer(new ChannelDescription(aAnswer)); - }, - - _notifyConnected: function() { - this._connected = true; - this._pendingClose = false; - this._pendingCloseReason = Cr.NS_OK; - - if (!this._listener) { - this._pendingOpen = true; - return; - } - - DEBUG && log("LegacyTCPControlChannel - notify opened"); //jshint ignore:line - this._listener.notifyConnected(); - }, - - _notifyDisconnected: function(aReason) { - this._connected = false; - this._pendingOpen = false; - this._pendingAnswer = null; - - // Remote endpoint closes the control channel with abnormal reason. - if (aReason == Cr.NS_OK && this._pendingCloseReason != Cr.NS_OK) { - aReason = this._pendingCloseReason; - } - - if (!this._listener) { - this._pendingClose = true; - this._pendingCloseReason = aReason; - return; - } - - DEBUG && log("LegacyTCPControlChannel - notify closed"); //jshint ignore:line - this._listener.notifyDisconnected(aReason); - }, - - disconnect: function(aReason) { - DEBUG && log("LegacyTCPControlChannel - close with reason: " + aReason); //jshint ignore:line - - if (this._connected) { - // default reason is NS_OK - if (typeof aReason !== "undefined" && aReason !== Cr.NS_OK) { - let msg = { - type: "requestSession:CloseReason", - presentationId: this._presentationId, - reason: aReason, - }; - this._sendMessage(msg); - this._pendingCloseReason = aReason; - } - - this._transport.setEventSink(null, null); - this._pump = null; - - this._input.close(); - this._output.close(); - - this._connected = false; - } - }, - - reconnect: function() { - // Legacy protocol doesn't support extra reconnect protocol. - // Trigger error handling for browser to shutdown all the resource locally. - throw Cr.NS_ERROR_NOT_IMPLEMENTED; - }, - - classID: Components.ID("{4027ce3d-06e3-4d06-a235-df329cb0d411}"), - QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlChannel, - Ci.nsIStreamListener]), -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([LegacyPresentationControlService]); //jshint ignore:line diff --git a/dom/presentation/provider/LegacyProviders.manifest b/dom/presentation/provider/LegacyProviders.manifest deleted file mode 100644 index 9408da0633..0000000000 --- a/dom/presentation/provider/LegacyProviders.manifest +++ /dev/null @@ -1,2 +0,0 @@ -component {b21816fe-8aff-4811-86d2-85a7444c557e} LegacyPresentationControlService.js -contract @mozilla.org/presentation/legacy-control-service;1 {b21816fe-8aff-4811-86d2-85a7444c557e} diff --git a/dom/presentation/provider/MulticastDNSDeviceProvider.cpp b/dom/presentation/provider/MulticastDNSDeviceProvider.cpp deleted file mode 100644 index 0cab915ac4..0000000000 --- a/dom/presentation/provider/MulticastDNSDeviceProvider.cpp +++ /dev/null @@ -1,1249 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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 "MulticastDNSDeviceProvider.h" - -#include "DeviceProviderHelpers.h" -#include "MainThreadUtils.h" -#include "mozilla/Logging.h" -#include "mozilla/Preferences.h" -#include "mozilla/Services.h" -#include "mozilla/Unused.h" -#include "nsComponentManagerUtils.h" -#include "nsIObserverService.h" -#include "nsIWritablePropertyBag2.h" -#include "nsServiceManagerUtils.h" -#include "nsTCPDeviceInfo.h" -#include "nsThreadUtils.h" - -#ifdef MOZ_WIDGET_ANDROID -#include "nsIPropertyBag2.h" -#endif // MOZ_WIDGET_ANDROID - -#define PREF_PRESENTATION_DISCOVERY "dom.presentation.discovery.enabled" -#define PREF_PRESENTATION_DISCOVERY_TIMEOUT_MS "dom.presentation.discovery.timeout_ms" -#define PREF_PRESENTATION_DISCOVERABLE "dom.presentation.discoverable" -#define PREF_PRESENTATION_DISCOVERABLE_ENCRYPTED "dom.presentation.discoverable.encrypted" -#define PREF_PRESENTATION_DISCOVERABLE_RETRY_MS "dom.presentation.discoverable.retry_ms" -#define PREF_PRESENTATION_DEVICE_NAME "dom.presentation.device.name" - -#define SERVICE_TYPE "_presentation-ctrl._tcp" -#define PROTOCOL_VERSION_TAG "version" -#define CERT_FINGERPRINT_TAG "certFingerprint" - -static mozilla::LazyLogModule sMulticastDNSProviderLogModule("MulticastDNSDeviceProvider"); - -#undef LOG_I -#define LOG_I(...) MOZ_LOG(sMulticastDNSProviderLogModule, mozilla::LogLevel::Debug, (__VA_ARGS__)) -#undef LOG_E -#define LOG_E(...) MOZ_LOG(sMulticastDNSProviderLogModule, mozilla::LogLevel::Error, (__VA_ARGS__)) - -namespace mozilla { -namespace dom { -namespace presentation { - -static const char* kObservedPrefs[] = { - PREF_PRESENTATION_DISCOVERY, - PREF_PRESENTATION_DISCOVERY_TIMEOUT_MS, - PREF_PRESENTATION_DISCOVERABLE, - PREF_PRESENTATION_DEVICE_NAME, - nullptr -}; - -namespace { - -#ifdef MOZ_WIDGET_ANDROID -static void -GetAndroidDeviceName(nsACString& aRetVal) -{ - nsCOMPtr infoService = do_GetService("@mozilla.org/system-info;1"); - MOZ_ASSERT(infoService, "Could not find a system info service"); - - Unused << NS_WARN_IF(NS_FAILED(infoService->GetPropertyAsACString( - NS_LITERAL_STRING("device"), aRetVal))); -} -#endif // MOZ_WIDGET_ANDROID - -} //anonymous namespace - -/** - * This wrapper is used to break circular-reference problem. - */ -class DNSServiceWrappedListener final - : public nsIDNSServiceDiscoveryListener - , public nsIDNSRegistrationListener - , public nsIDNSServiceResolveListener - , public nsIPresentationControlServerListener -{ -public: - NS_DECL_ISUPPORTS - NS_FORWARD_SAFE_NSIDNSSERVICEDISCOVERYLISTENER(mListener) - NS_FORWARD_SAFE_NSIDNSREGISTRATIONLISTENER(mListener) - NS_FORWARD_SAFE_NSIDNSSERVICERESOLVELISTENER(mListener) - NS_FORWARD_SAFE_NSIPRESENTATIONCONTROLSERVERLISTENER(mListener) - - explicit DNSServiceWrappedListener() = default; - - nsresult SetListener(MulticastDNSDeviceProvider* aListener) - { - mListener = aListener; - return NS_OK; - } - -private: - virtual ~DNSServiceWrappedListener() = default; - - MulticastDNSDeviceProvider* mListener = nullptr; -}; - -NS_IMPL_ISUPPORTS(DNSServiceWrappedListener, - nsIDNSServiceDiscoveryListener, - nsIDNSRegistrationListener, - nsIDNSServiceResolveListener, - nsIPresentationControlServerListener) - -NS_IMPL_ISUPPORTS(MulticastDNSDeviceProvider, - nsIPresentationDeviceProvider, - nsIDNSServiceDiscoveryListener, - nsIDNSRegistrationListener, - nsIDNSServiceResolveListener, - nsIPresentationControlServerListener, - nsIObserver) - -MulticastDNSDeviceProvider::~MulticastDNSDeviceProvider() -{ - Uninit(); -} - -nsresult -MulticastDNSDeviceProvider::Init() -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (mInitialized) { - return NS_OK; - } - - nsresult rv; - - mMulticastDNS = do_GetService(DNSSERVICEDISCOVERY_CONTRACT_ID, &rv); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - mWrappedListener = new DNSServiceWrappedListener(); - if (NS_WARN_IF(NS_FAILED(rv = mWrappedListener->SetListener(this)))) { - return rv; - } - - mPresentationService = do_CreateInstance(PRESENTATION_CONTROL_SERVICE_CONTACT_ID, &rv); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - mDiscoveryTimer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - mServerRetryTimer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - Preferences::AddStrongObservers(this, kObservedPrefs); - - mDiscoveryEnabled = Preferences::GetBool(PREF_PRESENTATION_DISCOVERY); - mDiscoveryTimeoutMs = Preferences::GetUint(PREF_PRESENTATION_DISCOVERY_TIMEOUT_MS); - mDiscoverable = Preferences::GetBool(PREF_PRESENTATION_DISCOVERABLE); - mDiscoverableEncrypted = Preferences::GetBool(PREF_PRESENTATION_DISCOVERABLE_ENCRYPTED); - mServerRetryMs = Preferences::GetUint(PREF_PRESENTATION_DISCOVERABLE_RETRY_MS); - mServiceName = Preferences::GetCString(PREF_PRESENTATION_DEVICE_NAME); - -#ifdef MOZ_WIDGET_ANDROID - // FIXME: Bug 1185806 - Provide a common device name setting. - if (mServiceName.IsEmpty()) { - GetAndroidDeviceName(mServiceName); - Unused << Preferences::SetCString(PREF_PRESENTATION_DEVICE_NAME, mServiceName); - } -#endif // MOZ_WIDGET_ANDROID - - Unused << mPresentationService->SetId(mServiceName); - - if (mDiscoveryEnabled && NS_WARN_IF(NS_FAILED(rv = ForceDiscovery()))) { - return rv; - } - - if (mDiscoverable && NS_WARN_IF(NS_FAILED(rv = StartServer()))) { - return rv; - } - - mInitialized = true; - return NS_OK; -} - -nsresult -MulticastDNSDeviceProvider::Uninit() -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (!mInitialized) { - return NS_OK; - } - - ClearDevices(); - - Preferences::RemoveObservers(this, kObservedPrefs); - - StopDiscovery(NS_OK); - StopServer(); - - mMulticastDNS = nullptr; - - if (mWrappedListener) { - mWrappedListener->SetListener(nullptr); - mWrappedListener = nullptr; - } - - mInitialized = false; - return NS_OK; -} - -nsresult -MulticastDNSDeviceProvider::StartServer() -{ - LOG_I("StartServer: %s (%d)", mServiceName.get(), mDiscoverable); - MOZ_ASSERT(NS_IsMainThread()); - - if (!mDiscoverable) { - return NS_OK; - } - - nsresult rv; - - uint16_t servicePort; - if (NS_WARN_IF(NS_FAILED(rv = mPresentationService->GetPort(&servicePort)))) { - return rv; - } - - /** - * If |servicePort| is non-zero, it means PresentationControlService is running. - * Otherwise, we should make it start serving. - */ - if (servicePort) { - return RegisterMDNSService(); - } - - if (NS_WARN_IF(NS_FAILED(rv = mPresentationService->SetListener(mWrappedListener)))) { - return rv; - } - - AbortServerRetry(); - - if (NS_WARN_IF(NS_FAILED(rv = mPresentationService->StartServer(mDiscoverableEncrypted, 0)))) { - return rv; - } - - return NS_OK; -} - -nsresult -MulticastDNSDeviceProvider::StopServer() -{ - LOG_I("StopServer: %s", mServiceName.get()); - MOZ_ASSERT(NS_IsMainThread()); - - UnregisterMDNSService(NS_OK); - - AbortServerRetry(); - - if (mPresentationService) { - mPresentationService->SetListener(nullptr); - mPresentationService->Close(); - } - - return NS_OK; -} - -void -MulticastDNSDeviceProvider::AbortServerRetry() -{ - if (mIsServerRetrying) { - mIsServerRetrying = false; - mServerRetryTimer->Cancel(); - } -} - -nsresult -MulticastDNSDeviceProvider::RegisterMDNSService() -{ - LOG_I("RegisterMDNSService: %s", mServiceName.get()); - - if (!mDiscoverable) { - return NS_OK; - } - - // Cancel on going service registration. - UnregisterMDNSService(NS_OK); - - nsresult rv; - - uint16_t servicePort; - if (NS_FAILED(rv = mPresentationService->GetPort(&servicePort)) || - !servicePort) { - // Abort service registration if server port is not available. - return rv; - } - - /** - * Register the presentation control channel server as an mDNS service. - */ - nsCOMPtr serviceInfo = - do_CreateInstance(DNSSERVICEINFO_CONTRACT_ID, &rv); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - if (NS_WARN_IF(NS_FAILED(rv = serviceInfo->SetServiceType( - NS_LITERAL_CSTRING(SERVICE_TYPE))))) { - return rv; - } - if (NS_WARN_IF(NS_FAILED(rv = serviceInfo->SetServiceName(mServiceName)))) { - return rv; - } - if (NS_WARN_IF(NS_FAILED(rv = serviceInfo->SetPort(servicePort)))) { - return rv; - } - - nsCOMPtr propBag = - do_CreateInstance("@mozilla.org/hash-property-bag;1"); - MOZ_ASSERT(propBag); - - uint32_t version; - rv = mPresentationService->GetVersion(&version); - MOZ_ASSERT(NS_SUCCEEDED(rv)); - - rv = propBag->SetPropertyAsUint32(NS_LITERAL_STRING(PROTOCOL_VERSION_TAG), - version); - MOZ_ASSERT(NS_SUCCEEDED(rv)); - - if (mDiscoverableEncrypted) { - nsAutoCString certFingerprint; - rv = mPresentationService->GetCertFingerprint(certFingerprint); - MOZ_ASSERT(NS_SUCCEEDED(rv)); - - rv = propBag->SetPropertyAsACString(NS_LITERAL_STRING(CERT_FINGERPRINT_TAG), - certFingerprint); - MOZ_ASSERT(NS_SUCCEEDED(rv)); - } - - if (NS_WARN_IF(NS_FAILED(rv = serviceInfo->SetAttributes(propBag)))) { - return rv; - } - - return mMulticastDNS->RegisterService(serviceInfo, - mWrappedListener, - getter_AddRefs(mRegisterRequest)); -} - -nsresult -MulticastDNSDeviceProvider::UnregisterMDNSService(nsresult aReason) -{ - LOG_I("UnregisterMDNSService: %s (0x%08x)", mServiceName.get(), aReason); - MOZ_ASSERT(NS_IsMainThread()); - - if (mRegisterRequest) { - mRegisterRequest->Cancel(aReason); - mRegisterRequest = nullptr; - } - - return NS_OK; -} - -nsresult -MulticastDNSDeviceProvider::StopDiscovery(nsresult aReason) -{ - LOG_I("StopDiscovery (0x%08x)", aReason); - - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(mDiscoveryTimer); - - Unused << mDiscoveryTimer->Cancel(); - - if (mDiscoveryRequest) { - mDiscoveryRequest->Cancel(aReason); - mDiscoveryRequest = nullptr; - } - - return NS_OK; -} - -nsresult -MulticastDNSDeviceProvider::Connect(Device* aDevice, - nsIPresentationControlChannel** aRetVal) -{ - MOZ_ASSERT(aDevice); - MOZ_ASSERT(mPresentationService); - - RefPtr deviceInfo = new TCPDeviceInfo(aDevice->Id(), - aDevice->Address(), - aDevice->Port(), - aDevice->CertFingerprint()); - - return mPresentationService->Connect(deviceInfo, aRetVal); -} - -bool -MulticastDNSDeviceProvider::IsCompatibleServer(nsIDNSServiceInfo* aServiceInfo) -{ - MOZ_ASSERT(aServiceInfo); - - nsCOMPtr propBag; - if (NS_WARN_IF(NS_FAILED( - aServiceInfo->GetAttributes(getter_AddRefs(propBag)))) || !propBag) { - return false; - } - - uint32_t remoteVersion; - if (NS_WARN_IF(NS_FAILED( - propBag->GetPropertyAsUint32(NS_LITERAL_STRING(PROTOCOL_VERSION_TAG), - &remoteVersion)))) { - return false; - } - - bool isCompatible = false; - Unused << NS_WARN_IF(NS_FAILED( - mPresentationService->IsCompatibleServer(remoteVersion, - &isCompatible))); - - return isCompatible; -} - -nsresult -MulticastDNSDeviceProvider::AddDevice(const nsACString& aId, - const nsACString& aServiceName, - const nsACString& aServiceType, - const nsACString& aAddress, - const uint16_t aPort, - const nsACString& aCertFingerprint) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(mPresentationService); - - RefPtr device = new Device(aId, /* ID */ - aServiceName, - aServiceType, - aAddress, - aPort, - aCertFingerprint, - DeviceState::eActive, - this); - - nsCOMPtr listener; - if (NS_SUCCEEDED(GetListener(getter_AddRefs(listener))) && listener) { - Unused << listener->AddDevice(device); - } - - mDevices.AppendElement(device); - - return NS_OK; -} - -nsresult -MulticastDNSDeviceProvider::UpdateDevice(const uint32_t aIndex, - const nsACString& aServiceName, - const nsACString& aServiceType, - const nsACString& aAddress, - const uint16_t aPort, - const nsACString& aCertFingerprint) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(mPresentationService); - - if (NS_WARN_IF(aIndex >= mDevices.Length())) { - return NS_ERROR_INVALID_ARG; - } - - RefPtr device = mDevices[aIndex]; - device->Update(aServiceName, aServiceType, aAddress, aPort, aCertFingerprint); - device->ChangeState(DeviceState::eActive); - - nsCOMPtr listener; - if (NS_SUCCEEDED(GetListener(getter_AddRefs(listener))) && listener) { - Unused << listener->UpdateDevice(device); - } - - return NS_OK; -} - -nsresult -MulticastDNSDeviceProvider::RemoveDevice(const uint32_t aIndex) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(mPresentationService); - - if (NS_WARN_IF(aIndex >= mDevices.Length())) { - return NS_ERROR_INVALID_ARG; - } - - RefPtr device = mDevices[aIndex]; - - LOG_I("RemoveDevice: %s", device->Id().get()); - mDevices.RemoveElementAt(aIndex); - - nsCOMPtr listener; - if (NS_SUCCEEDED(GetListener(getter_AddRefs(listener))) && listener) { - Unused << listener->RemoveDevice(device); - } - - return NS_OK; -} - -bool -MulticastDNSDeviceProvider::FindDeviceById(const nsACString& aId, - uint32_t& aIndex) -{ - MOZ_ASSERT(NS_IsMainThread()); - - RefPtr device = new Device(aId, - /* aName = */ EmptyCString(), - /* aType = */ EmptyCString(), - /* aHost = */ EmptyCString(), - /* aPort = */ 0, - /* aCertFingerprint */ EmptyCString(), - /* aState = */ DeviceState::eUnknown, - /* aProvider = */ nullptr); - size_t index = mDevices.IndexOf(device, 0, DeviceIdComparator()); - - if (index == mDevices.NoIndex) { - return false; - } - - aIndex = index; - return true; -} - -bool -MulticastDNSDeviceProvider::FindDeviceByAddress(const nsACString& aAddress, - uint32_t& aIndex) -{ - MOZ_ASSERT(NS_IsMainThread()); - - RefPtr device = new Device(/* aId = */ EmptyCString(), - /* aName = */ EmptyCString(), - /* aType = */ EmptyCString(), - aAddress, - /* aPort = */ 0, - /* aCertFingerprint */ EmptyCString(), - /* aState = */ DeviceState::eUnknown, - /* aProvider = */ nullptr); - size_t index = mDevices.IndexOf(device, 0, DeviceAddressComparator()); - - if (index == mDevices.NoIndex) { - return false; - } - - aIndex = index; - return true; -} - -void -MulticastDNSDeviceProvider::MarkAllDevicesUnknown() -{ - MOZ_ASSERT(NS_IsMainThread()); - - for (auto& device : mDevices) { - device->ChangeState(DeviceState::eUnknown); - } -} - -void -MulticastDNSDeviceProvider::ClearUnknownDevices() -{ - MOZ_ASSERT(NS_IsMainThread()); - - size_t i = mDevices.Length(); - while (i > 0) { - --i; - if (mDevices[i]->State() == DeviceState::eUnknown) { - Unused << NS_WARN_IF(NS_FAILED(RemoveDevice(i))); - } - } -} - -void -MulticastDNSDeviceProvider::ClearDevices() -{ - MOZ_ASSERT(NS_IsMainThread()); - - size_t i = mDevices.Length(); - while (i > 0) { - --i; - Unused << NS_WARN_IF(NS_FAILED(RemoveDevice(i))); - } -} - -// nsIPresentationDeviceProvider -NS_IMETHODIMP -MulticastDNSDeviceProvider::GetListener(nsIPresentationDeviceListener** aListener) -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (NS_WARN_IF(!aListener)) { - return NS_ERROR_INVALID_POINTER; - } - - nsresult rv; - nsCOMPtr listener = - do_QueryReferent(mDeviceListener, &rv); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - listener.forget(aListener); - - return NS_OK; -} - -NS_IMETHODIMP -MulticastDNSDeviceProvider::SetListener(nsIPresentationDeviceListener* aListener) -{ - MOZ_ASSERT(NS_IsMainThread()); - - mDeviceListener = do_GetWeakReference(aListener); - - nsresult rv; - if (mDeviceListener) { - if (NS_WARN_IF(NS_FAILED(rv = Init()))) { - return rv; - } - } else { - if (NS_WARN_IF(NS_FAILED(rv = Uninit()))) { - return rv; - } - } - - return NS_OK; -} - -NS_IMETHODIMP -MulticastDNSDeviceProvider::ForceDiscovery() -{ - LOG_I("ForceDiscovery (%d)", mDiscoveryEnabled); - MOZ_ASSERT(NS_IsMainThread()); - - if (!mDiscoveryEnabled) { - return NS_OK; - } - - MOZ_ASSERT(mDiscoveryTimer); - MOZ_ASSERT(mMulticastDNS); - - // if it's already discovering, extend existing discovery timeout. - nsresult rv; - if (mIsDiscovering) { - Unused << mDiscoveryTimer->Cancel(); - - if (NS_WARN_IF(NS_FAILED( rv = mDiscoveryTimer->Init(this, - mDiscoveryTimeoutMs, - nsITimer::TYPE_ONE_SHOT)))) { - return rv; - } - return NS_OK; - } - - StopDiscovery(NS_OK); - - if (NS_WARN_IF(NS_FAILED(rv = mMulticastDNS->StartDiscovery( - NS_LITERAL_CSTRING(SERVICE_TYPE), - mWrappedListener, - getter_AddRefs(mDiscoveryRequest))))) { - return rv; - } - - return NS_OK; -} - -// nsIDNSServiceDiscoveryListener -NS_IMETHODIMP -MulticastDNSDeviceProvider::OnDiscoveryStarted(const nsACString& aServiceType) -{ - LOG_I("OnDiscoveryStarted"); - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(mDiscoveryTimer); - - MarkAllDevicesUnknown(); - - nsresult rv; - if (NS_WARN_IF(NS_FAILED(rv = mDiscoveryTimer->Init(this, - mDiscoveryTimeoutMs, - nsITimer::TYPE_ONE_SHOT)))) { - return rv; - } - - mIsDiscovering = true; - - return NS_OK; -} - -NS_IMETHODIMP -MulticastDNSDeviceProvider::OnDiscoveryStopped(const nsACString& aServiceType) -{ - LOG_I("OnDiscoveryStopped"); - MOZ_ASSERT(NS_IsMainThread()); - - ClearUnknownDevices(); - - mIsDiscovering = false; - - return NS_OK; -} - -NS_IMETHODIMP -MulticastDNSDeviceProvider::OnServiceFound(nsIDNSServiceInfo* aServiceInfo) -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (NS_WARN_IF(!aServiceInfo)) { - return NS_ERROR_INVALID_ARG; - } - - nsresult rv ; - - nsAutoCString serviceName; - if (NS_WARN_IF(NS_FAILED(rv = aServiceInfo->GetServiceName(serviceName)))) { - return rv; - } - - LOG_I("OnServiceFound: %s", serviceName.get()); - - if (mMulticastDNS) { - if (NS_WARN_IF(NS_FAILED(rv = mMulticastDNS->ResolveService( - aServiceInfo, mWrappedListener)))) { - return rv; - } - } - - return NS_OK; -} - -NS_IMETHODIMP -MulticastDNSDeviceProvider::OnServiceLost(nsIDNSServiceInfo* aServiceInfo) -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (NS_WARN_IF(!aServiceInfo)) { - return NS_ERROR_INVALID_ARG; - } - - nsresult rv; - - nsAutoCString serviceName; - if (NS_WARN_IF(NS_FAILED(rv = aServiceInfo->GetServiceName(serviceName)))) { - return rv; - } - - LOG_I("OnServiceLost: %s", serviceName.get()); - - nsAutoCString host; - if (NS_WARN_IF(NS_FAILED(rv = aServiceInfo->GetHost(host)))) { - return rv; - } - - uint32_t index; - if (!FindDeviceById(host, index)) { - // given device was not found - return NS_OK; - } - - if (NS_WARN_IF(NS_FAILED(rv = RemoveDevice(index)))) { - return rv; - } - - return NS_OK; -} - -NS_IMETHODIMP -MulticastDNSDeviceProvider::OnStartDiscoveryFailed(const nsACString& aServiceType, - int32_t aErrorCode) -{ - LOG_E("OnStartDiscoveryFailed: %d", aErrorCode); - MOZ_ASSERT(NS_IsMainThread()); - - return NS_OK; -} - -NS_IMETHODIMP -MulticastDNSDeviceProvider::OnStopDiscoveryFailed(const nsACString& aServiceType, - int32_t aErrorCode) -{ - LOG_E("OnStopDiscoveryFailed: %d", aErrorCode); - MOZ_ASSERT(NS_IsMainThread()); - - return NS_OK; -} - -// nsIDNSRegistrationListener -NS_IMETHODIMP -MulticastDNSDeviceProvider::OnServiceRegistered(nsIDNSServiceInfo* aServiceInfo) -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (NS_WARN_IF(!aServiceInfo)) { - return NS_ERROR_INVALID_ARG; - } - nsresult rv; - - nsAutoCString name; - if (NS_WARN_IF(NS_FAILED(rv = aServiceInfo->GetServiceName(name)))) { - return rv; - } - - LOG_I("OnServiceRegistered (%s)", name.get()); - mRegisteredName = name; - - if (mMulticastDNS) { - if (NS_WARN_IF(NS_FAILED(rv = mMulticastDNS->ResolveService( - aServiceInfo, mWrappedListener)))) { - return rv; - } - } - - return NS_OK; -} - -NS_IMETHODIMP -MulticastDNSDeviceProvider::OnServiceUnregistered(nsIDNSServiceInfo* aServiceInfo) -{ - LOG_I("OnServiceUnregistered"); - MOZ_ASSERT(NS_IsMainThread()); - - return NS_OK; -} - -NS_IMETHODIMP -MulticastDNSDeviceProvider::OnRegistrationFailed(nsIDNSServiceInfo* aServiceInfo, - int32_t aErrorCode) -{ - LOG_E("OnRegistrationFailed: %d", aErrorCode); - MOZ_ASSERT(NS_IsMainThread()); - - mRegisterRequest = nullptr; - - if (aErrorCode == nsIDNSRegistrationListener::ERROR_SERVICE_NOT_RUNNING) { - return NS_DispatchToMainThread( - NewRunnableMethod(this, &MulticastDNSDeviceProvider::RegisterMDNSService)); - } - - return NS_OK; -} - -NS_IMETHODIMP -MulticastDNSDeviceProvider::OnUnregistrationFailed(nsIDNSServiceInfo* aServiceInfo, - int32_t aErrorCode) -{ - LOG_E("OnUnregistrationFailed: %d", aErrorCode); - MOZ_ASSERT(NS_IsMainThread()); - - return NS_OK; -} - -// nsIDNSServiceResolveListener -NS_IMETHODIMP -MulticastDNSDeviceProvider::OnServiceResolved(nsIDNSServiceInfo* aServiceInfo) -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (NS_WARN_IF(!aServiceInfo)) { - return NS_ERROR_INVALID_ARG; - } - - nsresult rv; - - nsAutoCString serviceName; - if (NS_WARN_IF(NS_FAILED(rv = aServiceInfo->GetServiceName(serviceName)))) { - return rv; - } - - LOG_I("OnServiceResolved: %s", serviceName.get()); - - nsAutoCString host; - if (NS_WARN_IF(NS_FAILED(rv = aServiceInfo->GetHost(host)))) { - return rv; - } - - if (mRegisteredName == serviceName) { - LOG_I("ignore self"); - - if (NS_WARN_IF(NS_FAILED(rv = mPresentationService->SetId(host)))) { - return rv; - } - - return NS_OK; - } - - if (!IsCompatibleServer(aServiceInfo)) { - LOG_I("ignore incompatible service: %s", serviceName.get()); - return NS_OK; - } - - nsAutoCString address; - if (NS_WARN_IF(NS_FAILED(rv = aServiceInfo->GetAddress(address)))) { - return rv; - } - - uint16_t port; - if (NS_WARN_IF(NS_FAILED(rv = aServiceInfo->GetPort(&port)))) { - return rv; - } - - nsAutoCString serviceType; - if (NS_WARN_IF(NS_FAILED(rv = aServiceInfo->GetServiceType(serviceType)))) { - return rv; - } - - nsCOMPtr propBag; - if (NS_WARN_IF(NS_FAILED( - aServiceInfo->GetAttributes(getter_AddRefs(propBag)))) || !propBag) { - return rv; - } - - nsAutoCString certFingerprint; - Unused << propBag->GetPropertyAsACString(NS_LITERAL_STRING(CERT_FINGERPRINT_TAG), - certFingerprint); - - uint32_t index; - if (FindDeviceById(host, index)) { - return UpdateDevice(index, - serviceName, - serviceType, - address, - port, - certFingerprint); - } else { - return AddDevice(host, - serviceName, - serviceType, - address, - port, - certFingerprint); - } - - return NS_OK; -} - -NS_IMETHODIMP -MulticastDNSDeviceProvider::OnResolveFailed(nsIDNSServiceInfo* aServiceInfo, - int32_t aErrorCode) -{ - LOG_E("OnResolveFailed: %d", aErrorCode); - MOZ_ASSERT(NS_IsMainThread()); - - return NS_OK; -} - -// nsIPresentationControlServerListener -NS_IMETHODIMP -MulticastDNSDeviceProvider::OnServerReady(uint16_t aPort, - const nsACString& aCertFingerprint) -{ - LOG_I("OnServerReady: %d, %s", aPort, PromiseFlatCString(aCertFingerprint).get()); - MOZ_ASSERT(NS_IsMainThread()); - - if (mDiscoverable) { - RegisterMDNSService(); - } - - return NS_OK; -} - -NS_IMETHODIMP -MulticastDNSDeviceProvider::OnServerStopped(nsresult aResult) -{ - LOG_I("OnServerStopped: (0x%08x)", aResult); - - UnregisterMDNSService(aResult); - - // Try restart server if it is stopped abnormally. - if (NS_FAILED(aResult) && mDiscoverable) { - mIsServerRetrying = true; - mServerRetryTimer->Init(this, mServerRetryMs, nsITimer::TYPE_ONE_SHOT); - } - - return NS_OK; -} - -// Create a new device if we were unable to find one with the address. -already_AddRefed -MulticastDNSDeviceProvider::GetOrCreateDevice(nsITCPDeviceInfo* aDeviceInfo) -{ - nsAutoCString address; - Unused << aDeviceInfo->GetAddress(address); - - RefPtr device; - uint32_t index; - if (FindDeviceByAddress(address, index)) { - device = mDevices[index]; - } else { - // Create a one-time device object for non-discoverable controller. - // This device will not be in the list of available devices and cannot - // be used for requesting session. - nsAutoCString id; - Unused << aDeviceInfo->GetId(id); - uint16_t port; - Unused << aDeviceInfo->GetPort(&port); - - device = new Device(id, - /* aName = */ id, - /* aType = */ EmptyCString(), - address, - port, - /* aCertFingerprint */ EmptyCString(), - DeviceState::eActive, - /* aProvider = */ nullptr); - } - - return device.forget(); -} - -NS_IMETHODIMP -MulticastDNSDeviceProvider::OnSessionRequest(nsITCPDeviceInfo* aDeviceInfo, - const nsAString& aUrl, - const nsAString& aPresentationId, - nsIPresentationControlChannel* aControlChannel) -{ - MOZ_ASSERT(NS_IsMainThread()); - - nsAutoCString address; - Unused << aDeviceInfo->GetAddress(address); - - LOG_I("OnSessionRequest: %s", address.get()); - - RefPtr device = GetOrCreateDevice(aDeviceInfo); - nsCOMPtr listener; - if (NS_SUCCEEDED(GetListener(getter_AddRefs(listener))) && listener) { - Unused << listener->OnSessionRequest(device, aUrl, aPresentationId, - aControlChannel); - } - - return NS_OK; -} - -NS_IMETHODIMP -MulticastDNSDeviceProvider::OnTerminateRequest(nsITCPDeviceInfo* aDeviceInfo, - const nsAString& aPresentationId, - nsIPresentationControlChannel* aControlChannel, - bool aIsFromReceiver) -{ - MOZ_ASSERT(NS_IsMainThread()); - - nsAutoCString address; - Unused << aDeviceInfo->GetAddress(address); - - LOG_I("OnTerminateRequest: %s", address.get()); - - RefPtr device = GetOrCreateDevice(aDeviceInfo); - nsCOMPtr listener; - if (NS_SUCCEEDED(GetListener(getter_AddRefs(listener))) && listener) { - Unused << listener->OnTerminateRequest(device, aPresentationId, - aControlChannel, aIsFromReceiver); - } - - return NS_OK; -} - -NS_IMETHODIMP -MulticastDNSDeviceProvider::OnReconnectRequest(nsITCPDeviceInfo* aDeviceInfo, - const nsAString& aUrl, - const nsAString& aPresentationId, - nsIPresentationControlChannel* aControlChannel) -{ - MOZ_ASSERT(NS_IsMainThread()); - - nsAutoCString address; - Unused << aDeviceInfo->GetAddress(address); - - LOG_I("OnReconnectRequest: %s", address.get()); - - RefPtr device = GetOrCreateDevice(aDeviceInfo); - nsCOMPtr listener; - if (NS_SUCCEEDED(GetListener(getter_AddRefs(listener))) && listener) { - Unused << listener->OnReconnectRequest(device, aUrl, aPresentationId, - aControlChannel); - } - - return NS_OK; -} - -// nsIObserver -NS_IMETHODIMP -MulticastDNSDeviceProvider::Observe(nsISupports* aSubject, - const char* aTopic, - const char16_t* aData) -{ - MOZ_ASSERT(NS_IsMainThread()); - - NS_ConvertUTF16toUTF8 data(aData); - LOG_I("Observe: topic = %s, data = %s", aTopic, data.get()); - - if (!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) { - if (data.EqualsLiteral(PREF_PRESENTATION_DISCOVERY)) { - OnDiscoveryChanged(Preferences::GetBool(PREF_PRESENTATION_DISCOVERY)); - } else if (data.EqualsLiteral(PREF_PRESENTATION_DISCOVERY_TIMEOUT_MS)) { - OnDiscoveryTimeoutChanged(Preferences::GetUint(PREF_PRESENTATION_DISCOVERY_TIMEOUT_MS)); - } else if (data.EqualsLiteral(PREF_PRESENTATION_DISCOVERABLE)) { - OnDiscoverableChanged(Preferences::GetBool(PREF_PRESENTATION_DISCOVERABLE)); - } else if (data.EqualsLiteral(PREF_PRESENTATION_DEVICE_NAME)) { - nsAdoptingCString newServiceName = Preferences::GetCString(PREF_PRESENTATION_DEVICE_NAME); - if (!mServiceName.Equals(newServiceName)) { - OnServiceNameChanged(newServiceName); - } - } - } else if (!strcmp(aTopic, NS_TIMER_CALLBACK_TOPIC)) { - nsCOMPtr timer = do_QueryInterface(aSubject); - if (!timer) { - return NS_ERROR_UNEXPECTED; - } - - if (timer == mDiscoveryTimer) { - StopDiscovery(NS_OK); - } else if (timer == mServerRetryTimer) { - mIsServerRetrying = false; - StartServer(); - } - } - - return NS_OK; -} - -nsresult -MulticastDNSDeviceProvider::OnDiscoveryChanged(bool aEnabled) -{ - LOG_I("DiscoveryEnabled = %d\n", aEnabled); - MOZ_ASSERT(NS_IsMainThread()); - - mDiscoveryEnabled = aEnabled; - - if (mDiscoveryEnabled) { - return ForceDiscovery(); - } - - return StopDiscovery(NS_OK); -} - -nsresult -MulticastDNSDeviceProvider::OnDiscoveryTimeoutChanged(uint32_t aTimeoutMs) -{ - LOG_I("OnDiscoveryTimeoutChanged = %d\n", aTimeoutMs); - MOZ_ASSERT(NS_IsMainThread()); - - mDiscoveryTimeoutMs = aTimeoutMs; - - return NS_OK; -} - -nsresult -MulticastDNSDeviceProvider::OnDiscoverableChanged(bool aEnabled) -{ - LOG_I("Discoverable = %d\n", aEnabled); - MOZ_ASSERT(NS_IsMainThread()); - - mDiscoverable = aEnabled; - - if (mDiscoverable) { - return StartServer(); - } - - return StopServer(); -} - -nsresult -MulticastDNSDeviceProvider::OnServiceNameChanged(const nsACString& aServiceName) -{ - LOG_I("serviceName = %s\n", PromiseFlatCString(aServiceName).get()); - MOZ_ASSERT(NS_IsMainThread()); - - mServiceName = aServiceName; - - nsresult rv; - if (NS_WARN_IF(NS_FAILED(rv = UnregisterMDNSService(NS_OK)))) { - return rv; - } - - if (mDiscoverable) { - return RegisterMDNSService(); - } - - return NS_OK; -} - -// MulticastDNSDeviceProvider::Device -NS_IMPL_ISUPPORTS(MulticastDNSDeviceProvider::Device, - nsIPresentationDevice) - -// nsIPresentationDevice -NS_IMETHODIMP -MulticastDNSDeviceProvider::Device::GetId(nsACString& aId) -{ - aId = mId; - - return NS_OK; -} - -NS_IMETHODIMP -MulticastDNSDeviceProvider::Device::GetName(nsACString& aName) -{ - aName = mName; - - return NS_OK; -} - -NS_IMETHODIMP -MulticastDNSDeviceProvider::Device::GetType(nsACString& aType) -{ - aType = mType; - - return NS_OK; -} - -NS_IMETHODIMP -MulticastDNSDeviceProvider::Device::EstablishControlChannel( - nsIPresentationControlChannel** aRetVal) -{ - if (!mProvider) { - return NS_ERROR_FAILURE; - } - - return mProvider->Connect(this, aRetVal); -} - -NS_IMETHODIMP -MulticastDNSDeviceProvider::Device::Disconnect() -{ - // No need to do anything when disconnect. - return NS_OK; -} - -NS_IMETHODIMP -MulticastDNSDeviceProvider::Device::IsRequestedUrlSupported( - const nsAString& aRequestedUrl, - bool* aRetVal) -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (!aRetVal) { - return NS_ERROR_INVALID_POINTER; - } - - // TV 2.6 also supports presentation Apps and HTTP/HTTPS hosted receiver page. - if (DeviceProviderHelpers::IsFxTVSupportedAppUrl(aRequestedUrl) || - DeviceProviderHelpers::IsCommonlySupportedScheme(aRequestedUrl)) { - *aRetVal = true; - } - - return NS_OK; -} - -} // namespace presentation -} // namespace dom -} // namespace mozilla diff --git a/dom/presentation/provider/MulticastDNSDeviceProvider.h b/dom/presentation/provider/MulticastDNSDeviceProvider.h deleted file mode 100644 index c6a91b3d81..0000000000 --- a/dom/presentation/provider/MulticastDNSDeviceProvider.h +++ /dev/null @@ -1,225 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_dom_presentation_provider_MulticastDNSDeviceProvider_h -#define mozilla_dom_presentation_provider_MulticastDNSDeviceProvider_h - -#include "mozilla/RefPtr.h" -#include "nsCOMPtr.h" -#include "nsICancelable.h" -#include "nsIDNSServiceDiscovery.h" -#include "nsIObserver.h" -#include "nsIPresentationDevice.h" -#include "nsIPresentationDeviceProvider.h" -#include "nsIPresentationControlService.h" -#include "nsITimer.h" -#include "nsString.h" -#include "nsTArray.h" -#include "nsWeakPtr.h" - -class nsITCPDeviceInfo; - -namespace mozilla { -namespace dom { -namespace presentation { - -class DNSServiceWrappedListener; -class MulticastDNSService; - -class MulticastDNSDeviceProvider final - : public nsIPresentationDeviceProvider - , public nsIDNSServiceDiscoveryListener - , public nsIDNSRegistrationListener - , public nsIDNSServiceResolveListener - , public nsIPresentationControlServerListener - , public nsIObserver -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIPRESENTATIONDEVICEPROVIDER - NS_DECL_NSIDNSSERVICEDISCOVERYLISTENER - NS_DECL_NSIDNSREGISTRATIONLISTENER - NS_DECL_NSIDNSSERVICERESOLVELISTENER - NS_DECL_NSIPRESENTATIONCONTROLSERVERLISTENER - NS_DECL_NSIOBSERVER - - explicit MulticastDNSDeviceProvider() = default; - nsresult Init(); - nsresult Uninit(); - -private: - enum class DeviceState : uint32_t { - eUnknown, - eActive - }; - - class Device final : public nsIPresentationDevice - { - public: - NS_DECL_ISUPPORTS - NS_DECL_NSIPRESENTATIONDEVICE - - explicit Device(const nsACString& aId, - const nsACString& aName, - const nsACString& aType, - const nsACString& aAddress, - const uint16_t aPort, - const nsACString& aCertFingerprint, - DeviceState aState, - MulticastDNSDeviceProvider* aProvider) - : mId(aId) - , mName(aName) - , mType(aType) - , mAddress(aAddress) - , mPort(aPort) - , mCertFingerprint(aCertFingerprint) - , mState(aState) - , mProvider(aProvider) - { - } - - const nsCString& Id() const - { - return mId; - } - - const nsCString& Address() const - { - return mAddress; - } - - uint16_t Port() const - { - return mPort; - } - - const nsCString& CertFingerprint() const - { - return mCertFingerprint; - } - - DeviceState State() const - { - return mState; - } - - void ChangeState(DeviceState aState) - { - mState = aState; - } - - void Update(const nsACString& aName, - const nsACString& aType, - const nsACString& aAddress, - const uint16_t aPort, - const nsACString& aCertFingerprint) - { - mName = aName; - mType = aType; - mAddress = aAddress; - mPort = aPort; - mCertFingerprint = aCertFingerprint; - } - - private: - virtual ~Device() = default; - - nsCString mId; - nsCString mName; - nsCString mType; - nsCString mAddress; - uint16_t mPort; - nsCString mCertFingerprint; - DeviceState mState; - MulticastDNSDeviceProvider* mProvider; - }; - - struct DeviceIdComparator { - bool Equals(const RefPtr& aA, const RefPtr& aB) const { - return aA->Id() == aB->Id(); - } - }; - - struct DeviceAddressComparator { - bool Equals(const RefPtr& aA, const RefPtr& aB) const { - return aA->Address() == aB->Address(); - } - }; - - virtual ~MulticastDNSDeviceProvider(); - nsresult StartServer(); - nsresult StopServer(); - void AbortServerRetry(); - nsresult RegisterMDNSService(); - nsresult UnregisterMDNSService(nsresult aReason); - nsresult StopDiscovery(nsresult aReason); - nsresult Connect(Device* aDevice, - nsIPresentationControlChannel** aRetVal); - bool IsCompatibleServer(nsIDNSServiceInfo* aServiceInfo); - - // device manipulation - nsresult AddDevice(const nsACString& aId, - const nsACString& aServiceName, - const nsACString& aServiceType, - const nsACString& aAddress, - const uint16_t aPort, - const nsACString& aCertFingerprint); - nsresult UpdateDevice(const uint32_t aIndex, - const nsACString& aServiceName, - const nsACString& aServiceType, - const nsACString& aAddress, - const uint16_t aPort, - const nsACString& aCertFingerprint); - nsresult RemoveDevice(const uint32_t aIndex); - bool FindDeviceById(const nsACString& aId, - uint32_t& aIndex); - - bool FindDeviceByAddress(const nsACString& aAddress, - uint32_t& aIndex); - - already_AddRefed - GetOrCreateDevice(nsITCPDeviceInfo* aDeviceInfo); - - void MarkAllDevicesUnknown(); - void ClearUnknownDevices(); - void ClearDevices(); - - // preferences - nsresult OnDiscoveryChanged(bool aEnabled); - nsresult OnDiscoveryTimeoutChanged(uint32_t aTimeoutMs); - nsresult OnDiscoverableChanged(bool aEnabled); - nsresult OnServiceNameChanged(const nsACString& aServiceName); - - bool mInitialized = false; - nsWeakPtr mDeviceListener; - nsCOMPtr mPresentationService; - nsCOMPtr mMulticastDNS; - RefPtr mWrappedListener; - - nsCOMPtr mDiscoveryRequest; - nsCOMPtr mRegisterRequest; - - nsTArray> mDevices; - - bool mDiscoveryEnabled = false; - bool mIsDiscovering = false; - uint32_t mDiscoveryTimeoutMs; - nsCOMPtr mDiscoveryTimer; - - bool mDiscoverable = false; - bool mDiscoverableEncrypted = false; - bool mIsServerRetrying = false; - uint32_t mServerRetryMs; - nsCOMPtr mServerRetryTimer; - - nsCString mServiceName; - nsCString mRegisteredName; -}; - -} // namespace presentation -} // namespace dom -} // namespace mozilla - -#endif // mozilla_dom_presentation_provider_MulticastDNSDeviceProvider_h diff --git a/dom/presentation/provider/PresentationControlService.js b/dom/presentation/provider/PresentationControlService.js deleted file mode 100644 index e9f92247f4..0000000000 --- a/dom/presentation/provider/PresentationControlService.js +++ /dev/null @@ -1,960 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -/* jshint esnext:true, globalstrict:true, moz:true, undef:true, unused:true */ -/* globals Components, dump */ -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -/* globals XPCOMUtils */ -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -/* globals Services */ -Cu.import("resource://gre/modules/Services.jsm"); -/* globals NetUtil */ -Cu.import("resource://gre/modules/NetUtil.jsm"); -/* globals setTimeout, clearTimeout */ -Cu.import("resource://gre/modules/Timer.jsm"); - -/* globals ControllerStateMachine */ -XPCOMUtils.defineLazyModuleGetter(this, "ControllerStateMachine", // jshint ignore:line - "resource://gre/modules/presentation/ControllerStateMachine.jsm"); -/* global ReceiverStateMachine */ -XPCOMUtils.defineLazyModuleGetter(this, "ReceiverStateMachine", // jshint ignore:line - "resource://gre/modules/presentation/ReceiverStateMachine.jsm"); - -const kProtocolVersion = 1; // need to review isCompatibleServer while fiddling the version number. -const kLocalCertName = "presentation"; - -const DEBUG = Services.prefs.getBoolPref("dom.presentation.tcp_server.debug"); -function log(aMsg) { - dump("-*- PresentationControlService.js: " + aMsg + "\n"); -} - -function TCPDeviceInfo(aAddress, aPort, aId, aCertFingerprint) { - this.address = aAddress; - this.port = aPort; - this.id = aId; - this.certFingerprint = aCertFingerprint || ""; -} - -function PresentationControlService() { - this._id = null; - this._port = 0; - this._serverSocket = null; -} - -PresentationControlService.prototype = { - /** - * If a user agent connects to this server, we create a control channel but - * hand it to |TCPDevice.listener| when the initial information exchange - * finishes. Therefore, we hold the control channels in this period. - */ - _controlChannels: [], - - startServer: function(aEncrypted, aPort) { - if (this._isServiceInit()) { - DEBUG && log("PresentationControlService - server socket has been initialized"); // jshint ignore:line - throw Cr.NS_ERROR_FAILURE; - } - - /** - * 0 or undefined indicates opt-out parameter, and a port will be selected - * automatically. - */ - let serverSocketPort = (typeof aPort !== "undefined" && aPort !== 0) ? aPort : -1; - - if (aEncrypted) { - let self = this; - let localCertService = Cc["@mozilla.org/security/local-cert-service;1"] - .getService(Ci.nsILocalCertService); - localCertService.getOrCreateCert(kLocalCertName, { - handleCert: function(aCert, aRv) { - DEBUG && log("PresentationControlService - handleCert"); // jshint ignore:line - if (aRv) { - self._notifyServerStopped(aRv); - } else { - self._serverSocket = Cc["@mozilla.org/network/tls-server-socket;1"] - .createInstance(Ci.nsITLSServerSocket); - - self._serverSocketInit(serverSocketPort, aCert); - } - } - }); - } else { - this._serverSocket = Cc["@mozilla.org/network/server-socket;1"] - .createInstance(Ci.nsIServerSocket); - - this._serverSocketInit(serverSocketPort, null); - } - }, - - _serverSocketInit: function(aPort, aCert) { - if (!this._serverSocket) { - DEBUG && log("PresentationControlService - create server socket fail."); // jshint ignore:line - throw Cr.NS_ERROR_FAILURE; - } - - try { - this._serverSocket.init(aPort, false, -1); - - if (aCert) { - this._serverSocket.serverCert = aCert; - this._serverSocket.setSessionTickets(false); - let requestCert = Ci.nsITLSServerSocket.REQUEST_NEVER; - this._serverSocket.setRequestClientCertificate(requestCert); - } - - this._serverSocket.asyncListen(this); - } catch (e) { - // NS_ERROR_SOCKET_ADDRESS_IN_USE - DEBUG && log("PresentationControlService - init server socket fail: " + e); // jshint ignore:line - throw Cr.NS_ERROR_FAILURE; - } - - this._port = this._serverSocket.port; - - DEBUG && log("PresentationControlService - service start on port: " + this._port); // jshint ignore:line - - // Monitor network interface change to restart server socket. - Services.obs.addObserver(this, "network:offline-status-changed", false); - - this._notifyServerReady(); - }, - - _notifyServerReady: function() { - Services.tm.mainThread.dispatch(() => { - if (this._listener) { - this._listener.onServerReady(this._port, this.certFingerprint); - } - }, Ci.nsIThread.DISPATCH_NORMAL); - }, - - _notifyServerStopped: function(aRv) { - Services.tm.mainThread.dispatch(() => { - if (this._listener) { - this._listener.onServerStopped(aRv); - } - }, Ci.nsIThread.DISPATCH_NORMAL); - }, - - isCompatibleServer: function(aVersion) { - // No compatibility issue for the first version of control protocol - return this.version === aVersion; - }, - - get id() { - return this._id; - }, - - set id(aId) { - this._id = aId; - }, - - get port() { - return this._port; - }, - - get version() { - return kProtocolVersion; - }, - - get certFingerprint() { - if (!this._serverSocket.serverCert) { - return null; - } - - return this._serverSocket.serverCert.sha256Fingerprint; - }, - - set listener(aListener) { - this._listener = aListener; - }, - - get listener() { - return this._listener; - }, - - _isServiceInit: function() { - return this._serverSocket !== null; - }, - - connect: function(aDeviceInfo) { - if (!this.id) { - DEBUG && log("PresentationControlService - Id has not initialized; connect fails"); // jshint ignore:line - return null; - } - DEBUG && log("PresentationControlService - connect to " + aDeviceInfo.id); // jshint ignore:line - - let socketTransport = this._attemptConnect(aDeviceInfo); - return new TCPControlChannel(this, - socketTransport, - aDeviceInfo, - "sender"); - }, - - _attemptConnect: function(aDeviceInfo) { - let sts = Cc["@mozilla.org/network/socket-transport-service;1"] - .getService(Ci.nsISocketTransportService); - - let socketTransport; - try { - if (aDeviceInfo.certFingerprint) { - let overrideService = Cc["@mozilla.org/security/certoverride;1"] - .getService(Ci.nsICertOverrideService); - overrideService.rememberTemporaryValidityOverrideUsingFingerprint( - aDeviceInfo.address, - aDeviceInfo.port, - aDeviceInfo.certFingerprint, - Ci.nsICertOverrideService.ERROR_UNTRUSTED | Ci.nsICertOverrideService.ERROR_MISMATCH); - - socketTransport = sts.createTransport(["ssl"], - 1, - aDeviceInfo.address, - aDeviceInfo.port, - null); - } else { - socketTransport = sts.createTransport(null, - 0, - aDeviceInfo.address, - aDeviceInfo.port, - null); - } - // Shorten the connection failure procedure. - socketTransport.setTimeout(Ci.nsISocketTransport.TIMEOUT_CONNECT, 2); - } catch (e) { - DEBUG && log("PresentationControlService - createTransport throws: " + e); // jshint ignore:line - // Pop the exception to |TCPDevice.establishControlChannel| - throw Cr.NS_ERROR_FAILURE; - } - return socketTransport; - }, - - responseSession: function(aDeviceInfo, aSocketTransport) { - if (!this._isServiceInit()) { - DEBUG && log("PresentationControlService - should never receive remote " + - "session request before server socket initialization"); // jshint ignore:line - return null; - } - DEBUG && log("PresentationControlService - responseSession to " + - JSON.stringify(aDeviceInfo)); // jshint ignore:line - return new TCPControlChannel(this, - aSocketTransport, - aDeviceInfo, - "receiver"); - }, - - // Triggered by TCPControlChannel - onSessionRequest: function(aDeviceInfo, aUrl, aPresentationId, aControlChannel) { - DEBUG && log("PresentationControlService - onSessionRequest: " + - aDeviceInfo.address + ":" + aDeviceInfo.port); // jshint ignore:line - if (!this.listener) { - this.releaseControlChannel(aControlChannel); - return; - } - - this.listener.onSessionRequest(aDeviceInfo, - aUrl, - aPresentationId, - aControlChannel); - this.releaseControlChannel(aControlChannel); - }, - - onSessionTerminate: function(aDeviceInfo, aPresentationId, aControlChannel, aIsFromReceiver) { - DEBUG && log("TCPPresentationServer - onSessionTerminate: " + - aDeviceInfo.address + ":" + aDeviceInfo.port); // jshint ignore:line - if (!this.listener) { - this.releaseControlChannel(aControlChannel); - return; - } - - this.listener.onTerminateRequest(aDeviceInfo, - aPresentationId, - aControlChannel, - aIsFromReceiver); - this.releaseControlChannel(aControlChannel); - }, - - onSessionReconnect: function(aDeviceInfo, aUrl, aPresentationId, aControlChannel) { - DEBUG && log("TCPPresentationServer - onSessionReconnect: " + - aDeviceInfo.address + ":" + aDeviceInfo.port); // jshint ignore:line - if (!this.listener) { - this.releaseControlChannel(aControlChannel); - return; - } - - this.listener.onReconnectRequest(aDeviceInfo, - aUrl, - aPresentationId, - aControlChannel); - this.releaseControlChannel(aControlChannel); - }, - - // nsIServerSocketListener (Triggered by nsIServerSocket.init) - onSocketAccepted: function(aServerSocket, aClientSocket) { - DEBUG && log("PresentationControlService - onSocketAccepted: " + - aClientSocket.host + ":" + aClientSocket.port); // jshint ignore:line - let deviceInfo = new TCPDeviceInfo(aClientSocket.host, aClientSocket.port); - this.holdControlChannel(this.responseSession(deviceInfo, aClientSocket)); - }, - - holdControlChannel: function(aControlChannel) { - this._controlChannels.push(aControlChannel); - }, - - releaseControlChannel: function(aControlChannel) { - let index = this._controlChannels.indexOf(aControlChannel); - if (index !== -1) { - delete this._controlChannels[index]; - } - }, - - // nsIServerSocketListener (Triggered by nsIServerSocket.init) - onStopListening: function(aServerSocket, aStatus) { - DEBUG && log("PresentationControlService - onStopListening: " + aStatus); // jshint ignore:line - }, - - close: function() { - DEBUG && log("PresentationControlService - close"); // jshint ignore:line - if (this._isServiceInit()) { - DEBUG && log("PresentationControlService - close server socket"); // jshint ignore:line - this._serverSocket.close(); - this._serverSocket = null; - - Services.obs.removeObserver(this, "network:offline-status-changed"); - - this._notifyServerStopped(Cr.NS_OK); - } - this._port = 0; - }, - - // nsIObserver - observe: function(aSubject, aTopic, aData) { - DEBUG && log("PresentationControlService - observe: " + aTopic); // jshint ignore:line - switch (aTopic) { - case "network:offline-status-changed": { - if (aData == "offline") { - DEBUG && log("network offline"); // jshint ignore:line - return; - } - this._restartServer(); - break; - } - } - }, - - _restartServer: function() { - DEBUG && log("PresentationControlService - restart service"); // jshint ignore:line - - // restart server socket - if (this._isServiceInit()) { - this.close(); - - try { - this.startServer(); - } catch (e) { - DEBUG && log("PresentationControlService - restart service fail: " + e); // jshint ignore:line - } - } - }, - - classID: Components.ID("{f4079b8b-ede5-4b90-a112-5b415a931deb}"), - QueryInterface : XPCOMUtils.generateQI([Ci.nsIServerSocketListener, - Ci.nsIPresentationControlService, - Ci.nsIObserver]), -}; - -function ChannelDescription(aInit) { - this._type = aInit.type; - switch (this._type) { - case Ci.nsIPresentationChannelDescription.TYPE_TCP: - this._tcpAddresses = Cc["@mozilla.org/array;1"] - .createInstance(Ci.nsIMutableArray); - for (let address of aInit.tcpAddress) { - let wrapper = Cc["@mozilla.org/supports-cstring;1"] - .createInstance(Ci.nsISupportsCString); - wrapper.data = address; - this._tcpAddresses.appendElement(wrapper, false); - } - - this._tcpPort = aInit.tcpPort; - break; - case Ci.nsIPresentationChannelDescription.TYPE_DATACHANNEL: - this._dataChannelSDP = aInit.dataChannelSDP; - break; - } -} - -ChannelDescription.prototype = { - _type: 0, - _tcpAddresses: null, - _tcpPort: 0, - _dataChannelSDP: "", - - get type() { - return this._type; - }, - - get tcpAddress() { - return this._tcpAddresses; - }, - - get tcpPort() { - return this._tcpPort; - }, - - get dataChannelSDP() { - return this._dataChannelSDP; - }, - - classID: Components.ID("{82507aea-78a2-487e-904a-858a6c5bf4e1}"), - QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationChannelDescription]), -}; - -// Helper function: transfer nsIPresentationChannelDescription to json -function discriptionAsJson(aDescription) { - let json = {}; - json.type = aDescription.type; - switch(aDescription.type) { - case Ci.nsIPresentationChannelDescription.TYPE_TCP: - let addresses = aDescription.tcpAddress.QueryInterface(Ci.nsIArray); - json.tcpAddress = []; - for (let idx = 0; idx < addresses.length; idx++) { - let address = addresses.queryElementAt(idx, Ci.nsISupportsCString); - json.tcpAddress.push(address.data); - } - json.tcpPort = aDescription.tcpPort; - break; - case Ci.nsIPresentationChannelDescription.TYPE_DATACHANNEL: - json.dataChannelSDP = aDescription.dataChannelSDP; - break; - } - return json; -} - -const kDisconnectTimeout = 5000; -const kTerminateTimeout = 5000; - -function TCPControlChannel(presentationService, - transport, - deviceInfo, - direction) { - DEBUG && log("create TCPControlChannel for : " + direction); // jshint ignore:line - this._deviceInfo = deviceInfo; - this._direction = direction; - this._transport = transport; - - this._presentationService = presentationService; - - if (direction === "receiver") { - // Need to set security observer before I/O stream operation. - this._setSecurityObserver(this); - } - - let currentThread = Services.tm.currentThread; - transport.setEventSink(this, currentThread); - - this._input = this._transport.openInputStream(0, 0, 0) - .QueryInterface(Ci.nsIAsyncInputStream); - this._input.asyncWait(this.QueryInterface(Ci.nsIStreamListener), - Ci.nsIAsyncInputStream.WAIT_CLOSURE_ONLY, - 0, - currentThread); - - this._output = this._transport - .openOutputStream(Ci.nsITransport.OPEN_UNBUFFERED, 0, 0) - .QueryInterface(Ci.nsIAsyncOutputStream); - - this._outgoingMsgs = []; - - - this._stateMachine = - (direction === "sender") ? new ControllerStateMachine(this, presentationService.id) - : new ReceiverStateMachine(this); - - if (direction === "receiver" && !transport.securityInfo) { - // Since the transport created by server socket is already CONNECTED_TO. - this._outgoingEnabled = true; - this._createInputStreamPump(); - } -} - -TCPControlChannel.prototype = { - _outgoingEnabled: false, - _incomingEnabled: false, - _pendingOpen: false, - _pendingOffer: null, - _pendingAnswer: null, - _pendingClose: null, - _pendingCloseReason: null, - _pendingReconnect: false, - - sendOffer: function(aOffer) { - this._stateMachine.sendOffer(discriptionAsJson(aOffer)); - }, - - sendAnswer: function(aAnswer) { - this._stateMachine.sendAnswer(discriptionAsJson(aAnswer)); - }, - - sendIceCandidate: function(aCandidate) { - this._stateMachine.updateIceCandidate(aCandidate); - }, - - launch: function(aPresentationId, aUrl) { - this._stateMachine.launch(aPresentationId, aUrl); - }, - - terminate: function(aPresentationId) { - if (!this._terminatingId) { - this._terminatingId = aPresentationId; - this._stateMachine.terminate(aPresentationId); - - // Start a guard timer to ensure terminateAck is processed. - this._terminateTimer = setTimeout(() => { - DEBUG && log("TCPControlChannel - terminate timeout: " + aPresentationId); // jshint ignore:line - delete this._terminateTimer; - if (this._pendingDisconnect) { - this._pendingDisconnect(); - } else { - this.disconnect(Cr.NS_OK); - } - }, kTerminateTimeout); - } else { - this._stateMachine.terminateAck(aPresentationId); - delete this._terminatingId; - } - }, - - _flushOutgoing: function() { - if (!this._outgoingEnabled || this._outgoingMsgs.length === 0) { - return; - } - - this._output.asyncWait(this, 0, 0, Services.tm.currentThread); - }, - - // may throw an exception - _send: function(aMsg) { - DEBUG && log("TCPControlChannel - Send: " + JSON.stringify(aMsg, null, 2)); // jshint ignore:line - - /** - * XXX In TCP streaming, it is possible that more than one message in one - * TCP packet. We use line delimited JSON to identify where one JSON encoded - * object ends and the next begins. Therefore, we do not allow newline - * characters whithin the whole message, and add a newline at the end. - * Please see the parser code in |onDataAvailable|. - */ - let message = JSON.stringify(aMsg).replace(["\n"], "") + "\n"; - try { - this._output.write(message, message.length); - } catch(e) { - DEBUG && log("TCPControlChannel - Failed to send message: " + e.name); // jshint ignore:line - throw e; - } - }, - - _setSecurityObserver: function(observer) { - if (this._transport && this._transport.securityInfo) { - DEBUG && log("TCPControlChannel - setSecurityObserver: " + observer); // jshint ignore:line - let connectionInfo = this._transport.securityInfo - .QueryInterface(Ci.nsITLSServerConnectionInfo); - connectionInfo.setSecurityObserver(observer); - } - }, - - // nsITLSServerSecurityObserver - onHandshakeDone: function(socket, clientStatus) { - log("TCPControlChannel - onHandshakeDone: TLS version: " + clientStatus.tlsVersionUsed.toString(16)); - this._setSecurityObserver(null); - - // Process input/output after TLS handshake is complete. - this._outgoingEnabled = true; - this._createInputStreamPump(); - }, - - // nsIAsyncOutputStream - onOutputStreamReady: function() { - DEBUG && log("TCPControlChannel - onOutputStreamReady"); // jshint ignore:line - if (this._outgoingMsgs.length === 0) { - return; - } - - try { - this._send(this._outgoingMsgs[0]); - } catch (e) { - if (e.result === Cr.NS_BASE_STREAM_WOULD_BLOCK) { - this._output.asyncWait(this, 0, 0, Services.tm.currentThread); - return; - } - - this._closeTransport(); - return; - } - this._outgoingMsgs.shift(); - this._flushOutgoing(); - }, - - // nsIAsyncInputStream (Triggered by nsIInputStream.asyncWait) - // Only used for detecting connection refused - onInputStreamReady: function(aStream) { - DEBUG && log("TCPControlChannel - onInputStreamReady"); // jshint ignore:line - try { - aStream.available(); - } catch (e) { - DEBUG && log("TCPControlChannel - onInputStreamReady error: " + e.name); // jshint ignore:line - // NS_ERROR_CONNECTION_REFUSED - this._notifyDisconnected(e.result); - } - }, - - // nsITransportEventSink (Triggered by nsISocketTransport.setEventSink) - onTransportStatus: function(aTransport, aStatus) { - DEBUG && log("TCPControlChannel - onTransportStatus: " + aStatus.toString(16) + - " with role: " + this._direction); // jshint ignore:line - if (aStatus === Ci.nsISocketTransport.STATUS_CONNECTED_TO) { - this._outgoingEnabled = true; - this._createInputStreamPump(); - } - }, - - // nsIRequestObserver (Triggered by nsIInputStreamPump.asyncRead) - onStartRequest: function() { - DEBUG && log("TCPControlChannel - onStartRequest with role: " + - this._direction); // jshint ignore:line - this._incomingEnabled = true; - }, - - // nsIRequestObserver (Triggered by nsIInputStreamPump.asyncRead) - onStopRequest: function(aRequest, aContext, aStatus) { - DEBUG && log("TCPControlChannel - onStopRequest: " + aStatus + - " with role: " + this._direction); // jshint ignore:line - this._stateMachine.onChannelClosed(aStatus, true); - }, - - // nsIStreamListener (Triggered by nsIInputStreamPump.asyncRead) - onDataAvailable: function(aRequest, aContext, aInputStream) { - let data = NetUtil.readInputStreamToString(aInputStream, - aInputStream.available()); - DEBUG && log("TCPControlChannel - onDataAvailable: " + data); // jshint ignore:line - - // Parser of line delimited JSON. Please see |_send| for more informaiton. - let jsonArray = data.split("\n"); - jsonArray.pop(); - for (let json of jsonArray) { - let msg; - try { - msg = JSON.parse(json); - } catch (e) { - DEBUG && log("TCPSignalingChannel - error in parsing json: " + e); // jshint ignore:line - } - - this._handleMessage(msg); - } - }, - - _createInputStreamPump: function() { - if (this._pump) { - return; - } - - DEBUG && log("TCPControlChannel - create pump with role: " + - this._direction); // jshint ignore:line - this._pump = Cc["@mozilla.org/network/input-stream-pump;1"]. - createInstance(Ci.nsIInputStreamPump); - this._pump.init(this._input, -1, -1, 0, 0, false); - this._pump.asyncRead(this, null); - this._stateMachine.onChannelReady(); - }, - - // Handle command from remote side - _handleMessage: function(aMsg) { - DEBUG && log("TCPControlChannel - handleMessage from " + - JSON.stringify(this._deviceInfo) + ": " + JSON.stringify(aMsg)); // jshint ignore:line - this._stateMachine.onCommand(aMsg); - }, - - get listener() { - return this._listener; - }, - - set listener(aListener) { - DEBUG && log("TCPControlChannel - set listener: " + aListener); // jshint ignore:line - if (!aListener) { - this._listener = null; - return; - } - - this._listener = aListener; - if (this._pendingOpen) { - this._pendingOpen = false; - DEBUG && log("TCPControlChannel - notify pending opened"); // jshint ignore:line - this._listener.notifyConnected(); - } - - if (this._pendingOffer) { - let offer = this._pendingOffer; - DEBUG && log("TCPControlChannel - notify pending offer: " + - JSON.stringify(offer)); // jshint ignore:line - this._listener.onOffer(new ChannelDescription(offer)); - this._pendingOffer = null; - } - - if (this._pendingAnswer) { - let answer = this._pendingAnswer; - DEBUG && log("TCPControlChannel - notify pending answer: " + - JSON.stringify(answer)); // jshint ignore:line - this._listener.onAnswer(new ChannelDescription(answer)); - this._pendingAnswer = null; - } - - if (this._pendingClose) { - DEBUG && log("TCPControlChannel - notify pending closed"); // jshint ignore:line - this._notifyDisconnected(this._pendingCloseReason); - this._pendingClose = null; - } - - if (this._pendingReconnect) { - DEBUG && log("TCPControlChannel - notify pending reconnected"); // jshint ignore:line - this._notifyReconnected(); - this._pendingReconnect = false; - } - }, - - /** - * These functions are designed to handle the interaction with listener - * appropriately. |_FUNC| is to handle |this._listener.FUNC|. - */ - _onOffer: function(aOffer) { - if (!this._incomingEnabled) { - return; - } - if (!this._listener) { - this._pendingOffer = aOffer; - return; - } - DEBUG && log("TCPControlChannel - notify offer: " + - JSON.stringify(aOffer)); // jshint ignore:line - this._listener.onOffer(new ChannelDescription(aOffer)); - }, - - _onAnswer: function(aAnswer) { - if (!this._incomingEnabled) { - return; - } - if (!this._listener) { - this._pendingAnswer = aAnswer; - return; - } - DEBUG && log("TCPControlChannel - notify answer: " + - JSON.stringify(aAnswer)); // jshint ignore:line - this._listener.onAnswer(new ChannelDescription(aAnswer)); - }, - - _notifyConnected: function() { - this._pendingClose = false; - this._pendingCloseReason = Cr.NS_OK; - - if (!this._listener) { - this._pendingOpen = true; - return; - } - - DEBUG && log("TCPControlChannel - notify opened with role: " + - this._direction); // jshint ignore:line - this._listener.notifyConnected(); - }, - - _notifyDisconnected: function(aReason) { - this._pendingOpen = false; - this._pendingOffer = null; - this._pendingAnswer = null; - - // Remote endpoint closes the control channel with abnormal reason. - if (aReason == Cr.NS_OK && this._pendingCloseReason != Cr.NS_OK) { - aReason = this._pendingCloseReason; - } - - if (!this._listener) { - this._pendingClose = true; - this._pendingCloseReason = aReason; - return; - } - - DEBUG && log("TCPControlChannel - notify closed with role: " + - this._direction); // jshint ignore:line - this._listener.notifyDisconnected(aReason); - }, - - _notifyReconnected: function() { - if (!this._listener) { - this._pendingReconnect = true; - return; - } - - DEBUG && log("TCPControlChannel - notify reconnected with role: " + - this._direction); // jshint ignore:line - this._listener.notifyReconnected(); - }, - - _closeOutgoing: function() { - if (this._outgoingEnabled) { - this._output.close(); - this._outgoingEnabled = false; - } - }, - _closeIncoming: function() { - if (this._incomingEnabled) { - this._pump = null; - this._input.close(); - this._incomingEnabled = false; - } - }, - _closeTransport: function() { - if (this._disconnectTimer) { - clearTimeout(this._disconnectTimer); - delete this._disconnectTimer; - } - - if (this._terminateTimer) { - clearTimeout(this._terminateTimer); - delete this._terminateTimer; - } - - delete this._pendingDisconnect; - - this._transport.setEventSink(null, null); - - this._closeIncoming(); - this._closeOutgoing(); - this._presentationService.releaseControlChannel(this); - }, - - disconnect: function(aReason) { - DEBUG && log("TCPControlChannel - disconnect with reason: " + aReason); // jshint ignore:line - - // Pending disconnect during termination procedure. - if (this._terminateTimer) { - // Store only the first disconnect action. - if (!this._pendingDisconnect) { - this._pendingDisconnect = this.disconnect.bind(this, aReason); - } - return; - } - - if (this._outgoingEnabled && !this._disconnectTimer) { - // default reason is NS_OK - aReason = !aReason ? Cr.NS_OK : aReason; - - this._stateMachine.onChannelClosed(aReason, false); - - // Start a guard timer to ensure the transport will be closed. - this._disconnectTimer = setTimeout(() => { - DEBUG && log("TCPControlChannel - disconnect timeout"); // jshint ignore:line - this._closeTransport(); - }, kDisconnectTimeout); - } - }, - - reconnect: function(aPresentationId, aUrl) { - DEBUG && log("TCPControlChannel - reconnect with role: " + - this._direction); // jshint ignore:line - if (this._direction != "sender") { - return Cr.NS_ERROR_FAILURE; - } - - this._stateMachine.reconnect(aPresentationId, aUrl); - }, - - // callback from state machine - sendCommand: function(command) { - this._outgoingMsgs.push(command); - this._flushOutgoing(); - }, - - notifyDeviceConnected: function(deviceId) { - switch (this._direction) { - case "receiver": - this._deviceInfo.id = deviceId; - break; - } - this._notifyConnected(); - }, - - notifyDisconnected: function(reason) { - this._closeTransport(); - this._notifyDisconnected(reason); - }, - - notifyLaunch: function(presentationId, url) { - switch (this._direction) { - case "receiver": - this._presentationService.onSessionRequest(this._deviceInfo, - url, - presentationId, - this); - break; - } - }, - - notifyTerminate: function(presentationId) { - if (!this._terminatingId) { - this._terminatingId = presentationId; - this._presentationService.onSessionTerminate(this._deviceInfo, - presentationId, - this, - this._direction === "sender"); - return; - } - - // Cancel terminate guard timer after receiving terminate-ack. - if (this._terminateTimer) { - clearTimeout(this._terminateTimer); - delete this._terminateTimer; - } - - if (this._terminatingId !== presentationId) { - // Requested presentation Id doesn't matched with the one in ACK. - // Disconnect the control channel with error. - DEBUG && log("TCPControlChannel - unmatched terminatingId: " + presentationId); // jshint ignore:line - this.disconnect(Cr.NS_ERROR_FAILURE); - } - - delete this._terminatingId; - if (this._pendingDisconnect) { - this._pendingDisconnect(); - } - }, - - notifyReconnect: function(presentationId, url) { - switch (this._direction) { - case "receiver": - this._presentationService.onSessionReconnect(this._deviceInfo, - url, - presentationId, - this); - break; - case "sender": - this._notifyReconnected(); - break; - } - }, - - notifyOffer: function(offer) { - this._onOffer(offer); - }, - - notifyAnswer: function(answer) { - this._onAnswer(answer); - }, - - notifyIceCandidate: function(candidate) { - this._listener.onIceCandidate(candidate); - }, - - classID: Components.ID("{fefb8286-0bdc-488b-98bf-0c11b485c955}"), - QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlChannel, - Ci.nsIStreamListener]), -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PresentationControlService]); // jshint ignore:line diff --git a/dom/presentation/provider/PresentationDeviceProviderModule.cpp b/dom/presentation/provider/PresentationDeviceProviderModule.cpp deleted file mode 100644 index 9c084e7dbb..0000000000 --- a/dom/presentation/provider/PresentationDeviceProviderModule.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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 "DisplayDeviceProvider.h" -#include "MulticastDNSDeviceProvider.h" -#include "mozilla/ModuleUtils.h" - -#ifdef MOZ_WIDGET_ANDROID -#include "LegacyMDNSDeviceProvider.h" -#endif //MOZ_WIDGET_ANDROID - -#define MULTICAST_DNS_PROVIDER_CID \ - {0x814f947a, 0x52f7, 0x41c9, \ - { 0x94, 0xa1, 0x36, 0x84, 0x79, 0x72, 0x84, 0xac }} -#define DISPLAY_DEVICE_PROVIDER_CID \ - { 0x515d9879, 0xfe0b, 0x4d9f, \ - { 0x89, 0x49, 0x7f, 0xa7, 0x65, 0x6c, 0x01, 0x0e } } - -#ifdef MOZ_WIDGET_ANDROID -#define LEGACY_MDNS_PROVIDER_CID \ - { 0x6885ff39, 0xd98c, 0x4356, \ - { 0x9e, 0xb3, 0x56, 0x56, 0x31, 0x63, 0x0a, 0xf6 } } -#endif //MOZ_WIDGET_ANDROID - -#define DISPLAY_DEVICE_PROVIDER_CONTRACT_ID "@mozilla.org/presentation-device/displaydevice-provider;1" -#define MULTICAST_DNS_PROVIDER_CONTRACT_ID "@mozilla.org/presentation-device/multicastdns-provider;1" - -#ifdef MOZ_WIDGET_ANDROID -#define LEGACY_MDNS_PROVIDER_CONTRACT_ID "@mozilla.org/presentation-device/legacy-mdns-provider;1" -#endif //MOZ_WIDGET_ANDROID - -using mozilla::dom::presentation::MulticastDNSDeviceProvider; -using mozilla::dom::presentation::DisplayDeviceProvider; - -#ifdef MOZ_WIDGET_ANDROID -using mozilla::dom::presentation::legacy::LegacyMDNSDeviceProvider; -#endif //MOZ_WIDGET_ANDROID - -NS_GENERIC_FACTORY_CONSTRUCTOR(MulticastDNSDeviceProvider) -NS_DEFINE_NAMED_CID(MULTICAST_DNS_PROVIDER_CID); - -NS_GENERIC_FACTORY_CONSTRUCTOR(DisplayDeviceProvider) -NS_DEFINE_NAMED_CID(DISPLAY_DEVICE_PROVIDER_CID); - -#ifdef MOZ_WIDGET_ANDROID -NS_GENERIC_FACTORY_CONSTRUCTOR(LegacyMDNSDeviceProvider) -NS_DEFINE_NAMED_CID(LEGACY_MDNS_PROVIDER_CID); -#endif //MOZ_WIDGET_ANDROID - -static const mozilla::Module::CIDEntry kPresentationDeviceProviderCIDs[] = { - { &kMULTICAST_DNS_PROVIDER_CID, false, nullptr, MulticastDNSDeviceProviderConstructor }, - { &kDISPLAY_DEVICE_PROVIDER_CID, false, nullptr, DisplayDeviceProviderConstructor }, -#ifdef MOZ_WIDGET_ANDROID - { &kLEGACY_MDNS_PROVIDER_CID, false, nullptr, LegacyMDNSDeviceProviderConstructor }, -#endif //MOZ_WIDGET_ANDROID - { nullptr } -}; - -static const mozilla::Module::ContractIDEntry kPresentationDeviceProviderContracts[] = { - { MULTICAST_DNS_PROVIDER_CONTRACT_ID, &kMULTICAST_DNS_PROVIDER_CID }, - { DISPLAY_DEVICE_PROVIDER_CONTRACT_ID, &kDISPLAY_DEVICE_PROVIDER_CID }, -#ifdef MOZ_WIDGET_ANDROID - { LEGACY_MDNS_PROVIDER_CONTRACT_ID, &kLEGACY_MDNS_PROVIDER_CID }, -#endif //MOZ_WIDGET_ANDROID - { nullptr } -}; - -static const mozilla::Module::CategoryEntry kPresentationDeviceProviderCategories[] = { -#if defined(MOZ_WIDGET_COCOA) || defined(MOZ_WIDGET_ANDROID) - { PRESENTATION_DEVICE_PROVIDER_CATEGORY, "MulticastDNSDeviceProvider", MULTICAST_DNS_PROVIDER_CONTRACT_ID }, -#endif -#ifdef MOZ_WIDGET_ANDROID - { PRESENTATION_DEVICE_PROVIDER_CATEGORY, "LegacyMDNSDeviceProvider", LEGACY_MDNS_PROVIDER_CONTRACT_ID }, -#endif //MOZ_WIDGET_ANDROID - { nullptr } -}; - -static const mozilla::Module kPresentationDeviceProviderModule = { - mozilla::Module::kVersion, - kPresentationDeviceProviderCIDs, - kPresentationDeviceProviderContracts, - kPresentationDeviceProviderCategories -}; - -NSMODULE_DEFN(PresentationDeviceProviderModule) = &kPresentationDeviceProviderModule; diff --git a/dom/presentation/provider/ReceiverStateMachine.jsm b/dom/presentation/provider/ReceiverStateMachine.jsm deleted file mode 100644 index 23ebb5a4e2..0000000000 --- a/dom/presentation/provider/ReceiverStateMachine.jsm +++ /dev/null @@ -1,238 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -/* jshint esnext:true, globalstrict:true, moz:true, undef:true, unused:true */ -/* globals Components, dump */ - -"use strict"; - -this.EXPORTED_SYMBOLS = ["ReceiverStateMachine"]; // jshint ignore:line - -const { utils: Cu } = Components; - -/* globals State, CommandType */ -Cu.import("resource://gre/modules/presentation/StateMachineHelper.jsm"); - -const DEBUG = false; -function debug(str) { - dump("-*- ReceiverStateMachine: " + str + "\n"); -} - -var handlers = [ - function _initHandler(stateMachine, command) { - // shouldn't receive any command at init state - DEBUG && debug("unexpected command: " + JSON.stringify(command)); // jshint ignore:line - }, - function _connectingHandler(stateMachine, command) { - switch (command.type) { - case CommandType.CONNECT: - stateMachine._sendCommand({ - type: CommandType.CONNECT_ACK - }); - stateMachine.state = State.CONNECTED; - stateMachine._notifyDeviceConnected(command.deviceId); - break; - case CommandType.DISCONNECT: - stateMachine.state = State.CLOSED; - stateMachine._notifyDisconnected(command.reason); - break; - default: - debug("unexpected command: " + JSON.stringify(command)); - // ignore unexpected command - break; - } - }, - function _connectedHandler(stateMachine, command) { - switch (command.type) { - case CommandType.DISCONNECT: - stateMachine.state = State.CLOSED; - stateMachine._notifyDisconnected(command.reason); - break; - case CommandType.LAUNCH: - stateMachine._notifyLaunch(command.presentationId, - command.url); - stateMachine._sendCommand({ - type: CommandType.LAUNCH_ACK, - presentationId: command.presentationId - }); - break; - case CommandType.TERMINATE: - stateMachine._notifyTerminate(command.presentationId); - break; - case CommandType.TERMINATE_ACK: - stateMachine._notifyTerminate(command.presentationId); - break; - case CommandType.OFFER: - case CommandType.ICE_CANDIDATE: - stateMachine._notifyChannelDescriptor(command); - break; - case CommandType.RECONNECT: - stateMachine._notifyReconnect(command.presentationId, - command.url); - stateMachine._sendCommand({ - type: CommandType.RECONNECT_ACK, - presentationId: command.presentationId - }); - break; - default: - debug("unexpected command: " + JSON.stringify(command)); - // ignore unexpected command - break; - } - }, - function _closingHandler(stateMachine, command) { - switch (command.type) { - case CommandType.DISCONNECT: - stateMachine.state = State.CLOSED; - stateMachine._notifyDisconnected(command.reason); - break; - default: - debug("unexpected command: " + JSON.stringify(command)); - // ignore unexpected command - break; - } - }, - function _closedHandler(stateMachine, command) { - // ignore every command in closed state. - DEBUG && debug("unexpected command: " + JSON.stringify(command)); // jshint ignore:line - }, -]; - -function ReceiverStateMachine(channel) { - this.state = State.INIT; - this._channel = channel; -} - -ReceiverStateMachine.prototype = { - launch: function _launch() { - // presentation session can only be launched by controlling UA. - debug("receiver shouldn't trigger launch"); - }, - - terminate: function _terminate(presentationId) { - if (this.state === State.CONNECTED) { - this._sendCommand({ - type: CommandType.TERMINATE, - presentationId: presentationId, - }); - } - }, - - terminateAck: function _terminateAck(presentationId) { - if (this.state === State.CONNECTED) { - this._sendCommand({ - type: CommandType.TERMINATE_ACK, - presentationId: presentationId, - }); - } - }, - - reconnect: function _reconnect() { - debug("receiver shouldn't trigger reconnect"); - }, - - sendOffer: function _sendOffer() { - // offer can only be sent by controlling UA. - debug("receiver shouldn't generate offer"); - }, - - sendAnswer: function _sendAnswer(answer) { - if (this.state === State.CONNECTED) { - this._sendCommand({ - type: CommandType.ANSWER, - answer: answer, - }); - } - }, - - updateIceCandidate: function _updateIceCandidate(candidate) { - if (this.state === State.CONNECTED) { - this._sendCommand({ - type: CommandType.ICE_CANDIDATE, - candidate: candidate, - }); - } - }, - - onCommand: function _onCommand(command) { - handlers[this.state](this, command); - }, - - onChannelReady: function _onChannelReady() { - if (this.state === State.INIT) { - this.state = State.CONNECTING; - } - }, - - onChannelClosed: function _onChannelClose(reason, isByRemote) { - switch (this.state) { - case State.CONNECTED: - if (isByRemote) { - this.state = State.CLOSED; - this._notifyDisconnected(reason); - } else { - this._sendCommand({ - type: CommandType.DISCONNECT, - reason: reason - }); - this.state = State.CLOSING; - this._closeReason = reason; - } - break; - case State.CLOSING: - if (isByRemote) { - this.state = State.CLOSED; - if (this._closeReason) { - reason = this._closeReason; - delete this._closeReason; - } - this._notifyDisconnected(reason); - } else { - // do nothing and wait for remote channel closed. - } - break; - default: - DEBUG && debug("unexpected channel close: " + reason + ", " + isByRemote); // jshint ignore:line - break; - } - }, - - _sendCommand: function _sendCommand(command) { - this._channel.sendCommand(command); - }, - - _notifyDeviceConnected: function _notifyDeviceConnected(deviceName) { - this._channel.notifyDeviceConnected(deviceName); - }, - - _notifyDisconnected: function _notifyDisconnected(reason) { - this._channel.notifyDisconnected(reason); - }, - - _notifyLaunch: function _notifyLaunch(presentationId, url) { - this._channel.notifyLaunch(presentationId, url); - }, - - _notifyTerminate: function _notifyTerminate(presentationId) { - this._channel.notifyTerminate(presentationId); - }, - - _notifyReconnect: function _notifyReconnect(presentationId, url) { - this._channel.notifyReconnect(presentationId, url); - }, - - _notifyChannelDescriptor: function _notifyChannelDescriptor(command) { - switch (command.type) { - case CommandType.OFFER: - this._channel.notifyOffer(command.offer); - break; - case CommandType.ICE_CANDIDATE: - this._channel.notifyIceCandidate(command.candidate); - break; - } - }, -}; - -this.ReceiverStateMachine = ReceiverStateMachine; // jshint ignore:line diff --git a/dom/presentation/provider/StateMachineHelper.jsm b/dom/presentation/provider/StateMachineHelper.jsm deleted file mode 100644 index 6e07863d41..0000000000 --- a/dom/presentation/provider/StateMachineHelper.jsm +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -/* jshint esnext:true, globalstrict:true, moz:true, undef:true, unused:true */ - -"use strict"; - -this.EXPORTED_SYMBOLS = ["State", "CommandType"]; // jshint ignore:line - -const State = Object.freeze({ - INIT: 0, - CONNECTING: 1, - CONNECTED: 2, - CLOSING: 3, - CLOSED: 4, -}); - -const CommandType = Object.freeze({ - // control channel life cycle - CONNECT: "connect", // { deviceId: } - CONNECT_ACK: "connect-ack", // { presentationId: } - DISCONNECT: "disconnect", // { reason: } - // presentation session life cycle - LAUNCH: "launch", // { presentationId: , url: } - LAUNCH_ACK: "launch-ack", // { presentationId: } - TERMINATE: "terminate", // { presentationId: } - TERMINATE_ACK: "terminate-ack", // { presentationId: } - RECONNECT: "reconnect", // { presentationId: } - RECONNECT_ACK: "reconnect-ack", // { presentationId: } - // session transport establishment - OFFER: "offer", // { offer: } - ANSWER: "answer", // { answer: } - ICE_CANDIDATE: "ice-candidate", // { candidate: } -}); - -this.State = State; // jshint ignore:line -this.CommandType = CommandType; // jshint ignore:line diff --git a/dom/presentation/provider/moz.build b/dom/presentation/provider/moz.build deleted file mode 100644 index 18428b50ed..0000000000 --- a/dom/presentation/provider/moz.build +++ /dev/null @@ -1,40 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -EXTRA_COMPONENTS += [ - 'BuiltinProviders.manifest', - 'PresentationControlService.js' -] - -UNIFIED_SOURCES += [ - 'DeviceProviderHelpers.cpp', - 'DisplayDeviceProvider.cpp', - 'MulticastDNSDeviceProvider.cpp', - 'PresentationDeviceProviderModule.cpp', -] - -EXTRA_JS_MODULES.presentation += [ - 'ControllerStateMachine.jsm', - 'ReceiverStateMachine.jsm', - 'StateMachineHelper.jsm', -] - -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android': - EXTRA_COMPONENTS += [ - # For android presentation device - 'AndroidCastDeviceProvider.js', - 'AndroidCastDeviceProvider.manifest', - # for TV 2.5 device backward capability - 'LegacyPresentationControlService.js', - 'LegacyProviders.manifest', - ] - - UNIFIED_SOURCES += [ - 'LegacyMDNSDeviceProvider.cpp', - ] - -include('/ipc/chromium/chromium-config.mozbuild') -FINAL_LIBRARY = 'xul' diff --git a/dom/presentation/provider/nsTCPDeviceInfo.h b/dom/presentation/provider/nsTCPDeviceInfo.h deleted file mode 100644 index 118f6c8ac2..0000000000 --- a/dom/presentation/provider/nsTCPDeviceInfo.h +++ /dev/null @@ -1,77 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef __TCPDeviceInfo_h__ -#define __TCPDeviceInfo_h__ - -namespace mozilla { -namespace dom { -namespace presentation { - -class TCPDeviceInfo final : public nsITCPDeviceInfo -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSITCPDEVICEINFO - - explicit TCPDeviceInfo(const nsACString& aId, - const nsACString& aAddress, - const uint16_t aPort, - const nsACString& aCertFingerprint) - : mId(aId) - , mAddress(aAddress) - , mPort(aPort) - , mCertFingerprint(aCertFingerprint) - { - } - -private: - virtual ~TCPDeviceInfo() {} - - nsCString mId; - nsCString mAddress; - uint16_t mPort; - nsCString mCertFingerprint; -}; - -NS_IMPL_ISUPPORTS(TCPDeviceInfo, - nsITCPDeviceInfo) - -// nsITCPDeviceInfo -NS_IMETHODIMP -TCPDeviceInfo::GetId(nsACString& aId) -{ - aId = mId; - return NS_OK; -} - -NS_IMETHODIMP -TCPDeviceInfo::GetAddress(nsACString& aAddress) -{ - aAddress = mAddress; - return NS_OK; -} - -NS_IMETHODIMP -TCPDeviceInfo::GetPort(uint16_t* aPort) -{ - *aPort = mPort; - return NS_OK; -} - -NS_IMETHODIMP -TCPDeviceInfo::GetCertFingerprint(nsACString& aCertFingerprint) -{ - aCertFingerprint = mCertFingerprint; - return NS_OK; -} - -} // namespace presentation -} // namespace dom -} // namespace mozilla - -#endif /* !__TCPDeviceInfo_h__ */ - diff --git a/dom/presentation/tests/mochitest/PresentationDeviceInfoChromeScript.js b/dom/presentation/tests/mochitest/PresentationDeviceInfoChromeScript.js deleted file mode 100644 index 2bc069f6b2..0000000000 --- a/dom/presentation/tests/mochitest/PresentationDeviceInfoChromeScript.js +++ /dev/null @@ -1,150 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -'use strict'; - -const { classes: Cc, interfaces: Ci, utils: Cu } = Components; - -Cu.import('resource://gre/modules/PresentationDeviceInfoManager.jsm'); - -const { XPCOMUtils } = Cu.import('resource://gre/modules/XPCOMUtils.jsm'); - -const manager = Cc['@mozilla.org/presentation-device/manager;1'] - .getService(Ci.nsIPresentationDeviceManager); - -var testProvider = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDeviceProvider]), - forceDiscovery: function() { - sendAsyncMessage('force-discovery'); - }, - listener: null, -}; - -var testDevice = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDevice]), - establishControlChannel: function() { - return null; - }, - disconnect: function() {}, - isRequestedUrlSupported: function(requestedUrl) { - return true; - }, - id: null, - name: null, - type: null, - listener: null, -}; - -var testDevice1 = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDevice]), - id: 'dummyid', - name: 'dummyName', - type: 'dummyType', - establishControlChannel: function(url, presentationId) { - return null; - }, - disconnect: function() {}, - isRequestedUrlSupported: function(requestedUrl) { - return true; - }, -}; - -var testDevice2 = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDevice]), - id: 'dummyid', - name: 'dummyName', - type: 'dummyType', - establishControlChannel: function(url, presentationId) { - return null; - }, - disconnect: function() {}, - isRequestedUrlSupported: function(requestedUrl) { - return true; - }, -}; - -var mockedDeviceWithoutSupportedURL = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDevice]), - id: 'dummyid', - name: 'dummyName', - type: 'dummyType', - establishControlChannel: function(url, presentationId) { - return null; - }, - disconnect: function() {}, - isRequestedUrlSupported: function(requestedUrl) { - return false; - }, -}; - -var mockedDeviceSupportHttpsURL = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDevice]), - id: 'dummyid', - name: 'dummyName', - type: 'dummyType', - establishControlChannel: function(url, presentationId) { - return null; - }, - disconnect: function() {}, - isRequestedUrlSupported: function(requestedUrl) { - if (requestedUrl.indexOf("https://") != -1) { - return true; - } - return false; - }, -}; - -addMessageListener('setup', function() { - manager.addDeviceProvider(testProvider); - - sendAsyncMessage('setup-complete'); -}); - -addMessageListener('trigger-device-add', function(device) { - testDevice.id = device.id; - testDevice.name = device.name; - testDevice.type = device.type; - manager.addDevice(testDevice); -}); - -addMessageListener('trigger-add-unsupport-url-device', function() { - manager.addDevice(mockedDeviceWithoutSupportedURL); -}); - -addMessageListener('trigger-add-multiple-devices', function() { - manager.addDevice(testDevice1); - manager.addDevice(testDevice2); -}); - -addMessageListener('trigger-add-https-devices', function() { - manager.addDevice(mockedDeviceSupportHttpsURL); -}); - - -addMessageListener('trigger-device-update', function(device) { - testDevice.id = device.id; - testDevice.name = device.name; - testDevice.type = device.type; - manager.updateDevice(testDevice); -}); - -addMessageListener('trigger-device-remove', function() { - manager.removeDevice(testDevice); -}); - -addMessageListener('trigger-remove-unsupported-device', function() { - manager.removeDevice(mockedDeviceWithoutSupportedURL); -}); - -addMessageListener('trigger-remove-multiple-devices', function() { - manager.removeDevice(testDevice1); - manager.removeDevice(testDevice2); -}); - -addMessageListener('trigger-remove-https-devices', function() { - manager.removeDevice(mockedDeviceSupportHttpsURL); -}); - -addMessageListener('teardown', function() { - manager.removeDeviceProvider(testProvider); -}); diff --git a/dom/presentation/tests/mochitest/PresentationSessionChromeScript.js b/dom/presentation/tests/mochitest/PresentationSessionChromeScript.js deleted file mode 100644 index 3052bdcb10..0000000000 --- a/dom/presentation/tests/mochitest/PresentationSessionChromeScript.js +++ /dev/null @@ -1,470 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -'use strict'; - -const { classes: Cc, interfaces: Ci, manager: Cm, utils: Cu, results: Cr } = Components; - -Cu.import('resource://gre/modules/XPCOMUtils.jsm'); -Cu.import('resource://gre/modules/Services.jsm'); -Cu.import('resource://gre/modules/Timer.jsm'); - -const uuidGenerator = Cc["@mozilla.org/uuid-generator;1"] - .getService(Ci.nsIUUIDGenerator); - -function registerMockedFactory(contractId, mockedClassId, mockedFactory) { - var originalClassId, originalFactory; - - var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar); - if (!registrar.isCIDRegistered(mockedClassId)) { - try { - originalClassId = registrar.contractIDToCID(contractId); - originalFactory = Cm.getClassObject(Cc[contractId], Ci.nsIFactory); - } catch (ex) { - originalClassId = ""; - originalFactory = null; - } - if (originalFactory) { - registrar.unregisterFactory(originalClassId, originalFactory); - } - registrar.registerFactory(mockedClassId, "", contractId, mockedFactory); - } - - return { contractId: contractId, - mockedClassId: mockedClassId, - mockedFactory: mockedFactory, - originalClassId: originalClassId, - originalFactory: originalFactory }; -} - -function registerOriginalFactory(contractId, mockedClassId, mockedFactory, originalClassId, originalFactory) { - if (originalFactory) { - var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar); - registrar.unregisterFactory(mockedClassId, mockedFactory); - registrar.registerFactory(originalClassId, "", contractId, originalFactory); - } -} - -var sessionId = 'test-session-id-' + uuidGenerator.generateUUID().toString(); - -const address = Cc["@mozilla.org/supports-cstring;1"] - .createInstance(Ci.nsISupportsCString); -address.data = "127.0.0.1"; -const addresses = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray); -addresses.appendElement(address, false); - -const mockedChannelDescription = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationChannelDescription]), - get type() { - if (Services.prefs.getBoolPref("dom.presentation.session_transport.data_channel.enable")) { - return Ci.nsIPresentationChannelDescription.TYPE_DATACHANNEL; - } - return Ci.nsIPresentationChannelDescription.TYPE_TCP; - }, - tcpAddress: addresses, - tcpPort: 1234, -}; - -const mockedServerSocket = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIServerSocket, - Ci.nsIFactory]), - createInstance: function(aOuter, aIID) { - if (aOuter) { - throw Components.results.NS_ERROR_NO_AGGREGATION; - } - return this.QueryInterface(aIID); - }, - get port() { - return this._port; - }, - set listener(listener) { - this._listener = listener; - }, - init: function(port, loopbackOnly, backLog) { - if (port != -1) { - this._port = port; - } else { - this._port = 5678; - } - }, - asyncListen: function(listener) { - this._listener = listener; - }, - close: function() { - this._listener.onStopListening(this, Cr.NS_BINDING_ABORTED); - }, - simulateOnSocketAccepted: function(serverSocket, socketTransport) { - this._listener.onSocketAccepted(serverSocket, socketTransport); - } -}; - -const mockedSocketTransport = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsISocketTransport]), -}; - -const mockedControlChannel = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlChannel]), - set listener(listener) { - this._listener = listener; - }, - get listener() { - return this._listener; - }, - sendOffer: function(offer) { - sendAsyncMessage('offer-sent', this._isValidSDP(offer)); - }, - sendAnswer: function(answer) { - sendAsyncMessage('answer-sent', this._isValidSDP(answer)); - - if (answer.type == Ci.nsIPresentationChannelDescription.TYPE_TCP) { - this._listener.QueryInterface(Ci.nsIPresentationSessionTransportCallback).notifyTransportReady(); - } - }, - _isValidSDP: function(aSDP) { - var isValid = false; - if (aSDP.type == Ci.nsIPresentationChannelDescription.TYPE_TCP) { - try { - var addresses = aSDP.tcpAddress; - if (addresses.length > 0) { - for (var i = 0; i < addresses.length; i++) { - // Ensure CString addresses are used. Otherwise, an error will be thrown. - addresses.queryElementAt(i, Ci.nsISupportsCString); - } - - isValid = true; - } - } catch (e) { - isValid = false; - } - } else if (aSDP.type == Ci.nsIPresentationChannelDescription.TYPE_DATACHANNEL) { - isValid = (aSDP.dataChannelSDP == "test-sdp"); - } - return isValid; - }, - launch: function(presentationId, url) { - sessionId = presentationId; - }, - terminate: function(presentationId) { - sendAsyncMessage('sender-terminate', presentationId); - }, - reconnect: function(presentationId, url) { - sendAsyncMessage('start-reconnect', url); - }, - notifyReconnected: function() { - this._listener - .QueryInterface(Ci.nsIPresentationControlChannelListener) - .notifyReconnected(); - }, - disconnect: function(reason) { - sendAsyncMessage('control-channel-closed', reason); - this._listener.QueryInterface(Ci.nsIPresentationControlChannelListener).notifyDisconnected(reason); - }, - simulateReceiverReady: function() { - this._listener.QueryInterface(Ci.nsIPresentationControlChannelListener).notifyReceiverReady(); - }, - simulateOnOffer: function() { - sendAsyncMessage('offer-received'); - this._listener.QueryInterface(Ci.nsIPresentationControlChannelListener).onOffer(mockedChannelDescription); - }, - simulateOnAnswer: function() { - sendAsyncMessage('answer-received'); - this._listener.QueryInterface(Ci.nsIPresentationControlChannelListener).onAnswer(mockedChannelDescription); - }, - simulateNotifyConnected: function() { - sendAsyncMessage('control-channel-opened'); - this._listener.QueryInterface(Ci.nsIPresentationControlChannelListener).notifyConnected(); - }, -}; - -const mockedDevice = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDevice]), - id: 'id', - name: 'name', - type: 'type', - establishControlChannel: function(url, presentationId) { - sendAsyncMessage('control-channel-established'); - return mockedControlChannel; - }, - disconnect: function() {}, - isRequestedUrlSupported: function(requestedUrl) { - return true; - }, -}; - -const mockedDevicePrompt = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDevicePrompt, - Ci.nsIFactory]), - createInstance: function(aOuter, aIID) { - if (aOuter) { - throw Components.results.NS_ERROR_NO_AGGREGATION; - } - return this.QueryInterface(aIID); - }, - set request(request) { - this._request = request; - }, - get request() { - return this._request; - }, - promptDeviceSelection: function(request) { - this._request = request; - sendAsyncMessage('device-prompt'); - }, - simulateSelect: function() { - this._request.select(mockedDevice); - }, - simulateCancel: function(result) { - this._request.cancel(result); - } -}; - -const mockedSessionTransport = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationSessionTransport, - Ci.nsIPresentationSessionTransportBuilder, - Ci.nsIPresentationTCPSessionTransportBuilder, - Ci.nsIPresentationDataChannelSessionTransportBuilder, - Ci.nsIPresentationControlChannelListener, - Ci.nsIFactory]), - createInstance: function(aOuter, aIID) { - if (aOuter) { - throw Components.results.NS_ERROR_NO_AGGREGATION; - } - return this.QueryInterface(aIID); - }, - set callback(callback) { - this._callback = callback; - }, - get callback() { - return this._callback; - }, - get selfAddress() { - return this._selfAddress; - }, - buildTCPSenderTransport: function(transport, listener) { - this._listener = listener; - this._role = Ci.nsIPresentationService.ROLE_CONTROLLER; - this._listener.onSessionTransport(this); - this._listener = null; - sendAsyncMessage('data-transport-initialized'); - - setTimeout(()=>{ - this.simulateTransportReady(); - }, 0); - }, - buildTCPReceiverTransport: function(description, listener) { - this._listener = listener; - this._role = Ci.nsIPresentationService.ROLE_RECEIVER; - - var addresses = description.QueryInterface(Ci.nsIPresentationChannelDescription).tcpAddress; - this._selfAddress = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsINetAddr]), - address: (addresses.length > 0) ? - addresses.queryElementAt(0, Ci.nsISupportsCString).data : "", - port: description.QueryInterface(Ci.nsIPresentationChannelDescription).tcpPort, - }; - - setTimeout(()=>{ - this._listener.onSessionTransport(this); - this._listener = null; - }, 0); - }, - // in-process case - buildDataChannelTransport: function(role, window, listener) { - this._listener = listener; - this._role = role; - - var hasNavigator = window ? (typeof window.navigator != "undefined") : false; - sendAsyncMessage('check-navigator', hasNavigator); - - setTimeout(()=>{ - this._listener.onSessionTransport(this); - this._listener = null; - this.simulateTransportReady(); - }, 0); - }, - enableDataNotification: function() { - sendAsyncMessage('data-transport-notification-enabled'); - }, - send: function(data) { - sendAsyncMessage('message-sent', data); - }, - close: function(reason) { - sendAsyncMessage('data-transport-closed', reason); - this._callback.QueryInterface(Ci.nsIPresentationSessionTransportCallback).notifyTransportClosed(reason); - }, - simulateTransportReady: function() { - this._callback.QueryInterface(Ci.nsIPresentationSessionTransportCallback).notifyTransportReady(); - }, - simulateIncomingMessage: function(message) { - this._callback.QueryInterface(Ci.nsIPresentationSessionTransportCallback).notifyData(message, false); - }, - onOffer: function(aOffer) { - }, - onAnswer: function(aAnswer) { - } -}; - -const mockedNetworkInfo = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkInfo]), - getAddresses: function(ips, prefixLengths) { - ips.value = ["127.0.0.1"]; - prefixLengths.value = [0]; - return 1; - }, -}; - -const mockedNetworkManager = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkManager, - Ci.nsIFactory]), - createInstance: function(aOuter, aIID) { - if (aOuter) { - throw Components.results.NS_ERROR_NO_AGGREGATION; - } - return this.QueryInterface(aIID); - }, - get activeNetworkInfo() { - return mockedNetworkInfo; - }, -}; - -var requestPromise = null; - -const mockedRequestUIGlue = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationRequestUIGlue, - Ci.nsIFactory]), - createInstance: function(aOuter, aIID) { - if (aOuter) { - throw Components.results.NS_ERROR_NO_AGGREGATION; - } - return this.QueryInterface(aIID); - }, - sendRequest: function(aUrl, aSessionId) { - sendAsyncMessage('receiver-launching', aSessionId); - return requestPromise; - }, -}; - -// Register mocked factories. -const originalFactoryData = []; -originalFactoryData.push(registerMockedFactory("@mozilla.org/presentation-device/prompt;1", - uuidGenerator.generateUUID(), - mockedDevicePrompt)); -originalFactoryData.push(registerMockedFactory("@mozilla.org/network/server-socket;1", - uuidGenerator.generateUUID(), - mockedServerSocket)); -originalFactoryData.push(registerMockedFactory("@mozilla.org/presentation/presentationtcpsessiontransport;1", - uuidGenerator.generateUUID(), - mockedSessionTransport)); -originalFactoryData.push(registerMockedFactory("@mozilla.org/presentation/datachanneltransportbuilder;1", - uuidGenerator.generateUUID(), - mockedSessionTransport)); -originalFactoryData.push(registerMockedFactory("@mozilla.org/network/manager;1", - uuidGenerator.generateUUID(), - mockedNetworkManager)); -originalFactoryData.push(registerMockedFactory("@mozilla.org/presentation/requestuiglue;1", - uuidGenerator.generateUUID(), - mockedRequestUIGlue)); - -function tearDown() { - requestPromise = null; - mockedServerSocket.listener = null; - mockedControlChannel.listener = null; - mockedDevice.listener = null; - mockedDevicePrompt.request = null; - mockedSessionTransport.callback = null; - - var deviceManager = Cc['@mozilla.org/presentation-device/manager;1'] - .getService(Ci.nsIPresentationDeviceManager); - deviceManager.QueryInterface(Ci.nsIPresentationDeviceListener).removeDevice(mockedDevice); - - // Register original factories. - for (var data of originalFactoryData) { - registerOriginalFactory(data.contractId, data.mockedClassId, - data.mockedFactory, data.originalClassId, - data.originalFactory); - } - - sendAsyncMessage('teardown-complete'); -} - -addMessageListener('trigger-device-add', function() { - var deviceManager = Cc['@mozilla.org/presentation-device/manager;1'] - .getService(Ci.nsIPresentationDeviceManager); - deviceManager.QueryInterface(Ci.nsIPresentationDeviceListener).addDevice(mockedDevice); -}); - -addMessageListener('trigger-device-prompt-select', function() { - mockedDevicePrompt.simulateSelect(); -}); - -addMessageListener('trigger-device-prompt-cancel', function(result) { - mockedDevicePrompt.simulateCancel(result); -}); - -addMessageListener('trigger-incoming-session-request', function(url) { - var deviceManager = Cc['@mozilla.org/presentation-device/manager;1'] - .getService(Ci.nsIPresentationDeviceManager); - deviceManager.QueryInterface(Ci.nsIPresentationDeviceListener) - .onSessionRequest(mockedDevice, url, sessionId, mockedControlChannel); -}); - -addMessageListener('trigger-incoming-terminate-request', function() { - var deviceManager = Cc['@mozilla.org/presentation-device/manager;1'] - .getService(Ci.nsIPresentationDeviceManager); - deviceManager.QueryInterface(Ci.nsIPresentationDeviceListener) - .onTerminateRequest(mockedDevice, sessionId, mockedControlChannel, true); -}); - -addMessageListener('trigger-reconnected-acked', function(url) { - mockedControlChannel.notifyReconnected(); -}); - -addMessageListener('trigger-incoming-offer', function() { - mockedControlChannel.simulateOnOffer(); -}); - -addMessageListener('trigger-incoming-answer', function() { - mockedControlChannel.simulateOnAnswer(); -}); - -addMessageListener('trigger-incoming-transport', function() { - mockedServerSocket.simulateOnSocketAccepted(mockedServerSocket, mockedSocketTransport); -}); - -addMessageListener('trigger-control-channel-open', function(reason) { - mockedControlChannel.simulateNotifyConnected(); -}); - -addMessageListener('trigger-control-channel-close', function(reason) { - mockedControlChannel.disconnect(reason); -}); - -addMessageListener('trigger-data-transport-close', function(reason) { - mockedSessionTransport.close(reason); -}); - -addMessageListener('trigger-incoming-message', function(message) { - mockedSessionTransport.simulateIncomingMessage(message); -}); - -addMessageListener('teardown', function() { - tearDown(); -}); - -var controlChannelListener; -addMessageListener('save-control-channel-listener', function() { - controlChannelListener = mockedControlChannel.listener; -}); - -addMessageListener('restore-control-channel-listener', function(message) { - mockedControlChannel.listener = controlChannelListener; - controlChannelListener = null; -}); - -var obs = Cc["@mozilla.org/observer-service;1"] - .getService(Ci.nsIObserverService); -obs.addObserver(function observer(aSubject, aTopic, aData) { - obs.removeObserver(observer, aTopic); - - requestPromise = aSubject; -}, 'setup-request-promise', false); diff --git a/dom/presentation/tests/mochitest/PresentationSessionChromeScript1UA.js b/dom/presentation/tests/mochitest/PresentationSessionChromeScript1UA.js deleted file mode 100644 index 82d7362b29..0000000000 --- a/dom/presentation/tests/mochitest/PresentationSessionChromeScript1UA.js +++ /dev/null @@ -1,366 +0,0 @@ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, -* You can obtain one at http://mozilla.org/MPL/2.0/. */ - -'use strict'; - -const { classes: Cc, interfaces: Ci, manager: Cm, utils: Cu, results: Cr } = Components; - -Cu.import('resource://gre/modules/XPCOMUtils.jsm'); -Cu.import('resource://gre/modules/Services.jsm'); - -const uuidGenerator = Cc["@mozilla.org/uuid-generator;1"] - .getService(Ci.nsIUUIDGenerator); - -function debug(str) { - // dump('DEBUG -*- PresentationSessionChromeScript1UA -*-: ' + str + '\n'); -} - -const originalFactoryData = []; -var sessionId; // Store the uuid generated by PresentationRequest. -var triggerControlChannelError = false; // For simulating error during control channel establishment. - -// control channel of sender -const mockControlChannelOfSender = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlChannel]), - set listener(listener) { - // PresentationControllingInfo::SetControlChannel - if (listener) { - debug('set listener for mockControlChannelOfSender without null'); - } else { - debug('set listener for mockControlChannelOfSender with null'); - } - this._listener = listener; - }, - get listener() { - return this._listener; - }, - notifyConnected: function() { - // send offer after notifyConnected immediately - this._listener - .QueryInterface(Ci.nsIPresentationControlChannelListener) - .notifyConnected(); - }, - notifyReconnected: function() { - // send offer after notifyOpened immediately - this._listener - .QueryInterface(Ci.nsIPresentationControlChannelListener) - .notifyReconnected(); - }, - sendOffer: function(offer) { - Services.tm.mainThread.dispatch(() => { - mockControlChannelOfReceiver.onOffer(offer); - }, Ci.nsIThread.DISPATCH_NORMAL); - }, - onAnswer: function(answer) { - this._listener - .QueryInterface(Ci.nsIPresentationControlChannelListener) - .onAnswer(answer); - }, - launch: function(presentationId, url) { - sessionId = presentationId; - sendAsyncMessage('sender-launch', url); - }, - disconnect: function(reason) { - if (!this._listener) { - return; - } - this._listener - .QueryInterface(Ci.nsIPresentationControlChannelListener) - .notifyDisconnected(reason); - mockControlChannelOfReceiver.disconnect(); - }, - terminate: function(presentationId) { - sendAsyncMessage('sender-terminate'); - }, - reconnect: function(presentationId, url) { - sendAsyncMessage('start-reconnect', url); - }, - sendIceCandidate: function(candidate) { - mockControlChannelOfReceiver.notifyIceCandidate(candidate); - }, - notifyIceCandidate: function(candidate) { - if (!this._listener) { - return; - } - - this._listener - .QueryInterface(Ci.nsIPresentationControlChannelListener) - .onIceCandidate(candidate); - }, -}; - -// control channel of receiver -const mockControlChannelOfReceiver = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlChannel]), - set listener(listener) { - // PresentationPresentingInfo::SetControlChannel - if (listener) { - debug('set listener for mockControlChannelOfReceiver without null'); - } else { - debug('set listener for mockControlChannelOfReceiver with null'); - } - this._listener = listener; - - if (this._pendingOpened) { - this._pendingOpened = false; - this.notifyConnected(); - } - }, - get listener() { - return this._listener; - }, - notifyConnected: function() { - // do nothing - if (!this._listener) { - this._pendingOpened = true; - return; - } - this._listener - .QueryInterface(Ci.nsIPresentationControlChannelListener) - .notifyConnected(); - }, - onOffer: function(offer) { - this._listener - .QueryInterface(Ci.nsIPresentationControlChannelListener) - .onOffer(offer); - }, - sendAnswer: function(answer) { - Services.tm.mainThread.dispatch(() => { - mockControlChannelOfSender.onAnswer(answer); - }, Ci.nsIThread.DISPATCH_NORMAL); - }, - disconnect: function(reason) { - if (!this._listener) { - return; - } - - this._listener - .QueryInterface(Ci.nsIPresentationControlChannelListener) - .notifyDisconnected(reason); - sendAsyncMessage('control-channel-receiver-closed', reason); - }, - terminate: function(presentaionId) { - }, - sendIceCandidate: function(candidate) { - mockControlChannelOfReceiver.notifyIceCandidate(candidate); - }, - notifyIceCandidate: function(candidate) { - if (!this._listener) { - return; - } - - this._listener - .QueryInterface(Ci.nsIPresentationControlChannelListener) - .onIceCandidate(candidate); - }, -}; - -const mockDevice = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDevice]), - id: 'id', - name: 'name', - type: 'type', - establishControlChannel: function(url, presentationId) { - if (triggerControlChannelError) { - throw Cr.NS_ERROR_FAILURE; - } - sendAsyncMessage('control-channel-established'); - return mockControlChannelOfSender; - }, - disconnect: function() { - sendAsyncMessage('device-disconnected'); - }, - isRequestedUrlSupported: function(requestedUrl) { - return true; - }, -}; - -const mockDevicePrompt = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDevicePrompt, - Ci.nsIFactory]), - createInstance: function(aOuter, aIID) { - if (aOuter) { - throw Components.results.NS_ERROR_NO_AGGREGATION; - } - return this.QueryInterface(aIID); - }, - set request(request) { - this._request = request; - }, - get request() { - return this._request; - }, - promptDeviceSelection: function(request) { - this._request = request; - sendAsyncMessage('device-prompt'); - }, - simulateSelect: function() { - this._request.select(mockDevice); - }, - simulateCancel: function() { - this._request.cancel(); - } -}; - -const mockRequestUIGlue = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationRequestUIGlue, - Ci.nsIFactory]), - set promise(aPromise) { - this._promise = aPromise - }, - get promise() { - return this._promise; - }, - createInstance: function(aOuter, aIID) { - if (aOuter) { - throw Components.results.NS_ERROR_NO_AGGREGATION; - } - return this.QueryInterface(aIID); - }, - sendRequest: function(aUrl, aSessionId) { - return this.promise; - }, -}; - -function initMockAndListener() { - - function registerMockFactory(contractId, mockClassId, mockFactory) { - var originalClassId, originalFactory; - - var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar); - if (!registrar.isCIDRegistered(mockClassId)) { - try { - originalClassId = registrar.contractIDToCID(contractId); - originalFactory = Cm.getClassObject(Cc[contractId], Ci.nsIFactory); - } catch (ex) { - originalClassId = ""; - originalFactory = null; - } - if (originalFactory) { - registrar.unregisterFactory(originalClassId, originalFactory); - } - registrar.registerFactory(mockClassId, "", contractId, mockFactory); - } - - return { contractId: contractId, - mockClassId: mockClassId, - mockFactory: mockFactory, - originalClassId: originalClassId, - originalFactory: originalFactory }; - } - // Register mock factories. - const uuidGenerator = Cc["@mozilla.org/uuid-generator;1"] - .getService(Ci.nsIUUIDGenerator); - originalFactoryData.push(registerMockFactory("@mozilla.org/presentation-device/prompt;1", - uuidGenerator.generateUUID(), - mockDevicePrompt)); - originalFactoryData.push(registerMockFactory("@mozilla.org/presentation/requestuiglue;1", - uuidGenerator.generateUUID(), - mockRequestUIGlue)); - - addMessageListener('trigger-device-add', function() { - debug('Got message: trigger-device-add'); - var deviceManager = Cc['@mozilla.org/presentation-device/manager;1'] - .getService(Ci.nsIPresentationDeviceManager); - deviceManager.QueryInterface(Ci.nsIPresentationDeviceListener) - .addDevice(mockDevice); - }); - - addMessageListener('trigger-device-prompt-select', function() { - debug('Got message: trigger-device-prompt-select'); - mockDevicePrompt.simulateSelect(); - }); - - addMessageListener('trigger-on-session-request', function(url) { - debug('Got message: trigger-on-session-request'); - var deviceManager = Cc['@mozilla.org/presentation-device/manager;1'] - .getService(Ci.nsIPresentationDeviceManager); - deviceManager.QueryInterface(Ci.nsIPresentationDeviceListener) - .onSessionRequest(mockDevice, - url, - sessionId, - mockControlChannelOfReceiver); - }); - - addMessageListener('trigger-on-terminate-request', function() { - debug('Got message: trigger-on-terminate-request'); - var deviceManager = Cc['@mozilla.org/presentation-device/manager;1'] - .getService(Ci.nsIPresentationDeviceManager); - deviceManager.QueryInterface(Ci.nsIPresentationDeviceListener) - .onTerminateRequest(mockDevice, - sessionId, - mockControlChannelOfReceiver, - false); - }); - - addMessageListener('trigger-control-channel-open', function(reason) { - debug('Got message: trigger-control-channel-open'); - mockControlChannelOfSender.notifyConnected(); - mockControlChannelOfReceiver.notifyConnected(); - }); - - addMessageListener('trigger-control-channel-error', function(reason) { - debug('Got message: trigger-control-channel-open'); - triggerControlChannelError = true; - }); - - addMessageListener('trigger-reconnected-acked', function(url) { - debug('Got message: trigger-reconnected-acked'); - mockControlChannelOfSender.notifyReconnected(); - var deviceManager = Cc['@mozilla.org/presentation-device/manager;1'] - .getService(Ci.nsIPresentationDeviceManager); - deviceManager.QueryInterface(Ci.nsIPresentationDeviceListener) - .onReconnectRequest(mockDevice, - url, - sessionId, - mockControlChannelOfReceiver); - }); - - // Used to call sendAsyncMessage in chrome script from receiver. - addMessageListener('forward-command', function(command_data) { - let command = JSON.parse(command_data); - sendAsyncMessage(command.name, command.data); - }); - - addMessageListener('teardown', teardown); - - var obs = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService); - obs.addObserver(function setupRequestPromiseHandler(aSubject, aTopic, aData) { - debug('Got observer: setup-request-promise'); - obs.removeObserver(setupRequestPromiseHandler, aTopic); - mockRequestUIGlue.promise = aSubject; - sendAsyncMessage('promise-setup-ready'); - }, 'setup-request-promise', false); -} - -function teardown() { - - function registerOriginalFactory(contractId, mockedClassId, mockedFactory, originalClassId, originalFactory) { - if (originalFactory) { - var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar); - registrar.unregisterFactory(mockedClassId, mockedFactory); - registrar.registerFactory(originalClassId, "", contractId, originalFactory); - } - } - - mockRequestUIGlue.promise = null; - mockControlChannelOfSender.listener = null; - mockControlChannelOfReceiver.listener = null; - mockDevicePrompt.request = null; - - var deviceManager = Cc['@mozilla.org/presentation-device/manager;1'] - .getService(Ci.nsIPresentationDeviceManager); - deviceManager.QueryInterface(Ci.nsIPresentationDeviceListener) - .removeDevice(mockDevice); - // Register original factories. - for (var data of originalFactoryData) { - registerOriginalFactory(data.contractId, data.mockClassId, - data.mockFactory, data.originalClassId, - data.originalFactory); - } - sendAsyncMessage('teardown-complete'); -} - -initMockAndListener(); diff --git a/dom/presentation/tests/mochitest/PresentationSessionFrameScript.js b/dom/presentation/tests/mochitest/PresentationSessionFrameScript.js deleted file mode 100644 index 77240ab5f7..0000000000 --- a/dom/presentation/tests/mochitest/PresentationSessionFrameScript.js +++ /dev/null @@ -1,258 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -function loadPrivilegedScriptTest() { - /** - * The script is loaded as - * (a) a privileged script in content process for dc_sender.html - * (b) a frame script in the remote iframe process for dc_receiver_oop.html - * |type port == "undefined"| indicates the script is load by - * |loadPrivilegedScript| which is the first case. - */ - function sendMessage(type, data) { - if (typeof port == "undefined") { - sendAsyncMessage(type, {'data': data}); - } else { - port.postMessage({'type': type, - 'data': data - }); - } - } - - if (typeof port != "undefined") { - /** - * When the script is loaded by |loadPrivilegedScript|, these APIs - * are exposed to this script. - */ - port.onmessage = (e) => { - var type = e.data['type']; - if (!handlers.hasOwnProperty(type)) { - return; - } - var args = [e]; - handlers[type].forEach(handler => handler.apply(null, args)); - }; - var handlers = {}; - addMessageListener = function(message, handler) { - if (handlers.hasOwnProperty(message)) { - handlers[message].push(handler); - } else { - handlers[message] = [handler]; - } - }; - removeMessageListener = function(message, handler) { - if (!handler || !handlers.hasOwnProperty(message)) { - return; - } - var index = handlers[message].indexOf(handler); - if (index != -1) { - handlers[message].splice(index, 1); - } - }; - } - - const { classes: Cc, interfaces: Ci, manager: Cm, utils: Cu, results: Cr } = Components; - - const mockedChannelDescription = { - QueryInterface : function (iid) { - const interfaces = [Ci.nsIPresentationChannelDescription]; - - if (!interfaces.some(v => iid.equals(v))) { - throw Cr.NS_ERROR_NO_INTERFACE; - } - return this; - }, - get type() { - if (Services.prefs.getBoolPref("dom.presentation.session_transport.data_channel.enable")) { - return Ci.nsIPresentationChannelDescription.TYPE_DATACHANNEL; - } - return Ci.nsIPresentationChannelDescription.TYPE_TCP; - }, - get dataChannelSDP() { - return "test-sdp"; - } - }; - - function setTimeout(callback, delay) { - let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - timer.initWithCallback({ notify: callback }, - delay, - Ci.nsITimer.TYPE_ONE_SHOT); - return timer; - } - - const mockedSessionTransport = { - QueryInterface : function (iid) { - const interfaces = [Ci.nsIPresentationSessionTransport, - Ci.nsIPresentationDataChannelSessionTransportBuilder, - Ci.nsIFactory]; - - if (!interfaces.some(v => iid.equals(v))) { - throw Cr.NS_ERROR_NO_INTERFACE; - } - return this; - }, - createInstance: function(aOuter, aIID) { - if (aOuter) { - throw Components.results.NS_ERROR_NO_AGGREGATION; - } - return this.QueryInterface(aIID); - }, - set callback(callback) { - this._callback = callback; - }, - get callback() { - return this._callback; - }, - /* OOP case */ - buildDataChannelTransport: function(role, window, listener) { - dump("PresentationSessionFrameScript: build data channel transport\n"); - this._listener = listener; - this._role = role; - - var hasNavigator = window ? (typeof window.navigator != "undefined") : false; - sendMessage('check-navigator', hasNavigator); - - if (this._role == Ci.nsIPresentationService.ROLE_CONTROLLER) { - this._listener.sendOffer(mockedChannelDescription); - } - }, - - enableDataNotification: function() { - sendMessage('data-transport-notification-enabled'); - }, - send: function(data) { - sendMessage('message-sent', data); - }, - close: function(reason) { - sendMessage('data-transport-closed', reason); - this._callback.QueryInterface(Ci.nsIPresentationSessionTransportCallback).notifyTransportClosed(reason); - this._callback = null; - }, - simulateTransportReady: function() { - this._callback.QueryInterface(Ci.nsIPresentationSessionTransportCallback).notifyTransportReady(); - }, - simulateIncomingMessage: function(message) { - this._callback.QueryInterface(Ci.nsIPresentationSessionTransportCallback).notifyData(message, false); - }, - onOffer: function(aOffer) { - this._listener.sendAnswer(mockedChannelDescription); - this._onSessionTransport(); - }, - onAnswer: function(aAnswer) { - this._onSessionTransport(); - }, - _onSessionTransport: function() { - setTimeout(()=>{ - this._listener.onSessionTransport(this); - this.simulateTransportReady(); - this._listener = null; - }, 0); - } - }; - - - function tearDown() { - mockedSessionTransport.callback = null; - - /* Register original factories. */ - for (var data of originalFactoryData) { - registerOriginalFactory(data.contractId, data.mockedClassId, - data.mockedFactory, data.originalClassId, - data.originalFactory); - } - sendMessage("teardown-complete"); - } - - - function registerMockedFactory(contractId, mockedClassId, mockedFactory) { - var originalClassId, originalFactory; - var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar); - - if (!registrar.isCIDRegistered(mockedClassId)) { - try { - originalClassId = registrar.contractIDToCID(contractId); - originalFactory = Cm.getClassObject(Cc[contractId], Ci.nsIFactory); - } catch (ex) { - originalClassId = ""; - originalFactory = null; - } - if (originalFactory) { - registrar.unregisterFactory(originalClassId, originalFactory); - } - registrar.registerFactory(mockedClassId, "", contractId, mockedFactory); - } - - return { contractId: contractId, - mockedClassId: mockedClassId, - mockedFactory: mockedFactory, - originalClassId: originalClassId, - originalFactory: originalFactory }; - } - - function registerOriginalFactory(contractId, mockedClassId, mockedFactory, originalClassId, originalFactory) { - if (originalFactory) { - var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar); - registrar.unregisterFactory(mockedClassId, mockedFactory); - registrar.registerFactory(originalClassId, "", contractId, originalFactory); - } - } - - /* Register mocked factories. */ - const originalFactoryData = []; - const uuidGenerator = Cc["@mozilla.org/uuid-generator;1"] - .getService(Ci.nsIUUIDGenerator); - originalFactoryData.push(registerMockedFactory("@mozilla.org/presentation/datachanneltransportbuilder;1", - uuidGenerator.generateUUID(), - mockedSessionTransport)); - - addMessageListener('trigger-incoming-message', function(event) { - mockedSessionTransport.simulateIncomingMessage(event.data.data); - }); - addMessageListener('teardown', ()=>tearDown()); -} - -// Exposed to the caller of |loadPrivilegedScript| -var contentScript = { - handlers: {}, - addMessageListener: function(message, handler) { - if (this.handlers.hasOwnProperty(message)) { - this.handlers[message].push(handler); - } else { - this.handlers[message] = [handler]; - } - }, - removeMessageListener: function(message, handler) { - if (!handler || !this.handlers.hasOwnProperty(message)) { - return; - } - var index = this.handlers[message].indexOf(handler); - if (index != -1) { - this.handlers[message].splice(index, 1); - } - }, - sendAsyncMessage: function(message, data) { - port.postMessage({'type': message, - 'data': data - }); - } -} - -if (!SpecialPowers.isMainProcess()) { - var port; - try { - port = SpecialPowers.loadPrivilegedScript(loadPrivilegedScriptTest.toSource()); - } catch (e) { - ok(false, "loadPrivilegedScript shoulde not throw" + e); - } - - port.onmessage = (e) => { - var type = e.data['type']; - if (!contentScript.handlers.hasOwnProperty(type)) { - return; - } - var args = [e.data['data']]; - contentScript.handlers[type].forEach(handler => handler.apply(null, args)); - }; -} diff --git a/dom/presentation/tests/mochitest/chrome.ini b/dom/presentation/tests/mochitest/chrome.ini deleted file mode 100644 index 83841f4f8c..0000000000 --- a/dom/presentation/tests/mochitest/chrome.ini +++ /dev/null @@ -1,14 +0,0 @@ -[DEFAULT] -support-files = - PresentationDeviceInfoChromeScript.js - PresentationSessionChromeScript.js - -[test_presentation_datachannel_sessiontransport.html] -skip-if = os == 'android' -[test_presentation_device_info.html] -[test_presentation_sender_startWithDevice.html] -skip-if = toolkit == 'android' # Bug 1129785 -[test_presentation_tcp_sender.html] -skip-if = toolkit == 'android' # Bug 1129785 -[test_presentation_tcp_sender_default_request.html] -skip-if = toolkit == 'android' # Bug 1129785 diff --git a/dom/presentation/tests/mochitest/file_presentation_1ua_receiver.html b/dom/presentation/tests/mochitest/file_presentation_1ua_receiver.html deleted file mode 100644 index cf02d2b2c8..0000000000 --- a/dom/presentation/tests/mochitest/file_presentation_1ua_receiver.html +++ /dev/null @@ -1,220 +0,0 @@ - - - - - - Test for B2G PresentationReceiver at receiver side - - -
- - - diff --git a/dom/presentation/tests/mochitest/file_presentation_1ua_wentaway.html b/dom/presentation/tests/mochitest/file_presentation_1ua_wentaway.html deleted file mode 100644 index 370cb92e1f..0000000000 --- a/dom/presentation/tests/mochitest/file_presentation_1ua_wentaway.html +++ /dev/null @@ -1,95 +0,0 @@ - - - - - - Test for B2G PresentationReceiver at receiver side - - -
- - - diff --git a/dom/presentation/tests/mochitest/file_presentation_mixed_security_contexts.html b/dom/presentation/tests/mochitest/file_presentation_mixed_security_contexts.html deleted file mode 100644 index f042d2994f..0000000000 --- a/dom/presentation/tests/mochitest/file_presentation_mixed_security_contexts.html +++ /dev/null @@ -1,159 +0,0 @@ - - - - - -Test allow-presentation sandboxing flag - - - - - diff --git a/dom/presentation/tests/mochitest/file_presentation_non_receiver.html b/dom/presentation/tests/mochitest/file_presentation_non_receiver.html deleted file mode 100644 index 1203523ac3..0000000000 --- a/dom/presentation/tests/mochitest/file_presentation_non_receiver.html +++ /dev/null @@ -1,41 +0,0 @@ - - - - - Test for B2G PresentationReceiver on a non-receiver page at receiver side - - -
- - - diff --git a/dom/presentation/tests/mochitest/file_presentation_non_receiver_inner_iframe.html b/dom/presentation/tests/mochitest/file_presentation_non_receiver_inner_iframe.html deleted file mode 100644 index c95eddf573..0000000000 --- a/dom/presentation/tests/mochitest/file_presentation_non_receiver_inner_iframe.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - Test for B2G PresentationReceiver on a non-receiver inner iframe of the receiver page at receiver side - - -
- - - diff --git a/dom/presentation/tests/mochitest/file_presentation_receiver.html b/dom/presentation/tests/mochitest/file_presentation_receiver.html deleted file mode 100644 index 46a330b5fc..0000000000 --- a/dom/presentation/tests/mochitest/file_presentation_receiver.html +++ /dev/null @@ -1,140 +0,0 @@ - - - - - Test for B2G PresentationReceiver at receiver side - - -
- - - diff --git a/dom/presentation/tests/mochitest/file_presentation_receiver_auxiliary_navigation.html b/dom/presentation/tests/mochitest/file_presentation_receiver_auxiliary_navigation.html deleted file mode 100644 index 3a60603101..0000000000 --- a/dom/presentation/tests/mochitest/file_presentation_receiver_auxiliary_navigation.html +++ /dev/null @@ -1,60 +0,0 @@ - - - - - Test for sandboxed auxiliary navigation flag in receiver page - - -
- - - diff --git a/dom/presentation/tests/mochitest/file_presentation_receiver_establish_connection_error.html b/dom/presentation/tests/mochitest/file_presentation_receiver_establish_connection_error.html deleted file mode 100644 index 6b1f2152fb..0000000000 --- a/dom/presentation/tests/mochitest/file_presentation_receiver_establish_connection_error.html +++ /dev/null @@ -1,79 +0,0 @@ - - - - - Test for connection establishing errors of B2G Presentation API at receiver side - - -
- - - diff --git a/dom/presentation/tests/mochitest/file_presentation_receiver_inner_iframe.html b/dom/presentation/tests/mochitest/file_presentation_receiver_inner_iframe.html deleted file mode 100644 index 3bd5ac4b1b..0000000000 --- a/dom/presentation/tests/mochitest/file_presentation_receiver_inner_iframe.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - Test for B2G PresentationReceiver in an inner iframe of the receiver page at receiver side - - -
- - - diff --git a/dom/presentation/tests/mochitest/file_presentation_reconnect.html b/dom/presentation/tests/mochitest/file_presentation_reconnect.html deleted file mode 100644 index 174ccd3f3a..0000000000 --- a/dom/presentation/tests/mochitest/file_presentation_reconnect.html +++ /dev/null @@ -1,102 +0,0 @@ - - - - - -Test allow-presentation sandboxing flag - - - - - diff --git a/dom/presentation/tests/mochitest/file_presentation_sandboxed_presentation.html b/dom/presentation/tests/mochitest/file_presentation_sandboxed_presentation.html deleted file mode 100644 index 369621cee2..0000000000 --- a/dom/presentation/tests/mochitest/file_presentation_sandboxed_presentation.html +++ /dev/null @@ -1,114 +0,0 @@ - - - - - -Test allow-presentation sandboxing flag - - - - - diff --git a/dom/presentation/tests/mochitest/file_presentation_terminate.html b/dom/presentation/tests/mochitest/file_presentation_terminate.html deleted file mode 100644 index a26a44b90d..0000000000 --- a/dom/presentation/tests/mochitest/file_presentation_terminate.html +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - Test for B2G PresentationReceiver at receiver side - - -
- - - diff --git a/dom/presentation/tests/mochitest/file_presentation_terminate_establish_connection_error.html b/dom/presentation/tests/mochitest/file_presentation_terminate_establish_connection_error.html deleted file mode 100644 index d8df8a1a67..0000000000 --- a/dom/presentation/tests/mochitest/file_presentation_terminate_establish_connection_error.html +++ /dev/null @@ -1,114 +0,0 @@ - - - - - - Test for B2G PresentationReceiver at receiver side - - -
- - - diff --git a/dom/presentation/tests/mochitest/file_presentation_unknown_content_type.test b/dom/presentation/tests/mochitest/file_presentation_unknown_content_type.test deleted file mode 100644 index 8b13789179..0000000000 --- a/dom/presentation/tests/mochitest/file_presentation_unknown_content_type.test +++ /dev/null @@ -1 +0,0 @@ - diff --git a/dom/presentation/tests/mochitest/file_presentation_unknown_content_type.test^headers^ b/dom/presentation/tests/mochitest/file_presentation_unknown_content_type.test^headers^ deleted file mode 100644 index fc044e3c49..0000000000 --- a/dom/presentation/tests/mochitest/file_presentation_unknown_content_type.test^headers^ +++ /dev/null @@ -1 +0,0 @@ -Content-Type: application/unknown diff --git a/dom/presentation/tests/mochitest/mochitest.ini b/dom/presentation/tests/mochitest/mochitest.ini deleted file mode 100644 index f96e07f1e0..0000000000 --- a/dom/presentation/tests/mochitest/mochitest.ini +++ /dev/null @@ -1,77 +0,0 @@ -[DEFAULT] -support-files = - PresentationDeviceInfoChromeScript.js - PresentationSessionChromeScript.js - PresentationSessionFrameScript.js - PresentationSessionChromeScript1UA.js - file_presentation_1ua_receiver.html - test_presentation_1ua_sender_and_receiver.js - file_presentation_non_receiver_inner_iframe.html - file_presentation_non_receiver.html - file_presentation_receiver.html - file_presentation_receiver_establish_connection_error.html - file_presentation_receiver_inner_iframe.html - file_presentation_1ua_wentaway.html - test_presentation_1ua_connection_wentaway.js - file_presentation_receiver_auxiliary_navigation.html - test_presentation_receiver_auxiliary_navigation.js - file_presentation_sandboxed_presentation.html - file_presentation_terminate.html - test_presentation_terminate.js - file_presentation_terminate_establish_connection_error.html - test_presentation_terminate_establish_connection_error.js - file_presentation_reconnect.html - file_presentation_unknown_content_type.test - file_presentation_unknown_content_type.test^headers^ - test_presentation_tcp_receiver_establish_connection_unknown_content_type.js - file_presentation_mixed_security_contexts.html - -[test_presentation_dc_sender.html] -[test_presentation_dc_receiver.html] -skip-if = (e10s || toolkit == 'android') # Bug 1129785 -[test_presentation_dc_receiver_oop.html] -skip-if = (e10s || toolkit == 'android') # Bug 1129785 -[test_presentation_1ua_sender_and_receiver_inproc.html] -skip-if = (e10s || toolkit == 'android') # Bug 1129785 -[test_presentation_1ua_sender_and_receiver_oop.html] -skip-if = (e10s || toolkit == 'android') # Bug 1129785 -[test_presentation_1ua_connection_wentaway_inproc.html] -skip-if = (e10s || toolkit == 'android') # Bug 1129785 -[test_presentation_1ua_connection_wentaway_oop.html] -skip-if = (e10s || toolkit == 'android') # Bug 1129785 -[test_presentation_device_info_permission.html] -[test_presentation_tcp_sender_disconnect.html] -skip-if = toolkit == 'android' # Bug 1129785 -[test_presentation_tcp_sender_establish_connection_error.html] -skip-if = toolkit == 'android' # Bug 1129785 -[test_presentation_tcp_receiver_establish_connection_error.html] -skip-if = (e10s || toolkit == 'android' || os == 'mac' || os == 'win') # Bug 1129785, Bug 1204709 -[test_presentation_tcp_receiver_establish_connection_timeout.html] -skip-if = (e10s || toolkit == 'android') # Bug 1129785 -[test_presentation_tcp_receiver_establish_connection_unknown_content_type_inproc.html] -skip-if = (e10s || toolkit == 'android') -[test_presentation_tcp_receiver_establish_connection_unknown_content_type_oop.html] -skip-if = (e10s || toolkit == 'android') -[test_presentation_tcp_receiver.html] -skip-if = (e10s || toolkit == 'android') # Bug 1129785 -[test_presentation_tcp_receiver_oop.html] -skip-if = (e10s || toolkit == 'android') # Bug 1129785 -[test_presentation_receiver_auxiliary_navigation_inproc.html] -skip-if = e10s -[test_presentation_receiver_auxiliary_navigation_oop.html] -skip-if = e10s -[test_presentation_terminate_inproc.html] -skip-if = (e10s || toolkit == 'android') -[test_presentation_terminate_oop.html] -skip-if = (e10s || toolkit == 'android') -[test_presentation_terminate_establish_connection_error_inproc.html] -skip-if = (e10s || toolkit == 'android') -[test_presentation_terminate_establish_connection_error_oop.html] -skip-if = (e10s || toolkit == 'android') -[test_presentation_sender_on_terminate_request.html] -skip-if = toolkit == 'android' -[test_presentation_sandboxed_presentation.html] -skip-if = true # bug 1315867 -[test_presentation_reconnect.html] -[test_presentation_mixed_security_contexts.html] -[test_presentation_availability.html] diff --git a/dom/presentation/tests/mochitest/test_presentation_1ua_connection_wentaway.js b/dom/presentation/tests/mochitest/test_presentation_1ua_connection_wentaway.js deleted file mode 100644 index dbeb4ffcc6..0000000000 --- a/dom/presentation/tests/mochitest/test_presentation_1ua_connection_wentaway.js +++ /dev/null @@ -1,175 +0,0 @@ -'use strict'; - -SimpleTest.waitForExplicitFinish(); -SimpleTest.requestFlakyTimeout('Test for guarantee not firing async event'); - -function debug(str) { - // info(str); -} - -var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('PresentationSessionChromeScript1UA.js')); -var receiverUrl = SimpleTest.getTestFileURL('file_presentation_1ua_wentaway.html'); -var request; -var connection; -var receiverIframe; - -function setup() { - gScript.addMessageListener('device-prompt', function devicePromptHandler() { - debug('Got message: device-prompt'); - gScript.removeMessageListener('device-prompt', devicePromptHandler); - gScript.sendAsyncMessage('trigger-device-prompt-select'); - }); - - gScript.addMessageListener('control-channel-established', function controlChannelEstablishedHandler() { - gScript.removeMessageListener('control-channel-established', - controlChannelEstablishedHandler); - gScript.sendAsyncMessage("trigger-control-channel-open"); - }); - - gScript.addMessageListener('sender-launch', function senderLaunchHandler(url) { - debug('Got message: sender-launch'); - gScript.removeMessageListener('sender-launch', senderLaunchHandler); - is(url, receiverUrl, 'Receiver: should receive the same url'); - receiverIframe = document.createElement('iframe'); - receiverIframe.setAttribute("mozbrowser", "true"); - receiverIframe.setAttribute("mozpresentation", receiverUrl); - var oop = location.pathname.indexOf('_inproc') == -1; - receiverIframe.setAttribute("remote", oop); - - receiverIframe.setAttribute('src', receiverUrl); - receiverIframe.addEventListener("mozbrowserloadend", function mozbrowserloadendHander() { - receiverIframe.removeEventListener("mozbrowserloadend", mozbrowserloadendHander); - info("Receiver loaded."); - }); - - // This event is triggered when the iframe calls "alert". - receiverIframe.addEventListener("mozbrowsershowmodalprompt", function receiverListener(evt) { - var message = evt.detail.message; - if (/^OK /.exec(message)) { - ok(true, message.replace(/^OK /, "")); - } else if (/^KO /.exec(message)) { - ok(false, message.replace(/^KO /, "")); - } else if (/^INFO /.exec(message)) { - info(message.replace(/^INFO /, "")); - } else if (/^COMMAND /.exec(message)) { - var command = JSON.parse(message.replace(/^COMMAND /, "")); - gScript.sendAsyncMessage(command.name, command.data); - } else if (/^DONE$/.exec(message)) { - receiverIframe.removeEventListener("mozbrowsershowmodalprompt", - receiverListener); - teardown(); - } - }, false); - - var promise = new Promise(function(aResolve, aReject) { - document.body.appendChild(receiverIframe); - aResolve(receiverIframe); - }); - - var obs = SpecialPowers.Cc["@mozilla.org/observer-service;1"] - .getService(SpecialPowers.Ci.nsIObserverService); - obs.notifyObservers(promise, 'setup-request-promise', null); - }); - - gScript.addMessageListener('promise-setup-ready', function promiseSetupReadyHandler() { - debug('Got message: promise-setup-ready'); - gScript.removeMessageListener('promise-setup-ready', - promiseSetupReadyHandler); - gScript.sendAsyncMessage('trigger-on-session-request', receiverUrl); - }); - - return Promise.resolve(); -} - -function testCreateRequest() { - return new Promise(function(aResolve, aReject) { - info('Sender: --- testCreateRequest ---'); - request = new PresentationRequest(receiverUrl); - request.getAvailability().then((aAvailability) => { - is(aAvailability.value, false, "Sender: should have no available device after setup"); - aAvailability.onchange = function() { - aAvailability.onchange = null; - ok(aAvailability.value, "Sender: Device should be available."); - aResolve(); - } - - gScript.sendAsyncMessage('trigger-device-add'); - }).catch((aError) => { - ok(false, "Sender: Error occurred when getting availability: " + aError); - teardown(); - aReject(); - }); - }); -} - -function testStartConnection() { - return new Promise(function(aResolve, aReject) { - request.start().then((aConnection) => { - connection = aConnection; - ok(connection, "Sender: Connection should be available."); - ok(connection.id, "Sender: Connection ID should be set."); - is(connection.state, "connecting", "Sender: The initial state should be connecting."); - connection.onconnect = function() { - connection.onconnect = null; - is(connection.state, "connected", "Connection should be connected."); - aResolve(); - }; - }).catch((aError) => { - ok(false, "Sender: Error occurred when establishing a connection: " + aError); - teardown(); - aReject(); - }); - }); -} - -function testConnectionWentaway() { - return new Promise(function(aResolve, aReject) { - info('Sender: --- testConnectionWentaway ---'); - connection.onclose = function() { - connection.onclose = null; - is(connection.state, "closed", "Sender: Connection should be closed."); - receiverIframe.addEventListener('mozbrowserclose', function closeHandler() { - ok(false, 'wentaway should not trigger receiver close'); - aResolve(); - }); - setTimeout(aResolve, 3000); - }; - gScript.addMessageListener('ready-to-remove-receiverFrame', function onReadyToRemove() { - gScript.removeMessageListener('ready-to-remove-receiverFrame', onReadyToRemove); - receiverIframe.src = "http://example.com"; - }); - }); -} - -function teardown() { - gScript.addMessageListener('teardown-complete', function teardownCompleteHandler() { - debug('Got message: teardown-complete'); - gScript.removeMessageListener('teardown-complete', teardownCompleteHandler); - gScript.destroy(); - SimpleTest.finish(); - }); - - gScript.sendAsyncMessage('teardown'); -} - -function runTests() { - setup().then(testCreateRequest) - .then(testStartConnection) - .then(testConnectionWentaway) - .then(teardown); -} - -SpecialPowers.pushPermissions([ - {type: 'presentation-device-manage', allow: false, context: document}, - {type: "browser", allow: true, context: document}, -], () => { - SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true], - ["dom.presentation.controller.enabled", true], - ["dom.presentation.receiver.enabled", true], - ["dom.presentation.test.enabled", true], - ["dom.mozBrowserFramesEnabled", true], - ["dom.ipc.tabs.disabled", false], - ["network.disable.ipc.security", true], - ["dom.presentation.test.stage", 0]]}, - runTests); -}); diff --git a/dom/presentation/tests/mochitest/test_presentation_1ua_connection_wentaway_inproc.html b/dom/presentation/tests/mochitest/test_presentation_1ua_connection_wentaway_inproc.html deleted file mode 100644 index 68491d81b4..0000000000 --- a/dom/presentation/tests/mochitest/test_presentation_1ua_connection_wentaway_inproc.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - Test for B2G Presentation API when sender and receiver at the same side - - - - - - Test for PresentationConnectionCloseEvent with wentaway reason - - - diff --git a/dom/presentation/tests/mochitest/test_presentation_1ua_connection_wentaway_oop.html b/dom/presentation/tests/mochitest/test_presentation_1ua_connection_wentaway_oop.html deleted file mode 100644 index 68491d81b4..0000000000 --- a/dom/presentation/tests/mochitest/test_presentation_1ua_connection_wentaway_oop.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - Test for B2G Presentation API when sender and receiver at the same side - - - - - - Test for PresentationConnectionCloseEvent with wentaway reason - - - diff --git a/dom/presentation/tests/mochitest/test_presentation_1ua_sender_and_receiver.js b/dom/presentation/tests/mochitest/test_presentation_1ua_sender_and_receiver.js deleted file mode 100644 index 8a7787b40d..0000000000 --- a/dom/presentation/tests/mochitest/test_presentation_1ua_sender_and_receiver.js +++ /dev/null @@ -1,370 +0,0 @@ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, -* You can obtain one at http://mozilla.org/MPL/2.0/. */ - -'use strict'; - -function debug(str) { - // info(str); -} - -var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('PresentationSessionChromeScript1UA.js')); -var receiverUrl = SimpleTest.getTestFileURL('file_presentation_1ua_receiver.html'); -var request; -var connection; -var receiverIframe; -var presentationId; -const DATA_ARRAY = [0, 255, 254, 0, 1, 2, 3, 0, 255, 255, 254, 0]; -const DATA_ARRAY_BUFFER = new ArrayBuffer(DATA_ARRAY.length); -const TYPED_DATA_ARRAY = new Uint8Array(DATA_ARRAY_BUFFER); -TYPED_DATA_ARRAY.set(DATA_ARRAY); - -function postMessageToIframe(aType) { - receiverIframe.src = receiverUrl + "#" + - encodeURIComponent(JSON.stringify({ type: aType })); -} - -function setup() { - - gScript.addMessageListener('device-prompt', function devicePromptHandler() { - debug('Got message: device-prompt'); - gScript.removeMessageListener('device-prompt', devicePromptHandler); - gScript.sendAsyncMessage('trigger-device-prompt-select'); - }); - - gScript.addMessageListener('control-channel-established', function controlChannelEstablishedHandler() { - gScript.removeMessageListener('control-channel-established', - controlChannelEstablishedHandler); - gScript.sendAsyncMessage("trigger-control-channel-open"); - }); - - gScript.addMessageListener('sender-launch', function senderLaunchHandler(url) { - debug('Got message: sender-launch'); - gScript.removeMessageListener('sender-launch', senderLaunchHandler); - is(url, receiverUrl, 'Receiver: should receive the same url'); - receiverIframe = document.createElement('iframe'); - receiverIframe.setAttribute('src', receiverUrl); - receiverIframe.setAttribute("mozbrowser", "true"); - receiverIframe.setAttribute("mozpresentation", receiverUrl); - var oop = location.pathname.indexOf('_inproc') == -1; - receiverIframe.setAttribute("remote", oop); - - // This event is triggered when the iframe calls "alert". - receiverIframe.addEventListener("mozbrowsershowmodalprompt", function receiverListener(evt) { - var message = evt.detail.message; - debug('Got iframe message: ' + message); - if (/^OK /.exec(message)) { - ok(true, message.replace(/^OK /, "")); - } else if (/^KO /.exec(message)) { - ok(false, message.replace(/^KO /, "")); - } else if (/^INFO /.exec(message)) { - info(message.replace(/^INFO /, "")); - } else if (/^COMMAND /.exec(message)) { - var command = JSON.parse(message.replace(/^COMMAND /, "")); - gScript.sendAsyncMessage(command.name, command.data); - } else if (/^DONE$/.exec(message)) { - receiverIframe.removeEventListener("mozbrowsershowmodalprompt", - receiverListener); - } - }, false); - - var promise = new Promise(function(aResolve, aReject) { - document.body.appendChild(receiverIframe); - aResolve(receiverIframe); - }); - - var obs = SpecialPowers.Cc["@mozilla.org/observer-service;1"] - .getService(SpecialPowers.Ci.nsIObserverService); - obs.notifyObservers(promise, 'setup-request-promise', null); - }); - - gScript.addMessageListener('promise-setup-ready', function promiseSetupReadyHandler() { - debug('Got message: promise-setup-ready'); - gScript.removeMessageListener('promise-setup-ready', promiseSetupReadyHandler); - gScript.sendAsyncMessage('trigger-on-session-request', receiverUrl); - }); - - return Promise.resolve(); -} - -function testCreateRequest() { - return new Promise(function(aResolve, aReject) { - info('Sender: --- testCreateRequest ---'); - request = new PresentationRequest("file_presentation_1ua_receiver.html"); - request.getAvailability().then((aAvailability) => { - is(aAvailability.value, false, "Sender: should have no available device after setup"); - aAvailability.onchange = function() { - aAvailability.onchange = null; - ok(aAvailability.value, "Sender: Device should be available."); - aResolve(); - } - - gScript.sendAsyncMessage('trigger-device-add'); - }).catch((aError) => { - ok(false, "Sender: Error occurred when getting availability: " + aError); - teardown(); - aReject(); - }); - }); -} - -function testStartConnection() { - return new Promise(function(aResolve, aReject) { - request.start().then((aConnection) => { - connection = aConnection; - ok(connection, "Sender: Connection should be available."); - ok(connection.id, "Sender: Connection ID should be set."); - is(connection.state, "connecting", "The initial state should be connecting."); - is(connection.url, receiverUrl, "request URL should be expanded to absolute URL"); - connection.onconnect = function() { - connection.onconnect = null; - is(connection.state, "connected", "Connection should be connected."); - presentationId = connection.id; - aResolve(); - }; - }).catch((aError) => { - ok(false, "Sender: Error occurred when establishing a connection: " + aError); - teardown(); - aReject(); - }); - - let request2 = new PresentationRequest("/"); - request2.start().then(() => { - ok(false, "Sender: session start should fail while there is an unsettled promise."); - }).catch((aError) => { - is(aError.name, "OperationError", "Expect to get OperationError."); - }); - }); -} - -function testSendMessage() { - return new Promise(function(aResolve, aReject) { - info('Sender: --- testSendMessage ---'); - gScript.addMessageListener('trigger-message-from-sender', function triggerMessageFromSenderHandler() { - debug('Got message: trigger-message-from-sender'); - gScript.removeMessageListener('trigger-message-from-sender', triggerMessageFromSenderHandler); - info('Send message to receiver'); - connection.send('msg-sender-to-receiver'); - }); - - gScript.addMessageListener('message-from-sender-received', function messageFromSenderReceivedHandler() { - debug('Got message: message-from-sender-received'); - gScript.removeMessageListener('message-from-sender-received', messageFromSenderReceivedHandler); - aResolve(); - }); - }); -} - -function testIncomingMessage() { - return new Promise(function(aResolve, aReject) { - info('Sender: --- testIncomingMessage ---'); - connection.addEventListener('message', function messageHandler(evt) { - connection.removeEventListener('message', messageHandler); - let msg = evt.data; - is(msg, "msg-receiver-to-sender", "Sender: Sender should receive message from Receiver"); - postMessageToIframe('message-from-receiver-received'); - aResolve(); - }); - postMessageToIframe('trigger-message-from-receiver'); - }); -} - -function testSendBlobMessage() { - return new Promise(function(aResolve, aReject) { - info('Sender: --- testSendBlobMessage ---'); - connection.addEventListener('message', function messageHandler(evt) { - connection.removeEventListener('message', messageHandler); - let msg = evt.data; - is(msg, "testIncomingBlobMessage", "Sender: Sender should receive message from Receiver"); - let blob = new Blob(["Hello World"], {type : 'text/plain'}); - connection.send(blob); - aResolve(); - }); - }); -} - -function testSendArrayBuffer() { - return new Promise(function(aResolve, aReject) { - info('Sender: --- testSendArrayBuffer ---'); - connection.addEventListener('message', function messageHandler(evt) { - connection.removeEventListener('message', messageHandler); - let msg = evt.data; - is(msg, "testIncomingArrayBuffer", "Sender: Sender should receive message from Receiver"); - connection.send(DATA_ARRAY_BUFFER); - aResolve(); - }); - }); -} - -function testSendArrayBufferView() { - return new Promise(function(aResolve, aReject) { - info('Sender: --- testSendArrayBufferView ---'); - connection.addEventListener('message', function messageHandler(evt) { - connection.removeEventListener('message', messageHandler); - let msg = evt.data; - is(msg, "testIncomingArrayBufferView", "Sender: Sender should receive message from Receiver"); - connection.send(TYPED_DATA_ARRAY); - aResolve(); - }); - }); -} - -function testCloseConnection() { - info('Sender: --- testCloseConnection ---'); - // Test terminate immediate after close. - function controlChannelEstablishedHandler() - { - gScript.removeMessageListener('control-channel-established', - controlChannelEstablishedHandler); - ok(false, "terminate after close should do nothing"); - } - gScript.addMessageListener('ready-to-close', function onReadyToClose() { - gScript.removeMessageListener('ready-to-close', onReadyToClose); - connection.close(); - - gScript.addMessageListener('control-channel-established', controlChannelEstablishedHandler); - connection.terminate(); - }); - - return Promise.all([ - new Promise(function(aResolve, aReject) { - connection.onclose = function() { - connection.onclose = null; - is(connection.state, 'closed', 'Sender: Connection should be closed.'); - gScript.removeMessageListener('control-channel-established', - controlChannelEstablishedHandler); - aResolve(); - }; - }), - new Promise(function(aResolve, aReject) { - let timeout = setTimeout(function() { - gScript.removeMessageListener('device-disconnected', - deviceDisconnectedHandler); - ok(true, "terminate after close should not trigger device.disconnect"); - aResolve(); - }, 3000); - - function deviceDisconnectedHandler() { - gScript.removeMessageListener('device-disconnected', - deviceDisconnectedHandler); - ok(false, "terminate after close should not trigger device.disconnect"); - clearTimeout(timeout); - aResolve(); - } - - gScript.addMessageListener('device-disconnected', deviceDisconnectedHandler); - }), - new Promise(function(aResolve, aReject) { - gScript.addMessageListener('receiver-closed', function onReceiverClosed() { - gScript.removeMessageListener('receiver-closed', onReceiverClosed); - gScript.removeMessageListener('control-channel-established', - controlChannelEstablishedHandler); - aResolve(); - }); - }), - ]); -} - -function testTerminateAfterClose() { - info('Sender: --- testTerminateAfterClose ---'); - return Promise.race([ - new Promise(function(aResolve, aReject) { - connection.onterminate = function() { - connection.onterminate = null; - ok(false, 'terminate after close should do nothing'); - aResolve(); - }; - connection.terminate(); - }), - new Promise(function(aResolve, aReject) { - setTimeout(function() { - is(connection.state, 'closed', 'Sender: Connection should be closed.'); - aResolve(); - }, 3000); - }), - ]); -} - -function testReconnect() { - return new Promise(function(aResolve, aReject) { - info('Sender: --- testReconnect ---'); - gScript.addMessageListener('control-channel-established', function controlChannelEstablished() { - gScript.removeMessageListener('control-channel-established', controlChannelEstablished); - gScript.sendAsyncMessage("trigger-control-channel-open"); - }); - - gScript.addMessageListener('start-reconnect', function startReconnectHandler(url) { - debug('Got message: start-reconnect'); - gScript.removeMessageListener('start-reconnect', startReconnectHandler); - is(url, receiverUrl, "URLs should be the same.") - gScript.sendAsyncMessage('trigger-reconnected-acked', url); - }); - - gScript.addMessageListener('ready-to-reconnect', function onReadyToReconnect() { - gScript.removeMessageListener('ready-to-reconnect', onReadyToReconnect); - request.reconnect(presentationId).then((aConnection) => { - connection = aConnection; - ok(connection, "Sender: Connection should be available."); - is(connection.id, presentationId, "The presentationId should be the same."); - is(connection.state, "connecting", "The initial state should be connecting."); - connection.onconnect = function() { - connection.onconnect = null; - is(connection.state, "connected", "Connection should be connected."); - aResolve(); - }; - }).catch((aError) => { - ok(false, "Sender: Error occurred when establishing a connection: " + aError); - teardown(); - aReject(); - }); - }); - - postMessageToIframe('prepare-for-reconnect'); - }); -} - -function teardown() { - gScript.addMessageListener('teardown-complete', function teardownCompleteHandler() { - debug('Got message: teardown-complete'); - gScript.removeMessageListener('teardown-complete', teardownCompleteHandler); - gScript.destroy(); - SimpleTest.finish(); - }); - - gScript.sendAsyncMessage('teardown'); -} - -function runTests() { - setup().then(testCreateRequest) - .then(testStartConnection) - .then(testSendMessage) - .then(testIncomingMessage) - .then(testSendBlobMessage) - .then(testCloseConnection) - .then(testReconnect) - .then(testSendArrayBuffer) - .then(testSendArrayBufferView) - .then(testCloseConnection) - .then(testTerminateAfterClose) - .then(teardown); -} - -SimpleTest.waitForExplicitFinish(); -SimpleTest.requestFlakyTimeout('Test for guarantee not firing async event'); -SpecialPowers.pushPermissions([ - {type: 'presentation-device-manage', allow: false, context: document}, - {type: "browser", allow: true, context: document}, -], () => { - SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true], - /* Mocked TCP session transport builder in the test */ - ["dom.presentation.session_transport.data_channel.enable", true], - ["dom.presentation.controller.enabled", true], - ["dom.presentation.receiver.enabled", true], - ["dom.presentation.test.enabled", true], - ["dom.presentation.test.stage", 0], - ["dom.mozBrowserFramesEnabled", true], - ["network.disable.ipc.security", true], - ["media.navigator.permission.disabled", true]]}, - runTests); -}); diff --git a/dom/presentation/tests/mochitest/test_presentation_1ua_sender_and_receiver_inproc.html b/dom/presentation/tests/mochitest/test_presentation_1ua_sender_and_receiver_inproc.html deleted file mode 100644 index 520b1a98c3..0000000000 --- a/dom/presentation/tests/mochitest/test_presentation_1ua_sender_and_receiver_inproc.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - Test for B2G Presentation API when sender and receiver at the same side - - - - - - Test for B2G Presentation API when sender and receiver at the same side - - - diff --git a/dom/presentation/tests/mochitest/test_presentation_1ua_sender_and_receiver_oop.html b/dom/presentation/tests/mochitest/test_presentation_1ua_sender_and_receiver_oop.html deleted file mode 100644 index e744e68029..0000000000 --- a/dom/presentation/tests/mochitest/test_presentation_1ua_sender_and_receiver_oop.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - Test for B2G Presentation API when sender and receiver at the same side (OOP ver.) - - - - - - Test for B2G Presentation API when sender and receiver at the same side (OOP ver.) - - - diff --git a/dom/presentation/tests/mochitest/test_presentation_availability.html b/dom/presentation/tests/mochitest/test_presentation_availability.html deleted file mode 100644 index 89f1ad1b7e..0000000000 --- a/dom/presentation/tests/mochitest/test_presentation_availability.html +++ /dev/null @@ -1,236 +0,0 @@ - - - - - - Test for PresentationAvailability - - - - -Test PresentationAvailability - - - diff --git a/dom/presentation/tests/mochitest/test_presentation_datachannel_sessiontransport.html b/dom/presentation/tests/mochitest/test_presentation_datachannel_sessiontransport.html deleted file mode 100644 index 89a51afb7d..0000000000 --- a/dom/presentation/tests/mochitest/test_presentation_datachannel_sessiontransport.html +++ /dev/null @@ -1,245 +0,0 @@ - - - - - - Test for data channel as session transport in Presentation API - - - - -Test for data channel as session transport in Presentation API - -
-
-
- - diff --git a/dom/presentation/tests/mochitest/test_presentation_dc_receiver.html b/dom/presentation/tests/mochitest/test_presentation_dc_receiver.html deleted file mode 100644 index a42489bdb5..0000000000 --- a/dom/presentation/tests/mochitest/test_presentation_dc_receiver.html +++ /dev/null @@ -1,141 +0,0 @@ - - - - - - Test for B2G PresentationConnection API at receiver side - - - - -Test for B2G PresentationConnection API at receiver side -

- -

-
-
-
diff --git a/dom/presentation/tests/mochitest/test_presentation_dc_receiver_oop.html b/dom/presentation/tests/mochitest/test_presentation_dc_receiver_oop.html
deleted file mode 100644
index b289b0be68..0000000000
--- a/dom/presentation/tests/mochitest/test_presentation_dc_receiver_oop.html
+++ /dev/null
@@ -1,213 +0,0 @@
-
-
-
-
-  
-  Test for B2G PresentationConnection API at receiver side (OOP)
-  
-  
-  
-
-
-Test B2G PresentationConnection API at receiver side (OOP)
-

- -

-
-
-
diff --git a/dom/presentation/tests/mochitest/test_presentation_dc_sender.html b/dom/presentation/tests/mochitest/test_presentation_dc_sender.html
deleted file mode 100644
index 97e252e840..0000000000
--- a/dom/presentation/tests/mochitest/test_presentation_dc_sender.html
+++ /dev/null
@@ -1,291 +0,0 @@
-
-
-
-
-  
-  Test for B2G Presentation API at sender side
-  
-  
-  
-
-
-Test for B2G Presentation API at sender side
-
-
-
diff --git a/dom/presentation/tests/mochitest/test_presentation_device_info.html b/dom/presentation/tests/mochitest/test_presentation_device_info.html
deleted file mode 100644
index 77253e41db..0000000000
--- a/dom/presentation/tests/mochitest/test_presentation_device_info.html
+++ /dev/null
@@ -1,144 +0,0 @@
-
-
-
-
-  
-  Test for B2G Presentation Device Info API
-  
-  
-
-
-Test for B2G Presentation Device Info API
-
-
-
-
diff --git a/dom/presentation/tests/mochitest/test_presentation_device_info_permission.html b/dom/presentation/tests/mochitest/test_presentation_device_info_permission.html
deleted file mode 100644
index c7f7ac96d4..0000000000
--- a/dom/presentation/tests/mochitest/test_presentation_device_info_permission.html
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-  
-  Test for B2G Presentation Device Info API Permission
-  
-  
-
-
-Test for B2G Presentation Device Info API Permission
-
-
-
-
diff --git a/dom/presentation/tests/mochitest/test_presentation_mixed_security_contexts.html b/dom/presentation/tests/mochitest/test_presentation_mixed_security_contexts.html
deleted file mode 100644
index 31918a2c40..0000000000
--- a/dom/presentation/tests/mochitest/test_presentation_mixed_security_contexts.html
+++ /dev/null
@@ -1,81 +0,0 @@
-
-
-
-
-  
-  Test default request for B2G Presentation API at sender side
-  
-  
-
-
-Test allow-presentation sandboxing flag
-
-
-
-
diff --git a/dom/presentation/tests/mochitest/test_presentation_receiver_auxiliary_navigation.js b/dom/presentation/tests/mochitest/test_presentation_receiver_auxiliary_navigation.js
deleted file mode 100644
index 0647bff3a8..0000000000
--- a/dom/presentation/tests/mochitest/test_presentation_receiver_auxiliary_navigation.js
+++ /dev/null
@@ -1,77 +0,0 @@
-"use strict";
-
-var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL("PresentationSessionChromeScript.js"));
-var receiverUrl = SimpleTest.getTestFileURL("file_presentation_receiver_auxiliary_navigation.html");
-
-var obs = SpecialPowers.Cc["@mozilla.org/observer-service;1"]
-          .getService(SpecialPowers.Ci.nsIObserverService);
-
-function setup() {
-  return new Promise(function(aResolve, aReject) {
-    gScript.sendAsyncMessage("trigger-device-add");
-
-    var iframe = document.createElement("iframe");
-    iframe.setAttribute("mozbrowser", "true");
-    iframe.setAttribute("mozpresentation", receiverUrl);
-    var oop = location.pathname.indexOf('_inproc') == -1;
-    iframe.setAttribute("remote", oop);
-    iframe.setAttribute("src", receiverUrl);
-
-    // This event is triggered when the iframe calls "postMessage".
-    iframe.addEventListener("mozbrowsershowmodalprompt", function listener(aEvent) {
-      var message = aEvent.detail.message;
-      if (/^OK /.exec(message)) {
-        ok(true, "Message from iframe: " + message);
-      } else if (/^KO /.exec(message)) {
-        ok(false, "Message from iframe: " + message);
-      } else if (/^INFO /.exec(message)) {
-        info("Message from iframe: " + message);
-      } else if (/^COMMAND /.exec(message)) {
-        var command = JSON.parse(message.replace(/^COMMAND /, ""));
-        gScript.sendAsyncMessage(command.name, command.data);
-      } else if (/^DONE$/.exec(message)) {
-        ok(true, "Messaging from iframe complete.");
-        iframe.removeEventListener("mozbrowsershowmodalprompt", listener);
-
-        teardown();
-      }
-    }, false);
-
-    var promise = new Promise(function(aResolve, aReject) {
-      document.body.appendChild(iframe);
-
-      aResolve(iframe);
-    });
-    obs.notifyObservers(promise, "setup-request-promise", null);
-
-    aResolve();
-  });
-}
-
-function teardown() {
-  gScript.addMessageListener("teardown-complete", function teardownCompleteHandler() {
-    gScript.removeMessageListener("teardown-complete", teardownCompleteHandler);
-    gScript.destroy();
-    SimpleTest.finish();
-  });
-
-  gScript.sendAsyncMessage("teardown");
-}
-
-function runTests() {
-  setup().then();
-}
-
-SimpleTest.waitForExplicitFinish();
-SpecialPowers.pushPermissions([
-  {type: "presentation-device-manage", allow: false, context: document},
-  {type: "browser", allow: true, context: document},
-], function() {
-  SpecialPowers.pushPrefEnv({ "set": [["dom.presentation.enabled", true],
-                                      ["dom.presentation.controller.enabled", true],
-                                      ["dom.presentation.receiver.enabled", true],
-                                      ["dom.mozBrowserFramesEnabled", true],
-                                      ["network.disable.ipc.security", true],
-                                      ["dom.presentation.session_transport.data_channel.enable", false]]},
-                            runTests);
-});
diff --git a/dom/presentation/tests/mochitest/test_presentation_receiver_auxiliary_navigation_inproc.html b/dom/presentation/tests/mochitest/test_presentation_receiver_auxiliary_navigation_inproc.html
deleted file mode 100644
index f873fa3da4..0000000000
--- a/dom/presentation/tests/mochitest/test_presentation_receiver_auxiliary_navigation_inproc.html
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-  
-  
-    
-    Test for B2G Presentation API when sender and receiver at the same side
-    
-    
-  
-  
-    
-      Test for receiver page with sandboxed auxiliary navigation browsing context flag.
-    
-  
-
diff --git a/dom/presentation/tests/mochitest/test_presentation_receiver_auxiliary_navigation_oop.html b/dom/presentation/tests/mochitest/test_presentation_receiver_auxiliary_navigation_oop.html
deleted file mode 100644
index f873fa3da4..0000000000
--- a/dom/presentation/tests/mochitest/test_presentation_receiver_auxiliary_navigation_oop.html
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-  
-  
-    
-    Test for B2G Presentation API when sender and receiver at the same side
-    
-    
-  
-  
-    
-      Test for receiver page with sandboxed auxiliary navigation browsing context flag.
-    
-  
-
diff --git a/dom/presentation/tests/mochitest/test_presentation_reconnect.html b/dom/presentation/tests/mochitest/test_presentation_reconnect.html
deleted file mode 100644
index 079b7f5c5a..0000000000
--- a/dom/presentation/tests/mochitest/test_presentation_reconnect.html
+++ /dev/null
@@ -1,379 +0,0 @@
-
-
-
-
-  
-  Test for B2G Presentation API at sender side
-  
-  
-  
-
-
-Test for Presentation API at sender side
-
-
-
-
diff --git a/dom/presentation/tests/mochitest/test_presentation_sandboxed_presentation.html b/dom/presentation/tests/mochitest/test_presentation_sandboxed_presentation.html
deleted file mode 100644
index dc17209c5a..0000000000
--- a/dom/presentation/tests/mochitest/test_presentation_sandboxed_presentation.html
+++ /dev/null
@@ -1,75 +0,0 @@
-
-
-
-
-  
-  Test default request for B2G Presentation API at sender side
-  
-  
-
-
-Test allow-presentation sandboxing flag
-
-
-
-
diff --git a/dom/presentation/tests/mochitest/test_presentation_sender_on_terminate_request.html b/dom/presentation/tests/mochitest/test_presentation_sender_on_terminate_request.html
deleted file mode 100644
index d0c8af0ad7..0000000000
--- a/dom/presentation/tests/mochitest/test_presentation_sender_on_terminate_request.html
+++ /dev/null
@@ -1,187 +0,0 @@
-
-
-
-
-  
-  Test onTerminateRequest at sender side
-  
-  
-
-
-Test onTerminateRequest at sender side
-
-
-
diff --git a/dom/presentation/tests/mochitest/test_presentation_sender_startWithDevice.html b/dom/presentation/tests/mochitest/test_presentation_sender_startWithDevice.html
deleted file mode 100644
index 27b17bb321..0000000000
--- a/dom/presentation/tests/mochitest/test_presentation_sender_startWithDevice.html
+++ /dev/null
@@ -1,173 +0,0 @@
-
-
-
-
-  
-  Test startWithDevice for B2G Presentation API at sender side
-  
-  
-
-
-Test startWithDevice for B2G Presentation API at sender side
-
-
-
diff --git a/dom/presentation/tests/mochitest/test_presentation_tcp_receiver.html b/dom/presentation/tests/mochitest/test_presentation_tcp_receiver.html
deleted file mode 100644
index f26184f0b2..0000000000
--- a/dom/presentation/tests/mochitest/test_presentation_tcp_receiver.html
+++ /dev/null
@@ -1,137 +0,0 @@
-
-
-
-
-  
-  Test for B2G PresentationConnection API at receiver side
-  
-  
-
-
-Test for B2G PresentationConnection API at receiver side
-

- -

-
-
-
diff --git a/dom/presentation/tests/mochitest/test_presentation_tcp_receiver_establish_connection_error.html b/dom/presentation/tests/mochitest/test_presentation_tcp_receiver_establish_connection_error.html
deleted file mode 100644
index 0935aaaf9c..0000000000
--- a/dom/presentation/tests/mochitest/test_presentation_tcp_receiver_establish_connection_error.html
+++ /dev/null
@@ -1,110 +0,0 @@
-
-
-
-
-  
-  Test for connection establishing errors of B2G Presentation API at receiver side
-  
-  
-
-
-Test for connection establishing errors of B2G Presentation API at receiver side
-
-
-
diff --git a/dom/presentation/tests/mochitest/test_presentation_tcp_receiver_establish_connection_timeout.html b/dom/presentation/tests/mochitest/test_presentation_tcp_receiver_establish_connection_timeout.html
deleted file mode 100644
index 1dc002644f..0000000000
--- a/dom/presentation/tests/mochitest/test_presentation_tcp_receiver_establish_connection_timeout.html
+++ /dev/null
@@ -1,81 +0,0 @@
-
-
-
-
-  
-  Test for connection establishing timeout of B2G Presentation API at receiver side
-  
-  
-
-
-Test for connection establishing timeout of B2G Presentation API at receiver side
-
-
-
diff --git a/dom/presentation/tests/mochitest/test_presentation_tcp_receiver_establish_connection_unknown_content_type.js b/dom/presentation/tests/mochitest/test_presentation_tcp_receiver_establish_connection_unknown_content_type.js
deleted file mode 100644
index d73f84cf8a..0000000000
--- a/dom/presentation/tests/mochitest/test_presentation_tcp_receiver_establish_connection_unknown_content_type.js
+++ /dev/null
@@ -1,88 +0,0 @@
-'use strict';
-
-var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('PresentationSessionChromeScript.js'));
-var receiverUrl = SimpleTest.getTestFileURL('file_presentation_unknown_content_type.test');
-
-var obs = SpecialPowers.Cc['@mozilla.org/observer-service;1']
-          .getService(SpecialPowers.Ci.nsIObserverService);
-
-var receiverIframe;
-
-function setup() {
-  return new Promise(function(aResolve, aReject) {
-    gScript.sendAsyncMessage('trigger-device-add');
-
-    receiverIframe = document.createElement('iframe');
-    receiverIframe.setAttribute('mozbrowser', 'true');
-    receiverIframe.setAttribute('mozpresentation', receiverUrl);
-    receiverIframe.setAttribute('src', receiverUrl);
-    var oop = location.pathname.indexOf('_inproc') == -1;
-    receiverIframe.setAttribute("remote", oop);
-
-    var promise = new Promise(function(aResolve, aReject) {
-      document.body.appendChild(receiverIframe);
-
-      aResolve(receiverIframe);
-    });
-    obs.notifyObservers(promise, 'setup-request-promise', null);
-
-    aResolve();
-  });
-}
-
-function testIncomingSessionRequestReceiverLaunchUnknownContentType() {
-  let promise = Promise.all([
-    new Promise(function(aResolve, aReject) {
-      gScript.addMessageListener('receiver-launching', function launchReceiverHandler(aSessionId) {
-        gScript.removeMessageListener('receiver-launching', launchReceiverHandler);
-        info('Trying to launch receiver page.');
-
-        receiverIframe.addEventListener('mozbrowserclose', function() {
-          ok(true, 'observe receiver window closed');
-          aResolve();
-        });
-      });
-    }),
-    new Promise(function(aResolve, aReject) {
-      gScript.addMessageListener('control-channel-closed', function controlChannelClosedHandler(aReason) {
-        gScript.removeMessageListener('control-channel-closed', controlChannelClosedHandler);
-        is(aReason, 0x80530020 /* NS_ERROR_DOM_OPERATION_ERR */, 'The control channel is closed due to load failure.');
-        aResolve();
-      });
-    })
-  ]);
-
-  gScript.sendAsyncMessage('trigger-incoming-session-request', receiverUrl);
-  return promise;
-}
-
-function teardown() {
-  gScript.addMessageListener('teardown-complete', function teardownCompleteHandler() {
-    gScript.removeMessageListener('teardown-complete', teardownCompleteHandler);
-    gScript.destroy();
-    SimpleTest.finish();
-  });
-
-  gScript.sendAsyncMessage('teardown');
-}
-
-function runTests() {
-  setup().
-  then(testIncomingSessionRequestReceiverLaunchUnknownContentType).
-  then(teardown);
-}
-
-SimpleTest.waitForExplicitFinish();
-SpecialPowers.pushPermissions([
-  {type: 'presentation-device-manage', allow: false, context: document},
-  {type: 'browser', allow: true, context: document},
-], function() {
-  SpecialPowers.pushPrefEnv({ 'set': [['dom.presentation.enabled', true],
-                                      ["dom.presentation.controller.enabled", true],
-                                      ["dom.presentation.receiver.enabled", true],
-                                      ['dom.presentation.session_transport.data_channel.enable', false],
-                                      ['dom.mozBrowserFramesEnabled', true],
-                                      ["network.disable.ipc.security", true],
-                                      ['dom.ipc.tabs.disabled', false]]},
-                            runTests);
-});
diff --git a/dom/presentation/tests/mochitest/test_presentation_tcp_receiver_establish_connection_unknown_content_type_inproc.html b/dom/presentation/tests/mochitest/test_presentation_tcp_receiver_establish_connection_unknown_content_type_inproc.html
deleted file mode 100644
index 8ade1d72d7..0000000000
--- a/dom/presentation/tests/mochitest/test_presentation_tcp_receiver_establish_connection_unknown_content_type_inproc.html
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-  
-  Test for unknown content type of B2G Presentation API at receiver side
-  
-  
-
-
-Test for unknown content type of B2G Presentation API at receiver side
-    
-
-
diff --git a/dom/presentation/tests/mochitest/test_presentation_tcp_receiver_establish_connection_unknown_content_type_oop.html b/dom/presentation/tests/mochitest/test_presentation_tcp_receiver_establish_connection_unknown_content_type_oop.html
deleted file mode 100644
index b2d2d3c6eb..0000000000
--- a/dom/presentation/tests/mochitest/test_presentation_tcp_receiver_establish_connection_unknown_content_type_oop.html
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-  
-  Test for unknown content type of B2G Presentation API at receiver side (OOP)
-  
-  
-
-
-Test for unknown content type of B2G Presentation API at receiver side (OOP)
-    
-
-
diff --git a/dom/presentation/tests/mochitest/test_presentation_tcp_receiver_oop.html b/dom/presentation/tests/mochitest/test_presentation_tcp_receiver_oop.html
deleted file mode 100644
index bfbc7947a5..0000000000
--- a/dom/presentation/tests/mochitest/test_presentation_tcp_receiver_oop.html
+++ /dev/null
@@ -1,178 +0,0 @@
-
-
-
-
-  
-  Test for B2G PresentationConnection API at receiver side (OOP)
-  
-  
-
-
-Test B2G PresentationConnection API at receiver side (OOP)
-

- -

-
-
-
diff --git a/dom/presentation/tests/mochitest/test_presentation_tcp_sender.html b/dom/presentation/tests/mochitest/test_presentation_tcp_sender.html
deleted file mode 100644
index 8df34c884f..0000000000
--- a/dom/presentation/tests/mochitest/test_presentation_tcp_sender.html
+++ /dev/null
@@ -1,260 +0,0 @@
-
-
-
-
-  
-  Test for B2G Presentation API at sender side
-  
-  
-
-
-Test for B2G Presentation API at sender side
-
-
-
diff --git a/dom/presentation/tests/mochitest/test_presentation_tcp_sender_default_request.html b/dom/presentation/tests/mochitest/test_presentation_tcp_sender_default_request.html
deleted file mode 100644
index 60247ec986..0000000000
--- a/dom/presentation/tests/mochitest/test_presentation_tcp_sender_default_request.html
+++ /dev/null
@@ -1,151 +0,0 @@
-
-
-
-
-  
-  Test default request for B2G Presentation API at sender side
-  
-  
-
-
-Test default request for B2G Presentation API at sender side
-
-
-
diff --git a/dom/presentation/tests/mochitest/test_presentation_tcp_sender_disconnect.html b/dom/presentation/tests/mochitest/test_presentation_tcp_sender_disconnect.html
deleted file mode 100644
index a95da104f3..0000000000
--- a/dom/presentation/tests/mochitest/test_presentation_tcp_sender_disconnect.html
+++ /dev/null
@@ -1,160 +0,0 @@
-
-
-
-
-  
-  Test for disconnection of B2G Presentation API at sender side
-  
-  
-
-
-Test for disconnection of B2G Presentation API at sender side
-
-
-
diff --git a/dom/presentation/tests/mochitest/test_presentation_tcp_sender_establish_connection_error.html b/dom/presentation/tests/mochitest/test_presentation_tcp_sender_establish_connection_error.html
deleted file mode 100644
index 557ae71a6f..0000000000
--- a/dom/presentation/tests/mochitest/test_presentation_tcp_sender_establish_connection_error.html
+++ /dev/null
@@ -1,514 +0,0 @@
-
-
-
-
-  
-  Test for connection establishing errors of B2G Presentation API at sender side
-  
-  
-
-
-Test for connection establishing errors of B2G Presentation API at sender side
-
-
-
diff --git a/dom/presentation/tests/mochitest/test_presentation_terminate.js b/dom/presentation/tests/mochitest/test_presentation_terminate.js
deleted file mode 100644
index 8ebfd9d641..0000000000
--- a/dom/presentation/tests/mochitest/test_presentation_terminate.js
+++ /dev/null
@@ -1,243 +0,0 @@
-'use strict';
-
-SimpleTest.waitForExplicitFinish();
-SimpleTest.requestFlakyTimeout('Test for guarantee not firing async event');
-
-function debug(str) {
-  // info(str);
-}
-
-var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('PresentationSessionChromeScript1UA.js'));
-var receiverUrl = SimpleTest.getTestFileURL('file_presentation_terminate.html');
-var request;
-var connection;
-var receiverIframe;
-
-function setup() {
-  gScript.addMessageListener('device-prompt', function devicePromptHandler() {
-    debug('Got message: device-prompt');
-    gScript.removeMessageListener('device-prompt', devicePromptHandler);
-    gScript.sendAsyncMessage('trigger-device-prompt-select');
-  });
-
-  gScript.addMessageListener('control-channel-established', function controlChannelEstablishedHandler() {
-    gScript.removeMessageListener('control-channel-established',
-                                  controlChannelEstablishedHandler);
-    gScript.sendAsyncMessage('trigger-control-channel-open');
-  });
-
-  gScript.addMessageListener('sender-launch', function senderLaunchHandler(url) {
-    debug('Got message: sender-launch');
-    gScript.removeMessageListener('sender-launch', senderLaunchHandler);
-    is(url, receiverUrl, 'Receiver: should receive the same url');
-    receiverIframe = document.createElement('iframe');
-    receiverIframe.setAttribute('mozbrowser', 'true');
-    receiverIframe.setAttribute('mozpresentation', receiverUrl);
-    var oop = location.pathname.indexOf('_inproc') == -1;
-    receiverIframe.setAttribute('remote', oop);
-
-    receiverIframe.setAttribute('src', receiverUrl);
-    receiverIframe.addEventListener('mozbrowserloadend', function mozbrowserloadendHander() {
-      receiverIframe.removeEventListener('mozbrowserloadend', mozbrowserloadendHander);
-      info('Receiver loaded.');
-    });
-
-    // This event is triggered when the iframe calls 'alert'.
-    receiverIframe.addEventListener('mozbrowsershowmodalprompt', function receiverListener(evt) {
-      var message = evt.detail.message;
-      if (/^OK /.exec(message)) {
-        ok(true, message.replace(/^OK /, ''));
-      } else if (/^KO /.exec(message)) {
-        ok(false, message.replace(/^KO /, ''));
-      } else if (/^INFO /.exec(message)) {
-        info(message.replace(/^INFO /, ''));
-      } else if (/^COMMAND /.exec(message)) {
-        var command = JSON.parse(message.replace(/^COMMAND /, ''));
-        gScript.sendAsyncMessage(command.name, command.data);
-      } else if (/^DONE$/.exec(message)) {
-        ok(true, 'Messaging from iframe complete.');
-        receiverIframe.removeEventListener('mozbrowsershowmodalprompt',
-                                            receiverListener);
-      }
-    }, false);
-
-    var promise = new Promise(function(aResolve, aReject) {
-      document.body.appendChild(receiverIframe);
-      aResolve(receiverIframe);
-    });
-
-    var obs = SpecialPowers.Cc['@mozilla.org/observer-service;1']
-                           .getService(SpecialPowers.Ci.nsIObserverService);
-    obs.notifyObservers(promise, 'setup-request-promise', null);
-  });
-
-  gScript.addMessageListener('promise-setup-ready', function promiseSetupReadyHandler() {
-    debug('Got message: promise-setup-ready');
-    gScript.removeMessageListener('promise-setup-ready',
-                                  promiseSetupReadyHandler);
-    gScript.sendAsyncMessage('trigger-on-session-request', receiverUrl);
-  });
-
-  return Promise.resolve();
-}
-
-function testCreateRequest() {
-  return new Promise(function(aResolve, aReject) {
-    info('Sender: --- testCreateRequest ---');
-    request = new PresentationRequest(receiverUrl);
-    request.getAvailability().then((aAvailability) => {
-      is(aAvailability.value, false, "Sender: should have no available device after setup");
-      aAvailability.onchange = function() {
-        aAvailability.onchange = null;
-        ok(aAvailability.value, 'Sender: Device should be available.');
-        aResolve();
-      }
-
-      gScript.sendAsyncMessage('trigger-device-add');
-    }).catch((aError) => {
-      ok(false, 'Sender: Error occurred when getting availability: ' + aError);
-      teardown();
-      aReject();
-    });
-  });
-}
-
-function testStartConnection() {
-  return new Promise(function(aResolve, aReject) {
-    request.start().then((aConnection) => {
-      connection = aConnection;
-      ok(connection, 'Sender: Connection should be available.');
-      ok(connection.id, 'Sender: Connection ID should be set.');
-      is(connection.state, 'connecting', 'Sender: The initial state should be connecting.');
-      connection.onconnect = function() {
-        connection.onconnect = null;
-        is(connection.state, 'connected', 'Connection should be connected.');
-        aResolve();
-      };
-
-      info('Sender: test terminate at connecting state');
-      connection.onterminate = function() {
-        connection.onterminate = null;
-        ok(false, 'Should not be able to terminate at connecting state');
-        aReject();
-      }
-      connection.terminate();
-    }).catch((aError) => {
-      ok(false, 'Sender: Error occurred when establishing a connection: ' + aError);
-      teardown();
-      aReject();
-    });
-  });
-}
-
-function testConnectionTerminate() {
-  return new Promise(function(aResolve, aReject) {
-    info('Sender: --- testConnectionTerminate---');
-    connection.onterminate = function() {
-      connection.onterminate = null;
-      is(connection.state, 'terminated', 'Sender: Connection should be terminated.');
-    };
-    gScript.addMessageListener('control-channel-established', function controlChannelEstablishedHandler() {
-      gScript.removeMessageListener('control-channel-established',
-                                    controlChannelEstablishedHandler);
-      gScript.sendAsyncMessage('trigger-control-channel-open');
-    });
-    gScript.addMessageListener('sender-terminate', function senderTerminateHandler() {
-      gScript.removeMessageListener('sender-terminate',
-                                    senderTerminateHandler);
-
-      Promise.all([
-        new Promise((resolve) => {
-          gScript.addMessageListener('device-disconnected', function deviceDisconnectedHandler() {
-            gScript.removeMessageListener('device-disconnected', deviceDisconnectedHandler);
-            ok(true, 'observe device disconnect');
-            resolve();
-          });
-        }),
-        new Promise((resolve) => {
-          receiverIframe.addEventListener('mozbrowserclose', function() {
-            ok(true, 'observe receiver page closing');
-            resolve();
-          });
-        }),
-      ]).then(aResolve);
-
-      gScript.sendAsyncMessage('trigger-on-terminate-request');
-    });
-    gScript.addMessageListener('ready-to-terminate', function onReadyToTerminate() {
-      gScript.removeMessageListener('ready-to-terminate', onReadyToTerminate);
-      connection.terminate();
-
-      // test unexpected close right after terminate
-      connection.onclose = function() {
-        ok(false, 'close after terminate should do nothing');
-      };
-      connection.close();
-    });
-  });
-}
-
-function testSendAfterTerminate() {
-  return new Promise(function(aResolve, aReject) {
-    try {
-      connection.send('something');
-      ok(false, 'PresentationConnection.send should be failed');
-    } catch (e) {
-      is(e.name, 'InvalidStateError', 'Must throw InvalidStateError');
-    }
-    aResolve();
-  });
-}
-
-function testCloseAfterTerminate() {
-  return Promise.race([
-      new Promise(function(aResolve, aReject) {
-        connection.onclose = function() {
-          connection.onclose = null;
-          ok(false, 'close at terminated state should do nothing');
-          aResolve();
-        };
-        connection.close();
-      }),
-      new Promise(function(aResolve, aReject) {
-        setTimeout(function() {
-          is(connection.state, 'terminated', 'Sender: Connection should be terminated.');
-          aResolve();
-        }, 3000);
-      }),
-  ]);
-}
-
-function teardown() {
-  gScript.addMessageListener('teardown-complete', function teardownCompleteHandler() {
-    debug('Got message: teardown-complete');
-    gScript.removeMessageListener('teardown-complete', teardownCompleteHandler);
-    gScript.destroy();
-    SimpleTest.finish();
-  });
-  gScript.sendAsyncMessage('teardown');
-}
-
-function runTests() {
-  setup().then(testCreateRequest)
-         .then(testStartConnection)
-         .then(testConnectionTerminate)
-         .then(testSendAfterTerminate)
-         .then(testCloseAfterTerminate)
-         .then(teardown);
-}
-
-SpecialPowers.pushPermissions([
-  {type: 'presentation-device-manage', allow: false, context: document},
-  {type: 'browser', allow: true, context: document},
-], () => {
-  SpecialPowers.pushPrefEnv({ 'set': [['dom.presentation.enabled', true],
-                                      ["dom.presentation.controller.enabled", true],
-                                      ["dom.presentation.receiver.enabled", true],
-                                      ['dom.presentation.test.enabled', true],
-                                      ['dom.mozBrowserFramesEnabled', true],
-                                      ["network.disable.ipc.security", true],
-                                      ['dom.ipc.tabs.disabled', false],
-                                      ['dom.presentation.test.stage', 0]]},
-                            runTests);
-});
diff --git a/dom/presentation/tests/mochitest/test_presentation_terminate_establish_connection_error.js b/dom/presentation/tests/mochitest/test_presentation_terminate_establish_connection_error.js
deleted file mode 100644
index a1d477aab0..0000000000
--- a/dom/presentation/tests/mochitest/test_presentation_terminate_establish_connection_error.js
+++ /dev/null
@@ -1,197 +0,0 @@
-'use strict';
-
-SimpleTest.waitForExplicitFinish();
-SimpleTest.requestFlakyTimeout('Test for guarantee not firing async event');
-
-function debug(str) {
-  // info(str);
-}
-
-var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('PresentationSessionChromeScript1UA.js'));
-var receiverUrl = SimpleTest.getTestFileURL('file_presentation_terminate_establish_connection_error.html');
-var request;
-var connection;
-var receiverIframe;
-
-function postMessageToIframe(aType) {
-  receiverIframe.src = receiverUrl + "#" +
-                       encodeURIComponent(JSON.stringify({ type: aType }));
-}
-
-function setup() {
-  gScript.addMessageListener('device-prompt', function devicePromptHandler() {
-    debug('Got message: device-prompt');
-    gScript.removeMessageListener('device-prompt', devicePromptHandler);
-    gScript.sendAsyncMessage('trigger-device-prompt-select');
-  });
-
-  gScript.addMessageListener('control-channel-established', function controlChannelEstablishedHandler() {
-    gScript.removeMessageListener('control-channel-established',
-                                  controlChannelEstablishedHandler);
-    gScript.sendAsyncMessage('trigger-control-channel-open');
-  });
-
-  gScript.addMessageListener('sender-launch', function senderLaunchHandler(url) {
-    debug('Got message: sender-launch');
-    gScript.removeMessageListener('sender-launch', senderLaunchHandler);
-    is(url, receiverUrl, 'Receiver: should receive the same url');
-    receiverIframe = document.createElement('iframe');
-    receiverIframe.setAttribute('mozbrowser', 'true');
-    receiverIframe.setAttribute('mozpresentation', receiverUrl);
-    var oop = location.pathname.indexOf('_inproc') == -1;
-    receiverIframe.setAttribute('remote', oop);
-
-    receiverIframe.setAttribute('src', receiverUrl);
-    receiverIframe.addEventListener('mozbrowserloadend', function mozbrowserloadendHander() {
-      receiverIframe.removeEventListener('mozbrowserloadend', mozbrowserloadendHander);
-      info('Receiver loaded.');
-    });
-
-    // This event is triggered when the iframe calls 'alert'.
-    receiverIframe.addEventListener('mozbrowsershowmodalprompt', function receiverListener(evt) {
-      var message = evt.detail.message;
-      if (/^OK /.exec(message)) {
-        ok(true, message.replace(/^OK /, ''));
-      } else if (/^KO /.exec(message)) {
-        ok(false, message.replace(/^KO /, ''));
-      } else if (/^INFO /.exec(message)) {
-        info(message.replace(/^INFO /, ''));
-      } else if (/^COMMAND /.exec(message)) {
-        var command = JSON.parse(message.replace(/^COMMAND /, ''));
-        gScript.sendAsyncMessage(command.name, command.data);
-      } else if (/^DONE$/.exec(message)) {
-        ok(true, 'Messaging from iframe complete.');
-        receiverIframe.removeEventListener('mozbrowsershowmodalprompt',
-                                            receiverListener);
-      }
-    }, false);
-
-    var promise = new Promise(function(aResolve, aReject) {
-      document.body.appendChild(receiverIframe);
-      aResolve(receiverIframe);
-    });
-
-    var obs = SpecialPowers.Cc['@mozilla.org/observer-service;1']
-                           .getService(SpecialPowers.Ci.nsIObserverService);
-    obs.notifyObservers(promise, 'setup-request-promise', null);
-  });
-
-  gScript.addMessageListener('promise-setup-ready', function promiseSetupReadyHandler() {
-    debug('Got message: promise-setup-ready');
-    gScript.removeMessageListener('promise-setup-ready',
-                                  promiseSetupReadyHandler);
-    gScript.sendAsyncMessage('trigger-on-session-request', receiverUrl);
-  });
-
-  return Promise.resolve();
-}
-
-function testCreateRequest() {
-  return new Promise(function(aResolve, aReject) {
-    info('Sender: --- testCreateRequest ---');
-    request = new PresentationRequest(receiverUrl);
-    request.getAvailability().then((aAvailability) => {
-      is(aAvailability.value, false, "Sender: should have no available device after setup");
-      aAvailability.onchange = function() {
-        aAvailability.onchange = null;
-        ok(aAvailability.value, 'Sender: Device should be available.');
-        aResolve();
-      }
-
-      gScript.sendAsyncMessage('trigger-device-add');
-    }).catch((aError) => {
-      ok(false, 'Sender: Error occurred when getting availability: ' + aError);
-      teardown();
-      aReject();
-    });
-  });
-}
-
-function testStartConnection() {
-  return new Promise(function(aResolve, aReject) {
-    request.start().then((aConnection) => {
-      connection = aConnection;
-      ok(connection, 'Sender: Connection should be available.');
-      ok(connection.id, 'Sender: Connection ID should be set.');
-      is(connection.state, 'connecting', 'Sender: The initial state should be connecting.');
-      connection.onconnect = function() {
-        connection.onconnect = null;
-        is(connection.state, 'connected', 'Connection should be connected.');
-        aResolve();
-      };
-    }).catch((aError) => {
-      ok(false, 'Sender: Error occurred when establishing a connection: ' + aError);
-      teardown();
-      aReject();
-    });
-  });
-}
-
-function testConnectionTerminate() {
-  info('Sender: --- testConnectionTerminate---');
-  let promise = Promise.all([
-    new Promise(function(aResolve, aReject) {
-      connection.onclose = function() {
-        connection.onclose = null;
-        is(connection.state, 'closed', 'Sender: Connection should be closed.');
-        aResolve();
-      };
-    }),
-    new Promise(function(aResolve, aReject) {
-      function deviceDisconnectedHandler() {
-        gScript.removeMessageListener('device-disconnected', deviceDisconnectedHandler);
-        ok(true, 'should not receive device disconnect');
-        aResolve();
-      }
-
-      gScript.addMessageListener('device-disconnected', deviceDisconnectedHandler);
-    }),
-    new Promise(function(aResolve, aReject) {
-      receiverIframe.addEventListener('mozbrowserclose', function() {
-        ok(true, 'observe receiver page closing');
-        aResolve();
-      });
-    })
-  ]);
-
-  gScript.addMessageListener('prepare-for-terminate', function prepareForTerminateHandler() {
-    debug('Got message: prepare-for-terminate');
-    gScript.removeMessageListener('prepare-for-terminate', prepareForTerminateHandler);
-    gScript.sendAsyncMessage('trigger-control-channel-error');
-    postMessageToIframe('ready-to-terminate');
-  });
-
-  return promise;
-}
-
-function teardown() {
-  gScript.addMessageListener('teardown-complete', function teardownCompleteHandler() {
-    debug('Got message: teardown-complete');
-    gScript.removeMessageListener('teardown-complete', teardownCompleteHandler);
-    gScript.destroy();
-    SimpleTest.finish();
-  });
-  gScript.sendAsyncMessage('teardown');
-}
-
-function runTests() {
-  setup().then(testCreateRequest)
-         .then(testStartConnection)
-         .then(testConnectionTerminate)
-         .then(teardown);
-}
-
-SpecialPowers.pushPermissions([
-  {type: 'presentation-device-manage', allow: false, context: document},
-  {type: 'browser', allow: true, context: document},
-], () => {
-  SpecialPowers.pushPrefEnv({ 'set': [['dom.presentation.enabled', true],
-                                      ["dom.presentation.controller.enabled", true],
-                                      ["dom.presentation.receiver.enabled", true],
-                                      ['dom.presentation.test.enabled', true],
-                                      ['dom.mozBrowserFramesEnabled', true],
-                                      ["network.disable.ipc.security", true],
-                                      ['dom.ipc.tabs.disabled', false],
-                                      ['dom.presentation.test.stage', 0]]},
-                            runTests);
-});
diff --git a/dom/presentation/tests/mochitest/test_presentation_terminate_establish_connection_error_inproc.html b/dom/presentation/tests/mochitest/test_presentation_terminate_establish_connection_error_inproc.html
deleted file mode 100644
index ccf0767f1f..0000000000
--- a/dom/presentation/tests/mochitest/test_presentation_terminate_establish_connection_error_inproc.html
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-  
-  
-    
-    Test for control channel establish error during PresentationConnection.terminate()
-    
-    
-  
-  
-    
-      Test for constrol channel establish error during PresentationConnection.terminate()
-    
-  
-
diff --git a/dom/presentation/tests/mochitest/test_presentation_terminate_establish_connection_error_oop.html b/dom/presentation/tests/mochitest/test_presentation_terminate_establish_connection_error_oop.html
deleted file mode 100644
index ccf0767f1f..0000000000
--- a/dom/presentation/tests/mochitest/test_presentation_terminate_establish_connection_error_oop.html
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-  
-  
-    
-    Test for control channel establish error during PresentationConnection.terminate()
-    
-    
-  
-  
-    
-      Test for constrol channel establish error during PresentationConnection.terminate()
-    
-  
-
diff --git a/dom/presentation/tests/mochitest/test_presentation_terminate_inproc.html b/dom/presentation/tests/mochitest/test_presentation_terminate_inproc.html
deleted file mode 100644
index 33bbcda572..0000000000
--- a/dom/presentation/tests/mochitest/test_presentation_terminate_inproc.html
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-  
-  
-    
-    Test for PresentationConnection.terminate()
-    
-    
-  
-  
-    
-      Test for PresentationConnection.terminate()
-    
-  
-
diff --git a/dom/presentation/tests/mochitest/test_presentation_terminate_oop.html b/dom/presentation/tests/mochitest/test_presentation_terminate_oop.html
deleted file mode 100644
index 33bbcda572..0000000000
--- a/dom/presentation/tests/mochitest/test_presentation_terminate_oop.html
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-  
-  
-    
-    Test for PresentationConnection.terminate()
-    
-    
-  
-  
-    
-      Test for PresentationConnection.terminate()
-    
-  
-
diff --git a/dom/presentation/tests/xpcshell/test_multicast_dns_device_provider.js b/dom/presentation/tests/xpcshell/test_multicast_dns_device_provider.js
deleted file mode 100644
index 137a5609a6..0000000000
--- a/dom/presentation/tests/xpcshell/test_multicast_dns_device_provider.js
+++ /dev/null
@@ -1,1318 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-/* global Services, do_register_cleanup, do_test_pending */
-
-"use strict";
-
-const { classes: Cc, interfaces: Ci, manager: Cm, results: Cr, utils: Cu } = Components;
-
-Cu.import("resource://gre/modules/Promise.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-const INFO_CONTRACT_ID = "@mozilla.org/toolkit/components/mdnsresponder/dns-info;1";
-const PROVIDER_CONTRACT_ID = "@mozilla.org/presentation-device/multicastdns-provider;1";
-const SD_CONTRACT_ID = "@mozilla.org/toolkit/components/mdnsresponder/dns-sd;1";
-const UUID_CONTRACT_ID = "@mozilla.org/uuid-generator;1";
-const SERVER_CONTRACT_ID = "@mozilla.org/presentation/control-service;1";
-
-const PREF_DISCOVERY = "dom.presentation.discovery.enabled";
-const PREF_DISCOVERABLE = "dom.presentation.discoverable";
-const PREF_DEVICENAME= "dom.presentation.device.name";
-
-const LATEST_VERSION = 1;
-const SERVICE_TYPE = "_presentation-ctrl._tcp";
-const versionAttr = Cc["@mozilla.org/hash-property-bag;1"]
-                      .createInstance(Ci.nsIWritablePropertyBag2);
-versionAttr.setPropertyAsUint32("version", LATEST_VERSION);
-
-var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
-
-function sleep(aMs) {
-  let deferred = Promise.defer();
-
-  let timer = Cc["@mozilla.org/timer;1"]
-                .createInstance(Ci.nsITimer);
-
-  timer.initWithCallback({
-    notify: function () {
-      deferred.resolve();
-    },
-  }, aMs, timer.TYPE_ONE_SHOT);
-
-  return deferred.promise;
-}
-
-function MockFactory(aClass) {
-  this._cls = aClass;
-}
-MockFactory.prototype = {
-  createInstance: function(aOuter, aIID) {
-    if (aOuter) {
-      throw Cr.NS_ERROR_NO_AGGREGATION;
-    }
-    switch(typeof(this._cls)) {
-      case "function":
-        return new this._cls().QueryInterface(aIID);
-      case "object":
-        return this._cls.QueryInterface(aIID);
-      default:
-        return null;
-    }
-  },
-  lockFactory: function(aLock) {
-    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-  },
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory])
-};
-
-function ContractHook(aContractID, aClass) {
-  this._contractID = aContractID;
-  this.classID = Cc[UUID_CONTRACT_ID].getService(Ci.nsIUUIDGenerator).generateUUID();
-  this._newFactory = new MockFactory(aClass);
-
-  if (!this.hookedMap.has(this._contractID)) {
-    this.hookedMap.set(this._contractID, []);
-  }
-
-  this.init();
-}
-
-ContractHook.prototype = {
-  hookedMap: new Map(), // remember only the most original factory.
-
-  init: function() {
-    this.reset();
-
-    let oldContract = this.unregister();
-    this.hookedMap.get(this._contractID).push(oldContract);
-    registrar.registerFactory(this.classID,
-                              "",
-                              this._contractID,
-                              this._newFactory);
-
-    do_register_cleanup(() => { this.cleanup.apply(this); });
-  },
-
-  reset: function() {},
-
-  cleanup: function() {
-    this.reset();
-
-    this.unregister();
-    let prevContract = this.hookedMap.get(this._contractID).pop();
-
-    if (prevContract.factory) {
-      registrar.registerFactory(prevContract.classID,
-                                "",
-                                this._contractID,
-                                prevContract.factory);
-    }
-  },
-
-  unregister: function() {
-    var classID, factory;
-
-    try {
-      classID = registrar.contractIDToCID(this._contractID);
-      factory = Cm.getClassObject(Cc[this._contractID], Ci.nsIFactory);
-    } catch (ex) {
-      classID = "";
-      factory = null;
-    }
-
-    if (factory) {
-      registrar.unregisterFactory(classID, factory);
-    }
-
-    return { classID: classID, factory: factory };
-  }
-};
-
-function MockDNSServiceInfo() {}
-MockDNSServiceInfo.prototype = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIDNSServiceInfo]),
-
-  set host(aHost) {
-    this._host = aHost;
-  },
-
-  get host() {
-    return this._host;
-  },
-
-  set address(aAddress) {
-    this._address = aAddress;
-  },
-
-  get address() {
-    return this._address;
-  },
-
-  set port(aPort) {
-    this._port = aPort;
-  },
-
-  get port() {
-    return this._port;
-  },
-
-  set serviceName(aServiceName) {
-    this._serviceName = aServiceName;
-  },
-
-  get serviceName() {
-    return this._serviceName;
-  },
-
-  set serviceType(aServiceType) {
-    this._serviceType = aServiceType;
-  },
-
-  get serviceType() {
-    return this._serviceType;
-  },
-
-  set domainName(aDomainName) {
-    this._domainName = aDomainName;
-  },
-
-  get domainName() {
-    return this._domainName;
-  },
-
-  set attributes(aAttributes) {
-    this._attributes = aAttributes;
-  },
-
-  get attributes() {
-    return this._attributes;
-  }
-};
-
-function TestPresentationDeviceListener() {
-  this.devices = {};
-}
-TestPresentationDeviceListener.prototype = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDeviceListener,
-                                         Ci.nsISupportsWeakReference]),
-
-  addDevice: function(device) { this.devices[device.id] = device; },
-  removeDevice: function(device) { delete this.devices[device.id]; },
-  updateDevice: function(device) { this.devices[device.id] = device; },
-  onSessionRequest: function(device, url, presentationId, controlChannel) {},
-
-  count: function() {
-    var size = 0, key;
-    for (key in this.devices) {
-        if (this.devices.hasOwnProperty(key)) {
-          ++size;
-        }
-    }
-    return size;
-  }
-};
-
-function createDevice(host, port, serviceName, serviceType, domainName, attributes) {
-  let device = new MockDNSServiceInfo();
-  device.host = host || "";
-  device.port = port || 0;
-  device.address = host || "";
-  device.serviceName = serviceName || "";
-  device.serviceType = serviceType || "";
-  device.domainName = domainName || "";
-  device.attributes = attributes || versionAttr;
-  return device;
-}
-
-function registerService() {
-  Services.prefs.setBoolPref(PREF_DISCOVERABLE, true);
-
-  let deferred = Promise.defer();
-
-  let mockObj = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIDNSServiceDiscovery]),
-    startDiscovery: function(serviceType, listener) {},
-    registerService: function(serviceInfo, listener) {
-      deferred.resolve();
-      this.serviceRegistered++;
-      return {
-        QueryInterface: XPCOMUtils.generateQI([Ci.nsICancelable]),
-        cancel: function() {
-          this.serviceUnregistered++;
-        }.bind(this)
-      };
-    },
-    resolveService: function(serviceInfo, listener) {},
-    serviceRegistered: 0,
-    serviceUnregistered: 0
-  };
-  let contractHook = new ContractHook(SD_CONTRACT_ID, mockObj);
-  let provider = Cc[PROVIDER_CONTRACT_ID].createInstance(Ci.nsIPresentationDeviceProvider);
-
-  Assert.equal(mockObj.serviceRegistered, 0);
-  Assert.equal(mockObj.serviceUnregistered, 0);
-
-  // Register
-  provider.listener = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDeviceListener,
-                                           Ci.nsISupportsWeakReference]),
-    addDevice: function(device) {},
-    removeDevice: function(device) {},
-    updateDevice: function(device) {},
-  };
-
-  deferred.promise.then(function() {
-    Assert.equal(mockObj.serviceRegistered, 1);
-    Assert.equal(mockObj.serviceUnregistered, 0);
-
-    // Unregister
-    provider.listener = null;
-    Assert.equal(mockObj.serviceRegistered, 1);
-    Assert.equal(mockObj.serviceUnregistered, 1);
-
-    run_next_test();
-  });
-}
-
-function noRegisterService() {
-  Services.prefs.setBoolPref(PREF_DISCOVERABLE, false);
-
-  let deferred = Promise.defer();
-
-  let mockObj = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIDNSServiceDiscovery]),
-    startDiscovery: function(serviceType, listener) {},
-    registerService: function(serviceInfo, listener) {
-      deferred.resolve();
-      Assert.ok(false, "should not register service if not discoverable");
-    },
-    resolveService: function(serviceInfo, listener) {},
-  };
-
-  let contractHook = new ContractHook(SD_CONTRACT_ID, mockObj);
-  let provider = Cc[PROVIDER_CONTRACT_ID].createInstance(Ci.nsIPresentationDeviceProvider);
-
-  // Try register
-  provider.listener = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDeviceListener,
-                                           Ci.nsISupportsWeakReference]),
-    addDevice: function(device) {},
-    removeDevice: function(device) {},
-    updateDevice: function(device) {},
-  };
-
-  let race = Promise.race([
-    deferred.promise,
-    sleep(1000),
-  ]);
-
-  race.then(() => {
-    provider.listener = null;
-
-    run_next_test();
-  });
-}
-
-function registerServiceDynamically() {
-  Services.prefs.setBoolPref(PREF_DISCOVERABLE, false);
-
-  let deferred = Promise.defer();
-
-  let mockObj = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIDNSServiceDiscovery]),
-    startDiscovery: function(serviceType, listener) {},
-    registerService: function(serviceInfo, listener) {
-      deferred.resolve();
-      this.serviceRegistered++;
-      return {
-        QueryInterface: XPCOMUtils.generateQI([Ci.nsICancelable]),
-        cancel: function() {
-          this.serviceUnregistered++;
-        }.bind(this)
-      };
-    },
-    resolveService: function(serviceInfo, listener) {},
-    serviceRegistered: 0,
-    serviceUnregistered: 0
-  };
-  let contractHook = new ContractHook(SD_CONTRACT_ID, mockObj);
-  let provider = Cc[PROVIDER_CONTRACT_ID].createInstance(Ci.nsIPresentationDeviceProvider);
-
-  Assert.equal(mockObj.serviceRegistered, 0);
-  Assert.equal(mockObj.serviceRegistered, 0);
-
-  // Try Register
-  provider.listener = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDeviceListener,
-                                           Ci.nsISupportsWeakReference]),
-    addDevice: function(device) {},
-    removeDevice: function(device) {},
-    updateDevice: function(device) {},
-  };
-
-  Assert.equal(mockObj.serviceRegistered, 0);
-  Assert.equal(mockObj.serviceUnregistered, 0);
-
-  // Enable registration
-  Services.prefs.setBoolPref(PREF_DISCOVERABLE, true);
-
-  deferred.promise.then(function() {
-    Assert.equal(mockObj.serviceRegistered, 1);
-    Assert.equal(mockObj.serviceUnregistered, 0);
-
-    // Disable registration
-    Services.prefs.setBoolPref(PREF_DISCOVERABLE, false);
-    Assert.equal(mockObj.serviceRegistered, 1);
-    Assert.equal(mockObj.serviceUnregistered, 1);
-
-    // Try unregister
-    provider.listener = null;
-    Assert.equal(mockObj.serviceRegistered, 1);
-    Assert.equal(mockObj.serviceUnregistered, 1);
-
-    run_next_test();
-  });
-}
-
-function addDevice() {
-  Services.prefs.setBoolPref(PREF_DISCOVERY, true);
-
-  let mockDevice = createDevice("device.local",
-                                12345,
-                                "service.name",
-                                SERVICE_TYPE);
-  let mockObj = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIDNSServiceDiscovery]),
-    startDiscovery: function(serviceType, listener) {
-      listener.onDiscoveryStarted(serviceType);
-      listener.onServiceFound(createDevice("",
-                                           0,
-                                           mockDevice.serviceName,
-                                           mockDevice.serviceType));
-      return {
-        QueryInterface: XPCOMUtils.generateQI([Ci.nsICancelable]),
-        cancel: function() {}
-      };
-    },
-    registerService: function(serviceInfo, listener) {},
-    resolveService: function(serviceInfo, listener) {
-      Assert.equal(serviceInfo.serviceName, mockDevice.serviceName);
-      Assert.equal(serviceInfo.serviceType, mockDevice.serviceType);
-      listener.onServiceResolved(createDevice(mockDevice.host,
-                                              mockDevice.port,
-                                              mockDevice.serviceName,
-                                              mockDevice.serviceType));
-    }
-  };
-
-  let contractHook = new ContractHook(SD_CONTRACT_ID, mockObj);
-  let provider = Cc[PROVIDER_CONTRACT_ID].createInstance(Ci.nsIPresentationDeviceProvider);
-  let listener = new TestPresentationDeviceListener();
-  Assert.equal(listener.count(), 0);
-
-  // Start discovery
-  provider.listener = listener;
-  Assert.equal(listener.count(), 1);
-
-  // Force discovery again
-  provider.forceDiscovery();
-  Assert.equal(listener.count(), 1);
-
-  provider.listener = null;
-  Assert.equal(listener.count(), 1);
-
-  run_next_test();
-}
-
-function filterDevice() {
-  Services.prefs.setBoolPref(PREF_DISCOVERY, true);
-
-  let mockDevice = createDevice("device.local",
-                                12345,
-                                "service.name",
-                                SERVICE_TYPE);
-  let mockObj = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIDNSServiceDiscovery]),
-    startDiscovery: function(serviceType, listener) {
-      listener.onDiscoveryStarted(serviceType);
-      listener.onServiceFound(createDevice("",
-                                           0,
-                                           mockDevice.serviceName,
-                                           mockDevice.serviceType));
-      return {
-        QueryInterface: XPCOMUtils.generateQI([Ci.nsICancelable]),
-        cancel: function() {}
-      };
-    },
-    registerService: function(serviceInfo, listener) {},
-    resolveService: function(serviceInfo, listener) {
-      Assert.equal(serviceInfo.serviceName, mockDevice.serviceName);
-      Assert.equal(serviceInfo.serviceType, mockDevice.serviceType);
-      listener.onServiceResolved(createDevice(mockDevice.host,
-                                              mockDevice.port,
-                                              mockDevice.serviceName,
-                                              mockDevice.serviceType));
-    }
-  };
-
-  let contractHook = new ContractHook(SD_CONTRACT_ID, mockObj);
-  let provider = Cc[PROVIDER_CONTRACT_ID].createInstance(Ci.nsIPresentationDeviceProvider);
-  let listener = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDeviceListener,
-                                           Ci.nsISupportsWeakReference]),
-    addDevice: function(device) {
-      let tests = [
-        { requestedUrl: "app://fling-player.gaiamobile.org/index.html", supported: true },
-        { requestedUrl: "app://notification-receiver.gaiamobile.org/index.html", supported: true },
-        { requestedUrl: "http://example.com", supported: true },
-        { requestedUrl: "https://example.com", supported: true },
-        { requestedUrl: "ftp://example.com", supported: false },
-        { requestedUrl: "app://unknown-app-id", supported: false },
-        { requestedUrl: "unknowSchem://example.com", supported: false },
-      ];
-
-      for (let test of tests) {
-        Assert.equal(device.isRequestedUrlSupported(test.requestedUrl), test.supported);
-      }
-
-      provider.listener = null;
-      run_next_test();
-    },
-    updateDevice: function() {},
-    removeDevice: function() {},
-    onSessionRequest: function() {},
-  };
-
-  provider.listener = listener;
-}
-
-function handleSessionRequest() {
-  Services.prefs.setBoolPref(PREF_DISCOVERY, true);
-  Services.prefs.setBoolPref(PREF_DISCOVERABLE, false);
-
-  const testUrl = "http://example.com";
-  const testPresentationId = "test-presentation-id";
-  const testDeviceName = "test-device-name";
-
-  Services.prefs.setCharPref(PREF_DEVICENAME, testDeviceName);
-
-  let mockDevice = createDevice("device.local",
-                                12345,
-                                "service.name",
-                                SERVICE_TYPE);
-  let mockSDObj = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIDNSServiceDiscovery]),
-    startDiscovery: function(serviceType, listener) {
-      listener.onDiscoveryStarted(serviceType);
-      listener.onServiceFound(createDevice("",
-                                           0,
-                                           mockDevice.serviceName,
-                                           mockDevice.serviceType));
-      return {
-        QueryInterface: XPCOMUtils.generateQI([Ci.nsICancelable]),
-        cancel: function() {}
-      };
-    },
-    registerService: function(serviceInfo, listener) {},
-    resolveService: function(serviceInfo, listener) {
-      listener.onServiceResolved(createDevice(mockDevice.host,
-                                              mockDevice.port,
-                                              mockDevice.serviceName,
-                                              mockDevice.serviceType));
-    }
-  };
-
-  let mockServerObj = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlService]),
-    connect: function(deviceInfo) {
-      this.request = {
-        deviceInfo: deviceInfo,
-      };
-      return {
-        QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlChannel]),
-      };
-    },
-    id: "",
-    version: LATEST_VERSION,
-    isCompatibleServer: function(version) {
-      return this.version === version;
-    }
-  };
-
-  let contractHookSD = new ContractHook(SD_CONTRACT_ID, mockSDObj);
-  let contractHookServer = new ContractHook(SERVER_CONTRACT_ID, mockServerObj);
-  let provider = Cc[PROVIDER_CONTRACT_ID].createInstance(Ci.nsIPresentationDeviceProvider);
-  let listener = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDeviceListener,
-                                           Ci.nsISupportsWeakReference]),
-    addDevice: function(device) {
-      this.device = device;
-    },
-  };
-
-  provider.listener = listener;
-
-  let controlChannel = listener.device.establishControlChannel();
-
-  Assert.equal(mockServerObj.request.deviceInfo.id, mockDevice.host);
-  Assert.equal(mockServerObj.request.deviceInfo.address, mockDevice.host);
-  Assert.equal(mockServerObj.request.deviceInfo.port, mockDevice.port);
-  Assert.equal(mockServerObj.id, testDeviceName);
-
-  provider.listener = null;
-
-  run_next_test();
-}
-
-function handleOnSessionRequest() {
-  Services.prefs.setBoolPref(PREF_DISCOVERY, true);
-  Services.prefs.setBoolPref(PREF_DISCOVERABLE, true);
-
-  let mockDevice = createDevice("device.local",
-                                12345,
-                                "service.name",
-                                SERVICE_TYPE);
-  let mockSDObj = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIDNSServiceDiscovery]),
-    startDiscovery: function(serviceType, listener) {
-      listener.onDiscoveryStarted(serviceType);
-      listener.onServiceFound(createDevice("",
-                                           0,
-                                           mockDevice.serviceName,
-                                           mockDevice.serviceType));
-      return {
-        QueryInterface: XPCOMUtils.generateQI([Ci.nsICancelable]),
-        cancel: function() {}
-      };
-    },
-    registerService: function(serviceInfo, listener) {},
-    resolveService: function(serviceInfo, listener) {
-      listener.onServiceResolved(createDevice(mockDevice.host,
-                                              mockDevice.port,
-                                              mockDevice.serviceName,
-                                              mockDevice.serviceType));
-    }
-  };
-
-  let mockServerObj = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlService]),
-    startServer: function() {},
-    sessionRequest: function() {},
-    close: function() {},
-    id: '',
-    version: LATEST_VERSION,
-    port: 0,
-    listener: null,
-  };
-
-  let contractHookSD = new ContractHook(SD_CONTRACT_ID, mockSDObj);
-  let contractHookServer = new ContractHook(SERVER_CONTRACT_ID, mockServerObj);
-  let provider = Cc[PROVIDER_CONTRACT_ID].createInstance(Ci.nsIPresentationDeviceProvider);
-  let listener = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDeviceListener,
-                                           Ci.nsISupportsWeakReference]),
-    addDevice: function(device) {},
-    removeDevice: function(device) {},
-    updateDevice: function(device) {},
-    onSessionRequest: function(device, url, presentationId, controlChannel) {
-      Assert.ok(true, "receive onSessionRequest event");
-      this.request = {
-        deviceId: device.id,
-        url: url,
-        presentationId: presentationId,
-      };
-    }
-  };
-
-  provider.listener = listener;
-
-  const deviceInfo = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsITCPDeviceInfo]),
-    id: mockDevice.host,
-    address: mockDevice.host,
-    port: 54321,
-  };
-
-  const testUrl = "http://example.com";
-  const testPresentationId = "test-presentation-id";
-  const testControlChannel = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlChannel]),
-  };
-  provider.QueryInterface(Ci.nsIPresentationControlServerListener)
-          .onSessionRequest(deviceInfo, testUrl, testPresentationId, testControlChannel);
-
-  Assert.equal(listener.request.deviceId, deviceInfo.id);
-  Assert.equal(listener.request.url, testUrl);
-  Assert.equal(listener.request.presentationId, testPresentationId);
-
-  provider.listener = null;
-
-  run_next_test();
-}
-
-function handleOnSessionRequestFromUnknownDevice() {
-  Services.prefs.setBoolPref(PREF_DISCOVERY, false);
-  Services.prefs.setBoolPref(PREF_DISCOVERABLE, true);
-
-  let mockSDObj = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIDNSServiceDiscovery]),
-    startDiscovery: function(serviceType, listener) {},
-    registerService: function(serviceInfo, listener) {},
-    resolveService: function(serviceInfo, listener) {}
-  };
-
-  let mockServerObj = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlService]),
-    startServer: function() {},
-    sessionRequest: function() {},
-    close: function() {},
-    id: '',
-    version: LATEST_VERSION,
-    port: 0,
-    listener: null,
-  };
-
-  let contractHookSD = new ContractHook(SD_CONTRACT_ID, mockSDObj);
-  let contractHookServer = new ContractHook(SERVER_CONTRACT_ID, mockServerObj);
-  let provider = Cc[PROVIDER_CONTRACT_ID].createInstance(Ci.nsIPresentationDeviceProvider);
-  let listener = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDeviceListener,
-                                           Ci.nsISupportsWeakReference]),
-    addDevice: function(device) {
-      Assert.ok(false, "shouldn't create any new device");
-    },
-    removeDevice: function(device) {
-      Assert.ok(false, "shouldn't remote any device");
-    },
-    updateDevice: function(device) {
-      Assert.ok(false, "shouldn't update any device");
-    },
-    onSessionRequest: function(device, url, presentationId, controlChannel) {
-      Assert.ok(true, "receive onSessionRequest event");
-      this.request = {
-        deviceId: device.id,
-        url: url,
-        presentationId: presentationId,
-      };
-    }
-  };
-
-  provider.listener = listener;
-
-  const deviceInfo = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsITCPDeviceInfo]),
-    id: "unknown-device.local",
-    address: "unknown-device.local",
-    port: 12345,
-  };
-
-  const testUrl = "http://example.com";
-  const testPresentationId = "test-presentation-id";
-  const testControlChannel = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlChannel]),
-  };
-  provider.QueryInterface(Ci.nsIPresentationControlServerListener)
-          .onSessionRequest(deviceInfo, testUrl, testPresentationId, testControlChannel);
-
-  Assert.equal(listener.request.deviceId, deviceInfo.id);
-  Assert.equal(listener.request.url, testUrl);
-  Assert.equal(listener.request.presentationId, testPresentationId);
-
-  provider.listener = null;
-
-  run_next_test();
-}
-
-function noAddDevice() {
-  Services.prefs.setBoolPref(PREF_DISCOVERY, false);
-
-  let mockDevice = createDevice("device.local", 12345, "service.name", SERVICE_TYPE);
-  let mockObj = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIDNSServiceDiscovery]),
-    startDiscovery: function(serviceType, listener) {
-      Assert.ok(false, "shouldn't perform any device discovery");
-    },
-    registerService: function(serviceInfo, listener) {},
-    resolveService: function(serviceInfo, listener) {
-    }
-  };
-  let contractHook = new ContractHook(SD_CONTRACT_ID, mockObj);
-
-  let provider = Cc[PROVIDER_CONTRACT_ID].createInstance(Ci.nsIPresentationDeviceProvider);
-  let listener = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDeviceListener,
-                                           Ci.nsISupportsWeakReference]),
-    addDevice: function(device) {},
-    removeDevice: function(device) {},
-    updateDevice: function(device) {},
-  };
-  provider.listener = listener;
-  provider.forceDiscovery();
-  provider.listener = null;
-
-  run_next_test();
-}
-
-function ignoreIncompatibleDevice() {
-  Services.prefs.setBoolPref(PREF_DISCOVERY, false);
-  Services.prefs.setBoolPref(PREF_DISCOVERABLE, true);
-
-  let mockDevice = createDevice("device.local",
-                                12345,
-                                "service.name",
-                                SERVICE_TYPE);
-
-  let deferred = Promise.defer();
-
-  let mockSDObj = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIDNSServiceDiscovery]),
-    startDiscovery: function(serviceType, listener) {
-      listener.onDiscoveryStarted(serviceType);
-      listener.onServiceFound(createDevice("",
-                                           0,
-                                           mockDevice.serviceName,
-                                           mockDevice.serviceType));
-      return {
-        QueryInterface: XPCOMUtils.generateQI([Ci.nsICancelable]),
-        cancel: function() {}
-      };
-    },
-    registerService: function(serviceInfo, listener) {
-      deferred.resolve();
-      listener.onServiceRegistered(createDevice("",
-                                                54321,
-                                                mockDevice.serviceName,
-                                                mockDevice.serviceType));
-      return {
-        QueryInterface: XPCOMUtils.generateQI([Ci.nsICancelable]),
-        cancel: function() {}
-      };
-    },
-    resolveService: function(serviceInfo, listener) {
-      Assert.equal(serviceInfo.serviceName, mockDevice.serviceName);
-      Assert.equal(serviceInfo.serviceType, mockDevice.serviceType);
-      listener.onServiceResolved(createDevice(mockDevice.host,
-                                              mockDevice.port,
-                                              mockDevice.serviceName,
-                                              mockDevice.serviceType));
-    }
-  };
-
-  let mockServerObj = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlService]),
-    startServer: function() {
-      Services.tm.currentThread.dispatch(() => {
-        this.listener.onServerReady(this.port, this.certFingerprint);
-      }, Ci.nsIThread.DISPATCH_NORMAL);
-    },
-    sessionRequest: function() {},
-    close: function() {},
-    id: '',
-    version: LATEST_VERSION,
-    isCompatibleServer: function(version) {
-      return false;
-    },
-    port: 54321,
-    certFingerprint: 'mock-cert-fingerprint',
-    listener: null,
-  };
-
-  let contractHookSD = new ContractHook(SD_CONTRACT_ID, mockSDObj);
-  let contractHookServer = new ContractHook(SERVER_CONTRACT_ID, mockServerObj);
-  let provider = Cc[PROVIDER_CONTRACT_ID].createInstance(Ci.nsIPresentationDeviceProvider);
-  let listener = new TestPresentationDeviceListener();
-
-  // Register service
-  provider.listener = listener;
-
-  deferred.promise.then(function() {
-    Assert.equal(mockServerObj.id, mockDevice.host);
-
-    // Start discovery
-    Services.prefs.setBoolPref(PREF_DISCOVERY, true);
-    Assert.equal(listener.count(), 0);
-
-    provider.listener = null;
-
-    run_next_test();
-  });
-}
-
-function ignoreSelfDevice() {
-  Services.prefs.setBoolPref(PREF_DISCOVERY, false);
-  Services.prefs.setBoolPref(PREF_DISCOVERABLE, true);
-
-  let mockDevice = createDevice("device.local",
-                                12345,
-                                "service.name",
-                                SERVICE_TYPE);
-
-  let deferred = Promise.defer();
-  let mockSDObj = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIDNSServiceDiscovery]),
-    startDiscovery: function(serviceType, listener) {
-      listener.onDiscoveryStarted(serviceType);
-      listener.onServiceFound(createDevice("",
-                                           0,
-                                           mockDevice.serviceName,
-                                           mockDevice.serviceType));
-      return {
-        QueryInterface: XPCOMUtils.generateQI([Ci.nsICancelable]),
-        cancel: function() {}
-      };
-    },
-    registerService: function(serviceInfo, listener) {
-      deferred.resolve();
-      listener.onServiceRegistered(createDevice("",
-                                                0,
-                                                mockDevice.serviceName,
-                                                mockDevice.serviceType));
-      return {
-        QueryInterface: XPCOMUtils.generateQI([Ci.nsICancelable]),
-        cancel: function() {}
-      };
-    },
-    resolveService: function(serviceInfo, listener) {
-      Assert.equal(serviceInfo.serviceName, mockDevice.serviceName);
-      Assert.equal(serviceInfo.serviceType, mockDevice.serviceType);
-      listener.onServiceResolved(createDevice(mockDevice.host,
-                                              mockDevice.port,
-                                              mockDevice.serviceName,
-                                              mockDevice.serviceType));
-    }
-  };
-
-  let mockServerObj = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlService]),
-    startServer: function() {
-      Services.tm.currentThread.dispatch(() => {
-        this.listener.onServerReady(this.port, this.certFingerprint);
-      }, Ci.nsIThread.DISPATCH_NORMAL);
-    },
-    sessionRequest: function() {},
-    close: function() {},
-    id: '',
-    version: LATEST_VERSION,
-    isCompatibleServer: function(version) {
-      return this.version === version;
-    },
-    port: 54321,
-    certFingerprint: 'mock-cert-fingerprint',
-    listener: null,
-  };
-
-  let contractHookSD = new ContractHook(SD_CONTRACT_ID, mockSDObj);
-  let contractHookServer = new ContractHook(SERVER_CONTRACT_ID, mockServerObj);
-  let provider = Cc[PROVIDER_CONTRACT_ID].createInstance(Ci.nsIPresentationDeviceProvider);
-  let listener = new TestPresentationDeviceListener();
-
-  // Register service
-  provider.listener = listener;
-  deferred.promise.then(() => {
-    Assert.equal(mockServerObj.id, mockDevice.host);
-
-    // Start discovery
-    Services.prefs.setBoolPref(PREF_DISCOVERY, true);
-    Assert.equal(listener.count(), 0);
-
-    provider.listener = null;
-
-    run_next_test();
-  });
-}
-
-function addDeviceDynamically() {
-  Services.prefs.setBoolPref(PREF_DISCOVERY, false);
-
-  let mockDevice = createDevice("device.local",
-                                12345,
-                                "service.name",
-                                SERVICE_TYPE);
-  let mockObj = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIDNSServiceDiscovery]),
-    startDiscovery: function(serviceType, listener) {
-      listener.onDiscoveryStarted(serviceType);
-      listener.onServiceFound(createDevice("",
-                                           0,
-                                           mockDevice.serviceName,
-                                           mockDevice.serviceType));
-      return {
-        QueryInterface: XPCOMUtils.generateQI([Ci.nsICancelable]),
-        cancel: function() {}
-      };
-    },
-    registerService: function(serviceInfo, listener) {},
-    resolveService: function(serviceInfo, listener) {
-      Assert.equal(serviceInfo.serviceName, mockDevice.serviceName);
-      Assert.equal(serviceInfo.serviceType, mockDevice.serviceType);
-      listener.onServiceResolved(createDevice(mockDevice.host,
-                                              mockDevice.port,
-                                              mockDevice.serviceName,
-                                              mockDevice.serviceType));
-    }
-  };
-
-  let contractHook = new ContractHook(SD_CONTRACT_ID, mockObj);
-  let provider = Cc[PROVIDER_CONTRACT_ID].createInstance(Ci.nsIPresentationDeviceProvider);
-  let listener = new TestPresentationDeviceListener();
-  provider.listener = listener;
-  Assert.equal(listener.count(), 0);
-
-  // Enable discovery
-  Services.prefs.setBoolPref(PREF_DISCOVERY, true);
-  Assert.equal(listener.count(), 1);
-
-  // Try discovery again
-  provider.forceDiscovery();
-  Assert.equal(listener.count(), 1);
-
-  // Try discovery once more
-  Services.prefs.setBoolPref(PREF_DISCOVERY, false);
-  Services.prefs.setBoolPref(PREF_DISCOVERY, true);
-  provider.forceDiscovery();
-  Assert.equal(listener.count(), 1);
-
-  provider.listener = null;
-
-  run_next_test();
-}
-
-function updateDevice() {
-  Services.prefs.setBoolPref(PREF_DISCOVERY, true);
-
-  let mockDevice1 = createDevice("A.local", 12345, "N1", SERVICE_TYPE);
-  let mockDevice2 = createDevice("A.local", 23456, "N2", SERVICE_TYPE);
-
-  let mockObj = {
-    discovered: false,
-
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIDNSServiceDiscovery]),
-    startDiscovery: function(serviceType, listener) {
-      listener.onDiscoveryStarted(serviceType);
-
-      if (!this.discovered) {
-        listener.onServiceFound(mockDevice1);
-      } else {
-        listener.onServiceFound(mockDevice2);
-      }
-      this.discovered = true;
-
-      return {
-        QueryInterface: XPCOMUtils.generateQI([Ci.nsICancelable]),
-        cancel: function() {
-          listener.onDiscoveryStopped(serviceType);
-        }
-      };
-    },
-    registerService: function(serviceInfo, listener) {},
-    resolveService: function(serviceInfo, listener) {
-      Assert.equal(serviceInfo.serviceType, SERVICE_TYPE);
-      if (serviceInfo.serviceName == "N1") {
-        listener.onServiceResolved(mockDevice1);
-      } else if (serviceInfo.serviceName == "N2") {
-        listener.onServiceResolved(mockDevice2);
-      } else {
-        Assert.ok(false);
-      }
-    }
-  };
-
-  let contractHook = new ContractHook(SD_CONTRACT_ID, mockObj);
-  let provider = Cc[PROVIDER_CONTRACT_ID].createInstance(Ci.nsIPresentationDeviceProvider);
-  let listener = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDeviceListener,
-                                           Ci.nsISupportsWeakReference]),
-
-    addDevice: function(device) {
-      Assert.ok(!this.isDeviceAdded);
-      Assert.equal(device.id, mockDevice1.host);
-      Assert.equal(device.name, mockDevice1.serviceName);
-      this.isDeviceAdded = true;
-    },
-    removeDevice: function(device) { Assert.ok(false); },
-    updateDevice: function(device) {
-      Assert.ok(!this.isDeviceUpdated);
-      Assert.equal(device.id, mockDevice2.host);
-      Assert.equal(device.name, mockDevice2.serviceName);
-      this.isDeviceUpdated = true;
-    },
-
-    isDeviceAdded: false,
-    isDeviceUpdated: false
-  };
-  Assert.equal(listener.isDeviceAdded, false);
-  Assert.equal(listener.isDeviceUpdated, false);
-
-  // Start discovery
-  provider.listener = listener; // discover: N1
-
-  Assert.equal(listener.isDeviceAdded, true);
-  Assert.equal(listener.isDeviceUpdated, false);
-
-  // temporarily disable to stop discovery and re-enable
-  Services.prefs.setBoolPref(PREF_DISCOVERY, false);
-  Services.prefs.setBoolPref(PREF_DISCOVERY, true);
-
-  provider.forceDiscovery(); // discover: N2
-
-  Assert.equal(listener.isDeviceAdded, true);
-  Assert.equal(listener.isDeviceUpdated, true);
-
-  provider.listener = null;
-
-  run_next_test();
-}
-
-function diffDiscovery() {
-  Services.prefs.setBoolPref(PREF_DISCOVERY, true);
-
-  let mockDevice1 = createDevice("A.local", 12345, "N1", SERVICE_TYPE);
-  let mockDevice2 = createDevice("B.local", 23456, "N2", SERVICE_TYPE);
-  let mockDevice3 = createDevice("C.local", 45678, "N3", SERVICE_TYPE);
-
-  let mockObj = {
-    discovered: false,
-
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIDNSServiceDiscovery]),
-    startDiscovery: function(serviceType, listener) {
-      listener.onDiscoveryStarted(serviceType);
-
-      if (!this.discovered) {
-        listener.onServiceFound(mockDevice1);
-        listener.onServiceFound(mockDevice2);
-      } else {
-        listener.onServiceFound(mockDevice1);
-        listener.onServiceFound(mockDevice3);
-      }
-      this.discovered = true;
-
-      return {
-        QueryInterface: XPCOMUtils.generateQI([Ci.nsICancelable]),
-        cancel: function() {
-          listener.onDiscoveryStopped(serviceType);
-        }
-      };
-    },
-    registerService: function(serviceInfo, listener) {},
-    resolveService: function(serviceInfo, listener) {
-      Assert.equal(serviceInfo.serviceType, SERVICE_TYPE);
-      if (serviceInfo.serviceName == "N1") {
-        listener.onServiceResolved(mockDevice1);
-      } else if (serviceInfo.serviceName == "N2") {
-        listener.onServiceResolved(mockDevice2);
-      } else if (serviceInfo.serviceName == "N3") {
-        listener.onServiceResolved(mockDevice3);
-      } else {
-        Assert.ok(false);
-      }
-    }
-  };
-
-  let contractHook = new ContractHook(SD_CONTRACT_ID, mockObj);
-  let provider = Cc[PROVIDER_CONTRACT_ID].createInstance(Ci.nsIPresentationDeviceProvider);
-  let listener = new TestPresentationDeviceListener();
-  Assert.equal(listener.count(), 0);
-
-  // Start discovery
-  provider.listener = listener; // discover: N1, N2
-  Assert.equal(listener.count(), 2);
-  Assert.equal(listener.devices['A.local'].name, mockDevice1.serviceName);
-  Assert.equal(listener.devices['B.local'].name, mockDevice2.serviceName);
-  Assert.ok(!listener.devices['C.local']);
-
-  // temporarily disable to stop discovery and re-enable
-  Services.prefs.setBoolPref(PREF_DISCOVERY, false);
-  Services.prefs.setBoolPref(PREF_DISCOVERY, true);
-
-  provider.forceDiscovery(); // discover: N1, N3, going to remove: N2
-  Assert.equal(listener.count(), 3);
-  Assert.equal(listener.devices['A.local'].name, mockDevice1.serviceName);
-  Assert.equal(listener.devices['B.local'].name, mockDevice2.serviceName);
-  Assert.equal(listener.devices['C.local'].name, mockDevice3.serviceName);
-
-  // temporarily disable to stop discovery and re-enable
-  Services.prefs.setBoolPref(PREF_DISCOVERY, false);
-  Services.prefs.setBoolPref(PREF_DISCOVERY, true);
-
-  provider.forceDiscovery(); // discover: N1, N3, remove: N2
-  Assert.equal(listener.count(), 2);
-  Assert.equal(listener.devices['A.local'].name, mockDevice1.serviceName);
-  Assert.ok(!listener.devices['B.local']);
-  Assert.equal(listener.devices['C.local'].name, mockDevice3.serviceName);
-
-  provider.listener = null;
-
-  run_next_test();
-}
-
-function serverClosed() {
-  Services.prefs.setBoolPref(PREF_DISCOVERABLE, true);
-  Services.prefs.setBoolPref(PREF_DISCOVERY, true);
-
-  let mockDevice = createDevice("device.local",
-                                12345,
-                                "service.name",
-                                SERVICE_TYPE);
-
-  let mockObj = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIDNSServiceDiscovery]),
-    startDiscovery: function(serviceType, listener) {
-      listener.onDiscoveryStarted(serviceType);
-      listener.onServiceFound(createDevice("",
-                                           0,
-                                           mockDevice.serviceName,
-                                           mockDevice.serviceType));
-      return {
-        QueryInterface: XPCOMUtils.generateQI([Ci.nsICancelable]),
-        cancel: function() {}
-      };
-    },
-    registerService: function(serviceInfo, listener) {
-      this.serviceRegistered++;
-      return {
-        QueryInterface: XPCOMUtils.generateQI([Ci.nsICancelable]),
-        cancel: function() {
-          this.serviceUnregistered++;
-        }.bind(this)
-      };
-    },
-    resolveService: function(serviceInfo, listener) {
-      Assert.equal(serviceInfo.serviceName, mockDevice.serviceName);
-      Assert.equal(serviceInfo.serviceType, mockDevice.serviceType);
-      listener.onServiceResolved(createDevice(mockDevice.host,
-                                              mockDevice.port,
-                                              mockDevice.serviceName,
-                                              mockDevice.serviceType));
-    },
-    serviceRegistered: 0,
-    serviceUnregistered: 0
-  };
-  let contractHook = new ContractHook(SD_CONTRACT_ID, mockObj);
-  let provider = Cc[PROVIDER_CONTRACT_ID].createInstance(Ci.nsIPresentationDeviceProvider);
-
-  Assert.equal(mockObj.serviceRegistered, 0);
-  Assert.equal(mockObj.serviceUnregistered, 0);
-
-  // Register
-  let listener = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDeviceListener,
-                                           Ci.nsISupportsWeakReference]),
-    addDevice: function(device) { this.devices.push(device); },
-    removeDevice: function(device) {},
-    updateDevice: function(device) {},
-    devices: []
-  };
-  Assert.equal(listener.devices.length, 0);
-
-  provider.listener = listener;
-  Assert.equal(mockObj.serviceRegistered, 1);
-  Assert.equal(mockObj.serviceUnregistered, 0);
-  Assert.equal(listener.devices.length, 1);
-
-  let serverListener = provider.QueryInterface(Ci.nsIPresentationControlServerListener);
-  let randomPort = 9527;
-  serverListener.onServerReady(randomPort, '');
-
-  Assert.equal(mockObj.serviceRegistered, 2);
-  Assert.equal(mockObj.serviceUnregistered, 1);
-  Assert.equal(listener.devices.length, 1);
-
-  // Unregister
-  provider.listener = null;
-  Assert.equal(mockObj.serviceRegistered, 2);
-  Assert.equal(mockObj.serviceUnregistered, 2);
-  Assert.equal(listener.devices.length, 1);
-
-  run_next_test();
-}
-
-function serverRetry() {
-  Services.prefs.setBoolPref(PREF_DISCOVERY, false);
-  Services.prefs.setBoolPref(PREF_DISCOVERABLE, true);
-
-  let isRetrying = false;
-
-  let mockSDObj = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIDNSServiceDiscovery]),
-    startDiscovery: function(serviceType, listener) {},
-    registerService: function(serviceInfo, listener) {
-      Assert.ok(isRetrying, "register service after retrying startServer");
-      provider.listener = null;
-      run_next_test();
-    },
-    resolveService: function(serviceInfo, listener) {}
-  };
-
-  let mockServerObj = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlService]),
-    startServer: function(encrypted, port) {
-      if (!isRetrying) {
-        isRetrying = true;
-        Services.tm.currentThread.dispatch(() => {
-          this.listener.onServerStopped(Cr.NS_ERROR_FAILURE);
-        }, Ci.nsIThread.DISPATCH_NORMAL);
-      } else {
-        this.port = 54321;
-        Services.tm.currentThread.dispatch(() => {
-          this.listener.onServerReady(this.port, this.certFingerprint);
-        }, Ci.nsIThread.DISPATCH_NORMAL);
-      }
-    },
-    sessionRequest: function() {},
-    close: function() {},
-    id: '',
-    version: LATEST_VERSION,
-    port: 0,
-    certFingerprint: 'mock-cert-fingerprint',
-    listener: null,
-  };
-
-  let contractHookSD = new ContractHook(SD_CONTRACT_ID, mockSDObj);
-  let contractHookServer = new ContractHook(SERVER_CONTRACT_ID, mockServerObj);
-  let provider = Cc[PROVIDER_CONTRACT_ID].createInstance(Ci.nsIPresentationDeviceProvider);
-  let listener = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDeviceListener,
-                                           Ci.nsISupportsWeakReference]),
-    addDevice: function(device) {},
-    removeDevice: function(device) {},
-    updateDevice: function(device) {},
-    onSessionRequest: function(device, url, presentationId, controlChannel) {}
-  };
-
-  provider.listener = listener;
-}
-
-function run_test() {
-  // Need profile dir to store the key / cert
-  do_get_profile();
-  // Ensure PSM is initialized
-  Cc["@mozilla.org/psm;1"].getService(Ci.nsISupports);
-
-  let infoHook = new ContractHook(INFO_CONTRACT_ID, MockDNSServiceInfo);
-
-  do_register_cleanup(() => {
-    Services.prefs.clearUserPref(PREF_DISCOVERY);
-    Services.prefs.clearUserPref(PREF_DISCOVERABLE);
-  });
-
-  add_test(registerService);
-  add_test(noRegisterService);
-  add_test(registerServiceDynamically);
-  add_test(addDevice);
-  add_test(filterDevice);
-  add_test(handleSessionRequest);
-  add_test(handleOnSessionRequest);
-  add_test(handleOnSessionRequestFromUnknownDevice);
-  add_test(noAddDevice);
-  add_test(ignoreIncompatibleDevice);
-  add_test(ignoreSelfDevice);
-  add_test(addDeviceDynamically);
-  add_test(updateDevice);
-  add_test(diffDiscovery);
-  add_test(serverClosed);
-  add_test(serverRetry);
-
-  run_next_test();
-}
diff --git a/dom/presentation/tests/xpcshell/test_presentation_device_manager.js b/dom/presentation/tests/xpcshell/test_presentation_device_manager.js
deleted file mode 100644
index 68f07df656..0000000000
--- a/dom/presentation/tests/xpcshell/test_presentation_device_manager.js
+++ /dev/null
@@ -1,244 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-'use strict';
-
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
-
-Cu.import('resource://gre/modules/XPCOMUtils.jsm');
-Cu.import('resource://gre/modules/Services.jsm');
-
-const manager = Cc['@mozilla.org/presentation-device/manager;1']
-                  .getService(Ci.nsIPresentationDeviceManager);
-
-function TestPresentationDevice() {}
-
-
-function TestPresentationControlChannel() {}
-
-TestPresentationControlChannel.prototype = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlChannel]),
-  sendOffer: function(offer) {},
-  sendAnswer: function(answer) {},
-  disconnect: function() {},
-  launch: function() {},
-  terminate: function() {},
-  reconnect: function() {},
-  set listener(listener) {},
-  get listener() {},
-};
-
-var testProvider = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDeviceProvider]),
-
-  forceDiscovery: function() {
-  },
-  set listener(listener) {
-  },
-  get listener() {
-  },
-};
-
-const forbiddenRequestedUrl = 'http://example.com';
-var testDevice = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDevice]),
-  id: 'id',
-  name: 'name',
-  type: 'type',
-  establishControlChannel: function(url, presentationId) {
-    return null;
-  },
-  disconnect: function() {},
-  isRequestedUrlSupported: function(requestedUrl) {
-    return forbiddenRequestedUrl !== requestedUrl;
-  },
-};
-
-function addProvider() {
-  Object.defineProperty(testProvider, 'listener', {
-    configurable: true,
-    set: function(listener) {
-      Assert.strictEqual(listener, manager, 'listener setter is invoked by PresentationDeviceManager');
-      delete testProvider.listener;
-      run_next_test();
-    },
-  });
-  manager.addDeviceProvider(testProvider);
-}
-
-function forceDiscovery() {
-  testProvider.forceDiscovery = function() {
-    testProvider.forceDiscovery = function() {};
-    Assert.ok(true, 'forceDiscovery is invoked by PresentationDeviceManager');
-    run_next_test();
-  };
-  manager.forceDiscovery();
-}
-
-function addDevice() {
-  Services.obs.addObserver(function observer(subject, topic, data) {
-    Services.obs.removeObserver(observer, topic);
-
-    let updatedDevice = subject.QueryInterface(Ci.nsIPresentationDevice);
-    Assert.equal(updatedDevice.id, testDevice.id, 'expected device id');
-    Assert.equal(updatedDevice.name, testDevice.name, 'expected device name');
-    Assert.equal(updatedDevice.type, testDevice.type, 'expected device type');
-    Assert.equal(data, 'add', 'expected update type');
-
-    Assert.ok(manager.deviceAvailable, 'device is available');
-
-    let devices = manager.getAvailableDevices();
-    Assert.equal(devices.length, 1, 'expect 1 available device');
-
-    let device = devices.queryElementAt(0, Ci.nsIPresentationDevice);
-    Assert.equal(device.id, testDevice.id, 'expected device id');
-    Assert.equal(device.name, testDevice.name, 'expected device name');
-    Assert.equal(device.type, testDevice.type, 'expected device type');
-
-    run_next_test();
-  }, 'presentation-device-change', false);
-  manager.QueryInterface(Ci.nsIPresentationDeviceListener).addDevice(testDevice);
-}
-
-function updateDevice() {
-  Services.obs.addObserver(function observer(subject, topic, data) {
-    Services.obs.removeObserver(observer, topic);
-
-    let updatedDevice = subject.QueryInterface(Ci.nsIPresentationDevice);
-    Assert.equal(updatedDevice.id, testDevice.id, 'expected device id');
-    Assert.equal(updatedDevice.name, testDevice.name, 'expected device name');
-    Assert.equal(updatedDevice.type, testDevice.type, 'expected device type');
-    Assert.equal(data, 'update', 'expected update type');
-
-    Assert.ok(manager.deviceAvailable, 'device is available');
-
-    let devices = manager.getAvailableDevices();
-    Assert.equal(devices.length, 1, 'expect 1 available device');
-
-    let device = devices.queryElementAt(0, Ci.nsIPresentationDevice);
-    Assert.equal(device.id, testDevice.id, 'expected device id');
-    Assert.equal(device.name, testDevice.name, 'expected name after device update');
-    Assert.equal(device.type, testDevice.type, 'expected device type');
-
-    run_next_test();
-  }, 'presentation-device-change', false);
-  testDevice.name = 'updated-name';
-  manager.QueryInterface(Ci.nsIPresentationDeviceListener).updateDevice(testDevice);
-}
-
-function filterDevice() {
-  let presentationUrls = Cc['@mozilla.org/array;1'].createInstance(Ci.nsIMutableArray);
-  let url = Cc['@mozilla.org/supports-string;1'].createInstance(Ci.nsISupportsString);
-  url.data = forbiddenRequestedUrl;
-  presentationUrls.appendElement(url, false);
-  let devices = manager.getAvailableDevices(presentationUrls);
-  Assert.equal(devices.length, 0, 'expect 0 available device for example.com');
-  run_next_test();
-}
-
-function sessionRequest() {
-  let testUrl = 'http://www.example.org/';
-  let testPresentationId = 'test-presentation-id';
-  let testControlChannel = new TestPresentationControlChannel();
-  Services.obs.addObserver(function observer(subject, topic, data) {
-    Services.obs.removeObserver(observer, topic);
-
-    let request = subject.QueryInterface(Ci.nsIPresentationSessionRequest);
-
-    Assert.equal(request.device.id, testDevice.id, 'expected device');
-    Assert.equal(request.url, testUrl, 'expected requesting URL');
-    Assert.equal(request.presentationId, testPresentationId, 'expected presentation Id');
-
-    run_next_test();
-  }, 'presentation-session-request', false);
-  manager.QueryInterface(Ci.nsIPresentationDeviceListener)
-         .onSessionRequest(testDevice, testUrl, testPresentationId, testControlChannel);
-}
-
-function terminateRequest() {
-  let testUrl = 'http://www.example.org/';
-  let testPresentationId = 'test-presentation-id';
-  let testControlChannel = new TestPresentationControlChannel();
-  let testIsFromReceiver = true;
-  Services.obs.addObserver(function observer(subject, topic, data) {
-    Services.obs.removeObserver(observer, topic);
-
-    let request = subject.QueryInterface(Ci.nsIPresentationTerminateRequest);
-
-    Assert.equal(request.device.id, testDevice.id, 'expected device');
-    Assert.equal(request.presentationId, testPresentationId, 'expected presentation Id');
-    Assert.equal(request.isFromReceiver, testIsFromReceiver, 'expected isFromReceiver');
-
-    run_next_test();
-  }, 'presentation-terminate-request', false);
-  manager.QueryInterface(Ci.nsIPresentationDeviceListener)
-         .onTerminateRequest(testDevice, testPresentationId,
-                             testControlChannel, testIsFromReceiver);
-}
-
-function reconnectRequest() {
-  let testUrl = 'http://www.example.org/';
-  let testPresentationId = 'test-presentation-id';
-  let testControlChannel = new TestPresentationControlChannel();
-  Services.obs.addObserver(function observer(subject, topic, data) {
-    Services.obs.removeObserver(observer, topic);
-
-    let request = subject.QueryInterface(Ci.nsIPresentationSessionRequest);
-
-    Assert.equal(request.device.id, testDevice.id, 'expected device');
-    Assert.equal(request.url, testUrl, 'expected requesting URL');
-    Assert.equal(request.presentationId, testPresentationId, 'expected presentation Id');
-
-    run_next_test();
-  }, 'presentation-reconnect-request', false);
-  manager.QueryInterface(Ci.nsIPresentationDeviceListener)
-         .onReconnectRequest(testDevice, testUrl, testPresentationId, testControlChannel);
-}
-
-function removeDevice() {
-  Services.obs.addObserver(function observer(subject, topic, data) {
-    Services.obs.removeObserver(observer, topic);
-
-    let updatedDevice = subject.QueryInterface(Ci.nsIPresentationDevice);
-    Assert.equal(updatedDevice.id, testDevice.id, 'expected device id');
-    Assert.equal(updatedDevice.name, testDevice.name, 'expected device name');
-    Assert.equal(updatedDevice.type, testDevice.type, 'expected device type');
-    Assert.equal(data, 'remove', 'expected update type');
-
-    Assert.ok(!manager.deviceAvailable, 'device is not available');
-
-    let devices = manager.getAvailableDevices();
-    Assert.equal(devices.length, 0, 'expect 0 available device');
-
-    run_next_test();
-  }, 'presentation-device-change', false);
-  manager.QueryInterface(Ci.nsIPresentationDeviceListener).removeDevice(testDevice);
-}
-
-function removeProvider() {
-  Object.defineProperty(testProvider, 'listener', {
-    configurable: true,
-    set: function(listener) {
-      Assert.strictEqual(listener, null, 'unsetListener is invoked by PresentationDeviceManager');
-      delete testProvider.listener;
-      run_next_test();
-    },
-  });
-  manager.removeDeviceProvider(testProvider);
-}
-
-add_test(addProvider);
-add_test(forceDiscovery);
-add_test(addDevice);
-add_test(updateDevice);
-add_test(filterDevice);
-add_test(sessionRequest);
-add_test(terminateRequest);
-add_test(reconnectRequest);
-add_test(removeDevice);
-add_test(removeProvider);
-
-function run_test() {
-  run_next_test();
-}
diff --git a/dom/presentation/tests/xpcshell/test_presentation_session_transport.js b/dom/presentation/tests/xpcshell/test_presentation_session_transport.js
deleted file mode 100644
index 8e207bc22f..0000000000
--- a/dom/presentation/tests/xpcshell/test_presentation_session_transport.js
+++ /dev/null
@@ -1,198 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-'use strict';
-
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr, Constructor: CC } = Components;
-const ServerSocket = CC("@mozilla.org/network/server-socket;1",
-                        "nsIServerSocket",
-                        "init");
-
-Cu.import('resource://gre/modules/XPCOMUtils.jsm');
-Cu.import('resource://gre/modules/Services.jsm');
-
-var testServer = null;
-var clientTransport = null;
-var serverTransport = null;
-
-var clientBuilder = null;
-var serverBuilder = null;
-
-const clientMessage = "Client Message";
-const serverMessage = "Server Message";
-
-const address = Cc["@mozilla.org/supports-cstring;1"]
-                  .createInstance(Ci.nsISupportsCString);
-address.data = "127.0.0.1";
-const addresses = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
-addresses.appendElement(address, false);
-
-const serverChannelDescription = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationChannelDescription]),
-  type: 1,
-  tcpAddress: addresses,
-};
-
-var isClientReady = false;
-var isServerReady = false;
-var isClientClosed = false;
-var isServerClosed = false;
-
-const clientCallback = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationSessionTransportCallback]),
-  notifyTransportReady: function () {
-    Assert.ok(true, "Client transport ready.");
-
-    isClientReady = true;
-    if (isClientReady && isServerReady) {
-      run_next_test();
-    }
-  },
-  notifyTransportClosed: function (aReason) {
-    Assert.ok(true, "Client transport is closed.");
-
-    isClientClosed = true;
-    if (isClientClosed && isServerClosed) {
-      run_next_test();
-    }
-  },
-  notifyData: function(aData) {
-    Assert.equal(aData, serverMessage, "Client transport receives data.");
-    run_next_test();
-  },
-};
-
-const serverCallback = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationSessionTransportCallback]),
-  notifyTransportReady: function () {
-    Assert.ok(true, "Server transport ready.");
-
-    isServerReady = true;
-    if (isClientReady && isServerReady) {
-      run_next_test();
-    }
-  },
-  notifyTransportClosed: function (aReason) {
-    Assert.ok(true, "Server transport is closed.");
-
-    isServerClosed = true;
-    if (isClientClosed && isServerClosed) {
-      run_next_test();
-    }
-  },
-  notifyData: function(aData) {
-    Assert.equal(aData, clientMessage, "Server transport receives data.");
-    run_next_test();
-  },
-};
-
-const clientListener = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationSessionTransportBuilderListener]),
-  onSessionTransport(aTransport) {
-    Assert.ok(true, "Client Transport is built.");
-    clientTransport = aTransport;
-    clientTransport.callback = clientCallback;
-
-    if (serverTransport) {
-      run_next_test();
-    }
-  }
-}
-
-const serverListener = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationSessionTransportBuilderListener]),
-  onSessionTransport(aTransport) {
-    Assert.ok(true, "Server Transport is built.");
-    serverTransport = aTransport;
-    serverTransport.callback = serverCallback;
-    serverTransport.enableDataNotification();
-
-    if (clientTransport) {
-      run_next_test();
-    }
-  }
-}
-
-function TestServer() {
-  this.serverSocket = ServerSocket(-1, true, -1);
-  this.serverSocket.asyncListen(this)
-}
-
-TestServer.prototype = {
-  onSocketAccepted: function(aSocket, aTransport) {
-    print("Test server gets a client connection.");
-    serverBuilder = Cc["@mozilla.org/presentation/presentationtcpsessiontransport;1"]
-                      .createInstance(Ci.nsIPresentationTCPSessionTransportBuilder);
-    serverBuilder.buildTCPSenderTransport(aTransport, serverListener);
-  },
-  onStopListening: function(aSocket) {
-    print("Test server stops listening.");
-  },
-  close: function() {
-    if (this.serverSocket) {
-      this.serverSocket.close();
-      this.serverSocket = null;
-    }
-  }
-};
-
-// Set up the transport connection and ensure |notifyTransportReady| triggered
-// at both sides.
-function setup() {
-  clientBuilder = Cc["@mozilla.org/presentation/presentationtcpsessiontransport;1"]
-                    .createInstance(Ci.nsIPresentationTCPSessionTransportBuilder);
-  clientBuilder.buildTCPReceiverTransport(serverChannelDescription, clientListener);
-}
-
-// Test |selfAddress| attribute of |nsIPresentationSessionTransport|.
-function selfAddress() {
-  var serverSelfAddress = serverTransport.selfAddress;
-  Assert.equal(serverSelfAddress.address, address.data, "The self address of server transport should be set.");
-  Assert.equal(serverSelfAddress.port, testServer.serverSocket.port, "The port of server transport should be set.");
-
-  var clientSelfAddress = clientTransport.selfAddress;
-  Assert.ok(clientSelfAddress.address, "The self address of client transport should be set.");
-  Assert.ok(clientSelfAddress.port, "The port of client transport should be set.");
-
-  run_next_test();
-}
-
-// Test the client sends a message and then a corresponding notification gets
-// triggered at the server side.
-function clientSendMessage() {
-  clientTransport.send(clientMessage);
-}
-
-// Test the server sends a message an then a corresponding notification gets
-// triggered at the client side.
-function serverSendMessage() {
-  serverTransport.send(serverMessage);
-  // The client enables data notification even after the incoming message has
-  // been sent, and should still be able to consume it.
-  clientTransport.enableDataNotification();
-}
-
-function transportClose() {
-  clientTransport.close(Cr.NS_OK);
-}
-
-function shutdown() {
-  testServer.close();
-  run_next_test();
-}
-
-add_test(setup);
-add_test(selfAddress);
-add_test(clientSendMessage);
-add_test(serverSendMessage);
-add_test(transportClose);
-add_test(shutdown);
-
-function run_test() {
-  testServer = new TestServer();
-  // Get the port of the test server.
-  serverChannelDescription.tcpPort = testServer.serverSocket.port;
-
-  run_next_test();
-}
diff --git a/dom/presentation/tests/xpcshell/test_presentation_state_machine.js b/dom/presentation/tests/xpcshell/test_presentation_state_machine.js
deleted file mode 100644
index fcaf34da6b..0000000000
--- a/dom/presentation/tests/xpcshell/test_presentation_state_machine.js
+++ /dev/null
@@ -1,236 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-/* jshint esnext:true, globalstrict:true, moz:true, undef:true, unused:true */
-/* globals Components,Assert,run_next_test,add_test,do_execute_soon */
-
-'use strict';
-
-const { utils: Cu, results: Cr } = Components;
-
-/* globals ControllerStateMachine */
-Cu.import('resource://gre/modules/presentation/ControllerStateMachine.jsm');
-/* globals ReceiverStateMachine */
-Cu.import('resource://gre/modules/presentation/ReceiverStateMachine.jsm');
-/* globals State */
-Cu.import('resource://gre/modules/presentation/StateMachineHelper.jsm');
-
-const testControllerId = 'test-controller-id';
-const testPresentationId = 'test-presentation-id';
-const testUrl = 'http://example.org';
-
-let mockControllerChannel = {};
-let mockReceiverChannel = {};
-
-let controllerState = new ControllerStateMachine(mockControllerChannel, testControllerId);
-let receiverState = new ReceiverStateMachine(mockReceiverChannel);
-
-mockControllerChannel.sendCommand = function(command) {
-  do_execute_soon(function() {
-    receiverState.onCommand(command);
-  });
-};
-
-mockReceiverChannel.sendCommand = function(command) {
-  do_execute_soon(function() {
-    controllerState.onCommand(command);
-  });
-};
-
-function connect() {
-  Assert.equal(controllerState.state, State.INIT, 'controller in init state');
-  Assert.equal(receiverState.state, State.INIT, 'receiver in init state');
-  // step 1: underlying connection is ready
-  controllerState.onChannelReady();
-  Assert.equal(controllerState.state, State.CONNECTING, 'controller in connecting state');
-  receiverState.onChannelReady();
-  Assert.equal(receiverState.state, State.CONNECTING, 'receiver in connecting state');
-
-  // step 2: receiver reply to connect command
-  mockReceiverChannel.notifyDeviceConnected = function(deviceId) {
-    Assert.equal(deviceId, testControllerId, 'receiver connect to mock controller');
-    Assert.equal(receiverState.state, State.CONNECTED, 'receiver in connected state');
-
-    // step 3: controller receive connect-ack command
-    mockControllerChannel.notifyDeviceConnected = function() {
-      Assert.equal(controllerState.state, State.CONNECTED, 'controller in connected state');
-      run_next_test();
-    };
-  };
-}
-
-function launch() {
-  Assert.equal(controllerState.state, State.CONNECTED, 'controller in connected state');
-  Assert.equal(receiverState.state, State.CONNECTED, 'receiver in connected state');
-
-  controllerState.launch(testPresentationId, testUrl);
-  mockReceiverChannel.notifyLaunch = function(presentationId, url) {
-    Assert.equal(receiverState.state, State.CONNECTED, 'receiver in connected state');
-    Assert.equal(presentationId, testPresentationId, 'expected presentationId received');
-    Assert.equal(url, testUrl, 'expected url received');
-
-    mockControllerChannel.notifyLaunch = function(presentationId) {
-      Assert.equal(controllerState.state, State.CONNECTED, 'controller in connected state');
-      Assert.equal(presentationId, testPresentationId, 'expected presentationId received from ack');
-
-      run_next_test();
-    };
-  };
-}
-
-function terminateByController() {
-  Assert.equal(controllerState.state, State.CONNECTED, 'controller in connected state');
-  Assert.equal(receiverState.state, State.CONNECTED, 'receiver in connected state');
-
-  controllerState.terminate(testPresentationId);
-  mockReceiverChannel.notifyTerminate = function(presentationId) {
-    Assert.equal(receiverState.state, State.CONNECTED, 'receiver in connected state');
-    Assert.equal(presentationId, testPresentationId, 'expected presentationId received');
-
-    mockControllerChannel.notifyTerminate = function(presentationId) {
-      Assert.equal(controllerState.state, State.CONNECTED, 'controller in connected state');
-      Assert.equal(presentationId, testPresentationId, 'expected presentationId received from ack');
-
-      run_next_test();
-    };
-
-    receiverState.terminateAck(presentationId);
-  };
-}
-
-function terminateByReceiver() {
-  Assert.equal(controllerState.state, State.CONNECTED, 'controller in connected state');
-  Assert.equal(receiverState.state, State.CONNECTED, 'receiver in connected state');
-
-  receiverState.terminate(testPresentationId);
-  mockControllerChannel.notifyTerminate = function(presentationId) {
-    Assert.equal(controllerState.state, State.CONNECTED, 'controller in connected state');
-    Assert.equal(presentationId, testPresentationId, 'expected presentationId received');
-
-    mockReceiverChannel.notifyTerminate = function(presentationId) {
-      Assert.equal(receiverState.state, State.CONNECTED, 'receiver in connected state');
-      Assert.equal(presentationId, testPresentationId, 'expected presentationId received from ack');
-      run_next_test();
-    };
-
-    controllerState.terminateAck(presentationId);
-  };
-}
-
-function exchangeSDP() {
-  Assert.equal(controllerState.state, State.CONNECTED, 'controller in connected state');
-  Assert.equal(receiverState.state, State.CONNECTED, 'receiver in connected state');
-
-  const testOffer = 'test-offer';
-  const testAnswer = 'test-answer';
-  const testIceCandidate = 'test-ice-candidate';
-  controllerState.sendOffer(testOffer);
-  mockReceiverChannel.notifyOffer = function(offer) {
-    Assert.equal(offer, testOffer, 'expected offer received');
-
-    receiverState.sendAnswer(testAnswer);
-    mockControllerChannel.notifyAnswer = function(answer) {
-      Assert.equal(answer, testAnswer, 'expected answer received');
-
-      controllerState.updateIceCandidate(testIceCandidate);
-      mockReceiverChannel.notifyIceCandidate = function(candidate) {
-        Assert.equal(candidate, testIceCandidate, 'expected ice candidate received in receiver');
-
-        receiverState.updateIceCandidate(testIceCandidate);
-        mockControllerChannel.notifyIceCandidate = function(candidate) {
-          Assert.equal(candidate, testIceCandidate, 'expected ice candidate received in controller');
-
-          run_next_test();
-        };
-      };
-    };
-  };
-}
-
-function disconnect() {
-  // step 1: controller send disconnect command
-  controllerState.onChannelClosed(Cr.NS_OK, false);
-  Assert.equal(controllerState.state, State.CLOSING, 'controller in closing state');
-
-  mockReceiverChannel.notifyDisconnected = function(reason) {
-    Assert.equal(reason, Cr.NS_OK, 'receive close reason');
-    Assert.equal(receiverState.state, State.CLOSED, 'receiver in closed state');
-
-    receiverState.onChannelClosed(Cr.NS_OK, true);
-    Assert.equal(receiverState.state, State.CLOSED, 'receiver in closed state');
-
-    mockControllerChannel.notifyDisconnected = function(reason) {
-      Assert.equal(reason, Cr.NS_OK, 'receive close reason');
-      Assert.equal(controllerState.state, State.CLOSED, 'controller in closed state');
-
-      run_next_test();
-    };
-    controllerState.onChannelClosed(Cr.NS_OK, true);
-  };
-}
-
-function receiverDisconnect() {
-  // initial state: controller and receiver are connected
-  controllerState.state = State.CONNECTED;
-  receiverState.state = State.CONNECTED;
-
-  // step 1: controller send disconnect command
-  receiverState.onChannelClosed(Cr.NS_OK, false);
-  Assert.equal(receiverState.state, State.CLOSING, 'receiver in closing state');
-
-  mockControllerChannel.notifyDisconnected = function(reason) {
-    Assert.equal(reason, Cr.NS_OK, 'receive close reason');
-    Assert.equal(controllerState.state, State.CLOSED, 'controller in closed state');
-
-    controllerState.onChannelClosed(Cr.NS_OK, true);
-    Assert.equal(controllerState.state, State.CLOSED, 'controller in closed state');
-
-    mockReceiverChannel.notifyDisconnected = function(reason) {
-      Assert.equal(reason, Cr.NS_OK, 'receive close reason');
-      Assert.equal(receiverState.state, State.CLOSED, 'receiver in closed state');
-
-      run_next_test();
-    };
-    receiverState.onChannelClosed(Cr.NS_OK, true);
-  };
-}
-
-function abnormalDisconnect() {
-  // initial state: controller and receiver are connected
-  controllerState.state = State.CONNECTED;
-  receiverState.state = State.CONNECTED;
-
-  const testErrorReason = Cr.NS_ERROR_FAILURE;
-  // step 1: controller send disconnect command
-  controllerState.onChannelClosed(testErrorReason, false);
-  Assert.equal(controllerState.state, State.CLOSING, 'controller in closing state');
-
-  mockReceiverChannel.notifyDisconnected = function(reason) {
-    Assert.equal(reason, testErrorReason, 'receive abnormal close reason');
-    Assert.equal(receiverState.state, State.CLOSED, 'receiver in closed state');
-
-    receiverState.onChannelClosed(Cr.NS_OK, true);
-    Assert.equal(receiverState.state, State.CLOSED, 'receiver in closed state');
-
-    mockControllerChannel.notifyDisconnected = function(reason) {
-      Assert.equal(reason, testErrorReason, 'receive abnormal close reason');
-      Assert.equal(controllerState.state, State.CLOSED, 'controller in closed state');
-
-      run_next_test();
-    };
-    controllerState.onChannelClosed(Cr.NS_OK, true);
-  };
-}
-
-add_test(connect);
-add_test(launch);
-add_test(terminateByController);
-add_test(terminateByReceiver);
-add_test(exchangeSDP);
-add_test(disconnect);
-add_test(receiverDisconnect);
-add_test(abnormalDisconnect);
-
-function run_test() { // jshint ignore:line
-  run_next_test();
-}
diff --git a/dom/presentation/tests/xpcshell/test_tcp_control_channel.js b/dom/presentation/tests/xpcshell/test_tcp_control_channel.js
deleted file mode 100644
index 5f3df584d7..0000000000
--- a/dom/presentation/tests/xpcshell/test_tcp_control_channel.js
+++ /dev/null
@@ -1,398 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-'use strict';
-
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
-
-Cu.import('resource://gre/modules/XPCOMUtils.jsm');
-Cu.import('resource://gre/modules/Services.jsm');
-
-var pcs;
-
-// Call |run_next_test| if all functions in |names| are called
-function makeJointSuccess(names) {
-  let funcs = {}, successCount = 0;
-  names.forEach(function(name) {
-    funcs[name] = function() {
-      do_print('got expected: ' + name);
-      if (++successCount === names.length)
-        run_next_test();
-    };
-  });
-  return funcs;
-}
-
-function TestDescription(aType, aTcpAddress, aTcpPort) {
-  this.type = aType;
-  this.tcpAddress = Cc["@mozilla.org/array;1"]
-                      .createInstance(Ci.nsIMutableArray);
-  for (let address of aTcpAddress) {
-    let wrapper = Cc["@mozilla.org/supports-cstring;1"]
-                    .createInstance(Ci.nsISupportsCString);
-    wrapper.data = address;
-    this.tcpAddress.appendElement(wrapper, false);
-  }
-  this.tcpPort = aTcpPort;
-}
-
-TestDescription.prototype = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationChannelDescription]),
-}
-
-const CONTROLLER_CONTROL_CHANNEL_PORT = 36777;
-const PRESENTER_CONTROL_CHANNEL_PORT = 36888;
-
-var CLOSE_CONTROL_CHANNEL_REASON = Cr.NS_OK;
-var candidate;
-
-// presenter's presentation channel description
-const OFFER_ADDRESS = '192.168.123.123';
-const OFFER_PORT = 123;
-
-// controller's presentation channel description
-const ANSWER_ADDRESS = '192.168.321.321';
-const ANSWER_PORT = 321;
-
-function loopOfferAnser() {
-  pcs = Cc["@mozilla.org/presentation/control-service;1"]
-        .createInstance(Ci.nsIPresentationControlService);
-  pcs.id = 'controllerID';
-  pcs.listener = {
-    onServerReady: function() {
-      testPresentationServer();
-    }
-  };
-
-  // First run with TLS enabled.
-  pcs.startServer(true, PRESENTER_CONTROL_CHANNEL_PORT);
-}
-
-
-function testPresentationServer() {
-  let yayFuncs = makeJointSuccess(['controllerControlChannelClose',
-                                   'presenterControlChannelClose',
-                                   'controllerControlChannelReconnect',
-                                   'presenterControlChannelReconnect']);
-  let presenterControlChannel;
-
-  pcs.listener = {
-
-    onSessionRequest: function(deviceInfo, url, presentationId, controlChannel) {
-      presenterControlChannel = controlChannel;
-      Assert.equal(deviceInfo.id, pcs.id, 'expected device id');
-      Assert.equal(deviceInfo.address, '127.0.0.1', 'expected device address');
-      Assert.equal(url, 'http://example.com', 'expected url');
-      Assert.equal(presentationId, 'testPresentationId', 'expected presentation id');
-
-      presenterControlChannel.listener = {
-        status: 'created',
-        onOffer: function(aOffer) {
-          Assert.equal(this.status, 'opened', '1. presenterControlChannel: get offer, send answer');
-          this.status = 'onOffer';
-
-          let offer = aOffer.QueryInterface(Ci.nsIPresentationChannelDescription);
-          Assert.strictEqual(offer.tcpAddress.queryElementAt(0,Ci.nsISupportsCString).data,
-                             OFFER_ADDRESS,
-                             'expected offer address array');
-          Assert.equal(offer.tcpPort, OFFER_PORT, 'expected offer port');
-          try {
-            let tcpType = Ci.nsIPresentationChannelDescription.TYPE_TCP;
-            let answer = new TestDescription(tcpType, [ANSWER_ADDRESS], ANSWER_PORT);
-            presenterControlChannel.sendAnswer(answer);
-          } catch (e) {
-            Assert.ok(false, 'sending answer fails' + e);
-          }
-        },
-        onAnswer: function(aAnswer) {
-          Assert.ok(false, 'get answer');
-        },
-        onIceCandidate: function(aCandidate) {
-          Assert.ok(true, '3. presenterControlChannel: get ice candidate, close channel');
-          let recvCandidate = JSON.parse(aCandidate);
-          for (let key in recvCandidate) {
-            if (typeof(recvCandidate[key]) !== "function") {
-              Assert.equal(recvCandidate[key], candidate[key], "key " + key + " should match.");
-            }
-          }
-          presenterControlChannel.disconnect(CLOSE_CONTROL_CHANNEL_REASON);
-        },
-        notifyConnected: function() {
-          Assert.equal(this.status, 'created', '0. presenterControlChannel: opened');
-          this.status = 'opened';
-        },
-        notifyDisconnected: function(aReason) {
-          Assert.equal(this.status, 'onOffer', '4. presenterControlChannel: closed');
-          Assert.equal(aReason, CLOSE_CONTROL_CHANNEL_REASON, 'presenterControlChannel notify closed');
-          this.status = 'closed';
-          yayFuncs.controllerControlChannelClose();
-        },
-        QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlChannelListener]),
-      };
-    },
-    onReconnectRequest: function(deviceInfo, url, presentationId, controlChannel) {
-      Assert.equal(url, 'http://example.com', 'expected url');
-      Assert.equal(presentationId, 'testPresentationId', 'expected presentation id');
-      yayFuncs.presenterControlChannelReconnect();
-    },
-
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlServerListener]),
-  };
-
-  let presenterDeviceInfo = {
-    id: 'presentatorID',
-    address: '127.0.0.1',
-    port: PRESENTER_CONTROL_CHANNEL_PORT,
-    certFingerprint: pcs.certFingerprint,
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsITCPDeviceInfo]),
-  };
-
-  let controllerControlChannel = pcs.connect(presenterDeviceInfo);
-
-  controllerControlChannel.listener = {
-    status: 'created',
-    onOffer: function(offer) {
-      Assert.ok(false, 'get offer');
-    },
-    onAnswer: function(aAnswer) {
-      Assert.equal(this.status, 'opened', '2. controllerControlChannel: get answer, send ICE candidate');
-
-      let answer = aAnswer.QueryInterface(Ci.nsIPresentationChannelDescription);
-      Assert.strictEqual(answer.tcpAddress.queryElementAt(0,Ci.nsISupportsCString).data,
-                         ANSWER_ADDRESS,
-                         'expected answer address array');
-      Assert.equal(answer.tcpPort, ANSWER_PORT, 'expected answer port');
-      candidate = {
-        candidate: "1 1 UDP 1 127.0.0.1 34567 type host",
-        sdpMid: "helloworld",
-        sdpMLineIndex: 1
-      };
-      controllerControlChannel.sendIceCandidate(JSON.stringify(candidate));
-    },
-    onIceCandidate: function(aCandidate) {
-      Assert.ok(false, 'get ICE candidate');
-    },
-    notifyConnected: function() {
-      Assert.equal(this.status, 'created', '0. controllerControlChannel: opened, send offer');
-      controllerControlChannel.launch('testPresentationId', 'http://example.com');
-      this.status = 'opened';
-      try {
-        let tcpType = Ci.nsIPresentationChannelDescription.TYPE_TCP;
-        let offer = new TestDescription(tcpType, [OFFER_ADDRESS], OFFER_PORT)
-        controllerControlChannel.sendOffer(offer);
-      } catch (e) {
-        Assert.ok(false, 'sending offer fails:' + e);
-      }
-    },
-    notifyDisconnected: function(aReason) {
-      this.status = 'closed';
-      Assert.equal(aReason, CLOSE_CONTROL_CHANNEL_REASON, '4. controllerControlChannel notify closed');
-      yayFuncs.presenterControlChannelClose();
-
-      let reconnectControllerControlChannel = pcs.connect(presenterDeviceInfo);
-      reconnectControllerControlChannel.listener = {
-        notifyConnected: function() {
-          reconnectControllerControlChannel.reconnect('testPresentationId', 'http://example.com');
-        },
-        notifyReconnected: function() {
-          yayFuncs.controllerControlChannelReconnect();
-        },
-        QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlChannelListener]),
-      };
-    },
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlChannelListener]),
-  };
-}
-
-function terminateRequest() {
-  let yayFuncs = makeJointSuccess(['controllerControlChannelConnected',
-                                   'controllerControlChannelDisconnected',
-                                   'presenterControlChannelDisconnected',
-                                   'terminatedByController',
-                                   'terminatedByReceiver']);
-  let controllerControlChannel;
-  let terminatePhase = 'controller';
-
-  pcs.listener = {
-    onTerminateRequest: function(deviceInfo, presentationId, controlChannel, isFromReceiver) {
-      Assert.equal(deviceInfo.address, '127.0.0.1', 'expected device address');
-      Assert.equal(presentationId, 'testPresentationId', 'expected presentation id');
-      controlChannel.terminate(presentationId); // Reply terminate ack.
-
-      if (terminatePhase === 'controller') {
-        controllerControlChannel = controlChannel;
-        Assert.equal(deviceInfo.id, pcs.id, 'expected controller device id');
-        Assert.equal(isFromReceiver, false, 'expected request from controller');
-        yayFuncs.terminatedByController();
-
-        controllerControlChannel.listener = {
-          notifyConnected: function() {
-            Assert.ok(true, 'control channel notify connected');
-            yayFuncs.controllerControlChannelConnected();
-
-            terminatePhase = 'receiver';
-            controllerControlChannel.terminate('testPresentationId');
-          },
-          notifyDisconnected: function(aReason) {
-            Assert.equal(aReason, CLOSE_CONTROL_CHANNEL_REASON, 'controllerControlChannel notify disconncted');
-            yayFuncs.controllerControlChannelDisconnected();
-          },
-          QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlChannelListener]),
-        };
-      } else {
-        Assert.equal(deviceInfo.id, presenterDeviceInfo.id, 'expected presenter device id');
-        Assert.equal(isFromReceiver, true, 'expected request from receiver');
-        yayFuncs.terminatedByReceiver();
-        presenterControlChannel.disconnect(CLOSE_CONTROL_CHANNEL_REASON);
-      }
-    },
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsITCPPresentationServerListener]),
-  };
-
-  let presenterDeviceInfo = {
-    id: 'presentatorID',
-    address: '127.0.0.1',
-    port: PRESENTER_CONTROL_CHANNEL_PORT,
-    certFingerprint: pcs.certFingerprint,
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsITCPDeviceInfo]),
-  };
-
-  let presenterControlChannel = pcs.connect(presenterDeviceInfo);
-
-  presenterControlChannel.listener = {
-    notifyConnected: function() {
-      presenterControlChannel.terminate('testPresentationId');
-    },
-    notifyDisconnected: function(aReason) {
-      Assert.equal(aReason, CLOSE_CONTROL_CHANNEL_REASON, '4. presenterControlChannel notify disconnected');
-      yayFuncs.presenterControlChannelDisconnected();
-    },
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlChannelListener]),
-  };
-}
-
-function terminateRequestAbnormal() {
-  let yayFuncs = makeJointSuccess(['controllerControlChannelConnected',
-                                   'controllerControlChannelDisconnected',
-                                   'presenterControlChannelDisconnected']);
-  let controllerControlChannel;
-
-  pcs.listener = {
-    onTerminateRequest: function(deviceInfo, presentationId, controlChannel, isFromReceiver) {
-      Assert.equal(deviceInfo.id, pcs.id, 'expected controller device id');
-      Assert.equal(deviceInfo.address, '127.0.0.1', 'expected device address');
-      Assert.equal(presentationId, 'testPresentationId', 'expected presentation id');
-      Assert.equal(isFromReceiver, false, 'expected request from controller');
-      controlChannel.terminate('unmatched-presentationId'); // Reply abnormal terminate ack.
-
-      controllerControlChannel = controlChannel;
-
-      controllerControlChannel.listener = {
-          notifyConnected: function() {
-          Assert.ok(true, 'control channel notify connected');
-          yayFuncs.controllerControlChannelConnected();
-        },
-        notifyDisconnected: function(aReason) {
-          Assert.equal(aReason, Cr.NS_ERROR_FAILURE, 'controllerControlChannel notify disconncted with error');
-          yayFuncs.controllerControlChannelDisconnected();
-        },
-        QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlChannelListener]),
-      };
-    },
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsITCPPresentationServerListener]),
-  };
-
-  let presenterDeviceInfo = {
-    id: 'presentatorID',
-    address: '127.0.0.1',
-    port: PRESENTER_CONTROL_CHANNEL_PORT,
-    certFingerprint: pcs.certFingerprint,
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsITCPDeviceInfo]),
-  };
-
-  let presenterControlChannel = pcs.connect(presenterDeviceInfo);
-
-  presenterControlChannel.listener = {
-    notifyConnected: function() {
-      presenterControlChannel.terminate('testPresentationId');
-    },
-    notifyDisconnected: function(aReason) {
-      Assert.equal(aReason, Cr.NS_ERROR_FAILURE, '4. presenterControlChannel notify disconnected with error');
-      yayFuncs.presenterControlChannelDisconnected();
-    },
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlChannelListener]),
-  };
-}
-
-function setOffline() {
-  pcs.listener = {
-    onServerReady: function(aPort, aCertFingerprint) {
-      Assert.notEqual(aPort, 0, 'TCPPresentationServer port changed and the port should be valid');
-      pcs.close();
-      run_next_test();
-    },
-  };
-
-  // Let the server socket restart automatically.
-  Services.io.offline = true;
-  Services.io.offline = false;
-}
-
-function oneMoreLoop() {
-  try {
-    pcs.listener = {
-      onServerReady: function() {
-        testPresentationServer();
-      }
-    };
-
-    // Second run with TLS disabled.
-    pcs.startServer(false, PRESENTER_CONTROL_CHANNEL_PORT);
-  } catch (e) {
-    Assert.ok(false, 'TCP presentation init fail:' + e);
-    run_next_test();
-  }
-}
-
-
-function shutdown()
-{
-  pcs.listener = {
-    onServerReady: function(aPort, aCertFingerprint) {
-      Assert.ok(false, 'TCPPresentationServer port changed');
-    },
-  };
-  pcs.close();
-  Assert.equal(pcs.port, 0, "TCPPresentationServer closed");
-  run_next_test();
-}
-
-// Test manually close control channel with NS_ERROR_FAILURE
-function changeCloseReason() {
-  CLOSE_CONTROL_CHANNEL_REASON = Cr.NS_ERROR_FAILURE;
-  run_next_test();
-}
-
-add_test(loopOfferAnser);
-add_test(terminateRequest);
-add_test(terminateRequestAbnormal);
-add_test(setOffline);
-add_test(changeCloseReason);
-add_test(oneMoreLoop);
-add_test(shutdown);
-
-function run_test() {
-  // Need profile dir to store the key / cert
-  do_get_profile();
-  // Ensure PSM is initialized
-  Cc["@mozilla.org/psm;1"].getService(Ci.nsISupports);
-
-  Services.prefs.setBoolPref("dom.presentation.tcp_server.debug", true);
-
-  do_register_cleanup(() => {
-    Services.prefs.clearUserPref("dom.presentation.tcp_server.debug");
-  });
-
-  run_next_test();
-}
diff --git a/dom/presentation/tests/xpcshell/xpcshell.ini b/dom/presentation/tests/xpcshell/xpcshell.ini
deleted file mode 100644
index 8a9c305a01..0000000000
--- a/dom/presentation/tests/xpcshell/xpcshell.ini
+++ /dev/null
@@ -1,9 +0,0 @@
-[DEFAULT]
-head =
-tail =
-
-[test_multicast_dns_device_provider.js]
-[test_presentation_device_manager.js]
-[test_presentation_session_transport.js]
-[test_tcp_control_channel.js]
-[test_presentation_state_machine.js]
diff --git a/dom/webidl/Navigator.webidl b/dom/webidl/Navigator.webidl
index c353e8be75..7ca612f986 100644
--- a/dom/webidl/Navigator.webidl
+++ b/dom/webidl/Navigator.webidl
@@ -330,11 +330,6 @@ partial interface Navigator {
                      optional (ArrayBufferView or Blob or DOMString or FormData)? data = null);
 };
 
-partial interface Navigator {
-  [Throws, Pref="dom.presentation.enabled", SameObject]
-  readonly attribute Presentation? presentation;
-};
-
 partial interface Navigator {
   [NewObject, Func="mozilla::dom::TCPSocket::ShouldTCPSocketExist"]
   readonly attribute LegacyMozTCPSocket mozTCPSocket;
diff --git a/dom/webidl/Presentation.webidl b/dom/webidl/Presentation.webidl
deleted file mode 100644
index d5b3316163..0000000000
--- a/dom/webidl/Presentation.webidl
+++ /dev/null
@@ -1,30 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/.
- *
- * The origin of this IDL file is
- * https://w3c.github.io/presentation-api/#interface-presentation
- */
-
-[Pref="dom.presentation.enabled"]
-interface Presentation {
- /*
-  * This should be used by the UA as the default presentation request for the
-  * controller. When the UA wishes to initiate a PresentationConnection on the
-  * controller's behalf, it MUST start a presentation connection using the default
-  * presentation request (as if the controller had called |defaultRequest.start()|).
-  *
-  * Only used by controlling browsing context (senders).
-  */
-  [Pref="dom.presentation.controller.enabled"]
-  attribute PresentationRequest? defaultRequest;
-
-  /*
-   * This should be available on the receiving browsing context in order to
-   * access the controlling browsing context and communicate with them.
-   */
-  [SameObject,
-   Pref="dom.presentation.receiver.enabled"]
-  readonly attribute PresentationReceiver? receiver;
-};
diff --git a/dom/webidl/PresentationAvailability.webidl b/dom/webidl/PresentationAvailability.webidl
deleted file mode 100644
index f72b88565d..0000000000
--- a/dom/webidl/PresentationAvailability.webidl
+++ /dev/null
@@ -1,22 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/.
- *
- * The origin of this IDL file is
- * https://w3c.github.io/presentation-api/#interface-presentationavailability
- */
-
-[Pref="dom.presentation.controller.enabled"]
-interface PresentationAvailability : EventTarget {
-  /*
-   * If there is at least one device discovered by UA, the value is |true|.
-   * Otherwise, its value should be |false|.
-   */
-  readonly attribute boolean value;
-
-  /*
-   * It is called when device availability changes.
-   */
-  attribute EventHandler onchange;
-};
diff --git a/dom/webidl/PresentationConnection.webidl b/dom/webidl/PresentationConnection.webidl
deleted file mode 100644
index 9676d20692..0000000000
--- a/dom/webidl/PresentationConnection.webidl
+++ /dev/null
@@ -1,96 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/.
- *
- * The origin of this IDL file is
- * https://w3c.github.io/presentation-api/#interface-presentationconnection
- */
-
-enum PresentationConnectionState
-{
-  // The initial state when a PresentationConnection is ceated.
-  "connecting",
-
-  // Existing presentation, and the communication channel is active.
-  "connected",
-
-  // Existing presentation, but the communication channel is inactive.
-  "closed",
-
-  // The presentation is nonexistent anymore. It could be terminated manually,
-  // or either controlling or receiving browsing context is no longer available.
-  "terminated"
-};
-
-enum PresentationConnectionBinaryType
-{
-  "blob",
-  "arraybuffer"
-};
-
-[Pref="dom.presentation.enabled"]
-interface PresentationConnection : EventTarget {
-  /*
-   * Unique id for all existing connections.
-   */
-  [Constant]
-  readonly attribute DOMString id;
-
-  /*
-   * Specifies the connection's presentation URL.
-   */
-  readonly attribute DOMString url;
-
-  /*
-   * @value "connected", "closed", or "terminated".
-   */
-  readonly attribute PresentationConnectionState state;
-
-  attribute EventHandler onconnect;
-  attribute EventHandler onclose;
-  attribute EventHandler onterminate;
-  attribute PresentationConnectionBinaryType binaryType;
-
-  /*
-   * After a communication channel has been established between the controlling
-   * and receiving context, this function is called to send message out, and the
-   * event handler "onmessage" will be invoked at the remote side.
-   *
-   * This function only works when the state is "connected".
-   */
-  [Throws]
-  void send(DOMString data);
-
-  [Throws]
-  void send(Blob data);
-
-  [Throws]
-  void send(ArrayBuffer data);
-
-  [Throws]
-  void send(ArrayBufferView data);
-
-  /*
-   * It is triggered when receiving messages.
-   */
-  attribute EventHandler onmessage;
-
-  /*
-   * Both the controlling and receiving browsing context can close the
-   * connection. Then the connection state should turn into "closed".
-   *
-   * This function only works when the state is "connected" or "connecting".
-   */
-  [Throws]
-  void close();
-
-  /*
-   * Both the controlling and receiving browsing context can terminate the
-   * connection. Then the connection state should turn into "terminated".
-   *
-   * This function only works when the state is not "connected".
-   */
-   [Throws]
-   void terminate();
-};
diff --git a/dom/webidl/PresentationConnectionAvailableEvent.webidl b/dom/webidl/PresentationConnectionAvailableEvent.webidl
deleted file mode 100644
index 9efecb7d62..0000000000
--- a/dom/webidl/PresentationConnectionAvailableEvent.webidl
+++ /dev/null
@@ -1,22 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/.
- *
- * The origin of this IDL file is
- * https://w3c.github.io/presentation-api/#interface-presentationconnectionavailableevent
- */
-
-[Constructor(DOMString type,
-             PresentationConnectionAvailableEventInit eventInitDict),
- Pref="dom.presentation.enabled"]
-interface PresentationConnectionAvailableEvent : Event
-{
-  [SameObject]
-  readonly attribute PresentationConnection connection;
-};
-
-dictionary PresentationConnectionAvailableEventInit : EventInit
-{
-  required PresentationConnection connection;
-};
diff --git a/dom/webidl/PresentationConnectionCloseEvent.webidl b/dom/webidl/PresentationConnectionCloseEvent.webidl
deleted file mode 100644
index da6c25545e..0000000000
--- a/dom/webidl/PresentationConnectionCloseEvent.webidl
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/.
- *
- * The origin of this IDL file is
- * https://w3c.github.io/presentation-api/#interface-presentationconnectioncloseevent
- */
-
-enum PresentationConnectionClosedReason
-{
-  // The communication encountered an unrecoverable error.
-  "error",
-
-  // |PresentationConnection.close()| is called by controlling browsing context
-  // or the receiving browsing context.
-  "closed",
-
-  // The connection is closed because the destination browsing context
-  // that owned the connection navigated or was discarded.
-  "wentaway"
-};
-
-[Constructor(DOMString type,
-             PresentationConnectionCloseEventInit eventInitDict),
- Pref="dom.presentation.enabled"]
-interface PresentationConnectionCloseEvent : Event
-{
-  readonly attribute PresentationConnectionClosedReason reason;
-
-  // The message is a human readable description of
-  // how the communication channel encountered an error.
-  // It is empty when the closed reason is closed or wentaway.
-  readonly attribute DOMString message;
-};
-
-dictionary PresentationConnectionCloseEventInit : EventInit
-{
-  required PresentationConnectionClosedReason reason;
-  DOMString message = "";
-};
diff --git a/dom/webidl/PresentationConnectionList.webidl b/dom/webidl/PresentationConnectionList.webidl
deleted file mode 100644
index 2c90ce9de4..0000000000
--- a/dom/webidl/PresentationConnectionList.webidl
+++ /dev/null
@@ -1,25 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/.
- *
- * The origin of this IDL file is
- * https://w3c.github.io/presentation-api/#interface-presentationconnectionlist
- */
-
-[Pref="dom.presentation.receiver.enabled"]
-interface PresentationConnectionList : EventTarget {
-  /*
-   * Return the non-terminated set of presentation connections in the
-   * set of presentation controllers.
-   * TODO: Use FrozenArray once available. (Bug 1236777)
-   * readonly attribute FrozenArray connections;
-   */
-  [Frozen, Cached, Pure]
-  readonly attribute sequence connections;
-
-  /*
-   * It is called when an incoming connection is connected.
-   */
-  attribute EventHandler onconnectionavailable;
-};
diff --git a/dom/webidl/PresentationDeviceInfoManager.webidl b/dom/webidl/PresentationDeviceInfoManager.webidl
deleted file mode 100644
index 6ccace3247..0000000000
--- a/dom/webidl/PresentationDeviceInfoManager.webidl
+++ /dev/null
@@ -1,26 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/.
- */
-
-dictionary PresentationDeviceInfo {
-  DOMString id;
-  DOMString name;
-  DOMString type;
-};
-
-[NavigatorProperty="mozPresentationDeviceInfo",
- JSImplementation="@mozilla.org/presentation-device/deviceInfo;1",
- Pref="dom.presentation.enabled",
- ChromeOnly]
-interface PresentationDeviceInfoManager : EventTarget {
-  // notify if any device updated.
-  attribute EventHandler ondevicechange;
-
-  // retrieve all available device infos
-  Promise> getAll();
-
-  // Force all registered device provider to update device information.
-  void forceDiscovery();
-};
diff --git a/dom/webidl/PresentationReceiver.webidl b/dom/webidl/PresentationReceiver.webidl
deleted file mode 100644
index 4acb37cf37..0000000000
--- a/dom/webidl/PresentationReceiver.webidl
+++ /dev/null
@@ -1,18 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/.
- *
- * The origin of this IDL file is
- * https://w3c.github.io/presentation-api/#interface-presentationreceiver
- */
-
-[Pref="dom.presentation.receiver.enabled"]
-interface PresentationReceiver {
-  /*
-   * Get a list which contains all connected presentation connections
-   * in a receiving browsing context.
-   */
-  [SameObject, Throws]
-  readonly attribute Promise connectionList;
-};
diff --git a/dom/webidl/PresentationRequest.webidl b/dom/webidl/PresentationRequest.webidl
deleted file mode 100644
index c0c5fb8a6e..0000000000
--- a/dom/webidl/PresentationRequest.webidl
+++ /dev/null
@@ -1,86 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/.
- *
- * The origin of this IDL file is
- * https://w3c.github.io/presentation-api/#interface-presentationrequest
- */
-
-[Constructor(DOMString url),
- Constructor(sequence urls),
- Pref="dom.presentation.controller.enabled"]
-interface PresentationRequest : EventTarget {
-  /*
-   * A requesting page use start() to start a new connection, and it will be
-   * returned with the promise. UA may show a prompt box with a list of
-   * available devices and ask the user to grant permission, choose a device, or
-   * cancel the operation.
-   *
-   * The promise is resolved when the presenting page is successfully loaded and
-   * the communication channel is established, i.e., the connection state is
-   * "connected".
-   *
-   * The promise may be rejected duo to one of the following reasons:
-   * - "OperationError": Unexpected error occurs.
-   * - "NotFoundError":  No available device.
-   * - "AbortError":     User dismiss/cancel the device prompt box.
-   * - "NetworkError":   Failed to establish the control channel or data channel.
-   * - "TimeoutError":   Presenting page takes too long to load.
-   * - "SecurityError":  This operation is insecure.
-   */
-  [Throws]
-  Promise start();
-
-  /*
-   * A requesting page can use reconnect(presentationId) to reopen a
-   * non-terminated presentation connection.
-   *
-   * The promise is resolved when a new presentation connection is created.
-   * The connection state is "connecting".
-   *
-   * The promise may be rejected duo to one of the following reasons:
-   * - "OperationError": Unexpected error occurs.
-   * - "NotFoundError":  Can not find a presentation connection with the presentationId.
-   * - "SecurityError":  This operation is insecure.
-   */
-  [Throws]
-  Promise reconnect(DOMString presentationId);
-
- /*
-  * UA triggers device discovery mechanism periodically and monitor device
-  * availability.
-  *
-  * The promise may be rejected duo to one of the following reasons:
-  * - "NotSupportedError": Unable to continuously monitor the availability.
-  * - "SecurityError":  This operation is insecure.
-  */
-  [Throws]
-  Promise getAvailability();
-
-  /*
-   * It is called when a connection associated with a PresentationRequest is created.
-   * The event is fired for all connections that are created for the controller.
-   */
-  attribute EventHandler onconnectionavailable;
-
-  /*
-   * A chrome page, or page which has presentation-device-manage permissiongs,
-   * uses startWithDevice() to start a new connection with specified device,
-   * and it will be returned with the promise. UA may show a prompt box with a
-   * list of available devices and ask the user to grant permission, choose a
-   * device, or cancel the operation.
-   *
-   * The promise is resolved when the presenting page is successfully loaded and
-   * the communication channel is established, i.e., the connection state is
-   * "connected".
-   *
-   * The promise may be rejected duo to one of the following reasons:
-   * - "OperationError": Unexpected error occurs.
-   * - "NotFoundError":  No available device.
-   * - "NetworkError":   Failed to establish the control channel or data channel.
-   * - "TimeoutError":   Presenting page takes too long to load.
-   */
-  [ChromeOnly, Throws]
-  Promise startWithDevice(DOMString deviceId);
-};
diff --git a/dom/webidl/moz.build b/dom/webidl/moz.build
index 4740887f3f..aaf19a89a2 100644
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -353,13 +353,6 @@ WEBIDL_FILES = [
     'PopupBoxObject.webidl',
     'Position.webidl',
     'PositionError.webidl',
-    'Presentation.webidl',
-    'PresentationAvailability.webidl',
-    'PresentationConnection.webidl',
-    'PresentationConnectionList.webidl',
-    'PresentationDeviceInfoManager.webidl',
-    'PresentationReceiver.webidl',
-    'PresentationRequest.webidl',
     'ProcessingInstruction.webidl',
     'ProfileTimelineMarker.webidl',
     'Promise.webidl',
@@ -706,8 +699,6 @@ GENERATED_EVENTS_WEBIDL_FILES = [
     'PluginCrashedEvent.webidl',
     'PopStateEvent.webidl',
     'PopupBlockedEvent.webidl',
-    'PresentationConnectionAvailableEvent.webidl',
-    'PresentationConnectionCloseEvent.webidl',
     'ProgressEvent.webidl',
     'RecordErrorEvent.webidl',
     'ScrollViewChangeEvent.webidl',
-- 
cgit v1.2.3