Bug 1694865 part 3: Move id management to MsaaAccessible. r=morgan

Differential Revision: https://phabricator.services.mozilla.com/D112934
This commit is contained in:
James Teh 2021-04-28 06:21:44 +00:00
Родитель 539707ee5f
Коммит 431c171587
13 изменённых файлов: 131 добавлений и 109 удалений

Просмотреть файл

@ -909,7 +909,7 @@ void NotificationController::WillRefresh(mozilla::TimeStamp aTime) {
#if defined(XP_WIN)
parentIPCDoc->ConstructChildDocInParentProcess(
ipcDoc, id, AccessibleWrap::GetChildIDFor(childDoc));
ipcDoc, id, MsaaAccessible::GetChildIDFor(childDoc));
#else
nsCOMPtr<nsIBrowserChild> browserChild =
do_GetInterface(mDocument->DocumentNode()->GetDocShell());

Просмотреть файл

@ -1763,7 +1763,7 @@ void DocAccessible::DoInitialUpdate() {
IAccessibleHolder holder(
CreateHolderFromAccessible(WrapNotNull(this)));
MOZ_ASSERT(!holder.IsNull());
int32_t childID = AccessibleWrap::GetChildIDFor(this);
int32_t childID = MsaaAccessible::GetChildIDFor(this);
#else
int32_t holder = 0, childID = 0;
#endif

Просмотреть файл

@ -17,7 +17,7 @@ void DocAccessibleChildBase::SerializeTree(LocalAccessible* aRoot,
nsTArray<AccessibleData>& aTree) {
uint64_t id = reinterpret_cast<uint64_t>(aRoot->UniqueID());
#if defined(XP_WIN)
int32_t msaaId = AccessibleWrap::GetChildIDFor(aRoot);
int32_t msaaId = MsaaAccessible::GetChildIDFor(aRoot);
#endif
a11y::role role = aRoot->Role();
uint32_t childCount = aRoot->ChildCount();

Просмотреть файл

@ -339,7 +339,7 @@ ia2Accessible::get_uniqueID(long* aUniqueID) {
if (!aUniqueID) return E_INVALIDARG;
AccessibleWrap* acc = static_cast<AccessibleWrap*>(this);
*aUniqueID = AccessibleWrap::GetChildIDFor(acc);
*aUniqueID = MsaaAccessible::GetChildIDFor(acc);
return S_OK;
}

Просмотреть файл

@ -64,7 +64,6 @@ const uint32_t USE_ROLE_STRING = 0;
static gAccessibles = 0;
#endif
MsaaIdGenerator AccessibleWrap::sIDGen;
StaticAutoPtr<nsTArray<AccessibleWrap::HandlerControllerData>>
AccessibleWrap::sHandlerControllers;
@ -76,13 +75,7 @@ static const int32_t kIEnumVariantDisconnected = -1;
// AccessibleWrap
////////////////////////////////////////////////////////////////////////////////
AccessibleWrap::AccessibleWrap(nsIContent* aContent, DocAccessible* aDoc)
: LocalAccessible(aContent, aDoc), mID(kNoID) {}
AccessibleWrap::~AccessibleWrap() {
if (mID != kNoID) {
sIDGen.ReleaseID(WrapNotNull(this));
}
}
: LocalAccessible(aContent, aDoc) {}
ITypeInfo* AccessibleWrap::gTypeInfo = nullptr;
@ -1077,11 +1070,6 @@ void AccessibleWrap::GetNativeInterface(void** aOutAccessible) {
NS_ADDREF_THIS();
}
void AccessibleWrap::SetID(uint32_t aID) {
MOZ_ASSERT(XRE_IsParentProcess() && IsProxy());
mID = aID;
}
static bool IsHandlerInvalidationNeeded(uint32_t aEvent) {
// We want to return true for any events that would indicate that something
// in the handler cache is out of date.
@ -1123,7 +1111,7 @@ void AccessibleWrap::FireWinEvent(LocalAccessible* aTarget,
uint32_t winEvent = gWinEventMap[aEventType];
if (!winEvent) return;
int32_t childID = GetChildIDFor(aTarget);
int32_t childID = MsaaAccessible::GetChildIDFor(aTarget);
if (!childID) return; // Can't fire an event without a child ID
HWND hwnd = GetHWNDFor(aTarget);
@ -1187,37 +1175,6 @@ DocRemoteAccessibleWrap* AccessibleWrap::DocProxyWrapper() const {
//------- Helper methods ---------
int32_t AccessibleWrap::GetChildIDFor(LocalAccessible* aAccessible) {
// A child ID of the window is required, when we use NotifyWinEvent,
// so that the 3rd party application can call back and get the IAccessible
// the event occurred on.
if (!aAccessible) {
return 0;
}
// Chrome should use mID which has been generated by the content process.
if (aAccessible->IsProxy()) {
const uint32_t id = static_cast<AccessibleWrap*>(aAccessible)->mID;
MOZ_ASSERT(id != kNoID);
return id;
}
if (!aAccessible->Document()) return 0;
uint32_t* id = &static_cast<AccessibleWrap*>(aAccessible)->mID;
if (*id != kNoID) return *id;
*id = sIDGen.GetID();
MOZ_ASSERT(!aAccessible->IsProxy());
DocAccessibleWrap* doc =
static_cast<DocAccessibleWrap*>(aAccessible->Document());
doc->AddID(*id, static_cast<AccessibleWrap*>(aAccessible));
return *id;
}
HWND AccessibleWrap::GetHWNDFor(LocalAccessible* aAccessible) {
if (!aAccessible) {
return nullptr;
@ -1311,7 +1268,7 @@ static already_AddRefed<IDispatch> GetProxiedAccessibleInSubtree(
const DocAccessibleParent* aDoc, const VARIANT& aVarChild) {
auto wrapper = static_cast<DocRemoteAccessibleWrap*>(WrapperFor(aDoc));
RefPtr<IAccessible> comProxy;
int32_t docWrapperChildId = AccessibleWrap::GetChildIDFor(wrapper);
int32_t docWrapperChildId = MsaaAccessible::GetChildIDFor(wrapper);
// Only document accessible proxies at the top level of their content process
// are created with a pointer to their COM proxy.
if (aDoc->IsTopLevelInContentProcess()) {
@ -1648,18 +1605,6 @@ ITypeInfo* AccessibleWrap::GetTI(LCID lcid) {
return gTypeInfo;
}
/* static */
uint32_t AccessibleWrap::GetContentProcessIdFor(
dom::ContentParentId aIPCContentId) {
return sIDGen.GetContentProcessIDFor(aIPCContentId);
}
/* static */
void AccessibleWrap::ReleaseContentProcessIdFor(
dom::ContentParentId aIPCContentId) {
sIDGen.ReleaseContentProcessIDFor(aIPCContentId);
}
/* static */
void AccessibleWrap::SetHandlerControl(DWORD aPid,
RefPtr<IHandlerControl> aCtrl) {
@ -1726,7 +1671,7 @@ bool AccessibleWrap::DispatchTextChangeToHandler(bool aIsInsert,
return false;
}
long msaaId = GetChildIDFor(this);
long msaaId = MsaaAccessible::GetChildIDFor(this);
DWORD ourPid = ::GetCurrentProcessId();
@ -1763,13 +1708,3 @@ bool AccessibleWrap::DispatchTextChangeToHandler(bool aIsInsert,
return SUCCEEDED(hr);
}
/* static */
void AccessibleWrap::AssignChildIDTo(NotNull<sdnAccessible*> aSdnAcc) {
aSdnAcc->SetUniqueID(sIDGen.GetID());
}
/* static */
void AccessibleWrap::ReleaseChildID(NotNull<sdnAccessible*> aSdnAcc) {
sIDGen.ReleaseID(aSdnAcc);
}

Просмотреть файл

@ -11,7 +11,6 @@
#include "LocalAccessible.h"
#include "MsaaAccessible.h"
#include "mozilla/a11y/AccessibleHandler.h"
#include "mozilla/a11y/MsaaIdGenerator.h"
#include "mozilla/a11y/RemoteAccessible.h"
#include "mozilla/Attributes.h"
#include "mozilla/mscom/Utils.h"
@ -153,7 +152,6 @@ class AccessibleWrap : public LocalAccessible, public MsaaAccessible {
virtual void Shutdown() override;
// Helper methods
static int32_t GetChildIDFor(LocalAccessible* aAccessible);
static HWND GetHWNDFor(LocalAccessible* aAccessible);
static void FireWinEvent(LocalAccessible* aTarget, uint32_t aEventType);
@ -203,13 +201,6 @@ class AccessibleWrap : public LocalAccessible, public MsaaAccessible {
static IDispatch* NativeAccessible(LocalAccessible* aAccessible);
uint32_t GetExistingID() const { return mID; }
static const uint32_t kNoID = 0;
void SetID(uint32_t aID);
static uint32_t GetContentProcessIdFor(dom::ContentParentId aIPCContentId);
static void ReleaseContentProcessIdFor(dom::ContentParentId aIPCContentId);
static void SetHandlerControl(DWORD aPid, RefPtr<IHandlerControl> aCtrl);
static void InvalidateHandlers();
@ -217,13 +208,8 @@ class AccessibleWrap : public LocalAccessible, public MsaaAccessible {
bool DispatchTextChangeToHandler(bool aIsInsert, const nsString& aText,
int32_t aStart, uint32_t aLen);
static void AssignChildIDTo(NotNull<sdnAccessible*> aSdnAcc);
static void ReleaseChildID(NotNull<sdnAccessible*> aSdnAcc);
protected:
virtual ~AccessibleWrap();
uint32_t mID;
virtual ~AccessibleWrap() = default;
HRESULT
ResolveChild(const VARIANT& aVarChild, IAccessible** aOutInterface);
@ -246,8 +232,6 @@ class AccessibleWrap : public LocalAccessible, public MsaaAccessible {
static ITypeInfo* gTypeInfo;
static MsaaIdGenerator sIDGen;
enum navRelations {
NAVRELATION_CONTROLLED_BY = 0x1000,
NAVRELATION_CONTROLLER_FOR = 0x1001,

Просмотреть файл

@ -0,0 +1,80 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=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/. */
#include "MsaaAccessible.h"
#include "sdnAccessible.h"
using namespace mozilla;
using namespace mozilla::a11y;
MsaaIdGenerator MsaaAccessible::sIDGen;
MsaaAccessible::MsaaAccessible() : mID(kNoID) {}
MsaaAccessible::~MsaaAccessible() {
if (mID != kNoID) {
sIDGen.ReleaseID(WrapNotNull(this));
}
}
void MsaaAccessible::SetID(uint32_t aID) {
MOZ_ASSERT(XRE_IsParentProcess() &&
static_cast<AccessibleWrap*>(this)->IsProxy());
mID = aID;
}
int32_t MsaaAccessible::GetChildIDFor(LocalAccessible* aAccessible) {
// A child ID of the window is required, when we use NotifyWinEvent,
// so that the 3rd party application can call back and get the IAccessible
// the event occurred on.
if (!aAccessible) {
return 0;
}
// Chrome should use mID which has been generated by the content process.
if (aAccessible->IsProxy()) {
const uint32_t id = static_cast<AccessibleWrap*>(aAccessible)->mID;
MOZ_ASSERT(id != kNoID);
return id;
}
if (!aAccessible->Document()) return 0;
uint32_t* id = &static_cast<AccessibleWrap*>(aAccessible)->mID;
if (*id != kNoID) return *id;
*id = sIDGen.GetID();
MOZ_ASSERT(!aAccessible->IsProxy());
DocAccessibleWrap* doc =
static_cast<DocAccessibleWrap*>(aAccessible->Document());
doc->AddID(*id, static_cast<AccessibleWrap*>(aAccessible));
return *id;
}
/* static */
uint32_t MsaaAccessible::GetContentProcessIdFor(
dom::ContentParentId aIPCContentId) {
return sIDGen.GetContentProcessIDFor(aIPCContentId);
}
/* static */
void MsaaAccessible::ReleaseContentProcessIdFor(
dom::ContentParentId aIPCContentId) {
sIDGen.ReleaseContentProcessIDFor(aIPCContentId);
}
/* static */
void MsaaAccessible::AssignChildIDTo(NotNull<sdnAccessible*> aSdnAcc) {
aSdnAcc->SetUniqueID(sIDGen.GetID());
}
/* static */
void MsaaAccessible::ReleaseChildID(NotNull<sdnAccessible*> aSdnAcc) {
sIDGen.ReleaseID(aSdnAcc);
}

Просмотреть файл

@ -11,14 +11,37 @@
#include "ia2AccessibleComponent.h"
#include "ia2AccessibleHyperlink.h"
#include "ia2AccessibleValue.h"
#include "mozilla/a11y/MsaaIdGenerator.h"
#include "mozilla/dom/ipc/IdType.h"
namespace mozilla {
namespace a11y {
class LocalAccessible;
class sdnAccessible;
class MsaaAccessible : public ia2Accessible,
public ia2AccessibleComponent,
public ia2AccessibleHyperlink,
public ia2AccessibleValue {};
public ia2AccessibleValue {
public:
MsaaAccessible();
uint32_t GetExistingID() const { return mID; }
static const uint32_t kNoID = 0;
void SetID(uint32_t aID);
static int32_t GetChildIDFor(LocalAccessible* aAccessible);
static uint32_t GetContentProcessIdFor(dom::ContentParentId aIPCContentId);
static void ReleaseContentProcessIdFor(dom::ContentParentId aIPCContentId);
static void AssignChildIDTo(NotNull<sdnAccessible*> aSdnAcc);
static void ReleaseChildID(NotNull<sdnAccessible*> aSdnAcc);
protected:
virtual ~MsaaAccessible();
uint32_t mID;
static MsaaIdGenerator sIDGen;
};
} // namespace a11y
} // namespace mozilla

Просмотреть файл

@ -7,6 +7,7 @@
#include "MsaaIdGenerator.h"
#include "mozilla/a11y/AccessibleWrap.h"
#include "mozilla/a11y/MsaaAccessible.h"
#include "mozilla/Assertions.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/DebugOnly.h"
@ -81,7 +82,7 @@ uint32_t MsaaIdGenerator::GetID() {
}
bool MsaaIdGenerator::ReleaseID(uint32_t aID) {
MOZ_ASSERT(aID != AccessibleWrap::kNoID);
MOZ_ASSERT(aID != MsaaAccessible::kNoID);
detail::MsaaIDCracker cracked(aID);
if (cracked.GetContentProcessId() != ResolveContentProcessID()) {
return false;
@ -90,14 +91,12 @@ bool MsaaIdGenerator::ReleaseID(uint32_t aID) {
return true;
}
void MsaaIdGenerator::ReleaseID(NotNull<AccessibleWrap*> aAccWrap) {
if (!ReleaseID(aAccWrap->GetExistingID())) {
// This may happen if chrome holds a proxy whose ID was originally generated
// by a content process. Since ReleaseID only has meaning in the process
// that originally generated that ID, we ignore ReleaseID calls for any ID
// that did not come from the current process.
MOZ_ASSERT(aAccWrap->IsProxy());
}
void MsaaIdGenerator::ReleaseID(NotNull<MsaaAccessible*> aMsaaAcc) {
// ReleaseID may fail if chrome holds a proxy whose ID was originally
// generated by a content process. Since ReleaseID only has meaning in the
// process that originally generated that ID, we ignore ReleaseID calls for
// any ID that did not come from the current process.
ReleaseID(aMsaaAcc->GetExistingID());
}
void MsaaIdGenerator::ReleaseID(NotNull<sdnAccessible*> aSdnAcc) {

Просмотреть файл

@ -15,7 +15,7 @@
namespace mozilla {
namespace a11y {
class AccessibleWrap;
class MsaaAccessible;
class sdnAccessible;
/**
@ -34,7 +34,7 @@ class MsaaIdGenerator {
constexpr MsaaIdGenerator();
uint32_t GetID();
void ReleaseID(NotNull<AccessibleWrap*> aAccWrap);
void ReleaseID(NotNull<MsaaAccessible*> aMsaaAcc);
void ReleaseID(NotNull<sdnAccessible*> aSdnAcc);
bool IsChromeID(uint32_t aID);
bool IsIDForThisContentProcess(uint32_t aID);

Просмотреть файл

@ -31,6 +31,7 @@ UNIFIED_SOURCES += [
"HyperTextAccessibleWrap.cpp",
"ImageAccessibleWrap.cpp",
"IUnknownImpl.cpp",
"MsaaAccessible.cpp",
"MsaaIdGenerator.cpp",
"nsWinUtils.cpp",
"Platform.cpp",

Просмотреть файл

@ -29,7 +29,7 @@ using namespace mozilla::a11y;
sdnAccessible::~sdnAccessible() {
if (mUniqueId.isSome()) {
AccessibleWrap::ReleaseChildID(WrapNotNull(this));
MsaaAccessible::ReleaseChildID(WrapNotNull(this));
}
}
@ -107,10 +107,10 @@ sdnAccessible::get_nodeInfo(BSTR __RPC_FAR* aNodeName,
// model.
AccessibleWrap* accessible = GetAccessible();
if (accessible) {
*aUniqueID = AccessibleWrap::GetChildIDFor(accessible);
*aUniqueID = MsaaAccessible::GetChildIDFor(accessible);
} else {
if (mUniqueId.isNothing()) {
AccessibleWrap::AssignChildIDTo(WrapNotNull(this));
MsaaAccessible::AssignChildIDTo(WrapNotNull(this));
}
MOZ_ASSERT(mUniqueId.isSome());
*aUniqueID = mUniqueId.value();

Просмотреть файл

@ -1679,7 +1679,7 @@ void ContentParent::Init() {
if (!mozilla::a11y::Compatibility::IsOldJAWS()) {
Unused << SendActivateA11y(
::GetCurrentThreadId(),
a11y::AccessibleWrap::GetContentProcessIdFor(ChildID()));
a11y::MsaaAccessible::GetContentProcessIdFor(ChildID()));
}
# else
Unused << SendActivateA11y(0, 0);
@ -2125,7 +2125,7 @@ void ContentParent::ActorDestroy(ActorDestroyReason why) {
mBlobURLs.Clear();
#if defined(XP_WIN) && defined(ACCESSIBILITY)
a11y::AccessibleWrap::ReleaseContentProcessIdFor(ChildID());
a11y::MsaaAccessible::ReleaseContentProcessIdFor(ChildID());
#endif
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
@ -3610,7 +3610,7 @@ ContentParent::Observe(nsISupports* aSubject, const char* aTopic,
if (!mozilla::a11y::Compatibility::IsOldJAWS()) {
Unused << SendActivateA11y(
::GetCurrentThreadId(),
a11y::AccessibleWrap::GetContentProcessIdFor(ChildID()));
a11y::MsaaAccessible::GetContentProcessIdFor(ChildID()));
}
# else
Unused << SendActivateA11y(0, 0);
@ -5884,7 +5884,7 @@ ContentParent::RecvUnstoreAndBroadcastBlobURLUnregistration(
mozilla::ipc::IPCResult ContentParent::RecvGetA11yContentId(
uint32_t* aContentId) {
#if defined(XP_WIN) && defined(ACCESSIBILITY)
*aContentId = a11y::AccessibleWrap::GetContentProcessIdFor(ChildID());
*aContentId = a11y::MsaaAccessible::GetContentProcessIdFor(ChildID());
MOZ_ASSERT(*aContentId);
return IPC_OK();
#else