Skip to content

Commit

Permalink
feat: report analytics for the network connection
Browse files Browse the repository at this point in the history
Will emit new 'network.info' action with the online/offline status and
extra details for native like the network type and
'isConnectionExpensive' flag.
  • Loading branch information
paweldomas committed Aug 23, 2019
1 parent 2c70388 commit 6ae9bbe
Show file tree
Hide file tree
Showing 20 changed files with 377 additions and 2 deletions.
1 change: 1 addition & 0 deletions android/sdk/build.gradle
Expand Up @@ -56,6 +56,7 @@ dependencies {
implementation project(':react-native-background-timer')
implementation project(':react-native-calendar-events')
implementation project(':react-native-community-async-storage')
implementation project(':react-native-community_netinfo')
implementation project(':react-native-immersive')
implementation project(':react-native-keep-awake')
implementation project(':react-native-linear-gradient')
Expand Down
Expand Up @@ -193,6 +193,7 @@ static void initReactInstanceManager(Activity activity) {
new com.oblador.vectoricons.VectorIconsPackage(),
new com.ocetnik.timer.BackgroundTimerPackage(),
new com.reactnativecommunity.asyncstorage.AsyncStoragePackage(),
new com.reactnativecommunity.netinfo.NetInfoPackage(),
new com.reactnativecommunity.webview.RNCWebViewPackage(),
new com.rnimmersive.RNImmersivePackage(),
new com.zmxv.RNSound.RNSoundPackage(),
Expand Down
2 changes: 2 additions & 0 deletions android/settings.gradle
Expand Up @@ -7,6 +7,8 @@ include ':react-native-calendar-events'
project(':react-native-calendar-events').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-calendar-events/android')
include ':react-native-community-async-storage'
project(':react-native-community-async-storage').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/async-storage/android')
include ':react-native-community_netinfo'
project(':react-native-community_netinfo').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/netinfo/android')
include ':react-native-google-signin'
project(':react-native-google-signin').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-google-signin/android')
include ':react-native-immersive'
Expand Down
1 change: 1 addition & 0 deletions ios/Podfile
Expand Up @@ -47,6 +47,7 @@ target 'JitsiMeet' do
pod 'react-native-background-timer', :path => '../node_modules/react-native-background-timer'
pod 'react-native-calendar-events', :path => '../node_modules/react-native-calendar-events'
pod 'react-native-keep-awake', :path => '../node_modules/react-native-keep-awake'
pod 'react-native-netinfo', :path => '../node_modules/@react-native-community/netinfo'
pod 'react-native-webview', :path => '../node_modules/react-native-webview'
pod 'react-native-webrtc', :path => '../node_modules/react-native-webrtc'
pod 'BVLinearGradient', :path => '../node_modules/react-native-linear-gradient'
Expand Down
8 changes: 7 additions & 1 deletion ios/Podfile.lock
Expand Up @@ -139,6 +139,8 @@ PODS:
- React
- react-native-keep-awake (4.0.0):
- React
- react-native-netinfo (4.1.5):
- React
- react-native-webrtc (1.69.2):
- React
- react-native-webview (5.8.1):
Expand Down Expand Up @@ -203,6 +205,7 @@ DEPENDENCIES:
- react-native-background-timer (from `../node_modules/react-native-background-timer`)
- react-native-calendar-events (from `../node_modules/react-native-calendar-events`)
- react-native-keep-awake (from `../node_modules/react-native-keep-awake`)
- react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)
- react-native-webrtc (from `../node_modules/react-native-webrtc`)
- react-native-webview (from `../node_modules/react-native-webview`)
- React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`)
Expand Down Expand Up @@ -271,6 +274,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-calendar-events"
react-native-keep-awake:
:path: "../node_modules/react-native-keep-awake"
react-native-netinfo:
:path: "../node_modules/@react-native-community/netinfo"
react-native-webrtc:
:path: "../node_modules/react-native-webrtc"
react-native-webview:
Expand Down Expand Up @@ -340,6 +345,7 @@ SPEC CHECKSUMS:
react-native-background-timer: 0d34748e53a972507c66963490c775321a88f6f2
react-native-calendar-events: 2fe35a9294af05de0ed819d3a1b5dac048d2c010
react-native-keep-awake: eba3137546b10003361b37c761f6c429b59814ae
react-native-netinfo: 8d8db463bcc5db66a8ac5c48a7d86beb3b92f61a
react-native-webrtc: 1415d2a54b2246dd85ba95eb3e4bf2b66533f951
react-native-webview: a95842e3f351a6d2c8bc8bcc9eab689c7e7e5ad4
React-RCTActionSheet: b0f1ea83f4bf75fb966eae9bfc47b78c8d3efd90
Expand All @@ -359,6 +365,6 @@ SPEC CHECKSUMS:
RNWatch: 09738b339eceb66e4d80a2371633ca5fb380fa42
yoga: 312528f5bbbba37b4dcea5ef00e8b4033fdd9411

PODFILE CHECKSUM: 6b6e260b4be4e86f9d05c0d7dab40f60118bb355
PODFILE CHECKSUM: 0907bfe60b5b5f11dbdc6b4e65d40a248d000513

COCOAPODS: 1.7.2
5 changes: 5 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Expand Up @@ -35,6 +35,7 @@
"@atlaskit/tooltip": "12.1.13",
"@microsoft/microsoft-graph-client": "1.1.0",
"@react-native-community/async-storage": "1.3.4",
"@react-native-community/netinfo": "4.1.5",
"@tensorflow-models/body-pix": "^1.0.1",
"@tensorflow/tfjs": "^1.1.2",
"@webcomponents/url": "0.7.1",
Expand Down
21 changes: 21 additions & 0 deletions react/features/analytics/AnalyticsEvents.js
Expand Up @@ -271,6 +271,27 @@ export function createInviteDialogEvent(
};
}

/**
* Creates an event which reports about the current network information reported by the operating system.
*
* @param {boolean} isOnline - Tells whether or not the internet is reachable.
* @param {string} [networkType] - Network type, see {@code NetworkInfo} type defined by the 'base/net-info' feature.
* @param {Object} [details] - Extra info, see {@code NetworkInfo} type defined by the 'base/net-info' feature.
* @returns {Object}
*/
export function createNetworkInfoEvent({ isOnline, networkType, details }) {
const attributes = { isOnline };

// Do no include optional stuff or Amplitude handler will log warnings.
networkType && (attributes.networkType = networkType);
details && (attributes.details = details);

return {
action: 'network.info',
attributes
};
}

/**
* Creates an "offer/answer failure" event.
*
Expand Down
11 changes: 10 additions & 1 deletion react/features/analytics/middleware.js
Expand Up @@ -6,6 +6,7 @@ import {
SET_ROOM
} from '../base/conference';
import { SET_CONFIG } from '../base/config';
import { SET_NETWORK_INFO } from '../base/net-info';
import { MiddlewareRegistry } from '../base/redux';
import {
getLocalAudioTrack,
Expand All @@ -16,7 +17,7 @@ import {
} from '../base/tracks';

import { UPDATE_LOCAL_TRACKS_DURATION } from './actionTypes';
import { createLocalTracksDurationEvent } from './AnalyticsEvents';
import { createLocalTracksDurationEvent, createNetworkInfoEvent } from './AnalyticsEvents';
import { initAnalytics, resetAnalytics, sendAnalytics } from './functions';

/**
Expand Down Expand Up @@ -127,6 +128,14 @@ MiddlewareRegistry.register(store => next => action => {
});
break;
}
case SET_NETWORK_INFO:
sendAnalytics(
createNetworkInfoEvent({
isOnline: action.isOnline,
details: action.details,
networkType: action.networkType
}));
break;
case SET_ROOM: {
initAnalytics(store);
break;
Expand Down
66 changes: 66 additions & 0 deletions react/features/base/net-info/NetworkInfoService.native.js
@@ -0,0 +1,66 @@
// @flow
import EventEmitter from 'events';
import NetInfo from '@react-native-community/netinfo';
import type { NetInfoState, NetInfoSubscription } from '@react-native-community/netinfo';

import { ONLINE_STATE_CHANGED_EVENT } from './events';

import type { NetworkInfo } from './types';

/**
* The network info service implementation for iOS and Android. 'react-native-netinfo' seems to support windows as well,
* but that has not been tested and is nto used by jitsi-meet.
*/
export default class NetworkInfoService extends EventEmitter {
/**
* Stores the native subscription for future cleanup.
*/
_subscription: NetInfoSubscription;

/**
* Converts library's structure to {@link NetworkInfo} used by jitsi-meet.
*
* @param {NetInfoState} netInfoState - The new state given by the native library.
* @private
* @returns {NetworkInfo}
*/
static _convertNetInfoState(netInfoState: NetInfoState): NetworkInfo {
return {
isOnline: netInfoState.isInternetReachable,
details: netInfoState.details,
networkType: netInfoState.type
};
}

/**
* Checks for support.
*
* @returns {boolean}
*/
static isSupported() {
return Boolean(NetInfo);
}

/**
* Starts the service.
*
* @returns {void}
*/
start() {
this._subscription = NetInfo.addEventListener(netInfoState => {
this.emit(ONLINE_STATE_CHANGED_EVENT, NetworkInfoService._convertNetInfoState(netInfoState));
});
}

/**
* Stops the service.
*
* @returns {void}
*/
stop() {
if (this._subscription) {
this._subscription();
this._subscription = undefined;
}
}
}
58 changes: 58 additions & 0 deletions react/features/base/net-info/NetworkInfoService.web.js
@@ -0,0 +1,58 @@
import EventEmitter from 'events';

import { ONLINE_STATE_CHANGED_EVENT } from './events';

/**
* The network info service implementation for web (Chrome, Firefox and Safari).
*/
export default class NetworkInfoService extends EventEmitter {

/**
* Creates new instance...
*/
constructor() {
super();
this._onlineStateListener = this._handleOnlineStatusChange.bind(this, /* online */ true);
this._offlineStateListener = this._handleOnlineStatusChange.bind(this, /* offline */ false);
}

/**
* Callback function to track the online state.
*
* @param {boolean} isOnline - Is the browser online or not.
* @private
* @returns {void}
*/
_handleOnlineStatusChange(isOnline) {
this.emit(ONLINE_STATE_CHANGED_EVENT, { isOnline });
}

/**
* Checks for support.
*
* @returns {boolean}
*/
static isSupported() {
return window.addEventListener && typeof navigator.onLine !== 'undefined';
}

/**
* Starts the service.
*
* @returns {void}
*/
start() {
window.addEventListener('online', this._onlineStateListener);
window.addEventListener('offline', this._offlineStateListener);
}

/**
* Stops the service.
*
* @returns {void}
*/
stop() {
window.removeEventListener('online', this._onlineStateListener);
window.removeEventListener('offline', this._offlineStateListener);
}
}
13 changes: 13 additions & 0 deletions react/features/base/net-info/actionTypes.js
@@ -0,0 +1,13 @@
/**
* The action dispatched when the {@link NetworkInfo} structure is being updated.
*
* @type {string}
*/
export const SET_NETWORK_INFO = 'SET_NETWORK_INFO';

/**
* Tha action dispatched by 'base/net-info' middleware in order to store the cleanup function for later use.
* @type {string}
* @private
*/
export const _STORE_NETWORK_INFO_CLEANUP = 'STORE_NETWORK_INFO_CLEANUP';
42 changes: 42 additions & 0 deletions react/features/base/net-info/actions.js
@@ -0,0 +1,42 @@
// @flow

import { SET_NETWORK_INFO, _STORE_NETWORK_INFO_CLEANUP } from './actionTypes';

import type { NetworkInfo } from './types';

/**
* Up[dates the network info state.
*
* @param {NetworkInfo} networkInfo - The new network state to be set.
* @returns {{
* type: SET_NETWORK_INFO,
* isOnline: boolean,
* networkType: string,
* details: Object
* }}
*/
export function setNetworkInfo({ isOnline, networkType, details }: NetworkInfo): Object {
return {
type: SET_NETWORK_INFO,
isOnline,
networkType,
details
};
}

/**
* Stored the cleanup function used to shutdown the {@code NetworkInfoService}.
*
* @param {Function} cleanup - The cleanup function to be called on {@code APP_WILL_UNMOUNT}.
* @returns {{
* type: _STORE_NETWORK_INFO_CLEANUP,
* cleanup: Function
* }}
* @private
*/
export function _storeNetworkInfoCleanup(cleanup: Function): Object {
return {
type: _STORE_NETWORK_INFO_CLEANUP,
cleanup
};
}
6 changes: 6 additions & 0 deletions react/features/base/net-info/constants.js
@@ -0,0 +1,6 @@
/**
* The name for Redux store key used by the 'base/net-info' feature.
*
* @type {string}
*/
export const STORE_NAME = 'features/base/net-info';
1 change: 1 addition & 0 deletions react/features/base/net-info/events.js
@@ -0,0 +1 @@
export const ONLINE_STATE_CHANGED_EVENT = 'network-info-online-status-change';
4 changes: 4 additions & 0 deletions react/features/base/net-info/index.js
@@ -0,0 +1,4 @@
export * from './actionTypes';

import './middleware';
import './reducer';
5 changes: 5 additions & 0 deletions react/features/base/net-info/logger.js
@@ -0,0 +1,5 @@
// @flow

import { getLogger } from '../logging/functions';

export default getLogger('features/base/net-info');

0 comments on commit 6ae9bbe

Please sign in to comment.