@webex/plugin-meetings 3.0.0-beta.26 → 3.0.0-beta.261

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (361) hide show
  1. package/README.md +46 -8
  2. package/dist/annotation/annotation.types.js +7 -0
  3. package/dist/annotation/annotation.types.js.map +1 -0
  4. package/dist/annotation/constants.js +49 -0
  5. package/dist/annotation/constants.js.map +1 -0
  6. package/dist/annotation/index.js +342 -0
  7. package/dist/annotation/index.js.map +1 -0
  8. package/dist/breakouts/breakout.js +114 -14
  9. package/dist/breakouts/breakout.js.map +1 -1
  10. package/dist/breakouts/edit-lock-error.js +52 -0
  11. package/dist/breakouts/edit-lock-error.js.map +1 -0
  12. package/dist/breakouts/events.js +45 -0
  13. package/dist/breakouts/events.js.map +1 -0
  14. package/dist/breakouts/index.js +841 -19
  15. package/dist/breakouts/index.js.map +1 -1
  16. package/dist/breakouts/request.js +78 -0
  17. package/dist/breakouts/request.js.map +1 -0
  18. package/dist/breakouts/utils.js +67 -0
  19. package/dist/breakouts/utils.js.map +1 -0
  20. package/dist/common/errors/webex-errors.js +28 -7
  21. package/dist/common/errors/webex-errors.js.map +1 -1
  22. package/dist/common/logs/logger-proxy.js +1 -1
  23. package/dist/common/logs/logger-proxy.js.map +1 -1
  24. package/dist/common/queue.js +24 -9
  25. package/dist/common/queue.js.map +1 -1
  26. package/dist/config.js +5 -10
  27. package/dist/config.js.map +1 -1
  28. package/dist/constants.js +196 -28
  29. package/dist/constants.js.map +1 -1
  30. package/dist/controls-options-manager/enums.js +14 -2
  31. package/dist/controls-options-manager/enums.js.map +1 -1
  32. package/dist/controls-options-manager/index.js +109 -15
  33. package/dist/controls-options-manager/index.js.map +1 -1
  34. package/dist/controls-options-manager/types.js +7 -0
  35. package/dist/controls-options-manager/types.js.map +1 -0
  36. package/dist/controls-options-manager/util.js +309 -18
  37. package/dist/controls-options-manager/util.js.map +1 -1
  38. package/dist/index.js +112 -1
  39. package/dist/index.js.map +1 -1
  40. package/dist/interpretation/collection.js +23 -0
  41. package/dist/interpretation/collection.js.map +1 -0
  42. package/dist/interpretation/index.js +366 -0
  43. package/dist/interpretation/index.js.map +1 -0
  44. package/dist/interpretation/siLanguage.js +25 -0
  45. package/dist/interpretation/siLanguage.js.map +1 -0
  46. package/dist/locus-info/controlsUtils.js +91 -2
  47. package/dist/locus-info/controlsUtils.js.map +1 -1
  48. package/dist/locus-info/index.js +381 -62
  49. package/dist/locus-info/index.js.map +1 -1
  50. package/dist/locus-info/infoUtils.js +7 -1
  51. package/dist/locus-info/infoUtils.js.map +1 -1
  52. package/dist/locus-info/mediaSharesUtils.js +43 -1
  53. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  54. package/dist/locus-info/parser.js +224 -63
  55. package/dist/locus-info/parser.js.map +1 -1
  56. package/dist/locus-info/selfUtils.js +89 -14
  57. package/dist/locus-info/selfUtils.js.map +1 -1
  58. package/dist/media/index.js +58 -116
  59. package/dist/media/index.js.map +1 -1
  60. package/dist/media/properties.js +60 -121
  61. package/dist/media/properties.js.map +1 -1
  62. package/dist/meeting/in-meeting-actions.js +82 -2
  63. package/dist/meeting/in-meeting-actions.js.map +1 -1
  64. package/dist/meeting/index.js +3022 -2795
  65. package/dist/meeting/index.js.map +1 -1
  66. package/dist/meeting/locusMediaRequest.js +292 -0
  67. package/dist/meeting/locusMediaRequest.js.map +1 -0
  68. package/dist/meeting/muteState.js +230 -124
  69. package/dist/meeting/muteState.js.map +1 -1
  70. package/dist/meeting/request.js +256 -196
  71. package/dist/meeting/request.js.map +1 -1
  72. package/dist/meeting/util.js +601 -417
  73. package/dist/meeting/util.js.map +1 -1
  74. package/dist/meeting-info/index.js +70 -7
  75. package/dist/meeting-info/index.js.map +1 -1
  76. package/dist/meeting-info/meeting-info-v2.js +189 -51
  77. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  78. package/dist/meeting-info/util.js +1 -1
  79. package/dist/meeting-info/util.js.map +1 -1
  80. package/dist/meeting-info/utilv2.js +36 -36
  81. package/dist/meeting-info/utilv2.js.map +1 -1
  82. package/dist/meetings/collection.js +22 -0
  83. package/dist/meetings/collection.js.map +1 -1
  84. package/dist/meetings/index.js +372 -90
  85. package/dist/meetings/index.js.map +1 -1
  86. package/dist/meetings/meetings.types.js +7 -0
  87. package/dist/meetings/meetings.types.js.map +1 -0
  88. package/dist/meetings/request.js +2 -0
  89. package/dist/meetings/request.js.map +1 -1
  90. package/dist/meetings/util.js +88 -1
  91. package/dist/meetings/util.js.map +1 -1
  92. package/dist/member/index.js +49 -0
  93. package/dist/member/index.js.map +1 -1
  94. package/dist/member/types.js +25 -0
  95. package/dist/member/types.js.map +1 -0
  96. package/dist/member/util.js +121 -25
  97. package/dist/member/util.js.map +1 -1
  98. package/dist/members/collection.js +10 -0
  99. package/dist/members/collection.js.map +1 -1
  100. package/dist/members/index.js +86 -5
  101. package/dist/members/index.js.map +1 -1
  102. package/dist/members/request.js +106 -38
  103. package/dist/members/request.js.map +1 -1
  104. package/dist/members/types.js +15 -0
  105. package/dist/members/types.js.map +1 -0
  106. package/dist/members/util.js +316 -233
  107. package/dist/members/util.js.map +1 -1
  108. package/dist/metrics/constants.js +10 -5
  109. package/dist/metrics/constants.js.map +1 -1
  110. package/dist/metrics/index.js +1 -468
  111. package/dist/metrics/index.js.map +1 -1
  112. package/dist/multistream/mediaRequestManager.js +238 -49
  113. package/dist/multistream/mediaRequestManager.js.map +1 -1
  114. package/dist/multistream/receiveSlot.js +49 -16
  115. package/dist/multistream/receiveSlot.js.map +1 -1
  116. package/dist/multistream/receiveSlotManager.js +52 -34
  117. package/dist/multistream/receiveSlotManager.js.map +1 -1
  118. package/dist/multistream/remoteMedia.js +44 -18
  119. package/dist/multistream/remoteMedia.js.map +1 -1
  120. package/dist/multistream/remoteMediaGroup.js +60 -3
  121. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  122. package/dist/multistream/remoteMediaManager.js +209 -59
  123. package/dist/multistream/remoteMediaManager.js.map +1 -1
  124. package/dist/multistream/sendSlotManager.js +233 -0
  125. package/dist/multistream/sendSlotManager.js.map +1 -0
  126. package/dist/reachability/index.js +161 -57
  127. package/dist/reachability/index.js.map +1 -1
  128. package/dist/reachability/request.js +17 -8
  129. package/dist/reachability/request.js.map +1 -1
  130. package/dist/reconnection-manager/index.js +199 -154
  131. package/dist/reconnection-manager/index.js.map +1 -1
  132. package/dist/recording-controller/index.js +21 -2
  133. package/dist/recording-controller/index.js.map +1 -1
  134. package/dist/recording-controller/util.js +9 -8
  135. package/dist/recording-controller/util.js.map +1 -1
  136. package/dist/roap/index.js +23 -29
  137. package/dist/roap/index.js.map +1 -1
  138. package/dist/roap/request.js +112 -97
  139. package/dist/roap/request.js.map +1 -1
  140. package/dist/roap/turnDiscovery.js +96 -36
  141. package/dist/roap/turnDiscovery.js.map +1 -1
  142. package/dist/rtcMetrics/constants.js +12 -0
  143. package/dist/rtcMetrics/constants.js.map +1 -0
  144. package/dist/rtcMetrics/index.js +117 -0
  145. package/dist/rtcMetrics/index.js.map +1 -0
  146. package/dist/statsAnalyzer/index.js +51 -34
  147. package/dist/statsAnalyzer/index.js.map +1 -1
  148. package/dist/statsAnalyzer/mqaUtil.js +6 -6
  149. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  150. package/dist/types/annotation/annotation.types.d.ts +42 -0
  151. package/dist/types/annotation/constants.d.ts +31 -0
  152. package/dist/types/annotation/index.d.ts +117 -0
  153. package/dist/types/breakouts/edit-lock-error.d.ts +15 -0
  154. package/dist/types/breakouts/events.d.ts +8 -0
  155. package/dist/types/breakouts/request.d.ts +22 -0
  156. package/dist/types/breakouts/utils.d.ts +15 -0
  157. package/dist/types/common/errors/webex-errors.d.ts +13 -1
  158. package/dist/types/common/queue.d.ts +9 -7
  159. package/dist/types/config.d.ts +1 -6
  160. package/dist/types/constants.d.ts +155 -21
  161. package/dist/types/controls-options-manager/enums.d.ts +11 -1
  162. package/dist/types/controls-options-manager/index.d.ts +17 -1
  163. package/dist/types/controls-options-manager/types.d.ts +43 -0
  164. package/dist/types/controls-options-manager/util.d.ts +1 -7
  165. package/dist/types/index.d.ts +6 -4
  166. package/dist/types/interpretation/collection.d.ts +5 -0
  167. package/dist/types/interpretation/index.d.ts +5 -0
  168. package/dist/types/interpretation/siLanguage.d.ts +5 -0
  169. package/dist/types/locus-info/index.d.ts +57 -4
  170. package/dist/types/locus-info/parser.d.ts +65 -6
  171. package/dist/types/media/index.d.ts +2 -0
  172. package/dist/types/media/properties.d.ts +34 -48
  173. package/dist/types/meeting/in-meeting-actions.d.ts +82 -2
  174. package/dist/types/meeting/index.d.ts +344 -506
  175. package/dist/types/meeting/locusMediaRequest.d.ts +74 -0
  176. package/dist/types/meeting/muteState.d.ts +99 -23
  177. package/dist/types/meeting/request.d.ts +72 -43
  178. package/dist/types/meeting/util.d.ts +101 -1
  179. package/dist/types/meeting-info/index.d.ts +13 -1
  180. package/dist/types/meeting-info/meeting-info-v2.d.ts +31 -1
  181. package/dist/types/meetings/collection.d.ts +8 -0
  182. package/dist/types/meetings/index.d.ts +86 -12
  183. package/dist/types/meetings/meetings.types.d.ts +4 -0
  184. package/dist/types/member/index.d.ts +13 -0
  185. package/dist/types/member/types.d.ts +32 -0
  186. package/dist/types/members/collection.d.ts +5 -0
  187. package/dist/types/members/index.d.ts +35 -2
  188. package/dist/types/members/request.d.ts +73 -9
  189. package/dist/types/members/types.d.ts +24 -0
  190. package/dist/types/members/util.d.ts +209 -1
  191. package/dist/types/metrics/constants.d.ts +9 -4
  192. package/dist/types/metrics/index.d.ts +4 -119
  193. package/dist/types/multistream/mediaRequestManager.d.ts +73 -5
  194. package/dist/types/multistream/receiveSlot.d.ts +16 -12
  195. package/dist/types/multistream/receiveSlotManager.d.ts +19 -4
  196. package/dist/types/multistream/remoteMedia.d.ts +8 -29
  197. package/dist/types/multistream/remoteMediaGroup.d.ts +0 -9
  198. package/dist/types/multistream/remoteMediaManager.d.ts +46 -2
  199. package/dist/types/multistream/sendSlotManager.d.ts +61 -0
  200. package/dist/types/reachability/index.d.ts +44 -7
  201. package/dist/types/reachability/request.d.ts +7 -3
  202. package/dist/types/reconnection-manager/index.d.ts +9 -0
  203. package/dist/types/recording-controller/index.d.ts +15 -1
  204. package/dist/types/recording-controller/util.d.ts +5 -4
  205. package/dist/types/roap/request.d.ts +15 -11
  206. package/dist/types/roap/turnDiscovery.d.ts +18 -1
  207. package/dist/types/rtcMetrics/constants.d.ts +4 -0
  208. package/dist/types/rtcMetrics/index.d.ts +47 -0
  209. package/dist/types/statsAnalyzer/index.d.ts +6 -1
  210. package/package.json +23 -20
  211. package/src/annotation/annotation.types.ts +50 -0
  212. package/src/annotation/constants.ts +36 -0
  213. package/src/annotation/index.ts +328 -0
  214. package/src/breakouts/README.md +44 -14
  215. package/src/breakouts/breakout.ts +87 -9
  216. package/src/breakouts/edit-lock-error.ts +25 -0
  217. package/src/breakouts/events.ts +56 -0
  218. package/src/breakouts/index.ts +710 -10
  219. package/src/breakouts/request.ts +55 -0
  220. package/src/breakouts/utils.ts +57 -0
  221. package/src/common/errors/webex-errors.ts +27 -2
  222. package/src/common/logs/logger-proxy.ts +1 -1
  223. package/src/common/queue.ts +22 -8
  224. package/src/config.ts +4 -9
  225. package/src/constants.ts +178 -18
  226. package/src/controls-options-manager/enums.ts +12 -0
  227. package/src/controls-options-manager/index.ts +116 -21
  228. package/src/controls-options-manager/types.ts +59 -0
  229. package/src/controls-options-manager/util.ts +294 -14
  230. package/src/index.ts +40 -0
  231. package/src/interpretation/README.md +60 -0
  232. package/src/interpretation/collection.ts +19 -0
  233. package/src/interpretation/index.ts +332 -0
  234. package/src/interpretation/siLanguage.ts +18 -0
  235. package/src/locus-info/controlsUtils.ts +108 -0
  236. package/src/locus-info/index.ts +412 -59
  237. package/src/locus-info/infoUtils.ts +10 -2
  238. package/src/locus-info/mediaSharesUtils.ts +48 -0
  239. package/src/locus-info/parser.ts +231 -39
  240. package/src/locus-info/selfUtils.ts +81 -5
  241. package/src/media/index.ts +100 -122
  242. package/src/media/properties.ts +70 -108
  243. package/src/meeting/in-meeting-actions.ts +163 -3
  244. package/src/meeting/index.ts +2471 -2306
  245. package/src/meeting/locusMediaRequest.ts +313 -0
  246. package/src/meeting/muteState.ts +229 -131
  247. package/src/meeting/request.ts +172 -121
  248. package/src/meeting/util.ts +588 -394
  249. package/src/meeting-info/index.ts +79 -8
  250. package/src/meeting-info/meeting-info-v2.ts +168 -14
  251. package/src/meeting-info/util.ts +1 -1
  252. package/src/meeting-info/utilv2.ts +23 -23
  253. package/src/meetings/collection.ts +20 -0
  254. package/src/meetings/index.ts +414 -108
  255. package/src/meetings/meetings.types.ts +12 -0
  256. package/src/meetings/request.ts +2 -0
  257. package/src/meetings/util.ts +103 -4
  258. package/src/member/index.ts +49 -0
  259. package/src/member/types.ts +38 -0
  260. package/src/member/util.ts +127 -25
  261. package/src/members/collection.ts +8 -0
  262. package/src/members/index.ts +107 -6
  263. package/src/members/request.ts +97 -17
  264. package/src/members/types.ts +28 -0
  265. package/src/members/util.ts +319 -240
  266. package/src/metrics/constants.ts +9 -4
  267. package/src/metrics/index.ts +1 -490
  268. package/src/multistream/mediaRequestManager.ts +289 -79
  269. package/src/multistream/receiveSlot.ts +55 -18
  270. package/src/multistream/receiveSlotManager.ts +46 -24
  271. package/src/multistream/remoteMedia.ts +27 -2
  272. package/src/multistream/remoteMediaGroup.ts +59 -0
  273. package/src/multistream/remoteMediaManager.ts +148 -30
  274. package/src/multistream/sendSlotManager.ts +170 -0
  275. package/src/reachability/index.ts +165 -37
  276. package/src/reachability/request.ts +17 -8
  277. package/src/reconnection-manager/index.ts +81 -54
  278. package/src/recording-controller/index.ts +20 -3
  279. package/src/recording-controller/util.ts +26 -9
  280. package/src/roap/index.ts +23 -30
  281. package/src/roap/request.ts +100 -104
  282. package/src/roap/turnDiscovery.ts +51 -25
  283. package/src/rtcMetrics/constants.ts +3 -0
  284. package/src/rtcMetrics/index.ts +100 -0
  285. package/src/statsAnalyzer/index.ts +73 -35
  286. package/src/statsAnalyzer/mqaUtil.ts +8 -10
  287. package/test/integration/spec/converged-space-meetings.js +233 -0
  288. package/test/integration/spec/journey.js +320 -261
  289. package/test/integration/spec/space-meeting.js +76 -3
  290. package/test/unit/spec/annotation/index.ts +418 -0
  291. package/test/unit/spec/breakouts/breakout.ts +142 -24
  292. package/test/unit/spec/breakouts/edit-lock-error.ts +30 -0
  293. package/test/unit/spec/breakouts/events.ts +89 -0
  294. package/test/unit/spec/breakouts/index.ts +1545 -48
  295. package/test/unit/spec/breakouts/request.ts +104 -0
  296. package/test/unit/spec/breakouts/utils.js +72 -0
  297. package/test/unit/spec/common/queue.js +31 -2
  298. package/test/unit/spec/controls-options-manager/index.js +163 -0
  299. package/test/unit/spec/controls-options-manager/util.js +576 -60
  300. package/test/unit/spec/fixture/locus.js +1 -0
  301. package/test/unit/spec/interpretation/collection.ts +15 -0
  302. package/test/unit/spec/interpretation/index.ts +589 -0
  303. package/test/unit/spec/interpretation/siLanguage.ts +28 -0
  304. package/test/unit/spec/locus-info/controlsUtils.js +316 -43
  305. package/test/unit/spec/locus-info/index.js +1283 -33
  306. package/test/unit/spec/locus-info/infoUtils.js +37 -15
  307. package/test/unit/spec/locus-info/mediaSharesUtils.ts +22 -0
  308. package/test/unit/spec/locus-info/parser.js +62 -22
  309. package/test/unit/spec/locus-info/selfConstant.js +27 -4
  310. package/test/unit/spec/locus-info/selfUtils.js +208 -17
  311. package/test/unit/spec/media/index.ts +104 -37
  312. package/test/unit/spec/meeting/in-meeting-actions.ts +81 -3
  313. package/test/unit/spec/meeting/index.js +4095 -1913
  314. package/test/unit/spec/meeting/locusMediaRequest.ts +442 -0
  315. package/test/unit/spec/meeting/muteState.js +408 -208
  316. package/test/unit/spec/meeting/request.js +440 -45
  317. package/test/unit/spec/meeting/utils.js +679 -64
  318. package/test/unit/spec/meeting-info/index.js +293 -0
  319. package/test/unit/spec/meeting-info/meetinginfov2.js +517 -5
  320. package/test/unit/spec/meeting-info/utilv2.js +21 -0
  321. package/test/unit/spec/meetings/collection.js +14 -0
  322. package/test/unit/spec/meetings/index.js +941 -151
  323. package/test/unit/spec/meetings/utils.js +206 -2
  324. package/test/unit/spec/member/index.js +58 -4
  325. package/test/unit/spec/member/util.js +479 -35
  326. package/test/unit/spec/members/index.js +319 -1
  327. package/test/unit/spec/members/request.js +206 -27
  328. package/test/unit/spec/members/utils.js +184 -0
  329. package/test/unit/spec/metrics/index.js +1 -50
  330. package/test/unit/spec/multistream/mediaRequestManager.ts +803 -162
  331. package/test/unit/spec/multistream/receiveSlot.ts +72 -13
  332. package/test/unit/spec/multistream/receiveSlotManager.ts +58 -28
  333. package/test/unit/spec/multistream/remoteMedia.ts +30 -0
  334. package/test/unit/spec/multistream/remoteMediaGroup.ts +266 -0
  335. package/test/unit/spec/multistream/remoteMediaManager.ts +326 -0
  336. package/test/unit/spec/multistream/sendSlotManager.ts +242 -0
  337. package/test/unit/spec/reachability/index.ts +343 -9
  338. package/test/unit/spec/reachability/request.js +68 -0
  339. package/test/unit/spec/reconnection-manager/index.js +84 -9
  340. package/test/unit/spec/recording-controller/index.js +294 -218
  341. package/test/unit/spec/recording-controller/util.js +223 -96
  342. package/test/unit/spec/roap/index.ts +31 -51
  343. package/test/unit/spec/roap/request.ts +203 -85
  344. package/test/unit/spec/roap/turnDiscovery.ts +48 -13
  345. package/test/unit/spec/rtcMetrics/index.ts +68 -0
  346. package/test/unit/spec/stats-analyzer/index.js +29 -2
  347. package/test/utils/constants.js +9 -0
  348. package/test/utils/integrationTestUtils.js +46 -0
  349. package/test/utils/testUtils.js +0 -45
  350. package/test/utils/webex-config.js +4 -0
  351. package/test/utils/webex-test-users.js +6 -3
  352. package/dist/meeting/effectsState.js +0 -262
  353. package/dist/meeting/effectsState.js.map +0 -1
  354. package/dist/metrics/config.js +0 -299
  355. package/dist/metrics/config.js.map +0 -1
  356. package/dist/types/meeting/effectsState.d.ts +0 -42
  357. package/dist/types/metrics/config.d.ts +0 -178
  358. package/src/index.js +0 -16
  359. package/src/meeting/effectsState.ts +0 -211
  360. package/src/metrics/config.ts +0 -495
  361. package/test/unit/spec/meeting/effectsState.js +0 -285
@@ -1,17 +1,34 @@
1
- import {DISPLAY_HINTS} from '../constants';
1
+ import {DISPLAY_HINTS, SELF_POLICY} from '../constants';
2
2
  import RecordingAction from './enums';
3
+ import MeetingUtil from '../meeting/util';
3
4
 
4
- const canUserStart = (displayHints: Array<string>): boolean =>
5
- displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_START);
5
+ const canUserStart = (
6
+ displayHints: Array<string>,
7
+ userPolicies: Record<SELF_POLICY, boolean>
8
+ ): boolean =>
9
+ displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_START) &&
10
+ MeetingUtil.selfSupportsFeature(SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD, userPolicies);
6
11
 
7
- const canUserPause = (displayHints: Array<string>): boolean =>
8
- displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_PAUSE);
12
+ const canUserPause = (
13
+ displayHints: Array<string>,
14
+ userPolicies: Record<SELF_POLICY, boolean>
15
+ ): boolean =>
16
+ displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_PAUSE) &&
17
+ MeetingUtil.selfSupportsFeature(SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD, userPolicies);
9
18
 
10
- const canUserResume = (displayHints: Array<string>): boolean =>
11
- displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_RESUME);
19
+ const canUserResume = (
20
+ displayHints: Array<string>,
21
+ userPolicies: Record<SELF_POLICY, boolean>
22
+ ): boolean =>
23
+ displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_RESUME) &&
24
+ MeetingUtil.selfSupportsFeature(SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD, userPolicies);
12
25
 
13
- const canUserStop = (displayHints: Array<string>): boolean =>
14
- displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_STOP);
26
+ const canUserStop = (
27
+ displayHints: Array<string>,
28
+ userPolicies: Record<SELF_POLICY, boolean>
29
+ ): boolean =>
30
+ displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_STOP) &&
31
+ MeetingUtil.selfSupportsFeature(SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD, userPolicies);
15
32
 
16
33
  const extractLocusId = (url: string) => {
17
34
  return url?.split('/').pop();
package/src/roap/index.ts CHANGED
@@ -7,6 +7,7 @@ import LoggerProxy from '../common/logs/logger-proxy';
7
7
  import RoapRequest from './request';
8
8
  import TurnDiscovery from './turnDiscovery';
9
9
  import Meeting from '../meeting';
10
+ import MeetingUtil from '../meeting/util';
10
11
 
11
12
  /**
12
13
  * Roap options
@@ -98,11 +99,8 @@ export default class Roap extends StatelessWebexPlugin {
98
99
  roapMessage,
99
100
  locusSelfUrl: meeting.selfUrl,
100
101
  mediaId: options.mediaId,
101
- correlationId: options.correlationId,
102
- audioMuted: meeting.isAudioMuted(),
103
- videoMuted: meeting.isVideoMuted(),
104
102
  meetingId: meeting.id,
105
- preferTranscoding: !meeting.isMultistream,
103
+ locusMediaRequest: meeting.locusMediaRequest,
106
104
  })
107
105
  .then(() => {
108
106
  LoggerProxy.logger.log(`Roap:index#sendRoapOK --> ROAP OK sent with seq ${options.seq}`);
@@ -135,11 +133,8 @@ export default class Roap extends StatelessWebexPlugin {
135
133
  roapMessage,
136
134
  locusSelfUrl: meeting.selfUrl,
137
135
  mediaId: options.mediaId,
138
- correlationId: options.correlationId,
139
- audioMuted: meeting.isAudioMuted(),
140
- videoMuted: meeting.isVideoMuted(),
141
136
  meetingId: meeting.id,
142
- preferTranscoding: !meeting.isMultistream,
137
+ locusMediaRequest: meeting.locusMediaRequest,
143
138
  });
144
139
  }
145
140
 
@@ -167,11 +162,8 @@ export default class Roap extends StatelessWebexPlugin {
167
162
  roapMessage,
168
163
  locusSelfUrl: meeting.selfUrl,
169
164
  mediaId: options.mediaId,
170
- correlationId: options.correlationId,
171
- audioMuted: meeting.isAudioMuted(),
172
- videoMuted: meeting.isVideoMuted(),
173
165
  meetingId: meeting.id,
174
- preferTranscoding: !meeting.isMultistream,
166
+ locusMediaRequest: meeting.locusMediaRequest,
175
167
  })
176
168
  .then(() => {
177
169
  LoggerProxy.logger.log(
@@ -199,26 +191,27 @@ export default class Roap extends StatelessWebexPlugin {
199
191
  // When reconnecting, it's important that the first roap message being sent out has empty media id.
200
192
  // Normally this is the roap offer, but when TURN discovery is enabled,
201
193
  // then this is the TURN discovery request message
202
- const sendEmptyMediaId = reconnect && !meeting.config.experimental.enableTurnDiscovery;
194
+ return this.turnDiscovery.isSkipped(meeting).then((isTurnDiscoverySkipped) => {
195
+ const sendEmptyMediaId = reconnect && isTurnDiscoverySkipped;
203
196
 
204
- return this.roapRequest
205
- .sendRoap({
206
- roapMessage,
207
- correlationId: meeting.correlationId,
208
- locusSelfUrl: meeting.selfUrl,
209
- mediaId: sendEmptyMediaId ? '' : meeting.mediaId,
210
- audioMuted: meeting.isAudioMuted(),
211
- videoMuted: meeting.isVideoMuted(),
212
- meetingId: meeting.id,
213
- preferTranscoding: !meeting.isMultistream,
214
- })
215
- .then(({locus, mediaConnections}) => {
216
- if (mediaConnections) {
217
- meeting.updateMediaConnections(mediaConnections);
218
- }
197
+ return this.roapRequest
198
+ .sendRoap({
199
+ roapMessage,
200
+ locusSelfUrl: meeting.selfUrl,
201
+ mediaId: sendEmptyMediaId ? '' : meeting.mediaId,
202
+ meetingId: meeting.id,
203
+ preferTranscoding: !meeting.isMultistream,
204
+ locusMediaRequest: meeting.locusMediaRequest,
205
+ ipVersion: MeetingUtil.getIpVersion(meeting.webex),
206
+ })
207
+ .then(({locus, mediaConnections}) => {
208
+ if (mediaConnections) {
209
+ meeting.updateMediaConnections(mediaConnections);
210
+ }
219
211
 
220
- return locus;
221
- });
212
+ return locus;
213
+ });
214
+ });
222
215
  }
223
216
 
224
217
  /**
@@ -1,43 +1,45 @@
1
- /* global window */
2
1
  // @ts-ignore
3
2
  import {StatelessWebexPlugin} from '@webex/webex-core';
4
3
 
5
4
  import LoggerProxy from '../common/logs/logger-proxy';
6
- import {MEDIA, HTTP_VERBS, REACHABILITY} from '../constants';
7
- import Metrics from '../metrics';
8
- import {eventType} from '../metrics/config';
5
+ import {IP_VERSION, REACHABILITY} from '../constants';
6
+ import {LocusMediaRequest} from '../meeting/locusMediaRequest';
9
7
 
10
8
  /**
11
9
  * @class RoapRequest
12
10
  */
13
11
  export default class RoapRequest extends StatelessWebexPlugin {
14
12
  /**
15
- * Joins a meeting via ROAP
13
+ * Returns reachability data.
16
14
  * @param {Object} localSdp
17
- * @returns {Promise} returns a promise that resolves/rejects whatever the request does
15
+ * @returns {Object}
18
16
  */
19
- async attachRechabilityData(localSdp) {
17
+ async attachReachabilityData(localSdp) {
18
+ let joinCookie;
19
+
20
+ // @ts-ignore
21
+ const reachabilityResult = await this.webex.meetings.reachability.getReachabilityResults();
22
+
23
+ if (reachabilityResult && Object.keys(reachabilityResult).length) {
24
+ localSdp.reachability = reachabilityResult;
25
+ }
26
+
20
27
  // @ts-ignore
21
- const reachabilityData = await this.webex.boundedStorage
22
- .get(REACHABILITY.namespace, REACHABILITY.localStorage)
28
+ const joinCookieRaw = await this.webex.boundedStorage
29
+ .get(REACHABILITY.namespace, REACHABILITY.localStorageJoinCookie)
23
30
  .catch(() => {});
24
31
 
25
- if (reachabilityData) {
32
+ if (joinCookieRaw) {
26
33
  try {
27
- const reachabilityResult = JSON.parse(reachabilityData);
28
-
29
- /* istanbul ignore else */
30
- if (reachabilityResult && Object.keys(reachabilityResult).length) {
31
- localSdp.reachability = reachabilityResult;
32
- }
34
+ joinCookie = JSON.parse(joinCookieRaw);
33
35
  } catch (e) {
34
36
  LoggerProxy.logger.error(
35
- `Roap:request#attachReachabilityData --> Error in parsing reachability data: ${e}`
37
+ `MeetingRequest#constructor --> Error in parsing join cookie data: ${e}`
36
38
  );
37
39
  }
38
40
  }
39
41
 
40
- return localSdp;
42
+ return {localSdp, joinCookie};
41
43
  }
42
44
 
43
45
  /**
@@ -47,111 +49,105 @@ export default class RoapRequest extends StatelessWebexPlugin {
47
49
  * @param {String} options.locusSelfUrl
48
50
  * @param {String} options.mediaId
49
51
  * @param {String} options.correlationId
50
- * @param {Boolean} options.audioMuted
51
- * @param {Boolean} options.videoMuted
52
52
  * @param {String} options.meetingId
53
- * @param {Boolean} options.preferTranscoding
53
+ * @param {IP_VERSION} options.ipVersion only required for offers
54
54
  * @returns {Promise} returns the response/failure of the request
55
55
  */
56
- sendRoap(options: {
56
+ async sendRoap(options: {
57
57
  roapMessage: any;
58
58
  locusSelfUrl: string;
59
59
  mediaId: string;
60
- correlationId: string;
61
- audioMuted: boolean;
62
- videoMuted: boolean;
63
60
  meetingId: string;
64
- preferTranscoding?: boolean;
61
+ ipVersion?: IP_VERSION;
62
+ locusMediaRequest?: LocusMediaRequest;
65
63
  }) {
66
- const {roapMessage, locusSelfUrl, mediaId, correlationId, meetingId} = options;
64
+ const {roapMessage, locusSelfUrl, mediaId, meetingId, locusMediaRequest, ipVersion} = options;
67
65
 
68
66
  if (!mediaId) {
69
- LoggerProxy.logger.info('Roap:request#sendRoap --> Race Condition /call mediaID not present');
67
+ LoggerProxy.logger.info('Roap:request#sendRoap --> sending empty mediaID');
70
68
  }
71
69
 
72
- const mediaUrl = `${locusSelfUrl}/${MEDIA}`;
73
- // @ts-ignore
74
- const deviceUrl = this.webex.internal.device.url;
70
+ if (!locusMediaRequest) {
71
+ LoggerProxy.logger.warn(
72
+ 'Roap:request#sendRoap --> locusMediaRequest unavailable, not sending roap'
73
+ );
74
+
75
+ return Promise.reject(new Error('sendRoap called when locusMediaRequest is undefined'));
76
+ }
77
+ const {localSdp: localSdpWithReachabilityData, joinCookie} = await this.attachReachabilityData({
78
+ roapMessage,
79
+ });
75
80
 
76
81
  LoggerProxy.logger.info(
77
- `Roap:request#sendRoap --> ${mediaUrl} \n ${roapMessage.messageType} \n seq:${roapMessage.seq}`
82
+ `Roap:request#sendRoap --> ${locusSelfUrl} \n ${roapMessage.messageType} \n seq:${roapMessage.seq}`
78
83
  );
79
84
 
80
- Metrics.postEvent({event: eventType.MEDIA_REQUEST, meetingId});
85
+ // @ts-ignore
86
+ this.webex.internal.newMetrics.submitClientEvent({
87
+ name: 'client.locus.media.request',
88
+ options: {
89
+ meetingId,
90
+ },
91
+ });
81
92
 
82
- return this.attachRechabilityData({
83
- roapMessage,
84
- // eslint-disable-next-line no-warning-comments
85
- // TODO: check whats the need for video and audiomute
86
- audioMuted: !!options.audioMuted,
87
- videoMuted: !!options.videoMuted,
88
- }).then((sdpWithReachability) => {
89
- // @ts-ignore
90
- return this.webex
91
- .request({
92
- uri: mediaUrl,
93
- method: HTTP_VERBS.PUT,
94
- body: {
95
- device: {
96
- url: deviceUrl,
97
- // @ts-ignore
98
- deviceType: this.config.meetings.deviceType,
99
- },
100
- correlationId,
101
- localMedias: [
102
- {
103
- localSdp: JSON.stringify(sdpWithReachability),
104
- mediaId: options.mediaId,
105
- },
106
- ],
107
- clientMediaPreferences: {
108
- preferTranscoding: options.preferTranscoding ?? true,
109
- },
93
+ return locusMediaRequest
94
+ .send({
95
+ type: 'RoapMessage',
96
+ selfUrl: locusSelfUrl,
97
+ joinCookie,
98
+ mediaId,
99
+ roapMessage,
100
+ reachability: localSdpWithReachabilityData.reachability,
101
+ ipVersion,
102
+ })
103
+ .then((res) => {
104
+ // @ts-ignore
105
+ this.webex.internal.newMetrics.submitClientEvent({
106
+ name: 'client.locus.media.response',
107
+ options: {
108
+ meetingId,
110
109
  },
111
- })
112
- .then((res) => {
113
- Metrics.postEvent({event: eventType.MEDIA_RESPONSE, meetingId});
114
-
115
- // always it will be the first mediaConnection Object
116
- const mediaConnections =
117
- res.body.mediaConnections &&
118
- res.body.mediaConnections.length > 0 &&
119
- res.body.mediaConnections[0];
120
-
121
- LoggerProxy.logger.info(
122
- `Roap:request#sendRoap --> response:${JSON.stringify(
123
- mediaConnections,
124
- null,
125
- 2
126
- )}'\n StatusCode:'${res.statusCode}`
127
- );
128
- const {locus} = res.body;
129
-
130
- locus.roapSeq = options.roapMessage.seq;
131
-
132
- return {
133
- locus,
134
- ...(mediaConnections && {mediaConnections: res.body.mediaConnections}),
135
- };
136
- })
137
- .catch((err) => {
138
- Metrics.postEvent({
139
- event: eventType.MEDIA_RESPONSE,
110
+ });
111
+ // always it will be the first mediaConnection Object
112
+ const mediaConnections =
113
+ res.body.mediaConnections &&
114
+ res.body.mediaConnections.length > 0 &&
115
+ res.body.mediaConnections[0];
116
+
117
+ LoggerProxy.logger.debug(
118
+ `Roap:request#sendRoap --> response:${JSON.stringify(
119
+ mediaConnections,
120
+ null,
121
+ 2
122
+ )}'\n StatusCode:'${res.statusCode}`
123
+ );
124
+ const {locus} = res.body;
125
+
126
+ locus.roapSeq = options.roapMessage.seq;
127
+
128
+ return {
129
+ locus,
130
+ ...(mediaConnections && {mediaConnections: res.body.mediaConnections}),
131
+ };
132
+ })
133
+ .catch((err) => {
134
+ // @ts-ignore
135
+ this.webex.internal.newMetrics.submitClientEvent({
136
+ name: 'client.locus.media.response',
137
+ options: {
140
138
  meetingId,
141
- data: {error: Metrics.parseLocusError(err, true)},
142
- });
143
- LoggerProxy.logger.error(
144
- `Roap:request#sendRoap --> Error:${JSON.stringify(err, null, 2)}`
145
- );
146
- LoggerProxy.logger.error(
147
- `Roap:request#sendRoapRequest --> errorBody:${JSON.stringify(
148
- roapMessage,
149
- null,
150
- 2
151
- )} + '\\n mediaId:'${options.mediaId}`
152
- );
153
- throw err;
139
+ rawError: err,
140
+ },
154
141
  });
155
- });
142
+ LoggerProxy.logger.error(`Roap:request#sendRoap --> Error:${JSON.stringify(err, null, 2)}`);
143
+ LoggerProxy.logger.error(
144
+ `Roap:request#sendRoapRequest --> errorBody:${JSON.stringify(
145
+ roapMessage,
146
+ null,
147
+ 2
148
+ )} + '\\n mediaId:'${options.mediaId}`
149
+ );
150
+ throw err;
151
+ });
156
152
  }
157
153
  }
@@ -8,6 +8,7 @@ import {ROAP} from '../constants';
8
8
 
9
9
  import RoapRequest from './request';
10
10
  import Meeting from '../meeting';
11
+ import MeetingUtil from '../meeting/util';
11
12
 
12
13
  const TURN_DISCOVERY_TIMEOUT = 10; // in seconds
13
14
 
@@ -176,15 +177,14 @@ export default class TurnDiscovery {
176
177
  return this.roapRequest
177
178
  .sendRoap({
178
179
  roapMessage,
179
- correlationId: meeting.correlationId,
180
180
  // @ts-ignore - Fix missing type
181
181
  locusSelfUrl: meeting.selfUrl,
182
182
  // @ts-ignore - Fix missing type
183
183
  mediaId: isReconnecting ? '' : meeting.mediaId,
184
- audioMuted: meeting.isAudioMuted(),
185
- videoMuted: meeting.isVideoMuted(),
186
184
  meetingId: meeting.id,
187
- preferTranscoding: !meeting.isMultistream,
185
+ locusMediaRequest: meeting.locusMediaRequest,
186
+ // @ts-ignore - because of meeting.webex
187
+ ipVersion: MeetingUtil.getIpVersion(meeting.webex),
188
188
  })
189
189
  .then(({mediaConnections}) => {
190
190
  if (mediaConnections) {
@@ -213,14 +213,54 @@ export default class TurnDiscovery {
213
213
  locusSelfUrl: meeting.selfUrl,
214
214
  // @ts-ignore - fix type
215
215
  mediaId: meeting.mediaId,
216
- correlationId: meeting.correlationId,
217
- audioMuted: meeting.isAudioMuted(),
218
- videoMuted: meeting.isVideoMuted(),
219
216
  meetingId: meeting.id,
220
- preferTranscoding: !meeting.isMultistream,
217
+ locusMediaRequest: meeting.locusMediaRequest,
221
218
  });
222
219
  }
223
220
 
221
+ /**
222
+ * Gets the reason why reachability is skipped.
223
+ *
224
+ * @param {Meeting} meeting
225
+ * @returns {Promise<string>} Promise with empty string if reachability is not skipped or a reason if it is skipped
226
+ */
227
+ private async getSkipReason(meeting: Meeting): Promise<string> {
228
+ const isAnyPublicClusterReachable =
229
+ // @ts-ignore - fix type
230
+ await meeting.webex.meetings.reachability.isAnyPublicClusterReachable();
231
+
232
+ if (isAnyPublicClusterReachable) {
233
+ LoggerProxy.logger.info(
234
+ 'Roap:turnDiscovery#getSkipReason --> reachability has not failed, skipping TURN discovery'
235
+ );
236
+
237
+ return 'reachability';
238
+ }
239
+
240
+ // @ts-ignore - fix type
241
+ if (!meeting.config.experimental.enableTurnDiscovery) {
242
+ LoggerProxy.logger.info(
243
+ 'Roap:turnDiscovery#getSkipReason --> TURN discovery disabled in config, skipping it'
244
+ );
245
+
246
+ return 'config';
247
+ }
248
+
249
+ return '';
250
+ }
251
+
252
+ /**
253
+ * Checks if TURN discovery is skipped.
254
+ *
255
+ * @param {Meeting} meeting
256
+ * @returns {Boolean} true if TURN discovery is being skipped, false if it is being done
257
+ */
258
+ async isSkipped(meeting) {
259
+ const skipReason = await this.getSkipReason(meeting);
260
+
261
+ return !!skipReason;
262
+ }
263
+
224
264
  /**
225
265
  * Retrieves TURN server information from the backend by doing
226
266
  * a roap message exchange:
@@ -239,29 +279,15 @@ export default class TurnDiscovery {
239
279
  * @returns {Promise}
240
280
  */
241
281
  async doTurnDiscovery(meeting: Meeting, isReconnecting?: boolean) {
242
- // @ts-ignore - fix type
243
- const isAnyClusterReachable = await meeting.webex.meetings.reachability.isAnyClusterReachable();
244
-
245
- if (isAnyClusterReachable) {
246
- LoggerProxy.logger.info(
247
- 'Roap:turnDiscovery#doTurnDiscovery --> reachability has not failed, skipping TURN discovery'
248
- );
282
+ const turnDiscoverySkippedReason = await this.getSkipReason(meeting);
249
283
 
284
+ if (turnDiscoverySkippedReason) {
250
285
  return {
251
286
  turnServerInfo: undefined,
252
- turnDiscoverySkippedReason: 'reachability',
287
+ turnDiscoverySkippedReason,
253
288
  };
254
289
  }
255
290
 
256
- // @ts-ignore - fix type
257
- if (!meeting.config.experimental.enableTurnDiscovery) {
258
- LoggerProxy.logger.info(
259
- 'Roap:turnDiscovery#doTurnDiscovery --> TURN discovery disabled in config, skipping it'
260
- );
261
-
262
- return {turnServerInfo: undefined, turnDiscoverySkippedReason: 'config'};
263
- }
264
-
265
291
  return this.sendRoapTurnDiscoveryRequest(meeting, isReconnecting)
266
292
  .then(() => this.waitForTurnDiscoveryResponse())
267
293
  .then(() => this.sendRoapOK(meeting))
@@ -0,0 +1,3 @@
1
+ const RTC_METRICS = {APP_ID: 'FFB51ED5-4319-4C55-8303-B1F2FCCDE231'};
2
+
3
+ export {RTC_METRICS as default};
@@ -0,0 +1,100 @@
1
+ import RTC_METRICS from './constants';
2
+
3
+ /**
4
+ * Rtc Metrics
5
+ */
6
+ export default class RtcMetrics {
7
+ /**
8
+ * Array of MetricData items to be sent to the metrics service.
9
+ */
10
+ metricsQueue = [];
11
+
12
+ intervalId: number;
13
+
14
+ webex: any;
15
+
16
+ meetingId: string;
17
+
18
+ correlationId: string;
19
+
20
+ /**
21
+ * Initialize the interval.
22
+ *
23
+ * @param {object} webex - The main `webex` object.
24
+ * @param {string} meetingId - The meeting id.
25
+ * @param {string} correlationId - The correlation id.
26
+ */
27
+ constructor(webex, meetingId, correlationId) {
28
+ // `window` is used to prevent typescript from returning a NodeJS.Timer.
29
+ this.intervalId = window.setInterval(this.checkMetrics.bind(this), 30 * 1000);
30
+ this.meetingId = meetingId;
31
+ this.webex = webex;
32
+ this.correlationId = correlationId;
33
+ // Send the first set of metrics at 5 seconds in the case of a user leaving the call shortly after joining.
34
+ setTimeout(this.checkMetrics.bind(this), 5 * 1000);
35
+ }
36
+
37
+ /**
38
+ * Check to see if the metrics queue has any items.
39
+ *
40
+ * @returns {void}
41
+ */
42
+ private checkMetrics() {
43
+ if (this.metricsQueue.length) {
44
+ this.sendMetrics();
45
+ this.metricsQueue = [];
46
+ }
47
+ }
48
+
49
+ /**
50
+ * Add metrics items to the metrics queue.
51
+ *
52
+ * @param {object} data - An object with a payload array of metrics items.
53
+ *
54
+ * @returns {void}
55
+ */
56
+ addMetrics(data) {
57
+ if (data.payload.length) {
58
+ this.metricsQueue.push(data);
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Clear the metrics interval.
64
+ *
65
+ * @returns {void}
66
+ */
67
+ closeMetrics() {
68
+ this.checkMetrics();
69
+ clearInterval(this.intervalId);
70
+ }
71
+
72
+ /**
73
+ * Send metrics to the metrics service.
74
+ *
75
+ * @returns {void}
76
+ */
77
+ private sendMetrics() {
78
+ this.webex.request({
79
+ method: 'POST',
80
+ service: 'unifiedTelemetry',
81
+ resource: 'metric/v2',
82
+ headers: {
83
+ type: 'webrtcMedia',
84
+ appId: RTC_METRICS.APP_ID,
85
+ },
86
+ body: {
87
+ metrics: [
88
+ {
89
+ type: 'webrtc',
90
+ version: '1.0.1',
91
+ userId: this.webex.internal.device.userId,
92
+ meetingId: this.meetingId,
93
+ correlationId: this.correlationId,
94
+ data: this.metricsQueue,
95
+ },
96
+ ],
97
+ },
98
+ });
99
+ }
100
+ }