Verified Commit 30d19aa0 authored by Eitan Isaacson's avatar Eitan Isaacson Committed by ma1
Browse files

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

parent 9f2eaedb
Loading
Loading
Loading
Loading
+56 −18
Original line number Diff line number Diff line
@@ -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);
+25 −1
Original line number Diff line number Diff line
@@ -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
+0 −1
Original line number Diff line number Diff line
@@ -29,7 +29,6 @@
#endif

#if defined(ANDROID)
#  include "mozilla/a11y/SessionAccessibility.h"
#  define ACQUIRE_ANDROID_LOCK \
    MonitorAutoLock mal(nsAccessibilityService::GetAndroidMonitor());
#else
+0 −8
Original line number Diff line number Diff line
@@ -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();

+0 −5
Original line number Diff line number Diff line
@@ -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",