gecko-dev/accessible/ipc/win/HandlerProvider.h
James Teh 39c71764d7 Bug 1431256 part 1: Accessible HandlerProvider: Implement a method to optimally retrieve all children in a single call. r=MarcoZ
When considering a large document, a huge number of the children we return are text leaf nodes.
Marshaling full objects is expensive, but for text leaf nodes, the client is only interested in the text and a few other pieces of information.
Therefore, rather than returning the full object for text leaf accessibles, we just return the text and other necessary information.
For other non-text children, we return the full object as usual.

In addition, clients normally use the IEnumVARIANT interface to retrieve children in a single call.
However, it doesn't allow you to specify a starting index.
Therefore, you must first call the Reset method to reset the starting point to 0.
Practically, this means an extra cross-process call whenever the caller fetches children.
When dealing with a large document, this can be a significant number of wasted calls.
This new method retrieves all children always starting at the first using a single call.

MozReview-Commit-ID: A9lc7BBTWdb

--HG--
extra : rebase_source : d50507c182ab7760c17c5e7bb9956f46a3dc188c
2018-03-21 10:08:53 -04:00

115 lines
4.9 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_a11y_HandlerProvider_h
#define mozilla_a11y_HandlerProvider_h
#include "mozilla/a11y/AccessibleHandler.h"
#include "mozilla/AlreadyAddRefed.h"
#include "mozilla/Atomics.h"
#include "mozilla/mscom/IHandlerProvider.h"
#include "mozilla/mscom/Ptr.h"
#include "mozilla/mscom/StructStream.h"
#include "mozilla/Mutex.h"
#include "mozilla/UniquePtr.h"
#include "HandlerData.h"
struct NEWEST_IA2_INTERFACE;
namespace mozilla {
namespace mscom {
class StructToStream;
} // namespace mscom
namespace a11y {
class HandlerProvider final : public IGeckoBackChannel
, public mscom::IHandlerProvider
{
public:
HandlerProvider(REFIID aIid, mscom::InterceptorTargetPtr<IUnknown> aTarget);
// IUnknown
STDMETHODIMP QueryInterface(REFIID riid, void** ppv) override;
STDMETHODIMP_(ULONG) AddRef() override;
STDMETHODIMP_(ULONG) Release() override;
// IHandlerProvider
STDMETHODIMP GetHandler(NotNull<CLSID*> aHandlerClsid) override;
STDMETHODIMP GetHandlerPayloadSize(NotNull<mscom::IInterceptor*> aInterceptor,
NotNull<DWORD*> aOutPayloadSize) override;
STDMETHODIMP WriteHandlerPayload(NotNull<mscom::IInterceptor*> aInterceptor,
NotNull<IStream*> aStream) override;
STDMETHODIMP_(REFIID) MarshalAs(REFIID aIid) override;
STDMETHODIMP DisconnectHandlerRemotes() override;
STDMETHODIMP_(REFIID) GetEffectiveOutParamIid(REFIID aCallIid,
ULONG aCallMethod) override;
STDMETHODIMP NewInstance(REFIID aIid,
mscom::InterceptorTargetPtr<IUnknown> aTarget,
NotNull<mscom::IHandlerProvider**> aOutNewPayload) override;
// IGeckoBackChannel
STDMETHODIMP put_HandlerControl(long aPid, IHandlerControl* aCtrl) override;
STDMETHODIMP Refresh(DynamicIA2Data* aOutData) override;
STDMETHODIMP get_AllTextInfo(BSTR* aText,
IAccessibleHyperlink*** aHyperlinks,
long* aNHyperlinks,
IA2TextSegment** aAttribRuns,
long* aNAttribRuns) override;
STDMETHODIMP get_RelationsInfo(IARelationData** aRelations,
long* aNRelations) override;
STDMETHODIMP get_AllChildren(AccChildData** aChildren,
ULONG* aNChildren) override;
private:
~HandlerProvider() = default;
void SetHandlerControlOnMainThread(DWORD aPid,
mscom::ProxyUniquePtr<IHandlerControl> aCtrl);
void GetAndSerializePayload(const MutexAutoLock&,
NotNull<mscom::IInterceptor*> aInterceptor);
void BuildStaticIA2Data(NotNull<mscom::IInterceptor*> aInterceptor,
StaticIA2Data* aOutData);
void BuildDynamicIA2Data(DynamicIA2Data* aOutIA2Data);
void BuildInitialIA2Data(NotNull<mscom::IInterceptor*> aInterceptor,
StaticIA2Data* aOutStaticData,
DynamicIA2Data* aOutDynamicData);
static void CleanupStaticIA2Data(StaticIA2Data& aData);
bool IsTargetInterfaceCacheable();
// Replace a raw object from the main thread with a wrapped, intercepted
// object suitable for calling from the MTA.
// The reference to the original object is adopted; i.e. you should not
// separately release it.
// This is intended for objects returned from method calls on the main thread.
template<typename Interface> HRESULT ToWrappedObject(Interface** aObj);
void GetAllTextInfoMainThread(BSTR* aText,
IAccessibleHyperlink*** aHyperlinks,
long* aNHyperlinks,
IA2TextSegment** aAttribRuns,
long* aNAttribRuns,
HRESULT* result);
void GetRelationsInfoMainThread(IARelationData** aRelations,
long* aNRelations,
HRESULT* result);
void GetAllChildrenMainThread(AccChildData** aChildren, ULONG* aNChildren,
HRESULT* result);
Atomic<uint32_t> mRefCnt;
Mutex mMutex; // Protects mSerializer
const IID mTargetUnkIid;
mscom::InterceptorTargetPtr<IUnknown> mTargetUnk; // Constant, main thread only
UniquePtr<mscom::StructToStream> mSerializer;
RefPtr<IUnknown> mFastMarshalUnk;
};
} // namespace a11y
} // namespace mozilla
#endif // mozilla_a11y_HandlerProvider_h