You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TestConnectionInfo.js 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. // @flow
  2. import React, { Component, Fragment } from 'react';
  3. import { getLocalParticipant } from '../../participants';
  4. import { connect } from '../../redux';
  5. // FIXME this imports feature to 'base'
  6. import { statsEmitter } from '../../../connection-indicator';
  7. import { TestHint } from './index';
  8. import { isTestModeEnabled } from '../functions';
  9. /**
  10. * Defines the TestConnectionInfo's properties.
  11. */
  12. type Props = {
  13. /**
  14. * The JitsiConference's connection state. It's the lib-jitsi-meet's event
  15. * name converted to a string directly. At the time of this writing these
  16. * are the possible values:
  17. * 'conference.connectionEstablished'
  18. * 'conference.connectionInterrupted'
  19. * 'conference.connectionRestored'
  20. */
  21. _conferenceConnectionState: string,
  22. /**
  23. * This will be a boolean converted to a string. The value will be 'true'
  24. * once the conference is joined (the XMPP MUC room to be specific).
  25. */
  26. _conferenceJoinedState: string,
  27. /**
  28. * The local participant's ID. Required to be able to observe the local RTP
  29. * stats.
  30. */
  31. _localUserId: string,
  32. /**
  33. * Indicates whether or not the test mode is currently on. Otherwise the
  34. * TestConnectionInfo component will not render.
  35. */
  36. _testMode: boolean
  37. }
  38. /**
  39. * Describes the TestConnectionInfo's state.
  40. */
  41. type State = {
  42. /**
  43. * The RTP stats section.
  44. */
  45. stats: {
  46. /**
  47. * The local bitrate.
  48. */
  49. bitrate: {
  50. /**
  51. * The local download RTP bitrate.
  52. */
  53. download: number,
  54. /**
  55. * The local upload RTP bitrate.
  56. */
  57. upload: number
  58. }
  59. }
  60. }
  61. /**
  62. * The component will expose some of the app state to the jitsi-meet-torture
  63. * through the UI accessibility layer which is visible to the tests. The Web
  64. * tests currently will execute JavaScript and access globals variables to learn
  65. * this information, but there's no such option on React Native(maybe that's
  66. * a good thing).
  67. */
  68. class TestConnectionInfo extends Component<Props, State> {
  69. _onStatsUpdated: Object => void;
  70. /**
  71. * Initializes new <tt>TestConnectionInfo</tt> instance.
  72. *
  73. * @param {Object} props - The read-only properties with which the new
  74. * instance is to be initialized.
  75. */
  76. constructor(props: Props) {
  77. super(props);
  78. this._onStatsUpdated = this._onStatsUpdated.bind(this);
  79. this.state = {
  80. stats: {
  81. bitrate: {
  82. download: 0,
  83. upload: 0
  84. }
  85. }
  86. };
  87. }
  88. /**
  89. * The {@link statsEmitter} callback hoked up for the local participant.
  90. *
  91. * @param {Object} stats - These are the RTP stats. Look in
  92. * the lib-jitsi-meet for more details on the actual structure or add
  93. * a console print and figure out there.
  94. * @returns {void}
  95. * @private
  96. */
  97. _onStatsUpdated(stats = {}) {
  98. this.setState({
  99. stats: {
  100. bitrate: {
  101. download: stats.bitrate.download,
  102. upload: stats.bitrate.upload
  103. }
  104. }
  105. });
  106. }
  107. /**
  108. * Starts listening for the local RTP stat updates.
  109. *
  110. * @inheritdoc
  111. * returns {void}
  112. */
  113. componentDidMount() {
  114. statsEmitter.subscribeToClientStats(
  115. this.props._localUserId, this._onStatsUpdated);
  116. }
  117. /**
  118. * Updates which user's stats are being listened to (the local participant's
  119. * id changes).
  120. *
  121. * @inheritdoc
  122. * returns {void}
  123. */
  124. componentDidUpdate(prevProps: Props) {
  125. if (prevProps._localUserId !== this.props._localUserId) {
  126. statsEmitter.unsubscribeToClientStats(
  127. prevProps._localUserId, this._onStatsUpdated);
  128. statsEmitter.subscribeToClientStats(
  129. this.props._localUserId, this._onStatsUpdated);
  130. }
  131. }
  132. /**
  133. * Removes the local stats listener.
  134. *
  135. * @private
  136. * @returns {void}
  137. */
  138. componentWillUnmount() {
  139. statsEmitter.unsubscribeToClientStats(
  140. this.props._localUserId, this._onStatsUpdated);
  141. }
  142. /**
  143. * Renders the component if the app is currently running in the test mode
  144. * (config.testing.testMode == true).
  145. *
  146. * @returns {ReactElement|null}
  147. */
  148. render() {
  149. if (!this.props._testMode) {
  150. return null;
  151. }
  152. return (
  153. <Fragment accessible = { false } >
  154. <TestHint
  155. id = 'org.jitsi.meet.conference.connectionState'
  156. value = { this.props._conferenceConnectionState } />
  157. <TestHint
  158. id = 'org.jitsi.meet.conference.joinedState'
  159. value = { this.props._conferenceJoinedState } />
  160. <TestHint
  161. id = 'org.jitsi.meet.stats.rtp'
  162. value = { JSON.stringify(this.state.stats) } />
  163. </Fragment>
  164. );
  165. }
  166. }
  167. /**
  168. * Maps (parts of) the Redux state to the associated TestConnectionInfo's props.
  169. *
  170. * @param {Object} state - The Redux state.
  171. * @private
  172. * @returns {{
  173. * _conferenceConnectionState: string,
  174. * _conferenceJoinedState: string,
  175. * _localUserId: string,
  176. * _testMode: boolean
  177. * }}
  178. */
  179. function _mapStateToProps(state) {
  180. const conferenceJoined
  181. = Boolean(state['features/base/conference'].conference);
  182. const localParticipant = getLocalParticipant(state);
  183. return {
  184. _conferenceConnectionState: state['features/testing'].connectionState,
  185. _conferenceJoinedState: conferenceJoined.toString(),
  186. _localUserId: localParticipant && localParticipant.id,
  187. _testMode: isTestModeEnabled(state)
  188. };
  189. }
  190. export default connect(_mapStateToProps)(TestConnectionInfo);