Bug 1543287: Add embedded out-of-process iframe DocAccessibleParent as a child of its embedder DocAccessibleParent. r=eeejay,nika

For iframes in a different process to their embedder, when the embedded iframe content process tells the parent process about the iframe document, it does not have the actor for the parent document accessible, nor does it know the accessible id of the embedding iframe.
However, the embedder will have previously sendt the actor and id for the embedder accessible to the parent via PBrowserBridge, so we can use that to identify the parent accessible.

Differential Revision: https://phabricator.services.mozilla.com/D31395

--HG--
extra : moz-landing-system : lando
This commit is contained in:
James Teh 2019-05-29 04:36:18 +00:00
Родитель 25b9e2f1f5
Коммит bfb6c4c160
3 изменённых файлов: 51 добавлений и 0 удалений

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

@ -6,6 +6,7 @@
#include "DocAccessibleParent.h"
#include "mozilla/a11y/Platform.h"
#include "mozilla/dom/BrowserBridgeParent.h"
#include "mozilla/dom/BrowserParent.h"
#include "xpcAccessibleDocument.h"
#include "xpcAccEvents.h"
@ -836,5 +837,23 @@ mozilla::ipc::IPCResult DocAccessibleParent::RecvBatch(
}
#endif // !defined(XP_WIN)
Tuple<DocAccessibleParent*, uint64_t> DocAccessibleParent::GetRemoteEmbedder() {
dom::BrowserParent* embeddedBrowser = dom::BrowserParent::GetFrom(Manager());
dom::BrowserBridgeParent* bridge = embeddedBrowser->GetBrowserBridgeParent();
if (!bridge) {
return Tuple<DocAccessibleParent*, uint64_t>(nullptr, 0);
}
DocAccessibleParent* doc;
uint64_t id;
Tie(doc, id) = bridge->GetEmbedderAccessible();
if (doc && doc->IsShutdown()) {
// Sometimes, the embedder document is destroyed before its
// BrowserBridgeParent. Don't return a destroyed document.
doc = nullptr;
id = 0;
}
return Tuple<DocAccessibleParent*, uint64_t>(doc, id);
}
} // namespace a11y
} // namespace mozilla

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

@ -10,6 +10,7 @@
#include "nsAccessibilityService.h"
#include "mozilla/a11y/PDocAccessibleParent.h"
#include "mozilla/a11y/ProxyAccessible.h"
#include "mozilla/Tuple.h"
#include "nsClassHashtable.h"
#include "nsHashKeys.h"
#include "nsISupportsImpl.h"
@ -214,6 +215,13 @@ class DocAccessibleParent : public ProxyAccessible,
const uint64_t& aBatchType, nsTArray<BatchData>&& aData) override;
#endif
/**
* If this is an iframe document rendered in a different process to its
* embedder, return the DocAccessibleParent and id for the embedder
* accessible. Otherwise, return null and 0.
*/
Tuple<DocAccessibleParent*, uint64_t> GetRemoteEmbedder();
private:
~DocAccessibleParent() {
LiveDocs().Remove(mActorID);

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

@ -1115,6 +1115,30 @@ mozilla::ipc::IPCResult BrowserParent::RecvPDocAccessibleConstructor(
}
# endif
return IPC_OK();
}
a11y::DocAccessibleParent* embedderDoc;
uint64_t embedderID;
Tie(embedderDoc, embedderID) = doc->GetRemoteEmbedder();
if (embedderDoc) {
// Iframe document rendered in a different process to its embedder.
// In this case, we don't get aParentDoc and aParentID.
MOZ_ASSERT(!aParentDoc && !aParentID);
MOZ_ASSERT(embedderID);
mozilla::ipc::IPCResult added = embedderDoc->AddChildDoc(doc, embedderID);
if (!added) {
# ifdef DEBUG
return added;
# else
return IPC_OK();
# endif
}
# ifdef XP_WIN
if (a11y::nsWinUtils::IsWindowEmulationStarted()) {
doc->SetEmulatedWindowHandle(embedderDoc->GetEmulatedWindowHandle());
}
# endif
return IPC_OK();
} else {
// null aParentDoc means this document is at the top level in the child