summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaurice Kalinowski <maurice.kalinowski@qt.io>2016-09-20 12:36:32 +0200
committerMaurice Kalinowski <maurice.kalinowski@qt.io>2016-09-21 10:03:20 +0000
commit9aa3e78fd1cc5ceceea6ccc647a04707c9260c23 (patch)
tree8fe336cb0975e316f558070f9bfccafa6b7be176
parent2b917aae1befd1cf5c047050607097f63cd583e8 (diff)
winrt: Fix thread affinity for transactionsv5.8.0-beta1
Native callbacks do not give any guarantee on the thread it is invoked on. For latest Windows 10 preview builds purchase result callbacks are happening on another thread. This causes problems instantiating a new transaction object. Hence, delay the allocation for the backend thread. Change-Id: I89df5e55de5e7c75cfa36662c330a5cf2434c3d3 Reviewed-by: Oliver Wolff <oliver.wolff@qt.io> Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
-rw-r--r--src/purchasing/inapppurchase/winrt/qwinrtinapppurchasebackend.cpp39
-rw-r--r--src/purchasing/inapppurchase/winrt/qwinrtinapppurchasebackend_p.h32
2 files changed, 56 insertions, 15 deletions
diff --git a/src/purchasing/inapppurchase/winrt/qwinrtinapppurchasebackend.cpp b/src/purchasing/inapppurchase/winrt/qwinrtinapppurchasebackend.cpp
index 68920d2..37ed8a9 100644
--- a/src/purchasing/inapppurchase/winrt/qwinrtinapppurchasebackend.cpp
+++ b/src/purchasing/inapppurchase/winrt/qwinrtinapppurchasebackend.cpp
@@ -260,16 +260,13 @@ inline bool compareProductTypes(QInAppProduct::ProductType qtType, ProductType n
return false;
}
-QWinRTInAppTransaction* createTransaction(AsyncStatus status,
- QWinRTInAppProduct *product,
- QWinRTInAppPurchaseBackend *backend,
- QString receipt = QString())
+void QWinRTInAppPurchaseBackend::createTransactionDelayed(qt_WinRTTransactionData data)
{
- QInAppTransaction::TransactionStatus qStatus = (status == AsyncStatus::Completed) ?
+ QInAppTransaction::TransactionStatus qStatus = (data.status == AsyncStatus::Completed) ?
QInAppTransaction::PurchaseApproved : QInAppTransaction::PurchaseFailed;
QInAppTransaction::FailureReason reason;
- switch (status) {
+ switch (data.status) {
case AsyncStatus::Completed:
reason = QInAppTransaction::NoFailure;
break;
@@ -282,8 +279,11 @@ QWinRTInAppTransaction* createTransaction(AsyncStatus status,
break;
}
- auto transaction = new QWinRTInAppTransaction(qStatus, product, reason, receipt, backend);
- return transaction;
+ auto transaction = new QWinRTInAppTransaction(qStatus, data.product, reason, data.receipt, this);
+ transaction->m_purchaseResults = data.purchaseResults;
+ emit transactionReady(transaction);
+
+ return;
}
class QWinRTInAppPurchaseBackendPrivate
@@ -310,6 +310,9 @@ QWinRTInAppPurchaseBackend::QWinRTInAppPurchaseBackend(QObject *parent)
: QInAppPurchaseBackend(parent)
{
d_ptr.reset(new QWinRTInAppPurchaseBackendPrivate(this));
+
+ qRegisterMetaType<qt_WinRTTransactionData>("TransactionData");
+
qCDebug(lcPurchasingBackend) << __FUNCTION__;
}
@@ -568,8 +571,10 @@ void QWinRTInAppPurchaseBackend::purchaseProduct(QWinRTInAppProduct *product)
else
qWarning("Could not receive transaction receipt.");
- auto transaction = createTransaction(status, product, this, receiptQ);
- emit transactionReady(transaction);
+ qt_WinRTTransactionData tData(status, product, receiptQ);
+ QMetaObject::invokeMethod(this, "createTransactionDelayed", Qt::QueuedConnection,
+ Q_ARG(qt_WinRTTransactionData, tData));
+
return S_OK;
});
hr = appOp->put_Completed(purchaseCallback.Get());
@@ -593,8 +598,10 @@ void QWinRTInAppPurchaseBackend::purchaseProduct(QWinRTInAppProduct *product)
else
qWarning("Could not receive transaction receipt.");
- auto transaction = createTransaction(status, product, this, receiptQ);
- emit transactionReady(transaction);
+ qt_WinRTTransactionData tData(status, product, receiptQ);
+ QMetaObject::invokeMethod(this, "createTransactionDelayed", Qt::QueuedConnection,
+ Q_ARG(qt_WinRTTransactionData, tData));
+
return S_OK;
});
hr = purchaseOp->put_Completed(purchaseCallback.Get());
@@ -623,9 +630,11 @@ void QWinRTInAppPurchaseBackend::purchaseProduct(QWinRTInAppProduct *product)
Q_ASSERT_SUCCEEDED(hr);
receiptQ = hStringToQString(receiptH);
}
- auto transaction = createTransaction(status, product, this, receiptQ);
- transaction->m_purchaseResults = purchaseResults;
- emit transactionReady(transaction);
+
+ qt_WinRTTransactionData tData(status, product, receiptQ, purchaseResults);
+ QMetaObject::invokeMethod(this, "createTransactionDelayed", Qt::QueuedConnection,
+ Q_ARG(qt_WinRTTransactionData, tData));
+
return S_OK;
});
diff --git a/src/purchasing/inapppurchase/winrt/qwinrtinapppurchasebackend_p.h b/src/purchasing/inapppurchase/winrt/qwinrtinapppurchasebackend_p.h
index ce83b79..af48908 100644
--- a/src/purchasing/inapppurchase/winrt/qwinrtinapppurchasebackend_p.h
+++ b/src/purchasing/inapppurchase/winrt/qwinrtinapppurchasebackend_p.h
@@ -44,11 +44,41 @@
#include "qinappproduct.h"
#include "qinapptransaction.h"
+#include <Windows.ApplicationModel.store.h>
+#include <wrl.h>
+
+namespace ABI {
+ namespace Windows {
+ namespace Foundation {
+ enum class AsyncStatus;
+ }
+ }
+}
+
QT_BEGIN_NAMESPACE
class QWinRTInAppProduct;
class QWinRTInAppPurchaseBackendPrivate;
class QWinRTInAppTransaction;
+class QWinRTInAppPurchaseBackend;
+
+struct qt_WinRTTransactionData
+{
+ qt_WinRTTransactionData() { }
+ explicit qt_WinRTTransactionData(ABI::Windows::Foundation::AsyncStatus s,
+ QWinRTInAppProduct *p,
+ const QString &r,
+ Microsoft::WRL::ComPtr<ABI::Windows::ApplicationModel::Store::IPurchaseResults> pRes = Microsoft::WRL::ComPtr<ABI::Windows::ApplicationModel::Store::IPurchaseResults>())
+ : status(s)
+ , product(p)
+ , receipt(r)
+ , purchaseResults(pRes)
+ { }
+ ABI::Windows::Foundation::AsyncStatus status;
+ QWinRTInAppProduct *product;
+ QString receipt;
+ Microsoft::WRL::ComPtr<ABI::Windows::ApplicationModel::Store::IPurchaseResults> purchaseResults;
+};
class QWinRTInAppPurchaseBackend : public QInAppPurchaseBackend
{
@@ -68,6 +98,8 @@ public:
void purchaseProduct(QWinRTInAppProduct *product);
void fulfillConsumable(QWinRTInAppTransaction *transaction);
+public slots:
+ void createTransactionDelayed(qt_WinRTTransactionData data);
private:
QScopedPointer<QWinRTInAppPurchaseBackendPrivate> d_ptr;
Q_DECLARE_PRIVATE(QWinRTInAppPurchaseBackend)