Bug 1825891 - P2: Remove Android's non-CTW implementation. r=Jamie,geckoview-reviewers,m_kato

Differential Revision: https://phabricator.services.mozilla.com/D174516
This commit is contained in:
Eitan Isaacson 2023-04-13 17:58:57 +00:00
Родитель ea0675fb68
Коммит c275c3a7d9
15 изменённых файлов: 14 добавлений и 803 удалений

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

@ -62,32 +62,6 @@ nsresult AccessibleWrap::HandleAccEvent(AccEvent* aEvent) {
static_cast<DocAccessibleWrap*>(accessible->Document());
if (doc) {
switch (aEvent->GetEventType()) {
case nsIAccessibleEvent::EVENT_FOCUS: {
if (DocAccessibleWrap* topContentDoc =
doc->GetTopLevelContentDoc(accessible)) {
topContentDoc->CacheFocusPath(accessible);
}
break;
}
case nsIAccessibleEvent::EVENT_VIRTUALCURSOR_CHANGED: {
AccVCChangeEvent* vcEvent = downcast_accEvent(aEvent);
auto newPosition =
static_cast<AccessibleWrap*>(vcEvent->NewAccessible());
if (newPosition) {
if (DocAccessibleWrap* topContentDoc =
doc->GetTopLevelContentDoc(accessible)) {
topContentDoc->CacheFocusPath(newPosition);
}
}
break;
}
case nsIAccessibleEvent::EVENT_REORDER: {
if (DocAccessibleWrap* topContentDoc =
doc->GetTopLevelContentDoc(accessible)) {
topContentDoc->CacheViewport(true);
}
break;
}
case nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED: {
if (accessible != aEvent->Document() && !aEvent->IsFromUserInput()) {
AccCaretMoveEvent* caretEvent = downcast_accEvent(aEvent);

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

@ -23,8 +23,6 @@
using namespace mozilla;
using namespace mozilla::a11y;
const uint32_t kCacheRefreshInterval = 500;
#define UNIQUE_ID(acc) \
!acc || (acc->IsDoc() && acc->AsDoc()->IPCDoc()) \
? 0 \
@ -62,164 +60,6 @@ void DocAccessibleWrap::Shutdown() {
DocAccessible::Shutdown();
}
void DocAccessibleWrap::DoInitialUpdate() {
DocAccessible::DoInitialUpdate();
CacheViewport(true);
}
nsresult DocAccessibleWrap::HandleAccEvent(AccEvent* aEvent) {
switch (aEvent->GetEventType()) {
case nsIAccessibleEvent::EVENT_SCROLLING_END:
CacheViewport(false);
break;
case nsIAccessibleEvent::EVENT_SCROLLING:
UpdateFocusPathBounds();
break;
default:
break;
}
return DocAccessible::HandleAccEvent(aEvent);
}
void DocAccessibleWrap::CacheViewportCallback(nsITimer* aTimer,
void* aDocAccParam) {
RefPtr<DocAccessibleWrap> docAcc(
dont_AddRef(reinterpret_cast<DocAccessibleWrap*>(aDocAccParam)));
if (!docAcc || docAcc->HasShutdown() ||
(IPCAccessibilityActive() && !docAcc->IPCDoc())) {
return;
}
PresShell* presShell = docAcc->PresShellPtr();
nsIFrame* rootFrame = presShell->GetRootFrame();
if (!rootFrame) {
return;
}
nsTArray<nsIFrame*> frames;
nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
nsRect scrollPort = sf ? sf->GetScrollPortRect() : rootFrame->GetRect();
nsLayoutUtils::GetFramesForArea(
RelativeTo{presShell->GetRootFrame()}, scrollPort, frames,
{nsLayoutUtils::FrameForPointOption::OnlyVisible});
AccessibleHashtable inViewAccs;
for (size_t i = 0; i < frames.Length(); i++) {
nsIContent* content = frames.ElementAt(i)->GetContent();
if (!content) {
continue;
}
LocalAccessible* visibleAcc = docAcc->GetAccessibleOrContainer(content);
if (!visibleAcc) {
continue;
}
for (LocalAccessible* acc = visibleAcc; acc && acc != docAcc->LocalParent();
acc = acc->LocalParent()) {
const bool alreadyPresent =
inViewAccs.WithEntryHandle(acc->UniqueID(), [&](auto&& entry) {
if (entry) {
return true;
}
entry.Insert(RefPtr{acc});
return false;
});
if (alreadyPresent) {
break;
}
}
}
if (IPCAccessibilityActive()) {
DocAccessibleChild* ipcDoc = docAcc->IPCDoc();
nsTArray<BatchData> cacheData(inViewAccs.Count());
for (auto iter = inViewAccs.Iter(); !iter.Done(); iter.Next()) {
LocalAccessible* accessible = iter.Data();
nsAutoString name;
accessible->Name(name);
nsAutoString textValue;
accessible->Value(textValue);
nsAutoString nodeID;
accessible->DOMNodeID(nodeID);
nsAutoString description;
accessible->Description(description);
cacheData.AppendElement(BatchData(
OriginDocument(WrapNotNull(accessible->Document()->IPCDoc())),
UNIQUE_ID(accessible), accessible->State(), accessible->Bounds(),
accessible->ActionCount(), name, textValue, nodeID, description,
UnspecifiedNaN<double>(), UnspecifiedNaN<double>(),
UnspecifiedNaN<double>(), UnspecifiedNaN<double>(), nullptr));
}
ipcDoc->SendBatch(eBatch_Viewport, cacheData);
} else if (RefPtr<SessionAccessibility> sessionAcc =
SessionAccessibility::GetInstanceFor(docAcc)) {
nsTArray<Accessible*> accessibles(inViewAccs.Count());
for (const auto& entry : inViewAccs) {
accessibles.AppendElement(entry.GetWeak());
}
sessionAcc->ReplaceViewportCache(accessibles);
}
if (docAcc->mCachePivotBoundaries) {
a11y::Pivot pivot(docAcc);
TraversalRule rule(java::SessionAccessibility::HTML_GRANULARITY_DEFAULT,
true);
Accessible* maybeFirst = pivot.First(rule);
Accessible* maybeLast = pivot.Last(rule);
LocalAccessible* first = maybeFirst ? maybeFirst->AsLocal() : nullptr;
LocalAccessible* last = maybeLast ? maybeLast->AsLocal() : nullptr;
// If first/last are null, pass the root document as pivot boundary.
if (IPCAccessibilityActive()) {
DocAccessibleChild* ipcDoc = docAcc->IPCDoc();
DocAccessibleChild* firstDoc =
first ? first->Document()->IPCDoc() : ipcDoc;
DocAccessibleChild* lastDoc = last ? last->Document()->IPCDoc() : ipcDoc;
if (ipcDoc && firstDoc && lastDoc) {
// One or more of the documents may not have recieved an IPC doc yet.
// In that case, just throw away this update. We will get a new one soon
// enough.
ipcDoc->GetPlatformExtension()->SendSetPivotBoundaries(
WrapNotNull(firstDoc), UNIQUE_ID(first), WrapNotNull(lastDoc),
UNIQUE_ID(last));
}
} else if (RefPtr<SessionAccessibility> sessionAcc =
SessionAccessibility::GetInstanceFor(docAcc)) {
sessionAcc->UpdateAccessibleFocusBoundaries(
first ? static_cast<AccessibleWrap*>(first) : docAcc,
last ? static_cast<AccessibleWrap*>(last) : docAcc);
}
docAcc->mCachePivotBoundaries = false;
}
if (docAcc->mCacheRefreshTimer) {
docAcc->mCacheRefreshTimer = nullptr;
}
}
void DocAccessibleWrap::CacheViewport(bool aCachePivotBoundaries) {
if (StaticPrefs::accessibility_cache_enabled_AtStartup()) {
return;
}
mCachePivotBoundaries |= aCachePivotBoundaries;
if (IsTopLevelContentDoc() && !mCacheRefreshTimer) {
NS_NewTimerWithFuncCallback(getter_AddRefs(mCacheRefreshTimer),
CacheViewportCallback, this,
kCacheRefreshInterval, nsITimer::TYPE_ONE_SHOT,
"a11y::DocAccessibleWrap::CacheViewport");
if (mCacheRefreshTimer) {
NS_ADDREF_THIS(); // Kung fu death grip
}
}
}
DocAccessibleWrap* DocAccessibleWrap::GetTopLevelContentDoc(
AccessibleWrap* aAccessible) {
DocAccessibleWrap* doc =
@ -237,91 +77,4 @@ bool DocAccessibleWrap::IsTopLevelContentDoc() {
(!parentDoc || !parentDoc->DocumentNode()->IsContentDocument());
}
void DocAccessibleWrap::CacheFocusPath(AccessibleWrap* aAccessible) {
if (StaticPrefs::accessibility_cache_enabled_AtStartup()) {
return;
}
mFocusPath.Clear();
if (IPCAccessibilityActive()) {
DocAccessibleChild* ipcDoc = IPCDoc();
nsTArray<BatchData> cacheData;
for (AccessibleWrap* acc = aAccessible; acc && acc != this->LocalParent();
acc = static_cast<AccessibleWrap*>(acc->LocalParent())) {
nsAutoString name;
acc->Name(name);
nsAutoString textValue;
acc->Value(textValue);
nsAutoString nodeID;
acc->DOMNodeID(nodeID);
nsAutoString description;
acc->Description(description);
RefPtr<AccAttributes> attributes = acc->Attributes();
cacheData.AppendElement(BatchData(
OriginDocument(WrapNotNull(acc->Document()->IPCDoc())),
UNIQUE_ID(acc), acc->State(), acc->Bounds(), acc->ActionCount(), name,
textValue, nodeID, description, acc->CurValue(), acc->MinValue(),
acc->MaxValue(), acc->Step(), attributes));
mFocusPath.InsertOrUpdate(acc->UniqueID(), RefPtr{acc});
}
ipcDoc->SendBatch(eBatch_FocusPath, cacheData);
} else if (RefPtr<SessionAccessibility> sessionAcc =
SessionAccessibility::GetInstanceFor(this)) {
nsTArray<Accessible*> accessibles;
for (LocalAccessible* acc = aAccessible; acc && acc != this->LocalParent();
acc = acc->LocalParent()) {
accessibles.AppendElement(acc);
mFocusPath.InsertOrUpdate(acc->UniqueID(), RefPtr{acc});
}
sessionAcc->ReplaceFocusPathCache(accessibles);
}
}
void DocAccessibleWrap::UpdateFocusPathBounds() {
if (StaticPrefs::accessibility_cache_enabled_AtStartup()) {
return;
}
if (!mFocusPath.Count()) {
return;
}
if (IPCAccessibilityActive()) {
DocAccessibleChild* ipcDoc = IPCDoc();
nsTArray<BatchData> boundsData(mFocusPath.Count());
for (auto iter = mFocusPath.Iter(); !iter.Done(); iter.Next()) {
LocalAccessible* accessible = iter.Data();
if (!accessible || accessible->IsDefunct()) {
MOZ_ASSERT_UNREACHABLE("Focus path cached accessible is gone.");
continue;
}
boundsData.AppendElement(BatchData(
OriginDocument(WrapNotNull(accessible->Document()->IPCDoc())),
UNIQUE_ID(accessible), 0, accessible->Bounds(), 0, nsString(),
nsString(), nsString(), nsString(), UnspecifiedNaN<double>(),
UnspecifiedNaN<double>(), UnspecifiedNaN<double>(),
UnspecifiedNaN<double>(), RefPtr<AccAttributes>{}));
}
ipcDoc->SendBatch(eBatch_BoundsUpdate, boundsData);
} else if (RefPtr<SessionAccessibility> sessionAcc =
SessionAccessibility::GetInstanceFor(this)) {
nsTArray<Accessible*> accessibles(mFocusPath.Count());
for (auto iter = mFocusPath.Iter(); !iter.Done(); iter.Next()) {
LocalAccessible* accessible = iter.Data();
if (!accessible || accessible->IsDefunct()) {
MOZ_ASSERT_UNREACHABLE("Focus path cached accessible is gone.");
continue;
}
accessibles.AppendElement(accessible);
}
sessionAcc->UpdateCachedBounds(accessibles);
}
}
#undef UNIQUE_ID

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

@ -22,35 +22,9 @@ class DocAccessibleWrap : public DocAccessible {
virtual void Shutdown() override;
virtual nsresult HandleAccEvent(AccEvent* aEvent) override;
DocAccessibleWrap* GetTopLevelContentDoc(AccessibleWrap* aAccessible);
bool IsTopLevelContentDoc();
void CacheFocusPath(AccessibleWrap* aAccessible);
void CacheViewport(bool aCachePivotBoundaries);
enum {
eBatch_Viewport = 0,
eBatch_FocusPath = 1,
eBatch_BoundsUpdate = 2,
};
protected:
virtual void DoInitialUpdate() override;
private:
void UpdateFocusPathBounds();
static void CacheViewportCallback(nsITimer* aTimer, void* aDocAccParam);
nsCOMPtr<nsITimer> mCacheRefreshTimer;
bool mCachePivotBoundaries;
AccessibleHashtable mFocusPath;
};
} // namespace a11y

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

@ -224,36 +224,6 @@ void a11y::ProxyAnnouncementEvent(RemoteAccessible* aTarget,
}
}
void a11y::ProxyBatch(RemoteAccessible* aDocument, const uint64_t aBatchType,
const nsTArray<RemoteAccessible*>& aAccessibles,
const nsTArray<BatchData>& aData) {
RefPtr<SessionAccessibility> sessionAcc =
SessionAccessibility::GetInstanceFor(aDocument);
if (!sessionAcc) {
return;
}
nsTArray<Accessible*> accessibles(aAccessibles.Length());
for (size_t i = 0; i < aAccessibles.Length(); i++) {
accessibles.AppendElement(aAccessibles.ElementAt(i));
}
switch (aBatchType) {
case DocAccessibleWrap::eBatch_Viewport:
sessionAcc->ReplaceViewportCache(accessibles, aData);
break;
case DocAccessibleWrap::eBatch_FocusPath:
sessionAcc->ReplaceFocusPathCache(accessibles, aData);
break;
case DocAccessibleWrap::eBatch_BoundsUpdate:
sessionAcc->UpdateCachedBounds(accessibles, aData);
break;
default:
MOZ_ASSERT_UNREACHABLE("Unknown batch type.");
break;
}
}
bool a11y::LocalizeString(const nsAString& aToken, nsAString& aLocalized) {
MOZ_ASSERT(XRE_IsParentProcess());

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

@ -180,8 +180,8 @@ void SessionAccessibility::Click(int32_t aID) {
FORWARD_ACTION_TO_ACCESSIBLE(DoAction, 0);
}
bool SessionAccessibility::CachedPivot(int32_t aID, int32_t aGranularity,
bool aForward, bool aInclusive) {
bool SessionAccessibility::Pivot(int32_t aID, int32_t aGranularity,
bool aForward, bool aInclusive) {
MOZ_ASSERT(IsCacheEnabled(), "Cache is enabled");
MOZ_ASSERT(AndroidBridge::IsJavaUiThread());
MonitorAutoLock mal(nsAccessibilityService::GetAndroidMonitor());
@ -190,7 +190,14 @@ bool SessionAccessibility::CachedPivot(int32_t aID, int32_t aGranularity,
if (acc->IsLocal()) {
nsAppShell::PostEvent(
[this, self, aID, aGranularity, aForward, aInclusive] {
Pivot(aID, aGranularity, aForward, aInclusive);
MonitorAutoLock mal(nsAccessibilityService::GetAndroidMonitor());
if (Accessible* _acc = GetAccessibleByID(aID)) {
MOZ_ASSERT(_acc && _acc->IsLocal());
if (LocalAccessible* localAcc = _acc->AsLocal()) {
static_cast<AccessibleWrap*>(localAcc)->PivotTo(
aGranularity, aForward, aInclusive);
}
}
});
return true;
}
@ -211,11 +218,6 @@ bool SessionAccessibility::CachedPivot(int32_t aID, int32_t aGranularity,
return false;
}
void SessionAccessibility::Pivot(int32_t aID, int32_t aGranularity,
bool aForward, bool aInclusive) {
FORWARD_EXT_ACTION_TO_ACCESSIBLE(PivotTo, aGranularity, aForward, aInclusive);
}
void SessionAccessibility::ExploreByTouch(int32_t aID, float aX, float aY) {
auto gvAccessor(mWindow.Access());
if (gvAccessor) {
@ -563,310 +565,6 @@ void SessionAccessibility::SendAnnouncementEvent(Accessible* aAccessible,
java::SessionAccessibility::CLASSNAME_WEBVIEW, eventInfo);
}
void SessionAccessibility::ReplaceViewportCache(
const nsTArray<Accessible*>& aAccessibles,
const nsTArray<BatchData>& aData) {
auto infos = jni::ObjectArray::New<java::GeckoBundle>(aAccessibles.Length());
for (size_t i = 0; i < aAccessibles.Length(); i++) {
Accessible* acc = aAccessibles.ElementAt(i);
if (!acc) {
MOZ_ASSERT_UNREACHABLE("Updated accessible is gone.");
continue;
}
if (aData.Length() == aAccessibles.Length()) {
const BatchData& data = aData.ElementAt(i);
auto bundle = ToBundle(acc, data.State(), data.Bounds(),
data.ActionCount(), data.Name(), data.TextValue(),
data.DOMNodeID(), data.Description());
infos->SetElement(i, bundle);
} else {
infos->SetElement(i, ToBundle(acc, true));
}
}
mSessionAccessibility->ReplaceViewportCache(infos);
SendWindowContentChangedEvent();
}
void SessionAccessibility::ReplaceFocusPathCache(
const nsTArray<Accessible*>& aAccessibles,
const nsTArray<BatchData>& aData) {
auto infos = jni::ObjectArray::New<java::GeckoBundle>(aAccessibles.Length());
for (size_t i = 0; i < aAccessibles.Length(); i++) {
Accessible* acc = aAccessibles.ElementAt(i);
if (!acc) {
MOZ_ASSERT_UNREACHABLE("Updated accessible is gone.");
continue;
}
if (aData.Length() == aAccessibles.Length()) {
const BatchData& data = aData.ElementAt(i);
auto bundle =
ToBundle(acc, data.State(), data.Bounds(), data.ActionCount(),
data.Name(), data.TextValue(), data.DOMNodeID(),
data.Description(), data.CurValue(), data.MinValue(),
data.MaxValue(), data.Step(), data.Attributes());
infos->SetElement(i, bundle);
} else {
infos->SetElement(i, ToBundle(acc));
}
}
mSessionAccessibility->ReplaceFocusPathCache(infos);
}
void SessionAccessibility::UpdateCachedBounds(
const nsTArray<Accessible*>& aAccessibles,
const nsTArray<BatchData>& aData) {
auto infos = jni::ObjectArray::New<java::GeckoBundle>(aAccessibles.Length());
for (size_t i = 0; i < aAccessibles.Length(); i++) {
Accessible* acc = aAccessibles.ElementAt(i);
if (!acc) {
MOZ_ASSERT_UNREACHABLE("Updated accessible is gone.");
continue;
}
if (aData.Length() == aAccessibles.Length()) {
const BatchData& data = aData.ElementAt(i);
auto bundle = ToBundle(acc, data.State(), data.Bounds(),
data.ActionCount(), data.Name(), data.TextValue(),
data.DOMNodeID(), data.Description());
infos->SetElement(i, bundle);
} else {
infos->SetElement(i, ToBundle(acc, true));
}
}
mSessionAccessibility->UpdateCachedBounds(infos);
}
void SessionAccessibility::UpdateAccessibleFocusBoundaries(Accessible* aFirst,
Accessible* aLast) {
mSessionAccessibility->UpdateAccessibleFocusBoundaries(
aFirst ? AccessibleWrap::GetVirtualViewID(aFirst) : kNoID,
aLast ? AccessibleWrap::GetVirtualViewID(aLast) : kNoID);
}
mozilla::java::GeckoBundle::LocalRef SessionAccessibility::ToBundle(
Accessible* aAccessible, bool aSmall) {
nsAutoString name;
aAccessible->Name(name);
nsAutoString textValue;
aAccessible->Value(textValue);
nsAutoString nodeID;
aAccessible->DOMNodeID(nodeID);
nsAutoString description;
aAccessible->Description(description);
uint64_t state = aAccessible->State();
LayoutDeviceIntRect bounds = aAccessible->Bounds();
uint8_t actionCount = aAccessible->ActionCount();
if (aSmall) {
return ToBundle(aAccessible, state, bounds, actionCount, name, textValue,
nodeID, description);
}
double curValue = UnspecifiedNaN<double>();
double minValue = UnspecifiedNaN<double>();
double maxValue = UnspecifiedNaN<double>();
double step = UnspecifiedNaN<double>();
if (aAccessible->HasNumericValue()) {
curValue = aAccessible->CurValue();
minValue = aAccessible->MinValue();
maxValue = aAccessible->MaxValue();
step = aAccessible->Step();
}
RefPtr<AccAttributes> attributes = aAccessible->Attributes();
return ToBundle(aAccessible, state, bounds, actionCount, name, textValue,
nodeID, description, curValue, minValue, maxValue, step,
attributes);
}
mozilla::java::GeckoBundle::LocalRef SessionAccessibility::ToBundle(
Accessible* aAccessible, const uint64_t aState,
const LayoutDeviceIntRect& aBounds, const uint8_t aActionCount,
const nsString& aName, const nsString& aTextValue,
const nsString& aDOMNodeID, const nsString& aDescription,
const double& aCurVal, const double& aMinVal, const double& aMaxVal,
const double& aStep, AccAttributes* aAttributes) {
MOZ_ASSERT(NS_IsMainThread());
int32_t virtualViewID = AccessibleWrap::GetVirtualViewID(aAccessible);
GECKOBUNDLE_START(nodeInfo);
GECKOBUNDLE_PUT(nodeInfo, "id", java::sdk::Integer::ValueOf(virtualViewID));
Accessible* parent = virtualViewID != kNoID ? aAccessible->Parent() : nullptr;
GECKOBUNDLE_PUT(nodeInfo, "parentId",
java::sdk::Integer::ValueOf(
parent ? AccessibleWrap::GetVirtualViewID(parent) : 0));
role role = aAccessible->Role();
if (role == roles::LINK && !(aState & states::LINKED)) {
// A link without the linked state (<a> with no href) shouldn't be presented
// as a link.
role = roles::TEXT;
}
uint32_t flags = AccessibleWrap::GetFlags(role, aState, aActionCount);
GECKOBUNDLE_PUT(nodeInfo, "flags", java::sdk::Integer::ValueOf(flags));
GECKOBUNDLE_PUT(
nodeInfo, "className",
java::sdk::Integer::ValueOf(AccessibleWrap::AndroidClass(aAccessible)));
nsAutoString hint;
if (aState & states::EDITABLE) {
// An editable field's name is populated in the hint.
hint.Assign(aName);
GECKOBUNDLE_PUT(nodeInfo, "text", jni::StringParam(aTextValue));
} else {
if (role == roles::LINK || role == roles::HEADING) {
GECKOBUNDLE_PUT(nodeInfo, "description", jni::StringParam(aName));
} else {
GECKOBUNDLE_PUT(nodeInfo, "text", jni::StringParam(aName));
}
}
if (!aDescription.IsEmpty()) {
if (!hint.IsEmpty()) {
// If this is an editable, the description is concatenated with a
// whitespace directly after the name.
hint.AppendLiteral(" ");
}
hint.Append(aDescription);
}
if ((aState & states::REQUIRED) != 0) {
nsAutoString requiredString;
if (LocalizeString(u"stateRequired"_ns, requiredString)) {
if (!hint.IsEmpty()) {
// If the hint is non-empty, concatenate with a comma for a brief pause.
hint.AppendLiteral(", ");
}
hint.Append(requiredString);
}
}
if (!hint.IsEmpty()) {
GECKOBUNDLE_PUT(nodeInfo, "hint", jni::StringParam(hint));
}
nsAutoString geckoRole;
nsAutoString roleDescription;
if (virtualViewID != kNoID) {
AccessibleWrap::GetRoleDescription(role, aAttributes, geckoRole,
roleDescription);
}
GECKOBUNDLE_PUT(nodeInfo, "roleDescription",
jni::StringParam(roleDescription));
GECKOBUNDLE_PUT(nodeInfo, "geckoRole", jni::StringParam(geckoRole));
if (!aDOMNodeID.IsEmpty()) {
GECKOBUNDLE_PUT(nodeInfo, "viewIdResourceName",
jni::StringParam(aDOMNodeID));
}
const int32_t data[4] = {aBounds.x, aBounds.y, aBounds.x + aBounds.width,
aBounds.y + aBounds.height};
GECKOBUNDLE_PUT(nodeInfo, "bounds", jni::IntArray::New(data, 4));
if (aAccessible->HasNumericValue()) {
GECKOBUNDLE_START(rangeInfo);
if (aMaxVal == 1 && aMinVal == 0) {
GECKOBUNDLE_PUT(rangeInfo, "type",
java::sdk::Integer::ValueOf(2)); // percent
} else if (std::round(aStep) != aStep) {
GECKOBUNDLE_PUT(rangeInfo, "type",
java::sdk::Integer::ValueOf(1)); // float
} else {
GECKOBUNDLE_PUT(rangeInfo, "type",
java::sdk::Integer::ValueOf(0)); // integer
}
if (!std::isnan(aCurVal)) {
GECKOBUNDLE_PUT(rangeInfo, "current", java::sdk::Double::New(aCurVal));
}
if (!std::isnan(aMinVal)) {
GECKOBUNDLE_PUT(rangeInfo, "min", java::sdk::Double::New(aMinVal));
}
if (!std::isnan(aMaxVal)) {
GECKOBUNDLE_PUT(rangeInfo, "max", java::sdk::Double::New(aMaxVal));
}
GECKOBUNDLE_FINISH(rangeInfo);
GECKOBUNDLE_PUT(nodeInfo, "rangeInfo", rangeInfo);
}
if (aAttributes) {
nsString inputTypeAttr;
aAttributes->GetAttribute(nsGkAtoms::textInputType, inputTypeAttr);
int32_t inputType = AccessibleWrap::GetInputType(inputTypeAttr);
if (inputType) {
GECKOBUNDLE_PUT(nodeInfo, "inputType",
java::sdk::Integer::ValueOf(inputType));
}
Maybe<int32_t> rowIndex =
aAttributes->GetAttribute<int32_t>(nsGkAtoms::posinset);
if (rowIndex) {
GECKOBUNDLE_START(collectionItemInfo);
GECKOBUNDLE_PUT(collectionItemInfo, "rowIndex",
java::sdk::Integer::ValueOf(*rowIndex - 1));
GECKOBUNDLE_PUT(collectionItemInfo, "columnIndex",
java::sdk::Integer::ValueOf(0));
GECKOBUNDLE_PUT(collectionItemInfo, "rowSpan",
java::sdk::Integer::ValueOf(1));
GECKOBUNDLE_PUT(collectionItemInfo, "columnSpan",
java::sdk::Integer::ValueOf(1));
GECKOBUNDLE_FINISH(collectionItemInfo);
GECKOBUNDLE_PUT(nodeInfo, "collectionItemInfo", collectionItemInfo);
}
Maybe<int32_t> rowCount =
aAttributes->GetAttribute<int32_t>(nsGkAtoms::child_item_count);
if (rowCount) {
GECKOBUNDLE_START(collectionInfo);
GECKOBUNDLE_PUT(collectionInfo, "rowCount",
java::sdk::Integer::ValueOf(*rowCount));
GECKOBUNDLE_PUT(collectionInfo, "columnCount",
java::sdk::Integer::ValueOf(1));
if (aAttributes->HasAttribute(nsGkAtoms::tree)) {
GECKOBUNDLE_PUT(collectionInfo, "isHierarchical",
java::sdk::Boolean::TRUE());
}
if (aAccessible->IsSelect()) {
int32_t selectionMode = (aState & states::MULTISELECTABLE) ? 2 : 1;
GECKOBUNDLE_PUT(collectionInfo, "selectionMode",
java::sdk::Integer::ValueOf(selectionMode));
}
GECKOBUNDLE_FINISH(collectionInfo);
GECKOBUNDLE_PUT(nodeInfo, "collectionInfo", collectionInfo);
}
}
if (!nsAccUtils::MustPrune(aAccessible)) {
auto childCount = aAccessible->ChildCount();
nsTArray<int32_t> children(childCount);
for (uint32_t i = 0; i < childCount; i++) {
auto child = aAccessible->ChildAt(i);
children.AppendElement(AccessibleWrap::GetVirtualViewID(child));
}
GECKOBUNDLE_PUT(nodeInfo, "children",
jni::IntArray::New(children.Elements(), children.Length()));
}
GECKOBUNDLE_FINISH(nodeInfo);
return nodeInfo;
}
void SessionAccessibility::PopulateNodeInfo(
Accessible* aAccessible, mozilla::jni::Object::Param aNodeInfo) {
nsAutoString name;

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

@ -56,9 +56,7 @@ class SessionAccessibility final
int GetNodeClassName(int32_t aID);
void SetText(int32_t aID, jni::String::Param aText);
void Click(int32_t aID);
void Pivot(int32_t aID, int32_t aGranularity, bool aForward, bool aInclusive);
bool CachedPivot(int32_t aID, int32_t aGranularity, bool aForward,
bool aInclusive);
bool Pivot(int32_t aID, int32_t aGranularity, bool aForward, bool aInclusive);
void ExploreByTouch(int32_t aID, float aX, float aY);
void NavigateText(int32_t aID, int32_t aGranularity, int32_t aStartOffset,
int32_t aEndOffset, bool aForward, bool aSelect);
@ -91,21 +89,6 @@ class SessionAccessibility final
const nsAString& aAnnouncement,
uint16_t aPriority);
// Cache methods
void ReplaceViewportCache(
const nsTArray<Accessible*>& aAccessibles,
const nsTArray<BatchData>& aData = nsTArray<BatchData>());
void ReplaceFocusPathCache(
const nsTArray<Accessible*>& aAccessibles,
const nsTArray<BatchData>& aData = nsTArray<BatchData>());
void UpdateCachedBounds(
const nsTArray<Accessible*>& aAccessibles,
const nsTArray<BatchData>& aData = nsTArray<BatchData>());
void UpdateAccessibleFocusBoundaries(Accessible* aFirst, Accessible* aLast);
Accessible* GetAccessibleByID(int32_t aID) const;
static const int32_t kNoID = -1;
@ -120,20 +103,6 @@ class SessionAccessibility final
private:
~SessionAccessibility() {}
mozilla::java::GeckoBundle::LocalRef ToBundle(Accessible* aAccessible,
bool aSmall = false);
mozilla::java::GeckoBundle::LocalRef ToBundle(
Accessible* aAccessible, const uint64_t aState,
const LayoutDeviceIntRect& aBounds, const uint8_t aActionCount,
const nsString& aName, const nsString& aTextValue,
const nsString& aDOMNodeID, const nsString& aDescription,
const double& aCurVal = UnspecifiedNaN<double>(),
const double& aMinVal = UnspecifiedNaN<double>(),
const double& aMaxVal = UnspecifiedNaN<double>(),
const double& aStep = UnspecifiedNaN<double>(),
AccAttributes* aAttributes = nullptr);
void PopulateNodeInfo(Accessible* aAccessible,
mozilla::jni::Object::Param aNodeInfo);

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

@ -135,12 +135,6 @@ void ProxyScrollingEvent(RemoteAccessible* aTarget, uint32_t aEventType,
void ProxyAnnouncementEvent(RemoteAccessible* aTarget,
const nsAString& aAnnouncement, uint16_t aPriority);
class BatchData;
void ProxyBatch(RemoteAccessible* aDocument, const uint64_t aBatchType,
const nsTArray<RemoteAccessible*>& aAccessibles,
const nsTArray<BatchData>& aData);
bool LocalizeString(const nsAString& aToken, nsAString& aLocalized);
#endif

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

@ -1265,37 +1265,6 @@ mozilla::ipc::IPCResult DocAccessibleParent::RecvFocusEvent(
#endif // defined(XP_WIN)
#if !defined(XP_WIN)
mozilla::ipc::IPCResult DocAccessibleParent::RecvBatch(
const uint64_t& aBatchType, nsTArray<BatchData>&& aData) {
// Only do something in Android. We can't ifdef the entire protocol out in
// the ipdl because it doesn't allow preprocessing.
# if defined(ANDROID)
if (mShutdown) {
return IPC_OK();
}
nsTArray<RemoteAccessible*> proxies(aData.Length());
for (size_t i = 0; i < aData.Length(); i++) {
DocAccessibleParent* doc = static_cast<DocAccessibleParent*>(
aData.ElementAt(i).Document().get_PDocAccessible().AsParent().get());
MOZ_ASSERT(doc);
if (doc->IsShutdown()) {
continue;
}
RemoteAccessible* proxy = doc->GetAccessible(aData.ElementAt(i).ID());
if (!proxy) {
MOZ_ASSERT_UNREACHABLE("No proxy found!");
continue;
}
proxies.AppendElement(proxy);
}
ProxyBatch(this, aBatchType, proxies, aData);
# endif // defined(XP_WIN)
return IPC_OK();
}
bool DocAccessibleParent::DeallocPDocAccessiblePlatformExtParent(
PDocAccessiblePlatformExtParent* aActor) {
delete aActor;

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

@ -281,9 +281,6 @@ class DocAccessibleParent : public RemoteAccessible,
#endif
#if !defined(XP_WIN)
virtual mozilla::ipc::IPCResult RecvBatch(
const uint64_t& aBatchType, nsTArray<BatchData>&& aData) override;
virtual bool DeallocPDocAccessiblePlatformExtParent(
PDocAccessiblePlatformExtParent* aActor) override;

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

@ -14,32 +14,5 @@
namespace mozilla {
namespace a11y {
mozilla::ipc::IPCResult DocAccessiblePlatformExtParent::RecvSetPivotBoundaries(
PDocAccessibleParent* aFirstDoc, uint64_t aFirst,
PDocAccessibleParent* aLastDoc, uint64_t aLast) {
MOZ_ASSERT(aFirstDoc);
MOZ_ASSERT(aLastDoc);
RefPtr<SessionAccessibility> sessionAcc =
SessionAccessibility::GetInstanceFor(
static_cast<DocAccessibleParent*>(Manager()));
if (!sessionAcc) {
return IPC_OK();
}
RemoteAccessible* first =
static_cast<DocAccessibleParent*>(aFirstDoc)->GetAccessible(aFirst);
RemoteAccessible* last =
static_cast<DocAccessibleParent*>(aLastDoc)->GetAccessible(aLast);
// We may not have proxy accessibles available yet for those accessibles
// in the parent process.
if (first && last) {
sessionAcc->UpdateAccessibleFocusBoundaries(first, last);
}
return IPC_OK();
}
} // namespace a11y
} // namespace mozilla

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

@ -11,10 +11,6 @@
namespace mozilla {
namespace a11y {
class DocAccessiblePlatformExtParent : public PDocAccessiblePlatformExtParent {
public:
mozilla::ipc::IPCResult RecvSetPivotBoundaries(
PDocAccessibleParent* aFirstDoc, uint64_t aFirst,
PDocAccessibleParent* aLastDoc, uint64_t aLast);
};
} // namespace a11y
} // namespace mozilla

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

@ -16,8 +16,6 @@ protocol PDocAccessiblePlatformExt {
child:
async __delete__();
async PivotTo(uint64_t aID, int32_t aGranularity, bool aForward, bool aInclusive);
async NavigateText(uint64_t aID, int32_t aGranularity, int32_t aStartOffset, int32_t aEndOffset, bool aForward, bool aSelect);
async SetSelection(uint64_t aID, int32_t aStart, int32_t aEnd);
@ -27,9 +25,6 @@ child:
async Copy(uint64_t aID);
async Paste(uint64_t aID);
parent:
async SetPivotBoundaries(PDocAccessible aFirstDoc, uint64_t aFirst, PDocAccessible aLastDoc, uint64_t aLast);
};
}
}

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

@ -14,7 +14,6 @@ if CONFIG["ACCESSIBILITY"]:
SOURCES += [
"DocAccessiblePlatformExtChild.cpp",
"DocAccessiblePlatformExtParent.cpp",
]
LOCAL_INCLUDES += [

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

@ -40,24 +40,6 @@ union OriginDocument
PDocAccessible;
};
struct BatchData
{
OriginDocument Document;
uint64_t ID;
uint64_t State;
LayoutDeviceIntRect Bounds;
uint8_t ActionCount;
nsString Name;
nsString TextValue;
nsString DOMNodeID;
nsString Description;
double CurValue;
double MinValue;
double MaxValue;
double Step;
nullable AccAttributes Attributes;
};
struct ShowEventData
{
uint64_t ID;
@ -126,9 +108,6 @@ parent:
*/
async BindChildDoc(PDocAccessible aChildDoc, uint64_t aID);
// Android
async Batch(uint64_t aBatchType, BatchData[] aData);
/*
* Cache The World
*/

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

@ -675,13 +675,8 @@ public class SessionAccessibility {
return false;
}
return cachedPivot(id, granularity, forward, inclusive);
}
private boolean cachedPivot(
final int id, final String granularity, final boolean forward, final boolean inclusive) {
final int gran = java.util.Arrays.asList(sHtmlGranularities).indexOf(granularity);
final boolean success = nativeProvider.cachedPivotNative(id, gran, forward, inclusive);
final boolean success = nativeProvider.pivotNative(id, gran, forward, inclusive);
if (!success && !forward) {
// If we failed to pivot backwards set the root view as the a11y focus.
sendEvent(
@ -723,12 +718,8 @@ public class SessionAccessibility {
@WrapForJNI(dispatchTo = "gecko")
public native void click(int id);
@WrapForJNI(dispatchTo = "gecko", stubName = "Pivot")
public native void pivotNative(int id, int granularity, boolean forward, boolean inclusive);
@WrapForJNI(dispatchTo = "current", stubName = "CachedPivot")
public native boolean cachedPivotNative(
int id, int granularity, boolean forward, boolean inclusive);
@WrapForJNI(dispatchTo = "current", stubName = "Pivot")
public native boolean pivotNative(int id, int granularity, boolean forward, boolean inclusive);
@WrapForJNI(dispatchTo = "gecko")
public native void exploreByTouch(int id, float x, float y);
@ -761,26 +752,6 @@ public class SessionAccessibility {
});
}
@WrapForJNI(calledFrom = "gecko")
private void replaceViewportCache(final GeckoBundle[] bundles) {
// XXX: Will be removed
}
@WrapForJNI(calledFrom = "gecko")
private void replaceFocusPathCache(final GeckoBundle[] bundles) {
// XXX: Will be removed
}
@WrapForJNI(calledFrom = "gecko")
private void updateCachedBounds(final GeckoBundle[] bundles) {
// XXX: Will be removed
}
@WrapForJNI(calledFrom = "gecko")
private void updateAccessibleFocusBoundaries(final int firstNode, final int lastNode) {
// XXX: Will be removed
}
@WrapForJNI
private void populateNodeInfo(
final AccessibilityNodeInfo node,