diff --git a/Classes/CallDelegate.h b/Classes/CallDelegate.h index 02b69b026..516c2074d 100644 --- a/Classes/CallDelegate.h +++ b/Classes/CallDelegate.h @@ -1,27 +1,48 @@ -// -// CallDelegate.h -// linphone -// -// Created by Pierre-Eric Pelloux-Prayer on 03/11/11. -// Copyright (c) 2011 __MyCompanyName__. All rights reserved. -// +/* LinphoneManager.h + * + * Copyright (C) 2011 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ #import #include "linphonecore.h" +enum CallDelegateType { + CD_UNDEFINED = 0, + CD_NEW_CALL, + CD_ZRTP, + CD_VIDEO_UPDATE, + CD_STOP_VIDEO_ON_LOW_BATTERY, + CD_TRANSFER_CALL +}; @protocol UIActionSheetCustomDelegate -- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex withUserDatas:(void*) datas; +- (void)actionSheet:(UIActionSheet *)actionSheet ofType:(enum CallDelegateType) type clickedButtonAtIndex:(NSInteger)buttonIndex withUserDatas:(void*) datas; @end - @interface CallDelegate : NSObject { - + enum CallDelegateType eventType; LinphoneCall* call; id delegate; + NSTimer* timeout; } +@property (nonatomic) enum CallDelegateType eventType; @property (nonatomic) LinphoneCall* call; @property (nonatomic, retain) id delegate; +@property (nonatomic, retain) NSTimer* timeout; @end diff --git a/Classes/CallDelegate.m b/Classes/CallDelegate.m index 6ae87a25c..4aef98fa9 100644 --- a/Classes/CallDelegate.m +++ b/Classes/CallDelegate.m @@ -1,20 +1,62 @@ -// -// CallDelegate.m -// linphone -// -// Created by Pierre-Eric Pelloux-Prayer on 03/11/11. -// Copyright (c) 2011 __MyCompanyName__. All rights reserved. -// +/* LinphoneManager.h + * + * Copyright (C) 2011 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ #import "CallDelegate.h" @implementation CallDelegate +@synthesize eventType; @synthesize call; @synthesize delegate; +@synthesize timeout; -(void) actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex { - [delegate actionSheet:actionSheet clickedButtonAtIndex:buttonIndex withUserDatas:call]; + if (timeout) { + [timeout invalidate]; + timeout = nil; + } + if (eventType == CD_UNDEFINED) { + ms_error("Incorrect usage of CallDelegate/ActionSheet: eventType must be set"); + } + [delegate actionSheet:actionSheet ofType:eventType clickedButtonAtIndex:buttonIndex withUserDatas:call]; +} + +-(void) actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex { + if (timeout) { + [timeout invalidate]; + timeout = nil; + } + if (eventType == CD_UNDEFINED) { + ms_error("Incorrect usage of CallDelegate/ActionSheet: eventType must be set"); + } + [delegate actionSheet:actionSheet ofType:eventType clickedButtonAtIndex:buttonIndex withUserDatas:call]; +} + +-(void) actionSheetCancel:(UIActionSheet *)actionSheet { + if (timeout) { + [timeout invalidate]; + timeout = nil; + } + if (eventType == CD_UNDEFINED) { + ms_error("Incorrect usage of CallDelegate/ActionSheet: eventType must be set"); + } + [delegate actionSheet:actionSheet ofType:eventType clickedButtonAtIndex:actionSheet.cancelButtonIndex withUserDatas:call]; } @end diff --git a/Classes/CallHistoryTableViewController.m b/Classes/CallHistoryTableViewController.m index 60d438d9b..72633984f 100644 --- a/Classes/CallHistoryTableViewController.m +++ b/Classes/CallHistoryTableViewController.m @@ -116,7 +116,8 @@ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease]; - + [cell.textLabel setTextColor:[UIColor colorWithRed:0.7 green:0.745 blue:0.78 alpha:1.0]]; + [cell.detailTextLabel setTextColor:cell.textLabel.textColor]; } // Set up the cell... @@ -127,7 +128,7 @@ NSString *path; if (callLogs->dir == LinphoneCallIncoming) { if (callLogs->status == LinphoneCallSuccess) { - path = [[NSBundle mainBundle] pathForResource:@"in_call" ofType:@"png"]; + path = [[NSBundle mainBundle] pathForResource:callLogs->video_enabled?@"in_call_video":@"in_call" ofType:@"png"]; } else { //missed call path = [[NSBundle mainBundle] pathForResource:@"missed_call" ofType:@"png"]; @@ -135,7 +136,7 @@ partyToDisplay=callLogs->from; } else { - path = [[NSBundle mainBundle] pathForResource:@"out_call" ofType:@"png"]; + path = [[NSBundle mainBundle] pathForResource:callLogs->video_enabled?@"out_call_video":@"out_call" ofType:@"png"]; partyToDisplay=callLogs->to; } @@ -147,12 +148,12 @@ const char* displayName = linphone_address_get_display_name(partyToDisplay); if (displayName) { - NSString* str1 = [NSString stringWithCString:displayName encoding:[NSString defaultCStringEncoding]]; + NSString* str1 = [NSString stringWithFormat:@"%s", displayName]; [cell.textLabel setText:str1]; NSString* str2 = [NSString stringWithFormat:@"%s"/* [%s]"*/,username/*,callLogs->start_date*/]; [cell.detailTextLabel setText:str2]; } else { - NSString* str1 = [NSString stringWithCString:username encoding:[NSString defaultCStringEncoding]]; + NSString* str1 = [NSString stringWithFormat:@"%s", username]; [cell.textLabel setText:str1]; [cell.detailTextLabel setText:nil]; } diff --git a/Classes/ConferenceCallDetailView.m b/Classes/ConferenceCallDetailView.m index ed6ebafea..231fcb4ce 100644 --- a/Classes/ConferenceCallDetailView.m +++ b/Classes/ConferenceCallDetailView.m @@ -88,9 +88,11 @@ NSTimer *callQualityRefresher; [mute reset]; [speaker reset]; [[UIApplication sharedApplication] setIdleTimerDisabled:YES]; + [super viewWillAppear:animated]; } -(void) viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; callQualityRefresher = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(updateCallQuality) @@ -148,21 +150,7 @@ NSTimer *callQualityRefresher; } } UIImageView* callquality = (UIImageView*) [cell viewWithTag:3]; - if (linphone_call_get_average_quality(call) >= 4) { - [callquality setImage: [IncallViewController stat_sys_signal_4]]; - } - else if (linphone_call_get_average_quality(call) >= 3) { - [callquality setImage: [IncallViewController stat_sys_signal_3]]; - } - else if (linphone_call_get_average_quality(call) >= 2) { - [callquality setImage: [IncallViewController stat_sys_signal_2]]; - } - else if (linphone_call_get_average_quality(call) >= 1) { - [callquality setImage: [IncallViewController stat_sys_signal_1]]; - } - else { - [callquality setImage: [IncallViewController stat_sys_signal_0]]; - } + [IncallViewController updateIndicator:callquality withCallQuality:linphone_call_get_average_quality(call)]; tableView.rowHeight = 80; return cell; diff --git a/Classes/ConsoleViewController.m b/Classes/ConsoleViewController.m index c2ee28379..246ced0eb 100644 --- a/Classes/ConsoleViewController.m +++ b/Classes/ConsoleViewController.m @@ -58,6 +58,7 @@ NSMutableString* MoreViewController_logs; */ -(void) viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; [logs setText:MoreViewController_logs]; } diff --git a/Classes/InCallViewController-ipad.xib b/Classes/InCallViewController-ipad.xib index 17661327c..51b1dfa66 100644 --- a/Classes/InCallViewController-ipad.xib +++ b/Classes/InCallViewController-ipad.xib @@ -11,11 +11,13 @@ 933 - IBUIViewController IBUIButton - IBUIView - IBUITableView + IBUIImageView + IBUIViewController IBProxyObject + IBUIActivityIndicatorView + IBUITableView + IBUIView com.apple.InterfaceBuilder.IBCocoaTouchPlugin @@ -38,6 +40,114 @@ 274 + + + 274 + + + + 292 + {768, 1024} + + + + _NS:569 + NO + IBIPadFramework + + + + 292 + {{20, 956}, {28, 28}} + + + + _NS:567 + NO + IBIPadFramework + + + + 292 + {{366, 493}, {37, 37}} + + + + _NS:1062 + NO + IBIPadFramework + NO + 0 + + + + 292 + {{598, 799}, {170, 225}} + + + + + 3 + MQA + + 2 + + + IBIPadFramework + + + {768, 1024} + + + + _NS:212 + + 3 + MC42NjY2NjY2NjY3AA + + IBIPadFramework + + + + 292 + {{224, 740}, {320, 66}} + + + + NO + IBIPadFramework + 0 + 0 + 1 + Change camera + + 3 + MQA + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + 3 + MC41AA + + + NSImage + clavier-01-108px.png + + + Helvetica-Bold + Helvetica + 2 + 15 + + + Helvetica-Bold + 15 + 16 + + 274 @@ -49,9 +159,7 @@ 3 MSAwAA - - 2 - + YES IBIPadFramework @@ -82,18 +190,12 @@ IBIPadFramework 0 0 - - 3 - MQA - + 1 MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA - - 3 - MC41AA - + NSImage stopcall-red.png @@ -102,17 +204,8 @@ NSImage clavier-01-106px.png - - Helvetica-Bold - Helvetica - 2 - 15 - - - Helvetica-Bold - 15 - 16 - + + {{224, 937}, {320, 77}} @@ -133,7 +226,7 @@ 292 - {{107, 70}, {106, 66}} + {{80, 70}, {80, 66}} @@ -207,7 +300,7 @@ 292 - {{0, 70}, {107, 66}} + {{0, 70}, {80, 66}} @@ -233,7 +326,7 @@ 292 - {{213, 70}, {107, 66}} + {{240, 70}, {80, 66}} @@ -262,10 +355,10 @@ -2147483356 - {{213, 70}, {107, 66}} + {{240, 70}, {80, 66}} - + NO NO @@ -280,13 +373,50 @@ MC4xOTYwNzg0MzE0IDAuMzA5ODAzOTIxNiAwLjUyMTU2ODYyNzUAA - + NSImage clavier-01-160px.png + + + 292 + {{160, 70}, {80, 66}} + + + + + NO + NO + IBIPadFramework + 0 + 0 + transfer + + + 1 + MC4xOTYwNzg0MzE0IDAuMzA5ODAzOTIxNiAwLjUyMTU2ODYyNzUAA + + + + + + + + + 292 + {{262, 84}, {37, 37}} + + + + _NS:1062 + NO + IBIPadFramework + NO + 0 + 292 @@ -347,10 +477,10 @@ 292 - {{107, 70}, {106, 66}} + {{80, 70}, {80, 66}} - + NO NO @@ -396,7 +526,7 @@ {{119, 251}, {82, 52}} - + NO NO @@ -411,7 +541,7 @@ - + @@ -420,10 +550,7 @@ - - 3 - MC42NjY2NjY2NjY3AA - + NO NO IBIPadFramework @@ -437,7 +564,7 @@ - + @@ -460,7 +587,7 @@ - + @@ -480,7 +607,7 @@ - + @@ -503,7 +630,7 @@ - + @@ -526,7 +653,7 @@ - + @@ -549,7 +676,7 @@ - + @@ -572,7 +699,7 @@ - + @@ -595,7 +722,7 @@ - + @@ -618,7 +745,7 @@ - + @@ -641,7 +768,7 @@ - + @@ -664,7 +791,7 @@ - + @@ -687,7 +814,7 @@ - + {{178, 146}, {320, 310}} @@ -706,7 +833,7 @@ {{0, 20}, {768, 1004}} - + _NS:212 IBIPadFramework @@ -726,51 +853,11 @@ - addCall + callTableView - + - 112 - - - - addVideo - - - - 113 - - - - close - - - - 115 - - - - contacts - - - - 116 - - - - controlSubView - - - - 117 - - - - eight - - - - 118 + 114 @@ -780,22 +867,6 @@ 119 - - - five - - - - 120 - - - - four - - - - 121 - hangUpView @@ -806,19 +877,11 @@ - hash + speaker - + - 123 - - - - mergeCalls - - - - 124 + 132 @@ -830,27 +893,43 @@ - nine + addVideo - + - 126 + 113 - one + mergeCalls - + - 127 + 124 - padSubView + addCall - + - 128 + 112 + + + + contacts + + + + 116 + + + + dialer + + + + 141 @@ -860,6 +939,30 @@ 129 + + + controlSubView + + + + 117 + + + + five + + + + 120 + + + + nine + + + + 126 + seven @@ -878,19 +981,11 @@ - speaker + four - + - 132 - - - - star - - - - 133 + 121 @@ -900,6 +995,14 @@ 134 + + + zero + + + + 137 + two @@ -908,6 +1011,54 @@ 135 + + + close + + + + 115 + + + + hash + + + + 123 + + + + eight + + + + 118 + + + + one + + + + 127 + + + + star + + + + 133 + + + + padSubView + + + + 128 + view @@ -918,27 +1069,67 @@ - zero + videoGroup - + - 137 + 159 - callTableView + videoView - + - 114 + 161 - dialer + videoPreview - + - 141 + 162 + + + + videoCallQuality + + + + 163 + + + + videoCameraSwitch + + + + 164 + + + + videoUpdateIndicator + + + + 167 + + + + videoWaitingForFirstImage + + + + 168 + + + + transfer + + + + 170 @@ -1018,10 +1209,31 @@ + + + + 61 + + + + + 88 + + + + + + + + 98 + + + end + 89 @@ -1031,55 +1243,27 @@ - + + + controls - - 97 - - - pauseresume - 96 speaker - - 95 - - - dialer - - - 94 - - - contacts - - - 93 - - - addcall - 92 mute - - 91 - - - merge - 90 @@ -1087,12 +1271,34 @@ video - 88 - - - - - + 91 + + + merge + + + 93 + + + addcall + + + 94 + + + contacts + + + 95 + + + dialer + + + 97 + + + pauseresume 87 @@ -1116,70 +1322,10 @@ pad - 111 - + 99 + - star - - - 110 - - - 1 - - - 109 - - - 8 - - - 108 - - - hash - - - 107 - - - close - - - 106 - - - 2 - - - 105 - - - 0 - - - 104 - - - 3 - - - 103 - - - 4 - - - 102 - - - 6 - - - 101 - - - 7 + 5 100 @@ -1188,21 +1334,123 @@ 9 - 99 - + 101 + - 5 + 7 - 98 - - - end + 102 + + + 6 - 61 - + 103 + + + 4 + + + 104 + + + 3 + + + 105 + + + 0 + + + 106 + + + 2 + + + 107 + + + close + + + 108 + + + hash + + + 109 + + + 8 + + + 110 + + + 1 + + + 111 + + + star + + + 152 + + + + + + + + video + + + 158 + + + + video_preview + + + 157 + + + video_view + + + 153 + + + call_quality_video + + + 154 + + + + + 165 + + + toggleVideoIndicator + + + 166 + + + + + 169 + + + transfer @@ -1235,13 +1483,22 @@ com.apple.InterfaceBuilder.IBCocoaTouchPlugin UIDigitButton com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + UICamSwitch + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIAddVideoButton + UIToggleVideoButton com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin @@ -1266,7 +1523,7 @@ - 144 + 170 @@ -1286,7 +1543,7 @@ UIButton - UIButton + UIToggleVideoButton UITableView UIButton UIViewController @@ -1310,8 +1567,16 @@ UIButton UIButton UIButton + UIButton UIButton + UIImageView + UICamSwitch + UIView + UIView + UIActivityIndicatorView + UIView VideoViewController + UIActivityIndicatorView UIButton @@ -1321,7 +1586,7 @@ addVideo - UIButton + UIToggleVideoButton callTableView @@ -1415,14 +1680,46 @@ three UIButton + + transfer + UIButton + two UIButton + + videoCallQuality + UIImageView + + + videoCameraSwitch + UICamSwitch + + + videoGroup + UIView + + + videoPreview + UIView + + + videoUpdateIndicator + UIActivityIndicatorView + + + videoView + UIView + videoViewController VideoViewController + + videoWaitingForFirstImage + UIActivityIndicatorView + zero UIButton @@ -1433,14 +1730,6 @@ ./Classes/IncallViewController.h - - UIAddVideoButton - UIButton - - IBProjectSource - ./Classes/UIAddVideoButton.h - - UICamSwitch UIButton @@ -1500,6 +1789,25 @@ ./Classes/UIToggleButton.h + + UIToggleVideoButton + UIButton + + videoUpdateIndicator + UIActivityIndicatorView + + + videoUpdateIndicator + + videoUpdateIndicator + UIActivityIndicatorView + + + + IBProjectSource + ./Classes/UIToggleVideoButton.h + + VideoViewController UIViewController @@ -1628,6 +1936,7 @@ {107, 67} {107, 67} {106, 60} + {108, 60} {160, 60} {106, 67} {107, 67} diff --git a/Classes/IncallViewController.h b/Classes/IncallViewController.h index a17617aa6..0d7340568 100644 --- a/Classes/IncallViewController.h +++ b/Classes/IncallViewController.h @@ -22,7 +22,8 @@ #import "ConferenceCallDetailView.h" #import #include "UILinphone.h" - +#import "UIToggleVideoButton.h" +#import "VideoZoomHandler.h" @class VideoViewController; @interface IncallViewController : UIViewController { @@ -36,9 +37,10 @@ UIButton* pause; UISpeakerButton* speaker; UIButton* contacts; - UIButton* addVideo; + UIToggleVideoButton* addVideo; UITableView* callTableView; UIButton* addCall, *mergeCalls; + UIButton* transfer; //key pad @@ -58,6 +60,14 @@ UIDigitButton* hash; UIButton* close; + UIView* videoGroup; + UIView* videoView; + UIView* videoPreview; + UIImageView* videoCallQuality; + UICamSwitch* videoCameraSwitch; + UIActivityIndicatorView* videoUpdateIndicator; + UIActivityIndicatorView* videoWaitingForFirstImage; + bool dismissed; NSTimer *durationRefreasher; @@ -78,14 +88,11 @@ UIImage* verified, *unverified; UIImage* stat_sys_signal_0, *stat_sys_signal_1, *stat_sys_signal_2, *stat_sys_signal_3, *stat_sys_signal_4; - UIActionSheet* zrtpVerificationSheet; -} + UIActionSheet* visibleActionSheet; -+ (UIImage*) stat_sys_signal_0; -+ (UIImage*) stat_sys_signal_1; -+ (UIImage*) stat_sys_signal_2; -+ (UIImage*) stat_sys_signal_3; -+ (UIImage*) stat_sys_signal_4; + NSTimer* hideControlsTimer; + VideoZoomHandler* videoZoomHandler; +} -(void)displayStatus:(NSString*) message; @@ -93,6 +100,7 @@ +(LinphoneCall*) retrieveCallAtIndex: (NSInteger) index inConference:(bool) conf; + (void) updateCellImageView:(UIImageView*)imageView Label:(UILabel*)label DetailLabel:(UILabel*)detailLabel AndAccessoryView:(UIView*)accessoryView withCall:(LinphoneCall*) call; ++(void) updateIndicator:(UIImageView*) indicator withCallQuality:(float) quality; @property (nonatomic, retain) IBOutlet UIView* controlSubView; @property (nonatomic, retain) IBOutlet UIView* padSubView; @@ -105,10 +113,11 @@ @property (nonatomic, retain) IBOutlet UIButton* pause; @property (nonatomic, retain) IBOutlet UIButton* speaker; @property (nonatomic, retain) IBOutlet UIButton* contacts; -@property (nonatomic, retain) IBOutlet UIButton* addVideo; +@property (nonatomic, retain) IBOutlet UIToggleVideoButton* addVideo; @property (nonatomic, retain) IBOutlet UITableView* callTableView; @property (nonatomic, retain) IBOutlet UIButton* addCall; @property (nonatomic, retain) IBOutlet UIButton* mergeCalls; +@property (nonatomic, retain) IBOutlet UIButton* transfer; @property (nonatomic, retain) IBOutlet UIButton* one; @property (nonatomic, retain) IBOutlet UIButton* two; @@ -124,4 +133,13 @@ @property (nonatomic, retain) IBOutlet UIButton* hash; @property (nonatomic, retain) IBOutlet UIButton* close; @property (nonatomic, retain) IBOutlet VideoViewController* videoViewController; + +@property (nonatomic, retain) IBOutlet UIView* videoGroup; +@property (nonatomic, retain) IBOutlet UIView* videoView; +@property (nonatomic, retain) IBOutlet UIView* videoPreview; +@property (nonatomic, retain) IBOutlet UIImageView* videoCallQuality; +@property (nonatomic, retain) IBOutlet UICamSwitch* videoCameraSwitch; +@property (nonatomic, retain) IBOutlet UIActivityIndicatorView* videoUpdateIndicator; +@property (nonatomic, retain) IBOutlet UIActivityIndicatorView* videoWaitingForFirstImage; + @end diff --git a/Classes/IncallViewController.m b/Classes/IncallViewController.m index b0bdf7cf7..588b289c5 100644 --- a/Classes/IncallViewController.m +++ b/Classes/IncallViewController.m @@ -24,6 +24,10 @@ #include "LinphoneManager.h" #include "private.h" #import "ContactPickerDelegate.h" +#import +#import +#import +#import #define STRINGIFY(x) #x #define TOSTRING(x) STRINGIFY(x) @@ -48,6 +52,7 @@ const NSInteger SECURE_BUTTON_TAG=5; @synthesize callTableView; @synthesize addCall; @synthesize mergeCalls; +@synthesize transfer; @synthesize one; @synthesize two; @@ -63,27 +68,29 @@ const NSInteger SECURE_BUTTON_TAG=5; @synthesize hash; @synthesize videoViewController; +@synthesize videoGroup; +@synthesize videoView; +@synthesize videoPreview; +@synthesize videoCallQuality; +@synthesize videoCameraSwitch; +@synthesize videoUpdateIndicator; +@synthesize videoWaitingForFirstImage; + @synthesize addVideo; -+ (UIImage*) stat_sys_signal_0 { - return [UIImage imageNamed:@"stat_sys_signal_0.png"]; -} - -+ (UIImage*) stat_sys_signal_1 { - return [UIImage imageNamed:@"stat_sys_signal_1.png"]; -} - -+ (UIImage*) stat_sys_signal_2 { - return [UIImage imageNamed:@"stat_sys_signal_2.png"]; -} - -+ (UIImage*) stat_sys_signal_3 { - return [UIImage imageNamed:@"stat_sys_signal_3.png"]; -} - -+ (UIImage*) stat_sys_signal_4 { - return [UIImage imageNamed:@"stat_sys_signal_4.png"]; ++(void) updateIndicator:(UIImageView*) indicator withCallQuality:(float) quality { + if (quality >= 4 || quality < 0) { + [indicator setImage:[UIImage imageNamed:@"stat_sys_signal_4.png"]]; + } else if (quality >= 3) { + [indicator setImage:[UIImage imageNamed:@"stat_sys_signal_3.png"]]; + } else if (quality >= 2) { + [indicator setImage:[UIImage imageNamed:@"stat_sys_signal_2.png"]]; + } else if (quality >= 1) { + [indicator setImage:[UIImage imageNamed:@"stat_sys_signal_1.png"]]; + } else { + [indicator setImage:[UIImage imageNamed:@"stat_sys_signal_0.png"]]; + } } bool isInConference(LinphoneCall* call) { @@ -105,26 +112,219 @@ int callCount(LinphoneCore* lc) { return count; } --(void) updateUIFromLinphoneState:(UIViewController *)viewCtrl { + + +void addAnimationFadeTransition(UIView* view, float duration) { + CATransition* animation = [CATransition animation]; + animation.type = kCATransitionFromBottom; // kCATransitionFade; + animation.duration = duration; + [view.layer addAnimation:animation forKey:nil]; +} + +-(void) orientationChanged: (NSNotification*) notif { + int oldLinphoneOrientation = linphone_core_get_device_rotation([LinphoneManager getLc]); + UIDeviceOrientation orientation = [UIDevice currentDevice].orientation; + int newRotation = 0; + switch (orientation) { + case UIInterfaceOrientationLandscapeRight: + newRotation = 270; + break; + case UIInterfaceOrientationLandscapeLeft: + newRotation = 90; + break; + default: + newRotation = 0; + } + if (oldLinphoneOrientation != newRotation) { + linphone_core_set_device_rotation([LinphoneManager getLc], newRotation); + linphone_core_set_native_video_window_id([LinphoneManager getLc],(unsigned long)videoView); + + LinphoneCall* call = linphone_core_get_current_call([LinphoneManager getLc]); + if (call && linphone_call_params_video_enabled(linphone_call_get_current_params(call))) { + //Orientation has changed, must call update call + linphone_core_update_call([LinphoneManager getLc], call, NULL); + + + /* animate button images rotation */ +#define degreesToRadians(x) (M_PI * x / 180.0) + CGAffineTransform transform = CGAffineTransformIdentity; + switch (orientation) { + case UIInterfaceOrientationLandscapeRight: + transform = CGAffineTransformMakeRotation(degreesToRadians(90)); + break; + case UIInterfaceOrientationLandscapeLeft: + transform = CGAffineTransformMakeRotation(degreesToRadians(-90)); + break; + default: + transform = CGAffineTransformIdentity; + break; + } + + [UIView beginAnimations:nil context:NULL]; + [UIView setAnimationDuration:0.2f]; + endCtrl.imageView.transform = transform; + mute.imageView.transform = transform; + speaker.imageView.transform = transform; + pause.imageView.transform = transform; + contacts.imageView.transform = transform; + addCall.imageView.transform = transform; + addVideo.imageView.transform = transform; + dialer.imageView.transform = transform; + videoCallQuality.transform = transform; + [UIView commitAnimations]; + } + } +} + +-(void) showControls:(id)sender { + if (hideControlsTimer) { + [hideControlsTimer invalidate]; + hideControlsTimer = nil; + } + // show controls + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:0.3]; + [controlSubView setAlpha:1.0]; + [hangUpView setAlpha:1.0]; + if ([LinphoneManager instance].frontCamId !=nil ) { + // only show camera switch button if we have more than 1 camera + [videoCameraSwitch setAlpha:1.0]; + } + [UIView commitAnimations]; + + // hide controls in 5 sec + hideControlsTimer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(hideControls:) userInfo:nil repeats:NO]; +} + +-(void) hideControls:(id)sender { + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:0.3]; + [controlSubView setAlpha:0.0]; + [hangUpView setAlpha:0.0]; + [videoCameraSwitch setAlpha:0.0]; + [UIView commitAnimations]; + + hideControlsTimer = nil; +} + +-(void) batteryLevelChanged: (NSNotification*) notif { + LinphoneCall* call = linphone_core_get_current_call([LinphoneManager getLc]); + if (!call || !linphone_call_params_video_enabled(linphone_call_get_current_params(call))) + return; + LinphoneCallAppData* appData = (LinphoneCallAppData*) linphone_call_get_user_pointer(call); + if ([UIDevice currentDevice].batteryState == UIDeviceBatteryStateUnplugged) { + float level = [UIDevice currentDevice].batteryLevel; + ms_message("Video call is running. Battery level: %.2f", level); + if (level < 0.1 && !appData->batteryWarningShown) { + // notify user + CallDelegate* cd = [[CallDelegate alloc] init]; + cd.eventType = CD_STOP_VIDEO_ON_LOW_BATTERY; + cd.delegate = self; + cd.call = call; + + if (visibleActionSheet != nil) { + [visibleActionSheet dismissWithClickedButtonIndex:visibleActionSheet.cancelButtonIndex animated:TRUE]; + } + NSString* title = NSLocalizedString(@"Battery is running low. Stop video ?",nil); + visibleActionSheet = [[UIActionSheet alloc] initWithTitle:title + delegate:cd + cancelButtonTitle:NSLocalizedString(@"Continue video",nil) + destructiveButtonTitle:NSLocalizedString(@"Stop video",nil) + otherButtonTitles:nil]; + + visibleActionSheet.actionSheetStyle = UIActionSheetStyleDefault; + [visibleActionSheet showInView:self.view]; + appData->batteryWarningShown = TRUE; + } + } +} + +-(void) enableVideoDisplay { + [self orientationChanged:nil]; + + [videoZoomHandler resetZoom]; + + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:1.0]; + [videoGroup setAlpha:1.0]; + [controlSubView setAlpha:0.0]; + [hangUpView setAlpha:0.0]; + [callTableView setAlpha:0.0]; + [UIView commitAnimations]; + + videoView.alpha = 1.0; + videoView.hidden = FALSE; + + linphone_core_set_native_video_window_id([LinphoneManager getLc],(unsigned long)videoView); + linphone_core_set_native_preview_window_id([LinphoneManager getLc],(unsigned long)videoPreview); + + [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide]; + + // This is a bit hacky: take into account toolbar removal (only once). + // It's probably possible to do this from the Xib file (?) + static bool done = false; + if (!done) { + ms_message("old center: %f %f", videoView.center.x, videoView.center.y); + videoView.center = CGPointMake(videoView.center.x, videoView.center.y + (self.view.frame.size.height - videoView.window.frame.size.height)); + ms_message("new center: %f %f", videoView.center.x, videoView.center.y); + done = true; + } + + [self batteryLevelChanged:nil]; +} + +-(void) disableVideoDisplay { + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:1.0]; + [videoGroup setAlpha:0.0]; + [controlSubView setAlpha:1.0]; + [hangUpView setAlpha:1.0]; + [callTableView setAlpha:1.0]; + [videoCameraSwitch setAlpha:0.0]; + [UIView commitAnimations]; + + if (hideControlsTimer != nil) { + [hideControlsTimer invalidate]; + hideControlsTimer = nil; + } + + /* restore buttons orientation */ + endCtrl.imageView.transform = CGAffineTransformIdentity; + mute.imageView.transform = CGAffineTransformIdentity; + speaker.imageView.transform = CGAffineTransformIdentity; + pause.imageView.transform = CGAffineTransformIdentity; + contacts.imageView.transform = CGAffineTransformIdentity; + addCall.imageView.transform = CGAffineTransformIdentity; + dialer.imageView.transform = CGAffineTransformIdentity; + videoCallQuality.transform = CGAffineTransformIdentity; + + [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone]; +} + +/* Update in call view buttons (visibility, state, ...) and call duration text. + This is called periodically. The fullUpdate boolean is set when called after an event (call state change for instance) */ +-(void) updateUIFromLinphoneState:(BOOL) fullUpdate { activeCallCell = nil; - [mute reset]; - - LinphoneCore* lc; - + + // check LinphoneCore is initialized + LinphoneCore* lc = nil; @try { lc = [LinphoneManager getLc]; - - [LinphoneManager set:pause hidden:(callCount([LinphoneManager getLc]) > 1) withName:"PAUSE button" andReason:"call count"]; - [LinphoneManager set:mergeCalls hidden:!pause.hidden withName:"MERGE button" andReason:"call count"]; - - [callTableView reloadData]; } @catch (NSException* exc) { return; } - LinphoneCall* selectedCall = linphone_core_get_current_call([LinphoneManager getLc]); + // 1 call: show pause button, otherwise show merge btn + [LinphoneManager set:pause hidden:(callCount(lc) > 1) withName:"PAUSE button" andReason:"call count"]; + [LinphoneManager set:mergeCalls hidden:!pause.hidden withName:"MERGE button" andReason:"call count"]; + // reload table (glow update + call duration) + [callTableView reloadData]; + + LinphoneCall* currentCall = linphone_core_get_current_call([LinphoneManager getLc]); int callsCount = linphone_core_get_calls_nb(lc); + // hide pause/resume if in conference - if (selectedCall) { + if (currentCall) { + [mute reset]; if (linphone_core_is_in_conference(lc)) { [LinphoneManager set:pause hidden:YES withName:"PAUSE button" andReason:"is in conference"]; } @@ -134,6 +334,23 @@ int callCount(LinphoneCore* lc) { } else { [LinphoneManager set:pause hidden:YES withName:"PAUSE button" andReason:AT]; } + + if (fullUpdate) { + videoUpdateIndicator.hidden = YES; + LinphoneCallState state = linphone_call_get_state(currentCall); + if (state == LinphoneCallStreamsRunning || state == LinphoneCallUpdated || state == LinphoneCallUpdatedByRemote) { + if (linphone_call_params_video_enabled(linphone_call_get_current_params(currentCall))) { + [addVideo setTitle:NSLocalizedString(@"-video", nil) forState:UIControlStateNormal]; + [IncallViewController updateIndicator: videoCallQuality withCallQuality:linphone_call_get_average_quality(currentCall)]; + } else { + [addVideo setTitle:NSLocalizedString(@"+video", nil) forState:UIControlStateNormal]; + } + [addVideo setEnabled:YES]; + } else { + [addVideo setEnabled:NO]; + [videoCallQuality setImage:nil]; + } + } } else { if (callsCount == 1) { LinphoneCall* c = (LinphoneCall*)linphone_core_get_calls(lc)->data; @@ -145,10 +362,11 @@ int callCount(LinphoneCore* lc) { } else { [LinphoneManager set:pause hidden:YES withName:"PAUSE button" andReason:AT]; } + [addVideo setEnabled:NO]; } [LinphoneManager set:mergeCalls hidden:!pause.hidden withName:"MERGE button" andReason:AT]; - // update conference details view if diaplsyed + // update conference details view if displayed if (self.presentedViewController == conferenceDetail) { if (!linphone_core_is_in_conference(lc)) [self dismissModalViewControllerAnimated:YES]; @@ -201,6 +419,15 @@ int callCount(LinphoneCore* lc) { } + UITapGestureRecognizer* singleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(showControls:)]; + [singleFingerTap setNumberOfTapsRequired:1]; + [videoGroup addGestureRecognizer:singleFingerTap]; + [singleFingerTap release]; + + videoZoomHandler = [[VideoZoomHandler alloc] init]; + [videoZoomHandler setup:videoGroup]; + videoGroup.alpha = 0; + mVideoShown=FALSE; mIncallViewIsReady=FALSE; mVideoIsPending=FALSE; @@ -208,11 +435,90 @@ int callCount(LinphoneCore* lc) { callTableView.rowHeight = 80; + [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(batteryLevelChanged:) name:UIDeviceBatteryLevelDidChangeNotification object:nil]; + + + [videoCameraSwitch setPreview:videoPreview]; + addVideo.videoUpdateIndicator = videoUpdateIndicator; + + [transfer addTarget:self action:@selector(transferPressed) forControlEvents:UIControlEventTouchUpInside]; + + // prevent buttons resizing + /* + endCtrl.imageView.contentMode = UIViewContentModeCenter; + mute.imageView.contentMode = UIViewContentModeCenter; + speaker.imageView.contentMode = UIViewContentModeCenter; + pause.imageView.contentMode = UIViewContentModeCenter; + contacts.imageView.contentMode = UIViewContentModeCenter; + addCall.imageView.contentMode = UIViewContentModeCenter; + dialer.imageView.contentMode = UIViewContentModeCenter;*/ + +} + +-(void) transferPressed { + /* allow only if call is active */ + if (!linphone_core_get_current_call([LinphoneManager getLc])) + return; + + /* build UIActionSheet */ + if (visibleActionSheet != nil) { + [visibleActionSheet dismissWithClickedButtonIndex:visibleActionSheet.cancelButtonIndex animated:TRUE]; + } + + CallDelegate* cd = [[CallDelegate alloc] init]; + cd.eventType = CD_TRANSFER_CALL; + cd.delegate = self; + cd.call = linphone_core_get_current_call([LinphoneManager getLc]); + NSString* title = NSLocalizedString(@"Transfer to ...",nil); + visibleActionSheet = [[UIActionSheet alloc] initWithTitle:title + delegate:cd + cancelButtonTitle:nil + destructiveButtonTitle:nil // NSLocalizedString(@"Other...",nil) + otherButtonTitles:nil]; + + // add button for each trasnfer-to valid call + const MSList* calls = linphone_core_get_calls([LinphoneManager getLc]); + while (calls) { + LinphoneCall* call = (LinphoneCall*) calls->data; + LinphoneCallAppData* data = ((LinphoneCallAppData*)linphone_call_get_user_pointer(call)); + if (call != cd.call && !linphone_call_get_current_params(call)->in_conference) { + const LinphoneAddress* addr = linphone_call_get_remote_address(call); + NSString* btnTitle = [NSString stringWithFormat : NSLocalizedString(@"%s",nil), (linphone_address_get_display_name(addr) ?linphone_address_get_display_name(addr):linphone_address_get_username(addr))]; + data->transferButtonIndex = [visibleActionSheet addButtonWithTitle:btnTitle]; + } else { + data->transferButtonIndex = -1; + } + calls = calls->next; + } + + if (visibleActionSheet.numberOfButtons == 0) { + [visibleActionSheet release]; + visibleActionSheet = nil; + + [UICallButton enableTransforMode:YES]; + [[LinphoneManager instance] displayDialer]; + } else { + // add 'Other' option + [visibleActionSheet addButtonWithTitle:NSLocalizedString(@"Other...",nil)]; + + // add cancel button on iphone + if (![LinphoneManager runningOnIpad]) { + [visibleActionSheet addButtonWithTitle:NSLocalizedString(@"Cancel",nil)]; + } + + visibleActionSheet.actionSheetStyle = UIActionSheetStyleDefault; + if ([LinphoneManager runningOnIpad]) + [visibleActionSheet showFromRect:transfer.bounds inView:transfer animated:NO]; + else + [visibleActionSheet showInView:self.view]; + } } -(void) addCallPressed { [LinphoneManager logUIElementPressed:"CALL button"]; - [self dismissModalViewControllerAnimated:true]; + [[LinphoneManager instance] displayDialer]; } @@ -231,6 +537,9 @@ int callCount(LinphoneCore* lc) { if (linphone_call_get_state(currentCall) == LinphoneCallStreamsRunning) { [pause setSelected:NO]; linphone_core_pause_call(lc, currentCall); + + // hide video view + [self disableVideoDisplay]; } } else { if (linphone_core_get_calls_nb(lc) == 1) { @@ -238,6 +547,11 @@ int callCount(LinphoneCore* lc) { if (linphone_call_get_state(c) == LinphoneCallPaused) { linphone_core_resume_call(lc, c); [pause setSelected:YES]; + + const LinphoneCallParams* p = linphone_call_get_current_params(c); + if (linphone_call_params_video_enabled(p)) { + [self enableVideoDisplay]; + } } } } @@ -245,10 +559,13 @@ int callCount(LinphoneCore* lc) { -(void)updateCallsDurations { - [self updateUIFromLinphoneState: nil]; + [self updateUIFromLinphoneState: NO]; } --(void) viewWillAppear:(BOOL)animated {} +-(void) awakeFromNib +{ + +} -(void)viewDidAppear:(BOOL)animated { [[UIApplication sharedApplication] setIdleTimerDisabled:YES]; @@ -282,17 +599,16 @@ int callCount(LinphoneCore* lc) { if ([device respondsToSelector:@selector(isMultitaskingSupported)] && [device isMultitaskingSupported]) { bool enableVideo = [[NSUserDefaults standardUserDefaults] boolForKey:@"enable_video_preference"]; - bool startVideo = [[NSUserDefaults standardUserDefaults] boolForKey:@"start_video_preference"]; - - [LinphoneManager set:contacts hidden:(enableVideo && !startVideo) withName:"CONTACT button" andReason:AT]; + + [LinphoneManager set:contacts hidden:enableVideo withName:"CONTACT button" andReason:AT]; [LinphoneManager set:addVideo hidden:!contacts.hidden withName:"ADD_VIDEO button" andReason:AT]; } } } -(void) viewWillDisappear:(BOOL)animated { - if (zrtpVerificationSheet != nil) { - [zrtpVerificationSheet dismissWithClickedButtonIndex:2 animated:NO]; + if (visibleActionSheet != nil) { + [visibleActionSheet dismissWithClickedButtonIndex:visibleActionSheet.cancelButtonIndex animated:NO]; } } @@ -305,6 +621,7 @@ int callCount(LinphoneCore* lc) { } if (!mVideoShown) [[UIApplication sharedApplication] setIdleTimerDisabled:false]; mIncallViewIsReady=FALSE; + dismissed = false; } - (void)viewDidUnload { @@ -319,31 +636,27 @@ int callCount(LinphoneCore* lc) { } -(void) displayPad:(bool) enable { - [LinphoneManager set:callTableView hidden:enable withName:"CALL_TABLE view" andReason:AT]; + if (videoView.hidden) + [LinphoneManager set:callTableView hidden:enable withName:"CALL_TABLE view" andReason:AT]; [LinphoneManager set:hangUpView hidden:enable withName:"HANG_UP view" andReason:AT]; [LinphoneManager set:controlSubView hidden:enable withName:"CONTROL view" andReason:AT]; [LinphoneManager set:padSubView hidden:!enable withName:"PAD view" andReason:AT]; } -(void) displayCall:(LinphoneCall*) call InProgressFromUI:(UIViewController*) viewCtrl forUser:(NSString*) username withDisplayName:(NSString*) displayName { - //restaure view + //restore view [self displayPad:false]; dismissed = false; UIDevice *device = [UIDevice currentDevice]; device.proximityMonitoringEnabled = YES; if ([speaker isOn]) [speaker toggle]; - [self updateUIFromLinphoneState: nil]; + [self updateUIFromLinphoneState: YES]; } -(void) displayIncomingCall:(LinphoneCall *)call NotificationFromUI:(UIViewController *)viewCtrl forUser:(NSString *)username withDisplayName:(NSString *)displayName { } --(void) dismissVideoView { - [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone]; - [self dismissModalViewControllerAnimated:FALSE];//just in case - mVideoShown=FALSE; -} -(void) displayInCall:(LinphoneCall*) call FromUI:(UIViewController*) viewCtrl forUser:(NSString*) username withDisplayName:(NSString*) displayName { dismissed = false; UIDevice *device = [UIDevice currentDevice]; @@ -351,15 +664,16 @@ int callCount(LinphoneCore* lc) { if (call !=nil && linphone_call_get_dir(call)==LinphoneCallIncoming) { if ([speaker isOn]) [speaker toggle]; } - [self updateUIFromLinphoneState: nil]; - if (self.presentedViewController == (UIViewController*)mVideoViewController) { - [self dismissVideoView]; - } + [self updateUIFromLinphoneState: YES]; + + [self disableVideoDisplay]; } -(void) displayDialerFromUI:(UIViewController*) viewCtrl forUser:(NSString*) username withDisplayName:(NSString*) displayName { + [self disableVideoDisplay]; UIViewController* modalVC = self.modalViewController; UIDevice *device = [UIDevice currentDevice]; device.proximityMonitoringEnabled = NO; + dismissed = true; if (modalVC != nil) { mVideoIsPending=FALSE; // clear previous native window ids @@ -373,10 +687,35 @@ int callCount(LinphoneCore* lc) { } [self dismissModalViewControllerAnimated:FALSE]; //disable animation to avoid blanc bar just below status bar*/ - dismissed = true; - [self updateUIFromLinphoneState: nil]; + [self updateUIFromLinphoneState: YES]; } + +static void hideSpinner(LinphoneCall* lc, void* user_data); + +-(void) hideSpinnerIndicator: (LinphoneCall*)call { + if (!videoWaitingForFirstImage.hidden) { + videoWaitingForFirstImage.hidden = TRUE; + } /*else { + linphone_call_set_next_video_frame_decoded_callback(call, hideSpinner, self); + }*/ +} + +static void hideSpinner(LinphoneCall* call, void* user_data) { + IncallViewController* thiz = (IncallViewController*) user_data; + [thiz hideSpinnerIndicator:call]; +} + -(void) displayVideoCall:(LinphoneCall*) call FromUI:(UIViewController*) viewCtrl forUser:(NSString*) username withDisplayName:(NSString*) displayName { + + [self enableVideoDisplay]; + + [self updateUIFromLinphoneState: YES]; + videoWaitingForFirstImage.hidden = NO; + [videoWaitingForFirstImage startAnimating]; + + linphone_call_set_next_video_frame_decoded_callback(call, hideSpinner, self); + return; + if (mIncallViewIsReady) { [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone]; mVideoShown=TRUE; @@ -385,11 +724,51 @@ int callCount(LinphoneCore* lc) { else ms_message("Do not present again videoViewController"); } else { - //postepone presentation + //postpone presentation mVideoIsPending=TRUE; } } +-(void) dismissActionSheet: (id)o { + if (visibleActionSheet != nil) { + [visibleActionSheet dismissWithClickedButtonIndex:visibleActionSheet.cancelButtonIndex animated:TRUE]; + visibleActionSheet = nil; + } +} + +-(void) displayAskToEnableVideoCall:(LinphoneCall*) call forUser:(NSString*) username withDisplayName:(NSString*) displayName { + if (linphone_core_get_video_policy([LinphoneManager getLc])->automatically_accept) + return; + + // ask the user if he agrees + CallDelegate* cd = [[CallDelegate alloc] init]; + cd.eventType = CD_VIDEO_UPDATE; + cd.delegate = self; + cd.call = call; + + if (visibleActionSheet != nil) { + [visibleActionSheet dismissWithClickedButtonIndex:visibleActionSheet.cancelButtonIndex animated:TRUE]; + } + NSString* title = [NSString stringWithFormat : NSLocalizedString(@"'%@' would like to enable video",nil), ([displayName length] > 0) ?displayName:username]; + visibleActionSheet = [[UIActionSheet alloc] initWithTitle:title + delegate:cd + cancelButtonTitle:NSLocalizedString(@"Decline",nil) + destructiveButtonTitle:NSLocalizedString(@"Accept",nil) + otherButtonTitles:nil]; + + visibleActionSheet.actionSheetStyle = UIActionSheetStyleDefault; + [visibleActionSheet showInView:self.view]; + + /* start cancel timer */ + cd.timeout = [NSTimer scheduledTimerWithTimeInterval:30 target:self selector:@selector(dismissActionSheet:) userInfo:nil repeats:NO]; + [visibleActionSheet release]; +} + +-(void) firstVideoFrameDecoded: (LinphoneCall*) call { + // hide video in progress view indicator + videoWaitingForFirstImage.hidden = TRUE; +} + - (IBAction)doAction:(id)sender { if (sender == dialer) { @@ -497,6 +876,8 @@ int callCount(LinphoneCore* lc) { } const LinphoneAddress* addr = linphone_call_get_remote_address(call); + label.adjustsFontSizeToFitWidth = YES; + if (addr) { const char* lUserNameChars=linphone_address_get_username(addr); NSString* lUserName = lUserNameChars?[[[NSString alloc] initWithUTF8String:lUserNameChars] autorelease]:NSLocalizedString(@"Unknown",nil); @@ -540,10 +921,27 @@ int callCount(LinphoneCore* lc) { [ms appendFormat:@"%@...", NSLocalizedString(@"Ringing...", nil), nil]; break; case LinphoneCallPausedByRemote: - [ms appendFormat:@"%@...", NSLocalizedString(@"Paused by remote", nil), nil]; + { + switch (linphone_call_get_transfer_state(call)) { + case LinphoneCallOutgoingInit: + case LinphoneCallOutgoingProgress: + [ms appendFormat:@"%@...", NSLocalizedString(@"Transfer in progress", nil), nil]; + break; + case LinphoneCallConnected: + [ms appendFormat:@"%@", NSLocalizedString(@"Transfer successful", nil), nil]; + break; + case LinphoneCallError: + [ms appendFormat:@"%@", NSLocalizedString(@"Transfer failed", nil), nil]; + break; + case LinphoneCallIdle: + default: + [ms appendFormat:@"%@...", NSLocalizedString(@"Paused by remote", nil), nil]; + break; + } break; default: break; + } } } [detailLabel setText:ms]; @@ -627,21 +1025,7 @@ int callCount(LinphoneCore* lc) { [callquality setFrame:CGRectMake(0, 0, 28, 28)]; if (call->state == LinphoneCallStreamsRunning) { - if (linphone_call_get_average_quality(call) >= 4) { - [callquality setImage: [IncallViewController stat_sys_signal_4]]; - } - else if (linphone_call_get_average_quality(call) >= 3) { - [callquality setImage: [IncallViewController stat_sys_signal_3]]; - } - else if (linphone_call_get_average_quality(call) >= 2) { - [callquality setImage: [IncallViewController stat_sys_signal_2]]; - } - else if (linphone_call_get_average_quality(call) >= 1) { - [callquality setImage: [IncallViewController stat_sys_signal_1]]; - } - else { - [callquality setImage: [IncallViewController stat_sys_signal_0]]; - } + [IncallViewController updateIndicator: callquality withCallQuality:linphone_call_get_average_quality(call)]; } else { [callquality setImage:nil]; @@ -686,33 +1070,94 @@ int callCount(LinphoneCore* lc) { LinphoneCall* call = [IncallViewController retrieveCallAtIndex:path.row inConference:NO]; // start action sheet to validate/unvalidate zrtp code CallDelegate* cd = [[CallDelegate alloc] init]; + cd.eventType = CD_ZRTP; cd.delegate = self; cd.call = call; UIView* container=(UIView*)[callTableView cellForRowAtIndexPath:path].accessoryView; UIButton *button=(UIButton*)[container viewWithTag:SECURE_BUTTON_TAG]; [button setImage:nil forState:UIControlStateNormal]; - zrtpVerificationSheet = [[UIActionSheet alloc] initWithTitle:[NSString stringWithFormat:NSLocalizedString(@" Mark auth token '%s' as:",nil),linphone_call_get_authentication_token(call)] + if (visibleActionSheet != nil) { + [visibleActionSheet dismissWithClickedButtonIndex:visibleActionSheet.cancelButtonIndex animated:TRUE]; + } + visibleActionSheet = [[UIActionSheet alloc] initWithTitle:[NSString stringWithFormat:NSLocalizedString(@" Mark auth token '%s' as:",nil),linphone_call_get_authentication_token(call)] delegate:cd cancelButtonTitle:NSLocalizedString(@"Unverified",nil) destructiveButtonTitle:NSLocalizedString(@"Verified",nil) otherButtonTitles:nil]; - zrtpVerificationSheet.actionSheetStyle = UIActionSheetStyleDefault; - [zrtpVerificationSheet showInView:self.view]; - [zrtpVerificationSheet release]; + visibleActionSheet.actionSheetStyle = UIActionSheetStyleDefault; + [visibleActionSheet showInView:self.view]; + [visibleActionSheet release]; } } --(void) actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex withUserDatas:(void *)datas { +-(void) actionSheet:(UIActionSheet *)actionSheet ofType:(enum CallDelegateType)type clickedButtonAtIndex:(NSInteger)buttonIndex withUserDatas:(void *)datas { LinphoneCall* call = (LinphoneCall*)datas; // maybe we could verify call validity - - if (buttonIndex == 0) - linphone_call_set_authentication_token_verified(call, YES); - else if (buttonIndex == 1) - linphone_call_set_authentication_token_verified(call, NO); - zrtpVerificationSheet = nil; + + switch (type) { + case CD_ZRTP: { + if (buttonIndex == 0) + linphone_call_set_authentication_token_verified(call, YES); + else if (buttonIndex == 1) + linphone_call_set_authentication_token_verified(call, NO); + visibleActionSheet = nil; + break; + } + case CD_VIDEO_UPDATE: { + LinphoneCall* call = (LinphoneCall*)datas; + LinphoneCallParams* paramsCopy = linphone_call_params_copy(linphone_call_get_current_params(call)); + if ([visibleActionSheet destructiveButtonIndex] == buttonIndex) { + // accept video + linphone_call_params_enable_video(paramsCopy, TRUE); + linphone_core_accept_call_update([LinphoneManager getLc], call, paramsCopy); + } else { + // decline video + ms_message("User declined video proposal"); + linphone_core_accept_call_update([LinphoneManager getLc], call, NULL); + } + linphone_call_params_destroy(paramsCopy); + visibleActionSheet = nil; + break; + } + case CD_STOP_VIDEO_ON_LOW_BATTERY: { + LinphoneCall* call = (LinphoneCall*)datas; + LinphoneCallParams* paramsCopy = linphone_call_params_copy(linphone_call_get_current_params(call)); + if ([visibleActionSheet destructiveButtonIndex] == buttonIndex) { + // stop video + linphone_call_params_enable_video(paramsCopy, FALSE); + linphone_core_update_call([LinphoneManager getLc], call, paramsCopy); + } + break; + } + case CD_TRANSFER_CALL: { + LinphoneCall* call = (LinphoneCall*)datas; + // browse existing call and trasnfer to the one matching the btn id + const MSList* calls = linphone_core_get_calls([LinphoneManager getLc]); + while (calls) { + LinphoneCall* call2 = (LinphoneCall*) calls->data; + LinphoneCallAppData* data = ((LinphoneCallAppData*)linphone_call_get_user_pointer(call2)); + if (data->transferButtonIndex == buttonIndex) { + linphone_core_transfer_call_to_another([LinphoneManager getLc], call, call2); + return; + } + data->transferButtonIndex = -1; + calls = calls->next; + } + if (![LinphoneManager runningOnIpad] && buttonIndex == (actionSheet.numberOfButtons - 1)) { + // cancel button + return; + } + // user must jhave pressed 'other...' button as we did not find a call + // with the correct indice + [UICallButton enableTransforMode:YES]; + [[LinphoneManager instance] displayDialer]; + break; + } + default: + ms_error("Unhandled CallDelegate event of type: %d received - ignoring", type); + } } // UITableViewDataSource (required) @@ -779,8 +1224,7 @@ int callCount(LinphoneCore* lc) { linphone_core_resume_call([LinphoneManager getLc], selectedCall); } - [self updateUIFromLinphoneState: nil]; + [self updateUIFromLinphoneState: YES]; } - @end diff --git a/Classes/IncallViewController.xib b/Classes/IncallViewController.xib index 9a8d85d63..81185bcd5 100644 --- a/Classes/IncallViewController.xib +++ b/Classes/IncallViewController.xib @@ -12,11 +12,13 @@ YES - IBUIViewController IBUIButton - IBUIView - IBUITableView + IBUIImageView + IBUIViewController IBProxyObject + IBUIActivityIndicatorView + IBUITableView + IBUIView YES @@ -42,6 +44,119 @@ 274 YES + + + 292 + + YES + + + 292 + {320, 480} + + + + _NS:196 + + 3 + MCAwAA + + IBCocoaTouchFramework + + + + 292 + {{240, 354}, {80, 106}} + + + + + IBCocoaTouchFramework + + + + 292 + {{4, 428}, {28, 28}} + + + + _NS:567 + NO + IBCocoaTouchFramework + + + + 292 + {{141, 212}, {37, 37}} + + + + _NS:1030 + NO + IBCocoaTouchFramework + NO + YES + 0 + + + {320, 460} + + + + _NS:196 + + 2 + MC4wNTQ5MDE5NjA3OCAwLjA4MjM1Mjk0MTE4IDAuMTI5NDExNzY0NwA + + NO + IBCocoaTouchFramework + + + + 292 + {320, 66} + + + + + 1 + MSAwIDAuMDgyMzIwMjU5MDQgMC4xOAA + + NO + NO + 0.0 + IBCocoaTouchFramework + 0 + 0 + Change camera + + 3 + MQA + + + 1 + MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA + + + 3 + MC41AA + + + NSImage + clavier-01-106px.png + + + Helvetica-Bold + Helvetica + 2 + 15 + + + Helvetica-Bold + 15 + 16 + + 274 @@ -50,10 +165,7 @@ _NS:418 - - 3 - MCAwAA - + YES IBCocoaTouchFramework YES @@ -85,37 +197,19 @@ IBCocoaTouchFramework 0 0 - - 3 - MQA - + 1 MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA - - 3 - MC41AA - + NSImage stopcall-red.png - - NSImage - clavier-01-106px.png - - - Helvetica-Bold - Helvetica - 2 - 15 - - - Helvetica-Bold - 15 - 16 - + + + {{0, 393.5}, {320, 77}} @@ -134,7 +228,7 @@ 292 - {{107, 70}, {106, 66}} + {{80, 70}, {80, 66}} @@ -208,10 +302,10 @@ 292 - {{0, 70}, {107, 66}} + {{0, 70}, {80, 66}} - + NO NO @@ -231,10 +325,37 @@ + + + 292 + {{160, 70}, {80, 66}} + + + + + NO + NO + IBCocoaTouchFramework + 0 + 0 + Transfer + + + 1 + MC4xOTYwNzg0MzE0IDAuMzA5ODAzOTIxNiAwLjUyMTU2ODYyNzUAA + + + + + 2 + 15 + + + 292 - {{213, 70}, {107, 66}} + {{240, 70}, {80, 66}} @@ -263,10 +384,10 @@ -2147483356 - {{213, 70}, {107, 66}} + {{240, 70}, {80, 66}} - + NO NO @@ -274,13 +395,18 @@ 0 0 1 - video + video + + 3 + MC42NjY2NjY2NjY3AA + 1 MC4xOTYwNzg0MzE0IDAuMzA5ODAzOTIxNiAwLjUyMTU2ODYyNzUAA + NSImage clavier-01-160px.png @@ -288,13 +414,26 @@ + + + -2147483356 + {{261.5, 84.5}, {37, 37}} + + + + _NS:1030 + NO + IBCocoaTouchFramework + NO + 0 + 292 {{107, 4}, {106, 66}} - + NO NO @@ -347,12 +486,13 @@ 292 - {{107, 70}, {106, 66}} + {{80, 70}, {80, 66}} - + NO + NO NO IBCocoaTouchFramework 0 @@ -412,7 +552,7 @@ - + @@ -421,10 +561,7 @@ - - 3 - MC42NjY2NjY2NjY3AA - + NO NO IBCocoaTouchFramework @@ -438,7 +575,7 @@ - + @@ -461,7 +598,7 @@ - + @@ -481,7 +618,7 @@ - + @@ -504,7 +641,7 @@ - + @@ -527,7 +664,7 @@ - + @@ -550,7 +687,7 @@ - + @@ -573,7 +710,7 @@ - + @@ -596,7 +733,7 @@ - + @@ -619,7 +756,7 @@ - + @@ -642,7 +779,7 @@ - + @@ -665,7 +802,7 @@ - + @@ -688,7 +825,7 @@ - + {{0, 71}, {320, 310}} @@ -707,7 +844,7 @@ {{0, 20}, {320, 460}} - + NO IBCocoaTouchFramework @@ -726,155 +863,51 @@ YES - view + videoCallQuality - + - 23 + 138 - endCtrl + videoPreview - + - 99 + 130 - star + videoView - + - 56 + 133 - two + videoGroup - + - 59 + 129 - one + addVideo - + - 54 + 125 - four + mergeCalls - + - 67 - - - - hash - - - - 57 - - - - nine - - - - 58 - - - - padSubView - - - - 45 - - - - zero - - - - 55 - - - - seven - - - - 73 - - - - three - - - - 60 - - - - close - - - - 51 - - - - eight - - - - 75 - - - - six - - - - 71 - - - - five - - - - 69 - - - - hangUpView - - - - 122 - - - - callTableView - - - - 109 - - - - controlSubView - - - - 44 + 114 @@ -892,6 +925,14 @@ 112 + + + contacts + + + + 84 + dialer @@ -900,14 +941,6 @@ 49 - - - pause - - - - 115 - speaker @@ -918,27 +951,195 @@ - contacts + pause - + - 84 + 115 - mergeCalls + controlSubView - + - 114 + 44 - addVideo + callTableView - + - 125 + 109 + + + + five + + + + 69 + + + + nine + + + + 58 + + + + seven + + + + 73 + + + + six + + + + 71 + + + + four + + + + 67 + + + + three + + + + 60 + + + + zero + + + + 55 + + + + two + + + + 59 + + + + close + + + + 51 + + + + hash + + + + 57 + + + + eight + + + + 75 + + + + one + + + + 54 + + + + star + + + + 56 + + + + padSubView + + + + 45 + + + + endCtrl + + + + 99 + + + + hangUpView + + + + 122 + + + + view + + + + 23 + + + + videoCameraSwitch + + + + 141 + + + + videoUpdateIndicator + + + + 143 + + + + videoWaitingForFirstImage + + + + 145 + + + + transfer + + + + 150 @@ -1024,23 +1225,113 @@ + + - 120 - + 126 + YES - + + + + + video - 18 - - - end + 137 + + + videocallquality + + + 127 + + + preview + + + 132 + + + display + + + 26 + + + YES + + + + + + + + + + + + + controls + + + 123 + + + video + + + 104 + + + merge + + + 16 + + + mute + + + 111 + + + addcall + + + 15 + + + contacts + + + 17 + + + dialer + + + 13 + + + speaker + + + 113 + + + pauseresume + + + 106 + + 27 @@ -1064,78 +1355,12 @@ pad - - 31 - - - star - - - 30 - - - 1 - - - 33 - - - 8 - - - 40 - - - hash - 36 5 - - 29 - - - close - - - 39 - - - 2 - - - 41 - - - 0 - - - 38 - - - 3 - - - 35 - - - 4 - - - 37 - - - 6 - - - 34 - - - 7 - 32 @@ -1143,74 +1368,109 @@ 9 - 106 - - + 34 + + + 7 - 26 - + 37 + + + 6 + + + 35 + + + 4 + + + 38 + + + 3 + + + 41 + + + 0 + + + 39 + + + 2 + + + 29 + + + close + + + 40 + + + hash + + + 33 + + + 8 + + + 30 + + + 1 + + + 31 + + + star + + + 120 + YES - - - - - - - - + - controls + hangupview - 113 - - - pauseresume + 18 + + + end - 13 - - - speaker + 140 + + + camswitch - 17 - + 142 + - dialer + video_update_indicator - 15 - - - contacts + 144 + + - 111 - + 147 + - addcall - - - 16 - - - mute - - - 104 - - - merge - - - 123 - - - video + transfer @@ -1232,9 +1492,20 @@ 120.IBPluginDependency 123.CustomClassName 123.IBPluginDependency + 123.IBUIButtonInspectorSelectedStateConfigurationMetadataKey + 126.IBPluginDependency + 127.IBPluginDependency 13.CustomClassName 13.IBPluginDependency 13.IBUIButtonInspectorSelectedStateConfigurationMetadataKey + 132.IBPluginDependency + 137.IBPluginDependency + 140.CustomClassName + 140.IBPluginDependency + 142.IBPluginDependency + 144.IBPluginDependency + 147.IBPluginDependency + 147.IBUIButtonInspectorSelectedStateConfigurationMetadataKey 15.IBPluginDependency 16.CustomClassName 16.IBPluginDependency @@ -1287,12 +1558,23 @@ com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIAddVideoButton + UIToggleVideoButton + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin UISpeakerButton com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + UICamSwitch + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin UIMuteButton com.apple.InterfaceBuilder.IBCocoaTouchPlugin @@ -1343,7 +1625,7 @@ - 125 + 150 @@ -1367,9 +1649,7 @@ YES addCall - addToConf addVideo - callControlSubView callTableView close conferenceDetail @@ -1393,16 +1673,22 @@ speaker star three + transfer two + videoCallQuality + videoCameraSwitch + videoGroup + videoPreview + videoUpdateIndicator + videoView videoViewController + videoWaitingForFirstImage zero YES UIButton - UIButton - UIButton - UIView + UIToggleVideoButton UITableView UIButton UIViewController @@ -1427,7 +1713,15 @@ UIButton UIButton UIButton + UIButton + UIImageView + UICamSwitch + UIView + UIView + UIActivityIndicatorView + UIView VideoViewController + UIActivityIndicatorView UIButton @@ -1436,9 +1730,7 @@ YES addCall - addToConf addVideo - callControlSubView callTableView close conferenceDetail @@ -1462,8 +1754,16 @@ speaker star three + transfer two + videoCallQuality + videoCameraSwitch + videoGroup + videoPreview + videoUpdateIndicator + videoView videoViewController + videoWaitingForFirstImage zero @@ -1472,17 +1772,9 @@ addCall UIButton - - addToConf - UIButton - addVideo - UIButton - - - callControlSubView - UIView + UIToggleVideoButton callTableView @@ -1576,14 +1868,46 @@ three UIButton + + transfer + UIButton + two UIButton + + videoCallQuality + UIImageView + + + videoCameraSwitch + UICamSwitch + + + videoGroup + UIView + + + videoPreview + UIView + + + videoUpdateIndicator + UIActivityIndicatorView + + + videoView + UIView + videoViewController VideoViewController + + videoWaitingForFirstImage + UIActivityIndicatorView + zero UIButton @@ -1595,14 +1919,6 @@ ./Classes/IncallViewController.h - - UIAddVideoButton - UIButton - - IBProjectSource - ./Classes/UIAddVideoButton.h - - UICamSwitch UIButton @@ -1662,6 +1978,25 @@ ./Classes/UIToggleButton.h + + UIToggleVideoButton + UIButton + + videoUpdateIndicator + UIActivityIndicatorView + + + videoUpdateIndicator + + videoUpdateIndicator + UIActivityIndicatorView + + + + IBProjectSource + ./Classes/UIToggleVideoButton.h + + VideoViewController UIViewController @@ -1673,27 +2008,21 @@ mCallQualityLandLeft mCallQualityLandRight mCamSwitch - mCamSwitchLand mCamSwitchLandLeft mCamSwitchLandRight mDisplay - mDisplayLand mDisplayLandLeft mDisplayLandRight mHangUp - mHangUpLand mHangUpLandLeft mHangUpLandRight - mLandscape mLandscapeLeft mLandscapeRight mMute - mMuteLand mMuteLandLeft mMuteLandRight mPortrait mPreview - mPreviewLand mPreviewLandLeft mPreviewLandRight @@ -1705,23 +2034,17 @@ UICamSwitch UICamSwitch UICamSwitch - UICamSwitch - UIView UIView UIView UIView UIHangUpButton UIHangUpButton UIHangUpButton - UIHangUpButton - UIView UIView UIView UIMuteButton UIMuteButton UIMuteButton - UIMuteButton - UIView UIView UIView UIView @@ -1736,27 +2059,21 @@ mCallQualityLandLeft mCallQualityLandRight mCamSwitch - mCamSwitchLand mCamSwitchLandLeft mCamSwitchLandRight mDisplay - mDisplayLand mDisplayLandLeft mDisplayLandRight mHangUp - mHangUpLand mHangUpLandLeft mHangUpLandRight - mLandscape mLandscapeLeft mLandscapeRight mMute - mMuteLand mMuteLandLeft mMuteLandRight mPortrait mPreview - mPreviewLand mPreviewLandLeft mPreviewLandRight @@ -1778,10 +2095,6 @@ mCamSwitch UICamSwitch - - mCamSwitchLand - UICamSwitch - mCamSwitchLandLeft UICamSwitch @@ -1794,10 +2107,6 @@ mDisplay UIView - - mDisplayLand - UIView - mDisplayLandLeft UIView @@ -1810,10 +2119,6 @@ mHangUp UIHangUpButton - - mHangUpLand - UIHangUpButton - mHangUpLandLeft UIHangUpButton @@ -1822,10 +2127,6 @@ mHangUpLandRight UIHangUpButton - - mLandscape - UIView - mLandscapeLeft UIView @@ -1838,10 +2139,6 @@ mMute UIMuteButton - - mMuteLand - UIMuteButton - mMuteLandLeft UIMuteButton @@ -1858,10 +2155,6 @@ mPreview UIView - - mPreviewLand - UIView - mPreviewLandLeft UIView diff --git a/Classes/LinphoneAppDelegate.h b/Classes/LinphoneAppDelegate.h index f13b8cb84..f5e9508a1 100644 --- a/Classes/LinphoneAppDelegate.h +++ b/Classes/LinphoneAppDelegate.h @@ -48,6 +48,8 @@ -(void) setupUI; -(void) setupGSMInteraction; +-(void) startApplication; + @property (nonatomic, retain) IBOutlet UIWindow *window; @property (nonatomic, retain) IBOutlet UITabBarController* myTabBarController; @property (nonatomic, retain) ABPeoplePickerNavigationController* myPeoplePickerController; diff --git a/Classes/LinphoneAppDelegate.m b/Classes/LinphoneAppDelegate.m index f8ae57a8e..8162f851d 100644 --- a/Classes/LinphoneAppDelegate.m +++ b/Classes/LinphoneAppDelegate.m @@ -94,6 +94,15 @@ int __aeabi_idiv(int a, int b) { } } - (void)applicationDidBecomeActive:(UIApplication *)application { + if ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)] + && [UIApplication sharedApplication].applicationState == UIApplicationStateBackground + && [[NSUserDefaults standardUserDefaults] boolForKey:@"disable_autoboot_preference"]) { + // autoboot disabled, doing nothing + return; + } else if ([LinphoneManager instance] == nil) { + [self startApplication]; + } + [[LinphoneManager instance] becomeActive]; if (callCenter == nil) { @@ -151,7 +160,6 @@ int __aeabi_idiv(int a, int b) { [defaultsToRegister setObject:[prefSpecification objectForKey:@"DefaultValue"] forKey:key]; } } - [defaultsToRegister addEntriesFromDictionary:appDefaults]; [[NSUserDefaults standardUserDefaults] registerDefaults:defaultsToRegister]; [defaultsToRegister release]; @@ -201,6 +209,8 @@ int __aeabi_idiv(int a, int b) { [window makeKeyAndVisible]; [[LinphoneManager instance] setCallDelegate:myPhoneViewController]; + + [UIDevice currentDevice].batteryMonitoringEnabled = YES; } -(void) setupGSMInteraction { @@ -223,23 +233,33 @@ int __aeabi_idiv(int a, int b) { @"YES",@"g729_preference", // enable amr by default if compiled with #endif //@"+33",@"countrycode_preference", - nil]; + nil]; + + [self loadDefaultSettings: appDefaults]; + + if ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)] + && [UIApplication sharedApplication].applicationState == UIApplicationStateBackground + && [[NSUserDefaults standardUserDefaults] boolForKey:@"disable_autoboot_preference"]) { + // autoboot disabled, doing nothing + } else { + [self startApplication]; + } + return YES; +} + +-(void) startApplication { /* explicitely instanciate LinphoneManager */ LinphoneManager* lm = [[LinphoneManager alloc] init]; assert(lm == [LinphoneManager instance]); - [self loadDefaultSettings: appDefaults]; - [self setupUI]; - + [[LinphoneManager instance] startLibLinphone]; [[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeSound]; [self setupGSMInteraction]; - - return YES; } diff --git a/Classes/LinphoneUI/LinphoneManager.h b/Classes/LinphoneUI/LinphoneManager.h index f68b7739f..92fc3056d 100644 --- a/Classes/LinphoneUI/LinphoneManager.h +++ b/Classes/LinphoneUI/LinphoneManager.h @@ -23,6 +23,7 @@ #include "linphonecore.h" #import "LogView.h" #import "LinphoneUIDelegates.h" + typedef enum _Connectivity { wifi, wwan @@ -41,6 +42,12 @@ struct NetworkReachabilityContext { void (*networkStateChanged) (Connectivity newConnectivity); }; +typedef struct _LinphoneCallAppData { + bool_t batteryWarningShown; + // transfer data + int transferButtonIndex; +} LinphoneCallAppData; + @interface LinphoneManager : NSObject { @protected @@ -69,6 +76,8 @@ struct NetworkReachabilityContext { +(void) set:(UIView*)view hidden: (BOOL) hidden withName:(const char*)name andReason:(const char*) reason; +(void) logUIElementPressed:(const char*) name; +-(void) displayDialer; + -(void) registerLogView:(id) view; -(void) startLibLinphone; diff --git a/Classes/LinphoneUI/LinphoneManager.m b/Classes/LinphoneUI/LinphoneManager.m index adf367d07..195058561 100644 --- a/Classes/LinphoneUI/LinphoneManager.m +++ b/Classes/LinphoneUI/LinphoneManager.m @@ -65,23 +65,9 @@ extern void libmsbcg729_init(); return self; } +(LinphoneManager*) instance { - if (theLinphoneManager==nil) { - [[LinphoneManager alloc] init]; - } return theLinphoneManager; } --(NSString*) appendCountryCodeIfPossible:(NSString*) number { - if (![number hasPrefix:@"+"] && ![number hasPrefix:@"00"]) { - NSString* lCountryCode = [[NSUserDefaults standardUserDefaults] stringForKey:@"countrycode_preference"]; - if (lCountryCode && [lCountryCode length]>0) { - //append country code - return [lCountryCode stringByAppendingString:number]; - } - } - return number; -} - -(NSString*) getDisplayNameFromAddressBook:(NSString*) number andUpdateCallLog:(LinphoneCallLog*)log { //1 normalize NSString* lNormalizedNumber = [FastAddressBook normalizePhoneNumber:number]; @@ -152,6 +138,7 @@ extern void libmsbcg729_init(); [lE164Number release]; return; } + -(void) onCall:(LinphoneCall*) call StateChanged: (LinphoneCallState) new_state withMessage: (const char *) message { const char* lUserNameChars=linphone_address_get_username(linphone_call_get_remote_address(call)); NSString* lUserName = lUserNameChars?[[[NSString alloc] initWithUTF8String:lUserNameChars] autorelease]:NSLocalizedString(@"Unknown",nil); @@ -163,17 +150,13 @@ extern void libmsbcg729_init(); bool canHideInCallView = (linphone_core_get_calls([LinphoneManager getLc]) == NULL); - switch (new_state) { - - case LinphoneCallStreamsRunning: - //check video - if (linphone_call_params_video_enabled(linphone_call_get_current_params(call))) { - [callDelegate displayVideoCall:call FromUI:mCurrentViewController - forUser:lUserName - withDisplayName:lDisplayName]; - } - break; - + if (!linphone_call_get_user_pointer(call)) { + LinphoneCallAppData* data = (LinphoneCallAppData*) malloc(sizeof(LinphoneCallAppData)); + data->batteryWarningShown = FALSE; + linphone_call_set_user_pointer(call, data); + } + + switch (new_state) { case LinphoneCallIncomingReceived: [callDelegate displayIncomingCall:call NotificationFromUI:mCurrentViewController @@ -187,14 +170,38 @@ extern void libmsbcg729_init(); forUser:lUserName withDisplayName:lDisplayName]; break; - + case LinphoneCallPausedByRemote: case LinphoneCallConnected: [callDelegate displayInCall: call FromUI:mCurrentViewController forUser:lUserName withDisplayName:lDisplayName]; break; - + case LinphoneCallUpdatedByRemote: + { + const LinphoneCallParams* current = linphone_call_get_current_params(call); + const LinphoneCallParams* remote = linphone_call_get_remote_params(call); + + /* remote wants to add video */ + if (!linphone_call_params_video_enabled(current) && linphone_call_params_video_enabled(remote) && !linphone_core_get_video_policy(theLinphoneCore)->automatically_accept) { + linphone_core_defer_call_update(theLinphoneCore, call); + [callDelegate displayAskToEnableVideoCall:call forUser:lUserName withDisplayName:lDisplayName]; + } else if (linphone_call_params_video_enabled(current) && !linphone_call_params_video_enabled(remote)) { + [callDelegate displayInCall:call FromUI:mCurrentViewController forUser:lUserName withDisplayName:lDisplayName]; + } + break; + } + case LinphoneCallUpdated: + { + const LinphoneCallParams* current = linphone_call_get_current_params(call); + if (linphone_call_params_video_enabled(current)) { + [callDelegate displayVideoCall:call FromUI:mCurrentViewController forUser:lUserName withDisplayName:lDisplayName]; + } else { + [callDelegate displayInCall:call FromUI:mCurrentViewController forUser:lUserName withDisplayName:lDisplayName]; + } + break; + + } case LinphoneCallError: { /* NSString* lTitle= state->message!=nil?[NSString stringWithCString:state->message length:strlen(state->message)]: @"Error"; @@ -251,12 +258,31 @@ extern void libmsbcg729_init(); withDisplayName:lDisplayName]; } break; - default: + case LinphoneCallStreamsRunning: + //check video + if (linphone_call_params_video_enabled(linphone_call_get_current_params(call))) { + [callDelegate displayVideoCall:call FromUI:mCurrentViewController + forUser:lUserName + withDisplayName:lDisplayName]; + } else { + [callDelegate displayInCall:call FromUI:mCurrentViewController forUser:lUserName withDisplayName:lDisplayName]; + } break; + case LinphoneCallReleased: + free (linphone_call_get_user_pointer(call)); + break; + default: + break; } } +-(void) displayDialer { + [callDelegate displayDialerFromUI:mCurrentViewController + forUser:@"" + withDisplayName:@""]; +} + +(LinphoneCore*) getLc { if (theLinphoneCore==nil) { @throw([NSException exceptionWithName:@"LinphoneCoreException" reason:@"Linphone core not initialized yet" userInfo:nil]); @@ -311,13 +337,18 @@ static void linphone_iphone_call_state(LinphoneCore *lc, LinphoneCall* call, Lin LinphoneCallPausedByRemote */ [(LinphoneManager*)linphone_core_get_user_data(lc) onCall:call StateChanged: state withMessage: message]; - - - +} + +static void linphone_iphone_transfer_state_changed(LinphoneCore* lc, LinphoneCall* call, LinphoneCallState state) { + /* + LinhoneCallOutgoingProgress -> SalReferTrying + LinphoneCallConnected -> SalReferSuccess + LinphoneCallError -> SalReferFailed | * + */ } -(void) onRegister:(LinphoneCore *)lc cfg:(LinphoneProxyConfig*) cfg state:(LinphoneRegistrationState) state message:(const char*) message { - NSLog(@"NEW REGISTRATION STATE: '%s' (message: '%s')", linphone_registration_state_to_string(state), message); + ms_warning("NEW REGISTRATION STATE: '%s' (message: '%s')", linphone_registration_state_to_string(state), message); LinphoneAddress* lAddress = linphone_address_new(linphone_proxy_config_get_identity(cfg)); NSString* lUserName = linphone_address_get_username(lAddress)? [[NSString alloc] initWithUTF8String:linphone_address_get_username(lAddress) ]:@""; @@ -378,6 +409,7 @@ static void linphone_iphone_call_state(LinphoneCore *lc, LinphoneCall* call, Lin static void linphone_iphone_registration_state(LinphoneCore *lc, LinphoneProxyConfig* cfg, LinphoneRegistrationState state,const char* message) { [(LinphoneManager*)linphone_core_get_user_data(lc) onRegister:lc cfg:cfg state:state message:message]; } + static LinphoneCoreVTable linphonec_vtable = { .show =NULL, .call_state_changed =(LinphoneCallStateCb)linphone_iphone_call_state, @@ -390,7 +422,8 @@ static LinphoneCoreVTable linphonec_vtable = { .display_warning=linphone_iphone_log, .display_url=NULL, .text_received=NULL, - .dtmf_received=NULL + .dtmf_received=NULL, + .transfer_state_changed=linphone_iphone_transfer_state_changed }; @@ -448,7 +481,7 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach -(BOOL) reconfigureLinphoneIfNeeded:(NSDictionary *)settings { if (theLinphoneCore==nil) { - ms_warning("cannot configure linphone beacause not initialized yet"); + ms_warning("cannot configure linphone because not initialized yet"); return NO; } @@ -518,7 +551,7 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach transportValue.tcp_port=0; transportValue.udp_port=0; } else { - ms_error("unexpected trasnport [%s]",[transport cStringUsingEncoding:[NSString defaultCStringEncoding]]); + ms_error("unexpected transport [%s]",[transport cStringUsingEncoding:[NSString defaultCStringEncoding]]); } if (linphone_core_set_sip_transports(theLinphoneCore, &transportValue)) { ms_error("cannot set transport"); @@ -668,6 +701,11 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach linphone_core_set_firewall_policy(theLinphoneCore, LinphonePolicyNoFirewall); } + LinphoneVideoPolicy policy; + policy.automatically_accept = [[NSUserDefaults standardUserDefaults] boolForKey:@"start_video_preference"];; + policy.automatically_initiate = [[NSUserDefaults standardUserDefaults] boolForKey:@"start_video_preference"]; + linphone_core_set_video_policy(theLinphoneCore, &policy); + UIDevice* device = [UIDevice currentDevice]; bool backgroundSupported = false; if ([device respondsToSelector:@selector(isMultitaskingSupported)]) diff --git a/Classes/LinphoneUI/LinphoneUIDelegates.h b/Classes/LinphoneUI/LinphoneUIDelegates.h index 1f2938cfe..4d6b0477d 100644 --- a/Classes/LinphoneUI/LinphoneUIDelegates.h +++ b/Classes/LinphoneUI/LinphoneUIDelegates.h @@ -28,6 +28,8 @@ -(void) displayVideoCall:(LinphoneCall*) call FromUI:(UIViewController*) viewCtrl forUser:(NSString*) username withDisplayName:(NSString*) displayName; //status reporting -(void) displayStatus:(NSString*) message; +-(void) displayAskToEnableVideoCall:(LinphoneCall*) call forUser:(NSString*) username withDisplayName:(NSString*) displayName; +-(void) firstVideoFrameDecoded:(LinphoneCall*) call; @end diff --git a/Classes/LinphoneUI/UICallButton.h b/Classes/LinphoneUI/UICallButton.h index f5dc0db54..5fc1547fb 100644 --- a/Classes/LinphoneUI/UICallButton.h +++ b/Classes/LinphoneUI/UICallButton.h @@ -22,7 +22,11 @@ @interface UICallButton : UIButton { @private - UITextField* mAddress; + UITextField* mAddress; } -(void) initWithAddress:(UITextField*) address; + ++(void) enableTransforMode:(BOOL) enable; ++(BOOL) transforModeEnabled; + @end diff --git a/Classes/LinphoneUI/UICallButton.m b/Classes/LinphoneUI/UICallButton.m index 9b1fbf68d..6957344e5 100644 --- a/Classes/LinphoneUI/UICallButton.m +++ b/Classes/LinphoneUI/UICallButton.m @@ -23,6 +23,17 @@ @implementation UICallButton + +static BOOL transferMode = NO; + ++(void) enableTransforMode:(BOOL) enable { + transferMode = enable; +} + ++(BOOL) transforModeEnabled { + return transferMode; +} + -(void) touchUp:(id) sender { if (!linphone_core_is_network_reachabled([LinphoneManager getLc])) { UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Network Error",nil) @@ -54,13 +65,16 @@ LinphoneProxyConfig* proxyCfg; //get default proxy linphone_core_get_default_proxy([LinphoneManager getLc],&proxyCfg); - bool startVideo = [[NSUserDefaults standardUserDefaults] boolForKey:@"start_video_preference"]; LinphoneCallParams* lcallParams = linphone_core_create_default_call_parameters([LinphoneManager getLc]); - linphone_call_params_enable_video(lcallParams,startVideo&linphone_core_video_enabled([LinphoneManager getLc])); if ([mAddress.text length] == 0) return; //just return if ([mAddress.text hasPrefix:@"sip:"]) { - linphone_core_invite_with_params([LinphoneManager getLc],[mAddress.text cStringUsingEncoding:[NSString defaultCStringEncoding]],lcallParams); + if (transferMode) { + linphone_core_transfer_call([LinphoneManager getLc], linphone_core_get_current_call([LinphoneManager getLc]), [mAddress.text cStringUsingEncoding:[NSString defaultCStringEncoding]]); + } else { + linphone_core_invite_with_params([LinphoneManager getLc],[mAddress.text cStringUsingEncoding:[NSString defaultCStringEncoding]],lcallParams); + } + [UICallButton enableTransforMode:NO]; } else if ( proxyCfg==nil){ UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Invalid sip address",nil) message:NSLocalizedString(@"Either configure a SIP proxy server from settings prior to place a call or use a valid sip address (I.E sip:john@example.net)",nil) @@ -80,12 +94,16 @@ linphone_address_set_display_name(tmpAddress,(lDisplayName)?[lDisplayName cStringUsingEncoding:[NSString defaultCStringEncoding]]:nil); - - linphone_core_invite_address_with_params([LinphoneManager getLc],tmpAddress,lcallParams) ; + if (transferMode) { + linphone_core_transfer_call([LinphoneManager getLc], linphone_core_get_current_call([LinphoneManager getLc]), normalizedUserName); + } else { + linphone_core_invite_address_with_params([LinphoneManager getLc],tmpAddress,lcallParams) ; + } linphone_address_destroy(tmpAddress); } linphone_call_params_destroy(lcallParams); + [UICallButton enableTransforMode:NO]; } else if (linphone_core_inc_invite_pending([LinphoneManager getLc])) { linphone_core_accept_call([LinphoneManager getLc],linphone_core_get_current_call([LinphoneManager getLc])); } @@ -102,6 +120,7 @@ */ -(void) initWithAddress:(UITextField*) address{ mAddress=[address retain]; + transferMode = NO; [self addTarget:self action:@selector(touchUp:) forControlEvents:UIControlEventTouchUpInside]; } diff --git a/Classes/LinphoneUI/UICamSwitch.m b/Classes/LinphoneUI/UICamSwitch.m index 45c208c4d..aa0f5e51d 100644 --- a/Classes/LinphoneUI/UICamSwitch.m +++ b/Classes/LinphoneUI/UICamSwitch.m @@ -25,7 +25,7 @@ @synthesize preview; -(void) touchUp:(id) sender { if (nextCamId!=currentCamId) { - ms_message("Swithcing from [%s] to [%s]",currentCamId,nextCamId); + ms_message("Switching from [%s] to [%s]",currentCamId,nextCamId); linphone_core_set_video_device([LinphoneManager getLc], nextCamId); nextCamId=currentCamId; currentCamId = linphone_core_get_video_device([LinphoneManager getLc]); diff --git a/Classes/LinphoneUI/UIAddVideoButton.h b/Classes/LinphoneUI/UIToggleVideoButton.h similarity index 84% rename from Classes/LinphoneUI/UIAddVideoButton.h rename to Classes/LinphoneUI/UIToggleVideoButton.h index 275de0672..37a712ddd 100644 --- a/Classes/LinphoneUI/UIAddVideoButton.h +++ b/Classes/LinphoneUI/UIToggleVideoButton.h @@ -1,4 +1,4 @@ -/* UIAddVideoButton.h +/* UIToggleVideoButton.h * * Copyright (C) 2011 Belledonne Comunications, Grenoble, France * @@ -19,6 +19,12 @@ #import -@interface UIAddVideoButton : UIButton +@interface UIToggleVideoButton : UIButton { + UIActivityIndicatorView* videoUpdateIndicator; +} + - (id)initWithCoder:(NSCoder *)decoder; + +@property (nonatomic, retain) IBOutlet UIActivityIndicatorView* videoUpdateIndicator; + @end diff --git a/Classes/LinphoneUI/UIAddVideoButton.m b/Classes/LinphoneUI/UIToggleVideoButton.m similarity index 72% rename from Classes/LinphoneUI/UIAddVideoButton.m rename to Classes/LinphoneUI/UIToggleVideoButton.m index e34cdfb8f..1c96079a3 100644 --- a/Classes/LinphoneUI/UIAddVideoButton.m +++ b/Classes/LinphoneUI/UIToggleVideoButton.m @@ -1,4 +1,4 @@ -/* UIAddVideoButton.m +/* UIToggleVideoButton.m * * Copyright (C) 2011 Belledonne Comunications, Grenoble, France * @@ -17,21 +17,37 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#import "UIAddVideoButton.h" +#import "UIToggleVideoButton.h" #include "LinphoneManager.h" -@implementation UIAddVideoButton +@implementation UIToggleVideoButton + +@synthesize videoUpdateIndicator; -(void) touchUp:(id) sender { LinphoneCore* lc = [LinphoneManager getLc]; + + if (!linphone_core_video_enabled(lc)) + return; + + [videoUpdateIndicator startAnimating]; + videoUpdateIndicator.hidden = NO; + self.enabled = NO; + LinphoneCall* call = linphone_core_get_current_call([LinphoneManager getLc]); if (call) { LinphoneCallParams* call_params = linphone_call_params_copy(linphone_call_get_current_params(call)); - linphone_call_params_enable_video(call_params, TRUE); + if (linphone_call_params_video_enabled(call_params)) { + ms_message("Disabling video"); + linphone_call_params_enable_video(call_params, FALSE); + } else { + ms_message("Enabling video"); + linphone_call_params_enable_video(call_params, TRUE); + } linphone_core_update_call(lc, call, call_params); linphone_call_params_destroy(call_params); - } { - ms_warning("Cannot add video, because no current call"); + } else { + ms_warning("Cannot toggle video, because no current call"); } } diff --git a/Classes/LinphoneUI/VideoZoomHandler.h b/Classes/LinphoneUI/VideoZoomHandler.h new file mode 100644 index 000000000..6065d2453 --- /dev/null +++ b/Classes/LinphoneUI/VideoZoomHandler.h @@ -0,0 +1,18 @@ +// +// VideoZoomHandler.h +// linphone +// +// Created by Pierre-Eric Pelloux-Prayer on 25/04/12. +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#import + +@interface VideoZoomHandler : NSObject { + float zoomLevel, cx, cy; + UIView* videoView; +} +-(void) setup: (UIView*) videoView; +-(void) resetZoom; + +@end diff --git a/Classes/LinphoneUI/VideoZoomHandler.m b/Classes/LinphoneUI/VideoZoomHandler.m new file mode 100644 index 000000000..fb238fc69 --- /dev/null +++ b/Classes/LinphoneUI/VideoZoomHandler.m @@ -0,0 +1,101 @@ +// +// VideoZoomHandler.m +// linphone +// +// Created by Pierre-Eric Pelloux-Prayer on 25/04/12. +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#import "VideoZoomHandler.h" +#include "linphonecore.h" +#import "LinphoneManager.h" + +@implementation VideoZoomHandler + + +-(void) zoomInOut:(UITapGestureRecognizer*) reco { + if (zoomLevel != 1) + zoomLevel = 1; + else + zoomLevel = 2; + + if (zoomLevel != 1) { + CGPoint point = [reco locationInView:videoView]; + cx = point.x / videoView.frame.size.width; + cy = 1 - point.y / videoView.frame.size.height; + } else { + cx = cy = 0.5; + } + linphone_call_zoom_video(linphone_core_get_current_call([LinphoneManager getLc]), zoomLevel, cx, cy); +} + +-(void) videoPan:(UIPanGestureRecognizer*) reco { + if (zoomLevel <= 1.0) + return; + + float x,y; + CGPoint translation = [reco translationInView:videoView]; + if ([reco state] == UIGestureRecognizerStateEnded) { + cx -= translation.x / videoView.frame.size.width; + cy += translation.y / videoView.frame.size.height; + x = cx; + y = cy; + } else if ([reco state] == UIGestureRecognizerStateChanged) { + x = cx - translation.x / videoView.frame.size.width; + y = cy + translation.y / videoView.frame.size.height; + } else { + return; + } + + linphone_call_zoom_video(linphone_core_get_current_call([LinphoneManager getLc]), zoomLevel, x, y); +} + +-(void) pinch:(UIPinchGestureRecognizer*) reco { + float s = zoomLevel; + // CGPoint point = [reco locationInView:videoGroup]; + // float ccx = cx + (point.x / videoGroup.frame.size.width - 0.5) / s; + // float ccy = cy - (point.y / videoGroup.frame.size.height - 0.5) / s; + if ([reco state] == UIGestureRecognizerStateEnded) { + zoomLevel = MAX(MIN(zoomLevel * reco.scale, 3.0), 1.0); + s = zoomLevel; + // cx = ccx; + // cy = ccy; + } else if ([reco state] == UIGestureRecognizerStateChanged) { + s = zoomLevel * reco.scale; + s = MAX(MIN(s, 3.0), 1.0); + } else if ([reco state] == UIGestureRecognizerStateBegan) { + + } else { + return; + } + + + linphone_call_zoom_video(linphone_core_get_current_call([LinphoneManager getLc]), s, cx, cy); +} + +-(void) resetZoom { + zoomLevel = 1; + cx = cy = 0.5; +} + + +-(void) setup: (UIView*) view { + videoView = view; + + UITapGestureRecognizer* doubleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(zoomInOut:)]; + [doubleFingerTap setNumberOfTapsRequired:2]; + [doubleFingerTap setNumberOfTouchesRequired:1]; + [videoView addGestureRecognizer:doubleFingerTap]; + + UIPanGestureRecognizer* pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(videoPan:)]; + [videoView addGestureRecognizer:pan]; + UIPinchGestureRecognizer* pinchReco = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinch:)]; + [videoView addGestureRecognizer:pinchReco]; + + [doubleFingerTap release]; + [pan release]; + [pinchReco release]; + + [self resetZoom]; +} +@end diff --git a/Classes/MainScreenWithVideoPreview.m b/Classes/MainScreenWithVideoPreview.m index a9629a990..f4c6859e9 100644 --- a/Classes/MainScreenWithVideoPreview.m +++ b/Classes/MainScreenWithVideoPreview.m @@ -18,6 +18,7 @@ */ #import "MainScreenWithVideoPreview.h" #import +#import "LinphoneUI/LinphoneManager.h" @implementation MainScreenWithVideoPreview @synthesize window; @@ -71,12 +72,7 @@ - (void)viewDidLoad { [super viewDidLoad]; - - bool enableVideo = [[NSUserDefaults standardUserDefaults] boolForKey:@"enable_video_preference"]; - - if (enableVideo) { - [self initVideoPreview ]; - } + [phoneMainView.switchCamera addTarget:self action:@selector(switchCameraPressed) forControlEvents:UIControlEventTouchUpInside]; } -(void) switchCameraPressed { @@ -93,6 +89,10 @@ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc]init]; NSArray* array = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; + if ( [array count] == 0) { + ms_warning("No camera available (running on simulator ?"); + return; + } currentCamera = camIndex % [array count]; AVCaptureDevice* device = (AVCaptureDevice*) [array objectAtIndex:currentCamera]; input = [[AVCaptureDeviceInput deviceInputWithDevice:device @@ -106,19 +106,28 @@ [session startRunning]; } +-(void) startPreview:(id) a { + [window addSubview:self.view]; + [window sendSubviewToBack:self.view]; + [session startRunning]; +} + -(void) showPreview:(BOOL) show { bool enableVideo = [[NSUserDefaults standardUserDefaults] boolForKey:@"enable_video_preference"]; if (enableVideo) { + LinphoneCall* call = linphone_core_get_current_call([LinphoneManager getLc]); + if (show && call && linphone_call_params_video_enabled(linphone_call_get_current_params(call))) { + return; + } + if (session == nil) { [self initVideoPreview]; } if (show && !session.running) { - [window addSubview:self.view]; - [window sendSubviewToBack:self.view]; - [session startRunning]; + [self performSelectorInBackground:@selector(startPreview:) withObject:nil]; } else if (!show && session.running) { [self.view removeFromSuperview]; [session stopRunning]; @@ -131,8 +140,7 @@ } -(void) viewDidAppear:(BOOL)animated { - [phoneMainView.switchCamera addTarget:self action:@selector(switchCameraPressed) forControlEvents:UIControlEventTouchUpInside]; - + [super viewDidAppear:animated]; } -(void) viewDidDisappear:(BOOL)animated { diff --git a/Classes/PhoneViewController-ipad.xib b/Classes/PhoneViewController-ipad.xib index 824edbf14..fc15c4af0 100644 --- a/Classes/PhoneViewController-ipad.xib +++ b/Classes/PhoneViewController-ipad.xib @@ -163,7 +163,6 @@ IBIPadFramework 0 0 - 1 Back diff --git a/Classes/PhoneViewController.m b/Classes/PhoneViewController.m index cb803e988..e39d32ad4 100644 --- a/Classes/PhoneViewController.m +++ b/Classes/PhoneViewController.m @@ -77,7 +77,7 @@ if (config == NULL) { s = LinphoneRegistrationNone; - m = @"No SIP account configured"; + m = linphone_core_is_network_reachabled([LinphoneManager getLc]) ? NSLocalizedString(@"No SIP account configured", nil) : NSLocalizedString(@"Network down", nil); } else { s = linphone_proxy_config_get_state(config); @@ -103,9 +103,12 @@ bool zeroCall = (linphone_core_get_calls_nb([LinphoneManager getLc]) == 0); [LinphoneManager set:callLarge hidden:!zeroCall withName:"CALL_LARGE button" andReason:__FUNCTION__]; + [LinphoneManager set:switchCamera hidden:!zeroCall withName:"SWITCH_CAM button" andReason:__FUNCTION__]; [LinphoneManager set:callShort hidden:zeroCall withName:"CALL_SHORT button" andReason:__FUNCTION__]; [LinphoneManager set:backToCallView hidden:zeroCall withName:"BACK button" andReason:__FUNCTION__]; + [callShort setTitle:[UICallButton transforModeEnabled] ? @"transfer":@"call" forState:UIControlStateNormal]; + if (!callShort.hidden) [callShort setEnabled:!linphone_core_sound_resources_locked([LinphoneManager getLc])]; } @catch (NSException* exc) { @@ -120,6 +123,7 @@ - (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; if ([[NSUserDefaults standardUserDefaults] boolForKey:@"enable_first_login_view_preference"] == true) { myFirstLoginViewController = [[FirstLoginViewController alloc] initWithNibName:@"FirstLoginViewController" bundle:[NSBundle mainBundle]]; @@ -195,6 +199,7 @@ -(void)viewWillAppear:(BOOL)animated { [self updateCallAndBackButtons]; + [super viewWillAppear:animated]; } -(void) displayDialerFromUI:(UIViewController*) viewCtrl forUser:(NSString*) username withDisplayName:(NSString*) displayName { @@ -230,7 +235,6 @@ [myTabBarController setSelectedIndex:DIALER_TAB_INDEX]; [mMainScreenWithVideoPreview showPreview:YES]; - } //status reporting @@ -258,6 +262,7 @@ } } else { CallDelegate* cd = [[CallDelegate alloc] init]; + cd.eventType = CD_NEW_CALL; cd.delegate = self; cd.call = call; @@ -283,10 +288,19 @@ } -(void) backToCallViewPressed { - [self displayInCall: nil + [UICallButton enableTransforMode:NO]; + [self presentModalViewController:(UIViewController*)mIncallViewController animated:true]; + + LinphoneCall* call = linphone_core_get_current_call([LinphoneManager getLc]); + + if (!call || !linphone_call_params_video_enabled(linphone_call_get_current_params(call)) || linphone_call_get_state(call) != LinphoneCallStreamsRunning) { + [self displayInCall: call FromUI:nil forUser:nil withDisplayName:nil]; + } else { + [self displayVideoCall:call FromUI:nil forUser:nil withDisplayName:nil]; + } } -(void) displayCall: (LinphoneCall*) call InProgressFromUI:(UIViewController*) viewCtrl forUser:(NSString*) username withDisplayName:(NSString*) displayName { @@ -313,8 +327,11 @@ withDisplayName:displayName]; [LinphoneManager set:callLarge hidden:YES withName:"CALL_LARGE button" andReason:__FUNCTION__]; + [LinphoneManager set:switchCamera hidden:YES withName:"SWITCH_CAMERA button" andReason:__FUNCTION__]; [LinphoneManager set:callShort hidden:NO withName:"CALL_SHORT button" andReason:__FUNCTION__]; [LinphoneManager set:backToCallView hidden:NO withName:"CALL_BACK button" andReason:__FUNCTION__]; + + [self updateCallAndBackButtons]; } @@ -324,11 +341,19 @@ withDisplayName:displayName]; [mMainScreenWithVideoPreview showPreview:NO]; + [self updateCallAndBackButtons]; +} + +-(void) displayAskToEnableVideoCall:(LinphoneCall*) call forUser:(NSString*) username withDisplayName:(NSString*) displayName { + [mIncallViewController displayAskToEnableVideoCall:call forUser:username withDisplayName:displayName]; } -- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex withUserDatas:(void *)datas{ +- (void)actionSheet:(UIActionSheet *)actionSheet ofType:(enum CallDelegateType)type clickedButtonAtIndex:(NSInteger)buttonIndex withUserDatas:(void *)datas { + if (type != CD_NEW_CALL) + return; + LinphoneCall* call = (LinphoneCall*)datas; if (buttonIndex == actionSheet.destructiveButtonIndex ) { linphone_core_accept_call([LinphoneManager getLc],call); @@ -388,5 +413,9 @@ [self updateStatusSubView]; } +-(void) firstVideoFrameDecoded: (LinphoneCall*) call { + [mIncallViewController firstVideoFrameDecoded:call]; +} + @end diff --git a/Classes/VideoViewController.xib b/Classes/VideoViewController.xib index cd1e2025e..f7c680281 100644 --- a/Classes/VideoViewController.xib +++ b/Classes/VideoViewController.xib @@ -40,7 +40,6 @@ 292 {320, 460} - 1 MCAwIDAAA @@ -129,7 +128,6 @@ 292 {{211, 418}, {108, 62}} - NO IBCocoaTouchFramework 0 @@ -252,7 +250,6 @@ 292 {{420, 212}, {60, 108}} - NO IBCocoaTouchFramework 0 @@ -314,6 +311,19 @@ 274 + + YES + + + 292 + {{8, 285}, {28, 28}} + + + _NS:567 + NO + IBCocoaTouchFramework + + {{60, 0}, {420, 320}} @@ -392,7 +402,6 @@ 274 {{360, 233}, {106, 80}} - 3 MQA @@ -400,16 +409,6 @@ IBCocoaTouchFramework - - - 292 - {{68, 285}, {28, 28}} - - - _NS:567 - NO - IBCocoaTouchFramework - {480, 320} @@ -731,7 +730,6 @@ - @@ -780,17 +778,21 @@ display - - 59 - - - 39 + + YES + + display + + 59 + + + diff --git a/Resources/in_call.png b/Resources/in_call.png index d48369e6a..1e20bac2b 100644 Binary files a/Resources/in_call.png and b/Resources/in_call.png differ diff --git a/Resources/in_call_video.png b/Resources/in_call_video.png new file mode 100644 index 000000000..87fcb5b64 Binary files /dev/null and b/Resources/in_call_video.png differ diff --git a/Resources/missed_call.png b/Resources/missed_call.png index 315b49708..58d745612 100644 Binary files a/Resources/missed_call.png and b/Resources/missed_call.png differ diff --git a/Resources/out_call.png b/Resources/out_call.png index 7fef2b4ae..3077fdb08 100644 Binary files a/Resources/out_call.png and b/Resources/out_call.png differ diff --git a/Resources/out_call_video.png b/Resources/out_call_video.png new file mode 100644 index 000000000..fb6447f8e Binary files /dev/null and b/Resources/out_call_video.png differ diff --git a/Settings.bundle/Advanced.plist b/Settings.bundle/Advanced.plist index 977c1c36f..f535cadc8 100644 --- a/Settings.bundle/Advanced.plist +++ b/Settings.bundle/Advanced.plist @@ -88,6 +88,16 @@ Type PSToggleSwitchSpecifier + + DefaultValue + + Key + disable_autoboot_preference + Title + Disable application autostart + Type + PSToggleSwitchSpecifier + DefaultValue diff --git a/linphone.xcodeproj/project.pbxproj b/linphone.xcodeproj/project.pbxproj index 43720f891..76d09111c 100755 --- a/linphone.xcodeproj/project.pbxproj +++ b/linphone.xcodeproj/project.pbxproj @@ -117,8 +117,6 @@ 22BB1A69132FF16A005CD7AA /* UIEraseButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 22BB1A68132FF16A005CD7AA /* UIEraseButton.m */; }; 22C755601317E59C007BC101 /* UIBluetoothButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 22C7555F1317E59C007BC101 /* UIBluetoothButton.m */; }; 22D1B68112A3E0BE001AE361 /* libresolv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 22D1B68012A3E0BE001AE361 /* libresolv.dylib */; }; - 22D817AD147A9F33001CFB9C /* UIAddVideoButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 22D817AC147A9F33001CFB9C /* UIAddVideoButton.m */; }; - 22D817AE147A9F33001CFB9C /* UIAddVideoButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 22D817AC147A9F33001CFB9C /* UIAddVideoButton.m */; }; 22D8F11F147548E2008C97DB /* linphonerc in Resources */ = {isa = PBXBuildFile; fileRef = 2274550710700509006EC466 /* linphonerc */; }; 22D8F120147548E2008C97DB /* PhoneViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 22F2508D107141E100AC9B3F /* PhoneViewController.xib */; }; 22D8F121147548E2008C97DB /* ringback.wav in Resources */ = {isa = PBXBuildFile; fileRef = 22F254801073D99800AC9B3F /* ringback.wav */; }; @@ -218,6 +216,8 @@ 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; 340751971506459A00B89C47 /* CoreTelephony.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 340751961506459A00B89C47 /* CoreTelephony.framework */; }; 34075199150645A300B89C47 /* CoreTelephony.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 340751961506459A00B89C47 /* CoreTelephony.framework */; }; + 340751E7150F38FD00B89C47 /* UIToggleVideoButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 340751E6150F38FD00B89C47 /* UIToggleVideoButton.m */; }; + 340751E8150F38FD00B89C47 /* UIToggleVideoButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 340751E6150F38FD00B89C47 /* UIToggleVideoButton.m */; }; 340A75B014C0670B006AA708 /* ConferenceCallDetailView-ipad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 340A75AF14C0670A006AA708 /* ConferenceCallDetailView-ipad.xib */; }; 340A75B114C0670B006AA708 /* ConferenceCallDetailView-ipad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 340A75AF14C0670A006AA708 /* ConferenceCallDetailView-ipad.xib */; }; 3418843714C58BB100EA48C7 /* nowebcamCIF.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 3418843614C58BB100EA48C7 /* nowebcamCIF.jpg */; }; @@ -238,6 +238,8 @@ 3418845D14C7077400EA48C7 /* status_gray.png in Resources */ = {isa = PBXBuildFile; fileRef = 3418845B14C7077400EA48C7 /* status_gray.png */; }; 341FCA8E149798210084BC26 /* linphonerc-ipad in Resources */ = {isa = PBXBuildFile; fileRef = 341FCA8D149798210084BC26 /* linphonerc-ipad */; }; 341FCA8F149798210084BC26 /* linphonerc-ipad in Resources */ = {isa = PBXBuildFile; fileRef = 341FCA8D149798210084BC26 /* linphonerc-ipad */; }; + 34216F401547EBCD00EA9777 /* VideoZoomHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 34216F3F1547EBCD00EA9777 /* VideoZoomHandler.m */; }; + 34216F411547EBCD00EA9777 /* VideoZoomHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 34216F3F1547EBCD00EA9777 /* VideoZoomHandler.m */; }; 3422AA5014975EC9000D4E8A /* InCallViewController-ipad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3422AA4F14975EC9000D4E8A /* InCallViewController-ipad.xib */; }; 3422AA5114975EC9000D4E8A /* InCallViewController-ipad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3422AA4F14975EC9000D4E8A /* InCallViewController-ipad.xib */; }; 3422AA5314978352000D4E8A /* PhoneViewController-ipad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3422AA5214978352000D4E8A /* PhoneViewController-ipad.xib */; }; @@ -253,6 +255,8 @@ 344ABDE81484E723007420B6 /* libzrtpcpp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 344ABDE71484E723007420B6 /* libzrtpcpp.a */; }; 344ABDF114850AE9007420B6 /* libc++.1.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 344ABDEF14850AE9007420B6 /* libc++.1.dylib */; settings = {ATTRIBUTES = (Weak, ); }; }; 344ABDF214850AE9007420B6 /* libstdc++.6.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 344ABDF014850AE9007420B6 /* libstdc++.6.dylib */; settings = {ATTRIBUTES = (Weak, ); }; }; + 3485649F152C423F003FE041 /* in_call_video.png in Resources */ = {isa = PBXBuildFile; fileRef = 3485649D152C423F003FE041 /* in_call_video.png */; }; + 348564A0152C423F003FE041 /* out_call_video.png in Resources */ = {isa = PBXBuildFile; fileRef = 3485649E152C423F003FE041 /* out_call_video.png */; }; 34957F3F147D3FBF00DD7A09 /* secured.png in Resources */ = {isa = PBXBuildFile; fileRef = 34957F3E147D3FBF00DD7A09 /* secured.png */; }; 34A6ECEB14CF13CB00460C04 /* icone-linphone-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 34A6ECEA14CF13CB00460C04 /* icone-linphone-72.png */; }; 34C7646914CD51CD008E9607 /* contact_vide.png in Resources */ = {isa = PBXBuildFile; fileRef = 34C7646814CD51CD008E9607 /* contact_vide.png */; }; @@ -589,8 +593,6 @@ 22C7564A13265C6A007BC101 /* x509_vfy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = x509_vfy.h; sourceTree = ""; }; 22C7564B13265C6A007BC101 /* x509v3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = x509v3.h; sourceTree = ""; }; 22D1B68012A3E0BE001AE361 /* libresolv.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libresolv.dylib; path = usr/lib/libresolv.dylib; sourceTree = SDKROOT; }; - 22D817AB147A9F33001CFB9C /* UIAddVideoButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIAddVideoButton.h; sourceTree = ""; }; - 22D817AC147A9F33001CFB9C /* UIAddVideoButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIAddVideoButton.m; sourceTree = ""; }; 22D8F187147548E2008C97DB /* linphone-no-gpl-thirdparties.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "linphone-no-gpl-thirdparties.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 22E028B413B4CCBD0068A713 /* VideoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoViewController.h; sourceTree = ""; }; 22E028B513B4CCBD0068A713 /* VideoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VideoViewController.m; sourceTree = ""; }; @@ -614,6 +616,9 @@ 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 32CA4F630368D1EE00C91783 /* linphone_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = linphone_Prefix.pch; sourceTree = ""; }; 340751961506459A00B89C47 /* CoreTelephony.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreTelephony.framework; path = System/Library/Frameworks/CoreTelephony.framework; sourceTree = SDKROOT; }; + 340751E4150E4D0200B89C47 /* CallDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallDelegate.h; sourceTree = ""; }; + 340751E5150F38FC00B89C47 /* UIToggleVideoButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIToggleVideoButton.h; sourceTree = ""; }; + 340751E6150F38FD00B89C47 /* UIToggleVideoButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIToggleVideoButton.m; sourceTree = ""; }; 340A75AF14C0670A006AA708 /* ConferenceCallDetailView-ipad.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = "ConferenceCallDetailView-ipad.xib"; sourceTree = ""; }; 3418843614C58BB100EA48C7 /* nowebcamCIF.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = nowebcamCIF.jpg; path = submodules/linphone/mediastreamer2/src/nowebcamCIF.jpg; sourceTree = ""; }; 3418844514C6CAD300EA48C7 /* StatusSubViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StatusSubViewController.h; sourceTree = ""; }; @@ -625,6 +630,8 @@ 3418845214C6F66F00EA48C7 /* status_red.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = status_red.png; path = Resources/status_red.png; sourceTree = ""; }; 3418845B14C7077400EA48C7 /* status_gray.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = status_gray.png; path = Resources/status_gray.png; sourceTree = ""; }; 341FCA8D149798210084BC26 /* linphonerc-ipad */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "linphonerc-ipad"; sourceTree = ""; }; + 34216F3E1547EBCD00EA9777 /* VideoZoomHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VideoZoomHandler.h; path = LinphoneUI/VideoZoomHandler.h; sourceTree = ""; }; + 34216F3F1547EBCD00EA9777 /* VideoZoomHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VideoZoomHandler.m; path = LinphoneUI/VideoZoomHandler.m; sourceTree = ""; }; 3422AA4F14975EC9000D4E8A /* InCallViewController-ipad.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = "InCallViewController-ipad.xib"; sourceTree = ""; }; 3422AA5214978352000D4E8A /* PhoneViewController-ipad.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = "PhoneViewController-ipad.xib"; sourceTree = ""; }; 344ABD71147FC438007420B6 /* ConferenceCallDetailView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ConferenceCallDetailView.xib; sourceTree = ""; }; @@ -635,6 +642,8 @@ 344ABDE71484E723007420B6 /* libzrtpcpp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libzrtpcpp.a; path = "liblinphone-sdk/apple-darwin/lib/libzrtpcpp.a"; sourceTree = ""; }; 344ABDEF14850AE9007420B6 /* libc++.1.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libc++.1.dylib"; path = "usr/lib/libc++.1.dylib"; sourceTree = SDKROOT; }; 344ABDF014850AE9007420B6 /* libstdc++.6.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libstdc++.6.dylib"; path = "usr/lib/libstdc++.6.dylib"; sourceTree = SDKROOT; }; + 3485649D152C423F003FE041 /* in_call_video.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = in_call_video.png; path = Resources/in_call_video.png; sourceTree = ""; }; + 3485649E152C423F003FE041 /* out_call_video.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = out_call_video.png; path = Resources/out_call_video.png; sourceTree = ""; }; 34957F3E147D3FBF00DD7A09 /* secured.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = secured.png; path = Resources/secured.png; sourceTree = ""; }; 34A6ECEA14CF13CB00460C04 /* icone-linphone-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "icone-linphone-72.png"; path = "Resources/icone-linphone-72.png"; sourceTree = ""; }; 34C7646814CD51CD008E9607 /* contact_vide.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contact_vide.png; path = Resources/contact_vide.png; sourceTree = ""; }; @@ -752,6 +761,7 @@ 080E96DDFE201D6D7F000001 /* Classes */ = { isa = PBXGroup; children = ( + 340751E4150E4D0200B89C47 /* CallDelegate.h */, 2211DBBB14769C8200DEE054 /* CallDelegate.m */, 2214EB7012F84668002A5394 /* LinphoneUI */, 2218A92212FBE1340088A667 /* FirstLoginViewController.h */, @@ -795,6 +805,8 @@ 3418844514C6CAD300EA48C7 /* StatusSubViewController.h */, 3418844614C6CAD300EA48C7 /* StatusSubViewController.m */, 3418844714C6CAD300EA48C7 /* StatusSubViewController.xib */, + 34216F3E1547EBCD00EA9777 /* VideoZoomHandler.h */, + 34216F3F1547EBCD00EA9777 /* VideoZoomHandler.m */, ); path = Classes; sourceTree = ""; @@ -1007,6 +1019,8 @@ 2214EB7012F84668002A5394 /* LinphoneUI */ = { isa = PBXGroup; children = ( + 340751E5150F38FC00B89C47 /* UIToggleVideoButton.h */, + 340751E6150F38FD00B89C47 /* UIToggleVideoButton.m */, 2248E90C12F7E4CF00220D9C /* UIDigitButton.h */, 2248E90D12F7E4CF00220D9C /* UIDigitButton.m */, 2248E99D12F801C200220D9C /* LinphoneManager.h */, @@ -1034,8 +1048,6 @@ 223963161393CFAF001DE689 /* FastAddressBook.m */, 22AA8AFF13D83F6300B30535 /* UICamSwitch.h */, 22AA8B0013D83F6300B30535 /* UICamSwitch.m */, - 22D817AB147A9F33001CFB9C /* UIAddVideoButton.h */, - 22D817AC147A9F33001CFB9C /* UIAddVideoButton.m */, ); path = LinphoneUI; sourceTree = ""; @@ -1195,6 +1207,8 @@ 29B97317FDCFA39411CA2CEA /* Resources */ = { isa = PBXGroup; children = ( + 3485649D152C423F003FE041 /* in_call_video.png */, + 3485649E152C423F003FE041 /* out_call_video.png */, 34A6ECEA14CF13CB00460C04 /* icone-linphone-72.png */, 34C7646A14CD5585008E9607 /* dialer-orange.png */, 34C7646B14CD5585008E9607 /* history-orange.png */, @@ -1395,6 +1409,8 @@ 34C7646C14CD5585008E9607 /* dialer-orange.png in Resources */, 34C7646D14CD5585008E9607 /* history-orange.png in Resources */, 34A6ECEB14CF13CB00460C04 /* icone-linphone-72.png in Resources */, + 3485649F152C423F003FE041 /* in_call_video.png in Resources */, + 348564A0152C423F003FE041 /* out_call_video.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1497,10 +1513,11 @@ 22AA8B0113D83F6300B30535 /* UICamSwitch.m in Sources */, 2211DBBE14769C8300DEE054 /* CallDelegate.m in Sources */, 2211DBC014769CB200DEE054 /* IncallViewController.m in Sources */, - 22D817AD147A9F33001CFB9C /* UIAddVideoButton.m in Sources */, 344ABD77147FCB68007420B6 /* ConferenceCallDetailView.m in Sources */, 34CA8539148F692A00503C01 /* MainScreenWithVideoPreview.m in Sources */, 3418844814C6CAD300EA48C7 /* StatusSubViewController.m in Sources */, + 340751E7150F38FD00B89C47 /* UIToggleVideoButton.m in Sources */, + 34216F401547EBCD00EA9777 /* VideoZoomHandler.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1532,10 +1549,11 @@ 22D8F159147548E2008C97DB /* UICamSwitch.m in Sources */, 2211DBBF14769C8300DEE054 /* CallDelegate.m in Sources */, 2211DBC114769CB300DEE054 /* IncallViewController.m in Sources */, - 22D817AE147A9F33001CFB9C /* UIAddVideoButton.m in Sources */, 344ABD78147FCB68007420B6 /* ConferenceCallDetailView.m in Sources */, 34CA853A148F692A00503C01 /* MainScreenWithVideoPreview.m in Sources */, 3418844914C6CAD300EA48C7 /* StatusSubViewController.m in Sources */, + 340751E8150F38FD00B89C47 /* UIToggleVideoButton.m in Sources */, + 34216F411547EBCD00EA9777 /* VideoZoomHandler.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1574,7 +1592,7 @@ HAVE_SILK, ); GCC_THUMB_SUPPORT = NO; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_VERSION = com.apple.compilers.llvmgcc42; HEADER_SEARCH_PATHS = ( submodules/linphone/coreapi, submodules/linphone/mediastreamer2/include, @@ -1613,7 +1631,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 3.1; LIBRARY_SEARCH_PATHS = ""; LINK_WITH_STANDARD_LIBRARIES = YES; - PROVISIONING_PROFILE = "7EBE410C-11B9-4346-9977-2C3BEE43ED16"; + PROVISIONING_PROFILE = "32E63D15-36ED-474A-8157-8DD0770DF063"; SDKROOT = iphoneos; }; name = DistributionAdhoc; @@ -1640,7 +1658,7 @@ HAVE_SILK, ); GCC_THUMB_SUPPORT = NO; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_VERSION = com.apple.compilers.llvmgcc42; HEADER_SEARCH_PATHS = ( submodules/linphone/coreapi, submodules/linphone/mediastreamer2/include, @@ -1698,7 +1716,7 @@ submodules/externals/speex/include, ); INFOPLIST_FILE = "linphone-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 4.3; + IPHONEOS_DEPLOYMENT_TARGET = 4.0; LIBRARY_SEARCH_PATHS = ( "$(BUILT_PRODUCTS_DIR)", "\"$(SRCROOT)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins\"", @@ -1750,7 +1768,7 @@ submodules/externals/speex/include, ); INFOPLIST_FILE = "linphone-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 4.3; + IPHONEOS_DEPLOYMENT_TARGET = 4.0; LIBRARY_SEARCH_PATHS = ( "$(BUILT_PRODUCTS_DIR)", "\"$(SRCROOT)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins\"", @@ -1803,7 +1821,7 @@ submodules/externals/speex/include, ); INFOPLIST_FILE = "linphone-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 4.3; + IPHONEOS_DEPLOYMENT_TARGET = 4.0; LIBRARY_SEARCH_PATHS = ( "$(BUILT_PRODUCTS_DIR)", "\"$(SRCROOT)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins\"", @@ -1856,7 +1874,7 @@ submodules/externals/speex/include, ); INFOPLIST_FILE = "linphone-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 4.3; + IPHONEOS_DEPLOYMENT_TARGET = 4.0; LIBRARY_SEARCH_PATHS = ( "$(BUILT_PRODUCTS_DIR)", "\"$(SRCROOT)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins\"", @@ -1916,7 +1934,7 @@ HAVE_SILK, ); GCC_THUMB_SUPPORT = NO; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_VERSION = com.apple.compilers.llvmgcc42; HEADER_SEARCH_PATHS = ( submodules/linphone/coreapi, submodules/linphone/mediastreamer2/include, @@ -1983,7 +2001,7 @@ HAVE_SILK, ); GCC_THUMB_SUPPORT = NO; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_VERSION = com.apple.compilers.llvmgcc42; HEADER_SEARCH_PATHS = ( submodules/linphone/coreapi, submodules/linphone/mediastreamer2/include, diff --git a/linphonerc b/linphonerc index c9a14c5d3..6dd0d69b0 100644 --- a/linphonerc +++ b/linphonerc @@ -45,5 +45,5 @@ capture=1 show_local=0 enabled=1 size=qvga -display_filter_auto_rotate=0 +display_filter_auto_rotate=1 diff --git a/linphonerc-ipad b/linphonerc-ipad index 402f17b15..f537c1ee1 100644 --- a/linphonerc-ipad +++ b/linphonerc-ipad @@ -44,4 +44,5 @@ capture=1 show_local=0 enabled=1 size=vga +display_filter_auto_rotate=1 diff --git a/submodules/externals/libvpx b/submodules/externals/libvpx index c8df1656b..97495c5c5 160000 --- a/submodules/externals/libvpx +++ b/submodules/externals/libvpx @@ -1 +1 @@ -Subproject commit c8df1656bd94928059204242e778bd5b8b9dc7aa +Subproject commit 97495c5c5ced0ab5839a3026e0e528fa22c15d5a diff --git a/submodules/linphone b/submodules/linphone index 57d665e16..49631ae72 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit 57d665e1625c0c1c3872b92096d6b12e1217ecc2 +Subproject commit 49631ae72f33c9f667780d3b961344f61dee9889 diff --git a/submodules/msilbc b/submodules/msilbc index 3d49d56a5..fbb153573 160000 --- a/submodules/msilbc +++ b/submodules/msilbc @@ -1 +1 @@ -Subproject commit 3d49d56a596cf5611b43f7676af9103aacc11624 +Subproject commit fbb153573c0ccbda5e7191de9aa7d7d9e114b3d8