From 2495de66a0895f14f27eba9ad6a1ef4b0e7014e7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 15 Jul 2025 17:32:35 +0000 Subject: [PATCH 01/11] Initial plan From efe73aaca30999d6f773e3f2b0fdb6aca7359494 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 15 Jul 2025 18:23:08 +0000 Subject: [PATCH 02/11] Restore QueryProductDetailsResult and fix QueryProductDetailsAsync behavior Co-authored-by: jonathanpeppers <840039+jonathanpeppers@users.noreply.github.com> --- config.json | 2 +- .../billing/Additions/Additions.cs | 19 +++++++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/config.json b/config.json index b332f8e4a..fa1588321 100644 --- a/config.json +++ b/config.json @@ -2167,7 +2167,7 @@ "groupId": "com.android.billingclient", "artifactId": "billing", "version": "8.0.0", - "nugetVersion": "8.0.0", + "nugetVersion": "8.0.0.1", "nugetId": "Xamarin.Android.Google.BillingClient", "type": "xbd" }, diff --git a/source/com.android.billingclient/billing/Additions/Additions.cs b/source/com.android.billingclient/billing/Additions/Additions.cs index bdcb50dd3..266d7e830 100644 --- a/source/com.android.billingclient/billing/Additions/Additions.cs +++ b/source/com.android.billingclient/billing/Additions/Additions.cs @@ -27,6 +27,13 @@ public class QuerySkuDetailsResult public IList SkuDetails { get; set; } } + public class QueryProductDetailsResult + { + public BillingResult Result { get; set; } + + public IList ProductDetails { get; set; } + } + public class QueryPurchasesResult { public BillingResult Result { get; set; } @@ -117,7 +124,11 @@ public Task QueryProductDetailsAsync(QueryProductDeta var listener = new InternalProductDetailsResponseListener { - ProductDetailsResponseHandler = (r, queryResult) => tcs.TrySetResult(queryResult) + ProductDetailsResponseHandler = (r, s) => tcs.TrySetResult(new QueryProductDetailsResult + { + Result = r, + ProductDetails = s + }) }; QueryProductDetails(productDetailsParams, listener); @@ -238,10 +249,10 @@ public void OnSkuDetailsResponse(BillingResult result, IList skuDeta internal class InternalProductDetailsResponseListener : Java.Lang.Object, IProductDetailsResponseListener { - public Action ProductDetailsResponseHandler { get; set; } + public Action> ProductDetailsResponseHandler { get; set; } - public void OnProductDetailsResponse(BillingResult result, QueryProductDetailsResult queryResult) - => ProductDetailsResponseHandler?.Invoke(result, queryResult); + public void OnProductDetailsResponse(BillingResult result, IList productDetails) + => ProductDetailsResponseHandler?.Invoke(result, productDetails); } internal class InternalPurchasesResponseListener : Java.Lang.Object, IPurchasesResponseListener From 265625c3a8ecd1d0f01f748973c016f8628eacbe Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 15 Jul 2025 23:07:09 +0000 Subject: [PATCH 03/11] Add partial modifier to QueryProductDetailsResult and fix interface implementation Co-authored-by: jonathanpeppers <840039+jonathanpeppers@users.noreply.github.com> --- .../billing/Additions/Additions.cs | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/source/com.android.billingclient/billing/Additions/Additions.cs b/source/com.android.billingclient/billing/Additions/Additions.cs index 266d7e830..8076d79b6 100644 --- a/source/com.android.billingclient/billing/Additions/Additions.cs +++ b/source/com.android.billingclient/billing/Additions/Additions.cs @@ -27,11 +27,15 @@ public class QuerySkuDetailsResult public IList SkuDetails { get; set; } } - public class QueryProductDetailsResult + public partial class QueryProductDetailsResult { public BillingResult Result { get; set; } - public IList ProductDetails { get; set; } + public IList ProductDetails + { + get => ProductDetailsList; + set => throw new NotSupportedException("ProductDetails property is read-only. Use ProductDetailsList instead."); + } } public class QueryPurchasesResult @@ -124,11 +128,12 @@ public Task QueryProductDetailsAsync(QueryProductDeta var listener = new InternalProductDetailsResponseListener { - ProductDetailsResponseHandler = (r, s) => tcs.TrySetResult(new QueryProductDetailsResult + ProductDetailsResponseHandler = (r, s) => { - Result = r, - ProductDetails = s - }) + if (s != null) + s.Result = r; + tcs.TrySetResult(s); + } }; QueryProductDetails(productDetailsParams, listener); @@ -249,10 +254,10 @@ public void OnSkuDetailsResponse(BillingResult result, IList skuDeta internal class InternalProductDetailsResponseListener : Java.Lang.Object, IProductDetailsResponseListener { - public Action> ProductDetailsResponseHandler { get; set; } + public Action ProductDetailsResponseHandler { get; set; } - public void OnProductDetailsResponse(BillingResult result, IList productDetails) - => ProductDetailsResponseHandler?.Invoke(result, productDetails); + public void OnProductDetailsResponse(BillingResult result, Android.BillingClient.Api.QueryProductDetailsResult queryProductDetailsResult) + => ProductDetailsResponseHandler?.Invoke(result, queryProductDetailsResult); } internal class InternalPurchasesResponseListener : Java.Lang.Object, IPurchasesResponseListener From 4e939c789bde52ac7907db43fb85950c3f161fcd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 16 Jul 2025 01:44:23 +0000 Subject: [PATCH 04/11] Revert commit 265625c and add partial modifier to QueryProductDetailsResult Co-authored-by: jonathanpeppers <840039+jonathanpeppers@users.noreply.github.com> --- .../billing/Additions/Additions.cs | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/source/com.android.billingclient/billing/Additions/Additions.cs b/source/com.android.billingclient/billing/Additions/Additions.cs index 8076d79b6..72e48906f 100644 --- a/source/com.android.billingclient/billing/Additions/Additions.cs +++ b/source/com.android.billingclient/billing/Additions/Additions.cs @@ -31,11 +31,7 @@ public partial class QueryProductDetailsResult { public BillingResult Result { get; set; } - public IList ProductDetails - { - get => ProductDetailsList; - set => throw new NotSupportedException("ProductDetails property is read-only. Use ProductDetailsList instead."); - } + public IList ProductDetails { get; set; } } public class QueryPurchasesResult @@ -128,12 +124,11 @@ public Task QueryProductDetailsAsync(QueryProductDeta var listener = new InternalProductDetailsResponseListener { - ProductDetailsResponseHandler = (r, s) => + ProductDetailsResponseHandler = (r, s) => tcs.TrySetResult(new QueryProductDetailsResult { - if (s != null) - s.Result = r; - tcs.TrySetResult(s); - } + Result = r, + ProductDetails = s + }) }; QueryProductDetails(productDetailsParams, listener); @@ -254,10 +249,10 @@ public void OnSkuDetailsResponse(BillingResult result, IList skuDeta internal class InternalProductDetailsResponseListener : Java.Lang.Object, IProductDetailsResponseListener { - public Action ProductDetailsResponseHandler { get; set; } + public Action> ProductDetailsResponseHandler { get; set; } - public void OnProductDetailsResponse(BillingResult result, Android.BillingClient.Api.QueryProductDetailsResult queryProductDetailsResult) - => ProductDetailsResponseHandler?.Invoke(result, queryProductDetailsResult); + public void OnProductDetailsResponse(BillingResult result, IList productDetails) + => ProductDetailsResponseHandler?.Invoke(result, productDetails); } internal class InternalPurchasesResponseListener : Java.Lang.Object, IPurchasesResponseListener From d1de5f6abd286e02c6581b1264ad914b7ff15a40 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 16 Jul 2025 01:54:04 +0000 Subject: [PATCH 05/11] Fix QueryProductDetailsResult partial class and interface implementation Co-authored-by: jonathanpeppers <840039+jonathanpeppers@users.noreply.github.com> --- .../billing/Additions/Additions.cs | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/source/com.android.billingclient/billing/Additions/Additions.cs b/source/com.android.billingclient/billing/Additions/Additions.cs index 72e48906f..092de62d7 100644 --- a/source/com.android.billingclient/billing/Additions/Additions.cs +++ b/source/com.android.billingclient/billing/Additions/Additions.cs @@ -29,9 +29,19 @@ public class QuerySkuDetailsResult public partial class QueryProductDetailsResult { - public BillingResult Result { get; set; } + private BillingResult _result; + + public BillingResult Result + { + get => _result; + set => _result = value; + } - public IList ProductDetails { get; set; } + public IList ProductDetails + { + get => ProductDetailsList; + set => throw new NotSupportedException("ProductDetails property is read-only. Use ProductDetailsList instead."); + } } public class QueryPurchasesResult @@ -124,11 +134,12 @@ public Task QueryProductDetailsAsync(QueryProductDeta var listener = new InternalProductDetailsResponseListener { - ProductDetailsResponseHandler = (r, s) => tcs.TrySetResult(new QueryProductDetailsResult + ProductDetailsResponseHandler = (r, s) => { - Result = r, - ProductDetails = s - }) + if (s != null) + s.Result = r; + tcs.TrySetResult(s); + } }; QueryProductDetails(productDetailsParams, listener); @@ -249,10 +260,10 @@ public void OnSkuDetailsResponse(BillingResult result, IList skuDeta internal class InternalProductDetailsResponseListener : Java.Lang.Object, IProductDetailsResponseListener { - public Action> ProductDetailsResponseHandler { get; set; } + public Action ProductDetailsResponseHandler { get; set; } - public void OnProductDetailsResponse(BillingResult result, IList productDetails) - => ProductDetailsResponseHandler?.Invoke(result, productDetails); + public void OnProductDetailsResponse(BillingResult result, QueryProductDetailsResult queryProductDetailsResult) + => ProductDetailsResponseHandler?.Invoke(result, queryProductDetailsResult); } internal class InternalPurchasesResponseListener : Java.Lang.Object, IPurchasesResponseListener From 475b91a8468d9b0ba43629cc974c3f5db3ec0d40 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Wed, 16 Jul 2025 08:12:51 -0500 Subject: [PATCH 06/11] Revert "Fix QueryProductDetailsResult partial class and interface implementation" This reverts commit d1de5f6abd286e02c6581b1264ad914b7ff15a40. --- .../billing/Additions/Additions.cs | 29 ++++++------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/source/com.android.billingclient/billing/Additions/Additions.cs b/source/com.android.billingclient/billing/Additions/Additions.cs index 092de62d7..72e48906f 100644 --- a/source/com.android.billingclient/billing/Additions/Additions.cs +++ b/source/com.android.billingclient/billing/Additions/Additions.cs @@ -29,19 +29,9 @@ public class QuerySkuDetailsResult public partial class QueryProductDetailsResult { - private BillingResult _result; - - public BillingResult Result - { - get => _result; - set => _result = value; - } + public BillingResult Result { get; set; } - public IList ProductDetails - { - get => ProductDetailsList; - set => throw new NotSupportedException("ProductDetails property is read-only. Use ProductDetailsList instead."); - } + public IList ProductDetails { get; set; } } public class QueryPurchasesResult @@ -134,12 +124,11 @@ public Task QueryProductDetailsAsync(QueryProductDeta var listener = new InternalProductDetailsResponseListener { - ProductDetailsResponseHandler = (r, s) => + ProductDetailsResponseHandler = (r, s) => tcs.TrySetResult(new QueryProductDetailsResult { - if (s != null) - s.Result = r; - tcs.TrySetResult(s); - } + Result = r, + ProductDetails = s + }) }; QueryProductDetails(productDetailsParams, listener); @@ -260,10 +249,10 @@ public void OnSkuDetailsResponse(BillingResult result, IList skuDeta internal class InternalProductDetailsResponseListener : Java.Lang.Object, IProductDetailsResponseListener { - public Action ProductDetailsResponseHandler { get; set; } + public Action> ProductDetailsResponseHandler { get; set; } - public void OnProductDetailsResponse(BillingResult result, QueryProductDetailsResult queryProductDetailsResult) - => ProductDetailsResponseHandler?.Invoke(result, queryProductDetailsResult); + public void OnProductDetailsResponse(BillingResult result, IList productDetails) + => ProductDetailsResponseHandler?.Invoke(result, productDetails); } internal class InternalPurchasesResponseListener : Java.Lang.Object, IPurchasesResponseListener From e758a44235467da63a9881161634a8e023c9d06e Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Wed, 16 Jul 2025 08:38:30 -0500 Subject: [PATCH 07/11] Restore a small piece of d1de5f6abd286e02c6581b1264ad914b7ff15a40 --- .../com.android.billingclient/billing/Additions/Additions.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/com.android.billingclient/billing/Additions/Additions.cs b/source/com.android.billingclient/billing/Additions/Additions.cs index 72e48906f..5499a4459 100644 --- a/source/com.android.billingclient/billing/Additions/Additions.cs +++ b/source/com.android.billingclient/billing/Additions/Additions.cs @@ -251,8 +251,8 @@ internal class InternalProductDetailsResponseListener : Java.Lang.Object, IProdu { public Action> ProductDetailsResponseHandler { get; set; } - public void OnProductDetailsResponse(BillingResult result, IList productDetails) - => ProductDetailsResponseHandler?.Invoke(result, productDetails); + public void OnProductDetailsResponse(BillingResult result, QueryProductDetailsResult queryProductDetailsResult) + => ProductDetailsResponseHandler?.Invoke(result, queryProductDetailsResult?.ProductDetails); } internal class InternalPurchasesResponseListener : Java.Lang.Object, IPurchasesResponseListener From e0864f2a94a6f6933e81b337d1d10824008ac47f Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Wed, 16 Jul 2025 08:45:48 -0500 Subject: [PATCH 08/11] This implementation is even cleaner Obsolete ProductDetails in favor of ProductDetailsList --- .../billing/Additions/Additions.cs | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/source/com.android.billingclient/billing/Additions/Additions.cs b/source/com.android.billingclient/billing/Additions/Additions.cs index 5499a4459..bef8923b7 100644 --- a/source/com.android.billingclient/billing/Additions/Additions.cs +++ b/source/com.android.billingclient/billing/Additions/Additions.cs @@ -31,7 +31,12 @@ public partial class QueryProductDetailsResult { public BillingResult Result { get; set; } - public IList ProductDetails { get; set; } + [Obsolete ($"Use {nameof(ProductDetailsList)} instead")] + public IList ProductDetails + { + get => ProductDetailsList; + set { /* Obsolete property setter does nothing */ } + } } public class QueryPurchasesResult @@ -124,11 +129,7 @@ public Task QueryProductDetailsAsync(QueryProductDeta var listener = new InternalProductDetailsResponseListener { - ProductDetailsResponseHandler = (r, s) => tcs.TrySetResult(new QueryProductDetailsResult - { - Result = r, - ProductDetails = s - }) + ProductDetailsResponseHandler = (r, s) => tcs.TrySetResult(s) }; QueryProductDetails(productDetailsParams, listener); @@ -249,10 +250,14 @@ public void OnSkuDetailsResponse(BillingResult result, IList skuDeta internal class InternalProductDetailsResponseListener : Java.Lang.Object, IProductDetailsResponseListener { - public Action> ProductDetailsResponseHandler { get; set; } + public Action ProductDetailsResponseHandler { get; set; } public void OnProductDetailsResponse(BillingResult result, QueryProductDetailsResult queryProductDetailsResult) - => ProductDetailsResponseHandler?.Invoke(result, queryProductDetailsResult?.ProductDetails); + { + queryProductDetailsResult ??= new(); + queryProductDetailsResult.Result = result; + ProductDetailsResponseHandler?.Invoke(result, queryProductDetailsResult); + } } internal class InternalPurchasesResponseListener : Java.Lang.Object, IPurchasesResponseListener From 7bab16fccc81e1aa1e776efb6f76037e64364e7f Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Wed, 16 Jul 2025 08:47:27 -0500 Subject: [PATCH 09/11] Smaller diff --- .../billing/Additions/Additions.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/com.android.billingclient/billing/Additions/Additions.cs b/source/com.android.billingclient/billing/Additions/Additions.cs index bef8923b7..02c73cd1c 100644 --- a/source/com.android.billingclient/billing/Additions/Additions.cs +++ b/source/com.android.billingclient/billing/Additions/Additions.cs @@ -129,7 +129,7 @@ public Task QueryProductDetailsAsync(QueryProductDeta var listener = new InternalProductDetailsResponseListener { - ProductDetailsResponseHandler = (r, s) => tcs.TrySetResult(s) + ProductDetailsResponseHandler = (r, queryResult) => tcs.TrySetResult(queryResult) }; QueryProductDetails(productDetailsParams, listener); @@ -252,11 +252,11 @@ internal class InternalProductDetailsResponseListener : Java.Lang.Object, IProdu { public Action ProductDetailsResponseHandler { get; set; } - public void OnProductDetailsResponse(BillingResult result, QueryProductDetailsResult queryProductDetailsResult) + public void OnProductDetailsResponse(BillingResult result, QueryProductDetailsResult queryResult) { - queryProductDetailsResult ??= new(); - queryProductDetailsResult.Result = result; - ProductDetailsResponseHandler?.Invoke(result, queryProductDetailsResult); + queryResult ??= new(); + queryResult.Result = result; + ProductDetailsResponseHandler?.Invoke(result, queryResult); } } From 3b68558255245352924a6809a02dd8b97aec4ff8 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Wed, 16 Jul 2025 13:13:51 -0500 Subject: [PATCH 10/11] Update Additions.cs --- source/com.android.billingclient/billing/Additions/Additions.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/com.android.billingclient/billing/Additions/Additions.cs b/source/com.android.billingclient/billing/Additions/Additions.cs index 02c73cd1c..c7b3c9c31 100644 --- a/source/com.android.billingclient/billing/Additions/Additions.cs +++ b/source/com.android.billingclient/billing/Additions/Additions.cs @@ -29,6 +29,8 @@ public class QuerySkuDetailsResult public partial class QueryProductDetailsResult { + public QueryProductDetailsResult () { } + public BillingResult Result { get; set; } [Obsolete ($"Use {nameof(ProductDetailsList)} instead")] From 96fd2ea1ed65b60795f49f4b48261fe787c55323 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Wed, 16 Jul 2025 13:14:19 -0500 Subject: [PATCH 11/11] Update Additions.cs --- source/com.android.billingclient/billing/Additions/Additions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/com.android.billingclient/billing/Additions/Additions.cs b/source/com.android.billingclient/billing/Additions/Additions.cs index c7b3c9c31..0c13c4a69 100644 --- a/source/com.android.billingclient/billing/Additions/Additions.cs +++ b/source/com.android.billingclient/billing/Additions/Additions.cs @@ -29,7 +29,7 @@ public class QuerySkuDetailsResult public partial class QueryProductDetailsResult { - public QueryProductDetailsResult () { } + public QueryProductDetailsResult() { } public BillingResult Result { get; set; }