Skip to content

Conversation

@harryterkelsen
Copy link
Contributor

@harryterkelsen harryterkelsen commented Apr 2, 2019

By abstracting out the calls to [BinaryMessages] the same code
can be used for platform channels on the platform side as on the
framework side.

Description

This PR adds base classes to MethodChannel and BasicMessageChannel, which abstracts out a 'BinaryMessenger' which is responsible for actually moving the bytes across the platform divide. The existing Channel implementations use BinaryMessages to implement their BinaryMessenger. The "dual" channel, which sends messages from the platform side to the framework side, would use a different BinaryMessenger.

Related Issues

Checklist

Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes ([x]). This will ensure a smooth and quick review process.

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I signed the CLA.
  • I read and followed the Flutter Style Guide, including Features we expect every widget to implement.
  • I updated/added relevant documentation (doc comments with ///).
  • All existing and new tests are passing.
  • The analyzer (flutter analyze --flutter-repo) does not report any problems on my PR.
  • I am willing to follow-up on review comments in a timely manner.

Breaking Change

Does your PR require Flutter developers to manually update their apps to accommodate your change?

By abstracting out the calls to [BinaryMessages] the same code
can be used for platform channels on the platform side as on the
framework side.
@amirh
Copy link
Contributor

amirh commented Apr 2, 2019

Curious what do you think about the alternative of using the same mechanism setMockMessageHandler uses?

@harryterkelsen
Copy link
Contributor Author

After several discussions, I think we plan to support 2 approaches for plugins:

  1. You write a web plugin in Dart that is pretty a Dart port of the Android-specific code. In this approach, you need a platform channel that can send messages back to the framework side. I think it is cleaner to have Platform-side implementations of Channel than to register mock handlers on BinaryMessages.

  2. In the plugin, you have an if (const bool('dart.library.html')) { ... } where you have web-specific logic. This avoids channels altogether.

@goderbauer goderbauer added framework flutter/packages/flutter repository. See also f: labels. p: framework labels Apr 2, 2019
Copy link

@ClassyRemade ClassyRemade left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My name was not my intention. It's out there now!

@harryterkelsen
Copy link
Contributor Author

Ping!

@goderbauer
Copy link
Member

@amirh @collinjackson @bparrishMines Can somebody review this?

@harryterkelsen
Copy link
Contributor Author

@Hixie FYI this PR incorporates the changes we talked about in our meeting a few weeks ago.

@Hixie
Copy link
Contributor

Hixie commented Apr 13, 2019

This ends up being a bit convoluted, with BinaryMessages, BinaryMessenger, MethodChannel, BaseMethodChannel, BasicMessageChannel, and BaseMessageChannel. I'm not sure I'd be able to draw an accurate diagram of which class inherited from which, and which instantiated which, and which was static vs which was instantiatable, without referencing the code.

Could we instead just make BinaryMessages non-static? i.e. refactor it so that you call through to an singleton instance of that class, much as we do with things like the ImageCache? Then for the framework side the binding could set it up, and on the plugin side the plugin could set it up.

@harryterkelsen
Copy link
Contributor Author

That might not work for the web case. On the web we compile all of the code (platform side and client side) into one executable, so we wouldn't be able to have the two different compilations set up the binaryMessages singleton in two different ways.

What do you think about changing this CL so that instead of introducing a super-class, we just add an optional binaryMessenger argument to MethodChannel which defaults to one which uses BinaryMessages. On the platform side users can either use a normal method channel with their own binaryMessenger or we can supply a platform-side subclass of MethodChannel which has a binaryMessenger that sends data back to the framework side.

@harryterkelsen harryterkelsen changed the title Add super-classes to MethodChannel and BasicMessageChannel. Add binaryMessenger constructor argument to platform channels Apr 15, 2019
@dnfield
Copy link
Contributor

dnfield commented May 1, 2019

@hterkelsen @Hixie what's the path forward here? Are there more changes needed to this, or is it ready to land?

@Hixie
Copy link
Contributor

Hixie commented May 3, 2019

Sorry, haven't been checking my bugmail much recently.

The new PR is much closer to something reasonable, I think. Can we go further and just have BinaryMessages be an instance instead of static? Then we don't need both BinaryMessenger and BinaryMessages, we can just have the interface (public), and the default implementation (also public, but instance methods instead of static methods, and used as the default value to the arguments added in the current PR).

@dnfield
Copy link
Contributor

dnfield commented May 15, 2019

@hterkelsen - do you plan to continue with this? @Hixie - are these concerns meant to block landing this?

At this point the PR has been open for over a month - if we don't think we can keep making progress forward with this approach perhaps we should close it.

@Hixie
Copy link
Contributor

Hixie commented May 15, 2019

are these concerns meant to block landing this?

yes

@Hixie
Copy link
Contributor

Hixie commented May 20, 2019

I like the approach in this patch.

Please follow the breaking change policy (https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes).

@Hixie
Copy link
Contributor

Hixie commented May 20, 2019

I'll defer to @amirh, @dnfield, or @goderbauer for final review.

- Make the message handler typedef public.
- Fix typos in comments.
- Make clear that defaultBinaryMessenger has replaced BinaryMessages
@harryterkelsen
Copy link
Contributor Author

I tried to send an email to flutter-announce@googlegroups.com but it seems I don't have permission to post there.

I tried to send the following:

As part of a change to generalize Platform Channels so they may be used in Web Plugins, I intend to deprecate BinaryMessages.

Justification

The platform channels use BinaryMessages to send messages from the application to the platform side. The proposed change
will abstract the "binary messenger" in the platform channels such that an implementation which sends messages from the
platform side back to the application can use the same platform channel classes (MethodChannel, OptionalMethodChannel, etc).

Part of this change is to replace the collection of static methods in BinaryMessages with an interface for sending messages,
called BinaryMessenger, and a default instance of BinaryMessenger, called defaultBinaryMessenger.

Links to Issue and PR

Issue: #29629
PR: #30406

Migration Steps

defaultBinaryMessenger is a drop-in replacement for BinaryMessages. Simply find and replace every instance of BinaryMessages with defaultBinaryMessages.

Before:

BinaryMessages.setMessageHandler('my-channel', myHandler);

After:

defaultBinaryMessenger.setMessageHandler('my-channel', myHandler);

Conclusion

Please comment on the issue or contact me directly if this change will cause you any issues.

Thanks!

@Hixie
Copy link
Contributor

Hixie commented May 21, 2019

cc @kf6gpe for help with flutter-announce.

@harryterkelsen harryterkelsen requested a review from dnfield May 21, 2019 17:34
@kf6gpe
Copy link
Contributor

kf6gpe commented May 22, 2019

@hterkelsen Thanks for the pending contribution! I can give you posting rights to flutter-announce --- reach out to me at the email on my github page and we'll get you set up. Thanks!

/// Neither [name] nor [codec] may be null.
const BasicMessageChannel(this.name, this.codec);
/// None of [name], [codec], or [binaryMessenger] may be null.
const BasicMessageChannel(this.name, this.codec, [ this.binaryMessenger = defaultBinaryMessenger ])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make this a named parameter rather than an optional one? e.g. { this.binaryMessenger = defaultBinaryMessenger }? This ends up getting ugly/confusing if we have to add more parameters later.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I did it this way because MethodChannel has an optional argument for this.codec so I could only add binaryMessenger as another optional argument.

@Hixie
Copy link
Contributor

Hixie commented May 22, 2019 via email

@kf6gpe
Copy link
Contributor

kf6gpe commented May 22, 2019 via email

- make binaryMessenger a named argument in BasicMessageChannel
@harryterkelsen harryterkelsen requested a review from dnfield May 22, 2019 17:56
@harryterkelsen
Copy link
Contributor Author

Thanks, @dnfield. PTAL

Copy link
Contributor

@dnfield dnfield left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@harryterkelsen
Copy link
Contributor Author

Thanks! I'll land this tomorrow once the build is fixed and my breaking change announcement has been posted for 24 hours.

@harryterkelsen harryterkelsen merged commit 13e9bfc into flutter:master May 28, 2019
@harryterkelsen harryterkelsen deleted the flutter_channels_2 branch May 28, 2019 18:18
amirh added a commit to flutter/plugins that referenced this pull request May 28, 2019
flutter/flutter#30406 deprecated the usage of static BinaryMessages methods. As we cannot use the new defaultBinaryMessages mechanism before it makes it to stable, for now, we suppress the warnings.
blasten pushed a commit to blasten/flutter that referenced this pull request May 30, 2019
…r#30406)

* Deprecates `BinaryMessages` in favor of a default instance of `BinaryMessenger`, called `defaultBinaryMessenger`
* Platform channels use the `defaultBinaryMessenger` for their binaryMessenger default argument.
collinjackson pushed a commit to collinjackson/flutterfire-old2 that referenced this pull request Jun 24, 2019
flutter/flutter#30406 deprecated the usage of static BinaryMessages methods. As we cannot use the new defaultBinaryMessages mechanism before it makes it to stable, for now, we suppress the warnings.
collinjackson pushed a commit to firebase/flutterfire that referenced this pull request Aug 14, 2019
flutter/flutter#30406 deprecated the usage of static BinaryMessages methods. As we cannot use the new defaultBinaryMessages mechanism before it makes it to stable, for now, we suppress the warnings.
Akachu pushed a commit to Akachu/firebase_auth that referenced this pull request Sep 16, 2019
flutter/flutter#30406 deprecated the usage of static BinaryMessages methods. As we cannot use the new defaultBinaryMessages mechanism before it makes it to stable, for now, we suppress the warnings.
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 6, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants