Bug 1821956 part 2: Remove content process MSAA id generation. r=nlapre,ipc-reviewers,taskgraph-reviewers,mccr8,jmaher

Because a11y clients only talk to the parent process now, content processes don't need to generate MSAA ids.
They're all generated in the parent process.

Differential Revision: https://phabricator.services.mozilla.com/D177895
This commit is contained in:
James Teh 2023-05-21 22:23:47 +00:00
Родитель b7670454fd
Коммит c9479f6488
11 изменённых файлов: 47 добавлений и 355 удалений

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

@ -45,7 +45,6 @@
#ifdef XP_WIN
# include "mozilla/a11y/Compatibility.h"
# include "mozilla/dom/ContentChild.h"
# include "mozilla/StaticPtr.h"
#endif
@ -1486,21 +1485,7 @@ bool nsAccessibilityService::Init() {
if (XRE_IsParentProcess()) {
gApplicationAccessible = new ApplicationAccessibleWrap();
} else {
#if defined(XP_WIN)
dom::ContentChild* contentChild = dom::ContentChild::GetSingleton();
MOZ_ASSERT(contentChild);
// If we were instantiated by the chrome process, GetMsaaID() will return
// a non-zero value and we may safely continue with initialization.
if (!a11y::IsCacheActive() && !contentChild->GetMsaaID()) {
// Since we were not instantiated by chrome, we need to synchronously
// obtain a MSAA content process id.
contentChild->SendGetA11yContentId();
}
gApplicationAccessible = new ApplicationAccessibleWrap();
#else
gApplicationAccessible = new ApplicationAccessible();
#endif // defined(XP_WIN)
}
NS_ADDREF(gApplicationAccessible); // will release in Shutdown()

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

@ -127,21 +127,6 @@ int32_t MsaaAccessible::GetChildIDFor(Accessible* aAccessible) {
return *id;
}
/* static */
uint32_t MsaaAccessible::GetContentProcessIdFor(
dom::ContentParentId aIPCContentId) {
if (a11y::IsCacheActive()) {
return 0;
}
return sIDGen.GetContentProcessIDFor(aIPCContentId);
}
/* static */
void MsaaAccessible::ReleaseContentProcessIdFor(
dom::ContentParentId aIPCContentId) {
sIDGen.ReleaseContentProcessIDFor(aIPCContentId);
}
/* static */
void MsaaAccessible::AssignChildIDTo(NotNull<sdnAccessible*> aSdnAcc) {
aSdnAcc->SetUniqueID(sIDGen.GetID());

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

@ -37,8 +37,6 @@ class MsaaAccessible : public ia2Accessible,
static const uint32_t kNoID = 0;
static int32_t GetChildIDFor(Accessible* aAccessible);
static uint32_t GetContentProcessIdFor(dom::ContentParentId aIPCContentId);
static void ReleaseContentProcessIdFor(dom::ContentParentId aIPCContentId);
static void AssignChildIDTo(NotNull<sdnAccessible*> aSdnAcc);
static void ReleaseChildID(NotNull<sdnAccessible*> aSdnAcc);
static HWND GetHWNDFor(Accessible* aAccessible);

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

@ -6,105 +6,36 @@
#include "MsaaIdGenerator.h"
#include "mozilla/a11y/AccessibleWrap.h"
#include "mozilla/a11y/MsaaAccessible.h"
#include "mozilla/Assertions.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/Unused.h"
#include "nsAccessibilityService.h"
#include "nsTHashMap.h"
#include "sdnAccessible.h"
static const uint32_t kNumFullIDBits = 31UL;
// These constants may be adjusted to modify the proportion of the Child ID
// allocated to the content ID vs proportion allocated to the unique ID. They
// must always sum to 31, ie. the width of a 32-bit integer less the sign bit.
// NB: kNumContentProcessIDBits must be large enough to successfully hold the
// maximum permitted number of e10s content processes. If the e10s maximum
// number of content processes changes, then kNumContentProcessIDBits must also
// be updated if necessary to accommodate that new value!
static const uint32_t kNumContentProcessIDBits = 8UL;
static const uint32_t kNumUniqueIDBits = (31UL - kNumContentProcessIDBits);
static_assert(
kNumContentProcessIDBits + kNumUniqueIDBits == 31,
"Allocation of Content ID bits and Unique ID bits must sum to 31");
namespace mozilla {
namespace a11y {
namespace detail {
typedef nsTHashMap<nsUint64HashKey, uint32_t> ContentParentIdMap;
#pragma pack(push, 1)
union MsaaID {
int32_t mInt32;
uint32_t mUInt32;
struct {
uint32_t mUniqueID : kNumUniqueIDBits;
uint32_t mContentProcessID : kNumContentProcessIDBits;
uint32_t mSignBit : 1;
} mCracked;
};
#pragma pack(pop)
static uint32_t BuildMsaaID(const uint32_t aID,
const uint32_t aContentProcessID) {
MsaaID id;
id.mCracked.mSignBit = 0;
id.mCracked.mUniqueID = aID;
id.mCracked.mContentProcessID = aContentProcessID;
return ~id.mUInt32;
}
class MsaaIDCracker {
public:
explicit MsaaIDCracker(const uint32_t aMsaaID) { mID.mUInt32 = ~aMsaaID; }
uint32_t GetContentProcessId() { return mID.mCracked.mContentProcessID; }
uint32_t GetUniqueId() { return mID.mCracked.mUniqueID; }
private:
MsaaID mID;
};
} // namespace detail
uint32_t MsaaIdGenerator::GetID() {
if (!mIDSet) {
// XXX This is only a pointer because we need to decide how many bits we
// need for the IDSet at runtime. Once the cache pref is gone, this no
// longer needs to be a pointer.
mIDSet = MakeUnique<IDSet>(a11y::IsCacheActive() ? kNumFullIDBits
: kNumUniqueIDBits);
if (a11y::IsCacheActive()) {
// this is a static instance, so capturing this here is safe.
RunOnShutdown([this] {
if (mReleaseIDTimer) {
mReleaseIDTimer->Cancel();
ReleasePendingIDs();
}
});
}
if (!mGetIDCalled) {
mGetIDCalled = true;
// this is a static instance, so capturing this here is safe.
RunOnShutdown([this] {
if (mReleaseIDTimer) {
mReleaseIDTimer->Cancel();
ReleasePendingIDs();
}
});
}
uint32_t id = mIDSet->GetID();
if (a11y::IsCacheActive()) {
MOZ_ASSERT(id <= ((1UL << kNumFullIDBits) - 1UL));
return ~id;
}
MOZ_ASSERT(id <= ((1UL << kNumUniqueIDBits) - 1UL));
return detail::BuildMsaaID(id, ResolveContentProcessID());
uint32_t id = mIDSet.GetID();
MOZ_ASSERT(id <= ((1UL << kNumFullIDBits) - 1UL));
return ~id;
}
void MsaaIdGenerator::ReleasePendingIDs() {
for (auto id : mIDsToRelease) {
mIDSet->ReleaseID(~id);
mIDSet.ReleaseID(~id);
}
mIDsToRelease.Clear();
mReleaseIDTimer = nullptr;
@ -112,53 +43,35 @@ void MsaaIdGenerator::ReleasePendingIDs() {
bool MsaaIdGenerator::ReleaseID(uint32_t aID) {
MOZ_ASSERT(aID != MsaaAccessible::kNoID);
if (!mIDSet) {
// If we're in the parent process and we're trying to release an id created
// in a content process, mIDSet might not exist yet. Just ignore this.
MOZ_ASSERT(XRE_IsParentProcess());
return false;
}
if (a11y::IsCacheActive()) {
// Releasing an id means it can be reused. Reusing ids too quickly can
// cause problems for clients which process events asynchronously.
// Therefore, we release ids after a short delay. This doesn't seem to be
// necessary when the cache is disabled, perhaps because the COM runtime
// holds references to our objects for longer.
if (nsAccessibilityService::IsShutdown()) {
// If accessibility is shut down, no more Accessibles will be created.
// Also, if the service is shut down, it's possible XPCOM is also shutting
// down, in which case timers won't work. Thus, we release the id
// immediately.
mIDSet->ReleaseID(~aID);
return true;
}
const uint32_t kReleaseDelay = 1000;
mIDsToRelease.AppendElement(aID);
if (mReleaseIDTimer) {
mReleaseIDTimer->SetDelay(kReleaseDelay);
} else {
NS_NewTimerWithCallback(
getter_AddRefs(mReleaseIDTimer),
// mReleaseIDTimer is cancelled on shutdown and this is a static
// instance, so capturing this here is safe.
[this](nsITimer* aTimer) { ReleasePendingIDs(); }, kReleaseDelay,
nsITimer::TYPE_ONE_SHOT, "a11y::MsaaIdGenerator::ReleaseIDDelayed");
}
// Releasing an id means it can be reused. Reusing ids too quickly can
// cause problems for clients which process events asynchronously.
// Therefore, we release ids after a short delay. This doesn't seem to be
// necessary when the cache is disabled, perhaps because the COM runtime
// holds references to our objects for longer.
if (nsAccessibilityService::IsShutdown()) {
// If accessibility is shut down, no more Accessibles will be created.
// Also, if the service is shut down, it's possible XPCOM is also shutting
// down, in which case timers won't work. Thus, we release the id
// immediately.
mIDSet.ReleaseID(~aID);
return true;
}
detail::MsaaIDCracker cracked(aID);
if (cracked.GetContentProcessId() != ResolveContentProcessID()) {
return false;
const uint32_t kReleaseDelay = 1000;
mIDsToRelease.AppendElement(aID);
if (mReleaseIDTimer) {
mReleaseIDTimer->SetDelay(kReleaseDelay);
} else {
NS_NewTimerWithCallback(
getter_AddRefs(mReleaseIDTimer),
// mReleaseIDTimer is cancelled on shutdown and this is a static
// instance, so capturing this here is safe.
[this](nsITimer* aTimer) { ReleasePendingIDs(); }, kReleaseDelay,
nsITimer::TYPE_ONE_SHOT, "a11y::MsaaIdGenerator::ReleaseIDDelayed");
}
mIDSet->ReleaseID(cracked.GetUniqueId());
return true;
}
void MsaaIdGenerator::ReleaseID(NotNull<MsaaAccessible*> aMsaaAcc) {
// ReleaseID may fail if chrome holds a proxy whose ID was originally
// generated by a content process. Since ReleaseID only has meaning in the
// process that originally generated that ID, we ignore ReleaseID calls for
// any ID that did not come from the current process.
ReleaseID(aMsaaAcc->GetExistingID());
}
@ -170,124 +83,5 @@ void MsaaIdGenerator::ReleaseID(NotNull<sdnAccessible*> aSdnAcc) {
}
}
bool MsaaIdGenerator::IsChromeID(uint32_t aID) {
if (a11y::IsCacheActive()) {
return true;
}
detail::MsaaIDCracker cracked(aID);
return cracked.GetContentProcessId() == 0;
}
bool MsaaIdGenerator::IsIDForThisContentProcess(uint32_t aID) {
MOZ_ASSERT(XRE_IsContentProcess());
detail::MsaaIDCracker cracked(aID);
return cracked.GetContentProcessId() == ResolveContentProcessID();
}
bool MsaaIdGenerator::IsIDForContentProcess(
uint32_t aID, dom::ContentParentId aIPCContentProcessId) {
MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(!a11y::IsCacheActive());
detail::MsaaIDCracker cracked(aID);
return cracked.GetContentProcessId() ==
GetContentProcessIDFor(aIPCContentProcessId);
}
bool MsaaIdGenerator::IsSameContentProcessFor(uint32_t aFirstID,
uint32_t aSecondID) {
MOZ_ASSERT(!a11y::IsCacheActive());
detail::MsaaIDCracker firstCracked(aFirstID);
detail::MsaaIDCracker secondCracked(aSecondID);
return firstCracked.GetContentProcessId() ==
secondCracked.GetContentProcessId();
}
uint32_t MsaaIdGenerator::ResolveContentProcessID() {
if (XRE_IsParentProcess()) {
return 0;
}
dom::ContentChild* contentChild = dom::ContentChild::GetSingleton();
uint32_t result = contentChild->GetMsaaID();
MOZ_ASSERT(result);
return result;
}
/**
* Each dom::ContentParent has a 64-bit ID. This ID is monotonically increasing
* with each new content process, so those IDs are effectively single-use. OTOH,
* MSAA requires 32-bit IDs. Since we only allocate kNumContentProcessIDBits for
* the content process ID component, the MSAA content process ID value must be
* reusable. sContentParentIdMap holds the current associations between
* dom::ContentParent IDs and the MSAA content parent IDs that have been
* allocated to them.
*/
static StaticAutoPtr<detail::ContentParentIdMap> sContentParentIdMap;
static const uint32_t kBitsPerByte = 8UL;
// Set sContentProcessIdBitmap[0] to 1 to reserve the Chrome process's id
static uint64_t sContentProcessIdBitmap[(1UL << kNumContentProcessIDBits) /
(sizeof(uint64_t) * kBitsPerByte)] = {
1ULL};
static const uint32_t kBitsPerElement =
sizeof(sContentProcessIdBitmap[0]) * kBitsPerByte;
uint32_t MsaaIdGenerator::GetContentProcessIDFor(
dom::ContentParentId aIPCContentProcessID) {
MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
if (!sContentParentIdMap) {
sContentParentIdMap = new detail::ContentParentIdMap();
ClearOnShutdown(&sContentParentIdMap);
}
return sContentParentIdMap->LookupOrInsertWith(aIPCContentProcessID, [] {
uint32_t value = 0;
uint32_t index = 0;
for (; index < ArrayLength(sContentProcessIdBitmap); ++index) {
if (sContentProcessIdBitmap[index] == UINT64_MAX) {
continue;
}
uint32_t bitIndex =
CountTrailingZeroes64(~sContentProcessIdBitmap[index]);
MOZ_ASSERT(!(sContentProcessIdBitmap[index] & (1ULL << bitIndex)));
MOZ_ASSERT(bitIndex != 0 || index != 0);
sContentProcessIdBitmap[index] |= (1ULL << bitIndex);
value = index * kBitsPerElement + bitIndex;
break;
}
// If we run out of content process IDs, we're in trouble
MOZ_RELEASE_ASSERT(index < ArrayLength(sContentProcessIdBitmap));
return value;
});
}
void MsaaIdGenerator::ReleaseContentProcessIDFor(
dom::ContentParentId aIPCContentProcessID) {
MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
if (!sContentParentIdMap) {
// Since Content IDs are generated lazily, ContentParent might attempt
// to release an ID that was never allocated to begin with.
return;
}
Maybe<uint32_t> mapping = sContentParentIdMap->Extract(aIPCContentProcessID);
if (!mapping) {
// Since Content IDs are generated lazily, ContentParent might attempt
// to release an ID that was never allocated to begin with.
return;
}
uint32_t index = mapping.ref() / kBitsPerElement;
MOZ_ASSERT(index < ArrayLength(sContentProcessIdBitmap));
uint64_t mask = 1ULL << (mapping.ref() % kBitsPerElement);
MOZ_ASSERT(sContentProcessIdBitmap[index] & mask);
sContentProcessIdBitmap[index] &= ~mask;
}
} // namespace a11y
} // namespace mozilla

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

@ -11,7 +11,6 @@
#include "mozilla/dom/ipc/IdType.h"
#include "mozilla/NotNull.h"
#include "mozilla/UniquePtr.h"
#include "nsITimer.h"
namespace mozilla {
@ -23,43 +22,24 @@ class sdnAccessible;
/**
* This class is responsible for generating child IDs used by our MSAA
* implementation.
*
* If the accessibility cache is disabled, we must differentiate IDs based on
* the originating process of the accessible, so a portion of the ID's bits are
* allocated to storing that information. The remaining bits represent the
* unique ID of the accessible, within that content process.
*
* The constants kNumContentProcessIDBits and kNumUniqueIDBits in the
* implementation are responsible for determining the proportion of bits that
* are allocated for each purpose.
*
* If the accessibility cache is enabled, we don't need to differentiate IDs
* based on the originating process, so all bits of the ID are used for the
* unique ID.
*/
class MsaaIdGenerator {
public:
uint32_t GetID();
void ReleaseID(NotNull<MsaaAccessible*> aMsaaAcc);
void ReleaseID(NotNull<sdnAccessible*> aSdnAcc);
bool IsChromeID(uint32_t aID);
bool IsIDForThisContentProcess(uint32_t aID);
bool IsIDForContentProcess(uint32_t aID,
dom::ContentParentId aIPCContentProcessId);
bool IsSameContentProcessFor(uint32_t aFirstID, uint32_t aSecondID);
uint32_t GetContentProcessIDFor(dom::ContentParentId aIPCContentProcessID);
void ReleaseContentProcessIDFor(dom::ContentParentId aIPCContentProcessID);
private:
bool ReleaseID(uint32_t aID);
uint32_t ResolveContentProcessID();
void ReleasePendingIDs();
private:
UniquePtr<IDSet> mIDSet;
static constexpr uint32_t kNumFullIDBits = 31UL;
IDSet mIDSet{kNumFullIDBits};
nsTArray<uint32_t> mIDsToRelease;
nsCOMPtr<nsITimer> mReleaseIDTimer;
// Whether GetID has been called yet this session.
bool mGetIDCalled = false;
};
} // namespace a11y

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

@ -604,8 +604,7 @@ ContentChild::ContentChild()
: mID(uint64_t(-1))
#if defined(XP_WIN) && defined(ACCESSIBILITY)
,
mMainChromeTid(0),
mMsaaID(0)
mMainChromeTid(0)
#endif
,
mIsForBrowser(false),
@ -2553,14 +2552,11 @@ mozilla::ipc::IPCResult ContentChild::RecvFlushMemory(const nsString& reason) {
}
mozilla::ipc::IPCResult ContentChild::RecvActivateA11y(
const uint32_t& aMainChromeTid, const uint32_t& aMsaaID) {
const uint32_t& aMainChromeTid) {
#ifdef ACCESSIBILITY
# ifdef XP_WIN
MOZ_ASSERT(aMainChromeTid != 0);
mMainChromeTid = aMainChromeTid;
MOZ_ASSERT(a11y::IsCacheActive() ? !aMsaaID : aMsaaID);
mMsaaID = aMsaaID;
# endif // XP_WIN
// Start accessibility in content process if it's running in chrome
@ -3367,12 +3363,6 @@ mozilla::ipc::IPCResult ContentChild::RecvBlobURLUnregistration(
return IPC_OK();
}
#if defined(XP_WIN) && defined(ACCESSIBILITY)
bool ContentChild::SendGetA11yContentId() {
return PContentChild::SendGetA11yContentId(&mMsaaID);
}
#endif // defined(XP_WIN) && defined(ACCESSIBILITY)
void ContentChild::CreateGetFilesRequest(const nsAString& aDirectoryPath,
bool aRecursiveFlag, nsID& aUUID,
GetFilesHelperChild* aChild) {

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

@ -346,8 +346,7 @@ class ContentChild final : public PContentChild,
mozilla::ipc::IPCResult RecvFlushMemory(const nsString& reason);
mozilla::ipc::IPCResult RecvActivateA11y(const uint32_t& aMainChromeTid,
const uint32_t& aMsaaID);
mozilla::ipc::IPCResult RecvActivateA11y(const uint32_t& aMainChromeTid);
mozilla::ipc::IPCResult RecvShutdownA11y();
mozilla::ipc::IPCResult RecvApplicationForeground();
@ -459,8 +458,6 @@ class ContentChild final : public PContentChild,
#if defined(XP_WIN) && defined(ACCESSIBILITY)
uint32_t GetChromeMainThreadId() const { return mMainChromeTid; }
uint32_t GetMsaaID() const { return mMsaaID; }
#endif
bool IsForBrowser() const { return mIsForBrowser; }
@ -547,10 +544,6 @@ class ContentChild final : public PContentChild,
mozilla::ipc::IPCResult RecvAddDynamicScalars(
nsTArray<DynamicScalarDefinition>&& aDefs);
#if defined(XP_WIN) && defined(ACCESSIBILITY)
bool SendGetA11yContentId();
#endif // defined(XP_WIN) && defined(ACCESSIBILITY)
// Get a reference to the font list passed from the chrome process,
// for use during gfx initialization.
SystemFontList& SystemFontList() { return mFontList; }
@ -853,12 +846,6 @@ class ContentChild final : public PContentChild,
* The thread ID of the main thread in the chrome process.
*/
uint32_t mMainChromeTid;
/**
* This is an a11y-specific unique id for the content process that is
* generated by the chrome process.
*/
uint32_t mMsaaID;
#endif // defined(XP_WIN) && defined(ACCESSIBILITY)
AppInfo mAppInfo;

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

@ -1695,12 +1695,10 @@ void ContentParent::Init() {
# if defined(XP_WIN)
// Don't init content a11y if we detect an incompat version of JAWS in use.
if (!mozilla::a11y::Compatibility::IsOldJAWS()) {
Unused << SendActivateA11y(
::GetCurrentThreadId(),
a11y::MsaaAccessible::GetContentProcessIdFor(ChildID()));
Unused << SendActivateA11y(::GetCurrentThreadId());
}
# else
Unused << SendActivateA11y(0, 0);
Unused << SendActivateA11y(0);
# endif
}
#endif // #ifdef ACCESSIBILITY
@ -2238,10 +2236,6 @@ void ContentParent::ActorDestroy(ActorDestroyReason why) {
mBlobURLs.Clear();
#if defined(XP_WIN) && defined(ACCESSIBILITY)
a11y::MsaaAccessible::ReleaseContentProcessIdFor(ChildID());
#endif
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
AssertNotInPool();
#endif
@ -4079,12 +4073,10 @@ ContentParent::Observe(nsISupports* aSubject, const char* aTopic,
// Don't init content a11y if we detect an incompat version of JAWS in
// use.
if (!mozilla::a11y::Compatibility::IsOldJAWS()) {
Unused << SendActivateA11y(
::GetCurrentThreadId(),
a11y::MsaaAccessible::GetContentProcessIdFor(ChildID()));
Unused << SendActivateA11y(::GetCurrentThreadId());
}
# else
Unused << SendActivateA11y(0, 0);
Unused << SendActivateA11y(0);
# endif
} else {
// If possible, shut down accessibility in content process when
@ -6272,17 +6264,6 @@ ContentParent::RecvUnstoreAndBroadcastBlobURLUnregistration(
return IPC_OK();
}
mozilla::ipc::IPCResult ContentParent::RecvGetA11yContentId(
uint32_t* aContentId) {
#if defined(XP_WIN) && defined(ACCESSIBILITY)
*aContentId = a11y::MsaaAccessible::GetContentProcessIdFor(ChildID());
MOZ_ASSERT(*aContentId);
return IPC_OK();
#else
return IPC_FAIL_NO_REASON(this);
#endif
}
mozilla::ipc::IPCResult ContentParent::RecvA11yHandlerControl(
const uint32_t& aPid, const IHandlerControlHolder& aHandlerControl) {
#if defined(XP_WIN) && defined(ACCESSIBILITY)

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

@ -521,8 +521,6 @@ class ContentParent final : public PContentParent,
mozilla::ipc::IPCResult RecvUnstoreAndBroadcastBlobURLUnregistration(
const nsACString& aURI, nsIPrincipal* aPrincipal);
mozilla::ipc::IPCResult RecvGetA11yContentId(uint32_t* aContentId);
mozilla::ipc::IPCResult RecvA11yHandlerControl(
const uint32_t& aPid, const IHandlerControlHolder& aHandlerControl);

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

@ -754,11 +754,8 @@ child:
* Start accessibility engine in content process.
* @param aTid is the thread ID of the chrome process main thread. Only used
* on Windows; pass 0 on other platforms.
* @param aMsaaID is an a11y-specific unique id for the content process
* that is generated by the chrome process. Only used on
* Windows; pass 0 on other platforms.
*/
async ActivateA11y(uint32_t aMainChromeTid, uint32_t aMsaaID);
async ActivateA11y(uint32_t aMainChromeTid);
/**
* Shutdown accessibility engine in content process (if not in use).
@ -1641,7 +1638,6 @@ parent:
async RecordChildEvents(ChildEventData[] events);
async RecordDiscardedData(DiscardedData data);
sync GetA11yContentId() returns (uint32_t aContentId);
async A11yHandlerControl(uint32_t aPid,
IHandlerControlHolder aHandlerControl);

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

@ -155,8 +155,6 @@ description = for bug 1514869 - layout is blocked on font lookup, needs complete
description = for bug 1487212 - layout requires hyphenation data from a given omnijar resource - only called once per locale by a given content process
[PContent::RemovePermission]
description = legacy sync IPC - please add detailed description
[PContent::GetA11yContentId]
description = legacy sync IPC - please add detailed description
[PGMP::StartPlugin]
description = legacy sync IPC - please add detailed description
[PGMPService::LaunchGMP]