Repository: flutter
Issue: [plugin_platform_interface] Re-evaluate for Dart 3
Labels: package,team-ecosystem,P2,p: plugin_platform_interface,triaged-ecosystem

The reason `plugin_platform_interface` exists is to provide a structure to allow platform interfaces to enforce that implementations use `extends` rather than `implements` due to the extremely high potential for breakage with `implements`. With Dart 3, there's now a built-in way to enforce that, using `base class`.

The caveat is that there's a significant difference in behavior: with `base` you *cannot* mock the class, whereas with `platform_plugin_interface` we allow it via a mixin, for testing purposes only. We make use of this in the app-facing package unit tests, which (being unit tests) cannot use a real implementation.

I can see various options:

## 1. Do nothing

Keep using `plugin_platform_interface` as-is, and just update the package README to explain why it still exists.

Pros:
- No disruption to any code.

Cons:
- We have to maintain that package forever. It doesn't need a lot of changes, but it has had a few non-trivial adjustments over time, and there's https://github.com/flutter/flutter/issues/123241 open now.
- It becomes non-idiomatic: the language has a way of expressing exactly what we want (for production code), but we're doing something else.
- Enforcement is runtime, not compile-time.

## 2. Just switch to `base`

Switch all of our platform interfaces to use `base`. We could then deprecate `plugin_platform_interface`.

Pros:
- No need to maintain `plugin_platform_interface`.
- More idiomatic.
- Compile-time enforcement.

Cons:
- We would no longer be able to mock platform interfaces. Instead we would have to write manual mocks/stubs/fakes (depending on the exact testing needs) for testing the app-facing package.
- Anyone else currently mocking platform interfaces (hopefully this would be a small set, but it is one of the options [we list in docs](https://docs.flutter.dev/packages-and-plugins/plugins-in-tests) even if it is somewhat discouraged) would have to do the same.

## 3. Switch to `base` + provided manual mock

Switch all of our platform interfaces to use `base`, but include a manual mock implementation for test purposes as part of the package API. We could then deprecate `plugin_platform_interface`.

Pros:
- No need to maintain `plugin_platform_interface`.
- More idiomatic.
- Compile-time enforcement.
- Clients with mocks would have access to relatively easy replacement.

Cons:
- The provided mocks would likely be more complicated than the once we would write in option 2, since we would be maintaining our own use case plus any requested use cases from the community.
    - Mitigating this is that if our app-facing package tests are sufficiently good, we probably need mocks that can do almost everything, so it might not be much of a difference in practice.
- The mocks would be public API, so would be much harder for us to change.
- Adding test coverage in the app-facing package could require changes to the platform interface package.
    - This is probably not much of a problem in practice, since in general tests that would require changes there should be changes that are adding thing to the platform interface already.