Skip to content
Snippets Groups Projects
Verified Commit 15dfdc00 authored by Eitan Isaacson's avatar Eitan Isaacson Committed by Pier Angelo Vendrame
Browse files

Bug 1819160 - Map Android ids to doc/accessible id pairs. r=Jamie

parent 07ab3c00
No related branches found
No related tags found
1 merge request!815Rebased onto Firefox 115.3.1esr
......@@ -269,12 +269,9 @@ RefPtr<SessionAccessibility> SessionAccessibility::GetInstanceFor(
return GetInstanceFor(doc->GetPresShell());
}
} else {
DocAccessibleParent* remoteDoc = aAccessible->AsRemote()->Document();
if (remoteDoc->mSessionAccessibility) {
return remoteDoc->mSessionAccessibility;
}
dom::CanonicalBrowsingContext* cbc =
static_cast<dom::BrowserParent*>(remoteDoc->Manager())
static_cast<dom::BrowserParent*>(
aAccessible->AsRemote()->Document()->Manager())
->GetBrowsingContext()
->Top();
dom::BrowserParent* bp = cbc->GetBrowserParent();
......@@ -285,10 +282,7 @@ RefPtr<SessionAccessibility> SessionAccessibility::GetInstanceFor(
if (auto element = bp->GetOwnerElement()) {
if (auto doc = element->OwnerDoc()) {
if (nsPresContext* presContext = doc->GetPresContext()) {
RefPtr<SessionAccessibility> sessionAcc =
GetInstanceFor(presContext->PresShell());
remoteDoc->mSessionAccessibility = sessionAcc;
return sessionAcc;
return GetInstanceFor(presContext->PresShell());
}
} else {
MOZ_ASSERT_UNREACHABLE(
......@@ -684,14 +678,7 @@ void SessionAccessibility::PopulateNodeInfo(
}
Accessible* SessionAccessibility::GetAccessibleByID(int32_t aID) const {
Accessible* accessible = mIDToAccessibleMap.Get(aID);
if (accessible && accessible->IsLocal() &&
accessible->AsLocal()->IsDefunct()) {
MOZ_ASSERT_UNREACHABLE("Registered accessible is defunct!");
return nullptr;
}
return accessible;
return mIDToAccessibleMap.Get(aID);
}
#ifdef DEBUG
......@@ -705,6 +692,58 @@ static bool IsDetachedDoc(Accessible* aAccessible) {
}
#endif
SessionAccessibility::IDMappingEntry::IDMappingEntry(Accessible* aAccessible)
: mInternalID(0) {
*this = aAccessible;
}
SessionAccessibility::IDMappingEntry&
SessionAccessibility::IDMappingEntry::operator=(Accessible* aAccessible) {
mInternalID = aAccessible->ID();
MOZ_ASSERT(!(mInternalID & IS_REMOTE), "First bit is used in accessible ID!");
if (aAccessible->IsRemote()) {
mInternalID |= IS_REMOTE;
}
Accessible* docAcc = nsAccUtils::DocumentFor(aAccessible);
MOZ_ASSERT(docAcc);
if (docAcc) {
MOZ_ASSERT(docAcc->IsRemote() == aAccessible->IsRemote());
if (docAcc->IsRemote()) {
mDoc = docAcc->AsRemote()->AsDoc();
} else {
mDoc = docAcc->AsLocal();
}
}
return *this;
}
SessionAccessibility::IDMappingEntry::operator Accessible*() const {
if (mInternalID == 0) {
return static_cast<LocalAccessible*>(mDoc.get());
}
if (mInternalID == IS_REMOTE) {
return static_cast<DocAccessibleParent*>(mDoc.get());
}
if (mInternalID & IS_REMOTE) {
return static_cast<DocAccessibleParent*>(mDoc.get())
->GetAccessible(mInternalID & ~IS_REMOTE);
}
Accessible* accessible =
static_cast<LocalAccessible*>(mDoc.get())
->AsDoc()
->GetAccessibleByUniqueID(reinterpret_cast<void*>(mInternalID));
// If the accessible is retrievable from the DocAccessible, it can't be
// defunct.
MOZ_ASSERT(!accessible->AsLocal()->IsDefunct());
return accessible;
}
void SessionAccessibility::RegisterAccessible(Accessible* aAccessible) {
if (IPCAccessibilityActive()) {
// Don't register accessible in content process.
......@@ -766,7 +805,6 @@ void SessionAccessibility::UnregisterAccessible(Accessible* aAccessible) {
}
RefPtr<SessionAccessibility> sessionAcc = GetInstanceFor(aAccessible);
MOZ_ASSERT(sessionAcc, "Need SessionAccessibility to unregister Accessible!");
if (sessionAcc) {
Accessible* registeredAcc =
sessionAcc->mIDToAccessibleMap.Get(virtualViewID);
......
......@@ -110,10 +110,34 @@ class SessionAccessibility final
jni::NativeWeakPtr<widget::GeckoViewSupport> mWindow; // Parent only
java::SessionAccessibility::NativeProvider::GlobalRef mSessionAccessibility;
class IDMappingEntry {
public:
explicit IDMappingEntry(Accessible* aAccessible);
IDMappingEntry& operator=(Accessible* aAccessible);
operator Accessible*() const;
private:
// A strong reference to a DocAccessible or DocAccessibleParent. They don't
// share any useful base class except nsISupports, so we use that.
// When we retrieve the document from this reference we cast it to
// LocalAccessible in the DocAccessible case because DocAccessible has
// multiple inheritance paths for nsISupports.
RefPtr<nsISupports> mDoc;
// The ID of the accessible as used in the internal doc mapping.
// We rely on this ID being pointer derived and therefore divisible by two
// so we can use the first bit to mark if it is remote or not.
uint64_t mInternalID;
static const uintptr_t IS_REMOTE = 0x1;
};
/*
* This provides a mapping from 32 bit id to accessible objects.
*/
nsTHashMap<nsUint32HashKey, Accessible*> mIDToAccessibleMap;
nsBaseHashtable<nsUint32HashKey, IDMappingEntry, Accessible*>
mIDToAccessibleMap;
};
} // namespace a11y
......
......@@ -29,7 +29,6 @@
#endif
#if defined(ANDROID)
# include "mozilla/a11y/SessionAccessibility.h"
# define ACQUIRE_ANDROID_LOCK \
MonitorAutoLock mal(nsAccessibilityService::GetAndroidMonitor());
#else
......
......@@ -29,10 +29,6 @@ class xpcAccessibleGeneric;
class DocAccessiblePlatformExtParent;
#endif
#ifdef ANDROID
class SessionAccessibility;
#endif
/*
* These objects live in the main process and comunicate with and represent
* an accessible document in a content process.
......@@ -348,10 +344,6 @@ class DocAccessibleParent : public RemoteAccessible,
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) override;
#ifdef ANDROID
RefPtr<SessionAccessibility> mSessionAccessibility;
#endif
private:
~DocAccessibleParent();
......
......@@ -24,11 +24,6 @@ else:
LOCAL_INCLUDES += [
"/accessible/mac",
]
elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "android":
LOCAL_INCLUDES += [
"/accessible/android",
"/widget/android",
]
else:
LOCAL_INCLUDES += [
"/accessible/other",
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment