Merge remote-tracking branch 'public/master' into dev_cmake

This commit is contained in:
Gautier Pelloux-Prayer 2015-06-01 12:28:57 +02:00
commit f9cfdbe8aa
82 changed files with 187 additions and 122 deletions

View file

@ -64,7 +64,7 @@
[linkLabel setText:NSLocalizedString(@"http://www.linphone.org", nil)];
[licenseLabel setText:NSLocalizedString(@"GNU General Public License V2 ", nil)];
[copyrightLabel setText:NSLocalizedString(@"© 2010-2012 Belledonne Communications ", nil)];
[copyrightLabel setText:NSLocalizedString(@"© 2010 Belledonne Communications ", nil)];
[linkLabel addGestureRecognizer:linkTapGestureRecognizer];

View file

@ -46,7 +46,14 @@ typedef NSString* IAPPurchaseNotificationStatus;
//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!
// 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 and:
//1 week = 3 minutes
//1 month = 5 minutes
//2 months = 10 minutes
//3 months = 15 minutes
//6 months = 30 minutes
//1 year = 1 hour
@interface InAppProductsManager : NSObject <SKProductsRequestDelegate, SKPaymentTransactionObserver> {
NSString *latestReceiptMD5;
@ -64,11 +71,16 @@ typedef NSString* IAPPurchaseNotificationStatus;
// TRUE if manager is available for usage - will be FALSE if an operation is already in progress or if not initialized or not enabled
@property (readonly) BOOL available;
// TRUE if accountActivate was started but we did not receive response from server yet
@property (readonly) BOOL accountActivationInProgress;
- (BOOL)isPurchasedWithID:(NSString*)productId;
// Purchase an account. You should not use this if manager is not available yet.
- (BOOL)purchaseAccount:(NSString *)phoneNumber withPassword:(NSString *)password andEmail:(NSString*)email;
- (BOOL)purchaseAccount:(NSString *)phoneNumber withPassword:(NSString *)password andEmail:(NSString*)email monthly:(BOOL)monthly;
// Purchase a product. You should not use this if manager is not available yet.
- (BOOL)purchaseWitID:(NSString *)productID;
// Activate purchased account.
- (BOOL)activateAccount:(NSString *)phoneNumber;
// restore user purchases. You should not use this if manager is not available yet. Must be at a user action ONLY.
- (BOOL)restore;

View file

@ -32,9 +32,10 @@
#import "InAppProductsViewController.h"
@interface InAppProductsManager()
@property (retain, nonatomic) NSDictionary *accountCreationData;
// needed because request:didFailWithError method is already used by SKProductsRequestDelegate...
@property (nonatomic, retain) InAppProductsXMLRPCDelegate *xmlrpc;
@property (retain, nonatomic) NSDate *expirationDate;
@property (retain, nonatomic) NSDictionary *accountCreationData;
// needed because request:didFailWithError method is already used by SKProductsRequestDelegate...
@property (nonatomic, retain) InAppProductsXMLRPCDelegate *xmlrpc;
@end
@implementation InAppProductsManager
@ -47,7 +48,7 @@
_enabled = (([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) && ([SKPaymentQueue canMakePayments]) && ([[LinphoneManager instance] lpConfigBoolForKey:@"enabled" forSection:@"in_app_purchase"]));
_initialized = false;
_available = false;
_accountActivationInProgress = false;
if (_enabled) {
self.xmlrpc = [[InAppProductsXMLRPCDelegate alloc] init];
_status = kIAPNotReady;
@ -64,7 +65,9 @@
if (!_enabled) return FALSE;
for (NSString *prod in _productsIDPurchased) {
if ([prod isEqual: productID]) {
NSDate *now = [[[NSDate alloc] init] autorelease];
// since multiple ID represent the same product, we must not check it
if (/*[prod isEqual: productID] &&*/[self.expirationDate earlierDate:now] == now) {
bool isBought = true;
LOGE(@"%@ is %s bought.", prod, isBought?"":"NOT");
return isBought;
@ -75,7 +78,7 @@
- (BOOL)purchaseWitID:(NSString *)productID {
if (!_enabled||!_initialized||!_available) {
NSDictionary* dict = @{@"product_id":productID, @"error_msg": NSLocalizedString(@"In apps not ready yet", nil)};
NSDictionary* dict = @{@"product_id":productID, @"error_msg": NSLocalizedString(@"Cannot purchase anything yet, please try again later.", nil)};
[self postNotificationforStatus:kIAPPurchaseFailed withDict:dict];
return FALSE;
}
@ -95,9 +98,9 @@
}
}
- (BOOL)purchaseAccount:(NSString *)phoneNumber withPassword:(NSString *)password andEmail:(NSString*)email {
- (BOOL)purchaseAccount:(NSString *)phoneNumber withPassword:(NSString *)password andEmail:(NSString*)email monthly:(BOOL)monthly {
if (phoneNumber) {
NSString* productID = [[LinphoneManager instance] lpConfigStringForKey:@"paid_account_id" forSection:@"in_app_purchase"];
NSString* productID = [[LinphoneManager instance] lpConfigStringForKey:(monthly?@"paid_account_id_monthly":@"paid_account_id") forSection:@"in_app_purchase"];
self.accountCreationData = @{ @"phoneNumber":[phoneNumber retain], @"password":[password retain], @"email":[email retain] };
if (![self purchaseWitID:productID]) {
@ -108,6 +111,34 @@
return false;
}
- (BOOL)activateAccount:(NSString *)phoneNumber {
if (phoneNumber) {
NSString *receiptBase64 = [self getReceipt];
if (receiptBase64) {
NSURL *URL = [NSURL URLWithString:[[LinphoneManager instance] lpConfigStringForKey:@"receipt_validation_url" forSection:@"in_app_purchase"]];
XMLRPCRequest *request = [[XMLRPCRequest alloc] initWithURL: URL];
//buying for the first time: need to create the account
//if ([transaction.transactionIdentifier isEqualToString:transaction.originalTransaction.transactionIdentifier]) {
[request setMethod: @"activate_account" withParameters:[NSArray arrayWithObjects:
@"",
phoneNumber,
receiptBase64,
@"",
@"apple",
nil]];
_accountActivationInProgress = YES;
XMLRPCConnectionManager *manager = [XMLRPCConnectionManager sharedManager];
[manager spawnConnectionWithXMLRPCRequest: request delegate: self.xmlrpc];
LOGI(@"XMLRPC query %@", [request method]);
[request release];
return true;
} else {
LOGE(@"Trying to activate account but no receipt available yet (probably doing it too soon)");
}
}
return false;
}
-(BOOL)restore {
if (!_enabled||!_initialized||!_available) {
NSDictionary* dict = @{@"error_msg": NSLocalizedString(@"In apps not ready yet", nil)};
@ -197,70 +228,66 @@
}
}
- (void)validateReceipt: (SKPaymentTransaction*)transaction {
NSString *receiptBase64 = nil;
- (NSString*) getReceipt {
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...
return nil;
}
NSString *receiptBase64 = [[NSData dataWithContentsOfURL:receiptURL] base64EncodedStringWithOptions:0];
LOGI(@"Found appstore receipt %@", [receiptBase64 md5]);
return receiptBase64;
}
- (void)validateReceipt: (SKPaymentTransaction*)transaction {
NSString *receiptBase64 = [self getReceipt];
if (receiptBase64 == nil) {
SKRequest* req = [[SKReceiptRefreshRequest alloc] init];
LOGI(@"Receipt not found yet, trying to retrieve it...");
req.delegate = self;
[req start];
return;
}
receiptBase64 = [[NSData dataWithContentsOfURL:receiptURL] base64EncodedStringWithOptions:0];
LOGI(@"Found appstore receipt %@", [receiptBase64 md5]);
//only check the receipt if it has changed
if (latestReceiptMD5 == nil || ![latestReceiptMD5 isEqualToString:[receiptBase64 md5]]) {
// transaction is null when restoring user purchases at application start or if user clicks the "restore" button
// 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];
// transaction is null when restoring user purchases at application start or if user clicks the "restore" button
if (!transaction || [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]) {
if (self.accountCreationData.count == 3) {
[request setMethod: @"create_account_from_in_app_purchase" withParameters:[NSArray arrayWithObjects:
@"",
[_accountCreationData objectForKey:@"phoneNumber"],
receiptBase64,
@"",
@"apple",
[_accountCreationData objectForKey:@"email"],
nil]];
self.accountCreationData = nil;
// otherwise simply renewing
} else {
if ([[self getPhoneNumber] length] > 0) {
//buying for the first time: need to create the account
//if ([transaction.transactionIdentifier isEqualToString:transaction.originalTransaction.transactionIdentifier]) {
if (self.accountCreationData.count == 3) {
[request setMethod: @"create_account_from_in_app_purchase" withParameters:[NSArray arrayWithObjects:
@"",
[_accountCreationData objectForKey:@"phoneNumber"],
receiptBase64,
@"",
@"apple",
[_accountCreationData objectForKey:@"email"],
nil]];
self.accountCreationData = nil;
// otherwise simply renewing
} else {
if ([[self getPhoneNumber] length] > 0) {
[request setMethod: @"get_expiration_date" withParameters:[NSArray arrayWithObjects:
[self getPhoneNumber],
receiptBase64,
@"",
@"apple",
nil]];
} else {
LOGW(@"No SIP URI configured, doing nothing");
_available = true;
return;
}
} else {
LOGW(@"No SIP URI configured, doing nothing");
_available = true;
return;
}
} else {
LOGE(@"Hum, not handling product with ID %@", transaction.payment.productIdentifier);
_available = true;
return;
}
latestReceiptMD5 = [[receiptBase64 md5] retain];
XMLRPCConnectionManager *manager = [XMLRPCConnectionManager sharedManager];
[manager spawnConnectionWithXMLRPCRequest: request delegate: self.xmlrpc];
LOGI(@"XMLRPC query %@: %@", [request method], [request body]);
LOGI(@"XMLRPC query %@", [request method]);
[request release];
} else {
LOGW(@"Not checking receipt since it has already been done!");
@ -311,7 +338,7 @@
NSDictionary* dict = @{@"product_id": transaction.payment.productIdentifier};
[self postNotificationforStatus:kIAPPurchaseCancelled withDict:dict];
} else {
NSString* errlast = [NSString stringWithFormat:@"Purchase of %@ failed: %@.",transaction.payment.productIdentifier,transaction.error.localizedDescription];
NSString* errlast = [NSString stringWithFormat:@"Purchase failed: %@.",transaction.error.localizedDescription];
LOGE(@"SKPaymentTransactionStateFailed: %@", errlast);
NSDictionary* dict = @{@"product_id": transaction.payment.productIdentifier, @"error_msg": errlast};
[self postNotificationforStatus:kIAPPurchaseFailed withDict:dict];
@ -324,7 +351,7 @@
- (void)paymentQueue:(SKPaymentQueue *)queue removedTransactions:(NSArray *)transactions {
for(SKPaymentTransaction * transaction in transactions) {
LOGI(@"%@ was removed from the payment queue.", transaction.payment.productIdentifier);
LOGD(@"%@ was removed from the payment queue.", transaction.payment.productIdentifier);
}
}
@ -350,6 +377,10 @@
_available = true;
if ([[request method] isEqualToString:@"activate_account"]) {
_accountActivationInProgress = NO;
}
LOGI(@"XMLRPC response %@: %@", [request method], [response body]);
NSString* productID = [[LinphoneManager instance] lpConfigStringForKey:@"paid_account_id" forSection:@"in_app_purchase"];
@ -361,22 +392,26 @@
// response object can either be expiration date (long long number or an error string)
double timeinterval = [[response object] doubleValue];
if (timeinterval != 0.0f) {
NSDate *expirationDate = [NSDate dateWithTimeIntervalSince1970:timeinterval/1000];
NSDate *now = [[NSDate alloc] init];
NSDictionary* dict = @{@"product_id": productID, @"expires_date": expirationDate};
if ([expirationDate earlierDate:now] == expirationDate) {
self.expirationDate = [NSDate dateWithTimeIntervalSince1970:timeinterval/1000];
NSDate *now = [[[NSDate alloc] init] autorelease];
NSDictionary* dict = @{@"product_id": productID, @"expires_date": self.expirationDate};
if ([self.expirationDate earlierDate:now] == self.expirationDate) {
LOGW(@"Account has expired");
[self postNotificationforStatus:kIAPPurchaseExpired withDict:dict];
} else {
LOGI(@"Account valid until %@", self.expirationDate);
[_productsIDPurchased addObject:productID];
[self postNotificationforStatus:kIAPPurchaseSucceeded withDict:dict];
}
} else {
self.expirationDate = nil;
NSString *error = [response object];
LOGE(@"Failed with error %@", error);
NSString *errorMsg;
if ([error isEqualToString:@"ERROR_ACCOUNT_ALREADY_EXISTS"]) {
errorMsg=NSLocalizedString(@"You have already registered an account.", nil);
errorMsg=NSLocalizedString(@"This account is already registered.", nil);
} else if ([error isEqualToString:@"ERROR_UID_ALREADY_IN_USE"]) {
errorMsg=NSLocalizedString(@"You already own an account.", nil);
} else if ([error isEqualToString:@"ERROR_ACCOUNT_DOESNT_EXIST"]) {
errorMsg=NSLocalizedString(@"You have already purchased an account but it does not exist anymore.", nil);
} else if ([error isEqualToString:@"ERROR_PURCHASE_CANCELLED"]) {
@ -415,6 +450,10 @@
_available = true;
if ([[request method] isEqualToString:@"activate_account"]) {
_accountActivationInProgress = NO;
}
LOGE(@"Communication issue (%@)", [error localizedDescription]);
NSString *errorString = [NSString stringWithFormat:NSLocalizedString(@"Communication issue (%@)", nil), [error localizedDescription]];
UIAlertView* errorView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Communication issue", nil)
@ -434,7 +473,7 @@
[[NSNotificationCenter defaultCenter] postNotificationName:status object:self userInfo:nil];
LOGE(@"Not supported, triggering %@", status);
}
- (BOOL)purchaseAccount:(NSString *)phoneNumber withPassword:(NSString *)password andEmail:(NSString*)email { [self postNotificationforStatus:kIAPPurchaseFailed]; return false; }
- (BOOL)purchaseAccount:(NSString *)phoneNumber withPassword:(NSString *)password andEmail:(NSString *)email monthly:(BOOL)monthly { [self postNotificationforStatus:kIAPPurchaseFailed]; return false; }
- (BOOL)restore { [self postNotificationforStatus:kIAPRestoreFailed]; return false; }
- (BOOL)retrievePurchases { [self postNotificationforStatus:kIAPRestoreFailed]; return false; }
- (BOOL)purchaseWitID:(NSString *)productID { [self postNotificationforStatus:kIAPPurchaseFailed]; return FALSE; }
@ -444,6 +483,7 @@
- (void)XMLRPCRequest:(XMLRPCRequest *)request didReceiveResponse:(XMLRPCResponse *)response { }
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions { }
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response { }
- (BOOL)activateAccount:(NSString *)phoneNumber { return FALSE; }
#endif
@end
@ -470,6 +510,6 @@
}
- (void)request:(XMLRPCRequest *)request didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
}
@end

View file

@ -194,11 +194,7 @@ struct codec_name_pref_table codec_pref_table[]={
}
+ (BOOL)runningOnIpad {
#ifdef UI_USER_INTERFACE_IDIOM
return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
#else
return NO;
#endif
return ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad);
}
+ (BOOL)isRunningTests {
@ -299,8 +295,6 @@ struct codec_name_pref_table codec_pref_table[]={
#endif
}
_iapManager = [[InAppProductsManager alloc] init];
[self migrateFromUserPrefs];
}
return self;
@ -1403,6 +1397,8 @@ static BOOL libStarted = FALSE;
// create linphone core
[self createLinphoneCore];
_iapManager = [[InAppProductsManager alloc] init];
linphone_core_migrate_to_multi_transport(theLinphoneCore);
// init audio session (just getting the instance will init)

View file

@ -172,7 +172,7 @@
// Set selected+over background: IB lack !
[speakerButton setBackgroundImage:[UIImage imageNamed:@"speaker_on_over.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
[speakerButtonLandscape setBackgroundImage:[UIImage imageNamed:@"sspeaker_on_over_landscape.png"]
[speakerButtonLandscape setBackgroundImage:[UIImage imageNamed:@"speaker_on_over_landscape.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
[LinphoneUtils buttonFixStates:speakerButton];

View file

@ -626,7 +626,7 @@ static RootViewManager* rootViewManagerInstance = nil;
}
if (linphone_call_get_reason(call) == LinphoneReasonNotFound) {
lMessage = [NSString stringWithFormat : NSLocalizedString(@"'%@' not registered", nil), lUserName];
lMessage = [NSString stringWithFormat : NSLocalizedString(@"%@ not registered", nil), lUserName];
} else {
if (message != nil) {
lMessage = [NSString stringWithFormat : NSLocalizedString(@"%@\nReason was: %@", nil), lMessage, message];

View file

@ -595,6 +595,10 @@ static UICompositeViewDescription *compositeDescription = nil;
LinphoneManager* lm = [LinphoneManager instance];
NSMutableSet *hiddenKeys = [NSMutableSet set];
#ifndef HAVE_SSL
[hiddenKeys addObject:@"media_encryption_preference"];
#endif
#ifndef DEBUG
[hiddenKeys addObject:@"release_button"];
[hiddenKeys addObject:@"clear_cache_button"];

View file

@ -933,7 +933,7 @@ static UICompositeViewDescription *compositeDescription = nil;
NSString *identity = [self identityFromUsername:username];
[self checkUserExist:identity];
} else {
[iapm purchaseAccount:username withPassword:password andEmail:email];
[iapm purchaseAccount:username withPassword:password andEmail:email monthly:FALSE];
// inAppPurchaseNotification will take care of bringing us to the next view now
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -16,7 +16,7 @@
<key>Key</key>
<string>speex_16k_preference</string>
<key>Title</key>
<string>Speex 16Khz</string>
<string>Speex 16kHz</string>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
</dict>
@ -26,7 +26,7 @@
<key>Key</key>
<string>speex_8k_preference</string>
<key>Title</key>
<string>Speex 8Khz</string>
<string>Speex 8kHz</string>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
</dict>
@ -46,7 +46,7 @@
<key>Key</key>
<string>silk_24k_preference</string>
<key>Title</key>
<string>Silk 24Khz</string>
<string>Silk 24kHz</string>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
</dict>
@ -56,7 +56,7 @@
<key>Key</key>
<string>silk_16k_preference</string>
<key>Title</key>
<string>Silk 16Khz</string>
<string>Silk 16kHz</string>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
</dict>
@ -128,7 +128,7 @@
<key>Key</key>
<string>g722_preference</string>
<key>Title</key>
<string>G722</string>
<string>G.722</string>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
</dict>
@ -138,7 +138,7 @@
<key>Key</key>
<string>g729_preference</string>
<key>Title</key>
<string>G729</string>
<string>G.729</string>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
</dict>
@ -158,7 +158,7 @@
<key>Key</key>
<string>ilbc_preference</string>
<key>Title</key>
<string>ILBC</string>
<string>iLBC</string>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
</dict>

View file

@ -28,7 +28,7 @@
<key>Key</key>
<string>substitute_+_by_00_preference</string>
<key>Title</key>
<string>Substitue + by 00</string>
<string>Substitute + by 00</string>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
</dict>

View file

@ -74,7 +74,7 @@
<key>Key</key>
<string>mp4v-es_preference</string>
<key>Title</key>
<string>mpeg4</string>
<string>MPEG-4</string>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
</dict>
@ -84,7 +84,7 @@
<key>Key</key>
<string>h264_preference</string>
<key>Title</key>
<string>h264</string>
<string>H.264</string>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
</dict>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,19 +1,19 @@
"Codecs" = "Codecs";
"Speex 16Khz" = "Speex 16Khz";
"Speex 8Khz" = "Speex 8Khz";
"Speex 16kHz" = "Speex 16kHz";
"Speex 8kHz" = "Speex 8kHz";
"Opus 48kHz" = "Opus 48kHz";
"Silk 24Khz" = "Silk 24Khz";
"Silk 16Khz" = "Silk 16Khz";
"Silk 24kHz" = "Silk 24kHz";
"Silk 16kHz" = "Silk 16kHz";
"AAC-ELD 16kHz" = "AAC-ELD 16kHz";
"AAC-ELD 22kHz" = "AAC-ELD 22kHz";
"AAC-ELD 32kHz" = "AAC-ELD 32kHz";
"AAC-ELD 44kHz" = "AAC-ELD 44kHz";
"AAC-ELD 48kHz" = "AAC-ELD 48kHz";
"AMR" = "AMR";
"G722" = "G722";
"G729" = "G729";
"G.722" = "G.722";
"G.729" = "G.729";
"GSM" = "GSM";
"ILBC" = "ILBC";
"iLBC" = "iLBC";
"PCMU" = "PCMU";
"PCMA" = "PCMA";
"Advanced" = "Advanced";

View file

@ -1,5 +1,5 @@
"Prefix" = "Prefix";
"Substitue + by 00" = "Substitue + by 00";
"Substitute + by 00" = "Substitute + by 00";
"Send inband DTMFs" = "Send inband DTMFs";
"Send SIP INFO DTMFs" = "Send SIP INFO DTMFs";
"Incoming call timeout" = "Incoming call timeout";

View file

@ -18,6 +18,7 @@
"Network" = "Network";
"Tunnel" = "Tunnel";
"Advanced" = "Advanced";
"Extra features" = "Extra features";
"Development debug actions" = "Development debug actions";
"About" = "About";
"Quit" = "Quit";

View file

@ -4,6 +4,6 @@
"Show preview" = "Show preview";
"Preferred video size" = "Preferred video size";
"Codecs" = "Codecs";
"mpeg4" = "mpeg4";
"h264" = "h264";
"MPEG-4" = "MPEG-4";
"H.264" = "H.264";
"VP8" = "VP8";

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,39 +1,39 @@
#!/usr/bin/env bash
#!/bin/bash -x
# Install underscore-cli for hacking
if ! which underscore &> /dev/null; then
npm install -g underscore-cli
npm install -g underscore-cli
fi
cd Screens
# Prepare location to collect delete commands
if test "$TRAVIS_BUILD_NUMBER" = ""; then
TRAVIS_BUILD_NUMBER="dev"
fi
output_dir="Screens"
download_cmds=""
if "*.png" 2>/dev/null; then
# Prepare location to collect delete commands
if test "$TRAVIS_BUILD_NUMBER" = ""; then
TRAVIS_BUILD_NUMBER="dev"
fi
output_dir="Screens"
download_cmds=""
# curl from http://imgur.com/tools/imgurbash.sh via http://imgur.com/tools
# Documentation: http://code.google.com/p/imgur-api/source/browse/wiki/ImageUploading.wiki?r=82
api_key=$IMGUR_KEY
oIFS=$IFS
IFS=$'\n'
for filepath in $(find . -name '*.png'); do
# echo "File $filepath"
# echo "Command: curl https://api.imgur.com/3/upload.json -H \"Authorization: Client-ID $api_key\" -F "image=@\"$filepath\"""
result="$(curl https://api.imgur.com/3/upload.json -H "Authorization: Client-ID $api_key" -F "image=@\"$filepath\"" )"
# result='{"rsp":{"stat":"ok","image":{"image_hash":"dKZ0YK9","delete_hash":"r0MsZp11K9vawLf","original_image":"http:\/\/i.imgur.com\/dKZ0YK9.png","large_thumbnail":"http:\/\/i.imgur.com\/dKZ0YK9l.jpg","small_thumbnail":"http:\/\/i.imgur.com\/dKZ0YK9s.jpg","imgur_page":"http:\/\/imgur.com\/dKZ0YK9","delete_page":"http:\/\/imgur.com\/delete\/r0MsZp11K9vawLf"}}}'
lol="$(echo $result | underscore extract success)"
if test $lol != "true"; then
echo "There was a problem uploading \"$filepath\"" 1>&2
echo "$result" 1>&2
else
download_cmds="${download_cmds}wget $(echo "$result" | underscore extract 'data.link')\n"
fi
done
IFS=$oIFS
echo "All uploads complete!"
echo ""
echo "Download via:"
echo -e " $download_cmds"
# curl from http://imgur.com/tools/imgurbash.sh via http://imgur.com/tools
# Documentation: http://code.google.com/p/imgur-api/source/browse/wiki/ImageUploading.wiki?r=82
api_key=$IMGUR_KEY
for filepath in *.png; do
# echo "File $filepath"
# echo "Command: curl https://api.imgur.com/3/upload.json -H \"Authorization: Client-ID $api_key\" -F "image=@\"$filepath\"""
result="$(curl https://api.imgur.com/3/upload.json -H "Authorization: Client-ID $api_key" -F "image=@\"$filepath\"" )"
# result='{"rsp":{"stat":"ok","image":{"image_hash":"dKZ0YK9","delete_hash":"r0MsZp11K9vawLf","original_image":"http:\/\/i.imgur.com\/dKZ0YK9.png","large_thumbnail":"http:\/\/i.imgur.com\/dKZ0YK9l.jpg","small_thumbnail":"http:\/\/i.imgur.com\/dKZ0YK9s.jpg","imgur_page":"http:\/\/imgur.com\/dKZ0YK9","delete_page":"http:\/\/imgur.com\/delete\/r0MsZp11K9vawLf"}}}'
succeeded="$(echo $result | underscore extract success)"
if [ "$succeeded" != "true" ]; then
echo "There was a problem uploading \"$filepath\": $result"
else
download_cmds="${download_cmds}wget $(echo "$result" | underscore extract 'data.link')\n"
fi
done
echo "All uploads complete!"
echo ""
echo "Download via: $download_cmds"
else
echo "Could not find any PNG in $PWD, something must be broken!"
fi

View file

@ -47,15 +47,19 @@ already_sync=$(mktemp -t tag_missing_resources)
to_sync=$(mktemp -t tag_missing_resources)
grep -oE '([^ /"])*.png' ../linphone.xcodeproj/project.pbxproj | sort -u > $already_sync
find ../Resources/ -name *.png -exec basename {} \; | sort -u > $to_sync
find ../Resources/ -not -path '*/Images.xcassets/*' -name '*.png' -exec basename {} \; | sort -u > $to_sync
# clean red tags
cd ../Resources && tag -r red $(cat $to_sync $already_sync) && cd - 1>/dev/null
for file in $to_sync $already_sync; do
find ../Resources -name $file -exec tag -r red {} \;
done
# 'comm' command output files contained in second file but not in first nor in common
non_synced_files=$(comm -13 $already_sync $to_sync)
cd ../Resources/ && tag -a red $non_synced_files && cd - 1>/dev/null
for file in $non_synced_files; do
find ../Resources -name $file -exec tag -a red {} \;
done
rm $already_sync $to_sync

View file

@ -126,6 +126,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 */; };
63D2680F1B174A5E00A2CC11 /* numpad_one_voicemail_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 63D2680D1B174A5E00A2CC11 /* numpad_one_voicemail_default.png */; };
63D268101B174A5E00A2CC11 /* numpad_one_voicemail_over.png in Resources */ = {isa = PBXBuildFile; fileRef = 63D2680E1B174A5E00A2CC11 /* numpad_one_voicemail_over.png */; };
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 */; };
@ -1045,6 +1047,8 @@
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>"; };
63D2680D1B174A5E00A2CC11 /* numpad_one_voicemail_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = numpad_one_voicemail_default.png; path = Resources/numpad_one_voicemail_default.png; sourceTree = "<group>"; };
63D2680E1B174A5E00A2CC11 /* numpad_one_voicemail_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = numpad_one_voicemail_over.png; path = Resources/numpad_one_voicemail_over.png; sourceTree = "<group>"; };
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>"; };
@ -2806,6 +2810,8 @@
D3F83F3F1582223B00336684 /* numpad_nine_over.png */,
D3F83F2E1582223B00336684 /* numpad_one_default.png */,
D3F83F2F1582223B00336684 /* numpad_one_over.png */,
63D2680D1B174A5E00A2CC11 /* numpad_one_voicemail_default.png */,
63D2680E1B174A5E00A2CC11 /* numpad_one_voicemail_over.png */,
D3F83F3A1582223B00336684 /* numpad_seven_default.png */,
D3F83F3B1582223B00336684 /* numpad_seven_over.png */,
D3F83F401582223B00336684 /* numpad_sharp_default.png */,
@ -3328,6 +3334,7 @@
70571E1A13FABCB000CDD3C2 /* rootca.pem in Resources */,
D347347E1580E5F8003C7B8C /* history_default.png in Resources */,
D347347F1580E5F8003C7B8C /* history_selected.png in Resources */,
63D268101B174A5E00A2CC11 /* numpad_one_voicemail_over.png in Resources */,
D38327F31580FE3A00FA0D23 /* contacts_default.png in Resources */,
D38327F41580FE3A00FA0D23 /* contacts_selected.png in Resources */,
D38327F51580FE3A00FA0D23 /* dialer_default.png in Resources */,
@ -3528,6 +3535,7 @@
639CEB061A1DF4F1004DE38F /* UIChatRoomCell.xib in Resources */,
D3A8BB7B15A6CC3200F96BE5 /* chat_bubble_outgoing.png in Resources */,
D3A8BB7D15A6CC3200F96BE5 /* chat_bubble_incoming.png in Resources */,
63D2680F1B174A5E00A2CC11 /* numpad_one_voicemail_default.png in Resources */,
F0C1F9101A28781F009402C9 /* corner-left-bottom.png in Resources */,
D3A8BB7F15A6CC3200F96BE5 /* setup_back_disabled.png in Resources */,
D3A8BB8115A6CC3200F96BE5 /* setup_cancel_disabled.png in Resources */,

@ -1 +1 @@
Subproject commit 97bdfd1f51c441c441e713de8c1d50cd037cda5d
Subproject commit 1ffd890571879bba9a58251dfe7dd5249c011517