-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[pigeon] Kotlin implementation for ProxyApis #6371
[pigeon] Kotlin implementation for ProxyApis #6371
Conversation
abstract class PigeonProxyApiBaseCodec( | ||
val binaryMessenger: BinaryMessenger, | ||
val instanceManager: PigeonInstanceManager | ||
) : StandardMessageCodec() { | ||
/** | ||
* An implementation of [PigeonApiProxyApiTestClass] used to add a new Dart instance of | ||
* `ProxyApiTestClass` to the Dart `InstanceManager`. | ||
*/ | ||
abstract fun getPigeonApiProxyApiTestClass(): PigeonApiProxyApiTestClass | ||
|
||
/** | ||
* An implementation of [PigeonApiProxyApiSuperClass] used to add a new Dart instance of | ||
* `ProxyApiSuperClass` to the Dart `InstanceManager`. | ||
*/ | ||
abstract fun getPigeonApiProxyApiSuperClass(): PigeonApiProxyApiSuperClass | ||
|
||
/** | ||
* An implementation of [PigeonApiProxyApiInterface] used to add a new Dart instance of | ||
* `ProxyApiInterface` to the Dart `InstanceManager`. | ||
*/ | ||
abstract fun getPigeonApiProxyApiInterface(): PigeonApiProxyApiInterface | ||
|
||
fun setUpMessageHandlers() { | ||
PigeonApiProxyApiTestClass.setUpMessageHandlers( | ||
binaryMessenger, getPigeonApiProxyApiTestClass()) | ||
PigeonApiProxyApiSuperClass.setUpMessageHandlers( | ||
binaryMessenger, getPigeonApiProxyApiSuperClass()) | ||
} | ||
|
||
override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? { | ||
return when (type) { | ||
128.toByte() -> { | ||
return instanceManager.getInstance( | ||
readValue(buffer).let { if (it is Int) it.toLong() else it as Long }) | ||
} | ||
else -> super.readValueOfType(type, buffer) | ||
} | ||
} | ||
|
||
override fun writeValue(stream: ByteArrayOutputStream, value: Any?) { | ||
if (value is ProxyApiTestClass) { | ||
getPigeonApiProxyApiTestClass().pigeon_newInstance(value) {} | ||
} else if (value is com.example.test_plugin.ProxyApiSuperClass) { | ||
getPigeonApiProxyApiSuperClass().pigeon_newInstance(value) {} | ||
} else if (value is ProxyApiInterface) { | ||
getPigeonApiProxyApiInterface().pigeon_newInstance(value) {} | ||
} | ||
|
||
when { | ||
instanceManager.containsInstance(value) -> { | ||
stream.write(128) | ||
writeValue(stream, instanceManager.getIdentifierForStrongReference(value)) | ||
} | ||
else -> super.writeValue(stream, value) | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@camsim99 FYI
@stuartmorgan @tarrinneal This is one of the places where the design changes from the implementation in the doc. I wanted to improve the scenario of when a method returns a ProxyApi
or a list/map of a ProxyApi
:
class Basket {
Apple giveMeAnApple();
List<Apple> giveMeApples();
}
Typically we solve this by manually handling adding a new instance when we implement the api:
class PigeonApiBasketImpl {
Apple giveMeAnApple(Basket instance) {
final Apple apple = instance.giveMeAnApple();
if (!instanceManager.containsInstance(apple)) {
instanceManager.addHostCreatedInstance(apple);
}
return apple;
}
List<Apple> giveMeApples(Basket instance) {
final List<Apple> apples = instance.giveMeApples();
for (Apple apple in apples) {
if (!instanceManager.containsInstance(apple)) {
instanceManager.addHostCreatedInstance(apple);
}
}
return apples;
}
}
This change makes the codec the central class that contains all the proxy api implementations, so the writeValue
can handle creating new dart instances automatically by calling pigeon_newInstance
. And pigeon_newInstance
would handle the logic shown in the methods above.
This also:
- Creates a registrar like class that ensures a user implements each proxy api.
- Provides access to a central class with every api implementation which prevents the need for multiple instances of the same api implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may end up overlapping with some of the codec work I'm about to do as well. I think it's generally a good idea to create a central codec though. We may end up with multiple codecs implementing each other.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My main concern at this point is that the number of custom inputs is limited to around 120, so if there are a lot of proxy apis, enums, and or data classes, we may not be able to accommodate them all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As of right now, the generation of the ProxyApi
codec is separate from Host/Flutter APIs codecs. Mainly because:
- ProxyApis don't support data classes
- ProxyApis support other ProxyApis in the codec and Host/Flutter APIs don't.
So they currently don't really share anything. If you create a central custom codec for all the APIs, then ProxyApis
should only need one dedicated spot that uses the InstanceManager
: https://github.com/flutter/packages/blob/main/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/proxy_api_tests.gen.dart#L374.
Also, as a side note, since all data classes have an I realized this wouldn't work since the reader wouldn't know what class to call this on.encode/decode
could you create a base data class for all the data classes and only use one spot.
Are you planning to add the full implementation and test suite to this pr? |
I wasn't planning on doing that for this PR, but I can if you prefer the full implementation. This PR just adds the Kotlin ProxyApi utility classes, including the |
@bparrishMines I think there needs to be some plumbing added to have the kotlin files generate using the tool/generate script |
@tarrinneal What do you mean? I have been using |
yep, If it's working then don't worry about it :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few more things here, should be easy.
return ProxyApiSuperClass() | ||
} | ||
|
||
override fun aBool(pigeon_instance: ProxyApiTestClass): Boolean { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why was this change necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's at a place where we can land it and start making incremental changes as needed. Good job with it all, and thanks for your patience!
flutter/packages@2a0f254...c9c0004 2024-08-30 10687576+bparrishMines@users.noreply.github.com [pigeon] Kotlin implementation for ProxyApis (flutter/packages#6371) 2024-08-29 louisehsu@google.com [in_app_purchase_storekit] Add storekit 2 support for canMakePayments and products (flutter/packages#7473) 2024-08-29 mhvdijk@gmail.com [flutter_adaptive_scaffold] Add correct material spacing and panes (flutter/packages#7428) 2024-08-29 34871572+gmackall@users.noreply.github.com [many] Upgrade example apps to AGP 8.5.2 (if they were below 8.1.0) (flutter/packages#7521) 2024-08-29 tarrinneal@gmail.com [pigeon] allow gen of unused classes (flutter/packages#7529) 2024-08-29 magder@google.com Increase deprecation check minimum to iOS 14 and macOS 13 (flutter/packages#7431) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages-flutter-autoroll Please CC flutter-ecosystem@google.com,rmistry@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
flutter/packages@2a0f254...c9c0004 2024-08-30 10687576+bparrishMines@users.noreply.github.com [pigeon] Kotlin implementation for ProxyApis (flutter/packages#6371) 2024-08-29 louisehsu@google.com [in_app_purchase_storekit] Add storekit 2 support for canMakePayments and products (flutter/packages#7473) 2024-08-29 mhvdijk@gmail.com [flutter_adaptive_scaffold] Add correct material spacing and panes (flutter/packages#7428) 2024-08-29 34871572+gmackall@users.noreply.github.com [many] Upgrade example apps to AGP 8.5.2 (if they were below 8.1.0) (flutter/packages#7521) 2024-08-29 tarrinneal@gmail.com [pigeon] allow gen of unused classes (flutter/packages#7529) 2024-08-29 magder@google.com Increase deprecation check minimum to iOS 14 and macOS 13 (flutter/packages#7431) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages-flutter-autoroll Please CC flutter-ecosystem@google.com,rmistry@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
flutter/packages@2a0f254...c9c0004 2024-08-30 10687576+bparrishMines@users.noreply.github.com [pigeon] Kotlin implementation for ProxyApis (flutter/packages#6371) 2024-08-29 louisehsu@google.com [in_app_purchase_storekit] Add storekit 2 support for canMakePayments and products (flutter/packages#7473) 2024-08-29 mhvdijk@gmail.com [flutter_adaptive_scaffold] Add correct material spacing and panes (flutter/packages#7428) 2024-08-29 34871572+gmackall@users.noreply.github.com [many] Upgrade example apps to AGP 8.5.2 (if they were below 8.1.0) (flutter/packages#7521) 2024-08-29 tarrinneal@gmail.com [pigeon] allow gen of unused classes (flutter/packages#7529) 2024-08-29 magder@google.com Increase deprecation check minimum to iOS 14 and macOS 13 (flutter/packages#7431) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages-flutter-autoroll Please CC flutter-ecosystem@google.com,rmistry@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Kotlin portion of flutter/flutter#134777
Pre-launch Checklist
dart format
.)[shared_preferences]
pubspec.yaml
with an appropriate new version according to the pub versioning philosophy, or this PR is exempt from version changes.CHANGELOG.md
to add a description of the change, following repository CHANGELOG style.///
).If you need help, consider asking for advice on the #hackers-new channel on Discord.