From af92b0a7e02aa72c28254811b0817d69c24a0165 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Mon, 12 Mar 2012 11:27:45 +0100 Subject: [PATCH 01/34] VideoViewController not used anymore --- Classes/IncallViewController.h | 10 ++ Classes/IncallViewController.m | 137 ++++++++++++++++++++++- Classes/IncallViewController.xib | 186 ++++++++++++++++++++----------- Classes/LinphoneAppDelegate.m | 5 +- 4 files changed, 269 insertions(+), 69 deletions(-) diff --git a/Classes/IncallViewController.h b/Classes/IncallViewController.h index a17617aa6..ac1081718 100644 --- a/Classes/IncallViewController.h +++ b/Classes/IncallViewController.h @@ -58,6 +58,10 @@ UIDigitButton* hash; UIButton* close; + UIView* videoGroup; + UIView* videoView; + UIView* videoPreview; + bool dismissed; NSTimer *durationRefreasher; @@ -79,6 +83,8 @@ 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; + + NSTimer* hideControlsTimer; } + (UIImage*) stat_sys_signal_0; @@ -124,4 +130,8 @@ @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; @end diff --git a/Classes/IncallViewController.m b/Classes/IncallViewController.m index b0bdf7cf7..1c3dd590b 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) @@ -63,6 +67,10 @@ const NSInteger SECURE_BUTTON_TAG=5; @synthesize hash; @synthesize videoViewController; +@synthesize videoGroup; +@synthesize videoView; +@synthesize videoPreview; + @synthesize addVideo; @@ -105,6 +113,76 @@ int callCount(LinphoneCore* lc) { return count; } + + +void addAnimationFadeTransition(UIView* view, float duration) { + CATransition* animation = [CATransition animation]; + animation.type = kCATransitionFromBottom; // kCATransitionFade; + animation.duration = duration; + [view.layer addAnimation:animation forKey:nil]; +} + +-(void) showControls:(id)sender { + if (hideControlsTimer) { + [hideControlsTimer invalidate]; + hideControlsTimer = nil; + } + // show controls + addAnimationFadeTransition(controlSubView, 0.2); + controlSubView.hidden = FALSE; + + addAnimationFadeTransition(hangUpView, 0.2); + hangUpView.hidden = FALSE; + + // hide controls in 5 sec + hideControlsTimer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(hideControls:) userInfo:nil repeats:NO]; +} + +-(void) hideControls:(id)sender { + addAnimationFadeTransition(controlSubView, 0.4); + controlSubView.hidden = TRUE; + addAnimationFadeTransition(hangUpView, 0.4); + hangUpView.hidden = TRUE; + + hideControlsTimer = nil; +} + +-(void) enableVideoDisplay { + [videoGroup setHidden:FALSE]; + [controlSubView setHidden:TRUE]; + [hangUpView setHidden:TRUE]; + [callTableView setHidden:TRUE]; + + linphone_core_set_native_video_window_id([LinphoneManager getLc],(unsigned long)videoView); + linphone_core_set_native_preview_window_id([LinphoneManager getLc],(unsigned long)videoPreview); + linphone_core_set_device_rotation([LinphoneManager getLc], 0); + + [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide]; + + static bool done = false; + if (!done) { + NSLog(@"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)); + NSLog(@"new center: %f %f", videoView.center.x, videoView.center.y); + done = true; + } + +} + +-(void) disableVideoDisplay { + [videoGroup setHidden:TRUE]; + [controlSubView setHidden:FALSE]; + [hangUpView setHidden:FALSE]; + [callTableView setHidden:FALSE]; + + if (hideControlsTimer != nil) { + [hideControlsTimer invalidate]; + hideControlsTimer = nil; + } + + [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone]; +} + -(void) updateUIFromLinphoneState:(UIViewController *)viewCtrl { activeCallCell = nil; [mute reset]; @@ -201,6 +279,10 @@ int callCount(LinphoneCore* lc) { } + UITapGestureRecognizer* singleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(showControls:)]; + [videoGroup addGestureRecognizer:singleFingerTap]; + [singleFingerTap release]; + mVideoShown=FALSE; mIncallViewIsReady=FALSE; mVideoIsPending=FALSE; @@ -208,6 +290,10 @@ int callCount(LinphoneCore* lc) { callTableView.rowHeight = 80; + [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:nil]; + + } -(void) addCallPressed { @@ -231,6 +317,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 +327,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]; + } } } } @@ -248,7 +342,32 @@ int callCount(LinphoneCore* lc) { [self updateUIFromLinphoneState: nil]; } --(void) viewWillAppear:(BOOL)animated {} +-(void) orientationChanged: (NSNotification*) notif { + int oldLinphoneOrientation = linphone_core_get_device_rotation([LinphoneManager getLc]); + UIDeviceOrientation orientation = [UIDevice currentDevice].orientation; + switch (orientation) { + case UIInterfaceOrientationPortrait: + linphone_core_set_device_rotation([LinphoneManager getLc], 0); + break; + case UIInterfaceOrientationLandscapeRight: + linphone_core_set_device_rotation([LinphoneManager getLc], 270); + break; + case UIInterfaceOrientationLandscapeLeft: + linphone_core_set_device_rotation([LinphoneManager getLc], 90); + break; + } + if ((oldLinphoneOrientation != linphone_core_get_device_rotation([LinphoneManager getLc])) + && linphone_core_get_current_call([LinphoneManager getLc])) { + linphone_core_set_native_video_window_id([LinphoneManager getLc],(unsigned long)videoView); + //Orientation has change, must call update call + linphone_core_update_call([LinphoneManager getLc], linphone_core_get_current_call([LinphoneManager getLc]), NULL); + } +} + +-(void) awakeFromNib +{ + +} -(void)viewDidAppear:(BOOL)animated { [[UIApplication sharedApplication] setIdleTimerDisabled:YES]; @@ -319,13 +438,14 @@ 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]; @@ -352,11 +472,14 @@ int callCount(LinphoneCore* lc) { if ([speaker isOn]) [speaker toggle]; } [self updateUIFromLinphoneState: nil]; - if (self.presentedViewController == (UIViewController*)mVideoViewController) { + + [self disableVideoDisplay]; + /*if (self.presentedViewController == (UIViewController*)mVideoViewController) { [self dismissVideoView]; - } + }*/ } -(void) displayDialerFromUI:(UIViewController*) viewCtrl forUser:(NSString*) username withDisplayName:(NSString*) displayName { + [self disableVideoDisplay]; UIViewController* modalVC = self.modalViewController; UIDevice *device = [UIDevice currentDevice]; device.proximityMonitoringEnabled = NO; @@ -377,6 +500,10 @@ int callCount(LinphoneCore* lc) { [self updateUIFromLinphoneState: nil]; } -(void) displayVideoCall:(LinphoneCall*) call FromUI:(UIViewController*) viewCtrl forUser:(NSString*) username withDisplayName:(NSString*) displayName { + + [self enableVideoDisplay]; + return; + if (mIncallViewIsReady) { [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone]; mVideoShown=TRUE; diff --git a/Classes/IncallViewController.xib b/Classes/IncallViewController.xib index 9a8d85d63..ee1eac9e3 100644 --- a/Classes/IncallViewController.xib +++ b/Classes/IncallViewController.xib @@ -42,6 +42,51 @@ 274 YES + + + 292 + + YES + + + 292 + {320, 480} + + + + _NS:196 + + 3 + MCAwAA + + IBCocoaTouchFramework + + + + 292 + {{240, 354}, {80, 106}} + + + + + 3 + MQA + + 2 + + + IBCocoaTouchFramework + + + {320, 460} + + + + _NS:196 + + NO + IBCocoaTouchFramework + 274 @@ -50,10 +95,7 @@ _NS:418 - - 3 - MCAwAA - + YES IBCocoaTouchFramework YES @@ -707,7 +749,7 @@ {{0, 20}, {320, 460}} - + NO IBCocoaTouchFramework @@ -940,6 +982,30 @@ 125 + + + videoGroup + + + + 129 + + + + videoPreview + + + + 130 + + + + videoView + + + + 133 + doAction: @@ -1024,6 +1090,7 @@ + @@ -1035,6 +1102,7 @@ + hangupview 18 @@ -1212,6 +1280,29 @@ video + + 126 + + + YES + + + + + video + + + 127 + + + preview + + + 132 + + + display + @@ -1232,9 +1323,12 @@ 120.IBPluginDependency 123.CustomClassName 123.IBPluginDependency + 126.IBPluginDependency + 127.IBPluginDependency 13.CustomClassName 13.IBPluginDependency 13.IBUIButtonInspectorSelectedStateConfigurationMetadataKey + 132.IBPluginDependency 15.IBPluginDependency 16.CustomClassName 16.IBPluginDependency @@ -1289,10 +1383,13 @@ com.apple.InterfaceBuilder.IBCocoaTouchPlugin UIAddVideoButton 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 UIMuteButton com.apple.InterfaceBuilder.IBCocoaTouchPlugin @@ -1343,7 +1440,7 @@ - 125 + 133 @@ -1367,9 +1464,7 @@ YES addCall - addToConf addVideo - callControlSubView callTableView close conferenceDetail @@ -1394,6 +1489,9 @@ star three two + videoGroup + videoPreview + videoView videoViewController zero @@ -1401,8 +1499,6 @@ YES UIButton UIButton - UIButton - UIView UITableView UIButton UIViewController @@ -1427,6 +1523,9 @@ UIButton UIButton UIButton + UIView + UIView + UIView VideoViewController UIButton @@ -1436,9 +1535,7 @@ YES addCall - addToConf addVideo - callControlSubView callTableView close conferenceDetail @@ -1463,6 +1560,9 @@ star three two + videoGroup + videoPreview + videoView videoViewController zero @@ -1472,18 +1572,10 @@ addCall UIButton - - addToConf - UIButton - addVideo UIButton - - callControlSubView - UIView - callTableView UITableView @@ -1580,6 +1672,18 @@ two UIButton + + videoGroup + UIView + + + videoPreview + UIView + + + videoView + UIView + videoViewController VideoViewController @@ -1673,27 +1777,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 +1803,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 +1828,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 +1864,6 @@ mCamSwitch UICamSwitch - - mCamSwitchLand - UICamSwitch - mCamSwitchLandLeft UICamSwitch @@ -1794,10 +1876,6 @@ mDisplay UIView - - mDisplayLand - UIView - mDisplayLandLeft UIView @@ -1810,10 +1888,6 @@ mHangUp UIHangUpButton - - mHangUpLand - UIHangUpButton - mHangUpLandLeft UIHangUpButton @@ -1822,10 +1896,6 @@ mHangUpLandRight UIHangUpButton - - mLandscape - UIView - mLandscapeLeft UIView @@ -1838,10 +1908,6 @@ mMute UIMuteButton - - mMuteLand - UIMuteButton - mMuteLandLeft UIMuteButton @@ -1858,10 +1924,6 @@ mPreview UIView - - mPreviewLand - UIView - mPreviewLandLeft UIView diff --git a/Classes/LinphoneAppDelegate.m b/Classes/LinphoneAppDelegate.m index d84fa8dd9..3f9ebdc61 100644 --- a/Classes/LinphoneAppDelegate.m +++ b/Classes/LinphoneAppDelegate.m @@ -29,7 +29,7 @@ #include "LinphoneManager.h" #include "linphonecore.h" -#if __clang__ && TARGET_OS_IPHONE +#if __clang__ && __arm__ extern int __divsi3(int a, int b); int __aeabi_idiv(int a, int b) { return __divsi3(a,b); @@ -116,7 +116,8 @@ int __aeabi_idiv(int a, int b) { #endif #ifdef HAVE_G729 @"YES",@"g729_preference", // enable amr by default if compiled with -#endif @"NO",@"debugenable_preference", +#endif + @"NO",@"debugenable_preference", //@"+33",@"countrycode_preference", nil]; From 079b43b6befd05ec36adc52c3c8049455090dc20 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Mon, 12 Mar 2012 13:45:51 +0100 Subject: [PATCH 02/34] Rotate control buttons in video view (on device orientation change) --- Classes/CallDelegate.h | 39 +- Classes/CallDelegate.m | 58 +- Classes/InCallViewController-ipad.xib | 672 +++++++++++------- Classes/IncallViewController.h | 2 +- Classes/IncallViewController.m | 195 +++-- Classes/IncallViewController.xib | 23 +- Classes/LinphoneUI/LinphoneManager.h | 1 + Classes/LinphoneUI/LinphoneManager.m | 36 +- Classes/LinphoneUI/LinphoneUIDelegates.h | 1 + Classes/LinphoneUI/UICallButton.m | 2 - ...AddVideoButton.h => UIToggleVideoButton.h} | 4 +- ...AddVideoButton.m => UIToggleVideoButton.m} | 22 +- Classes/PhoneViewController.m | 10 +- Classes/VideoViewController-ipad.xib | 205 +----- linphone.xcodeproj/project.pbxproj | 26 +- submodules/externals/exosip | 2 +- submodules/linphone | 2 +- 17 files changed, 745 insertions(+), 555 deletions(-) rename Classes/LinphoneUI/{UIAddVideoButton.h => UIToggleVideoButton.h} (94%) rename Classes/LinphoneUI/{UIAddVideoButton.m => UIToggleVideoButton.m} (77%) diff --git a/Classes/CallDelegate.h b/Classes/CallDelegate.h index 02b69b026..d32864706 100644 --- a/Classes/CallDelegate.h +++ b/Classes/CallDelegate.h @@ -1,27 +1,46 @@ -// -// 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 +}; @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/InCallViewController-ipad.xib b/Classes/InCallViewController-ipad.xib index 17661327c..7921a5ac7 100644 --- a/Classes/InCallViewController-ipad.xib +++ b/Classes/InCallViewController-ipad.xib @@ -11,10 +11,11 @@ 933 + IBUIImageView IBUIViewController - IBUIButton - IBUIView IBUITableView + IBUIView + IBUIButton IBProxyObject @@ -44,12 +45,12 @@ {768, 805} - + _NS:408 3 MSAwAA - + 2 @@ -62,6 +63,99 @@ 22 22 + + + -2147483374 + + + + 292 + {768, 1024} + + + + _NS:569 + NO + IBIPadFramework + + + + 292 + {{20, 956}, {28, 28}} + + + + _NS:567 + NO + IBIPadFramework + + + + 292 + {{598, 799}, {170, 225}} + + + + + 3 + MQA + + + IBIPadFramework + + + + 292 + {{0, 962}, {108, 62}} + + + + NO + IBIPadFramework + 0 + 0 + 1 + switch + + 3 + MQA + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + 3 + MC41AA + + + NSImage + clavier-01-108px.png + + + Helvetica-Bold + Helvetica + 2 + 15 + + + Helvetica-Bold + 15 + 16 + + + + {768, 1024} + + + + _NS:212 + + 3 + MC42NjY2NjY2NjY3AA + + IBIPadFramework + 292 @@ -82,18 +176,12 @@ IBIPadFramework 0 0 - - 3 - MQA - + 1 MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA - - 3 - MC41AA - + NSImage stopcall-red.png @@ -102,17 +190,8 @@ NSImage clavier-01-106px.png - - Helvetica-Bold - Helvetica - 2 - 15 - - - Helvetica-Bold - 15 - 16 - + + {{224, 937}, {320, 77}} @@ -411,7 +490,7 @@ - + @@ -420,10 +499,7 @@ - - 3 - MC42NjY2NjY2NjY3AA - + NO NO IBIPadFramework @@ -437,7 +513,7 @@ - + @@ -460,7 +536,7 @@ - + @@ -480,7 +556,7 @@ - + @@ -503,7 +579,7 @@ - + @@ -526,7 +602,7 @@ - + @@ -549,7 +625,7 @@ - + @@ -572,7 +648,7 @@ - + @@ -595,7 +671,7 @@ - + @@ -618,7 +694,7 @@ - + @@ -641,7 +717,7 @@ - + @@ -664,7 +740,7 @@ - + @@ -687,7 +763,7 @@ - + {{178, 146}, {320, 310}} @@ -726,51 +802,11 @@ - addCall + callTableView - + - 112 - - - - addVideo - - - - 113 - - - - close - - - - 115 - - - - contacts - - - - 116 - - - - controlSubView - - - - 117 - - - - eight - - - - 118 + 114 @@ -780,22 +816,6 @@ 119 - - - five - - - - 120 - - - - four - - - - 121 - hangUpView @@ -806,19 +826,11 @@ - hash + speaker - + - 123 - - - - mergeCalls - - - - 124 + 132 @@ -830,27 +842,43 @@ - nine + addVideo - + - 126 + 113 - one + mergeCalls - + - 127 + 124 - padSubView + addCall - + - 128 + 112 + + + + contacts + + + + 116 + + + + dialer + + + + 141 @@ -860,6 +888,30 @@ 129 + + + controlSubView + + + + 117 + + + + five + + + + 120 + + + + nine + + + + 126 + seven @@ -878,19 +930,11 @@ - speaker + four - + - 132 - - - - star - - - - 133 + 121 @@ -900,6 +944,14 @@ 134 + + + zero + + + + 137 + two @@ -908,6 +960,54 @@ 135 + + + close + + + + 115 + + + + hash + + + + 123 + + + + eight + + + + 118 + + + + one + + + + 127 + + + + star + + + + 133 + + + + padSubView + + + + 128 + view @@ -918,27 +1018,27 @@ - zero + videoGroup - + - 137 + 159 - callTableView + videoView - + - 114 + 161 - dialer + videoPreview - + - 141 + 162 @@ -1019,9 +1119,29 @@ + + + 61 + + + + + 88 + + + + + + + + 98 + + + end + 89 @@ -1038,48 +1158,18 @@ controls - - 97 - - - pauseresume - 96 speaker - - 95 - - - dialer - - - 94 - - - contacts - - - 93 - - - addcall - 92 mute - - 91 - - - merge - 90 @@ -1087,12 +1177,34 @@ video - 88 - - - - - + 91 + + + merge + + + 93 + + + addcall + + + 94 + + + contacts + + + 95 + + + dialer + + + 97 + + + pauseresume 87 @@ -1116,70 +1228,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 +1240,105 @@ 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 + + + 154 + + + + + 153 + + + call_quality_video @@ -1235,13 +1371,19 @@ 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 - UIAddVideoButton + UIToggleVideoButton com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin @@ -1266,7 +1408,7 @@ - 144 + 162 @@ -1311,6 +1453,9 @@ UIButton UIButton UIButton + UIView + UIView + UIView VideoViewController UIButton @@ -1419,6 +1564,18 @@ two UIButton + + videoGroup + UIView + + + videoPreview + UIView + + + videoView + UIView + videoViewController VideoViewController @@ -1433,14 +1590,6 @@ ./Classes/IncallViewController.h - - UIAddVideoButton - UIButton - - IBProjectSource - ./Classes/UIAddVideoButton.h - - UICamSwitch UIButton @@ -1500,6 +1649,14 @@ ./Classes/UIToggleButton.h + + UIToggleVideoButton + UIButton + + IBProjectSource + ./Classes/UIToggleVideoButton.h + + VideoViewController UIViewController @@ -1628,6 +1785,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 ac1081718..16d5ae004 100644 --- a/Classes/IncallViewController.h +++ b/Classes/IncallViewController.h @@ -82,7 +82,7 @@ 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; NSTimer* hideControlsTimer; } diff --git a/Classes/IncallViewController.m b/Classes/IncallViewController.m index 1c3dd590b..2e740d733 100644 --- a/Classes/IncallViewController.m +++ b/Classes/IncallViewController.m @@ -122,6 +122,61 @@ void addAnimationFadeTransition(UIView* view, float 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; + switch (orientation) { + case UIInterfaceOrientationPortrait: + linphone_core_set_device_rotation([LinphoneManager getLc], 0); + break; + case UIInterfaceOrientationLandscapeRight: + linphone_core_set_device_rotation([LinphoneManager getLc], 270); + break; + case UIInterfaceOrientationLandscapeLeft: + linphone_core_set_device_rotation([LinphoneManager getLc], 90); + break; + default: + break; + } + if (oldLinphoneOrientation != linphone_core_get_device_rotation([LinphoneManager getLc])) { + 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 change, 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; + [UIView commitAnimations]; + } + } +} + -(void) showControls:(id)sender { if (hideControlsTimer) { [hideControlsTimer invalidate]; @@ -148,6 +203,8 @@ void addAnimationFadeTransition(UIView* view, float duration) { } -(void) enableVideoDisplay { + [self orientationChanged:nil]; + [videoGroup setHidden:FALSE]; [controlSubView setHidden:TRUE]; [hangUpView setHidden:TRUE]; @@ -155,7 +212,6 @@ void addAnimationFadeTransition(UIView* view, float duration) { linphone_core_set_native_video_window_id([LinphoneManager getLc],(unsigned long)videoView); linphone_core_set_native_preview_window_id([LinphoneManager getLc],(unsigned long)videoPreview); - linphone_core_set_device_rotation([LinphoneManager getLc], 0); [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide]; @@ -180,6 +236,15 @@ void addAnimationFadeTransition(UIView* view, float duration) { 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; + [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone]; } @@ -212,6 +277,12 @@ void addAnimationFadeTransition(UIView* view, float duration) { } else { [LinphoneManager set:pause hidden:YES withName:"PAUSE button" andReason:AT]; } + + if (linphone_call_params_video_enabled(linphone_call_get_current_params(selectedCall))) { + addVideo.titleLabel.text = NSLocalizedString(@"-video", nil); + } else { + addVideo.titleLabel.text = NSLocalizedString(@"+video", nil); + } } else { if (callsCount == 1) { LinphoneCall* c = (LinphoneCall*)linphone_core_get_calls(lc)->data; @@ -342,28 +413,6 @@ void addAnimationFadeTransition(UIView* view, float duration) { [self updateUIFromLinphoneState: nil]; } --(void) orientationChanged: (NSNotification*) notif { - int oldLinphoneOrientation = linphone_core_get_device_rotation([LinphoneManager getLc]); - UIDeviceOrientation orientation = [UIDevice currentDevice].orientation; - switch (orientation) { - case UIInterfaceOrientationPortrait: - linphone_core_set_device_rotation([LinphoneManager getLc], 0); - break; - case UIInterfaceOrientationLandscapeRight: - linphone_core_set_device_rotation([LinphoneManager getLc], 270); - break; - case UIInterfaceOrientationLandscapeLeft: - linphone_core_set_device_rotation([LinphoneManager getLc], 90); - break; - } - if ((oldLinphoneOrientation != linphone_core_get_device_rotation([LinphoneManager getLc])) - && linphone_core_get_current_call([LinphoneManager getLc])) { - linphone_core_set_native_video_window_id([LinphoneManager getLc],(unsigned long)videoView); - //Orientation has change, must call update call - linphone_core_update_call([LinphoneManager getLc], linphone_core_get_current_call([LinphoneManager getLc]), NULL); - } -} - -(void) awakeFromNib { @@ -403,15 +452,15 @@ void addAnimationFadeTransition(UIView* view, float duration) { 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]; } } @@ -459,11 +508,6 @@ void addAnimationFadeTransition(UIView* view, float duration) { } --(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]; @@ -474,9 +518,6 @@ void addAnimationFadeTransition(UIView* view, float duration) { [self updateUIFromLinphoneState: nil]; [self disableVideoDisplay]; - /*if (self.presentedViewController == (UIViewController*)mVideoViewController) { - [self dismissVideoView]; - }*/ } -(void) displayDialerFromUI:(UIViewController*) viewCtrl forUser:(NSString*) username withDisplayName:(NSString*) displayName { [self disableVideoDisplay]; @@ -512,11 +553,46 @@ void addAnimationFadeTransition(UIView* view, float duration) { 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]; +} + - (IBAction)doAction:(id)sender { if (sender == dialer) { @@ -813,33 +889,60 @@ void addAnimationFadeTransition(UIView* view, float duration) { 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; + } + default: + ms_error("Unhandled CallDelegate event of type: %d received - ignoring", type); + } } // UITableViewDataSource (required) diff --git a/Classes/IncallViewController.xib b/Classes/IncallViewController.xib index ee1eac9e3..3cc434a7b 100644 --- a/Classes/IncallViewController.xib +++ b/Classes/IncallViewController.xib @@ -81,7 +81,7 @@ {320, 460} - + _NS:196 NO @@ -395,6 +395,7 @@ NO + NO NO IBCocoaTouchFramework 0 @@ -1381,7 +1382,7 @@ com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIAddVideoButton + UIToggleVideoButton com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin @@ -1440,7 +1441,7 @@ - 133 + 134 @@ -1699,14 +1700,6 @@ ./Classes/IncallViewController.h - - UIAddVideoButton - UIButton - - IBProjectSource - ./Classes/UIAddVideoButton.h - - UICamSwitch UIButton @@ -1766,6 +1759,14 @@ ./Classes/UIToggleButton.h + + UIToggleVideoButton + UIButton + + IBProjectSource + ./Classes/UIToggleVideoButton.h + + VideoViewController UIViewController diff --git a/Classes/LinphoneUI/LinphoneManager.h b/Classes/LinphoneUI/LinphoneManager.h index 95aaa8d60..42874fa8d 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 diff --git a/Classes/LinphoneUI/LinphoneManager.m b/Classes/LinphoneUI/LinphoneManager.m index 295aa96c0..ea5fabb4f 100644 --- a/Classes/LinphoneUI/LinphoneManager.m +++ b/Classes/LinphoneUI/LinphoneManager.m @@ -150,6 +150,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); @@ -169,7 +170,9 @@ extern void libmsbcg729_init(); [callDelegate displayVideoCall:call FromUI:mCurrentViewController forUser:lUserName withDisplayName:lDisplayName]; - } + } else { + [callDelegate displayInCall:call FromUI:mCurrentViewController forUser:lUserName withDisplayName:lDisplayName]; + } break; case LinphoneCallIncomingReceived: @@ -192,7 +195,31 @@ extern void libmsbcg729_init(); 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"; @@ -649,6 +676,11 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach bool enableSrtp = [[NSUserDefaults standardUserDefaults] boolForKey:@"enable_srtp_preference"]; linphone_core_set_media_encryption(theLinphoneCore, enableSrtp?LinphoneMediaEncryptionSRTP:LinphoneMediaEncryptionZRTP); + 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..0023ede04 100644 --- a/Classes/LinphoneUI/LinphoneUIDelegates.h +++ b/Classes/LinphoneUI/LinphoneUIDelegates.h @@ -28,6 +28,7 @@ -(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; @end diff --git a/Classes/LinphoneUI/UICallButton.m b/Classes/LinphoneUI/UICallButton.m index 8ab033b6d..39661926c 100644 --- a/Classes/LinphoneUI/UICallButton.m +++ b/Classes/LinphoneUI/UICallButton.m @@ -52,9 +52,7 @@ 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:"]) { diff --git a/Classes/LinphoneUI/UIAddVideoButton.h b/Classes/LinphoneUI/UIToggleVideoButton.h similarity index 94% rename from Classes/LinphoneUI/UIAddVideoButton.h rename to Classes/LinphoneUI/UIToggleVideoButton.h index 275de0672..c9a6cc83c 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,6 @@ #import -@interface UIAddVideoButton : UIButton +@interface UIToggleVideoButton : UIButton - (id)initWithCoder:(NSCoder *)decoder; @end diff --git a/Classes/LinphoneUI/UIAddVideoButton.m b/Classes/LinphoneUI/UIToggleVideoButton.m similarity index 77% rename from Classes/LinphoneUI/UIAddVideoButton.m rename to Classes/LinphoneUI/UIToggleVideoButton.m index e34cdfb8f..9f8db414d 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,31 @@ * 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 -(void) touchUp:(id) sender { LinphoneCore* lc = [LinphoneManager getLc]; + + if (!linphone_core_video_enabled(lc)) + return; + 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/PhoneViewController.m b/Classes/PhoneViewController.m index cb803e988..42c5e5352 100644 --- a/Classes/PhoneViewController.m +++ b/Classes/PhoneViewController.m @@ -258,6 +258,7 @@ } } else { CallDelegate* cd = [[CallDelegate alloc] init]; + cd.eventType = CD_NEW_CALL; cd.delegate = self; cd.call = call; @@ -326,9 +327,16 @@ [mMainScreenWithVideoPreview showPreview:NO]; } +-(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); diff --git a/Classes/VideoViewController-ipad.xib b/Classes/VideoViewController-ipad.xib index 6aee67bb2..f1f29d7f1 100644 --- a/Classes/VideoViewController-ipad.xib +++ b/Classes/VideoViewController-ipad.xib @@ -37,7 +37,6 @@ 274 {768, 1004} - 4 MAA @@ -53,18 +52,25 @@ 292 {{-9, 0}, {777, 1004}} - _NS:569 NO IBIPadFramework + + + 292 + {{20, 956}, {28, 28}} + + _NS:567 + NO + IBIPadFramework + 292 {{329, 942}, {108, 62}} - NO IBIPadFramework @@ -107,7 +113,6 @@ 292 {{223, 942}, {108, 62}} - NO IBIPadFramework @@ -128,7 +133,6 @@ 292 {{598, 779}, {170, 225}} - 3 MQA @@ -143,7 +147,6 @@ 292 {{436, 942}, {108, 62}} - NO IBIPadFramework @@ -161,20 +164,9 @@ - - - 292 - {{20, 956}, {28, 28}} - - - _NS:567 - NO - IBIPadFramework - {768, 1004} - _NS:212 @@ -192,7 +184,6 @@ 292 {1004, 768} - _NS:569 NO @@ -203,7 +194,6 @@ 292 {{779, 598}, {225, 170}} - 3 MQA @@ -216,7 +206,6 @@ 292 {{341, 706}, {108, 62}} - NO IBIPadFramework @@ -237,7 +226,6 @@ 292 {{448, 706}, {108, 62}} - NO IBIPadFramework @@ -259,7 +247,6 @@ 292 {{555, 706}, {108, 62}} - NO IBIPadFramework @@ -282,7 +269,6 @@ 292 {{20, 720}, {28, 28}} - _NS:567 NO IBIPadFramework @@ -290,7 +276,6 @@ {1004, 768} - _NS:212 @@ -312,7 +297,6 @@ 292 {1004, 768} - _NS:569 NO @@ -323,7 +307,6 @@ 292 {{779, 598}, {225, 170}} - 3 MQA @@ -336,7 +319,6 @@ 292 {{341, 706}, {108, 62}} - NO IBIPadFramework @@ -357,7 +339,6 @@ 292 {{448, 706}, {108, 62}} - NO IBIPadFramework @@ -379,7 +360,6 @@ 292 {{555, 706}, {108, 62}} - NO IBIPadFramework @@ -402,7 +382,6 @@ 292 {{20, 720}, {28, 28}} - _NS:567 NO IBIPadFramework @@ -410,7 +389,6 @@ {1004, 768} - _NS:212 @@ -813,170 +791,7 @@ 53 - - - - UICamSwitch - UIButton - - preview - UIView - - - preview - - preview - UIView - - - - IBProjectSource - ./Classes/UICamSwitch.h - - - - UIHangUpButton - UIButton - - IBProjectSource - ./Classes/UIHangUpButton.h - - - - UIMuteButton - UIToggleButton - - IBProjectSource - ./Classes/UIMuteButton.h - - - - UIToggleButton - UIButton - - IBProjectSource - ./Classes/UIToggleButton.h - - - - VideoViewController - UIViewController - - UIImageView - UIImageView - UIImageView - UICamSwitch - UICamSwitch - UICamSwitch - UIView - UIView - UIView - UIHangUpButton - UIHangUpButton - UIHangUpButton - UIView - UIView - UIMuteButton - UIMuteButton - UIMuteButton - UIView - UIView - UIView - UIView - - - - mCallQuality - UIImageView - - - mCallQualityLandLeft - UIImageView - - - mCallQualityLandRight - UIImageView - - - mCamSwitch - UICamSwitch - - - mCamSwitchLandLeft - UICamSwitch - - - mCamSwitchLandRight - UICamSwitch - - - mDisplay - UIView - - - mDisplayLandLeft - UIView - - - mDisplayLandRight - UIView - - - mHangUp - UIHangUpButton - - - mHangUpLandLeft - UIHangUpButton - - - mHangUpLandRight - UIHangUpButton - - - mLandscapeLeft - UIView - - - mLandscapeRight - UIView - - - mMute - UIMuteButton - - - mMuteLandLeft - UIMuteButton - - - mMuteLandRight - UIMuteButton - - - mPortrait - UIView - - - mPreview - UIView - - - mPreviewLandLeft - UIView - - - mPreviewLandRight - UIView - - - - IBProjectSource - ./Classes/VideoViewController.h - - - - + 0 IBIPadFramework YES diff --git a/linphone.xcodeproj/project.pbxproj b/linphone.xcodeproj/project.pbxproj index 43720f891..6b6213ba4 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 */; }; @@ -589,8 +589,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 +612,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 = ""; }; @@ -752,6 +753,7 @@ 080E96DDFE201D6D7F000001 /* Classes */ = { isa = PBXGroup; children = ( + 340751E4150E4D0200B89C47 /* CallDelegate.h */, 2211DBBB14769C8200DEE054 /* CallDelegate.m */, 2214EB7012F84668002A5394 /* LinphoneUI */, 2218A92212FBE1340088A667 /* FirstLoginViewController.h */, @@ -1007,6 +1009,8 @@ 2214EB7012F84668002A5394 /* LinphoneUI */ = { isa = PBXGroup; children = ( + 340751E5150F38FC00B89C47 /* UIToggleVideoButton.h */, + 340751E6150F38FD00B89C47 /* UIToggleVideoButton.m */, 2248E90C12F7E4CF00220D9C /* UIDigitButton.h */, 2248E90D12F7E4CF00220D9C /* UIDigitButton.m */, 2248E99D12F801C200220D9C /* LinphoneManager.h */, @@ -1034,8 +1038,6 @@ 223963161393CFAF001DE689 /* FastAddressBook.m */, 22AA8AFF13D83F6300B30535 /* UICamSwitch.h */, 22AA8B0013D83F6300B30535 /* UICamSwitch.m */, - 22D817AB147A9F33001CFB9C /* UIAddVideoButton.h */, - 22D817AC147A9F33001CFB9C /* UIAddVideoButton.m */, ); path = LinphoneUI; sourceTree = ""; @@ -1497,10 +1499,10 @@ 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 */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1532,10 +1534,10 @@ 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 */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1574,7 +1576,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, @@ -1640,7 +1642,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, @@ -1916,7 +1918,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 +1985,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/submodules/externals/exosip b/submodules/externals/exosip index b3e55a3c9..8483ca292 160000 --- a/submodules/externals/exosip +++ b/submodules/externals/exosip @@ -1 +1 @@ -Subproject commit b3e55a3c93b39af43666acec45191b41f2016fa0 +Subproject commit 8483ca292c10e4bca3331040dd9babf8431d0393 diff --git a/submodules/linphone b/submodules/linphone index 4006baf28..86cb50783 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit 4006baf2895166f78b8fe4c2721fa77656607988 +Subproject commit 86cb50783bf6923fc812219066d4aefd656ee80a From a7ac89fd79dd4c1c8a9b36e8187457d20048580e Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Wed, 14 Mar 2012 11:43:05 +0100 Subject: [PATCH 03/34] Animate transitions video <-> audio calls --- Classes/IncallViewController.m | 56 +++++++++++++++++----------- Classes/IncallViewController.xib | 17 +++++---- Classes/LinphoneUI/LinphoneManager.m | 2 +- 3 files changed, 45 insertions(+), 30 deletions(-) diff --git a/Classes/IncallViewController.m b/Classes/IncallViewController.m index 2e740d733..0ae8d5465 100644 --- a/Classes/IncallViewController.m +++ b/Classes/IncallViewController.m @@ -183,21 +183,22 @@ void addAnimationFadeTransition(UIView* view, float duration) { hideControlsTimer = nil; } // show controls - addAnimationFadeTransition(controlSubView, 0.2); - controlSubView.hidden = FALSE; - - addAnimationFadeTransition(hangUpView, 0.2); - hangUpView.hidden = FALSE; + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:0.3]; + [controlSubView setAlpha:1.0]; + [hangUpView 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 { - addAnimationFadeTransition(controlSubView, 0.4); - controlSubView.hidden = TRUE; - addAnimationFadeTransition(hangUpView, 0.4); - hangUpView.hidden = TRUE; + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:0.3]; + [controlSubView setAlpha:0.0]; + [hangUpView setAlpha:0.0]; + [UIView commitAnimations]; hideControlsTimer = nil; } @@ -205,10 +206,13 @@ void addAnimationFadeTransition(UIView* view, float duration) { -(void) enableVideoDisplay { [self orientationChanged:nil]; - [videoGroup setHidden:FALSE]; - [controlSubView setHidden:TRUE]; - [hangUpView setHidden:TRUE]; - [callTableView setHidden:TRUE]; + [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]; linphone_core_set_native_video_window_id([LinphoneManager getLc],(unsigned long)videoView); linphone_core_set_native_preview_window_id([LinphoneManager getLc],(unsigned long)videoPreview); @@ -226,10 +230,13 @@ void addAnimationFadeTransition(UIView* view, float duration) { } -(void) disableVideoDisplay { - [videoGroup setHidden:TRUE]; - [controlSubView setHidden:FALSE]; - [hangUpView setHidden:FALSE]; - [callTableView setHidden:FALSE]; + [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]; + [UIView commitAnimations]; if (hideControlsTimer != nil) { [hideControlsTimer invalidate]; @@ -278,10 +285,15 @@ void addAnimationFadeTransition(UIView* view, float duration) { [LinphoneManager set:pause hidden:YES withName:"PAUSE button" andReason:AT]; } - if (linphone_call_params_video_enabled(linphone_call_get_current_params(selectedCall))) { - addVideo.titleLabel.text = NSLocalizedString(@"-video", nil); + if (linphone_call_get_state(selectedCall) == LinphoneCallStreamsRunning) { + if (linphone_call_params_video_enabled(linphone_call_get_current_params(selectedCall))) { + [addVideo setTitle:NSLocalizedString(@"-video", nil) forState:UIControlStateNormal]; + } else { + [addVideo setTitle:NSLocalizedString(@"+video", nil) forState:UIControlStateNormal]; + } + [addVideo setEnabled:YES]; } else { - addVideo.titleLabel.text = NSLocalizedString(@"+video", nil); + [addVideo setEnabled:NO]; } } else { if (callsCount == 1) { @@ -294,6 +306,7 @@ void addAnimationFadeTransition(UIView* view, float duration) { } 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]; @@ -450,8 +463,7 @@ void addAnimationFadeTransition(UIView* view, float duration) { 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 withName:"CONTACT button" andReason:AT]; [LinphoneManager set:addVideo hidden:!contacts.hidden withName:"ADD_VIDEO button" andReason:AT]; } diff --git a/Classes/IncallViewController.xib b/Classes/IncallViewController.xib index 3cc434a7b..82c7d024a 100644 --- a/Classes/IncallViewController.xib +++ b/Classes/IncallViewController.xib @@ -81,7 +81,7 @@ {320, 460} - + _NS:196 NO @@ -316,8 +316,12 @@ 0 0 1 - video + video + + 3 + MC42NjY2NjY2NjY3AA + 1 MC4xOTYwNzg0MzE0IDAuMzA5ODAzOTIxNiAwLjUyMTU2ODYyNzUAA @@ -464,10 +468,7 @@ - - 3 - MC42NjY2NjY2NjY3AA - + NO NO IBCocoaTouchFramework @@ -1324,6 +1325,7 @@ 120.IBPluginDependency 123.CustomClassName 123.IBPluginDependency + 123.IBUIButtonInspectorSelectedStateConfigurationMetadataKey 126.IBPluginDependency 127.IBPluginDependency 13.CustomClassName @@ -1384,6 +1386,7 @@ com.apple.InterfaceBuilder.IBCocoaTouchPlugin UIToggleVideoButton com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin UISpeakerButton @@ -1441,7 +1444,7 @@ - 134 + 136 diff --git a/Classes/LinphoneUI/LinphoneManager.m b/Classes/LinphoneUI/LinphoneManager.m index ea5fabb4f..1bc1097d5 100644 --- a/Classes/LinphoneUI/LinphoneManager.m +++ b/Classes/LinphoneUI/LinphoneManager.m @@ -188,7 +188,7 @@ extern void libmsbcg729_init(); forUser:lUserName withDisplayName:lDisplayName]; break; - + case LinphoneCallPausedByRemote: case LinphoneCallConnected: [callDelegate displayInCall: call FromUI:mCurrentViewController From d30ce42682a81c55c5673959ee0e889d1590b4ee Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Wed, 14 Mar 2012 16:49:22 +0100 Subject: [PATCH 04/34] Add call quality indicator in video mode --- Classes/ConferenceCallDetailView.m | 16 +--- Classes/InCallViewController-ipad.xib | 119 ++++++++++++++------------ Classes/IncallViewController.h | 9 +- Classes/IncallViewController.m | 51 ++++------- Classes/IncallViewController.xib | 73 ++++++++++++---- Classes/VideoViewController.xib | 42 ++++----- linphonerc | 1 + submodules/linphone | 2 +- 8 files changed, 168 insertions(+), 145 deletions(-) diff --git a/Classes/ConferenceCallDetailView.m b/Classes/ConferenceCallDetailView.m index ed6ebafea..6ec3bf877 100644 --- a/Classes/ConferenceCallDetailView.m +++ b/Classes/ConferenceCallDetailView.m @@ -148,21 +148,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/InCallViewController-ipad.xib b/Classes/InCallViewController-ipad.xib index 7921a5ac7..5eafb957e 100644 --- a/Classes/InCallViewController-ipad.xib +++ b/Classes/InCallViewController-ipad.xib @@ -45,12 +45,12 @@ {768, 805} - + _NS:408 3 MSAwAA - + 2 @@ -63,53 +63,53 @@ 22 22 - + -2147483374 - - + + 292 {768, 1024} - + - + _NS:569 NO IBIPadFramework - - + + 292 {{20, 956}, {28, 28}} - + - + _NS:567 NO IBIPadFramework - - + + 292 {{598, 799}, {170, 225}} - + 3 MQA - + IBIPadFramework - - + + 292 {{0, 962}, {108, 62}} - + - + NO IBIPadFramework 0 @@ -138,7 +138,7 @@ 2 15 - + Helvetica-Bold 15 16 @@ -148,7 +148,7 @@ {768, 1024} - + _NS:212 3 @@ -191,7 +191,7 @@ clavier-01-106px.png - + {{224, 937}, {320, 77}} @@ -490,7 +490,7 @@ - + @@ -513,7 +513,7 @@ - + @@ -536,7 +536,7 @@ - + @@ -556,7 +556,7 @@ - + @@ -579,7 +579,7 @@ - + @@ -602,7 +602,7 @@ - + @@ -625,7 +625,7 @@ - + @@ -648,7 +648,7 @@ - + @@ -671,7 +671,7 @@ - + @@ -694,7 +694,7 @@ - + @@ -717,7 +717,7 @@ - + @@ -740,7 +740,7 @@ - + @@ -763,7 +763,7 @@ - + {{178, 146}, {320, 310}} @@ -1020,7 +1020,7 @@ videoGroup - + 159 @@ -1028,7 +1028,7 @@ videoView - + 161 @@ -1036,10 +1036,18 @@ videoPreview - + 162 + + + videoCallQuality + + + + 163 + dataSource @@ -1119,7 +1127,7 @@ - + @@ -1307,37 +1315,37 @@ 152 - + - - - - + + + + video 158 - - + + video_preview 157 - - + + video_view 154 - - + + 153 - - + + call_quality_video @@ -1408,7 +1416,7 @@ - 162 + 163 @@ -1453,6 +1461,7 @@ UIButton UIButton UIButton + UIImageView UIView UIView UIView @@ -1564,6 +1573,10 @@ two UIButton + + videoCallQuality + UIImageView + videoGroup UIView diff --git a/Classes/IncallViewController.h b/Classes/IncallViewController.h index 16d5ae004..696937041 100644 --- a/Classes/IncallViewController.h +++ b/Classes/IncallViewController.h @@ -61,6 +61,7 @@ UIView* videoGroup; UIView* videoView; UIView* videoPreview; + UIImageView* videoCallQuality; bool dismissed; @@ -87,18 +88,13 @@ NSTimer* hideControlsTimer; } -+ (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; - -(void)displayStatus:(NSString*) message; - (IBAction)doAction:(id)sender; +(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; @@ -134,4 +130,5 @@ @property (nonatomic, retain) IBOutlet UIView* videoGroup; @property (nonatomic, retain) IBOutlet UIView* videoView; @property (nonatomic, retain) IBOutlet UIView* videoPreview; +@property (nonatomic, retain) IBOutlet UIImageView* videoCallQuality; @end diff --git a/Classes/IncallViewController.m b/Classes/IncallViewController.m index 0ae8d5465..12098d3b0 100644 --- a/Classes/IncallViewController.m +++ b/Classes/IncallViewController.m @@ -70,28 +70,23 @@ const NSInteger SECURE_BUTTON_TAG=5; @synthesize videoGroup; @synthesize videoView; @synthesize videoPreview; +@synthesize videoCallQuality; @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) { @@ -172,6 +167,7 @@ void addAnimationFadeTransition(UIView* view, float duration) { addCall.imageView.transform = transform; addVideo.imageView.transform = transform; dialer.imageView.transform = transform; + videoCallQuality.transform = transform; [UIView commitAnimations]; } } @@ -251,6 +247,7 @@ void addAnimationFadeTransition(UIView* view, float duration) { contacts.imageView.transform = CGAffineTransformIdentity; addCall.imageView.transform = CGAffineTransformIdentity; dialer.imageView.transform = CGAffineTransformIdentity; + videoCallQuality.transform = CGAffineTransformIdentity; [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone]; } @@ -288,12 +285,14 @@ void addAnimationFadeTransition(UIView* view, float duration) { if (linphone_call_get_state(selectedCall) == LinphoneCallStreamsRunning) { if (linphone_call_params_video_enabled(linphone_call_get_current_params(selectedCall))) { [addVideo setTitle:NSLocalizedString(@"-video", nil) forState:UIControlStateNormal]; + [IncallViewController updateIndicator: videoCallQuality withCallQuality:linphone_call_get_average_quality(selectedCall)]; } else { [addVideo setTitle:NSLocalizedString(@"+video", nil) forState:UIControlStateNormal]; } [addVideo setEnabled:YES]; } else { [addVideo setEnabled:NO]; + [videoCallQuality setImage:nil]; } } else { if (callsCount == 1) { @@ -842,21 +841,7 @@ void addAnimationFadeTransition(UIView* view, float duration) { [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]; diff --git a/Classes/IncallViewController.xib b/Classes/IncallViewController.xib index 82c7d024a..35234f6ba 100644 --- a/Classes/IncallViewController.xib +++ b/Classes/IncallViewController.xib @@ -12,6 +12,7 @@ YES + IBUIImageView IBUIViewController IBUIButton IBUIView @@ -53,7 +54,7 @@ {320, 480} - + _NS:196 3 @@ -77,6 +78,17 @@ IBCocoaTouchFramework + + + 292 + {{4, 428}, {28, 28}} + + + + _NS:567 + NO + IBCocoaTouchFramework + {320, 460} @@ -872,14 +884,6 @@ 51 - - - eight - - - - 75 - six @@ -1008,6 +1012,22 @@ 133 + + + eight + + + + 75 + + + + videoCallQuality + + + + 138 + doAction: @@ -1146,12 +1166,6 @@ 1 - - 33 - - - 8 - 40 @@ -1287,8 +1301,9 @@ YES - + + video @@ -1296,6 +1311,9 @@ 127 + + YES + preview @@ -1305,6 +1323,18 @@ display + + 137 + + + videocallquality + + + 33 + + + 8 + @@ -1332,6 +1362,7 @@ 13.IBPluginDependency 13.IBUIButtonInspectorSelectedStateConfigurationMetadataKey 132.IBPluginDependency + 137.IBPluginDependency 15.IBPluginDependency 16.CustomClassName 16.IBPluginDependency @@ -1394,6 +1425,7 @@ com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin UIMuteButton com.apple.InterfaceBuilder.IBCocoaTouchPlugin @@ -1444,7 +1476,7 @@ - 136 + 138 @@ -1493,6 +1525,7 @@ star three two + videoCallQuality videoGroup videoPreview videoView @@ -1527,6 +1560,7 @@ UIButton UIButton UIButton + UIImageView UIView UIView UIView @@ -1564,6 +1598,7 @@ star three two + videoCallQuality videoGroup videoPreview videoView @@ -1676,6 +1711,10 @@ two UIButton + + videoCallQuality + UIImageView + videoGroup UIView 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/linphonerc b/linphonerc index ef80ec31e..6dd0d69b0 100644 --- a/linphonerc +++ b/linphonerc @@ -45,4 +45,5 @@ capture=1 show_local=0 enabled=1 size=qvga +display_filter_auto_rotate=1 diff --git a/submodules/linphone b/submodules/linphone index 86cb50783..933c931a0 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit 86cb50783bf6923fc812219066d4aefd656ee80a +Subproject commit 933c931a0cd928e74bece7807099f38583d42a3c From 47bd00bde7d9340920dd1cfeb4ed70b438f4d76f Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Wed, 14 Mar 2012 17:40:25 +0100 Subject: [PATCH 05/34] Restore 'switch' camera feature --- Classes/InCallViewController-ipad.xib | 167 ++--- Classes/IncallViewController.h | 2 + Classes/IncallViewController.m | 9 +- Classes/IncallViewController.xib | 877 ++++++++++++++------------ Classes/LinphoneUI/UICamSwitch.m | 2 +- submodules/linphone | 2 +- 6 files changed, 566 insertions(+), 493 deletions(-) diff --git a/Classes/InCallViewController-ipad.xib b/Classes/InCallViewController-ipad.xib index 5eafb957e..517f2cf6f 100644 --- a/Classes/InCallViewController-ipad.xib +++ b/Classes/InCallViewController-ipad.xib @@ -39,33 +39,9 @@ 274 - - - 274 - {768, 805} - - - - _NS:408 - - 3 - MSAwAA - - 2 - - - YES - IBIPadFramework - YES - 0 - YES - 80 - 22 - 22 - - -2147483374 + 274 @@ -73,7 +49,7 @@ {768, 1024} - + _NS:569 NO IBIPadFramework @@ -99,51 +75,12 @@ 3 MQA - + + 2 + IBIPadFramework - - - 292 - {{0, 962}, {108, 62}} - - - - NO - IBIPadFramework - 0 - 0 - 1 - switch - - 3 - MQA - - - 1 - MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA - - - 3 - MC41AA - - - NSImage - clavier-01-108px.png - - - Helvetica-Bold - Helvetica - 2 - 15 - - - Helvetica-Bold - 15 - 16 - - {768, 1024} @@ -156,6 +93,69 @@ 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 + {768, 805} + + + + _NS:408 + + 3 + MSAwAA + + + YES + IBIPadFramework + YES + 0 + YES + 80 + 22 + 22 + 292 @@ -475,7 +475,7 @@ {{119, 251}, {82, 52}} - + NO NO @@ -1048,6 +1048,14 @@ 163 + + + videoCameraSwitch + + + + 164 + dataSource @@ -1126,8 +1134,9 @@ - + + @@ -1319,7 +1328,6 @@ - @@ -1337,17 +1345,17 @@ video_view - - 154 - - - 153 call_quality_video + + 154 + + + @@ -1416,7 +1424,7 @@ - 163 + 164 @@ -1462,6 +1470,7 @@ UIButton UIButton UIImageView + UICamSwitch UIView UIView UIView @@ -1577,6 +1586,10 @@ videoCallQuality UIImageView + + videoCameraSwitch + UICamSwitch + videoGroup UIView diff --git a/Classes/IncallViewController.h b/Classes/IncallViewController.h index 696937041..e3d57e1c7 100644 --- a/Classes/IncallViewController.h +++ b/Classes/IncallViewController.h @@ -62,6 +62,7 @@ UIView* videoView; UIView* videoPreview; UIImageView* videoCallQuality; + UICamSwitch* videoCameraSwitch; bool dismissed; @@ -131,4 +132,5 @@ @property (nonatomic, retain) IBOutlet UIView* videoView; @property (nonatomic, retain) IBOutlet UIView* videoPreview; @property (nonatomic, retain) IBOutlet UIImageView* videoCallQuality; +@property (nonatomic, retain) IBOutlet UICamSwitch* videoCameraSwitch; @end diff --git a/Classes/IncallViewController.m b/Classes/IncallViewController.m index 12098d3b0..f4c0d7d0f 100644 --- a/Classes/IncallViewController.m +++ b/Classes/IncallViewController.m @@ -71,6 +71,7 @@ const NSInteger SECURE_BUTTON_TAG=5; @synthesize videoView; @synthesize videoPreview; @synthesize videoCallQuality; +@synthesize videoCameraSwitch; @synthesize addVideo; @@ -183,6 +184,10 @@ void addAnimationFadeTransition(UIView* view, float duration) { [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 @@ -194,6 +199,7 @@ void addAnimationFadeTransition(UIView* view, float duration) { [UIView setAnimationDuration:0.3]; [controlSubView setAlpha:0.0]; [hangUpView setAlpha:0.0]; + [videoCameraSwitch setAlpha:0.0]; [UIView commitAnimations]; hideControlsTimer = nil; @@ -232,6 +238,7 @@ void addAnimationFadeTransition(UIView* view, float duration) { [controlSubView setAlpha:1.0]; [hangUpView setAlpha:1.0]; [callTableView setAlpha:1.0]; + [videoCameraSwitch setAlpha:0.0]; [UIView commitAnimations]; if (hideControlsTimer != nil) { @@ -376,7 +383,7 @@ void addAnimationFadeTransition(UIView* view, float duration) { [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:nil]; - + [videoCameraSwitch setPreview:videoPreview]; } -(void) addCallPressed { diff --git a/Classes/IncallViewController.xib b/Classes/IncallViewController.xib index 35234f6ba..ef6e7df9a 100644 --- a/Classes/IncallViewController.xib +++ b/Classes/IncallViewController.xib @@ -12,11 +12,11 @@ YES - IBUIImageView - IBUIViewController - IBUIButton - IBUIView IBUITableView + IBUIViewController + IBUIImageView + IBUIView + IBUIButton IBProxyObject @@ -54,7 +54,7 @@ {320, 480} - + _NS:196 3 @@ -78,7 +78,7 @@ IBCocoaTouchFramework - + 292 {{4, 428}, {28, 28}} @@ -99,6 +99,52 @@ 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 @@ -139,37 +185,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}} @@ -456,7 +484,7 @@ {{119, 251}, {82, 52}} - + NO NO @@ -471,7 +499,7 @@ - + @@ -494,7 +522,7 @@ - + @@ -517,7 +545,7 @@ - + @@ -537,7 +565,7 @@ - + @@ -560,7 +588,7 @@ - + @@ -583,7 +611,7 @@ - + @@ -606,7 +634,7 @@ - + @@ -629,7 +657,7 @@ - + @@ -652,7 +680,7 @@ - + @@ -675,7 +703,7 @@ - + @@ -698,7 +726,7 @@ - + @@ -721,7 +749,7 @@ - + @@ -744,7 +772,7 @@ - + {{0, 71}, {320, 310}} @@ -782,219 +810,11 @@ YES - view + videoCallQuality - + - 23 - - - - endCtrl - - - - 99 - - - - star - - - - 56 - - - - two - - - - 59 - - - - one - - - - 54 - - - - four - - - - 67 - - - - hash - - - - 57 - - - - nine - - - - 58 - - - - padSubView - - - - 45 - - - - zero - - - - 55 - - - - seven - - - - 73 - - - - three - - - - 60 - - - - close - - - - 51 - - - - six - - - - 71 - - - - five - - - - 69 - - - - hangUpView - - - - 122 - - - - callTableView - - - - 109 - - - - controlSubView - - - - 44 - - - - mute - - - - 80 - - - - addCall - - - - 112 - - - - dialer - - - - 49 - - - - pause - - - - 115 - - - - speaker - - - - 82 - - - - contacts - - - - 84 - - - - mergeCalls - - - - 114 - - - - addVideo - - - - 125 - - - - videoGroup - - - - 129 + 138 @@ -1012,6 +832,174 @@ 133 + + + videoGroup + + + + 129 + + + + addVideo + + + + 125 + + + + mergeCalls + + + + 114 + + + + mute + + + + 80 + + + + addCall + + + + 112 + + + + contacts + + + + 84 + + + + dialer + + + + 49 + + + + speaker + + + + 82 + + + + pause + + + + 115 + + + + controlSubView + + + + 44 + + + + callTableView + + + + 109 + + + + five + + + + 69 + + + + nine + + + + 58 + + + + seven + + + + 73 + + + + six + + + + 71 + + + + four + + + + 67 + + + + three + + + + 60 + + + + zero + + + + 55 + + + + two + + + + 59 + + + + close + + + + 51 + + + + hash + + + + 57 + eight @@ -1022,11 +1010,59 @@ - videoCallQuality + one - + - 138 + 54 + + + + star + + + + 56 + + + + padSubView + + + + 45 + + + + endCtrl + + + + 99 + + + + hangUpView + + + + 122 + + + + view + + + + 23 + + + + videoCameraSwitch + + + + 141 @@ -1113,24 +1149,109 @@ + - 120 - + 126 + YES - + + + - hangupview + 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 @@ -1154,72 +1275,12 @@ pad - - 31 - - - star - - - 30 - - - 1 - - - 40 - - - hash - 36 5 - - 29 - - - close - - - 39 - - - 2 - - - 41 - - - 0 - - - 38 - - - 3 - - - 35 - - - 4 - - - 37 - - - 6 - - - 34 - - - 7 - 32 @@ -1227,107 +1288,52 @@ 9 - 106 - - + 34 + + + 7 - 26 - - - YES - - - - - - - - - - - controls + 37 + + + 6 - 113 - - - pauseresume + 35 + + + 4 - 13 - - - speaker + 38 + + + 3 - 17 - - - dialer + 41 + + + 0 - 15 - - - contacts + 39 + + + 2 - 111 - - - addcall + 29 + + + close - 16 - - - mute - - - 104 - - - merge - - - 123 - - - video - - - 126 - - - YES - - - - - - video - - - 127 - - - YES - - - preview - - - 132 - - - display - - - 137 - - - videocallquality + 40 + + + hash 33 @@ -1335,6 +1341,40 @@ 8 + + 30 + + + 1 + + + 31 + + + star + + + 120 + + + YES + + + + hangupview + + + 18 + + + end + + + 140 + + + camswitch + @@ -1363,6 +1403,8 @@ 13.IBUIButtonInspectorSelectedStateConfigurationMetadataKey 132.IBPluginDependency 137.IBPluginDependency + 140.CustomClassName + 140.IBPluginDependency 15.IBPluginDependency 16.CustomClassName 16.IBPluginDependency @@ -1425,6 +1467,8 @@ com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin + UICamSwitch + com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin UIMuteButton com.apple.InterfaceBuilder.IBCocoaTouchPlugin @@ -1476,7 +1520,7 @@ - 138 + 141 @@ -1526,6 +1570,7 @@ three two videoCallQuality + videoCameraSwitch videoGroup videoPreview videoView @@ -1561,6 +1606,7 @@ UIButton UIButton UIImageView + UICamSwitch UIView UIView UIView @@ -1599,6 +1645,7 @@ three two videoCallQuality + videoCameraSwitch videoGroup videoPreview videoView @@ -1715,6 +1762,10 @@ videoCallQuality UIImageView + + videoCameraSwitch + UICamSwitch + videoGroup UIView 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/submodules/linphone b/submodules/linphone index 933c931a0..058d6b297 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit 933c931a0cd928e74bece7807099f38583d42a3c +Subproject commit 058d6b2972138f8d2b3eb945fca19980544a1f12 From 8ccbfc55c80e0ea410c4237fd35cd68f030dee35 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Fri, 23 Mar 2012 13:50:49 +0100 Subject: [PATCH 06/34] Hide video view by default --- Classes/IncallViewController.m | 6 +++++- Classes/IncallViewController.xib | 30 +++++++++++++++++------------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/Classes/IncallViewController.m b/Classes/IncallViewController.m index f4c0d7d0f..cede3d142 100644 --- a/Classes/IncallViewController.m +++ b/Classes/IncallViewController.m @@ -216,6 +216,9 @@ void addAnimationFadeTransition(UIView* view, float duration) { [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); @@ -228,7 +231,6 @@ void addAnimationFadeTransition(UIView* view, float duration) { NSLog(@"new center: %f %f", videoView.center.x, videoView.center.y); done = true; } - } -(void) disableVideoDisplay { @@ -371,6 +373,8 @@ void addAnimationFadeTransition(UIView* view, float duration) { UITapGestureRecognizer* singleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(showControls:)]; [videoGroup addGestureRecognizer:singleFingerTap]; + videoGroup.alpha = 0; + [singleFingerTap release]; mVideoShown=FALSE; diff --git a/Classes/IncallViewController.xib b/Classes/IncallViewController.xib index ef6e7df9a..3d53bbb0b 100644 --- a/Classes/IncallViewController.xib +++ b/Classes/IncallViewController.xib @@ -56,9 +56,9 @@ _NS:196 - - 3 - MCAwAA + + 2 + MSAwLjU3MjI5NTY2NTcgMC41NzIzMDYyNzU0AA IBCocoaTouchFramework @@ -68,13 +68,10 @@ {{240, 354}, {80, 106}} - + - 3 - MQA - - 2 - + 1 + MC41MTk0NjE2OTQgMSAwLjA4NjA4NjE0NwA IBCocoaTouchFramework @@ -95,7 +92,10 @@ _NS:196 - + + 1 + MC40MzUwMTEzNDA3IDAuNjI1IDEAA + NO IBCocoaTouchFramework @@ -105,7 +105,7 @@ {320, 66} - + 1 MSAwIDAuMDgyMzIwMjU5MDQgMC4xOAA @@ -153,7 +153,10 @@ _NS:418 - + + 3 + MCAwAA + YES IBCocoaTouchFramework YES @@ -367,6 +370,7 @@ MC4xOTYwNzg0MzE0IDAuMzA5ODAzOTIxNiAwLjUyMTU2ODYyNzUAA + NSImage clavier-01-160px.png @@ -484,7 +488,7 @@ {{119, 251}, {82, 52}} - + NO NO From 6bdb1428cfeb06e7bf1f9f24964ccb47b7ce6e00 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Fri, 23 Mar 2012 14:02:58 +0100 Subject: [PATCH 07/34] fix previous commit --- Classes/IncallViewController.xib | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/Classes/IncallViewController.xib b/Classes/IncallViewController.xib index 3d53bbb0b..7d55123e4 100644 --- a/Classes/IncallViewController.xib +++ b/Classes/IncallViewController.xib @@ -56,9 +56,9 @@ _NS:196 - - 2 - MSAwLjU3MjI5NTY2NTcgMC41NzIzMDYyNzU0AA + + 3 + MCAwAA IBCocoaTouchFramework @@ -69,10 +69,7 @@ - - 1 - MC41MTk0NjE2OTQgMSAwLjA4NjA4NjE0NwA - + IBCocoaTouchFramework @@ -93,8 +90,8 @@ _NS:196 - 1 - MC40MzUwMTEzNDA3IDAuNjI1IDEAA + 2 + MC4wNTQ5MDE5NjA3OCAwLjA4MjM1Mjk0MTE4IDAuMTI5NDExNzY0NwA NO IBCocoaTouchFramework @@ -153,10 +150,7 @@ _NS:418 - - 3 - MCAwAA - + YES IBCocoaTouchFramework YES @@ -178,7 +172,6 @@ {{0, 1}, {320, 66}} - 1 MSAwIDAuMDgyMzIwMjU5MDQgMC4xOAA From 7a63d313ef7dd0afe27c2a34e4a49aa0025ea7cb Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Fri, 23 Mar 2012 15:08:04 +0100 Subject: [PATCH 08/34] Add 'busy' indicator when pressing add/remove video button --- Classes/IncallViewController.h | 7 ++- Classes/IncallViewController.m | 37 +++++++------ Classes/IncallViewController.xib | 66 +++++++++++++++++++++--- Classes/LinphoneUI/LinphoneManager.m | 26 +++++----- Classes/LinphoneUI/UIToggleVideoButton.h | 8 ++- Classes/LinphoneUI/UIToggleVideoButton.m | 6 +++ submodules/linphone | 2 +- 7 files changed, 111 insertions(+), 41 deletions(-) diff --git a/Classes/IncallViewController.h b/Classes/IncallViewController.h index e3d57e1c7..a7336bb22 100644 --- a/Classes/IncallViewController.h +++ b/Classes/IncallViewController.h @@ -22,6 +22,7 @@ #import "ConferenceCallDetailView.h" #import #include "UILinphone.h" +#import "UIToggleVideoButton.h" @class VideoViewController; @@ -36,7 +37,7 @@ UIButton* pause; UISpeakerButton* speaker; UIButton* contacts; - UIButton* addVideo; + UIToggleVideoButton* addVideo; UITableView* callTableView; UIButton* addCall, *mergeCalls; @@ -63,6 +64,7 @@ UIView* videoPreview; UIImageView* videoCallQuality; UICamSwitch* videoCameraSwitch; + UIActivityIndicatorView* videoUpdateIndicator; bool dismissed; @@ -108,7 +110,7 @@ @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; @@ -133,4 +135,5 @@ @property (nonatomic, retain) IBOutlet UIView* videoPreview; @property (nonatomic, retain) IBOutlet UIImageView* videoCallQuality; @property (nonatomic, retain) IBOutlet UICamSwitch* videoCameraSwitch; +@property (nonatomic, retain) IBOutlet UIActivityIndicatorView* videoUpdateIndicator; @end diff --git a/Classes/IncallViewController.m b/Classes/IncallViewController.m index cede3d142..550320619 100644 --- a/Classes/IncallViewController.m +++ b/Classes/IncallViewController.m @@ -72,6 +72,7 @@ const NSInteger SECURE_BUTTON_TAG=5; @synthesize videoPreview; @synthesize videoCallQuality; @synthesize videoCameraSwitch; +@synthesize videoUpdateIndicator; @synthesize addVideo; @@ -261,7 +262,7 @@ void addAnimationFadeTransition(UIView* view, float duration) { [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone]; } --(void) updateUIFromLinphoneState:(UIViewController *)viewCtrl { +-(void) updateUIFromLinphoneState:(BOOL) fullUpdate { activeCallCell = nil; [mute reset]; @@ -291,17 +292,21 @@ void addAnimationFadeTransition(UIView* view, float duration) { [LinphoneManager set:pause hidden:YES withName:"PAUSE button" andReason:AT]; } - if (linphone_call_get_state(selectedCall) == LinphoneCallStreamsRunning) { - if (linphone_call_params_video_enabled(linphone_call_get_current_params(selectedCall))) { - [addVideo setTitle:NSLocalizedString(@"-video", nil) forState:UIControlStateNormal]; - [IncallViewController updateIndicator: videoCallQuality withCallQuality:linphone_call_get_average_quality(selectedCall)]; + if (fullUpdate) { + videoUpdateIndicator.hidden = YES; + LinphoneCallState state = linphone_call_get_state(selectedCall); + if (state == LinphoneCallStreamsRunning || state == LinphoneCallUpdated || state == LinphoneCallUpdatedByRemote) { + if (linphone_call_params_video_enabled(linphone_call_get_current_params(selectedCall))) { + [addVideo setTitle:NSLocalizedString(@"-video", nil) forState:UIControlStateNormal]; + [IncallViewController updateIndicator: videoCallQuality withCallQuality:linphone_call_get_average_quality(selectedCall)]; + } else { + [addVideo setTitle:NSLocalizedString(@"+video", nil) forState:UIControlStateNormal]; + } + [addVideo setEnabled:YES]; } else { - [addVideo setTitle:NSLocalizedString(@"+video", nil) forState:UIControlStateNormal]; + [addVideo setEnabled:NO]; + [videoCallQuality setImage:nil]; } - [addVideo setEnabled:YES]; - } else { - [addVideo setEnabled:NO]; - [videoCallQuality setImage:nil]; } } else { if (callsCount == 1) { @@ -388,6 +393,7 @@ void addAnimationFadeTransition(UIView* view, float duration) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:nil]; [videoCameraSwitch setPreview:videoPreview]; + addVideo.videoUpdateIndicator = videoUpdateIndicator; } -(void) addCallPressed { @@ -433,7 +439,7 @@ void addAnimationFadeTransition(UIView* view, float duration) { -(void)updateCallsDurations { - [self updateUIFromLinphoneState: nil]; + [self updateUIFromLinphoneState: NO]; } -(void) awakeFromNib @@ -523,7 +529,7 @@ void addAnimationFadeTransition(UIView* view, float duration) { 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 { @@ -537,7 +543,7 @@ void addAnimationFadeTransition(UIView* view, float duration) { if (call !=nil && linphone_call_get_dir(call)==LinphoneCallIncoming) { if ([speaker isOn]) [speaker toggle]; } - [self updateUIFromLinphoneState: nil]; + [self updateUIFromLinphoneState: YES]; [self disableVideoDisplay]; } @@ -560,11 +566,12 @@ void addAnimationFadeTransition(UIView* view, float duration) { [self dismissModalViewControllerAnimated:FALSE]; //disable animation to avoid blanc bar just below status bar*/ dismissed = true; - [self updateUIFromLinphoneState: nil]; + [self updateUIFromLinphoneState: YES]; } -(void) displayVideoCall:(LinphoneCall*) call FromUI:(UIViewController*) viewCtrl forUser:(NSString*) username withDisplayName:(NSString*) displayName { [self enableVideoDisplay]; + [self updateUIFromLinphoneState: YES]; return; if (mIncallViewIsReady) { @@ -1017,7 +1024,7 @@ void addAnimationFadeTransition(UIView* view, float duration) { linphone_core_resume_call([LinphoneManager getLc], selectedCall); } - [self updateUIFromLinphoneState: nil]; + [self updateUIFromLinphoneState: YES]; } diff --git a/Classes/IncallViewController.xib b/Classes/IncallViewController.xib index 7d55123e4..ee5e4d9cc 100644 --- a/Classes/IncallViewController.xib +++ b/Classes/IncallViewController.xib @@ -12,12 +12,13 @@ YES - IBUITableView - IBUIViewController - IBUIImageView - IBUIView IBUIButton + IBUIImageView + IBUIViewController IBProxyObject + IBUIActivityIndicatorView + IBUITableView + IBUIView YES @@ -172,6 +173,7 @@ {{0, 1}, {320, 66}} + 1 MSAwIDAuMDgyMzIwMjU5MDQgMC4xOAA @@ -344,7 +346,7 @@ {{213, 70}, {107, 66}} - + NO NO @@ -371,6 +373,19 @@ + + + -2147483356 + {{247.5, 84.5}, {37, 37}} + + + + _NS:1030 + NO + IBCocoaTouchFramework + NO + 0 + 292 @@ -1061,6 +1076,14 @@ 141 + + + videoUpdateIndicator + + + + 143 + doAction: @@ -1193,6 +1216,7 @@ + controls @@ -1372,6 +1396,12 @@ camswitch + + 142 + + + video_update_indicator + @@ -1402,6 +1432,7 @@ 137.IBPluginDependency 140.CustomClassName 140.IBPluginDependency + 142.IBPluginDependency 15.IBPluginDependency 16.CustomClassName 16.IBPluginDependency @@ -1467,6 +1498,7 @@ UICamSwitch com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin UIMuteButton com.apple.InterfaceBuilder.IBCocoaTouchPlugin @@ -1517,7 +1549,7 @@ - 141 + 143 @@ -1570,6 +1602,7 @@ videoCameraSwitch videoGroup videoPreview + videoUpdateIndicator videoView videoViewController zero @@ -1577,7 +1610,7 @@ YES UIButton - UIButton + UIToggleVideoButton UITableView UIButton UIViewController @@ -1606,6 +1639,7 @@ UICamSwitch UIView UIView + UIActivityIndicatorView UIView VideoViewController UIButton @@ -1645,6 +1679,7 @@ videoCameraSwitch videoGroup videoPreview + videoUpdateIndicator videoView videoViewController zero @@ -1657,7 +1692,7 @@ addVideo - UIButton + UIToggleVideoButton callTableView @@ -1771,6 +1806,10 @@ videoPreview UIView + + videoUpdateIndicator + UIActivityIndicatorView + videoView UIView @@ -1852,6 +1891,17 @@ UIToggleVideoButton UIButton + + videoUpdateIndicator + UIActivityIndicatorView + + + videoUpdateIndicator + + videoUpdateIndicator + UIActivityIndicatorView + + IBProjectSource ./Classes/UIToggleVideoButton.h diff --git a/Classes/LinphoneUI/LinphoneManager.m b/Classes/LinphoneUI/LinphoneManager.m index 1bc1097d5..28a8e3eba 100644 --- a/Classes/LinphoneUI/LinphoneManager.m +++ b/Classes/LinphoneUI/LinphoneManager.m @@ -162,19 +162,7 @@ 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]; - } else { - [callDelegate displayInCall:call FromUI:mCurrentViewController forUser:lUserName withDisplayName:lDisplayName]; - } - break; - + switch (new_state) { case LinphoneCallIncomingReceived: [callDelegate displayIncomingCall:call NotificationFromUI:mCurrentViewController @@ -276,8 +264,18 @@ 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; + default: + break; } } diff --git a/Classes/LinphoneUI/UIToggleVideoButton.h b/Classes/LinphoneUI/UIToggleVideoButton.h index c9a6cc83c..37a712ddd 100644 --- a/Classes/LinphoneUI/UIToggleVideoButton.h +++ b/Classes/LinphoneUI/UIToggleVideoButton.h @@ -19,6 +19,12 @@ #import -@interface UIToggleVideoButton : UIButton +@interface UIToggleVideoButton : UIButton { + UIActivityIndicatorView* videoUpdateIndicator; +} + - (id)initWithCoder:(NSCoder *)decoder; + +@property (nonatomic, retain) IBOutlet UIActivityIndicatorView* videoUpdateIndicator; + @end diff --git a/Classes/LinphoneUI/UIToggleVideoButton.m b/Classes/LinphoneUI/UIToggleVideoButton.m index 9f8db414d..1c96079a3 100644 --- a/Classes/LinphoneUI/UIToggleVideoButton.m +++ b/Classes/LinphoneUI/UIToggleVideoButton.m @@ -22,12 +22,18 @@ @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)); diff --git a/submodules/linphone b/submodules/linphone index 058d6b297..a43d75d8a 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit 058d6b2972138f8d2b3eb945fca19980544a1f12 +Subproject commit a43d75d8a36099f14638eaf14606535fe559df7b From a8717b856f28bb6f7716ffcbb6e59899c5d16a57 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Fri, 23 Mar 2012 15:57:10 +0100 Subject: [PATCH 09/34] Add (commented out) code to prevent video controls buttons scaling --- Classes/IncallViewController.m | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Classes/IncallViewController.m b/Classes/IncallViewController.m index 550320619..1b44b2247 100644 --- a/Classes/IncallViewController.m +++ b/Classes/IncallViewController.m @@ -394,6 +394,17 @@ void addAnimationFadeTransition(UIView* view, float duration) { [videoCameraSwitch setPreview:videoPreview]; addVideo.videoUpdateIndicator = videoUpdateIndicator; + + // 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) addCallPressed { From b7c5aff208145bca310ccbfd86c3b121e03fec15 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Mon, 26 Mar 2012 15:26:21 +0200 Subject: [PATCH 10/34] video: show spinner until 1st frame is successfully received/decoded/shown --- Classes/InCallViewController-ipad.xib | 97 +++++++++++++++++++++--- Classes/IncallViewController.h | 3 + Classes/IncallViewController.m | 8 +- Classes/IncallViewController.xib | 48 ++++++++++-- Classes/LinphoneUI/LinphoneManager.m | 12 ++- Classes/LinphoneUI/LinphoneUIDelegates.h | 1 + Classes/PhoneViewController.m | 4 + submodules/linphone | 2 +- 8 files changed, 157 insertions(+), 18 deletions(-) diff --git a/Classes/InCallViewController-ipad.xib b/Classes/InCallViewController-ipad.xib index 517f2cf6f..3a00313b4 100644 --- a/Classes/InCallViewController-ipad.xib +++ b/Classes/InCallViewController-ipad.xib @@ -11,12 +11,13 @@ 933 + IBUIButton IBUIImageView IBUIViewController + IBProxyObject + IBUIActivityIndicatorView IBUITableView IBUIView - IBUIButton - IBProxyObject com.apple.InterfaceBuilder.IBCocoaTouchPlugin @@ -65,13 +66,25 @@ NO IBIPadFramework + + + 292 + {{366, 493}, {37, 37}} + + + _NS:1062 + NO + IBIPadFramework + NO + 0 + 292 {{598, 799}, {170, 225}} - + 3 MQA @@ -140,7 +153,7 @@ {768, 805} - + _NS:408 3 @@ -344,7 +357,7 @@ {{213, 70}, {107, 66}} - + NO NO @@ -366,6 +379,19 @@ + + + 292 + {{247.5, 84.5}, {37, 37}} + + + + _NS:1062 + NO + IBIPadFramework + NO + 0 + 292 @@ -782,7 +808,7 @@ {{0, 20}, {768, 1004}} - + _NS:212 IBIPadFramework @@ -1056,6 +1082,22 @@ 164 + + + videoUpdateIndicator + + + + 167 + + + + videoWaitingForFirstImage + + + + 168 + dataSource @@ -1171,6 +1213,7 @@ + controls @@ -1329,6 +1372,7 @@ + video @@ -1336,6 +1380,7 @@ 158 + video_preview @@ -1356,6 +1401,17 @@ + + 165 + + + toggleVideoIndicator + + + 166 + + + @@ -1393,6 +1449,8 @@ 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 @@ -1424,7 +1482,7 @@ - 164 + 168 @@ -1444,7 +1502,7 @@ UIButton - UIButton + UIToggleVideoButton UITableView UIButton UIViewController @@ -1473,8 +1531,10 @@ UICamSwitch UIView UIView + UIActivityIndicatorView UIView VideoViewController + UIActivityIndicatorView UIButton @@ -1484,7 +1544,7 @@ addVideo - UIButton + UIToggleVideoButton callTableView @@ -1598,6 +1658,10 @@ videoPreview UIView + + videoUpdateIndicator + UIActivityIndicatorView + videoView UIView @@ -1606,6 +1670,10 @@ videoViewController VideoViewController + + videoWaitingForFirstImage + UIActivityIndicatorView + zero UIButton @@ -1678,6 +1746,17 @@ UIToggleVideoButton UIButton + + videoUpdateIndicator + UIActivityIndicatorView + + + videoUpdateIndicator + + videoUpdateIndicator + UIActivityIndicatorView + + IBProjectSource ./Classes/UIToggleVideoButton.h diff --git a/Classes/IncallViewController.h b/Classes/IncallViewController.h index a7336bb22..81f6e588c 100644 --- a/Classes/IncallViewController.h +++ b/Classes/IncallViewController.h @@ -65,6 +65,7 @@ UIImageView* videoCallQuality; UICamSwitch* videoCameraSwitch; UIActivityIndicatorView* videoUpdateIndicator; + UIActivityIndicatorView* videoWaitingForFirstImage; bool dismissed; @@ -136,4 +137,6 @@ @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 1b44b2247..926d84d5b 100644 --- a/Classes/IncallViewController.m +++ b/Classes/IncallViewController.m @@ -73,6 +73,7 @@ const NSInteger SECURE_BUTTON_TAG=5; @synthesize videoCallQuality; @synthesize videoCameraSwitch; @synthesize videoUpdateIndicator; +@synthesize videoWaitingForFirstImage; @synthesize addVideo; @@ -583,6 +584,7 @@ void addAnimationFadeTransition(UIView* view, float duration) { [self enableVideoDisplay]; [self updateUIFromLinphoneState: YES]; + videoWaitingForFirstImage.hidden = NO; return; if (mIncallViewIsReady) { @@ -633,6 +635,11 @@ void addAnimationFadeTransition(UIView* view, float duration) { [visibleActionSheet release]; } +-(void) firstVideoFrameDecoded: (LinphoneCall*) call { + // hide video in progress view indicator + videoWaitingForFirstImage.hidden = TRUE; +} + - (IBAction)doAction:(id)sender { if (sender == dialer) { @@ -1038,5 +1045,4 @@ void addAnimationFadeTransition(UIView* view, float duration) { [self updateUIFromLinphoneState: YES]; } - @end diff --git a/Classes/IncallViewController.xib b/Classes/IncallViewController.xib index ee5e4d9cc..0d5a16bd6 100644 --- a/Classes/IncallViewController.xib +++ b/Classes/IncallViewController.xib @@ -84,6 +84,19 @@ NO IBCocoaTouchFramework + + + 292 + {{141, 212}, {37, 37}} + + + _NS:1030 + NO + IBCocoaTouchFramework + NO + YES + 0 + {320, 460} @@ -346,7 +359,7 @@ {{213, 70}, {107, 66}} - + NO NO @@ -373,7 +386,7 @@ - + -2147483356 {{247.5, 84.5}, {37, 37}} @@ -1080,10 +1093,18 @@ videoUpdateIndicator - + 143 + + + videoWaitingForFirstImage + + + + 145 + doAction: @@ -1181,6 +1202,7 @@ + video @@ -1216,7 +1238,7 @@ - + controls @@ -1398,10 +1420,15 @@ 142 - + video_update_indicator + + 144 + + + @@ -1433,6 +1460,7 @@ 140.CustomClassName 140.IBPluginDependency 142.IBPluginDependency + 144.IBPluginDependency 15.IBPluginDependency 16.CustomClassName 16.IBPluginDependency @@ -1499,6 +1527,7 @@ com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin UIMuteButton com.apple.InterfaceBuilder.IBCocoaTouchPlugin @@ -1549,7 +1578,7 @@ - 143 + 145 @@ -1605,6 +1634,7 @@ videoUpdateIndicator videoView videoViewController + videoWaitingForFirstImage zero @@ -1642,6 +1672,7 @@ UIActivityIndicatorView UIView VideoViewController + UIActivityIndicatorView UIButton @@ -1682,6 +1713,7 @@ videoUpdateIndicator videoView videoViewController + videoWaitingForFirstImage zero @@ -1818,6 +1850,10 @@ videoViewController VideoViewController + + videoWaitingForFirstImage + UIActivityIndicatorView + zero UIButton diff --git a/Classes/LinphoneUI/LinphoneManager.m b/Classes/LinphoneUI/LinphoneManager.m index 28a8e3eba..3221ca359 100644 --- a/Classes/LinphoneUI/LinphoneManager.m +++ b/Classes/LinphoneUI/LinphoneManager.m @@ -400,6 +400,15 @@ 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]; } + +-(void) call_video_first_image_decoded:(LinphoneCall*) call { + [callDelegate firstVideoFrameDecoded: call]; +} + +static void linphone_call_first_video_frame(LinphoneCore* lc, LinphoneCall* call) { + [[LinphoneManager instance] call_video_first_image_decoded: call]; +} + static LinphoneCoreVTable linphonec_vtable = { .show =NULL, .call_state_changed =(LinphoneCallStateCb)linphone_iphone_call_state, @@ -412,7 +421,8 @@ static LinphoneCoreVTable linphonec_vtable = { .display_warning=linphone_iphone_log, .display_url=NULL, .text_received=NULL, - .dtmf_received=NULL + .dtmf_received=NULL, + .call_first_video_frame=linphone_call_first_video_frame }; diff --git a/Classes/LinphoneUI/LinphoneUIDelegates.h b/Classes/LinphoneUI/LinphoneUIDelegates.h index 0023ede04..4d6b0477d 100644 --- a/Classes/LinphoneUI/LinphoneUIDelegates.h +++ b/Classes/LinphoneUI/LinphoneUIDelegates.h @@ -29,6 +29,7 @@ //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/PhoneViewController.m b/Classes/PhoneViewController.m index 42c5e5352..65de89c11 100644 --- a/Classes/PhoneViewController.m +++ b/Classes/PhoneViewController.m @@ -396,5 +396,9 @@ [self updateStatusSubView]; } +-(void) firstVideoFrameDecoded: (LinphoneCall*) call { + [mIncallViewController firstVideoFrameDecoded:call]; +} + @end diff --git a/submodules/linphone b/submodules/linphone index a43d75d8a..c474ef27b 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit a43d75d8a36099f14638eaf14606535fe559df7b +Subproject commit c474ef27bc1b6d2951bb3a4c8ad7343f7171bbea From 0b178c40b1b9b5f817fed02c65d3c0a452ae5157 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Mon, 26 Mar 2012 17:27:49 +0200 Subject: [PATCH 11/34] Fix merge error --- Classes/VideoViewController-ipad.xib | 192 +++++++++++++++++++++++++-- 1 file changed, 182 insertions(+), 10 deletions(-) diff --git a/Classes/VideoViewController-ipad.xib b/Classes/VideoViewController-ipad.xib index 3bad877cd..01b0daa4c 100644 --- a/Classes/VideoViewController-ipad.xib +++ b/Classes/VideoViewController-ipad.xib @@ -60,20 +60,12 @@ NO IBIPadFramework - - - 292 - {{20, 956}, {28, 28}} - - _NS:567 - NO - IBIPadFramework - 292 {{329, 962}, {108, 62}} + NO IBIPadFramework @@ -116,6 +108,7 @@ 292 {{223, 962}, {108, 62}} + NO IBIPadFramework @@ -152,6 +145,7 @@ 292 {{436, 962}, {108, 62}} + NO IBIPadFramework @@ -183,6 +177,7 @@ {768, 1024} + _NS:212 @@ -200,6 +195,7 @@ 292 {1024, 768} + _NS:569 NO @@ -210,6 +206,7 @@ 292 {{799, 598}, {225, 170}} + 3 MQA @@ -222,6 +219,7 @@ 292 {{351, 706}, {108, 62}} + NO IBIPadFramework @@ -242,6 +240,7 @@ 292 {{458, 706}, {108, 62}} + NO IBIPadFramework @@ -263,6 +262,7 @@ 292 {{565, 706}, {108, 62}} + NO IBIPadFramework @@ -285,6 +285,7 @@ 292 {{20, 720}, {28, 28}} + _NS:567 NO IBIPadFramework @@ -292,6 +293,7 @@ {1024, 768} + _NS:212 @@ -313,6 +315,7 @@ 292 {1024, 768} + _NS:569 NO @@ -323,6 +326,7 @@ 292 {{799, 598}, {225, 170}} + 3 MQA @@ -335,6 +339,7 @@ 292 {{351, 706}, {108, 62}} + NO IBIPadFramework @@ -355,6 +360,7 @@ 292 {{458, 706}, {108, 62}} + NO IBIPadFramework @@ -376,6 +382,7 @@ 292 {{565, 706}, {108, 62}} + NO IBIPadFramework @@ -398,6 +405,7 @@ 292 {{20, 720}, {28, 28}} + _NS:567 NO IBIPadFramework @@ -405,6 +413,7 @@ {1024, 768} + _NS:212 @@ -807,7 +816,170 @@ 53 - + + + + UICamSwitch + UIButton + + preview + UIView + + + preview + + preview + UIView + + + + IBProjectSource + ./Classes/UICamSwitch.h + + + + UIHangUpButton + UIButton + + IBProjectSource + ./Classes/UIHangUpButton.h + + + + UIMuteButton + UIToggleButton + + IBProjectSource + ./Classes/UIMuteButton.h + + + + UIToggleButton + UIButton + + IBProjectSource + ./Classes/UIToggleButton.h + + + + VideoViewController + UIViewController + + UIImageView + UIImageView + UIImageView + UICamSwitch + UICamSwitch + UICamSwitch + UIView + UIView + UIView + UIHangUpButton + UIHangUpButton + UIHangUpButton + UIView + UIView + UIMuteButton + UIMuteButton + UIMuteButton + UIView + UIView + UIView + UIView + + + + mCallQuality + UIImageView + + + mCallQualityLandLeft + UIImageView + + + mCallQualityLandRight + UIImageView + + + mCamSwitch + UICamSwitch + + + mCamSwitchLandLeft + UICamSwitch + + + mCamSwitchLandRight + UICamSwitch + + + mDisplay + UIView + + + mDisplayLandLeft + UIView + + + mDisplayLandRight + UIView + + + mHangUp + UIHangUpButton + + + mHangUpLandLeft + UIHangUpButton + + + mHangUpLandRight + UIHangUpButton + + + mLandscapeLeft + UIView + + + mLandscapeRight + UIView + + + mMute + UIMuteButton + + + mMuteLandLeft + UIMuteButton + + + mMuteLandRight + UIMuteButton + + + mPortrait + UIView + + + mPreview + UIView + + + mPreviewLandLeft + UIView + + + mPreviewLandRight + UIView + + + + IBProjectSource + ./Classes/VideoViewController.h + + + + 0 IBIPadFramework YES From 9633d4ccb8dd883e19c03c301e10d2fd492764d5 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Tue, 27 Mar 2012 09:32:30 +0200 Subject: [PATCH 12/34] Code cleanup --- Classes/LinphoneAppDelegate.m | 6 ++++-- Classes/LinphoneUI/LinphoneManager.m | 17 +++-------------- submodules/linphone | 2 +- 3 files changed, 8 insertions(+), 17 deletions(-) diff --git a/Classes/LinphoneAppDelegate.m b/Classes/LinphoneAppDelegate.m index c397dc18f..fbb0524fb 100644 --- a/Classes/LinphoneAppDelegate.m +++ b/Classes/LinphoneAppDelegate.m @@ -220,13 +220,15 @@ 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]; /* explicitely instanciate LinphoneManager */ LinphoneManager* lm = [[LinphoneManager alloc] init]; assert(lm == [LinphoneManager instance]); - [self loadDefaultSettings: appDefaults]; + [self setupUI]; diff --git a/Classes/LinphoneUI/LinphoneManager.m b/Classes/LinphoneUI/LinphoneManager.m index cc9f0841e..30a3a526f 100644 --- a/Classes/LinphoneUI/LinphoneManager.m +++ b/Classes/LinphoneUI/LinphoneManager.m @@ -71,17 +71,6 @@ extern void libmsbcg729_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]; @@ -342,7 +331,7 @@ static void linphone_iphone_call_state(LinphoneCore *lc, LinphoneCall* call, Lin } -(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) ]:@""; @@ -483,7 +472,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; } @@ -553,7 +542,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"); diff --git a/submodules/linphone b/submodules/linphone index 8ffeb3eb7..83b2a2875 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit 8ffeb3eb7c7e5738883f6c247330316753bf173e +Subproject commit 83b2a28753afd37e10fa3e863758170c034a24b3 From b38d2f89cf698bd42cb6b8e047f5fca89208579d Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Tue, 27 Mar 2012 11:28:36 +0200 Subject: [PATCH 13/34] Add a 'do not auto start application' setting --- Classes/LinphoneAppDelegate.h | 2 ++ Classes/LinphoneAppDelegate.m | 27 ++++++++++++++++++++++----- Classes/LinphoneUI/LinphoneManager.m | 3 --- Settings.bundle/Advanced.plist | 10 ++++++++++ 4 files changed, 34 insertions(+), 8 deletions(-) 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 fbb0524fb..c0f8723b6 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) { @@ -223,22 +232,30 @@ int __aeabi_idiv(int a, int b) { 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 setupUI]; - + [[LinphoneManager instance] startLibLinphone]; [[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeSound]; [self setupGSMInteraction]; - - return YES; } diff --git a/Classes/LinphoneUI/LinphoneManager.m b/Classes/LinphoneUI/LinphoneManager.m index 30a3a526f..f04fac224 100644 --- a/Classes/LinphoneUI/LinphoneManager.m +++ b/Classes/LinphoneUI/LinphoneManager.m @@ -65,9 +65,6 @@ extern void libmsbcg729_init(); return self; } +(LinphoneManager*) instance { - if (theLinphoneManager==nil) { - [[LinphoneManager alloc] init]; - } return theLinphoneManager; } 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 From 501466bcfbd48395563356e08a2c7da16943f029 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Tue, 27 Mar 2012 14:19:42 +0200 Subject: [PATCH 14/34] Auto resize address text to fit label's width --- Classes/IncallViewController.m | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Classes/IncallViewController.m b/Classes/IncallViewController.m index 926d84d5b..c1a03b788 100644 --- a/Classes/IncallViewController.m +++ b/Classes/IncallViewController.m @@ -404,8 +404,8 @@ void addAnimationFadeTransition(UIView* view, float duration) { pause.imageView.contentMode = UIViewContentModeCenter; contacts.imageView.contentMode = UIViewContentModeCenter; addCall.imageView.contentMode = UIViewContentModeCenter; - dialer.imageView.contentMode = UIViewContentModeCenter; - */ + dialer.imageView.contentMode = UIViewContentModeCenter;*/ + } -(void) addCallPressed { @@ -585,6 +585,7 @@ void addAnimationFadeTransition(UIView* view, float duration) { [self enableVideoDisplay]; [self updateUIFromLinphoneState: YES]; videoWaitingForFirstImage.hidden = NO; + [videoWaitingForFirstImage startAnimating]; return; if (mIncallViewIsReady) { @@ -747,6 +748,8 @@ void addAnimationFadeTransition(UIView* view, float duration) { } 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); From e0c46d1ba7addc3f4c2b6344c2a5573fe1d3c02c Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Tue, 27 Mar 2012 15:23:43 +0200 Subject: [PATCH 15/34] Call history: differentiate audio only/video calls --- Classes/CallHistoryTableViewController.m | 4 ++-- submodules/linphone | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Classes/CallHistoryTableViewController.m b/Classes/CallHistoryTableViewController.m index 60d438d9b..1a06c1661 100644 --- a/Classes/CallHistoryTableViewController.m +++ b/Classes/CallHistoryTableViewController.m @@ -147,12 +147,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%s", displayName, callLogs->video_enabled?" (video)":""]; [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%s", username, callLogs->video_enabled?" (video)":""]; [cell.textLabel setText:str1]; [cell.detailTextLabel setText:nil]; } diff --git a/submodules/linphone b/submodules/linphone index 83b2a2875..9a21860f4 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit 83b2a28753afd37e10fa3e863758170c034a24b3 +Subproject commit 9a21860f49a6c4c52f5aafbcba84cf960d94b400 From bbc4e348f18d5a51e3d3afb8413e1782d04be340 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Tue, 27 Mar 2012 16:43:01 +0200 Subject: [PATCH 16/34] Notify the user (once) if during a video call the battery level goes below 10% --- Classes/CallDelegate.h | 3 +- Classes/IncallViewController.m | 48 +++++++++++++++++++++++++++- Classes/LinphoneAppDelegate.m | 2 ++ Classes/LinphoneUI/LinphoneManager.h | 4 +++ Classes/LinphoneUI/LinphoneManager.m | 9 ++++++ 5 files changed, 64 insertions(+), 2 deletions(-) diff --git a/Classes/CallDelegate.h b/Classes/CallDelegate.h index d32864706..f09b1fdbf 100644 --- a/Classes/CallDelegate.h +++ b/Classes/CallDelegate.h @@ -24,7 +24,8 @@ enum CallDelegateType { CD_UNDEFINED = 0, CD_NEW_CALL, CD_ZRTP, - CD_VIDEO_UPDATE + CD_VIDEO_UPDATE, + CD_STOP_VIDEO_ON_LOW_BATTERY }; @protocol UIActionSheetCustomDelegate diff --git a/Classes/IncallViewController.m b/Classes/IncallViewController.m index c1a03b788..1b0d2a049 100644 --- a/Classes/IncallViewController.m +++ b/Classes/IncallViewController.m @@ -207,6 +207,38 @@ void addAnimationFadeTransition(UIView* view, float duration) { 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]; @@ -233,6 +265,8 @@ void addAnimationFadeTransition(UIView* view, float duration) { NSLog(@"new center: %f %f", videoView.center.x, videoView.center.y); done = true; } + + [self batteryLevelChanged:nil]; } -(void) disableVideoDisplay { @@ -392,7 +426,9 @@ void addAnimationFadeTransition(UIView* view, float duration) { [[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; @@ -976,6 +1012,16 @@ void addAnimationFadeTransition(UIView* view, float duration) { 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; + } default: ms_error("Unhandled CallDelegate event of type: %d received - ignoring", type); } diff --git a/Classes/LinphoneAppDelegate.m b/Classes/LinphoneAppDelegate.m index c0f8723b6..138693a3d 100644 --- a/Classes/LinphoneAppDelegate.m +++ b/Classes/LinphoneAppDelegate.m @@ -207,6 +207,8 @@ int __aeabi_idiv(int a, int b) { [window makeKeyAndVisible]; [[LinphoneManager instance] setCallDelegate:myPhoneViewController]; + + [UIDevice currentDevice].batteryMonitoringEnabled = YES; } -(void) setupGSMInteraction { diff --git a/Classes/LinphoneUI/LinphoneManager.h b/Classes/LinphoneUI/LinphoneManager.h index 0977ce2ee..701e4bfa4 100644 --- a/Classes/LinphoneUI/LinphoneManager.h +++ b/Classes/LinphoneUI/LinphoneManager.h @@ -42,6 +42,10 @@ struct NetworkReachabilityContext { void (*networkStateChanged) (Connectivity newConnectivity); }; +typedef struct _LinphoneCallAppData { + bool_t batteryWarningShown; +} LinphoneCallAppData; + @interface LinphoneManager : NSObject { @protected diff --git a/Classes/LinphoneUI/LinphoneManager.m b/Classes/LinphoneUI/LinphoneManager.m index f04fac224..af4ca92da 100644 --- a/Classes/LinphoneUI/LinphoneManager.m +++ b/Classes/LinphoneUI/LinphoneManager.m @@ -150,6 +150,12 @@ extern void libmsbcg729_init(); bool canHideInCallView = (linphone_core_get_calls([LinphoneManager getLc]) == NULL); + 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 @@ -262,6 +268,9 @@ extern void libmsbcg729_init(); [callDelegate displayInCall:call FromUI:mCurrentViewController forUser:lUserName withDisplayName:lDisplayName]; } break; + case LinphoneCallReleased: + free (linphone_call_get_user_pointer(call)); + break; default: break; } From 4855e4744407c45edb6427b363895486dea40024 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Fri, 30 Mar 2012 14:17:43 +0200 Subject: [PATCH 17/34] Implement call transfers, and fix video spinner --- Classes/CallDelegate.h | 3 +- Classes/IncallViewController.h | 2 + Classes/IncallViewController.m | 88 +++++++++++++++++++++++++++- Classes/IncallViewController.xib | 82 +++++++++++++++++++++----- Classes/LinphoneUI/LinphoneManager.h | 3 + Classes/LinphoneUI/LinphoneManager.m | 17 +++--- Classes/LinphoneUI/UICallButton.h | 6 +- Classes/LinphoneUI/UICallButton.m | 27 ++++++++- Classes/PhoneViewController.m | 17 +++++- submodules/linphone | 2 +- 10 files changed, 213 insertions(+), 34 deletions(-) diff --git a/Classes/CallDelegate.h b/Classes/CallDelegate.h index f09b1fdbf..516c2074d 100644 --- a/Classes/CallDelegate.h +++ b/Classes/CallDelegate.h @@ -25,7 +25,8 @@ enum CallDelegateType { CD_NEW_CALL, CD_ZRTP, CD_VIDEO_UPDATE, - CD_STOP_VIDEO_ON_LOW_BATTERY + CD_STOP_VIDEO_ON_LOW_BATTERY, + CD_TRANSFER_CALL }; @protocol UIActionSheetCustomDelegate diff --git a/Classes/IncallViewController.h b/Classes/IncallViewController.h index 81f6e588c..e1bd40cdb 100644 --- a/Classes/IncallViewController.h +++ b/Classes/IncallViewController.h @@ -40,6 +40,7 @@ UIToggleVideoButton* addVideo; UITableView* callTableView; UIButton* addCall, *mergeCalls; + UIButton* transfer; //key pad @@ -115,6 +116,7 @@ @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; diff --git a/Classes/IncallViewController.m b/Classes/IncallViewController.m index 1b0d2a049..384cc840e 100644 --- a/Classes/IncallViewController.m +++ b/Classes/IncallViewController.m @@ -52,6 +52,7 @@ const NSInteger SECURE_BUTTON_TAG=5; @synthesize callTableView; @synthesize addCall; @synthesize mergeCalls; +@synthesize transfer; @synthesize one; @synthesize two; @@ -432,6 +433,8 @@ void addAnimationFadeTransition(UIView* view, float duration) { [videoCameraSwitch setPreview:videoPreview]; addVideo.videoUpdateIndicator = videoUpdateIndicator; + [transfer addTarget:self action:@selector(transferPressed) forControlEvents:UIControlEventTouchUpInside]; + // prevent buttons resizing /* endCtrl.imageView.contentMode = UIViewContentModeCenter; @@ -444,9 +447,49 @@ void addAnimationFadeTransition(UIView* view, float duration) { } +-(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 call to:",nil); + visibleActionSheet = [[UIActionSheet alloc] initWithTitle:title + delegate:cd + cancelButtonTitle:NSLocalizedString(@"Cancel",nil) + destructiveButtonTitle:NSLocalizedString(@"A new call",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; + } + + visibleActionSheet.actionSheetStyle = UIActionSheetStyleDefault; + [visibleActionSheet showInView:self.view]; +} + -(void) addCallPressed { [LinphoneManager logUIElementPressed:"CALL button"]; - [self dismissModalViewControllerAnimated:true]; + [[LinphoneManager instance] displayDialer]; } @@ -549,6 +592,7 @@ void addAnimationFadeTransition(UIView* view, float duration) { } if (!mVideoShown) [[UIApplication sharedApplication] setIdleTimerDisabled:false]; mIncallViewIsReady=FALSE; + dismissed = false; } - (void)viewDidUnload { @@ -600,6 +644,7 @@ void addAnimationFadeTransition(UIView* view, float duration) { UIViewController* modalVC = self.modalViewController; UIDevice *device = [UIDevice currentDevice]; device.proximityMonitoringEnabled = NO; + dismissed = true; if (modalVC != nil) { mVideoIsPending=FALSE; // clear previous native window ids @@ -613,15 +658,33 @@ void addAnimationFadeTransition(UIView* view, float duration) { } [self dismissModalViewControllerAnimated:FALSE]; //disable animation to avoid blanc bar just below status bar*/ - dismissed = true; [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) { @@ -1022,6 +1085,27 @@ void addAnimationFadeTransition(UIView* view, float duration) { } break; } + case CD_TRANSFER_CALL: { + LinphoneCall* call = (LinphoneCall*)datas; + if (buttonIndex == actionSheet.destructiveButtonIndex) { + // transfer to a new call: enable transfer mode and hide incallview + [UICallButton enableTransforMode:YES]; + [[LinphoneManager instance] displayDialer]; + } else { + // 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); + } + data->transferButtonIndex = -1; + calls = calls->next; + } + } + break; + } default: ms_error("Unhandled CallDelegate event of type: %d received - ignoring", type); } diff --git a/Classes/IncallViewController.xib b/Classes/IncallViewController.xib index 0d5a16bd6..7d509ae97 100644 --- a/Classes/IncallViewController.xib +++ b/Classes/IncallViewController.xib @@ -55,7 +55,7 @@ {320, 480} - + _NS:196 3 @@ -90,6 +90,7 @@ {{141, 212}, {37, 37}} + _NS:1030 NO IBCocoaTouchFramework @@ -227,7 +228,7 @@ 292 - {{107, 70}, {106, 66}} + {{160, 4}, {80, 66}} @@ -260,7 +261,7 @@ 292 - {{0, 4}, {107, 66}} + {{0, 4}, {80, 66}} @@ -301,10 +302,10 @@ 292 - {{0, 70}, {107, 66}} + {{0, 70}, {80, 66}} - + NO NO @@ -324,10 +325,37 @@ + + + 292 + {{80, 70}, {160, 66}} + + + + + NO + NO + IBCocoaTouchFramework + 0 + 0 + Transfer + + + 1 + MC4xOTYwNzg0MzE0IDAuMzA5ODAzOTIxNiAwLjUyMTU2ODYyNzUAA + + + + + 2 + 15 + + + 292 - {{213, 70}, {107, 66}} + {{240, 70}, {80, 66}} @@ -356,7 +384,7 @@ -2147483356 - {{213, 70}, {107, 66}} + {{240, 70}, {80, 66}} @@ -389,7 +417,7 @@ -2147483356 - {{247.5, 84.5}, {37, 37}} + {{261.5, 84.5}, {37, 37}} @@ -402,10 +430,10 @@ 292 - {{107, 4}, {106, 66}} + {{80, 4}, {80, 66}} - + NO NO @@ -428,7 +456,7 @@ 292 - {{213, 4}, {107, 66}} + {{240, 4}, {80, 66}} @@ -458,10 +486,10 @@ 292 - {{107, 70}, {106, 66}} + {{160, 4}, {80, 66}} - + NO NO @@ -1105,6 +1133,14 @@ 145 + + + transfer + + + + 150 + doAction: @@ -1239,6 +1275,7 @@ + controls @@ -1429,6 +1466,12 @@ + + 147 + + + transfer + @@ -1461,6 +1504,8 @@ 140.IBPluginDependency 142.IBPluginDependency 144.IBPluginDependency + 147.IBPluginDependency + 147.IBUIButtonInspectorSelectedStateConfigurationMetadataKey 15.IBPluginDependency 16.CustomClassName 16.IBPluginDependency @@ -1528,6 +1573,8 @@ com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin UIMuteButton com.apple.InterfaceBuilder.IBCocoaTouchPlugin @@ -1578,7 +1625,7 @@ - 145 + 150 @@ -1626,6 +1673,7 @@ speaker star three + transfer two videoCallQuality videoCameraSwitch @@ -1665,6 +1713,7 @@ UIButton UIButton UIButton + UIButton UIImageView UICamSwitch UIView @@ -1705,6 +1754,7 @@ speaker star three + transfer two videoCallQuality videoCameraSwitch @@ -1818,6 +1868,10 @@ three UIButton + + transfer + UIButton + two UIButton diff --git a/Classes/LinphoneUI/LinphoneManager.h b/Classes/LinphoneUI/LinphoneManager.h index 701e4bfa4..b0cace918 100644 --- a/Classes/LinphoneUI/LinphoneManager.h +++ b/Classes/LinphoneUI/LinphoneManager.h @@ -44,6 +44,7 @@ struct NetworkReachabilityContext { typedef struct _LinphoneCallAppData { bool_t batteryWarningShown; + int transferButtonIndex; } LinphoneCallAppData; @@ -74,6 +75,8 @@ typedef struct _LinphoneCallAppData { +(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 af4ca92da..ef5498cca 100644 --- a/Classes/LinphoneUI/LinphoneManager.m +++ b/Classes/LinphoneUI/LinphoneManager.m @@ -277,6 +277,12 @@ extern void libmsbcg729_init(); } +-(void) displayDialer { + [callDelegate displayDialerFromUI:mCurrentViewController + forUser:@"" + withDisplayName:@""]; +} + +(LinphoneCore*) getLc { if (theLinphoneCore==nil) { @throw([NSException exceptionWithName:@"LinphoneCoreException" reason:@"Linphone core not initialized yet" userInfo:nil]); @@ -399,14 +405,6 @@ static void linphone_iphone_registration_state(LinphoneCore *lc, LinphoneProxyCo [(LinphoneManager*)linphone_core_get_user_data(lc) onRegister:lc cfg:cfg state:state message:message]; } --(void) call_video_first_image_decoded:(LinphoneCall*) call { - [callDelegate firstVideoFrameDecoded: call]; -} - -static void linphone_call_first_video_frame(LinphoneCore* lc, LinphoneCall* call) { - [[LinphoneManager instance] call_video_first_image_decoded: call]; -} - static LinphoneCoreVTable linphonec_vtable = { .show =NULL, .call_state_changed =(LinphoneCallStateCb)linphone_iphone_call_state, @@ -419,8 +417,7 @@ static LinphoneCoreVTable linphonec_vtable = { .display_warning=linphone_iphone_log, .display_url=NULL, .text_received=NULL, - .dtmf_received=NULL, - .call_first_video_frame=linphone_call_first_video_frame + .dtmf_received=NULL }; 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 080912cd8..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) @@ -58,7 +69,12 @@ 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) @@ -78,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])); } @@ -100,6 +120,7 @@ */ -(void) initWithAddress:(UITextField*) address{ mAddress=[address retain]; + transferMode = NO; [self addTarget:self action:@selector(touchUp:) forControlEvents:UIControlEventTouchUpInside]; } diff --git a/Classes/PhoneViewController.m b/Classes/PhoneViewController.m index 65de89c11..091e04901 100644 --- a/Classes/PhoneViewController.m +++ b/Classes/PhoneViewController.m @@ -106,6 +106,8 @@ [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) { @@ -230,7 +232,6 @@ [myTabBarController setSelectedIndex:DIALER_TAB_INDEX]; [mMainScreenWithVideoPreview showPreview:YES]; - } //status reporting @@ -284,10 +285,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 { @@ -316,6 +326,8 @@ [LinphoneManager set:callLarge hidden:YES withName:"CALL_LARGE 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]; } @@ -325,6 +337,7 @@ withDisplayName:displayName]; [mMainScreenWithVideoPreview showPreview:NO]; + [self updateCallAndBackButtons]; } -(void) displayAskToEnableVideoCall:(LinphoneCall*) call forUser:(NSString*) username withDisplayName:(NSString*) displayName { diff --git a/submodules/linphone b/submodules/linphone index 9a21860f4..d481382fb 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit 9a21860f49a6c4c52f5aafbcba84cf960d94b400 +Subproject commit d481382fb4c55300737d1f6fc02cecb4d509cc60 From c491c0d6615502ca7935a4f0b873de89f7b0c8f6 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Tue, 3 Apr 2012 16:44:13 +0200 Subject: [PATCH 18/34] Call transfer notifications support --- Classes/IncallViewController.m | 19 ++++++++++++++++++- Classes/LinphoneUI/LinphoneManager.h | 1 + Classes/LinphoneUI/LinphoneManager.m | 14 ++++++++++---- submodules/linphone | 2 +- 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/Classes/IncallViewController.m b/Classes/IncallViewController.m index 384cc840e..f5ba66ade 100644 --- a/Classes/IncallViewController.m +++ b/Classes/IncallViewController.m @@ -892,10 +892,27 @@ static void hideSpinner(LinphoneCall* call, void* user_data) { [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]; diff --git a/Classes/LinphoneUI/LinphoneManager.h b/Classes/LinphoneUI/LinphoneManager.h index b0cace918..92fc3056d 100644 --- a/Classes/LinphoneUI/LinphoneManager.h +++ b/Classes/LinphoneUI/LinphoneManager.h @@ -44,6 +44,7 @@ struct NetworkReachabilityContext { typedef struct _LinphoneCallAppData { bool_t batteryWarningShown; + // transfer data int transferButtonIndex; } LinphoneCallAppData; diff --git a/Classes/LinphoneUI/LinphoneManager.m b/Classes/LinphoneUI/LinphoneManager.m index ef5498cca..195058561 100644 --- a/Classes/LinphoneUI/LinphoneManager.m +++ b/Classes/LinphoneUI/LinphoneManager.m @@ -337,9 +337,14 @@ 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 { @@ -417,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 }; diff --git a/submodules/linphone b/submodules/linphone index d481382fb..e7123e495 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit d481382fb4c55300737d1f6fc02cecb4d509cc60 +Subproject commit e7123e495aa88c5432b1a7c21e5f9de39ef5bc90 From 5b9da66d89601b7b1f7fe55e715bc9041c970eb6 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Wed, 4 Apr 2012 10:07:27 +0200 Subject: [PATCH 19/34] Add transfer button to ipad xib --- Classes/InCallViewController-ipad.xib | 69 ++++++++++++++++++++++----- Classes/IncallViewController.xib | 12 ++--- 2 files changed, 64 insertions(+), 17 deletions(-) diff --git a/Classes/InCallViewController-ipad.xib b/Classes/InCallViewController-ipad.xib index 3a00313b4..c9752f961 100644 --- a/Classes/InCallViewController-ipad.xib +++ b/Classes/InCallViewController-ipad.xib @@ -50,7 +50,7 @@ {768, 1024} - + _NS:569 NO IBIPadFramework @@ -72,6 +72,7 @@ {{366, 493}, {37, 37}} + _NS:1062 NO IBIPadFramework @@ -225,7 +226,7 @@ 292 - {{107, 70}, {106, 66}} + {{80, 70}, {80, 66}} @@ -299,7 +300,7 @@ 292 - {{0, 70}, {107, 66}} + {{0, 70}, {80, 66}} @@ -325,7 +326,7 @@ 292 - {{213, 70}, {107, 66}} + {{240, 70}, {80, 66}} @@ -354,7 +355,7 @@ -2147483356 - {{213, 70}, {107, 66}} + {{240, 70}, {80, 66}} @@ -372,17 +373,42 @@ MC4xOTYwNzg0MzE0IDAuMzA5ODAzOTIxNiAwLjUyMTU2ODYyNzUAA - + NSImage clavier-01-160px.png + + + -2147483356 + {{160, 70}, {80, 66}} + + + + + NO + NO + IBIPadFramework + 0 + 0 + 1 + transfer + + + 1 + MC4xOTYwNzg0MzE0IDAuMzA5ODAzOTIxNiAwLjUyMTU2ODYyNzUAA + + + + + + 292 - {{247.5, 84.5}, {37, 37}} + {{262, 84}, {37, 37}} @@ -452,10 +478,10 @@ 292 - {{107, 70}, {106, 66}} + {{80, 70}, {80, 66}} - + NO NO @@ -1098,6 +1124,14 @@ 168 + + + transfer + + + + 170 + dataSource @@ -1210,10 +1244,11 @@ - + + controls @@ -1412,6 +1447,12 @@ + + 169 + + + transfer + @@ -1451,6 +1492,7 @@ 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 @@ -1482,7 +1524,7 @@ - 168 + 170 @@ -1526,6 +1568,7 @@ UIButton UIButton UIButton + UIButton UIButton UIImageView UICamSwitch @@ -1638,6 +1681,10 @@ three UIButton + + transfer + UIButton + two UIButton diff --git a/Classes/IncallViewController.xib b/Classes/IncallViewController.xib index 7d509ae97..81185bcd5 100644 --- a/Classes/IncallViewController.xib +++ b/Classes/IncallViewController.xib @@ -228,7 +228,7 @@ 292 - {{160, 4}, {80, 66}} + {{80, 70}, {80, 66}} @@ -261,7 +261,7 @@ 292 - {{0, 4}, {80, 66}} + {{0, 4}, {107, 66}} @@ -328,7 +328,7 @@ 292 - {{80, 70}, {160, 66}} + {{160, 70}, {80, 66}} @@ -430,7 +430,7 @@ 292 - {{80, 4}, {80, 66}} + {{107, 4}, {106, 66}} @@ -456,7 +456,7 @@ 292 - {{240, 4}, {80, 66}} + {{213, 4}, {107, 66}} @@ -486,7 +486,7 @@ 292 - {{160, 4}, {80, 66}} + {{80, 70}, {80, 66}} From c7193ec514e8ad26b2f70d1bc7afa5cf11a2c1b6 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Wed, 4 Apr 2012 10:56:58 +0200 Subject: [PATCH 20/34] Update call history icons --- Classes/CallHistoryTableViewController.m | 11 ++++++----- Resources/in_call.png | Bin 3267 -> 4087 bytes Resources/in_call_video.png | Bin 0 -> 5233 bytes Resources/missed_call.png | Bin 4166 -> 4178 bytes Resources/out_call.png | Bin 3260 -> 4030 bytes Resources/out_call_video.png | Bin 0 -> 5161 bytes linphone.xcodeproj/project.pbxproj | 8 ++++++++ 7 files changed, 14 insertions(+), 5 deletions(-) create mode 100644 Resources/in_call_video.png create mode 100644 Resources/out_call_video.png diff --git a/Classes/CallHistoryTableViewController.m b/Classes/CallHistoryTableViewController.m index 1a06c1661..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 stringWithFormat:@"%s%s", displayName, callLogs->video_enabled?" (video)":""]; + 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 stringWithFormat:@"%s%s", username, callLogs->video_enabled?" (video)":""]; + NSString* str1 = [NSString stringWithFormat:@"%s", username]; [cell.textLabel setText:str1]; [cell.detailTextLabel setText:nil]; } diff --git a/Resources/in_call.png b/Resources/in_call.png index d48369e6a2eefabff23f95082f4e51f3451d305a..1e20bac2b152d1821be96f547f27e25a280814fe 100644 GIT binary patch literal 4087 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 BFv9=< diff --git a/Resources/in_call_video.png b/Resources/in_call_video.png new file mode 100644 index 0000000000000000000000000000000000000000..87fcb5b64667a8f79a3f1c07795e1a87b56ec29a GIT binary patch literal 5233 zcmV-%6prhOP)Px#24YJ`L;wH)0002_L%V+f000SaNLh0L01sgR01sgSs6VG^00007bV*G`2iyb% z2q+cpSzMX`000?uMObu0Z*6U5Zgc=ca%Ew3Wn>_CX>@2HM@dakSAh-}000xrNkl2?}RuidJl8$0LR_kYb3570G8_lIig20TF$oDZ^Co?;BWOVietAQ2JVZ#Q!@ z_e*dGPuZXv((M&*7@5bqXpiPhX)*6q8n z(M^39m*u`Y5dFRe!We>xd>bIXJs=|x%+l^efVBpIfid*$Ue~tjH!3ITgWxi*LteQ?>7r6 zaU+C?WeGSe3qp*@o-s`xDP?4z!E7O7KJ<6)mHG$W)4A_+xn~~l3}yxkm*167AA~y~ z?_8wg3)YDe5h-69kg)(6Nd5i^K*!nzH%OsTX0=B35eDg-0l?+Yb}g1CtVp)y`cSPf-M+8&KWu9)#K^?4#){07|fyp zIWtmDz2Gy1X`0}j1GB7ws18g7RQ^=}YK&oFmBBcyt2;Mt*=UNeY3slREWm!PZ zys0q)GG|z0o69Fqw-8x7Ei{)`A5Q>e0E7^0y^>*#0S~TF`LBBnSpx#inzZ`P2r*#^ z5ivzL>&odR7-NugUReqtAd=>?xTMC&87VVFfDjW7At1&KXEoM1YhkT{$lXGYv!4<> z)I!ucmL(v>2y1h5LDpCR8V>|=RIf-W9%EvpTpp7dAt=B(XL#@6oJGnOE*m&&?^)LA zDx6E;Wu%l4Vnm1u6mugIttj5B4GgM70oSEu3?3))x1~?P697ONq5mEEG#i5UN`etm4qU4%q@x0;{zK-dkjL zh|#KBNg1hFjX+u5%#38zN@7Y{wU_!L<%}hS_IZqHNS^^`47{_Lyo0k2&N&!k?rHB9 z5Mv0=S%~-+BU09ji3p^u{1uQ}rbJY%g4Gpe&WI_hC4i7h)&>ZyG4R%4o;)7r3A<^+ zJWVa0+yUA0IHop~ls2z%L{B%s5)qTe5@JSf)q5!*i>phiW?%$n{hl!fwt}&nu$w*R zX~H!5Vj*;QS?58~Mw53IyLkq)Xyzn>oCS;w&H^E6fXEOC7y`-MI)=s=SYt4G1z|VO z*v&Jh$-~;)YW3b^Kcu=Z?_CSLM0(nD76=2GxCHScaG-SxZHPbw7&36q!aIlEJmK+i zhsTE<=4u%?*0{Ra29+_U`Sn^5ro_mJAq=1dauH2otAT8#Kh7CUUcq?S&3M@Du-na; zyoWK=GA_^^kT)#^z^Wh4EQs@5>I=PqF(wERNJy_KjTWZG-sC-Y^VIJ1JYn*_)iJk5 z!Mj@oVx%xM7z5rr>~<5Re6RiA7$HKfm>?pUA$^`_kH^Oy9(HqaQ`PEP;iJ_)?m_)y zwFv+if_DxwD=S-ru(HFsxUEuF65yHR;=TfSV(s}mw^GS zV{HWm048=wlSj@w&7!PDObG&kA+0quX3W^_CauVw?HSbt&+Xd)vNd<2_r(L}e!l9b zw~tDDXfEnJqxZf|Yf>3g z>keB!M@fr&AEnkUr!P9)l+&V1md_lE*=S=Cxpn`l^s|1RGZ(V3fWiujg2Bx?)|7~H zT$L=e*0!E_1;-Xik0BZ)KI5HMbPN@PCeTfU6L)RP&;gp>7mqO^rG%JLX{Bc5TqU0h zfPNf0gCp1jxj0&iHEIzGglQI{g&)C|pIK`aIOkxk@?*Au)3jWIo6&Gy9gsS=5mUml zL>!7pVOauVj6-)%3OR^Xpg*0O9cNj!iYFq_#sX}~!kjhmURho5RoF0<7O=Hivq*7y zkiSeQcWQ3qumtQ6OH+@;q}Gy4!%4<#PN!?No~~|qz|oaefDFNqfi(nYG~@Cys~Wxx z_he>xH@LdexH3XVvF1+%es_H^$^cCPLjj41F}C|$IMToJe6%D*~3QoCO+tn<`g)V(B3t<+doK%d~zzEnMf{vS&45|`< z>LP|TnTDcqWgYAKqXu7PXwBMM$`_hmQ%f4uVv|~gs|_oQ$vMoE$K;*LRJ}mN6;R}l zOkQ2pLQ+z-$6@LB5LHVn0+6W;ZU<#7T~>@M_0Hk?qEG|2f+yS)fST;7;6aduORP!y zSS8qdXEA%PLW<>+Un0$9-mC*cM)^arqX{m0A z2qCPrP}?l&Egq@5BwJdznk6YyYnsZWjHt#YnzXv3=ypVN>nS*u{ER7X{c6_k1a zQjWc_9170F3{$@D>9h>44aGgF_BW=iHA+xdmQp$zhtrXTUq9G$B@5}3v8^Jn)^YO5 z%Mc5Wxh7jG@v0P=XAfT#BGfE0BWH`urTWjRnjh2KPRrdR7RcA~_`_L&({- zxG}yqW`Xx;h3KyW#a#o8dY0-4Ky@WD#ETwuilBK|3g** zm4%g$AZdjLy}^Yw;*d}%bc=a%c$hsNcN3hmD^OePs)B6c)tZfzxg{7eLX(7__GK?$Y9pNo>&Um8mll6oWH_KE_Ye9Dc`84tX+6OLuHL47PtCqLbs4ARPfGW znp|@sTiK3mX`7)KjLyOtgHXxHfm}44ku!A;je9*M#Naqsy7YFymaJUYN|%czE(c_| zK9z~>wZoVyZln470cy%yYmf1<%s6Ydb#p5VlYx#eAe5fF_YOWr_~_uv+=&vO8A$*p zZdfyOFFuJt6x%F{u?D78^WNF^9M`Yt>$0M&1a$&h24szavkvS~(oWN7$tx(EN`3rT z8Q4)f_0dx|HmppMlUifoy+cYFQ}PG}j3qc64ht3p06SS4#Vh5?*YZQXS|sx^Z#DD#7wlKbr7 zQ-+UDgR-Esk4v>LK$hI?S?cr8EeTMGtLs9(V$rq?4_#^{SFsRNSXS>GcDuRE0c!7~ z((y7-93qT?A!#hFD|)J_+&?oWaE=Vz_EDOPX&}fTR}B~$H5&T&B0Ae1V#47NR)V3RbdbiJoK^n3e5V(v z1UL)KzNq6Bq?+QUoI8ox;Ng-6GeQWB#5Aq%V*6P2xls8#0nuw_F_j?hy+=$@2R1`& z<7nI}=P_o`svSEGV0h<-0!_|0O+M7$M_d0lW_{HjLX6lSwwaQwy6zP;NB{&aKJ|lB ztdIUs3^@kHfXKrd?(x8wR!uV>PrI7haxH-93-m*)bv$yPvx;?{({r*KTbM1JRrk6Q zU~f5{;qh|rt3E>XN~HR_D9sh^vH7!rjIm@)Tdh@-)^$l;26U96m8?YpRF-uVz~Sxd zbTLc4&8|*nbV7~VuW>PigvCcV7eEH>b>B=+eRM-a239oCuLW{gWn1f@d#(r43&O29 z`YVN4<)_Adji*xH^HxXg_d`suA;8#P%-#ebA6;7f5fS#eO>!T}u09e=>Sl)+OM#eD zX`;zSjJJ(lXlZ!m?R3k8vc!4jKVOG@RtT_a+kWElPd)DEEu)i=G3lC(+V>A3w#i)` zd5{&;a4d+CGPZ3rn@mYpeaJ5XM240UeHxU{voEKMC>fedV^BV2MRbBzIgS~6vQuI# zOT_+gz{~3%hb8n;Y8e=6Ss$cR;&25eH{qXLsHS&saa00XHEQIIlYOqYvAVo+Je)bU zZOfEbfB*a_ZCwLvtIwA=!6EyykU-WN<1t}bgF~$luI+{@ z{>HU}dW{b zrlH)r6is-2l%Z`-wP`{*RV~Ie0RRG}GA^ znxUvqO6X&)UBO#_q7CP0I+_rch?o6>pUq$6heToUjRYNrgo!)K-XGiT6- zK&+mxfwI=BwqA}dCvcc1-`wZLL0yiUp{pZZt%h*M(nfl{Z#<1AH9c2mZZ#Ph0>QMk z9jbEFnfPhC&Jr|-asHw@&tJ5Vg=!`=fE`oD^UEtz%J}*6ie-s<;kM>a?*(i+8hAdY zYsv{XW@sCjK7vqY;6tzoL92JlTHSLIJm{tfhsnFPpr9(~`(n-PI zBAhd0zXYVRqc@c;)*pRAUp8mSpJjJC zKFAqx=o)6S`a8M;T<1q>;rJOIz3)WXSciNJ!I~*m$3UpMFw0VQTTEm z_CAPwxh?Rvh5U|<6Ln2E4V!=HZNl+0hWMFSqx0>)v}H9uWX?^eT$x}^2wYoG;G8)c ztGL`kgjRJ3i}U8g@Ib7fgpPO#PqOq+{D^O6_V5Z zhA{@-ml{PJc=8b8l^z%XjP0XuRdKTJw_K`RJfR(EJegd>Tc1yn2!OK&54*XIp3y?( z-3;>AOyP@%bX>@<7uT*@ybTazS2EHqA$f6@Rhp~kNcDEKr3_Vm9Tc35c+Oe;c-*x( zX3ZY2hXqM!HLEUT?CI6vsyq={z4y+CkI}ZLb4t@?ipFQ#QG74u{xl$OF(9&W0+-)( z1?*Ui8Y)s6>)QK-SZlCfLVIsQ+45(CammBQG4Jere8s)&bsQ~e`}@~Y!aKpJTN3nQ z`q+;NeIA&T3`#?~%$P%0!v6E)L3LTX885E~JUzeQu!Pm(n$9cL!Oww99+JVcL@j;p ziJzL9I_g$lafI5Pt^+GYZD7cNi7{{~UvpYASQ^P7`{{Gx-Z_xbH}|R%Anz;=i*B^8 zJ?l;+_6>1F#|Qk&75#}pqEi{)S2P8mA{WQ^*fK@ZIbuRD*Yr#)Wx3zk4-Yg|#F8`?-dFYTYvZ~2{fEac3bU)jvIdUt`(nEW~a z-mJmm$HNW}yQ#m?SAomc6&co)xk9y`!xE5K0olz{v#2V~`5SJovYIqF`?}fl-^T}d z=dc7F@47~{POW3;+AdvV%qrJw{TCuFzW#N1*y)CdoK-nL&lCLQV617|MR7E?a6t_D zQ-GkYs#wRyZdoqqKb4e^awMbHirh@NRK4zMb6lUP#-nu&H>?p+{Q~ zMDUk{jZF;U^VdR-*dY01Yi{MMIqmilZa;>|`z(=M&S+f>#F>Kg@3W9k=I^)SCcgSS rNNyWV2N8s2!T-ul$ItxDKEMA5+G#H+bB_Ez00000NkvXXu0mjf4@Af) literal 0 HcmV?d00001 diff --git a/Resources/missed_call.png b/Resources/missed_call.png index 315b49708d1d64f1c3bfc0d29964c47ebeb9c372..58d745612a3b71f3d7f7b33b093179f73c9c704f 100644 GIT binary patch literal 4178 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 Q^8f$<07*qoM6N<$f>ZwF_5c6? diff --git a/Resources/out_call.png b/Resources/out_call.png index 7fef2b4ae619f9febba445900f1f7fbd8f3f6461..3077fdb0875bfb7a4768c68b92c566e0c57fbd88 100644 GIT binary patch literal 4030 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 Xq_tsbF7?j500000NkvXXu0mjfdiBS@ literal 0 HcmV?d00001 diff --git a/linphone.xcodeproj/project.pbxproj b/linphone.xcodeproj/project.pbxproj index 6b6213ba4..0d902225b 100755 --- a/linphone.xcodeproj/project.pbxproj +++ b/linphone.xcodeproj/project.pbxproj @@ -253,6 +253,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 */; }; @@ -636,6 +638,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 = ""; }; @@ -1197,6 +1201,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 */, @@ -1397,6 +1403,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; }; From 89c039935b042d0076e3cdb0f6679cb0417425dc Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Wed, 4 Apr 2012 12:01:29 +0200 Subject: [PATCH 21/34] Fixes for ipad transfer and video rotation --- Classes/InCallViewController-ipad.xib | 17 ++++++++--------- Classes/IncallViewController.m | 7 +++++-- Classes/MainScreenWithVideoPreview.m | 4 ++++ linphonerc-ipad | 1 + 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/Classes/InCallViewController-ipad.xib b/Classes/InCallViewController-ipad.xib index c9752f961..b040469f2 100644 --- a/Classes/InCallViewController-ipad.xib +++ b/Classes/InCallViewController-ipad.xib @@ -180,7 +180,6 @@ {{0, 1}, {320, 66}} - 1 MSAwIDAuMDgyMzIwMjU5MDQgMC4xOAA @@ -373,16 +372,16 @@ MC4xOTYwNzg0MzE0IDAuMzA5ODAzOTIxNiAwLjUyMTU2ODYyNzUAA - + NSImage clavier-01-160px.png - + - -2147483356 + 292 {{160, 70}, {80, 66}} @@ -401,7 +400,7 @@ MC4xOTYwNzg0MzE0IDAuMzA5ODAzOTIxNiAwLjUyMTU2ODYyNzUAA - + @@ -481,7 +480,7 @@ {{80, 70}, {80, 66}} - + NO NO @@ -1128,7 +1127,7 @@ transfer - + 170 @@ -1248,7 +1247,7 @@ - + controls @@ -1449,7 +1448,7 @@ 169 - + transfer diff --git a/Classes/IncallViewController.m b/Classes/IncallViewController.m index f5ba66ade..c6e6bcad9 100644 --- a/Classes/IncallViewController.m +++ b/Classes/IncallViewController.m @@ -464,7 +464,7 @@ void addAnimationFadeTransition(UIView* view, float duration) { NSString* title = NSLocalizedString(@"Transfer call to:",nil); visibleActionSheet = [[UIActionSheet alloc] initWithTitle:title delegate:cd - cancelButtonTitle:NSLocalizedString(@"Cancel",nil) + cancelButtonTitle:[LinphoneManager runningOnIpad] ? nil : NSLocalizedString(@"Cancel",nil) destructiveButtonTitle:NSLocalizedString(@"A new call",nil) otherButtonTitles:nil]; @@ -484,7 +484,10 @@ void addAnimationFadeTransition(UIView* view, float duration) { } visibleActionSheet.actionSheetStyle = UIActionSheetStyleDefault; - [visibleActionSheet showInView:self.view]; + if ([LinphoneManager runningOnIpad]) + [visibleActionSheet showFromRect:transfer.bounds inView:transfer animated:NO]; + else + [visibleActionSheet showInView:self.view]; } -(void) addCallPressed { diff --git a/Classes/MainScreenWithVideoPreview.m b/Classes/MainScreenWithVideoPreview.m index a9629a990..220c9bd73 100644 --- a/Classes/MainScreenWithVideoPreview.m +++ b/Classes/MainScreenWithVideoPreview.m @@ -93,6 +93,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 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 From ef0b1edba135de416726f2cf7d874d9517848b61 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Tue, 17 Apr 2012 11:16:07 +0200 Subject: [PATCH 22/34] Add zoom support (using double tap/pinch/pan gestures) Conflicts: submodules/linphone --- Classes/IncallViewController.h | 1 + Classes/IncallViewController.m | 78 ++++++++++++++++++++++++++++++ linphone.xcodeproj/project.pbxproj | 2 +- submodules/externals/exosip | 2 +- submodules/linphone | 2 +- submodules/mssilk | 2 +- 6 files changed, 83 insertions(+), 4 deletions(-) diff --git a/Classes/IncallViewController.h b/Classes/IncallViewController.h index e1bd40cdb..117a9f648 100644 --- a/Classes/IncallViewController.h +++ b/Classes/IncallViewController.h @@ -91,6 +91,7 @@ UIActionSheet* visibleActionSheet; NSTimer* hideControlsTimer; + float zoomLevel, cx, cy; } -(void)displayStatus:(NSString*) message; diff --git a/Classes/IncallViewController.m b/Classes/IncallViewController.m index c6e6bcad9..0d1e28ee4 100644 --- a/Classes/IncallViewController.m +++ b/Classes/IncallViewController.m @@ -243,6 +243,9 @@ void addAnimationFadeTransition(UIView* view, float duration) { -(void) enableVideoDisplay { [self orientationChanged:nil]; + zoomLevel = 1; + cx = cy = 0.5; + [UIView beginAnimations:nil context:nil]; [UIView setAnimationDuration:1.0]; [videoGroup setAlpha:1.0]; @@ -368,6 +371,66 @@ void addAnimationFadeTransition(UIView* view, float duration) { } } +-(void) zoomInOut:(UITapGestureRecognizer*) reco { + if (zoomLevel != 1) + zoomLevel = 1; + else + zoomLevel = 2; + + if (zoomLevel != 1) { + CGPoint point = [reco locationInView:videoGroup]; + cx = point.x / videoGroup.frame.size.width; + cy = 1 - point.y / videoGroup.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:videoGroup]; + if ([reco state] == UIGestureRecognizerStateEnded) { + cx -= translation.x / videoGroup.frame.size.width; + cy += translation.y / videoGroup.frame.size.height; + x = cx; + y = cy; + } else if ([reco state] == UIGestureRecognizerStateChanged) { + x = cx - translation.x / videoGroup.frame.size.width; + y = cy + translation.y / videoGroup.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); +} + // Implement viewDidLoad to do additional setup after loading the view, typically from a nib. - (void)viewDidLoad { [super viewDidLoad]; @@ -413,10 +476,25 @@ void addAnimationFadeTransition(UIView* view, float duration) { } UITapGestureRecognizer* singleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(showControls:)]; + [singleFingerTap setNumberOfTapsRequired:1]; [videoGroup addGestureRecognizer:singleFingerTap]; + + UITapGestureRecognizer* doubleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(zoomInOut:)]; + [doubleFingerTap setNumberOfTapsRequired:2]; + [doubleFingerTap setNumberOfTouchesRequired:1]; + [videoGroup addGestureRecognizer:doubleFingerTap]; + + UIPanGestureRecognizer* pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(videoPan:)]; + [videoGroup addGestureRecognizer:pan]; + UIPinchGestureRecognizer* pinchReco = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinch:)]; + [videoGroup addGestureRecognizer:pinchReco]; videoGroup.alpha = 0; [singleFingerTap release]; + [doubleFingerTap release]; + [pan release]; + [pinchReco release]; + cx = cy = 0.5; mVideoShown=FALSE; mIncallViewIsReady=FALSE; diff --git a/linphone.xcodeproj/project.pbxproj b/linphone.xcodeproj/project.pbxproj index 0d902225b..7b0afb044 100755 --- a/linphone.xcodeproj/project.pbxproj +++ b/linphone.xcodeproj/project.pbxproj @@ -1623,7 +1623,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; diff --git a/submodules/externals/exosip b/submodules/externals/exosip index 014f5a021..8483ca292 160000 --- a/submodules/externals/exosip +++ b/submodules/externals/exosip @@ -1 +1 @@ -Subproject commit 014f5a021ad4a0c024088edbb721f144a6f96699 +Subproject commit 8483ca292c10e4bca3331040dd9babf8431d0393 diff --git a/submodules/linphone b/submodules/linphone index 2111e92a3..02369158f 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit 2111e92a393cd0cbf3934ea1de406904f0d34bca +Subproject commit 02369158f50408f4d805fe0284a37aa8fe953105 diff --git a/submodules/mssilk b/submodules/mssilk index 391b6d6b0..498a7c526 160000 --- a/submodules/mssilk +++ b/submodules/mssilk @@ -1 +1 @@ -Subproject commit 391b6d6b0fdf6854e5a25f287c4d8461730a1d40 +Subproject commit 498a7c526192392e402e72b7e9f2c6c381bdb7fd From 9a06d54ec1bc39a868dc2a8d133ebec706b600f6 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Tue, 17 Apr 2012 11:47:05 +0200 Subject: [PATCH 23/34] set submodules to correct versions --- submodules/externals/exosip | 2 +- submodules/msilbc | 2 +- submodules/mssilk | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/submodules/externals/exosip b/submodules/externals/exosip index 8483ca292..014f5a021 160000 --- a/submodules/externals/exosip +++ b/submodules/externals/exosip @@ -1 +1 @@ -Subproject commit 8483ca292c10e4bca3331040dd9babf8431d0393 +Subproject commit 014f5a021ad4a0c024088edbb721f144a6f96699 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 diff --git a/submodules/mssilk b/submodules/mssilk index 498a7c526..391b6d6b0 160000 --- a/submodules/mssilk +++ b/submodules/mssilk @@ -1 +1 @@ -Subproject commit 498a7c526192392e402e72b7e9f2c6c381bdb7fd +Subproject commit 391b6d6b0fdf6854e5a25f287c4d8461730a1d40 From 65b9ea58982eb6fe4c8179477f7f8bec718632e6 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Tue, 17 Apr 2012 18:06:05 +0200 Subject: [PATCH 24/34] optimize time for setting up audio units --- linphone.xcodeproj/project.pbxproj | 8 ++++---- submodules/linphone | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/linphone.xcodeproj/project.pbxproj b/linphone.xcodeproj/project.pbxproj index 7b0afb044..a4cb37d3d 100755 --- a/linphone.xcodeproj/project.pbxproj +++ b/linphone.xcodeproj/project.pbxproj @@ -1708,7 +1708,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\"", @@ -1760,7 +1760,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\"", @@ -1813,7 +1813,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\"", @@ -1866,7 +1866,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\"", diff --git a/submodules/linphone b/submodules/linphone index 02369158f..b213faf9b 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit 02369158f50408f4d805fe0284a37aa8fe953105 +Subproject commit b213faf9bd8665d2dc3fbb60d57f8d7568e09136 From 30d52391c78edab7e6cdeb54fce999d1245e19bc Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Tue, 17 Apr 2012 16:08:46 +0200 Subject: [PATCH 25/34] Transfer: go directly to dialer if only 1 call --- Classes/IncallViewController.m | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/Classes/IncallViewController.m b/Classes/IncallViewController.m index 0d1e28ee4..7fdd2fa4f 100644 --- a/Classes/IncallViewController.m +++ b/Classes/IncallViewController.m @@ -124,20 +124,19 @@ void addAnimationFadeTransition(UIView* view, float duration) { -(void) orientationChanged: (NSNotification*) notif { int oldLinphoneOrientation = linphone_core_get_device_rotation([LinphoneManager getLc]); UIDeviceOrientation orientation = [UIDevice currentDevice].orientation; + int newRotation = 0; switch (orientation) { - case UIInterfaceOrientationPortrait: - linphone_core_set_device_rotation([LinphoneManager getLc], 0); - break; case UIInterfaceOrientationLandscapeRight: - linphone_core_set_device_rotation([LinphoneManager getLc], 270); + newRotation = 270; break; case UIInterfaceOrientationLandscapeLeft: - linphone_core_set_device_rotation([LinphoneManager getLc], 90); + newRotation = 90; break; default: - break; + newRotation = 0; } - if (oldLinphoneOrientation != linphone_core_get_device_rotation([LinphoneManager getLc])) { + 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]); @@ -561,11 +560,19 @@ void addAnimationFadeTransition(UIView* view, float duration) { calls = calls->next; } - visibleActionSheet.actionSheetStyle = UIActionSheetStyleDefault; - if ([LinphoneManager runningOnIpad]) - [visibleActionSheet showFromRect:transfer.bounds inView:transfer animated:NO]; - else - [visibleActionSheet showInView:self.view]; + if (visibleActionSheet.numberOfButtons == ([LinphoneManager runningOnIpad] ? 1 : 2)) { + [visibleActionSheet release]; + visibleActionSheet = nil; + + [UICallButton enableTransforMode:YES]; + [[LinphoneManager instance] displayDialer]; + } else { + visibleActionSheet.actionSheetStyle = UIActionSheetStyleDefault; + if ([LinphoneManager runningOnIpad]) + [visibleActionSheet showFromRect:transfer.bounds inView:transfer animated:NO]; + else + [visibleActionSheet showInView:self.view]; + } } -(void) addCallPressed { From a37197a32a1e04b2d6f49355dafcf0b1ef129185 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Tue, 17 Apr 2012 16:09:11 +0200 Subject: [PATCH 26/34] Various ipad UI fixes --- Classes/ConferenceCallDetailView.m | 2 ++ Classes/ConsoleViewController.m | 1 + Classes/InCallViewController-ipad.xib | 2 +- Classes/MainScreenWithVideoPreview.m | 7 +++++++ Classes/PhoneViewController-ipad.xib | 1 - Classes/PhoneViewController.m | 4 ++++ 6 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Classes/ConferenceCallDetailView.m b/Classes/ConferenceCallDetailView.m index 6ec3bf877..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) 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 b040469f2..51b1dfa66 100644 --- a/Classes/InCallViewController-ipad.xib +++ b/Classes/InCallViewController-ipad.xib @@ -180,6 +180,7 @@ {{0, 1}, {320, 66}} + 1 MSAwIDAuMDgyMzIwMjU5MDQgMC4xOAA @@ -392,7 +393,6 @@ IBIPadFramework 0 0 - 1 transfer diff --git a/Classes/MainScreenWithVideoPreview.m b/Classes/MainScreenWithVideoPreview.m index 220c9bd73..4252d06bb 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; @@ -115,6 +116,11 @@ 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]; } @@ -135,6 +141,7 @@ } -(void) viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; [phoneMainView.switchCamera addTarget:self action:@selector(switchCameraPressed) forControlEvents:UIControlEventTouchUpInside]; } 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 091e04901..9229aafd1 100644 --- a/Classes/PhoneViewController.m +++ b/Classes/PhoneViewController.m @@ -103,6 +103,7 @@ 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__]; @@ -122,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]]; @@ -197,6 +199,7 @@ -(void)viewWillAppear:(BOOL)animated { [self updateCallAndBackButtons]; + [super viewWillAppear:animated]; } -(void) displayDialerFromUI:(UIViewController*) viewCtrl forUser:(NSString*) username withDisplayName:(NSString*) displayName { @@ -324,6 +327,7 @@ 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__]; From 966c3ad85ee4ffc2c53ce37131cca31d951b6d21 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Wed, 18 Apr 2012 10:09:17 +0200 Subject: [PATCH 27/34] ipad: start background preview in a separate thread --- Classes/MainScreenWithVideoPreview.m | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/Classes/MainScreenWithVideoPreview.m b/Classes/MainScreenWithVideoPreview.m index 4252d06bb..a820849f5 100644 --- a/Classes/MainScreenWithVideoPreview.m +++ b/Classes/MainScreenWithVideoPreview.m @@ -72,12 +72,6 @@ - (void)viewDidLoad { [super viewDidLoad]; - - bool enableVideo = [[NSUserDefaults standardUserDefaults] boolForKey:@"enable_video_preference"]; - - if (enableVideo) { - [self initVideoPreview ]; - } } -(void) switchCameraPressed { @@ -111,13 +105,19 @@ [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))) { + v if (show && call && linphone_call_params_video_enabled(linphone_call_get_current_params(call))) { return; } @@ -126,9 +126,7 @@ } 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]; From fb4e1387e5aaff9b86b4a679bbc8ad6eddd4901c Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Thu, 19 Apr 2012 10:06:01 +0200 Subject: [PATCH 28/34] Fix typo --- Classes/MainScreenWithVideoPreview.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/MainScreenWithVideoPreview.m b/Classes/MainScreenWithVideoPreview.m index a820849f5..fe7f7dddb 100644 --- a/Classes/MainScreenWithVideoPreview.m +++ b/Classes/MainScreenWithVideoPreview.m @@ -117,7 +117,7 @@ if (enableVideo) { LinphoneCall* call = linphone_core_get_current_call([LinphoneManager getLc]); - v if (show && call && linphone_call_params_video_enabled(linphone_call_get_current_params(call))) { + if (show && call && linphone_call_params_video_enabled(linphone_call_get_current_params(call))) { return; } From 57d67ec60acf4fdcc56bfaab4f01377790157131 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Thu, 19 Apr 2012 10:43:41 +0200 Subject: [PATCH 29/34] Update 'transfer call' ActionSheet --- Classes/IncallViewController.m | 49 +++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/Classes/IncallViewController.m b/Classes/IncallViewController.m index 7fdd2fa4f..7a46b5a9c 100644 --- a/Classes/IncallViewController.m +++ b/Classes/IncallViewController.m @@ -538,11 +538,11 @@ void addAnimationFadeTransition(UIView* view, float duration) { cd.eventType = CD_TRANSFER_CALL; cd.delegate = self; cd.call = linphone_core_get_current_call([LinphoneManager getLc]); - NSString* title = NSLocalizedString(@"Transfer call to:",nil); + NSString* title = NSLocalizedString(@"Transfer to ...",nil); visibleActionSheet = [[UIActionSheet alloc] initWithTitle:title delegate:cd - cancelButtonTitle:[LinphoneManager runningOnIpad] ? nil : NSLocalizedString(@"Cancel",nil) - destructiveButtonTitle:NSLocalizedString(@"A new call",nil) + cancelButtonTitle:nil + destructiveButtonTitle:nil // NSLocalizedString(@"Other...",nil) otherButtonTitles:nil]; // add button for each trasnfer-to valid call @@ -560,13 +560,21 @@ void addAnimationFadeTransition(UIView* view, float duration) { calls = calls->next; } - if (visibleActionSheet.numberOfButtons == ([LinphoneManager runningOnIpad] ? 1 : 2)) { + 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]; @@ -1192,23 +1200,26 @@ static void hideSpinner(LinphoneCall* call, void* user_data) { } case CD_TRANSFER_CALL: { LinphoneCall* call = (LinphoneCall*)datas; - if (buttonIndex == actionSheet.destructiveButtonIndex) { - // transfer to a new call: enable transfer mode and hide incallview - [UICallButton enableTransforMode:YES]; - [[LinphoneManager instance] displayDialer]; - } else { - // 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); - } - data->transferButtonIndex = -1; - calls = calls->next; + // 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: From dcbcce43b847eec128529a8753befc3f51d7036f Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Thu, 19 Apr 2012 12:21:35 +0200 Subject: [PATCH 30/34] Update linphone (bug fix for unauthenticated accounts) --- Classes/IncallViewController.m | 42 +++++++++++++++++++--------------- submodules/linphone | 2 +- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/Classes/IncallViewController.m b/Classes/IncallViewController.m index 7a46b5a9c..53fae1c06 100644 --- a/Classes/IncallViewController.m +++ b/Classes/IncallViewController.m @@ -261,11 +261,13 @@ void addAnimationFadeTransition(UIView* view, float duration) { [[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) { - NSLog(@"old center: %f %f", videoView.center.x, videoView.center.y); + 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)); - NSLog(@"new center: %f %f", videoView.center.x, videoView.center.y); + ms_message("new center: %f %f", videoView.center.x, videoView.center.y); done = true; } @@ -300,26 +302,30 @@ void addAnimationFadeTransition(UIView* view, float duration) { [[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"]; } @@ -332,11 +338,11 @@ void addAnimationFadeTransition(UIView* view, float duration) { if (fullUpdate) { videoUpdateIndicator.hidden = YES; - LinphoneCallState state = linphone_call_get_state(selectedCall); + 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(selectedCall))) { + 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(selectedCall)]; + [IncallViewController updateIndicator: videoCallQuality withCallQuality:linphone_call_get_average_quality(currentCall)]; } else { [addVideo setTitle:NSLocalizedString(@"+video", nil) forState:UIControlStateNormal]; } @@ -361,7 +367,7 @@ void addAnimationFadeTransition(UIView* view, float duration) { } [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]; @@ -409,7 +415,7 @@ void addAnimationFadeTransition(UIView* view, float duration) { -(void) pinch:(UIPinchGestureRecognizer*) reco { float s = zoomLevel; - CGPoint point = [reco locationInView:videoGroup]; + // 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) { diff --git a/submodules/linphone b/submodules/linphone index b213faf9b..1e25bf2a3 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit b213faf9bd8665d2dc3fbb60d57f8d7568e09136 +Subproject commit 1e25bf2a30cd6b9c78593cc19a14f38de8873aa7 From c2748f0c1120cf5fccffd9f40e151592835523ac Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 20 Apr 2012 22:49:57 +0200 Subject: [PATCH 31/34] update linphone submodules for bugfixes: no more audio after gsm call interrupting the sip call shutdown dtmf stream before creating audio preload graph --- submodules/linphone | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/linphone b/submodules/linphone index 1e25bf2a3..93bed082d 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit 1e25bf2a30cd6b9c78593cc19a14f38de8873aa7 +Subproject commit 93bed082d2c61a88bf793aa748e365744ce8df5b From dd33f588c52295ee5b1a3fdef1688eefa78e4335 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Thu, 19 Apr 2012 14:56:31 +0200 Subject: [PATCH 32/34] Differentiate status message: 'no sip account' and 'network down' (on 1st start) --- Classes/MainScreenWithVideoPreview.m | 3 +-- Classes/PhoneViewController.m | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Classes/MainScreenWithVideoPreview.m b/Classes/MainScreenWithVideoPreview.m index fe7f7dddb..f4c6859e9 100644 --- a/Classes/MainScreenWithVideoPreview.m +++ b/Classes/MainScreenWithVideoPreview.m @@ -72,6 +72,7 @@ - (void)viewDidLoad { [super viewDidLoad]; + [phoneMainView.switchCamera addTarget:self action:@selector(switchCameraPressed) forControlEvents:UIControlEventTouchUpInside]; } -(void) switchCameraPressed { @@ -140,8 +141,6 @@ -(void) viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; - [phoneMainView.switchCamera addTarget:self action:@selector(switchCameraPressed) forControlEvents:UIControlEventTouchUpInside]; - } -(void) viewDidDisappear:(BOOL)animated { diff --git a/Classes/PhoneViewController.m b/Classes/PhoneViewController.m index 9229aafd1..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); From 3bf2f14af1b6837e8201df39882ca68c40603e6e Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Tue, 24 Apr 2012 11:46:31 +0200 Subject: [PATCH 33/34] Update linphone --- Classes/IncallViewController.m | 2 +- submodules/linphone | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Classes/IncallViewController.m b/Classes/IncallViewController.m index 53fae1c06..130b9dd5b 100644 --- a/Classes/IncallViewController.m +++ b/Classes/IncallViewController.m @@ -141,7 +141,7 @@ void addAnimationFadeTransition(UIView* view, float duration) { LinphoneCall* call = linphone_core_get_current_call([LinphoneManager getLc]); if (call && linphone_call_params_video_enabled(linphone_call_get_current_params(call))) { - //Orientation has change, must call update call + //Orientation has changed, must call update call linphone_core_update_call([LinphoneManager getLc], call, NULL); diff --git a/submodules/linphone b/submodules/linphone index 93bed082d..49631ae72 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit 93bed082d2c61a88bf793aa748e365744ce8df5b +Subproject commit 49631ae72f33c9f667780d3b961344f61dee9889 From dfaeaba47f67caa12c584e9855b6bd94ad073070 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Wed, 25 Apr 2012 10:53:12 +0200 Subject: [PATCH 34/34] Split zoom handling to a new file --- Classes/IncallViewController.h | 6 +- Classes/IncallViewController.m | 83 ++------------------- Classes/LinphoneUI/VideoZoomHandler.h | 18 +++++ Classes/LinphoneUI/VideoZoomHandler.m | 101 ++++++++++++++++++++++++++ linphone.xcodeproj/project.pbxproj | 8 ++ submodules/externals/libvpx | 2 +- 6 files changed, 136 insertions(+), 82 deletions(-) create mode 100644 Classes/LinphoneUI/VideoZoomHandler.h create mode 100644 Classes/LinphoneUI/VideoZoomHandler.m diff --git a/Classes/IncallViewController.h b/Classes/IncallViewController.h index 117a9f648..0d7340568 100644 --- a/Classes/IncallViewController.h +++ b/Classes/IncallViewController.h @@ -23,7 +23,7 @@ #import #include "UILinphone.h" #import "UIToggleVideoButton.h" - +#import "VideoZoomHandler.h" @class VideoViewController; @interface IncallViewController : UIViewController { @@ -89,9 +89,9 @@ 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* visibleActionSheet; - + NSTimer* hideControlsTimer; - float zoomLevel, cx, cy; + VideoZoomHandler* videoZoomHandler; } -(void)displayStatus:(NSString*) message; diff --git a/Classes/IncallViewController.m b/Classes/IncallViewController.m index 130b9dd5b..588b289c5 100644 --- a/Classes/IncallViewController.m +++ b/Classes/IncallViewController.m @@ -242,8 +242,7 @@ void addAnimationFadeTransition(UIView* view, float duration) { -(void) enableVideoDisplay { [self orientationChanged:nil]; - zoomLevel = 1; - cx = cy = 0.5; + [videoZoomHandler resetZoom]; [UIView beginAnimations:nil context:nil]; [UIView setAnimationDuration:1.0]; @@ -376,66 +375,6 @@ void addAnimationFadeTransition(UIView* view, float duration) { } } --(void) zoomInOut:(UITapGestureRecognizer*) reco { - if (zoomLevel != 1) - zoomLevel = 1; - else - zoomLevel = 2; - - if (zoomLevel != 1) { - CGPoint point = [reco locationInView:videoGroup]; - cx = point.x / videoGroup.frame.size.width; - cy = 1 - point.y / videoGroup.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:videoGroup]; - if ([reco state] == UIGestureRecognizerStateEnded) { - cx -= translation.x / videoGroup.frame.size.width; - cy += translation.y / videoGroup.frame.size.height; - x = cx; - y = cy; - } else if ([reco state] == UIGestureRecognizerStateChanged) { - x = cx - translation.x / videoGroup.frame.size.width; - y = cy + translation.y / videoGroup.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); -} - // Implement viewDidLoad to do additional setup after loading the view, typically from a nib. - (void)viewDidLoad { [super viewDidLoad]; @@ -483,23 +422,11 @@ void addAnimationFadeTransition(UIView* view, float duration) { UITapGestureRecognizer* singleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(showControls:)]; [singleFingerTap setNumberOfTapsRequired:1]; [videoGroup addGestureRecognizer:singleFingerTap]; - - UITapGestureRecognizer* doubleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(zoomInOut:)]; - [doubleFingerTap setNumberOfTapsRequired:2]; - [doubleFingerTap setNumberOfTouchesRequired:1]; - [videoGroup addGestureRecognizer:doubleFingerTap]; - - UIPanGestureRecognizer* pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(videoPan:)]; - [videoGroup addGestureRecognizer:pan]; - UIPinchGestureRecognizer* pinchReco = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinch:)]; - [videoGroup addGestureRecognizer:pinchReco]; - videoGroup.alpha = 0; - [singleFingerTap release]; - [doubleFingerTap release]; - [pan release]; - [pinchReco release]; - cx = cy = 0.5; + + videoZoomHandler = [[VideoZoomHandler alloc] init]; + [videoZoomHandler setup:videoGroup]; + videoGroup.alpha = 0; mVideoShown=FALSE; mIncallViewIsReady=FALSE; 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/linphone.xcodeproj/project.pbxproj b/linphone.xcodeproj/project.pbxproj index a4cb37d3d..76d09111c 100755 --- a/linphone.xcodeproj/project.pbxproj +++ b/linphone.xcodeproj/project.pbxproj @@ -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 */; }; @@ -628,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 = ""; }; @@ -801,6 +805,8 @@ 3418844514C6CAD300EA48C7 /* StatusSubViewController.h */, 3418844614C6CAD300EA48C7 /* StatusSubViewController.m */, 3418844714C6CAD300EA48C7 /* StatusSubViewController.xib */, + 34216F3E1547EBCD00EA9777 /* VideoZoomHandler.h */, + 34216F3F1547EBCD00EA9777 /* VideoZoomHandler.m */, ); path = Classes; sourceTree = ""; @@ -1511,6 +1517,7 @@ 34CA8539148F692A00503C01 /* MainScreenWithVideoPreview.m in Sources */, 3418844814C6CAD300EA48C7 /* StatusSubViewController.m in Sources */, 340751E7150F38FD00B89C47 /* UIToggleVideoButton.m in Sources */, + 34216F401547EBCD00EA9777 /* VideoZoomHandler.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1546,6 +1553,7 @@ 34CA853A148F692A00503C01 /* MainScreenWithVideoPreview.m in Sources */, 3418844914C6CAD300EA48C7 /* StatusSubViewController.m in Sources */, 340751E8150F38FD00B89C47 /* UIToggleVideoButton.m in Sources */, + 34216F411547EBCD00EA9777 /* VideoZoomHandler.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 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