зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1694865 part 5: Move shutdown code into MsaaAccessible. r=morgan
Differential Revision: https://phabricator.services.mozilla.com/D112936
This commit is contained in:
Родитель
6e9e04fb17
Коммит
7aa8ea0a24
|
@ -44,7 +44,6 @@
|
|||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/ReverseIterator.h"
|
||||
#include "mozilla/mscom/AsyncInvoker.h"
|
||||
#include "mozilla/mscom/Interceptor.h"
|
||||
|
||||
#include "oleacc.h"
|
||||
|
||||
|
@ -81,37 +80,7 @@ ITypeInfo* AccessibleWrap::gTypeInfo = nullptr;
|
|||
NS_IMPL_ISUPPORTS_INHERITED0(AccessibleWrap, LocalAccessible)
|
||||
|
||||
void AccessibleWrap::Shutdown() {
|
||||
if (mID != kNoID) {
|
||||
auto doc = static_cast<DocAccessibleWrap*>(mDoc.get());
|
||||
// Accessibles can be shut down twice in some cases. When this happens,
|
||||
// doc will be null.
|
||||
if (doc) {
|
||||
doc->RemoveID(mID);
|
||||
}
|
||||
}
|
||||
|
||||
if (XRE_IsContentProcess()) {
|
||||
// Bug 1434822: To improve performance for cross-process COM, we disable COM
|
||||
// garbage collection. However, this means we never receive Release calls
|
||||
// from clients, so defunct accessibles can never be deleted. Since we
|
||||
// know when an accessible is shutting down, we can work around this by
|
||||
// forcing COM to disconnect this object from all of its remote clients,
|
||||
// which will cause associated references to be released.
|
||||
IUnknown* unk = static_cast<IAccessible*>(this);
|
||||
mscom::Interceptor::DisconnectRemotesForTarget(unk);
|
||||
// If an accessible was retrieved via IAccessibleHypertext::hyperlink*,
|
||||
// it will have a different Interceptor that won't be matched by the above
|
||||
// call, even though it's the same object. Therefore, call it again with
|
||||
// the IAccessibleHyperlink pointer. We can remove this horrible hack once
|
||||
// bug 1440267 is fixed.
|
||||
unk = static_cast<IAccessibleHyperlink*>(this);
|
||||
mscom::Interceptor::DisconnectRemotesForTarget(unk);
|
||||
for (auto& assocUnk : mAssociatedCOMObjectsForDisconnection) {
|
||||
mscom::Interceptor::DisconnectRemotesForTarget(assocUnk);
|
||||
}
|
||||
mAssociatedCOMObjectsForDisconnection.Clear();
|
||||
}
|
||||
|
||||
MsaaShutdown();
|
||||
LocalAccessible::Shutdown();
|
||||
}
|
||||
|
||||
|
|
|
@ -167,20 +167,6 @@ class AccessibleWrap : public LocalAccessible, public MsaaAccessible {
|
|||
static void UpdateSystemCaretFor(RemoteAccessible* aProxy,
|
||||
const LayoutDeviceIntRect& aCaretRect);
|
||||
|
||||
/**
|
||||
* Associate a COM object with this LocalAccessible so it will be disconnected
|
||||
* from remote clients when this LocalAccessible shuts down.
|
||||
* This should only be called with separate COM objects with a different
|
||||
* IUnknown to this AccessibleWrap; e.g. IAccessibleRelation.
|
||||
*/
|
||||
void AssociateCOMObjectForDisconnection(IUnknown* aObject) {
|
||||
// We only need to track these for content processes because COM garbage
|
||||
// collection is disabled there.
|
||||
if (XRE_IsContentProcess()) {
|
||||
mAssociatedCOMObjectsForDisconnection.AppendElement(aObject);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static void UpdateSystemCaretFor(HWND aCaretWnd,
|
||||
const LayoutDeviceIntRect& aCaretRect);
|
||||
|
@ -268,8 +254,6 @@ class AccessibleWrap : public LocalAccessible, public MsaaAccessible {
|
|||
};
|
||||
|
||||
static StaticAutoPtr<nsTArray<HandlerControllerData>> sHandlerControllers;
|
||||
|
||||
nsTArray<RefPtr<IUnknown>> mAssociatedCOMObjectsForDisconnection;
|
||||
};
|
||||
|
||||
static inline AccessibleWrap* WrapperFor(const RemoteAccessible* aProxy) {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "MsaaAccessible.h"
|
||||
#include "mozilla/dom/BrowserBridgeParent.h"
|
||||
#include "mozilla/dom/BrowserParent.h"
|
||||
#include "mozilla/mscom/Interceptor.h"
|
||||
#include "sdnAccessible.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
@ -22,6 +23,39 @@ MsaaAccessible::~MsaaAccessible() {
|
|||
}
|
||||
}
|
||||
|
||||
void MsaaAccessible::MsaaShutdown() {
|
||||
if (mID != kNoID) {
|
||||
auto doc = static_cast<DocAccessibleWrap*>(LocalAcc()->Document());
|
||||
// Accessibles can be shut down twice in some cases. When this happens,
|
||||
// doc will be null.
|
||||
if (doc) {
|
||||
doc->RemoveID(mID);
|
||||
}
|
||||
}
|
||||
|
||||
if (XRE_IsContentProcess()) {
|
||||
// Bug 1434822: To improve performance for cross-process COM, we disable COM
|
||||
// garbage collection. However, this means we never receive Release calls
|
||||
// from clients, so defunct accessibles can never be deleted. Since we
|
||||
// know when an accessible is shutting down, we can work around this by
|
||||
// forcing COM to disconnect this object from all of its remote clients,
|
||||
// which will cause associated references to be released.
|
||||
IUnknown* unk = static_cast<IAccessible*>(this);
|
||||
mscom::Interceptor::DisconnectRemotesForTarget(unk);
|
||||
// If an accessible was retrieved via IAccessibleHypertext::hyperlink*,
|
||||
// it will have a different Interceptor that won't be matched by the above
|
||||
// call, even though it's the same object. Therefore, call it again with
|
||||
// the IAccessibleHyperlink pointer. We can remove this horrible hack once
|
||||
// bug 1440267 is fixed.
|
||||
unk = static_cast<IAccessibleHyperlink*>(this);
|
||||
mscom::Interceptor::DisconnectRemotesForTarget(unk);
|
||||
for (auto& assocUnk : mAssociatedCOMObjectsForDisconnection) {
|
||||
mscom::Interceptor::DisconnectRemotesForTarget(assocUnk);
|
||||
}
|
||||
mAssociatedCOMObjectsForDisconnection.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
void MsaaAccessible::SetID(uint32_t aID) {
|
||||
MOZ_ASSERT(XRE_IsParentProcess() &&
|
||||
static_cast<AccessibleWrap*>(this)->IsProxy());
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "ia2AccessibleValue.h"
|
||||
#include "mozilla/a11y/MsaaIdGenerator.h"
|
||||
#include "mozilla/dom/ipc/IdType.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
@ -45,6 +46,22 @@ class MsaaAccessible : public ia2Accessible,
|
|||
[[nodiscard]] already_AddRefed<IAccessible> GetIAccessibleFor(
|
||||
const VARIANT& aVarChild, bool* aIsDefunct);
|
||||
|
||||
/**
|
||||
* Associate a COM object with this MsaaAccessible so it will be disconnected
|
||||
* from remote clients when this MsaaAccessible shuts down.
|
||||
* This should only be called with separate COM objects with a different
|
||||
* IUnknown to this MsaaAccessible; e.g. IAccessibleRelation.
|
||||
*/
|
||||
void AssociateCOMObjectForDisconnection(IUnknown* aObject) {
|
||||
// We only need to track these for content processes because COM garbage
|
||||
// collection is disabled there.
|
||||
if (XRE_IsContentProcess()) {
|
||||
mAssociatedCOMObjectsForDisconnection.AppendElement(aObject);
|
||||
}
|
||||
}
|
||||
|
||||
void MsaaShutdown();
|
||||
|
||||
protected:
|
||||
virtual ~MsaaAccessible();
|
||||
|
||||
|
@ -60,6 +77,8 @@ class MsaaAccessible : public ia2Accessible,
|
|||
*/
|
||||
[[nodiscard]] already_AddRefed<IAccessible> GetRemoteIAccessibleFor(
|
||||
const VARIANT& aVarChild);
|
||||
|
||||
nsTArray<RefPtr<IUnknown>> mAssociatedCOMObjectsForDisconnection;
|
||||
};
|
||||
|
||||
} // namespace a11y
|
||||
|
|
Загрузка…
Ссылка в новой задаче