From 1124fb525bf7b8341170d886b8de070e20323efd Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Sun, 13 May 2018 22:46:04 +0200 Subject: Remove other gonk widget conditionals and unused files. Tag #288. --- accessible/jsat/PointerAdapter.jsm | 11 - build/gyp.mozbuild | 19 +- devtools/shared/discovery/discovery.js | 13 +- dom/base/moz.build | 5 - dom/canvas/test/webgl-mochitest/driver-info.js | 3 - dom/events/moz.build | 5 - dom/geolocation/moz.build | 4 - dom/indexedDB/test/unit/xpcshell-child-process.ini | 2 +- .../test/unit/xpcshell-parent-process.ini | 1 - dom/ipc/moz.build | 2 +- dom/media/encoder/fmp4_muxer/AMRBox.cpp | 84 - dom/media/encoder/fmp4_muxer/AMRBox.h | 50 - dom/media/encoder/fmp4_muxer/AVCBox.cpp | 87 - dom/media/encoder/fmp4_muxer/AVCBox.h | 59 - dom/media/encoder/fmp4_muxer/EVRCBox.cpp | 84 - dom/media/encoder/fmp4_muxer/EVRCBox.h | 50 - dom/media/encoder/fmp4_muxer/ISOControl.cpp | 415 --- dom/media/encoder/fmp4_muxer/ISOControl.h | 250 -- dom/media/encoder/fmp4_muxer/ISOMediaBoxes.cpp | 1550 -------- dom/media/encoder/fmp4_muxer/ISOMediaBoxes.h | 781 ---- dom/media/encoder/fmp4_muxer/ISOMediaWriter.cpp | 229 -- dom/media/encoder/fmp4_muxer/ISOMediaWriter.h | 108 - dom/media/encoder/fmp4_muxer/ISOTrackMetadata.h | 131 - dom/media/encoder/fmp4_muxer/MP4ESDS.cpp | 138 - dom/media/encoder/fmp4_muxer/MP4ESDS.h | 87 - dom/media/encoder/fmp4_muxer/MuxerOperation.h | 57 - dom/media/encoder/fmp4_muxer/moz.build | 22 - dom/media/encoder/moz.build | 13 - dom/media/platforms/omx/GonkOmxPlatformLayer.cpp | 667 ---- dom/media/platforms/omx/GonkOmxPlatformLayer.h | 205 - dom/media/platforms/omx/moz.build | 23 - dom/media/standalone/moz.build | 2 +- dom/media/systemservices/moz.build | 10 - dom/moz.build | 7 - dom/network/EthernetManager.js | 655 ---- dom/network/EthernetManager.manifest | 2 - dom/network/NetUtils.cpp | 200 - dom/network/NetUtils.h | 75 - dom/network/NetworkStatsDB.jsm | 1285 ------- dom/network/NetworkStatsManager.js | 388 -- dom/network/NetworkStatsManager.manifest | 14 - dom/network/NetworkStatsService.jsm | 1171 ------ dom/network/NetworkStatsServiceProxy.js | 90 - dom/network/NetworkStatsServiceProxy.manifest | 2 - dom/network/interfaces/moz.build | 6 - dom/network/interfaces/nsIEthernetManager.idl | 137 - .../interfaces/nsINetworkStatsServiceProxy.idl | 64 - dom/network/moz.build | 22 - dom/permission/tests/mochitest.ini | 1 - dom/speakermanager/SpeakerManager.cpp | 217 -- dom/speakermanager/SpeakerManager.h | 66 - dom/speakermanager/SpeakerManagerService.cpp | 224 -- dom/speakermanager/SpeakerManagerService.h | 79 - dom/speakermanager/SpeakerManagerServiceChild.cpp | 121 - dom/speakermanager/SpeakerManagerServiceChild.h | 44 - dom/speakermanager/moz.build | 23 - dom/speakermanager/tests/mochitest.ini | 3 - dom/speakermanager/tests/test_speakermanager.html | 53 - dom/tethering/TetheringManager.js | 92 - dom/tethering/TetheringManager.manifest | 4 - dom/tethering/moz.build | 12 - dom/tethering/tests/marionette/head.js | 768 ---- dom/tethering/tests/marionette/manifest.ini | 7 - .../tests/marionette/test_wifi_tethering_dun.js | 37 - .../marionette/test_wifi_tethering_enabled.js | 12 - dom/webidl/MozNetworkStats.webidl | 73 - dom/webidl/MozNetworkStatsAlarm.webidl | 13 - dom/webidl/MozNetworkStatsData.webidl | 12 - dom/webidl/MozNetworkStatsInterface.webidl | 26 - dom/webidl/MozNetworkStatsManager.webidl | 96 - dom/webidl/MozSpeakerManager.webidl | 18 - dom/webidl/MozWifiCapabilities.webidl | 46 - dom/webidl/MozWifiConnectionInfoEvent.webidl | 43 - dom/webidl/MozWifiManager.webidl | 347 -- dom/webidl/MozWifiP2pManager.webidl | 147 - dom/webidl/MozWifiP2pStatusChangeEvent.webidl | 20 - dom/webidl/MozWifiStationInfoEvent.webidl | 19 - dom/webidl/MozWifiStatusChangeEvent.webidl | 27 - dom/webidl/moz.build | 27 +- dom/wifi/DOMWifiManager.js | 543 --- dom/wifi/DOMWifiManager.manifest | 18 - dom/wifi/DOMWifiP2pManager.js | 328 -- dom/wifi/DOMWifiP2pManager.manifest | 6 - dom/wifi/StateMachine.jsm | 205 - dom/wifi/WifiCertService.cpp | 536 --- dom/wifi/WifiCertService.h | 40 - dom/wifi/WifiCommand.jsm | 594 --- dom/wifi/WifiHotspotUtils.cpp | 188 - dom/wifi/WifiHotspotUtils.h | 46 - dom/wifi/WifiNetUtil.jsm | 154 - dom/wifi/WifiP2pManager.jsm | 1649 -------- dom/wifi/WifiP2pWorkerObserver.jsm | 319 -- dom/wifi/WifiProxyService.cpp | 357 -- dom/wifi/WifiProxyService.h | 49 - dom/wifi/WifiUtils.cpp | 521 --- dom/wifi/WifiUtils.h | 107 - dom/wifi/WifiWorker.h | 9 - dom/wifi/WifiWorker.js | 3928 -------------------- dom/wifi/WifiWorker.manifest | 1 - dom/wifi/moz.build | 41 - dom/wifi/nsIWifi.idl | 60 - dom/wifi/nsIWifiCertService.idl | 54 - dom/wifi/nsIWifiService.idl | 22 - dom/wifi/test/marionette/head.js | 1486 -------- dom/wifi/test/marionette/manifest.ini | 22 - dom/wifi/test/marionette/test_wifi_associate.js | 35 - .../marionette/test_wifi_associate_WPA_EAP_PEAP.js | 623 ---- .../marionette/test_wifi_associate_WPA_EAP_TLS.js | 622 ---- .../marionette/test_wifi_associate_WPA_EAP_TTLS.js | 623 ---- .../marionette/test_wifi_associate_wo_connect.js | 55 - dom/wifi/test/marionette/test_wifi_auto_connect.js | 44 - dom/wifi/test/marionette/test_wifi_enable.js | 11 - dom/wifi/test/marionette/test_wifi_enable_api.js | 13 - .../test_wifi_manage_pkcs12_certificate.js | 338 -- .../test_wifi_manage_server_certificate.js | 106 - .../test_wifi_manage_user_certificate.js | 34 - dom/wifi/test/marionette/test_wifi_scan.js | 43 - dom/wifi/test/marionette/test_wifi_static_ip.js | 65 - .../marionette/test_wifi_tethering_wifi_active.js | 74 - .../test_wifi_tethering_wifi_disabled.js | 11 - .../test_wifi_tethering_wifi_inactive.js | 21 - dom/xhr/tests/mochitest.ini | 7 - gfx/gl/GLContextProviderEGL.cpp | 2 +- gfx/tests/mochitest/test_acceleration.html | 2 +- ipc/app/moz.build | 6 - ipc/chromium/moz.build | 2 - ipc/hal/DaemonRunnables.h | 950 ----- ipc/hal/DaemonSocket.cpp | 258 -- ipc/hal/DaemonSocket.h | 63 - ipc/hal/DaemonSocketConnector.cpp | 239 -- ipc/hal/DaemonSocketConnector.h | 61 - ipc/hal/DaemonSocketConsumer.cpp | 33 - ipc/hal/DaemonSocketConsumer.h | 68 - ipc/hal/DaemonSocketMessageHandlers.h | 40 - ipc/hal/DaemonSocketPDU.cpp | 197 - ipc/hal/DaemonSocketPDU.h | 94 - ipc/hal/DaemonSocketPDUHelpers.cpp | 321 -- ipc/hal/DaemonSocketPDUHelpers.h | 1283 ------- ipc/hal/moz.build | 27 - ipc/keystore/KeyStore.cpp | 981 ----- ipc/keystore/KeyStore.h | 141 - ipc/keystore/KeyStoreConnector.cpp | 234 -- ipc/keystore/KeyStoreConnector.h | 57 - ipc/keystore/moz.build | 18 - ipc/moz.build | 6 - ipc/netd/Netd.cpp | 374 -- ipc/netd/Netd.h | 81 - ipc/netd/moz.build | 17 - ipc/unixfd/UnixFdWatcher.cpp | 123 - ipc/unixfd/UnixFdWatcher.h | 69 - ipc/unixfd/UnixFileWatcher.cpp | 45 - ipc/unixfd/UnixFileWatcher.h | 33 - ipc/unixfd/UnixSocketWatcher.cpp | 136 - ipc/unixfd/UnixSocketWatcher.h | 72 - ipc/unixfd/moz.build | 21 - ipc/unixsocket/ConnectionOrientedSocket.cpp | 202 - ipc/unixsocket/ConnectionOrientedSocket.h | 122 - ipc/unixsocket/DataSocket.cpp | 136 - ipc/unixsocket/DataSocket.h | 145 - ipc/unixsocket/ListenSocket.cpp | 432 --- ipc/unixsocket/ListenSocket.h | 93 - ipc/unixsocket/ListenSocketConsumer.cpp | 20 - ipc/unixsocket/ListenSocketConsumer.h | 46 - ipc/unixsocket/SocketBase.cpp | 449 --- ipc/unixsocket/SocketBase.h | 585 --- ipc/unixsocket/StreamSocket.cpp | 482 --- ipc/unixsocket/StreamSocket.h | 95 - ipc/unixsocket/StreamSocketConsumer.cpp | 20 - ipc/unixsocket/StreamSocketConsumer.h | 60 - ipc/unixsocket/UnixSocketConnector.cpp | 38 - ipc/unixsocket/UnixSocketConnector.h | 102 - ipc/unixsocket/moz.build | 31 - layout/build/moz.build | 5 - layout/tools/reftest/bootstrap.js | 9 - layout/tools/reftest/reftest.jsm | 8 +- layout/tools/reftest/runreftest.py | 7 +- media/libcubeb/src/moz.build | 21 +- media/mtransport/common.build | 5 - media/mtransport/gonk_addrs.cpp | 170 - media/mtransport/test/moz.build | 2 +- media/omx-plugin/lib/ics/libstagefright/moz.build | 15 +- media/omx-plugin/lib/ics/libutils/moz.build | 7 +- .../lib/ics/libvideoeditorplayer/moz.build | 7 +- media/omx-plugin/moz.build | 33 +- media/webrtc/moz.build | 35 +- media/webrtc/signaling/test/moz.build | 2 +- mozglue/build/cpuacct.c | 61 - mozglue/build/cpuacct.h | 41 - mozglue/build/moz.build | 5 - netwerk/base/moz.build | 5 - netwerk/dns/mdns/libmdns/moz.build | 10 +- netwerk/standalone/moz.build | 2 +- netwerk/wifi/moz.build | 11 +- netwerk/wifi/nsWifiMonitorGonk.cpp | 181 - old-configure.in | 161 +- python/mozbuild/mozbuild/backend/cpp_eclipse.py | 25 +- python/mozbuild/mozbuild/base.py | 5 - python/mozbuild/mozbuild/mozinfo.py | 10 +- python/mozbuild/mozbuild/test/test_testing.py | 4 +- .../marionette_harness/tests/webapi-tests.ini | 2 - testing/mochitest/runtests.py | 5 +- testing/modules/tests/xpcshell/xpcshell.ini | 2 +- testing/mozbase/mozrunner/mozrunner/utils.py | 5 +- testing/xpcshell/example/unit/xpcshell.ini | 2 +- toolkit/components/captivedetect/captivedetect.js | 2 +- .../osfile/modules/osfile_async_front.jsm | 4 +- .../osfile/tests/xpcshell/test_constants.js | 7 +- .../tests/xpcshell/test_osfile_async_setDates.js | 6 +- .../osfile/tests/xpcshell/test_path_constants.js | 2 +- .../components/telemetry/TelemetryEnvironment.jsm | 44 +- toolkit/components/telemetry/TelemetrySession.jsm | 2 +- toolkit/components/telemetry/TelemetryStorage.jsm | 2 +- toolkit/components/telemetry/tests/unit/head.js | 2 +- toolkit/crashreporter/crashreporter.mozbuild | 3 - .../google-breakpad/src/client/linux/moz.build | 3 - toolkit/identity/tests/unit/xpcshell.ini | 2 +- toolkit/jetpack/moz.build | 189 +- toolkit/library/moz.build | 34 - toolkit/modules/UpdateUtils.jsm | 18 - toolkit/moz.configure | 9 +- .../extensions/test/xpcshell/xpcshell-shared.ini | 2 +- .../extensions/test/xpcshell/xpcshell-unpack.ini | 2 +- .../mozapps/extensions/test/xpcshell/xpcshell.ini | 2 +- toolkit/mozapps/update/nsUpdateService.js | 334 +- .../mozapps/update/updater/automounter_gonk.cpp | 251 -- toolkit/mozapps/update/updater/automounter_gonk.h | 48 - toolkit/mozapps/update/updater/progressui_gonk.cpp | 53 - .../mozapps/update/updater/updater-common.build | 11 - toolkit/toolkit.mozbuild | 2 +- tools/profiler/moz.build | 3 - widget/tests/TestAppShellSteadyState.cpp | 2 +- xpcom/threads/moz.build | 2 - 232 files changed, 256 insertions(+), 36730 deletions(-) delete mode 100644 dom/media/encoder/fmp4_muxer/AMRBox.cpp delete mode 100644 dom/media/encoder/fmp4_muxer/AMRBox.h delete mode 100644 dom/media/encoder/fmp4_muxer/AVCBox.cpp delete mode 100644 dom/media/encoder/fmp4_muxer/AVCBox.h delete mode 100644 dom/media/encoder/fmp4_muxer/EVRCBox.cpp delete mode 100644 dom/media/encoder/fmp4_muxer/EVRCBox.h delete mode 100644 dom/media/encoder/fmp4_muxer/ISOControl.cpp delete mode 100644 dom/media/encoder/fmp4_muxer/ISOControl.h delete mode 100644 dom/media/encoder/fmp4_muxer/ISOMediaBoxes.cpp delete mode 100644 dom/media/encoder/fmp4_muxer/ISOMediaBoxes.h delete mode 100644 dom/media/encoder/fmp4_muxer/ISOMediaWriter.cpp delete mode 100644 dom/media/encoder/fmp4_muxer/ISOMediaWriter.h delete mode 100644 dom/media/encoder/fmp4_muxer/ISOTrackMetadata.h delete mode 100644 dom/media/encoder/fmp4_muxer/MP4ESDS.cpp delete mode 100644 dom/media/encoder/fmp4_muxer/MP4ESDS.h delete mode 100644 dom/media/encoder/fmp4_muxer/MuxerOperation.h delete mode 100644 dom/media/encoder/fmp4_muxer/moz.build delete mode 100644 dom/media/platforms/omx/GonkOmxPlatformLayer.cpp delete mode 100644 dom/media/platforms/omx/GonkOmxPlatformLayer.h delete mode 100644 dom/network/EthernetManager.js delete mode 100644 dom/network/EthernetManager.manifest delete mode 100644 dom/network/NetUtils.cpp delete mode 100644 dom/network/NetUtils.h delete mode 100644 dom/network/NetworkStatsDB.jsm delete mode 100644 dom/network/NetworkStatsManager.js delete mode 100644 dom/network/NetworkStatsManager.manifest delete mode 100644 dom/network/NetworkStatsService.jsm delete mode 100644 dom/network/NetworkStatsServiceProxy.js delete mode 100644 dom/network/NetworkStatsServiceProxy.manifest delete mode 100644 dom/network/interfaces/nsIEthernetManager.idl delete mode 100644 dom/network/interfaces/nsINetworkStatsServiceProxy.idl delete mode 100644 dom/speakermanager/SpeakerManager.cpp delete mode 100644 dom/speakermanager/SpeakerManager.h delete mode 100644 dom/speakermanager/SpeakerManagerService.cpp delete mode 100644 dom/speakermanager/SpeakerManagerService.h delete mode 100644 dom/speakermanager/SpeakerManagerServiceChild.cpp delete mode 100644 dom/speakermanager/SpeakerManagerServiceChild.h delete mode 100644 dom/speakermanager/moz.build delete mode 100644 dom/speakermanager/tests/mochitest.ini delete mode 100644 dom/speakermanager/tests/test_speakermanager.html delete mode 100644 dom/tethering/TetheringManager.js delete mode 100644 dom/tethering/TetheringManager.manifest delete mode 100644 dom/tethering/moz.build delete mode 100644 dom/tethering/tests/marionette/head.js delete mode 100644 dom/tethering/tests/marionette/manifest.ini delete mode 100644 dom/tethering/tests/marionette/test_wifi_tethering_dun.js delete mode 100644 dom/tethering/tests/marionette/test_wifi_tethering_enabled.js delete mode 100644 dom/webidl/MozNetworkStats.webidl delete mode 100644 dom/webidl/MozNetworkStatsAlarm.webidl delete mode 100644 dom/webidl/MozNetworkStatsData.webidl delete mode 100644 dom/webidl/MozNetworkStatsInterface.webidl delete mode 100644 dom/webidl/MozNetworkStatsManager.webidl delete mode 100644 dom/webidl/MozSpeakerManager.webidl delete mode 100644 dom/webidl/MozWifiCapabilities.webidl delete mode 100644 dom/webidl/MozWifiConnectionInfoEvent.webidl delete mode 100644 dom/webidl/MozWifiManager.webidl delete mode 100644 dom/webidl/MozWifiP2pManager.webidl delete mode 100644 dom/webidl/MozWifiP2pStatusChangeEvent.webidl delete mode 100644 dom/webidl/MozWifiStationInfoEvent.webidl delete mode 100644 dom/webidl/MozWifiStatusChangeEvent.webidl delete mode 100644 dom/wifi/DOMWifiManager.js delete mode 100644 dom/wifi/DOMWifiManager.manifest delete mode 100644 dom/wifi/DOMWifiP2pManager.js delete mode 100644 dom/wifi/DOMWifiP2pManager.manifest delete mode 100644 dom/wifi/StateMachine.jsm delete mode 100644 dom/wifi/WifiCertService.cpp delete mode 100644 dom/wifi/WifiCertService.h delete mode 100644 dom/wifi/WifiCommand.jsm delete mode 100644 dom/wifi/WifiHotspotUtils.cpp delete mode 100644 dom/wifi/WifiHotspotUtils.h delete mode 100644 dom/wifi/WifiNetUtil.jsm delete mode 100644 dom/wifi/WifiP2pManager.jsm delete mode 100644 dom/wifi/WifiP2pWorkerObserver.jsm delete mode 100644 dom/wifi/WifiProxyService.cpp delete mode 100644 dom/wifi/WifiProxyService.h delete mode 100644 dom/wifi/WifiUtils.cpp delete mode 100644 dom/wifi/WifiUtils.h delete mode 100644 dom/wifi/WifiWorker.h delete mode 100644 dom/wifi/WifiWorker.js delete mode 100644 dom/wifi/WifiWorker.manifest delete mode 100644 dom/wifi/moz.build delete mode 100644 dom/wifi/nsIWifi.idl delete mode 100644 dom/wifi/nsIWifiCertService.idl delete mode 100644 dom/wifi/nsIWifiService.idl delete mode 100644 dom/wifi/test/marionette/head.js delete mode 100644 dom/wifi/test/marionette/manifest.ini delete mode 100644 dom/wifi/test/marionette/test_wifi_associate.js delete mode 100644 dom/wifi/test/marionette/test_wifi_associate_WPA_EAP_PEAP.js delete mode 100644 dom/wifi/test/marionette/test_wifi_associate_WPA_EAP_TLS.js delete mode 100644 dom/wifi/test/marionette/test_wifi_associate_WPA_EAP_TTLS.js delete mode 100644 dom/wifi/test/marionette/test_wifi_associate_wo_connect.js delete mode 100644 dom/wifi/test/marionette/test_wifi_auto_connect.js delete mode 100644 dom/wifi/test/marionette/test_wifi_enable.js delete mode 100644 dom/wifi/test/marionette/test_wifi_enable_api.js delete mode 100644 dom/wifi/test/marionette/test_wifi_manage_pkcs12_certificate.js delete mode 100644 dom/wifi/test/marionette/test_wifi_manage_server_certificate.js delete mode 100644 dom/wifi/test/marionette/test_wifi_manage_user_certificate.js delete mode 100644 dom/wifi/test/marionette/test_wifi_scan.js delete mode 100644 dom/wifi/test/marionette/test_wifi_static_ip.js delete mode 100644 dom/wifi/test/marionette/test_wifi_tethering_wifi_active.js delete mode 100644 dom/wifi/test/marionette/test_wifi_tethering_wifi_disabled.js delete mode 100644 dom/wifi/test/marionette/test_wifi_tethering_wifi_inactive.js delete mode 100644 ipc/hal/DaemonRunnables.h delete mode 100644 ipc/hal/DaemonSocket.cpp delete mode 100644 ipc/hal/DaemonSocket.h delete mode 100644 ipc/hal/DaemonSocketConnector.cpp delete mode 100644 ipc/hal/DaemonSocketConnector.h delete mode 100644 ipc/hal/DaemonSocketConsumer.cpp delete mode 100644 ipc/hal/DaemonSocketConsumer.h delete mode 100644 ipc/hal/DaemonSocketMessageHandlers.h delete mode 100644 ipc/hal/DaemonSocketPDU.cpp delete mode 100644 ipc/hal/DaemonSocketPDU.h delete mode 100644 ipc/hal/DaemonSocketPDUHelpers.cpp delete mode 100644 ipc/hal/DaemonSocketPDUHelpers.h delete mode 100644 ipc/hal/moz.build delete mode 100644 ipc/keystore/KeyStore.cpp delete mode 100644 ipc/keystore/KeyStore.h delete mode 100644 ipc/keystore/KeyStoreConnector.cpp delete mode 100644 ipc/keystore/KeyStoreConnector.h delete mode 100644 ipc/keystore/moz.build delete mode 100644 ipc/netd/Netd.cpp delete mode 100644 ipc/netd/Netd.h delete mode 100644 ipc/netd/moz.build delete mode 100644 ipc/unixfd/UnixFdWatcher.cpp delete mode 100644 ipc/unixfd/UnixFdWatcher.h delete mode 100644 ipc/unixfd/UnixFileWatcher.cpp delete mode 100644 ipc/unixfd/UnixFileWatcher.h delete mode 100644 ipc/unixfd/UnixSocketWatcher.cpp delete mode 100644 ipc/unixfd/UnixSocketWatcher.h delete mode 100644 ipc/unixfd/moz.build delete mode 100644 ipc/unixsocket/ConnectionOrientedSocket.cpp delete mode 100644 ipc/unixsocket/ConnectionOrientedSocket.h delete mode 100644 ipc/unixsocket/DataSocket.cpp delete mode 100644 ipc/unixsocket/DataSocket.h delete mode 100644 ipc/unixsocket/ListenSocket.cpp delete mode 100644 ipc/unixsocket/ListenSocket.h delete mode 100644 ipc/unixsocket/ListenSocketConsumer.cpp delete mode 100644 ipc/unixsocket/ListenSocketConsumer.h delete mode 100644 ipc/unixsocket/SocketBase.cpp delete mode 100644 ipc/unixsocket/SocketBase.h delete mode 100644 ipc/unixsocket/StreamSocket.cpp delete mode 100644 ipc/unixsocket/StreamSocket.h delete mode 100644 ipc/unixsocket/StreamSocketConsumer.cpp delete mode 100644 ipc/unixsocket/StreamSocketConsumer.h delete mode 100644 ipc/unixsocket/UnixSocketConnector.cpp delete mode 100644 ipc/unixsocket/UnixSocketConnector.h delete mode 100644 ipc/unixsocket/moz.build delete mode 100644 media/mtransport/gonk_addrs.cpp delete mode 100644 mozglue/build/cpuacct.c delete mode 100644 mozglue/build/cpuacct.h delete mode 100644 netwerk/wifi/nsWifiMonitorGonk.cpp delete mode 100644 toolkit/mozapps/update/updater/automounter_gonk.cpp delete mode 100644 toolkit/mozapps/update/updater/automounter_gonk.h delete mode 100644 toolkit/mozapps/update/updater/progressui_gonk.cpp diff --git a/accessible/jsat/PointerAdapter.jsm b/accessible/jsat/PointerAdapter.jsm index ff54976b7..1fb77646b 100644 --- a/accessible/jsat/PointerAdapter.jsm +++ b/accessible/jsat/PointerAdapter.jsm @@ -46,17 +46,6 @@ var PointerRelay = { // jshint ignore:line 'touchend' : true }; break; - case 'gonk': - this._eventsOfInterest = { - 'touchstart' : true, - 'touchmove' : true, - 'touchend' : true, - 'mousedown' : false, - 'mousemove' : false, - 'mouseup': false, - 'click': false }; - break; - default: // Desktop. this._eventsOfInterest = { diff --git a/build/gyp.mozbuild b/build/gyp.mozbuild index ff04f6aac..10c3af95d 100644 --- a/build/gyp.mozbuild +++ b/build/gyp.mozbuild @@ -79,22 +79,15 @@ if os == 'WINNT': MSVS_OS_BITS=64 if CONFIG['HAVE_64BIT_BUILD'] else 32, ) elif os == 'Android': - if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': - gyp_vars['build_with_gonk'] = 1 - gyp_vars['moz_widget_toolkit_gonk'] = 1 - gyp_vars['opus_complexity'] = 1 - if int(CONFIG['ANDROID_VERSION']) >= 18: - gyp_vars['moz_webrtc_omx'] = 1 - else: - gyp_vars.update( - gtest_target_type='executable', - moz_webrtc_mediacodec=1, - android_toolchain=CONFIG.get('ANDROID_TOOLCHAIN', ''), - ) + gyp_vars.update( + gtest_target_type='executable', + moz_webrtc_mediacodec=1, + android_toolchain=CONFIG.get('ANDROID_TOOLCHAIN', ''), + ) flavors = { 'WINNT': 'win', - 'Android': 'linux' if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' else 'android', + 'Android': 'android', 'Linux': 'linux', 'Darwin': 'mac' if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa' else 'ios', 'SunOS': 'solaris', diff --git a/devtools/shared/discovery/discovery.js b/devtools/shared/discovery/discovery.js index d0b49f129..3aa82ef6e 100644 --- a/devtools/shared/discovery/discovery.js +++ b/devtools/shared/discovery/discovery.js @@ -181,18 +181,7 @@ LocalDevice.prototype = { * Triggers the |name| setter to persist if needed. */ _generate: function () { - if (Services.appinfo.widgetToolkit == "gonk") { - // For Firefox OS devices, create one from the device name plus a little - // randomness. The goal is just to distinguish devices in an office - // environment where many people may have the same device model for - // testing purposes (which would otherwise all report the same name). - let name = libcutils.property_get("ro.product.device"); - // Pick a random number from [0, 2^32) - let randomID = Math.floor(Math.random() * Math.pow(2, 32)); - // To hex and zero pad - randomID = ("00000000" + randomID.toString(16)).slice(-8); - this.name = name + "-" + randomID; - } else if (Services.appinfo.widgetToolkit == "android") { + if (Services.appinfo.widgetToolkit == "android") { // For Firefox for Android, use the device's model name. // TODO: Bug 1180997: Find the right way to expose an editable name this.name = sysInfo.get("device"); diff --git a/dom/base/moz.build b/dom/base/moz.build index 76c765b1c..77eb01ba6 100755 --- a/dom/base/moz.build +++ b/dom/base/moz.build @@ -462,11 +462,6 @@ LOCAL_INCLUDES += [ '/xpcom/ds', ] -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': - LOCAL_INCLUDES += [ - '../system/gonk', - ] - if CONFIG['MOZ_WEBRTC']: LOCAL_INCLUDES += [ '/netwerk/sctp/datachannel', diff --git a/dom/canvas/test/webgl-mochitest/driver-info.js b/dom/canvas/test/webgl-mochitest/driver-info.js index e2f6e003a..3f2fe102c 100644 --- a/dom/canvas/test/webgl-mochitest/driver-info.js +++ b/dom/canvas/test/webgl-mochitest/driver-info.js @@ -81,9 +81,6 @@ DriverInfo = (function() { var versionMatch = /Mac OS X (\d+.\d+)/.exec(navigator.userAgent); version = versionMatch ? parseFloat(versionMatch[1]) : null; - } else if (runtime.widgetToolkit == 'gonk') { - os = OS.B2G; - } else if (navigator.appVersion.indexOf('Android') != -1) { os = OS.ANDROID; // From layout/tools/reftest/reftest.js: diff --git a/dom/events/moz.build b/dom/events/moz.build index ee4946038..ec3813207 100644 --- a/dom/events/moz.build +++ b/dom/events/moz.build @@ -153,10 +153,5 @@ LOCAL_INCLUDES += [ '/layout/xul/tree/', ] -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': - LOCAL_INCLUDES += [ - '/dom/wifi', - ] - if CONFIG['GNU_CXX']: CXXFLAGS += ['-Wno-error=shadow'] diff --git a/dom/geolocation/moz.build b/dom/geolocation/moz.build index bb3fcb583..4339d5a7f 100644 --- a/dom/geolocation/moz.build +++ b/dom/geolocation/moz.build @@ -30,10 +30,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android': LOCAL_INCLUDES += [ '/dom/system/android', ] -elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': - LOCAL_INCLUDES += [ - '/dom/system/gonk', - ] elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': LOCAL_INCLUDES += [ '/dom/system/mac', diff --git a/dom/indexedDB/test/unit/xpcshell-child-process.ini b/dom/indexedDB/test/unit/xpcshell-child-process.ini index 970fe8c3d..5918471ea 100644 --- a/dom/indexedDB/test/unit/xpcshell-child-process.ini +++ b/dom/indexedDB/test/unit/xpcshell-child-process.ini @@ -6,7 +6,7 @@ dupe-manifest = head = xpcshell-head-child-process.js tail = -skip-if = toolkit == 'android' || toolkit == 'gonk' +skip-if = toolkit == 'android' support-files = GlobalObjectsChild.js GlobalObjectsComponent.js diff --git a/dom/indexedDB/test/unit/xpcshell-parent-process.ini b/dom/indexedDB/test/unit/xpcshell-parent-process.ini index 22bc861cc..04df5f552 100644 --- a/dom/indexedDB/test/unit/xpcshell-parent-process.ini +++ b/dom/indexedDB/test/unit/xpcshell-parent-process.ini @@ -6,7 +6,6 @@ dupe-manifest = head = xpcshell-head-parent-process.js tail = -skip-if = toolkit == 'gonk' support-files = bug1056939_profile.zip defaultStorageUpgrade_profile.zip diff --git a/dom/ipc/moz.build b/dom/ipc/moz.build index 1dbe1fedb..c34ac5d48 100644 --- a/dom/ipc/moz.build +++ b/dom/ipc/moz.build @@ -147,7 +147,7 @@ if CONFIG['OS_ARCH'] != 'WINNT': DEFINES['BIN_SUFFIX'] = '"%s"' % CONFIG['BIN_SUFFIX'] -if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gtk2', 'gonk'): +if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gtk2'): DEFINES['MOZ_ENABLE_FREETYPE'] = True if CONFIG['MOZ_TOOLKIT_SEARCH']: diff --git a/dom/media/encoder/fmp4_muxer/AMRBox.cpp b/dom/media/encoder/fmp4_muxer/AMRBox.cpp deleted file mode 100644 index cd1a34fae..000000000 --- a/dom/media/encoder/fmp4_muxer/AMRBox.cpp +++ /dev/null @@ -1,84 +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 "ISOControl.h" -#include "ISOMediaBoxes.h" -#include "AMRBox.h" -#include "ISOTrackMetadata.h" - -namespace mozilla { - -nsresult -AMRSampleEntry::Generate(uint32_t* aBoxSize) -{ - uint32_t box_size; - nsresult rv = amr_special_box->Generate(&box_size); - NS_ENSURE_SUCCESS(rv, rv); - size += box_size; - - *aBoxSize = size; - return NS_OK; -} - -nsresult -AMRSampleEntry::Write() -{ - BoxSizeChecker checker(mControl, size); - nsresult rv; - rv = AudioSampleEntry::Write(); - NS_ENSURE_SUCCESS(rv, rv); - rv = amr_special_box->Write(); - NS_ENSURE_SUCCESS(rv, rv); - - return NS_OK; -} - -AMRSampleEntry::AMRSampleEntry(ISOControl* aControl) - : AudioSampleEntry(NS_LITERAL_CSTRING("samr"), aControl) -{ - amr_special_box = new AMRSpecificBox(aControl); - MOZ_COUNT_CTOR(AMRSampleEntry); -} - -AMRSampleEntry::~AMRSampleEntry() -{ - MOZ_COUNT_DTOR(AMRSampleEntry); -} - -nsresult -AMRSpecificBox::Generate(uint32_t* aBoxSize) -{ - nsresult rv; - FragmentBuffer* frag = mControl->GetFragment(Audio_Track); - rv = frag->GetCSD(amrDecSpecInfo); - NS_ENSURE_SUCCESS(rv, rv); - - size += amrDecSpecInfo.Length(); - *aBoxSize = size; - - return NS_OK; -} - -nsresult -AMRSpecificBox::Write() -{ - BoxSizeChecker checker(mControl, size); - Box::Write(); - mControl->Write(amrDecSpecInfo.Elements(), amrDecSpecInfo.Length()); - return NS_OK; -} - -AMRSpecificBox::AMRSpecificBox(ISOControl* aControl) - : Box(NS_LITERAL_CSTRING("damr"), aControl) -{ - MOZ_COUNT_CTOR(AMRSpecificBox); -} - -AMRSpecificBox::~AMRSpecificBox() -{ - MOZ_COUNT_DTOR(AMRSpecificBox); -} - -} diff --git a/dom/media/encoder/fmp4_muxer/AMRBox.h b/dom/media/encoder/fmp4_muxer/AMRBox.h deleted file mode 100644 index 645d7f89c..000000000 --- a/dom/media/encoder/fmp4_muxer/AMRBox.h +++ /dev/null @@ -1,50 +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 AMRBOX_h_ -#define AMRBOX_h_ - -#include "nsTArray.h" -#include "MuxerOperation.h" - -namespace mozilla { - -class ISOControl; - -// 3GPP TS 26.244 6.7 'AMRSpecificBox field for AMRSampleEntry box' -// Box type: 'damr' -class AMRSpecificBox : public Box { -public: - // 3GPP members - nsTArray amrDecSpecInfo; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // AMRSpecificBox methods - AMRSpecificBox(ISOControl* aControl); - ~AMRSpecificBox(); -}; - -// 3GPP TS 26.244 6.5 'AMRSampleEntry box' -// Box type: 'sawb' -class AMRSampleEntry : public AudioSampleEntry { -public: - // 3GPP members - RefPtr amr_special_box; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // AMRSampleEntry methods - AMRSampleEntry(ISOControl* aControl); - ~AMRSampleEntry(); -}; - -} - -#endif // AMRBOX_h_ diff --git a/dom/media/encoder/fmp4_muxer/AVCBox.cpp b/dom/media/encoder/fmp4_muxer/AVCBox.cpp deleted file mode 100644 index a45cda8b7..000000000 --- a/dom/media/encoder/fmp4_muxer/AVCBox.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 -#include "ISOControl.h" -#include "ISOMediaBoxes.h" -#include "AVCBox.h" - -namespace mozilla { - -nsresult -AVCSampleEntry::Generate(uint32_t* aBoxSize) -{ - uint32_t avc_box_size = 0; - nsresult rv; - rv = avcConfigBox->Generate(&avc_box_size); - NS_ENSURE_SUCCESS(rv, rv); - - size += avc_box_size; - - *aBoxSize = size; - - return NS_OK; -} - -nsresult -AVCSampleEntry::Write() -{ - BoxSizeChecker checker(mControl, size); - nsresult rv; - rv = VisualSampleEntry::Write(); - NS_ENSURE_SUCCESS(rv, rv); - rv = avcConfigBox->Write(); - NS_ENSURE_SUCCESS(rv, rv); - - return NS_OK; -} - -AVCSampleEntry::AVCSampleEntry(ISOControl* aControl) - : VisualSampleEntry(NS_LITERAL_CSTRING("avc1"), aControl) -{ - avcConfigBox = new AVCConfigurationBox(aControl); - MOZ_COUNT_CTOR(AVCSampleEntry); -} - -AVCSampleEntry::~AVCSampleEntry() -{ - MOZ_COUNT_DTOR(AVCSampleEntry); -} - -AVCConfigurationBox::AVCConfigurationBox(ISOControl* aControl) - : Box(NS_LITERAL_CSTRING("avcC"), aControl) -{ - MOZ_COUNT_CTOR(AVCConfigurationBox); -} - -AVCConfigurationBox::~AVCConfigurationBox() -{ - MOZ_COUNT_DTOR(AVCConfigurationBox); -} - -nsresult -AVCConfigurationBox::Generate(uint32_t* aBoxSize) -{ - nsresult rv; - FragmentBuffer* frag = mControl->GetFragment(Video_Track); - rv = frag->GetCSD(avcConfig); - NS_ENSURE_SUCCESS(rv, rv); - size += avcConfig.Length(); - *aBoxSize = size; - return NS_OK; -} - -nsresult -AVCConfigurationBox::Write() -{ - BoxSizeChecker checker(mControl, size); - Box::Write(); - - mControl->Write(avcConfig.Elements(), avcConfig.Length()); - - return NS_OK; -} - -} diff --git a/dom/media/encoder/fmp4_muxer/AVCBox.h b/dom/media/encoder/fmp4_muxer/AVCBox.h deleted file mode 100644 index 9640d9e8f..000000000 --- a/dom/media/encoder/fmp4_muxer/AVCBox.h +++ /dev/null @@ -1,59 +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 AVCBox_h_ -#define AVCBox_h_ - -#include "nsTArray.h" -#include "ISOMediaBoxes.h" - -namespace mozilla { - -class ISOControl; - -// 14496-12 8.5.2.2 -#define resolution_72_dpi 0x00480000 -#define video_depth 0x0018 - -// 14496-15 5.3.4.1 'Sample description name and format' -// Box type: 'avcC' -class AVCConfigurationBox : public Box { -public: - // ISO BMFF members - - // avcConfig is CodecSpecificData from 14496-15 '5.3.4.1 Sample description - // name and format. - // These data are generated by encoder and we encapsulated the generated - // bitstream into box directly. - nsTArray avcConfig; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // AVCConfigurationBox methods - AVCConfigurationBox(ISOControl* aControl); - ~AVCConfigurationBox(); -}; - -// 14496-15 5.3.4.1 'Sample description name and format' -// Box type: 'avc1' -class AVCSampleEntry : public VisualSampleEntry { -public: - // ISO BMFF members - RefPtr avcConfigBox; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // VisualSampleEntry methods - AVCSampleEntry(ISOControl* aControl); - ~AVCSampleEntry(); -}; - -} - -#endif // AVCBox_h_ diff --git a/dom/media/encoder/fmp4_muxer/EVRCBox.cpp b/dom/media/encoder/fmp4_muxer/EVRCBox.cpp deleted file mode 100644 index 096e4013d..000000000 --- a/dom/media/encoder/fmp4_muxer/EVRCBox.cpp +++ /dev/null @@ -1,84 +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 "ISOControl.h" -#include "ISOMediaBoxes.h" -#include "EVRCBox.h" -#include "ISOTrackMetadata.h" - -namespace mozilla { - -nsresult -EVRCSampleEntry::Generate(uint32_t* aBoxSize) -{ - uint32_t box_size; - nsresult rv = evrc_special_box->Generate(&box_size); - NS_ENSURE_SUCCESS(rv, rv); - size += box_size; - - *aBoxSize = size; - return NS_OK; -} - -nsresult -EVRCSampleEntry::Write() -{ - BoxSizeChecker checker(mControl, size); - nsresult rv; - rv = AudioSampleEntry::Write(); - NS_ENSURE_SUCCESS(rv, rv); - rv = evrc_special_box->Write(); - NS_ENSURE_SUCCESS(rv, rv); - - return NS_OK; -} - -EVRCSampleEntry::EVRCSampleEntry(ISOControl* aControl) - : AudioSampleEntry(NS_LITERAL_CSTRING("sevc"), aControl) -{ - evrc_special_box = new EVRCSpecificBox(aControl); - MOZ_COUNT_CTOR(EVRCSampleEntry); -} - -EVRCSampleEntry::~EVRCSampleEntry() -{ - MOZ_COUNT_DTOR(EVRCSampleEntry); -} - -nsresult -EVRCSpecificBox::Generate(uint32_t* aBoxSize) -{ - nsresult rv; - FragmentBuffer* frag = mControl->GetFragment(Audio_Track); - rv = frag->GetCSD(evrcDecSpecInfo); - NS_ENSURE_SUCCESS(rv, rv); - - size += evrcDecSpecInfo.Length(); - *aBoxSize = size; - - return NS_OK; -} - -nsresult -EVRCSpecificBox::Write() -{ - BoxSizeChecker checker(mControl, size); - Box::Write(); - mControl->Write(evrcDecSpecInfo.Elements(), evrcDecSpecInfo.Length()); - return NS_OK; -} - -EVRCSpecificBox::EVRCSpecificBox(ISOControl* aControl) - : Box(NS_LITERAL_CSTRING("devc"), aControl) -{ - MOZ_COUNT_CTOR(EVRCSpecificBox); -} - -EVRCSpecificBox::~EVRCSpecificBox() -{ - MOZ_COUNT_DTOR(EVRCSpecificBox); -} - -} diff --git a/dom/media/encoder/fmp4_muxer/EVRCBox.h b/dom/media/encoder/fmp4_muxer/EVRCBox.h deleted file mode 100644 index 31355849a..000000000 --- a/dom/media/encoder/fmp4_muxer/EVRCBox.h +++ /dev/null @@ -1,50 +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 EVRCBOX_h_ -#define EVRCBOX_h_ - -#include "nsTArray.h" -#include "MuxerOperation.h" - -namespace mozilla { - -class ISOControl; - -// 3GPP TS 26.244 6.7 'EVRCSpecificBox field for EVRCSampleEntry box' -// Box type: 'devc' -class EVRCSpecificBox : public Box { -public: - // 3GPP members - nsTArray evrcDecSpecInfo; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // EVRCSpecificBox methods - EVRCSpecificBox(ISOControl* aControl); - ~EVRCSpecificBox(); -}; - -// 3GPP TS 26.244 6.5 'EVRCSampleEntry box' -// Box type: 'sevc' -class EVRCSampleEntry : public AudioSampleEntry { -public: - // 3GPP members - RefPtr evrc_special_box; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // EVRCSampleEntry methods - EVRCSampleEntry(ISOControl* aControl); - ~EVRCSampleEntry(); -}; - -} - -#endif // EVRCBOX_h_ diff --git a/dom/media/encoder/fmp4_muxer/ISOControl.cpp b/dom/media/encoder/fmp4_muxer/ISOControl.cpp deleted file mode 100644 index 6addaeb30..000000000 --- a/dom/media/encoder/fmp4_muxer/ISOControl.cpp +++ /dev/null @@ -1,415 +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 -#include "nsAutoPtr.h" -#include "ISOControl.h" -#include "ISOMediaBoxes.h" -#include "EncodedFrameContainer.h" - -namespace mozilla { - -// For MP4 creation_time and modification_time offset from January 1, 1904 to -// January 1, 1970. -#define iso_time_offset 2082844800 - -FragmentBuffer::FragmentBuffer(uint32_t aTrackType, uint32_t aFragDuration) - : mTrackType(aTrackType) - , mFragDuration(aFragDuration) - , mMediaStartTime(0) - , mFragmentNumber(0) - , mLastFrameTimeOfLastFragment(0) - , mEOS(false) -{ - mFragArray.AppendElement(); - MOZ_COUNT_CTOR(FragmentBuffer); -} - -FragmentBuffer::~FragmentBuffer() -{ - MOZ_COUNT_DTOR(FragmentBuffer); -} - -bool -FragmentBuffer::HasEnoughData() -{ - // Audio or video frame is enough to form a moof. - return (mFragArray.Length() > 1); -} - -nsresult -FragmentBuffer::GetCSD(nsTArray& aCSD) -{ - if (!mCSDFrame) { - return NS_ERROR_FAILURE; - } - aCSD.AppendElements(mCSDFrame->GetFrameData().Elements(), - mCSDFrame->GetFrameData().Length()); - - return NS_OK; -} - -nsresult -FragmentBuffer::AddFrame(EncodedFrame* aFrame) -{ - // already EOS, it rejects all new data. - if (mEOS) { - MOZ_ASSERT(0); - return NS_OK; - } - - EncodedFrame::FrameType type = aFrame->GetFrameType(); - if (type == EncodedFrame::AAC_CSD || type == EncodedFrame::AVC_CSD || - type == EncodedFrame::AMR_AUDIO_CSD || type == EncodedFrame::EVRC_AUDIO_CSD) { - mCSDFrame = aFrame; - // Use CSD's timestamp as the start time. Encoder should send CSD frame first - // and then data frames. - mMediaStartTime = aFrame->GetTimeStamp(); - mFragmentNumber = 1; - return NS_OK; - } - - // if the timestamp is incorrect, abort it. - if (aFrame->GetTimeStamp() < mMediaStartTime) { - MOZ_ASSERT(false); - return NS_ERROR_FAILURE; - } - - mFragArray.LastElement().AppendElement(aFrame); - - // check if current fragment is reach the fragment duration. - if ((aFrame->GetTimeStamp() - mMediaStartTime) >= (mFragDuration * mFragmentNumber)) { - mFragArray.AppendElement(); - mFragmentNumber++; - } - - return NS_OK; -} - -nsresult -FragmentBuffer::GetFirstFragment(nsTArray>& aFragment, - bool aFlush) -{ - // It should be called only if there is a complete fragment in mFragArray. - if (mFragArray.Length() <= 1 && !mEOS) { - MOZ_ASSERT(false); - return NS_ERROR_FAILURE; - } - - if (aFlush) { - aFragment.SwapElements(mFragArray.ElementAt(0)); - mFragArray.RemoveElementAt(0); - } else { - aFragment.AppendElements(mFragArray.ElementAt(0)); - } - return NS_OK; -} - -uint32_t -FragmentBuffer::GetFirstFragmentSampleNumber() -{ - return mFragArray.ElementAt(0).Length(); -} - -uint32_t -FragmentBuffer::GetFirstFragmentSampleSize() -{ - uint32_t size = 0; - uint32_t len = mFragArray.ElementAt(0).Length(); - for (uint32_t i = 0; i < len; i++) { - size += mFragArray.ElementAt(0).ElementAt(i)->GetFrameData().Length(); - } - return size; -} - -ISOControl::ISOControl(uint32_t aMuxingType) - : mMuxingType(aMuxingType) - , mAudioFragmentBuffer(nullptr) - , mVideoFragmentBuffer(nullptr) - , mFragNum(0) - , mOutputSize(0) - , mBitCount(0) - , mBit(0) -{ - // Create a data array for first mp4 Box, ftyp. - mOutBuffers.SetLength(1); - MOZ_COUNT_CTOR(ISOControl); -} - -ISOControl::~ISOControl() -{ - MOZ_COUNT_DTOR(ISOControl); -} - -uint32_t -ISOControl::GetNextTrackID() -{ - return (mMetaArray.Length() + 1); -} - -uint32_t -ISOControl::GetTrackID(TrackMetadataBase::MetadataKind aKind) -{ - for (uint32_t i = 0; i < mMetaArray.Length(); i++) { - if (mMetaArray[i]->GetKind() == aKind) { - return (i + 1); - } - } - - // Track ID shouldn't be 0. It must be something wrong here. - MOZ_ASSERT(0); - return 0; -} - -nsresult -ISOControl::SetMetadata(TrackMetadataBase* aTrackMeta) -{ - if (aTrackMeta->GetKind() == TrackMetadataBase::METADATA_AAC || - aTrackMeta->GetKind() == TrackMetadataBase::METADATA_AMR || - aTrackMeta->GetKind() == TrackMetadataBase::METADATA_AVC || - aTrackMeta->GetKind() == TrackMetadataBase::METADATA_EVRC) { - mMetaArray.AppendElement(aTrackMeta); - return NS_OK; - } - return NS_ERROR_FAILURE; -} - -nsresult -ISOControl::GetAudioMetadata(RefPtr& aAudMeta) -{ - for (uint32_t i = 0; i < mMetaArray.Length() ; i++) { - if (mMetaArray[i]->GetKind() == TrackMetadataBase::METADATA_AAC || - mMetaArray[i]->GetKind() == TrackMetadataBase::METADATA_AMR || - mMetaArray[i]->GetKind() == TrackMetadataBase::METADATA_EVRC) { - aAudMeta = static_cast(mMetaArray[i].get()); - return NS_OK; - } - } - return NS_ERROR_FAILURE; -} - -nsresult -ISOControl::GetVideoMetadata(RefPtr& aVidMeta) -{ - for (uint32_t i = 0; i < mMetaArray.Length() ; i++) { - if (mMetaArray[i]->GetKind() == TrackMetadataBase::METADATA_AVC) { - aVidMeta = static_cast(mMetaArray[i].get()); - return NS_OK; - } - } - return NS_ERROR_FAILURE; -} - -bool -ISOControl::HasAudioTrack() -{ - RefPtr audMeta; - GetAudioMetadata(audMeta); - return audMeta; -} - -bool -ISOControl::HasVideoTrack() -{ - RefPtr vidMeta; - GetVideoMetadata(vidMeta); - return vidMeta; -} - -nsresult -ISOControl::SetFragment(FragmentBuffer* aFragment) -{ - if (aFragment->GetType() == Audio_Track) { - mAudioFragmentBuffer = aFragment; - } else { - mVideoFragmentBuffer = aFragment; - } - return NS_OK; -} - -FragmentBuffer* -ISOControl::GetFragment(uint32_t aType) -{ - if (aType == Audio_Track) { - return mAudioFragmentBuffer; - } else if (aType == Video_Track){ - return mVideoFragmentBuffer; - } - MOZ_ASSERT(0); - return nullptr; -} - -nsresult -ISOControl::GetBufs(nsTArray>* aOutputBufs) -{ - uint32_t len = mOutBuffers.Length(); - for (uint32_t i = 0; i < len; i++) { - mOutBuffers[i].SwapElements(*aOutputBufs->AppendElement()); - } - return FlushBuf(); -} - -nsresult -ISOControl::FlushBuf() -{ - mOutBuffers.SetLength(1); - return NS_OK; -} - -uint32_t -ISOControl::WriteAVData(nsTArray& aArray) -{ - MOZ_ASSERT(!mBitCount); - - uint32_t len = aArray.Length(); - if (!len) { - return 0; - } - - mOutputSize += len; - - // The last element already has data, allocated a new element for pointer - // swapping. - if (mOutBuffers.LastElement().Length()) { - mOutBuffers.AppendElement(); - } - // Swap the video/audio data pointer. - mOutBuffers.LastElement().SwapElements(aArray); - // Following data could be boxes, so appending a new uint8_t array here. - mOutBuffers.AppendElement(); - - return len; -} - -uint32_t -ISOControl::WriteBits(uint64_t aBits, size_t aNumBits) -{ - uint8_t output_byte = 0; - - MOZ_ASSERT(aNumBits <= 64); - // TODO: rewritten following with bitset? - for (size_t i = aNumBits; i > 0; i--) { - mBit |= (((aBits >> (i - 1)) & 1) << (8 - ++mBitCount)); - if (mBitCount == 8) { - Write(&mBit, sizeof(uint8_t)); - mBit = 0; - mBitCount = 0; - output_byte++; - } - } - return output_byte; -} - -uint32_t -ISOControl::Write(uint8_t* aBuf, uint32_t aSize) -{ - mOutBuffers.LastElement().AppendElements(aBuf, aSize); - mOutputSize += aSize; - return aSize; -} - -uint32_t -ISOControl::Write(uint8_t aData) -{ - MOZ_ASSERT(!mBitCount); - Write((uint8_t*)&aData, sizeof(uint8_t)); - return sizeof(uint8_t); -} - -uint32_t -ISOControl::GetBufPos() -{ - uint32_t len = mOutBuffers.Length(); - uint32_t pos = 0; - for (uint32_t i = 0; i < len; i++) { - pos += mOutBuffers.ElementAt(i).Length(); - } - return pos; -} - -uint32_t -ISOControl::WriteFourCC(const char* aType) -{ - // Bit operation should be aligned to byte before writing any byte data. - MOZ_ASSERT(!mBitCount); - - uint32_t size = strlen(aType); - if (size == 4) { - return Write((uint8_t*)aType, size); - } - - return 0; -} - -nsresult -ISOControl::GenerateFtyp() -{ - nsresult rv; - uint32_t size; - nsAutoPtr type_box(new FileTypeBox(this)); - rv = type_box->Generate(&size); - NS_ENSURE_SUCCESS(rv, rv); - rv = type_box->Write(); - NS_ENSURE_SUCCESS(rv, rv); - return NS_OK; -} - -nsresult -ISOControl::GenerateMoov() -{ - nsresult rv; - uint32_t size; - nsAutoPtr moov_box(new MovieBox(this)); - rv = moov_box->Generate(&size); - NS_ENSURE_SUCCESS(rv, rv); - rv = moov_box->Write(); - NS_ENSURE_SUCCESS(rv, rv); - return NS_OK; -} - -nsresult -ISOControl::GenerateMoof(uint32_t aTrackType) -{ - mFragNum++; - - nsresult rv; - uint32_t size; - uint64_t first_sample_offset = mOutputSize; - nsAutoPtr moof_box(new MovieFragmentBox(aTrackType, this)); - nsAutoPtr mdat_box(new MediaDataBox(aTrackType, this)); - - rv = moof_box->Generate(&size); - NS_ENSURE_SUCCESS(rv, rv); - first_sample_offset += size; - rv = mdat_box->Generate(&size); - NS_ENSURE_SUCCESS(rv, rv); - first_sample_offset += mdat_box->FirstSampleOffsetInMediaDataBox(); - - // correct offset info - nsTArray> tfhds; - rv = moof_box->Find(NS_LITERAL_CSTRING("tfhd"), tfhds); - NS_ENSURE_SUCCESS(rv, rv); - uint32_t len = tfhds.Length(); - for (uint32_t i = 0; i < len; i++) { - TrackFragmentHeaderBox* tfhd = (TrackFragmentHeaderBox*) tfhds.ElementAt(i).get(); - rv = tfhd->UpdateBaseDataOffset(first_sample_offset); - NS_ENSURE_SUCCESS(rv, rv); - } - - rv = moof_box->Write(); - NS_ENSURE_SUCCESS(rv, rv); - rv = mdat_box->Write(); - NS_ENSURE_SUCCESS(rv, rv); - - return NS_OK; -} - -uint32_t -ISOControl::GetTime() -{ - return (uint64_t)time(nullptr) + iso_time_offset; -} - -} diff --git a/dom/media/encoder/fmp4_muxer/ISOControl.h b/dom/media/encoder/fmp4_muxer/ISOControl.h deleted file mode 100644 index 3c445caee..000000000 --- a/dom/media/encoder/fmp4_muxer/ISOControl.h +++ /dev/null @@ -1,250 +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 ISOCOMPOSITOR_H_ -#define ISOCOMPOSITOR_H_ - -#include "mozilla/EndianUtils.h" -#include "nsTArray.h" -#include "ISOTrackMetadata.h" -#include "EncodedFrameContainer.h" - -namespace mozilla { - -class Box; -class ISOControl; - -/** - * This class collects elementary stream data to form a fragment. - * ISOMediaWriter will check if the data is enough; if yes, the corresponding - * moof will be created and write to ISOControl. - * Each audio and video has its own fragment and only one during the whole - * life cycle, when a fragment is formed in ISOControl, Flush() needs to - * be called to reset it. - */ -class FragmentBuffer { -public: - // aTrackType: it could be Audio_Track or Video_Track. - // aFragDuration: it is the fragment duration. (microsecond per unit) - // Audio and video have the same fragment duration. - FragmentBuffer(uint32_t aTrackType, uint32_t aFragDuration); - ~FragmentBuffer(); - - // Get samples of first fragment, that will swap all the elements in the - // mFragArray[0] when aFlush = true, and caller is responsible for drop - // EncodedFrame reference count. - nsresult GetFirstFragment(nsTArray>& aFragment, - bool aFlush = false); - - // Add sample frame to the last element fragment of mFragArray. If sample - // number is enough, it will append a new fragment element. And the new - // sample will be added to the new fragment element of mFragArray. - nsresult AddFrame(EncodedFrame* aFrame); - - // Get total sample size of first complete fragment size. - uint32_t GetFirstFragmentSampleSize(); - - // Get sample number of first complete fragment. - uint32_t GetFirstFragmentSampleNumber(); - - // Check if it accumulates enough frame data. - // It returns true when data is enough to form a fragment. - bool HasEnoughData(); - - // Called by ISOMediaWriter when TrackEncoder has sent the last frame. The - // remains frame data will form the last moof and move the state machine to - // in ISOMediaWriter to last phrase. - nsresult SetEndOfStream() { - mEOS = true; - return NS_OK; - } - bool EOS() { return mEOS; } - - // CSD (codec specific data), it is generated by encoder and the data depends - // on codec type. This data will be sent as a special frame from encoder to - // ISOMediaWriter and pass to this class via AddFrame(). - nsresult GetCSD(nsTArray& aCSD); - - bool HasCSD() { return mCSDFrame; } - - uint32_t GetType() { return mTrackType; } - - void SetLastFragmentLastFrameTime(uint32_t aTime) { - mLastFrameTimeOfLastFragment = aTime; - } - - uint32_t GetLastFragmentLastFrameTime() { - return mLastFrameTimeOfLastFragment; - } - -private: - uint32_t mTrackType; - - // Fragment duration, microsecond per unit. - uint32_t mFragDuration; - - // Media start time, microsecond per unit. - // Together with mFragDuration, mFragmentNumber and EncodedFrame->GetTimeStamp(), - // when the difference between current frame time and mMediaStartTime is - // exceeded current fragment ceiling timeframe, that means current fragment has - // enough data and a new element in mFragArray will be added. - uint64_t mMediaStartTime; - - // Current fragment number. It will be increase when a new element of - // mFragArray is created. - // Note: - // It only means the fragment number of current accumulated frames, not - // the current 'creating' fragment mFragNum in ISOControl. - uint32_t mFragmentNumber; - - // The last frame time stamp of last fragment. It is for calculating the - // play duration of first frame in current fragment. The frame duration is - // defined as "current frame timestamp - last frame timestamp" here. So it - // needs to keep the last timestamp of last fragment. - uint32_t mLastFrameTimeOfLastFragment; - - // Array of fragments, each element has enough samples to form a - // complete fragment. - nsTArray>> mFragArray; - - // Codec specific data frame, it will be generated by encoder and send to - // ISOMediaWriter through WriteEncodedTrack(). The data will be vary depends - // on codec type. - RefPtr mCSDFrame; - - // END_OF_STREAM from ContainerWriter - bool mEOS; -}; - -/** - * ISOControl will be carried to each box when box is created. It is the main - * bridge for box to output stream to ContainerWriter and retrieve information. - * ISOControl acts 3 different roles: - * 1. Holds the pointer of audio metadata, video metadata, fragment and - * pass them to boxes. - * 2. Provide the functions to generate the base structure of MP4; they are - * GenerateFtyp, GenerateMoov, GenerateMoof, and GenerateMfra. - * 3. The actually writer used by MuxOperation::Write() in each box. It provides - * writing methods for different kind of data; they are Write, WriteArray, - * WriteBits...etc. - */ -class ISOControl { - -friend class Box; - -public: - ISOControl(uint32_t aMuxingType); - ~ISOControl(); - - nsresult GenerateFtyp(); - nsresult GenerateMoov(); - nsresult GenerateMoof(uint32_t aTrackType); - - // Swap elementary stream pointer to output buffers. - uint32_t WriteAVData(nsTArray& aArray); - - uint32_t Write(uint8_t* aBuf, uint32_t aSize); - - uint32_t Write(uint8_t aData); - - template - uint32_t Write(T aData) { - MOZ_ASSERT(!mBitCount); - - aData = NativeEndian::swapToNetworkOrder(aData); - Write((uint8_t*)&aData, sizeof(T)); - return sizeof(T); - } - - template - uint32_t WriteArray(const T &aArray, uint32_t aSize) { - MOZ_ASSERT(!mBitCount); - - uint32_t size = 0; - for (uint32_t i = 0; i < aSize; i++) { - size += Write(aArray[i]); - } - return size; - } - - uint32_t WriteFourCC(const char* aType); - - // Bit writing. Note: it needs to be byte-boundary before using - // others non-bit writing function. - uint32_t WriteBits(uint64_t aBits, size_t aNumBits); - - // This is called by GetContainerData and swap all the buffers to aOutputBuffers. - nsresult GetBufs(nsTArray>* aOutputBufs); - - // Presentation time in seconds since midnight, Jan. 1, 1904, in UTC time. - uint32_t GetTime(); - - // current fragment number - uint32_t GetCurFragmentNumber() { return mFragNum; } - - nsresult SetFragment(FragmentBuffer* aFragment); - FragmentBuffer* GetFragment(uint32_t aType); - - uint32_t GetMuxingType() { return mMuxingType; } - - nsresult SetMetadata(TrackMetadataBase* aTrackMeta); - nsresult GetAudioMetadata(RefPtr& aAudMeta); - nsresult GetVideoMetadata(RefPtr& aVidMeta); - - // Track ID is the Metadata index in mMetaArray. It allows only 1 audio - // track and 1 video track in this muxer. In this muxer, it is prohibt to have - // mutiple audio track or video track in the same file. - uint32_t GetTrackID(TrackMetadataBase::MetadataKind aKind); - uint32_t GetNextTrackID(); - - bool HasAudioTrack(); - bool HasVideoTrack(); - -private: - uint32_t GetBufPos(); - nsresult FlushBuf(); - - // One of value in TYPE_XXX, defined in ISOMediaWriter. - uint32_t mMuxingType; - - // Audio and video fragments are owned by ISOMediaWriter. - // They don't need to worry about pointer going stale because ISOMediaWriter's - // lifetime is longer than ISOControl. - FragmentBuffer* mAudioFragmentBuffer; - FragmentBuffer* mVideoFragmentBuffer; - - // Generated fragment number - uint32_t mFragNum; - - // The (index + 1) will be the track ID. - nsTArray> mMetaArray; - - // Array of output buffers. - // To save memory usage, audio/video sample will be swapped into a new element - // of this array. - // - // For example, - // mOutBuffers[0] --> boxes (allocated by muxer) - // mOutBuffers[1] --> video raw data (allocated by encoder) - // mOutBuffers[2] --> video raw data (allocated by encoder) - // mOutBuffers[3] --> video raw data (allocated by encoder) - // mOutBuffers[4] --> boxes (allocated by muxer) - // mOutBuffers[5] --> audio raw data (allocated by encoder) - // ...etc. - // - nsTArray> mOutBuffers; - - // Accumulate output size from Write(). - uint64_t mOutputSize; - - // Bit writing operation. Note: the mBitCount should be 0 before any - // byte-boundary writing method be called (Write(uint32_t), Write(uint16_t)...etc); - // otherwise, there will be assertion on these functions. - uint8_t mBitCount; - uint8_t mBit; -}; - -} -#endif diff --git a/dom/media/encoder/fmp4_muxer/ISOMediaBoxes.cpp b/dom/media/encoder/fmp4_muxer/ISOMediaBoxes.cpp deleted file mode 100644 index 32a0c577b..000000000 --- a/dom/media/encoder/fmp4_muxer/ISOMediaBoxes.cpp +++ /dev/null @@ -1,1550 +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 -#include "TrackMetadataBase.h" -#include "ISOMediaBoxes.h" -#include "ISOControl.h" -#include "ISOMediaWriter.h" -#include "EncodedFrameContainer.h" -#include "ISOTrackMetadata.h" -#include "MP4ESDS.h" -#include "AMRBox.h" -#include "AVCBox.h" -#include "EVRCBox.h" -#include "VideoUtils.h" - -namespace mozilla { - -// 14496-12 6.2.2 'Data Types and fields' -const uint32_t iso_matrix[] = { 0x00010000, 0, 0, - 0, 0x00010000, 0, - 0, 0, 0x40000000 }; - -uint32_t -set_sample_flags(bool aSync) -{ - std::bitset<32> flags; - flags.set(16, !aSync); - return flags.to_ulong(); -} - -Box::BoxSizeChecker::BoxSizeChecker(ISOControl* aControl, uint32_t aSize) -{ - mControl = aControl; - ori_size = mControl->GetBufPos(); - box_size = aSize; - MOZ_COUNT_CTOR(BoxSizeChecker); -} - -Box::BoxSizeChecker::~BoxSizeChecker() -{ - uint32_t cur_size = mControl->GetBufPos(); - if ((cur_size - ori_size) != box_size) { - MOZ_ASSERT(false); - } - - MOZ_COUNT_DTOR(BoxSizeChecker); -} - -nsresult -MediaDataBox::Generate(uint32_t* aBoxSize) -{ - mFirstSampleOffset = size; - mAllSampleSize = 0; - - if (mTrackType & Audio_Track) { - FragmentBuffer* frag = mControl->GetFragment(Audio_Track); - mAllSampleSize += frag->GetFirstFragmentSampleSize(); - } - if (mTrackType & Video_Track) { - FragmentBuffer* frag = mControl->GetFragment(Video_Track); - mAllSampleSize += frag->GetFirstFragmentSampleSize(); - } - - size += mAllSampleSize; - *aBoxSize = size; - return NS_OK; -} - -nsresult -MediaDataBox::Write() -{ - nsresult rv; - BoxSizeChecker checker(mControl, size); - Box::Write(); - nsTArray types; - types.AppendElement(Audio_Track); - types.AppendElement(Video_Track); - - for (uint32_t l = 0; l < types.Length(); l++) { - if (mTrackType & types[l]) { - FragmentBuffer* frag = mControl->GetFragment(types[l]); - nsTArray> frames; - - // Here is the last time we get fragment frames, flush it! - rv = frag->GetFirstFragment(frames, true); - NS_ENSURE_SUCCESS(rv, rv); - - uint32_t len = frames.Length(); - for (uint32_t i = 0; i < len; i++) { - nsTArray frame_buffer; - frames.ElementAt(i)->SwapOutFrameData(frame_buffer); - mControl->WriteAVData(frame_buffer); - } - } - } - - return NS_OK; -} - -MediaDataBox::MediaDataBox(uint32_t aTrackType, ISOControl* aControl) - : Box(NS_LITERAL_CSTRING("mdat"), aControl) - , mAllSampleSize(0) - , mFirstSampleOffset(0) - , mTrackType(aTrackType) -{ - MOZ_COUNT_CTOR(MediaDataBox); -} - -MediaDataBox::~MediaDataBox() -{ - MOZ_COUNT_DTOR(MediaDataBox); -} - -uint32_t -TrackRunBox::fillSampleTable() -{ - uint32_t table_size = 0; - nsresult rv; - nsTArray> frames; - FragmentBuffer* frag = mControl->GetFragment(mTrackType); - - rv = frag->GetFirstFragment(frames); - if (NS_FAILED(rv)) { - return 0; - } - uint32_t len = frames.Length(); - sample_info_table = MakeUnique(len); - // Create sample table according to 14496-12 8.8.8.2. - for (uint32_t i = 0; i < len; i++) { - // Sample size. - sample_info_table[i].sample_size = 0; - if (flags.to_ulong() & flags_sample_size_present) { - sample_info_table[i].sample_size = frames.ElementAt(i)->GetFrameData().Length(); - mAllSampleSize += sample_info_table[i].sample_size; - table_size += sizeof(uint32_t); - } - - // Sample flags. - sample_info_table[i].sample_flags = 0; - if (flags.to_ulong() & flags_sample_flags_present) { - sample_info_table[i].sample_flags = - set_sample_flags( - (frames.ElementAt(i)->GetFrameType() == EncodedFrame::AVC_I_FRAME)); - table_size += sizeof(uint32_t); - } - - // Sample duration. - sample_info_table[i].sample_duration = 0; - if (flags.to_ulong() & flags_sample_duration_present) { - // Calculate each frame's duration, it is decided by "current frame - // timestamp - last frame timestamp". - uint64_t frame_time = 0; - if (i == 0) { - frame_time = frames.ElementAt(i)->GetTimeStamp() - - frag->GetLastFragmentLastFrameTime(); - } else { - frame_time = frames.ElementAt(i)->GetTimeStamp() - - frames.ElementAt(i - 1)->GetTimeStamp(); - // Keep the last frame time of current fagment, it will be used to calculate - // the first frame duration of next fragment. - if ((len - 1) == i) { - frag->SetLastFragmentLastFrameTime(frames.ElementAt(i)->GetTimeStamp()); - } - } - - // In TrackRunBox, there should be exactly one type, either audio or video. - MOZ_ASSERT((mTrackType & Video_Track) ^ (mTrackType & Audio_Track)); - sample_info_table[i].sample_duration = (mTrackType & Video_Track ? - frame_time * mVideoMeta->GetVideoClockRate() / USECS_PER_S : - frame_time * mAudioMeta->GetAudioSampleRate() / USECS_PER_S); - - table_size += sizeof(uint32_t); - } - - sample_info_table[i].sample_composition_time_offset = 0; - } - return table_size; -} - -nsresult -TrackRunBox::Generate(uint32_t* aBoxSize) -{ - FragmentBuffer* frag = mControl->GetFragment(mTrackType); - sample_count = frag->GetFirstFragmentSampleNumber(); - size += sizeof(sample_count); - - // data_offset needs to be updated if there is other - // TrackRunBox before this one. - if (flags.to_ulong() & flags_data_offset_present) { - data_offset = 0; - size += sizeof(data_offset); - } - size += fillSampleTable(); - - *aBoxSize = size; - - return NS_OK; -} - -nsresult -TrackRunBox::SetDataOffset(uint32_t aOffset) -{ - data_offset = aOffset; - return NS_OK; -} - -nsresult -TrackRunBox::Write() -{ - WRITE_FULLBOX(mControl, size) - mControl->Write(sample_count); - if (flags.to_ulong() & flags_data_offset_present) { - mControl->Write(data_offset); - } - for (uint32_t i = 0; i < sample_count; i++) { - if (flags.to_ulong() & flags_sample_duration_present) { - mControl->Write(sample_info_table[i].sample_duration); - } - if (flags.to_ulong() & flags_sample_size_present) { - mControl->Write(sample_info_table[i].sample_size); - } - if (flags.to_ulong() & flags_sample_flags_present) { - mControl->Write(sample_info_table[i].sample_flags); - } - } - - return NS_OK; -} - -TrackRunBox::TrackRunBox(uint32_t aType, uint32_t aFlags, ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("trun"), 0, aFlags, aControl) - , sample_count(0) - , data_offset(0) - , first_sample_flags(0) - , mAllSampleSize(0) - , mTrackType(aType) -{ - MOZ_COUNT_CTOR(TrackRunBox); -} - -TrackRunBox::~TrackRunBox() -{ - MOZ_COUNT_DTOR(TrackRunBox); -} - -nsresult -TrackFragmentHeaderBox::UpdateBaseDataOffset(uint64_t aOffset) -{ - base_data_offset = aOffset; - return NS_OK; -} - -nsresult -TrackFragmentHeaderBox::Generate(uint32_t* aBoxSize) -{ - track_ID = (mTrackType == Audio_Track ? - mControl->GetTrackID(mAudioMeta->GetKind()) : - mControl->GetTrackID(mVideoMeta->GetKind())); - size += sizeof(track_ID); - - if (flags.to_ulong() & base_data_offset_present) { - // base_data_offset needs to add size of 'trun', 'tfhd' and - // header of 'mdat' later. - base_data_offset = 0; - size += sizeof(base_data_offset); - } - if (flags.to_ulong() & default_sample_duration_present) { - if (mTrackType == Video_Track) { - if (!mVideoMeta->GetVideoFrameRate()) { - // 0 means frame rate is variant, so it is wrong to write - // default_sample_duration. - MOZ_ASSERT(0); - default_sample_duration = 0; - } else { - default_sample_duration = mVideoMeta->GetVideoClockRate() / mVideoMeta->GetVideoFrameRate(); - } - } else if (mTrackType == Audio_Track) { - default_sample_duration = mAudioMeta->GetAudioFrameDuration(); - } else { - MOZ_ASSERT(0); - return NS_ERROR_FAILURE; - } - size += sizeof(default_sample_duration); - } - *aBoxSize = size; - return NS_OK; -} - -nsresult -TrackFragmentHeaderBox::Write() -{ - WRITE_FULLBOX(mControl, size) - mControl->Write(track_ID); - if (flags.to_ulong() & base_data_offset_present) { - mControl->Write(base_data_offset); - } - if (flags.to_ulong() & default_sample_duration_present) { - mControl->Write(default_sample_duration); - } - return NS_OK; -} - -TrackFragmentHeaderBox::TrackFragmentHeaderBox(uint32_t aType, - uint32_t aFlags, - ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("tfhd"), 0, aFlags, aControl) - , track_ID(0) - , base_data_offset(0) - , default_sample_duration(0) -{ - mTrackType = aType; - MOZ_COUNT_CTOR(TrackFragmentHeaderBox); -} - -TrackFragmentHeaderBox::~TrackFragmentHeaderBox() -{ - MOZ_COUNT_DTOR(TrackFragmentHeaderBox); -} - -TrackFragmentBox::TrackFragmentBox(uint32_t aType, ISOControl* aControl) - : DefaultContainerImpl(NS_LITERAL_CSTRING("traf"), aControl) - , mTrackType(aType) -{ - // Flags in TrackFragmentHeaderBox. - uint32_t tf_flags = base_data_offset_present; - - // Ideally, audio encoder generates audio frame in const rate. However, some - // audio encoders don't do it so the audio frame duration needs to be checked - // here. - if ((mTrackType & Audio_Track) && mAudioMeta->GetAudioFrameDuration()) { - tf_flags |= default_sample_duration_present; - } - - boxes.AppendElement(new TrackFragmentHeaderBox(aType, tf_flags, aControl)); - - // Always adds flags_data_offset_present in each TrackRunBox, Android - // parser requires this flag to calculate the correct bitstream offset. - uint32_t tr_flags = flags_sample_size_present | flags_data_offset_present; - - // Flags in TrackRunBox. - // If there is no default sample duration exists, each frame duration needs to - // be recored in the TrackRunBox. - tr_flags |= (tf_flags & default_sample_duration_present ? 0 : flags_sample_duration_present); - - // For video, add sample_flags to record I frame. - tr_flags |= (mTrackType & Video_Track ? flags_sample_flags_present : 0); - - boxes.AppendElement(new TrackRunBox(mTrackType, tr_flags, aControl)); - MOZ_COUNT_CTOR(TrackFragmentBox); -} - -TrackFragmentBox::~TrackFragmentBox() -{ - MOZ_COUNT_DTOR(TrackFragmentBox); -} - -nsresult -MovieFragmentHeaderBox::Generate(uint32_t* aBoxSize) -{ - sequence_number = mControl->GetCurFragmentNumber(); - size += sizeof(sequence_number); - *aBoxSize = size; - return NS_OK; -} - -nsresult -MovieFragmentHeaderBox::Write() -{ - WRITE_FULLBOX(mControl, size) - mControl->Write(sequence_number); - return NS_OK; -} - -MovieFragmentHeaderBox::MovieFragmentHeaderBox(uint32_t aTrackType, - ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("mfhd"), 0, 0, aControl) - , sequence_number(0) - , mTrackType(aTrackType) -{ - MOZ_COUNT_CTOR(MovieFragmentHeaderBox); -} - -MovieFragmentHeaderBox::~MovieFragmentHeaderBox() -{ - MOZ_COUNT_DTOR(MovieFragmentHeaderBox); -} - -MovieFragmentBox::MovieFragmentBox(uint32_t aType, ISOControl* aControl) - : DefaultContainerImpl(NS_LITERAL_CSTRING("moof"), aControl) - , mTrackType(aType) -{ - boxes.AppendElement(new MovieFragmentHeaderBox(mTrackType, aControl)); - - if (mTrackType & Audio_Track) { - boxes.AppendElement( - new TrackFragmentBox(Audio_Track, aControl)); - } - if (mTrackType & Video_Track) { - boxes.AppendElement( - new TrackFragmentBox(Video_Track, aControl)); - } - MOZ_COUNT_CTOR(MovieFragmentBox); -} - -MovieFragmentBox::~MovieFragmentBox() -{ - MOZ_COUNT_DTOR(MovieFragmentBox); -} - -nsresult -MovieFragmentBox::Generate(uint32_t* aBoxSize) -{ - nsresult rv = DefaultContainerImpl::Generate(aBoxSize); - NS_ENSURE_SUCCESS(rv, rv); - - // Correct data_offset if there are both audio and video track in - // this fragment. This offset means the offset in the MediaDataBox. - if (mTrackType & (Audio_Track | Video_Track)) { - nsTArray> truns; - rv = Find(NS_LITERAL_CSTRING("trun"), truns); - NS_ENSURE_SUCCESS(rv, rv); - uint32_t len = truns.Length(); - uint32_t data_offset = 0; - for (uint32_t i = 0; i < len; i++) { - TrackRunBox* trun = (TrackRunBox*) truns.ElementAt(i).get(); - rv = trun->SetDataOffset(data_offset); - NS_ENSURE_SUCCESS(rv, rv); - data_offset += trun->GetAllSampleSize(); - } - } - - return NS_OK; -} - -nsresult -TrackExtendsBox::Generate(uint32_t* aBoxSize) -{ - track_ID = (mTrackType == Audio_Track ? - mControl->GetTrackID(mAudioMeta->GetKind()) : - mControl->GetTrackID(mVideoMeta->GetKind())); - - if (mTrackType == Audio_Track) { - default_sample_description_index = 1; - default_sample_duration = mAudioMeta->GetAudioFrameDuration(); - default_sample_size = mAudioMeta->GetAudioFrameSize(); - default_sample_flags = set_sample_flags(1); - } else if (mTrackType == Video_Track) { - default_sample_description_index = 1; - // Video meta data has assigned framerate, it implies that this video's - // frame rate should be fixed. - if (mVideoMeta->GetVideoFrameRate()) { - default_sample_duration = - mVideoMeta->GetVideoClockRate() / mVideoMeta->GetVideoFrameRate(); - } - default_sample_size = 0; - default_sample_flags = set_sample_flags(0); - } else { - MOZ_ASSERT(0); - return NS_ERROR_FAILURE; - } - - size += sizeof(track_ID) + - sizeof(default_sample_description_index) + - sizeof(default_sample_duration) + - sizeof(default_sample_size) + - sizeof(default_sample_flags); - - *aBoxSize = size; - - return NS_OK; -} - -nsresult -TrackExtendsBox::Write() -{ - WRITE_FULLBOX(mControl, size) - mControl->Write(track_ID); - mControl->Write(default_sample_description_index); - mControl->Write(default_sample_duration); - mControl->Write(default_sample_size); - mControl->Write(default_sample_flags); - - return NS_OK; -} - -TrackExtendsBox::TrackExtendsBox(uint32_t aType, ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("trex"), 0, 0, aControl) - , track_ID(0) - , default_sample_description_index(0) - , default_sample_duration(0) - , default_sample_size(0) - , default_sample_flags(0) - , mTrackType(aType) -{ - MOZ_COUNT_CTOR(TrackExtendsBox); -} - -TrackExtendsBox::~TrackExtendsBox() -{ - MOZ_COUNT_DTOR(TrackExtendsBox); -} - -MovieExtendsBox::MovieExtendsBox(ISOControl* aControl) - : DefaultContainerImpl(NS_LITERAL_CSTRING("mvex"), aControl) -{ - if (mAudioMeta) { - boxes.AppendElement(new TrackExtendsBox(Audio_Track, aControl)); - } - if (mVideoMeta) { - boxes.AppendElement(new TrackExtendsBox(Video_Track, aControl)); - } - MOZ_COUNT_CTOR(MovieExtendsBox); -} - -MovieExtendsBox::~MovieExtendsBox() -{ - MOZ_COUNT_DTOR(MovieExtendsBox); -} - -nsresult -ChunkOffsetBox::Generate(uint32_t* aBoxSize) -{ - // We don't need time to sample table in fragmented mp4. - entry_count = 0; - size += sizeof(entry_count); - *aBoxSize = size; - return NS_OK; -} - -nsresult -ChunkOffsetBox::Write() -{ - WRITE_FULLBOX(mControl, size) - mControl->Write(entry_count); - return NS_OK; -} - -ChunkOffsetBox::ChunkOffsetBox(uint32_t aType, ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("stco"), 0, 0, aControl) - , entry_count(0) -{ - MOZ_COUNT_CTOR(ChunkOffsetBox); -} - -ChunkOffsetBox::~ChunkOffsetBox() -{ - MOZ_COUNT_DTOR(ChunkOffsetBox); -} - -nsresult -SampleToChunkBox::Generate(uint32_t* aBoxSize) -{ - // We don't need time to sample table in fragmented mp4 - entry_count = 0; - size += sizeof(entry_count); - *aBoxSize = size; - return NS_OK; -} - -nsresult -SampleToChunkBox::Write() -{ - WRITE_FULLBOX(mControl, size) - mControl->Write(entry_count); - return NS_OK; -} - -SampleToChunkBox::SampleToChunkBox(uint32_t aType, ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("stsc"), 0, 0, aControl) - , entry_count(0) -{ - MOZ_COUNT_CTOR(SampleToChunkBox); -} - -SampleToChunkBox::~SampleToChunkBox() -{ - MOZ_COUNT_DTOR(SampleToChunkBox); -} - -nsresult -TimeToSampleBox::Generate(uint32_t* aBoxSize) -{ - // We don't need time to sample table in fragmented mp4. - entry_count = 0; - size += sizeof(entry_count); - *aBoxSize = size; - return NS_OK; -} - -nsresult -TimeToSampleBox::Write() -{ - WRITE_FULLBOX(mControl, size) - mControl->Write(entry_count); - return NS_OK; -} - -TimeToSampleBox::TimeToSampleBox(uint32_t aType, ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("stts"), 0, 0, aControl) - , entry_count(0) -{ - MOZ_COUNT_CTOR(TimeToSampleBox); -} - -TimeToSampleBox::~TimeToSampleBox() -{ - MOZ_COUNT_DTOR(TimeToSampleBox); -} - -nsresult -SampleDescriptionBox::Generate(uint32_t* aBoxSize) -{ - entry_count = 1; - size += sizeof(entry_count); - - nsresult rv; - uint32_t box_size; - rv = sample_entry_box->Generate(&box_size); - NS_ENSURE_SUCCESS(rv, rv); - size += box_size; - *aBoxSize = size; - - return NS_OK; -} - -nsresult -SampleDescriptionBox::Write() -{ - WRITE_FULLBOX(mControl, size) - nsresult rv; - mControl->Write(entry_count); - rv = sample_entry_box->Write(); - NS_ENSURE_SUCCESS(rv, rv); - - return NS_OK; -} - -SampleDescriptionBox::SampleDescriptionBox(uint32_t aType, ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("stsd"), 0, 0, aControl) - , entry_count(0) -{ - mTrackType = aType; - - switch (mTrackType) { - case Audio_Track: - { - CreateAudioSampleEntry(sample_entry_box); - } - break; - case Video_Track: - { - CreateVideoSampleEntry(sample_entry_box); - } - break; - } - MOZ_ASSERT(sample_entry_box); - MOZ_COUNT_CTOR(SampleDescriptionBox); -} - -nsresult -SampleDescriptionBox::CreateAudioSampleEntry(RefPtr& aSampleEntry) -{ - if (mAudioMeta->GetKind() == TrackMetadataBase::METADATA_AMR) { - aSampleEntry = new AMRSampleEntry(mControl); - } else if (mAudioMeta->GetKind() == TrackMetadataBase::METADATA_AAC) { - aSampleEntry = new MP4AudioSampleEntry(mControl); - } else if (mAudioMeta->GetKind() == TrackMetadataBase::METADATA_EVRC) { - aSampleEntry = new EVRCSampleEntry(mControl); - } else { - MOZ_ASSERT(0); - } - return NS_OK; -} - -nsresult -SampleDescriptionBox::CreateVideoSampleEntry(RefPtr& aSampleEntry) -{ - if (mVideoMeta->GetKind() == TrackMetadataBase::METADATA_AVC) { - aSampleEntry = new AVCSampleEntry(mControl); - } else { - MOZ_ASSERT(0); - } - return NS_OK; -} - -SampleDescriptionBox::~SampleDescriptionBox() -{ - MOZ_COUNT_DTOR(SampleDescriptionBox); -} - -nsresult -SampleSizeBox::Generate(uint32_t* aBoxSize) -{ - size += sizeof(sample_size) + - sizeof(sample_count); - *aBoxSize = size; - return NS_OK; -} - -nsresult -SampleSizeBox::Write() -{ - WRITE_FULLBOX(mControl, size) - mControl->Write(sample_size); - mControl->Write(sample_count); - return NS_OK; -} - -SampleSizeBox::SampleSizeBox(ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("stsz"), 0, 0, aControl) - , sample_size(0) - , sample_count(0) -{ - MOZ_COUNT_CTOR(SampleSizeBox); -} - -SampleSizeBox::~SampleSizeBox() -{ - MOZ_COUNT_DTOR(SampleSizeBox); -} - -SampleTableBox::SampleTableBox(uint32_t aType, ISOControl* aControl) - : DefaultContainerImpl(NS_LITERAL_CSTRING("stbl"), aControl) -{ - boxes.AppendElement(new SampleDescriptionBox(aType, aControl)); - boxes.AppendElement(new TimeToSampleBox(aType, aControl)); - boxes.AppendElement(new SampleToChunkBox(aType, aControl)); - boxes.AppendElement(new SampleSizeBox(aControl)); - boxes.AppendElement(new ChunkOffsetBox(aType, aControl)); - MOZ_COUNT_CTOR(SampleTableBox); -} - -SampleTableBox::~SampleTableBox() -{ - MOZ_COUNT_DTOR(SampleTableBox); -} - -nsresult -DataEntryUrlBox::Generate(uint32_t* aBoxSize) -{ - // location is null here, do nothing - size += location.Length(); - *aBoxSize = size; - - return NS_OK; -} - -nsresult -DataEntryUrlBox::Write() -{ - WRITE_FULLBOX(mControl, size) - return NS_OK; -} - -DataEntryUrlBox::DataEntryUrlBox() - : FullBox(NS_LITERAL_CSTRING("url "), 0, 0, (ISOControl*) nullptr) -{ - MOZ_COUNT_CTOR(DataEntryUrlBox); -} - -DataEntryUrlBox::DataEntryUrlBox(ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("url "), 0, flags_media_at_the_same_file, aControl) -{ - MOZ_COUNT_CTOR(DataEntryUrlBox); -} - -DataEntryUrlBox::DataEntryUrlBox(const DataEntryUrlBox& aBox) - : FullBox(aBox.boxType, aBox.version, aBox.flags.to_ulong(), aBox.mControl) -{ - location = aBox.location; - MOZ_COUNT_CTOR(DataEntryUrlBox); -} - -DataEntryUrlBox::~DataEntryUrlBox() -{ - MOZ_COUNT_DTOR(DataEntryUrlBox); -} - -nsresult DataReferenceBox::Generate(uint32_t* aBoxSize) -{ - entry_count = 1; // only allow on entry here - size += sizeof(uint32_t); - - for (uint32_t i = 0; i < entry_count; i++) { - uint32_t box_size = 0; - DataEntryUrlBox* url = new DataEntryUrlBox(mControl); - url->Generate(&box_size); - size += box_size; - urls.AppendElement(url); - } - - *aBoxSize = size; - - return NS_OK; -} - -nsresult DataReferenceBox::Write() -{ - WRITE_FULLBOX(mControl, size) - mControl->Write(entry_count); - - for (uint32_t i = 0; i < entry_count; i++) { - urls[i]->Write(); - } - - return NS_OK; -} - -DataReferenceBox::DataReferenceBox(ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("dref"), 0, 0, aControl) - , entry_count(0) -{ - MOZ_COUNT_CTOR(DataReferenceBox); -} - -DataReferenceBox::~DataReferenceBox() -{ - MOZ_COUNT_DTOR(DataReferenceBox); -} - -DataInformationBox::DataInformationBox(ISOControl* aControl) - : DefaultContainerImpl(NS_LITERAL_CSTRING("dinf"), aControl) -{ - boxes.AppendElement(new DataReferenceBox(aControl)); - MOZ_COUNT_CTOR(DataInformationBox); -} - -DataInformationBox::~DataInformationBox() -{ - MOZ_COUNT_DTOR(DataInformationBox); -} - -nsresult -VideoMediaHeaderBox::Generate(uint32_t* aBoxSize) -{ - size += sizeof(graphicsmode) + - sizeof(opcolor); - - *aBoxSize = size; - - return NS_OK; -} - -nsresult -VideoMediaHeaderBox::Write() -{ - WRITE_FULLBOX(mControl, size) - mControl->Write(graphicsmode); - mControl->WriteArray(opcolor, 3); - return NS_OK; -} - -VideoMediaHeaderBox::VideoMediaHeaderBox(ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("vmhd"), 0, 1, aControl) - , graphicsmode(0) -{ - memset(opcolor, 0 , sizeof(opcolor)); - MOZ_COUNT_CTOR(VideoMediaHeaderBox); -} - -VideoMediaHeaderBox::~VideoMediaHeaderBox() -{ - MOZ_COUNT_DTOR(VideoMediaHeaderBox); -} - -nsresult -SoundMediaHeaderBox::Generate(uint32_t* aBoxSize) -{ - balance = 0; - reserved = 0; - size += sizeof(balance) + - sizeof(reserved); - - *aBoxSize = size; - - return NS_OK; -} - -nsresult -SoundMediaHeaderBox::Write() -{ - WRITE_FULLBOX(mControl, size) - mControl->Write(balance); - mControl->Write(reserved); - - return NS_OK; -} - -SoundMediaHeaderBox::SoundMediaHeaderBox(ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("smhd"), 0, 0, aControl) -{ - MOZ_COUNT_CTOR(SoundMediaHeaderBox); -} - -SoundMediaHeaderBox::~SoundMediaHeaderBox() -{ - MOZ_COUNT_DTOR(SoundMediaHeaderBox); -} - -MediaInformationBox::MediaInformationBox(uint32_t aType, ISOControl* aControl) - : DefaultContainerImpl(NS_LITERAL_CSTRING("minf"), aControl) -{ - mTrackType = aType; - - if (mTrackType == Audio_Track) { - boxes.AppendElement(new SoundMediaHeaderBox(aControl)); - } else if (mTrackType == Video_Track) { - boxes.AppendElement(new VideoMediaHeaderBox(aControl)); - } else { - MOZ_ASSERT(0); - } - - boxes.AppendElement(new DataInformationBox(aControl)); - boxes.AppendElement(new SampleTableBox(aType, aControl)); - MOZ_COUNT_CTOR(MediaInformationBox); -} - -MediaInformationBox::~MediaInformationBox() -{ - MOZ_COUNT_DTOR(MediaInformationBox); -} - -nsresult -HandlerBox::Generate(uint32_t* aBoxSize) -{ - pre_defined = 0; - if (mTrackType == Audio_Track) { - handler_type = FOURCC('s', 'o', 'u', 'n'); - } else if (mTrackType == Video_Track) { - handler_type = FOURCC('v', 'i', 'd', 'e'); - } - - size += sizeof(pre_defined) + - sizeof(handler_type) + - sizeof(reserved); - - *aBoxSize = size; - - return NS_OK; -} - -nsresult -HandlerBox::Write() -{ - WRITE_FULLBOX(mControl, size) - mControl->Write(pre_defined); - mControl->Write(handler_type); - mControl->WriteArray(reserved, 3); - - return NS_OK; -} - -HandlerBox::HandlerBox(uint32_t aType, ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("hdlr"), 0, 0, aControl) - , pre_defined(0) - , handler_type(0) -{ - mTrackType = aType; - memset(reserved, 0 , sizeof(reserved)); - MOZ_COUNT_CTOR(HandlerBox); -} - -HandlerBox::~HandlerBox() -{ - MOZ_COUNT_DTOR(HandlerBox); -} - -MediaHeaderBox::MediaHeaderBox(uint32_t aType, ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("mdhd"), 0, 0, aControl) - , creation_time(0) - , modification_time(0) - , timescale(0) - , duration(0) - , pad(0) - , lang1(0) - , lang2(0) - , lang3(0) - , pre_defined(0) -{ - mTrackType = aType; - MOZ_COUNT_CTOR(MediaHeaderBox); -} - -MediaHeaderBox::~MediaHeaderBox() -{ - MOZ_COUNT_DTOR(MediaHeaderBox); -} - -uint32_t -MediaHeaderBox::GetTimeScale() -{ - if (mTrackType == Audio_Track) { - return mAudioMeta->GetAudioSampleRate(); - } - - return mVideoMeta->GetVideoClockRate(); -} - -nsresult -MediaHeaderBox::Generate(uint32_t* aBoxSize) -{ - creation_time = mControl->GetTime(); - modification_time = mControl->GetTime(); - timescale = GetTimeScale(); - duration = 0; // fragmented mp4 - - pad = 0; - lang1 = 'u' - 0x60; // "und" underdetermined language - lang2 = 'n' - 0x60; - lang3 = 'd' - 0x60; - size += (pad.size() + lang1.size() + lang2.size() + lang3.size()) / CHAR_BIT; - - pre_defined = 0; - size += sizeof(creation_time) + - sizeof(modification_time) + - sizeof(timescale) + - sizeof(duration) + - sizeof(pre_defined); - - *aBoxSize = size; - - return NS_OK; -} - -nsresult -MediaHeaderBox::Write() -{ - WRITE_FULLBOX(mControl, size) - mControl->Write(creation_time); - mControl->Write(modification_time); - mControl->Write(timescale); - mControl->Write(duration); - mControl->WriteBits(pad.to_ulong(), pad.size()); - mControl->WriteBits(lang1.to_ulong(), lang1.size()); - mControl->WriteBits(lang2.to_ulong(), lang2.size()); - mControl->WriteBits(lang3.to_ulong(), lang3.size()); - mControl->Write(pre_defined); - - return NS_OK; -} - -MovieBox::MovieBox(ISOControl* aControl) - : DefaultContainerImpl(NS_LITERAL_CSTRING("moov"), aControl) -{ - boxes.AppendElement(new MovieHeaderBox(aControl)); - if (aControl->HasAudioTrack()) { - boxes.AppendElement(new TrackBox(Audio_Track, aControl)); - } - if (aControl->HasVideoTrack()) { - boxes.AppendElement(new TrackBox(Video_Track, aControl)); - } - boxes.AppendElement(new MovieExtendsBox(aControl)); - MOZ_COUNT_CTOR(MovieBox); -} - -MovieBox::~MovieBox() -{ - MOZ_COUNT_DTOR(MovieBox); -} - -nsresult -MovieHeaderBox::Generate(uint32_t* aBoxSize) -{ - creation_time = mControl->GetTime(); - modification_time = mControl->GetTime(); - timescale = GetTimeScale(); - duration = 0; // The duration is always 0 in fragmented mp4. - next_track_ID = mControl->GetNextTrackID(); - - size += sizeof(next_track_ID) + - sizeof(creation_time) + - sizeof(modification_time) + - sizeof(timescale) + - sizeof(duration) + - sizeof(rate) + - sizeof(volume) + - sizeof(reserved16) + - sizeof(reserved32) + - sizeof(matrix) + - sizeof(pre_defined); - - *aBoxSize = size; - - return NS_OK; -} - -nsresult -MovieHeaderBox::Write() -{ - WRITE_FULLBOX(mControl, size) - mControl->Write(creation_time); - mControl->Write(modification_time); - mControl->Write(timescale); - mControl->Write(duration); - mControl->Write(rate); - mControl->Write(volume); - mControl->Write(reserved16); - mControl->WriteArray(reserved32, 2); - mControl->WriteArray(matrix, 9); - mControl->WriteArray(pre_defined, 6); - mControl->Write(next_track_ID); - - return NS_OK; -} - -uint32_t -MovieHeaderBox::GetTimeScale() -{ - // Only audio track in container. - if (mAudioMeta && !mVideoMeta) { - return mAudioMeta->GetAudioSampleRate(); - } - - // return video rate - return mVideoMeta->GetVideoClockRate(); -} - -MovieHeaderBox::~MovieHeaderBox() -{ - MOZ_COUNT_DTOR(MovieHeaderBox); -} - -MovieHeaderBox::MovieHeaderBox(ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("mvhd"), 0, 0, aControl) - , creation_time(0) - , modification_time(0) - , timescale(90000) - , duration(0) - , rate(0x00010000) - , volume(0x0100) - , reserved16(0) - , next_track_ID(1) -{ - memcpy(matrix, iso_matrix, sizeof(matrix)); - memset(reserved32, 0, sizeof(reserved32)); - memset(pre_defined, 0, sizeof(pre_defined)); - MOZ_COUNT_CTOR(MovieHeaderBox); -} - -TrackHeaderBox::TrackHeaderBox(uint32_t aType, ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("tkhd"), 0, - flags_track_enabled | flags_track_in_movie | flags_track_in_preview, - aControl) - , creation_time(0) - , modification_time(0) - , track_ID(0) - , reserved(0) - , duration(0) - , layer(0) - , alternate_group(0) - , volume(0) - , reserved3(0) - , width(0) - , height(0) -{ - mTrackType = aType; - memcpy(matrix, iso_matrix, sizeof(matrix)); - memset(reserved2, 0, sizeof(reserved2)); - MOZ_COUNT_CTOR(TrackHeaderBox); -} - -TrackHeaderBox::~TrackHeaderBox() -{ - MOZ_COUNT_DTOR(TrackHeaderBox); -} - -nsresult -TrackHeaderBox::Generate(uint32_t* aBoxSize) -{ - creation_time = mControl->GetTime(); - modification_time = mControl->GetTime(); - track_ID = (mTrackType == Audio_Track ? - mControl->GetTrackID(mAudioMeta->GetKind()) : - mControl->GetTrackID(mVideoMeta->GetKind())); - // fragmented mp4 - duration = 0; - - // volume, audiotrack is always 0x0100 in 14496-12 8.3.2.2 - volume = (mTrackType == Audio_Track ? 0x0100 : 0); - - if (mTrackType == Video_Track) { - width = mVideoMeta->GetVideoDisplayWidth() << 16; - height = mVideoMeta->GetVideoDisplayHeight() << 16; - // Check display size, using the pixel size if any of them is invalid. - if (!width || !height) { - width = mVideoMeta->GetVideoWidth() << 16; - height = mVideoMeta->GetVideoHeight() << 16; - } - } - - size += sizeof(creation_time) + - sizeof(modification_time) + - sizeof(track_ID) + - sizeof(reserved) + - sizeof(duration) + - sizeof(reserved2) + - sizeof(layer) + - sizeof(alternate_group) + - sizeof(volume) + - sizeof(reserved3) + - sizeof(matrix) + - sizeof(width) + - sizeof(height); - - *aBoxSize = size; - - return NS_OK; -} - -nsresult -TrackHeaderBox::Write() -{ - WRITE_FULLBOX(mControl, size) - mControl->Write(creation_time); - mControl->Write(modification_time); - mControl->Write(track_ID); - mControl->Write(reserved); - mControl->Write(duration); - mControl->WriteArray(reserved2, 2); - mControl->Write(layer); - mControl->Write(alternate_group); - mControl->Write(volume); - mControl->Write(reserved3); - mControl->WriteArray(matrix, 9); - mControl->Write(width); - mControl->Write(height); - - return NS_OK; -} - -nsresult -FileTypeBox::Generate(uint32_t* aBoxSize) -{ - minor_version = 0; - - if (mControl->GetMuxingType() == ISOMediaWriter::TYPE_FRAG_MP4) { - if (!mControl->HasVideoTrack() && mControl->HasAudioTrack()) { - major_brand = "M4A "; - } else { - major_brand = "MP42"; - } - compatible_brands.AppendElement("mp42"); - compatible_brands.AppendElement("isom"); - } else if (mControl->GetMuxingType() == ISOMediaWriter::TYPE_FRAG_3GP) { - major_brand = "3gp9"; - // According to 3GPP TS 26.244 V12.2.0, section 5.3.4, it's recommended to - // list all compatible brands here. 3GP spec supports fragment from '3gp6'. - compatible_brands.AppendElement("3gp9"); - compatible_brands.AppendElement("3gp8"); - compatible_brands.AppendElement("3gp7"); - compatible_brands.AppendElement("3gp6"); - compatible_brands.AppendElement("isom"); - } else if (mControl->GetMuxingType() == ISOMediaWriter::TYPE_FRAG_3G2) { - major_brand = "3g2a"; - // 3GPP2 Release 0 and A and 3GPP Release 6 allow movie fragmentation - compatible_brands.AppendElement("3gp9"); - compatible_brands.AppendElement("3gp8"); - compatible_brands.AppendElement("3gp7"); - compatible_brands.AppendElement("3gp6"); - compatible_brands.AppendElement("isom"); - compatible_brands.AppendElement("3g2c"); - compatible_brands.AppendElement("3g2b"); - compatible_brands.AppendElement("3g2a"); - } else { - MOZ_ASSERT(0); - } - - size += major_brand.Length() + - sizeof(minor_version) + - compatible_brands.Length() * 4; - - *aBoxSize = size; - - return NS_OK; -} - -nsresult -FileTypeBox::Write() -{ - BoxSizeChecker checker(mControl, size); - Box::Write(); - mControl->WriteFourCC(major_brand.get()); - mControl->Write(minor_version); - uint32_t len = compatible_brands.Length(); - for (uint32_t i = 0; i < len; i++) { - mControl->WriteFourCC(compatible_brands[i].get()); - } - - return NS_OK; -} - -FileTypeBox::FileTypeBox(ISOControl* aControl) - : Box(NS_LITERAL_CSTRING("ftyp"), aControl) - , minor_version(0) -{ - MOZ_COUNT_CTOR(FileTypeBox); -} - -FileTypeBox::~FileTypeBox() -{ - MOZ_COUNT_DTOR(FileTypeBox); -} - -MediaBox::MediaBox(uint32_t aType, ISOControl* aControl) - : DefaultContainerImpl(NS_LITERAL_CSTRING("mdia"), aControl) -{ - mTrackType = aType; - boxes.AppendElement(new MediaHeaderBox(aType, aControl)); - boxes.AppendElement(new HandlerBox(aType, aControl)); - boxes.AppendElement(new MediaInformationBox(aType, aControl)); - MOZ_COUNT_CTOR(MediaBox); -} - -MediaBox::~MediaBox() -{ - MOZ_COUNT_DTOR(MediaBox); -} - -nsresult -DefaultContainerImpl::Generate(uint32_t* aBoxSize) -{ - nsresult rv; - uint32_t box_size; - uint32_t len = boxes.Length(); - for (uint32_t i = 0; i < len; i++) { - rv = boxes.ElementAt(i)->Generate(&box_size); - NS_ENSURE_SUCCESS(rv, rv); - size += box_size; - } - *aBoxSize = size; - return NS_OK; -} - -nsresult -DefaultContainerImpl::Find(const nsACString& aType, - nsTArray>& aOperations) -{ - nsresult rv = Box::Find(aType, aOperations); - NS_ENSURE_SUCCESS(rv, rv); - - uint32_t len = boxes.Length(); - for (uint32_t i = 0; i < len; i++) { - rv = boxes.ElementAt(i)->Find(aType, aOperations); - NS_ENSURE_SUCCESS(rv, rv); - } - return NS_OK; -} - -nsresult -DefaultContainerImpl::Write() -{ - BoxSizeChecker checker(mControl, size); - Box::Write(); - - nsresult rv; - uint32_t len = boxes.Length(); - for (uint32_t i = 0; i < len; i++) { - rv = boxes.ElementAt(i)->Write(); - NS_ENSURE_SUCCESS(rv, rv); - } - - return NS_OK; -} - -DefaultContainerImpl::DefaultContainerImpl(const nsACString& aType, - ISOControl* aControl) - : Box(aType, aControl) -{ -} - -nsresult -Box::Write() -{ - mControl->Write(size); - mControl->WriteFourCC(boxType.get()); - return NS_OK; -} - -nsresult -Box::Find(const nsACString& aType, nsTArray>& aOperations) -{ - if (boxType == aType) { - aOperations.AppendElement(this); - } - return NS_OK; -} - -Box::Box(const nsACString& aType, ISOControl* aControl) - : size(8), mControl(aControl) -{ - MOZ_ASSERT(aType.Length() == 4); - boxType = aType; - aControl->GetAudioMetadata(mAudioMeta); - aControl->GetVideoMetadata(mVideoMeta); -} - -FullBox::FullBox(const nsACString& aType, uint8_t aVersion, uint32_t aFlags, - ISOControl* aControl) - : Box(aType, aControl) -{ - std::bitset<24> tmp_flags(aFlags); - version = aVersion; - flags = tmp_flags; - size += sizeof(version) + flags.size() / CHAR_BIT; -} - -nsresult -FullBox::Write() -{ - Box::Write(); - mControl->Write(version); - mControl->WriteBits(flags.to_ulong(), flags.size()); - return NS_OK; -} - -TrackBox::TrackBox(uint32_t aTrackType, ISOControl* aControl) - : DefaultContainerImpl(NS_LITERAL_CSTRING("trak"), aControl) -{ - boxes.AppendElement(new TrackHeaderBox(aTrackType, aControl)); - boxes.AppendElement(new MediaBox(aTrackType, aControl)); - MOZ_COUNT_CTOR(TrackBox); -} - -TrackBox::~TrackBox() -{ - MOZ_COUNT_DTOR(TrackBox); -} - -SampleEntryBox::SampleEntryBox(const nsACString& aFormat, ISOControl* aControl) - : Box(aFormat, aControl) - , data_reference_index(0) -{ - data_reference_index = 1; // There is only one data reference in each track. - size += sizeof(reserved) + - sizeof(data_reference_index); - memset(reserved, 0, sizeof(reserved)); -} - -nsresult -SampleEntryBox::Write() -{ - Box::Write(); - mControl->Write(reserved, sizeof(reserved)); - mControl->Write(data_reference_index); - return NS_OK; -} - -nsresult -AudioSampleEntry::Write() -{ - SampleEntryBox::Write(); - mControl->Write(sound_version); - mControl->Write(reserved2, sizeof(reserved2)); - mControl->Write(channels); - mControl->Write(sample_size); - mControl->Write(compressionId); - mControl->Write(packet_size); - mControl->Write(timeScale); - return NS_OK; -} - -AudioSampleEntry::AudioSampleEntry(const nsACString& aFormat, ISOControl* aControl) - : SampleEntryBox(aFormat, aControl) - , sound_version(0) - , channels(2) - , sample_size(16) - , compressionId(0) - , packet_size(0) - , timeScale(0) -{ - memset(reserved2, 0 , sizeof(reserved2)); - channels = mAudioMeta->GetAudioChannels(); - timeScale = mAudioMeta->GetAudioSampleRate() << 16; - - size += sizeof(sound_version) + - sizeof(reserved2) + - sizeof(sample_size) + - sizeof(channels) + - sizeof(packet_size) + - sizeof(compressionId) + - sizeof(timeScale); - - MOZ_COUNT_CTOR(AudioSampleEntry); -} - -AudioSampleEntry::~AudioSampleEntry() -{ - MOZ_COUNT_DTOR(AudioSampleEntry); -} - -nsresult -VisualSampleEntry::Write() -{ - SampleEntryBox::Write(); - - mControl->Write(reserved, sizeof(reserved)); - mControl->Write(width); - mControl->Write(height); - mControl->Write(horizresolution); - mControl->Write(vertresolution); - mControl->Write(reserved2); - mControl->Write(frame_count); - mControl->Write(compressorName, sizeof(compressorName)); - mControl->Write(depth); - mControl->Write(pre_defined); - - return NS_OK; -} - -VisualSampleEntry::VisualSampleEntry(const nsACString& aFormat, ISOControl* aControl) - : SampleEntryBox(aFormat, aControl) - , width(0) - , height(0) - , horizresolution(resolution_72_dpi) - , vertresolution(resolution_72_dpi) - , reserved2(0) - , frame_count(1) - , depth(video_depth) - , pre_defined(-1) -{ - memset(reserved, 0 , sizeof(reserved)); - memset(compressorName, 0 , sizeof(compressorName)); - - // both fields occupy 16 bits defined in 14496-2 6.2.3. - width = mVideoMeta->GetVideoWidth(); - height = mVideoMeta->GetVideoHeight(); - - size += sizeof(reserved) + - sizeof(width) + - sizeof(height) + - sizeof(horizresolution) + - sizeof(vertresolution) + - sizeof(reserved2) + - sizeof(frame_count) + - sizeof(compressorName) + - sizeof(depth) + - sizeof(pre_defined); - - MOZ_COUNT_CTOR(VisualSampleEntry); -} - -VisualSampleEntry::~VisualSampleEntry() -{ - MOZ_COUNT_DTOR(VisualSampleEntry); -} - -} diff --git a/dom/media/encoder/fmp4_muxer/ISOMediaBoxes.h b/dom/media/encoder/fmp4_muxer/ISOMediaBoxes.h deleted file mode 100644 index a6dc1b046..000000000 --- a/dom/media/encoder/fmp4_muxer/ISOMediaBoxes.h +++ /dev/null @@ -1,781 +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 ISOMediaBoxes_h_ -#define ISOMediaBoxes_h_ - -#include -#include "nsString.h" -#include "nsTArray.h" -#include "nsAutoPtr.h" -#include "MuxerOperation.h" -#include "mozilla/UniquePtr.h" - -#define WRITE_FULLBOX(_compositor, _size) \ - BoxSizeChecker checker(_compositor, _size); \ - FullBox::Write(); - -#define FOURCC(a, b, c, d) ( ((a) << 24) | ((b) << 16) | ((c) << 8) | (d) ) - -namespace mozilla { - -/** - * track type from spec 8.4.3.3 - */ -#define Audio_Track 0x01 -#define Video_Track 0x02 - -class AudioTrackMetadata; -class VideoTrackMetadata; -class ISOControl; - -/** - * This is the base class for all ISO media format boxes. - * It provides the fields of box type(four CC) and size. - * The data members in the beginning of a Box (or its descendants) - * are the 14496-12 defined member. Other members prefix with 'm' - * are private control data. - * - * This class is for inherited only, it shouldn't be instanced directly. - */ -class Box : public MuxerOperation { -protected: - // ISO BMFF members - uint32_t size; // 14496-12 4-2 'Object Structure'. Size of this box. - nsCString boxType; // four CC name, all table names are listed in - // 14496-12 table 1. - -public: - // MuxerOperation methods - nsresult Write() override; - nsresult Find(const nsACString& aType, - nsTArray>& aOperations) override; - - // This helper class will compare the written size in Write() and the size in - // Generate(). If their are not equal, it will assert. - class BoxSizeChecker { - public: - BoxSizeChecker(ISOControl* aControl, uint32_t aSize); - ~BoxSizeChecker(); - - uint32_t ori_size; - uint32_t box_size; - ISOControl* mControl; - }; - -protected: - Box() = delete; - Box(const nsACString& aType, ISOControl* aControl); - - ISOControl* mControl; - RefPtr mAudioMeta; - RefPtr mVideoMeta; -}; - -/** - * FullBox (and its descendants) is the box which contains the 'real' data - * members. It is the edge in the ISO box structure and it doesn't contain - * any box. - * - * This class is for inherited only, it shouldn't be instanced directly. - */ -class FullBox : public Box { -public: - // ISO BMFF members - uint8_t version; // 14496-12 4.2 'Object Structure' - std::bitset<24> flags; // - - // MuxerOperation methods - nsresult Write() override; - -protected: - // FullBox methods - FullBox(const nsACString& aType, uint8_t aVersion, uint32_t aFlags, - ISOControl* aControl); - FullBox() = delete; -}; - -/** - * The default implementation of the container box. - * Basically, the container box inherits this class and overrides the - * constructor only. - * - * According to 14496-12 3.1.1 'container box', a container box is - * 'box whose sole purpose is to contain and group a set of related boxes' - * - * This class is for inherited only, it shouldn't be instanced directly. - */ -class DefaultContainerImpl : public Box { -public: - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - nsresult Find(const nsACString& aType, - nsTArray>& aOperations) override; - -protected: - // DefaultContainerImpl methods - DefaultContainerImpl(const nsACString& aType, ISOControl* aControl); - DefaultContainerImpl() = delete; - - nsTArray> boxes; -}; - -// 14496-12 4.3 'File Type Box' -// Box type: 'ftyp' -class FileTypeBox : public Box { -public: - // ISO BMFF members - nsCString major_brand; // four chars - uint32_t minor_version; - nsTArray compatible_brands; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // FileTypeBox methods - FileTypeBox(ISOControl* aControl); - ~FileTypeBox(); -}; - -// 14496-12 8.2.1 'Movie Box' -// Box type: 'moov' -// MovieBox contains MovieHeaderBox, TrackBox and MovieExtendsBox. -class MovieBox : public DefaultContainerImpl { -public: - MovieBox(ISOControl* aControl); - ~MovieBox(); -}; - -// 14496-12 8.2.2 'Movie Header Box' -// Box type: 'mvhd' -class MovieHeaderBox : public FullBox { -public: - // ISO BMFF members - uint32_t creation_time; - uint32_t modification_time; - uint32_t timescale; - uint32_t duration; - uint32_t rate; - uint16_t volume; - uint16_t reserved16; - uint32_t reserved32[2]; - uint32_t matrix[9]; - uint32_t pre_defined[6]; - uint32_t next_track_ID; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // MovieHeaderBox methods - MovieHeaderBox(ISOControl* aControl); - ~MovieHeaderBox(); - uint32_t GetTimeScale(); -}; - -// 14496-12 8.4.2 'Media Header Box' -// Box type: 'mdhd' -class MediaHeaderBox : public FullBox { -public: - // ISO BMFF members - uint32_t creation_time; - uint32_t modification_time; - uint32_t timescale; - uint32_t duration; - std::bitset<1> pad; - std::bitset<5> lang1; - std::bitset<5> lang2; - std::bitset<5> lang3; - uint16_t pre_defined; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // MediaHeaderBox methods - MediaHeaderBox(uint32_t aType, ISOControl* aControl); - ~MediaHeaderBox(); - uint32_t GetTimeScale(); - -protected: - uint32_t mTrackType; -}; - -// 14496-12 8.3.1 'Track Box' -// Box type: 'trak' -// TrackBox contains TrackHeaderBox and MediaBox. -class TrackBox : public DefaultContainerImpl { -public: - TrackBox(uint32_t aTrackType, ISOControl* aControl); - ~TrackBox(); -}; - -// 14496-12 8.1.1 'Media Data Box' -// Box type: 'mdat' -class MediaDataBox : public Box { -public: - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // MediaDataBox methods - uint32_t GetAllSampleSize() { return mAllSampleSize; } - uint32_t FirstSampleOffsetInMediaDataBox() { return mFirstSampleOffset; } - MediaDataBox(uint32_t aTrackType, ISOControl* aControl); - ~MediaDataBox(); - -protected: - uint32_t mAllSampleSize; // All audio and video sample size in this box. - uint32_t mFirstSampleOffset; // The offset of first sample in this box from - // the beginning of this mp4 file. - uint32_t mTrackType; -}; - -// flags for TrackRunBox::flags, 14496-12 8.8.8.1. -#define flags_data_offset_present 0x000001 -#define flags_first_sample_flags_present 0x000002 -#define flags_sample_duration_present 0x000100 -#define flags_sample_size_present 0x000200 -#define flags_sample_flags_present 0x000400 -#define flags_sample_composition_time_offsets_present 0x000800 - -// flag for TrackRunBox::tbl::sample_flags and TrackExtendsBox::default_sample_flags -// which is defined in 14496-12 8.8.3.1. -uint32_t set_sample_flags(bool aSync); - -// 14496-12 8.8.8 'Track Fragment Run Box' -// Box type: 'trun' -class TrackRunBox : public FullBox { -public: - // ISO BMFF members - typedef struct { - uint32_t sample_duration; - uint32_t sample_size; - uint32_t sample_flags; - uint32_t sample_composition_time_offset; - } tbl; - - uint32_t sample_count; - // the following are optional fields - uint32_t data_offset; // data offset exists when audio/video are present in file. - uint32_t first_sample_flags; - UniquePtr sample_info_table; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // TrackRunBox methods - uint32_t GetAllSampleSize() { return mAllSampleSize; } - nsresult SetDataOffset(uint32_t aOffset); - - TrackRunBox(uint32_t aType, uint32_t aFlags, ISOControl* aControl); - ~TrackRunBox(); - -protected: - uint32_t fillSampleTable(); - - uint32_t mAllSampleSize; - uint32_t mTrackType; -}; - -// tf_flags in TrackFragmentHeaderBox, 14496-12 8.8.7.1. -#define base_data_offset_present 0x000001 -#define sample_description_index_present 0x000002 -#define default_sample_duration_present 0x000008 -#define default_sample_size_present 0x000010 -#define default_sample_flags_present 0x000020 -#define duration_is_empty 0x010000 -#define default_base_is_moof 0x020000 - -// 14496-12 8.8.7 'Track Fragment Header Box' -// Box type: 'tfhd' -class TrackFragmentHeaderBox : public FullBox { -public: - // ISO BMFF members - uint32_t track_ID; - uint64_t base_data_offset; - uint32_t default_sample_duration; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // TrackFragmentHeaderBox methods - nsresult UpdateBaseDataOffset(uint64_t aOffset); // The offset of the first - // sample in file. - - TrackFragmentHeaderBox(uint32_t aType, uint32_t aFlags, ISOControl* aControl); - ~TrackFragmentHeaderBox(); - -protected: - uint32_t mTrackType; -}; - -// 14496-12 8.8.6 'Track Fragment Box' -// Box type: 'traf' -// TrackFragmentBox cotains TrackFragmentHeaderBox and TrackRunBox. -class TrackFragmentBox : public DefaultContainerImpl { -public: - TrackFragmentBox(uint32_t aType, ISOControl* aControl); - ~TrackFragmentBox(); - -protected: - uint32_t mTrackType; -}; - -// 14496-12 8.8.5 'Movie Fragment Header Box' -// Box type: 'mfhd' -class MovieFragmentHeaderBox : public FullBox { -public: - // ISO BMFF members - uint32_t sequence_number; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // MovieFragmentHeaderBox methods - MovieFragmentHeaderBox(uint32_t aType, ISOControl* aControl); - ~MovieFragmentHeaderBox(); - -protected: - uint32_t mTrackType; -}; - -// 14496-12 8.8.4 'Movie Fragment Box' -// Box type: 'moof' -// MovieFragmentBox contains MovieFragmentHeaderBox and TrackFragmentBox. -class MovieFragmentBox : public DefaultContainerImpl { -public: - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - - // MovieFragmentBox methods - MovieFragmentBox(uint32_t aType, ISOControl* aControl); - ~MovieFragmentBox(); - -protected: - uint32_t mTrackType; -}; - -// 14496-12 8.8.3 'Track Extends Box' -// Box type: 'trex' -class TrackExtendsBox : public FullBox { -public: - // ISO BMFF members - uint32_t track_ID; - uint32_t default_sample_description_index; - uint32_t default_sample_duration; - uint32_t default_sample_size; - uint32_t default_sample_flags; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // TrackExtendsBox methods - TrackExtendsBox(uint32_t aType, ISOControl* aControl); - ~TrackExtendsBox(); - -protected: - uint32_t mTrackType; -}; - -// 14496-12 8.8.1 'Movie Extends Box' -// Box type: 'mvex' -// MovieExtendsBox contains TrackExtendsBox. -class MovieExtendsBox : public DefaultContainerImpl { -public: - MovieExtendsBox(ISOControl* aControl); - ~MovieExtendsBox(); -}; - -// 14496-12 8.7.5 'Chunk Offset Box' -// Box type: 'stco' -class ChunkOffsetBox : public FullBox { -public: - // ISO BMFF members - typedef struct { - uint32_t chunk_offset; - } tbl; - - uint32_t entry_count; - UniquePtr sample_tbl; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // ChunkOffsetBox methods - ChunkOffsetBox(uint32_t aType, ISOControl* aControl); - ~ChunkOffsetBox(); - -protected: - uint32_t mTrackType; -}; - -// 14496-12 8.7.4 'Sample To Chunk Box' -// Box type: 'stsc' -class SampleToChunkBox : public FullBox { -public: - // ISO BMFF members - typedef struct { - uint32_t first_chunk; - uint32_t sample_per_chunk; - uint32_t sample_description_index; - } tbl; - - uint32_t entry_count; - UniquePtr sample_tbl; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // SampleToChunkBox methods - SampleToChunkBox(uint32_t aType, ISOControl* aControl); - ~SampleToChunkBox(); - -protected: - uint32_t mTrackType; -}; - -// 14496-12 8.6.1.2 'Decoding Time to Sample Box' -// Box type: 'stts' -class TimeToSampleBox : public FullBox { -public: - // ISO BMFF members - typedef struct { - uint32_t sample_count; - uint32_t sample_delta; - } tbl; - - uint32_t entry_count; - UniquePtr sample_tbl; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // TimeToSampleBox methods - TimeToSampleBox(uint32_t aType, ISOControl* aControl); - ~TimeToSampleBox(); - -protected: - uint32_t mTrackType; -}; - -/** - * 14496-12 8.5.2 'Sample Description Box' - * This is the base class for VisualSampleEntry and AudioSampleEntry. - * - * This class is for inherited only, it shouldn't be instanced directly. - * - * The inhertied tree of a codec box should be: - * - * +--> AVCSampleEntry - * +--> VisualSampleEntryBox + - * | +--> ... - * SampleEntryBox + - * | +--> MP4AudioSampleEntry - * +--> AudioSampleEntryBox + - * +--> AMRSampleEntry - * + - * +--> ... - * - */ -class SampleEntryBox : public Box { -public: - // ISO BMFF members - uint8_t reserved[6]; - uint16_t data_reference_index; - - // sampleentrybox methods - SampleEntryBox(const nsACString& aFormat, ISOControl* aControl); - - // MuxerOperation methods - nsresult Write() override; - -protected: - SampleEntryBox() = delete; -}; - -// 14496-12 8.5.2 'Sample Description Box' -// Box type: 'stsd' -class SampleDescriptionBox : public FullBox { -public: - // ISO BMFF members - uint32_t entry_count; - RefPtr sample_entry_box; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // SampleDescriptionBox methods - SampleDescriptionBox(uint32_t aType, ISOControl* aControl); - ~SampleDescriptionBox(); - -protected: - nsresult CreateAudioSampleEntry(RefPtr& aSampleEntry); - nsresult CreateVideoSampleEntry(RefPtr& aSampleEntry); - - uint32_t mTrackType; -}; - -// 14496-12 8.5.2.2 -// The base class for audio codec box. -// This class is for inherited only, it shouldn't be instanced directly. -class AudioSampleEntry : public SampleEntryBox { -public: - // ISO BMFF members - uint16_t sound_version; - uint8_t reserved2[6]; - uint16_t channels; - uint16_t sample_size; - uint16_t compressionId; - uint16_t packet_size; - uint32_t timeScale; // (sample rate of media) <<16 - - // MuxerOperation methods - nsresult Write() override; - - ~AudioSampleEntry(); - -protected: - AudioSampleEntry(const nsACString& aFormat, ISOControl* aControl); -}; - -// 14496-12 8.5.2.2 -// The base class for video codec box. -// This class is for inherited only, it shouldn't be instanced directly. -class VisualSampleEntry : public SampleEntryBox { -public: - // ISO BMFF members - uint8_t reserved[16]; - uint16_t width; - uint16_t height; - - uint32_t horizresolution; // 72 dpi - uint32_t vertresolution; // 72 dpi - uint32_t reserved2; - uint16_t frame_count; // 1, defined in 14496-12 8.5.2.2 - - uint8_t compressorName[32]; - uint16_t depth; // 0x0018, defined in 14496-12 8.5.2.2; - uint16_t pre_defined; // -1, defined in 14496-12 8.5.2.2; - - // MuxerOperation methods - nsresult Write() override; - - // VisualSampleEntry methods - ~VisualSampleEntry(); - -protected: - VisualSampleEntry(const nsACString& aFormat, ISOControl* aControl); -}; - -// 14496-12 8.7.3.2 'Sample Size Box' -// Box type: 'stsz' -class SampleSizeBox : public FullBox { -public: - // ISO BMFF members - uint32_t sample_size; - uint32_t sample_count; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // SampleSizeBox methods - SampleSizeBox(ISOControl* aControl); - ~SampleSizeBox(); -}; - -// 14496-12 8.5.1 'Sample Table Box' -// Box type: 'stbl' -// -// SampleTableBox contains SampleDescriptionBox, -// TimeToSampleBox, -// SampleToChunkBox, -// SampleSizeBox and -// ChunkOffsetBox. -class SampleTableBox : public DefaultContainerImpl { -public: - SampleTableBox(uint32_t aType, ISOControl* aControl); - ~SampleTableBox(); -}; - -// 14496-12 8.7.2 'Data Reference Box' -// Box type: 'url ' -class DataEntryUrlBox : public FullBox { -public: - // ISO BMFF members - // flags in DataEntryUrlBox::flags - const static uint16_t flags_media_at_the_same_file = 0x0001; - - nsCString location; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // DataEntryUrlBox methods - DataEntryUrlBox(); - DataEntryUrlBox(ISOControl* aControl); - DataEntryUrlBox(const DataEntryUrlBox& aBox); - ~DataEntryUrlBox(); -}; - -// 14496-12 8.7.2 'Data Reference Box' -// Box type: 'dref' -class DataReferenceBox : public FullBox { -public: - // ISO BMFF members - uint32_t entry_count; - nsTArray> urls; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // DataReferenceBox methods - DataReferenceBox(ISOControl* aControl); - ~DataReferenceBox(); -}; - -// 14496-12 8.7.1 'Data Information Box' -// Box type: 'dinf' -// DataInformationBox contains DataReferenceBox. -class DataInformationBox : public DefaultContainerImpl { -public: - DataInformationBox(ISOControl* aControl); - ~DataInformationBox(); -}; - -// 14496-12 8.4.5.2 'Video Media Header Box' -// Box type: 'vmhd' -class VideoMediaHeaderBox : public FullBox { -public: - // ISO BMFF members - uint16_t graphicsmode; - uint16_t opcolor[3]; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // VideoMediaHeaderBox methods - VideoMediaHeaderBox(ISOControl* aControl); - ~VideoMediaHeaderBox(); -}; - -// 14496-12 8.4.5.3 'Sound Media Header Box' -// Box type: 'smhd' -class SoundMediaHeaderBox : public FullBox { -public: - // ISO BMFF members - uint16_t balance; - uint16_t reserved; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // SoundMediaHeaderBox methods - SoundMediaHeaderBox(ISOControl* aControl); - ~SoundMediaHeaderBox(); -}; - -// 14496-12 8.4.4 'Media Information Box' -// Box type: 'minf' -// MediaInformationBox contains SoundMediaHeaderBox, DataInformationBox and -// SampleTableBox. -class MediaInformationBox : public DefaultContainerImpl { -public: - MediaInformationBox(uint32_t aType, ISOControl* aControl); - ~MediaInformationBox(); - -protected: - uint32_t mTrackType; -}; - -// flags for TrackHeaderBox::flags. -#define flags_track_enabled 0x000001 -#define flags_track_in_movie 0x000002 -#define flags_track_in_preview 0x000004 - -// 14496-12 8.3.2 'Track Header Box' -// Box type: 'tkhd' -class TrackHeaderBox : public FullBox { -public: - // ISO BMFF members - // version = 0 - uint32_t creation_time; - uint32_t modification_time; - uint32_t track_ID; - uint32_t reserved; - uint32_t duration; - - uint32_t reserved2[2]; - uint16_t layer; - uint16_t alternate_group; - uint16_t volume; - uint16_t reserved3; - uint32_t matrix[9]; - uint32_t width; - uint32_t height; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // TrackHeaderBox methods - TrackHeaderBox(uint32_t aType, ISOControl* aControl); - ~TrackHeaderBox(); - -protected: - uint32_t mTrackType; -}; - -// 14496-12 8.4.3 'Handler Reference Box' -// Box type: 'hdlr' -class HandlerBox : public FullBox { -public: - // ISO BMFF members - uint32_t pre_defined; - uint32_t handler_type; - uint32_t reserved[3]; - nsCString name; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // HandlerBox methods - HandlerBox(uint32_t aType, ISOControl* aControl); - ~HandlerBox(); - -protected: - uint32_t mTrackType; -}; - -// 14496-12 8.4.1 'Media Box' -// Box type: 'mdia' -// MediaBox contains MediaHeaderBox, HandlerBox, and MediaInformationBox. -class MediaBox : public DefaultContainerImpl { -public: - MediaBox(uint32_t aType, ISOControl* aControl); - ~MediaBox(); - -protected: - uint32_t mTrackType; -}; - -} -#endif // ISOMediaBoxes_h_ diff --git a/dom/media/encoder/fmp4_muxer/ISOMediaWriter.cpp b/dom/media/encoder/fmp4_muxer/ISOMediaWriter.cpp deleted file mode 100644 index cb4524e00..000000000 --- a/dom/media/encoder/fmp4_muxer/ISOMediaWriter.cpp +++ /dev/null @@ -1,229 +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 "ISOMediaWriter.h" -#include "ISOControl.h" -#include "ISOMediaBoxes.h" -#include "ISOTrackMetadata.h" -#include "nsThreadUtils.h" -#include "MediaEncoder.h" -#include "VideoUtils.h" -#include "GeckoProfiler.h" - -#undef LOG -#define LOG(args, ...) - -namespace mozilla { - -const static uint32_t FRAG_DURATION = 2 * USECS_PER_S; // microsecond per unit - -ISOMediaWriter::ISOMediaWriter(uint32_t aType, uint32_t aHint) - : ContainerWriter() - , mState(MUXING_HEAD) - , mBlobReady(false) - , mType(0) -{ - if (aType & CREATE_AUDIO_TRACK) { - mType |= Audio_Track; - } - if (aType & CREATE_VIDEO_TRACK) { - mType |= Video_Track; - } - mControl = new ISOControl(aHint); - MOZ_COUNT_CTOR(ISOMediaWriter); -} - -ISOMediaWriter::~ISOMediaWriter() -{ - MOZ_COUNT_DTOR(ISOMediaWriter); -} - -nsresult -ISOMediaWriter::RunState() -{ - nsresult rv; - switch (mState) { - case MUXING_HEAD: - { - rv = mControl->GenerateFtyp(); - NS_ENSURE_SUCCESS(rv, rv); - rv = mControl->GenerateMoov(); - NS_ENSURE_SUCCESS(rv, rv); - mState = MUXING_FRAG; - break; - } - case MUXING_FRAG: - { - rv = mControl->GenerateMoof(mType); - NS_ENSURE_SUCCESS(rv, rv); - - bool EOS; - if (ReadyToRunState(EOS) && EOS) { - mState = MUXING_DONE; - } - break; - } - case MUXING_DONE: - { - break; - } - } - mBlobReady = true; - return NS_OK; -} - -nsresult -ISOMediaWriter::WriteEncodedTrack(const EncodedFrameContainer& aData, - uint32_t aFlags) -{ - PROFILER_LABEL("ISOMediaWriter", "WriteEncodedTrack", - js::ProfileEntry::Category::OTHER); - // Muxing complete, it doesn't allowed to reentry again. - if (mState == MUXING_DONE) { - MOZ_ASSERT(false); - return NS_ERROR_FAILURE; - } - - FragmentBuffer* frag = nullptr; - uint32_t len = aData.GetEncodedFrames().Length(); - - if (!len) { - // no frame? why bother to WriteEncodedTrack - return NS_OK; - } - for (uint32_t i = 0; i < len; i++) { - RefPtr frame(aData.GetEncodedFrames()[i]); - EncodedFrame::FrameType type = frame->GetFrameType(); - if (type == EncodedFrame::AAC_AUDIO_FRAME || - type == EncodedFrame::AAC_CSD || - type == EncodedFrame::AMR_AUDIO_FRAME || - type == EncodedFrame::AMR_AUDIO_CSD || - type == EncodedFrame::EVRC_AUDIO_FRAME || - type == EncodedFrame::EVRC_AUDIO_CSD) { - frag = mAudioFragmentBuffer; - } else if (type == EncodedFrame::AVC_I_FRAME || - type == EncodedFrame::AVC_P_FRAME || - type == EncodedFrame::AVC_B_FRAME || - type == EncodedFrame::AVC_CSD) { - frag = mVideoFragmentBuffer; - } else { - MOZ_ASSERT(0); - return NS_ERROR_FAILURE; - } - - frag->AddFrame(frame); - } - - // Encoder should send CSD (codec specific data) frame before sending the - // audio/video frames. When CSD data is ready, it is sufficient to generate a - // moov data. If encoder doesn't send CSD yet, muxer needs to wait before - // generating anything. - if (mType & Audio_Track && (!mAudioFragmentBuffer || - !mAudioFragmentBuffer->HasCSD())) { - return NS_OK; - } - if (mType & Video_Track && (!mVideoFragmentBuffer || - !mVideoFragmentBuffer->HasCSD())) { - return NS_OK; - } - - // Only one FrameType in EncodedFrameContainer so it doesn't need to be - // inside the for-loop. - if (frag && (aFlags & END_OF_STREAM)) { - frag->SetEndOfStream(); - } - - nsresult rv; - bool EOS; - if (ReadyToRunState(EOS)) { - // Because track encoder won't generate new data after EOS, it needs to make - // sure the state reaches MUXING_DONE when EOS is signaled. - do { - rv = RunState(); - } while (EOS && mState != MUXING_DONE); - NS_ENSURE_SUCCESS(rv, rv); - } - - return NS_OK; -} - -bool -ISOMediaWriter::ReadyToRunState(bool& aEOS) -{ - aEOS = false; - bool bReadyToMux = true; - if ((mType & Audio_Track) && (mType & Video_Track)) { - if (!mAudioFragmentBuffer->HasEnoughData()) { - bReadyToMux = false; - } - if (!mVideoFragmentBuffer->HasEnoughData()) { - bReadyToMux = false; - } - - if (mAudioFragmentBuffer->EOS() && mVideoFragmentBuffer->EOS()) { - aEOS = true; - bReadyToMux = true; - } - } else if (mType == Audio_Track) { - if (!mAudioFragmentBuffer->HasEnoughData()) { - bReadyToMux = false; - } - if (mAudioFragmentBuffer->EOS()) { - aEOS = true; - bReadyToMux = true; - } - } else if (mType == Video_Track) { - if (!mVideoFragmentBuffer->HasEnoughData()) { - bReadyToMux = false; - } - if (mVideoFragmentBuffer->EOS()) { - aEOS = true; - bReadyToMux = true; - } - } - - return bReadyToMux; -} - -nsresult -ISOMediaWriter::GetContainerData(nsTArray>* aOutputBufs, - uint32_t aFlags) -{ - PROFILER_LABEL("ISOMediaWriter", "GetContainerData", - js::ProfileEntry::Category::OTHER); - if (mBlobReady) { - if (mState == MUXING_DONE) { - mIsWritingComplete = true; - } - mBlobReady = false; - return mControl->GetBufs(aOutputBufs); - } - return NS_OK; -} - -nsresult -ISOMediaWriter::SetMetadata(TrackMetadataBase* aMetadata) -{ - PROFILER_LABEL("ISOMediaWriter", "SetMetadata", - js::ProfileEntry::Category::OTHER); - if (aMetadata->GetKind() == TrackMetadataBase::METADATA_AAC || - aMetadata->GetKind() == TrackMetadataBase::METADATA_AMR || - aMetadata->GetKind() == TrackMetadataBase::METADATA_EVRC) { - mControl->SetMetadata(aMetadata); - mAudioFragmentBuffer = new FragmentBuffer(Audio_Track, FRAG_DURATION); - mControl->SetFragment(mAudioFragmentBuffer); - return NS_OK; - } - if (aMetadata->GetKind() == TrackMetadataBase::METADATA_AVC) { - mControl->SetMetadata(aMetadata); - mVideoFragmentBuffer = new FragmentBuffer(Video_Track, FRAG_DURATION); - mControl->SetFragment(mVideoFragmentBuffer); - return NS_OK; - } - - return NS_ERROR_FAILURE; -} - -} // namespace mozilla diff --git a/dom/media/encoder/fmp4_muxer/ISOMediaWriter.h b/dom/media/encoder/fmp4_muxer/ISOMediaWriter.h deleted file mode 100644 index cccbbe3cb..000000000 --- a/dom/media/encoder/fmp4_muxer/ISOMediaWriter.h +++ /dev/null @@ -1,108 +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 ISOMediaWriter_h_ -#define ISOMediaWriter_h_ - -#include "ContainerWriter.h" -#include "nsAutoPtr.h" -#include "nsIRunnable.h" - -namespace mozilla { - -class ISOControl; -class FragmentBuffer; - -class ISOMediaWriter : public ContainerWriter -{ -public: - // Generate an fragmented MP4 stream, ISO/IEC 14496-12. - // Brand names in 'ftyp' box are 'isom' and 'mp42'. - const static uint32_t TYPE_FRAG_MP4 = 1 << 0; - - // Generate an fragmented 3GP stream, 3GPP TS 26.244, - // '5.4.3 Basic profile'. - // Brand names in 'ftyp' box are '3gp9' and 'isom'. - const static uint32_t TYPE_FRAG_3GP = 1 << 1; - - // Generate an fragmented 3G2 stream, 3GPP2 C.S0050-B - // Brand names in 'ftyp' box are '3g2c' and 'isom' - const static uint32_t TYPE_FRAG_3G2 = 1 << 2; - - // aType is the combination of CREATE_AUDIO_TRACK and CREATE_VIDEO_TRACK. - // It is a hint to muxer that the output streaming contains audio, video - // or both. - // - // aHint is one of the value in TYPE_XXXXXXXX. It is a hint to muxer what kind - // of ISO format should be generated. - ISOMediaWriter(uint32_t aType, uint32_t aHint = TYPE_FRAG_MP4); - ~ISOMediaWriter(); - - // ContainerWriter methods - nsresult WriteEncodedTrack(const EncodedFrameContainer &aData, - uint32_t aFlags = 0) override; - - nsresult GetContainerData(nsTArray>* aOutputBufs, - uint32_t aFlags = 0) override; - - nsresult SetMetadata(TrackMetadataBase* aMetadata) override; - -protected: - /** - * The state of each state will generate one or more blob. - * Each blob will be a moov, moof, moof... until receiving EOS. - * The generated sequence is: - * - * moov -> moof -> moof -> ... -> moof -> moof - * - * Following is the details of each state. - * MUXING_HEAD: - * It collects the metadata to generate a moov. The state transits to - * MUXING_HEAD after output moov blob. - * - * MUXING_FRAG: - * It collects enough audio/video data to generate a fragment blob. This - * will be repeated until END_OF_STREAM and then transiting to MUXING_DONE. - * - * MUXING_DONE: - * End of ISOMediaWriter life cycle. - */ - enum MuxState { - MUXING_HEAD, - MUXING_FRAG, - MUXING_DONE, - }; - -private: - nsresult RunState(); - - // True if one of following conditions hold: - // 1. Audio/Video accumulates enough data to generate a moof. - // 2. Get EOS signal. - // aEOS will be assigned to true if it gets EOS signal. - bool ReadyToRunState(bool& aEOS); - - // The main class to generate and iso box. Its life time is same as - // ISOMediaWriter and deleted only if ISOMediaWriter is destroyed. - nsAutoPtr mControl; - - // Buffers to keep audio/video data frames, they are created when metadata is - // received. Only one instance for each media type is allowed and they will be - // deleted only if ISOMediaWriter is destroyed. - nsAutoPtr mAudioFragmentBuffer; - nsAutoPtr mVideoFragmentBuffer; - - MuxState mState; - - // A flag to indicate the output buffer is ready to blob out. - bool mBlobReady; - - // Combination of Audio_Track or Video_Track. - uint32_t mType; -}; - -} // namespace mozilla - -#endif // ISOMediaWriter_h_ diff --git a/dom/media/encoder/fmp4_muxer/ISOTrackMetadata.h b/dom/media/encoder/fmp4_muxer/ISOTrackMetadata.h deleted file mode 100644 index 3613e1e9e..000000000 --- a/dom/media/encoder/fmp4_muxer/ISOTrackMetadata.h +++ /dev/null @@ -1,131 +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 ISOTrackMetadata_h_ -#define ISOTrackMetadata_h_ - -#include "TrackMetadataBase.h" - -namespace mozilla { - -class AACTrackMetadata : public AudioTrackMetadata { -public: - // AudioTrackMetadata members - uint32_t GetAudioFrameDuration() override { return mFrameDuration; } - uint32_t GetAudioFrameSize() override { return mFrameSize; } - uint32_t GetAudioSampleRate() override { return mSampleRate; } - uint32_t GetAudioChannels() override { return mChannels; } - - // TrackMetadataBase member - MetadataKind GetKind() const override { return METADATA_AAC; } - - // AACTrackMetadata members - AACTrackMetadata() - : mSampleRate(0) - , mFrameDuration(0) - , mFrameSize(0) - , mChannels(0) { - MOZ_COUNT_CTOR(AACTrackMetadata); - } - ~AACTrackMetadata() { MOZ_COUNT_DTOR(AACTrackMetadata); } - - uint32_t mSampleRate; // From 14496-3 table 1.16, it could be 7350 ~ 96000. - uint32_t mFrameDuration; // Audio frame duration based on SampleRate. - uint32_t mFrameSize; // Audio frame size, 0 is variant size. - uint32_t mChannels; // Channel number, it should be 1 or 2. -}; - -// AVC clock rate is 90k Hz. -#define AVC_CLOCK_RATE 90000 - -class AVCTrackMetadata : public VideoTrackMetadata { -public: - // VideoTrackMetadata members - uint32_t GetVideoHeight() override { return mHeight; } - uint32_t GetVideoWidth() override {return mWidth; } - uint32_t GetVideoDisplayHeight() override { return mDisplayHeight; } - uint32_t GetVideoDisplayWidth() override { return mDisplayWidth; } - uint32_t GetVideoClockRate() override { return AVC_CLOCK_RATE; } - uint32_t GetVideoFrameRate() override { return mFrameRate; } - - // TrackMetadataBase member - MetadataKind GetKind() const override { return METADATA_AVC; } - - // AVCTrackMetadata - AVCTrackMetadata() - : mHeight(0) - , mWidth(0) - , mDisplayHeight(0) - , mDisplayWidth(0) - , mFrameRate(0) { - MOZ_COUNT_CTOR(AVCTrackMetadata); - } - ~AVCTrackMetadata() { MOZ_COUNT_DTOR(AVCTrackMetadata); } - - uint32_t mHeight; - uint32_t mWidth; - uint32_t mDisplayHeight; - uint32_t mDisplayWidth; - uint32_t mFrameRate; // frames per second -}; - - -// AMR sample rate is 8000 samples/s. -#define AMR_SAMPLE_RATE 8000 - -// Channel number is always 1. -#define AMR_CHANNELS 1 - -// AMR speech codec, 3GPP TS 26.071. Encoder and continer support AMR-NB only -// currently. -class AMRTrackMetadata : public AudioTrackMetadata { -public: - // AudioTrackMetadata members - // - // The number of sample sets generates by encoder is variant. So the - // frame duration and frame size are both 0. - uint32_t GetAudioFrameDuration() override { return 0; } - uint32_t GetAudioFrameSize() override { return 0; } - uint32_t GetAudioSampleRate() override { return AMR_SAMPLE_RATE; } - uint32_t GetAudioChannels() override { return AMR_CHANNELS; } - - // TrackMetadataBase member - MetadataKind GetKind() const override { return METADATA_AMR; } - - // AMRTrackMetadata members - AMRTrackMetadata() { MOZ_COUNT_CTOR(AMRTrackMetadata); } - ~AMRTrackMetadata() { MOZ_COUNT_DTOR(AMRTrackMetadata); } -}; - -// EVRC sample rate is 8000 samples/s. -#define EVRC_SAMPLE_RATE 8000 - -class EVRCTrackMetadata : public AudioTrackMetadata { -public: - // AudioTrackMetadata members - // - // The number of sample sets generates by encoder is variant. So the - // frame duration and frame size are both 0. - uint32_t GetAudioFrameDuration() override { return 0; } - uint32_t GetAudioFrameSize() override { return 0; } - uint32_t GetAudioSampleRate() override { return EVRC_SAMPLE_RATE; } - uint32_t GetAudioChannels() override { return mChannels; } - - // TrackMetadataBase member - MetadataKind GetKind() const override { return METADATA_EVRC; } - - // EVRCTrackMetadata members - EVRCTrackMetadata() - : mChannels(0) { - MOZ_COUNT_CTOR(EVRCTrackMetadata); - } - ~EVRCTrackMetadata() { MOZ_COUNT_DTOR(EVRCTrackMetadata); } - - uint32_t mChannels; // Channel number, it should be 1 or 2. -}; - -} - -#endif // ISOTrackMetadata_h_ diff --git a/dom/media/encoder/fmp4_muxer/MP4ESDS.cpp b/dom/media/encoder/fmp4_muxer/MP4ESDS.cpp deleted file mode 100644 index 72880b5cb..000000000 --- a/dom/media/encoder/fmp4_muxer/MP4ESDS.cpp +++ /dev/null @@ -1,138 +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 -#include "ISOControl.h" -#include "ISOMediaBoxes.h" -#include "MP4ESDS.h" - -namespace mozilla { - -nsresult -MP4AudioSampleEntry::Generate(uint32_t* aBoxSize) -{ - uint32_t box_size; - nsresult rv = es->Generate(&box_size); - NS_ENSURE_SUCCESS(rv, rv); - size += box_size; - - *aBoxSize = size; - return NS_OK; -} - -nsresult -MP4AudioSampleEntry::Write() -{ - BoxSizeChecker checker(mControl, size); - nsresult rv; - rv = AudioSampleEntry::Write(); - NS_ENSURE_SUCCESS(rv, rv); - rv = es->Write(); - NS_ENSURE_SUCCESS(rv, rv); - - return NS_OK; -} - -MP4AudioSampleEntry::MP4AudioSampleEntry(ISOControl* aControl) - : AudioSampleEntry(NS_LITERAL_CSTRING("mp4a"), aControl) -{ - es = new ESDBox(aControl); - MOZ_COUNT_CTOR(MP4AudioSampleEntry); -} - -MP4AudioSampleEntry::~MP4AudioSampleEntry() -{ - MOZ_COUNT_DTOR(MP4AudioSampleEntry); -} - -nsresult -ESDBox::Generate(uint32_t* aBoxSize) -{ - uint32_t box_size; - es_descriptor->Generate(&box_size); - size += box_size; - *aBoxSize = size; - return NS_OK; -} - -nsresult -ESDBox::Write() -{ - WRITE_FULLBOX(mControl, size) - es_descriptor->Write(); - return NS_OK; -} - -ESDBox::ESDBox(ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("esds"), 0, 0, aControl) -{ - es_descriptor = new ES_Descriptor(aControl); - MOZ_COUNT_CTOR(ESDBox); -} - -ESDBox::~ESDBox() -{ - MOZ_COUNT_DTOR(ESDBox); -} - -nsresult -ES_Descriptor::Find(const nsACString& aType, - nsTArray>& aOperations) -{ - // ES_Descriptor is not a real ISOMediaBox, so we return nothing here. - return NS_OK; -} - -nsresult -ES_Descriptor::Write() -{ - mControl->Write(tag); - mControl->Write(length); - mControl->Write(ES_ID); - mControl->WriteBits(streamDependenceFlag.to_ulong(), streamDependenceFlag.size()); - mControl->WriteBits(URL_Flag.to_ulong(), URL_Flag.size()); - mControl->WriteBits(reserved.to_ulong(), reserved.size()); - mControl->WriteBits(streamPriority.to_ulong(), streamPriority.size()); - mControl->Write(DecodeSpecificInfo.Elements(), DecodeSpecificInfo.Length()); - - return NS_OK; -} - -nsresult -ES_Descriptor::Generate(uint32_t* aBoxSize) -{ - nsresult rv; - // 14496-1 '8.3.4 DecoderConfigDescriptor' - // 14496-1 '10.2.3 SL Packet Header Configuration' - FragmentBuffer* frag = mControl->GetFragment(Audio_Track); - rv = frag->GetCSD(DecodeSpecificInfo); - NS_ENSURE_SUCCESS(rv, rv); - - length = sizeof(ES_ID) + 1; - length += DecodeSpecificInfo.Length(); - - *aBoxSize = sizeof(tag) + sizeof(length) + length; - return NS_OK; -} - -ES_Descriptor::ES_Descriptor(ISOControl* aControl) - : tag(ESDescrTag) - , length(0) - , ES_ID(0) - , streamDependenceFlag(0) - , URL_Flag(0) - , reserved(0) - , streamPriority(0) - , mControl(aControl) -{ - MOZ_COUNT_CTOR(ES_Descriptor); -} - -ES_Descriptor::~ES_Descriptor() -{ - MOZ_COUNT_DTOR(ES_Descriptor); -} - -} diff --git a/dom/media/encoder/fmp4_muxer/MP4ESDS.h b/dom/media/encoder/fmp4_muxer/MP4ESDS.h deleted file mode 100644 index ee91312c1..000000000 --- a/dom/media/encoder/fmp4_muxer/MP4ESDS.h +++ /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/. */ - -#ifndef MP4ESDS_h_ -#define MP4ESDS_h_ - -#include "nsTArray.h" -#include "MuxerOperation.h" - -namespace mozilla { - -class ISOControl; - -/** - * ESDS tag - */ -#define ESDescrTag 0x03 - -/** - * 14496-1 '8.3.3 ES_Descriptor'. - * It will get DecoderConfigDescriptor and SLConfigDescriptor from - * AAC CSD data. - */ -class ES_Descriptor : public MuxerOperation { -public: - // ISO BMFF members - uint8_t tag; // ESDescrTag - uint8_t length; - uint16_t ES_ID; - std::bitset<1> streamDependenceFlag; - std::bitset<1> URL_Flag; - std::bitset<1> reserved; - std::bitset<5> streamPriority; - - nsTArray DecodeSpecificInfo; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - nsresult Find(const nsACString& aType, - nsTArray>& aOperations) override; - - // ES_Descriptor methods - ES_Descriptor(ISOControl* aControl); - ~ES_Descriptor(); - -protected: - ISOControl* mControl; -}; - -// 14496-14 5.6 'Sample Description Boxes' -// Box type: 'esds' -class ESDBox : public FullBox { -public: - // ISO BMFF members - RefPtr es_descriptor; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // ESDBox methods - ESDBox(ISOControl* aControl); - ~ESDBox(); -}; - -// 14496-14 5.6 'Sample Description Boxes' -// Box type: 'mp4a' -class MP4AudioSampleEntry : public AudioSampleEntry { -public: - // ISO BMFF members - RefPtr es; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // MP4AudioSampleEntry methods - MP4AudioSampleEntry(ISOControl* aControl); - ~MP4AudioSampleEntry(); -}; - -} - -#endif // MP4ESDS_h_ diff --git a/dom/media/encoder/fmp4_muxer/MuxerOperation.h b/dom/media/encoder/fmp4_muxer/MuxerOperation.h deleted file mode 100644 index 0b83c89b0..000000000 --- a/dom/media/encoder/fmp4_muxer/MuxerOperation.h +++ /dev/null @@ -1,57 +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 "nsString.h" -#include "nsTArray.h" - -#ifndef MuxerOperation_h_ -#define MuxerOperation_h_ - -namespace mozilla { - -/** - * The interface for ISO box. All Boxes inherit from this interface. - * Generate() and Write() are needed to be called to produce a complete box. - * - * Generate() will generate all the data structures and their size. - * - * Write() will write all data into muxing output stream (ISOControl actually) - * and update the data which can't be known at Generate() (for example, the - * offset of the video data in mp4 file). - * - * ISO base media format is composed of several container boxes and the contained - * boxes. The container boxes hold a list of MuxerOperation which is implemented - * by contained boxes. The contained boxes will be called via the list. - * For example: - * MovieBox (container) ---> boxes (array of MuxerOperation) - * |---> MovieHeaderBox (full box) - * |---> TrakBox (container) - * |---> MovieExtendsBox (container) - * - * The complete box structure can be found at 14496-12 E.2 "The‘isom’brand". - */ -class MuxerOperation { -public: - NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MuxerOperation) - - // Generate data of this box and its contained box, and calculate box size. - virtual nsresult Generate(uint32_t* aBoxSize) = 0; - - // Write data to stream. - virtual nsresult Write() = 0; - - // Find the box type via its name (name is the box type defined in 14496-12; - // for example, 'moov' is the name of MovieBox). - // It can only look child boxes including itself and the box in the boxes - // list if exists. It can't look parent boxes. - virtual nsresult Find(const nsACString& aType, - nsTArray>& aOperations) = 0; - -protected: - virtual ~MuxerOperation() {} -}; - -} -#endif diff --git a/dom/media/encoder/fmp4_muxer/moz.build b/dom/media/encoder/fmp4_muxer/moz.build deleted file mode 100644 index 5ff274be5..000000000 --- a/dom/media/encoder/fmp4_muxer/moz.build +++ /dev/null @@ -1,22 +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/. - -EXPORTS += [ - 'ISOMediaWriter.h', - 'ISOTrackMetadata.h', -] - -UNIFIED_SOURCES += [ - 'AMRBox.cpp', - 'AVCBox.cpp', - 'EVRCBox.cpp', - 'ISOControl.cpp', - 'ISOMediaBoxes.cpp', - 'ISOMediaWriter.cpp', - 'MP4ESDS.cpp', -] - -FINAL_LIBRARY = 'xul' diff --git a/dom/media/encoder/moz.build b/dom/media/encoder/moz.build index 0d5cdc16f..f29430cb0 100644 --- a/dom/media/encoder/moz.build +++ b/dom/media/encoder/moz.build @@ -7,9 +7,6 @@ with Files('*'): BUG_COMPONENT = ('Core', 'Video/Audio: Recording') -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': - DIRS += ['fmp4_muxer'] - EXPORTS += [ 'ContainerWriter.h', 'EncodedFrameContainer.h', @@ -37,16 +34,6 @@ FINAL_LIBRARY = 'xul' # These includes are from Android JB, for use of MediaCodec. LOCAL_INCLUDES += ['/ipc/chromium/src'] -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and CONFIG['ANDROID_VERSION'] > '15': - LOCAL_INCLUDES += [ - '%' + '%s/%s' % (CONFIG['ANDROID_SOURCE'], d) for d in [ - 'frameworks/av/include/media', - 'frameworks/native/include', - 'frameworks/native/opengl/include', - ] - - ] - include('/ipc/chromium/chromium-config.mozbuild') # Suppress some GCC warnings being treated as errors: diff --git a/dom/media/platforms/omx/GonkOmxPlatformLayer.cpp b/dom/media/platforms/omx/GonkOmxPlatformLayer.cpp deleted file mode 100644 index 870566cf5..000000000 --- a/dom/media/platforms/omx/GonkOmxPlatformLayer.cpp +++ /dev/null @@ -1,667 +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 "GonkOmxPlatformLayer.h" - -#include -#include -#include -#include -#include - -#include "mozilla/Monitor.h" -#include "mozilla/layers/TextureClient.h" -#include "mozilla/layers/GrallocTextureClient.h" -#include "mozilla/layers/ImageBridgeChild.h" -#include "mozilla/layers/TextureClientRecycleAllocator.h" - -#include "ImageContainer.h" -#include "MediaInfo.h" -#include "OmxDataDecoder.h" - - -#ifdef LOG -#undef LOG -#endif - -#define LOG(arg, ...) MOZ_LOG(sPDMLog, mozilla::LogLevel::Debug, ("GonkOmxPlatformLayer(%p)::%s: " arg, this, __func__, ##__VA_ARGS__)) - -#define CHECK_ERR(err) \ - if (err != OK) { \ - LOG("error %d at %s", err, __func__); \ - return NS_ERROR_FAILURE; \ - } \ - -// Android proprietary value. -#define ANDROID_OMX_VIDEO_CodingVP8 (static_cast(9)) - -using namespace android; - -namespace mozilla { - -// In Gonk, the software component name has prefix "OMX.google". It needs to -// have a way to use hardware codec first. -bool IsSoftwareCodec(const char* aComponentName) -{ - nsAutoCString str(aComponentName); - return (str.Find(NS_LITERAL_CSTRING("OMX.google.")) == -1 ? false : true); -} - -bool IsInEmulator() -{ - char propQemu[PROPERTY_VALUE_MAX]; - property_get("ro.kernel.qemu", propQemu, ""); - return !strncmp(propQemu, "1", 1); -} - -class GonkOmxObserver : public BnOMXObserver { -public: - void onMessage(const omx_message& aMsg) - { - switch (aMsg.type) { - case omx_message::EVENT: - { - sp self = this; - nsCOMPtr r = NS_NewRunnableFunction([self, aMsg] () { - if (self->mClient && self->mClient->Event(aMsg.u.event_data.event, - aMsg.u.event_data.data1, - aMsg.u.event_data.data2)) - { - return; - } - }); - mTaskQueue->Dispatch(r.forget()); - break; - } - case omx_message::EMPTY_BUFFER_DONE: - { - sp self = this; - nsCOMPtr r = NS_NewRunnableFunction([self, aMsg] () { - if (!self->mPromiseLayer) { - return; - } - BufferData::BufferID id = (BufferData::BufferID)aMsg.u.buffer_data.buffer; - self->mPromiseLayer->EmptyFillBufferDone(OMX_DirInput, id); - }); - mTaskQueue->Dispatch(r.forget()); - break; - } - case omx_message::FILL_BUFFER_DONE: - { - sp self = this; - nsCOMPtr r = NS_NewRunnableFunction([self, aMsg] () { - if (!self->mPromiseLayer) { - return; - } - - // TODO: these codes look a little ugly, it'd be better to improve them. - RefPtr buf; - BufferData::BufferID id = (BufferData::BufferID)aMsg.u.extended_buffer_data.buffer; - buf = self->mPromiseLayer->FindAndRemoveBufferHolder(OMX_DirOutput, id); - MOZ_RELEASE_ASSERT(buf); - GonkBufferData* gonkBuffer = static_cast(buf.get()); - - // Copy the critical information to local buffer. - if (gonkBuffer->IsLocalBuffer()) { - gonkBuffer->mBuffer->nOffset = aMsg.u.extended_buffer_data.range_offset; - gonkBuffer->mBuffer->nFilledLen = aMsg.u.extended_buffer_data.range_length; - gonkBuffer->mBuffer->nFlags = aMsg.u.extended_buffer_data.flags; - gonkBuffer->mBuffer->nTimeStamp = aMsg.u.extended_buffer_data.timestamp; - } - self->mPromiseLayer->EmptyFillBufferDone(OMX_DirOutput, buf); - }); - mTaskQueue->Dispatch(r.forget()); - break; - } - default: - { - LOG("Unhandle event %d", aMsg.type); - } - } - } - - void Shutdown() - { - MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn()); - mPromiseLayer = nullptr; - mClient = nullptr; - } - - GonkOmxObserver(TaskQueue* aTaskQueue, OmxPromiseLayer* aPromiseLayer, OmxDataDecoder* aDataDecoder) - : mTaskQueue(aTaskQueue) - , mPromiseLayer(aPromiseLayer) - , mClient(aDataDecoder) - {} - -protected: - RefPtr mTaskQueue; - // TODO: - // we should combine both event handlers into one. And we should provide - // an unified way for event handling in OmxPlatformLayer class. - RefPtr mPromiseLayer; - RefPtr mClient; -}; - -// This class allocates Gralloc buffer and manages TextureClient's recycle. -class GonkTextureClientRecycleHandler : public layers::ITextureClientRecycleAllocator -{ - typedef MozPromise TextureClientRecyclePromise; - -public: - GonkTextureClientRecycleHandler(OMX_VIDEO_PORTDEFINITIONTYPE& aDef) - : ITextureClientRecycleAllocator() - , mMonitor("GonkTextureClientRecycleHandler") - { - RefPtr bridge = layers::ImageBridgeChild::GetSingleton(); - - // Allocate Gralloc texture memory. - layers::GrallocTextureData* textureData = - layers::GrallocTextureData::Create(gfx::IntSize(aDef.nFrameWidth, aDef.nFrameHeight), - aDef.eColorFormat, - gfx::BackendType::NONE, - GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_SW_READ_OFTEN, - bridge); - - mGraphBuffer = textureData->GetGraphicBuffer(); - MOZ_ASSERT(mGraphBuffer.get()); - - mTextureClient = - layers::TextureClient::CreateWithData(textureData, - layers::TextureFlags::DEALLOCATE_CLIENT | layers::TextureFlags::RECYCLE, - bridge); - MOZ_ASSERT(mTextureClient); - - mPromise.SetMonitor(&mMonitor); - } - - RefPtr WaitforRecycle() - { - MonitorAutoLock lock(mMonitor); - MOZ_ASSERT(!!mGraphBuffer.get()); - - mTextureClient->SetRecycleAllocator(this); - return mPromise.Ensure(__func__); - } - - // DO NOT use smart pointer to receive TextureClient; otherwise it will - // distrupt the reference count. - layers::TextureClient* GetTextureClient() - { - return mTextureClient; - } - - GraphicBuffer* GetGraphicBuffer() - { - MonitorAutoLock lock(mMonitor); - return mGraphBuffer.get(); - } - - // This function is called from layers thread. - void RecycleTextureClient(layers::TextureClient* aClient) override - { - MOZ_ASSERT(mTextureClient == aClient); - - // Clearing the recycle allocator drops a reference, so make sure we stay alive - // for the duration of this function. - RefPtr kungFuDeathGrip(this); - aClient->SetRecycleAllocator(nullptr); - - { - MonitorAutoLock lock(mMonitor); - mPromise.ResolveIfExists(mTextureClient, __func__); - } - } - - void Shutdown() - { - MonitorAutoLock lock(mMonitor); - - mPromise.RejectIfExists(NS_ERROR_FAILURE, __func__); - - // DO NOT clear TextureClient here. - // The ref count could be 1 and RecycleCallback will be called if we clear - // the ref count here. That breaks the whole mechanism. (RecycleCallback - // should be called from layers) - mGraphBuffer = nullptr; - } - -private: - // Because TextureClient calls RecycleCallbackl when ref count is 1, so we - // should hold only one reference here and use raw pointer when out of this - // class. - RefPtr mTextureClient; - - // It is protected by mMonitor. - sp mGraphBuffer; - - // It is protected by mMonitor. - MozPromiseHolder mPromise; - - Monitor mMonitor; -}; - -GonkBufferData::GonkBufferData(bool aLiveInLocal, - GonkOmxPlatformLayer* aGonkPlatformLayer) - : BufferData(nullptr) - , mId(0) - , mGonkPlatformLayer(aGonkPlatformLayer) -{ - if (!aLiveInLocal) { - mMirrorBuffer = new OMX_BUFFERHEADERTYPE; - PodZero(mMirrorBuffer.get()); - mBuffer = mMirrorBuffer.get(); - } -} - -void -GonkBufferData::ReleaseBuffer() -{ - if (mTextureClientRecycleHandler) { - mTextureClientRecycleHandler->Shutdown(); - mTextureClientRecycleHandler = nullptr; - } -} - -nsresult -GonkBufferData::InitSharedMemory(android::IMemory* aMemory) -{ - MOZ_RELEASE_ASSERT(mMirrorBuffer.get()); - - // aMemory is a IPC memory, it is safe to use it here. - mBuffer->pBuffer = (OMX_U8*)aMemory->pointer(); - mBuffer->nAllocLen = aMemory->size(); - return NS_OK; -} - -nsresult -GonkBufferData::InitLocalBuffer(IOMX::buffer_id aId) -{ - MOZ_RELEASE_ASSERT(!mMirrorBuffer.get()); - - mBuffer = (OMX_BUFFERHEADERTYPE*)aId; - return NS_OK; -} - -nsresult -GonkBufferData::InitGraphicBuffer(OMX_VIDEO_PORTDEFINITIONTYPE& aDef) -{ - mTextureClientRecycleHandler = new GonkTextureClientRecycleHandler(aDef); - - if (!mTextureClientRecycleHandler->GetGraphicBuffer()) { - return NS_ERROR_FAILURE; - } - - return NS_OK; -} - -already_AddRefed -GonkBufferData::GetPlatformMediaData() -{ - if (mGonkPlatformLayer->GetTrackInfo()->GetAsAudioInfo()) { - // This is audio decoding. - return nullptr; - } - - if (!mTextureClientRecycleHandler) { - // There is no GraphicBuffer, it should fallback to normal YUV420 VideoData. - return nullptr; - } - - VideoInfo info(*mGonkPlatformLayer->GetTrackInfo()->GetAsVideoInfo()); - RefPtr data = - VideoData::CreateAndCopyIntoTextureClient(info, - 0, - mBuffer->nTimeStamp, - 1, - mTextureClientRecycleHandler->GetTextureClient(), - false, - 0, - info.ImageRect()); - LOG("%p, disp width %d, height %d, pic width %d, height %d, time %ld", - this, info.mDisplay.width, info.mDisplay.height, - info.mImage.width, info.mImage.height, mBuffer->nTimeStamp); - - // Get TextureClient Promise here to wait for resolved. - RefPtr self(this); - mTextureClientRecycleHandler->WaitforRecycle() - ->Then(mGonkPlatformLayer->GetTaskQueue(), __func__, - [self] () { - self->mPromise.ResolveIfExists(self, __func__); - }, - [self] () { - OmxBufferFailureHolder failure(OMX_ErrorUndefined, self); - self->mPromise.RejectIfExists(failure, __func__); - }); - - return data.forget(); -} - -GonkOmxPlatformLayer::GonkOmxPlatformLayer(OmxDataDecoder* aDataDecoder, - OmxPromiseLayer* aPromiseLayer, - TaskQueue* aTaskQueue, - layers::ImageContainer* aImageContainer) - : mTaskQueue(aTaskQueue) - , mImageContainer(aImageContainer) - , mNode(0) -{ - mOmxObserver = new GonkOmxObserver(mTaskQueue, aPromiseLayer, aDataDecoder); -} - -nsresult -GonkOmxPlatformLayer::AllocateOmxBuffer(OMX_DIRTYPE aType, - BUFFERLIST* aBufferList) -{ - MOZ_ASSERT(!mMemoryDealer[aType].get()); - - // Get port definition. - OMX_PARAM_PORTDEFINITIONTYPE def; - nsTArray portindex; - GetPortIndices(portindex); - for (auto idx : portindex) { - InitOmxParameter(&def); - def.nPortIndex = idx; - - OMX_ERRORTYPE err = GetParameter(OMX_IndexParamPortDefinition, - &def, - sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); - if (err != OMX_ErrorNone) { - return NS_ERROR_FAILURE; - } else if (def.eDir == aType) { - LOG("Get OMX_IndexParamPortDefinition: port: %d, type: %d", def.nPortIndex, def.eDir); - break; - } - } - - size_t t = 0; - - // Configure video output GraphicBuffer for video decoding acceleration. - bool useGralloc = false; - if (aType == OMX_DirOutput && mQuirks.test(kRequiresAllocateBufferOnOutputPorts) && - (def.eDomain == OMX_PortDomainVideo)) { - if (NS_FAILED(EnableOmxGraphicBufferPort(def))) { - return NS_ERROR_FAILURE; - } - - LOG("Enable OMX GraphicBuffer port, number %d, width %d, height %d", def.nBufferCountActual, - def.format.video.nFrameWidth, def.format.video.nFrameHeight); - - useGralloc = true; - - t = 1024; // MemoryDealer doesn't like 0, it's just for MemoryDealer happy. - } else { - t = def.nBufferCountActual * def.nBufferSize; - LOG("Buffer count %d, buffer size %d", def.nBufferCountActual, def.nBufferSize); - } - - bool liveinlocal = mOmx->livesLocally(mNode, getpid()); - - // MemoryDealer is a IPC buffer allocator in Gonk because IOMX is actually - // lives in mediaserver. - mMemoryDealer[aType] = new MemoryDealer(t, "Gecko-OMX"); - for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) { - RefPtr buffer; - IOMX::buffer_id bufferID; - status_t st; - nsresult rv; - - buffer = new GonkBufferData(liveinlocal, this); - if (useGralloc) { - // Buffer is lived remotely. Use GraphicBuffer for decoded video frame display. - rv = buffer->InitGraphicBuffer(def.format.video); - NS_ENSURE_SUCCESS(rv, rv); - st = mOmx->useGraphicBuffer(mNode, - def.nPortIndex, - buffer->mTextureClientRecycleHandler->GetGraphicBuffer(), - &bufferID); - CHECK_ERR(st); - } else { - sp mem = mMemoryDealer[aType]->allocate(def.nBufferSize); - MOZ_ASSERT(mem.get()); - - if ((mQuirks.test(kRequiresAllocateBufferOnInputPorts) && aType == OMX_DirInput) || - (mQuirks.test(kRequiresAllocateBufferOnOutputPorts) && aType == OMX_DirOutput)) { - // Buffer is lived remotely. We allocate a local OMX_BUFFERHEADERTYPE - // as the mirror of the remote OMX_BUFFERHEADERTYPE. - st = mOmx->allocateBufferWithBackup(mNode, aType, mem, &bufferID); - CHECK_ERR(st); - rv = buffer->InitSharedMemory(mem.get()); - NS_ENSURE_SUCCESS(rv, rv); - } else { - // Buffer is lived locally, bufferID is the actually OMX_BUFFERHEADERTYPE - // pointer. - st = mOmx->useBuffer(mNode, aType, mem, &bufferID); - CHECK_ERR(st); - rv = buffer->InitLocalBuffer(bufferID); - NS_ENSURE_SUCCESS(rv, rv); - } - } - - rv = buffer->SetBufferId(bufferID); - NS_ENSURE_SUCCESS(rv, rv); - - aBufferList->AppendElement(buffer); - } - - return NS_OK; -} - -nsresult -GonkOmxPlatformLayer::ReleaseOmxBuffer(OMX_DIRTYPE aType, - BUFFERLIST* aBufferList) -{ - status_t st; - uint32_t len = aBufferList->Length(); - for (uint32_t i = 0; i < len; i++) { - GonkBufferData* buffer = static_cast(aBufferList->ElementAt(i).get()); - IOMX::buffer_id id = (OMX_BUFFERHEADERTYPE*) buffer->ID(); - st = mOmx->freeBuffer(mNode, aType, id); - if (st != OK) { - return NS_ERROR_FAILURE; - } - buffer->ReleaseBuffer(); - } - aBufferList->Clear(); - mMemoryDealer[aType].clear(); - - return NS_OK; -} - -nsresult -GonkOmxPlatformLayer::EnableOmxGraphicBufferPort(OMX_PARAM_PORTDEFINITIONTYPE& aDef) -{ - status_t st; - - st = mOmx->enableGraphicBuffers(mNode, aDef.nPortIndex, OMX_TRUE); - CHECK_ERR(st); - - return NS_OK; -} - -OMX_ERRORTYPE -GonkOmxPlatformLayer::GetState(OMX_STATETYPE* aType) -{ - return (OMX_ERRORTYPE)mOmx->getState(mNode, aType); -} - -OMX_ERRORTYPE -GonkOmxPlatformLayer::GetParameter(OMX_INDEXTYPE aParamIndex, - OMX_PTR aComponentParameterStructure, - OMX_U32 aComponentParameterSize) -{ - return (OMX_ERRORTYPE)mOmx->getParameter(mNode, - aParamIndex, - aComponentParameterStructure, - aComponentParameterSize); -} - -OMX_ERRORTYPE -GonkOmxPlatformLayer::SetParameter(OMX_INDEXTYPE aParamIndex, - OMX_PTR aComponentParameterStructure, - OMX_U32 aComponentParameterSize) -{ - return (OMX_ERRORTYPE)mOmx->setParameter(mNode, - aParamIndex, - aComponentParameterStructure, - aComponentParameterSize); -} - -nsresult -GonkOmxPlatformLayer::Shutdown() -{ - mOmx->freeNode(mNode); - mOmxObserver->Shutdown(); - mOmxObserver = nullptr; - mOmxClient.disconnect(); - - return NS_OK; -} - -OMX_ERRORTYPE -GonkOmxPlatformLayer::InitOmxToStateLoaded(const TrackInfo* aInfo) -{ - mInfo = aInfo; - status_t err = mOmxClient.connect(); - if (err != OK) { - return OMX_ErrorUndefined; - } - mOmx = mOmxClient.interface(); - if (!mOmx.get()) { - return OMX_ErrorUndefined; - } - - LOG("find componenet for mime type %s", mInfo->mMimeType.Data()); - - nsTArray components; - if (FindComponents(mInfo->mMimeType, &components)) { - for (auto comp : components) { - if (LoadComponent(comp)) { - return OMX_ErrorNone; - } - } - } - - LOG("no component is loaded"); - return OMX_ErrorUndefined; -} - -OMX_ERRORTYPE -GonkOmxPlatformLayer::EmptyThisBuffer(BufferData* aData) -{ - return (OMX_ERRORTYPE)mOmx->emptyBuffer(mNode, - (IOMX::buffer_id)aData->ID(), - aData->mBuffer->nOffset, - aData->mBuffer->nFilledLen, - aData->mBuffer->nFlags, - aData->mBuffer->nTimeStamp); -} - -OMX_ERRORTYPE -GonkOmxPlatformLayer::FillThisBuffer(BufferData* aData) -{ - return (OMX_ERRORTYPE)mOmx->fillBuffer(mNode, (IOMX::buffer_id)aData->ID()); -} - -OMX_ERRORTYPE -GonkOmxPlatformLayer::SendCommand(OMX_COMMANDTYPE aCmd, - OMX_U32 aParam1, - OMX_PTR aCmdData) -{ - return (OMX_ERRORTYPE)mOmx->sendCommand(mNode, aCmd, aParam1); -} - -bool -GonkOmxPlatformLayer::LoadComponent(const ComponentInfo& aComponent) -{ - status_t err = mOmx->allocateNode(aComponent.mName, mOmxObserver, &mNode); - if (err == OK) { - mQuirks = aComponent.mQuirks; - LOG("Load OpenMax component %s, alloc input %d, alloc output %d, live locally %d", - aComponent.mName, mQuirks.test(kRequiresAllocateBufferOnInputPorts), - mQuirks.test(kRequiresAllocateBufferOnOutputPorts), - mOmx->livesLocally(mNode, getpid())); - return true; - } - return false; -} - -layers::ImageContainer* -GonkOmxPlatformLayer::GetImageContainer() -{ - return mImageContainer; -} - -const TrackInfo* -GonkOmxPlatformLayer::GetTrackInfo() -{ - return mInfo; -} - -bool -GonkOmxPlatformLayer::FindComponents(const nsACString& aMimeType, - nsTArray* aComponents) -{ - static const MediaCodecList* codecs = MediaCodecList::getInstance(); - - bool useHardwareCodecOnly = false; - - // H264 and H263 has different profiles, software codec doesn't support high profile. - // So we use hardware codec only. - if (!IsInEmulator() && - (aMimeType.EqualsLiteral("video/avc") || - aMimeType.EqualsLiteral("video/mp4") || - aMimeType.EqualsLiteral("video/mp4v-es") || - aMimeType.EqualsLiteral("video/3gp"))) { - useHardwareCodecOnly = true; - } - - const char* mime = aMimeType.Data(); - // Translate VP8 MIME type to Android format. - if (aMimeType.EqualsLiteral("video/webm; codecs=vp8")) { - mime = "video/x-vnd.on2.vp8"; - } - - size_t start = 0; - bool found = false; - while (true) { - ssize_t index = codecs->findCodecByType(mime, false /* encoder */, start); - if (index < 0) { - break; - } - start = index + 1; - - const char* name = codecs->getCodecName(index); - if (IsSoftwareCodec(name) && useHardwareCodecOnly) { - continue; - } - - found = true; - - if (!aComponents) { - continue; - } - ComponentInfo* comp = aComponents->AppendElement(); - comp->mName = name; - if (codecs->codecHasQuirk(index, "requires-allocate-on-input-ports")) { - comp->mQuirks.set(kRequiresAllocateBufferOnInputPorts); - } - if (codecs->codecHasQuirk(index, "requires-allocate-on-output-ports")) { - comp->mQuirks.set(kRequiresAllocateBufferOnOutputPorts); - } - } - - return found; -} - -OMX_VIDEO_CODINGTYPE -GonkOmxPlatformLayer::CompressionFormat() -{ - MOZ_ASSERT(mInfo); - - return mInfo->mMimeType.EqualsLiteral("video/webm; codecs=vp8") ? - ANDROID_OMX_VIDEO_CodingVP8 : OmxPlatformLayer::CompressionFormat(); -} - -} // mozilla diff --git a/dom/media/platforms/omx/GonkOmxPlatformLayer.h b/dom/media/platforms/omx/GonkOmxPlatformLayer.h deleted file mode 100644 index aaa8c654d..000000000 --- a/dom/media/platforms/omx/GonkOmxPlatformLayer.h +++ /dev/null @@ -1,205 +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/. */ - -#if !defined(GonkOmxPlatformLayer_h_) -#define GonkOmxPlatformLayer_h_ - -#pragma GCC visibility push(default) - -#include - -#include -#include -#include "nsAutoPtr.h" - -#include "OMX_Component.h" - -#include "OmxPlatformLayer.h" - -class nsACString; - -namespace android { -class IMemory; -class MemoryDealer; -} - -namespace mozilla { - -class GonkOmxObserver; -class GonkOmxPlatformLayer; -class GonkTextureClientRecycleHandler; - -/* - * Due to Android's omx node could live in local process (client) or remote - * process (mediaserver). And there are 3 kinds of buffer in Android OMX. - * - * 1. - * When buffer is in local process, the IOMX::buffer_id is OMX_BUFFERHEADERTYPE - * pointer actually, it is safe to use it directly. - * - * 2. - * When buffer is in remote process, the OMX_BUFFERHEADERTYPE pointer is 'IN' the - * remote process. It can't be used in local process, so here it allocates a - * local OMX_BUFFERHEADERTYPE. The raw/decoded data is in the android shared - * memory, IMemory. - * - * 3. - * When buffer is in remote process for the display output port. It uses - * GraphicBuffer to accelerate the decoding and display. - * - */ -class GonkBufferData : public OmxPromiseLayer::BufferData { -protected: - virtual ~GonkBufferData() {} - -public: - GonkBufferData(bool aLiveInLocal, - GonkOmxPlatformLayer* aLayer); - - BufferID ID() override - { - return mId; - } - - already_AddRefed GetPlatformMediaData() override; - - bool IsLocalBuffer() - { - return !!mMirrorBuffer.get(); - } - - void ReleaseBuffer(); - - nsresult SetBufferId(android::IOMX::buffer_id aId) - { - mId = aId; - return NS_OK; - } - - // The mBuffer is in local process. And aId is actually the OMX_BUFFERHEADERTYPE - // pointer. It doesn't need a mirror buffer. - nsresult InitLocalBuffer(android::IOMX::buffer_id aId); - - // aMemory is an IPC based memory which will be used as the pBuffer in - // mBuffer. And the mBuffer will be the mirror OMX_BUFFERHEADERTYPE - // of the one in the remote process. - nsresult InitSharedMemory(android::IMemory* aMemory); - - // GraphicBuffer is for video decoding acceleration on output port. - // Then mBuffer is the mirror OMX_BUFFERHEADERTYPE of the one in the remote - // process. - nsresult InitGraphicBuffer(OMX_VIDEO_PORTDEFINITIONTYPE& aDef); - - // Android OMX uses this id to pass the buffer between OMX component and - // client. - android::IOMX::buffer_id mId; - - // mMirrorBuffer are used only when the omx node is in mediaserver. - // Due to IPC problem, the mId is the OMX_BUFFERHEADERTYPE address in mediaserver. - // It can't mapping to client process, so we need a local OMX_BUFFERHEADERTYPE - // here to mirror the remote OMX_BUFFERHEADERTYPE in mediaserver. - nsAutoPtr mMirrorBuffer; - - // It creates GraphicBuffer and manages TextureClient. - RefPtr mTextureClientRecycleHandler; - - GonkOmxPlatformLayer* mGonkPlatformLayer; -}; - -class GonkOmxPlatformLayer : public OmxPlatformLayer { -public: - enum { - kRequiresAllocateBufferOnInputPorts = 0, - kRequiresAllocateBufferOnOutputPorts, - QUIRKS, - }; - typedef std::bitset Quirks; - - struct ComponentInfo { - const char* mName; - Quirks mQuirks; - }; - - GonkOmxPlatformLayer(OmxDataDecoder* aDataDecoder, - OmxPromiseLayer* aPromiseLayer, - TaskQueue* aTaskQueue, - layers::ImageContainer* aImageContainer); - - nsresult AllocateOmxBuffer(OMX_DIRTYPE aType, BUFFERLIST* aBufferList) override; - - nsresult ReleaseOmxBuffer(OMX_DIRTYPE aType, BUFFERLIST* aBufferList) override; - - OMX_ERRORTYPE GetState(OMX_STATETYPE* aType) override; - - OMX_ERRORTYPE GetParameter(OMX_INDEXTYPE aParamIndex, - OMX_PTR aComponentParameterStructure, - OMX_U32 aComponentParameterSize) override; - - OMX_ERRORTYPE SetParameter(OMX_INDEXTYPE nIndex, - OMX_PTR aComponentParameterStructure, - OMX_U32 aComponentParameterSize) override; - - OMX_ERRORTYPE InitOmxToStateLoaded(const TrackInfo* aInfo) override; - - OMX_ERRORTYPE EmptyThisBuffer(BufferData* aData) override; - - OMX_ERRORTYPE FillThisBuffer(BufferData* aData) override; - - OMX_ERRORTYPE SendCommand(OMX_COMMANDTYPE aCmd, - OMX_U32 aParam1, - OMX_PTR aCmdData) override; - - nsresult Shutdown() override; - - static bool FindComponents(const nsACString& aMimeType, - nsTArray* aComponents = nullptr); - - // Android/QCOM decoder uses its own OMX_VIDEO_CodingVP8 definition in - // frameworks/native/media/include/openmax/OMX_Video.h, not the one defined - // in OpenMAX v1.1.2 OMX_VideoExt.h - OMX_VIDEO_CODINGTYPE CompressionFormat() override; - -protected: - friend GonkBufferData; - - layers::ImageContainer* GetImageContainer(); - - const TrackInfo* GetTrackInfo(); - - TaskQueue* GetTaskQueue() - { - return mTaskQueue; - } - - nsresult EnableOmxGraphicBufferPort(OMX_PARAM_PORTDEFINITIONTYPE& aDef); - - bool LoadComponent(const ComponentInfo& aComponent); - - friend class GonkOmxObserver; - - RefPtr mTaskQueue; - - RefPtr mImageContainer; - - // OMX_DirInput is 0, OMX_DirOutput is 1. - android::sp mMemoryDealer[2]; - - android::sp mOmxObserver; - - android::sp mOmx; - - android::IOMX::node_id mNode; - - android::OMXClient mOmxClient; - - Quirks mQuirks; -}; - -} - -#pragma GCC visibility pop - -#endif // GonkOmxPlatformLayer_h_ diff --git a/dom/media/platforms/omx/moz.build b/dom/media/platforms/omx/moz.build index 9f641d937..661e280e0 100644 --- a/dom/media/platforms/omx/moz.build +++ b/dom/media/platforms/omx/moz.build @@ -21,29 +21,6 @@ LOCAL_INCLUDES += [ include('/ipc/chromium/chromium-config.mozbuild') -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and (CONFIG['ANDROID_VERSION'] == '19' or CONFIG['ANDROID_VERSION'] == '20'): - # Suppress some GCC/clang warnings being treated as errors: - # - about attributes on forward declarations for types that are already - # defined, which complains about an important MOZ_EXPORT for android::AString - # - about multi-character constants which are used in codec-related code - if CONFIG['GNU_CC'] or CONFIG['CLANG_CL']: - CXXFLAGS += [ - '-Wno-error=attributes', - '-Wno-error=multichar' - ] - CXXFLAGS += [ - '-I%s/%s' % (CONFIG['ANDROID_SOURCE'], d) for d in [ - 'frameworks/base/include/binder', - 'frameworks/base/include/utils', - ] - ] - UNIFIED_SOURCES += [ - 'GonkOmxPlatformLayer.cpp', - ] - EXTRA_DSO_LDOPTS += [ - '-libbinder', - ] - FINAL_LIBRARY = 'xul' if CONFIG['GNU_CXX']: diff --git a/dom/media/standalone/moz.build b/dom/media/standalone/moz.build index 5d2c5a6e7..959703765 100644 --- a/dom/media/standalone/moz.build +++ b/dom/media/standalone/moz.build @@ -4,7 +4,7 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -if CONFIG['OS_TARGET'] != 'WINNT' and CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk': +if CONFIG['OS_TARGET'] != 'WINNT': Library('media_standalone') UNIFIED_SOURCES += [ diff --git a/dom/media/systemservices/moz.build b/dom/media/systemservices/moz.build index 33e5ed1f1..82a5c5e72 100644 --- a/dom/media/systemservices/moz.build +++ b/dom/media/systemservices/moz.build @@ -42,16 +42,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': UNIFIED_SOURCES += ['OSXRunLoopSingleton.cpp'] EXPORTS += ['OSXRunLoopSingleton.h'] -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': - if CONFIG['ANDROID_VERSION'] >= '17': - LOCAL_INCLUDES += [ - '%' + '%s/frameworks/wilhelm/include' % CONFIG['ANDROID_SOURCE'], - ] - else: - LOCAL_INCLUDES += [ - '%' + '%s/system/media/wilhelm/include' % CONFIG['ANDROID_SOURCE'], - ] - if CONFIG['_MSC_VER']: DEFINES['__PRETTY_FUNCTION__'] = '__FUNCSIG__' diff --git a/dom/moz.build b/dom/moz.build index 90ea60cbe..358fc6411 100644 --- a/dom/moz.build +++ b/dom/moz.build @@ -105,13 +105,6 @@ DIRS += [ if CONFIG['OS_ARCH'] == 'WINNT': DIRS += ['plugins/ipc/hangui'] -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': - DIRS += [ - 'speakermanager', - 'tethering', - 'wifi', - ] - if CONFIG['MOZ_SECUREELEMENT']: DIRS += ['secureelement'] diff --git a/dom/network/EthernetManager.js b/dom/network/EthernetManager.js deleted file mode 100644 index 4b11e5666..000000000 --- a/dom/network/EthernetManager.js +++ /dev/null @@ -1,655 +0,0 @@ -/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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, results: Cr} = Components; - -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -const TOPIC_INTERFACE_STATE_CHANGED = "network-interface-state-changed"; - -const ETHERNET_NETWORK_IFACE_PREFIX = "eth"; -const DEFAULT_ETHERNET_NETWORK_IFACE = "eth0"; - -const INTERFACE_IPADDR_NULL = "0.0.0.0"; -const INTERFACE_GATEWAY_NULL = "0.0.0.0"; -const INTERFACE_PREFIX_NULL = 0; -const INTERFACE_MACADDR_NULL = "00:00:00:00:00:00"; - -const NETWORK_INTERFACE_UP = "up"; -const NETWORK_INTERFACE_DOWN = "down"; - -const IP_MODE_DHCP = "dhcp"; -const IP_MODE_STATIC = "static"; - -const PREF_NETWORK_DEBUG_ENABLED = "network.debugging.enabled"; - -XPCOMUtils.defineLazyServiceGetter(this, "gNetworkManager", - "@mozilla.org/network/manager;1", - "nsINetworkManager"); - -XPCOMUtils.defineLazyServiceGetter(this, "gNetworkService", - "@mozilla.org/network/service;1", - "nsINetworkService"); - -let debug; -function updateDebug() { - let debugPref = false; // set default value here. - try { - debugPref = debugPref || Services.prefs.getBoolPref(PREF_NETWORK_DEBUG_ENABLED); - } catch (e) {} - - if (debugPref) { - debug = function(s) { - dump("-*- EthernetManager: " + s + "\n"); - }; - } else { - debug = function(s) {}; - } -} -updateDebug(); - -// nsINetworkInterface - -function EthernetInterface(attr) { - this.info.state = attr.state; - this.info.type = attr.type; - this.info.name = attr.name; - this.info.ipMode = attr.ipMode; - this.info.ips = [attr.ip]; - this.info.prefixLengths = [attr.prefixLength]; - this.info.gateways = [attr.gateway]; - this.info.dnses = attr.dnses; - this.httpProxyHost = ""; - this.httpProxyPort = 0; -} -EthernetInterface.prototype = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkInterface]), - - updateConfig: function(config) { - debug("Interface " + this.info.name + " updateConfig " + JSON.stringify(config)); - this.info.state = (config.state != undefined) ? - config.state : this.info.state; - this.info.ips = (config.ip != undefined) ? [config.ip] : this.info.ips; - this.info.prefixLengths = (config.prefixLength != undefined) ? - [config.prefixLength] : this.info.prefixLengths; - this.info.gateways = (config.gateway != undefined) ? - [config.gateway] : this.info.gateways; - this.info.dnses = (config.dnses != undefined) ? config.dnses : this.info.dnses; - this.httpProxyHost = (config.httpProxyHost != undefined) ? - config.httpProxyHost : this.httpProxyHost; - this.httpProxyPort = (config.httpProxyPort != undefined) ? - config.httpProxyPort : this.httpProxyPort; - this.info.ipMode = (config.ipMode != undefined) ? - config.ipMode : this.info.ipMode; - }, - - info: { - getAddresses: function(ips, prefixLengths) { - ips.value = this.ips.slice(); - prefixLengths.value = this.prefixLengths.slice(); - - return this.ips.length; - }, - - getGateways: function(count) { - if (count) { - count.value = this.gateways.length; - } - return this.gateways.slice(); - }, - - getDnses: function(count) { - if (count) { - count.value = this.dnses.length; - } - return this.dnses.slice(); - } - } -}; - -// nsIEthernetManager - -/* - * Network state transition diagram - * - * ---------- enable --------- connect ----------- disconnect -------------- - * | Disabled | -----> | Enabled | -------> | Connected | <----------> | Disconnected | - * ---------- --------- ----------- connect -------------- - * ^ | | | - * | disable | | | - * ----------------------------------------------------------------------- - */ - -function EthernetManager() { - debug("EthernetManager start"); - - // Interface list. - this.ethernetInterfaces = {}; - - // Used to memorize last connection information. - this.lastStaticConfig = {}; - - Services.obs.addObserver(this, "xpcom-shutdown", false); -} - -EthernetManager.prototype = { - classID: Components.ID("a96441dd-36b3-4f7f-963b-2c032e28a039"), - QueryInterface: XPCOMUtils.generateQI([Ci.nsIEthernetManager]), - - ethernetInterfaces: null, - lastStaticConfig: null, - - observer: function(subject, topic, data) { - switch (topic) { - case "xpcom-shutdown": - debug("xpcom-shutdown"); - - this._shutdown(); - - Services.obs.removeObserver(this, "xpcom-shutdown"); - break; - } - }, - - _shutdown: function() { - debug("Shuting down"); - (function onRemove(ifnameList) { - if (!ifnameList.length) { - return; - } - - let ifname = ifnameList.shift(); - this.removeInterface(ifname, { notify: onRemove.bind(this, ifnameList) }); - }).call(this, Object.keys(this.ethernetInterfaces)); - }, - - get interfaceList() { - return Object.keys(this.ethernetInterfaces); - }, - - scan: function(callback) { - debug("Scan"); - - gNetworkService.getInterfaces(function(success, list) { - let ethList = []; - - if (!success) { - if (callback) { - callback.notify(ethList); - } - return; - } - - for (let i = 0; i < list.length; i++) { - debug("Found interface " + list[i]); - if (!list[i].startsWith(ETHERNET_NETWORK_IFACE_PREFIX)) { - continue; - } - ethList.push(list[i]); - } - - if (callback) { - callback.notify(ethList); - } - }); - }, - - addInterface: function(ifname, callback) { - debug("Add interface " + ifname); - - if (!ifname || !ifname.startsWith(ETHERNET_NETWORK_IFACE_PREFIX)) { - if (callback) { - callback.notify(false, "Invalid interface."); - } - return; - } - - if (this.ethernetInterfaces[ifname]) { - if (callback) { - callback.notify(true, "Interface already exists."); - } - return; - } - - gNetworkService.getInterfaceConfig(ifname, function(success, result) { - if (!success) { - if (callback) { - callback.notify(false, "Netd error."); - } - return; - } - - // Since the operation may still succeed with an invalid interface name, - // check the mac address as well. - if (result.macAddr == INTERFACE_MACADDR_NULL) { - if (callback) { - callback.notify(false, "Interface not found."); - } - return; - } - - this.ethernetInterfaces[ifname] = new EthernetInterface({ - state: result.link == NETWORK_INTERFACE_UP ? - Ci.nsINetworkInfo.NETWORK_STATE_DISABLED : - Ci.nsINetworkInfo.NETWORK_STATE_ENABLED, - name: ifname, - type: Ci.nsINetworkInfo.NETWORK_TYPE_ETHERNET, - ip: result.ip, - prefixLength: result.prefix, - ipMode: IP_MODE_DHCP - }); - - // Register the interface to NetworkManager. - gNetworkManager.registerNetworkInterface(this.ethernetInterfaces[ifname]); - - debug("Add interface " + ifname + " succeeded with " + - JSON.stringify(this.ethernetInterfaces[ifname])); - - if (callback) { - callback.notify(true, "ok"); - } - }.bind(this)); - }, - - removeInterface: function(ifname, callback) { - debug("Remove interface " + ifname); - - if (!ifname || !ifname.startsWith(ETHERNET_NETWORK_IFACE_PREFIX)) { - if (callback) { - callback.notify(false, "Invalid interface."); - } - return; - } - - if (!this.ethernetInterfaces[ifname]) { - if (callback) { - callback.notify(true, "Interface does not exist."); - } - return; - } - - // Make sure interface is disable before removing. - this.disable(ifname, { notify: function(success, message) { - // Unregister the interface from NetworkManager and also remove it from - // the interface list. - gNetworkManager.unregisterNetworkInterface(this.ethernetInterfaces[ifname]); - delete this.ethernetInterfaces[ifname]; - - debug("Remove interface " + ifname + " succeeded."); - - if (callback) { - callback.notify(true, "ok"); - } - }.bind(this)}); - }, - - updateInterfaceConfig: function(ifname, config, callback) { - debug("Update interface config with " + ifname); - - this._ensureIfname(ifname, callback, function(iface) { - if (!config) { - if (callback) { - callback.notify(false, "No config to update."); - } - return; - } - - // Network state can not be modified externally. - if (config.state) { - delete config.state; - } - - let currentIpMode = iface.info.ipMode; - - // Update config. - this.ethernetInterfaces[iface.info.name].updateConfig(config); - - // Do not automatically re-connect if the interface is not in connected - // state. - if (iface.info.state != Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED) { - if (callback) { - callback.notify(true, "ok"); - } - return; - } - - let newIpMode = this.ethernetInterfaces[iface.info.name].info.ipMode; - - if (newIpMode == IP_MODE_STATIC) { - this._setStaticIP(iface.info.name, callback); - return; - } - if ((currentIpMode == IP_MODE_STATIC) && (newIpMode == IP_MODE_DHCP)) { - gNetworkService.stopDhcp(iface.info.name, function(success) { - if (success) { - debug("DHCP for " + iface.info.name + " stopped."); - } - }); - - // Clear the current network settings before do dhcp request, otherwise - // dhcp settings could fail. - this.disconnect(iface.info.name, { notify: function(success, message) { - if (!success) { - if (callback) { - callback.notify("Disconnect failed."); - } - return; - } - this._runDhcp(iface.info.name, callback); - }.bind(this) }); - return; - } - - if (callback) { - callback.notify(true, "ok"); - } - }.bind(this)); - }, - - enable: function(ifname, callback) { - debug("Enable interface " + ifname); - - this._ensureIfname(ifname, callback, function(iface) { - // Interface can be only enabled in the state of disabled. - if (iface.info.state != Ci.nsINetworkInfo.NETWORK_STATE_DISABLED) { - if (callback) { - callback.notify(true, "Interface already enabled."); - } - return; - } - - let ips = {}; - let prefixLengths = {}; - iface.info.getAddresses(ips, prefixLengths); - let config = { ifname: iface.info.name, - ip: ips.value[0], - prefix: prefixLengths.value[0], - link: NETWORK_INTERFACE_UP }; - gNetworkService.setInterfaceConfig(config, function(success) { - if (!success) { - if (callback) { - callback.notify(false, "Netd Error."); - } - return; - } - - this.ethernetInterfaces[iface.info.name].updateConfig({ - state: Ci.nsINetworkInfo.NETWORK_STATE_ENABLED - }); - - debug("Enable interface " + iface.info.name + " succeeded."); - - if (callback) { - callback.notify(true, "ok"); - } - }.bind(this)); - }.bind(this)); - }, - - disable: function(ifname, callback) { - debug("Disable interface " + ifname); - - this._ensureIfname(ifname, callback, function(iface) { - if (iface.info.state == Ci.nsINetworkInfo.NETWORK_STATE_DISABLED) { - if (callback) { - callback.notify(true, "Interface already disabled."); - } - return; - } - - if (iface.info.state == Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED) { - gNetworkService.stopDhcp(iface.info.name, function(success) { - if (success) { - debug("DHCP for " + iface.info.name + " stopped."); - } - }); - } - - let ips = {}; - let prefixLengths = {}; - iface.info.getAddresses(ips, prefixLengths); - let config = { ifname: iface.info.name, - ip: ips.value[0], - prefix: prefixLengths.value[0], - link: NETWORK_INTERFACE_DOWN }; - gNetworkService.setInterfaceConfig(config, function(success) { - if (!success) { - if (callback) { - callback.notify(false, "Netd Error."); - } - return; - } - - this.ethernetInterfaces[iface.info.name].updateConfig({ - state: Ci.nsINetworkInfo.NETWORK_STATE_DISABLED - }); - - debug("Disable interface " + iface.info.name + " succeeded."); - - if (callback) { - callback.notify(true, "ok"); - } - }.bind(this)); - }.bind(this)); - }, - - connect: function(ifname, callback) { - debug("Connect interface " + ifname); - - this._ensureIfname(ifname, callback, function(iface) { - // Interface can only be connected in the state of enabled or - // disconnected. - if (iface.info.state == Ci.nsINetworkInfo.NETWORK_STATE_DISABLED || - iface.info.state == Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED) { - if (callback) { - callback.notify(true, "Interface " + ifname + " is not available or " - + " already connected."); - } - return; - } - - if (iface.info.ipMode == IP_MODE_DHCP) { - this._runDhcp(iface.info.name, callback); - return; - } - - if (iface.info.ipMode == IP_MODE_STATIC) { - if (this._checkConfigNull(iface) && this.lastStaticConfig[iface.info.name]) { - debug("Connect with lastStaticConfig " + - JSON.stringify(this.lastStaticConfig[iface.info.name])); - this.ethernetInterfaces[iface.info.name].updateConfig( - this.lastStaticConfig[iface.info.name]); - } - this._setStaticIP(iface.info.name, callback); - return; - } - - if (callback) { - callback.notify(false, "IP mode is wrong or not set."); - } - }.bind(this)); - }, - - disconnect: function(ifname, callback) { - debug("Disconnect interface " + ifname); - - this._ensureIfname(ifname, callback, function(iface) { - // Interface can be only disconnected in the state of connected. - if (iface.info.state != Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED) { - if (callback) { - callback.notify(true, "Interface is already disconnected"); - } - return; - } - - let config = { ifname: iface.info.name, - ip: INTERFACE_IPADDR_NULL, - prefix: INTERFACE_PREFIX_NULL, - link: NETWORK_INTERFACE_UP }; - gNetworkService.setInterfaceConfig(config, function(success) { - if (!success) { - if (callback) { - callback.notify(false, "Netd error."); - } - return; - } - - // Stop dhcp daemon. - gNetworkService.stopDhcp(iface.info.name, function(success) { - if (success) { - debug("DHCP for " + iface.info.name + " stopped."); - } - }); - - this.ethernetInterfaces[iface.info.name].updateConfig({ - state: Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED, - ip: INTERFACE_IPADDR_NULL, - prefixLength: INTERFACE_PREFIX_NULL, - gateway: INTERFACE_GATEWAY_NULL - }); - - gNetworkManager.updateNetworkInterface(this.ethernetInterfaces[ifname]); - - debug("Disconnect interface " + iface.info.name + " succeeded."); - - if (callback) { - callback.notify(true, "ok"); - } - }.bind(this)); - }.bind(this)); - }, - - _checkConfigNull: function(iface) { - let ips = {}; - let prefixLengths = {}; - let gateways = iface.info.getGateways(); - iface.info.getAddresses(ips, prefixLengths); - - if (ips.value[0] == INTERFACE_IPADDR_NULL && - prefixLengths.value[0] == INTERFACE_PREFIX_NULL && - gateways[0] == INTERFACE_GATEWAY_NULL) { - return true; - } - - return false; - }, - - _ensureIfname: function(ifname, callback, func) { - // If no given ifname, use the default one. - if (!ifname) { - ifname = DEFAULT_ETHERNET_NETWORK_IFACE; - } - - let iface = this.ethernetInterfaces[ifname]; - if (!iface) { - if (callback) { - callback.notify(true, "Interface " + ifname + " is not available."); - } - return; - } - - func.call(this, iface); - }, - - _runDhcp: function(ifname, callback) { - debug("runDhcp with " + ifname); - - if (!this.ethernetInterfaces[ifname]) { - if (callback) { - callback.notify(false, "Invalid interface."); - } - return; - } - - gNetworkService.dhcpRequest(ifname, function(success, result) { - if (!success) { - if (callback) { - callback.notify(false, "DHCP failed."); - } - return; - } - - debug("DHCP succeeded with " + JSON.stringify(result)); - - // Clear last static network information when connecting with dhcp mode. - if (this.lastStaticConfig[ifname]) { - this.lastStaticConfig[ifname] = null; - } - - this.ethernetInterfaces[ifname].updateConfig({ - state: Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED, - ip: result.ipaddr_str, - gateway: result.gateway_str, - prefixLength: result.prefixLength, - dnses: [result.dns1_str, result.dns2_str] - }); - - gNetworkManager.updateNetworkInterface(this.ethernetInterfaces[ifname]); - - debug("Connect interface " + ifname + " with DHCP succeeded."); - - if (callback) { - callback.notify(true, "ok"); - } - }.bind(this)); - }, - - _setStaticIP: function(ifname, callback) { - let iface = this.ethernetInterfaces[ifname]; - if (!iface) { - if (callback) { - callback.notify(false, "Invalid interface."); - } - return; - } - - let ips = {}; - let prefixLengths = {}; - iface.info.getAddresses(ips, prefixLengths); - - let config = { ifname: iface.info.name, - ip: ips.value[0], - prefix: prefixLengths.value[0], - link: NETWORK_INTERFACE_UP }; - gNetworkService.setInterfaceConfig(config, function(success) { - if (!success) { - if (callback) { - callback.notify(false, "Netd Error."); - } - return; - } - - // Keep the lastest static network information. - let ips = {}; - let prefixLengths = {}; - let gateways = iface.info.getGateways(); - iface.info.getAddresses(ips, prefixLengths); - - this.lastStaticConfig[iface.info.name] = { - ip: ips.value[0], - prefixLength: prefixLengths.value[0], - gateway: gateways[0] - }; - - this.ethernetInterfaces[ifname].updateConfig({ - state: Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED, - }); - - gNetworkManager.updateNetworkInterface(this.ethernetInterfaces[ifname]); - - debug("Connect interface " + ifname + " with static ip succeeded."); - - if (callback) { - callback.notify(true, "ok"); - } - }.bind(this)); - }, -} - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([EthernetManager]); diff --git a/dom/network/EthernetManager.manifest b/dom/network/EthernetManager.manifest deleted file mode 100644 index d25a069e1..000000000 --- a/dom/network/EthernetManager.manifest +++ /dev/null @@ -1,2 +0,0 @@ -component {a96441dd-36b3-4f7f-963b-2c032e28a039} EthernetManager.js -contract @mozilla.org/ethernetManager;1 {a96441dd-36b3-4f7f-963b-2c032e28a039} diff --git a/dom/network/NetUtils.cpp b/dom/network/NetUtils.cpp deleted file mode 100644 index 78c5be802..000000000 --- a/dom/network/NetUtils.cpp +++ /dev/null @@ -1,200 +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 "NetUtils.h" -#include -#include -#include "prinit.h" -#include "mozilla/Assertions.h" -#include "nsDebug.h" -#include "SystemProperty.h" - -using mozilla::system::Property; - -static void* sNetUtilsLib; -static PRCallOnceType sInitNetUtilsLib; - -static PRStatus -InitNetUtilsLib() -{ - sNetUtilsLib = dlopen("/system/lib/libnetutils.so", RTLD_LAZY); - // We might fail to open the hardware lib. That's OK. - return PR_SUCCESS; -} - -static void* -GetNetUtilsLibHandle() -{ - PR_CallOnce(&sInitNetUtilsLib, InitNetUtilsLib); - return sNetUtilsLib; -} - -// static -void* -NetUtils::GetSharedLibrary() -{ - void* netLib = GetNetUtilsLibHandle(); - if (!netLib) { - NS_WARNING("No /system/lib/libnetutils.so"); - } - return netLib; -} - -// static -int32_t -NetUtils::SdkVersion() -{ - char propVersion[Property::VALUE_MAX_LENGTH]; - Property::Get("ro.build.version.sdk", propVersion, "0"); - int32_t version = strtol(propVersion, nullptr, 10); - return version; -} - -DEFINE_DLFUNC(ifc_enable, int32_t, const char*) -DEFINE_DLFUNC(ifc_disable, int32_t, const char*) -DEFINE_DLFUNC(ifc_configure, int32_t, const char*, in_addr_t, uint32_t, - in_addr_t, in_addr_t, in_addr_t) -DEFINE_DLFUNC(ifc_reset_connections, int32_t, const char*, const int32_t) -DEFINE_DLFUNC(ifc_set_default_route, int32_t, const char*, in_addr_t) -DEFINE_DLFUNC(ifc_add_route, int32_t, const char*, const char*, uint32_t, const char*) -DEFINE_DLFUNC(ifc_remove_route, int32_t, const char*, const char*, uint32_t, const char*) -DEFINE_DLFUNC(ifc_remove_host_routes, int32_t, const char*) -DEFINE_DLFUNC(ifc_remove_default_route, int32_t, const char*) -DEFINE_DLFUNC(dhcp_stop, int32_t, const char*) - -NetUtils::NetUtils() -{ -} - -int32_t NetUtils::do_ifc_enable(const char *ifname) -{ - USE_DLFUNC(ifc_enable) - return ifc_enable(ifname); -} - -int32_t NetUtils::do_ifc_disable(const char *ifname) -{ - USE_DLFUNC(ifc_disable) - return ifc_disable(ifname); -} - -int32_t NetUtils::do_ifc_configure(const char *ifname, - in_addr_t address, - uint32_t prefixLength, - in_addr_t gateway, - in_addr_t dns1, - in_addr_t dns2) -{ - USE_DLFUNC(ifc_configure) - int32_t ret = ifc_configure(ifname, address, prefixLength, gateway, dns1, dns2); - return ret; -} - -int32_t NetUtils::do_ifc_reset_connections(const char *ifname, - const int32_t resetMask) -{ - USE_DLFUNC(ifc_reset_connections) - return ifc_reset_connections(ifname, resetMask); -} - -int32_t NetUtils::do_ifc_set_default_route(const char *ifname, - in_addr_t gateway) -{ - USE_DLFUNC(ifc_set_default_route) - return ifc_set_default_route(ifname, gateway); -} - -int32_t NetUtils::do_ifc_add_route(const char *ifname, - const char *dst, - uint32_t prefixLength, - const char *gateway) -{ - USE_DLFUNC(ifc_add_route) - return ifc_add_route(ifname, dst, prefixLength, gateway); -} - -int32_t NetUtils::do_ifc_remove_route(const char *ifname, - const char *dst, - uint32_t prefixLength, - const char *gateway) -{ - USE_DLFUNC(ifc_remove_route) - return ifc_remove_route(ifname, dst, prefixLength, gateway); -} - -int32_t NetUtils::do_ifc_remove_host_routes(const char *ifname) -{ - USE_DLFUNC(ifc_remove_host_routes) - return ifc_remove_host_routes(ifname); -} - -int32_t NetUtils::do_ifc_remove_default_route(const char *ifname) -{ - USE_DLFUNC(ifc_remove_default_route) - return ifc_remove_default_route(ifname); -} - -int32_t NetUtils::do_dhcp_stop(const char *ifname) -{ - USE_DLFUNC(dhcp_stop) - return dhcp_stop(ifname); -} - -int32_t NetUtils::do_dhcp_do_request(const char *ifname, - char *ipaddr, - char *gateway, - uint32_t *prefixLength, - char *dns1, - char *dns2, - char *server, - uint32_t *lease, - char* vendorinfo) -{ - int32_t ret = -1; - uint32_t sdkVersion = SdkVersion(); - - if (sdkVersion == 15) { - // ICS - // http://androidxref.com/4.0.4/xref/system/core/libnetutils/dhcp_utils.c#149 - DEFINE_DLFUNC(dhcp_do_request, int32_t, const char*, char*, char*, uint32_t*, char*, char*, char*, uint32_t*) - USE_DLFUNC(dhcp_do_request) - vendorinfo[0] = '\0'; - - ret = dhcp_do_request(ifname, ipaddr, gateway, prefixLength, dns1, dns2, - server, lease); - } else if (sdkVersion == 16 || sdkVersion == 17) { - // JB 4.1 and 4.2 - // http://androidxref.com/4.1.2/xref/system/core/libnetutils/dhcp_utils.c#175 - // http://androidxref.com/4.2.2_r1/xref/system/core/include/netutils/dhcp.h#26 - DEFINE_DLFUNC(dhcp_do_request, int32_t, const char*, char*, char*, uint32_t*, char*, char*, char*, uint32_t*, char*) - USE_DLFUNC(dhcp_do_request) - ret = dhcp_do_request(ifname, ipaddr, gateway, prefixLength, dns1, dns2, - server, lease, vendorinfo); - } else if (sdkVersion == 18) { - // JB 4.3 - // http://androidxref.com/4.3_r2.1/xref/system/core/libnetutils/dhcp_utils.c#181 - DEFINE_DLFUNC(dhcp_do_request, int32_t, const char*, char*, char*, uint32_t*, char**, char*, uint32_t*, char*, char*) - USE_DLFUNC(dhcp_do_request) - char *dns[3] = {dns1, dns2, nullptr}; - char domains[Property::VALUE_MAX_LENGTH]; - ret = dhcp_do_request(ifname, ipaddr, gateway, prefixLength, dns, - server, lease, vendorinfo, domains); - } else if (sdkVersion >= 19) { - // KitKat 4.4.X - // http://androidxref.com/4.4_r1/xref/system/core/libnetutils/dhcp_utils.c#18 - // Lollipop 5.0 - //http://androidxref.com/5.0.0_r2/xref/system/core/libnetutils/dhcp_utils.c#186 - DEFINE_DLFUNC(dhcp_do_request, int32_t, const char*, char*, char*, uint32_t*, char**, char*, uint32_t*, char*, char*, char*) - USE_DLFUNC(dhcp_do_request) - char *dns[3] = {dns1, dns2, nullptr}; - char domains[Property::VALUE_MAX_LENGTH]; - char mtu[Property::VALUE_MAX_LENGTH]; - ret = dhcp_do_request(ifname, ipaddr, gateway, prefixLength, dns, server, lease, vendorinfo, domains, mtu); - } else { - NS_WARNING("Unable to perform do_dhcp_request: unsupported sdk version!"); - } - return ret; -} diff --git a/dom/network/NetUtils.h b/dom/network/NetUtils.h deleted file mode 100644 index 4af365406..000000000 --- a/dom/network/NetUtils.h +++ /dev/null @@ -1,75 +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/. */ - -/** - * Abstraction on top of the network support from libnetutils that we - * use to set up network connections. - */ - -#ifndef NetUtils_h -#define NetUtils_h - -#include "arpa/inet.h" - -// Copied from ifc.h -#define RESET_IPV4_ADDRESSES 0x01 -#define RESET_IPV6_ADDRESSES 0x02 -#define RESET_ALL_ADDRESSES (RESET_IPV4_ADDRESSES | RESET_IPV6_ADDRESSES) - -// Implements netutils functions. No need for an abstract class here since we -// only have a one sdk specific method (dhcp_do_request) -class NetUtils -{ -public: - static void* GetSharedLibrary(); - - NetUtils(); - - int32_t do_ifc_enable(const char *ifname); - int32_t do_ifc_disable(const char *ifname); - int32_t do_ifc_configure(const char *ifname, - in_addr_t address, - uint32_t prefixLength, - in_addr_t gateway, - in_addr_t dns1, - in_addr_t dns2); - int32_t do_ifc_reset_connections(const char *ifname, const int32_t resetMask); - int32_t do_ifc_set_default_route(const char *ifname, in_addr_t gateway); - int32_t do_ifc_add_route(const char *ifname, - const char *dst, - uint32_t prefixLength, - const char *gateway); - int32_t do_ifc_remove_route(const char *ifname, - const char *dst, - uint32_t prefixLength, - const char *gateway); - int32_t do_ifc_remove_host_routes(const char *ifname); - int32_t do_ifc_remove_default_route(const char *ifname); - int32_t do_dhcp_stop(const char *ifname); - int32_t do_dhcp_do_request(const char *ifname, - char *ipaddr, - char *gateway, - uint32_t *prefixLength, - char *dns1, - char *dns2, - char *server, - uint32_t *lease, - char* vendorinfo); - - static int32_t SdkVersion(); -}; - -// Defines a function type with the right arguments and return type. -#define DEFINE_DLFUNC(name, ret, args...) typedef ret (*FUNC##name)(args); - -// Set up a dlsymed function ready to use. -#define USE_DLFUNC(name) \ - FUNC##name name = (FUNC##name) dlsym(GetSharedLibrary(), #name); \ - if (!name) { \ - MOZ_CRASH("Symbol not found in shared library : " #name); \ - } - -#endif // NetUtils_h diff --git a/dom/network/NetworkStatsDB.jsm b/dom/network/NetworkStatsDB.jsm deleted file mode 100644 index aa74d40ad..000000000 --- a/dom/network/NetworkStatsDB.jsm +++ /dev/null @@ -1,1285 +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"; - -this.EXPORTED_SYMBOLS = ['NetworkStatsDB']; - -const DEBUG = false; -function debug(s) { dump("-*- NetworkStatsDB: " + s + "\n"); } - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/IndexedDBHelper.jsm"); -Cu.importGlobalProperties(["indexedDB"]); - -XPCOMUtils.defineLazyServiceGetter(this, "appsService", - "@mozilla.org/AppsService;1", - "nsIAppsService"); - -const DB_NAME = "net_stats"; -const DB_VERSION = 9; -const DEPRECATED_STATS_STORE_NAME = - [ - "net_stats_v2", // existed only in DB version 2 - "net_stats", // existed in DB version 1 and 3 to 5 - "net_stats_store", // existed in DB version 6 to 8 - ]; -const STATS_STORE_NAME = "net_stats_store_v3"; // since DB version 9 -const ALARMS_STORE_NAME = "net_alarm"; - -// Constant defining the maximum values allowed per interface. If more, older -// will be erased. -const VALUES_MAX_LENGTH = 6 * 30; - -// Constant defining the rate of the samples. Daily. -const SAMPLE_RATE = 1000 * 60 * 60 * 24; - -this.NetworkStatsDB = function NetworkStatsDB() { - if (DEBUG) { - debug("Constructor"); - } - this.initDBHelper(DB_NAME, DB_VERSION, [STATS_STORE_NAME, ALARMS_STORE_NAME]); -} - -NetworkStatsDB.prototype = { - __proto__: IndexedDBHelper.prototype, - - dbNewTxn: function dbNewTxn(store_name, txn_type, callback, txnCb) { - function successCb(result) { - txnCb(null, result); - } - function errorCb(error) { - txnCb(error, null); - } - return this.newTxn(txn_type, store_name, callback, successCb, errorCb); - }, - - /** - * The onupgradeneeded handler of the IDBOpenDBRequest. - * This function is called in IndexedDBHelper open() method. - * - * @param {IDBTransaction} aTransaction - * {IDBDatabase} aDb - * {64-bit integer} aOldVersion The version number on local storage. - * {64-bit integer} aNewVersion The version number to be upgraded to. - * - * @note Be careful with the database upgrade pattern. - * Because IndexedDB operations are performed asynchronously, we must - * apply a recursive approach instead of an iterative approach while - * upgrading versions. - */ - upgradeSchema: function upgradeSchema(aTransaction, aDb, aOldVersion, aNewVersion) { - if (DEBUG) { - debug("upgrade schema from: " + aOldVersion + " to " + aNewVersion + " called!"); - } - let db = aDb; - let objectStore; - - // An array of upgrade functions for each version. - let upgradeSteps = [ - function upgrade0to1() { - if (DEBUG) debug("Upgrade 0 to 1: Create object stores and indexes."); - - // Create the initial database schema. - objectStore = db.createObjectStore(DEPRECATED_STATS_STORE_NAME[1], - { keyPath: ["connectionType", "timestamp"] }); - objectStore.createIndex("connectionType", "connectionType", { unique: false }); - objectStore.createIndex("timestamp", "timestamp", { unique: false }); - objectStore.createIndex("rxBytes", "rxBytes", { unique: false }); - objectStore.createIndex("txBytes", "txBytes", { unique: false }); - objectStore.createIndex("rxTotalBytes", "rxTotalBytes", { unique: false }); - objectStore.createIndex("txTotalBytes", "txTotalBytes", { unique: false }); - - upgradeNextVersion(); - }, - - function upgrade1to2() { - if (DEBUG) debug("Upgrade 1 to 2: Do nothing."); - upgradeNextVersion(); - }, - - function upgrade2to3() { - if (DEBUG) debug("Upgrade 2 to 3: Add keyPath appId to object store."); - - // In order to support per-app traffic data storage, the original - // objectStore needs to be replaced by a new objectStore with new - // key path ("appId") and new index ("appId"). - // Also, since now networks are identified by their - // [networkId, networkType] not just by their connectionType, - // to modify the keyPath is mandatory to delete the object store - // and create it again. Old data is going to be deleted because the - // networkId for each sample can not be set. - - // In version 1.2 objectStore name was 'net_stats_v2', to avoid errors when - // upgrading from 1.2 to 1.3 objectStore name should be checked. - let stores = db.objectStoreNames; - let deprecatedName = DEPRECATED_STATS_STORE_NAME[0]; - let storeName = DEPRECATED_STATS_STORE_NAME[1]; - if(stores.contains(deprecatedName)) { - // Delete the obsolete stats store. - db.deleteObjectStore(deprecatedName); - } else { - // Re-create stats object store without copying records. - db.deleteObjectStore(storeName); - } - - objectStore = db.createObjectStore(storeName, { keyPath: ["appId", "network", "timestamp"] }); - objectStore.createIndex("appId", "appId", { unique: false }); - objectStore.createIndex("network", "network", { unique: false }); - objectStore.createIndex("networkType", "networkType", { unique: false }); - objectStore.createIndex("timestamp", "timestamp", { unique: false }); - objectStore.createIndex("rxBytes", "rxBytes", { unique: false }); - objectStore.createIndex("txBytes", "txBytes", { unique: false }); - objectStore.createIndex("rxTotalBytes", "rxTotalBytes", { unique: false }); - objectStore.createIndex("txTotalBytes", "txTotalBytes", { unique: false }); - - upgradeNextVersion(); - }, - - function upgrade3to4() { - if (DEBUG) debug("Upgrade 3 to 4: Delete redundant indexes."); - - // Delete redundant indexes (leave "network" only). - objectStore = aTransaction.objectStore(DEPRECATED_STATS_STORE_NAME[1]); - if (objectStore.indexNames.contains("appId")) { - objectStore.deleteIndex("appId"); - } - if (objectStore.indexNames.contains("networkType")) { - objectStore.deleteIndex("networkType"); - } - if (objectStore.indexNames.contains("timestamp")) { - objectStore.deleteIndex("timestamp"); - } - if (objectStore.indexNames.contains("rxBytes")) { - objectStore.deleteIndex("rxBytes"); - } - if (objectStore.indexNames.contains("txBytes")) { - objectStore.deleteIndex("txBytes"); - } - if (objectStore.indexNames.contains("rxTotalBytes")) { - objectStore.deleteIndex("rxTotalBytes"); - } - if (objectStore.indexNames.contains("txTotalBytes")) { - objectStore.deleteIndex("txTotalBytes"); - } - - upgradeNextVersion(); - }, - - function upgrade4to5() { - if (DEBUG) debug("Upgrade 4 to 5: Create object store for alarms."); - - // In order to manage alarms, it is necessary to use a global counter - // (totalBytes) that will increase regardless of the system reboot. - objectStore = aTransaction.objectStore(DEPRECATED_STATS_STORE_NAME[1]); - - // Now, systemBytes will hold the old totalBytes and totalBytes will - // keep the increasing counter. |counters| will keep the track of - // accumulated values. - let counters = {}; - - objectStore.openCursor().onsuccess = function(event) { - let cursor = event.target.result; - if (!cursor){ - // upgrade4to5 completed now. - upgradeNextVersion(); - return; - } - - cursor.value.rxSystemBytes = cursor.value.rxTotalBytes; - cursor.value.txSystemBytes = cursor.value.txTotalBytes; - - if (cursor.value.appId == 0) { - let netId = cursor.value.network[0] + '' + cursor.value.network[1]; - if (!counters[netId]) { - counters[netId] = { - rxCounter: 0, - txCounter: 0, - lastRx: 0, - lastTx: 0 - }; - } - - let rxDiff = cursor.value.rxSystemBytes - counters[netId].lastRx; - let txDiff = cursor.value.txSystemBytes - counters[netId].lastTx; - if (rxDiff < 0 || txDiff < 0) { - // System reboot between samples, so take the current one. - rxDiff = cursor.value.rxSystemBytes; - txDiff = cursor.value.txSystemBytes; - } - - counters[netId].rxCounter += rxDiff; - counters[netId].txCounter += txDiff; - cursor.value.rxTotalBytes = counters[netId].rxCounter; - cursor.value.txTotalBytes = counters[netId].txCounter; - - counters[netId].lastRx = cursor.value.rxSystemBytes; - counters[netId].lastTx = cursor.value.txSystemBytes; - } else { - cursor.value.rxTotalBytes = cursor.value.rxSystemBytes; - cursor.value.txTotalBytes = cursor.value.txSystemBytes; - } - - cursor.update(cursor.value); - cursor.continue(); - }; - - // Create object store for alarms. - objectStore = db.createObjectStore(ALARMS_STORE_NAME, { keyPath: "id", autoIncrement: true }); - objectStore.createIndex("alarm", ['networkId','threshold'], { unique: false }); - objectStore.createIndex("manifestURL", "manifestURL", { unique: false }); - }, - - function upgrade5to6() { - if (DEBUG) debug("Upgrade 5 to 6: Add keyPath serviceType to object store."); - - // In contrast to "per-app" traffic data, "system-only" traffic data - // refers to data which can not be identified by any applications. - // To further support "system-only" data storage, the data can be - // saved by service type (e.g., Tethering, OTA). Thus it's needed to - // have a new key ("serviceType") for the ojectStore. - let newObjectStore; - let deprecatedName = DEPRECATED_STATS_STORE_NAME[1]; - newObjectStore = db.createObjectStore(DEPRECATED_STATS_STORE_NAME[2], - { keyPath: ["appId", "serviceType", "network", "timestamp"] }); - newObjectStore.createIndex("network", "network", { unique: false }); - - // Copy the data from the original objectStore to the new objectStore. - objectStore = aTransaction.objectStore(deprecatedName); - objectStore.openCursor().onsuccess = function(event) { - let cursor = event.target.result; - if (!cursor) { - db.deleteObjectStore(deprecatedName); - // upgrade5to6 completed now. - upgradeNextVersion(); - return; - } - - let newStats = cursor.value; - newStats.serviceType = ""; - newObjectStore.put(newStats); - cursor.continue(); - }; - }, - - function upgrade6to7() { - if (DEBUG) debug("Upgrade 6 to 7: Replace alarm threshold by relativeThreshold."); - - // Replace threshold attribute of alarm index by relativeThreshold in alarms DB. - // Now alarms are indexed by relativeThreshold, which is the threshold relative - // to current system stats. - let alarmsStore = aTransaction.objectStore(ALARMS_STORE_NAME); - - // Delete "alarm" index. - if (alarmsStore.indexNames.contains("alarm")) { - alarmsStore.deleteIndex("alarm"); - } - - // Create new "alarm" index. - alarmsStore.createIndex("alarm", ['networkId','relativeThreshold'], { unique: false }); - - // Populate new "alarm" index attributes. - alarmsStore.openCursor().onsuccess = function(event) { - let cursor = event.target.result; - if (!cursor) { - upgrade6to7_updateTotalBytes(); - return; - } - - cursor.value.relativeThreshold = cursor.value.threshold; - cursor.value.absoluteThreshold = cursor.value.threshold; - delete cursor.value.threshold; - - cursor.update(cursor.value); - cursor.continue(); - } - - function upgrade6to7_updateTotalBytes() { - if (DEBUG) debug("Upgrade 6 to 7: Update TotalBytes."); - // Previous versions save accumulative totalBytes, increasing although the system - // reboots or resets stats. But is necessary to reset the total counters when reset - // through 'clearInterfaceStats'. - let statsStore = aTransaction.objectStore(DEPRECATED_STATS_STORE_NAME[2]); - let networks = []; - - // Find networks stored in the database. - statsStore.index("network").openKeyCursor(null, "nextunique").onsuccess = function(event) { - let cursor = event.target.result; - - // Store each network into an array. - if (cursor) { - networks.push(cursor.key); - cursor.continue(); - return; - } - - // Start to deal with each network. - let pending = networks.length; - - if (pending === 0) { - // Found no records of network. upgrade6to7 completed now. - upgradeNextVersion(); - return; - } - - networks.forEach(function(network) { - let lowerFilter = [0, "", network, 0]; - let upperFilter = [0, "", network, ""]; - let range = IDBKeyRange.bound(lowerFilter, upperFilter, false, false); - - // Find number of samples for a given network. - statsStore.count(range).onsuccess = function(event) { - let recordCount = event.target.result; - - // If there are more samples than the max allowed, there is no way to know - // when does reset take place. - if (recordCount === 0 || recordCount >= VALUES_MAX_LENGTH) { - pending--; - if (pending === 0) { - upgradeNextVersion(); - } - return; - } - - let last = null; - // Reset detected if the first sample totalCounters are different than bytes - // counters. If so, the total counters should be recalculated. - statsStore.openCursor(range).onsuccess = function(event) { - let cursor = event.target.result; - if (!cursor) { - pending--; - if (pending === 0) { - upgradeNextVersion(); - } - return; - } - if (!last) { - if (cursor.value.rxTotalBytes == cursor.value.rxBytes && - cursor.value.txTotalBytes == cursor.value.txBytes) { - pending--; - if (pending === 0) { - upgradeNextVersion(); - } - return; - } - - cursor.value.rxTotalBytes = cursor.value.rxBytes; - cursor.value.txTotalBytes = cursor.value.txBytes; - cursor.update(cursor.value); - last = cursor.value; - cursor.continue(); - return; - } - - // Recalculate the total counter for last / current sample - cursor.value.rxTotalBytes = last.rxTotalBytes + cursor.value.rxBytes; - cursor.value.txTotalBytes = last.txTotalBytes + cursor.value.txBytes; - cursor.update(cursor.value); - last = cursor.value; - cursor.continue(); - } - } - }, this); // end of networks.forEach() - }; // end of statsStore.index("network").openKeyCursor().onsuccess callback - } // end of function upgrade6to7_updateTotalBytes - }, - - function upgrade7to8() { - if (DEBUG) debug("Upgrade 7 to 8: Create index serviceType."); - - // Create index for 'ServiceType' in order to make it retrievable. - let statsStore = aTransaction.objectStore(DEPRECATED_STATS_STORE_NAME[2]); - statsStore.createIndex("serviceType", "serviceType", { unique: false }); - - upgradeNextVersion(); - }, - - function upgrade8to9() { - if (DEBUG) debug("Upgrade 8 to 9: Add keyPath isInBrowser to " + - "network stats object store"); - - // Since B2G v2.0, there is no stand-alone browser app anymore. - // The browser app is a mozbrowser iframe element owned by system app. - // In order to separate traffic generated from system and browser, we - // have to add a new attribute |isInBrowser| as keyPath. - // Refer to bug 1070944 for more detail. - let newObjectStore; - let deprecatedName = DEPRECATED_STATS_STORE_NAME[2]; - newObjectStore = db.createObjectStore(STATS_STORE_NAME, - { keyPath: ["appId", "isInBrowser", "serviceType", - "network", "timestamp"] }); - newObjectStore.createIndex("network", "network", { unique: false }); - newObjectStore.createIndex("serviceType", "serviceType", { unique: false }); - - // Copy records from the current object store to the new one. - objectStore = aTransaction.objectStore(deprecatedName); - objectStore.openCursor().onsuccess = function (event) { - let cursor = event.target.result; - if (!cursor) { - db.deleteObjectStore(deprecatedName); - // upgrade8to9 completed now. - return; - } - let newStats = cursor.value; - // Augment records by adding the new isInBrowser attribute. - // Notes: - // 1. Key value cannot be boolean type. Use 1/0 instead of true/false. - // 2. Most traffic of system app should come from its browser iframe, - // thus assign isInBrowser as 1 for system app. - let manifestURL = appsService.getManifestURLByLocalId(newStats.appId); - if (manifestURL && manifestURL.search(/app:\/\/system\./) === 0) { - newStats.isInBrowser = 1; - } else { - newStats.isInBrowser = 0; - } - newObjectStore.put(newStats); - cursor.continue(); - }; - } - ]; - - let index = aOldVersion; - let outer = this; - - function upgradeNextVersion() { - if (index == aNewVersion) { - debug("Upgrade finished."); - return; - } - - try { - var i = index++; - if (DEBUG) debug("Upgrade step: " + i + "\n"); - upgradeSteps[i].call(outer); - } catch (ex) { - dump("Caught exception " + ex); - throw ex; - return; - } - } - - if (aNewVersion > upgradeSteps.length) { - debug("No migration steps for the new version!"); - aTransaction.abort(); - return; - } - - upgradeNextVersion(); - }, - - importData: function importData(aStats) { - let stats = { appId: aStats.appId, - isInBrowser: aStats.isInBrowser ? 1 : 0, - serviceType: aStats.serviceType, - network: [aStats.networkId, aStats.networkType], - timestamp: aStats.timestamp, - rxBytes: aStats.rxBytes, - txBytes: aStats.txBytes, - rxSystemBytes: aStats.rxSystemBytes, - txSystemBytes: aStats.txSystemBytes, - rxTotalBytes: aStats.rxTotalBytes, - txTotalBytes: aStats.txTotalBytes }; - - return stats; - }, - - exportData: function exportData(aStats) { - let stats = { appId: aStats.appId, - isInBrowser: aStats.isInBrowser ? true : false, - serviceType: aStats.serviceType, - networkId: aStats.network[0], - networkType: aStats.network[1], - timestamp: aStats.timestamp, - rxBytes: aStats.rxBytes, - txBytes: aStats.txBytes, - rxTotalBytes: aStats.rxTotalBytes, - txTotalBytes: aStats.txTotalBytes }; - - return stats; - }, - - normalizeDate: function normalizeDate(aDate) { - // Convert to UTC according to timezone and - // filter timestamp to get SAMPLE_RATE precission - let timestamp = aDate.getTime() - aDate.getTimezoneOffset() * 60 * 1000; - timestamp = Math.floor(timestamp / SAMPLE_RATE) * SAMPLE_RATE; - return timestamp; - }, - - saveStats: function saveStats(aStats, aResultCb) { - let isAccumulative = aStats.isAccumulative; - let timestamp = this.normalizeDate(aStats.date); - - let stats = { appId: aStats.appId, - isInBrowser: aStats.isInBrowser, - serviceType: aStats.serviceType, - networkId: aStats.networkId, - networkType: aStats.networkType, - timestamp: timestamp, - rxBytes: isAccumulative ? 0 : aStats.rxBytes, - txBytes: isAccumulative ? 0 : aStats.txBytes, - rxSystemBytes: isAccumulative ? aStats.rxBytes : 0, - txSystemBytes: isAccumulative ? aStats.txBytes : 0, - rxTotalBytes: isAccumulative ? aStats.rxBytes : 0, - txTotalBytes: isAccumulative ? aStats.txBytes : 0 }; - - stats = this.importData(stats); - - this.dbNewTxn(STATS_STORE_NAME, "readwrite", function(aTxn, aStore) { - if (DEBUG) { - debug("Filtered time: " + new Date(timestamp)); - debug("New stats: " + JSON.stringify(stats)); - } - - let lowerFilter = [stats.appId, stats.isInBrowser, stats.serviceType, - stats.network, 0]; - let upperFilter = [stats.appId, stats.isInBrowser, stats.serviceType, - stats.network, ""]; - let range = IDBKeyRange.bound(lowerFilter, upperFilter, false, false); - - let request = aStore.openCursor(range, 'prev'); - request.onsuccess = function onsuccess(event) { - let cursor = event.target.result; - if (!cursor) { - // Empty, so save first element. - - if (!isAccumulative) { - this._saveStats(aTxn, aStore, stats); - return; - } - - // There could be a time delay between the point when the network - // interface comes up and the point when the database is initialized. - // In this short interval some traffic data are generated but are not - // registered by the first sample. - stats.rxBytes = stats.rxTotalBytes; - stats.txBytes = stats.txTotalBytes; - - // However, if the interface is not switched on after the database is - // initialized (dual sim use case) stats should be set to 0. - let req = aStore.index("network").openKeyCursor(null, "nextunique"); - req.onsuccess = function onsuccess(event) { - let cursor = event.target.result; - if (cursor) { - if (cursor.key[1] == stats.network[1]) { - stats.rxBytes = 0; - stats.txBytes = 0; - this._saveStats(aTxn, aStore, stats); - return; - } - - cursor.continue(); - return; - } - - this._saveStats(aTxn, aStore, stats); - }.bind(this); - - return; - } - - // There are old samples - if (DEBUG) { - debug("Last value " + JSON.stringify(cursor.value)); - } - - // Remove stats previous to now - VALUE_MAX_LENGTH - this._removeOldStats(aTxn, aStore, stats.appId, stats.isInBrowser, - stats.serviceType, stats.network, stats.timestamp); - - // Process stats before save - this._processSamplesDiff(aTxn, aStore, cursor, stats, isAccumulative); - }.bind(this); - }.bind(this), aResultCb); - }, - - /* - * This function check that stats are saved in the database following the sample rate. - * In this way is easier to find elements when stats are requested. - */ - _processSamplesDiff: function _processSamplesDiff(aTxn, - aStore, - aLastSampleCursor, - aNewSample, - aIsAccumulative) { - let lastSample = aLastSampleCursor.value; - - // Get difference between last and new sample. - let diff = (aNewSample.timestamp - lastSample.timestamp) / SAMPLE_RATE; - if (diff % 1) { - // diff is decimal, so some error happened because samples are stored as a multiple - // of SAMPLE_RATE - aTxn.abort(); - throw new Error("Error processing samples"); - } - - if (DEBUG) { - debug("New: " + aNewSample.timestamp + " - Last: " + - lastSample.timestamp + " - diff: " + diff); - } - - // If the incoming data has a accumulation feature, the new - // |txBytes|/|rxBytes| is assigend by differnces between the new - // |txTotalBytes|/|rxTotalBytes| and the last |txTotalBytes|/|rxTotalBytes|. - // Else, if incoming data is non-accumulative, the |txBytes|/|rxBytes| - // is the new |txBytes|/|rxBytes|. - let rxDiff = 0; - let txDiff = 0; - if (aIsAccumulative) { - rxDiff = aNewSample.rxSystemBytes - lastSample.rxSystemBytes; - txDiff = aNewSample.txSystemBytes - lastSample.txSystemBytes; - if (rxDiff < 0 || txDiff < 0) { - rxDiff = aNewSample.rxSystemBytes; - txDiff = aNewSample.txSystemBytes; - } - aNewSample.rxBytes = rxDiff; - aNewSample.txBytes = txDiff; - - aNewSample.rxTotalBytes = lastSample.rxTotalBytes + rxDiff; - aNewSample.txTotalBytes = lastSample.txTotalBytes + txDiff; - } else { - rxDiff = aNewSample.rxBytes; - txDiff = aNewSample.txBytes; - } - - if (diff == 1) { - // New element. - - // If the incoming data is non-accumulative, the new - // |rxTotalBytes|/|txTotalBytes| needs to be updated by adding new - // |rxBytes|/|txBytes| to the last |rxTotalBytes|/|txTotalBytes|. - if (!aIsAccumulative) { - aNewSample.rxTotalBytes = aNewSample.rxBytes + lastSample.rxTotalBytes; - aNewSample.txTotalBytes = aNewSample.txBytes + lastSample.txTotalBytes; - } - - this._saveStats(aTxn, aStore, aNewSample); - return; - } - if (diff > 1) { - // Some samples lost. Device off during one or more samplerate periods. - // Time or timezone changed - // Add lost samples with 0 bytes and the actual one. - if (diff > VALUES_MAX_LENGTH) { - diff = VALUES_MAX_LENGTH; - } - - let data = []; - for (let i = diff - 2; i >= 0; i--) { - let time = aNewSample.timestamp - SAMPLE_RATE * (i + 1); - let sample = { appId: aNewSample.appId, - isInBrowser: aNewSample.isInBrowser, - serviceType: aNewSample.serviceType, - network: aNewSample.network, - timestamp: time, - rxBytes: 0, - txBytes: 0, - rxSystemBytes: lastSample.rxSystemBytes, - txSystemBytes: lastSample.txSystemBytes, - rxTotalBytes: lastSample.rxTotalBytes, - txTotalBytes: lastSample.txTotalBytes }; - - data.push(sample); - } - - data.push(aNewSample); - this._saveStats(aTxn, aStore, data); - return; - } - if (diff == 0 || diff < 0) { - // New element received before samplerate period. It means that device has - // been restarted (or clock / timezone change). - // Update element. If diff < 0, clock or timezone changed back. Place data - // in the last sample. - - // Old |rxTotalBytes|/|txTotalBytes| needs to get updated by adding the - // last |rxTotalBytes|/|txTotalBytes|. - lastSample.rxBytes += rxDiff; - lastSample.txBytes += txDiff; - lastSample.rxSystemBytes = aNewSample.rxSystemBytes; - lastSample.txSystemBytes = aNewSample.txSystemBytes; - lastSample.rxTotalBytes += rxDiff; - lastSample.txTotalBytes += txDiff; - - if (DEBUG) { - debug("Update: " + JSON.stringify(lastSample)); - } - let req = aLastSampleCursor.update(lastSample); - } - }, - - _saveStats: function _saveStats(aTxn, aStore, aNetworkStats) { - if (DEBUG) { - debug("_saveStats: " + JSON.stringify(aNetworkStats)); - } - - if (Array.isArray(aNetworkStats)) { - let len = aNetworkStats.length - 1; - for (let i = 0; i <= len; i++) { - aStore.put(aNetworkStats[i]); - } - } else { - aStore.put(aNetworkStats); - } - }, - - _removeOldStats: function _removeOldStats(aTxn, aStore, aAppId, aIsInBrowser, - aServiceType, aNetwork, aDate) { - // Callback function to remove old items when new ones are added. - let filterDate = aDate - (SAMPLE_RATE * VALUES_MAX_LENGTH - 1); - let lowerFilter = [aAppId, aIsInBrowser, aServiceType, aNetwork, 0]; - let upperFilter = [aAppId, aIsInBrowser, aServiceType, aNetwork, filterDate]; - let range = IDBKeyRange.bound(lowerFilter, upperFilter, false, false); - let lastSample = null; - let self = this; - - aStore.openCursor(range).onsuccess = function(event) { - var cursor = event.target.result; - if (cursor) { - lastSample = cursor.value; - cursor.delete(); - cursor.continue(); - return; - } - - // If all samples for a network are removed, an empty sample - // has to be saved to keep the totalBytes in order to compute - // future samples because system counters are not set to 0. - // Thus, if there are no samples left, the last sample removed - // will be saved again after setting its bytes to 0. - let request = aStore.index("network").openCursor(aNetwork); - request.onsuccess = function onsuccess(event) { - let cursor = event.target.result; - if (!cursor && lastSample != null) { - let timestamp = new Date(); - timestamp = self.normalizeDate(timestamp); - lastSample.timestamp = timestamp; - lastSample.rxBytes = 0; - lastSample.txBytes = 0; - self._saveStats(aTxn, aStore, lastSample); - } - }; - }; - }, - - clearInterfaceStats: function clearInterfaceStats(aNetwork, aResultCb) { - let network = [aNetwork.network.id, aNetwork.network.type]; - let self = this; - - // Clear and save an empty sample to keep sync with system counters - this.dbNewTxn(STATS_STORE_NAME, "readwrite", function(aTxn, aStore) { - let sample = null; - let request = aStore.index("network").openCursor(network, "prev"); - request.onsuccess = function onsuccess(event) { - let cursor = event.target.result; - if (cursor) { - if (!sample && cursor.value.appId == 0) { - sample = cursor.value; - } - - cursor.delete(); - cursor.continue(); - return; - } - - if (sample) { - let timestamp = new Date(); - timestamp = self.normalizeDate(timestamp); - sample.timestamp = timestamp; - sample.appId = 0; - sample.isInBrowser = 0; - sample.serviceType = ""; - sample.rxBytes = 0; - sample.txBytes = 0; - sample.rxTotalBytes = 0; - sample.txTotalBytes = 0; - - self._saveStats(aTxn, aStore, sample); - } - }; - }, this._resetAlarms.bind(this, aNetwork.networkId, aResultCb)); - }, - - clearStats: function clearStats(aNetworks, aResultCb) { - let index = 0; - let stats = []; - let self = this; - - let callback = function(aError, aResult) { - index++; - - if (!aError && index < aNetworks.length) { - self.clearInterfaceStats(aNetworks[index], callback); - return; - } - - aResultCb(aError, aResult); - }; - - if (!aNetworks[index]) { - aResultCb(null, true); - return; - } - this.clearInterfaceStats(aNetworks[index], callback); - }, - - getCurrentStats: function getCurrentStats(aNetwork, aDate, aResultCb) { - if (DEBUG) { - debug("Get current stats for " + JSON.stringify(aNetwork) + " since " + aDate); - } - - let network = [aNetwork.id, aNetwork.type]; - if (aDate) { - this._getCurrentStatsFromDate(network, aDate, aResultCb); - return; - } - - this._getCurrentStats(network, aResultCb); - }, - - _getCurrentStats: function _getCurrentStats(aNetwork, aResultCb) { - this.dbNewTxn(STATS_STORE_NAME, "readonly", function(txn, store) { - let request = null; - let upperFilter = [0, 1, "", aNetwork, Date.now()]; - let range = IDBKeyRange.upperBound(upperFilter, false); - let result = { rxBytes: 0, txBytes: 0, - rxTotalBytes: 0, txTotalBytes: 0 }; - - request = store.openCursor(range, "prev"); - - request.onsuccess = function onsuccess(event) { - let cursor = event.target.result; - if (cursor) { - result.rxBytes = result.rxTotalBytes = cursor.value.rxTotalBytes; - result.txBytes = result.txTotalBytes = cursor.value.txTotalBytes; - } - - txn.result = result; - }; - }.bind(this), aResultCb); - }, - - _getCurrentStatsFromDate: function _getCurrentStatsFromDate(aNetwork, aDate, aResultCb) { - aDate = new Date(aDate); - this.dbNewTxn(STATS_STORE_NAME, "readonly", function(txn, store) { - let request = null; - let start = this.normalizeDate(aDate); - let upperFilter = [0, 1, "", aNetwork, Date.now()]; - let range = IDBKeyRange.upperBound(upperFilter, false); - let result = { rxBytes: 0, txBytes: 0, - rxTotalBytes: 0, txTotalBytes: 0 }; - - request = store.openCursor(range, "prev"); - - request.onsuccess = function onsuccess(event) { - let cursor = event.target.result; - if (cursor) { - result.rxBytes = result.rxTotalBytes = cursor.value.rxTotalBytes; - result.txBytes = result.txTotalBytes = cursor.value.txTotalBytes; - } - - let timestamp = cursor.value.timestamp; - let range = IDBKeyRange.lowerBound(lowerFilter, false); - request = store.openCursor(range); - - request.onsuccess = function onsuccess(event) { - let cursor = event.target.result; - if (cursor) { - if (cursor.value.timestamp == timestamp) { - // There is one sample only. - result.rxBytes = cursor.value.rxBytes; - result.txBytes = cursor.value.txBytes; - } else { - result.rxBytes -= cursor.value.rxTotalBytes; - result.txBytes -= cursor.value.txTotalBytes; - } - } - - txn.result = result; - }; - }; - }.bind(this), aResultCb); - }, - - find: function find(aResultCb, aAppId, aBrowsingTrafficOnly, aServiceType, - aNetwork, aStart, aEnd, aAppManifestURL) { - let offset = (new Date()).getTimezoneOffset() * 60 * 1000; - let start = this.normalizeDate(aStart); - let end = this.normalizeDate(aEnd); - - if (DEBUG) { - debug("Find samples for appId: " + aAppId + - " browsingTrafficOnly: " + aBrowsingTrafficOnly + - " serviceType: " + aServiceType + - " network: " + JSON.stringify(aNetwork) + " from " + start + - " until " + end); - debug("Start time: " + new Date(start)); - debug("End time: " + new Date(end)); - } - - // Find samples of browsing traffic (isInBrowser = 1) first since they are - // needed no matter browsingTrafficOnly is true or false. - // We have to make two queries to database because we cannot filter correct - // records by a single query that sets ranges for two keys (isInBrowser and - // timestamp). We think it is because the keyPath contains an array - // (network) so such query does not work. - this.dbNewTxn(STATS_STORE_NAME, "readonly", function(aTxn, aStore) { - let network = [aNetwork.id, aNetwork.type]; - let lowerFilter = [aAppId, 1, aServiceType, network, start]; - let upperFilter = [aAppId, 1, aServiceType, network, end]; - let range = IDBKeyRange.bound(lowerFilter, upperFilter, false, false); - - let data = []; - - if (!aTxn.result) { - aTxn.result = {}; - } - aTxn.result.appManifestURL = aAppManifestURL; - aTxn.result.browsingTrafficOnly = aBrowsingTrafficOnly; - aTxn.result.serviceType = aServiceType; - aTxn.result.network = aNetwork; - aTxn.result.start = aStart; - aTxn.result.end = aEnd; - - let request = aStore.openCursor(range).onsuccess = function(event) { - var cursor = event.target.result; - if (cursor){ - // We use rxTotalBytes/txTotalBytes instead of rxBytes/txBytes for - // the first (oldest) sample. The rx/txTotalBytes fields record - // accumulative usage amount, which means even if old samples were - // expired and removed from the Database, we can still obtain the - // correct network usage. - if (data.length == 0) { - data.push({ rxBytes: cursor.value.rxTotalBytes, - txBytes: cursor.value.txTotalBytes, - date: new Date(cursor.value.timestamp + offset) }); - } else { - data.push({ rxBytes: cursor.value.rxBytes, - txBytes: cursor.value.txBytes, - date: new Date(cursor.value.timestamp + offset) }); - } - cursor.continue(); - return; - } - - if (aBrowsingTrafficOnly) { - this.fillResultSamples(start + offset, end + offset, data); - aTxn.result.data = data; - return; - } - - // Find samples of app traffic (isInBrowser = 0) as well if - // browsingTrafficOnly is false. - lowerFilter = [aAppId, 0, aServiceType, network, start]; - upperFilter = [aAppId, 0, aServiceType, network, end]; - range = IDBKeyRange.bound(lowerFilter, upperFilter, false, false); - request = aStore.openCursor(range).onsuccess = function(event) { - cursor = event.target.result; - if (cursor) { - var date = new Date(cursor.value.timestamp + offset); - var foundData = data.find(function (element, index, array) { - if (element.date.getTime() !== date.getTime()) { - return false; - } - return element; - }, date); - - if (foundData) { - foundData.rxBytes += cursor.value.rxBytes; - foundData.txBytes += cursor.value.txBytes; - } else { - // We use rxTotalBytes/txTotalBytes instead of rxBytes/txBytes - // for the first (oldest) sample. The rx/txTotalBytes fields - // record accumulative usage amount, which means even if old - // samples were expired and removed from the Database, we can - // still obtain the correct network usage. - if (data.length == 0) { - data.push({ rxBytes: cursor.value.rxTotalBytes, - txBytes: cursor.value.txTotalBytes, - date: new Date(cursor.value.timestamp + offset) }); - } else { - data.push({ rxBytes: cursor.value.rxBytes, - txBytes: cursor.value.txBytes, - date: new Date(cursor.value.timestamp + offset) }); - } - } - cursor.continue(); - return; - } - this.fillResultSamples(start + offset, end + offset, data); - aTxn.result.data = data; - }.bind(this); // openCursor(range).onsuccess() callback - }.bind(this); // openCursor(range).onsuccess() callback - }.bind(this), aResultCb); - }, - - /* - * Fill data array (samples from database) with empty samples to match - * requested start / end dates. - */ - fillResultSamples: function fillResultSamples(aStart, aEnd, aData) { - if (aData.length == 0) { - aData.push({ rxBytes: undefined, - txBytes: undefined, - date: new Date(aStart) }); - } - - while (aStart < aData[0].date.getTime()) { - aData.unshift({ rxBytes: undefined, - txBytes: undefined, - date: new Date(aData[0].date.getTime() - SAMPLE_RATE) }); - } - - while (aEnd > aData[aData.length - 1].date.getTime()) { - aData.push({ rxBytes: undefined, - txBytes: undefined, - date: new Date(aData[aData.length - 1].date.getTime() + SAMPLE_RATE) }); - } - }, - - getAvailableNetworks: function getAvailableNetworks(aResultCb) { - this.dbNewTxn(STATS_STORE_NAME, "readonly", function(aTxn, aStore) { - if (!aTxn.result) { - aTxn.result = []; - } - - let request = aStore.index("network").openKeyCursor(null, "nextunique"); - request.onsuccess = function onsuccess(event) { - let cursor = event.target.result; - if (cursor) { - aTxn.result.push({ id: cursor.key[0], - type: cursor.key[1] }); - cursor.continue(); - return; - } - }; - }, aResultCb); - }, - - isNetworkAvailable: function isNetworkAvailable(aNetwork, aResultCb) { - this.dbNewTxn(STATS_STORE_NAME, "readonly", function(aTxn, aStore) { - if (!aTxn.result) { - aTxn.result = false; - } - - let network = [aNetwork.id, aNetwork.type]; - let request = aStore.index("network").openKeyCursor(IDBKeyRange.only(network)); - request.onsuccess = function onsuccess(event) { - if (event.target.result) { - aTxn.result = true; - } - }; - }, aResultCb); - }, - - getAvailableServiceTypes: function getAvailableServiceTypes(aResultCb) { - this.dbNewTxn(STATS_STORE_NAME, "readonly", function(aTxn, aStore) { - if (!aTxn.result) { - aTxn.result = []; - } - - let request = aStore.index("serviceType").openKeyCursor(null, "nextunique"); - request.onsuccess = function onsuccess(event) { - let cursor = event.target.result; - if (cursor && cursor.key != "") { - aTxn.result.push({ serviceType: cursor.key }); - cursor.continue(); - return; - } - }; - }, aResultCb); - }, - - get sampleRate () { - return SAMPLE_RATE; - }, - - get maxStorageSamples () { - return VALUES_MAX_LENGTH; - }, - - logAllRecords: function logAllRecords(aResultCb) { - this.dbNewTxn(STATS_STORE_NAME, "readonly", function(aTxn, aStore) { - aStore.mozGetAll().onsuccess = function onsuccess(event) { - aTxn.result = event.target.result; - }; - }, aResultCb); - }, - - alarmToRecord: function alarmToRecord(aAlarm) { - let record = { networkId: aAlarm.networkId, - absoluteThreshold: aAlarm.absoluteThreshold, - relativeThreshold: aAlarm.relativeThreshold, - startTime: aAlarm.startTime, - data: aAlarm.data, - manifestURL: aAlarm.manifestURL, - pageURL: aAlarm.pageURL }; - - if (aAlarm.id) { - record.id = aAlarm.id; - } - - return record; - }, - - recordToAlarm: function recordToalarm(aRecord) { - let alarm = { networkId: aRecord.networkId, - absoluteThreshold: aRecord.absoluteThreshold, - relativeThreshold: aRecord.relativeThreshold, - startTime: aRecord.startTime, - data: aRecord.data, - manifestURL: aRecord.manifestURL, - pageURL: aRecord.pageURL }; - - if (aRecord.id) { - alarm.id = aRecord.id; - } - - return alarm; - }, - - addAlarm: function addAlarm(aAlarm, aResultCb) { - this.dbNewTxn(ALARMS_STORE_NAME, "readwrite", function(txn, store) { - if (DEBUG) { - debug("Going to add " + JSON.stringify(aAlarm)); - } - - let record = this.alarmToRecord(aAlarm); - store.put(record).onsuccess = function setResult(aEvent) { - txn.result = aEvent.target.result; - if (DEBUG) { - debug("Request successful. New record ID: " + txn.result); - } - }; - }.bind(this), aResultCb); - }, - - getFirstAlarm: function getFirstAlarm(aNetworkId, aResultCb) { - let self = this; - - this.dbNewTxn(ALARMS_STORE_NAME, "readonly", function(txn, store) { - if (DEBUG) { - debug("Get first alarm for network " + aNetworkId); - } - - let lowerFilter = [aNetworkId, 0]; - let upperFilter = [aNetworkId, ""]; - let range = IDBKeyRange.bound(lowerFilter, upperFilter); - - store.index("alarm").openCursor(range).onsuccess = function onsuccess(event) { - let cursor = event.target.result; - txn.result = null; - if (cursor) { - txn.result = self.recordToAlarm(cursor.value); - } - }; - }, aResultCb); - }, - - removeAlarm: function removeAlarm(aAlarmId, aManifestURL, aResultCb) { - this.dbNewTxn(ALARMS_STORE_NAME, "readwrite", function(txn, store) { - if (DEBUG) { - debug("Remove alarm " + aAlarmId); - } - - store.get(aAlarmId).onsuccess = function onsuccess(event) { - let record = event.target.result; - txn.result = false; - if (!record || (aManifestURL && record.manifestURL != aManifestURL)) { - return; - } - - store.delete(aAlarmId); - txn.result = true; - } - }, aResultCb); - }, - - removeAlarms: function removeAlarms(aManifestURL, aResultCb) { - this.dbNewTxn(ALARMS_STORE_NAME, "readwrite", function(txn, store) { - if (DEBUG) { - debug("Remove alarms of " + aManifestURL); - } - - store.index("manifestURL").openCursor(aManifestURL) - .onsuccess = function onsuccess(event) { - let cursor = event.target.result; - if (cursor) { - cursor.delete(); - cursor.continue(); - } - } - }, aResultCb); - }, - - updateAlarm: function updateAlarm(aAlarm, aResultCb) { - let self = this; - this.dbNewTxn(ALARMS_STORE_NAME, "readwrite", function(txn, store) { - if (DEBUG) { - debug("Update alarm " + aAlarm.id); - } - - let record = self.alarmToRecord(aAlarm); - store.openCursor(record.id).onsuccess = function onsuccess(event) { - let cursor = event.target.result; - txn.result = false; - if (cursor) { - cursor.update(record); - txn.result = true; - } - } - }, aResultCb); - }, - - getAlarms: function getAlarms(aNetworkId, aManifestURL, aResultCb) { - let self = this; - this.dbNewTxn(ALARMS_STORE_NAME, "readonly", function(txn, store) { - if (DEBUG) { - debug("Get alarms for " + aManifestURL); - } - - txn.result = []; - store.index("manifestURL").openCursor(aManifestURL) - .onsuccess = function onsuccess(event) { - let cursor = event.target.result; - if (!cursor) { - return; - } - - if (!aNetworkId || cursor.value.networkId == aNetworkId) { - txn.result.push(self.recordToAlarm(cursor.value)); - } - - cursor.continue(); - } - }, aResultCb); - }, - - _resetAlarms: function _resetAlarms(aNetworkId, aResultCb) { - this.dbNewTxn(ALARMS_STORE_NAME, "readwrite", function(txn, store) { - if (DEBUG) { - debug("Reset alarms for network " + aNetworkId); - } - - let lowerFilter = [aNetworkId, 0]; - let upperFilter = [aNetworkId, ""]; - let range = IDBKeyRange.bound(lowerFilter, upperFilter); - - store.index("alarm").openCursor(range).onsuccess = function onsuccess(event) { - let cursor = event.target.result; - if (cursor) { - if (cursor.value.startTime) { - cursor.value.relativeThreshold = cursor.value.threshold; - cursor.update(cursor.value); - } - cursor.continue(); - return; - } - }; - }, aResultCb); - } -}; diff --git a/dom/network/NetworkStatsManager.js b/dom/network/NetworkStatsManager.js deleted file mode 100644 index b963aba2b..000000000 --- a/dom/network/NetworkStatsManager.js +++ /dev/null @@ -1,388 +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 DEBUG = false; -function debug(s) { dump("-*- NetworkStatsManager: " + s + "\n"); } - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/DOMRequestHelper.jsm"); - -// Ensure NetworkStatsService and NetworkStatsDB are loaded in the parent process -// to receive messages from the child processes. -var appInfo = Cc["@mozilla.org/xre/app-info;1"]; -var isParentProcess = !appInfo || appInfo.getService(Ci.nsIXULRuntime) - .processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT; -if (isParentProcess) { - Cu.import("resource://gre/modules/NetworkStatsService.jsm"); -} - -XPCOMUtils.defineLazyServiceGetter(this, "cpmm", - "@mozilla.org/childprocessmessagemanager;1", - "nsISyncMessageSender"); - -// NetworkStatsData -const nsIClassInfo = Ci.nsIClassInfo; -const NETWORKSTATSDATA_CID = Components.ID("{3b16fe17-5583-483a-b486-b64a3243221c}"); - -function NetworkStatsData(aWindow, aData) { - this.rxBytes = aData.rxBytes; - this.txBytes = aData.txBytes; - this.date = new aWindow.Date(aData.date.getTime()); -} - -NetworkStatsData.prototype = { - classID : NETWORKSTATSDATA_CID, - - QueryInterface : XPCOMUtils.generateQI([]) -}; - -// NetworkStatsInterface -const NETWORKSTATSINTERFACE_CONTRACTID = "@mozilla.org/networkstatsinterface;1"; -const NETWORKSTATSINTERFACE_CID = Components.ID("{f540615b-d803-43ff-8200-2a9d145a5645}"); - -function NetworkStatsInterface() { - if (DEBUG) { - debug("NetworkStatsInterface Constructor"); - } -} - -NetworkStatsInterface.prototype = { - __init: function(aNetwork) { - this.type = aNetwork.type; - this.id = aNetwork.id; - }, - - classID : NETWORKSTATSINTERFACE_CID, - - contractID: NETWORKSTATSINTERFACE_CONTRACTID, - QueryInterface : XPCOMUtils.generateQI([]) -} - -// NetworkStats -const NETWORKSTATS_CID = Components.ID("{28904f59-8497-4ac0-904f-2af14b7fd3de}"); - -function NetworkStats(aWindow, aStats) { - if (DEBUG) { - debug("NetworkStats Constructor"); - } - this.appManifestURL = aStats.appManifestURL || null; - this.browsingTrafficOnly = aStats.browsingTrafficOnly || false; - this.serviceType = aStats.serviceType || null; - this.network = new aWindow.MozNetworkStatsInterface(aStats.network); - this.start = aStats.start ? new aWindow.Date(aStats.start.getTime()) : null; - this.end = aStats.end ? new aWindow.Date(aStats.end.getTime()) : null; - - let samples = this.data = new aWindow.Array(); - for (let i = 0; i < aStats.data.length; i++) { - samples.push(aWindow.MozNetworkStatsData._create( - aWindow, new NetworkStatsData(aWindow, aStats.data[i]))); - } -} - -NetworkStats.prototype = { - classID : NETWORKSTATS_CID, - - QueryInterface : XPCOMUtils.generateQI() -} - -// NetworkStatsAlarm -const NETWORKSTATSALARM_CID = Components.ID("{a93ea13e-409c-4189-9b1e-95fff220be55}"); - -function NetworkStatsAlarm(aWindow, aAlarm) { - this.alarmId = aAlarm.id; - this.network = new aWindow.MozNetworkStatsInterface(aAlarm.network); - this.threshold = aAlarm.threshold; - this.data = aAlarm.data; -} - -NetworkStatsAlarm.prototype = { - classID : NETWORKSTATSALARM_CID, - - QueryInterface : XPCOMUtils.generateQI([]) -}; - -// NetworkStatsManager - -const NETWORKSTATSMANAGER_CONTRACTID = "@mozilla.org/networkStatsManager;1"; -const NETWORKSTATSMANAGER_CID = Components.ID("{ceb874cd-cc1a-4e65-b404-cc2d3e42425f}"); - -function NetworkStatsManager() { - if (DEBUG) { - debug("Constructor"); - } -} - -NetworkStatsManager.prototype = { - __proto__: DOMRequestIpcHelper.prototype, - - getSamples: function getSamples(aNetwork, aStart, aEnd, aOptions) { - if (aStart > aEnd) { - throw Components.results.NS_ERROR_INVALID_ARG; - } - - // appManifestURL is used to query network statistics by app; - // serviceType is used to query network statistics by system service. - // It is illegal to specify both of them at the same time. - if (aOptions.appManifestURL && aOptions.serviceType) { - throw Components.results.NS_ERROR_NOT_IMPLEMENTED; - } - // browsingTrafficOnly is meaningful only when querying by app. - if (!aOptions.appManifestURL && aOptions.browsingTrafficOnly) { - throw Components.results.NS_ERROR_NOT_IMPLEMENTED; - } - - let appManifestURL = aOptions.appManifestURL; - let serviceType = aOptions.serviceType; - let browsingTrafficOnly = aOptions.browsingTrafficOnly; - - // TODO Bug 929410 Date object cannot correctly pass through cpmm/ppmm IPC - // This is just a work-around by passing timestamp numbers. - aStart = aStart.getTime(); - aEnd = aEnd.getTime(); - - let request = this.createRequest(); - cpmm.sendAsyncMessage("NetworkStats:Get", - { network: aNetwork.toJSON(), - start: aStart, - end: aEnd, - appManifestURL: appManifestURL, - browsingTrafficOnly: browsingTrafficOnly, - serviceType: serviceType, - id: this.getRequestId(request) }); - return request; - }, - - clearStats: function clearStats(aNetwork) { - let request = this.createRequest(); - cpmm.sendAsyncMessage("NetworkStats:Clear", - { network: aNetwork.toJSON(), - id: this.getRequestId(request) }); - return request; - }, - - clearAllStats: function clearAllStats() { - let request = this.createRequest(); - cpmm.sendAsyncMessage("NetworkStats:ClearAll", - {id: this.getRequestId(request)}); - return request; - }, - - addAlarm: function addAlarm(aNetwork, aThreshold, aOptions) { - let request = this.createRequest(); - cpmm.sendAsyncMessage("NetworkStats:SetAlarm", - {id: this.getRequestId(request), - data: {network: aNetwork.toJSON(), - threshold: aThreshold, - startTime: aOptions.startTime, - data: aOptions.data, - manifestURL: this.manifestURL, - pageURL: this.pageURL}}); - return request; - }, - - getAllAlarms: function getAllAlarms(aNetwork) { - let network = null; - if (aNetwork) { - network = aNetwork.toJSON(); - } - - let request = this.createRequest(); - cpmm.sendAsyncMessage("NetworkStats:GetAlarms", - {id: this.getRequestId(request), - data: {network: network, - manifestURL: this.manifestURL}}); - return request; - }, - - removeAlarms: function removeAlarms(aAlarmId) { - if (aAlarmId == 0) { - aAlarmId = -1; - } - - let request = this.createRequest(); - cpmm.sendAsyncMessage("NetworkStats:RemoveAlarms", - {id: this.getRequestId(request), - data: {alarmId: aAlarmId, - manifestURL: this.manifestURL}}); - - return request; - }, - - getAvailableNetworks: function getAvailableNetworks() { - let request = this.createRequest(); - cpmm.sendAsyncMessage("NetworkStats:GetAvailableNetworks", - { id: this.getRequestId(request) }); - return request; - }, - - getAvailableServiceTypes: function getAvailableServiceTypes() { - let request = this.createRequest(); - cpmm.sendAsyncMessage("NetworkStats:GetAvailableServiceTypes", - { id: this.getRequestId(request) }); - return request; - }, - - get sampleRate() { - return cpmm.sendSyncMessage("NetworkStats:SampleRate")[0]; - }, - - get maxStorageAge() { - return cpmm.sendSyncMessage("NetworkStats:MaxStorageAge")[0]; - }, - - receiveMessage: function(aMessage) { - if (DEBUG) { - debug("NetworkStatsmanager::receiveMessage: " + aMessage.name); - } - - let msg = aMessage.json; - let req = this.takeRequest(msg.id); - if (!req) { - if (DEBUG) { - debug("No request stored with id " + msg.id); - } - return; - } - - switch (aMessage.name) { - case "NetworkStats:Get:Return": - if (msg.error) { - Services.DOMRequest.fireError(req, msg.error); - return; - } - - let result = this._window.MozNetworkStats._create( - this._window, new NetworkStats(this._window, msg.result)); - if (DEBUG) { - debug("result: " + JSON.stringify(result)); - } - Services.DOMRequest.fireSuccess(req, result); - break; - - case "NetworkStats:GetAvailableNetworks:Return": - if (msg.error) { - Services.DOMRequest.fireError(req, msg.error); - return; - } - - let networks = new this._window.Array(); - for (let i = 0; i < msg.result.length; i++) { - let network = new this._window.MozNetworkStatsInterface(msg.result[i]); - networks.push(network); - } - - Services.DOMRequest.fireSuccess(req, networks); - break; - - case "NetworkStats:GetAvailableServiceTypes:Return": - if (msg.error) { - Services.DOMRequest.fireError(req, msg.error); - return; - } - - let serviceTypes = new this._window.Array(); - for (let i = 0; i < msg.result.length; i++) { - serviceTypes.push(msg.result[i]); - } - - Services.DOMRequest.fireSuccess(req, serviceTypes); - break; - - case "NetworkStats:Clear:Return": - case "NetworkStats:ClearAll:Return": - if (msg.error) { - Services.DOMRequest.fireError(req, msg.error); - return; - } - - Services.DOMRequest.fireSuccess(req, true); - break; - - case "NetworkStats:SetAlarm:Return": - case "NetworkStats:RemoveAlarms:Return": - if (msg.error) { - Services.DOMRequest.fireError(req, msg.error); - return; - } - - Services.DOMRequest.fireSuccess(req, msg.result); - break; - - case "NetworkStats:GetAlarms:Return": - if (msg.error) { - Services.DOMRequest.fireError(req, msg.error); - return; - } - - let alarms = new this._window.Array(); - for (let i = 0; i < msg.result.length; i++) { - // The WebIDL type of data is any, so we should manually clone it - // into the content window. - if ("data" in msg.result[i]) { - msg.result[i].data = Cu.cloneInto(msg.result[i].data, this._window); - } - let alarm = new NetworkStatsAlarm(this._window, msg.result[i]); - alarms.push(this._window.MozNetworkStatsAlarm._create(this._window, alarm)); - } - - Services.DOMRequest.fireSuccess(req, alarms); - break; - - default: - if (DEBUG) { - debug("Wrong message: " + aMessage.name); - } - } - }, - - init: function(aWindow) { - let principal = aWindow.document.nodePrincipal; - - this.initDOMRequestHelper(aWindow, ["NetworkStats:Get:Return", - "NetworkStats:GetAvailableNetworks:Return", - "NetworkStats:GetAvailableServiceTypes:Return", - "NetworkStats:Clear:Return", - "NetworkStats:ClearAll:Return", - "NetworkStats:SetAlarm:Return", - "NetworkStats:GetAlarms:Return", - "NetworkStats:RemoveAlarms:Return"]); - - // Init app properties. - let appsService = Cc["@mozilla.org/AppsService;1"] - .getService(Ci.nsIAppsService); - - this.manifestURL = appsService.getManifestURLByLocalId(principal.appId); - - let isApp = !!this.manifestURL.length; - if (isApp) { - this.pageURL = principal.URI.spec; - } - - this.window = aWindow; - }, - - // Called from DOMRequestIpcHelper - uninit: function uninit() { - if (DEBUG) { - debug("uninit call"); - } - }, - - classID : NETWORKSTATSMANAGER_CID, - contractID : NETWORKSTATSMANAGER_CONTRACTID, - QueryInterface : XPCOMUtils.generateQI([Ci.nsIDOMGlobalPropertyInitializer, - Ci.nsISupportsWeakReference, - Ci.nsIObserver]), -} - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([NetworkStatsAlarm, - NetworkStatsData, - NetworkStatsInterface, - NetworkStats, - NetworkStatsManager]); diff --git a/dom/network/NetworkStatsManager.manifest b/dom/network/NetworkStatsManager.manifest deleted file mode 100644 index 8e8700910..000000000 --- a/dom/network/NetworkStatsManager.manifest +++ /dev/null @@ -1,14 +0,0 @@ -component {3b16fe17-5583-483a-b486-b64a3243221c} NetworkStatsManager.js -contract @mozilla.org/networkStatsdata;1 {3b16fe17-5583-483a-b486-b64a3243221c} - -component {28904f59-8497-4ac0-904f-2af14b7fd3de} NetworkStatsManager.js -contract @mozilla.org/networkStats;1 {28904f59-8497-4ac0-904f-2af14b7fd3de} - -component {f540615b-d803-43ff-8200-2a9d145a5645} NetworkStatsManager.js -contract @mozilla.org/networkstatsinterface;1 {f540615b-d803-43ff-8200-2a9d145a5645} - -component {a93ea13e-409c-4189-9b1e-95fff220be55} NetworkStatsManager.js -contract @mozilla.org/networkstatsalarm;1 {a93ea13e-409c-4189-9b1e-95fff220be55} - -component {ceb874cd-cc1a-4e65-b404-cc2d3e42425f} NetworkStatsManager.js -contract @mozilla.org/networkStatsManager;1 {ceb874cd-cc1a-4e65-b404-cc2d3e42425f} diff --git a/dom/network/NetworkStatsService.jsm b/dom/network/NetworkStatsService.jsm deleted file mode 100644 index 4b6d69498..000000000 --- a/dom/network/NetworkStatsService.jsm +++ /dev/null @@ -1,1171 +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 DEBUG = false; -function debug(s) { - if (DEBUG) { - dump("-*- NetworkStatsService: " + s + "\n"); - } -} - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -this.EXPORTED_SYMBOLS = ["NetworkStatsService"]; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/NetworkStatsDB.jsm"); -Cu.import("resource://gre/modules/Timer.jsm"); - -const NET_NETWORKSTATSSERVICE_CONTRACTID = "@mozilla.org/network/netstatsservice;1"; -const NET_NETWORKSTATSSERVICE_CID = Components.ID("{18725604-e9ac-488a-8aa0-2471e7f6c0a4}"); - -const TOPIC_BANDWIDTH_CONTROL = "netd-bandwidth-control" - -const TOPIC_CONNECTION_STATE_CHANGED = "network-connection-state-changed"; -const NET_TYPE_WIFI = Ci.nsINetworkInfo.NETWORK_TYPE_WIFI; -const NET_TYPE_MOBILE = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE; - -// Networks have different status that NetworkStats API needs to be aware of. -// Network is present and ready, so NetworkManager provides the whole info. -const NETWORK_STATUS_READY = 0; -// Network is present but hasn't established a connection yet (e.g. SIM that has not -// enabled 3G since boot). -const NETWORK_STATUS_STANDBY = 1; -// Network is not present, but stored in database by the previous connections. -const NETWORK_STATUS_AWAY = 2; - -// The maximum traffic amount can be saved in the |cachedStats|. -const MAX_CACHED_TRAFFIC = 500 * 1000 * 1000; // 500 MB - -const QUEUE_TYPE_UPDATE_STATS = 0; -const QUEUE_TYPE_UPDATE_CACHE = 1; -const QUEUE_TYPE_WRITE_CACHE = 2; - -XPCOMUtils.defineLazyServiceGetter(this, "ppmm", - "@mozilla.org/parentprocessmessagemanager;1", - "nsIMessageListenerManager"); - -XPCOMUtils.defineLazyServiceGetter(this, "gRil", - "@mozilla.org/ril;1", - "nsIRadioInterfaceLayer"); - -XPCOMUtils.defineLazyServiceGetter(this, "networkService", - "@mozilla.org/network/service;1", - "nsINetworkService"); - -XPCOMUtils.defineLazyServiceGetter(this, "appsService", - "@mozilla.org/AppsService;1", - "nsIAppsService"); - -XPCOMUtils.defineLazyServiceGetter(this, "gSettingsService", - "@mozilla.org/settingsService;1", - "nsISettingsService"); - -XPCOMUtils.defineLazyServiceGetter(this, "messenger", - "@mozilla.org/system-message-internal;1", - "nsISystemMessagesInternal"); - -XPCOMUtils.defineLazyServiceGetter(this, "gIccService", - "@mozilla.org/icc/iccservice;1", - "nsIIccService"); - -this.NetworkStatsService = { - init: function() { - debug("Service started"); - - Services.obs.addObserver(this, "xpcom-shutdown", false); - Services.obs.addObserver(this, TOPIC_CONNECTION_STATE_CHANGED, false); - Services.obs.addObserver(this, TOPIC_BANDWIDTH_CONTROL, false); - Services.obs.addObserver(this, "profile-after-change", false); - - this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - - // Object to store network interfaces, each network interface is composed - // by a network object (network type and network Id) and a interfaceName - // that contains the name of the physical interface (wlan0, rmnet0, etc.). - // The network type can be 0 for wifi or 1 for mobile. On the other hand, - // the network id is '0' for wifi or the iccid for mobile (SIM). - // Each networkInterface is placed in the _networks object by the index of - // 'networkId + networkType'. - // - // _networks object allows to map available network interfaces at low level - // (wlan0, rmnet0, etc.) to a network. It's not mandatory to have a - // networkInterface per network but can't exist a networkInterface not - // being mapped to a network. - - this._networks = Object.create(null); - - // There is no way to know a priori if wifi connection is available, - // just when the wifi driver is loaded, but it is unloaded when - // wifi is switched off. So wifi connection is hardcoded - let netId = this.getNetworkId('0', NET_TYPE_WIFI); - this._networks[netId] = { network: { id: '0', - type: NET_TYPE_WIFI }, - interfaceName: null, - status: NETWORK_STATUS_STANDBY }; - - this.messages = ["NetworkStats:Get", - "NetworkStats:Clear", - "NetworkStats:ClearAll", - "NetworkStats:SetAlarm", - "NetworkStats:GetAlarms", - "NetworkStats:RemoveAlarms", - "NetworkStats:GetAvailableNetworks", - "NetworkStats:GetAvailableServiceTypes", - "NetworkStats:SampleRate", - "NetworkStats:MaxStorageAge"]; - - this.messages.forEach(function(aMsgName) { - ppmm.addMessageListener(aMsgName, this); - }, this); - - this._db = new NetworkStatsDB(); - - // Stats for all interfaces are updated periodically - this.timer.initWithCallback(this, this._db.sampleRate, - Ci.nsITimer.TYPE_REPEATING_PRECISE_CAN_SKIP); - - // Stats not from netd are firstly stored in the cached. - this.cachedStats = Object.create(null); - this.cachedStatsDate = new Date(); - - this.updateQueue = []; - this.isQueueRunning = false; - - this._currentAlarms = {}; - this.initAlarms(); - }, - - receiveMessage: function(aMessage) { - if (!aMessage.target.assertPermission("networkstats-manage")) { - return; - } - - debug("receiveMessage " + aMessage.name); - - let mm = aMessage.target; - let msg = aMessage.json; - - switch (aMessage.name) { - case "NetworkStats:Get": - this.getSamples(mm, msg); - break; - case "NetworkStats:Clear": - this.clearInterfaceStats(mm, msg); - break; - case "NetworkStats:ClearAll": - this.clearDB(mm, msg); - break; - case "NetworkStats:SetAlarm": - this.setAlarm(mm, msg); - break; - case "NetworkStats:GetAlarms": - this.getAlarms(mm, msg); - break; - case "NetworkStats:RemoveAlarms": - this.removeAlarms(mm, msg); - break; - case "NetworkStats:GetAvailableNetworks": - this.getAvailableNetworks(mm, msg); - break; - case "NetworkStats:GetAvailableServiceTypes": - this.getAvailableServiceTypes(mm, msg); - break; - case "NetworkStats:SampleRate": - // This message is sync. - return this._db.sampleRate; - case "NetworkStats:MaxStorageAge": - // This message is sync. - return this._db.maxStorageSamples * this._db.sampleRate; - } - }, - - observe: function observe(aSubject, aTopic, aData) { - switch (aTopic) { - case TOPIC_CONNECTION_STATE_CHANGED: - - // If new interface is registered (notified from NetworkService), - // the stats are updated for the new interface without waiting to - // complete the updating period. - - let networkInfo = aSubject.QueryInterface(Ci.nsINetworkInfo); - debug("Network " + networkInfo.name + " of type " + networkInfo.type + " status change"); - - let netId = this.convertNetworkInfo(networkInfo); - if (!netId) { - break; - } - - this._updateCurrentAlarm(netId); - - debug("NetId: " + netId); - this.updateStats(netId); - break; - - case TOPIC_BANDWIDTH_CONTROL: - debug("Bandwidth message from netd: " + JSON.stringify(aData)); - - let interfaceName = aData.substring(aData.lastIndexOf(" ") + 1); - for (let networkId in this._networks) { - if (interfaceName == this._networks[networkId].interfaceName) { - let currentAlarm = this._currentAlarms[networkId]; - if (Object.getOwnPropertyNames(currentAlarm).length !== 0) { - this._fireAlarm(currentAlarm.alarm); - } - break; - } - } - break; - - case "xpcom-shutdown": - debug("Service shutdown"); - - this.messages.forEach(function(aMsgName) { - ppmm.removeMessageListener(aMsgName, this); - }, this); - - Services.obs.removeObserver(this, "xpcom-shutdown"); - Services.obs.removeObserver(this, "profile-after-change"); - Services.obs.removeObserver(this, TOPIC_CONNECTION_STATE_CHANGED); - Services.obs.removeObserver(this, TOPIC_BANDWIDTH_CONTROL); - - this.timer.cancel(); - this.timer = null; - - // Update stats before shutdown - this.updateAllStats(); - break; - } - }, - - /* - * nsITimerCallback - * Timer triggers the update of all stats - */ - notify: function(aTimer) { - this.updateAllStats(); - }, - - /* - * nsINetworkStatsService - */ - getRilNetworks: function() { - let networks = {}; - let numRadioInterfaces = gRil.numRadioInterfaces; - for (let i = 0; i < numRadioInterfaces; i++) { - let icc = gIccService.getIccByServiceId(i); - let radioInterface = gRil.getRadioInterface(i); - if (icc && icc.iccInfo) { - let netId = this.getNetworkId(icc.iccInfo.iccid, - NET_TYPE_MOBILE); - networks[netId] = { id : icc.iccInfo.iccid, - type: NET_TYPE_MOBILE }; - } - } - return networks; - }, - - convertNetworkInfo: function(aNetworkInfo) { - if (aNetworkInfo.type != NET_TYPE_MOBILE && - aNetworkInfo.type != NET_TYPE_WIFI) { - return null; - } - - let id = '0'; - if (aNetworkInfo.type == NET_TYPE_MOBILE) { - if (!(aNetworkInfo instanceof Ci.nsIRilNetworkInfo)) { - debug("Error! Mobile network should be an nsIRilNetworkInfo!"); - return null; - } - - let rilNetwork = aNetworkInfo.QueryInterface(Ci.nsIRilNetworkInfo); - id = rilNetwork.iccId; - } - - let netId = this.getNetworkId(id, aNetworkInfo.type); - - if (!this._networks[netId]) { - this._networks[netId] = Object.create(null); - this._networks[netId].network = { id: id, - type: aNetworkInfo.type }; - } - - this._networks[netId].status = NETWORK_STATUS_READY; - this._networks[netId].interfaceName = aNetworkInfo.name; - return netId; - }, - - getNetworkId: function getNetworkId(aIccId, aNetworkType) { - return aIccId + '' + aNetworkType; - }, - - /* Function to ensure that one network is valid. The network is valid if its status is - * NETWORK_STATUS_READY, NETWORK_STATUS_STANDBY or NETWORK_STATUS_AWAY. - * - * The result is |netId| or null in case of a non-valid network - * aCallback is signatured as |function(netId)|. - */ - validateNetwork: function validateNetwork(aNetwork, aCallback) { - let netId = this.getNetworkId(aNetwork.id, aNetwork.type); - - if (this._networks[netId]) { - aCallback(netId); - return; - } - - // Check if network is valid (RIL entry) but has not established a connection yet. - // If so add to networks list with empty interfaceName. - let rilNetworks = this.getRilNetworks(); - if (rilNetworks[netId]) { - this._networks[netId] = Object.create(null); - this._networks[netId].network = rilNetworks[netId]; - this._networks[netId].status = NETWORK_STATUS_STANDBY; - this._currentAlarms[netId] = Object.create(null); - aCallback(netId); - return; - } - - // Check if network is available in the DB. - this._db.isNetworkAvailable(aNetwork, function(aError, aResult) { - if (aResult) { - this._networks[netId] = Object.create(null); - this._networks[netId].network = aNetwork; - this._networks[netId].status = NETWORK_STATUS_AWAY; - this._currentAlarms[netId] = Object.create(null); - aCallback(netId); - return; - } - - aCallback(null); - }.bind(this)); - }, - - getAvailableNetworks: function getAvailableNetworks(mm, msg) { - let self = this; - let rilNetworks = this.getRilNetworks(); - this._db.getAvailableNetworks(function onGetNetworks(aError, aResult) { - - // Also return the networks that are valid but have not - // established connections yet. - for (let netId in rilNetworks) { - let found = false; - for (let i = 0; i < aResult.length; i++) { - if (netId == self.getNetworkId(aResult[i].id, aResult[i].type)) { - found = true; - break; - } - } - if (!found) { - aResult.push(rilNetworks[netId]); - } - } - - mm.sendAsyncMessage("NetworkStats:GetAvailableNetworks:Return", - { id: msg.id, error: aError, result: aResult }); - }); - }, - - getAvailableServiceTypes: function getAvailableServiceTypes(mm, msg) { - this._db.getAvailableServiceTypes(function onGetServiceTypes(aError, aResult) { - mm.sendAsyncMessage("NetworkStats:GetAvailableServiceTypes:Return", - { id: msg.id, error: aError, result: aResult }); - }); - }, - - initAlarms: function initAlarms() { - debug("Init usage alarms"); - let self = this; - - for (let netId in this._networks) { - this._currentAlarms[netId] = Object.create(null); - - this._db.getFirstAlarm(netId, function getResult(error, result) { - if (!error && result) { - self._setAlarm(result, function onSet(error, success) { - if (error == "InvalidStateError") { - self._fireAlarm(result); - } - }); - } - }); - } - }, - - /* - * Function called from manager to get stats from database. - * In order to return updated stats, first is performed a call to - * updateAllStats function, which will get last stats from netd - * and update the database. - * Then, depending on the request (stats per appId or total stats) - * it retrieve them from database and return to the manager. - */ - getSamples: function getSamples(mm, msg) { - let network = msg.network; - let netId = this.getNetworkId(network.id, network.type); - - let appId = 0; - let appManifestURL = msg.appManifestURL; - if (appManifestURL) { - appId = appsService.getAppLocalIdByManifestURL(appManifestURL); - - if (!appId) { - mm.sendAsyncMessage("NetworkStats:Get:Return", - { id: msg.id, - error: "Invalid appManifestURL", result: null }); - return; - } - } - - let browsingTrafficOnly = msg.browsingTrafficOnly || false; - let serviceType = msg.serviceType || ""; - - let start = new Date(msg.start); - let end = new Date(msg.end); - - let callback = (function (aError, aResult) { - this._db.find(function onStatsFound(aError, aResult) { - mm.sendAsyncMessage("NetworkStats:Get:Return", - { id: msg.id, error: aError, result: aResult }); - }, appId, browsingTrafficOnly, serviceType, network, start, end, appManifestURL); - }).bind(this); - - this.validateNetwork(network, function onValidateNetwork(aNetId) { - if (!aNetId) { - mm.sendAsyncMessage("NetworkStats:Get:Return", - { id: msg.id, error: "Invalid connectionType", result: null }); - return; - } - - // If network is currently active we need to update the cached stats first before - // retrieving stats from the DB. - if (this._networks[aNetId].status == NETWORK_STATUS_READY) { - debug("getstats for network " + network.id + " of type " + network.type); - debug("appId: " + appId + " from appManifestURL: " + appManifestURL); - debug("browsingTrafficOnly: " + browsingTrafficOnly); - debug("serviceType: " + serviceType); - - if (appId || serviceType) { - this.updateCachedStats(callback); - return; - } - - this.updateStats(aNetId, function onStatsUpdated(aResult, aMessage) { - this.updateCachedStats(callback); - }.bind(this)); - return; - } - - // Network not active, so no need to update - this._db.find(function onStatsFound(aError, aResult) { - mm.sendAsyncMessage("NetworkStats:Get:Return", - { id: msg.id, error: aError, result: aResult }); - }, appId, browsingTrafficOnly, serviceType, network, start, end, appManifestURL); - }.bind(this)); - }, - - clearInterfaceStats: function clearInterfaceStats(mm, msg) { - let self = this; - let network = msg.network; - - debug("clear stats for network " + network.id + " of type " + network.type); - - this.validateNetwork(network, function onValidateNetwork(aNetId) { - if (!aNetId) { - mm.sendAsyncMessage("NetworkStats:Clear:Return", - { id: msg.id, error: "Invalid connectionType", result: null }); - return; - } - - network = {network: network, networkId: aNetId}; - self.updateStats(aNetId, function onUpdate(aResult, aMessage) { - if (!aResult) { - mm.sendAsyncMessage("NetworkStats:Clear:Return", - { id: msg.id, error: aMessage, result: null }); - return; - } - - self._db.clearInterfaceStats(network, function onDBCleared(aError, aResult) { - self._updateCurrentAlarm(aNetId); - mm.sendAsyncMessage("NetworkStats:Clear:Return", - { id: msg.id, error: aError, result: aResult }); - }); - }); - }); - }, - - clearDB: function clearDB(mm, msg) { - let self = this; - this._db.getAvailableNetworks(function onGetNetworks(aError, aResult) { - if (aError) { - mm.sendAsyncMessage("NetworkStats:ClearAll:Return", - { id: msg.id, error: aError, result: aResult }); - return; - } - - let networks = aResult; - networks.forEach(function(network, index) { - networks[index] = {network: network, networkId: self.getNetworkId(network.id, network.type)}; - }, self); - - self.updateAllStats(function onUpdate(aResult, aMessage){ - if (!aResult) { - mm.sendAsyncMessage("NetworkStats:ClearAll:Return", - { id: msg.id, error: aMessage, result: null }); - return; - } - - self._db.clearStats(networks, function onDBCleared(aError, aResult) { - networks.forEach(function(network, index) { - self._updateCurrentAlarm(network.networkId); - }, self); - mm.sendAsyncMessage("NetworkStats:ClearAll:Return", - { id: msg.id, error: aError, result: aResult }); - }); - }); - }); - }, - - updateAllStats: function updateAllStats(aCallback) { - let elements = []; - let lastElement = null; - let callback = (function (success, message) { - this.updateCachedStats(aCallback); - }).bind(this); - - // For each connectionType create an object containning the type - // and the 'queueIndex', the 'queueIndex' is an integer representing - // the index of a connection type in the global queue array. So, if - // the connection type is already in the queue it is not appended again, - // else it is pushed in 'elements' array, which later will be pushed to - // the queue array. - for (let netId in this._networks) { - if (this._networks[netId].status != NETWORK_STATUS_READY) { - continue; - } - - lastElement = { netId: netId, - queueIndex: this.updateQueueIndex(netId) }; - - if (lastElement.queueIndex == -1) { - elements.push({ netId: lastElement.netId, - callbacks: [], - queueType: QUEUE_TYPE_UPDATE_STATS }); - } - } - - if (!lastElement) { - // No elements need to be updated, probably because status is different than - // NETWORK_STATUS_READY. - if (aCallback) { - aCallback(true, "OK"); - } - return; - } - - if (elements.length > 0) { - // If length of elements is greater than 0, callback is set to - // the last element. - elements[elements.length - 1].callbacks.push(callback); - this.updateQueue = this.updateQueue.concat(elements); - } else { - // Else, it means that all connection types are already in the queue to - // be updated, so callback for this request is added to - // the element in the main queue with the index of the last 'lastElement'. - // But before is checked that element is still in the queue because it can - // be processed while generating 'elements' array. - let element = this.updateQueue[lastElement.queueIndex]; - if (aCallback && - (!element || element.netId != lastElement.netId)) { - aCallback(); - return; - } - - this.updateQueue[lastElement.queueIndex].callbacks.push(callback); - } - - // Call the function that process the elements of the queue. - this.processQueue(); - - if (DEBUG) { - this.logAllRecords(); - } - }, - - updateStats: function updateStats(aNetId, aCallback) { - // Check if the connection is in the main queue, push a new element - // if it is not being processed or add a callback if it is. - let index = this.updateQueueIndex(aNetId); - if (index == -1) { - this.updateQueue.push({ netId: aNetId, - callbacks: [aCallback], - queueType: QUEUE_TYPE_UPDATE_STATS }); - } else { - this.updateQueue[index].callbacks.push(aCallback); - return; - } - - // Call the function that process the elements of the queue. - this.processQueue(); - }, - - /* - * Find if a connection is in the main queue array and return its - * index, if it is not in the array return -1. - */ - updateQueueIndex: function updateQueueIndex(aNetId) { - return this.updateQueue.map(function(e) { return e.netId; }).indexOf(aNetId); - }, - - /* - * Function responsible of process all requests in the queue. - */ - processQueue: function processQueue(aResult, aMessage) { - // If aResult is not undefined, the caller of the function is the result - // of processing an element, so remove that element and call the callbacks - // it has. - let self = this; - - if (aResult != undefined) { - let item = this.updateQueue.shift(); - for (let callback of item.callbacks) { - if (callback) { - callback(aResult, aMessage); - } - } - } else { - // The caller is a function that has pushed new elements to the queue, - // if isQueueRunning is false it means there is no processing currently - // being done, so start. - if (this.isQueueRunning) { - return; - } else { - this.isQueueRunning = true; - } - } - - // Check length to determine if queue is empty and stop processing. - if (this.updateQueue.length < 1) { - this.isQueueRunning = false; - return; - } - - // Process the next item as soon as possible. - setTimeout(function () { - self.run(self.updateQueue[0]); - }, 0); - }, - - run: function run(item) { - switch (item.queueType) { - case QUEUE_TYPE_UPDATE_STATS: - this.update(item.netId, this.processQueue.bind(this)); - break; - case QUEUE_TYPE_UPDATE_CACHE: - this.updateCache(this.processQueue.bind(this)); - break; - case QUEUE_TYPE_WRITE_CACHE: - this.writeCache(item.stats, this.processQueue.bind(this)); - break; - } - }, - - update: function update(aNetId, aCallback) { - // Check if connection type is valid. - if (!this._networks[aNetId]) { - if (aCallback) { - aCallback(false, "Invalid network " + aNetId); - } - return; - } - - let interfaceName = this._networks[aNetId].interfaceName; - debug("Update stats for " + interfaceName); - - // Request stats to NetworkService, which will get stats from netd, passing - // 'networkStatsAvailable' as a callback. - if (interfaceName) { - networkService.getNetworkInterfaceStats(interfaceName, - this.networkStatsAvailable.bind(this, aCallback, aNetId)); - return; - } - - if (aCallback) { - aCallback(true, "ok"); - } - }, - - /* - * Callback of request stats. Store stats in database. - */ - networkStatsAvailable: function networkStatsAvailable(aCallback, aNetId, - aResult, aRxBytes, - aTxBytes, aTimestamp) { - if (!aResult) { - if (aCallback) { - aCallback(false, "Netd IPC error"); - } - return; - } - - let stats = { appId: 0, - isInBrowser: false, - serviceType: "", - networkId: this._networks[aNetId].network.id, - networkType: this._networks[aNetId].network.type, - date: new Date(aTimestamp), - rxBytes: aTxBytes, - txBytes: aRxBytes, - isAccumulative: true }; - - debug("Update stats for: " + JSON.stringify(stats)); - - this._db.saveStats(stats, function onSavedStats(aError, aResult) { - if (aCallback) { - if (aError) { - aCallback(false, aError); - return; - } - - aCallback(true, "OK"); - } - }); - }, - - /* - * Function responsible for receiving stats which are not from netd. - */ - saveStats: function saveStats(aAppId, aIsInIsolatedMozBrowser, aServiceType, - aNetworkInfo, aTimeStamp, aRxBytes, aTxBytes, - aIsAccumulative, aCallback) { - let netId = this.convertNetworkInfo(aNetworkInfo); - if (!netId) { - if (aCallback) { - aCallback(false, "Invalid network type"); - } - return; - } - - // Check if |aConnectionType|, |aAppId| and |aServiceType| are valid. - // There are two invalid cases for the combination of |aAppId| and - // |aServiceType|: - // a. Both |aAppId| is non-zero and |aServiceType| is non-empty. - // b. Both |aAppId| is zero and |aServiceType| is empty. - if (!this._networks[netId] || (aAppId && aServiceType) || - (!aAppId && !aServiceType)) { - debug("Invalid network interface, appId or serviceType"); - return; - } - - let stats = { appId: aAppId, - isInBrowser: aIsInIsolatedMozBrowser, - serviceType: aServiceType, - networkId: this._networks[netId].network.id, - networkType: this._networks[netId].network.type, - date: new Date(aTimeStamp), - rxBytes: aRxBytes, - txBytes: aTxBytes, - isAccumulative: aIsAccumulative }; - - this.updateQueue.push({ stats: stats, - callbacks: [aCallback], - queueType: QUEUE_TYPE_WRITE_CACHE }); - - this.processQueue(); - }, - - /* - * - */ - writeCache: function writeCache(aStats, aCallback) { - debug("saveStats: " + aStats.appId + " " + aStats.isInBrowser + " " + - aStats.serviceType + " " + aStats.networkId + " " + - aStats.networkType + " " + aStats.date + " " + - aStats.rxBytes + " " + aStats.txBytes); - - // Generate an unique key from |appId|, |isInBrowser|, |serviceType| and - // |netId|, which is used to retrieve data in |cachedStats|. - let netId = this.getNetworkId(aStats.networkId, aStats.networkType); - let key = aStats.appId + "" + aStats.isInBrowser + "" + - aStats.serviceType + "" + netId; - - // |cachedStats| only keeps the data with the same date. - // If the incoming date is different from |cachedStatsDate|, - // both |cachedStats| and |cachedStatsDate| will get updated. - let diff = (this._db.normalizeDate(aStats.date) - - this._db.normalizeDate(this.cachedStatsDate)) / - this._db.sampleRate; - if (diff != 0) { - this.updateCache(function onUpdated(success, message) { - this.cachedStatsDate = aStats.date; - this.cachedStats[key] = aStats; - - if (aCallback) { - aCallback(true, "ok"); - } - }.bind(this)); - return; - } - - // Try to find the matched row in the cached by |appId| and |connectionType|. - // If not found, save the incoming data into the cached. - let cachedStats = this.cachedStats[key]; - if (!cachedStats) { - this.cachedStats[key] = aStats; - if (aCallback) { - aCallback(true, "ok"); - } - return; - } - - // Find matched row, accumulate the traffic amount. - cachedStats.rxBytes += aStats.rxBytes; - cachedStats.txBytes += aStats.txBytes; - - // If new rxBytes or txBytes exceeds MAX_CACHED_TRAFFIC - // the corresponding row will be saved to indexedDB. - // Then, the row will be removed from the cached. - if (cachedStats.rxBytes > MAX_CACHED_TRAFFIC || - cachedStats.txBytes > MAX_CACHED_TRAFFIC) { - this._db.saveStats(cachedStats, function (error, result) { - debug("Application stats inserted in indexedDB"); - if (aCallback) { - aCallback(true, "ok"); - } - }); - delete this.cachedStats[key]; - return; - } - - if (aCallback) { - aCallback(true, "ok"); - } - }, - - updateCachedStats: function updateCachedStats(aCallback) { - this.updateQueue.push({ callbacks: [aCallback], - queueType: QUEUE_TYPE_UPDATE_CACHE }); - - this.processQueue(); - }, - - updateCache: function updateCache(aCallback) { - debug("updateCache: " + this.cachedStatsDate); - - let stats = Object.keys(this.cachedStats); - if (stats.length == 0) { - // |cachedStats| is empty, no need to update. - if (aCallback) { - aCallback(true, "no need to update"); - } - return; - } - - let index = 0; - this._db.saveStats(this.cachedStats[stats[index]], - function onSavedStats(error, result) { - debug("Application stats inserted in indexedDB"); - - // Clean up the |cachedStats| after updating. - if (index == stats.length - 1) { - this.cachedStats = Object.create(null); - - if (aCallback) { - aCallback(true, "ok"); - } - return; - } - - // Update is not finished, keep updating. - index += 1; - this._db.saveStats(this.cachedStats[stats[index]], - onSavedStats.bind(this, error, result)); - }.bind(this)); - }, - - get maxCachedTraffic () { - return MAX_CACHED_TRAFFIC; - }, - - logAllRecords: function logAllRecords() { - this._db.logAllRecords(function onResult(aError, aResult) { - if (aError) { - debug("Error: " + aError); - return; - } - - debug("===== LOG ====="); - debug("There are " + aResult.length + " items"); - debug(JSON.stringify(aResult)); - }); - }, - - getAlarms: function getAlarms(mm, msg) { - let self = this; - let network = msg.data.network; - let manifestURL = msg.data.manifestURL; - - if (network) { - this.validateNetwork(network, function onValidateNetwork(aNetId) { - if (!aNetId) { - mm.sendAsyncMessage("NetworkStats:GetAlarms:Return", - { id: msg.id, error: "InvalidInterface", result: null }); - return; - } - - self._getAlarms(mm, msg, aNetId, manifestURL); - }); - return; - } - - this._getAlarms(mm, msg, null, manifestURL); - }, - - _getAlarms: function _getAlarms(mm, msg, aNetId, aManifestURL) { - let self = this; - this._db.getAlarms(aNetId, aManifestURL, function onCompleted(error, result) { - if (error) { - mm.sendAsyncMessage("NetworkStats:GetAlarms:Return", - { id: msg.id, error: error, result: result }); - return; - } - - let alarms = [] - // NetworkStatsManager must return the network instead of the networkId. - for (let i = 0; i < result.length; i++) { - let alarm = result[i]; - alarms.push({ id: alarm.id, - network: self._networks[alarm.networkId].network, - threshold: alarm.absoluteThreshold, - data: alarm.data }); - } - - mm.sendAsyncMessage("NetworkStats:GetAlarms:Return", - { id: msg.id, error: null, result: alarms }); - }); - }, - - removeAlarms: function removeAlarms(mm, msg) { - let alarmId = msg.data.alarmId; - let manifestURL = msg.data.manifestURL; - - let self = this; - let callback = function onRemove(error, result) { - if (error) { - mm.sendAsyncMessage("NetworkStats:RemoveAlarms:Return", - { id: msg.id, error: error, result: result }); - return; - } - - for (let i in self._currentAlarms) { - let currentAlarm = self._currentAlarms[i].alarm; - if (currentAlarm && ((alarmId == currentAlarm.id) || - (alarmId == -1 && currentAlarm.manifestURL == manifestURL))) { - - self._updateCurrentAlarm(currentAlarm.networkId); - } - } - - mm.sendAsyncMessage("NetworkStats:RemoveAlarms:Return", - { id: msg.id, error: error, result: true }); - }; - - if (alarmId == -1) { - this._db.removeAlarms(manifestURL, callback); - } else { - this._db.removeAlarm(alarmId, manifestURL, callback); - } - }, - - /* - * Function called from manager to set an alarm. - */ - setAlarm: function setAlarm(mm, msg) { - let options = msg.data; - let network = options.network; - let threshold = options.threshold; - - debug("Set alarm at " + threshold + " for " + JSON.stringify(network)); - - if (threshold < 0) { - mm.sendAsyncMessage("NetworkStats:SetAlarm:Return", - { id: msg.id, error: "InvalidThresholdValue", result: null }); - return; - } - - let self = this; - this.validateNetwork(network, function onValidateNetwork(aNetId) { - if (!aNetId) { - mm.sendAsyncMessage("NetworkStats:SetAlarm:Return", - { id: msg.id, error: "InvalidiConnectionType", result: null }); - return; - } - - let newAlarm = { - id: null, - networkId: aNetId, - absoluteThreshold: threshold, - relativeThreshold: null, - startTime: options.startTime, - data: options.data, - pageURL: options.pageURL, - manifestURL: options.manifestURL - }; - - self._getAlarmQuota(newAlarm, function onUpdate(error, quota) { - if (error) { - mm.sendAsyncMessage("NetworkStats:SetAlarm:Return", - { id: msg.id, error: error, result: null }); - return; - } - - self._db.addAlarm(newAlarm, function addSuccessCb(error, newId) { - if (error) { - mm.sendAsyncMessage("NetworkStats:SetAlarm:Return", - { id: msg.id, error: error, result: null }); - return; - } - - newAlarm.id = newId; - self._setAlarm(newAlarm, function onSet(error, success) { - mm.sendAsyncMessage("NetworkStats:SetAlarm:Return", - { id: msg.id, error: error, result: newId }); - - if (error == "InvalidStateError") { - self._fireAlarm(newAlarm); - } - }); - }); - }); - }); - }, - - _setAlarm: function _setAlarm(aAlarm, aCallback) { - let currentAlarm = this._currentAlarms[aAlarm.networkId]; - if ((Object.getOwnPropertyNames(currentAlarm).length !== 0 && - aAlarm.relativeThreshold > currentAlarm.alarm.relativeThreshold) || - this._networks[aAlarm.networkId].status != NETWORK_STATUS_READY) { - aCallback(null, true); - return; - } - - let self = this; - - this._getAlarmQuota(aAlarm, function onUpdate(aError, aQuota) { - if (aError) { - aCallback(aError, null); - return; - } - - let callback = function onAlarmSet(aError) { - if (aError) { - debug("Set alarm error: " + aError); - aCallback("netdError", null); - return; - } - - self._currentAlarms[aAlarm.networkId].alarm = aAlarm; - - aCallback(null, true); - }; - - debug("Set alarm " + JSON.stringify(aAlarm)); - let interfaceName = self._networks[aAlarm.networkId].interfaceName; - if (interfaceName) { - networkService.setNetworkInterfaceAlarm(interfaceName, - aQuota, - callback); - return; - } - - aCallback(null, true); - }); - }, - - _getAlarmQuota: function _getAlarmQuota(aAlarm, aCallback) { - let self = this; - this.updateStats(aAlarm.networkId, function onStatsUpdated(aResult, aMessage) { - self._db.getCurrentStats(self._networks[aAlarm.networkId].network, - aAlarm.startTime, - function onStatsFound(error, result) { - if (error) { - debug("Error getting stats for " + - JSON.stringify(self._networks[aAlarm.networkId]) + ": " + error); - aCallback(error, result); - return; - } - - let quota = aAlarm.absoluteThreshold - result.rxBytes - result.txBytes; - - // Alarm set to a threshold lower than current rx/tx bytes. - if (quota <= 0) { - aCallback("InvalidStateError", null); - return; - } - - aAlarm.relativeThreshold = aAlarm.startTime - ? result.rxTotalBytes + result.txTotalBytes + quota - : aAlarm.absoluteThreshold; - - aCallback(null, quota); - }); - }); - }, - - _fireAlarm: function _fireAlarm(aAlarm) { - debug("Fire alarm"); - - let self = this; - this._db.removeAlarm(aAlarm.id, null, function onRemove(aError, aResult){ - if (!aError && !aResult) { - return; - } - - self._fireSystemMessage(aAlarm); - self._updateCurrentAlarm(aAlarm.networkId); - }); - }, - - _updateCurrentAlarm: function _updateCurrentAlarm(aNetworkId) { - this._currentAlarms[aNetworkId] = Object.create(null); - - let self = this; - this._db.getFirstAlarm(aNetworkId, function onGet(error, result){ - if (error) { - debug("Error getting the first alarm"); - return; - } - - if (!result) { - let interfaceName = self._networks[aNetworkId].interfaceName; - networkService.setNetworkInterfaceAlarm(interfaceName, -1, - function onComplete(){}); - return; - } - - self._setAlarm(result, function onSet(error, success){ - if (error == "InvalidStateError") { - self._fireAlarm(result); - return; - } - }); - }); - }, - - _fireSystemMessage: function _fireSystemMessage(aAlarm) { - debug("Fire system message: " + JSON.stringify(aAlarm)); - - let manifestURI = Services.io.newURI(aAlarm.manifestURL, null, null); - let pageURI = Services.io.newURI(aAlarm.pageURL, null, null); - - let alarm = { "id": aAlarm.id, - "threshold": aAlarm.absoluteThreshold, - "data": aAlarm.data }; - messenger.sendMessage("networkstats-alarm", alarm, pageURI, manifestURI); - } -}; - -NetworkStatsService.init(); diff --git a/dom/network/NetworkStatsServiceProxy.js b/dom/network/NetworkStatsServiceProxy.js deleted file mode 100644 index f3df4344d..000000000 --- a/dom/network/NetworkStatsServiceProxy.js +++ /dev/null @@ -1,90 +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 DEBUG = false; -function debug(s) { dump("-*- NetworkStatsServiceProxy: " + s + "\n"); } - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -this.EXPORTED_SYMBOLS = ["NetworkStatsServiceProxy"]; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/NetworkStatsService.jsm"); - -const NETWORKSTATSSERVICEPROXY_CONTRACTID = "@mozilla.org/networkstatsServiceProxy;1"; -const NETWORKSTATSSERVICEPROXY_CID = Components.ID("98fd8f69-784e-4626-aa59-56d6436a3c24"); -const nsINetworkStatsServiceProxy = Ci.nsINetworkStatsServiceProxy; - -function NetworkStatsServiceProxy() { - if (DEBUG) { - debug("Proxy started"); - } -} - -NetworkStatsServiceProxy.prototype = { - /* - * Function called in the protocol layer (HTTP, FTP, WebSocket ...etc) - * to pass the per-app stats to NetworkStatsService. - */ - saveAppStats: function saveAppStats(aAppId, aIsInIsolatedMozBrowser, aNetworkInfo, aTimeStamp, - aRxBytes, aTxBytes, aIsAccumulative, - aCallback) { - if (!aNetworkInfo) { - if (DEBUG) { - debug("|aNetworkInfo| is not specified. Failed to save stats. Returning."); - } - return; - } - - if (DEBUG) { - debug("saveAppStats: " + aAppId + " " + aIsInIsolatedMozBrowser + " " + - aNetworkInfo.type + " " + aTimeStamp + " " + - aRxBytes + " " + aTxBytes + " " + aIsAccumulative); - } - - if (aCallback) { - aCallback = aCallback.notify; - } - - NetworkStatsService.saveStats(aAppId, aIsInIsolatedMozBrowser, "", aNetworkInfo, - aTimeStamp, aRxBytes, aTxBytes, - aIsAccumulative, aCallback); - }, - - /* - * Function called in the points of different system services - * to pass the per-service stats to NetworkStatsService. - */ - saveServiceStats: function saveServiceStats(aServiceType, aNetworkInfo, - aTimeStamp, aRxBytes, aTxBytes, - aIsAccumulative, aCallback) { - if (!aNetworkInfo) { - if (DEBUG) { - debug("|aNetworkInfo| is not specified. Failed to save stats. Returning."); - } - return; - } - - if (DEBUG) { - debug("saveServiceStats: " + aServiceType + " " + aNetworkInfo.type + " " + - aTimeStamp + " " + aRxBytes + " " + aTxBytes + " " + - aIsAccumulative); - } - - if (aCallback) { - aCallback = aCallback.notify; - } - - NetworkStatsService.saveStats(0, false, aServiceType , aNetworkInfo, aTimeStamp, - aRxBytes, aTxBytes, aIsAccumulative, - aCallback); - }, - - classID : NETWORKSTATSSERVICEPROXY_CID, - QueryInterface : XPCOMUtils.generateQI([nsINetworkStatsServiceProxy]), -} - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([NetworkStatsServiceProxy]); diff --git a/dom/network/NetworkStatsServiceProxy.manifest b/dom/network/NetworkStatsServiceProxy.manifest deleted file mode 100644 index 24f09f088..000000000 --- a/dom/network/NetworkStatsServiceProxy.manifest +++ /dev/null @@ -1,2 +0,0 @@ -component {98fd8f69-784e-4626-aa59-56d6436a3c24} NetworkStatsServiceProxy.js -contract @mozilla.org/networkstatsServiceProxy;1 {98fd8f69-784e-4626-aa59-56d6436a3c24} diff --git a/dom/network/interfaces/moz.build b/dom/network/interfaces/moz.build index add687542..ad2e56bd6 100644 --- a/dom/network/interfaces/moz.build +++ b/dom/network/interfaces/moz.build @@ -10,10 +10,4 @@ XPIDL_SOURCES += [ 'nsIUDPSocketChild.idl', ] -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': - XPIDL_SOURCES += [ - 'nsIEthernetManager.idl', - 'nsINetworkStatsServiceProxy.idl', - ] - XPIDL_MODULE = 'dom_network' diff --git a/dom/network/interfaces/nsIEthernetManager.idl b/dom/network/interfaces/nsIEthernetManager.idl deleted file mode 100644 index 2b92dc88f..000000000 --- a/dom/network/interfaces/nsIEthernetManager.idl +++ /dev/null @@ -1,137 +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" - -[scriptable, function, uuid(2a3ad56c-edc0-439f-8aae-900b331ddf49)] -interface nsIEthernetManagerCallback : nsISupports -{ - /** - * Callback function used to report the success of different operations. - * - * @param success - * Boolean value indicates the success of an operation. - * @prarm message - * Message reported in the end of operation. - */ - void notify(in boolean success, in DOMString message); -}; - -[scriptable, function, uuid(1746e7dd-92d4-43fa-8ef4-bc13d0b60353)] -interface nsIEthernetManagerScanCallback : nsISupports -{ - /** - * Callback function used to report the result of scan function. - * - * @param list - * List of available ethernet interfaces. - */ - void notify(in jsval list); -}; - -/** - * An internal idl provides control to ethernet interfaces. - */ -[scriptable, uuid(81750c87-bb3b-4724-b955-834eafa53fd1)] -interface nsIEthernetManager : nsISupports -{ - /** - * List of exisiting interface name. - */ - readonly attribute jsval interfaceList; - - /** - * Scan available ethernet interfaces on device. - * - * @param callback - * Callback function. - */ - void scan(in nsIEthernetManagerScanCallback callback); - - /** - * Add a new interface to the interface list. - * - * @param ifname - * Interface name. Should be the form of "eth*". - * @param callback - * Callback function. - */ - void addInterface(in DOMString ifname, - in nsIEthernetManagerCallback callback); - - /** - * Remove an existing interface from the interface list. - * - * @param ifname - * Interface name. - * @param Callback - * Callback function. - */ - void removeInterface(in DOMString ifname, - in nsIEthernetManagerCallback callback); - - /** - * Update a conifg of an existing interface in the interface list. - * - * @param ifname - * Interface name. - * @param config - * .ip: IP address. - * .prefixLength: Mask length. - * .gateway: Gateway. - * .dnses: DNS addresses. - * .httpProxyHost: HTTP proxy host. - * .httpProxyPort: HTTP proxy port. - * .ipMode: IP mode, can be 'dhcp' or 'static'. - * @param callback - * Callback function. - */ - void updateInterfaceConfig(in DOMString ifname, - in jsval config, - in nsIEthernetManagerCallback callback); - - /** - * Enable networking of an existing interface in the interface list. - * - * @param ifname - * Interface name. - * @param callback - * Callback function. - */ - void enable(in DOMString ifname, - in nsIEthernetManagerCallback callback); - - /** - * Disable networking of an existing interface in the interface list. - * - * @param ifname - * Interface name. - * @param callback - * Callback function. - */ - void disable(in DOMString ifname, - in nsIEthernetManagerCallback callback); - - /** - * Make an existing interface connect to network. - * - * @param ifname - * Interface name. - * @param callback - * Callback function. - */ - void connect(in DOMString ifname, - in nsIEthernetManagerCallback callback); - - /** - * Disconnect a connected interface in the interface list. - * - * @param ifname - * Interface name. - * @param callback - * Callback function. - */ - void disconnect(in DOMString ifname, - in nsIEthernetManagerCallback callback); -}; diff --git a/dom/network/interfaces/nsINetworkStatsServiceProxy.idl b/dom/network/interfaces/nsINetworkStatsServiceProxy.idl deleted file mode 100644 index cd6765c68..000000000 --- a/dom/network/interfaces/nsINetworkStatsServiceProxy.idl +++ /dev/null @@ -1,64 +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 nsINetworkInfo; - -[scriptable, function, uuid(5f821529-1d80-4ab5-a933-4e1b3585b6bc)] -interface nsINetworkStatsServiceProxyCallback : nsISupports -{ - /* - * @param aResult callback result with boolean value - * @param aMessage message - */ - void notify(in boolean aResult, in jsval aMessage); -}; - -[scriptable, uuid(f4f3e901-e102-499d-9d37-dc9951f52df7)] -interface nsINetworkStatsServiceProxy : nsISupports -{ - /* - * An interface used to record per-app traffic data. - * @param aAppId app id - * @param aIsInIsolatedMozBrowser - * true if the frame is an isolated mozbrowser element.