gecko-dev/ipc/mscom/MainThreadHandoff.h

89 строки
3.0 KiB
C
Исходник Обычный вид История

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_mscom_MainThreadHandoff_h
#define mozilla_mscom_MainThreadHandoff_h
#include "mozilla/Assertions.h"
#include "mozilla/Move.h"
#include "mozilla/mscom/Interceptor.h"
#include "mozilla/mscom/MainThreadInvoker.h"
#include "mozilla/mscom/Utils.h"
#include "mozilla/Mutex.h"
#include "nsTArray.h"
namespace mozilla {
namespace mscom {
struct ArrayData;
class MainThreadHandoff final : public IInterceptorSink
, public ICallFrameWalker
{
public:
static HRESULT Create(IHandlerProvider* aHandlerProvider,
IInterceptorSink** aOutput);
template <typename Interface>
static HRESULT WrapInterface(STAUniquePtr<Interface> aTargetInterface,
Interface** aOutInterface)
{
return WrapInterface<Interface>(Move(aTargetInterface), nullptr,
aOutInterface);
}
template <typename Interface>
static HRESULT WrapInterface(STAUniquePtr<Interface> aTargetInterface,
IHandlerProvider* aHandlerProvider,
Interface** aOutInterface)
{
MOZ_ASSERT(!IsProxy(aTargetInterface.get()));
RefPtr<IInterceptorSink> handoff;
HRESULT hr = MainThreadHandoff::Create(aHandlerProvider,
getter_AddRefs(handoff));
if (FAILED(hr)) {
return hr;
}
return CreateInterceptor(Move(aTargetInterface), handoff, aOutInterface);
}
// IUnknown
STDMETHODIMP QueryInterface(REFIID riid, void** ppv) override;
STDMETHODIMP_(ULONG) AddRef() override;
STDMETHODIMP_(ULONG) Release() override;
// ICallFrameEvents
STDMETHODIMP OnCall(ICallFrame* aFrame) override;
// IInterceptorSink
STDMETHODIMP SetInterceptor(IWeakReference* aInterceptor) override;
Bug 1303060: Changes to a11y to enable the serving of a COM handler; r=tbsaunde 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
2017-04-05 00:23:55 +03:00
STDMETHODIMP GetHandler(NotNull<CLSID*> aHandlerClsid) override;
STDMETHODIMP GetHandlerPayloadSize(NotNull<DWORD*> aOutPayloadSize) override;
STDMETHODIMP WriteHandlerPayload(NotNull<IStream*> aStream) override;
STDMETHODIMP_(REFIID) MarshalAs(REFIID aIid) override;
// ICallFrameWalker
STDMETHODIMP OnWalkInterface(REFIID aIid, PVOID* aInterface, BOOL aIsInParam,
BOOL aIsOutParam) override;
private:
explicit MainThreadHandoff(IHandlerProvider* aHandlerProvider);
~MainThreadHandoff();
HRESULT FixArrayElements(ICallFrame* aFrame,
const ArrayData& aArrayData);
HRESULT FixIServiceProvider(ICallFrame* aFrame);
private:
ULONG mRefCnt;
RefPtr<IWeakReference> mInterceptor;
RefPtr<IHandlerProvider> mHandlerProvider;
};
} // namespace mscom
} // namespace mozilla
#endif // mozilla_mscom_MainThreadHandoff_h