Multiaccount: handle settings

This commit is contained in:
Gautier Pelloux-Prayer 2015-10-15 18:01:05 +02:00
parent a56ab71330
commit 8cb78d85a1
9 changed files with 154 additions and 109 deletions

View file

@ -29,5 +29,7 @@
}
- (void)transformLinphoneCoreToKeys;
- (void)transformAccountToKeys:(NSString *)username;
- (void)removeAccount;
@end

View file

@ -116,9 +116,73 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
}
}
- (void)transformAccountToKeys:(NSString *)username {
LinphoneCore *lc = [LinphoneManager getLc];
const MSList *proxies = linphone_core_get_proxy_config_list(lc);
while (proxies &&
strcmp(username.UTF8String,
linphone_address_get_username(linphone_proxy_config_get_identity_address(proxies->data))) != 0) {
proxies = proxies->next;
}
if (!proxies) {
// we must always find associated proxy config.
LOGF(@"Proxy not found for account with username %@. Please fix application.", username);
}
LinphoneProxyConfig *proxy = proxies->data;
[self setInteger:ms_list_index(linphone_core_get_proxy_config_list(lc), proxy)
forKey:@"current_proxy_config_preference"];
const LinphoneAddress *identity_addr = linphone_proxy_config_get_identity_address(proxy);
if (identity_addr) {
const char *server_addr = linphone_proxy_config_get_server_addr(proxy);
LinphoneAddress *proxy_addr = linphone_address_new(server_addr);
int port = linphone_address_get_port(proxy_addr);
[self setCString:linphone_address_get_username(identity_addr) forKey:@"username_preference"];
[self setCString:linphone_address_get_domain(identity_addr) forKey:@"domain_preference"];
if (strcmp(linphone_address_get_domain(identity_addr), linphone_address_get_domain(proxy_addr)) != 0 ||
port > 0) {
char tmp[256] = {0};
if (port > 0) {
snprintf(tmp, sizeof(tmp) - 1, "%s:%i", linphone_address_get_domain(proxy_addr), port);
} else
snprintf(tmp, sizeof(tmp) - 1, "%s", linphone_address_get_domain(proxy_addr));
[self setCString:tmp forKey:@"proxy_preference"];
}
const char *tname = "udp";
switch (linphone_address_get_transport(proxy_addr)) {
case LinphoneTransportTcp:
tname = "tcp";
break;
case LinphoneTransportTls:
tname = "tls";
break;
default:
break;
}
linphone_address_destroy(proxy_addr);
[self setCString:tname forKey:@"transport_preference"];
[self setBool:(linphone_proxy_config_get_route(proxy) != NULL) forKey:@"outbound_proxy_preference"];
[self setBool:linphone_proxy_config_avpf_enabled(proxy) forKey:@"avpf_preference"];
const LinphoneAuthInfo *ai =
linphone_core_find_auth_info(lc, NULL, [self stringForKey:@"username_preference"].UTF8String,
[self stringForKey:@"domain_preference"].UTF8String);
if (ai) {
[self setCString:linphone_auth_info_get_userid(ai) forKey:@"userid_preference"];
[self setCString:linphone_auth_info_get_passwd(ai) forKey:@"password_preference"];
// hidden but useful if provisioned
[self setCString:linphone_auth_info_get_ha1(ai) forKey:@"ha1_preference"];
}
}
}
- (void)transformLinphoneCoreToKeys {
LinphoneManager *lm = [LinphoneManager instance];
LinphoneCore *lc = [LinphoneManager getLc];
LinphoneProxyConfig *default_proxy = linphone_core_get_default_proxy_config(lc);
// root section
{
@ -134,80 +198,11 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
[self setBool:linphone_core_video_enabled(lc) forKey:@"enable_video_preference"];
[self setBool:[LinphoneManager.instance lpConfigBoolForKey:@"auto_answer"]
forKey:@"enable_auto_answer_preference"];
[self setBool:[lm lpConfigBoolForKey:@"advanced_account_preference"] forKey:@"advanced_account_preference"];
}
// account section
{
// todo
/*
LinphoneProxyConfig *cfg = NULL;
linphone_core_get_default_proxy(lc, &cfg);
if (cfg) {
const char *identity = linphone_proxy_config_get_identity(cfg);
LinphoneAddress *addr = linphone_address_new(identity);
if (addr) {
const char *proxy = linphone_proxy_config_get_addr(cfg);
LinphoneAddress *proxy_addr = linphone_address_new(proxy);
int port = linphone_address_get_port(proxy_addr);
[self setCString:linphone_address_get_username(addr) forKey:@"username_preference"];
[self setCString:linphone_address_get_domain(addr) forKey:@"domain_preference"];
if (strcmp(linphone_address_get_domain(addr), linphone_address_get_domain(proxy_addr)) != 0 ||
port > 0) {
char tmp[256] = {0};
if (port > 0) {
snprintf(tmp, sizeof(tmp) - 1, "%s:%i", linphone_address_get_domain(proxy_addr), port);
} else
snprintf(tmp, sizeof(tmp) - 1, "%s", linphone_address_get_domain(proxy_addr));
[self setCString:tmp forKey:@"proxy_preference"];
}
const char *tname = "udp";
switch (linphone_address_get_transport(proxy_addr)) {
case LinphoneTransportTcp:
tname = "tcp";
break;
case LinphoneTransportTls:
tname = "tls";
break;
default:
break;
}
linphone_address_destroy(addr);
linphone_address_destroy(proxy_addr);
[self setCString:tname forKey:@"transport_preference"];
[self setBool:(linphone_proxy_config_get_route(cfg) != NULL)forKey:@"outbound_proxy_preference"];
[self setBool:linphone_proxy_config_avpf_enabled(cfg) forKey:@"avpf_preference"];
// actually in Advanced section but proxy config dependent
[self setInteger:linphone_proxy_config_get_expires(cfg) forKey:@"expire_preference"];
// actually in Call section but proxy config dependent
[self setCString:linphone_proxy_config_get_dial_prefix(cfg) forKey:@"prefix_preference"];
// actually in Call section but proxy config dependent
[self setBool:linphone_proxy_config_get_dial_escape_plus(cfg) forKey:@"substitute_+_by_00_preference"];
}
} else {
[self setObject:@"" forKey:@"username_preference"];
[self setObject:@"" forKey:@"password_preference"];
[self setObject:@"" forKey:@"domain_preference"];
[self setObject:@"" forKey:@"proxy_preference"];
[self setCString:"udp" forKey:@"transport_preference"];
[self setBool:FALSE forKey:@"outbound_proxy_preference"];
[self setBool:FALSE forKey:@"avpf_preference"];
// actually in Advanced section but proxy config dependent
[self setInteger:[lm lpConfigIntForKey:@"reg_expires" forSection:@"default_values" withDefault:600]
forKey:@"expire_preference"];
}
LinphoneAuthInfo *ai;
const MSList *elem = linphone_core_get_auth_info_list(lc);
if (elem && (ai = (LinphoneAuthInfo *)elem->data)) {
[self setCString:linphone_auth_info_get_userid(ai) forKey:@"userid_preference"];
[self setCString:linphone_auth_info_get_passwd(ai) forKey:@"password_preference"];
// hidden but useful if provisioned
[self setCString:linphone_auth_info_get_ha1(ai) forKey:@"ha1_preference"];
}
[self setBool:[lm lpConfigBoolForKey:@"advanced_account_preference"] forKey:@"advanced_account_preference"];
*/
// this is filled by [self transformAccountToKeys] automatically
}
// audio section
@ -261,6 +256,13 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
[self setBool:[lm lpConfigBoolForKey:@"repeat_call_notification"]
forKey:@"repeat_call_notification_preference"];
// actually in Call section but proxy config dependent
const char *dial_prefix = default_proxy ? linphone_proxy_config_get_dial_prefix(default_proxy) : NULL;
[self setCString:dial_prefix forKey:@"prefix_preference"];
// actually in Call section but proxy config dependent
BOOL dial_escape_plus = default_proxy ? linphone_proxy_config_get_dial_escape_plus(default_proxy) : NO;
[self setBool:dial_escape_plus forKey:@"substitute_+_by_00_preference"];
}
// network section
@ -350,6 +352,10 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
}
linphone_address_destroy(parsed);
[self setCString:linphone_core_get_file_transfer_server(lc) forKey:@"file_transfer_server_url_preference"];
// actually in Advanced section but proxy config dependent
int expires = default_proxy ? linphone_proxy_config_get_expires(default_proxy) : -1;
[self setInteger:expires forKey:@"expire_preference"];
}
changedDict = [[NSMutableDictionary alloc] init];
@ -368,7 +374,8 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
[alertview show];
}
- (void)synchronizeAccount {
- (void)synchronizeAccounts {
LOGI(@"Account changed, synchronizing.");
LinphoneManager *lm = [LinphoneManager instance];
LinphoneCore *lc = [LinphoneManager getLc];
LinphoneProxyConfig *proxyCfg = NULL;
@ -590,7 +597,7 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
[self valueChangedForKey:@"substitute_+_by_00_preference"] || [self valueChangedForKey:@"use_ipv6"] ||
[self valueChangedForKey:@"avpf_preference"] || [self valueChangedForKey:@"pushnotification_preference"];
if (account_changed)
[self synchronizeAccount];
[self synchronizeAccounts];
bool enableVideo = [self boolForKey:@"enable_video_preference"];
linphone_core_enable_video(lc, enableVideo, enableVideo);
@ -823,4 +830,12 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
return YES;
}
- (void)removeAccount {
LinphoneCore *lc = [LinphoneManager getLc];
LinphoneProxyConfig *config = ms_list_nth_data(linphone_core_get_proxy_config_list(lc),
[self integerForKey:@"current_proxy_config_preference"]);
linphone_core_remove_proxy_config(lc, config);
linphone_core_clear_all_auth_info(lc); // TODO: only remove the right one
[self transformLinphoneCoreToKeys];
}
@end

View file

@ -876,6 +876,8 @@ static void linphone_iphone_popup_password_request(LinphoneCore *lc, const char
[alertView dismissWithClickedButtonIndex:0 animated:NO];
}
__weak UITextField *passwordField = [alertView textFieldAtIndex:0];
alertView = [[DTAlertView alloc]
initWithTitle:NSLocalizedString(@"Authentication needed.", nil)
message:[NSString stringWithFormat:NSLocalizedString(@"Registration failed because authentication is "
@ -885,8 +887,11 @@ static void linphone_iphone_popup_password_request(LinphoneCore *lc, const char
nil),
username, realm]];
alertView.alertViewStyle = UIAlertViewStyleSecureTextInput;
[alertView addCancelButtonWithTitle:NSLocalizedString(@"Cancel", nil) block:nil];
__weak UITextField *passwordField = [alertView textFieldAtIndex:0];
[alertView addCancelButtonWithTitle:NSLocalizedString(@"Go to settings", nil)
block:^{
SettingsView *view = VIEW(SettingsView);
[PhoneMainView.instance changeCurrentView:view.compositeViewDescription];
}];
[alertView addButtonWithTitle:NSLocalizedString(@"Continue", nil)
block:^{

View file

@ -337,6 +337,7 @@
labelTitleView.text = viewController.title;
[labelTitleView sizeToFit];
viewController.navigationItem.titleView = labelTitleView;
[super pushViewController:viewController animated:animated];
}
@ -358,9 +359,6 @@
@implementation SettingsView
@synthesize settingsController;
@synthesize navigationController;
#pragma mark - UICompositeViewDelegate Functions
static UICompositeViewDescription *compositeDescription = nil;
@ -388,21 +386,21 @@ static UICompositeViewDescription *compositeDescription = nil;
settingsStore = [[LinphoneCoreSettingsStore alloc] init];
settingsController.showDoneButton = FALSE;
settingsController.delegate = self;
settingsController.showCreditsFooter = FALSE;
settingsController.settingsStore = settingsStore;
_settingsController.showDoneButton = FALSE;
_settingsController.delegate = self;
_settingsController.showCreditsFooter = FALSE;
_settingsController.settingsStore = settingsStore;
[navigationController.view setBackgroundColor:[UIColor clearColor]];
[_navigationController.view setBackgroundColor:[UIColor clearColor]];
navigationController.view.frame = self.view.frame;
[navigationController pushViewController:settingsController animated:FALSE];
[self.view addSubview:navigationController.view];
_navigationController.view.frame = self.view.frame;
[_navigationController pushViewController:_settingsController animated:FALSE];
[self.view addSubview:_navigationController.view];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[settingsController dismiss:self];
[_settingsController dismiss:self];
// Set observer
[[NSNotificationCenter defaultCenter] removeObserver:self name:kIASKAppSettingChanged object:nil];
}
@ -412,8 +410,8 @@ static UICompositeViewDescription *compositeDescription = nil;
// Sync settings with linphone core settings
[settingsStore transformLinphoneCoreToKeys];
settingsController.hiddenKeys = [self findHiddenKeys];
[settingsController.tableView reloadData];
_settingsController.hiddenKeys = [self findHiddenKeys];
[_settingsController.tableView reloadData];
// Set observer
[[NSNotificationCenter defaultCenter] addObserver:self
@ -425,7 +423,7 @@ static UICompositeViewDescription *compositeDescription = nil;
#pragma mark - Event Functions
- (void)appSettingChanged:(NSNotification *)notif {
NSMutableSet *hiddenKeys = [NSMutableSet setWithSet:[settingsController hiddenKeys]];
NSMutableSet *hiddenKeys = [NSMutableSet setWithSet:[_settingsController hiddenKeys]];
NSMutableArray *keys = [NSMutableArray array];
BOOL removeFromHiddenKeys = TRUE;
@ -468,7 +466,7 @@ static UICompositeViewDescription *compositeDescription = nil;
[hiddenKeys addObject:key];
}
[settingsController setHiddenKeys:hiddenKeys animated:TRUE];
[_settingsController setHiddenKeys:hiddenKeys animated:TRUE];
}
#pragma mark -
@ -658,10 +656,27 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)settingsViewControllerDidEnd:(IASKAppSettingsViewController *)sender {
}
- (void)settingsViewControllerDidAppear:(IASKAppSettingsViewController *)sender {
// going to account: fill info
if ([sender.file isEqualToString:@"Account"]) {
LOGI(@"Going editting account %@", sender.title);
[settingsStore transformAccountToKeys:sender.title];
// coming back to default: if we were in account, we must synchronize account now
} else if ([sender.file isEqualToString:@"Root"]) {
[settingsStore synchronize];
// it's a bit violent... but IASK is not designed to dynamically change subviews' name
[_settingsController.settingsReader indexPathForKey:@"account_1_menu"]; // force refresh username'
[_settingsController.settingsReader indexPathForKey:@"account_2_menu"]; // force refresh username'
[_settingsController.settingsReader indexPathForKey:@"account_3_menu"]; // force refresh username'
[_settingsController.settingsReader indexPathForKey:@"account_4_menu"]; // force refresh username'
[_settingsController.settingsReader indexPathForKey:@"account_5_menu"]; // force refresh username'
[[_settingsController tableView] reloadData];
}
}
- (void)settingsViewController:(IASKAppSettingsViewController *)sender
buttonTappedForSpecifier:(IASKSpecifier *)specifier {
NSString *key = [specifier.specifierDict objectForKey:kIASKKey];
LinphoneCore *lc = [LinphoneManager getLc];
#ifdef DEBUG
if ([key isEqual:@"release_button"]) {
[UIApplication sharedApplication].keyWindow.rootViewController = nil;
@ -682,10 +697,6 @@ static UICompositeViewDescription *compositeDescription = nil;
[PhoneMainView.instance changeCurrentView:AssistantView.compositeViewDescription];
return;
} else if ([key isEqual:@"remove_proxy_button"]) {
if (linphone_core_get_default_proxy_config(lc) == NULL) {
return;
}
DTAlertView *alert = [[DTAlertView alloc]
initWithTitle:NSLocalizedString(@"Warning", nil)
message:NSLocalizedString(@"Are you sure to want to remove your proxy setup?", nil)];
@ -693,13 +704,21 @@ static UICompositeViewDescription *compositeDescription = nil;
[alert addCancelButtonWithTitle:NSLocalizedString(@"Cancel", nil) block:nil];
[alert addButtonWithTitle:NSLocalizedString(@"Yes", nil)
block:^{
linphone_core_clear_proxy_config(lc);
linphone_core_clear_all_auth_info(lc);
[settingsStore transformLinphoneCoreToKeys];
[settingsController.tableView reloadData];
[settingsStore removeAccount];
_settingsController.hiddenKeys = [self findHiddenKeys];
[_settingsController.settingsReader
indexPathForKey:@"account_1_menu"]; // force refresh username'
[_settingsController.settingsReader
indexPathForKey:@"account_2_menu"]; // force refresh username'
[_settingsController.settingsReader
indexPathForKey:@"account_3_menu"]; // force refresh username'
[_settingsController.settingsReader
indexPathForKey:@"account_4_menu"]; // force refresh username'
[_settingsController.settingsReader
indexPathForKey:@"account_5_menu"]; // force refresh username'
[_settingsController.navigationController popViewControllerAnimated:NO];
}];
[alert show];
} else if ([key isEqual:@"about_button"]) {
[PhoneMainView.instance changeCurrentView:AboutView.compositeViewDescription push:TRUE];
} else if ([key isEqualToString:@"reset_logs_button"]) {

View file

@ -26,6 +26,7 @@
@protocol IASKSettingsDelegate
- (void)settingsViewControllerDidEnd:(IASKAppSettingsViewController*)sender;
- (void)settingsViewControllerDidAppear:(IASKAppSettingsViewController *)sender;
@optional
#pragma mark - UITableView header customization

View file

@ -203,6 +203,12 @@ CGRect IASKCGRectSwap(CGRect rect);
object:[NSUserDefaults standardUserDefaults]];
[self userDefaultsDidChange]; // force update in case of changes while we were hidden
}
// hack gautier: be notified when changing page
if (self.delegate && [self.delegate conformsToProtocol:@protocol(IASKSettingsDelegate)]) {
[self.delegate settingsViewControllerDidAppear:self];
}
[super viewWillAppear:animated];
}
@ -720,8 +726,8 @@ CGRect IASKCGRectSwap(CGRect rect);
targetViewController.title = specifier.title;
targetViewController.showCreditsFooter = NO;
[[self navigationController] pushViewController:targetViewController animated:YES];
} else if ([[specifier type] isEqualToString:kIASKOpenURLSpecifier]) {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
} else if ([[specifier type] isEqualToString:kIASKOpenURLSpecifier]) {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:specifier.file]];
} else if ([[specifier type] isEqualToString:kIASKButtonSpecifier]) {
[tableView deselectRowAtIndexPath:indexPath animated:YES];

View file

@ -36,7 +36,7 @@ This SDK can be generated in 2 flavors:
* NO GPL third parties means that Linphone will only use non GPL code except for `liblinphone`, `mediastreamer2`, `oRTP` and `belle-sip`. If you choose this flavor, your final application is **still subject to GPL except if you have a [commercial license for the mentioned libraries](http://www.belledonne-communications.com/products.html)**.
To generate the liblinphone multi arch SDK without GPL third parties, invoke:
./prepare.py --disable-gpl-third-parties=no [other options] && make
./prepare.py --disable-gpl-third-parties [other options] && make
## Customizing features

View file

@ -2,7 +2,6 @@
<config xmlns="http://www.linphone.org/xsds/lpconfig.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.linphone.org/xsds/lpconfig.xsd lpconfig.xsd">
<section name="proxy_default_values">
<entry name="reg_proxy" overwrite="true">&lt;sip:sip.linphone.org;transport=tls&gt;</entry>
<entry name="reg_identity" overwrite="true">sip:?@sip.linphone.org</entry>
<entry name="reg_expires" overwrite="true">1314000</entry>
<entry name="reg_sendregister" overwrite="true">1</entry>
@ -12,11 +11,10 @@
<entry name="quality_reporting_collector" overwrite="true">sip:voip-metrics@sip.linphone.org;transport=tls</entry>
<entry name="quality_reporting_enabled" overwrite="true">1</entry>
<entry name="quality_reporting_interval" overwrite="true">180</entry>
<entry name="realm" overwrite="true">sip.linphone.org</entry>
</section>
<section name="assistant">
<entry name="username_regex" overwrite="true">^[a-z0-9-_\\.]*$</entry>
<entry name="username_regex" overwrite="true">^[a-z0-9_.\-]*$</entry>
<entry name="domain" overwrite="true">sip.linphone.org</entry>
<entry name="xmlrpc_url" overwrite="true">https://www.linphone.org/assistant.php</entry>
<entry name="sharing_server" overwrite="true">https://www.linphone.org:444/lft.php</entry>

View file

@ -2,7 +2,6 @@
<config xmlns="http://www.linphone.org/xsds/lpconfig.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.linphone.org/xsds/lpconfig.xsd lpconfig.xsd">
<section name="proxy_default_values">
<entry name="reg_proxy" overwrite="true">&lt;sip:sip.linphone.org;transport=tls&gt;</entry>
<entry name="reg_identity" overwrite="true">sip:?@sip.linphone.org</entry>
<entry name="reg_expires" overwrite="true">1314000</entry>
<entry name="reg_sendregister" overwrite="true">1</entry>
@ -16,7 +15,7 @@
</section>
<section name="assistant">
<entry name="username_regex" overwrite="true">^[a-z0-9-_\\.]*$</entry>
<entry name="username_regex" overwrite="true">^[a-z0-9_.\-]*$</entry>
<entry name="domain" overwrite="true">sip.linphone.org</entry>
<entry name="xmlrpc_url" overwrite="true">https://www.linphone.org/assistant.php</entry>
<entry name="sharing_server" overwrite="true">https://www.linphone.org:444/lft.php</entry>