Merge branch 'dev_inapp_purchase'

Conflicts:
	.tx/config
	Classes/Base.lproj/WizardViews.xib
	Classes/Utils/Utils.h
	Classes/Utils/Utils.m
	Classes/WizardViewController.h
	Classes/WizardViewController.m
	Resources/linphonerc-factory
	Resources/linphonerc-factory~ipad
This commit is contained in:
Gautier Pelloux-Prayer 2015-04-30 17:01:51 +02:00
commit 3b8ddd28a1
51 changed files with 1945 additions and 885 deletions

View file

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="4514" systemVersion="13B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6751" systemVersion="14B25" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3747"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6736"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="ChatRoomViewController">
@ -248,14 +249,11 @@
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<gestureRecognizers/>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
</view>
<tableViewController autoresizesArchivedViewToFullSize="NO" id="29" userLabel="tableController" customClass="ChatRoomTableViewController">
<extendedEdge key="edgesForExtendedLayout"/>
<simulatedStatusBarMetrics key="simulatedStatusBarMetrics"/>
<nil key="simulatedTopBarMetrics"/>
<nil key="simulatedBottomBarMetrics"/>
<simulatedOrientationMetrics key="simulatedOrientationMetrics"/>
<nil key="simulatedDestinationMetrics"/>
<connections>
<outlet property="view" destination="8" id="33"/>
</connections>
@ -281,4 +279,9 @@
<image name="chat_send_over.png" width="117" height="115"/>
<image name="toolsbar_background.png" width="5" height="88"/>
</resources>
</document>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<simulatedStatusBarMetrics key="statusBar"/>
<simulatedOrientationMetrics key="orientation"/>
<simulatedScreenMetrics key="destination" type="retina4"/>
</simulatedMetricsContainer>
</document>

View file

@ -22,6 +22,8 @@
<outlet property="provisionedDomain" destination="wRB-Sh-K8J" id="Ieb-x8-yL4"/>
<outlet property="provisionedPassword" destination="ClH-fT-a8N" id="h61-p1-4qG"/>
<outlet property="provisionedUsername" destination="MyR-eX-QTa" id="gmr-FI-hpH"/>
<outlet property="purchaseButton" destination="uIp-br-8Kv" id="Ov2-V4-LLx"/>
<outlet property="registerButton" destination="77" id="A9h-Es-kxv"/>
<outlet property="remoteProvisioningButton" destination="Kbn-dL-C5h" id="PPk-DJ-nEb"/>
<outlet property="transportChooser" destination="Nrv-SM-lMf" id="7iR-aG-eQf"/>
<outlet property="validateAccountView" destination="101" id="112"/>
@ -151,7 +153,7 @@
<color key="titleColor" red="0.72549019609999998" green="0.76862745099999996" blue="0.79607843140000001" alpha="1" colorSpace="deviceRGB"/>
</state>
<connections>
<action selector="onRemoteProvisioningClick:" destination="-1" eventType="touchUpInside" id="7oT-2f-Rrb"/>
<action selector="onRemoteProvisioningClick:" destination="-1" eventType="touchUpInside" id="Ruh-fu-0Vu"/>
</connections>
</button>
</subviews>
@ -242,6 +244,22 @@
<action selector="onRegisterClick:" destination="-1" eventType="touchUpInside" id="113"/>
</connections>
</button>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" id="uIp-br-8Kv" userLabel="purchaseButton" customClass="UILinphoneButton">
<rect key="frame" x="33" y="481" width="255" height="73"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Purchase"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="20"/>
<state key="normal" title="Purchase" backgroundImage="button_background_default.png">
<color key="titleColor" red="0.35686274509999999" green="0.39607843139999999" blue="0.43529411759999997" alpha="1" colorSpace="deviceRGB"/>
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<state key="highlighted" backgroundImage="button_background_over.png">
<color key="titleColor" red="0.72549019609999998" green="0.76862745099999996" blue="0.79607843140000001" alpha="1" colorSpace="deviceRGB"/>
</state>
<connections>
<action selector="onPurchaseAccountClick:" destination="-1" eventType="touchUpInside" id="BR1-hP-14E"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<point key="canvasLocation" x="927" y="295"/>

View file

@ -86,7 +86,7 @@
- (void)updateChatEntry:(LinphoneChatMessage*)chat {
NSInteger index = ms_list_index(self->messageList, chat);
if (index<0) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"chat entry doesn't exist"];
LOGW(@"chat entry doesn't exist");
return;
}
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:index inSection:0]] withRowAnimation:FALSE]; //just reload

View file

@ -262,7 +262,7 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)update {
if(chatRoom == NULL) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update chat room header: null contact"];
LOGW(@"Cannot update chat room header: null contact");
return;
}
@ -311,14 +311,13 @@ static UICompositeViewDescription *compositeDescription = nil;
static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState state,void* ud) {
ChatRoomViewController* thiz = (ChatRoomViewController*)ud;
const char*text = linphone_chat_message_get_text(msg);
[LinphoneLogger log:LinphoneLoggerLog
format:@"Delivery status for [%s] is [%s]",text,linphone_chat_message_state_to_string(state)];
LOGI(@"Delivery status for [%s] is [%s]",text,linphone_chat_message_state_to_string(state));
[thiz.tableController updateChatEntry:msg];
}
- (BOOL)sendMessage:(NSString *)message withExterlBodyUrl:(NSURL*)externalUrl withInternalURL:(NSURL*)internalUrl {
if(chatRoom == NULL) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot send message: No chatroom"];
LOGW(@"Cannot send message: No chatroom");
return FALSE;
}
@ -350,7 +349,7 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta
dispatch_async(dispatch_get_main_queue(), ^{
[waitView setHidden:TRUE];
if (error) {
[LinphoneLogger log:LinphoneLoggerError format:@"Cannot save image data downloaded [%@]", [error localizedDescription]];
LOGE(@"Cannot save image data downloaded [%@]", [error localizedDescription]);
UIAlertView* errorAlert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Transfer error", nil)
message:NSLocalizedString(@"Cannot write image to photo library", nil)
@ -361,7 +360,7 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta
[errorAlert release];
return;
}
[LinphoneLogger log:LinphoneLoggerLog format:@"Image saved to [%@]", [assetURL absoluteString]];
LOGI(@"Image saved to [%@]", [assetURL absoluteString]);
[self chatRoomStartImageUpload:image url:assetURL];
});
}];
@ -653,7 +652,7 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta
[transferView setHidden:TRUE];
NSString *url = [aimageSharing.connection.currentRequest.URL absoluteString];
if (aimageSharing.upload) {
[LinphoneLogger log:LinphoneLoggerError format:@"Cannot upload file to server [%@] because [%@]", url, [error localizedDescription]];
LOGE(@"Cannot upload file to server [%@] because [%@]", url, [error localizedDescription]);
UIAlertView* errorAlert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Transfer error", nil)
message:NSLocalizedString(@"Cannot transfer file to remote contact", nil)
delegate:nil
@ -662,7 +661,7 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta
[errorAlert show];
[errorAlert release];
} else {
[LinphoneLogger log:LinphoneLoggerError format:@"Cannot download file from [%@] because [%@]", url, [error localizedDescription]];
LOGE(@"Cannot download file from [%@] because [%@]", url, [error localizedDescription]);
UIAlertView* errorAlert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Transfer error", nil)
message:NSLocalizedString(@"Cannot transfer file from remote contact", nil)
delegate:nil
@ -691,7 +690,7 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta
orientation:(ALAssetOrientation)[image imageOrientation]
completionBlock:^(NSURL *assetURL, NSError *error){
if (error) {
[LinphoneLogger log:LinphoneLoggerError format:@"Cannot save image data downloaded [%@]", [error localizedDescription]];
LOGE(@"Cannot save image data downloaded [%@]", [error localizedDescription]);
UIAlertView* errorAlert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Transfer error", nil)
message:NSLocalizedString(@"Cannot write image to photo library", nil)
@ -702,7 +701,7 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta
[errorAlert release];
return;
}
[LinphoneLogger log:LinphoneLoggerLog format:@"Image saved to [%@]", [assetURL absoluteString]];
LOGI(@"Image saved to [%@]", [assetURL absoluteString]);
[LinphoneManager setValueInMessageAppData:[assetURL absoluteString] forKey:@"localimage" inMessage:chat];
[tableController updateChatEntry:chat];
}];

View file

@ -4,18 +4,18 @@
*
* 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
* 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 "ContactDetailsTableViewController.h"
#import "PhoneMainView.h"
@ -74,7 +74,7 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
labelArray = [[NSMutableArray alloc] initWithObjects:
[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"],
[NSString stringWithString:(NSString*)kABPersonPhoneMobileLabel],
[NSString stringWithString:(NSString*)kABPersonPhoneMobileLabel],
[NSString stringWithString:(NSString*)kABPersonPhoneIPhoneLabel],
[NSString stringWithString:(NSString*)kABPersonPhoneMainLabel], nil];
editingIndexPath = nil;
@ -94,7 +94,7 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
[self initContactDetailsTableViewController];
}
return self;
}
}
- (void)dealloc {
if(contact != nil && ABRecordGetRecordID(contact) == kABRecordInvalidID) {
@ -105,7 +105,7 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
}
[labelArray release];
[dataCache release];
[super dealloc];
}
@ -116,7 +116,7 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
[super viewDidLoad];
[headerController view]; // Force view load
[footerController view]; // Force view load
self.tableView.accessibilityIdentifier = @"Contact numbers table";
}
@ -176,12 +176,12 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
- (void)loadData {
[dataCache removeAllObjects];
if(contact == NULL)
if(contact == NULL)
return;
[LinphoneLogger logc:LinphoneLoggerLog format:"Load data from contact %p", contact];
// Phone numbers
LOGI(@"Load data from contact %p", contact);
// Phone numbers
{
ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonPhoneProperty);
NSMutableArray *subArray = [NSMutableArray array];
@ -196,7 +196,7 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
}
[dataCache addObject:subArray];
}
// SIP (IM)
{
ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonInstantMessageProperty);
@ -237,7 +237,7 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
}
[dataCache addObject:subArray];
}
// Email
if ([[LinphoneManager instance] lpConfigBoolForKey:@"show_contacts_emails_preference"] == true)
{
@ -274,7 +274,7 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
}
ABMultiValueIdentifier index;
NSError* error = NULL;
CFStringRef keys[] = { kABPersonInstantMessageUsernameKey, kABPersonInstantMessageServiceKey};
CFTypeRef values[] = { [value copy], [LinphoneManager instance].contactSipField };
CFDictionaryRef lDict = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values, 2, NULL, NULL);
@ -287,7 +287,7 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
}
if (!ABRecordSetValue(contact, kABPersonInstantMessageProperty, lMap, (CFErrorRef*)&error)) {
[LinphoneLogger log:LinphoneLoggerLog format:@"Can't set contact with value [%@] cause [%@]", value,[error localizedDescription]];
LOGI(@"Can't set contact with value [%@] cause [%@]", value,[error localizedDescription]);
CFRelease(lMap);
} else {
if (entry == nil) {
@ -314,7 +314,7 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
CFDictionaryRef lDict2 = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values, 2, NULL, NULL);
ABMultiValueReplaceValueAtIndex(lMap, lDict2, index);
if (!ABRecordSetValue(contact, kABPersonInstantMessageProperty, lMap, (CFErrorRef*)&error)) {
[LinphoneLogger log:LinphoneLoggerLog format:@"Can't set contact with value [%@] cause [%@]", value,[error localizedDescription]];
LOGI(@"Can't set contact with value [%@] cause [%@]", value,[error localizedDescription]);
}
CFRelease(lDict2);
linphone_address_destroy(address);
@ -324,7 +324,7 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
CFRelease(lMap);
}
CFRelease(lDict);
return entry;
}
@ -354,14 +354,14 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
if(!ABMultiValueAddValueAndLabel(lMap, [[value copy] autorelease], label, &identifier)) {
added = false;
}
if(added && ABRecordSetValue(contact, kABPersonPhoneProperty, lMap, (CFErrorRef*)&error)) {
Entry *entry = [[Entry alloc] initWithData:identifier];
[sectionArray addObject:entry];
[entry release];
} else {
added = false;
[LinphoneLogger log:LinphoneLoggerLog format:@"Can't add entry: %@", [error localizedDescription]];
LOGI(@"Can't add entry: %@", [error localizedDescription]);
}
CFRelease(lMap);
} else if(contactSections[section] == ContactSections_Sip) {
@ -371,7 +371,7 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
added=true;
} else {
added=false;
[LinphoneLogger log:LinphoneLoggerError format:@"Can't add entry for value: %@", value];
LOGE(@"Can't add entry for value: %@", value);
}
} else if(contactSections[section] == ContactSections_Email) {
ABMultiValueIdentifier identifier;
@ -387,18 +387,18 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
if(!ABMultiValueAddValueAndLabel(lMap, [[value copy] autorelease], label, &identifier)) {
added = false;
}
if(added && ABRecordSetValue(contact, kABPersonEmailProperty, lMap, (CFErrorRef*)&error)) {
Entry *entry = [[Entry alloc] initWithData:identifier];
[sectionArray addObject:entry];
[entry release];
} else {
added = false;
[LinphoneLogger log:LinphoneLoggerLog format:@"Can't add entry: %@", [error localizedDescription]];
LOGI(@"Can't add entry: %@", [error localizedDescription]);
}
CFRelease(lMap);
}
if (added && animated) {
// Update accessory
if (count > 0) {
@ -456,7 +456,7 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
}
[sectionArray removeObjectAtIndex:[indexPath row]];
NSArray *tagInsertIndexPath = [NSArray arrayWithObject:indexPath];
if (animated) {
[tableview deleteRowsAtIndexPaths:tagInsertIndexPath withRowAnimation:UITableViewRowAnimationFade];
@ -507,26 +507,26 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *kCellId = @"ContactDetailsCell";
UIEditableTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId];
if (cell == nil) {
if (cell == nil) {
cell = [[[UIEditableTableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:kCellId] autorelease];
[cell.detailTextField setDelegate:self];
[cell.detailTextField setAutocapitalizationType:UITextAutocapitalizationTypeNone];
[cell.detailTextField setAutocorrectionType:UITextAutocorrectionTypeNo];
[cell setBackgroundColor:[UIColor whiteColor]];
// Background View
UACellBackgroundView *selectedBackgroundView = [[[UACellBackgroundView alloc] initWithFrame:CGRectZero] autorelease];
cell.selectedBackgroundView = selectedBackgroundView;
[selectedBackgroundView setBackgroundColor:LINPHONE_TABLE_CELL_BACKGROUND_COLOR];
}
NSMutableArray *sectionDict = [self getSectionData:[indexPath section]];
Entry *entry = [sectionDict objectAtIndex:[indexPath row]];
NSString *value = @"";
// default label is our app name
NSString *label = [ContactDetailsTableViewController localizeLabel:[labelArray objectAtIndex:0]];
if(contactSections[[indexPath section]] == ContactSections_Number) {
ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonPhoneProperty);
NSInteger index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
@ -701,7 +701,7 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
[headerController setEditing:editing animated:animated];
[footerController setEditing:editing animated:animated];
if(animated) {
[self.tableView beginUpdates];
}
@ -732,7 +732,7 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
if(animated) {
[self.tableView endUpdates];
}
[super setEditing:editing animated:animated];
if(contactDetailsDelegate != nil) {
[contactDetailsDelegate onModification:nil];
@ -747,7 +747,7 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
return UITableViewCellEditingStyleDelete;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
if(section == ContactSections_None) {
return [headerController view];
} else {
@ -755,7 +755,7 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
}
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
if(section == (ContactSections_MAX - 1)) {
if(ABRecordGetRecordID(contact) != kABRecordInvalidID) {
return [footerController view];
@ -781,14 +781,14 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
return nil;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
if(section == ContactSections_None) {
return [UIContactDetailsHeader height:[headerController isEditing]];
} else {
// Hide section if nothing in it
if([[self getSectionData:section] count] > 0)
return 22;
else
else
return 0.000001f; // Hack UITableView = 0
}
}
@ -846,12 +846,12 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
[textField resignFirstResponder];
return YES;
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
UIView *view = [textField superview];
UIView *view = [textField superview];
// Find TableViewCell
while(view != nil && ![view isKindOfClass:[UIEditableTableViewCell class]]) view = [view superview];
if(view != nil) {
@ -878,7 +878,7 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
[cell.detailTextLabel setText:value];
} else {
[LinphoneLogger logc:LinphoneLoggerError format:"Not valid UIEditableTableViewCell"];
LOGE(@"Not valid UIEditableTableViewCell");
}
if(contactDetailsDelegate != nil) {
[self performSelector:@selector(updateModification) withObject:nil afterDelay:0];

View file

@ -4,18 +4,18 @@
*
* 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
* 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 "ContactDetailsViewController.h"
#import "PhoneMainView.h"
@ -47,16 +47,16 @@ static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef inf
ABAddressBookUnregisterExternalChangeCallback(addressBook, sync_address_book, self);
CFRelease(addressBook);
[tableController release];
[editButton release];
[backButton release];
[cancelButton release];
[super dealloc];
}
#pragma mark -
#pragma mark -
- (void)resetData {
[self disableEdit:FALSE];
@ -64,8 +64,8 @@ static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef inf
ABAddressBookRevert(addressBook);
return;
}
[LinphoneLogger logc:LinphoneLoggerLog format:"Reset data to contact %p", contact];
LOGI(@"Reset data to contact %p", contact);
ABRecordID recordID = ABRecordGetRecordID(contact);
ABAddressBookRevert(addressBook);
contact = ABAddressBookGetPersonWithRecordID(addressBook, recordID);
@ -88,27 +88,27 @@ static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef inf
[[PhoneMainView instance] popCurrentView];
return;
}
// Remove contact from book
if(ABRecordGetRecordID(contact) != kABRecordInvalidID) {
NSError* error = NULL;
ABAddressBookRemoveRecord(addressBook, contact, (CFErrorRef*)&error);
if (error != NULL) {
[LinphoneLogger log:LinphoneLoggerError format:@"Remove contact %p: Fail(%@)", contact, [error localizedDescription]];
LOGE(@"Remove contact %p: Fail(%@)", contact, [error localizedDescription]);
} else {
[LinphoneLogger logc:LinphoneLoggerLog format:"Remove contact %p: Success!", contact];
LOGI(@"Remove contact %p: Success!", contact);
}
contact = NULL;
// Save address book
error = NULL;
inhibUpdate = TRUE;
ABAddressBookSave(addressBook, (CFErrorRef*)&error);
inhibUpdate = FALSE;
if (error != NULL) {
[LinphoneLogger log:LinphoneLoggerError format:@"Save AddressBook: Fail(%@)", [error localizedDescription]];
LOGE(@"Save AddressBook: Fail(%@)", [error localizedDescription]);
} else {
[LinphoneLogger logc:LinphoneLoggerLog format:"Save AddressBook: Success!"];
LOGI(@"Save AddressBook: Success!");
}
[[LinphoneManager instance].fastAddressBook reload];
}
@ -119,27 +119,27 @@ static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef inf
[[PhoneMainView instance] popCurrentView];
return;
}
// Add contact to book
NSError* error = NULL;
if(ABRecordGetRecordID(contact) == kABRecordInvalidID) {
ABAddressBookAddRecord(addressBook, contact, (CFErrorRef*)&error);
if (error != NULL) {
[LinphoneLogger log:LinphoneLoggerError format:@"Add contact %p: Fail(%@)", contact, [error localizedDescription]];
LOGE(@"Add contact %p: Fail(%@)", contact, [error localizedDescription]);
} else {
[LinphoneLogger logc:LinphoneLoggerLog format:"Add contact %p: Success!", contact];
LOGI(@"Add contact %p: Success!", contact);
}
}
// Save address book
error = NULL;
inhibUpdate = TRUE;
ABAddressBookSave(addressBook, (CFErrorRef*)&error);
inhibUpdate = FALSE;
if (error != NULL) {
[LinphoneLogger log:LinphoneLoggerError format:@"Save AddressBook: Fail(%@)", [error localizedDescription]];
LOGE(@"Save AddressBook: Fail(%@)", [error localizedDescription]);
} else {
[LinphoneLogger logc:LinphoneLoggerLog format:"Save AddressBook: Success!"];
LOGI(@"Save AddressBook: Success!");
}
[[LinphoneManager instance].fastAddressBook reload];
}
@ -202,15 +202,15 @@ static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef inf
- (void)viewDidLoad{
[super viewDidLoad];
// Set selected+over background: IB lack !
[editButton setBackgroundImage:[UIImage imageNamed:@"contact_ok_over.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
// Set selected+disabled background: IB lack !
[editButton setBackgroundImage:[UIImage imageNamed:@"contact_ok_disabled.png"]
forState:(UIControlStateDisabled | UIControlStateSelected)];
[LinphoneUtils buttonFixStates:editButton];
[tableController.tableView setBackgroundColor:[UIColor clearColor]]; // Can't do it in Xib: issue with ios4
@ -233,12 +233,12 @@ static UICompositeViewDescription *compositeDescription = nil;
+ (UICompositeViewDescription *)compositeViewDescription {
if(compositeDescription == nil) {
compositeDescription = [[UICompositeViewDescription alloc] init:@"ContactDetails"
content:@"ContactDetailsViewController"
stateBar:nil
stateBarEnabled:false
tabBar:@"UIMainBar"
tabBarEnabled:true
compositeDescription = [[UICompositeViewDescription alloc] init:@"ContactDetails"
content:@"ContactDetailsViewController"
stateBar:nil
stateBarEnabled:false
tabBar:@"UIMainBar"
tabBarEnabled:true
fullscreen:false
landscapeMode:[LinphoneManager runningOnIpad]
portraitMode:true];

View file

@ -127,7 +127,7 @@ static int ms_strcmpfuz(const char * fuzzy_word, const char * sentence) {
}
- (void)loadData {
[LinphoneLogger logc:LinphoneLoggerLog format:"Load contact list"];
LOGI(@"Load contact list");
@synchronized (addressBookMap) {
// Reset Address book

View file

@ -292,6 +292,7 @@ static UICompositeViewDescription *compositeDescription = nil;
LOGE(@"Cannot sent logs: file is NULL");
return;
}
NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"];
NSString *filename = [appName stringByAppendingString:@".gz"];
NSString *mimeType = @"text/plain";

View file

@ -73,7 +73,7 @@
- (void)cancel {
[connection cancel];
[LinphoneLogger log:LinphoneLoggerLog format:@"File transfer interrupted by user"];
LOGI(@"File transfer interrupted by user");
if(delegate) {
[delegate imageSharingAborted:self];
}
@ -81,36 +81,36 @@
- (void)downloadImageFrom:(NSURL*)url {
[LinphoneLogger log:LinphoneLoggerLog format:@"downloading [%@]", [url absoluteString]];
LOGI(@"downloading [%@]", [url absoluteString]);
NSURLRequest* request = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
connection = [[NSURLConnection alloc] initWithRequest:request delegate: self];
}
- (void)uploadImageTo:(NSURL*)url image:(UIImage*)image {
[LinphoneLogger log:LinphoneLoggerLog format:@"downloading [%@]", [url absoluteString]];
LOGI(@"downloading [%@]", [url absoluteString]);
// setting up the request object now
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:url];
[request setHTTPMethod:@"POST"];
/*
add some header info now
we always need a boundary when we post a file
also we need to set the content type
You might want to generate a random boundary.. this is just the same
as my output from wireshark on a valid html post
*/
NSString *boundary = @"---------------------------14737809831466499882746641449";
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
[request addValue:contentType forHTTPHeaderField: @"Content-Type"];
/*
now lets create the body of the post
*/
@ -122,7 +122,7 @@
[body appendData:[NSData dataWithData:UIImageJPEGRepresentation(image, 1.0)]];
[body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:body];
connection = [[NSURLConnection alloc] initWithRequest:(NSURLRequest *)request delegate:self];
}
@ -152,8 +152,8 @@
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
NSHTTPURLResponse * httpResponse = (NSHTTPURLResponse *) response;
statusCode = httpResponse.statusCode;
[LinphoneLogger log:LinphoneLoggerLog format:@"File transfer status code [%i]", statusCode];
LOGI(@"File transfer status code [%i]", statusCode);
if (statusCode == 200 && !upload) {
totalBytesExpectedToRead = (int)[response expectedContentLength];
}
@ -169,14 +169,14 @@
}
if (upload) {
NSString* imageRemoteUrl = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
[LinphoneLogger log:LinphoneLoggerLog format:@"File can be downloaded from [%@]", imageRemoteUrl];
LOGI(@"File can be downloaded from [%@]", imageRemoteUrl);
if(delegate) {
[delegate imageSharingUploadDone:self url:[NSURL URLWithString:imageRemoteUrl]];
}
[imageRemoteUrl release];
} else {
UIImage* image = [UIImage imageWithData:data];
[LinphoneLogger log:LinphoneLoggerLog format:@"File downloaded"];
LOGI(@"File downloaded");
if(delegate) {
[delegate imageSharingDownloadDone:self image:image];
}

View file

@ -0,0 +1,27 @@
//
// InAppProductsCell.h
// linphone
//
// Created by Gautier Pelloux-Prayer on 15/04/15.
//
//
#import <UIKit/UIKit.h>
#import <StoreKit/StoreKit.h>
@interface InAppProductsCell : UITableViewCell {
}
@property (retain, nonatomic) IBOutlet UILabel *ptitle;
@property (retain, nonatomic) IBOutlet UILabel *pdescription;
@property (retain, nonatomic) IBOutlet UILabel *pprice;
@property (retain, nonatomic) IBOutlet UISwitch *ppurchased;
@property (nonatomic) BOOL isMaximized;
@property (retain, nonatomic) NSString *productID;
- (id)initWithIdentifier:(NSString*)identifier maximized:(bool)maximized;
+ (CGFloat)getHeight:(BOOL)maximized;
- (void)fillFromProduct:(SKProduct*)prod;
@end

View file

@ -0,0 +1,67 @@
//
// InAppProductsCell.m
// linphone
//
// Created by Gautier Pelloux-Prayer on 15/04/15.
//
//
#import "InAppProductsCell.h"
#import "LinphoneManager.h"
@implementation InAppProductsCell
- (void)setIsMaximized:(BOOL)isMaximized {
_isMaximized = isMaximized;
//show the BUY button only when not maximized
// _buyButton.hidden = !isMaximized;
self.frame = CGRectMake(self.frame.origin.x,
self.frame.origin.y,
self.frame.size.width,
[InAppProductsCell getHeight:isMaximized]);
}
- (void)fillFromProduct:(SKProduct *)prod {
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setLocale:prod.priceLocale];
[formatter setNumberStyle:NSNumberFormatterCurrencyStyle];
NSString * formattedPrice = [formatter stringFromNumber:prod.price];
[_ptitle setText: [prod localizedTitle]];
[_pdescription setText: [prod localizedDescription]];
[_pprice setText: formattedPrice];
[_ppurchased setOn: [[[LinphoneManager instance] iapManager] isPurchasedWithID:prod.productIdentifier]];
_productID = prod.productIdentifier;
}
- (id)initWithIdentifier:(NSString*)identifier maximized:(bool)maximized {
if ((self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]) != nil) {
NSArray *arrayOfViews = [[NSBundle mainBundle] loadNibNamed:@"InAppProductsCell"
owner:self
options:nil];
if ([arrayOfViews count] >= 1) {
[self.contentView addSubview:[arrayOfViews objectAtIndex:0]];
}
_isMaximized = maximized;
}
return self;
}
- (void)dealloc {
[_ptitle release];
[_pdescription release];
[_pprice release];
[_ppurchased release];
[super dealloc];
}
- (NSString *)description {
return [NSString stringWithFormat:@"%@ (%@): %@ (%@)", _ptitle.text, _pprice.text, _pdescription.text, _isMaximized ? @"maximized":@"minimized"];
}
+ (CGFloat)getHeight:(BOOL)maximized {
return maximized ? 40 : 40;
}
@end

View file

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6751" systemVersion="14B25" targetRuntime="iOS.CocoaTouch" variant="6xAndEarlier" propertyAccessControl="none">
<dependencies>
<deployment identifier="iOS"/>
<development version="5100" identifier="xcode"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6736"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="InAppProductsCell">
<connections>
<outlet property="pdescription" destination="4s8-UV-skT" id="gYv-YR-7Kx"/>
<outlet property="pprice" destination="jzs-nJ-jrK" id="UBe-qg-Gmj"/>
<outlet property="ppurchased" destination="Bcv-Vz-Tq1" id="EB5-Ic-nCq"/>
<outlet property="ptitle" destination="Np2-5N-fTR" id="X3D-TQ-R8R"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="Jvg-Ga-qnD" userLabel="view">
<rect key="frame" x="0.0" y="0.0" width="340" height="40"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="title" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="6" id="Np2-5N-fTR" userLabel="ptitle">
<rect key="frame" x="0.0" y="6" width="55" height="27"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="1" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="description..." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" id="4s8-UV-skT" userLabel="pdescription">
<rect key="frame" x="119" y="6" width="136" height="27"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="2" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="$0" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" id="jzs-nJ-jrK" userLabel="pprice">
<rect key="frame" x="63" y="6" width="48" height="27"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
<switch opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" id="Bcv-Vz-Tq1" userLabel="ppurchased">
<rect key="frame" x="263" y="6" width="79" height="27"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
</switch>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="14" y="539"/>
</view>
</objects>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<simulatedStatusBarMetrics key="statusBar"/>
<simulatedOrientationMetrics key="orientation"/>
<simulatedScreenMetrics key="destination" type="retina4"/>
</simulatedMetricsContainer>
</document>

View file

@ -0,0 +1,73 @@
/* InAppProductsManager.h
*
* Copyright (C) 2012 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 <Foundation/Foundation.h>
#import <StoreKit/StoreKit.h>
#import <XMLRPCConnectionDelegate.h>
@interface InAppProductsXMLRPCDelegate : NSObject <XMLRPCConnectionDelegate>
@end
#define IAPNotReadyYet @"IAPNotReadyYet" // startup status, manager is not ready yet
#define IAPAvailableSucceeded @"IAPAvailableSucceeded" //no data
#define IAPAvailableFailed @"IAPAvailableFailed" //data: error_msg
#define IAPPurchaseTrying @"IAPPurchaseTrying" //data: product_id
#define IAPPurchaseFailed @"IAPPurchaseFailed" //data: product_id, error_msg
#define IAPPurchaseSucceeded @"IAPPurchaseSucceeded" //data: product_id, expires_date
#define IAPRestoreFailed @"IAPRestoreFailed" //data: error_msg
#define IAPRestoreSucceeded @"IAPRestoreSucceeded" //no data
#define IAPReceiptFailed @"IAPReceiptFailed" //data: error_msg
#define IAPReceiptSucceeded @"IAPReceiptSucceeded" //no data
typedef NSString* IAPPurchaseNotificationStatus;
// InAppProductsManager take care of any in app purchase accessible within Linphone
// In order to use it, you must configure your linphonerc configuration correctly, such as:
//[in_app_purchase]
//enabled=1
//paid_account_id=test.autorenew_7days
//receipt_validation_url=https://www.linphone.org/inapp.php
//products_list=test.autorenew_7days
// Note: in Sandbox mode (test), autorenewal expire time is speed up (see http://stackoverflow.com/questions/8815271/what-expiry-date-should-i-see-for-in-app-purchase-in-the-application-sandbox) so that 7 days renewal is only 3 minutes!
@interface InAppProductsManager : NSObject <SKProductsRequestDelegate, SKPaymentTransactionObserver> {
NSString *latestReceiptMD5;
}
// needed because request:didFailWithError method is already used by SKProductsRequestDelegate...
@property (nonatomic, retain) InAppProductsXMLRPCDelegate *xmlrpc;
@property (nonatomic, retain) IAPPurchaseNotificationStatus status;
@property (nonatomic, strong) NSMutableArray *productsAvailable;
@property (nonatomic, strong) NSMutableArray *productsIDPurchased;
- (BOOL)isPurchasedWithID:(NSString*)productId;
- (void)purchaseAccount:(NSString*)sipURI withPassword:(NSString*)password;
- (BOOL)purchaseWitID:(NSString *)productID;
// restore user purchases. Must be at first launch or a user action ONLY.
- (void)restore;
- (void)retrievePurchases;
// internal API only due to methods conflict
- (void)XMLRPCRequest:(XMLRPCRequest *)request didReceiveResponse:(XMLRPCResponse *)response;
// internal API only due to methods conflict
- (void)XMLRPCRequest:(XMLRPCRequest *)request didFailWithError:(NSError *)error;
@end

View file

@ -0,0 +1,401 @@
/* InAppProductsManager.h
*
* Copyright (C) 2012 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 "InAppProductsManager.h"
// In app purchase are not supported by the Simulator
#import <XMLRPCConnection.h>
#import <XMLRPCConnectionManager.h>
#import <XMLRPCResponse.h>
#import <XMLRPCRequest.h>
#import "Utils.h"
#import "LinphoneManager.h"
#import "PhoneMainView.h"
#import "InAppProductsViewController.h"
@implementation InAppProductsXMLRPCDelegate {
InAppProductsManager *iapm;
}
#pragma mark - XMLRPCConnectionDelegate Functions
- (void)request:(XMLRPCRequest *)request didReceiveResponse:(XMLRPCResponse *)response {
[[[LinphoneManager instance] iapManager] XMLRPCRequest:request didReceiveResponse:response];
}
- (void)request:(XMLRPCRequest *)request didFailWithError:(NSError *)error {
[[[LinphoneManager instance] iapManager] XMLRPCRequest:request didFailWithError:error];
}
- (BOOL)request:(XMLRPCRequest *)request canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
return FALSE;
}
- (void)request:(XMLRPCRequest *)request didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
}
- (void)request:(XMLRPCRequest *)request didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
}
@end
@implementation InAppProductsManager {
NSString *accountCreationSipURI;
NSString *accountCreationPassword;
}
#if !TARGET_IPHONE_SIMULATOR
- (instancetype)init {
if ((self = [super init]) != nil) {
LOGE(@"Todo: //waiting for parent approval");
LOGE(@"Todo: if cancel date, no purchase");
_xmlrpc = [[InAppProductsXMLRPCDelegate alloc] init];
_status = IAPNotReadyYet;
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
[self loadProducts];
}
return self;
}
#define INAPP_AVAIL() ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) && ([SKPaymentQueue canMakePayments])
#pragma mark ProductListLoading
- (void)loadProducts {
if (!INAPP_AVAIL()) return;
NSArray * list = [[[[LinphoneManager instance] lpConfigStringForKey:@"products_list" forSection:@"in_app_purchase"] stringByReplacingOccurrencesOfString:@" " withString:@""] componentsSeparatedByString:@","];
_productsIDPurchased = [[NSMutableArray alloc] initWithCapacity:0];
SKProductsRequest *productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithArray:list]];
productsRequest.delegate = self;
[productsRequest start];
}
- (void)productsRequest:(SKProductsRequest *)request
didReceiveResponse:(SKProductsResponse *)response {
_productsAvailable = [[NSMutableArray arrayWithArray: response.products] retain];
LOGI(@"Found %lu products available", (unsigned long)_productsAvailable.count);
if (response.invalidProductIdentifiers.count > 0) {
for (NSString *invalidIdentifier in response.invalidProductIdentifiers) {
LOGW(@"Found product Identifier with invalid ID '%@'", invalidIdentifier);
}
NSDictionary* dict = @{@"error_msg": NSLocalizedString(@"Invalid products identifier", nil)};
[self postNotificationforStatus:IAPAvailableFailed withDict:dict];
} else {
[self postNotificationforStatus:IAPAvailableSucceeded withDict:nil];
}
}
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error {
LOGE(@"Impossible to retrieve list of products: %@", [error localizedFailureReason]);
NSDictionary* dict = @{@"error_msg": error ? [error localizedDescription] : NSLocalizedString(@"Product not available", commit)};
[self postNotificationforStatus:IAPAvailableFailed withDict:dict];
//well, let's retry...
[self loadProducts];
}
#pragma mark Other
- (BOOL)isPurchasedWithID:(NSString *)productID {
for (NSString *prod in _productsIDPurchased) {
if ([prod isEqual: productID]) {
bool isBought = true;
LOGE(@"%@ is %s bought.", prod, isBought?"":"NOT");
return isBought;
}
}
return false;
}
- (SKProduct*) productIDAvailable:(NSString*)productID {
for (SKProduct *product in _productsAvailable) {
if ([product.productIdentifier compare:productID options:NSLiteralSearch] == NSOrderedSame) {
return product;
}
}
return nil;
}
- (BOOL)purchaseWitID:(NSString *)productID {
SKProduct *prod = [self productIDAvailable:productID];
if (prod) {
NSDictionary* dict = @{@"product_id": productID};
[self postNotificationforStatus:IAPPurchaseTrying withDict:dict];
SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:prod];
[[SKPaymentQueue defaultQueue] addPayment:payment];
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
return TRUE;
} else {
NSDictionary* dict = @{@"product_id": productID, @"error_msg": @"Product not available"};
[self postNotificationforStatus:IAPPurchaseFailed withDict:dict];
return FALSE;
}
}
- (void)purchaseAccount:(NSString *)sipURI withPassword:(NSString *)password {
NSString* productID = [[LinphoneManager instance] lpConfigStringForKey:@"paid_account_id" forSection:@"in_app_purchase"];
accountCreationSipURI = [sipURI retain];
accountCreationPassword = [password retain];
if ([self purchaseWitID:productID]) {
accountCreationPassword = nil;
accountCreationSipURI = nil;
}
}
-(void)restore {
LOGI(@"Restoring user purchases...");
//force new query of our server
latestReceiptMD5 = nil;
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
- (void)requestDidFinish:(SKRequest *)request {
if([request isKindOfClass:[SKReceiptRefreshRequest class]]) {
NSURL *receiptUrl = [[NSBundle mainBundle] appStoreReceiptURL];
if ([[NSFileManager defaultManager] fileExistsAtPath:[receiptUrl path]]) {
LOGI(@"App Receipt exists");
[self validateReceipt:nil];
} else {
// This can happen if the user cancels the login screen for the store.
// If we get here it means there is no receipt and an attempt to get it failed because the user cancelled the login.
LOGF(@"Receipt request done but there is no receipt");
}
}
}
- (void)validateReceipt: (SKPaymentTransaction*)transaction {
NSString *receiptBase64 = nil;
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
// Test whether the receipt is present at the above URL
if(![[NSFileManager defaultManager] fileExistsAtPath:[receiptURL path]]) {
// We are probably in sandbox environment, trying to retrieve it...
SKRequest* req = [[SKReceiptRefreshRequest alloc] init];
LOGI(@"Receipt not found yet, trying to retrieve it...");
req.delegate = self;
[req start];
return;
}
LOGI(@"Found appstore receipt");
receiptBase64 = [[NSData dataWithContentsOfURL:receiptURL] base64EncodedStringWithOptions:0];
//only check the receipt if it has changed
if (latestReceiptMD5 == nil || ! [latestReceiptMD5 isEqualToString:[receiptBase64 md5]]) {
// We must validate the receipt on our server
NSURL *URL = [NSURL URLWithString:[[LinphoneManager instance] lpConfigStringForKey:@"receipt_validation_url" forSection:@"in_app_purchase"]];
XMLRPCRequest *request = [[XMLRPCRequest alloc] initWithURL: URL];
// Happen when restoring user purchases at application start or if user click the "restore" button
if (transaction == nil) {
[request setMethod: @"get_expiration_date" withParameters:[NSArray arrayWithObjects:
@"",
receiptBase64,
@"",
@"apple",
nil]];
} else if ([transaction.payment.productIdentifier isEqualToString:[[LinphoneManager instance] lpConfigStringForKey:@"paid_account_id" forSection:@"in_app_purchase"]]) {
//buying for the first time: need to create the account
if ([transaction.transactionIdentifier isEqualToString:transaction.originalTransaction.transactionIdentifier]) {
[request setMethod: @"create_account_from_in_app_purchase" withParameters:[NSArray arrayWithObjects:
@"",
accountCreationSipURI,
accountCreationPassword,
receiptBase64,
@"",
@"apple",
nil]];
accountCreationSipURI = nil;
accountCreationPassword = nil;
//simply renewing
} else {
[request setMethod: @"get_expiration_date" withParameters:[NSArray arrayWithObjects:
@"",
receiptBase64,
@"",
@"apple",
nil]];
}
} else {
LOGE(@"Hum, not handling product with ID %@", transaction.payment.productIdentifier);
return;
}
latestReceiptMD5 = [[receiptBase64 md5] retain];
XMLRPCConnectionManager *manager = [XMLRPCConnectionManager sharedManager];
[manager spawnConnectionWithXMLRPCRequest: request delegate: self.xmlrpc];
LOGI(@"XMLRPC query %@: %@", [request method], [request body]);
[request release];
} else {
LOGW(@"Not checking receipt since it has already been done!");
}
}
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {
for(SKPaymentTransaction * transaction in transactions) {
switch (transaction.transactionState) {
case SKPaymentTransactionStatePurchasing:
break;
case SKPaymentTransactionStatePurchased:
case SKPaymentTransactionStateRestored: {
[self validateReceipt: transaction];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
}
case SKPaymentTransactionStateDeferred:
//waiting for parent approval
break;
case SKPaymentTransactionStateFailed: {
NSString* errlast = [NSString stringWithFormat:@"Purchase of %@ failed: %@.",transaction.payment.productIdentifier,transaction.error.localizedDescription];
LOGE(@"SKPaymentTransactionStateFailed: %@", errlast);
NSDictionary* dict = @{@"product_id": transaction.payment.productIdentifier, @"error_msg": errlast};
[self postNotificationforStatus:IAPPurchaseFailed withDict:dict];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
}
}
}
}
- (void)paymentQueue:(SKPaymentQueue *)queue removedTransactions:(NSArray *)transactions {
for(SKPaymentTransaction * transaction in transactions) {
LOGI(@"%@ was removed from the payment queue.", transaction.payment.productIdentifier);
}
}
- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error {
if (error.code != SKErrorPaymentCancelled) {
NSDictionary* dict = @{@"error_msg": [error localizedDescription]};
[self postNotificationforStatus:IAPRestoreFailed withDict:dict];
}
}
- (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue {
LOGI(@"All restorable transactions have been processed by the payment queue.");
}
-(void)postNotificationforStatus:(IAPPurchaseNotificationStatus)status withDict:(NSDictionary*)dict {
_status = status;
[[NSNotificationCenter defaultCenter] postNotificationName:status object:self userInfo:dict];
LOGI(@"Triggering notification for status %@", status);
}
- (void)retrievePurchases {
[self validateReceipt:nil];
}
- (void)XMLRPCRequest:(XMLRPCRequest *)request didReceiveResponse:(XMLRPCResponse *)response {
LOGI(@"XMLRPC response %@: %@", [request method], [response body]);
NSString* productID = [[LinphoneManager instance] lpConfigStringForKey:@"paid_account_id" forSection:@"in_app_purchase"];
// validation succeeded
if(! [response isFault] && [response object] != nil) {
if([[request method] isEqualToString:@"get_expiration_date"]) {
//first remove it from list
[_productsIDPurchased removeObject:productID];
double expirationTime = [[response object] doubleValue] / 1000;
NSDate * expirationDate = [NSDate dateWithTimeIntervalSince1970:expirationTime];
NSDate *now = [[NSDate alloc] init];
if (([expirationDate earlierDate:now] == expirationDate) || (expirationTime < 1)) {
LOGI(@"Account has expired");
[[PhoneMainView instance] changeCurrentView:[InAppProductsViewController compositeViewDescription]];
expirationDate = [NSDate dateWithTimeIntervalSince1970:0];
} else {
[_productsIDPurchased addObject:productID];
}
NSDictionary* dict = @{@"product_id": productID, @"expires_date": expirationDate};
[self postNotificationforStatus:IAPReceiptSucceeded withDict:dict];
} else if([[request method] isEqualToString:@"create_account_from_in_app_purchase"]) {
[_productsIDPurchased removeObject:productID];
double timeinterval = [[response object] doubleValue] / 1000;
if (timeinterval != -2) {
NSDate *expirationDate = [NSDate dateWithTimeIntervalSince1970:timeinterval];
NSDate *now = [[NSDate alloc] init];
if ([expirationDate earlierDate:now] == expirationDate) {
LOGI(@"Account has expired");
[[PhoneMainView instance] changeCurrentView:[InAppProductsViewController compositeViewDescription]];
expirationDate = [NSDate dateWithTimeIntervalSince1970:0];
} else {
[_productsIDPurchased addObject:productID];
}
NSDictionary* dict = @{@"product_id": productID, @"expires_date": expirationDate};
[self postNotificationforStatus:IAPPurchaseSucceeded withDict:dict];
} else {
NSDictionary* dict = @{@"product_id": productID, @"error_msg": @"Unknown error"};
[self postNotificationforStatus:IAPPurchaseFailed withDict:dict];
}
}
} else {
NSString *errorString = NSLocalizedString(@"Unknown error", nil);
if ([response isFault]) {
errorString = [NSString stringWithFormat:NSLocalizedString(@"Communication issue (%@)", nil), [response faultString]];
} else if([response object] == nil) {
errorString = NSLocalizedString(@"Invalid server response", nil);
}
LOGE(@"Communication issue (%@)", [response faultString]);
UIAlertView* errorView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Communication issue",nil)
message:errorString
delegate:nil
cancelButtonTitle:NSLocalizedString(@"Continue",nil)
otherButtonTitles:nil,nil];
[errorView show];
[errorView release];
latestReceiptMD5 = nil;
NSDictionary* dict = @{@"error_msg": errorString};
[self postNotificationforStatus:IAPReceiptFailed withDict:dict];
}
}
- (void)XMLRPCRequest:(XMLRPCRequest *)request didFailWithError:(NSError *)error {
LOGE(@"Communication issue (%@)", [error localizedDescription]);
NSString *errorString = [NSString stringWithFormat:NSLocalizedString(@"Communication issue (%@)", nil), [error localizedDescription]];
UIAlertView* errorView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Communication issue", nil)
message:errorString
delegate:nil
cancelButtonTitle:NSLocalizedString(@"Continue", nil)
otherButtonTitles:nil,nil];
[errorView show];
[errorView release];
latestReceiptMD5 = nil;
NSDictionary* dict = @{@"error_msg": errorString};
[self postNotificationforStatus:IAPReceiptFailed withDict:dict];
}
#else
- (void)purchaseAccount:(NSString *)sipURI withPassword:(NSString *)password { LOGE(@"Not supported"); }
- (void)purchaseWithID:(NSString *)productId { LOGE(@"Not supported"); }
- (void)restore { LOGE(@"Not supported"); }
- (void)XMLRPCRequest:(XMLRPCRequest *)request didFailWithError:(NSError *)error { LOGE(@"Not supported"); }
- (void)XMLRPCRequest:(XMLRPCRequest *)request didReceiveResponse:(XMLRPCResponse *)response { LOGE(@"Not supported"); }
- (BOOL)isPurchasedWithID:(NSString *)productId { LOGE(@"Not supported"); return FALSE; }
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions { LOGE(@"Not supported"); }
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response { LOGE(@"Not supported"); }
- (void)retrievePurchases { LOGE(@"Not supported"); }
#endif
@end

View file

@ -0,0 +1,13 @@
//
// InAppProductsTableViewController.h
// linphone
//
// Created by Gautier Pelloux-Prayer on 16/04/15.
//
//
#import <UIKit/UIKit.h>
@interface InAppProductsTableViewController : UITableViewController
@end

View file

@ -0,0 +1,79 @@
//
// InAppProductsTableViewController.m
// linphone
//
// Created by Gautier Pelloux-Prayer on 16/04/15.
//
//
#import "InAppProductsTableViewController.h"
#import "InAppProductsCell.h"
#import "InAppProductsManager.h"
#import "LinphoneManager.h"
#import "DTAlertView.h"
@implementation InAppProductsTableViewController {
NSInteger currentExpanded;
InAppProductsManager *iapm;
}
- (void)viewWillAppear:(BOOL)animated {
currentExpanded = -1;
iapm = [[LinphoneManager instance] iapManager];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [iapm productsAvailable].count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *kCellId = @"InAppProductsCell";
InAppProductsCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId];
if (cell == nil) {
cell = [[[InAppProductsCell alloc] initWithIdentifier:kCellId maximized:(currentExpanded == indexPath.row)] autorelease];
}
SKProduct *prod = [[[[LinphoneManager instance] iapManager] productsAvailable] objectAtIndex:indexPath.row];
[cell fillFromProduct:prod];
cell.isMaximized = (currentExpanded == indexPath.row);
return cell;
}
//- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// if(currentExpanded == indexPath.row) {
// currentExpanded = -1;
// [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
// return;
// } else if(currentExpanded >= 0) {
// NSIndexPath *previousPath = [NSIndexPath indexPathForRow:currentExpanded inSection:0];
// currentExpanded = indexPath.row;
// [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:previousPath] withRowAnimation:UITableViewRowAnimationFade];
// }
// currentExpanded = indexPath.row;
// [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
//}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
InAppProductsCell *cell = (InAppProductsCell*)[tableView cellForRowAtIndexPath:indexPath];
if (cell.ppurchased.isOn) {
DTAlertView* alert = [[DTAlertView alloc] initWithTitle:NSLocalizedString(@"Already purchased", nil) message: [NSString stringWithFormat:NSLocalizedString(@"You already bought %@.",nil), cell.ptitle.text]];
[alert addCancelButtonWithTitle:NSLocalizedString(@"OK", nil) block:nil];
[alert show];
[alert release];
} else {
//try to purchase item, and if successfull change the switch
[[[LinphoneManager instance] iapManager] purchaseWitID: cell.productID];
}
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return [InAppProductsCell getHeight:(currentExpanded == indexPath.row)];
}
@end

View file

@ -0,0 +1,20 @@
//
// InAppProductsViewController.h
// linphone
//
// Created by Gautier Pelloux-Prayer on 15/04/15.
//
//
#import <UIKit/UIKit.h>
#import "UICompositeViewController.h"
#import "InAppProductsTableViewController.h"
@interface InAppProductsViewController : UIViewController<UICompositeViewDelegate> {
}
@property (nonatomic, retain) IBOutlet InAppProductsTableViewController* tableController;
@property (retain, nonatomic) IBOutlet UIView *waitView;
- (IBAction)onRestoreClicked:(UIButton *)sender;
@end

View file

@ -0,0 +1,83 @@
//
// InAppProductsViewController.m
// linphone
//
// Created by Gautier Pelloux-Prayer on 15/04/15.
//
//
#import "InAppProductsViewController.h"
#import "InAppProductsCell.h"
@implementation InAppProductsViewController
#pragma mark - Lifecycle Functions
- (id)init {
return [super initWithNibName:@"InAppProductsViewController" bundle:[NSBundle mainBundle]];
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[_tableController release];
[_waitView release];
[super dealloc];
}
#pragma mark - ViewController Functions
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
for (NSString* notification in [NSArray arrayWithObjects:IAPAvailableSucceeded, IAPRestoreSucceeded, IAPPurchaseSucceeded, IAPReceiptSucceeded, IAPPurchaseTrying, nil]) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(onIAPPurchaseNotification:)
name:notification
object:nil];
}
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
for (NSString* notification in [NSArray arrayWithObjects:IAPAvailableSucceeded, IAPRestoreSucceeded, IAPPurchaseSucceeded, IAPReceiptSucceeded, IAPPurchaseTrying, nil]) {
[[NSNotificationCenter defaultCenter] removeObserver:self
name:notification
object:nil];
}
}
- (void)onIAPPurchaseNotification:(NSNotification*)notif {
InAppProductsManager *iapm = [[LinphoneManager instance] iapManager];
[[_tableController tableView] reloadData];
[_waitView setHidden:([[iapm productsAvailable] count] != 0 && ![notif.name isEqualToString:IAPPurchaseTrying])];
}
#pragma mark - UICompositeViewDelegate Functions
static UICompositeViewDescription *compositeDescription = nil;
+ (UICompositeViewDescription *)compositeViewDescription {
if(compositeDescription == nil) {
compositeDescription = [[UICompositeViewDescription alloc] init:@"InAppProducts"
content:@"InAppProductsViewController"
stateBar:nil
stateBarEnabled:false
tabBar: @"UIMainBar"
tabBarEnabled:true
fullscreen:false
landscapeMode:[LinphoneManager runningOnIpad]
portraitMode:true];
}
return compositeDescription;
}
- (IBAction)onRestoreClicked:(UIButton *)sender {
[[[LinphoneManager instance] iapManager] restore];
}
@end

View file

@ -0,0 +1,70 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6751" systemVersion="14B25" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6736"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="InAppProductsViewController">
<connections>
<outlet property="tableController" destination="FRQ-Fw-iZ8" id="HVZ-37-Tau"/>
<outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
<outlet property="waitView" destination="4pA-a2-gQ7" id="4f0-jJ-Wv4"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT">
<rect key="frame" x="0.0" y="0.0" width="320" height="460"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" style="grouped" separatorStyle="default" rowHeight="44" sectionHeaderHeight="1" sectionFooterHeight="10" id="fwu-cz-Gse" userLabel="productsTable">
<rect key="frame" x="0.0" y="38" width="320" height="422"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="0.93725490196078431" green="0.93725490196078431" blue="0.95686274509803926" alpha="1" colorSpace="calibratedRGB"/>
<connections>
<outlet property="dataSource" destination="FRQ-Fw-iZ8" id="uQQ-fT-hHp"/>
<outlet property="delegate" destination="FRQ-Fw-iZ8" id="2Dx-aQ-XVB"/>
</connections>
</tableView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="XrD-Mn-6EM" userLabel="restoreButton">
<rect key="frame" x="0.0" y="0.0" width="320" height="30"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
<state key="normal" title="Restore">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="onRestoreClicked:" destination="-1" eventType="touchUpInside" id="ZYY-WP-1of"/>
</connections>
</button>
<view hidden="YES" alpha="0.49999999999999961" contentMode="scaleToFill" id="4pA-a2-gQ7" userLabel="waitView">
<rect key="frame" x="0.0" y="0.0" width="320" height="460"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" animating="YES" style="whiteLarge" id="K5m-Dx-cXk" userLabel="spinner">
<rect key="frame" x="142" y="211" width="37" height="37"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</activityIndicatorView>
</subviews>
<color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="517" y="-365"/>
</view>
<tableViewController extendedLayoutIncludesOpaqueBars="YES" id="FRQ-Fw-iZ8" userLabel="tableController" customClass="InAppProductsTableViewController">
<extendedEdge key="edgesForExtendedLayout" top="YES"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<size key="freeformSize" width="320" height="460"/>
<connections>
<outlet property="view" destination="fwu-cz-Gse" id="qar-Rf-89v"/>
</connections>
<point key="canvasLocation" x="139" y="-365"/>
</tableViewController>
</objects>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<simulatedStatusBarMetrics key="statusBar"/>
<simulatedOrientationMetrics key="orientation"/>
<simulatedScreenMetrics key="destination" type="retina4"/>
</simulatedMetricsContainer>
</document>

View file

@ -4,18 +4,18 @@
*
* 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
* 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 "InCallTableViewController.h"
#import "UICallCell.h"
@ -60,7 +60,7 @@ enum TableSection {
[self initInCallTableViewController];
}
return self;
}
}
- (void)dealloc {
[super dealloc];
@ -71,9 +71,9 @@ enum TableSection {
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
updateTime = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:@selector(update)
userInfo:nil
target:self
selector:@selector(update)
userInfo:nil
repeats:YES];
}
@ -97,7 +97,7 @@ enum TableSection {
+ (int)callCount:(LinphoneCore*) lc {
int count = 0;
const MSList* calls = linphone_core_get_calls(lc);
while (calls != 0) {
if (![InCallTableViewController isInConference:((LinphoneCall*)calls->data)]) {
count++;
@ -109,7 +109,7 @@ enum TableSection {
+ (LinphoneCall*)retrieveCallAtIndex: (NSInteger) index inConference:(bool) conf{
const MSList* calls = linphone_core_get_calls([LinphoneManager getLc]);
while (calls != 0) {
if ([InCallTableViewController isInConference:(LinphoneCall*)calls->data] == conf) {
if (index == 0)
@ -118,9 +118,9 @@ enum TableSection {
}
calls = calls->next;
}
if (calls == 0) {
[LinphoneLogger logc:LinphoneLoggerError format:"Cannot find call with index %d (in conf: %d)", index, conf];
LOGE(@"Cannot find call with index %d (in conf: %d)", index, conf);
return nil;
} else {
return (LinphoneCall*)calls->data;
@ -128,7 +128,7 @@ enum TableSection {
}
#pragma mark -
#pragma mark -
- (void)removeCallData:(LinphoneCall*) call {
// Remove data associated with the call
@ -174,7 +174,7 @@ enum TableSection {
for (int row = 0; row < [tableView numberOfRowsInSection:section]; row++) {
NSIndexPath* cellPath = [NSIndexPath indexPathForRow:row inSection:section];
UICallCell* cell = (UICallCell*) [tableView cellForRowAtIndexPath:cellPath];
[cell update];
[cell update];
}
}
}
@ -216,14 +216,14 @@ enum TableSection {
if (cell == nil) {
cell = [[[UICallCell alloc] initWithIdentifier:kCellId] autorelease];
}
bool inConference = indexPath.section == ConferenceSection;
LinphoneCore* lc = [LinphoneManager getLc];
LinphoneCall* currentCall = linphone_core_get_current_call(lc);
LinphoneCall* call = [InCallTableViewController retrieveCallAtIndex:indexPath.row inConference:inConference];
[cell setData:[self addCallData:call]];
// Update cell
if ([indexPath section] == CallSection && [indexPath row] == 0 && linphone_core_get_conference_size(lc) == 0) {
[cell setFirstCell:true];
@ -233,20 +233,20 @@ enum TableSection {
[cell setCurrentCall:(currentCall == call)];
[cell setConferenceCell:inConference];
[cell update];
/*if (linphone_core_get_calls_nb(lc) > 1 || linphone_core_get_conference_size(lc) > 0) {
tableView.scrollEnabled = true;
} else {
tableView.scrollEnabled = false;
}*/
return cell;
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
int count = 0;
LinphoneCore* lc = [LinphoneManager getLc];
if(section == CallSection) {
count = [InCallTableViewController callCount:lc];
} else {
@ -273,7 +273,7 @@ enum TableSection {
#pragma mark - UITableViewDelegate Functions
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
if(section == CallSection) {
return [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
} else if(section == ConferenceSection) {
@ -291,11 +291,11 @@ enum TableSection {
return [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
return [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
LinphoneCore* lc = [LinphoneManager getLc];
if(section == CallSection) {
return 0.000001f; // Hack UITableView = 0
@ -307,7 +307,7 @@ enum TableSection {
return 0.000001f; // Hack UITableView = 0
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
LinphoneCore* lc = [LinphoneManager getLc];
if(section == CallSection) {
return 0.000001f; // Hack UITableView = 0

View file

@ -4,18 +4,18 @@
*
* 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
* 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 <AudioToolbox/AudioToolbox.h>
#import <AddressBook/AddressBook.h>
@ -67,7 +67,7 @@ const NSInteger SECURE_BUTTON_TAG=5;
- (void)dealloc {
[callTableController release];
[callTableView release];
[videoGroup release];
[videoView release];
[videoPreview release];
@ -75,17 +75,17 @@ const NSInteger SECURE_BUTTON_TAG=5;
[testVideoView release];
#endif
[videoCameraSwitch release];
[videoWaitingForFirstImage release];
[videoZoomHandler release];
[[PhoneMainView instance].view removeGestureRecognizer:singleFingerTap];
[singleFingerTap release];
// Remove all observer
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
@ -96,12 +96,12 @@ static UICompositeViewDescription *compositeDescription = nil;
+ (UICompositeViewDescription *)compositeViewDescription {
if(compositeDescription == nil) {
compositeDescription = [[UICompositeViewDescription alloc] init:@"InCall"
content:@"InCallViewController"
stateBar:@"UIStateBar"
stateBarEnabled:true
tabBar:@"UICallBar"
tabBarEnabled:true
compositeDescription = [[UICompositeViewDescription alloc] init:@"InCall"
content:@"InCallViewController"
stateBar:@"UIStateBar"
stateBarEnabled:true
tabBar:@"UICallBar"
tabBarEnabled:true
fullscreen:false
landscapeMode:true
portraitMode:true];
@ -115,7 +115,7 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[[UIApplication sharedApplication] setIdleTimerDisabled:YES];
UIDevice *device = [UIDevice currentDevice];
device.proximityMonitoringEnabled = YES;
@ -130,14 +130,14 @@ static UICompositeViewDescription *compositeDescription = nil;
[hideControlsTimer invalidate];
hideControlsTimer = nil;
}
if( hiddenVolume ) {
[[PhoneMainView instance] setVolumeHidden:FALSE];
hiddenVolume = FALSE;
}
// Remove observer
[[NSNotificationCenter defaultCenter] removeObserver:self
[[NSNotificationCenter defaultCenter] removeObserver:self
name:kLinphoneCallUpdate
object:nil];
}
@ -145,11 +145,11 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// Set observer
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(callUpdateEvent:)
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(callUpdateEvent:)
name:kLinphoneCallUpdate
object:nil];
// Update on show
LinphoneCall* call = linphone_core_get_current_call([LinphoneManager getLc]);
LinphoneCallState state = (call != NULL)?linphone_call_get_state(call): 0;
@ -158,14 +158,14 @@ static UICompositeViewDescription *compositeDescription = nil;
// Set windows (warn memory leaks)
linphone_core_set_native_video_window_id([LinphoneManager getLc], (unsigned long)videoView);
linphone_core_set_native_preview_window_id([LinphoneManager getLc], (unsigned long)videoPreview);
// Enable tap
[singleFingerTap setEnabled:TRUE];
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
[[UIApplication sharedApplication] setIdleTimerDisabled:false];
UIDevice *device = [UIDevice currentDevice];
device.proximityMonitoringEnabled = NO;
@ -177,16 +177,16 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)viewDidLoad {
[super viewDidLoad];
[singleFingerTap setNumberOfTapsRequired:1];
[singleFingerTap setCancelsTouchesInView: FALSE];
[[PhoneMainView instance].view addGestureRecognizer:singleFingerTap];
[videoZoomHandler setup:videoGroup];
videoGroup.alpha = 0;
[videoCameraSwitch setPreview:videoPreview];
[callTableController.tableView setBackgroundColor:[UIColor clearColor]]; // Can't do it in Xib: issue with ios4
[callTableController.tableView setBackgroundView:nil]; // Can't do it in Xib: issue with ios4
}
@ -213,16 +213,16 @@ static UICompositeViewDescription *compositeDescription = nil;
}
// Update table
[callTableView reloadData];
[callTableView reloadData];
// Fake call update
if(call == NULL) {
return;
}
switch (state) {
case LinphoneCallIncomingReceived:
case LinphoneCallOutgoingInit:
switch (state) {
case LinphoneCallIncomingReceived:
case LinphoneCallOutgoingInit:
{
if(linphone_core_get_calls_nb(lc) > 1) {
[callTableController minimizeAll];
@ -258,10 +258,10 @@ static UICompositeViewDescription *compositeDescription = nil;
{
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_core_video_enabled(lc) && !linphone_call_params_video_enabled(current) &&
linphone_call_params_video_enabled(remote) &&
linphone_call_params_video_enabled(remote) &&
!linphone_core_get_video_policy(lc)->automatically_accept) {
linphone_core_defer_call_update(lc, call);
[self displayAskToEnableVideoCall:call];
@ -288,7 +288,7 @@ static UICompositeViewDescription *compositeDescription = nil;
default:
break;
}
}
- (void)showControls:(id)sender {
@ -296,7 +296,7 @@ static UICompositeViewDescription *compositeDescription = nil;
[hideControlsTimer invalidate];
hideControlsTimer = nil;
}
if([[[PhoneMainView instance] currentView] equal:[InCallViewController compositeViewDescription]] && videoShown) {
// show controls
[UIView beginAnimations:nil context:nil];
@ -306,7 +306,7 @@ static UICompositeViewDescription *compositeDescription = nil;
[callTableView setAlpha:1.0];
[videoCameraSwitch setAlpha:1.0];
[UIView commitAnimations];
// hide controls in 5 sec
hideControlsTimer = [NSTimer scheduledTimerWithTimeInterval:5.0
target:self
@ -321,15 +321,15 @@ static UICompositeViewDescription *compositeDescription = nil;
[hideControlsTimer invalidate];
hideControlsTimer = nil;
}
if([[[PhoneMainView instance] currentView] equal:[InCallViewController compositeViewDescription]] && videoShown) {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.3];
[videoCameraSwitch setAlpha:0.0];
[callTableView setAlpha:0.0];
[UIView commitAnimations];
[[PhoneMainView instance] showTabBar: false];
[[PhoneMainView instance] showStateBar: false];
}
@ -351,19 +351,19 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)enableVideoDisplay:(BOOL)animation {
if(videoShown && animation)
return;
videoShown = true;
[videoZoomHandler resetZoom];
if(animation) {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
}
[videoGroup setAlpha:1.0];
[callTableView setAlpha:0.0];
UIEdgeInsets insets = {33, 0, 25, 0};
[callTableView setContentInset:insets];
[callTableView setScrollIndicatorInsets:insets];
@ -372,31 +372,31 @@ static UICompositeViewDescription *compositeDescription = nil;
if(animation) {
[UIView commitAnimations];
}
if(linphone_core_self_view_enabled([LinphoneManager getLc])) {
[videoPreview setHidden:FALSE];
} else {
[videoPreview setHidden:TRUE];
}
if ([LinphoneManager instance].frontCamId != nil) {
// only show camera switch button if we have more than 1 camera
[videoCameraSwitch setHidden:FALSE];
}
[videoCameraSwitch setAlpha:0.0];
[[PhoneMainView instance] fullScreen: true];
[[PhoneMainView instance] showTabBar: false];
[[PhoneMainView instance] showStateBar: false];
#ifdef TEST_VIDEO_VIEW_CHANGE
[NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(_debugChangeVideoView) userInfo:nil repeats:YES];
#endif
// [self batteryLevelChanged:nil];
[videoWaitingForFirstImage setHidden: NO];
[videoWaitingForFirstImage startAnimating];
LinphoneCall *call = linphone_core_get_current_call([LinphoneManager getLc]);
//linphone_call_params_get_used_video_codec return 0 if no video stream enabled
if (call != NULL && linphone_call_params_get_used_video_codec(linphone_call_get_current_params(call))) {
@ -407,13 +407,13 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)disableVideoDisplay:(BOOL)animation {
if(!videoShown && animation)
return;
videoShown = false;
if(animation) {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
}
[videoGroup setAlpha:0.0];
[[PhoneMainView instance] showTabBar: true];
@ -427,20 +427,20 @@ static UICompositeViewDescription *compositeDescription = nil;
[callTableView setAlpha:1.0];
[videoCameraSwitch setHidden:TRUE];
if(animation) {
[UIView commitAnimations];
}
if (hideControlsTimer != nil) {
[hideControlsTimer invalidate];
hideControlsTimer = nil;
}
[[PhoneMainView instance] fullScreen:false];
}
- (void)displayVideoCall:(BOOL)animated {
- (void)displayVideoCall:(BOOL)animated {
[self enableVideoDisplay:animated];
}
@ -475,17 +475,17 @@ static void hideSpinner(LinphoneCall* call, void* user_data) {
- (void)displayAskToEnableVideoCall:(LinphoneCall*) call {
if (linphone_core_get_video_policy([LinphoneManager getLc])->automatically_accept)
return;
const char* lUserNameChars = linphone_address_get_username(linphone_call_get_remote_address(call));
NSString* lUserName = lUserNameChars?[[[NSString alloc] initWithUTF8String:lUserNameChars] autorelease]:NSLocalizedString(@"Unknown",nil);
const char* lDisplayNameChars = linphone_address_get_display_name(linphone_call_get_remote_address(call));
const char* lDisplayNameChars = linphone_address_get_display_name(linphone_call_get_remote_address(call));
NSString* lDisplayName = [lDisplayNameChars?[[NSString alloc] initWithUTF8String:lDisplayNameChars]:@"" autorelease];
NSString* title = [NSString stringWithFormat : NSLocalizedString(@"'%@' would like to enable video",nil), ([lDisplayName length] > 0)?lDisplayName:lUserName];
DTActionSheet *sheet = [[[DTActionSheet alloc] initWithTitle:title] autorelease];
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:30 target:self selector:@selector(dismissVideoActionSheet:) userInfo:sheet repeats:NO];
[sheet addButtonWithTitle:NSLocalizedString(@"Accept", nil) block:^() {
[LinphoneLogger logc:LinphoneLoggerLog format:"User accept video proposal"];
LOGI(@"User accept video proposal");
LinphoneCallParams* paramsCopy = linphone_call_params_copy(linphone_call_get_current_params(call));
linphone_call_params_enable_video(paramsCopy, TRUE);
linphone_core_accept_call_update([LinphoneManager getLc], call, paramsCopy);
@ -493,7 +493,7 @@ static void hideSpinner(LinphoneCall* call, void* user_data) {
[timer invalidate];
}];
DTActionSheetBlock cancelBlock = ^() {
[LinphoneLogger logc:LinphoneLoggerLog format:"User declined video proposal"];
LOGI(@"User declined video proposal");
LinphoneCallParams* paramsCopy = linphone_call_params_copy(linphone_call_get_current_params(call));
linphone_core_accept_call_update([LinphoneManager getLc], call, paramsCopy);
linphone_call_params_destroy(paramsCopy);

View file

@ -4,18 +4,18 @@
*
* 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
* 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 "PhoneMainView.h"
#import "linphoneAppDelegate.h"
@ -49,7 +49,7 @@
}
#pragma mark -
#pragma mark -
@ -62,23 +62,23 @@
LOGI(@"%@", NSStringFromSelector(_cmd));
LinphoneCore* lc = [LinphoneManager getLc];
LinphoneCall* call = linphone_core_get_current_call(lc);
if (call){
/* save call context */
LinphoneManager* instance = [LinphoneManager instance];
instance->currentCallContextBeforeGoingBackground.call = call;
instance->currentCallContextBeforeGoingBackground.cameraIsEnabled = linphone_call_camera_enabled(call);
const LinphoneCallParams* params = linphone_call_get_current_params(call);
if (linphone_call_params_video_enabled(params)) {
linphone_call_enable_camera(call, false);
}
}
if (![[LinphoneManager instance] resignActive]) {
}
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
@ -90,12 +90,12 @@
[[PhoneMainView instance] updateStatusBar:nil];
}
LinphoneManager* instance = [LinphoneManager instance];
[instance becomeActive];
LinphoneCore* lc = [LinphoneManager getLc];
LinphoneCall* call = linphone_core_get_current_call(lc);
if (call){
if (call == instance->currentCallContextBeforeGoingBackground.call) {
const LinphoneCallParams* params = linphone_call_get_current_params(call);
@ -115,23 +115,23 @@
}
- (UIUserNotificationCategory*)getMessageNotificationCategory {
UIMutableUserNotificationAction* reply = [[[UIMutableUserNotificationAction alloc] init] autorelease];
reply.identifier = @"reply";
reply.title = NSLocalizedString(@"Reply", nil);
reply.activationMode = UIUserNotificationActivationModeForeground;
reply.destructive = NO;
reply.authenticationRequired = YES;
UIMutableUserNotificationAction* mark_read = [[[UIMutableUserNotificationAction alloc] init] autorelease];
mark_read.identifier = @"mark_read";
mark_read.title = NSLocalizedString(@"Mark Read", nil);
mark_read.activationMode = UIUserNotificationActivationModeBackground;
mark_read.destructive = NO;
mark_read.authenticationRequired = NO;
NSArray* localRingActions = @[mark_read, reply];
UIMutableUserNotificationCategory* localRingNotifAction = [[[UIMutableUserNotificationCategory alloc] init] autorelease];
localRingNotifAction.identifier = @"incoming_msg";
[localRingNotifAction setActions:localRingActions forContext:UIUserNotificationActionContextDefault];
@ -147,17 +147,17 @@
answer.activationMode = UIUserNotificationActivationModeForeground;
answer.destructive = NO;
answer.authenticationRequired = YES;
UIMutableUserNotificationAction* decline = [[[UIMutableUserNotificationAction alloc] init] autorelease];
decline.identifier = @"decline";
decline.title = NSLocalizedString(@"Decline", nil);
decline.activationMode = UIUserNotificationActivationModeBackground;
decline.destructive = YES;
decline.authenticationRequired = NO;
NSArray* localRingActions = @[decline, answer];
UIMutableUserNotificationCategory* localRingNotifAction = [[[UIMutableUserNotificationCategory alloc] init] autorelease];
localRingNotifAction.identifier = @"incoming_call";
[localRingNotifAction setActions:localRingActions forContext:UIUserNotificationActionContextDefault];
@ -176,13 +176,13 @@
LinphoneManager* instance = [LinphoneManager instance];
BOOL background_mode = [instance lpConfigBoolForKey:@"backgroundmode_preference"];
BOOL start_at_boot = [instance lpConfigBoolForKey:@"start_at_boot_preference"];
if( !instance.isTesting ){
if( [app respondsToSelector:@selector(registerUserNotificationSettings:)] ){
/* iOS8 notifications can be actioned! Awesome: */
UIUserNotificationType notifTypes = UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert;
NSSet* categories = [NSSet setWithObjects:[self getCallNotificationCategory], [self getMessageNotificationCategory], nil];
UIUserNotificationSettings* userSettings = [UIUserNotificationSettings settingsForTypes:notifTypes categories:categories];
[app registerUserNotificationSettings:userSettings];
@ -194,7 +194,7 @@
} else {
NSLog(@"No remote push for testing");
}
if (state == UIApplicationStateBackground)
{
@ -208,7 +208,7 @@
}
bgStartId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[LinphoneLogger log:LinphoneLoggerWarning format:@"Background task for application launching expired."];
LOGW(@"Background task for application launching expired.");
[[UIApplication sharedApplication] endBackgroundTask:bgStartId];
}];
@ -223,7 +223,7 @@
NSDictionary *remoteNotif =[launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (remoteNotif){
[LinphoneLogger log:LinphoneLoggerLog format:@"PushNotification from launch received."];
LOGI(@"PushNotification from launch received.");
[self processRemoteNotification:remoteNotif];
}
if (bgStartId!=UIBackgroundTaskInvalid) [[UIApplication sharedApplication] endBackgroundTask:bgStartId];
@ -274,7 +274,7 @@
- (void)processRemoteNotification:(NSDictionary*)userInfo{
NSDictionary *aps = [userInfo objectForKey:@"aps"];
if(aps != nil) {
NSDictionary *alert = [aps objectForKey:@"alert"];
if(alert != nil) {
@ -292,7 +292,7 @@
if( callId != nil ){
[[LinphoneManager instance] addPushCallId:callId];
} else {
[LinphoneLogger log:LinphoneLoggerError format:@"PushNotification: does not have call-id yet, fix it !"];
LOGE(@"PushNotification: does not have call-id yet, fix it !");
}
if( [loc_key isEqualToString:@"IM_MSG"] ) {
@ -414,7 +414,7 @@
if( [[UIDevice currentDevice].systemVersion floatValue] >= 8){
LinphoneCore* lc = [LinphoneManager getLc];
[LinphoneLogger log:LinphoneLoggerLog format:@"%@", NSStringFromSelector(_cmd)];
LOGI(@"%@", NSStringFromSelector(_cmd));
if( [notification.category isEqualToString:@"incoming_call"]) {
if( [identifier isEqualToString:@"answer"] ){
// use the standard handler

View file

@ -67,8 +67,8 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
bool_t value = linphone_core_payload_type_enabled(lc,pt);
[self setBool:value forKey: pref];
}else{
[LinphoneLogger logc:LinphoneLoggerWarning format:"Codec %s/%i supported by core is not shown in iOS app config view.",
pt->mime_type,pt->clock_rate];
LOGW(@"Codec %s/%i supported by core is not shown in iOS app config view.",
pt->mime_type,pt->clock_rate);
}
}
}
@ -186,7 +186,7 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
[self transformCodecsToKeys: linphone_core_get_video_codecs(lc)];
[self setBool:linphone_core_adaptive_rate_control_enabled(lc) forKey:@"adaptive_rate_control_preference"];
[self setString:linphone_core_get_adaptive_rate_algorithm(lc) forKey:@"adaptive_rate_algorithm_preference"];
[self setInteger:lp_config_get_int(conf, "audio", "codec_bitrate_limit", kLinphoneAudioVbrCodecDefaultBitrate) forKey:@"audio_codec_bitrate_limit_preference"];
[self setInteger:lp_config_get_int(conf, LINPHONERC_APPLICATION_KEY, "voiceproc_preference", 1) forKey:@"voiceproc_preference"];
[self setInteger:lp_config_get_int(conf, "sound", "eq_active", 0) forKey:@"eq_active"];
@ -316,7 +316,7 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
// will also update the sip_*_port section of the config
if (linphone_core_set_sip_transports(lc, &transportValue)) {
[LinphoneLogger logc:LinphoneLoggerError format:"cannot set transport"];
LOGE(@"cannot set transport");
}
port_preference = linphone_core_get_sip_port(lc);
@ -326,7 +326,7 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
BOOL enable_ipv6 = [self boolForKey:@"use_ipv6"];
lp_config_set_int(conf, "sip", "use_ipv6", enable_ipv6);
if( linphone_core_ipv6_enabled(lc) != enable_ipv6){
[LinphoneLogger logc:LinphoneLoggerDebug format:"%@ IPV6", enable_ipv6?@"ENABLING":@"DISABLING"];
LOGD(@"%@ IPV6", enable_ipv6?@"ENABLING":@"DISABLING");
linphone_core_enable_ipv6(lc, enable_ipv6);
}
@ -689,7 +689,7 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
BOOL debugmode = [self boolForKey:@"debugenable_preference"];
lp_config_set_int(config, LINPHONERC_APPLICATION_KEY, "debugenable_preference", debugmode);
[[LinphoneManager instance] setLogsEnabled:debugmode];
BOOL animations = [self boolForKey:@"animations_preference"];
lp_config_set_int(config, LINPHONERC_APPLICATION_KEY, "animations_preference", animations);
@ -731,7 +731,7 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
} else if ([lTunnelPrefMode isEqualToString:@"auto"]) {
mode = tunnel_auto;
} else {
[LinphoneLogger logc:LinphoneLoggerError format:"Unexpected tunnel mode [%s]",[lTunnelPrefMode cStringUsingEncoding:[NSString defaultCStringEncoding]]];
LOGE(@"Unexpected tunnel mode [%s]",[lTunnelPrefMode cStringUsingEncoding:[NSString defaultCStringEncoding]]);
}
}

View file

@ -31,6 +31,7 @@
#import "IASKAppSettingsViewController.h"
#import "FastAddressBook.h"
#import "Utils.h"
#import "InAppProductsManager.h"
#include "linphone/linphonecore.h"
#include "linphone/linphone_tunnel.h"
@ -202,6 +203,6 @@ typedef struct _LinphoneManagerSounds {
@property (copy) void (^silentPushCompletion)(UIBackgroundFetchResult);
@property (readonly) BOOL wasRemoteProvisioned;
@property (readonly) LpConfig *configDb;
@property (readonly) InAppProductsManager *iapManager;
@end

View file

@ -268,10 +268,9 @@ struct codec_name_pref_table codec_pref_table[]={
AudioSessionInitialize(NULL, NULL, NULL, NULL);
OSStatus lStatus = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, audioRouteChangeListenerCallback, self);
if (lStatus) {
[LinphoneLogger logc:LinphoneLoggerError format:"cannot register route change handler [%ld]",lStatus];
LOGE(@"cannot register route change handler [%ld]",lStatus);
}
NSString *path = [[NSBundle mainBundle] pathForResource:@"msg" ofType:@"wav"];
self.messagePlayer = [[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL URLWithString:path] error:nil] autorelease];
@ -299,6 +298,7 @@ struct codec_name_pref_table codec_pref_table[]={
[self lpConfigSetBool:FALSE forKey:@"debugenable_preference"];
#endif
}
_iapManager = [[InAppProductsManager alloc] init];
[self migrateFromUserPrefs];
}
@ -311,7 +311,7 @@ struct codec_name_pref_table codec_pref_table[]={
OSStatus lStatus = AudioSessionRemovePropertyListenerWithUserData(kAudioSessionProperty_AudioRouteChange, audioRouteChangeListenerCallback, self);
if (lStatus) {
[LinphoneLogger logc:LinphoneLoggerError format:"cannot un register route change handler [%ld]", lStatus];
LOGE(@"cannot un register route change handler [%ld]", lStatus);
}
[[NSNotificationCenter defaultCenter] removeObserver:self forKeyPath:kLinphoneGlobalStateUpdate];
@ -326,7 +326,7 @@ struct codec_name_pref_table codec_pref_table[]={
- (void)silentPushFailed:(NSTimer*)timer
{
if( silentPushCompletion ){
[LinphoneLogger log:LinphoneLoggerLog format:@"silentPush failed, silentPushCompletion block: %p", silentPushCompletion ];
LOGI(@"silentPush failed, silentPushCompletion block: %p", silentPushCompletion );
silentPushCompletion(UIBackgroundFetchResultNoData);
silentPushCompletion = nil;
}
@ -356,7 +356,7 @@ static int check_should_migrate_images(void* data ,int argc,char** argv,char** c
if( sqlite3_open([newDbPath UTF8String], &newDb) != SQLITE_OK) {
[LinphoneLogger log:LinphoneLoggerError format:@"Can't open \"%@\" sqlite3 database.", newDbPath];
LOGE(@"Can't open \"%@\" sqlite3 database.", newDbPath);
return FALSE;
}
@ -369,14 +369,14 @@ static int check_should_migrate_images(void* data ,int argc,char** argv,char** c
}
[LinphoneLogger logc:LinphoneLoggerLog format:"Starting migration procedure"];
LOGI(@"Starting migration procedure");
if( shouldMigrate ){
// attach old database to the new one:
attach_stmt = sqlite3_mprintf("ATTACH DATABASE %Q AS oldchats", [oldDbPath UTF8String]);
if( sqlite3_exec(newDb, attach_stmt, NULL, NULL, &errMsg) != SQLITE_OK ){
[LinphoneLogger logc:LinphoneLoggerError format:"Can't attach old chat table, error[%s] ", errMsg];
LOGE(@"Can't attach old chat table, error[%s] ", errMsg);
sqlite3_free(errMsg);
goto exit_dbmigration;
}
@ -387,7 +387,7 @@ static int check_should_migrate_images(void* data ,int argc,char** argv,char** c
"SELECT localContact,remoteContact,direction,message,time,read,state,'-1' FROM oldchats.chat";
if( sqlite3_exec(newDb, migration_statement, NULL, NULL, &errMsg) != SQLITE_OK ){
[LinphoneLogger logc:LinphoneLoggerError format:"DB migration failed, error[%s] ", errMsg];
LOGE(@"DB migration failed, error[%s] ", errMsg);
sqlite3_free(errMsg);
goto exit_dbmigration;
}
@ -395,7 +395,7 @@ static int check_should_migrate_images(void* data ,int argc,char** argv,char** c
// invert direction of old messages, because iOS was storing the direction flag incorrectly
const char* invert_direction = "UPDATE history SET direction = NOT direction";
if( sqlite3_exec(newDb, invert_direction, NULL, NULL, &errMsg) != SQLITE_OK){
[LinphoneLogger log: LinphoneLoggerError format:@"Inverting direction failed, error[%s]", errMsg];
LOGE(@"Inverting direction failed, error[%s]", errMsg);
sqlite3_free(errMsg);
goto exit_dbmigration;
}
@ -410,14 +410,14 @@ static int check_should_migrate_images(void* data ,int argc,char** argv,char** c
char* from_conversion = sqlite3_mprintf("UPDATE history SET localContact = %Q WHERE localContact = ''", identity);
if( sqlite3_exec(newDb, from_conversion, NULL, NULL, &errMsg) != SQLITE_OK ){
[LinphoneLogger logc:LinphoneLoggerError format:"FROM conversion failed, error[%s] ", errMsg];
LOGE(@"FROM conversion failed, error[%s] ", errMsg);
sqlite3_free(errMsg);
}
sqlite3_free(from_conversion);
char* to_conversion = sqlite3_mprintf("UPDATE history SET remoteContact = %Q WHERE remoteContact = ''", identity);
if( sqlite3_exec(newDb, to_conversion, NULL, NULL, &errMsg) != SQLITE_OK ){
[LinphoneLogger logc:LinphoneLoggerError format:"DB migration failed, error[%s] ", errMsg];
LOGE(@"DB migration failed, error[%s] ", errMsg);
sqlite3_free(errMsg);
}
sqlite3_free(to_conversion);
@ -431,14 +431,14 @@ static int check_should_migrate_images(void* data ,int argc,char** argv,char** c
// move already stored images from the messages to the appdata JSON field
const char* assetslib_migration = "UPDATE history SET appdata='{\"localimage\":\"'||message||'\"}' , message='' WHERE message LIKE 'assets-library%'";
if( sqlite3_exec(newDb, assetslib_migration, NULL, NULL, &errMsg) != SQLITE_OK ){
[LinphoneLogger logc:LinphoneLoggerError format:"Assets-history migration for MESSAGE failed, error[%s] ", errMsg];
LOGE(@"Assets-history migration for MESSAGE failed, error[%s] ", errMsg);
sqlite3_free(errMsg);
}
// move already stored images from the url to the appdata JSON field
const char* assetslib_migration_fromurl = "UPDATE history SET appdata='{\"localimage\":\"'||url||'\"}' , url='' WHERE url LIKE 'assets-library%'";
if( sqlite3_exec(newDb, assetslib_migration_fromurl, NULL, NULL, &errMsg) != SQLITE_OK ){
[LinphoneLogger logc:LinphoneLoggerError format:"Assets-history migration for URL failed, error[%s] ", errMsg];
LOGE(@"Assets-history migration for URL failed, error[%s] ", errMsg);
sqlite3_free(errMsg);
}
@ -453,10 +453,10 @@ exit_dbmigration:
// in any case, we should remove the old chat db
if( shouldMigrate && ![[NSFileManager defaultManager] removeItemAtPath:oldDbPath error:&error] ){
[LinphoneLogger logc:LinphoneLoggerError format:"Could not remove old chat DB: %@", error];
LOGE(@"Could not remove old chat DB: %@", error);
}
[LinphoneLogger log:LinphoneLoggerLog format:@"Message storage migration finished: success = %@", migrated ? @"TRUE":@"FALSE"];
LOGI(@"Message storage migration finished: success = %@", migrated ? @"TRUE":@"FALSE");
return migrated;
}
@ -523,11 +523,11 @@ struct _entry_data {
static void dump_entry(const char* entry, void*data) {
struct _entry_data *d = (struct _entry_data*)data;
const char* value = lp_config_get_string(d->conf, d->section, entry, "");
[LinphoneLogger log:LinphoneLoggerLog format:@"%s=%s", entry, value];
LOGI(@"%s=%s", entry, value);
}
static void dump_section(const char* section, void* data){
[LinphoneLogger log:LinphoneLoggerLog format:@"[%s]", section ];
LOGI(@"[%s]", section );
struct _entry_data d = {(const LpConfig*)data, section};
lp_config_for_each_entry((const LpConfig*)data, section, dump_entry, &d);
}
@ -603,7 +603,7 @@ static void linphone_iphone_display_status(struct _LinphoneCore * lc, const char
- (void)localNotifContinue:(NSTimer*) timer {
UILocalNotification* notif = [timer userInfo];
if (notif){
[LinphoneLogger log:LinphoneLoggerLog format:@"cancelling/presenting local notif"];
LOGI(@"cancelling/presenting local notif");
[[UIApplication sharedApplication] cancelLocalNotification:notif];
[[UIApplication sharedApplication] presentLocalNotificationNow:notif];
}
@ -622,7 +622,7 @@ static void linphone_iphone_display_status(struct _LinphoneCore * lc, const char
// we were woken up by a silent push. Call the completion handler with NEWDATA
// so that the push is notified to the user
[LinphoneLogger log:LinphoneLoggerLog format:@"onCall - handler %p", silentPushCompletion];
LOGI(@"onCall - handler %p", silentPushCompletion);
silentPushCompletion(UIBackgroundFetchResultNewData);
silentPushCompletion = nil;
}
@ -664,7 +664,7 @@ static void linphone_iphone_display_status(struct _LinphoneCore * lc, const char
if ([lCTCallCenter currentCalls]!=nil) {
char *tmp=linphone_call_get_remote_address_as_string(call);
if (tmp) {
[LinphoneLogger logc:LinphoneLoggerLog format:"Mobile call ongoing... rejecting call from [%s]",tmp];
LOGI(@"Mobile call ongoing... rejecting call from [%s]",tmp);
ms_free(tmp);
}
linphone_core_decline_call(theLinphoneCore, call,LinphoneReasonBusy);
@ -704,7 +704,7 @@ static void linphone_iphone_display_status(struct _LinphoneCore * lc, const char
if (!incallBgTask){
incallBgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler: ^{
[LinphoneLogger log:LinphoneLoggerWarning format:@"Call cannot ring any more, too late"];
LOGW(@"Call cannot ring any more, too late");
[[UIApplication sharedApplication] endBackgroundTask:incallBgTask];
incallBgTask=0;
}];
@ -810,7 +810,7 @@ static void linphone_iphone_global_state_changed(LinphoneCore *lc, LinphoneGloba
}
-(void)onGlobalStateChanged:(LinphoneGlobalState)state withMessage:(const char*)message {
[LinphoneLogger log:LinphoneLoggerLog format:@"onGlobalStateChanged: %d (message: %s)", state, message];
LOGI(@"onGlobalStateChanged: %d (message: %s)", state, message);
NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:state], @"state",
@ -838,7 +838,7 @@ static void linphone_iphone_configuring_status_changed(LinphoneCore *lc, Linphon
}
-(void)onConfiguringStatusChanged:(LinphoneConfiguringState)status withMessage:(const char*)message {
[LinphoneLogger log:LinphoneLoggerLog format:@"onConfiguringStatusChanged: %d (message: %s)", status, message];
LOGI(@"onConfiguringStatusChanged: %d (message: %s)", status, message);
NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:status], @"state",
@ -864,7 +864,7 @@ static void linphone_iphone_configuring_status_changed(LinphoneCore *lc, Linphon
#pragma mark - Registration State Functions
- (void)onRegister:(LinphoneCore *)lc cfg:(LinphoneProxyConfig*) cfg state:(LinphoneRegistrationState) state message:(const char*) message {
[LinphoneLogger logc:LinphoneLoggerLog format:"NEW REGISTRATION STATE: '%s' (message: '%s')", linphone_registration_state_to_string(state), message];
LOGI(@"NEW REGISTRATION STATE: '%s' (message: '%s')", linphone_registration_state_to_string(state), message);
// Post event
NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
@ -888,7 +888,7 @@ static void linphone_iphone_registration_state(LinphoneCore *lc, LinphoneProxyCo
// we were woken up by a silent push. Call the completion handler with NEWDATA
// so that the push is notified to the user
[LinphoneLogger log:LinphoneLoggerLog format:@"onMessageReceived - handler %p", silentPushCompletion];
LOGI(@"onMessageReceived - handler %p", silentPushCompletion);
silentPushCompletion(UIBackgroundFetchResultNewData);
silentPushCompletion = nil;
}
@ -1045,7 +1045,7 @@ static void linphone_iphone_is_composing_received(LinphoneCore *lc, LinphoneChat
NSString *data = nil;
CFDictionaryRef dict = CNCopyCurrentNetworkInfo((CFStringRef)@"en0");
if(dict) {
[LinphoneLogger log:LinphoneLoggerDebug format:@"AP Wifi: %@", dict];
LOGI(@"AP Wifi: %@", dict);
data = [NSString stringWithString:(NSString*) CFDictionaryGetValue(dict, @"SSID")];
CFRelease(dict);
}
@ -1054,24 +1054,25 @@ static void linphone_iphone_is_composing_received(LinphoneCore *lc, LinphoneChat
}
static void showNetworkFlags(SCNetworkReachabilityFlags flags){
[LinphoneLogger logc:LinphoneLoggerLog format:"Network connection flags:"];
if (flags==0) [LinphoneLogger logc:LinphoneLoggerLog format:"no flags."];
LOGI(@"Network connection flags:");
if (flags==0)
LOGI(@"no flags.");
if (flags & kSCNetworkReachabilityFlagsTransientConnection)
[LinphoneLogger logc:LinphoneLoggerLog format:"kSCNetworkReachabilityFlagsTransientConnection"];
LOGI(@"kSCNetworkReachabilityFlagsTransientConnection");
if (flags & kSCNetworkReachabilityFlagsReachable)
[LinphoneLogger logc:LinphoneLoggerLog format:"kSCNetworkReachabilityFlagsReachable"];
LOGI(@"kSCNetworkReachabilityFlagsReachable");
if (flags & kSCNetworkReachabilityFlagsConnectionRequired)
[LinphoneLogger logc:LinphoneLoggerLog format:"kSCNetworkReachabilityFlagsConnectionRequired"];
LOGI(@"kSCNetworkReachabilityFlagsConnectionRequired");
if (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic)
[LinphoneLogger logc:LinphoneLoggerLog format:"kSCNetworkReachabilityFlagsConnectionOnTraffic"];
LOGI(@"kSCNetworkReachabilityFlagsConnectionOnTraffic");
if (flags & kSCNetworkReachabilityFlagsConnectionOnDemand)
[LinphoneLogger logc:LinphoneLoggerLog format:"kSCNetworkReachabilityFlagsConnectionOnDemand"];
LOGI(@"kSCNetworkReachabilityFlagsConnectionOnDemand");
if (flags & kSCNetworkReachabilityFlagsIsLocalAddress)
[LinphoneLogger logc:LinphoneLoggerLog format:"kSCNetworkReachabilityFlagsIsLocalAddress"];
LOGI(@"kSCNetworkReachabilityFlagsIsLocalAddress");
if (flags & kSCNetworkReachabilityFlagsIsDirect)
[LinphoneLogger logc:LinphoneLoggerLog format:"kSCNetworkReachabilityFlagsIsDirect"];
LOGI(@"kSCNetworkReachabilityFlagsIsDirect");
if (flags & kSCNetworkReachabilityFlagsIsWWAN)
[LinphoneLogger logc:LinphoneLoggerLog format:"kSCNetworkReachabilityFlagsIsWWAN"];
LOGI(@"kSCNetworkReachabilityFlagsIsWWAN");
}
static void networkReachabilityNotification(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) {
@ -1134,7 +1135,7 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach
}
linphone_core_set_network_reachable(theLinphoneCore,true);
linphone_core_iterate(theLinphoneCore);
[LinphoneLogger logc:LinphoneLoggerLog format:"Network connectivity changed to type [%s]",(newConnectivity==wifi?"wifi":"wwan")];
LOGI(@"Network connectivity changed to type [%s]",(newConnectivity==wifi?"wifi":"wwan"));
}
lLinphoneMgr.connectivity=newConnectivity;
switch (lLinphoneMgr.tunnelMode) {
@ -1164,7 +1165,7 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach
zeroAddress.sin_family = AF_INET;
if (proxyReachability) {
[LinphoneLogger logc:LinphoneLoggerLog format:"Cancelling old network reachability"];
LOGI(@"Cancelling old network reachability");
SCNetworkReachabilityUnscheduleFromRunLoop(proxyReachability, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
CFRelease(proxyReachability);
proxyReachability = nil;
@ -1189,11 +1190,11 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach
proxyReachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)&zeroAddress);
if (!SCNetworkReachabilitySetCallback(proxyReachability, (SCNetworkReachabilityCallBack)networkReachabilityCallBack, ctx)){
[LinphoneLogger logc:LinphoneLoggerError format:"Cannot register reachability cb: %s", SCErrorString(SCError())];
LOGE(@"Cannot register reachability cb: %s", SCErrorString(SCError()));
return;
}
if(!SCNetworkReachabilityScheduleWithRunLoop(proxyReachability, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode)){
[LinphoneLogger logc:LinphoneLoggerError format:"Cannot register schedule reachability cb: %s", SCErrorString(SCError())];
LOGE(@"Cannot register schedule reachability cb: %s", SCErrorString(SCError()));
return;
}
@ -1221,7 +1222,7 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach
return [number intValue];
} else {
CTTelephonyNetworkInfo* info = [[CTTelephonyNetworkInfo alloc] init];
NSString* currentRadio = info.currentRadioAccessTechnology;
NSString* currentRadio = [info.currentRadioAccessTechnology autorelease];
if( [currentRadio isEqualToString:CTRadioAccessTechnologyEdge]){
return network_2g;
} else if ([currentRadio isEqualToString:CTRadioAccessTechnologyLTE]){
@ -1283,7 +1284,6 @@ static LinphoneCoreVTable linphonec_vtable = {
[_contactSipField release];
_contactSipField = [[self lpConfigStringForKey:@"contact_im_type_value" withDefault:@"SIP"] retain];
fastAddressBook = [[FastAddressBook alloc] init];
linphone_core_set_root_ca(theLinphoneCore, lRootCa);
@ -1343,7 +1343,7 @@ static LinphoneCoreVTable linphonec_vtable = {
NSString* path = [LinphoneManager bundleFile:@"nowebcamCIF.jpg"];
if (path) {
const char* imagePath = [path cStringUsingEncoding:[NSString defaultCStringEncoding]];
[LinphoneLogger logc:LinphoneLoggerLog format:"Using '%s' as source image for no webcam", imagePath];
LOGI(@"Using '%s' as source image for no webcam", imagePath);
linphone_core_set_static_picture(theLinphoneCore, imagePath);
}
@ -1366,12 +1366,14 @@ static LinphoneCoreVTable linphonec_vtable = {
PayloadType *pt=linphone_core_find_payload_type(theLinphoneCore,"SILK",24000,-1);
if (pt) {
linphone_core_enable_payload_type(theLinphoneCore,pt,FALSE);
[LinphoneLogger logc:LinphoneLoggerWarning format:"SILK/24000 and video disabled on old iPhone 3G"];
LOGW(@"SILK/24000 and video disabled on old iPhone 3G");
}
linphone_core_enable_video(theLinphoneCore, FALSE, FALSE);
}
// Query our in-app server when core is ready in order to retrieve InApp purchases
[_iapManager retrievePurchases];
[LinphoneLogger logc:LinphoneLoggerWarning format:"Linphone [%s] started on [%s]", linphone_core_get_version(), [[UIDevice currentDevice].model cStringUsingEncoding:[NSString defaultCStringEncoding]]];
LOGW(@"Linphone [%s] started on [%s]", linphone_core_get_version(), [[UIDevice currentDevice].model cStringUsingEncoding:[NSString defaultCStringEncoding]]);
// Post event
@ -1390,7 +1392,7 @@ static BOOL libStarted = FALSE;
- (void)startLinphoneCore {
if ( libStarted ) {
[LinphoneLogger logc:LinphoneLoggerError format:"Liblinphone is already initialized!"];
LOGE(@"Liblinphone is already initialized!");
return;
}
@ -1433,10 +1435,10 @@ static BOOL libStarted = FALSE;
- (void)createLinphoneCore {
if (theLinphoneCore != nil) {
[LinphoneLogger logc:LinphoneLoggerLog format:"linphonecore is already created"];
LOGI(@"linphonecore is already created");
return;
}
[LinphoneLogger logc:LinphoneLoggerLog format:"Create linphonecore"];
LOGI(@"Create linphonecore");
connectivity=none;
@ -1500,7 +1502,7 @@ static BOOL libStarted = FALSE;
[[NSNotificationCenter defaultCenter] removeObserver:self];
if (theLinphoneCore != nil) { //just in case application terminate before linphone core initialization
[LinphoneLogger logc:LinphoneLoggerLog format:"Destroy linphonecore"];
LOGI(@"Destroy linphonecore");
linphone_core_destroy(theLinphoneCore);
theLinphoneCore = nil;
ms_exit(); // Uninitialize mediastreamer2
@ -1600,11 +1602,11 @@ static int comp_call_state_paused (const LinphoneCall* call, const void* param)
- (void) startCallPausedLongRunningTask {
pausedCallBgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler: ^{
[LinphoneLogger log:LinphoneLoggerWarning format:@"Call cannot be paused any more, too late"];
LOGW(@"Call cannot be paused any more, too late");
[[UIApplication sharedApplication] endBackgroundTask:pausedCallBgTask];
}];
[LinphoneLogger log:LinphoneLoggerLog format:@"Long running task started, remaining [%g s] because at least one call is paused"
,[[UIApplication sharedApplication] backgroundTimeRemaining]];
LOGI(@"Long running task started, remaining [%g s] because at least one call is paused"
,[[UIApplication sharedApplication] backgroundTimeRemaining]);
}
- (BOOL)enterBackgroundMode {
LinphoneProxyConfig* proxyCfg;
@ -1625,13 +1627,13 @@ static int comp_call_state_paused (const LinphoneCall* call, const void* param)
//register keepalive
if ([[UIApplication sharedApplication] setKeepAliveTimeout:600/*(NSTimeInterval)linphone_proxy_config_get_expires(proxyCfg)*/
handler:^{
[LinphoneLogger logc:LinphoneLoggerWarning format:"keepalive handler"];
LOGW(@"keepalive handler");
if (mLastKeepAliveDate)
[mLastKeepAliveDate release];
mLastKeepAliveDate=[NSDate date];
[mLastKeepAliveDate retain];
if (theLinphoneCore == nil) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"It seems that Linphone BG mode was deactivated, just skipping"];
LOGW(@"It seems that Linphone BG mode was deactivated, just skipping");
return;
}
//kick up network cnx, just in case
@ -1641,9 +1643,9 @@ static int comp_call_state_paused (const LinphoneCall* call, const void* param)
]) {
[LinphoneLogger logc:LinphoneLoggerLog format:"keepalive handler succesfully registered"];
LOGI(@"keepalive handler succesfully registered");
} else {
[LinphoneLogger logc:LinphoneLoggerLog format:"keepalive handler cannot be registered"];
LOGI(@"keepalive handler cannot be registered");
}
shouldEnterBgMode=TRUE;
}
@ -1667,11 +1669,11 @@ static int comp_call_state_paused (const LinphoneCall* call, const void* param)
}
linphone_core_stop_dtmf_stream(theLinphoneCore);
[LinphoneLogger logc:LinphoneLoggerLog format:"Entering [%s] bg mode",shouldEnterBgMode?"normal":"lite"];
LOGI(@"Entering [%s] bg mode",shouldEnterBgMode?"normal":"lite");
if (!shouldEnterBgMode ) {
if([[LinphoneManager instance] lpConfigBoolForKey:@"pushnotification_preference"]) {
[LinphoneLogger logc:LinphoneLoggerLog format:"Keeping lc core to handle push"];
LOGI(@"Keeping lc core to handle push");
/*destroy voip socket if any and reset connectivity mode*/
connectivity=none;
linphone_core_set_network_reachable(theLinphoneCore, FALSE);
@ -1706,7 +1708,7 @@ static int comp_call_state_paused (const LinphoneCall* call, const void* param)
NSDate *current=[NSDate date];
if ([current timeIntervalSinceDate:mLastKeepAliveDate]>700){
NSString *datestr=[mLastKeepAliveDate description];
[LinphoneLogger logc:LinphoneLoggerWarning format:"keepalive handler was called for the last time at %@",datestr];
LOGW(@"keepalive handler was called for the last time at %@",datestr);
}
}
@ -1714,14 +1716,14 @@ static int comp_call_state_paused (const LinphoneCall* call, const void* param)
- (void)beginInterruption {
LinphoneCall* c = linphone_core_get_current_call(theLinphoneCore);
[LinphoneLogger logc:LinphoneLoggerLog format:"Sound interruption detected!"];
LOGI(@"Sound interruption detected!");
if (c && linphone_call_get_state(c) == LinphoneCallStreamsRunning) {
linphone_core_pause_call(theLinphoneCore, c);
}
}
- (void)endInterruption {
[LinphoneLogger logc:LinphoneLoggerLog format:"Sound interruption ended!"];
LOGI(@"Sound interruption ended!");
}
- (void)refreshRegisters{
@ -1775,7 +1777,7 @@ static void audioRouteChangeListenerCallback (
OSStatus lStatus = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &lNewRouteSize, &lNewRoute);
if (!lStatus && lNewRouteSize > 0) {
NSString *route = (NSString *) lNewRoute;
[LinphoneLogger logc:LinphoneLoggerLog format:"Current audio route is [%s]", [route cStringUsingEncoding:[NSString defaultCStringEncoding]]];
LOGI(@"Current audio route is [%s]", [route cStringUsingEncoding:[NSString defaultCStringEncoding]]);
speakerEnabled = [route isEqualToString: @"Speaker"] ||
[route isEqualToString: @"SpeakerAndMicrophone"];
@ -1837,7 +1839,7 @@ static void audioRouteChangeListenerCallback (
if([self lpConfigBoolForKey:@"edge_opt_preference"]) {
bool low_bandwidth = self.network == network_2g;
if(low_bandwidth) {
[LinphoneLogger log:LinphoneLoggerLog format:@"Low bandwidth mode"];
LOGI(@"Low bandwidth mode");
}
linphone_call_params_enable_low_bandwidth(lcallParams, low_bandwidth);
}
@ -1859,7 +1861,7 @@ static void audioRouteChangeListenerCallback (
CTCallCenter* callCenter = [[CTCallCenter alloc] init];
if ([callCenter currentCalls]!=nil) {
[LinphoneLogger logc:LinphoneLoggerError format:"GSM call in progress, cancelling outgoing SIP call request"];
LOGE(@"GSM call in progress, cancelling outgoing SIP call request");
UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Cannot make call",nil)
message:NSLocalizedString(@"Please terminate GSM call",nil)
delegate:nil
@ -1879,7 +1881,7 @@ static void audioRouteChangeListenerCallback (
if([self lpConfigBoolForKey:@"edge_opt_preference"]) {
bool low_bandwidth = self.network == network_2g;
if(low_bandwidth) {
[LinphoneLogger log:LinphoneLoggerLog format:@"Low bandwidth mode"];
LOGI(@"Low bandwidth mode");
}
linphone_call_params_enable_low_bandwidth(lcallParams, low_bandwidth);
}
@ -1933,9 +1935,10 @@ static void audioRouteChangeListenerCallback (
// We are NOT responsible for creating the AppData.
LinphoneCallAppData* data=(LinphoneCallAppData*)linphone_call_get_user_pointer(call);
if (data==nil)
[LinphoneLogger log:LinphoneLoggerError format:@"New call instanciated but app data was not set. Expect it to crash."];
LOGE(@"New call instanciated but app data was not set. Expect it to crash.");
/* will be used later to notify user if video was not activated because of the linphone core*/
data->videoRequested = linphone_call_params_video_enabled(lcallParams);
else
data->videoRequested = linphone_call_params_video_enabled(lcallParams);
}
linphone_call_params_destroy(lcallParams);
}
@ -2038,21 +2041,21 @@ static void audioRouteChangeListenerCallback (
if(override) {
[fileManager removeItemAtPath:dst error:&error];
if(error != nil) {
[LinphoneLogger log:LinphoneLoggerError format:@"Can't remove \"%@\": %@", dst, [error localizedDescription]];
LOGE(@"Can't remove \"%@\": %@", dst, [error localizedDescription]);
return FALSE;
}
} else {
[LinphoneLogger log:LinphoneLoggerWarning format:@"\"%@\" already exists", dst];
LOGW(@"\"%@\" already exists", dst);
return FALSE;
}
}
if ([fileManager fileExistsAtPath:src] == NO) {
[LinphoneLogger log:LinphoneLoggerError format:@"Can't find \"%@\": %@", src, [error localizedDescription]];
LOGE(@"Can't find \"%@\": %@", src, [error localizedDescription]);
return FALSE;
}
[fileManager copyItemAtPath:src toPath:dst error:&error];
if(error != nil) {
[LinphoneLogger log:LinphoneLoggerError format:@"Can't copy \"%@\" to \"%@\": %@", src, dst, [error localizedDescription]];
LOGE(@"Can't copy \"%@\" to \"%@\": %@", src, dst, [error localizedDescription]);
return FALSE;
}
return TRUE;
@ -2181,7 +2184,7 @@ static void audioRouteChangeListenerCallback (
-(void) removeCTCallCenterCb {
if (mCallCenter != nil) {
[LinphoneLogger log:LinphoneLoggerLog format:@"Removing CT call center listener [%p]",mCallCenter];
LOGI(@"Removing CT call center listener [%p]",mCallCenter);
mCallCenter.callEventHandler=NULL;
[mCallCenter release];
}
@ -2192,7 +2195,7 @@ static void audioRouteChangeListenerCallback (
[self removeCTCallCenterCb];
mCallCenter = [[CTCallCenter alloc] init];
[LinphoneLogger log:LinphoneLoggerLog format:@"Adding CT call center listener [%p]",mCallCenter];
LOGI(@"Adding CT call center listener [%p]",mCallCenter);
mCallCenter.callEventHandler = ^(CTCall* call) {
// post on main thread
[self performSelectorOnMainThread:@selector(handleGSMCallInteration:)
@ -2208,11 +2211,11 @@ static void audioRouteChangeListenerCallback (
LinphoneCall* call = linphone_core_get_current_call(theLinphoneCore);
if ([ct currentCalls]!=nil) {
if (call) {
[LinphoneLogger log:LinphoneLoggerLog format:@"Pausing SIP call because GSM call"];
LOGI(@"Pausing SIP call because GSM call");
linphone_core_pause_call(theLinphoneCore, call);
[self startCallPausedLongRunningTask];
} else if (linphone_core_is_in_conference(theLinphoneCore)) {
[LinphoneLogger log:LinphoneLoggerLog format:@"Leaving conference call because GSM call"];
LOGI(@"Leaving conference call because GSM call");
linphone_core_leave_conference(theLinphoneCore);
[self startCallPausedLongRunningTask];
}
@ -2258,5 +2261,7 @@ static void audioRouteChangeListenerCallback (
}
}
#pragma InApp Purchase
@end

View file

@ -25,7 +25,7 @@
@implementation UIBluetoothButton
#define check_auresult(au,method) \
if (au!=0) [LinphoneLogger logc:LinphoneLoggerError format:"UIBluetoothButton error for %s: ret=%ld",method,au]
if (au!=0) LOGE(@"UIBluetoothButton error for %s: ret=%ld",method,au)
- (void)onOn {
//redirect audio to bluetooth

View file

@ -44,7 +44,7 @@
- (void)update {
if(call == NULL) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update call cell: null call or data"];
LOGW(@"Cannot update call cell: null call or data");
return;
}
const LinphoneAddress* addr = linphone_call_get_remote_address(call);
@ -377,7 +377,7 @@
- (void)update {
if(data == nil || data->call == NULL) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update call cell: null call or data"];
LOGW(@"Cannot update call cell: null call or data");
return;
}
LinphoneCall *call = data->call;
@ -442,7 +442,7 @@
- (void)updateStats {
if(data == nil || data->call == NULL) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update call cell: null call or data"];
LOGW(@"Cannot update call cell: null call or data");
return;
}
LinphoneCall *call = data->call;
@ -500,7 +500,7 @@
- (void)updateDetailsView {
if(data == nil || data->call == NULL) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update call cell: null call or data"];
LOGW(@"Cannot update call cell: null call or data");
return;
}
if(data->view == UICallCellOtherView_Avatar && avatarView.isHidden) {

View file

@ -79,7 +79,7 @@
}
}
if (newCamId){
[LinphoneLogger logc:LinphoneLoggerLog format:"Switching from [%s] to [%s]", currentCamId, newCamId];
LOGI(@"Switching from [%s] to [%s]", currentCamId, newCamId);
linphone_core_set_video_device([LinphoneManager getLc], newCamId);
LinphoneCall *call = linphone_core_get_current_call([LinphoneManager getLc]);
if(call != NULL) {

View file

@ -4,16 +4,16 @@
*
* 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 Library 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
* 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 Library 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.
*/
@ -39,9 +39,9 @@
NSArray *arrayOfViews = [[NSBundle mainBundle] loadNibNamed:@"UIChatCell"
owner:self
options:nil];
if ([arrayOfViews count] >= 1) {
[self.contentView addSubview:[arrayOfViews objectAtIndex:0]];
}
[chatContentLabel setAdjustsFontSizeToFitWidth:TRUE]; // Auto shrink: IB lack!
@ -69,7 +69,7 @@
}
#pragma mark -
#pragma mark -
- (NSString *)accessibilityValue {
return [NSString stringWithFormat:@"%@ - %@ (%ld)", addressLabel.text, chatContentLabel.text, (long)[unreadMessageLabel.text integerValue]];
@ -80,7 +80,7 @@
NSString *displayName = nil;
UIImage *image = nil;
if(chatRoom == nil) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update chat cell: null chat"];
LOGW(@"Cannot update chat cell: null chat");
return;
}
const LinphoneAddress* linphoneAddress = linphone_chat_room_get_peer_address(chatRoom);
@ -90,13 +90,13 @@
char *tmp = linphone_address_as_string_uri_only(linphoneAddress);
NSString *normalizedSipAddress = [NSString stringWithUTF8String:tmp];
ms_free(tmp);
ABRecordRef contact = [[[LinphoneManager instance] fastAddressBook] getContact:normalizedSipAddress];
if(contact != nil) {
displayName = [FastAddressBook getContactDisplayName:contact];
image = [FastAddressBook getContactImage:contact thumbnail:true];
}
// Display name
if(displayName == nil) {
const char* username = linphone_address_get_username(linphoneAddress);
@ -156,7 +156,7 @@
if(editing) {
[deleteButton setAlpha:1.0f];
} else {
[deleteButton setAlpha:0.0f];
[deleteButton setAlpha:0.0f];
}
if(animated) {
[UIView commitAnimations];
@ -168,7 +168,7 @@
- (IBAction)onDeleteClick: (id) event {
if(chatRoom != NULL) {
UIView *view = [self superview];
UIView *view = [self superview];
// Find TableViewCell
while( view != nil && ![view isKindOfClass:[UITableView class]]) view = [view superview];
if(view != nil) {

View file

@ -4,18 +4,18 @@
*
* 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 Library 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
* 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 Library 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 "UIChatRoomCell.h"
#import "UILinphone.h"
@ -68,7 +68,7 @@ static UIFont *CELL_FONT = nil;
[self addSubview:innerView];
[deleteButton setAlpha:0.0f];
// shift message box, otherwise it will collide with the bubble
CGRect messageCoords = [messageText frame];
messageCoords.origin.x += 2;
@ -93,16 +93,16 @@ static UIFont *CELL_FONT = nil;
[downloadButton release];
[imageTapGestureRecognizer release];
[resendTapGestureRecognizer release];
[super dealloc];
}
#pragma mark -
#pragma mark -
- (void)setChatMessage:(LinphoneChatMessage *)message {
self->chat = message;
[self update];
}
+ (NSString*)decodeTextMessage:(const char*)text {
@ -119,7 +119,7 @@ static UIFont *CELL_FONT = nil;
- (void)update {
if(chat == nil) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update chat room cell: null chat"];
LOGW(@"Cannot update chat room cell: null chat");
return;
}
const char* url = linphone_chat_message_get_external_body_url(chat);
@ -155,9 +155,9 @@ static UIFont *CELL_FONT = nil;
}
});
} failureBlock:^(NSError *error) {
[LinphoneLogger log:LinphoneLoggerError format:@"Can't read image"];
LOGE(@"Can't read image");
}];
[messageImageView setHidden:FALSE];
[downloadButton setHidden:TRUE];
} else {
@ -182,10 +182,10 @@ static UIFont *CELL_FONT = nil;
[messageImageView setImage:nil];
[messageImageView setHidden:TRUE];
[downloadButton setHidden:TRUE];
}
// Date
NSDate* message_date = [NSDate dateWithTimeIntervalSince1970:linphone_chat_message_get_time(chat)];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
@ -220,13 +220,13 @@ static UIFont *CELL_FONT = nil;
[dateLabel setAttributedText:resend_text];
[resend_text release];
}
if( outgoing){
[messageText setAccessibilityLabel:@"Outgoing message"];
} else {
[messageText setAccessibilityLabel:@"Incoming message"];
}
}
- (void)setEditing:(BOOL)editing {
@ -241,7 +241,7 @@ static UIFont *CELL_FONT = nil;
if(editing) {
[deleteButton setAlpha:1.0f];
} else {
[deleteButton setAlpha:0.0f];
[deleteButton setAlpha:0.0f];
}
if(animated) {
[UIView commitAnimations];
@ -330,7 +330,7 @@ static UIFont *CELL_FONT = nil;
- (IBAction)onDeleteClick:(id)event {
if(chat != NULL) {
UIView *view = [self superview];
UIView *view = [self superview];
// Find TableViewCell
while(view != nil && ![view isKindOfClass:[UITableView class]]) view = [view superview];
if(view != nil) {

View file

@ -4,18 +4,18 @@
*
* 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 Library 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
* 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 Library 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 "UICompositeViewController.h"
@ -52,8 +52,8 @@
return [self.name compare:description.name] == NSOrderedSame;
}
- (id)init:(NSString *)aname content:(NSString *)acontent stateBar:(NSString*)astateBar
stateBarEnabled:(BOOL) astateBarEnabled
- (id)init:(NSString *)aname content:(NSString *)acontent stateBar:(NSString*)astateBar
stateBarEnabled:(BOOL) astateBarEnabled
tabBar:(NSString*)atabBar
tabBarEnabled:(BOOL) atabBarEnabled
fullscreen:(BOOL) afullscreen
@ -69,7 +69,7 @@
self.landscapeMode = alandscapeMode;
self.portraitMode = aportraitMode;
self.darkBackground = false;
return self;
}
@ -131,22 +131,22 @@
[self initUICompositeViewController];
}
return self;
}
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self.stateBarViewController release];
[self.tabBarViewController release];
[self.contentViewController release];
[contentView release];
[stateBarView release];
[tabBarView release];
[viewControllerCache release];
[viewTransition release];
[currentViewDescription release];
[super dealloc];
}
@ -190,7 +190,7 @@
}
- (void)viewDidLoad {
/* Force landscape view to match portrait view, because portrait view inherits
/* Force landscape view to match portrait view, because portrait view inherits
the device screen size at load */
[self updateViewsFramesAccordingToLaunchOrientation];
[super viewDidLoad];
@ -201,7 +201,7 @@
[self.contentViewController viewWillAppear:animated];
[self.tabBarViewController viewWillAppear:animated];
[self.stateBarViewController viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(orientationDidChange:)
name:UIDeviceOrientationDidChangeNotification
@ -221,9 +221,9 @@
[self.contentViewController viewWillDisappear:animated];
[self.tabBarViewController viewWillDisappear:animated];
[self.stateBarViewController viewWillDisappear:animated];
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIDeviceOrientationDidChangeNotification
object:nil];
@ -340,7 +340,7 @@
}
}
if(remove) {
[LinphoneLogger log:LinphoneLoggerLog format:@"Free cached view: %@", key];
LOGI(@"Free cached view: %@", key);
[viewControllerCache removeObjectForKey:key];
}
}
@ -420,7 +420,7 @@
if(description != nil) {
oldViewDescription = currentViewDescription;
currentViewDescription = [description copy];
// Animate only with a previous screen
if(oldViewDescription != nil && viewTransition != nil) {
[contentView.layer removeAnimationForKey:@"transition"];
@ -454,7 +454,7 @@
self.stateBarViewController = newStateBarViewController;
self.contentViewController = newContentViewController;
self.tabBarViewController = newTabBarViewController;
// Update rotation
UIInterfaceOrientation correctOrientation = [self getCorrectInterfaceOrientation:(UIDeviceOrientation)[UIApplication sharedApplication].statusBarOrientation];
if(currentOrientation != correctOrientation) {
@ -487,11 +487,11 @@
} else {
oldViewDescription = (currentViewDescription != nil)? [currentViewDescription copy]: nil;
}
if(currentViewDescription == nil) {
return;
}
if(tabBar != nil) {
if(currentViewDescription.tabBarEnabled != [tabBar boolValue]) {
currentViewDescription.tabBarEnabled = [tabBar boolValue];
@ -499,7 +499,7 @@
tabBar = nil; // No change = No Update
}
}
if(stateBar != nil) {
if(currentViewDescription.stateBarEnabled != [stateBar boolValue]) {
currentViewDescription.stateBarEnabled = [stateBar boolValue];
@ -507,7 +507,7 @@
stateBar = nil; // No change = No Update
}
}
if(fullscreen != nil) {
if(currentViewDescription.fullscreen != [fullscreen boolValue]) {
currentViewDescription.fullscreen = [fullscreen boolValue];
@ -518,23 +518,23 @@
} else {
[[UIApplication sharedApplication] setStatusBarHidden:currentViewDescription.fullscreen withAnimation:UIStatusBarAnimationNone];
}
// Start animation
if(tabBar != nil || stateBar != nil || fullscreen != nil) {
[UIView beginAnimations:@"resize" context:nil];
[UIView setAnimationDuration:0.35];
[UIView setAnimationBeginsFromCurrentState:TRUE];
}
CGRect contentFrame = contentView.frame;
CGRect viewFrame = [self.view frame];
// Resize StateBar
CGRect stateBarFrame = stateBarView.frame;
int origin = IPHONE_STATUSBAR_HEIGHT;
if(currentViewDescription.fullscreen)
origin = 0;
if(self.stateBarViewController != nil && currentViewDescription.stateBarEnabled) {
contentFrame.origin.y = origin + stateBarFrame.size.height;
stateBarFrame.origin.y = origin;
@ -542,7 +542,7 @@
contentFrame.origin.y = origin;
stateBarFrame.origin.y = origin - stateBarFrame.size.height;
}
// Resize TabBar
CGRect tabFrame = tabBarView.frame;
if(self.tabBarViewController != nil && currentViewDescription.tabBarEnabled) {
@ -567,12 +567,12 @@
contentFrame.size.height = viewFrame.size.height - contentFrame.origin.y;
tabFrame.origin.y = viewFrame.size.height;
}
if(currentViewDescription.fullscreen) {
contentFrame.origin.y = origin;
contentFrame.size.height = viewFrame.size.height - contentFrame.origin.y;
}
// Set frames
[contentView setFrame: contentFrame];
[self.contentViewController.view setFrame: [contentView bounds]];
@ -584,12 +584,12 @@
frame = [self.stateBarViewController.view frame];
frame.size.width = [stateBarView bounds].size.width;
[self.stateBarViewController.view setFrame:frame];
// Commit animation
if(tabBar != nil || stateBar != nil || fullscreen != nil) {
[UIView commitAnimations];
}
// Change view
if(description != nil) {
[UICompositeViewController addSubView: self.contentViewController view:contentView];
@ -600,7 +600,7 @@
[UICompositeViewController addSubView: self.stateBarViewController view:stateBarView];
}
}
// Dealloc old view description
if(oldViewDescription != nil) {
[oldViewDescription release];

View file

@ -4,18 +4,18 @@
*
* 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 Library 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
* 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 Library 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 "UIContactCell.h"
#import "Utils.h"
@ -36,7 +36,7 @@
NSArray *arrayOfViews = [[NSBundle mainBundle] loadNibNamed:@"UIContactCell"
owner:self
options:nil];
if ([arrayOfViews count] >= 1) {
[self.contentView addSubview:[arrayOfViews objectAtIndex:0] ];
}
@ -48,7 +48,7 @@
[firstNameLabel release];
[lastNameLabel release];
[avatarImage release];
[super dealloc];
}
@ -60,7 +60,7 @@
[self update];
}
#pragma mark -
#pragma mark -
- (void)touchUp:(id) sender {
[self setHighlighted:true animated:true];
@ -76,10 +76,10 @@
- (void)update {
if(contact == NULL) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update contact cell: null contact"];
LOGW(@"Cannot update contact cell: null contact");
return;
}
CFStringRef lFirstName = ABRecordCopyValue(contact, kABPersonFirstNameProperty);
CFStringRef lLocalizedFirstName = (lFirstName != nil)?ABAddressBookCopyLocalizedLabel(lFirstName):nil;
CFStringRef lLastName = ABRecordCopyValue(contact, kABPersonLastNameProperty);
@ -92,17 +92,17 @@
}
else
[firstNameLabel setText: @""];
if(lLocalizedLastName != nil){
[lastNameLabel setText: (NSString *)lLocalizedLastName];
}
else
[lastNameLabel setText: @""];
if(lLocalizedFirstName == nil && lLocalizedLastName == nil) {
[firstNameLabel setText: (NSString *)lLocalizedOrganization];
}
if(lLocalizedOrganization != nil)
CFRelease(lLocalizedOrganization);
if(lOrganization != nil)
@ -124,7 +124,7 @@
//
CGRect firstNameFrame = [firstNameLabel frame];
CGRect lastNameFrame = [lastNameLabel frame];
// Compute firstName size
CGSize firstNameSize = [[firstNameLabel text] sizeWithFont:[firstNameLabel font]];
CGSize lastNameSize = [[lastNameLabel text] sizeWithFont:[lastNameLabel font]];
@ -134,10 +134,10 @@
firstNameSize.width *= limit/sum;
lastNameSize.width *= limit/sum;
}
firstNameFrame.size.width = firstNameSize.width;
lastNameFrame.size.width = lastNameSize.width;
// Compute lastName size & position
lastNameFrame.origin.x = firstNameFrame.origin.x + firstNameFrame.size.width;
if(firstNameFrame.size.width)
@ -158,7 +158,7 @@
[firstNameLabel setTextColor:[UIColor whiteColor]];
} else {
[lastNameLabel setTextColor:[UIColor blackColor]];
[firstNameLabel setTextColor:[UIColor blackColor]];
[firstNameLabel setTextColor:[UIColor blackColor]];
}
}

View file

@ -4,18 +4,18 @@
*
* 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 Library 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
* 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 Library 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 "UIContactDetailsHeader.h"
#import "Utils.h"
@ -78,9 +78,9 @@
[normalView release];
[editView release];
[tableView release];
[propertyList release];
[super dealloc];
}
@ -119,10 +119,10 @@
- (void)update {
if(contact == NULL) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update contact details header: null contact"];
LOGW(@"Cannot update contact details header: null contact");
return;
}
// Avatar image
{
UIImage *image = [FastAddressBook getContactImage:contact thumbnail:false];
@ -131,12 +131,12 @@
}
[avatarImage setImage:image];
}
// Contact label
{
[addressLabel setText:[FastAddressBook getContactDisplayName:contact]];
}
[tableView reloadData];
}
@ -154,7 +154,7 @@
if(!editing) {
[LinphoneUtils findAndResignFirstResponder:[self tableView]];
[self update];
}
}
if(animated) {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.3];
@ -164,7 +164,7 @@
[normalView setAlpha:0.0f];
} else {
[editView setAlpha:0.0f];
[normalView setAlpha:1.0f];
[normalView setAlpha:1.0f];
}
if(animated) {
[UIView commitAnimations];
@ -203,7 +203,7 @@
- (UITableViewCell *)tableView:(UITableView *)atableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *kCellId = @"ContactDetailsHeaderCell";
UIEditableTableViewCell *cell = [atableView dequeueReusableCellWithIdentifier:kCellId];
if (cell == nil) {
if (cell == nil) {
cell = [[[UIEditableTableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:kCellId] autorelease];
[cell.detailTextField setAutocapitalizationType:UITextAutocapitalizationTypeWords];
[cell.detailTextField setAutocorrectionType:UITextAutocorrectionTypeNo];
@ -236,7 +236,7 @@
}
}
[cell.detailTextField setDelegate:self];
return cell;
}
@ -257,16 +257,16 @@
}
if(controller != nil) {
controller.sourceType = type;
// Displays a control that allows the user to choose picture or
// movie capture, if both are available:
controller.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeImage];
// Hides the controls for moving & scaling pictures, or for
// trimming movies. To instead show the controls, use YES.
controller.allowsEditing = NO;
controller.imagePickerDelegate = self;
if([LinphoneManager runningOnIpad]) {
[controller.popoverController presentPopoverFromRect:[avatarImage frame] inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:FALSE];
}
@ -287,7 +287,7 @@
[sheet addDestructiveButtonWithTitle:NSLocalizedString(@"Remove", nil) block:^(){
NSError* error = NULL;
if(!ABPersonRemoveImageData(contact, (CFErrorRef*)error)) {
[LinphoneLogger log:LinphoneLoggerLog format:@"Can't remove entry: %@", [error localizedDescription]];
LOGI(@"Can't remove entry: %@", [error localizedDescription]);
}
[self update];
}];
@ -316,7 +316,7 @@
FastAddressBook* fab = [LinphoneManager instance].fastAddressBook;
NSError* error = NULL;
if(!ABPersonRemoveImageData(contact, (CFErrorRef*)error)) {
[LinphoneLogger log:LinphoneLoggerLog format:@"Can't remove entry: %@", [error localizedDescription]];
LOGI(@"Can't remove entry: %@", [error localizedDescription]);
}
NSData *dataRef = UIImageJPEGRepresentation(image, 0.9f);
CFDataRef cfdata = CFDataCreate(NULL,[dataRef bytes], [dataRef length]);
@ -324,13 +324,13 @@
[fab saveAddressBook];
if(!ABPersonSetImageData(contact, cfdata, (CFErrorRef*)error)) {
[LinphoneLogger log:LinphoneLoggerLog format:@"Can't add entry: %@", [error localizedDescription]];
LOGI(@"Can't add entry: %@", [error localizedDescription]);
} else {
[fab saveAddressBook];
}
CFRelease(cfdata);
[self update];
}
@ -345,7 +345,7 @@
#pragma mark - UITextFieldDelegate Functions
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
[textField resignFirstResponder];
return YES;
}
@ -358,10 +358,10 @@
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
UIView *view = [textField superview];
UIView *view = [textField superview];
// Find TableViewCell
while(view != nil && ![view isKindOfClass:[UIEditableTableViewCell class]]) view = [view superview];
if(view != nil) {
UIEditableTableViewCell *cell = (UIEditableTableViewCell*)view;
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
@ -370,10 +370,10 @@
NSError* error = NULL;
ABRecordSetValue(contact, property, [textField text], (CFErrorRef*)&error);
if (error != NULL) {
[LinphoneLogger log:LinphoneLoggerError format:@"Error when saving property %i in contact %p: Fail(%@)", property, contact, [error localizedDescription]];
}
LOGE(@"Error when saving property %i in contact %p: Fail(%@)", property, contact, [error localizedDescription]);
}
} else {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Not valid UIEditableTableViewCell"];
LOGW(@"Not valid UIEditableTableViewCell");
}
if(contactDetailsDelegate != nil) {
//add a mini delay to have the text updated BEFORE notifying the selector

View file

@ -4,18 +4,18 @@
*
* 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 Library 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
* 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 Library 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 "UIHistoryCell.h"
#import "LinphoneManager.h"
@ -37,11 +37,11 @@
NSArray *arrayOfViews = [[NSBundle mainBundle] loadNibNamed:@"UIHistoryCell"
owner:self
options:nil];
if ([arrayOfViews count] >= 1) {
[self.contentView addSubview:[arrayOfViews objectAtIndex:0]];
}
self->callLog = NULL;
}
return self;
@ -52,7 +52,7 @@
[deleteButton release];
[addressLabel release];
[imageView release];
[super dealloc];
}
@ -79,7 +79,7 @@
- (IBAction)onDelete:(id)event {
if(callLog != NULL) {
UIView *view = [self superview];
UIView *view = [self superview];
// Find TableViewCell
while(view != nil && ![view isKindOfClass:[UITableView class]]) view = [view superview];
if(view != nil) {
@ -91,7 +91,7 @@
}
#pragma mark -
#pragma mark -
- (NSString *)accessibilityValue {
// TODO: localize?
@ -108,12 +108,12 @@
- (void)update {
if(callLog == NULL) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update history cell: null callLog"];
LOGW(@"Cannot update history cell: null callLog");
return;
}
// Set up the cell...
LinphoneAddress* addr;
LinphoneAddress* addr;
UIImage *image;
if (linphone_call_log_get_dir(callLog) == LinphoneCallIncoming) {
if (linphone_call_log_get_status(callLog) != LinphoneCallMissed) {
@ -126,11 +126,11 @@
image = [UIImage imageNamed:@"call_status_outgoing.png"];
addr = linphone_call_log_get_to(callLog);
}
NSString* address = nil;
if(addr != NULL) {
BOOL useLinphoneAddress = true;
// contact name
// contact name
char* lAddress = linphone_address_as_string_uri_only(addr);
if(lAddress) {
NSString *normalizedSipAddress = [FastAddressBook normalizeSipURI:[NSString stringWithUTF8String:lAddress]];
@ -144,9 +144,9 @@
if(useLinphoneAddress) {
const char* lDisplayName = linphone_address_get_display_name(addr);
const char* lUserName = linphone_address_get_username(addr);
if (lDisplayName)
if (lDisplayName)
address = [NSString stringWithUTF8String:lDisplayName];
else if(lUserName)
else if(lUserName)
address = [NSString stringWithUTF8String:lUserName];
}
}
@ -169,10 +169,10 @@
}
if(editing) {
[deleteButton setAlpha:1.0f];
[detailsButton setAlpha:0.0f];
[detailsButton setAlpha:0.0f];
} else {
[detailsButton setAlpha:1.0f];
[deleteButton setAlpha:0.0f];
[deleteButton setAlpha:0.0f];
}
if(animated) {
[UIView commitAnimations];

View file

@ -28,12 +28,12 @@
- (UIColor *)lumColor:(float)mult {
float hsbH, hsbS, hsbB;
float rgbaR, rgbaG, rgbaB, rgbaA;
// Get RGB
CGColorRef cgColor = [self CGColor];
CGColorSpaceRef cgColorSpace = CGColorGetColorSpace(cgColor);
if(CGColorSpaceGetModel(cgColorSpace) != kCGColorSpaceModelRGB) {
[LinphoneLogger log:LinphoneLoggerWarning format:@"Can't convert not RGB color"];
LOGW(@"Can't convert not RGB color");
return self;
} else {
const CGFloat *colors = CGColorGetComponents(cgColor);
@ -42,26 +42,26 @@
rgbaB = colors[2];
rgbaA = CGColorGetAlpha(cgColor);
}
RGB2HSL(rgbaR, rgbaG, rgbaB, &hsbH, &hsbS, &hsbB);
hsbB = MIN(MAX(hsbB * mult, 0.0), 1.0);
HSL2RGB(hsbH, hsbS, hsbB, &rgbaR, &rgbaG, &rgbaB);
return [UIColor colorWithRed:rgbaR green:rgbaG blue:rgbaB alpha:rgbaA];
}
- (UIColor *)adjustHue:(float)hm saturation:(float)sm brightness:(float)bm alpha:(float)am {
float hsbH, hsbS, hsbB;
float rgbaR, rgbaG, rgbaB, rgbaA;
// Get RGB
CGColorRef cgColor = [self CGColor];
CGColorSpaceRef cgColorSpace = CGColorGetColorSpace(cgColor);
if(CGColorSpaceGetModel(cgColorSpace) != kCGColorSpaceModelRGB) {
[LinphoneLogger log:LinphoneLoggerWarning format:@"Can't convert not RGB color"];
LOGW(@"Can't convert not RGB color");
return self;
} else {
const CGFloat *colors = CGColorGetComponents(cgColor);
@ -70,16 +70,16 @@
rgbaB = colors[2];
rgbaA = CGColorGetAlpha(cgColor);
}
RGB2HSL(rgbaR, rgbaG, rgbaB, &hsbH, &hsbS, &hsbB);
hsbH = MIN(MAX(hsbH + hm, 0.0), 1.0);
hsbS = MIN(MAX(hsbS + sm, 0.0), 1.0);
hsbB = MIN(MAX(hsbB + bm, 0.0), 1.0);
rgbaA = MIN(MAX(rgbaA + am, 0.0), 1.0);
HSL2RGB(hsbH, hsbS, hsbB, &rgbaR, &rgbaG, &rgbaB);
return [UIColor colorWithRed:rgbaR green:rgbaG blue:rgbaB alpha:rgbaA];
}
@ -114,12 +114,12 @@
kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Little);
CGColorSpaceRelease(colorSpace);
if (!context) return nil;
CGRect rect = (CGRect){CGPointZero,{CGImageGetWidth(imageRef), CGImageGetHeight(imageRef)}};
CGContextDrawImage(context, rect, imageRef);
CGImageRef decompressedImageRef = CGBitmapContextCreateImage(context);
CGContextRelease(context);
UIImage *decompressedImage = [[UIImage alloc] initWithCGImage:decompressedImageRef scale:image.scale orientation:image.imageOrientation];
CGImageRelease(decompressedImageRef);
return [decompressedImage autorelease];

View file

@ -4,18 +4,18 @@
*
* 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
* 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 "UIPauseButton.h"
#import "LinphoneManager.h"
@ -46,7 +46,7 @@
[self initUIPauseButton];
}
return self;
}
}
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
@ -68,7 +68,7 @@
+ (int)notInConferenceCallCount: (LinphoneCore*) lc {
int count = 0;
const MSList* calls = linphone_core_get_calls(lc);
while (calls != 0) {
if (![UIPauseButton isInConference: (LinphoneCall*)calls->data]) {
count++;
@ -88,7 +88,7 @@
}
#pragma mark -
#pragma mark -
- (void)setType:(UIPauseButtonType) atype call:(LinphoneCall*)acall {
type = atype;
@ -105,14 +105,14 @@
if (call != nil) {
linphone_core_pause_call([LinphoneManager getLc], call);
} else {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot toggle pause buttton, because no current call"];
LOGW(@"Cannot toggle pause buttton, because no current call");
}
break;
}
case UIPauseButtonType_Conference:
{
linphone_core_leave_conference([LinphoneManager getLc]);
// Fake event
[[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneCallUpdate object:self];
break;
@ -123,7 +123,7 @@
if (currentCall != nil) {
linphone_core_pause_call([LinphoneManager getLc], currentCall);
} else {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot toggle pause buttton, because no current call"];
LOGW(@"Cannot toggle pause buttton, because no current call");
}
break;
}
@ -137,7 +137,7 @@
if (call != nil) {
linphone_core_resume_call([LinphoneManager getLc], call);
} else {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot toggle pause buttton, because no current call"];
LOGW(@"Cannot toggle pause buttton, because no current call");
}
break;
}
@ -154,7 +154,7 @@
if (currentCall != nil) {
linphone_core_resume_call([LinphoneManager getLc], currentCall);
} else {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot toggle pause buttton, because no current call"];
LOGW(@"Cannot toggle pause buttton, because no current call");
}
break;
}

View file

@ -44,7 +44,7 @@ static void audioRouteChangeListenerCallback (
AudioSessionInitialize(NULL, NULL, NULL, NULL);
OSStatus lStatus = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, audioRouteChangeListenerCallback, self);
if (lStatus) {
[LinphoneLogger logc:LinphoneLoggerError format:"cannot register route change handler [%ld]",lStatus];
LOGE(@"cannot register route change handler [%ld]",lStatus);
}
}
@ -75,7 +75,7 @@ static void audioRouteChangeListenerCallback (
- (void)dealloc {
OSStatus lStatus = AudioSessionRemovePropertyListenerWithUserData(kAudioSessionProperty_AudioRouteChange, audioRouteChangeListenerCallback, self);
if (lStatus) {
[LinphoneLogger logc:LinphoneLoggerError format:"cannot un register route change handler [%ld]", lStatus];
LOGE(@"cannot un register route change handler [%ld]", lStatus);
}
[super dealloc];
}

View file

@ -167,13 +167,13 @@ int messagesUnreadCount;
}
const char* body = linphone_content_get_buffer(content);
if ((body = strstr(body, "voice-message: ")) == NULL) {
[LinphoneLogger log:LinphoneLoggerWarning format:@"Received new NOTIFY from voice mail but could not find 'voice-message' in BODY. Ignoring it."];
LOGW(@"Received new NOTIFY from voice mail but could not find 'voice-message' in BODY. Ignoring it.");
return;
}
sscanf(body, "voice-message: %d", &messagesUnreadCount);
[LinphoneLogger log:LinphoneLoggerLog format:@"Received new NOTIFY from voice mail: there is/are now %d message(s) unread", messagesUnreadCount];
LOGI(@"Received new NOTIFY from voice mail: there is/are now %d message(s) unread", messagesUnreadCount);
// save in lpconfig for future
lp_config_set_int(linphone_core_get_config([LinphoneManager getLc]), "app", "voice_mail_messages_count", messagesUnreadCount);

View file

@ -72,7 +72,7 @@
linphone_core_update_call(lc, call, call_params);
linphone_call_params_destroy(call_params);
} else {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot toggle video button, because no current call"];
LOGW(@"Cannot toggle video button, because no current call");
}
}
@ -92,7 +92,7 @@
linphone_core_update_call(lc, call, call_params);
linphone_call_params_destroy(call_params);
} else {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot toggle video button, because no current call"];
LOGW(@"Cannot toggle video button, because no current call");
}
}

View file

@ -4,22 +4,23 @@
*
* 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
* 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 <QuartzCore/QuartzCore.h>
#import <AudioToolbox/AudioServices.h>
#import "InAppProductsViewController.h"
#import "LinphoneAppDelegate.h"
#import "PhoneMainView.h"
#import "Utils.h"
@ -144,7 +145,7 @@ static RootViewManager* rootViewManagerInstance = nil;
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[mainViewController release];
[inhibitedEvents release];
@ -168,16 +169,16 @@ static RootViewManager* rootViewManagerInstance = nil;
[super viewWillAppear:animated];
// Set observers
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(callUpdate:)
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(callUpdate:)
name:kLinphoneCallUpdate
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(registrationUpdate:)
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(registrationUpdate:)
name:kLinphoneRegistrationUpdate
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(textReceived:)
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(textReceived:)
name:kLinphoneTextReceived
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
@ -186,7 +187,7 @@ static RootViewManager* rootViewManagerInstance = nil;
object:nil];
[[UIDevice currentDevice] setBatteryMonitoringEnabled:YES];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(batteryLevelChanged:)
selector:@selector(batteryLevelChanged:)
name:UIDeviceBatteryLevelDidChangeNotification
object:nil];
@ -196,10 +197,10 @@ static RootViewManager* rootViewManagerInstance = nil;
[super viewWillDisappear:animated];
// Remove observers
[[NSNotificationCenter defaultCenter] removeObserver:self
[[NSNotificationCenter defaultCenter] removeObserver:self
name:kLinphoneCallUpdate
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
[[NSNotificationCenter defaultCenter] removeObserver:self
name:kLinphoneRegistrationUpdate
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
@ -209,10 +210,10 @@ static RootViewManager* rootViewManagerInstance = nil;
name:kLinphoneConfiguringStateUpdate
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIDeviceBatteryLevelDidChangeNotification
name:UIDeviceBatteryLevelDidChangeNotification
object:nil];
[[UIDevice currentDevice] setBatteryMonitoringEnabled:NO];
}
-(void)viewDidAppear:(BOOL)animated {
@ -269,7 +270,7 @@ static RootViewManager* rootViewManagerInstance = nil;
#pragma mark - Event Functions
- (void)textReceived:(NSNotification*)notif {
- (void)textReceived:(NSNotification*)notif {
LinphoneAddress* from = [[notif.userInfo objectForKey:@"from_address"] pointerValue];
NSString* callID = [notif.userInfo objectForKey:@"call-id"];
if(from != nil) {
@ -315,22 +316,22 @@ static RootViewManager* rootViewManagerInstance = nil;
LinphoneCall *call = [[notif.userInfo objectForKey: @"call"] pointerValue];
LinphoneCallState state = [[notif.userInfo objectForKey: @"state"] intValue];
NSString *message = [notif.userInfo objectForKey: @"message"];
bool canHideInCallView = (linphone_core_get_calls([LinphoneManager getLc]) == NULL);
// Don't handle call state during incoming call view
if([[self currentView] equal:[IncomingCallViewController compositeViewDescription]] && state != LinphoneCallError && state != LinphoneCallEnd) {
return;
}
switch (state) {
case LinphoneCallIncomingReceived:
switch (state) {
case LinphoneCallIncomingReceived:
case LinphoneCallIncomingEarlyMedia:
{
[self displayIncomingCall:call];
break;
}
case LinphoneCallOutgoingInit:
case LinphoneCallOutgoingInit:
case LinphoneCallPausedByRemote:
case LinphoneCallConnected:
case LinphoneCallStreamsRunning:
@ -342,7 +343,7 @@ static RootViewManager* rootViewManagerInstance = nil;
{
const LinphoneCallParams* current = linphone_call_get_current_params(call);
const LinphoneCallParams* remote = linphone_call_get_remote_params(call);
if (linphone_call_params_video_enabled(current) && !linphone_call_params_video_enabled(remote)) {
[self changeCurrentView:[InCallViewController compositeViewDescription]];
}
@ -352,7 +353,7 @@ static RootViewManager* rootViewManagerInstance = nil;
{
[self displayCallError:call message: message];
}
case LinphoneCallEnd:
case LinphoneCallEnd:
{
if (canHideInCallView) {
// Go to dialer view
@ -373,7 +374,7 @@ static RootViewManager* rootViewManagerInstance = nil;
}
#pragma mark -
#pragma mark -
- (void)orientationUpdate:(UIInterfaceOrientation)orientation {
int oldLinphoneOrientation = linphone_core_get_device_rotation([LinphoneManager getLc]);
@ -403,7 +404,6 @@ static RootViewManager* rootViewManagerInstance = nil;
}
}
}
- (void)startUp {
LinphoneCore* core = nil;
@try {
@ -450,7 +450,7 @@ static RootViewManager* rootViewManagerInstance = nil;
[trans setDuration:0.35];
[trans setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[trans setSubtype:transition];
return trans;
}
@ -462,13 +462,13 @@ static RootViewManager* rootViewManagerInstance = nil;
[trans setDuration:0.35];
[trans setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[trans setSubtype:transition];
return trans;
}
+ (CATransition*)getTransition:(UICompositeViewDescription *)old new:(UICompositeViewDescription *)new {
bool left = false;
if([old equal:[ChatViewController compositeViewDescription]]) {
if([new equal:[ContactsViewController compositeViewDescription]] ||
[new equal:[DialerViewController compositeViewDescription]] ||
@ -491,7 +491,7 @@ static RootViewManager* rootViewManagerInstance = nil;
if([new equal:[HistoryViewController compositeViewDescription]]) {
left = true;
}
}
}
if(left) {
return [PhoneMainView getBackwardTransition];
@ -557,7 +557,7 @@ static RootViewManager* rootViewManagerInstance = nil;
}
- (UIViewController*)_changeCurrentView:(UICompositeViewDescription*)view transition:(CATransition*)transition force:(BOOL)force {
[LinphoneLogger logc:LinphoneLoggerLog format:"PhoneMainView: Change current view to %@", [view name]];
LOGI(@"PhoneMainView: Change current view to %@", [view name]);
PhoneMainView* vc = [[RootViewManager instance] setViewControllerForDescription:view];
@ -575,10 +575,10 @@ static RootViewManager* rootViewManagerInstance = nil;
}
//[[RootViewManager instance] setViewControllerForDescription:view];
NSDictionary* mdict = [NSMutableDictionary dictionaryWithObject:vc->currentView forKey:@"view"];
[[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneMainViewChange object:self userInfo:mdict];
return [vc->mainViewController getCurrentViewController];
}
@ -600,13 +600,13 @@ static RootViewManager* rootViewManagerInstance = nil;
}
- (UIViewController*)popCurrentView {
[LinphoneLogger logc:LinphoneLoggerLog format:"PhoneMainView: Pop view"];
LOGI(@"PhoneMainView: Pop view");
NSMutableArray* viewStack = [RootViewManager instance].viewDescriptionStack;
if([viewStack count] > 1) {
[viewStack removeLastObject];
[self _changeCurrentView:[viewStack lastObject] transition:[PhoneMainView getBackwardTransition] force:TRUE];
return [mainViewController getCurrentViewController];
}
}
return nil;
}
@ -615,16 +615,16 @@ static RootViewManager* rootViewManagerInstance = nil;
NSString* lUserName = lUserNameChars?[[[NSString alloc] initWithUTF8String:lUserNameChars] autorelease]:NSLocalizedString(@"Unknown",nil);
NSString* lMessage;
NSString* lTitle;
//get default proxy
LinphoneProxyConfig* proxyCfg;
LinphoneProxyConfig* proxyCfg;
linphone_core_get_default_proxy([LinphoneManager getLc],&proxyCfg);
if (proxyCfg == nil) {
lMessage = NSLocalizedString(@"Please make sure your device is connected to the internet and double check your SIP account configuration in the settings.", nil);
} else {
lMessage = [NSString stringWithFormat : NSLocalizedString(@"Cannot call %@", nil), lUserName];
}
if (linphone_call_get_reason(call) == LinphoneReasonNotFound) {
lMessage = [NSString stringWithFormat : NSLocalizedString(@"'%@' not registered", nil), lUserName];
} else {
@ -634,9 +634,9 @@ static RootViewManager* rootViewManagerInstance = nil;
}
lTitle = NSLocalizedString(@"Call failed",nil);
UIAlertView* error = [[UIAlertView alloc] initWithTitle:lTitle
message:lMessage
delegate:nil
cancelButtonTitle:NSLocalizedString(@"Dismiss",nil)
message:lMessage
delegate:nil
cancelButtonTitle:NSLocalizedString(@"Dismiss",nil)
otherButtonTitles:nil];
[error show];
[error release];
@ -702,15 +702,15 @@ static RootViewManager* rootViewManagerInstance = nil;
- (void)batteryLevelChanged:(NSNotification*)notif {
float level = [UIDevice currentDevice].batteryLevel;
UIDeviceBatteryState state = [UIDevice currentDevice].batteryState;
[LinphoneLogger log:LinphoneLoggerDebug format:@"Battery state:%d level:%.2f", state, level];
LOGD(@"Battery state:%d level:%.2f", state, level);
LinphoneCall* call = linphone_core_get_current_call([LinphoneManager getLc]);
if (call && linphone_call_params_video_enabled(linphone_call_get_current_params(call))) {
LinphoneCallAppData* callData = (LinphoneCallAppData*) linphone_call_get_user_pointer(call);
if(callData != nil) {
if (state == UIDeviceBatteryStateUnplugged) {
if (level <= 0.2f && !callData->batteryWarningShown) {
[LinphoneLogger log:LinphoneLoggerLog format:@"Battery warning"];
LOGI(@"Battery warning");
DTActionSheet *sheet = [[[DTActionSheet alloc] initWithTitle:NSLocalizedString(@"Battery is running low. Stop video ?",nil)] autorelease];
[sheet addCancelButtonWithTitle:NSLocalizedString(@"Continue video", nil) block:nil];
[sheet addDestructiveButtonWithTitle:NSLocalizedString(@"Stop video", nil) block:^() {
@ -744,4 +744,4 @@ static RootViewManager* rootViewManagerInstance = nil;
linphone_core_terminate_call([LinphoneManager getLc], call);
}
@end
@end

View file

@ -4,24 +4,25 @@
*
* 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
* 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 "SettingsViewController.h"
#import "LinphoneManager.h"
#import "PhoneMainView.h"
#import "UILinphone.h"
#import "UACellBackgroundView.h"
#import "InAppProductsViewController.h"
#import "DCRoundSwitch.h"
@ -66,7 +67,7 @@
- (void)dealloc {
[_key release], _key = nil;
[super dealloc];
}
@ -112,7 +113,7 @@
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell * cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
// Background View
UACellBackgroundView *selectedBackgroundView = [[[UACellBackgroundView alloc] initWithFrame:CGRectZero] autorelease];
cell.selectedBackgroundView = selectedBackgroundView;
@ -154,7 +155,7 @@
- (void)toggledValue:(id)sender {
IASKSwitchEx *toggle = [[(IASKSwitchEx*)sender retain] autorelease];
IASKSpecifier *spec = [_settingsReader specifierForKey:[toggle key]];
if ([toggle isOn]) {
if ([spec trueValue] != nil) {
[self.settingsStore setObject:[spec trueValue] forKey:[toggle key]];
@ -182,16 +183,16 @@
- (void)initIASKAppSettingsViewControllerEx {
[self.view setBackgroundColor:[UIColor clearColor]];
// Force kIASKSpecifierValuesViewControllerIndex
static int kIASKSpecifierValuesViewControllerIndex = 0;
_viewList = [[NSMutableArray alloc] init];
[_viewList addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"IASKSpecifierValuesView", @"ViewName",nil]];
[_viewList addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"IASKAppSettingsView", @"ViewName",nil]];
NSMutableDictionary *newItemDict = [NSMutableDictionary dictionaryWithCapacity:3];
[newItemDict addEntriesFromDictionary: [_viewList objectAtIndex:kIASKSpecifierValuesViewControllerIndex]]; // copy the title and explain strings
IASKSpecifierValuesViewController *targetViewController = [[IASKSpecifierValuesViewControllerEx alloc] init];
// add the new view controller to the dictionary and then to the 'viewList' array
[newItemDict setObject:targetViewController forKey:@"viewController"];
@ -211,7 +212,7 @@
}
[specifiers replaceObjectAtIndex:j withObject:sp];
}
[dataSource replaceObjectAtIndex:i withObject:specifiers];
}
[r setDataSource:dataSource];
@ -221,7 +222,7 @@
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView setBackgroundColor:[UIColor clearColor]]; // Can't do it in Xib: issue with ios4
[self.tableView setBackgroundView:nil]; // Can't do it in Xib: issue with ios4
}
@ -236,8 +237,8 @@
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
UIEdgeInsets inset = {0, 0, 10, 0};
UIScrollView *scrollView = self.tableView;
[scrollView setContentInset:inset];
@ -246,7 +247,7 @@
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"About", nil) style:UIBarButtonItemStyleBordered target:self action:@selector(onAboutClick:)];
self.navigationItem.rightBarButtonItem = buttonItem;
[buttonItem release];
@ -254,7 +255,7 @@
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell * cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
if([cell isKindOfClass:[IASKPSTextFieldSpecifierViewCell class]]) {
UITextField *field = ((IASKPSTextFieldSpecifierViewCell*)cell).textField;
[field setTextColor:LINPHONE_MAIN_COLOR];
@ -265,7 +266,7 @@
} else {
cell.detailTextLabel.textColor = LINPHONE_MAIN_COLOR;
}
// Background View
UACellBackgroundView *selectedBackgroundView = [[[UACellBackgroundView alloc] initWithFrame:CGRectZero] autorelease];
cell.selectedBackgroundView = selectedBackgroundView;
@ -283,7 +284,7 @@
#pragma mark - UINavigationBarEx Class
@interface UINavigationBarEx: UINavigationBar {
}
@end
@ -412,12 +413,12 @@ static UICompositeViewDescription *compositeDescription = nil;
+ (UICompositeViewDescription *)compositeViewDescription {
if(compositeDescription == nil) {
compositeDescription = [[UICompositeViewDescription alloc] init:@"Settings"
content:@"SettingsViewController"
stateBar:nil
stateBarEnabled:false
tabBar: @"UIMainBar"
tabBarEnabled:true
compositeDescription = [[UICompositeViewDescription alloc] init:@"Settings"
content:@"SettingsViewController"
stateBar:nil
stateBarEnabled:false
tabBar: @"UIMainBar"
tabBarEnabled:true
fullscreen:false
landscapeMode:[LinphoneManager runningOnIpad]
portraitMode:true];
@ -430,16 +431,16 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)viewDidLoad {
[super viewDidLoad];
settingsStore = [[LinphoneCoreSettingsStore alloc] init];
settingsController.showDoneButton = FALSE;
settingsController.delegate = self;
settingsController.showCreditsFooter = FALSE;
settingsController.settingsStore = settingsStore;
[navigationController.view setBackgroundColor:[UIColor clearColor]];
navigationController.view.frame = self.view.frame;
[navigationController pushViewController:settingsController animated:FALSE];
[self.view addSubview: navigationController.view];
@ -449,23 +450,24 @@ static UICompositeViewDescription *compositeDescription = nil;
[super viewWillDisappear:animated];
[settingsController dismiss:self];
// Set observer
[[NSNotificationCenter defaultCenter] removeObserver:self
name:kIASKAppSettingChanged
[[NSNotificationCenter defaultCenter] removeObserver:self
name:kIASKAppSettingChanged
object:nil];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[settingsStore transformLinphoneCoreToKeys]; // Sync settings with linphone core settings
settingsController.hiddenKeys = [self findHiddenKeys];
[settingsController.tableView reloadData];
[settingsController.tableView reloadData];
// Set observer
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appSettingChanged:)
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appSettingChanged:)
name:kIASKAppSettingChanged
object:nil];
}
@ -592,7 +594,7 @@ static UICompositeViewDescription *compositeDescription = nil;
- (NSSet*)findHiddenKeys {
LinphoneManager* lm = [LinphoneManager instance];
NSMutableSet *hiddenKeys = [NSMutableSet set];
#ifndef DEBUG
[hiddenKeys addObject:@"release_button"];
[hiddenKeys addObject:@"clear_cache_button"];
@ -603,28 +605,28 @@ static UICompositeViewDescription *compositeDescription = nil;
[hiddenKeys addObject:@"send_logs_button"];
[hiddenKeys addObject:@"reset_logs_button"];
}
[hiddenKeys addObject:@"playback_gain_preference"];
[hiddenKeys addObject:@"microphone_gain_preference"];
[hiddenKeys addObject:@"network_limit_group"];
[hiddenKeys addObject:@"upload_bandwidth_preference"];
[hiddenKeys addObject:@"download_bandwidth_preference"];
[hiddenKeys addObject:@"incoming_call_timeout_preference"];
[hiddenKeys addObject:@"in_call_timeout_preference"];
[hiddenKeys addObject:@"wifi_only_preference"];
[hiddenKeys addObject:@"quit_button"]; // Hide for the moment
[hiddenKeys addObject:@"about_button"]; // Hide for the moment
if (!linphone_core_video_supported([LinphoneManager getLc]))
[hiddenKeys addObject:@"video_menu"];
if (![LinphoneManager isNotIphone3G])
[hiddenKeys addObject:@"silk_24k_preference"];
UIDevice* device = [UIDevice currentDevice];
if (![device respondsToSelector:@selector(isMultitaskingSupported)] || ![device isMultitaskingSupported]) {
[hiddenKeys addObject:@"backgroundmode_preference"];
@ -634,18 +636,18 @@ static UICompositeViewDescription *compositeDescription = nil;
[hiddenKeys addObject:@"start_at_boot_preference"];
}
}
[hiddenKeys addObject:@"enable_first_login_view_preference"];
#ifndef VIDEO_ENABLED
[hiddenKeys addObject:@"enable_video_preference"];
#endif //VIDEO_ENABLED
if (!linphone_core_video_enabled([LinphoneManager getLc])) {
[hiddenKeys addObject:@"video_menu"];
}
[hiddenKeys addObjectsFromArray:[[LinphoneManager unsupportedCodecs] allObjects]];
BOOL random_port = [lm lpConfigBoolForKey:@"random_port_preference"];
@ -660,14 +662,14 @@ static UICompositeViewDescription *compositeDescription = nil;
if(![lm lpConfigBoolForKey:@"debugenable_preference"]) {
[hiddenKeys addObject:@"console_button"];
}
if(![LinphoneManager runningOnIpad]) {
[hiddenKeys addObject:@"preview_preference"];
}
if([lm lpConfigBoolForKey:@"hide_run_assistant_preference"]) {
[hiddenKeys addObject:@"wizard_button"];
}
if (!linphone_core_tunnel_available()){
[hiddenKeys addObject:@"tunnel_menu"];
}
@ -748,7 +750,7 @@ static UICompositeViewDescription *compositeDescription = nil;
} else if ([key isEqual:@"send_logs_button"]) {
char * filepath = linphone_core_compress_log_collection(lc);
if (filepath == NULL) {
[LinphoneLogger log:LinphoneLoggerError format:@"Cannot sent logs: file is NULL"];
LOGE(@"Cannot sent logs: file is NULL");
return;
}
@ -765,11 +767,13 @@ static UICompositeViewDescription *compositeDescription = nil;
} else if ([filename hasSuffix:@".gz"]) {
mimeType = @"application/gzip";
} else {
[LinphoneLogger log:LinphoneLoggerError format:@"Unknown extension type: %@, cancelling email", filename];
LOGE(@"Unknown extension type: %@, cancelling email", filename);
return;
}
[self emailAttachment:[NSData dataWithContentsOfFile:[NSString stringWithUTF8String:filepath]] mimeType:mimeType name:filename];
ms_free(filepath);
} else if([key isEqual:@"in_app_products_button"]) {
[[PhoneMainView instance] changeCurrentView:[InAppProductsViewController compositeViewDescription] push:TRUE];
}
}
@ -784,7 +788,7 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)emailAttachment: (NSData*)attachment mimeType:(NSString*)type name:(NSString*)attachmentName
{
if (attachmentName == nil || type == nil || attachmentName == nil) {
[LinphoneLogger log:LinphoneLoggerError format:@"Trying to email attachment but mandatory field is missing"];
LOGE(@"Trying to email attachment but mandatory field is missing");
return;
}
@ -823,9 +827,9 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
if (error != nil) {
[LinphoneLogger log:LinphoneLoggerWarning format:@"Error while sending mail: %@", error];
LOGW(@"Error while sending mail: %@", error);
} else {
[LinphoneLogger log:LinphoneLoggerLog format:@"Mail completed with status: %d", result];
LOGI(@"Mail completed with status: %d", result);
}
[self dismissViewControllerAnimated:true completion:nil];
}

View file

@ -77,7 +77,7 @@ static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef inf
}
if (retImage != nil && retImage.size.width != retImage.size.height) {
[LinphoneLogger log:LinphoneLoggerLog format:@"Image is not square : cropping it."];
LOGI(@"Image is not square : cropping it.");
return [self squareImageCrop:retImage];
}
}
@ -107,7 +107,7 @@ static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef inf
}
+ (NSString*)normalizeSipURI:(NSString*)address {
// replace all whitespaces (non-breakable, utf8 nbsp etc.) by the "classical" whitespace
// replace all whitespaces (non-breakable, utf8 nbsp etc.) by the "classical" whitespace
address = [[address componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] componentsJoinedByString:@" "];
NSString *normalizedSipAddress = nil;
LinphoneAddress* linphoneAddress = linphone_core_interpret_url([LinphoneManager getLc], [address UTF8String]);
@ -185,7 +185,7 @@ static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef inf
[self loadData];
});
} else {
[LinphoneLogger log:LinphoneLoggerError format:@"Create AddressBook: Fail(%@)", [error localizedDescription]];
LOGE(@"Create AddressBook: Fail(%@)", [error localizedDescription]);
}
}

View file

@ -4,18 +4,18 @@
*
* 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
* 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.
*/
*/
#ifndef LINPHONE_UTILS_H
#define LINPHONE_UTILS_H
@ -38,8 +38,7 @@ typedef enum _LinphoneLoggerSeverity {
@interface LinphoneLogger : NSObject {
}
+ (void)log:(LinphoneLoggerSeverity) severity format:(NSString *)format,...;
+ (void)logc:(LinphoneLoggerSeverity) severity format:(const char *)format,...;
+ (void)log:(LinphoneLoggerSeverity)severity file:(const char*)file line:(int)line format:(NSString *)format,...;
@end
@ -62,11 +61,17 @@ typedef enum _LinphoneLoggerSeverity {
@end
void LOGI(NSString* format, ...) NS_FORMAT_FUNCTION(1,2);
void LOGD(NSString* format, ...) NS_FORMAT_FUNCTION(1,2);
void LOGW(NSString* format, ...) NS_FORMAT_FUNCTION(1,2);
void LOGE(NSString* format, ...) NS_FORMAT_FUNCTION(1,2);
void LOGF(NSString* format, ...) NS_FORMAT_FUNCTION(1,2);
#define LOGV(level, ...) [LinphoneLogger log:level file:__FILE__ line:__LINE__ format:__VA_ARGS__]
#define LOGI(...) LOGV(LinphoneLoggerLog, __VA_ARGS__)
#define LOGD(...) LOGV(LinphoneLoggerDebug, __VA_ARGS__)
#define LOGW(...) LOGV(LinphoneLoggerWarning, __VA_ARGS__)
#define LOGE(...) LOGV(LinphoneLoggerError, __VA_ARGS__)
#define LOGF(...) LOGV(LinphoneLoggerFatal, __VA_ARGS__)
#endif
@interface NSString(md5)
- (NSString *)md5;
@end

View file

@ -4,18 +4,18 @@
*
* 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
* 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 "Utils.h"
@ -24,46 +24,32 @@
@implementation LinphoneLogger
+ (void)logv:(LinphoneLoggerSeverity)severity format:(NSString*)format args:(va_list)args{
NSString *str = [[NSString alloc] initWithFormat: format arguments:args];
if(severity <= LinphoneLoggerDebug) {
ms_debug("%s", [str UTF8String]);
} else if(severity <= LinphoneLoggerLog) {
ms_message("%s", [str UTF8String]);
} else if(severity <= LinphoneLoggerWarning) {
ms_warning("%s", [str UTF8String]);
} else if(severity <= LinphoneLoggerError) {
ms_error("%s", [str UTF8String]);
} else if(severity <= LinphoneLoggerFatal) {
ms_fatal("%s", [str UTF8String]);
}
+ (void)logv:(LinphoneLoggerSeverity)severity file:(const char*)file line:(int)line format:(NSString*)format args:(va_list)args{
NSString *str = [[NSString alloc] initWithFormat:format arguments:args];
OrtpLogLevel ortp_severity;
int filesize = 20;
if (severity <= LinphoneLoggerDebug) {
ortp_severity = ORTP_DEBUG;
} else if(severity <= LinphoneLoggerLog) {
ortp_severity = ORTP_MESSAGE;
} else if(severity <= LinphoneLoggerWarning) {
ortp_severity = ORTP_WARNING;
} else if(severity <= LinphoneLoggerError) {
ortp_severity = ORTP_ERROR;
} else {
ortp_severity = ORTP_FATAL;
}
ortp_log(ortp_severity, "%*s:%3d - %s", filesize, file+MAX((int)strlen(file)-filesize,0), line, [str UTF8String]);
[str release];
}
+ (void)log:(LinphoneLoggerSeverity) severity format:(NSString *)format,... {
+ (void)log:(LinphoneLoggerSeverity) severity file:(const char*)file line:(int)line format:(NSString *)format,... {
va_list args;
va_start (args, format);
[LinphoneLogger logv:severity format:format args:args];
[LinphoneLogger logv:severity file:file line:line format:format args:args];
va_end (args);
}
+ (void)logc:(LinphoneLoggerSeverity) severity format:(const char *)format,... {
va_list args;
va_start (args, format);
if(severity <= LinphoneLoggerDebug) {
ortp_logv(ORTP_DEBUG, format, args);
} else if(severity <= LinphoneLoggerLog) {
ortp_logv(ORTP_MESSAGE, format, args);
} else if(severity <= LinphoneLoggerWarning) {
ortp_logv(ORTP_WARNING, format, args);
} else if(severity <= LinphoneLoggerError) {
ortp_logv(ORTP_ERROR, format, args);
} else if(severity <= LinphoneLoggerFatal) {
ortp_logv(ORTP_FATAL, format, args);
}
va_end (args);
}
@end
@implementation LinphoneUtils
@ -104,15 +90,15 @@
// Set selected+over title: IB lack !
[button setTitle:[button titleForState:UIControlStateSelected]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
// Set selected+over titleColor: IB lack !
[button setTitleColor:[button titleColorForState:UIControlStateHighlighted]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
// Set selected+disabled title: IB lack !
[button setTitle:[button titleForState:UIControlStateSelected]
forState:(UIControlStateDisabled | UIControlStateSelected)];
// Set selected+disabled titleColor: IB lack !
[button setTitleColor:[button titleColorForState:UIControlStateDisabled]
forState:(UIControlStateDisabled | UIControlStateSelected)];
@ -122,15 +108,15 @@
// Set selected+over title: IB lack !
[button setTitle:[button titleForState:UIControlStateSelected]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
// Set selected+over titleColor: IB lack !
[button setTitleColor:[button titleColorForState:UIControlStateSelected]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
// Set selected+disabled title: IB lack !
[button setTitle:[button titleForState:UIControlStateSelected]
forState:(UIControlStateDisabled | UIControlStateSelected)];
// Set selected+disabled titleColor: IB lack !
[button setTitleColor:[button titleColorForState:UIControlStateDisabled]
forState:(UIControlStateDisabled | UIControlStateSelected)];
@ -144,7 +130,7 @@
[LinphoneUtils addDictEntry:attributes item:[button titleForState:UIControlStateDisabled | UIControlStateHighlighted] key:@"title-disabled-highlighted"];
[LinphoneUtils addDictEntry:attributes item:[button titleForState:UIControlStateSelected | UIControlStateHighlighted] key:@"title-selected-highlighted"];
[LinphoneUtils addDictEntry:attributes item:[button titleForState:UIControlStateSelected | UIControlStateDisabled] key:@"title-selected-disabled"];
[LinphoneUtils addDictEntry:attributes item:[button titleColorForState:UIControlStateNormal] key:@"title-color-normal"];
[LinphoneUtils addDictEntry:attributes item:[button titleColorForState:UIControlStateHighlighted] key:@"title-color-highlighted"];
[LinphoneUtils addDictEntry:attributes item:[button titleColorForState:UIControlStateDisabled] key:@"title-color-disabled"];
@ -152,11 +138,11 @@
[LinphoneUtils addDictEntry:attributes item:[button titleColorForState:UIControlStateDisabled | UIControlStateHighlighted] key:@"title-color-disabled-highlighted"];
[LinphoneUtils addDictEntry:attributes item:[button titleColorForState:UIControlStateSelected | UIControlStateHighlighted] key:@"title-color-selected-highlighted"];
[LinphoneUtils addDictEntry:attributes item:[button titleColorForState:UIControlStateSelected | UIControlStateDisabled] key:@"title-color-selected-disabled"];
[LinphoneUtils addDictEntry:attributes item:NSStringFromUIEdgeInsets([button titleEdgeInsets]) key:@"title-edge"];
[LinphoneUtils addDictEntry:attributes item:NSStringFromUIEdgeInsets([button contentEdgeInsets]) key:@"content-edge"];
[LinphoneUtils addDictEntry:attributes item:NSStringFromUIEdgeInsets([button imageEdgeInsets]) key:@"image-edge"];
[LinphoneUtils addDictEntry:attributes item:[button imageForState:UIControlStateNormal] key:@"image-normal"];
[LinphoneUtils addDictEntry:attributes item:[button imageForState:UIControlStateHighlighted] key:@"image-highlighted"];
[LinphoneUtils addDictEntry:attributes item:[button imageForState:UIControlStateDisabled] key:@"image-disabled"];
@ -164,7 +150,7 @@
[LinphoneUtils addDictEntry:attributes item:[button imageForState:UIControlStateDisabled | UIControlStateHighlighted] key:@"image-disabled-highlighted"];
[LinphoneUtils addDictEntry:attributes item:[button imageForState:UIControlStateSelected | UIControlStateHighlighted] key:@"image-selected-highlighted"];
[LinphoneUtils addDictEntry:attributes item:[button imageForState:UIControlStateSelected | UIControlStateDisabled] key:@"image-selected-disabled"];
[LinphoneUtils addDictEntry:attributes item:[button backgroundImageForState:UIControlStateNormal] key:@"background-normal"];
[LinphoneUtils addDictEntry:attributes item:[button backgroundImageForState:UIControlStateHighlighted] key:@"background-highlighted"];
[LinphoneUtils addDictEntry:attributes item:[button backgroundImageForState:UIControlStateDisabled] key:@"background-disabled"];
@ -182,7 +168,7 @@
[button setTitle:[LinphoneUtils getDictEntry:attributes key:@"title-disabled-highlighted"] forState:UIControlStateDisabled | UIControlStateHighlighted];
[button setTitle:[LinphoneUtils getDictEntry:attributes key:@"title-selected-highlighted"] forState:UIControlStateSelected | UIControlStateHighlighted];
[button setTitle:[LinphoneUtils getDictEntry:attributes key:@"title-selected-disabled"] forState:UIControlStateSelected | UIControlStateDisabled];
[button setTitleColor:[LinphoneUtils getDictEntry:attributes key:@"title-color-normal"] forState:UIControlStateNormal];
[button setTitleColor:[LinphoneUtils getDictEntry:attributes key:@"title-color-highlighted"] forState:UIControlStateHighlighted];
[button setTitleColor:[LinphoneUtils getDictEntry:attributes key:@"title-color-disabled"] forState:UIControlStateDisabled];
@ -190,7 +176,7 @@
[button setTitleColor:[LinphoneUtils getDictEntry:attributes key:@"title-color-disabled-highlighted"] forState:UIControlStateDisabled | UIControlStateHighlighted];
[button setTitleColor:[LinphoneUtils getDictEntry:attributes key:@"title-color-selected-highlighted"] forState:UIControlStateSelected | UIControlStateHighlighted];
[button setTitleColor:[LinphoneUtils getDictEntry:attributes key:@"title-color-selected-disabled"] forState:UIControlStateSelected | UIControlStateDisabled];
[button setTitleEdgeInsets:UIEdgeInsetsFromString([LinphoneUtils getDictEntry:attributes key:@"title-edge"])];
[button setContentEdgeInsets:UIEdgeInsetsFromString([LinphoneUtils getDictEntry:attributes key:@"content-edge"])];
[button setImageEdgeInsets:UIEdgeInsetsFromString([LinphoneUtils getDictEntry:attributes key:@"image-edge"])];
@ -202,7 +188,7 @@
[button setImage:[LinphoneUtils getDictEntry:attributes key:@"image-disabled-highlighted"] forState:UIControlStateDisabled | UIControlStateHighlighted];
[button setImage:[LinphoneUtils getDictEntry:attributes key:@"image-selected-highlighted"] forState:UIControlStateSelected | UIControlStateHighlighted];
[button setImage:[LinphoneUtils getDictEntry:attributes key:@"image-selected-disabled"] forState:UIControlStateSelected | UIControlStateDisabled];
[button setBackgroundImage:[LinphoneUtils getDictEntry:attributes key:@"background-normal"] forState:UIControlStateNormal];
[button setBackgroundImage:[LinphoneUtils getDictEntry:attributes key:@"background-highlighted"] forState:UIControlStateHighlighted];
[button setBackgroundImage:[LinphoneUtils getDictEntry:attributes key:@"background-disabled"] forState:UIControlStateDisabled];
@ -241,34 +227,26 @@
if (floatSize < 1023)
return([NSString stringWithFormat:@"%1.1f MB",floatSize]);
floatSize = floatSize / 1024;
return([NSString stringWithFormat:@"%1.1f GB",floatSize]);
}
@end
#define LOGV(level, argstart) \
va_list args; \
va_start(args, argstart); \
[LinphoneLogger logv:level format:argstart args:args]; \
va_end(args);
@implementation NSString(md5)
void LOGI(NSString* format, ...){
LOGV(LinphoneLoggerLog, format);
#import <CommonCrypto/CommonDigest.h>
- (NSString *)md5 {
const char *ptr = [self UTF8String];
unsigned char md5Buffer[CC_MD5_DIGEST_LENGTH];
CC_MD5(ptr, (unsigned int)strlen(ptr), md5Buffer);
NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
[output appendFormat:@"%02x",md5Buffer[i]];
}
return output;
}
void LOGD(NSString* format, ...){
LOGV(LinphoneLoggerDebug, format);
}
void LOGW(NSString* format, ...){
LOGV(LinphoneLoggerWarning, format);
}
void LOGE(NSString* format, ...){
LOGV(LinphoneLoggerError, format);
}
void LOGF(NSString* format, ...){
LOGV(LinphoneLoggerFatal, format);
}
@end

View file

@ -4,23 +4,24 @@
*
* 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 Library 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
* 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 Library 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 <UIKit/UIKit.h>
#import <XMLRPCConnectionDelegate.h>
#import "UICompositeViewController.h"
#import "UILinphoneTextField.h"
#import "LinphoneUI/UILinphoneButton.h"
@interface WizardViewController : TPMultiLayoutViewController
<UITextFieldDelegate,
@ -54,6 +55,8 @@
@property (nonatomic, retain) IBOutlet UIButton *connectAccountButton;
@property (nonatomic, retain) IBOutlet UIButton *externalAccountButton;
@property (retain, nonatomic) IBOutlet UIButton *remoteProvisioningButton;
@property (retain, nonatomic) IBOutlet UILinphoneButton *registerButton;
@property (retain, nonatomic) IBOutlet UILinphoneButton *purchaseButton;
@property (retain, nonatomic) IBOutlet UILinphoneTextField *createAccountUsername;
@property (retain, nonatomic) IBOutlet UILinphoneTextField *connectAccountUsername;
@ -80,6 +83,7 @@
- (IBAction)onExternalAccountClick:(id)sender;
- (IBAction)onCheckValidationClick:(id)sender;
- (IBAction)onRemoteProvisioningClick:(id)sender;
- (IBAction)onPurchaseAccountClick:(id)sender;
- (IBAction)onSignInClick:(id)sender;
- (IBAction)onSignInExternalClick:(id)sender;

View file

@ -1,21 +1,22 @@
/* WizardViewController.m
*
* Copyright (C) 2012 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 Library 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
* 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 Library 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 "WizardViewController.h"
#import "LinphoneManager.h"
@ -83,18 +84,18 @@ typedef enum _ViewElement {
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[contentView release];
[welcomeView release];
[choiceView release];
[createAccountView release];
[connectAccountView release];
[externalAccountView release];
[validateAccountView release];
[waitView release];
[backButton release];
[startButton release];
[createAccountButton release];
@ -102,20 +103,25 @@ typedef enum _ViewElement {
[externalAccountButton release];
[choiceViewLogoImageView release];
[historyViews release];
[viewTapGestureRecognizer release];
[remoteProvisioningButton release];
[provisionedAccountView release];
[provisionedUsername release];
[provisionedPassword release];
[provisionedDomain release];
[_transportChooser release];
[_createAccountUsername release];
[_connectAccountUsername release];
[_externalAccountUsername release];
[_purchaseButton release];
[_registerButton release];
[super dealloc];
}
@ -126,12 +132,12 @@ static UICompositeViewDescription *compositeDescription = nil;
+ (UICompositeViewDescription *)compositeViewDescription {
if(compositeDescription == nil) {
compositeDescription = [[UICompositeViewDescription alloc] init:@"Wizard"
content:@"WizardViewController"
stateBar:nil
stateBarEnabled:false
tabBar:nil
tabBarEnabled:false
compositeDescription = [[UICompositeViewDescription alloc] init:@"Wizard"
content:@"WizardViewController"
stateBar:nil
stateBarEnabled:false
tabBar:nil
tabBarEnabled:false
fullscreen:false
landscapeMode:[LinphoneManager runningOnIpad]
portraitMode:true];
@ -145,7 +151,7 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(registrationUpdateEvent:)
name:kLinphoneRegistrationUpdate
@ -163,6 +169,18 @@ static UICompositeViewDescription *compositeDescription = nil;
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(inAppPurchaseNotification:)
name:IAPPurchaseSucceeded
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(inAppPurchaseNotification:)
name:IAPPurchaseTrying
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(inAppPurchaseNotification:)
name:IAPPurchaseFailed
object:nil];
}
- (void)viewWillDisappear:(BOOL)animated {
@ -180,16 +198,24 @@ static UICompositeViewDescription *compositeDescription = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillHideNotification
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:IAPPurchaseFailed
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:IAPPurchaseTrying
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:IAPPurchaseSucceeded
object:nil];
}
- (void)viewDidLoad {
[super viewDidLoad];
[viewTapGestureRecognizer setCancelsTouchesInView:FALSE];
[viewTapGestureRecognizer setDelegate:self];
[contentView addGestureRecognizer:viewTapGestureRecognizer];
if([LinphoneManager runningOnIpad]) {
[LinphoneUtils adjustFontSize:welcomeView mult:2.22f];
[LinphoneUtils adjustFontSize:choiceView mult:2.22f];
@ -211,6 +237,10 @@ static UICompositeViewDescription *compositeDescription = nil;
text.placeholder = NSLocalizedString(@"Username", nil);
}
}
BOOL mustPurchaseNewAccount = ([[LinphoneManager instance] lpConfigStringForKey:@"paid_account_id" forSection:@"in_app_purchase"] != nil);
_registerButton.hidden = mustPurchaseNewAccount;
_purchaseButton.hidden = !mustPurchaseNewAccount;
}
@ -241,7 +271,7 @@ static UICompositeViewDescription *compositeDescription = nil;
const LinphoneAuthInfo *auth = linphone_core_find_auth_info(lc, NULL, linphone_address_get_username(addr), linphone_proxy_config_get_domain(current_conf));
linphone_address_destroy(addr);
if( auth ){
[LinphoneLogger log:LinphoneLoggerLog format:@"A proxy config was set up with the remote provisioning, skip wizard"];
LOGI(@"A proxy config was set up with the remote provisioning, skip wizard");
[self onCancelClick:nil];
}
}
@ -286,14 +316,14 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)reset {
[self clearProxyConfig];
[[LinphoneManager instance] lpConfigSetBool:FALSE forKey:@"pushnotification_preference"];
LinphoneCore *lc = [LinphoneManager getLc];
LCSipTransports transportValue={5060,5060,-1,-1};
if (linphone_core_set_sip_transports(lc, &transportValue)) {
[LinphoneLogger logc:LinphoneLoggerError format:"cannot set transport"];
LOGE(@"cannot set transport");
}
[[LinphoneManager instance] lpConfigSetString:@"" forKey:@"sharing_server_preference"];
[[LinphoneManager instance] lpConfigSetBool:FALSE forKey:@"ice_preference"];
[[LinphoneManager instance] lpConfigSetString:@"" forKey:@"stun_preference"];
@ -351,7 +381,7 @@ static UICompositeViewDescription *compositeDescription = nil;
[startButton setHidden:true];
[backButton setHidden:false];
}
if (view == validateAccountView) {
[backButton setEnabled:FALSE];
} else if (view == choiceView) {
@ -399,7 +429,7 @@ static UICompositeViewDescription *compositeDescription = nil;
view = connectAccountView;
}
}
// Animation
if(animation && [[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference"] == true) {
CATransition* trans = [CATransition animation];
@ -413,14 +443,14 @@ static UICompositeViewDescription *compositeDescription = nil;
}
[contentView.layer addAnimation:trans forKey:@"Transition"];
}
// Stack current view
if(currentView != nil) {
if(!back)
[historyViews addObject:currentView];
[currentView removeFromSuperview];
}
// Set current view
currentView = view;
[contentView insertSubview:view atIndex:0];
@ -546,44 +576,44 @@ static UICompositeViewDescription *compositeDescription = nil;
#pragma mark - Linphone XMLRPC
- (void)checkUserExist:(NSString*)username {
[LinphoneLogger log:LinphoneLoggerLog format:@"XMLRPC check_account %@", username];
LOGI(@"XMLRPC check_account %@", username);
NSURL *URL = [NSURL URLWithString:[[LinphoneManager instance] lpConfigStringForKey:@"service_url" forSection:@"wizard"]];
XMLRPCRequest *request = [[XMLRPCRequest alloc] initWithURL: URL];
[request setMethod: @"check_account" withParameters:[NSArray arrayWithObjects:username, nil]];
XMLRPCConnectionManager *manager = [XMLRPCConnectionManager sharedManager];
[manager spawnConnectionWithXMLRPCRequest: request delegate: self];
[request release];
[waitView setHidden:false];
}
- (void)createAccount:(NSString*)identity password:(NSString*)password email:(NSString*)email {
NSString *useragent = [LinphoneManager getUserAgent];
[LinphoneLogger log:LinphoneLoggerLog format:@"XMLRPC create_account_with_useragent %@ %@ %@ %@", identity, password, email, useragent];
LOGI(@"XMLRPC create_account_with_useragent %@ %@ %@ %@", identity, password, email, useragent);
NSURL *URL = [NSURL URLWithString: [[LinphoneManager instance] lpConfigStringForKey:@"service_url" forSection:@"wizard"]];
XMLRPCRequest *request = [[XMLRPCRequest alloc] initWithURL: URL];
[request setMethod: @"create_account_with_useragent" withParameters:[NSArray arrayWithObjects:identity, password, email, useragent, nil]];
XMLRPCConnectionManager *manager = [XMLRPCConnectionManager sharedManager];
[manager spawnConnectionWithXMLRPCRequest: request delegate: self];
[request release];
[waitView setHidden:false];
}
- (void)checkAccountValidation:(NSString*)identity {
[LinphoneLogger log:LinphoneLoggerLog format:@"XMLRPC check_account_validated %@", identity];
LOGI(@"XMLRPC check_account_validated %@", identity);
NSURL *URL = [NSURL URLWithString: [[LinphoneManager instance] lpConfigStringForKey:@"service_url" forSection:@"wizard"]];
XMLRPCRequest *request = [[XMLRPCRequest alloc] initWithURL: URL];
[request setMethod: @"check_account_validated" withParameters:[NSArray arrayWithObjects:identity, nil]];
XMLRPCConnectionManager *manager = [XMLRPCConnectionManager sharedManager];
[manager spawnConnectionWithXMLRPCRequest: request delegate: self];
[request release];
[waitView setHidden:false];
}
@ -753,7 +783,7 @@ static UICompositeViewDescription *compositeDescription = nil;
[remoteInput release];
}
- (void) verificationSignInWithUsername:(NSString*)username password:(NSString*)password domain:(NSString*)domain withTransport:(NSString*)transport {
- (BOOL) verificationWithUsername:(NSString*)username password:(NSString*)password domain:(NSString*)domain withTransport:(NSString*)transport {
NSMutableString *errors = [NSMutableString string];
if ([username length] == 0) {
[errors appendString:[NSString stringWithFormat:NSLocalizedString(@"Please enter a valid username.\n", nil)]];
@ -771,7 +801,12 @@ static UICompositeViewDescription *compositeDescription = nil;
otherButtonTitles:nil,nil];
[errorView show];
[errorView release];
} else {
return FALSE;
}
return TRUE;
}
- (void) verificationSignInWithUsername:(NSString*)username password:(NSString*)password domain:(NSString*)domain withTransport:(NSString*)transport {
if ([self verificationWithUsername:username password:password domain:domain withTransport:transport]) {
[waitView setHidden:false];
if ([LinphoneManager instance].connectivity == none) {
DTAlertView *alert = [[DTAlertView alloc] initWithTitle:NSLocalizedString(@"No connectivity", nil)
@ -811,44 +846,50 @@ static UICompositeViewDescription *compositeDescription = nil;
[self verificationSignInWithUsername:username password:password domain:nil withTransport:nil];
}
- (BOOL)verificationRegisterWithUsername:(NSString*)username password:(NSString*)password password2:(NSString*)password2 email:(NSString*)email {
NSMutableString *errors = [NSMutableString string];
NSInteger username_length = [[LinphoneManager instance] lpConfigIntForKey:@"username_length" forSection:@"wizard"];
NSInteger password_length = [[LinphoneManager instance] lpConfigIntForKey:@"password_length" forSection:@"wizard"];
if ([username length] < username_length) {
[errors appendString:[NSString stringWithFormat:NSLocalizedString(@"The username is too short (minimum %d characters).\n", nil), username_length]];
}
if ([password length] < password_length) {
[errors appendString:[NSString stringWithFormat:NSLocalizedString(@"The password is too short (minimum %d characters).\n", nil), password_length]];
}
if (![password2 isEqualToString:password]) {
[errors appendString:NSLocalizedString(@"The passwords are different.\n", nil)];
}
NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", @".+@.+\\.[A-Za-z]{2}[A-Za-z]*"];
if(![emailTest evaluateWithObject:email]) {
[errors appendString:NSLocalizedString(@"The email is invalid.\n", nil)];
}
if([errors length]) {
UIAlertView* errorView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Check error(s)",nil)
message:[errors substringWithRange:NSMakeRange(0, [errors length] - 1)]
delegate:nil
cancelButtonTitle:NSLocalizedString(@"Continue",nil)
otherButtonTitles:nil,nil];
[errorView show];
[errorView release];
return FALSE;
}
return TRUE;
}
- (IBAction)onRegisterClick:(id)sender {
UITextField* username_tf = [WizardViewController findTextField:ViewElement_Username view:contentView];
NSString *username = username_tf.text;
NSString *password = [WizardViewController findTextField:ViewElement_Password view:contentView].text;
NSString *password2 = [WizardViewController findTextField:ViewElement_Password2 view:contentView].text;
NSString *email = [WizardViewController findTextField:ViewElement_Email view:contentView].text;
NSMutableString *errors = [NSMutableString string];
NSInteger username_length = [[LinphoneManager instance] lpConfigIntForKey:@"username_length" forSection:@"wizard"];
NSInteger password_length = [[LinphoneManager instance] lpConfigIntForKey:@"password_length" forSection:@"wizard"];
if ([username length] < username_length) {
[errors appendString:[NSString stringWithFormat:NSLocalizedString(@"The username is too short (minimum %d characters).\n", nil), username_length]];
}
if ([password length] < password_length) {
[errors appendString:[NSString stringWithFormat:NSLocalizedString(@"The password is too short (minimum %d characters).\n", nil), password_length]];
}
if (![password2 isEqualToString:password]) {
[errors appendString:NSLocalizedString(@"The passwords are different.\n", nil)];
}
NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", @".+@.+\\.[A-Za-z]{2}[A-Za-z]*"];
if(![emailTest evaluateWithObject:email]) {
[errors appendString:NSLocalizedString(@"The email is invalid.\n", nil)];
}
if([errors length]) {
UIAlertView* errorView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Check error(s)",nil)
message:[errors substringWithRange:NSMakeRange(0, [errors length] - 1)]
delegate:nil
cancelButtonTitle:NSLocalizedString(@"Continue",nil)
otherButtonTitles:nil,nil];
[errorView show];
[errorView release];
} else {
if ([self verificationRegisterWithUsername:username password:password password2:password2 email:email]) {
username = [username lowercaseString];
[username_tf setText:username];
NSString *identity = [self identityFromUsername:username];
@ -856,6 +897,45 @@ static UICompositeViewDescription *compositeDescription = nil;
}
}
- (void)inAppPurchaseNotification: (NSNotification*)notification {
BOOL wasWaitingForInApp = (currentView == createAccountView);
NSString *paidAccountID = [[LinphoneManager instance] lpConfigStringForKey:@"paid_account_id" forSection:@"in_app_purchase"];
if (wasWaitingForInApp
&& [paidAccountID isEqualToString:[notification.userInfo objectForKey:@"product_id"]]) {
if ([notification.name isEqual:IAPPurchaseTrying]) {
[waitView setHidden:false];
} else if ([notification.name isEqual:IAPPurchaseFailed]) {
[waitView setHidden:true];
} else if ([notification.name isEqual:IAPPurchaseSucceeded]) {
[waitView setHidden:true];
//now that the purchase is made, let's create the account.
[self onPurchaseAccountClick:self];
}
}
}
- (IBAction)onPurchaseAccountClick:(id)sender {
UITextField* username_tf = [WizardViewController findTextField:ViewElement_Username view:contentView];
NSString *username = username_tf.text;
NSString *password = [WizardViewController findTextField:ViewElement_Password view:contentView].text;
NSString *password2 = [WizardViewController findTextField:ViewElement_Password2 view:contentView].text;
NSString *email = [WizardViewController findTextField:ViewElement_Email view:contentView].text;
if ([self verificationRegisterWithUsername:username password:password password2:password2 email:email]) {
InAppProductsManager *iapm = [[LinphoneManager instance] iapManager];
//if has already purchased, continue
if ([iapm isPurchasedWithID:[[LinphoneManager instance] lpConfigStringForKey:@"paid_account_id" forSection:@"in_app_purchase"]]) {
username = [username lowercaseString];
[username_tf setText:username];
NSString *identity = [self identityFromUsername:username];
[self checkUserExist:identity];
} else {
[iapm purchaseAccount:username withPassword:password];
// inAppPurchaseNotification will take care of bringing us to the next view now
}
}
}
- (IBAction)onProvisionedLoginClick:(id)sender {
NSString *username = provisionedUsername.text;
NSString *password = provisionedPassword.text;
@ -894,14 +974,14 @@ static UICompositeViewDescription *compositeDescription = nil;
if( [url rangeOfString:@"://"].location == NSNotFound )
url = [NSString stringWithFormat:@"http://%@", url];
[LinphoneLogger log:LinphoneLoggerLog format:@"Should use remote provisioning URL %@", url];
LOGI(@"Should use remote provisioning URL %@", url);
linphone_core_set_provisioning_uri([LinphoneManager getLc], [url UTF8String]);
[waitView setHidden:false];
[[LinphoneManager instance] resetLinphoneCore];
}
} else {
[LinphoneLogger log:LinphoneLoggerLog format:@"Canceled remote provisioning"];
LOGI(@"Canceled remote provisioning");
}
}
@ -958,13 +1038,13 @@ static UICompositeViewDescription *compositeDescription = nil;
[UIView setAnimationDuration:duration];
[UIView setAnimationCurve:curve];
[UIView setAnimationBeginsFromCurrentState:TRUE];
// Move view
UIEdgeInsets inset = {0, 0, 0, 0};
[contentView setContentInset:inset];
[contentView setScrollIndicatorInsets:inset];
[contentView setShowsVerticalScrollIndicator:FALSE];
[UIView commitAnimations];
}
@ -977,14 +1057,14 @@ static UICompositeViewDescription *compositeDescription = nil;
[UIView setAnimationDuration:duration];
[UIView setAnimationCurve:curve];
[UIView setAnimationBeginsFromCurrentState:TRUE];
if(([[UIDevice currentDevice].systemVersion floatValue] < 8) &&
UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) {
int width = endFrame.size.height;
endFrame.size.height = endFrame.size.width;
endFrame.size.width = width;
}
// Change inset
{
UIEdgeInsets inset = {0,0,0,0};
@ -994,7 +1074,7 @@ static UICompositeViewDescription *compositeDescription = nil;
CGPoint gPos = [contentView convertPoint:pos toView:[UIApplication sharedApplication].keyWindow.rootViewController.view]; // Bypass IOS bug on landscape mode
inset.bottom = -(rect.size.height - gPos.y - endFrame.size.height);
if(inset.bottom < 0) inset.bottom = 0;
[contentView setContentInset:inset];
[contentView setScrollIndicatorInsets:inset];
CGRect fieldFrame = activeTextField.frame;
@ -1009,7 +1089,7 @@ static UICompositeViewDescription *compositeDescription = nil;
#pragma mark - XMLRPCConnectionDelegate Functions
- (void)request:(XMLRPCRequest *)request didReceiveResponse:(XMLRPCResponse *)response {
[LinphoneLogger log:LinphoneLoggerLog format:@"XMLRPC %@: %@", [request method], [response body]];
LOGI(@"XMLRPC %@: %@", [request method], [response body]);
[waitView setHidden:true];
if ([response isFault]) {
NSString *errorString = [NSString stringWithFormat:NSLocalizedString(@"Communication issue (%@)", nil), [response faultString]];
@ -1088,11 +1168,11 @@ static UICompositeViewDescription *compositeDescription = nil;
}
- (void)request:(XMLRPCRequest *)request didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
}
- (void)request:(XMLRPCRequest *)request didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
}
#pragma mark - TPMultiLayoutViewController Functions

View file

@ -17,4 +17,10 @@ display_filter_auto_rotate=0
[app]
#contact_display_username_only=1
#contact_filter_on_default_domain=1
#use_phone_number=0
#use_phone_number=0
[in_app_purchase]
enabled=1
paid_account_id=test.autorenew_7days
receipt_validation_url=https://www.linphone.org/inapp.php
products_list=test.autorenew_7days

View file

@ -16,4 +16,10 @@ display_filter_auto_rotate=0
[app]
#contact_display_username_only=1
#contact_filter_on_default_domain=1
#contact_filter_on_default_domain=1
[in_app_purchase]
enabled=1
paid_account_id=test.autorenew_7days
receipt_validation_url=https://www.linphone.org/inapp.php
products_list=test.autorenew_7days

View file

@ -242,6 +242,14 @@
<key>Type</key>
<string>PSChildPaneSpecifier</string>
</dict>
<dict>
<key>Key</key>
<string>in_app_products_button</string>
<key>Title</key>
<string>Extra features</string>
<key>Type</key>
<string>IASKButtonSpecifier</string>
</dict>
<dict>
<key>Title</key>
<string>Development debug actions</string>

View file

@ -5,13 +5,13 @@
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleDisplayName</key>
<string>Linphone</string>
<string>LinphoneTest</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIcons~ipad</key>
<dict/>
<key>CFBundleIdentifier</key>
<string>org.linphone.phone</string>
<string>org.linphone.phone.test</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleLocalizations</key>
@ -24,7 +24,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>3.7.6</string>
<string>1.0.0</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
@ -53,7 +53,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>2.2.6</string>
<string>4</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIApplicationExitsOnSuspend</key>

View file

@ -112,6 +112,11 @@
57F005CA15EE2D9200914747 /* linphonerc-factory~ipad in Resources */ = {isa = PBXBuildFile; fileRef = 57F005C715EE2D9200914747 /* linphonerc-factory~ipad */; };
631C4FB119D2A8F2004BFE77 /* UIDigitButtonLongPlus.m in Sources */ = {isa = PBXBuildFile; fileRef = 631C4FB019D2A8F2004BFE77 /* UIDigitButtonLongPlus.m */; };
631C4FB719D2C3A6004BFE77 /* UIDigitButtonLongVoiceMail.m in Sources */ = {isa = PBXBuildFile; fileRef = 631C4FB619D2C3A6004BFE77 /* UIDigitButtonLongVoiceMail.m */; };
6359DE7F1ADEB54200EA15C0 /* InAppProductsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6359DE7D1ADEB54200EA15C0 /* InAppProductsViewController.m */; };
6359DE801ADEB54200EA15C0 /* InAppProductsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6359DE7E1ADEB54200EA15C0 /* InAppProductsViewController.xib */; };
6359DE841ADEB64100EA15C0 /* InAppProductsCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 6359DE821ADEB64100EA15C0 /* InAppProductsCell.m */; };
6359DE851ADEB64100EA15C0 /* InAppProductsCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6359DE831ADEB64100EA15C0 /* InAppProductsCell.xib */; };
6359DE8B1ADF9EB900EA15C0 /* InAppProductsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6359DE8A1ADF9EB900EA15C0 /* InAppProductsTableViewController.m */; };
636316D11A1DEBCB0009B839 /* AboutViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 636316D31A1DEBCB0009B839 /* AboutViewController.xib */; };
636316D41A1DEC650009B839 /* SettingsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 636316D61A1DEC650009B839 /* SettingsViewController.xib */; };
636316D91A1DECC90009B839 /* PhoneMainView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 636316D71A1DECC90009B839 /* PhoneMainView.xib */; };
@ -122,6 +127,8 @@
639CEB061A1DF4F1004DE38F /* UIChatRoomCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 639CEB081A1DF4F1004DE38F /* UIChatRoomCell.xib */; };
639CEB091A1DF4FA004DE38F /* UIChatCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 639CEB0B1A1DF4FA004DE38F /* UIChatCell.xib */; };
63CD4B4F1A5AAC8C00B84282 /* DTAlertView.m in Sources */ = {isa = PBXBuildFile; fileRef = 63CD4B4E1A5AAC8C00B84282 /* DTAlertView.m */; };
63E59A3A1ADE6A0100646FB3 /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63E59A391ADE6A0100646FB3 /* StoreKit.framework */; };
63E59A3F1ADE70D900646FB3 /* InAppProductsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E59A3E1ADE70D900646FB3 /* InAppProductsManager.m */; };
63FB30351A680E73008CA393 /* UIRoundedImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 63FB30341A680E73008CA393 /* UIRoundedImageView.m */; };
70571E1A13FABCB000CDD3C2 /* rootca.pem in Resources */ = {isa = PBXBuildFile; fileRef = 70571E1913FABCB000CDD3C2 /* rootca.pem */; };
7066FC0C13E830E400EFC6DC /* libvpx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7066FC0B13E830E400EFC6DC /* libvpx.a */; };
@ -928,7 +935,6 @@
1D3623250D0F684500981E51 /* LinphoneAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LinphoneAppDelegate.m; sourceTree = "<group>"; };
1D6058910D05DD3D006BFB54 /* linphone.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = linphone.app; sourceTree = BUILT_PRODUCTS_DIR; };
1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
1FE76362DA6217E7341ED1DF /* libPods-KifTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-KifTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
220FAD2910765B400068D98F /* libgsm.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgsm.a; path = "liblinphone-sdk/apple-darwin/lib/libgsm.a"; sourceTree = "<group>"; };
220FAD2C10765B400068D98F /* libortp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libortp.a; path = "liblinphone-sdk/apple-darwin/lib/libortp.a"; sourceTree = "<group>"; };
220FAD2F10765B400068D98F /* libspeex.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libspeex.a; path = "liblinphone-sdk/apple-darwin/lib/libspeex.a"; sourceTree = "<group>"; };
@ -1019,6 +1025,14 @@
631C4FB519D2C3A6004BFE77 /* UIDigitButtonLongVoiceMail.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIDigitButtonLongVoiceMail.h; sourceTree = "<group>"; };
631C4FB619D2C3A6004BFE77 /* UIDigitButtonLongVoiceMail.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIDigitButtonLongVoiceMail.m; sourceTree = "<group>"; };
633E388219FFB0F400936D1C /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
6359DE7C1ADEB54200EA15C0 /* InAppProductsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InAppProductsViewController.h; sourceTree = "<group>"; };
6359DE7D1ADEB54200EA15C0 /* InAppProductsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InAppProductsViewController.m; sourceTree = "<group>"; };
6359DE7E1ADEB54200EA15C0 /* InAppProductsViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = InAppProductsViewController.xib; sourceTree = "<group>"; };
6359DE811ADEB64100EA15C0 /* InAppProductsCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InAppProductsCell.h; sourceTree = "<group>"; };
6359DE821ADEB64100EA15C0 /* InAppProductsCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InAppProductsCell.m; sourceTree = "<group>"; };
6359DE831ADEB64100EA15C0 /* InAppProductsCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = InAppProductsCell.xib; sourceTree = "<group>"; };
6359DE891ADF9EB900EA15C0 /* InAppProductsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InAppProductsTableViewController.h; sourceTree = "<group>"; };
6359DE8A1ADF9EB900EA15C0 /* InAppProductsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InAppProductsTableViewController.m; sourceTree = "<group>"; };
636316D21A1DEBCB0009B839 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/AboutViewController.xib; sourceTree = "<group>"; };
636316D51A1DEC650009B839 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/SettingsViewController.xib; sourceTree = "<group>"; };
636316D81A1DECC90009B839 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/PhoneMainView.xib; sourceTree = "<group>"; };
@ -1035,6 +1049,9 @@
639CEB0D1A1DF52C004DE38F /* ru */ = {isa = PBXFileReference; fileEncoding = 2483028224; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/UICallCell.strings; sourceTree = "<group>"; };
63CD4B4D1A5AAC8C00B84282 /* DTAlertView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTAlertView.h; sourceTree = "<group>"; };
63CD4B4E1A5AAC8C00B84282 /* DTAlertView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTAlertView.m; sourceTree = "<group>"; };
63E59A391ADE6A0100646FB3 /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; };
63E59A3D1ADE6ECB00646FB3 /* InAppProductsManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InAppProductsManager.h; sourceTree = "<group>"; };
63E59A3E1ADE70D900646FB3 /* InAppProductsManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InAppProductsManager.m; sourceTree = "<group>"; };
63EF7FDC1A24B5810017A416 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/AboutViewController.strings; sourceTree = "<group>"; };
63FB30331A680E73008CA393 /* UIRoundedImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIRoundedImageView.h; sourceTree = "<group>"; };
63FB30341A680E73008CA393 /* UIRoundedImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIRoundedImageView.m; sourceTree = "<group>"; };
@ -1892,6 +1909,7 @@
D37EE10916032DA4003608A6 /* libmediastreamer_base.a in Frameworks */,
D37EE10A16032DA4003608A6 /* libmediastreamer_voip.a in Frameworks */,
226F2ED81344B0EF00F6EF27 /* libmsamr.a in Frameworks */,
63E59A3A1ADE6A0100646FB3 /* StoreKit.framework in Frameworks */,
223148E61178A09900637D6A /* libmsilbc.a in Frameworks */,
226183B0147259670037138E /* libmssilk.a in Frameworks */,
22AA8AFE13D7125600B30535 /* libmsx264.a in Frameworks */,
@ -2034,6 +2052,16 @@
22405EFD1601C19000B92522 /* ImageViewController.h */,
22405EFE1601C19100B92522 /* ImageViewController.m */,
D37EE11016035793003608A6 /* ImageViewController.xib */,
6359DE811ADEB64100EA15C0 /* InAppProductsCell.h */,
6359DE821ADEB64100EA15C0 /* InAppProductsCell.m */,
6359DE831ADEB64100EA15C0 /* InAppProductsCell.xib */,
63E59A3D1ADE6ECB00646FB3 /* InAppProductsManager.h */,
63E59A3E1ADE70D900646FB3 /* InAppProductsManager.m */,
6359DE891ADF9EB900EA15C0 /* InAppProductsTableViewController.h */,
6359DE8A1ADF9EB900EA15C0 /* InAppProductsTableViewController.m */,
6359DE7C1ADEB54200EA15C0 /* InAppProductsViewController.h */,
6359DE7D1ADEB54200EA15C0 /* InAppProductsViewController.m */,
6359DE7E1ADEB54200EA15C0 /* InAppProductsViewController.xib */,
D31AAF5C159B3919002C6B02 /* InCallTableViewController.h */,
D31AAF5D159B3919002C6B02 /* InCallTableViewController.m */,
D3F83EE91582021700336684 /* InCallViewController.h */,
@ -2236,6 +2264,7 @@
29B97323FDCFA39411CA2CEA /* Frameworks */ = {
isa = PBXGroup;
children = (
63E59A391ADE6A0100646FB3 /* StoreKit.framework */,
F0FF66AA1ACAEEB0008A4486 /* IOKit.framework */,
F0B026F21AA710AF00FF49F7 /* libiconv.dylib */,
F05BAA611A5D594E00411815 /* libz.dylib */,
@ -2279,7 +2308,6 @@
22509041196BD902007863F6 /* libopenh264.a */,
22AF73C11754C0D000BE8398 /* libopus.a */,
220FAD2C10765B400068D98F /* libortp.a */,
1FE76362DA6217E7341ED1DF /* libPods-KifTests.a */,
57B0E35F173C010400A476B8 /* libpolarssl.a */,
F0BB8C34193624C800974404 /* libresolv.9.dylib */,
22D1B68012A3E0BE001AE361 /* libresolv.dylib */,
@ -3183,6 +3211,11 @@
TargetAttributes = {
1D6058900D05DD3D006BFB54 = {
DevelopmentTeam = Z2V957B3D6;
SystemCapabilities = {
com.apple.InAppPurchase = {
enabled = 1;
};
};
};
F08F118319C09C6A007D70C2 = {
DevelopmentTeam = Z2V957B3D6;
@ -3313,6 +3346,7 @@
D38327F71580FE3A00FA0D23 /* settings_default.png in Resources */,
D38327F81580FE3A00FA0D23 /* settings_selected.png in Resources */,
D38327F91580FE3A00FA0D23 /* chat_default.png in Resources */,
6359DE801ADEB54200EA15C0 /* InAppProductsViewController.xib in Resources */,
D38327FA1580FE3A00FA0D23 /* chat_selected.png in Resources */,
D3832800158100E400FA0D23 /* contacts_over.png in Resources */,
D3832801158100E400FA0D23 /* history_over.png in Resources */,
@ -3349,6 +3383,7 @@
D3F83F581582223B00336684 /* numpad_five_default.png in Resources */,
D3F83F5A1582223B00336684 /* numpad_five_over.png in Resources */,
D3F83F5C1582223B00336684 /* numpad_six_default.png in Resources */,
6359DE851ADEB64100EA15C0 /* InAppProductsCell.xib in Resources */,
636316D91A1DECC90009B839 /* PhoneMainView.xib in Resources */,
D3F83F5E1582223B00336684 /* numpad_six_over.png in Resources */,
D3F83F601582223B00336684 /* numpad_seven_default.png in Resources */,
@ -3991,6 +4026,7 @@
D37C639515AADDAF009D0BAC /* UIContactDetailsHeader.m in Sources */,
D37C639B15AADEF6009D0BAC /* ContactDetailsTableViewController.m in Sources */,
636316DE1A1DEF2F0009B839 /* UIButtonShrinkable.m in Sources */,
63E59A3F1ADE70D900646FB3 /* InAppProductsManager.m in Sources */,
D3C6526715AC1A8F0092A874 /* UIEditableTableViewCell.m in Sources */,
D378906515AC373B00BD776C /* ContactDetailsLabelViewController.m in Sources */,
D3E8F68615ADE05B0065A226 /* UIContactDetailsFooter.m in Sources */,
@ -4018,10 +4054,13 @@
D3807FFC15C2894A005BE9BC /* IASKPSTitleValueSpecifierViewCell.m in Sources */,
D3807FFE15C2894A005BE9BC /* IASKSlider.m in Sources */,
D380800015C2894A005BE9BC /* IASKSwitch.m in Sources */,
6359DE8B1ADF9EB900EA15C0 /* InAppProductsTableViewController.m in Sources */,
D380800215C2894A005BE9BC /* IASKTextField.m in Sources */,
D380800515C28A7A005BE9BC /* UILinphone.m in Sources */,
D380801315C299D0005BE9BC /* ColorSpaceUtilites.m in Sources */,
6359DE7F1ADEB54200EA15C0 /* InAppProductsViewController.m in Sources */,
D378AB2A15DCDB4A0098505D /* ImagePickerViewController.m in Sources */,
6359DE841ADEB64100EA15C0 /* InAppProductsCell.m in Sources */,
22405F001601C19200B92522 /* ImageViewController.m in Sources */,
D3ED40191602172200BF332B /* HPGrowingTextView.m in Sources */,
D3ED401B1602172200BF332B /* HPTextViewInternal.m in Sources */,
@ -4513,6 +4552,7 @@
ARCHS = "$(ARCHS_STANDARD)";
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_WARN_UNREACHABLE_CODE = NO;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COMPRESS_PNG_FILES = NO;
@ -4531,7 +4571,8 @@
DEBUG,
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_TREAT_WARNINGS_AS_ERRORS = NO;
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
HEADER_SEARCH_PATHS = (
"$(SRCROOT)/liblinphone-sdk/apple-darwin/include",
"$(SRCROOT)/Classes/Utils/NinePatch/",
@ -4597,9 +4638,10 @@
ARCHS = "$(ARCHS_STANDARD)";
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_WARN_UNREACHABLE_CODE = NO;
CODE_SIGN_ENTITLEMENTS = "";
CODE_SIGN_IDENTITY = "iPhone Distribution";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COMPRESS_PNG_FILES = NO;
COPY_PHASE_STRIP = NO;
FRAMEWORK_SEARCH_PATHS = "";
@ -4615,7 +4657,8 @@
HAVE_OPENH264,
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_TREAT_WARNINGS_AS_ERRORS = NO;
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
HEADER_SEARCH_PATHS = (
"$(SRCROOT)/liblinphone-sdk/apple-darwin/include",
"$(SRCROOT)/Classes/Utils/NinePatch/",
@ -4681,6 +4724,7 @@
ARCHS = "$(ARCHS_STANDARD)";
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_WARN_UNREACHABLE_CODE = NO;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COMPRESS_PNG_FILES = NO;
@ -4697,7 +4741,8 @@
HAVE_SSL,
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_TREAT_WARNINGS_AS_ERRORS = NO;
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
HEADER_SEARCH_PATHS = (
"$(SRCROOT)/liblinphone-sdk/apple-darwin/include",
"$(SRCROOT)/Classes/Utils/NinePatch/",
@ -4763,9 +4808,10 @@
ARCHS = "$(ARCHS_STANDARD)";
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_WARN_UNREACHABLE_CODE = NO;
CODE_SIGN_ENTITLEMENTS = "";
CODE_SIGN_IDENTITY = "iPhone Distribution";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COMPRESS_PNG_FILES = NO;
COPY_PHASE_STRIP = NO;
FRAMEWORK_SEARCH_PATHS = "";
@ -4780,7 +4826,8 @@
HAVE_SSL,
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_TREAT_WARNINGS_AS_ERRORS = NO;
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
HEADER_SEARCH_PATHS = (
"$(SRCROOT)/liblinphone-sdk/apple-darwin/include",
"$(SRCROOT)/Classes/Utils/NinePatch/",
@ -5285,6 +5332,7 @@
HEADER_SEARCH_PATHS = (
"$(inherited)",
"$(SRCROOT)/liblinphone-sdk/apple-darwin/include",
"$(SRCROOT)/Classes/Utils/XMLRPC/",
);
INFOPLIST_FILE = KifTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
@ -5329,6 +5377,7 @@
HEADER_SEARCH_PATHS = (
"$(inherited)",
"$(SRCROOT)/liblinphone-sdk/apple-darwin/include",
"$(SRCROOT)/Classes/Utils/XMLRPC/",
);
INFOPLIST_FILE = KifTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
@ -5373,6 +5422,7 @@
HEADER_SEARCH_PATHS = (
"$(inherited)",
"$(SRCROOT)/liblinphone-sdk/apple-darwin/include",
"$(SRCROOT)/Classes/Utils/XMLRPC/",
);
INFOPLIST_FILE = KifTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
@ -5417,6 +5467,7 @@
HEADER_SEARCH_PATHS = (
"$(inherited)",
"$(SRCROOT)/liblinphone-sdk/apple-darwin/include",
"$(SRCROOT)/Classes/Utils/XMLRPC/",
);
INFOPLIST_FILE = KifTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";