fix: InAppPurchase pre-emptive deallocation (#40938)

* fix: InAppPurchase pre-emptive deallocation

* test: try re-enabling IAP tests
This commit is contained in:
Shelley Vohr 2024-01-11 13:32:29 +01:00 коммит произвёл GitHub
Родитель b39ebb8625
Коммит d5d162b622
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 11 добавлений и 9 удалений

Просмотреть файл

@ -26,6 +26,7 @@
in_app_purchase::InAppPurchaseCallback callback_; in_app_purchase::InAppPurchaseCallback callback_;
NSInteger quantity_; NSInteger quantity_;
NSString* username_; NSString* username_;
InAppPurchase __strong* self_;
} }
- (id)initWithCallback:(in_app_purchase::InAppPurchaseCallback)callback - (id)initWithCallback:(in_app_purchase::InAppPurchaseCallback)callback
@ -53,6 +54,7 @@
callback_ = std::move(callback); callback_ = std::move(callback);
quantity_ = quantity; quantity_ = quantity;
username_ = [username copy]; username_ = [username copy];
self_ = self;
} }
return self; return self;
@ -91,6 +93,7 @@
// Return if the product is not found or invalid. // Return if the product is not found or invalid.
if (product == nil) { if (product == nil) {
[self runCallback:false]; [self runCallback:false];
self_ = nil;
return; return;
} }
@ -114,6 +117,7 @@
// Notify that the payment has been added to the queue with success. // Notify that the payment has been added to the queue with success.
[self runCallback:true]; [self runCallback:true];
self_ = nil;
} }
/** /**
@ -128,10 +132,6 @@
} }
} }
- (void)dealloc {
username_ = nil;
}
@end @end
// ============================================================================ // ============================================================================

Просмотреть файл

@ -24,6 +24,7 @@
@interface InAppPurchaseProduct : NSObject <SKProductsRequestDelegate> { @interface InAppPurchaseProduct : NSObject <SKProductsRequestDelegate> {
@private @private
in_app_purchase::InAppPurchaseProductsCallback callback_; in_app_purchase::InAppPurchaseProductsCallback callback_;
InAppPurchaseProduct __strong* self_;
} }
- (id)initWithCallback:(in_app_purchase::InAppPurchaseProductsCallback)callback; - (id)initWithCallback:(in_app_purchase::InAppPurchaseProductsCallback)callback;
@ -43,6 +44,7 @@
(in_app_purchase::InAppPurchaseProductsCallback)callback { (in_app_purchase::InAppPurchaseProductsCallback)callback {
if ((self = [super init])) { if ((self = [super init])) {
callback_ = std::move(callback); callback_ = std::move(callback);
self_ = self;
} }
return self; return self;
@ -81,6 +83,7 @@
// Send the callback to the browser thread. // Send the callback to the browser thread.
content::GetUIThreadTaskRunner({})->PostTask( content::GetUIThreadTaskRunner({})->PostTask(
FROM_HERE, base::BindOnce(std::move(callback_), converted)); FROM_HERE, base::BindOnce(std::move(callback_), converted));
self_ = nil;
} }
/** /**

Просмотреть файл

@ -1,5 +1,6 @@
import { expect } from 'chai'; import { expect } from 'chai';
import { inAppPurchase } from 'electron/main'; import { inAppPurchase } from 'electron/main';
import { ifdescribe } from './lib/spec-helpers';
describe('inAppPurchase module', function () { describe('inAppPurchase module', function () {
if (process.platform !== 'darwin') return; if (process.platform !== 'darwin') return;
@ -33,11 +34,9 @@ describe('inAppPurchase module', function () {
expect(inAppPurchase.getReceiptURL()).to.match(/_MASReceipt\/receipt$/); expect(inAppPurchase.getReceiptURL()).to.match(/_MASReceipt\/receipt$/);
}); });
// The following three tests are disabled because they hit Apple servers, and // This fails on x64 in CI - likely owing to some weirdness with the machines.
// Apple started blocking requests from AWS IPs (we think), so they fail on CI. // We should look into fixing it there but at least run it on arm6 machines.
// TODO: find a way to mock out the server requests so we can test these APIs ifdescribe(process.arch !== 'x64')('handles product purchases', () => {
// without relying on a remote service.
xdescribe('handles product purchases', () => {
it('purchaseProduct() fails when buying invalid product', async () => { it('purchaseProduct() fails when buying invalid product', async () => {
const success = await inAppPurchase.purchaseProduct('non-exist'); const success = await inAppPurchase.purchaseProduct('non-exist');
expect(success).to.be.false('failed to purchase non-existent product'); expect(success).to.be.false('failed to purchase non-existent product');