When marshaling a11y calls from the content process, there are quite a lot of cross-thread QueryInterface calls (ipc::mscom::Interceptor::QueryInterfaceTarget).
Some of these are for special COM interfaces like IAgileObject and IFastRundown, which we could just special case in Interceptor::QueryInterface like we do for INoMarshal.
However, it seems there are a lot of other interfaces being queried and it's not clear why.
This patch adds a new HandlerProvider method: IsInterfaceMaybeSupported.
This allows implementations to indicate when there are interfaces which they definitely don't support, allowing the call to be answered without a cross-thread call.
Differential Revision: https://phabricator.services.mozilla.com/D69285
--HG--
extra : moz-landing-system : lando
Because Interceptors disable COM garbage collection to improve performance, they never receive Release calls from remote clients.
If the object can be shut down while clients still hold a reference, this function can be used to force COM to disconnect all remote connections (using CoDisconnectObject) and thus release the associated references to the Interceptor, its target and any objects associated with the HandlerProvider.
A HandlerProvider::DisconnectHandlerRemotes method also had to be added to allow HandlerProviders to disconnect clients for their own objects.
MozReview-Commit-ID: JaxEkOtrP1M
--HG--
extra : rebase_source : bc7a4ab79458eaaddcef8df74ff4d6f685fbfdce
extra : histedit_source : 087f17f09a0c0e1c8e3b5f6d9690f331c15f0b95
Because Interceptors disable COM garbage collection to improve performance, they never receive Release calls from remote clients.
If the object can be shut down while clients still hold a reference, this function can be used to force COM to disconnect all remote connections (using CoDisconnectObject) and thus release the associated references to the Interceptor, its target and any objects associated with the HandlerProvider.
A HandlerProvider::DisconnectHandlerRemotes method also had to be added to allow HandlerProviders to disconnect clients for their own objects.
MozReview-Commit-ID: JaxEkOtrP1M
--HG--
extra : rebase_source : 2262af8fc3cb1aec8d9c8fc2762f3d61e188cb37
MozReview-Commit-ID: GTQF3x1pBtX
A general outline of the COM handler (a.k.a. the "smart proxy"):
COM handlers are pieces of code that are loaded by the COM runtime along with
a proxy and are layered above that proxy. This enables the COM handler to
interpose itself between the caller and the proxy, thus providing the
opportunity for the handler to manipulate an interface's method calls before
those calls reach the proxy.
Handlers are regular COM components that live in DLLs and are declared in the
Windows registry. In order to allow for the specifying of a handler (and an
optional payload to be sent with the proxy), the mscom library allows its
clients to specify an implementation of the IHandlerProvider interface.
IHandlerProvider consists of 5 functions:
* GetHandler returns the CLSID of the component that should be loaded into
the COM client's process. If GetHandler returns a failure code, then no
handler is loaded.
* GetHandlerPayloadSize and WriteHandlerPayload are for obtaining the payload
data. These calls are made on a background thread but need to do their work
on the main thread. We declare the payload struct in IDL. MIDL generates two
functions, IA2Payload_Encode and IA2Payload_Decode, which are used by
mscom::StructToStream to read and write that struct to and from buffers.
* The a11y payload struct also includes an interface, IGeckoBackChannel, that
allows the handler to communicate directly with Gecko. IGeckoBackChannel
currently provides two methods: one to allow the handler to request fresh
cache information, and the other to provide Gecko with its IHandlerControl
interface.
* MarshalAs accepts an IID that specifies the interface that is about to be
proxied. We may want to send a more sophisticated proxy than the one that
is requested. The desired IID is returned by this function. In the case of
a11y interfaces, we should always return IAccessible2_3 if we are asked for
one of its parent interfaces. This allows us to eliminate round trips to
resolve more sophisticated interfaces later on.
* NewInstance, which is needed to ensure that all descendent proxies are also
imbued with the same handler code.
The main focus of this patch is as follows:
1. Provide an implementation of the IHandlerProvider interface;
2. Populate the handler payload (ie, the cache) with data;
3. Modify CreateHolderFromAccessible to specify the HandlerPayload object;
4. Receive the IHandlerControl interface from the handler DLL and move it
into the chrome process.
Some more information about IHandlerControl:
There is one IHandlerControl per handler DLL instance. It is the interface that
we call in Gecko when we need to dispatch an event to the handler. In order to
ensure that events are dispatched in the correct order, we need to dispatch
those events from the chrome main thread so that they occur in sequential order
with calls to NotifyWinEvent.
--HG--
extra : rebase_source : acb44dead7cc5488424720e1bf58862b7b30374f