[iOS] Refactor muted state handling in CallKit

Rely solely on actual track state, rather than the desired state, (what
base/media represents).
This commit is contained in:
Saúl Ibarra Corretgé 2018-06-15 12:09:53 +02:00
parent 84c1c3dfd3
commit 8c7a3f16b1
1 changed files with 23 additions and 75 deletions

View File

@ -19,13 +19,16 @@ import {
import { getInviteURL } from '../../base/connection'; import { getInviteURL } from '../../base/connection';
import { import {
MEDIA_TYPE, MEDIA_TYPE,
SET_AUDIO_MUTED,
SET_VIDEO_MUTED,
isVideoMutedByAudioOnly, isVideoMutedByAudioOnly,
setAudioMuted setAudioMuted
} from '../../base/media'; } from '../../base/media';
import { MiddlewareRegistry } from '../../base/redux'; import { MiddlewareRegistry } from '../../base/redux';
import { TRACK_CREATE_ERROR, isLocalTrackMuted } from '../../base/tracks'; import {
TRACK_ADDED,
TRACK_REMOVED,
TRACK_UPDATED,
isLocalTrackMuted
} from '../../base/tracks';
import { _SET_CALLKIT_SUBSCRIPTIONS } from './actionTypes'; import { _SET_CALLKIT_SUBSCRIPTIONS } from './actionTypes';
import CallKit from './CallKit'; import CallKit from './CallKit';
@ -63,14 +66,10 @@ CallKit && MiddlewareRegistry.register(store => next => action => {
case CONFERENCE_WILL_JOIN: case CONFERENCE_WILL_JOIN:
return _conferenceWillJoin(store, next, action); return _conferenceWillJoin(store, next, action);
case SET_AUDIO_MUTED: case TRACK_ADDED:
return _setAudioMuted(store, next, action); case TRACK_REMOVED:
case TRACK_UPDATED:
case SET_VIDEO_MUTED: return _syncTrackState(store, next, action);
return _setVideoMuted(store, next, action);
case TRACK_CREATE_ERROR:
return _trackCreateError(store, next, action);
} }
return next(action); return next(action);
@ -293,40 +292,15 @@ function _onPerformSetMutedCallAction({ callUUID, muted: newValue }) {
const tracks = getState()['features/base/tracks']; const tracks = getState()['features/base/tracks'];
const oldValue = isLocalTrackMuted(tracks, MEDIA_TYPE.AUDIO); const oldValue = isLocalTrackMuted(tracks, MEDIA_TYPE.AUDIO);
if (oldValue !== newValue) { newValue = Boolean(newValue); // eslint-disable-line no-param-reassign
const value = Boolean(newValue);
sendAnalytics(createTrackMutedEvent('audio', 'callkit', value)); if (oldValue !== newValue) {
dispatch(setAudioMuted(value, /* ensureTrack */ true)); sendAnalytics(createTrackMutedEvent('audio', 'callkit', newValue));
dispatch(setAudioMuted(newValue, /* ensureTrack */ true));
} }
} }
} }
/**
* Notifies the feature callkit that the action {@link SET_AUDIO_MUTED} is being
* dispatched within a specific redux {@code store}.
*
* @param {Store} store - The redux store in which the specified {@code action}
* is being dispatched.
* @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
* specified {@code action} in the specified {@code store}.
* @param {Action} action - The redux action {@code SET_AUDIO_MUTED} which is
* being dispatched in the specified {@code store}.
* @private
* @returns {*} The value returned by {@code next(action)}.
*/
function _setAudioMuted({ getState }, next, action) {
const result = next(action);
const conference = getCurrentConference(getState);
if (conference && conference.callUUID) {
CallKit.setMuted(conference.callUUID, action.muted);
}
return result;
}
/** /**
* Notifies the feature callkit that the action * Notifies the feature callkit that the action
* {@link _SET_CALLKIT_SUBSCRIPTIONS} is being dispatched within a specific * {@link _SET_CALLKIT_SUBSCRIPTIONS} is being dispatched within a specific
@ -354,57 +328,31 @@ function _setCallKitSubscriptions({ getState }, next, action) {
} }
/** /**
* Notifies the feature callkit that the action {@link SET_VIDEO_MUTED} is being * Synchronize the muted state of tracks with CallKit.
* dispatched within a specific redux {@code store}.
* *
* @param {Store} store - The redux store in which the specified {@code action} * @param {Store} store - The redux store in which the specified {@code action}
* is being dispatched. * is being dispatched.
* @param {Dispatch} next - The redux {@code dispatch} function to dispatch the * @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
* specified {@code action} in the specified {@code store}. * specified {@code action} in the specified {@code store}.
* @param {Action} action - The redux action {@code SET_VIDEO_MUTED} which is * @param {Action} action - The redux action which is being dispatched in the
* being dispatched in the specified {@code store}. * specified {@code store}.
* @private * @private
* @returns {*} The value returned by {@code next(action)}. * @returns {*} The value returned by {@code next(action)}.
*/ */
function _setVideoMuted({ getState }, next, action) { function _syncTrackState({ getState }, next, action) {
const result = next(action);
const conference = getCurrentConference(getState);
if (conference && conference.callUUID) {
CallKit.updateCall(
conference.callUUID,
{ hasVideo: !isVideoMutedByAudioOnly(getState) });
}
return result;
}
/**
* Handles a track creation failure. This is relevant to us in the following
* (corner) case: if the user never gave their permission to use the microphone
* and try to unmute from the CallKit interface, this will fail, and we need to
* sync back the CallKit button state.
*
* @param {Store} store - The redux store in which the specified {@code action}
* is being dispatched.
* @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
* specified {@code action} in the specified {@code store}.
* @param {Action} action - The redux action {@code TRACK_CREARE_ERROR} which is
* being dispatched in the specified {@code store}.
* @private
* @returns {*} The value returned by {@code next(action)}.
*/
function _trackCreateError({ getState }, next, action) {
const result = next(action); const result = next(action);
const { track } = action;
const state = getState(); const state = getState();
const conference = getCurrentConference(state); const conference = getCurrentConference(state);
if (conference && conference.callUUID) { if (track.local && conference && conference.callUUID) {
const tracks = state['features/base/tracks']; const tracks = state['features/base/tracks'];
const muted = isLocalTrackMuted(tracks, MEDIA_TYPE.AUDIO); const muted = isLocalTrackMuted(tracks, MEDIA_TYPE.AUDIO);
CallKit.setMuted(conference.callUUID, muted); CallKit.setMuted(conference.callUUID, muted);
CallKit.updateCall(
conference.callUUID,
{ hasVideo: !isVideoMutedByAudioOnly(state) });
} }
return result; return result;