зеркало из 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/Preferences.h"
|
||||||
#include "mozilla/ReverseIterator.h"
|
#include "mozilla/ReverseIterator.h"
|
||||||
#include "mozilla/mscom/AsyncInvoker.h"
|
#include "mozilla/mscom/AsyncInvoker.h"
|
||||||
#include "mozilla/mscom/Interceptor.h"
|
|
||||||
|
|
||||||
#include "oleacc.h"
|
#include "oleacc.h"
|
||||||
|
|
||||||
|
@ -81,37 +80,7 @@ ITypeInfo* AccessibleWrap::gTypeInfo = nullptr;
|
||||||
NS_IMPL_ISUPPORTS_INHERITED0(AccessibleWrap, LocalAccessible)
|
NS_IMPL_ISUPPORTS_INHERITED0(AccessibleWrap, LocalAccessible)
|
||||||
|
|
||||||
void AccessibleWrap::Shutdown() {
|
void AccessibleWrap::Shutdown() {
|
||||||
if (mID != kNoID) {
|
MsaaShutdown();
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
LocalAccessible::Shutdown();
|
LocalAccessible::Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -167,20 +167,6 @@ class AccessibleWrap : public LocalAccessible, public MsaaAccessible {
|
||||||
static void UpdateSystemCaretFor(RemoteAccessible* aProxy,
|
static void UpdateSystemCaretFor(RemoteAccessible* aProxy,
|
||||||
const LayoutDeviceIntRect& aCaretRect);
|
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:
|
private:
|
||||||
static void UpdateSystemCaretFor(HWND aCaretWnd,
|
static void UpdateSystemCaretFor(HWND aCaretWnd,
|
||||||
const LayoutDeviceIntRect& aCaretRect);
|
const LayoutDeviceIntRect& aCaretRect);
|
||||||
|
@ -268,8 +254,6 @@ class AccessibleWrap : public LocalAccessible, public MsaaAccessible {
|
||||||
};
|
};
|
||||||
|
|
||||||
static StaticAutoPtr<nsTArray<HandlerControllerData>> sHandlerControllers;
|
static StaticAutoPtr<nsTArray<HandlerControllerData>> sHandlerControllers;
|
||||||
|
|
||||||
nsTArray<RefPtr<IUnknown>> mAssociatedCOMObjectsForDisconnection;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline AccessibleWrap* WrapperFor(const RemoteAccessible* aProxy) {
|
static inline AccessibleWrap* WrapperFor(const RemoteAccessible* aProxy) {
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "MsaaAccessible.h"
|
#include "MsaaAccessible.h"
|
||||||
#include "mozilla/dom/BrowserBridgeParent.h"
|
#include "mozilla/dom/BrowserBridgeParent.h"
|
||||||
#include "mozilla/dom/BrowserParent.h"
|
#include "mozilla/dom/BrowserParent.h"
|
||||||
|
#include "mozilla/mscom/Interceptor.h"
|
||||||
#include "sdnAccessible.h"
|
#include "sdnAccessible.h"
|
||||||
|
|
||||||
using namespace mozilla;
|
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) {
|
void MsaaAccessible::SetID(uint32_t aID) {
|
||||||
MOZ_ASSERT(XRE_IsParentProcess() &&
|
MOZ_ASSERT(XRE_IsParentProcess() &&
|
||||||
static_cast<AccessibleWrap*>(this)->IsProxy());
|
static_cast<AccessibleWrap*>(this)->IsProxy());
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "ia2AccessibleValue.h"
|
#include "ia2AccessibleValue.h"
|
||||||
#include "mozilla/a11y/MsaaIdGenerator.h"
|
#include "mozilla/a11y/MsaaIdGenerator.h"
|
||||||
#include "mozilla/dom/ipc/IdType.h"
|
#include "mozilla/dom/ipc/IdType.h"
|
||||||
|
#include "nsXULAppAPI.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace a11y {
|
namespace a11y {
|
||||||
|
@ -45,6 +46,22 @@ class MsaaAccessible : public ia2Accessible,
|
||||||
[[nodiscard]] already_AddRefed<IAccessible> GetIAccessibleFor(
|
[[nodiscard]] already_AddRefed<IAccessible> GetIAccessibleFor(
|
||||||
const VARIANT& aVarChild, bool* aIsDefunct);
|
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:
|
protected:
|
||||||
virtual ~MsaaAccessible();
|
virtual ~MsaaAccessible();
|
||||||
|
|
||||||
|
@ -60,6 +77,8 @@ class MsaaAccessible : public ia2Accessible,
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] already_AddRefed<IAccessible> GetRemoteIAccessibleFor(
|
[[nodiscard]] already_AddRefed<IAccessible> GetRemoteIAccessibleFor(
|
||||||
const VARIANT& aVarChild);
|
const VARIANT& aVarChild);
|
||||||
|
|
||||||
|
nsTArray<RefPtr<IUnknown>> mAssociatedCOMObjectsForDisconnection;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace a11y
|
} // namespace a11y
|
||||||
|
|
Загрузка…
Ссылка в новой задаче