mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-05-05 23:47:44 +02:00
Merge pull request #2673 from vector-im/riot_2646
VoIP: Fallback to matrix.org STUN server with a confirmation dialog
This commit is contained in:
+3
-1
@@ -5,7 +5,9 @@ Improvements:
|
||||
* Upgrade MatrixKit version ([v0.11.0](https://github.com/matrix-org/matrix-ios-kit/releases/tag/v0.11.0)).
|
||||
* Privacy: Prompt to accept integration manager policies on use (#2600).
|
||||
* Privacy: Make clear that device names are publicly readable (#2662).
|
||||
* Widgets: Whitelist [MSC1961](https://github.com/matrix-org/matrix-doc/pull/1961) widget urls
|
||||
* Widgets: Whitelist [MSC1961](https://github.com/matrix-org/matrix-doc/pull/1961) widget urls.
|
||||
* Settings: CALLS section: Always display the CallKit option but grey it out when not available (only on China).
|
||||
* VoIP: Fallback to matrix.org STUN server with a confirmation dialog (#2646).
|
||||
|
||||
Changes in 0.9.2 (2019-08-08)
|
||||
===============================================
|
||||
|
||||
@@ -2605,6 +2605,11 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
|
||||
// Let's call invite be valid for 1 minute
|
||||
mxSession.callManager.inviteLifetime = 60000;
|
||||
|
||||
if (RiotSettings.shared.allowStunServerFallback)
|
||||
{
|
||||
mxSession.callManager.fallbackSTUNServer = RiotSettings.shared.stunServerFallback;
|
||||
}
|
||||
|
||||
// Setup CallKit
|
||||
if ([MXCallKitAdapter callKitAvailable])
|
||||
{
|
||||
@@ -3850,6 +3855,12 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
|
||||
NSString *btnTitle = [NSString stringWithFormat:NSLocalizedStringFromTable(@"active_call_details", @"Vector", nil), callViewController.callerNameLabel.text];
|
||||
[self addCallStatusBar:btnTitle];
|
||||
}
|
||||
|
||||
if ([callViewController isKindOfClass:[CallViewController class]]
|
||||
&& ((CallViewController*)callViewController).shouldPromptForStunServerFallback)
|
||||
{
|
||||
[self promptForStunServerFallback];
|
||||
}
|
||||
|
||||
if (completion)
|
||||
{
|
||||
@@ -3883,6 +3894,52 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
|
||||
}
|
||||
}
|
||||
|
||||
- (void)promptForStunServerFallback
|
||||
{
|
||||
[_errorNotification dismissViewControllerAnimated:NO completion:nil];
|
||||
|
||||
NSString *stunFallbackHost = RiotSettings.shared.stunServerFallback;
|
||||
// Remove "stun:"
|
||||
stunFallbackHost = [stunFallbackHost componentsSeparatedByString:@":"].lastObject;
|
||||
|
||||
MXSession *mainSession = self.mxSessions.firstObject;
|
||||
NSString *homeServerName = mainSession.matrixRestClient.credentials.homeServerName;
|
||||
|
||||
NSString *message = [NSString stringWithFormat:@"%@\n\n%@",
|
||||
[NSString stringWithFormat:NSLocalizedStringFromTable(@"call_no_stun_server_error_message_1", @"Vector", nil), homeServerName],
|
||||
[NSString stringWithFormat: NSLocalizedStringFromTable(@"call_no_stun_server_error_message_2", @"Vector", nil), stunFallbackHost]];
|
||||
|
||||
_errorNotification = [UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"call_no_stun_server_error_title", @"Vector", nil)
|
||||
message:message
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[_errorNotification addAction:[UIAlertAction actionWithTitle:[NSString stringWithFormat: NSLocalizedStringFromTable(@"call_no_stun_server_error_use_fallback_button", @"Vector", nil), stunFallbackHost]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
RiotSettings.shared.allowStunServerFallback = YES;
|
||||
mainSession.callManager.fallbackSTUNServer = RiotSettings.shared.stunServerFallback;
|
||||
|
||||
[AppDelegate theDelegate].errorNotification = nil;
|
||||
}]];
|
||||
|
||||
[_errorNotification addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"]
|
||||
style:UIAlertActionStyleCancel
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
RiotSettings.shared.allowStunServerFallback = NO;
|
||||
|
||||
[AppDelegate theDelegate].errorNotification = nil;
|
||||
}]];
|
||||
|
||||
// Display the error notification
|
||||
if (!isErrorNotificationSuspended)
|
||||
{
|
||||
[_errorNotification mxk_setAccessibilityIdentifier:@"AppDelegateErrorAlert"];
|
||||
[self showNotificationAlert:_errorNotification];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Jitsi call
|
||||
|
||||
- (void)displayJitsiViewControllerWithWidget:(Widget*)jitsiWidget andVideo:(BOOL)video
|
||||
|
||||
@@ -59,6 +59,8 @@
|
||||
<false/>
|
||||
<key>createConferenceCallsWithJitsi</key>
|
||||
<true/>
|
||||
<key>stunServerFallback</key>
|
||||
<string>stun:turn.matrix.org</string>
|
||||
<key>enableRageShake</key>
|
||||
<true/>
|
||||
<key>maxAllowedMediaCacheSize</key>
|
||||
|
||||
@@ -405,6 +405,9 @@
|
||||
|
||||
"settings_enable_callkit" = "Integrated calling";
|
||||
"settings_callkit_info" = "Receive incoming calls on your lock screen. See your Riot calls in the system's call history. If iCloud is enabled, this call history will be shared with Apple.";
|
||||
"settings_calls_stun_server_fallback_button" = "Allow fallback call assist server";
|
||||
"settings_calls_stun_server_fallback_description" = "Allow fallback call assist server %@ when your homeserver does not offer one (your IP address would be shared during a call).";
|
||||
|
||||
"settings_ui_language" = "Language";
|
||||
"settings_ui_theme" = "Theme";
|
||||
"settings_ui_theme_auto" = "Auto";
|
||||
@@ -631,6 +634,11 @@
|
||||
"call_already_displayed" = "There is already a call in progress.";
|
||||
"call_jitsi_error" = "Failed to join the conference call.";
|
||||
|
||||
"call_no_stun_server_error_title" ="Call failed due to misconfigured server";
|
||||
"call_no_stun_server_error_message_1" ="Please ask the administrator of your homeserver %@ to configure a TURN server in order for calls to work reliably.";
|
||||
"call_no_stun_server_error_message_2" ="Alternatively, you can try to use the public server at %@, but this will not be as reliable, and it will share your IP address with that server. You can also manage this in Settings";
|
||||
"call_no_stun_server_error_use_fallback_button" = "Try using %@";
|
||||
|
||||
// No VoIP support
|
||||
"no_voip_title" = "Incoming call";
|
||||
"no_voip" = "%@ is calling you but %@ does not support calls yet.\nYou can ignore this notification and answer the call from another device or you can reject it.";
|
||||
|
||||
@@ -39,6 +39,7 @@ internal enum RiotDefaults {
|
||||
internal static let showRedactionsInRoomHistory: Bool = _document["showRedactionsInRoomHistory"]
|
||||
internal static let showUnsupportedEventsInRoomHistory: Bool = _document["showUnsupportedEventsInRoomHistory"]
|
||||
internal static let sortRoomMembersUsingLastSeenTime: Bool = _document["sortRoomMembersUsingLastSeenTime"]
|
||||
internal static let stunServerFallback: String = _document["stunServerFallback"]
|
||||
internal static let syncLocalContacts: Bool = _document["syncLocalContacts"]
|
||||
internal static let webAppUrl: String = _document["webAppUrl"]
|
||||
internal static let webAppUrlBeta: String = _document["webAppUrlBeta"]
|
||||
|
||||
@@ -370,6 +370,22 @@ internal enum VectorL10n {
|
||||
internal static var callJitsiError: String {
|
||||
return VectorL10n.tr("Vector", "call_jitsi_error")
|
||||
}
|
||||
/// Please ask the administrator of your homeserver %@ to configure a TURN server in order for calls to work reliably.
|
||||
internal static func callNoStunServerErrorMessage1(_ p1: String) -> String {
|
||||
return VectorL10n.tr("Vector", "call_no_stun_server_error_message_1", p1)
|
||||
}
|
||||
/// Alternatively, you can try to use the public server at %@, but this will not be as reliable, and it will share your IP address with that server. You can also manage this in Settings
|
||||
internal static func callNoStunServerErrorMessage2(_ p1: String) -> String {
|
||||
return VectorL10n.tr("Vector", "call_no_stun_server_error_message_2", p1)
|
||||
}
|
||||
/// Call failed due to misconfigured server
|
||||
internal static var callNoStunServerErrorTitle: String {
|
||||
return VectorL10n.tr("Vector", "call_no_stun_server_error_title")
|
||||
}
|
||||
/// Try using %@
|
||||
internal static func callNoStunServerErrorUseFallbackButton(_ p1: String) -> String {
|
||||
return VectorL10n.tr("Vector", "call_no_stun_server_error_use_fallback_button", p1)
|
||||
}
|
||||
/// Camera
|
||||
internal static var camera: String {
|
||||
return VectorL10n.tr("Vector", "camera")
|
||||
@@ -2394,6 +2410,14 @@ internal enum VectorL10n {
|
||||
internal static var settingsCallsSettings: String {
|
||||
return VectorL10n.tr("Vector", "settings_calls_settings")
|
||||
}
|
||||
/// Allow fallback call assist server
|
||||
internal static var settingsCallsStunServerFallbackButton: String {
|
||||
return VectorL10n.tr("Vector", "settings_calls_stun_server_fallback_button")
|
||||
}
|
||||
/// Allow fallback call assist server %@ when your homeserver does not offer one (your IP address would be shared during a call).
|
||||
internal static func settingsCallsStunServerFallbackDescription(_ p1: String) -> String {
|
||||
return VectorL10n.tr("Vector", "settings_calls_stun_server_fallback_description", p1)
|
||||
}
|
||||
/// Change password
|
||||
internal static var settingsChangePassword: String {
|
||||
return VectorL10n.tr("Vector", "settings_change_password")
|
||||
|
||||
@@ -30,6 +30,8 @@ final class RiotSettings: NSObject {
|
||||
static let notificationsShowDecryptedContent = "showDecryptedContent"
|
||||
static let pinRoomsWithMissedNotifications = "pinRoomsWithMissedNotif"
|
||||
static let pinRoomsWithUnreadMessages = "pinRoomsWithUnread"
|
||||
static let allowStunServerFallback = "allowStunServerFallback"
|
||||
static let stunServerFallback = "stunServerFallback"
|
||||
}
|
||||
|
||||
/// Riot Standard Room Member Power Level
|
||||
@@ -119,4 +121,24 @@ final class RiotSettings: NSObject {
|
||||
UserDefaults.standard.set(newValue, forKey: UserDefaultsKeys.createConferenceCallsWithJitsi)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: Calls
|
||||
|
||||
/// Indicate if `allowStunServerFallback` settings has been set once.
|
||||
var isAllowStunServerFallbackHasBeenSetOnce: Bool {
|
||||
return UserDefaults.standard.object(forKey: UserDefaultsKeys.allowStunServerFallback) != nil
|
||||
}
|
||||
|
||||
var allowStunServerFallback: Bool {
|
||||
get {
|
||||
return UserDefaults.standard.bool(forKey: UserDefaultsKeys.allowStunServerFallback)
|
||||
} set {
|
||||
UserDefaults.standard.set(newValue, forKey: UserDefaultsKeys.allowStunServerFallback)
|
||||
}
|
||||
}
|
||||
|
||||
var stunServerFallback: String? {
|
||||
return UserDefaults.standard.string(forKey: UserDefaultsKeys.stunServerFallback)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,4 +26,7 @@
|
||||
|
||||
@property (unsafe_unretained, nonatomic) IBOutlet NSLayoutConstraint *callerImageViewWidthConstraint;
|
||||
|
||||
// At the end of call, this flag indicates if the prompt to use the fallback should be displayed
|
||||
@property (nonatomic) BOOL shouldPromptForStunServerFallback;
|
||||
|
||||
@end
|
||||
|
||||
@@ -39,6 +39,9 @@
|
||||
|
||||
// Observe kThemeServiceDidChangeThemeNotification to handle user interface theme change.
|
||||
id kThemeServiceDidChangeThemeNotificationObserver;
|
||||
|
||||
// Flag to compute self.shouldPromptForStunServerFallback
|
||||
BOOL promptForStunServerFallback;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -52,6 +55,9 @@
|
||||
// Setup `MXKViewControllerHandling` properties
|
||||
self.enableBarTintColorStatusChange = NO;
|
||||
self.rageShakeManager = [RageShakeManager sharedManager];
|
||||
|
||||
promptForStunServerFallback = NO;
|
||||
_shouldPromptForStunServerFallback = NO;
|
||||
}
|
||||
|
||||
- (void)viewDidLoad
|
||||
@@ -229,6 +235,13 @@
|
||||
|
||||
#pragma mark - MXCallDelegate
|
||||
|
||||
- (void)call:(MXCall *)call stateDidChange:(MXCallState)state reason:(MXEvent *)event
|
||||
{
|
||||
[super call:call stateDidChange:state reason:event];
|
||||
|
||||
[self checkStunServerFallbackWithCallState:state];
|
||||
}
|
||||
|
||||
- (void)call:(MXCall *)call didEncounterError:(NSError *)error
|
||||
{
|
||||
if ([error.domain isEqualToString:MXEncryptingErrorDomain]
|
||||
@@ -333,6 +346,41 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Fallback STUN server
|
||||
|
||||
- (void)checkStunServerFallbackWithCallState:(MXCallState)callState
|
||||
{
|
||||
// Detect if we should display the prompt to fallback to the STUN server defined
|
||||
// in the app plist if the homeserver does not provide STUN or TURN servers.
|
||||
// We should if the call ends while we were in connecting state
|
||||
if (!self.mainSession.callManager.turnServers
|
||||
&& !self.mainSession.callManager.fallbackSTUNServer
|
||||
&& !RiotSettings.shared.isAllowStunServerFallbackHasBeenSetOnce)
|
||||
{
|
||||
switch (callState)
|
||||
{
|
||||
case MXCallStateConnecting:
|
||||
promptForStunServerFallback = YES;
|
||||
break;
|
||||
|
||||
case MXCallStateConnected:
|
||||
promptForStunServerFallback = NO;
|
||||
break;
|
||||
|
||||
case MXCallStateEnded:
|
||||
if (promptForStunServerFallback)
|
||||
{
|
||||
_shouldPromptForStunServerFallback = YES;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
- (UIImage*)picturePlaceholder
|
||||
|
||||
@@ -86,7 +86,9 @@ enum
|
||||
enum
|
||||
{
|
||||
CALLS_ENABLE_CALLKIT_INDEX = 0,
|
||||
CALLS_DESCRIPTION_INDEX,
|
||||
CALLS_CALLKIT_DESCRIPTION_INDEX,
|
||||
CALLS_ENABLE_STUN_SERVER_FALLBACK_INDEX,
|
||||
CALLS_STUN_SERVER_FALLBACK_DESCRIPTION_INDEX,
|
||||
CALLS_COUNT
|
||||
};
|
||||
|
||||
@@ -1265,9 +1267,11 @@ SingleImagePickerPresenterDelegate>
|
||||
}
|
||||
else if (section == SETTINGS_SECTION_CALLS_INDEX)
|
||||
{
|
||||
if ([MXCallKitAdapter callKitAvailable])
|
||||
count = CALLS_COUNT;
|
||||
|
||||
if (!RiotSettings.shared.stunServerFallback)
|
||||
{
|
||||
count = CALLS_COUNT;
|
||||
count -= 2;
|
||||
}
|
||||
}
|
||||
else if (section == SETTINGS_SECTION_USER_INTERFACE_INDEX)
|
||||
@@ -1827,16 +1831,52 @@ SingleImagePickerPresenterDelegate>
|
||||
labelAndSwitchCell.mxkSwitch.onTintColor = ThemeService.shared.theme.tintColor;
|
||||
labelAndSwitchCell.mxkSwitch.enabled = YES;
|
||||
[labelAndSwitchCell.mxkSwitch addTarget:self action:@selector(toggleCallKit:) forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
|
||||
if (![MXCallKitAdapter callKitAvailable])
|
||||
{
|
||||
labelAndSwitchCell.mxkSwitch.on = NO;
|
||||
labelAndSwitchCell.mxkSwitch.enabled = NO;
|
||||
labelAndSwitchCell.mxkLabel.enabled = NO;
|
||||
}
|
||||
|
||||
cell = labelAndSwitchCell;
|
||||
}
|
||||
else if (row == CALLS_DESCRIPTION_INDEX)
|
||||
else if (row == CALLS_CALLKIT_DESCRIPTION_INDEX)
|
||||
{
|
||||
MXKTableViewCell *globalInfoCell = [self getDefaultTableViewCell:tableView];
|
||||
globalInfoCell.textLabel.text = NSLocalizedStringFromTable(@"settings_callkit_info", @"Vector", nil);
|
||||
globalInfoCell.textLabel.numberOfLines = 0;
|
||||
globalInfoCell.selectionStyle = UITableViewCellSelectionStyleNone;
|
||||
|
||||
|
||||
if (![MXCallKitAdapter callKitAvailable])
|
||||
{
|
||||
globalInfoCell.textLabel.enabled = NO;
|
||||
}
|
||||
|
||||
cell = globalInfoCell;
|
||||
}
|
||||
else if (row == CALLS_ENABLE_STUN_SERVER_FALLBACK_INDEX)
|
||||
{
|
||||
MXKTableViewCellWithLabelAndSwitch* labelAndSwitchCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath];
|
||||
labelAndSwitchCell.mxkLabel.text = NSLocalizedStringFromTable(@"settings_calls_stun_server_fallback_button", @"Vector", nil);
|
||||
labelAndSwitchCell.mxkSwitch.on = RiotSettings.shared.allowStunServerFallback;
|
||||
labelAndSwitchCell.mxkSwitch.onTintColor = ThemeService.shared.theme.tintColor;
|
||||
labelAndSwitchCell.mxkSwitch.enabled = YES;
|
||||
[labelAndSwitchCell.mxkSwitch addTarget:self action:@selector(toggleStunServerFallback:) forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
cell = labelAndSwitchCell;
|
||||
}
|
||||
else if (row == CALLS_STUN_SERVER_FALLBACK_DESCRIPTION_INDEX)
|
||||
{
|
||||
NSString *stunFallbackHost = RiotSettings.shared.stunServerFallback;
|
||||
// Remove "stun:"
|
||||
stunFallbackHost = [stunFallbackHost componentsSeparatedByString:@":"].lastObject;
|
||||
|
||||
MXKTableViewCell *globalInfoCell = [self getDefaultTableViewCell:tableView];
|
||||
globalInfoCell.textLabel.text = [NSString stringWithFormat:NSLocalizedStringFromTable(@"settings_calls_stun_server_fallback_description", @"Vector", nil), stunFallbackHost];
|
||||
globalInfoCell.textLabel.numberOfLines = 0;
|
||||
globalInfoCell.selectionStyle = UITableViewCellSelectionStyleNone;
|
||||
|
||||
cell = globalInfoCell;
|
||||
}
|
||||
}
|
||||
@@ -2337,10 +2377,7 @@ SingleImagePickerPresenterDelegate>
|
||||
}
|
||||
else if (section == SETTINGS_SECTION_CALLS_INDEX)
|
||||
{
|
||||
if ([MXCallKitAdapter callKitAvailable])
|
||||
{
|
||||
return NSLocalizedStringFromTable(@"settings_calls_settings", @"Vector", nil);
|
||||
}
|
||||
return NSLocalizedStringFromTable(@"settings_calls_settings", @"Vector", nil);
|
||||
}
|
||||
else if (section == SETTINGS_SECTION_USER_INTERFACE_INDEX)
|
||||
{
|
||||
@@ -2486,13 +2523,6 @@ SingleImagePickerPresenterDelegate>
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (section == SETTINGS_SECTION_CALLS_INDEX)
|
||||
{
|
||||
if (![MXCallKitAdapter callKitAvailable])
|
||||
{
|
||||
return SECTION_TITLE_PADDING_WHEN_HIDDEN;
|
||||
}
|
||||
}
|
||||
else if (section == SETTINGS_SECTION_FLAIR_INDEX)
|
||||
{
|
||||
if (groupsDataSource.joinedGroupsSection == -1)
|
||||
@@ -2518,13 +2548,6 @@ SingleImagePickerPresenterDelegate>
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (section == SETTINGS_SECTION_CALLS_INDEX)
|
||||
{
|
||||
if (![MXCallKitAdapter callKitAvailable])
|
||||
{
|
||||
return SECTION_TITLE_PADDING_WHEN_HIDDEN;
|
||||
}
|
||||
}
|
||||
else if (section == SETTINGS_SECTION_FLAIR_INDEX)
|
||||
{
|
||||
if (groupsDataSource.joinedGroupsSection == -1)
|
||||
@@ -2953,6 +2976,14 @@ SingleImagePickerPresenterDelegate>
|
||||
[MXKAppSettings standardAppSettings].enableCallKit = switchButton.isOn;
|
||||
}
|
||||
|
||||
- (void)toggleStunServerFallback:(id)sender
|
||||
{
|
||||
UISwitch *switchButton = (UISwitch*)sender;
|
||||
RiotSettings.shared.allowStunServerFallback = switchButton.isOn;
|
||||
|
||||
self.mainSession.callManager.fallbackSTUNServer = RiotSettings.shared.allowStunServerFallback ? RiotSettings.shared.stunServerFallback : nil;
|
||||
}
|
||||
|
||||
- (void)toggleShowDecodedContent:(id)sender
|
||||
{
|
||||
UISwitch *switchButton = (UISwitch*)sender;
|
||||
|
||||
Reference in New Issue
Block a user