Merge commit '339a57599de44242ea4728ea48a20bc692328b06' into 3.16.X

This commit is contained in:
Brieuc Viel 2017-04-11 16:24:43 +02:00
commit 97a520631f
371 changed files with 1888 additions and 847 deletions

6
.gitmodules vendored
View file

@ -105,3 +105,9 @@
[submodule "submodules/externals/libjpeg-turbo"]
path = submodules/externals/libjpeg-turbo
url = git://git.linphone.org/libjpeg-turbo.git
[submodule "submodules/mediastreamer2"]
path = submodules/mediastreamer2
url = gitosis@git.linphone.org:mediastreamer2
[submodule "submodules/ortp"]
path = submodules/ortp
url = gitosis@git.linphone.org:ortp

View file

@ -226,3 +226,9 @@ source_file = Classes/Base.lproj/AssistantLinkView.strings
source_lang = en
file_filter = Classes/<lang>.lproj/CountryListView.strings
source_file = Classes/Base.lproj/CountryListView.strings
[linphone-ios.inappsettingschatstrings]
source_lang = en
file_filter = Settings/InAppSettings.bundle/<lang>.lproj/Chat.strings
source_file = Settings/InAppSettings.bundle/en.lproj/Chat.strings
type = STRINGS

View file

@ -5,12 +5,26 @@ Group changes to describe their impact on the project, as follows:
Added for new features.
Changed for changes in existing functionality.
Deprecated for once-stable features removed in upcoming releases.é
Deprecated for once-stable features removed in upcoming releases.
Removed for deprecated features removed in this release.
Fixed for any bug fixes.
Security to invite users to upgrade in case of vulnerabilities.
## [Unreleased]
## [3.16.2] - 2017-03-01
### Added
- Link to GPLv2 licence and Linphone privacy policy in About View.
### Changed
- Optimization of Contact Lists
### Fixed
- CallKit bugs when invalid SIP address
- CallKit error screens no longer displayed but ours
- Crashes in Contact Lists
- Presence supports network changes
- Uses of linked address instead of phone number in chat rooms
- Uses of display name instead of sip addresses in chat rooms and history lists
## [3.16.1] - 2017-09-01
@ -99,9 +113,9 @@ consider inputs to be phone numbers, otherwise SIP addresses.
### Added
- Initial version
[Unreleased]: https://github.com/BelledonneCommunications/linphone-iphone/compare/3.15...HEAD
[3.15]: http://www.linphone.org/releases/ios/liblinphone-iphone-sdk-3.14.12.zip
[3.13.9]: http://www.linphone.org/releases/ios/liblinphone-iphone-sdk-3.13.9.zip
[Unreleased]: https://github.com/BelledonneCommunications/linphone-iphone/compare/3.16.2...HEAD
[3.16.2]: http://www.linphone.org/releases/ios/liblinphone-iphone-sdk-3.16.2.zip
[3.16.1]: http://www.linphone.org/releases/ios/liblinphone-iphone-sdk-3.16.1.zip
[plugins registration]: https://github.com/BelledonneCommunications/linphone-iphone/blob/3.12.1/Classes/LinphoneManager.m#L1461-L1472
[openh264 issue 2434]: https://github.com/cisco/openh264/issues/2434
[Full IPv6 support to comply Apple requirements]: https://developer.apple.com/news/?id=05042016a

View file

@ -27,7 +27,11 @@
@property(weak, nonatomic) IBOutlet UILabel *descriptionLabel;
@property(weak, nonatomic) IBOutlet UILabel *appVersionLabel;
@property(weak, nonatomic) IBOutlet UILabel *libVersionLabel;
@property(weak, nonatomic) IBOutlet UILabel *licenceLabel;
@property(weak, nonatomic) IBOutlet UILabel *policyLabel;
- (IBAction)onLinkTap:(id)sender;
- (IBAction)onLicenceTap;
- (IBAction)onPolicyTap;
- (IBAction)onDialerBackClick:(id)sender;
@end

View file

@ -51,6 +51,16 @@ static UICompositeViewDescription *compositeDescription = nil;
_nameLabel.text = name;
_appVersionLabel.text = [NSString stringWithFormat:@"%@ iOS %s", name, LINPHONE_IOS_VERSION];
_libVersionLabel.text = [NSString stringWithFormat:@"%@ Core %s", name, linphone_core_get_version()];
UITapGestureRecognizer *tapGestureRecognizer =
[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onLicenceTap)];
tapGestureRecognizer.numberOfTapsRequired = 1;
[_licenceLabel addGestureRecognizer:tapGestureRecognizer];
_licenceLabel.userInteractionEnabled = YES;
UITapGestureRecognizer *tapGestureRecognizerPolicy =
[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onPolicyTap)];
tapGestureRecognizerPolicy.numberOfTapsRequired = 1;
[_policyLabel addGestureRecognizer:tapGestureRecognizerPolicy];
_policyLabel.userInteractionEnabled = YES;
}
#pragma mark - Action Functions
@ -63,6 +73,20 @@ static UICompositeViewDescription *compositeDescription = nil;
}
}
- (IBAction)onPolicyTap {
NSString *url = @"http://www.linphone.org/privacy-policy.html";
if (![UIApplication.sharedApplication openURL:[NSURL URLWithString:url]]) {
LOGE(@"Failed to open %@, invalid URL", url);
}
}
- (IBAction)onLicenceTap {
NSString *url = @"https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html";
if (![UIApplication.sharedApplication openURL:[NSURL URLWithString:url]]) {
LOGE(@"Failed to open %@, invalid URL", url);
}
}
- (IBAction)onDialerBackClick:(id)sender {
[PhoneMainView.instance popToView:DialerView.compositeViewDescription];
}

View file

@ -53,14 +53,21 @@
assistant_activate_phone_number_link);
LinphoneProxyConfig *cfg = linphone_core_get_default_proxy_config(LC);
if (cfg && strcmp("sip.linphone.org", linphone_proxy_config_get_domain(cfg)) == 0) {
if (cfg &&
strcmp([LinphoneManager.instance lpConfigStringForKey:@"domain_name"
inSection:@"app"
withDefault:@"sip.linphone.org"]
.UTF8String,
linphone_proxy_config_get_domain(cfg)) == 0) {
linphone_account_creator_set_username(
account_creator, linphone_address_get_username(linphone_proxy_config_get_identity_address(cfg)));
const LinphoneAuthInfo *info = linphone_proxy_config_find_auth_info(cfg);
if (linphone_auth_info_get_passwd(info))
linphone_account_creator_set_password(account_creator, linphone_auth_info_get_passwd(info));
else
linphone_account_creator_set_ha1(account_creator, linphone_auth_info_get_ha1(info));
if (info) {
if (linphone_auth_info_get_passwd(info))
linphone_account_creator_set_password(account_creator, linphone_auth_info_get_passwd(info));
else
linphone_account_creator_set_ha1(account_creator, linphone_auth_info_get_ha1(info));
}
linphone_account_creator_set_domain(account_creator, linphone_proxy_config_get_domain(cfg));
} else {
LOGW(@"Default proxy is NOT a sip.linphone.org, aborting");

View file

@ -873,21 +873,27 @@ static UICompositeViewDescription *compositeDescription = nil;
UIView *usernameView =
[self findView:ViewElement_UsernameFormView inView:self.contentView ofType:UIView.class];
usernameView.hidden = !usernameSwitch.isOn;
((UITextField *)[self findView:ViewElement_Phone
inView:_linphoneLoginView
ofType:[UIAssistantTextField class]])
.text = [NSString stringWithUTF8String:nationnal_significant_number];
if (nationnal_significant_number) {
((UITextField *)[self findView:ViewElement_Phone
inView:_linphoneLoginView
ofType:[UIAssistantTextField class]])
.text = [NSString stringWithUTF8String:nationnal_significant_number];
}
((UITextField *)[self findView:ViewElement_SMSCode
inView:_createAccountActivateSMSView
ofType:[UITextField class]])
.text = @"";
linphone_account_creator_set_activation_code(account_creator, "");
NSDictionary *country =
[CountryListView countryWithIso:[NSString stringWithUTF8String:dialplan.iso_country_code]];
[self didSelectCountry:country];
if (dialplan.iso_country_code) {
NSDictionary *country = [CountryListView
countryWithIso:[NSString stringWithUTF8String:dialplan.iso_country_code]];
[self didSelectCountry:country];
}
// Reset phone number in account_creator to be sure to let the user retry
linphone_account_creator_set_phone_number(account_creator, nationnal_significant_number,
dialplan.ccc);
if (nationnal_significant_number) {
linphone_account_creator_set_phone_number(account_creator, nationnal_significant_number,
dialplan.ccc);
}
}];
defaultAction.accessibilityLabel = @"PopUpResp";

41
Classes/AudioHelper.m Normal file
View file

@ -0,0 +1,41 @@
//
// AudioHelper.m
// linphone
//
// Created by REIS Benjamin on 01/03/2017.
//
//
#import "AudioHelper.h"
@implementation AudioHelper
+ (NSArray *)bluetoothRoutes {
return @[ AVAudioSessionPortBluetoothA2DP, AVAudioSessionPortBluetoothLE, AVAudioSessionPortBluetoothHFP ];
}
+ (AVAudioSessionPortDescription *)bluetoothAudioDevice {
return [AudioHelper audioDeviceFromTypes:[AudioHelper bluetoothRoutes]];
}
+ (AVAudioSessionPortDescription *)builtinAudioDevice {
NSArray *builtinRoutes = @[ AVAudioSessionPortBuiltInMic ];
return [AudioHelper audioDeviceFromTypes:builtinRoutes];
}
+ (AVAudioSessionPortDescription *)speakerAudioDevice {
NSArray *builtinRoutes = @[ AVAudioSessionPortBuiltInSpeaker ];
return [AudioHelper audioDeviceFromTypes:builtinRoutes];
}
+ (AVAudioSessionPortDescription *)audioDeviceFromTypes:(NSArray *)types {
NSArray *routes = [[AVAudioSession sharedInstance] availableInputs];
for (AVAudioSessionPortDescription *route in routes) {
if ([types containsObject:route.portType]) {
return route;
}
}
return nil;
}
@end

Binary file not shown.

View file

@ -1,8 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11201" systemVersion="16A323" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="16D32" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11161"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -12,7 +15,9 @@
<outlet property="descriptionLabel" destination="lTF-yt-Uqp" id="z8Q-Rk-T1S"/>
<outlet property="landscapeView" destination="sVO-4a-t1s" id="9ye-NV-onQ"/>
<outlet property="libVersionLabel" destination="ZYk-v1-CYZ" id="E4g-U8-zyp"/>
<outlet property="licenceLabel" destination="gVK-Xc-S59" id="XPV-ct-oGP"/>
<outlet property="nameLabel" destination="dFa-fl-SAE" id="kIv-p3-ga8"/>
<outlet property="policyLabel" destination="5Nl-Fs-ggi" id="xXc-PS-Eda"/>
<outlet property="portraitView" destination="HJH-1o-RXN" id="Hoa-uk-q9s"/>
<outlet property="view" destination="HJH-1o-RXN" id="t5Y-ob-1WC"/>
</connections>
@ -23,19 +28,19 @@
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view tag="1" contentMode="scaleToFill" id="HJH-1o-RXN">
<frame key="frameInset" minY="66"/>
<rect key="frame" x="0.0" y="66" width="375" height="601"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view tag="2" contentMode="scaleToFill" id="Whz-oo-Pwx" userLabel="topBar">
<frame key="frameInset" minX="0.0%" width="100.00%" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="3" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="color_F.png" id="h54-RV-eE6" userLabel="backgroundColor">
<frame key="frameInset" height="100.00%"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
</imageView>
<button opaque="NO" tag="4" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="ETk-tB-ZNl" userLabel="dialerBackButton" customClass="UIIconButton">
<frame key="frameInset" minY="0.0%" width="20.27%" height="100.00%"/>
<rect key="frame" x="299" y="0.0" width="76" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Add contact"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
@ -49,7 +54,7 @@
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" tag="5" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="ABOUT" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="iNt-9d-7si" userLabel="titleLabel">
<frame key="frameInset" minX="0.0%" minY="0.0%" width="100.00%" height="100.00%"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="27"/>
<color key="textColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@ -58,26 +63,26 @@
</subviews>
</view>
<view clipsSubviews="YES" multipleTouchEnabled="YES" tag="6" contentMode="scaleToFill" id="er6-WR-NP1">
<frame key="frameInset" minY="66" height="535"/>
<rect key="frame" x="0.0" y="66" width="375" height="535"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="7" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="color_C.png" id="fbO-x9-0Ue" userLabel="backgroundColor">
<frame key="frameInset" height="73.27%"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="392"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
</imageView>
<imageView userInteractionEnabled="NO" tag="8" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="splashscreen.png" id="wSQ-YD-dIQ" userLabel="logoImage">
<frame key="frameInset" minY="1.50%" height="31.03%"/>
<rect key="frame" x="0.0" y="8" width="375" height="166"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" tag="9" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="LINPHONE" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.10000000149011612" id="dFa-fl-SAE" userLabel="nameLabel">
<frame key="frameInset" minY="37.30%" height="47"/>
<rect key="frame" x="0.0" y="182" width="375" height="47"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="41"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="10" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" usesAttributedText="YES" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.10000000149011612" id="lTF-yt-Uqp" userLabel="descriptionLabel">
<frame key="frameInset" minY="47.30%" height="34"/>
<rect key="frame" x="0.0" y="237" width="375" height="34"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<attributedString key="attributedText">
<fragment content="The ">
@ -105,21 +110,21 @@
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="11" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Linphone iOS 8.0" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="gLk-Bc-zvx" userLabel="appVersionLabel">
<frame key="frameInset" minY="59.14%" height="21"/>
<rect key="frame" x="0.0" y="304" width="375" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.85415387153625488" green="0.85412830114364624" blue="0.85414278507232666" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="12" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Linphone Core 3.14.0" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="ZYk-v1-CYZ" userLabel="libVersionLabel">
<frame key="frameInset" minY="64.79%" height="21"/>
<rect key="frame" x="0.0" y="333" width="375" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.85415387153625488" green="0.85412830114364624" blue="0.85414278507232666" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" tag="13" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="https://www.linphone.org" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="1pe-zf-cQh" userLabel="siteURLLabel">
<frame key="frameInset" minY="79.05%" height="29"/>
<rect key="frame" x="0.0" y="400" width="375" height="29"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@ -128,15 +133,22 @@
<outletCollection property="gestureRecognizers" destination="l7c-wq-pii" appends="YES" id="olo-CD-gM3"/>
</connections>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="14" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="7" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" id="gVK-Xc-S59" userLabel="licenseLabel">
<frame key="frameInset" minY="81.68%" height="18.32%"/>
<label opaque="NO" userInteractionEnabled="NO" tag="14" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="7" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" id="gVK-Xc-S59" userLabel="licenseLabel">
<rect key="frame" x="0.0" y="474" width="375" height="61"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<string key="text">GNU General Public License V2
© 2010-2016 Belledonne Communications</string>
© 2010-2017 Belledonne Communications</string>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.33333333333333331" green="0.33333333333333331" blue="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="14" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="Visit our privacy policy" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="7" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" id="5Nl-Fs-ggi" userLabel="policyLabel">
<rect key="frame" x="0.0" y="437" width="375" height="29"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.33333333329999998" green="0.33333333329999998" blue="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</view>
</subviews>
@ -150,20 +162,20 @@
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view tag="1" contentMode="scaleToFill" id="sVO-4a-t1s">
<frame key="frameInset" minY="66"/>
<view tag="1" contentMode="scaleToFill" misplaced="YES" id="sVO-4a-t1s">
<rect key="frame" x="0.0" y="66" width="375" height="490"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view tag="2" contentMode="scaleToFill" id="OGe-ZS-scH" userLabel="topBar">
<frame key="frameInset" minX="0.0%" width="100.00%" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="3" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="color_F.png" id="Vi5-Wh-iOm" userLabel="backgroundColor">
<frame key="frameInset" height="100.00%"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
</imageView>
<button opaque="NO" tag="4" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="vX8-wO-ZEN" userLabel="dialerBackButton" customClass="UIIconButton">
<frame key="frameInset" minY="0.0%" width="20.27%" height="100.00%"/>
<rect key="frame" x="299" y="0.0" width="76" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Add contact"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
@ -177,7 +189,7 @@
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" tag="5" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="ABOUT" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="wKp-iH-ojJ" userLabel="titleLabel">
<frame key="frameInset" minX="0.0%" minY="0.0%" width="100.00%" height="100.00%"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="27"/>
<color key="textColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@ -186,26 +198,26 @@
</subviews>
</view>
<view clipsSubviews="YES" multipleTouchEnabled="YES" tag="6" contentMode="scaleToFill" id="Wvv-4f-Oa6">
<frame key="frameInset" minY="66" width="100.00%" height="243"/>
<rect key="frame" x="0.0" y="66" width="375" height="243"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="7" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="color_C.png" id="UBx-Gi-qTi" userLabel="backgroundColor">
<frame key="frameInset" height="73.25%"/>
<imageView userInteractionEnabled="NO" tag="7" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" image="color_C.png" id="UBx-Gi-qTi" userLabel="backgroundColor">
<rect key="frame" x="0.0" y="0.0" width="375" height="152"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
</imageView>
<imageView userInteractionEnabled="NO" tag="8" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="splashscreen.png" id="UhZ-5i-eU5" userLabel="logoImage">
<frame key="frameInset" minX="1.07%" minY="3.29%" width="31.73%" height="66.26%"/>
<imageView userInteractionEnabled="NO" tag="8" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" image="splashscreen.png" id="UhZ-5i-eU5" userLabel="logoImage">
<rect key="frame" x="0.0" y="-9" width="119" height="161"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" tag="9" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="LINPHONE" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.10000000149011612" id="fss-Tl-kRy" userLabel="nameLabel">
<frame key="frameInset" minX="34.13%" minY="8.16%" width="65.87%" height="47"/>
<label opaque="NO" userInteractionEnabled="NO" tag="9" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="LINPHONE" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.10000000149011612" id="fss-Tl-kRy" userLabel="nameLabel">
<rect key="frame" x="128" y="8" width="247" height="38"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="41"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="10" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" usesAttributedText="YES" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.10000000149011612" id="ASG-VC-Riv" userLabel="descLabel">
<frame key="frameInset" minX="34.13%" minY="33.97%" width="65.87%" height="34"/>
<label opaque="NO" userInteractionEnabled="NO" tag="10" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" usesAttributedText="YES" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.10000000149011612" id="ASG-VC-Riv" userLabel="descLabel">
<rect key="frame" x="120" y="54" width="247" height="34"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<attributedString key="attributedText">
<fragment content="The ">
@ -232,44 +244,49 @@
</attributedString>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="11" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Linphone iPhone 3.0" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="oYk-ih-BBi" userLabel="appVersionLabel">
<frame key="frameInset" minX="34.13%" minY="51.80%" width="65.87%" height="21"/>
<label opaque="NO" userInteractionEnabled="NO" tag="11" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="Linphone iPhone 3.0" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="oYk-ih-BBi" userLabel="appVersionLabel">
<rect key="frame" x="128" y="96" width="247" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.85415387153625488" green="0.85412830114364624" blue="0.85414278507232666" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="12" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Linphone Core 3.9.0" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="g2W-u5-yxg" userLabel="libVersionLabel">
<frame key="frameInset" minX="34.13%" minY="64.87%" width="65.87%" height="21"/>
<label opaque="NO" userInteractionEnabled="NO" tag="12" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="Linphone Core 3.9.0" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="g2W-u5-yxg" userLabel="libVersionLabel">
<rect key="frame" x="120" y="125" width="247" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.85415387153625488" green="0.85412830114364624" blue="0.85414278507232666" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" tag="13" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="https://www.linphone.org" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="uis-xz-Qsa" userLabel="siteURLLabel">
<frame key="frameInset" minY="100.00%" height="66" maxX="334"/>
<label opaque="NO" tag="13" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="https://www.linphone.org" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="jGU-DX-XcO" userLabel="siteURLLabel">
<rect key="frame" x="0.0" y="154" width="375" height="29"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="textColor" red="0.98766469960000003" green="0.27512490750000002" blue="0.029739789660000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="14" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="7" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" id="ToT-OI-B2F" userLabel="licenseLabel">
<frame key="frameInset" minX="333" minY="72.84%" height="27.16%"/>
<label opaque="NO" userInteractionEnabled="NO" tag="14" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="Visit our privacy policy" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="7" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" id="nld-cR-eba" userLabel="policyLabel">
<rect key="frame" x="0.0" y="173" width="375" height="41"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<string key="text">GNU General Public License V2
© 2010-2016 Belledonne Communications</string>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.33333333333333331" green="0.33333333333333331" blue="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="textColor" red="0.33333333329999998" green="0.33333333329999998" blue="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</view>
<label opaque="NO" userInteractionEnabled="NO" tag="14" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="GNU General Public License V2 © 2010-2017 Belledonne Communications" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="7" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" id="vqn-sI-DiC" userLabel="licenseLabel">
<rect key="frame" x="0.0" y="284" width="575" height="43"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.33333333329999998" green="0.33333333329999998" blue="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="801.5" y="280.5"/>
<point key="canvasLocation" x="871.5" y="248.5"/>
</view>
<tapGestureRecognizer id="l7c-wq-pii" userLabel="onLinkTap">
<connections>

View file

@ -94,6 +94,7 @@ static UICompositeViewDescription *compositeDescription = nil;
- (IBAction)onRoutesBluetoothClick:(id)sender {
[self hideRoutes:TRUE animated:TRUE];
[LinphoneManager.instance setSpeakerEnabled:FALSE];
[LinphoneManager.instance setBluetoothEnabled:TRUE];
}
@ -105,6 +106,7 @@ static UICompositeViewDescription *compositeDescription = nil;
- (IBAction)onRoutesSpeakerClick:(id)sender {
[self hideRoutes:TRUE animated:TRUE];
[LinphoneManager.instance setBluetoothEnabled:FALSE];
[LinphoneManager.instance setSpeakerEnabled:TRUE];
}
@ -119,19 +121,7 @@ static UICompositeViewDescription *compositeDescription = nil;
- (IBAction)onDeclineClick:(id)sender {
LinphoneCall *call = linphone_core_get_current_call(LC);
if (call) {
/*if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_9_x_Max) {
NSUUID *uuid = [LinphoneManager.instance.providerDelegate.uuids objectForKey:[NSString
stringWithUTF8String:linphone_call_log_get_call_id(linphone_call_get_call_log(call))]];
if(!uuid) {
linphone_core_terminate_call(LC, call);
return;
}
CXEndCallAction *act = [[CXEndCallAction alloc] initWithCallUUID:uuid];
CXTransaction *tr = [[CXTransaction alloc] initWithAction:act];
[LinphoneManager.instance.providerDelegate.controller requestTransaction:tr completion:^(NSError *err){}];
} else {*/
linphone_core_terminate_call(LC, call);
//}
linphone_call_terminate(call);
}
}

View file

@ -151,7 +151,7 @@
[result appendString:@"\n"];
// RTP stats section (packet loss count, etc)
rtp_stats_t rtp_stats = linphone_call_stats_get_rtp_stats(stats);
const rtp_stats_t rtp_stats = *linphone_call_stats_get_rtp_stats(stats);
[result
appendString:[NSString stringWithFormat:
@"RTP packets: %llu total, %lld cum loss, %llu discarded, %llu OOT, %llu bad",

View file

@ -17,6 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <AVFoundation/AVAudioSession.h>
#import <AddressBook/AddressBook.h>
#import <AudioToolbox/AudioToolbox.h>
#import <OpenGLES/EAGL.h>
@ -629,7 +630,7 @@ static void hideSpinner(LinphoneCall *call, void *user_data) {
LOGI(@"User declined video proposal");
if (call == linphone_core_get_current_call(LC)) {
LinphoneCallParams *params = linphone_core_create_call_params(LC, call);
linphone_core_accept_call_update(LC, call, params);
linphone_call_accept_update(call, params);
linphone_call_params_destroy(params);
[videoDismissTimer invalidate];
videoDismissTimer = nil;
@ -640,7 +641,7 @@ static void hideSpinner(LinphoneCall *call, void *user_data) {
if (call == linphone_core_get_current_call(LC)) {
LinphoneCallParams *params = linphone_core_create_call_params(LC, call);
linphone_call_params_enable_video(params, TRUE);
linphone_core_accept_call_update(LC, call, params);
linphone_call_accept_update(call, params);
linphone_call_params_destroy(params);
[videoDismissTimer invalidate];
videoDismissTimer = nil;
@ -710,6 +711,7 @@ static void hideSpinner(LinphoneCall *call, void *user_data) {
- (IBAction)onRoutesBluetoothClick:(id)sender {
[self hideRoutes:TRUE animated:TRUE];
[LinphoneManager.instance setSpeakerEnabled:FALSE];
[LinphoneManager.instance setBluetoothEnabled:TRUE];
}
@ -721,6 +723,7 @@ static void hideSpinner(LinphoneCall *call, void *user_data) {
- (IBAction)onRoutesSpeakerClick:(id)sender {
[self hideRoutes:TRUE animated:TRUE];
[LinphoneManager.instance setBluetoothEnabled:FALSE];
[LinphoneManager.instance setSpeakerEnabled:TRUE];
}

View file

@ -73,14 +73,25 @@
cell = [[UIChatCreateCell alloc] initWithIdentifier:kCellId];
}
cell.displayNameLabel.text = [_contacts.allValues objectAtIndex:indexPath.row];
cell.addressLabel.text = [_contacts.allKeys objectAtIndex:indexPath.row];
LinphoneAddress *addr = [LinphoneUtils normalizeSipOrPhoneAddress:[_contacts.allKeys objectAtIndex:indexPath.row]];
if (addr) {
cell.addressLabel.text = [NSString stringWithUTF8String:linphone_address_as_string(addr)];
} else {
cell.addressLabel.text = [_contacts.allKeys objectAtIndex:indexPath.row];
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
LinphoneChatRoom *room = linphone_core_get_chat_room_from_uri(
LC, ((NSString *)[_contacts.allKeys objectAtIndex:indexPath.row]).UTF8String);
NSString *uri;
LinphoneAddress *addr = [LinphoneUtils normalizeSipOrPhoneAddress:[_contacts.allKeys objectAtIndex:indexPath.row]];
if (addr) {
uri = [NSString stringWithUTF8String:linphone_address_as_string(addr)];
} else {
uri = [_contacts.allKeys objectAtIndex:indexPath.row];
}
LinphoneChatRoom *room = linphone_core_get_chat_room_from_uri(LC, uri.UTF8String);
if (!room) {
[PhoneMainView.instance popCurrentView];
UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Invalid address", nil)

View file

@ -102,6 +102,7 @@
[self.tableView reloadData];
size_t count = bctbx_list_size(messageList);
if (count) {
[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:(count - 1) inSection:0]];
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:(count - 1) inSection:0]
atScrollPosition:UITableViewScrollPositionBottom
animated:YES];
@ -126,8 +127,10 @@
if (index == -1 && count > 0) {
index = (int)count - 1;
}
linphone_chat_room_mark_as_read(_chatRoom);
if (!([UIApplication sharedApplication].applicationState == UIApplicationStateBackground ||
[UIApplication sharedApplication].applicationState == UIApplicationStateInactive)) {
linphone_chat_room_mark_as_read(_chatRoom);
}
TabBarView *tab = (TabBarView *)[PhoneMainView.instance.mainViewController
getCachedController:NSStringFromClass(TabBarView.class)];
[tab update:YES];

View file

@ -65,5 +65,7 @@
- (IBAction)onCallClick:(id)sender;
- (IBAction)onDeleteClick:(id)sender;
- (IBAction)onEditionChangeClick:(id)sender;
- (void)markAsRead;
- (void)update;
@end

View file

@ -157,6 +157,7 @@ static UICompositeViewDescription *compositeDescription = nil;
#pragma mark -
- (void)setChatRoom:(LinphoneChatRoom *)chatRoom {
_chatRoom = chatRoom;
[_messageField setText:@""];
[_tableController setChatRoom:_chatRoom];
@ -190,6 +191,16 @@ static UICompositeViewDescription *compositeDescription = nil;
_backToCallButton.hidden = !_callButton.hidden;
}
- (void)markAsRead {
linphone_chat_room_mark_as_read(_chatRoom);
if (IPAD) {
if (IPAD) {
ChatsListView *listView = VIEW(ChatsListView);
[listView.tableController markCellAsRead:_chatRoom];
}
}
}
- (void)update {
if (_chatRoom == NULL) {
LOGW(@"Cannot update chat room header: null contact");
@ -241,6 +252,10 @@ static UICompositeViewDescription *compositeDescription = nil;
[_tableController scrollToBottom:true];
if (linphone_core_lime_enabled(LC) == LinphoneLimeMandatory && !linphone_chat_room_lime_available(_chatRoom)) {
[LinphoneManager.instance alertLIME:_chatRoom];
}
return TRUE;
}
@ -343,10 +358,11 @@ static UICompositeViewDescription *compositeDescription = nil;
if (fromStr && cr_from_string) {
if (strcasecmp(cr_from_string, fromStr) == 0) {
if ([UIApplication sharedApplication].applicationState != UIApplicationStateBackground) {
if (!([UIApplication sharedApplication].applicationState == UIApplicationStateBackground ||
[UIApplication sharedApplication].applicationState == UIApplicationStateInactive)) {
linphone_chat_room_mark_as_read(room);
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneMessageReceived object:self];
}
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneMessageReceived object:self];
[_tableController addChatEntry:chat];
[_tableController scrollToLastUnread:TRUE];
}

View file

@ -24,4 +24,5 @@
@interface ChatsListTableView : UICheckBoxTableView
- (void)loadData;
- (void)markCellAsRead:(LinphoneChatRoom *)chatRoom;
@end

View file

@ -63,6 +63,14 @@
}
}
- (void)layoutSubviews {
[self.tableView layoutSubviews];
CGSize contentSize = self.tableView.contentSize;
contentSize.width = self.tableView.bounds.size.width;
self.tableView.contentSize = contentSize;
}
#pragma mark -
static int sorted_history_comparison(LinphoneChatRoom *to_insert, LinphoneChatRoom *elem) {
@ -130,6 +138,15 @@ static void chatTable_free_chatrooms(void *data) {
}
}
- (void)markCellAsRead:(LinphoneChatRoom *)chatRoom {
int idx = bctbx_list_index(data, VIEW(ChatConversationView).chatRoom);
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:idx inSection:0];
if (IPAD) {
UIChatCell *cell = (UIChatCell *)[self.tableView cellForRowAtIndexPath:indexPath];
[cell updateUnreadBadge];
}
}
#pragma mark - UITableViewDataSource Functions
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

View file

@ -21,6 +21,7 @@
@property(nonatomic, strong) NSMutableArray *sipAddresses;
@property(nonatomic, strong) NSMutableArray *emails;
@property(nonatomic, strong) NSMutableArray *phoneNumbers;
@property BOOL added;
- (void)setAvatar:(UIImage *)avatar;
- (UIImage *)avatar:(BOOL)thumbnail;

View file

@ -7,6 +7,7 @@
//
#import "Contact.h"
#import "ContactsListView.h"
@implementation Contact
@ -22,7 +23,7 @@
self = [super init];
_person = aperson;
_friend = afriend ? linphone_friend_ref(afriend) : NULL;
_added = FALSE;
if (_person) {
[self loadProperties];
@ -32,7 +33,12 @@
if (!_friend) {
_friend = linphone_friend_ref(linphone_core_create_friend(LC));
linphone_friend_set_ref_key(_friend, key);
linphone_friend_set_name(_friend, [NSString stringWithFormat:@"%@ %@", _firstName, _lastName].UTF8String);
linphone_friend_set_name(
_friend,
[NSString
stringWithFormat:@"%@%@", _firstName ? _firstName : @"",
_lastName ? [_firstName ? @" " : @"" stringByAppendingString:_lastName] : @""]
.UTF8String);
for (NSString* sipAddr in _sipAddresses) {
LinphoneAddress* addr = linphone_core_interpret_url(LC, sipAddr.UTF8String);
if (addr) {
@ -99,9 +105,10 @@
- (NSString *)displayName {
if (_friend) {
// const char *dp = linphone_address_get_display_name(linphone_friend_get_address(_friend));
//if (dp)
// return [NSString stringWithUTF8String:dp];
const char *friend_name = linphone_friend_get_name(_friend);
if (friend_name) {
return [NSString stringWithUTF8String:friend_name];
}
}
if (_person != nil) {
@ -186,10 +193,12 @@
- (BOOL)setSipAddress:(NSString *)sip atIndex:(NSInteger)index {
BOOL ret = FALSE;
NSString *normSip = NULL;
if (_person) {
normSip = [self setOrCreateSipContactEntry:index withValue:sip];
NSDictionary *lDict = @{
(NSString *) kABPersonInstantMessageUsernameKey : sip, (NSString *)
kABPersonInstantMessageServiceKey : LinphoneManager.instance.contactSipField
(NSString *)kABPersonInstantMessageUsernameKey : normSip ? normSip : sip,
(NSString *)kABPersonInstantMessageServiceKey : LinphoneManager.instance.contactSipField
};
ret = [self replaceInProperty:kABPersonInstantMessageProperty value:(__bridge CFTypeRef)(lDict) atIndex:index];
@ -336,6 +345,46 @@
}
#pragma mark - ABPerson utils
- (NSString *)setOrCreateSipContactEntry:(NSInteger)index withValue:(NSString *)value {
ABMultiValueRef lcMap = ABRecordCopyValue(_person, kABPersonInstantMessageProperty);
ABMutableMultiValueRef lMap;
NSString *ret = NULL;
if (lcMap != NULL) {
lMap = ABMultiValueCreateMutableCopy(lcMap);
CFRelease(lcMap);
} else {
lMap = ABMultiValueCreateMutable(kABStringPropertyType);
}
CFErrorRef error = NULL;
NSDictionary *lDict = @{
(NSString *)kABPersonInstantMessageUsernameKey : value,
(NSString *)kABPersonInstantMessageServiceKey : [LinphoneManager instance].contactSipField
};
if (![self replaceInProperty:kABPersonInstantMessageProperty value:(__bridge CFTypeRef)(lDict) atIndex:index]) {
LOGI(@"Can't set contact with value [%@] cause [%@]", value, [(__bridge NSError *)error localizedDescription]);
CFRelease(lMap);
} else {
CFRelease(lMap);
/*check if message type is kept or not*/
lcMap = ABRecordCopyValue(_person, kABPersonInstantMessageProperty);
lMap = ABMultiValueCreateMutableCopy(lcMap);
CFRelease(lcMap);
lDict = CFBridgingRelease(ABMultiValueCopyValueAtIndex(lMap, index));
if ([lDict objectForKey:(__bridge NSString *)kABPersonInstantMessageServiceKey] == nil) {
/*too bad probably a gtalk number, storing uri*/
ret = [FastAddressBook normalizeSipURI:value];
} else if (!_added) {
_added = TRUE;
[LinphoneManager.instance.fastAddressBook saveContact:self];
}
CFRelease(lMap);
}
return ret ? ret : value;
}
- (void)loadProperties {
// First and Last name
@ -369,7 +418,7 @@
}
// SIP (IM)
{
/*{
_sipAddresses = [[NSMutableArray alloc] init];
ABMultiValueRef map = ABRecordCopyValue(_person, kABPersonInstantMessageProperty);
if (map) {
@ -389,8 +438,88 @@
}
CFRelease(map);
}
}*/
// SIP (IM)
{
_sipAddresses = [[NSMutableArray alloc] init];
ABMultiValueRef lMap = ABRecordCopyValue(_person, kABPersonInstantMessageProperty);
if (lMap) {
for (int i = 0; i < ABMultiValueGetCount(lMap); ++i) {
CFDictionaryRef lDict = ABMultiValueCopyValueAtIndex(lMap, i);
BOOL add = false;
if (CFDictionaryContainsKey(lDict, kABPersonInstantMessageServiceKey)) {
if (CFStringCompare((CFStringRef)[LinphoneManager instance].contactSipField,
CFDictionaryGetValue(lDict, kABPersonInstantMessageServiceKey),
kCFCompareCaseInsensitive) == 0) {
add = true;
}
} else {
// check domain
LinphoneAddress *address = linphone_address_new(
[(NSString *)CFDictionaryGetValue(lDict, kABPersonInstantMessageUsernameKey) UTF8String]);
if (address) {
if ([[ContactSelection getSipFilter] compare:@"*" options:NSCaseInsensitiveSearch] ==
NSOrderedSame) {
add = true;
} else {
NSString *domain = [NSString stringWithCString:linphone_address_get_domain(address)
encoding:[NSString defaultCStringEncoding]];
add = [domain compare:[ContactSelection getSipFilter] options:NSCaseInsensitiveSearch] ==
NSOrderedSame;
}
linphone_address_destroy(address);
} else {
add = false;
}
}
if (add) {
NSString *value = (NSString *)(CFDictionaryGetValue(lDict, kABPersonInstantMessageUsernameKey));
if (value != NULL) {
[_sipAddresses addObject:value];
}
}
CFRelease(lDict);
}
CFRelease(lMap);
}
}
// SIP
/*{
_sipAddresses = [[NSMutableArray alloc] init];
ABMultiValueRef lMap = ABRecordCopyValue(_person, kABPersonInstantMessageProperty);
if (lMap) {
for (int i = 0; i < ABMultiValueGetCount(lMap); ++i) {
CFDictionaryRef lDict = ABMultiValueCopyValueAtIndex(lMap, i);
BOOL add = false;
if (CFDictionaryContainsKey(lDict, kABPersonInstantMessageServiceKey)) {
if (CFStringCompare((CFStringRef)LinphoneManager.instance.contactSipField,
CFDictionaryGetValue(lDict, kABPersonInstantMessageServiceKey),
kCFCompareCaseInsensitive) == 0) {
add = true;
}
} else {
add = true;
}
if (add) {
NSString *lValue =
(__bridge NSString *)CFDictionaryGetValue(lDict, kABPersonInstantMessageUsernameKey);
if(lValue) {
NSString *lNormalizedKey = [FastAddressBook normalizeSipURI:lValue];
if (lNormalizedKey != NULL) {
[_sipAddresses addObject:lNormalizedKey];
} else {
[_sipAddresses addObject:lValue];
}
}
}
CFRelease(lDict);
}
CFRelease(lMap);
}
}*/
// Email
{
_emails = [[NSMutableArray alloc] init];

View file

@ -44,7 +44,9 @@
#pragma mark -
- (void)onAddressBookUpdate:(NSNotification *)k {
if (!inhibUpdate && ![_tableController isEditing]) {
if (!inhibUpdate && ![_tableController isEditing] &&
(PhoneMainView.instance.currentView == self.compositeViewDescription) &&
(_nameLabel.text == PhoneMainView.instance.currentName)) {
[self resetData];
}
}
@ -220,7 +222,9 @@
}
- (void)viewWillDisappear:(BOOL)animated {
[_tableController.tableView removeObserver:self forKeyPath:@"contentSize"];
if (_tableController && _tableController.tableView && [_tableController.tableView observationInfo]) {
[_tableController.tableView removeObserver:self forKeyPath:@"contentSize"];
}
[super viewWillDisappear:animated];
PhoneMainView.instance.currentName = NULL;
if (self.tmpContact) {
@ -258,6 +262,24 @@
self.tmpContact = NULL;
[self saveData];
}
BOOL rm = TRUE;
for (NSString *sip in _contact.sipAddresses) {
if (![sip isEqualToString:@""]) {
rm = FALSE;
break;
}
}
if (rm) {
for (NSString *phone in _contact.phoneNumbers) {
if (![phone isEqualToString:@""]) {
rm = FALSE;
break;
}
}
}
if (rm) {
[LinphoneManager.instance.fastAddressBook removeContact:_contact];
}
}
#pragma mark - UICompositeViewDelegate Functions
@ -382,6 +404,25 @@ static UICompositeViewDescription *compositeDescription = nil;
}
[self saveData];
[self.tableController.tableView reloadData];
} else {
BOOL rm = TRUE;
for (NSString *sip in _contact.sipAddresses) {
if (![sip isEqualToString:@""]) {
rm = FALSE;
break;
}
}
if (rm) {
for (NSString *phone in _contact.phoneNumbers) {
if (![phone isEqualToString:@""]) {
rm = FALSE;
break;
}
}
}
if (rm) {
[LinphoneManager.instance.fastAddressBook removeContact:_contact];
}
}
[self setEditing:FALSE];

View file

@ -120,7 +120,7 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[ContactSelection setNameOrEmailFilter:@""];
_searchBar.showsCancelButton = (_searchBar.text.length > 0);
if (tableController.isEditing) {

View file

@ -169,6 +169,13 @@ static UICompositeViewDescription *compositeDescription = nil;
frame.origin = CGPointMake(0, 0);
_videoPreview.frame = frame;
_padView.hidden = !IPAD && UIInterfaceOrientationIsLandscape(toInterfaceOrientation);
if (linphone_core_get_calls_nb(LC)) {
_backButton.hidden = FALSE;
_addContactButton.hidden = TRUE;
} else {
_backButton.hidden = TRUE;
_addContactButton.hidden = FALSE;
}
}
- (void)viewDidAppear:(BOOL)animated {

View file

@ -301,7 +301,12 @@
- (NSString *)getPassword {
NSString *pass;
LinphoneProxyConfig *cfg = linphone_core_get_default_proxy_config(LC);
if (cfg && strcmp("sip.linphone.org", linphone_proxy_config_get_domain(cfg)) == 0) {
if (cfg &&
strcmp([LinphoneManager.instance lpConfigStringForKey:@"domain_name"
inSection:@"app"
withDefault:@"sip.linphone.org"]
.UTF8String,
linphone_proxy_config_get_domain(cfg)) == 0) {
const LinphoneAuthInfo *info = linphone_proxy_config_find_auth_info(cfg);
const char *tmpPass;
if (linphone_auth_info_get_passwd(info)) {

View file

@ -17,12 +17,12 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "PhoneMainView.h"
#import "ContactsListView.h"
#import "ContactDetailsView.h"
#import "ShopView.h"
#import "linphoneAppDelegate.h"
#import "LinphoneAppDelegate.h"
#import "AddressBook/ABPerson.h"
#import "ContactDetailsView.h"
#import "ContactsListView.h"
#import "PhoneMainView.h"
#import "ShopView.h"
#import "CoreTelephony/CTCallCenter.h"
#import "CoreTelephony/CTCall.h"
@ -117,7 +117,7 @@
}
if ((floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max)) {
if ([LinphoneManager.instance lpConfigBoolForKey:@"autoanswer_notif_preference"]) {
linphone_core_accept_call(LC, call);
linphone_call_accept(call);
[PhoneMainView.instance changeCurrentView:CallView.compositeViewDescription];
} else {
[PhoneMainView.instance displayIncomingCall:call];
@ -276,7 +276,6 @@
actions:[NSArray arrayWithObjects:act_confirm, act_deny, nil]
intentIdentifiers:[[NSMutableArray alloc] init]
options:UNNotificationCategoryOptionCustomDismissAction];
[UNUserNotificationCenter currentNotificationCenter].delegate = self;
[[UNUserNotificationCenter currentNotificationCenter]
requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionSound |
@ -422,8 +421,10 @@
if (aps != nil) {
NSDictionary *alert = [aps objectForKey:@"alert"];
NSString *loc_key = [aps objectForKey:@"loc-key"];
NSString *callId = [aps objectForKey:@"call-id"];
if (alert != nil) {
NSString *loc_key = [alert objectForKey:@"loc-key"];
loc_key = [alert objectForKey:@"loc-key"];
/*if we receive a remote notification, it is probably because our TCP background socket was no more working.
As a result, break it and refresh registers in order to make sure to receive incoming INVITE or MESSAGE*/
if (linphone_core_get_calls(LC) == NULL) { // if there are calls, obviously our TCP socket shall be working
@ -434,7 +435,7 @@
}
if (loc_key != nil) {
NSString *callId = [userInfo objectForKey:@"call-id"];
callId = [userInfo objectForKey:@"call-id"];
if (callId != nil) {
if ([callId isEqualToString:@""]){
//Present apn pusher notifications for info
@ -464,10 +465,26 @@
} else if ([callId isEqual: @""]) {
LOGE(@"PushNotification: does not have call-id yet, fix it !");
}
}
}
}
if ([loc_key isEqualToString:@"IC_MSG"]) {
[self fixRing];
}
if (callId) {
int index = -1;
NSDictionary *dict = LinphoneManager.instance.pushDict;
if ([[dict allKeys] containsObject:callId]) {
index = [(NSNumber *)[LinphoneManager.instance.pushDict objectForKey:callId] intValue] + 1;
} else {
index = 1;
}
[LinphoneManager.instance.pushDict setValue:[NSNumber numberWithInt:index] forKey:callId];
if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground && loc_key &&
index > 0) {
if ([loc_key isEqualToString:@"IC_MSG"]) {
[LinphoneManager.instance startPushLongRunningTask:FALSE];
[self fixRing];
} else if ([loc_key isEqualToString:@"IM_MSG"]) {
[LinphoneManager.instance startPushLongRunningTask:TRUE];
}
}
}
@ -670,11 +687,13 @@ didInvalidatePushTokenForType:(NSString *)type {
}
- (void)pushRegistry:(PKPushRegistry *)registry
didUpdatePushCredentials:(PKPushCredentials *)credentials
forType:(NSString *)type {
LOGI(@"PushKit credentials updated");
LOGI(@"voip token: %@", (credentials.token));
dispatch_async(dispatch_get_main_queue(), ^{[LinphoneManager.instance setPushNotificationToken:credentials.token];});
didUpdatePushCredentials:(PKPushCredentials *)credentials
forType:(PKPushType)type {
LOGI(@"PushKit credentials updated");
LOGI(@"voip token: %@", (credentials.token));
dispatch_async(dispatch_get_main_queue(), ^{
[LinphoneManager.instance setPushNotificationToken:credentials.token];
});
}
#pragma mark - UNUserNotifications Framework
@ -686,10 +705,13 @@ didInvalidatePushTokenForType:(NSString *)type {
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)())completionHandler {
LOGD(@"UN : response recieved");
LOGD(response.description);
LOGD(@"UN : response received");
LOGD(response.description);
NSString *callId = (NSString *)[response.notification.request.content.userInfo objectForKey:@"CallId"];
if (!callId) {
return;
}
LinphoneCall *call = [LinphoneManager.instance callByCallId:callId];
if (call) {
LinphoneCallAppData *data = (__bridge LinphoneCallAppData *)linphone_call_get_user_data(call);
@ -702,9 +724,9 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
if ([response.actionIdentifier isEqual:@"Answer"]) {
// use the standard handler
[PhoneMainView.instance changeCurrentView:CallView.compositeViewDescription];
linphone_core_accept_call(LC, call);
linphone_call_accept(call);
} else if ([response.actionIdentifier isEqual:@"Decline"]) {
linphone_core_decline_call(LC, call, LinphoneReasonDeclined);
linphone_call_decline(call, LinphoneReasonDeclined);
} else if ([response.actionIdentifier isEqual:@"Reply"]) {
LinphoneCore *lc = [LinphoneManager getLc];
NSString *replyText = [(UNTextInputNotificationResponse *)response userText];
@ -713,6 +735,10 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
if (room) {
LinphoneChatMessage *msg = linphone_chat_room_create_message(room, replyText.UTF8String);
linphone_chat_room_send_chat_message(room, msg);
if (linphone_core_lime_enabled(LC) == LinphoneLimeMandatory && !linphone_chat_room_lime_available(room)) {
[LinphoneManager.instance alertLIME:room];
}
linphone_chat_room_mark_as_read(room);
TabBarView *tab = (TabBarView *)[PhoneMainView.instance.mainViewController
getCachedController:NSStringFromClass(TabBarView.class)];
@ -734,7 +760,7 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
LOGI(@"User declined video proposal");
if (call == linphone_core_get_current_call(LC)) {
LinphoneCallParams *params = linphone_core_create_call_params(LC, call);
linphone_core_accept_call_update(LC, call, params);
linphone_call_accept_update(call, params);
linphone_call_params_destroy(params);
}
} else if ([response.actionIdentifier isEqual:@"Accept"]) {
@ -744,7 +770,7 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
[PhoneMainView.instance changeCurrentView:CallView.compositeViewDescription];
LinphoneCallParams *params = linphone_core_create_call_params(LC, call);
linphone_call_params_enable_video(params, TRUE);
linphone_core_accept_call_update(LC, call, params);
linphone_call_accept_update(call, params);
linphone_call_params_destroy(params);
}
} else if ([response.actionIdentifier isEqual:@"Confirm"]) {
@ -755,6 +781,8 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
if (linphone_core_get_current_call(LC) == call) {
linphone_call_set_authentication_token_verified(call, NO);
}
} else if ([response.actionIdentifier isEqual:@"Call"]) {
} else { // in this case the value is : com.apple.UNNotificationDefaultActionIdentifier
if ([response.notification.request.content.categoryIdentifier isEqual:@"call_cat"]) {
[PhoneMainView.instance displayIncomingCall:call];
@ -772,7 +800,7 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
LOGI(@"User declined video proposal");
if (call == linphone_core_get_current_call(LC)) {
LinphoneCallParams *params = linphone_core_create_call_params(LC, call);
linphone_core_accept_call_update(LC, call, params);
linphone_call_accept_update(call, params);
linphone_call_params_destroy(params);
[videoDismissTimer invalidate];
}
@ -782,7 +810,7 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
if (call == linphone_core_get_current_call(LC)) {
LinphoneCallParams *params = linphone_core_create_call_params(LC, call);
linphone_call_params_enable_video(params, TRUE);
linphone_core_accept_call_update(LC, call, params);
linphone_call_accept_update(call, params);
linphone_call_params_destroy(params);
[videoDismissTimer invalidate];
}
@ -795,10 +823,22 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
userInfo:sheet
repeats:NO];
} else if ([response.notification.request.content.categoryIdentifier isEqual:@"zrtp_request"]) {
[UIConfirmationDialog
ShowWithMessage:[NSString stringWithFormat:NSLocalizedString(
@"Confirm the following SAS with peer:\n%s", nil),
linphone_call_get_authentication_token(call)]
NSString *code = [NSString stringWithUTF8String:linphone_call_get_authentication_token(call)];
NSString *myCode;
NSString *correspondantCode;
if (linphone_call_get_dir(call) == LinphoneCallIncoming) {
myCode = [code substringToIndex:2];
correspondantCode = [code substringFromIndex:2];
} else {
correspondantCode = [code substringToIndex:2];
myCode = [code substringFromIndex:2];
}
NSString *message = [NSString stringWithFormat:NSLocalizedString(@"Confirm the following SAS with peer:\n"
@"Say : %@\n"
@"Your correspondant should say : %@",
nil),
myCode, correspondantCode];
[UIConfirmationDialog ShowWithMessage:message
cancelMessage:NSLocalizedString(@"DENY", nil)
confirmMessage:NSLocalizedString(@"ACCEPT", nil)
onCancelClick:^() {
@ -811,6 +851,8 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
linphone_call_set_authentication_token_verified(call, YES);
}
}];
} else if ([response.notification.request.content.categoryIdentifier isEqual:@"lime"]) {
return;
} else { // Missed call
[PhoneMainView.instance changeCurrentView:HistoryListView.compositeViewDescription];
}
@ -844,11 +886,11 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
if ([identifier isEqualToString:@"answer"]) {
// use the standard handler
[PhoneMainView.instance changeCurrentView:CallView.compositeViewDescription];
linphone_core_accept_call(LC, call);
linphone_call_accept(call);
} else if ([identifier isEqualToString:@"decline"]) {
LinphoneCall *call = linphone_core_get_current_call(LC);
if (call)
linphone_core_decline_call(LC, call, LinphoneReasonDeclined);
linphone_call_decline(call, LinphoneReasonDeclined);
}
} else if ([notification.category isEqualToString:@"incoming_msg"]) {
if ([identifier isEqualToString:@"reply"]) {
@ -858,7 +900,9 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
NSString *from = [notification.userInfo objectForKey:@"from_addr"];
LinphoneChatRoom *room = linphone_core_get_chat_room_from_uri(LC, [from UTF8String]);
if (room) {
linphone_chat_room_mark_as_read(room);
if (!([UIApplication sharedApplication].applicationState == UIApplicationStateBackground ||
[UIApplication sharedApplication].applicationState == UIApplicationStateInactive))
linphone_chat_room_mark_as_read(room);
TabBarView *tab = (TabBarView *)[PhoneMainView.instance.mainViewController
getCachedController:NSStringFromClass(TabBarView.class)];
[tab update:YES];
@ -888,11 +932,11 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
if ([identifier isEqualToString:@"answer"]) {
// use the standard handler
[PhoneMainView.instance changeCurrentView:CallView.compositeViewDescription];
linphone_core_accept_call(LC, call);
linphone_call_accept(call);
} else if ([identifier isEqualToString:@"decline"]) {
LinphoneCall *call = linphone_core_get_current_call(LC);
if (call)
linphone_core_decline_call(LC, call, LinphoneReasonDeclined);
linphone_call_decline(call, LinphoneReasonDeclined);
}
} else if ([notification.category isEqualToString:@"incoming_msg"] &&
[identifier isEqualToString:@"reply_inline"]) {
@ -903,7 +947,14 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
if (room) {
LinphoneChatMessage *msg = linphone_chat_room_create_message(room, replyText.UTF8String);
linphone_chat_room_send_chat_message(room, msg);
linphone_chat_room_mark_as_read(room);
if (linphone_core_lime_enabled(LC) == LinphoneLimeMandatory && !linphone_chat_room_lime_available(room)) {
[LinphoneManager.instance alertLIME:room];
}
if (!([UIApplication sharedApplication].applicationState == UIApplicationStateBackground ||
[UIApplication sharedApplication].applicationState == UIApplicationStateInactive)) {
linphone_chat_room_mark_as_read(room);
}
[PhoneMainView.instance updateApplicationBadgeNumber];
}
}

View file

@ -324,6 +324,12 @@
forKey:@"repeat_call_notification_preference"];
}
// chat section
{
[self setInteger:linphone_core_lime_enabled(LC) forKey:@"use_lime_preference"];
[self setCString:linphone_core_get_file_transfer_server(LC) forKey:@"file_transfer_server_url_preference"];
}
// network section
{
[self setBool:[lm lpConfigBoolForKey:@"edge_opt_preference" withDefault:NO] forKey:@"edge_opt_preference"];
@ -401,6 +407,7 @@
[self setBool:[lm lpConfigBoolForKey:@"start_at_boot_preference"] forKey:@"start_at_boot_preference"];
[self setBool:[lm lpConfigBoolForKey:@"autoanswer_notif_preference"] forKey:@"autoanswer_notif_preference"];
[self setBool:[lm lpConfigBoolForKey:@"show_msg_in_notif" withDefault:YES] forKey:@"show_msg_in_notif"];
[self setBool:[lm lpConfigBoolForKey:@"use_rls_presence" withDefault:YES] forKey:@"use_rls_presence"];
[self setBool:[lm lpConfigBoolForKey:@"enable_first_login_view_preference"]
forKey:@"enable_first_login_view_preference"];
LinphoneAddress *parsed = linphone_core_get_primary_contact_parsed(LC);
@ -409,7 +416,6 @@
[self setCString:linphone_address_get_username(parsed) forKey:@"primary_username_preference"];
linphone_address_destroy(parsed);
}
[self setCString:linphone_core_get_file_transfer_server(LC) forKey:@"file_transfer_server_url_preference"];
}
changedDict = [[NSMutableDictionary alloc] init];
@ -572,7 +578,12 @@
}
LinphoneAuthInfo *proxyAi = (LinphoneAuthInfo *)linphone_proxy_config_find_auth_info(proxyCfg);
char *realm;
if (proxyAi) {
realm = ms_strdup(linphone_auth_info_get_realm(proxyAi));
} else {
realm = NULL;
}
// setup new proxycfg
linphone_proxy_config_done(proxyCfg);
@ -588,12 +599,21 @@
LinphoneAddress *from = linphone_core_interpret_url(LC, identity);
if (from) {
const char *userid_str = (userID != nil) ? [userID UTF8String] : NULL;
LinphoneAuthInfo *info = linphone_auth_info_new(
linphone_address_get_username(from), userid_str, password ? password : NULL, password ? NULL : ha1,
linphone_proxy_config_get_realm(proxyCfg), linphone_proxy_config_get_domain(proxyCfg));
LinphoneAuthInfo *info;
if (password) {
info = linphone_auth_info_new(linphone_address_get_username(from), userid_str, password, NULL,
linphone_proxy_config_get_realm(proxyCfg),
linphone_proxy_config_get_domain(proxyCfg));
} else {
info = linphone_auth_info_new(linphone_address_get_username(from), userid_str, NULL, ha1,
realm ? realm : linphone_proxy_config_get_realm(proxyCfg),
linphone_proxy_config_get_domain(proxyCfg));
}
linphone_address_destroy(from);
linphone_core_add_auth_info(LC, info);
linphone_auth_info_destroy(info);
ms_free(realm);
}
bad_proxy:
@ -656,36 +676,36 @@
bool enableAutoAnswer = [self boolForKey:@"enable_auto_answer_preference"];
[LinphoneManager.instance lpConfigSetBool:enableAutoAnswer forKey:@"auto_answer"];
}
// audio section
{
[self synchronizeCodecs:linphone_core_get_audio_codecs(LC)];
float playback_gain = [self floatForKey:@"playback_gain_preference"];
linphone_core_set_playback_gain_db(LC, playback_gain);
float mic_gain = [self floatForKey:@"microphone_gain_preference"];
linphone_core_set_mic_gain_db(LC, mic_gain);
[lm lpConfigSetInt:[self integerForKey:@"audio_codec_bitrate_limit_preference"]
forKey:@"codec_bitrate_limit"
inSection:@"audio"];
BOOL voice_processing = [self boolForKey:@"voiceproc_preference"];
[lm lpConfigSetInt:voice_processing forKey:@"voiceproc_preference"];
BOOL equalizer = [self boolForKey:@"eq_active"];
[lm lpConfigSetBool:equalizer forKey:@"eq_active" inSection:@"sound"];
[LinphoneManager.instance configureVbrCodecs];
NSString *au_device = @"AU: Audio Unit Receiver";
if (!voice_processing) {
au_device = @"AU: Audio Unit NoVoiceProc";
}
// audio section
{
[self synchronizeCodecs:linphone_core_get_audio_codecs(LC)];
float playback_gain = [self floatForKey:@"playback_gain_preference"];
linphone_core_set_playback_gain_db(LC, playback_gain);
float mic_gain = [self floatForKey:@"microphone_gain_preference"];
linphone_core_set_mic_gain_db(LC, mic_gain);
[lm lpConfigSetInt:[self integerForKey:@"audio_codec_bitrate_limit_preference"]
forKey:@"codec_bitrate_limit"
inSection:@"audio"];
BOOL voice_processing = [self boolForKey:@"voiceproc_preference"];
[lm lpConfigSetInt:voice_processing forKey:@"voiceproc_preference"];
BOOL equalizer = [self boolForKey:@"eq_active"];
[lm lpConfigSetBool:equalizer forKey:@"eq_active" inSection:@"sound"];
[LinphoneManager.instance configureVbrCodecs];
NSString *au_device = @"AU: Audio Unit Receiver";
if (!voice_processing) {
au_device = @"AU: Audio Unit NoVoiceProc";
}
linphone_core_set_capture_device(LC, [au_device UTF8String]);
linphone_core_set_playback_device(LC, [au_device UTF8String]);
linphone_core_set_capture_device(LC, [au_device UTF8String]);
linphone_core_set_playback_device(LC, [au_device UTF8String]);
}
// video section
@ -743,6 +763,34 @@
forKey:@"repeat_call_notification"];
}
// chat section
{
int val = [self integerForKey:@"use_lime_preference"];
linphone_core_enable_lime(LC, val);
if (val == LinphoneLimeMandatory &&
(linphone_core_get_media_encryption(LC) != LinphoneMediaEncryptionZRTP)) {
linphone_core_set_media_encryption(LC, LinphoneMediaEncryptionZRTP);
[self setCString:"ZRTP" forKey:@"media_encryption_preference"];
UIAlertController *errView = [UIAlertController
alertControllerWithTitle:NSLocalizedString(@"ZRTP activation", nil)
message:
NSLocalizedString(
@"LIME requires ZRTP encryption.\n"
@"By activating LIME you automatically activate ZRTP media encryption.",
nil)
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:@"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action){
}];
[errView addAction:defaultAction];
[PhoneMainView.instance presentViewController:errView animated:YES completion:nil];
}
linphone_core_set_file_transfer_server(
LC, [[self stringForKey:@"file_transfer_server_url_preference"] UTF8String]);
}
// network section
{
BOOL edgeOpt = [self boolForKey:@"edge_opt_preference"];
@ -861,6 +909,36 @@
forKey:@"autoanswer_notif_preference"];
[lm lpConfigSetInt:[self integerForKey:@"show_msg_in_notif"] forKey:@"show_msg_in_notif"];
if ([self integerForKey:@"use_rls_presence"]) {
[self setInteger:0 forKey:@"use_rls_presence"];
NSString *rls_uri =
[lm lpConfigStringForKey:@"rls_uri" inSection:@"sip" withDefault:@"sips:rls@sip.linphone.org"];
LinphoneAddress *rls_addr = linphone_address_new(rls_uri.UTF8String);
const char *rls_domain = linphone_address_get_domain(rls_addr);
const MSList *proxies = linphone_core_get_proxy_config_list(LC);
if (!proxies) {
// Enable it if no proxy config for first launch of app
[self setInteger:1 forKey:@"use_rls_presence"];
} else {
while (proxies) {
const char *proxy_domain = linphone_proxy_config_get_domain(proxies->data);
if (strcmp(rls_domain, proxy_domain) == 0) {
[self setInteger:1 forKey:@"use_rls_presence"];
break;
}
proxies = proxies->next;
}
}
linphone_address_unref(rls_addr);
}
[lm lpConfigSetInt:[self integerForKey:@"use_rls_presence"] forKey:@"use_rls_presence"];
const MSList *lists = linphone_core_get_friends_lists(LC);
while (lists) {
linphone_friend_list_enable_subscriptions(lists->data, [self integerForKey:@"use_rls_presence"]);
lists = lists->next;
}
BOOL firstloginview = [self boolForKey:@"enable_first_login_view_preference"];
[lm lpConfigSetInt:firstloginview forKey:@"enable_first_login_view_preference"];
@ -878,9 +956,6 @@
[lm lpConfigSetInt:[self integerForKey:@"account_mandatory_advanced_preference"]
forKey:@"account_mandatory_advanced_preference"];
linphone_core_set_file_transfer_server(
LC, [[self stringForKey:@"file_transfer_server_url_preference"] UTF8String]);
}
changedDict = [[NSMutableDictionary alloc] init];

View file

@ -109,6 +109,7 @@ typedef struct _LinphoneManagerSounds {
Connectivity connectivity;
UIBackgroundTaskIdentifier pausedCallBgTask;
UIBackgroundTaskIdentifier incallBgTask;
UIBackgroundTaskIdentifier pushBgTask;
CTCallCenter* mCallCenter;
NSDate *mLastKeepAliveDate;
@public
@ -140,7 +141,8 @@ typedef struct _LinphoneManagerSounds {
- (void)acceptCallForCallId:(NSString*)callid;
- (LinphoneCall *)callByCallId:(NSString *)call_id;
- (void)cancelLocalNotifTimerForCallId:(NSString*)callid;
- (void)alertLIME:(LinphoneChatRoom *)room;
- (void)startPushLongRunningTask:(BOOL)msg;
+ (BOOL)langageDirectionIsRTL;
+ (void)kickOffNetworkConnection;
- (void)setupNetworkReachabilityCallback;
@ -157,7 +159,8 @@ typedef struct _LinphoneManagerSounds {
+ (NSString*)cacheDirectory;
- (void)acceptCall:(LinphoneCall *)call evenWithVideo:(BOOL)video;
- (BOOL)call:(const LinphoneAddress *)address;
- (void)call:(const LinphoneAddress *)address;
- (BOOL)doCall:(const LinphoneAddress *)iaddr;
+(id)getMessageAppDataForKey:(NSString*)key inMessage:(LinphoneChatMessage*)msg;
+(void)setValueInMessageAppData:(id)value forKey:(NSString*)key inMessage:(LinphoneChatMessage*)msg;
@ -218,5 +221,6 @@ typedef struct _LinphoneManagerSounds {
@property(strong, nonatomic) NSMutableArray *fileTransferDelegates;
@property BOOL nextCallIsTransfer;
@property BOOL conf;
@property NSDictionary *pushDict;
@end

View file

@ -24,14 +24,16 @@
#include <sys/sysctl.h>
#import <AVFoundation/AVAudioSession.h>
#import <AVFoundation/AVCaptureDevice.h>
#import <AudioToolbox/AudioToolbox.h>
#import <SystemConfiguration/SystemConfiguration.h>
#import <CoreTelephony/CTCallCenter.h>
#import <SystemConfiguration/CaptiveNetwork.h>
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import <SystemConfiguration/CaptiveNetwork.h>
#import <SystemConfiguration/SystemConfiguration.h>
#import "LinphoneManager.h"
#import "LinphoneCoreSettingsStore.h"
#import "LinphoneManager.h"
#import "Utils/AudioHelper.h"
#import "Utils/FileTransferDelegate.h"
#include "linphone/linphonecore_utils.h"
@ -79,7 +81,6 @@ extern void libmsamr_init(MSFactory *factory);
extern void libmsx264_init(MSFactory *factory);
extern void libmsopenh264_init(MSFactory *factory);
extern void libmssilk_init(MSFactory *factory);
extern void libmsbcg729_init(MSFactory *factory);
extern void libmswebrtc_init(MSFactory *factory);
#define FRONT_CAM_NAME \
@ -237,7 +238,6 @@ struct codec_name_pref_table codec_pref_table[] = {{"speex", 8000, "speex_8k_pre
- (id)init {
if ((self = [super init])) {
AudioSessionInitialize(NULL, NULL, NULL, NULL);
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(audioRouteChangeListenerCallback:)
name:AVAudioSessionRouteChangeNotification
@ -249,6 +249,7 @@ struct codec_name_pref_table codec_pref_table[] = {{"speex", 8000, "speex_8k_pre
_sounds.vibrate = kSystemSoundID_Vibrate;
_logs = [[NSMutableArray alloc] init];
_pushDict = [[NSMutableDictionary alloc] init];
_database = NULL;
_speakerEnabled = FALSE;
_bluetoothEnabled = FALSE;
@ -258,7 +259,6 @@ struct codec_name_pref_table codec_pref_table[] = {{"speex", 8000, "speex_8k_pre
pushCallIDs = [[NSMutableArray alloc] init];
_photoLibrary = [[ALAssetsLibrary alloc] init];
_isTesting = [LinphoneManager isRunningTests];
[self renameDefaultSettings];
[self copyDefaultSettings];
[self overrideDefaultSettings];
@ -503,7 +503,11 @@ exit_dbmigration:
LinphoneProxyConfig *proxy = (LinphoneProxyConfig *)proxies->data;
const char *addr = linphone_proxy_config_get_addr(proxy);
// we want to enable AVPF for the proxies
if (addr && strstr(addr, "sip.linphone.org") != 0) {
if (addr &&
strstr(addr, [LinphoneManager.instance lpConfigStringForKey:@"domain_name"
inSection:@"app"
withDefault:@"sip.linphone.org"]
.UTF8String) != 0) {
LOGI(@"Migrating proxy config to use AVPF");
linphone_proxy_config_enable_avpf(proxy, TRUE);
}
@ -518,7 +522,11 @@ exit_dbmigration:
LinphoneProxyConfig *proxy = (LinphoneProxyConfig *)proxies->data;
const char *addr = linphone_proxy_config_get_addr(proxy);
// we want to enable quality reporting for the proxies that are on linphone.org
if (addr && strstr(addr, "sip.linphone.org") != 0) {
if (addr &&
strstr(addr, [LinphoneManager.instance lpConfigStringForKey:@"domain_name"
inSection:@"app"
withDefault:@"sip.linphone.org"]
.UTF8String) != 0) {
LOGI(@"Migrating proxy config to send quality report");
linphone_proxy_config_set_quality_reporting_collector(
proxy, "sip:voip-metrics@sip.linphone.org;transport=tls");
@ -655,8 +663,25 @@ static void linphone_iphone_display_status(struct _LinphoneCore *lc, const char
NSString *address = [FastAddressBook displayNameForAddress:addr];
if (state == LinphoneCallIncomingReceived) {
// TESTING !!
// linphone_call_accept_early_media(call);
LinphoneCallLog *callLog = linphone_call_get_call_log(call);
NSString *callId = [NSString stringWithUTF8String:linphone_call_log_get_call_id(callLog)];
int index = [(NSNumber *)[_pushDict objectForKey:callId] intValue] - 1;
[_pushDict setValue:[NSNumber numberWithInt:index] forKey:callId];
BOOL need_bg_task = FALSE;
for (NSString *key in [_pushDict allKeys]) {
int value = [(NSNumber *)[_pushDict objectForKey:key] intValue];
if (value > 0) {
need_bg_task = TRUE;
break;
}
}
if (pushBgTask && !need_bg_task) {
LOGI(@"Call received, stopping background task");
[[UIApplication sharedApplication] endBackgroundTask:pushBgTask];
pushBgTask = 0;
}
/*first step is to re-enable ctcall center*/
CTCallCenter *lCTCallCenter = [[CTCallCenter alloc] init];
@ -668,15 +693,15 @@ static void linphone_iphone_display_status(struct _LinphoneCore *lc, const char
LOGI(@"Mobile call ongoing... rejecting call from [%s]", tmp);
ms_free(tmp);
}
linphone_core_decline_call(theLinphoneCore, call, LinphoneReasonBusy);
linphone_call_decline(call, LinphoneReasonBusy);
return;
}
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_9_x_Max && call &&
(linphone_core_get_calls_nb(LC) < 2)) {
#if !TARGET_IPHONE_SIMULATOR
NSString *callId =
[NSString stringWithUTF8String:linphone_call_log_get_call_id(linphone_call_get_call_log(call))];
NSString *address = [FastAddressBook displayNameForAddress:linphone_call_get_remote_address(call)];
NSUUID *uuid = [NSUUID UUID];
[LinphoneManager.instance.providerDelegate.calls setObject:callId forKey:uuid];
@ -686,6 +711,9 @@ static void linphone_iphone_display_status(struct _LinphoneCore *lc, const char
linphone_core_get_video_policy(LC)->automatically_accept &&
linphone_call_params_video_enabled(linphone_call_get_remote_params(call)));
[LinphoneManager.instance.providerDelegate reportIncomingCallwithUUID:uuid handle:address video:video];
#else
[PhoneMainView.instance displayIncomingCall:call];
#endif
} else if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
// Create a UNNotification
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
@ -864,11 +892,11 @@ static void linphone_iphone_display_status(struct _LinphoneCore *lc, const char
connectedAtDate:nil];
}
[self.providerDelegate.uuids removeObjectForKey:callId2];
[self.providerDelegate.calls removeObjectForKey:uuid];
[self.providerDelegate.provider reportCallWithUUID:uuid
endedAtDate:NULL
reason:CXCallEndedReasonRemoteEnded];
CXEndCallAction *act = [[CXEndCallAction alloc] initWithCallUUID:uuid];
CXTransaction *tr = [[CXTransaction alloc] initWithAction:act];
[LinphoneManager.instance.providerDelegate.controller requestTransaction:tr
completion:^(NSError *err){
}];
}
} else {
if (data != nil && data->notification != nil) {
@ -896,6 +924,9 @@ static void linphone_iphone_display_status(struct _LinphoneCore *lc, const char
}
}
}
if (state == LinphoneCallError) {
[PhoneMainView.instance popCurrentView];
}
}
if (state == LinphoneCallReleased) {
@ -1150,7 +1181,6 @@ static void linphone_iphone_popup_password_request(LinphoneCore *lc, const char
_silentPushCompletion = nil;
}
#pragma deploymate pop
NSString *callID = [NSString stringWithUTF8String:linphone_chat_message_get_custom_header(msg, "Call-ID")];
const LinphoneAddress *remoteAddress = linphone_chat_message_get_from_address(msg);
NSString *from = [FastAddressBook displayNameForAddress:remoteAddress];
@ -1158,116 +1188,202 @@ static void linphone_iphone_popup_password_request(LinphoneCore *lc, const char
char *c_address = linphone_address_as_string_uri_only(remoteAddress);
NSString *remote_uri = [NSString stringWithUTF8String:c_address];
ms_free(c_address);
int index = [(NSNumber *)[_pushDict objectForKey:callID] intValue] - 1;
[_pushDict setValue:[NSNumber numberWithInt:index] forKey:callID];
BOOL need_bg_task = FALSE;
for (NSString *key in [_pushDict allKeys]) {
int value = [(NSNumber *)[_pushDict objectForKey:key] intValue];
if (value > 0) {
need_bg_task = TRUE;
break;
}
}
if (pushBgTask && !need_bg_task) {
LOGI(@"Message received, stopping background task");
[[UIApplication sharedApplication] endBackgroundTask:pushBgTask];
pushBgTask = 0;
}
if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground || ((PhoneMainView.instance.currentView != ChatsListView.compositeViewDescription) && ((PhoneMainView.instance.currentView != ChatConversationView.compositeViewDescription))) || (PhoneMainView.instance.currentView == ChatConversationView.compositeViewDescription && room != PhoneMainView.instance.currentRoom)) {
// Create a new notification
if(floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max) {
NSArray *actions;
if ([[UIDevice.currentDevice systemVersion] floatValue] < 9 ||
[LinphoneManager.instance lpConfigBoolForKey:@"show_msg_in_notif"] == NO) {
UIMutableUserNotificationAction *reply = [[UIMutableUserNotificationAction alloc] init];
reply.identifier = @"reply";
reply.title = NSLocalizedString(@"Reply", nil);
reply.activationMode = UIUserNotificationActivationModeForeground;
reply.destructive = NO;
reply.authenticationRequired = YES;
UIMutableUserNotificationAction *mark_read = [[UIMutableUserNotificationAction alloc] init];
mark_read.identifier = @"mark_read";
mark_read.title = NSLocalizedString(@"Mark Read", nil);
mark_read.activationMode = UIUserNotificationActivationModeBackground;
mark_read.destructive = NO;
mark_read.authenticationRequired = NO;
actions = @[ mark_read, reply ];
} else {
// iOS 9 allows for inline reply. We don't propose mark_read in this case
UIMutableUserNotificationAction *reply_inline = [[UIMutableUserNotificationAction alloc] init];
reply_inline.identifier = @"reply_inline";
reply_inline.title = NSLocalizedString(@"Reply", nil);
reply_inline.activationMode = UIUserNotificationActivationModeBackground;
reply_inline.destructive = NO;
reply_inline.authenticationRequired = NO;
reply_inline.behavior = UIUserNotificationActionBehaviorTextInput;
actions = @[ reply_inline ];
}
UIMutableUserNotificationCategory *msgcat = [[UIMutableUserNotificationCategory alloc] init];
msgcat.identifier = @"incoming_msg";
[msgcat setActions:actions forContext:UIUserNotificationActionContextDefault];
[msgcat setActions:actions forContext:UIUserNotificationActionContextMinimal];
NSSet* categories = [NSSet setWithObjects:msgcat, nil];
UIUserNotificationSettings *set = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound) categories:categories];
[[UIApplication sharedApplication] registerUserNotificationSettings:set];
UILocalNotification *notif = [[UILocalNotification alloc] init];
if (notif) {
NSString *chat = [UIChatBubbleTextCell TextMessageForChat:msg];
notif.repeatInterval = 0;
if ([[UIDevice currentDevice].systemVersion floatValue] >= 8) {
if (linphone_chat_message_is_file_transfer(msg) || linphone_chat_message_is_text(msg)) {
if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground ||
((PhoneMainView.instance.currentView != ChatsListView.compositeViewDescription) &&
((PhoneMainView.instance.currentView != ChatConversationView.compositeViewDescription))) ||
(PhoneMainView.instance.currentView == ChatConversationView.compositeViewDescription &&
room != PhoneMainView.instance.currentRoom)) {
// Create a new notification
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max) {
NSArray *actions;
if ([[UIDevice.currentDevice systemVersion] floatValue] < 9 ||
[LinphoneManager.instance lpConfigBoolForKey:@"show_msg_in_notif"] == NO) {
UIMutableUserNotificationAction *reply = [[UIMutableUserNotificationAction alloc] init];
reply.identifier = @"reply";
reply.title = NSLocalizedString(@"Reply", nil);
reply.activationMode = UIUserNotificationActivationModeForeground;
reply.destructive = NO;
reply.authenticationRequired = YES;
UIMutableUserNotificationAction *mark_read = [[UIMutableUserNotificationAction alloc] init];
mark_read.identifier = @"mark_read";
mark_read.title = NSLocalizedString(@"Mark Read", nil);
mark_read.activationMode = UIUserNotificationActivationModeBackground;
mark_read.destructive = NO;
mark_read.authenticationRequired = NO;
actions = @[ mark_read, reply ];
} else {
// iOS 9 allows for inline reply. We don't propose mark_read in this case
UIMutableUserNotificationAction *reply_inline = [[UIMutableUserNotificationAction alloc] init];
reply_inline.identifier = @"reply_inline";
reply_inline.title = NSLocalizedString(@"Reply", nil);
reply_inline.activationMode = UIUserNotificationActivationModeBackground;
reply_inline.destructive = NO;
reply_inline.authenticationRequired = NO;
reply_inline.behavior = UIUserNotificationActionBehaviorTextInput;
actions = @[ reply_inline ];
}
UIMutableUserNotificationCategory *msgcat = [[UIMutableUserNotificationCategory alloc] init];
msgcat.identifier = @"incoming_msg";
[msgcat setActions:actions forContext:UIUserNotificationActionContextDefault];
[msgcat setActions:actions forContext:UIUserNotificationActionContextMinimal];
NSSet *categories = [NSSet setWithObjects:msgcat, nil];
UIUserNotificationSettings *set = [UIUserNotificationSettings
settingsForTypes:(UIUserNotificationTypeAlert | UIUserNotificationTypeBadge |
UIUserNotificationTypeSound)
categories:categories];
[[UIApplication sharedApplication] registerUserNotificationSettings:set];
UILocalNotification *notif = [[UILocalNotification alloc] init];
if (notif) {
NSString *chat = [UIChatBubbleTextCell TextMessageForChat:msg];
notif.repeatInterval = 0;
if ([[UIDevice currentDevice].systemVersion floatValue] >= 8) {
#pragma deploymate push "ignored-api-availability"
notif.category = @"incoming_msg";
notif.category = @"incoming_msg";
#pragma deploymate pop
}
if ([LinphoneManager.instance lpConfigBoolForKey:@"show_msg_in_notif" withDefault:YES]) {
notif.alertBody = [NSString stringWithFormat:NSLocalizedString(@"IM_FULLMSG", nil), from, chat];
} else {
notif.alertBody = [NSString stringWithFormat:NSLocalizedString(@"IM_MSG", nil), from];
}
notif.alertAction = NSLocalizedString(@"Show", nil);
notif.soundName = @"msg.caf";
notif.userInfo = @{ @"from" : from, @"from_addr" : remote_uri, @"call-id" : callID };
notif.accessibilityLabel = @"Message notif";
[[UIApplication sharedApplication] presentLocalNotificationNow:notif];
}
} else {
// Msg category
UNTextInputNotificationAction *act_reply =
[UNTextInputNotificationAction actionWithIdentifier:@"Reply"
title:NSLocalizedString(@"Reply", nil)
options:UNNotificationActionOptionNone];
UNNotificationAction *act_seen =
[UNNotificationAction actionWithIdentifier:@"Seen"
title:NSLocalizedString(@"Mark as seen", nil)
options:UNNotificationActionOptionNone];
UNNotificationCategory *cat_msg =
[UNNotificationCategory categoryWithIdentifier:@"msg_cat"
actions:[NSArray arrayWithObjects:act_reply, act_seen, nil]
intentIdentifiers:[[NSMutableArray alloc] init]
options:UNNotificationCategoryOptionCustomDismissAction];
[[UNUserNotificationCenter currentNotificationCenter]
requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionSound |
UNAuthorizationOptionBadge)
completionHandler:^(BOOL granted, NSError *_Nullable error) {
// Enable or disable features based on authorization.
if (error) {
LOGD(error.description);
}
}];
NSSet *categories = [NSSet setWithObjects:cat_msg, nil];
[[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:categories];
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
content.title = NSLocalizedString(@"Message received", nil);
if ([LinphoneManager.instance lpConfigBoolForKey:@"show_msg_in_notif" withDefault:YES]) {
content.subtitle = from;
content.body = [UIChatBubbleTextCell TextMessageForChat:msg];
}
if ([LinphoneManager.instance lpConfigBoolForKey:@"show_msg_in_notif" withDefault:YES]) {
notif.alertBody = [NSString stringWithFormat:NSLocalizedString(@"IM_FULLMSG", nil), from, chat];
} else {
notif.alertBody = [NSString stringWithFormat:NSLocalizedString(@"IM_MSG", nil), from];
}
notif.alertAction = NSLocalizedString(@"Show", nil);
notif.soundName = @"msg.caf";
notif.userInfo = @{ @"from" : from, @"from_addr" : remote_uri, @"call-id" : callID };
notif.accessibilityLabel = @"Message notif";
[[UIApplication sharedApplication] presentLocalNotificationNow:notif];
}
} else {
content.body = from;
// Msg category
UNTextInputNotificationAction *act_reply =
[UNTextInputNotificationAction actionWithIdentifier:@"Reply"
title:NSLocalizedString(@"Reply", nil)
options:UNNotificationActionOptionNone];
UNNotificationAction *act_seen =
[UNNotificationAction actionWithIdentifier:@"Seen"
title:NSLocalizedString(@"Mark as seen", nil)
options:UNNotificationActionOptionNone];
UNNotificationCategory *cat_msg =
[UNNotificationCategory categoryWithIdentifier:@"msg_cat"
actions:[NSArray arrayWithObjects:act_reply, act_seen, nil]
intentIdentifiers:[[NSMutableArray alloc] init]
options:UNNotificationCategoryOptionCustomDismissAction];
[[UNUserNotificationCenter currentNotificationCenter]
requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionSound |
UNAuthorizationOptionBadge)
completionHandler:^(BOOL granted, NSError *_Nullable error) {
// Enable or disable features based on authorization.
if (error) {
LOGD(error.description);
}
}];
NSSet *categories = [NSSet setWithObjects:cat_msg, nil];
[[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:categories];
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
content.title = NSLocalizedString(@"Message received", nil);
if ([LinphoneManager.instance lpConfigBoolForKey:@"show_msg_in_notif" withDefault:YES]) {
content.subtitle = from;
content.body = [UIChatBubbleTextCell TextMessageForChat:msg];
} else {
content.body = from;
}
content.sound = [UNNotificationSound soundNamed:@"msg.caf"];
content.categoryIdentifier = @"msg_cat";
content.userInfo = @{ @"from" : from, @"from_addr" : remote_uri, @"CallId" : callID };
content.accessibilityLabel = @"Message notif";
UNNotificationRequest *req =
[UNNotificationRequest requestWithIdentifier:@"call_request" content:content trigger:NULL];
[[UNUserNotificationCenter currentNotificationCenter]
addNotificationRequest:req
withCompletionHandler:^(NSError *_Nullable error) {
// Enable or disable features based on authorization.
if (error) {
LOGD(@"Error while adding notification request :");
LOGD(error.description);
}
}];
}
content.sound = [UNNotificationSound soundNamed:@"msg.caf"];
content.categoryIdentifier = @"msg_cat";
content.userInfo = @{ @"from" : from, @"from_addr" : remote_uri, @"call-id" : callID };
content.accessibilityLabel = @"Message notif";
}
// Post event
NSDictionary *dict = @{
@"room" : [NSValue valueWithPointer:room],
@"from_address" : [NSValue valueWithPointer:linphone_chat_message_get_from_address(msg)],
@"message" : [NSValue valueWithPointer:msg],
@"call-id" : callID
};
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneMessageReceived object:self userInfo:dict];
}
}
static void linphone_iphone_message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *message) {
[(__bridge LinphoneManager *)linphone_core_get_user_data(lc) onMessageReceived:lc room:room message:message];
}
static void linphone_iphone_message_received_unable_decrypt(LinphoneCore *lc, LinphoneChatRoom *room,
LinphoneChatMessage *message) {
NSString *msgId = [NSString stringWithUTF8String:linphone_chat_message_get_custom_header(message, "Call-ID")];
int index = [(NSNumber *)[LinphoneManager.instance.pushDict objectForKey:msgId] intValue] - 1;
[LinphoneManager.instance.pushDict setValue:[NSNumber numberWithInt:index] forKey:msgId];
BOOL need_bg_task = FALSE;
for (NSString *key in [LinphoneManager.instance.pushDict allKeys]) {
int value = [(NSNumber *)[LinphoneManager.instance.pushDict objectForKey:key] intValue];
if (value > 0) {
need_bg_task = TRUE;
break;
}
}
if (theLinphoneManager->pushBgTask && !need_bg_task) {
LOGI(@"Message received, stopping background task");
[[UIApplication sharedApplication] endBackgroundTask:theLinphoneManager->pushBgTask];
theLinphoneManager->pushBgTask = 0;
}
const LinphoneAddress *address = linphone_chat_message_get_peer_address(message);
NSString *strAddr = [FastAddressBook displayNameForAddress:address];
NSString *title = NSLocalizedString(@"LIME warning", nil);
NSString *body = [NSString
stringWithFormat:NSLocalizedString(@"You have received an encrypted message you are unable to decrypt from "
@"%@.\nYou need to call your correspondant in order to exchange your ZRTP "
@"keys if you want to decrypt the future messages you will receive.",
nil),
strAddr];
NSString *action = NSLocalizedString(@"Call", nil);
if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_9_x_Max) {
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
content.title = title;
content.body = body;
UNNotificationRequest *req =
[UNNotificationRequest requestWithIdentifier:@"call_request" content:content trigger:NULL];
[UNNotificationRequest requestWithIdentifier:@"decrypt_request" content:content trigger:NULL];
[[UNUserNotificationCenter currentNotificationCenter]
addNotificationRequest:req
withCompletionHandler:^(NSError *_Nullable error) {
@ -1277,21 +1393,32 @@ static void linphone_iphone_popup_password_request(LinphoneCore *lc, const char
LOGD(error.description);
}
}];
} else {
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.repeatInterval = 0;
notification.alertTitle = title;
notification.alertBody = body;
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
}
} else {
UIAlertController *errView =
[UIAlertController alertControllerWithTitle:title message:body preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action){
}];
UIAlertAction *callAction = [UIAlertAction actionWithTitle:action
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[LinphoneManager.instance call:address];
}];
[errView addAction:defaultAction];
[errView addAction:callAction];
[PhoneMainView.instance presentViewController:errView animated:YES completion:nil];
}
// Post event
NSDictionary *dict = @{
@"room" : [NSValue valueWithPointer:room],
@"from_address" : [NSValue valueWithPointer:linphone_chat_message_get_from_address(msg)],
@"message" : [NSValue valueWithPointer:msg],
@"call-id" : callID
};
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneMessageReceived object:self userInfo:dict];
}
static void linphone_iphone_message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *message) {
[(__bridge LinphoneManager *)linphone_core_get_user_data(lc) onMessageReceived:lc room:room message:message];
}
- (void)onNotifyReceived:(LinphoneCore *)lc
@ -1362,6 +1489,59 @@ static void linphone_iphone_call_encryption_changed(LinphoneCore *lc, LinphoneCa
}
#pragma mark - Message composition start
- (void)alertLIME:(LinphoneChatRoom *)room {
NSString *title = NSLocalizedString(@"LIME warning", nil);
NSString *body =
NSLocalizedString(@"You are trying to send a message using LIME to a contact not verified by ZRTP.\n"
@"Please call this contact and verify his ZRTP key before sending your messages.",
nil);
if ([UIApplication sharedApplication].applicationState != UIApplicationStateBackground) {
UIAlertController *errView =
[UIAlertController alertControllerWithTitle:title message:body preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:@"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action){
}];
[errView addAction:defaultAction];
UIAlertAction *callAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Call", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[self call:linphone_chat_room_get_peer_address(room)];
}];
[errView addAction:callAction];
[PhoneMainView.instance presentViewController:errView animated:YES completion:nil];
} else {
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_9_x_Max) {
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
content.title = title;
content.body = body;
content.categoryIdentifier = @"lime";
UNNotificationRequest *req = [UNNotificationRequest
requestWithIdentifier:@"lime_request"
content:content
trigger:[UNTimeIntervalNotificationTrigger triggerWithTimeInterval:1 repeats:NO]];
[[UNUserNotificationCenter currentNotificationCenter]
addNotificationRequest:req
withCompletionHandler:^(NSError *_Nullable error) {
// Enable or disable features based on authorization.
if (error) {
LOGD(@"Error while adding notification request :");
LOGD(error.description);
}
}];
} else {
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.repeatInterval = 0;
notification.alertTitle = title;
notification.alertBody = body;
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
}
}
}
- (void)onMessageComposeReceived:(LinphoneCore *)core forRoom:(LinphoneChatRoom *)room {
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneTextComposeEvent
@ -1634,6 +1814,7 @@ static LinphoneCoreVTable linphonec_vtable = {
.notify_presence_received_for_uri_or_tel = linphone_iphone_notify_presence_received_for_uri_or_tel,
.auth_info_requested = linphone_iphone_popup_password_request,
.message_received = linphone_iphone_message_received,
.message_received_unable_decrypt = linphone_iphone_message_received_unable_decrypt,
.transfer_state_changed = linphone_iphone_transfer_state_changed,
.is_composing_received = linphone_iphone_is_composing_received,
.configuring_status = linphone_iphone_configuring_status_changed,
@ -1779,6 +1960,11 @@ static BOOL libStarted = FALSE;
[PhoneMainView.instance presentViewController:errView animated:YES completion:nil];
}
// Enable notify policy for all
LinphoneImNotifPolicy *im_notif_policy;
im_notif_policy = linphone_core_get_im_notif_policy(theLinphoneCore);
linphone_im_notif_policy_enable_all(im_notif_policy);
if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
// go directly to bg mode
[self enterBackgroundMode];
@ -1790,7 +1976,12 @@ void popup_link_account_cb(LinphoneAccountCreator *creator, LinphoneAccountCreat
[LinphoneManager.instance lpConfigSetInt:0 forKey:@"must_link_account_time"];
} else {
LinphoneProxyConfig *cfg = linphone_core_get_default_proxy_config(LC);
if (cfg) {
if (cfg &&
strcmp(linphone_proxy_config_get_domain(cfg),
[LinphoneManager.instance lpConfigStringForKey:@"domain_name"
inSection:@"app"
withDefault:@"sip.linphone.org"]
.UTF8String) == 0) {
UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Link your account", nil)
message:[NSString stringWithFormat:NSLocalizedString(@"Link your Linphone.org account %s to your phone number.", nil),
linphone_address_get_username(linphone_proxy_config_get_identity_address(cfg))]
@ -1876,7 +2067,6 @@ void popup_link_account_cb(LinphoneAccountCreator *creator, LinphoneAccountCreat
libmsamr_init(f);
libmsx264_init(f);
libmsopenh264_init(f);
libmsbcg729_init(f);
libmswebrtc_init(f);
linphone_core_reload_ms_plugins(theLinphoneCore, NULL);
[self migrationAllPost];
@ -1962,7 +2152,10 @@ static int comp_call_id(const LinphoneCall *call, const char *callid) {
}
- (LinphoneCall *)callByCallId:(NSString *)call_id {
const bctbx_list_t *calls = linphone_core_get_calls(LC);
const bctbx_list_t *calls = linphone_core_get_calls(theLinphoneCore);
if (!calls || !call_id) {
return NULL;
}
bctbx_list_t *call_tmp = bctbx_list_find_custom(calls, (bctbx_compare_func)comp_call_id, [call_id UTF8String]);
if (!call_tmp) {
return NULL;
@ -2047,6 +2240,59 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
[[UIApplication sharedApplication] backgroundTimeRemaining]);
}
- (void)startPushLongRunningTask:(BOOL)msg {
[[UIApplication sharedApplication] endBackgroundTask:pushBgTask];
pushBgTask = 0;
pushBgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
if (msg) {
LOGW(@"Incomming message couldn't be received");
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
content.title = NSLocalizedString(@"Message received", nil);
content.body = NSLocalizedString(@"You have received a message.", nil);
content.categoryIdentifier = @"push_msg";
UNNotificationRequest *req =
[UNNotificationRequest requestWithIdentifier:@"push_msg" content:content trigger:NULL];
[[UNUserNotificationCenter currentNotificationCenter]
addNotificationRequest:req
withCompletionHandler:^(NSError *_Nullable error) {
// Enable or disable features based on authorization.
if (error) {
LOGD(@"Error while adding notification request :");
LOGD(error.description);
}
}];
} else {
LOGW(@"Incomming call couldn't be received");
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
content.title = NSLocalizedString(@"Missed call", nil);
content.body = NSLocalizedString(@"You have missed a call.", nil);
content.categoryIdentifier = @"push_call";
UNNotificationRequest *req =
[UNNotificationRequest requestWithIdentifier:@"push_call" content:content trigger:NULL];
[[UNUserNotificationCenter currentNotificationCenter]
addNotificationRequest:req
withCompletionHandler:^(NSError *_Nullable error) {
// Enable or disable features based on authorization.
if (error) {
LOGD(@"Error while adding notification request :");
LOGD(error.description);
}
}];
}
}
for (NSString *key in [LinphoneManager.instance.pushDict allKeys]) {
[LinphoneManager.instance.pushDict setValue:[NSNumber numberWithInt:0] forKey:key];
}
[[UIApplication sharedApplication] endBackgroundTask:pushBgTask];
pushBgTask = 0;
}];
LOGI(@"Long running task started, remaining [%g s] because a push has been received",
[[UIApplication sharedApplication] backgroundTimeRemaining]);
}
- (void)enableProxyPublish:(BOOL)enabled {
if (linphone_core_get_global_state(LC) != LinphoneGlobalOn || !linphone_core_get_default_friend_list(LC)) {
LOGW(@"Not changing presence configuration because linphone core not ready yet");
@ -2072,7 +2318,9 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
linphone_core_iterate(theLinphoneCore);
}
linphone_friend_list_enable_subscriptions(linphone_core_get_default_friend_list(LC), enabled);
linphone_friend_list_enable_subscriptions(linphone_core_get_default_friend_list(LC),
enabled &&
[LinphoneManager.instance lpConfigBoolForKey:@"use_rls_presence"]);
}
- (BOOL)enterBackgroundMode {
@ -2172,6 +2420,9 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
/*IOS specific*/
linphone_core_start_dtmf_stream(theLinphoneCore);
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo
completionHandler:^(BOOL granted){
}];
/*start the video preview in case we are in the main view*/
if (linphone_core_video_display_enabled(theLinphoneCore) && [self lpConfigBoolForKey:@"preview_preference"]) {
@ -2193,22 +2444,7 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
LinphoneCall *c = linphone_core_get_current_call(theLinphoneCore);
LOGI(@"Sound interruption detected!");
if (c && linphone_call_get_state(c) == LinphoneCallStreamsRunning) {
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_9_x_Max) {
NSUUID *uuid = (NSUUID *)[LinphoneManager.instance.providerDelegate.uuids
objectForKey:[NSString
stringWithUTF8String:linphone_call_log_get_call_id(linphone_call_get_call_log(c))]];
if (!uuid) {
linphone_core_pause_call(theLinphoneCore, c);
return;
}
CXSetHeldCallAction *act = [[CXSetHeldCallAction alloc] initWithCallUUID:uuid onHold:YES];
CXTransaction *tr = [[CXTransaction alloc] initWithAction:act];
[LinphoneManager.instance.providerDelegate.controller requestTransaction:tr
completion:^(NSError *err){
}];
} else {
linphone_core_pause_call(theLinphoneCore, c);
}
linphone_call_pause(c);
}
}
@ -2273,13 +2509,12 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
return true;
bool allow = true;
CFStringRef lNewRoute = CFSTR("Unknown");
UInt32 lNewRouteSize = sizeof(lNewRoute);
OSStatus lStatus = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &lNewRouteSize, &lNewRoute);
if (!lStatus && lNewRouteSize > 0) {
NSString *route = (__bridge NSString *)lNewRoute;
allow = ![route containsSubstring:@"Heads"] && ![route isEqualToString:@"Lineout"];
CFRelease(lNewRoute);
AVAudioSessionRouteDescription *newRoute = [AVAudioSession sharedInstance].currentRoute;
if (newRoute) {
NSString *route = newRoute.outputs[0].portType;
allow = !([route isEqualToString:AVAudioSessionPortLineOut] ||
[route isEqualToString:AVAudioSessionPortHeadphones] ||
[[AudioHelper bluetoothRoutes] containsObject:route]);
}
return allow;
}
@ -2297,17 +2532,14 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
AVAudioSessionRouteChangeReasonOldDeviceUnavailable) {
_bluetoothAvailable = NO;
}
AVAudioSessionRouteDescription *newRoute = [AVAudioSession sharedInstance].currentRoute;
CFStringRef newRoute = CFSTR("Unknown");
UInt32 newRouteSize = sizeof(newRoute);
OSStatus status = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &newRouteSize, &newRoute);
if (!status && newRouteSize > 0) {
NSString *route = (__bridge NSString *)newRoute;
if (newRoute) {
NSString *route = newRoute.outputs[0].portType;
LOGI(@"Current audio route is [%s]", [route UTF8String]);
_speakerEnabled = [route isEqualToString:@"Speaker"] || [route isEqualToString:@"SpeakerAndMicrophone"];
if ([route isEqualToString:@"HeadsetBT"] && !_speakerEnabled) {
_speakerEnabled = [route isEqualToString:AVAudioSessionPortBuiltInSpeaker];
if (([[AudioHelper bluetoothRoutes] containsObject:route]) && !_speakerEnabled) {
_bluetoothAvailable = TRUE;
_bluetoothEnabled = TRUE;
} else {
@ -2318,39 +2550,23 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneBluetoothAvailabilityUpdate
object:self
userInfo:dict];
CFRelease(newRoute);
}
}
- (void)setSpeakerEnabled:(BOOL)enable {
OSStatus ret;
_speakerEnabled = enable;
UInt32 override = kAudioSessionUnspecifiedError;
NSError *err;
if (!enable && _bluetoothAvailable) {
UInt32 bluetoothInputOverride = _bluetoothEnabled;
ret = AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryEnableBluetoothInput,
sizeof(bluetoothInputOverride), &bluetoothInputOverride);
// if setting bluetooth failed, it must be because the device is not available
// anymore (disconnected), so deactivate bluetooth.
if (ret != kAudioSessionNoError) {
_bluetoothAvailable = _bluetoothEnabled = FALSE;
}
if (enable && [self allowSpeaker]) {
[[AVAudioSession sharedInstance] overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:&err];
_bluetoothEnabled = FALSE;
} else {
AVAudioSessionPortDescription *builtinPort = [AudioHelper builtinAudioDevice];
[[AVAudioSession sharedInstance] setPreferredInput:builtinPort error:&err];
}
if (override != kAudioSessionNoError) {
if (enable && [self allowSpeaker]) {
override = kAudioSessionOverrideAudioRoute_Speaker;
ret = AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(override), &override);
_bluetoothEnabled = FALSE;
} else {
override = kAudioSessionOverrideAudioRoute_None;
ret = AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(override), &override);
}
}
if (ret != kAudioSessionNoError) {
LOGE(@"Failed to change audio route: err %d", ret);
if (err) {
LOGE(@"Failed to change audio route: err %@", err.localizedDescription);
}
}
@ -2358,8 +2574,21 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
if (_bluetoothAvailable) {
// The change of route will be done in setSpeakerEnabled
_bluetoothEnabled = enable;
[self setSpeakerEnabled:!_bluetoothEnabled && _speakerEnabled];
if (_bluetoothEnabled) {
NSError *err;
AVAudioSessionPortDescription *_bluetoothPort = [AudioHelper bluetoothAudioDevice];
[[AVAudioSession sharedInstance] setPreferredInput:_bluetoothPort error:&err];
// if setting bluetooth failed, it must be because the device is not available
// anymore (disconnected), so deactivate bluetooth.
if (err) {
_bluetoothEnabled = FALSE;
} else {
_speakerEnabled = FALSE;
return;
}
}
}
[self setSpeakerEnabled:_speakerEnabled];
}
#pragma mark - Call Functions
@ -2380,10 +2609,10 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
}
linphone_call_params_enable_video(lcallParams, video);
linphone_core_accept_call_with_params(theLinphoneCore, call, lcallParams);
linphone_call_accept_with_params(call, lcallParams);
}
- (BOOL)call:(const LinphoneAddress *)iaddr {
- (void)call:(const LinphoneAddress *)iaddr {
// First verify that network is available, abort otherwise.
if (!linphone_core_is_network_reachable(theLinphoneCore)) {
UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Network Error", nil)
@ -2396,7 +2625,7 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
[errView addAction:defaultAction];
[PhoneMainView.instance presentViewController:errView animated:YES completion:nil];
return FALSE;
return;
}
// Then check that no GSM calls are in progress, abort otherwise.
@ -2413,7 +2642,7 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
[errView addAction:defaultAction];
[PhoneMainView.instance presentViewController:errView animated:YES completion:nil];
return FALSE;
return;
}
// Then check that the supplied address is valid
@ -2429,9 +2658,29 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
[errView addAction:defaultAction];
[PhoneMainView.instance presentViewController:errView animated:YES completion:nil];
return FALSE;
return;
}
if (linphone_core_get_calls_nb(theLinphoneCore) < 1 &&
floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_9_x_Max &&
self.providerDelegate.callKitCalls < 1) {
self.providerDelegate.callKitCalls++;
NSUUID *uuid = [NSUUID UUID];
[LinphoneManager.instance.providerDelegate.uuids setObject:uuid forKey:@""];
LinphoneManager.instance.providerDelegate.pendingAddr = linphone_address_clone(iaddr);
NSString *address = [FastAddressBook displayNameForAddress:iaddr];
CXHandle *handle = [[CXHandle alloc] initWithType:CXHandleTypeGeneric value:address];
CXStartCallAction *act = [[CXStartCallAction alloc] initWithCallUUID:uuid handle:handle];
CXTransaction *tr = [[CXTransaction alloc] initWithAction:act];
[LinphoneManager.instance.providerDelegate.controller requestTransaction:tr
completion:^(NSError *err){
}];
} else {
[self doCall:iaddr];
}
}
- (BOOL)doCall:(const LinphoneAddress *)iaddr {
LinphoneAddress *addr = linphone_address_clone(iaddr);
NSString *displayName = [FastAddressBook displayNameForAddress:addr];
@ -2454,7 +2703,7 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
if (LinphoneManager.instance.nextCallIsTransfer) {
char *caddr = linphone_address_as_string(addr);
call = linphone_core_get_current_call(theLinphoneCore);
linphone_core_transfer_call(theLinphoneCore, call, caddr);
linphone_call_transfer(call, caddr);
LinphoneManager.instance.nextCallIsTransfer = NO;
ms_free(caddr);
} else {
@ -2785,7 +3034,7 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
if ([ct currentCalls] != nil) {
if (call) {
LOGI(@"Pausing SIP call because GSM call");
linphone_core_pause_call(theLinphoneCore, call);
linphone_call_pause(call);
[self startCallPausedLongRunningTask];
} else if (linphone_core_is_in_conference(theLinphoneCore)) {
LOGI(@"Leaving conference call because GSM call");

View file

@ -1,12 +1,17 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9060" systemVersion="15B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="15G1217" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9051"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="UIChatBubblePhotoCell">
<connections>
<outlet property="LIMEKO" destination="IST-5o-DCu" id="Bqt-1J-cTI"/>
<outlet property="avatarImage" destination="hD2-19-7IH" id="N1B-Jn-wTo"/>
<outlet property="backgroundColorImage" destination="U2P-5n-gg8" id="1Hn-bx-mua"/>
<outlet property="bottomBarColor" destination="6dA-3U-OPW" id="xJX-pe-zlu"/>
@ -17,6 +22,8 @@
<outlet property="fileTransferProgress" destination="USm-wC-GvG" id="POt-YD-NCG"/>
<outlet property="imageGestureRecognizer" destination="aDF-hC-ddO" id="2jh-Rr-eKk"/>
<outlet property="imageSubView" destination="GmN-7v-uuO" id="k9r-Xc-csv"/>
<outlet property="imdmIcon" destination="LPj-VT-0fH" id="yYh-pv-EJs"/>
<outlet property="imdmLabel" destination="44j-me-Iqi" id="m5R-Dm-V8g"/>
<outlet property="messageImageView" destination="yMW-cT-bpU" id="MNr-F2-abQ"/>
<outlet property="resendRecognizer" destination="5ZI-Ip-lGl" id="G2r-On-6mV"/>
<outlet property="statusErrorImage" destination="ASM-vr-ei3" id="MK9-hl-6UF"/>
@ -25,23 +32,21 @@
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="UGz-WT-BUv">
<rect key="frame" x="0.0" y="0.0" width="334" height="140"/>
<view contentMode="scaleToFill" misplaced="YES" id="UGz-WT-BUv">
<rect key="frame" x="0.0" y="0.0" width="334" height="161"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<view clipsSubviews="YES" contentMode="scaleToFill" id="Y7i-Gm-AdY" userLabel="innerView">
<rect key="frame" x="6" y="5" width="322" height="130"/>
<rect key="frame" x="6" y="5" width="322" height="151"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" alpha="0.20000000298023224" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="color_A.png" id="U2P-5n-gg8" userLabel="backgroundColorImage">
<rect key="frame" x="0.0" y="0.0" width="322" height="130"/>
<rect key="frame" x="0.0" y="0.0" width="322" height="151"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<animations/>
</imageView>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" image="avatar.png" id="hD2-19-7IH" userLabel="avatarImage" customClass="UIRoundedImageView">
<rect key="frame" x="7" y="7" width="40" height="40"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<animations/>
<accessibility key="accessibilityConfiguration" label="Contact avatar">
<accessibilityTraits key="traits" image="YES" notEnabled="YES"/>
<bool key="isElement" value="YES"/>
@ -50,10 +55,9 @@
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="11:35 John Doe" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="JyR-RQ-uwF" userLabel="contactDateLabel">
<rect key="frame" x="55" y="8" width="246" height="14"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<animations/>
<accessibility key="accessibilityConfiguration" label="Contact name"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<color key="textColor" red="1" green="0.36862745099999999" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="textColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<view contentMode="scaleToFill" id="8I3-n2-0kS" userLabel="view">
@ -63,7 +67,6 @@
<imageView contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="linphone_logo.png" id="yMW-cT-bpU" userLabel="image" customClass="UILoadingImageView">
<rect key="frame" x="0.0" y="0.0" width="259" height="68"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<animations/>
<gestureRecognizers/>
<connections>
<outletCollection property="gestureRecognizers" destination="aDF-hC-ddO" appends="YES" id="7kE-0j-s1g"/>
@ -76,29 +79,26 @@
<progressView opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="750" progress="0.5" id="USm-wC-GvG" userLabel="transferProgress">
<rect key="frame" x="10" y="0.0" width="238" height="2"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<animations/>
</progressView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="N75-gL-R6t" userLabel="downloadButton" customClass="UIRoundBorderedButton">
<rect key="frame" x="66" y="4" width="124" height="27"/>
<button opaque="NO" contentMode="scaleToFill" misplaced="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="N75-gL-R6t" userLabel="downloadButton" customClass="UIRoundBorderedButton">
<rect key="frame" x="66" y="4" width="115" height="27"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<animations/>
<accessibility key="accessibilityConfiguration" label="Download"/>
<state key="normal" title="DOWNLOAD" backgroundImage="color_G.png">
<color key="titleColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
<color key="titleColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<connections>
<action selector="onDownloadClick:" destination="-1" eventType="touchUpInside" id="8BO-9E-iOX"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="6dl-Nz-rdv" userLabel="cancelButton" customClass="UIRoundBorderedButton">
<rect key="frame" x="66" y="4" width="124" height="27"/>
<button opaque="NO" contentMode="scaleToFill" misplaced="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="6dl-Nz-rdv" userLabel="cancelButton" customClass="UIRoundBorderedButton">
<rect key="frame" x="66" y="4" width="115" height="27"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<animations/>
<accessibility key="accessibilityConfiguration" label="Cancel"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<state key="normal" title="CANCEL" backgroundImage="color_I.png">
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" backgroundImage="color_M.png"/>
<connections>
@ -106,39 +106,49 @@
</connections>
</button>
</subviews>
<animations/>
</view>
</subviews>
<animations/>
</view>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="color_A.png" id="6dA-3U-OPW" userLabel="bottomBarColor">
<rect key="frame" x="0.0" y="129" width="322" height="1"/>
<rect key="frame" x="0.0" y="150" width="322" height="1"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<animations/>
</imageView>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="chat_message_not_delivered.png" id="ASM-vr-ei3" userLabel="statusErrorImage">
<rect key="frame" x="302" y="0.0" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<animations/>
<accessibility key="accessibilityConfiguration" label="Delivery failed"/>
</imageView>
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" animating="YES" style="gray" id="Eab-ND-ix3" userLabel="statusInprogressSpinner">
<rect key="frame" x="302" y="0.0" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<animations/>
</activityIndicatorView>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" image="chat_unsecure.png" id="IST-5o-DCu" userLabel="LIMEKO">
<rect key="frame" x="308" y="6" width="8" height="12"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Delivery failed"/>
</imageView>
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="Delivered" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="44j-me-Iqi" userLabel="imdmLabel">
<rect key="frame" x="240" y="134" width="64" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="11"/>
<color key="textColor" red="1" green="0.36862745099999999" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" image="valid_default.png" id="LPj-VT-0fH" userLabel="imdmIcon">
<rect key="frame" x="306" y="136" width="13" height="13"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Delivery failed"/>
</imageView>
</subviews>
<animations/>
<connections>
<outletCollection property="gestureRecognizers" destination="5ZI-Ip-lGl" appends="YES" id="1iY-46-rRR"/>
</connections>
</view>
</subviews>
<animations/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="-95" y="166"/>
<point key="canvasLocation" x="-95" y="176.5"/>
</view>
<tapGestureRecognizer id="aDF-hC-ddO" userLabel="imageClick">
<connections>
@ -152,12 +162,19 @@
</tapGestureRecognizer>
</objects>
<resources>
<image name="avatar.png" width="255" height="255"/>
<image name="chat_message_not_delivered.png" width="11" height="9"/>
<image name="avatar.png" width="259" height="259"/>
<image name="chat_message_not_delivered.png" width="11" height="10"/>
<image name="chat_unsecure.png" width="18" height="27"/>
<image name="color_A.png" width="2" height="2"/>
<image name="color_G.png" width="2" height="2"/>
<image name="color_I.png" width="2" height="2"/>
<image name="color_M.png" width="2" height="2"/>
<image name="linphone_logo.png" width="26" height="22"/>
<image name="valid_default.png" width="28" height="19"/>
</resources>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<simulatedStatusBarMetrics key="statusBar"/>
<simulatedOrientationMetrics key="orientation"/>
<simulatedScreenMetrics key="destination" type="retina4_7.fullscreen"/>
</simulatedMetricsContainer>
</document>

View file

@ -1,17 +1,24 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9060" systemVersion="15B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="15G1217" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9051"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="UIChatBubbleTextCell">
<connections>
<outlet property="LIMEKO" destination="PqI-MR-8GC" id="tHK-Bp-80H"/>
<outlet property="avatarImage" destination="P1c-sD-eOv" id="h5P-hl-jbX"/>
<outlet property="backgroundColorImage" destination="ZIO-Cb-28G" id="asA-a1-Rko"/>
<outlet property="bottomBarColor" destination="mlr-pl-B6T" id="4Lk-Vn-E8h"/>
<outlet property="bubbleView" destination="ucH-2r-rar" id="XWU-yi-1z8"/>
<outlet property="contactDateLabel" destination="GRe-ur-aSb" id="DQA-v4-IjX"/>
<outlet property="imdmIcon" destination="WlS-fU-Aut" id="bYC-jb-Amo"/>
<outlet property="imdmLabel" destination="yKD-pC-Nhu" id="ge9-Yl-qsr"/>
<outlet property="messageText" destination="CYa-If-oB4" id="7xm-UF-1qB"/>
<outlet property="resendRecognizer" destination="OA2-9R-81Z" id="zVJ-IY-3yO"/>
<outlet property="statusErrorImage" destination="nLy-JO-TyL" id="ZkB-dR-cx2"/>
@ -24,23 +31,21 @@
<action selector="onResendClick:" destination="-1" id="l6k-1D-O4U"/>
</connections>
</tapGestureRecognizer>
<view contentMode="scaleToFill" id="ucH-2r-rar">
<rect key="frame" x="0.0" y="0.0" width="334" height="60"/>
<view contentMode="scaleToFill" misplaced="YES" id="ucH-2r-rar">
<rect key="frame" x="0.0" y="0.0" width="334" height="67"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<view clipsSubviews="YES" contentMode="scaleToFill" id="vdk-RV-QRU" userLabel="innerView">
<rect key="frame" x="6" y="5" width="322" height="50"/>
<rect key="frame" x="6" y="5" width="322" height="57"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" alpha="0.20000000000000001" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="color_A.png" id="ZIO-Cb-28G" userLabel="backgroundColorImage">
<rect key="frame" x="0.0" y="0.0" width="322" height="50"/>
<rect key="frame" x="0.0" y="0.0" width="322" height="57"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<animations/>
</imageView>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" image="avatar.png" id="P1c-sD-eOv" userLabel="avatarImage" customClass="UIRoundedImageView">
<rect key="frame" x="7" y="7" width="40" height="40"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<animations/>
<accessibility key="accessibilityConfiguration" label="Contact avatar">
<accessibilityTraits key="traits" image="YES" notEnabled="YES"/>
<bool key="isElement" value="YES"/>
@ -49,52 +54,70 @@
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="11:35 John Doe" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="GRe-ur-aSb" userLabel="contactDateLabel">
<rect key="frame" x="55" y="8" width="246" height="14"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<animations/>
<accessibility key="accessibilityConfiguration" label="Contact name"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<color key="textColor" red="1" green="0.36862745099999999" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="textColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="chat_message_not_delivered.png" id="nLy-JO-TyL" userLabel="statusErrorImage">
<rect key="frame" x="302" y="0.0" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<animations/>
<accessibility key="accessibilityConfiguration" label="Delivery failed"/>
</imageView>
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" animating="YES" style="gray" id="4Z8-PE-uPe" userLabel="statusInprogressSpinner">
<rect key="frame" x="302" y="0.0" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<animations/>
</activityIndicatorView>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="color_A.png" id="mlr-pl-B6T" userLabel="bottomBarColor">
<rect key="frame" x="0.0" y="49" width="322" height="1"/>
<rect key="frame" x="0.0" y="56" width="322" height="1"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<animations/>
</imageView>
<textView clipsSubviews="YES" contentMode="scaleToFill" scrollEnabled="NO" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" editable="NO" text="Lore ipsum..." id="CYa-If-oB4" userLabel="messageText" customClass="UITextViewNoDefine">
<rect key="frame" x="50" y="15" width="279" height="54"/>
<textView clipsSubviews="YES" contentMode="scaleToFill" misplaced="YES" scrollEnabled="NO" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" editable="NO" text="Lore ipsum..." id="CYa-If-oB4" userLabel="messageText" customClass="UITextViewNoDefine">
<rect key="frame" x="50" y="15" width="279" height="50"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<animations/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
<dataDetectorType key="dataDetectorTypes" link="YES"/>
</textView>
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" image="chat_unsecure.png" id="PqI-MR-8GC" userLabel="LIMEKO">
<rect key="frame" x="308" y="4" width="8" height="12"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Delivery failed"/>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="Read" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="yKD-pC-Nhu" userLabel="imdmLabel">
<rect key="frame" x="238" y="40" width="64" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
<fontDescription key="fontDescription" name=".AppleSystemUIFont" family=".AppleSystemUIFont" pointSize="11"/>
<color key="textColor" red="1" green="0.36862745099999999" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" image="chat_read.png" id="WlS-fU-Aut" userLabel="imdmIcon">
<rect key="frame" x="306" y="42" width="13" height="13"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Delivery failed"/>
</imageView>
</subviews>
<animations/>
<connections>
<outletCollection property="gestureRecognizers" destination="OA2-9R-81Z" appends="YES" id="Phx-YZ-cwz"/>
</connections>
</view>
</subviews>
<animations/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="26" y="55.5"/>
</view>
</objects>
<resources>
<image name="avatar.png" width="255" height="255"/>
<image name="chat_message_not_delivered.png" width="11" height="9"/>
<image name="avatar.png" width="259" height="259"/>
<image name="chat_message_not_delivered.png" width="11" height="10"/>
<image name="chat_read.png" width="24" height="24"/>
<image name="chat_unsecure.png" width="18" height="27"/>
<image name="color_A.png" width="2" height="2"/>
</resources>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<simulatedStatusBarMetrics key="statusBar"/>
<simulatedOrientationMetrics key="orientation"/>
<simulatedScreenMetrics key="destination" type="retina4_7.fullscreen"/>
</simulatedMetricsContainer>
</document>

View file

@ -318,9 +318,23 @@
LinphoneMediaEncryption enc =
linphone_call_params_get_media_encryption(linphone_call_get_current_params(call));
if (enc == LinphoneMediaEncryptionZRTP) {
NSString *code = [NSString stringWithUTF8String:linphone_call_get_authentication_token(call)];
NSString *myCode;
NSString *correspondantCode;
if (linphone_call_get_dir(call) == LinphoneCallIncoming) {
myCode = [code substringToIndex:2];
correspondantCode = [code substringFromIndex:2];
} else {
correspondantCode = [code substringToIndex:2];
myCode = [code substringFromIndex:2];
}
NSString *message =
[NSString stringWithFormat:NSLocalizedString(@"Confirm the following SAS with peer:\n%s", nil),
linphone_call_get_authentication_token(call)];
[NSString stringWithFormat:NSLocalizedString(@"Confirm the following SAS with peer:\n"
@"Say : %@\n"
@"Your correspondant should say : %@",
nil),
myCode, correspondantCode];
if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground &&
floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_9_x_Max) {
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];

View file

@ -57,11 +57,10 @@ INIT_WITH_COMMON_CF {
_friend ? linphone_presence_model_get_basic_status(linphone_friend_get_presence_model(_friend))
: LinphonePresenceBasicStatusClosed;
const LinphonePresenceModel *model = _friend ? linphone_friend_get_presence_model(_friend) : NULL;
LinphonePresenceActivity *activity =
model ? linphone_presence_model_get_activity(model) ?: LinphonePresenceActivityOffline : NULL;
LinphonePresenceActivity *activity = model ? linphone_presence_model_get_activity(model):NULL;
LOGE(@"Friend %s status is now %s/%s since %@", _friend ? linphone_friend_get_name(_friend) : "NULL",
basic == LinphonePresenceBasicStatusOpen ? "open" : "closed", linphone_presence_activity_to_string(activity),
basic == LinphonePresenceBasicStatusOpen ? "open" : "closed", activity? linphone_presence_activity_to_string(activity):"Unknown",
[NSDate dateWithTimeIntervalSince1970:linphone_presence_model_get_timestamp(model)]);
NSString *imageName;

View file

@ -18,8 +18,10 @@
*/
#import "UIBluetoothButton.h"
#import <AudioToolbox/AudioToolbox.h>
#import "../Utils/AudioHelper.h"
#import "Utils.h"
#import <AVFoundation/AVAudioSession.h>
#import <AudioToolbox/AudioToolbox.h>
#include "linphone/linphonecore.h"
@ -29,29 +31,11 @@
LOGE(@"UIBluetoothButton error for %s: ret=%ld", method, au)
- (void)onOn {
// redirect audio to bluetooth
UInt32 size = sizeof(CFStringRef);
CFStringRef route = CFSTR("HeadsetBT");
OSStatus result = AudioSessionSetProperty(kAudioSessionProperty_AudioRoute, size, &route);
check_auresult(result, "set kAudioSessionProperty_AudioRoute HeadsetBT");
int allowBluetoothInput = 1;
result = AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryEnableBluetoothInput,
sizeof(allowBluetoothInput), &allowBluetoothInput);
check_auresult(result, "set kAudioSessionProperty_OverrideCategoryEnableBluetoothInput 1");
[LinphoneManager.instance setBluetoothEnabled:TRUE];
}
- (void)onOff {
// redirect audio to bluetooth
int allowBluetoothInput = 0;
OSStatus result = AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryEnableBluetoothInput,
sizeof(allowBluetoothInput), &allowBluetoothInput);
check_auresult(result, "set kAudioSessionProperty_OverrideCategoryEnableBluetoothInput 0");
UInt32 size = sizeof(CFStringRef);
CFStringRef route = CFSTR("ReceiverAndMicrophone");
result = AudioSessionSetProperty(kAudioSessionProperty_AudioRoute, size, &route);
check_auresult(result, "set kAudioSessionProperty_AudioRoute ReceiverAndMicrophone");
[LinphoneManager.instance setBluetoothEnabled:FALSE];
}
- (bool)onUpdate {

View file

@ -36,6 +36,9 @@
@property(nonatomic, strong) id<ChatConversationDelegate> chatRoomDelegate;
@property(strong, nonatomic) IBOutlet UIView *bubbleView;
@property(strong, nonatomic) IBOutlet UITapGestureRecognizer *resendRecognizer;
@property(weak, nonatomic) IBOutlet UIImageView *LIMEKO;
@property(weak, nonatomic) IBOutlet UIImageView *imdmIcon;
@property(weak, nonatomic) IBOutlet UILabel *imdmLabel;
+ (CGSize)ViewSizeForMessage:(LinphoneChatMessage *)chat withWidth:(int)width;
@ -45,6 +48,7 @@
- (IBAction)onResendClick:(id)event;
- (void)update;
- (void)displayImdmStatus:(LinphoneChatMessageState)state;
+ (CGSize)ViewHeightForMessage:(LinphoneChatMessage *)chat withWidth:(int)width;
+ (NSString *)TextMessageForChat:(LinphoneChatMessage *)message;
+ (CGSize)computeBoundingBox:(NSString *)text size:(CGSize)size font:(UIFont *)font;

View file

@ -138,15 +138,6 @@
if (outgoing && state == LinphoneChatMessageStateInProgress) {
_statusErrorImage.hidden = YES;
[_statusInProgressSpinner startAnimating];
} else if (outgoing &&
(state == LinphoneChatMessageStateNotDelivered || state == LinphoneChatMessageStateFileTransferError)) {
_statusErrorImage.hidden = NO;
[_statusInProgressSpinner stopAnimating];
NSAttributedString *resend_text =
[[NSAttributedString alloc] initWithString:NSLocalizedString(@"Resend", @"Resend")
attributes:@{NSForegroundColorAttributeName : [UIColor redColor]}];
[_contactDateLabel setAttributedText:resend_text];
} else if (!outgoing && state == LinphoneChatMessageStateFileTransferError) {
_statusErrorImage.hidden = NO;
[_statusInProgressSpinner stopAnimating];
@ -159,6 +150,24 @@
[_messageText setAccessibilityLabel:@"Outgoing message"];
} else {
[_messageText setAccessibilityLabel:@"Incoming message"];
if (!([UIApplication sharedApplication].applicationState != UIApplicationStateBackground ||
[UIApplication sharedApplication].applicationState != UIApplicationStateInactive)) {
VIEW(ChatConversationView).markAsRead;
}
}
if (outgoing &&
(state == LinphoneChatMessageStateDeliveredToUser || state == LinphoneChatMessageStateDisplayed ||
state == LinphoneChatMessageStateNotDelivered || state == LinphoneChatMessageStateFileTransferError)) {
[self displayImdmStatus:state];
} else
[self displayImdmStatus:LinphoneChatMessageStateInProgress];
if (!outgoing && !linphone_chat_message_is_secured(_message) &&
linphone_core_lime_enabled(LC) == LinphoneLimeMandatory) {
_LIMEKO.hidden = FALSE;
} else {
_LIMEKO.hidden = TRUE;
}
}
@ -171,6 +180,21 @@
_resendRecognizer.enabled = !editing;
}
- (void)displayLIMEWarning {
UIAlertController *errView =
[UIAlertController alertControllerWithTitle:NSLocalizedString(@"LIME warning", nil)
message:NSLocalizedString(@"This message is not encrypted.", nil)
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action){
}];
[errView addAction:defaultAction];
[PhoneMainView.instance presentViewController:errView animated:YES completion:nil];
}
#pragma mark - Action Functions
- (IBAction)onDeleteClick:(id)event {
@ -184,6 +208,11 @@
}
- (IBAction)onResendClick:(id)event {
if (!_LIMEKO.hidden) {
[self displayLIMEWarning];
return;
}
if (_message == nil || !linphone_chat_message_is_outgoing(_message))
return;
@ -224,6 +253,33 @@ static void message_status(LinphoneChatMessage *msg, LinphoneChatMessageState st
[view.tableController updateChatEntry:msg];
}
- (void)displayImdmStatus:(LinphoneChatMessageState)state {
if (state == LinphoneChatMessageStateDeliveredToUser) {
[_imdmIcon setImage:[UIImage imageNamed:@"chat_delivered"]];
[_imdmLabel setText:NSLocalizedString(@"Delivered", nil)];
[_imdmLabel setTextColor:[UIColor grayColor]];
[_imdmIcon setHidden:FALSE];
[_imdmLabel setHidden:FALSE];
} else if (state == LinphoneChatMessageStateDisplayed) {
[_imdmIcon setImage:[UIImage imageNamed:@"chat_read"]];
[_imdmLabel setText:NSLocalizedString(@"Displayed", nil)];
[_imdmLabel
setTextColor:([UIColor colorWithRed:(24 / 255.0) green:(167 / 255.0) blue:(175 / 255.0) alpha:1.0])];
[_imdmIcon setHidden:FALSE];
[_imdmLabel setHidden:FALSE];
} else if (state == LinphoneChatMessageStateNotDelivered || state == LinphoneChatMessageStateFileTransferError) {
[_imdmIcon setImage:[UIImage imageNamed:@"chat_error"]];
[_imdmLabel setText:NSLocalizedString(@"Resend", nil)];
[_imdmLabel setTextColor:[UIColor redColor]];
[_imdmIcon setHidden:FALSE];
[_imdmLabel setHidden:FALSE];
} else {
[_imdmIcon setHidden:TRUE];
[_imdmLabel setHidden:TRUE];
}
}
#pragma mark - Bubble size computing
+ (CGSize)computeBoundingBox:(NSString *)text size:(CGSize)size font:(UIFont *)font {
@ -248,9 +304,9 @@ static void message_status(LinphoneChatMessage *msg, LinphoneChatMessageState st
}
static const CGFloat CELL_MIN_HEIGHT = 60.0f;
static const CGFloat CELL_MIN_WIDTH = 150.0f;
static const CGFloat CELL_MIN_WIDTH = 190.0f;
static const CGFloat CELL_MESSAGE_X_MARGIN = 78 + 10.0f;
static const CGFloat CELL_MESSAGE_Y_MARGIN = 44;
static const CGFloat CELL_MESSAGE_Y_MARGIN = 52; // 44;
static const CGFloat CELL_IMAGE_HEIGHT = 100.0f;
static const CGFloat CELL_IMAGE_WIDTH = 100.0f;

View file

@ -97,11 +97,11 @@
LinphoneManager.instance.conf = TRUE;
linphone_core_terminate_conference(LC);
} else if (currentcall != NULL) {
linphone_core_terminate_call(LC, currentcall);
linphone_call_terminate(currentcall);
} else {
const MSList *calls = linphone_core_get_calls(LC);
if (bctbx_list_size(calls) == 1) { // Only one call
linphone_core_terminate_call(LC, (LinphoneCall *)(calls->data));
linphone_call_terminate((LinphoneCall *)(calls->data));
}
}
}

View file

@ -82,22 +82,7 @@
switch (type) {
case UIPauseButtonType_Call: {
if (call != nil) {
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_9_x_Max) {
NSUUID *uuid = (NSUUID *)[LinphoneManager.instance.providerDelegate.uuids
objectForKey:[NSString stringWithUTF8String:linphone_call_log_get_call_id(
linphone_call_get_call_log(call))]];
if (!uuid) {
linphone_core_pause_call(LC, call);
return;
}
CXSetHeldCallAction *act = [[CXSetHeldCallAction alloc] initWithCallUUID:uuid onHold:YES];
CXTransaction *tr = [[CXTransaction alloc] initWithAction:act];
[LinphoneManager.instance.providerDelegate.controller requestTransaction:tr
completion:^(NSError *err){
}];
} else {
linphone_core_pause_call(LC, call);
}
linphone_call_pause(call);
} else {
LOGW(@"Cannot toggle pause buttton, because no current call");
}
@ -113,22 +98,7 @@
case UIPauseButtonType_CurrentCall: {
LinphoneCall *currentCall = [UIPauseButton getCall];
if (currentCall != nil) {
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_9_x_Max) {
NSUUID *uuid = (NSUUID *)[LinphoneManager.instance.providerDelegate.uuids
objectForKey:[NSString stringWithUTF8String:linphone_call_log_get_call_id(
linphone_call_get_call_log(currentCall))]];
if (!uuid) {
linphone_core_pause_call(LC, currentCall);
return;
}
CXSetHeldCallAction *act = [[CXSetHeldCallAction alloc] initWithCallUUID:uuid onHold:YES];
CXTransaction *tr = [[CXTransaction alloc] initWithAction:act];
[LinphoneManager.instance.providerDelegate.controller requestTransaction:tr
completion:^(NSError *err){
}];
} else {
linphone_core_pause_call(LC, currentCall);
}
linphone_call_pause(currentCall);
} else {
LOGW(@"Cannot toggle pause buttton, because no current call");
}
@ -141,22 +111,7 @@
switch (type) {
case UIPauseButtonType_Call: {
if (call != nil) {
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_9_x_Max) {
NSUUID *uuid = (NSUUID *)[LinphoneManager.instance.providerDelegate.uuids
objectForKey:[NSString stringWithUTF8String:linphone_call_log_get_call_id(
linphone_call_get_call_log(call))]];
if (!uuid) {
linphone_core_resume_call(LC, call);
return;
}
CXSetHeldCallAction *act = [[CXSetHeldCallAction alloc] initWithCallUUID:uuid onHold:NO];
CXTransaction *tr = [[CXTransaction alloc] initWithAction:act];
[LinphoneManager.instance.providerDelegate.controller requestTransaction:tr
completion:^(NSError *err){
}];
} else {
linphone_core_resume_call(LC, call);
}
linphone_call_resume(call);
} else {
LOGW(@"Cannot toggle pause buttton, because no current call");
}
@ -164,11 +119,9 @@
}
case UIPauseButtonType_Conference: {
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_9_x_Max) {
NSUUID *uuid = (NSUUID *)[LinphoneManager.instance.providerDelegate.uuids allValues].firstObject;
NSString *key = (NSString *)[LinphoneManager.instance.providerDelegate.uuids allKeys][0];
NSUUID *uuid = (NSUUID *)[LinphoneManager.instance.providerDelegate.uuids objectForKey:key];
if (!uuid) {
linphone_core_enter_conference(LC);
// Fake event
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneCallUpdate object:self];
return;
}
CXSetHeldCallAction *act = [[CXSetHeldCallAction alloc] initWithCallUUID:uuid onHold:NO];
@ -176,31 +129,15 @@
[LinphoneManager.instance.providerDelegate.controller requestTransaction:tr
completion:^(NSError *err){
}];
} else {
linphone_core_enter_conference(LC);
// Fake event
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneCallUpdate object:self];
}
linphone_core_enter_conference(LC);
// Fake event
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneCallUpdate object:self];
break;
}
case UIPauseButtonType_CurrentCall: {
LinphoneCall *currentCall = [UIPauseButton getCall];
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_9_x_Max) {
NSUUID *uuid = (NSUUID *)[LinphoneManager.instance.providerDelegate.uuids
objectForKey:[NSString stringWithUTF8String:linphone_call_log_get_call_id(
linphone_call_get_call_log(currentCall))]];
if (!uuid) {
linphone_core_resume_call(LC, currentCall);
return;
}
CXSetHeldCallAction *act = [[CXSetHeldCallAction alloc] initWithCallUUID:uuid onHold:NO];
CXTransaction *tr = [[CXTransaction alloc] initWithAction:act];
[LinphoneManager.instance.providerDelegate.controller requestTransaction:tr
completion:^(NSError *err){
}];
} else {
linphone_core_resume_call(LC, currentCall);
}
linphone_call_resume(currentCall);
break;
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show more