Skip to content

Commit

Permalink
Fix connection bar being flaky
Browse files Browse the repository at this point in the history
This also resolves a race condition that happened on iOS where the
state had been dispatched too soon (or too late, depending on ones
perspective).

Followup to #815/#812. Resolves #580.
  • Loading branch information
lgrahl committed Jun 26, 2019
1 parent 898e716 commit d4c5003
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 54 deletions.
4 changes: 3 additions & 1 deletion src/controllers/status.ts
Expand Up @@ -81,7 +81,9 @@ export class StatusController {
// Register event handlers
this.stateService.evtGlobalConnectionStateChange.attach(
(stateChange: threema.GlobalConnectionStateChange) => {
this.onStateChange(stateChange.state, stateChange.prevState);
$scope.$apply(() => {
this.onStateChange(stateChange.state, stateChange.prevState);
});
},
);
this.stateService.evtUnreadCountChange.attach(
Expand Down
112 changes: 59 additions & 53 deletions src/services/webclient.ts
Expand Up @@ -524,6 +524,7 @@ export class WebClientService {
}
break;
case 'task':
this.onTaskEstablished(resumeSession);
break;
case 'closing':
case 'closed':
Expand All @@ -536,59 +537,6 @@ export class WebClientService {
this.stateService.updateSignalingConnectionState(state, this.chosenTask, this.handoverDone);
});

// Once the connection is established, if this is a WebRTC connection,
// initiate the peer connection and start the handover.
this.salty.once('state-change:task', () => {
// Pushing complete
this.resetPushSession(true);

// Peer handshake
this.stateService.updateConnectionBuildupState('peer_handshake');

// Determine chosen task
const task = this.salty.getTask();
if (task.getName().indexOf('webrtc.tasks.saltyrtc.org') !== -1) {
this.chosenTask = threema.ChosenTask.WebRTC;
} else if (task.getName().indexOf('relayed-data.tasks.saltyrtc.org') !== -1) {
this.chosenTask = threema.ChosenTask.RelayedData;
} else {
throw new Error('Invalid or unknown task name: ' + task.getName());
}

// If the WebRTC task was chosen, initialize handover.
if (this.chosenTask === threema.ChosenTask.WebRTC) {
const browser = this.browserService.getBrowser();

// Firefox <53 does not yet support TLS. Skip it, to save allocations.
if (browser.isFirefox(true) && browser.version < 53) {
this.skipIceTls();
}

// Safari does not support our dual-stack TURN servers.
if (browser.isSafari(false)) {
this.skipIceDs();
}

this.pcHelper = new PeerConnectionHelper(this.$log, this.$q, this.$timeout,
this.$rootScope, this.webrtcTask,
this.config.ICE_SERVERS,
!this.config.VERBOSE_DEBUGGING);

// On state changes in the PeerConnectionHelper class, let state service know about it
this.pcHelper.onConnectionStateChange = (state: threema.TaskConnectionState) => {
this.stateService.updateTaskConnectionState(state);
};

// Initiate handover
this.webrtcTask.handover(this.pcHelper.peerConnection);

// Otherwise, no handover is necessary.
} else {
this.onHandover(resumeSession);
return;
}
});

// Handle disconnecting of a peer
this.salty.on('peer-disconnected', (ev: saltyrtc.SaltyRTCEvent) => {
this.$rootScope.$apply(() => {
Expand Down Expand Up @@ -866,6 +814,64 @@ export class WebClientService {
}
}

/**
* Once the SaltyRTC task has been established...
*
* - for Android, initiate the peer connection and start the handover,
* - for iOS, no further action is necessary and the connection is
* considered established.
*/
private onTaskEstablished(resumeSession: boolean) {
// Pushing complete
this.resetPushSession(true);

// Peer handshake
this.stateService.updateConnectionBuildupState('peer_handshake');

// Determine chosen task
const task = this.salty.getTask();
if (task.getName().indexOf('webrtc.tasks.saltyrtc.org') !== -1) {
this.chosenTask = threema.ChosenTask.WebRTC;
} else if (task.getName().indexOf('relayed-data.tasks.saltyrtc.org') !== -1) {
this.chosenTask = threema.ChosenTask.RelayedData;
} else {
throw new Error('Invalid or unknown task name: ' + task.getName());
}

// If the WebRTC task was chosen, initialize handover.
if (this.chosenTask === threema.ChosenTask.WebRTC) {
const browser = this.browserService.getBrowser();

// Firefox <53 does not yet support TLS. Skip it, to save allocations.
if (browser.isFirefox(true) && browser.version < 53) {
this.skipIceTls();
}

// Safari does not support our dual-stack TURN servers.
if (browser.isSafari(false)) {
this.skipIceDs();
}

this.pcHelper = new PeerConnectionHelper(this.$log, this.$q, this.$timeout,
this.$rootScope, this.webrtcTask,
this.config.ICE_SERVERS,
!this.config.VERBOSE_DEBUGGING);

// On state changes in the PeerConnectionHelper class, let state service know about it
this.pcHelper.onConnectionStateChange = (state: threema.TaskConnectionState) => {
this.stateService.updateTaskConnectionState(state);
};

// Initiate handover
this.webrtcTask.handover(this.pcHelper.peerConnection);

// Otherwise, no handover is necessary.
} else {
this.onHandover(resumeSession);
return;
}
}

/**
* For the WebRTC task, this is called when the DataChannel is open.
* For the relayed data task, this is called once the connection is established.
Expand Down

0 comments on commit d4c5003

Please sign in to comment.