{% set rfcid = “RFC-0189” %} {% include “docs/contribute/governance/rfcs/_common/_rfc_header.md” %}
This RFC proposes a model for how the fuchsia platform, the product session and the session shell work together to support complex graphical applications with multiple windows. In particular:
[^1]: These APIs will be defined in subsequent RFCs.
An important consequence of this is that applications integrate with the Fuchsia Platform rather than with a particular Fuchsia product, and thus an application that works with one Fuchsia product should work with any other Fuchsia product that supports the same set of windowing capabilities. In particular, an application that runs against one Fuchsia desktop product should run against any such product, regardless of the particular product session or system shell implementation.
This RFC expands on RFC-0092: Sessions. It describes the planned state rather than how things work today. The approach described in this RFC replaces all prior attempts (Modular, Session Framework) and is the plan of record moving forward.
Current Fuchsia APIs make it difficult for products and applications to implement rich window management and multi-window apps. The distinction between platform and product responsibilities is confusing, and the APIs supplied by the platform date from an earlier era of Fuchsia vision and lack some important features required for current work (e.g. Workstation). Multiple prior attempts have been made to solve this and related problems (modular, session framework) but none have been fully implemented across all Fuchsia surfaces.
The current state of the system lacks a clear division of responsibilities and has multiple ways to perform the same actions. This has led to fragmentation across different products. Ratifying the architecture now allows us to make future decisions about the APIs the platform will support in the future (such as potentially adopting Wayland for use in Fuchsia) and unblocks development for both shells and applications.
This RFC is likely the first of a series covering different aspects of window management. Its goal is to clarify the split between product and platform and make it easier to make later decisions about exactly what APIs to use (e.g. Wayland).
Facilitator: abarth@google.com
Reviewers:
Consulted: quiche@google.com, jasoncampbell@google.com, geb@google.com, masonben@google.com, jsankey@google.com, tjdetwiler@google.com
Socialization: Prior to publication via Gerrit a draft of this RFC was shared and discussed extensively with stakeholders.
For the purpose of this doc:
There are two main aspects of window management on Fuchsia: mechanism, and policy.
The Fuchsia SDK defines two API surfaces for window management policy:
The implementation details for client applications currently vary widely. Some applications implement the element role while others interact directly with the component framework and scenic, or implement the element manager API within the app. This RFC mandates simplifying this by moving to a single API for all application components.
This RFC does not currently express an opinion about whether the system shell and application components communicate directly with each other, or if a platform component should mediate these interactions.
The above diagram shows a possible architecture for a graphical product running on Fuchsia. The product session is responsible for launching the system shell and any applications. The application and system shell must communicate about any policy decisions, possibly through a window manager or “bridge” component supplied by the platform (see Possible platform bridge component below). Both the system shell and application must also communicate with the Fuchsia platform UI stack (which includes components that handle graphics and input processing) to execute on the “mechanism” aspects of window management. This communication may also happen through a bridge component.
The product session is the first product-specific component to be launched when a product boots up. On products with graphics, it has the following additional responsibilities:
This diagram shows a possible component hierarchy for the user experience. Note that this eliminates element manager. As shown, application components are children of the product session. Some products may choose to set things up differently, for example by creating a component in the product session's realm that is responsible for launching applications, or by delegating application component instantiation to some platform component with different capabilities.
Once launched, the application can contact scenic to create an application view, and then contact the system shell via the window management API to show that view as part of the system shell's user experience. The system shell contacts scenic to install the application view into the view tree, typically as a child of the root view.
An application may open a second top-level window by following the same flow described above for the initial window creation. Further window management actions such as resizing the application view, launching a popup, etc. require the application component to request these changes from the system shell via calls to the window management API. In general each component that is responsible for communicating directly with scenic about the contents of the View(s) that it owns. However, if a view owner/application wishes to change how its views are displayed (such as resizing, minimizing, or opening another top-level view), the system shell must somehow indicate that this action is permitted. The system shell may do so either by responding to client API calls, or by storing information in the view tree to indicate what that view is allowed to do and allowing Scenic to execute on the relevant policy.
Notes:
The above diagram shows a sample view tree for a system UI running multiple graphical applications The system shell view is the root view of the user experience. Note that the view tree may have different parent-child relationships than the component hierarchy shown above.
Not all system shell implementations will expose identical capabilities, because a system shell is in part implementing product-specific policy. Therefore, these implementations will vary per-product. For example, a smart watch might have a very simple UI with a single view on screen at a time, while a desktop would support multiple applications with multiple overlapping windows. Some products support user input via a touchscreen, while others support only mouse and keyboard.
For product-specific capabilities exposed outside of the “core set”, clients must be able to discover which of these capabilities are supported on the current product. This allows the client to tailor its behavior across different products, and makes it possible to implement graphical fuchsia applications that can function across different products.
Similarly, the system UI must tell the platform what features are currently available.
The platform may introduce a “bridge” component that mediates communication between the client application and the system UI. This component would be analogous to the window manager on other platforms and could then automate some “mechanism” actions for window management and reduce the need for developers to write code that sends low-level commands to the Fuchsia UI stack. This has the advantage of allowing the client to communicate with a single API surface for both mechanism and policy, which is a common pattern in other systems (e.g. in Wayland). By situating the bridge component in the platform, this would also allow products to share window management code and avoid duplication for similar functionality.
The decision about whether to use a platform bridge component/platform window manager is left to a future RFC.
This RFC addresses the high-level architecture for window management. Because we expect significant changes to the APIs involved via future RFCs, many implementation details should be addressed in those RFCs.
When APIs are in place, this RFC implies the removal of a number of legacy workarounds for the system's current deficiencies. In particular:
While graphics and user input processing can be very performance-sensitive, window management policy decisions such as opening a new application or window typically happen at “human speed” and thus do not require the same level of performance as rendering or input processing. Thus it's typically fine to use extra RPC when executing “control” actions such as opening a new window. However, care should be taken when designing APIs to ensure that any performance-sensitive flows (typically those involving data flow, such as putting frames on screen, routing user input) avoid unnecessary IPC and do not block unnecessarily on client responses. This is especially relevant in cases where the window manager and shell are not the same component. The performance implications of particular APIs should be addressed in detail in upcoming RFCs.
In order to provide a smooth experience for users, it's important to ensure that UI actions such as resize animations can be synchronized across multiple components. While this is mostly a function of the particular API and its guarantees about atomicity, architecture can influence how difficult it is to build user experiences where such synchronization is possible.
This RFC does not formally adopt a specific API, but the decisions contained in it were evaluated against the Wayland API, which has a stated goal of making “every frame perfect”. Synchronization concerns will be an important consideration when finalizing the APIs described in this RFC.
This RFC clarifies that the component hierarchy and view hierarchy do not have to be the same, and allows for the possibility of applications launching as children of the product session rather than the system shell (which may be less stable or less secure on some systems). This should make it easier for products to ensure that the component hierarchy within a product suits that product's particular security and privacy needs.
The security guarantees for the view system are addressed in detail in the view system RFC. Of note for this RFC is the guarantee that a view may only manipulate view focus when it or its child is currently focused, and that views that are disconnected from the view tree cannot receive user input. This means that the product session's installation of the system UI view and the window management policy decisions made by the system shell (such as installing a child view for a launched application) are also decisions about which components are eligible to receive user input at any given time. While the platform cannot guarantee that all products will implement secure behavior, the view system provides the building blocks for a product to create a secure experience.
The platform should provide conformance tests for all window management APIs so that both products and applications can ensure compatibility with the Fuchsia platform. These tests may vary depending on which extensions to the window management APIs are supported by a given application or product session.
System shell and Application developers may use the Test UI Stack to write integration tests for the interaction of their code with the Fuchsia platform UI stack.
This RFC and subsequent RFCs dealing with API specifics will require significant updates to the Session Framework documentation on fuchsia.dev to reflect updated expectations about the split between product and platform and the elimination of Element Manager.