Repository: flutter
Issue: Embrace the implicit view/multi-view dualism
Labels: framework,engine,P2,team-engine,triaged-engine

In today's world, there is the assumption of always having an (implicit) view to draw to because the global `window` variable is always pointing to something. This is true even if the `window` is not backed by an actual surface. In fact, the embedders can provide the surfacing backing this implicit view whenever they want (and they can also take it away) without the framework knowing about this.

In a multi view world we don't want to have this concept of an always available implicit view. Instead, the framework (or app) should request a window to be created which will trigger the embedder to provide a view the framework can draw into.

Embedders now need to know whether they should provide a backing surface for the implicit view without being asked for it or whether they should wait until a request for a window is made. The framework needs to know whether `runApp` should be drawing the app into some sort of implicit view that the engine provided or whether it should be requesting a window from the engine.

After some discussion we arrived at the conclusion that making this dualism explicit in both the embedder API and dart:ui is the best way forward to keep backwards compatibility with existing embedders and apps. Some embedders may also continue to use the implicit view model indefinitely if their platform doesn't actually support windows.

Action items:
- [x] `dart:ui` gains a new nullable (!) property on the `PlatformDispatcher` which points to the implicit view provided by the engine. If it is null, the framework is operating in multi-window mode and in order to draw UI it needs to request a window from the engine. If it is non-null, it functions similarly to the `window` property today and designates the implicit view into which `runApp` will draw its UI by default. It is guaranteed that the value of this new property never changes for the runtime of the app. If it is null at app startup, it will never change to anything non-null. If it is non-null it will never change its value. Suggested name for the new property on `PlatformDispatcher`: `implicitView` (name should be uninteresting enough to not gather any attention as this should only be accessed by the low-level bootstrapping code, everything else should obtain the current view via `View.of(context)`). https://github.com/flutter/engine/pull/39553
- [ ] The embedder API is extended with a flag (i.e. in the `FlutterProjectArgs`) to configure whether the engine is running in implicit view mode (default for backwards compatibility) or multi-view mode. If set to implicit view mode, the engine will configure the `implicitView` property in `dart:ui` to something non-null (same value that the `window` property gets today) and will make the appropriate callbacks to the embedder to render things on this implicit view (same as today). The embedder is expected to create a backing surface as necessary. If set to multi view mode, the engine will not create the `implicitView`. Instead, embedders are expected to add backing surfaces to the engine (that will be exposed to the framework as views) as requested by the framework (i.e. in response to a request to create a window). The API to add these surfaces is TBD.