Bug 1409928: Use e10s a11y handler cache for accessibles retrieved via IAccessibleHypertext. r=aklotz

IAccessibleHypertext::hyperlink returns an IAccessibleHyperlink, not an IAccessible2.
previously, the handler didn't know about this interface, so it wasn't used.
Thus, any accessibles retrieved in this way did not benefit from the cache.
This patch teaches the handler about IAccessibleHyperlink so the handler gets used in this case.

MozReview-Commit-ID: 17CxxGyCLrE

--HG--
extra : rebase_source : 7f933bfd880c9ee009eafe8cee4ece4ef83004cd
This commit is contained in:
James Teh 2017-10-13 17:01:20 +10:00
parent a6b525b33e
commit 627fc4f0b6
3 changed files with 187 additions and 4 deletions

View File

@ -187,10 +187,14 @@ HandlerProvider::BuildIA2Data(IA2Data* aOutIA2Data)
MOZ_ASSERT(mTargetUnk);
MOZ_ASSERT(IsTargetInterfaceCacheable());
RefPtr<NEWEST_IA2_INTERFACE>
target(static_cast<NEWEST_IA2_INTERFACE*>(mTargetUnk.get()));
RefPtr<NEWEST_IA2_INTERFACE> target;
HRESULT hr = mTargetUnk.get()->QueryInterface(NEWEST_IA2_IID,
getter_AddRefs(target));
if (FAILED(hr)) {
return;
}
HRESULT hr = E_UNEXPECTED;
hr = E_UNEXPECTED;
auto hasFailed = [&hr]() -> bool {
return FAILED(hr);
@ -294,7 +298,8 @@ HandlerProvider::ClearIA2Data(IA2Data& aData)
bool
HandlerProvider::IsTargetInterfaceCacheable()
{
return MarshalAs(mTargetUnkIid) == NEWEST_IA2_IID;
return MarshalAs(mTargetUnkIid) == NEWEST_IA2_IID ||
mTargetUnkIid == IID_IAccessibleHyperlink;
}
HRESULT

View File

@ -28,6 +28,7 @@
#include "Accessible2_i.c"
#include "Accessible2_2_i.c"
#include "Accessible2_3_i.c"
#include "AccessibleHyperlink_i.c"
namespace mozilla {
namespace a11y {
@ -60,6 +61,7 @@ AccessibleHandler::AccessibleHandler(IUnknown* aOuter, HRESULT* aResult)
, mDispatch(nullptr)
, mIA2PassThru(nullptr)
, mServProvPassThru(nullptr)
, mIAHyperlinkPassThru(nullptr)
, mCachedData()
, mCacheGen(0)
{
@ -104,6 +106,29 @@ AccessibleHandler::ResolveIA2()
return hr;
}
HRESULT
AccessibleHandler::ResolveIAHyperlink()
{
if (mIAHyperlinkPassThru) {
return S_OK;
}
RefPtr<IUnknown> proxy(GetProxy());
if (!proxy) {
return E_UNEXPECTED;
}
HRESULT hr = proxy->QueryInterface(IID_IAccessibleHyperlink,
reinterpret_cast<void**>(&mIAHyperlinkPassThru));
if (SUCCEEDED(hr)) {
// mIAHyperlinkPassThru is a weak reference
// (see comments in AccesssibleHandler.h)
mIAHyperlinkPassThru->Release();
}
return hr;
}
HRESULT
AccessibleHandler::MaybeUpdateCachedData()
{
@ -392,6 +417,8 @@ CopyBSTR(BSTR aSrc)
assignTo = CopyBSTR(mCachedData.mData.member); \
}
/*** IAccessible ***/
HRESULT
AccessibleHandler::get_accParent(IDispatch **ppdispParent)
{
@ -709,6 +736,8 @@ AccessibleHandler::put_accValue(VARIANT varChild, BSTR szValue)
return E_NOTIMPL;
}
/*** IAccessible2 ***/
HRESULT
AccessibleHandler::get_nRelations(long* nRelations)
{
@ -966,6 +995,8 @@ AccessibleHandler::get_attributes(BSTR* attributes)
return S_OK;
}
/*** IAccessible2_2 ***/
HRESULT
AccessibleHandler::get_attribute(BSTR name, VARIANT* attribute)
{
@ -1000,6 +1031,8 @@ AccessibleHandler::get_relationTargetsOfType(BSTR type, long maxTargets,
nTargets);
}
/*** IAccessible2_3 ***/
HRESULT
AccessibleHandler::get_selectionRanges(IA2Range** ranges, long* nRanges)
{
@ -1023,6 +1056,8 @@ static const GUID kUnsupportedServices[] = {
{0xb96fdb85, 0x7204, 0x4724, { 0x84, 0x2b, 0xc7, 0x05, 0x9d, 0xed, 0xb9, 0xd0 }}
};
/*** IServiceProvider ***/
HRESULT
AccessibleHandler::QueryService(REFGUID aServiceId, REFIID aIid,
void** aOutInterface)
@ -1064,6 +1099,8 @@ AccessibleHandler::QueryService(REFGUID aServiceId, REFIID aIid,
return mServProvPassThru->QueryService(aServiceId, aIid, aOutInterface);
}
/*** IProvideClassInfo ***/
HRESULT
AccessibleHandler::GetClassInfo(ITypeInfo** aOutTypeInfo)
{
@ -1075,6 +1112,124 @@ AccessibleHandler::GetClassInfo(ITypeInfo** aOutTypeInfo)
return ctl->GetHandlerTypeInfo(aOutTypeInfo);
}
/*** IAccessibleAction ***/
HRESULT
AccessibleHandler::nActions(long* nActions)
{
HRESULT hr = ResolveIAHyperlink();
if (FAILED(hr)) {
return hr;
}
return mIAHyperlinkPassThru->nActions(nActions);
}
HRESULT
AccessibleHandler::doAction(long actionIndex)
{
HRESULT hr = ResolveIAHyperlink();
if (FAILED(hr)) {
return hr;
}
return mIAHyperlinkPassThru->doAction(actionIndex);
}
HRESULT
AccessibleHandler::get_description(long actionIndex, BSTR* description)
{
HRESULT hr = ResolveIAHyperlink();
if (FAILED(hr)) {
return hr;
}
return mIAHyperlinkPassThru->get_description(actionIndex, description);
}
HRESULT
AccessibleHandler::get_keyBinding(long actionIndex,
long nMaxBindings,
BSTR** keyBindings,
long* nBindings)
{
HRESULT hr = ResolveIAHyperlink();
if (FAILED(hr)) {
return hr;
}
return mIAHyperlinkPassThru->get_keyBinding(
actionIndex, nMaxBindings, keyBindings, nBindings);
}
HRESULT
AccessibleHandler::get_name(long actionIndex, BSTR* name)
{
HRESULT hr = ResolveIAHyperlink();
if (FAILED(hr)) {
return hr;
}
return mIAHyperlinkPassThru->get_name(actionIndex, name);
}
HRESULT
AccessibleHandler::get_localizedName(long actionIndex, BSTR* localizedName)
{
HRESULT hr = ResolveIAHyperlink();
if (FAILED(hr)) {
return hr;
}
return mIAHyperlinkPassThru->get_localizedName(actionIndex, localizedName);
}
/*** IAccessibleHyperlink ***/
HRESULT
AccessibleHandler::get_anchor(long index, VARIANT* anchor)
{
HRESULT hr = ResolveIAHyperlink();
if (FAILED(hr)) {
return hr;
}
return mIAHyperlinkPassThru->get_anchor(index, anchor);
}
HRESULT
AccessibleHandler::get_anchorTarget(long index, VARIANT* anchorTarget)
{
HRESULT hr = ResolveIAHyperlink();
if (FAILED(hr)) {
return hr;
}
return mIAHyperlinkPassThru->get_anchorTarget(index, anchorTarget);
}
HRESULT
AccessibleHandler::get_startIndex(long* index)
{
HRESULT hr = ResolveIAHyperlink();
if (FAILED(hr)) {
return hr;
}
return mIAHyperlinkPassThru->get_startIndex(index);
}
HRESULT
AccessibleHandler::get_endIndex(long* index)
{
HRESULT hr = ResolveIAHyperlink();
if (FAILED(hr)) {
return hr;
}
return mIAHyperlinkPassThru->get_endIndex(index);
}
HRESULT
AccessibleHandler::get_valid(boolean* valid)
{
HRESULT hr = ResolveIAHyperlink();
if (FAILED(hr)) {
return hr;
}
return mIAHyperlinkPassThru->get_valid(valid);
}
} // namespace a11y
} // namespace mozilla

View File

@ -35,6 +35,7 @@ import NEWEST_IA2_IDL;
#if !defined(MOZILLA_INTERNAL_API)
#include "Accessible2_3.h"
#include "AccessibleHyperlink.h"
#include "Handler.h"
#include "mozilla/mscom/StructStream.h"
#include "mozilla/UniquePtr.h"
@ -49,6 +50,7 @@ class AccessibleHandler final : public mscom::Handler
, public NEWEST_IA2_INTERFACE
, public IServiceProvider
, public IProvideClassInfo
, public IAccessibleHyperlink
{
public:
static HRESULT Create(IUnknown* aOuter, REFIID aIid, void** aOutInterface);
@ -152,12 +154,32 @@ public:
// IProvideClassInfo
STDMETHODIMP GetClassInfo(ITypeInfo** aOutTypeInfo) override;
// IAccessibleAction
STDMETHODIMP nActions(long* nActions) override;
STDMETHODIMP doAction(long actionIndex) override;
STDMETHODIMP get_description(long actionIndex, BSTR* description) override;
STDMETHODIMP get_keyBinding(long actionIndex,
long nMaxBindings,
BSTR** keyBindings,
long* nBindings) override;
STDMETHODIMP get_name(long actionIndex, BSTR* name) override;
STDMETHODIMP get_localizedName(long actionIndex,
BSTR* localizedName) override;
// IAccessibleHyperlink
STDMETHODIMP get_anchor(long index, VARIANT* anchor) override;
STDMETHODIMP get_anchorTarget(long index, VARIANT* anchorTarget) override;
STDMETHODIMP get_startIndex(long* index) override;
STDMETHODIMP get_endIndex(long* index) override;
STDMETHODIMP get_valid(boolean* valid) override;
private:
AccessibleHandler(IUnknown* aOuter, HRESULT* aResult);
virtual ~AccessibleHandler();
HRESULT ResolveIA2();
HRESULT ResolveIDispatch();
HRESULT ResolveIAHyperlink();
HRESULT MaybeUpdateCachedData();
RefPtr<IUnknown> mDispatchUnk;
@ -183,6 +205,7 @@ private:
IDispatch* mDispatch; // weak
NEWEST_IA2_INTERFACE* mIA2PassThru; // weak
IServiceProvider* mServProvPassThru; // weak
IAccessibleHyperlink* mIAHyperlinkPassThru; // weak
IA2Payload mCachedData;
UniquePtr<mscom::StructToStream> mSerializer;
uint32_t mCacheGen;