Skip to content

Commit 47cfea4

Browse files
[in_app_purchase] Switch to Kotlin Pigeon (#11608)
Replaces the Java Pigeon generator with the Kotlin Pigeon generator, and adjusts the project accordingly: - Adds Kotlin build setings to Gradle. - Updates API signatures and number handling for Kotlin/Java generator differences. - Adds generic Java/Kotlin compat shim to create Result objects from Java, since those haven't been added to the Pigeon generator yet. - Updates tests to use constructors instead of builders, since the Kotlin generator doesn't create builders. - Updates tests to use a fake result value, instead of mocking the Java Pigeon response object. Most of this conversion was done by Gemini; I gave it my previous "Switch to Kotlin Pigeon" PRs for context, and let it do most of the work. Once it had a passing conversion I did some manual cleanup and warning fixing. This also converts Translator.java, which does SDK<->Pigeon type conversion, to Kotlin, per discussion in the linked issue: - I used Android Studio's auto-converter. - I did some manual cleanup (e.g., fixing nullability where it assumed nullable because the Java wasn't annotated, simplifying some switch return statements). - I added parameter names to all the constructors, so it's easy to see that the params are being passed correctly in review both now and in future changes. - I had Gemini do a pass over it to make the Kotlin simpler or more idiomatic. The big improvement was it replacing a bunch of manual list construction with `map`s. - Removed `currencyCodeFromSymbol`, which has been dead code for years. These steps are separate commits in case it's useful to review them separately Fixes flutter/flutter#185545 ## Pre-Review Checklist [^1]: Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling.
1 parent c3360ac commit 47cfea4

18 files changed

Lines changed: 3404 additions & 5450 deletions

File tree

packages/in_app_purchase/in_app_purchase_android/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.4.0+11
2+
3+
* Updates internal implementation to use Kotlin Pigeon.
4+
15
## 0.4.0+10
26

37
* Fixes dartdoc comments that accidentally used HTML.

packages/in_app_purchase/in_app_purchase_android/android/build.gradle.kts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
1+
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
2+
13
group = "io.flutter.plugins.inapppurchase"
24
version = "1.0-SNAPSHOT"
35

46
buildscript {
7+
val kotlinVersion = "2.3.20"
58
repositories {
69
google()
710
mavenCentral()
811
}
912

1013
dependencies {
1114
classpath("com.android.tools.build:gradle:8.13.1")
15+
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
1216
}
1317
}
1418

@@ -21,6 +25,13 @@ allprojects {
2125

2226
plugins {
2327
id("com.android.library")
28+
id("kotlin-android")
29+
}
30+
31+
kotlin {
32+
compilerOptions {
33+
jvmTarget = JvmTarget.fromTarget(JavaVersion.VERSION_17.toString())
34+
}
2435
}
2536

2637
android {

packages/in_app_purchase/in_app_purchase_android/android/src/main/java/io/flutter/plugins/inapppurchase/BillingClientFactory.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import android.content.Context;
88
import androidx.annotation.NonNull;
99
import com.android.billingclient.api.BillingClient;
10-
import io.flutter.plugins.inapppurchase.Messages.PlatformBillingChoiceMode;
1110

1211
/** Responsible for creating a {@link BillingClient} object. */
1312
interface BillingClientFactory {
@@ -25,7 +24,7 @@ interface BillingClientFactory {
2524
*/
2625
BillingClient createBillingClient(
2726
@NonNull Context context,
28-
@NonNull Messages.InAppPurchaseCallbackApi callbackApi,
27+
@NonNull InAppPurchaseCallbackApi callbackApi,
2928
PlatformBillingChoiceMode billingChoiceMode,
30-
Messages.PlatformPendingPurchasesParams pendingPurchasesParams);
29+
PlatformPendingPurchasesParams pendingPurchasesParams);
3130
}

packages/in_app_purchase/in_app_purchase_android/android/src/main/java/io/flutter/plugins/inapppurchase/BillingClientFactoryImpl.java

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,26 @@
44

55
package io.flutter.plugins.inapppurchase;
66

7-
import static io.flutter.plugins.inapppurchase.Translator.fromUserChoiceDetails;
8-
import static io.flutter.plugins.inapppurchase.Translator.toPendingPurchasesParams;
7+
import static io.flutter.plugins.inapppurchase.TranslatorKt.fromUserChoiceDetails;
8+
import static io.flutter.plugins.inapppurchase.TranslatorKt.toPendingPurchasesParams;
99

1010
import android.content.Context;
1111
import androidx.annotation.NonNull;
1212
import androidx.annotation.VisibleForTesting;
1313
import com.android.billingclient.api.BillingClient;
1414
import com.android.billingclient.api.UserChoiceBillingListener;
1515
import io.flutter.Log;
16-
import io.flutter.plugins.inapppurchase.Messages.PlatformBillingChoiceMode;
16+
import kotlin.Unit;
1717

1818
/** The implementation for {@link BillingClientFactory} for the plugin. */
1919
final class BillingClientFactoryImpl implements BillingClientFactory {
2020

2121
@Override
2222
public BillingClient createBillingClient(
2323
@NonNull Context context,
24-
@NonNull Messages.InAppPurchaseCallbackApi callbackApi,
24+
@NonNull InAppPurchaseCallbackApi callbackApi,
2525
PlatformBillingChoiceMode billingChoiceMode,
26-
Messages.PlatformPendingPurchasesParams pendingPurchasesParams) {
26+
PlatformPendingPurchasesParams pendingPurchasesParams) {
2727
BillingClient.Builder builder =
2828
BillingClient.newBuilder(context)
2929
.enablePendingPurchases(toPendingPurchasesParams(pendingPurchasesParams));
@@ -49,19 +49,19 @@ public BillingClient createBillingClient(
4949

5050
@VisibleForTesting
5151
/* package */ UserChoiceBillingListener createUserChoiceBillingListener(
52-
@NonNull Messages.InAppPurchaseCallbackApi callbackApi) {
52+
@NonNull InAppPurchaseCallbackApi callbackApi) {
5353
return userChoiceDetails ->
5454
callbackApi.userSelectedalternativeBilling(
5555
fromUserChoiceDetails(userChoiceDetails),
56-
new Messages.VoidResult() {
57-
@Override
58-
public void success() {}
59-
60-
@Override
61-
public void error(@NonNull Throwable error) {
62-
io.flutter.Log.e(
63-
"IN_APP_PURCHASE", "userSelectedalternativeBilling handler error: " + error);
64-
}
65-
});
56+
ResultCompat.asCompatCallback(
57+
result -> {
58+
Throwable error = result.exceptionOrNull();
59+
if (error != null) {
60+
io.flutter.Log.e(
61+
"IN_APP_PURCHASE",
62+
"userSelectedalternativeBilling handler error: " + error);
63+
}
64+
return Unit.INSTANCE;
65+
}));
6666
}
6767
}

packages/in_app_purchase/in_app_purchase_android/android/src/main/java/io/flutter/plugins/inapppurchase/InAppPurchasePlugin.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,15 @@ public void onDetachedFromActivityForConfigChanges() {
5858
}
5959

6060
private void setUpMethodChannel(BinaryMessenger messenger, Context context) {
61-
Messages.InAppPurchaseCallbackApi handler = new Messages.InAppPurchaseCallbackApi(messenger);
61+
InAppPurchaseCallbackApi handler = new InAppPurchaseCallbackApi(messenger, "");
6262
methodCallHandler =
6363
new MethodCallHandlerImpl(
6464
/* activity= */ null, context, handler, new BillingClientFactoryImpl());
65-
Messages.InAppPurchaseApi.setUp(messenger, methodCallHandler);
65+
InAppPurchaseApi.Companion.setUp(messenger, methodCallHandler);
6666
}
6767

6868
private void teardownMethodChannel(BinaryMessenger messenger) {
69-
Messages.InAppPurchaseApi.setUp(messenger, null);
69+
InAppPurchaseApi.Companion.setUp(messenger, null);
7070
methodCallHandler = null;
7171
}
7272

0 commit comments

Comments
 (0)