Skip to content

Commit

Permalink
Bug 1479039 - Update cached focus path bounds on scroll. r=snorp,yzen…
Browse files Browse the repository at this point in the history
… a=jcristau

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

--HG--
extra : source : b47fdd1194c70c21906769611e2abf1d3e8a0781
extra : histedit_source : 896e567a19427b716dec3de3942ee97ec7ff1ac0
  • Loading branch information
eeejay committed Nov 12, 2018
1 parent 683a26d commit 1738380
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 6 deletions.
46 changes: 45 additions & 1 deletion accessible/android/DocAccessibleWrap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ DocAccessibleWrap::HandleAccEvent(AccEvent* aEvent)
case nsIAccessibleEvent::EVENT_SCROLLING_END:
CacheViewport();
break;
case nsIAccessibleEvent::EVENT_SCROLLING:
UpdateFocusPathBounds();
break;
default:
break;
}
Expand Down Expand Up @@ -195,6 +198,7 @@ DocAccessibleWrap::GetTopLevelContentDoc(AccessibleWrap* aAccessible) {
void
DocAccessibleWrap::CacheFocusPath(AccessibleWrap* aAccessible)
{
mFocusPath.Clear();
if (IPCAccessibilityActive()) {
DocAccessibleChild* ipcDoc = IPCDoc();
nsTArray<BatchData> cacheData;
Expand Down Expand Up @@ -223,6 +227,7 @@ DocAccessibleWrap::CacheFocusPath(AccessibleWrap* aAccessible)
acc->MaxValue(),
acc->Step(),
attributes));
mFocusPath.Put(acc->UniqueID(), acc);
}

ipcDoc->SendBatch(eBatch_FocusPath, cacheData);
Expand All @@ -235,4 +240,43 @@ DocAccessibleWrap::CacheFocusPath(AccessibleWrap* aAccessible)

sessionAcc->ReplaceFocusPathCache(accessibles);
}
}
}

void
DocAccessibleWrap::UpdateFocusPathBounds()
{
if (!mFocusPath.Count()) {
return;
}

if (IPCAccessibilityActive()) {
DocAccessibleChild* ipcDoc = IPCDoc();
nsTArray<BatchData> boundsData(mFocusPath.Count());
for (auto iter = mFocusPath.Iter(); !iter.Done(); iter.Next()) {
Accessible* accessible = iter.Data();
auto uid = accessible->IsDoc() && accessible->AsDoc()->IPCDoc() ? 0
: reinterpret_cast<uint64_t>(accessible->UniqueID());
boundsData.AppendElement(BatchData(accessible->Document()->IPCDoc(),
uid,
0,
accessible->Bounds(),
nsString(),
nsString(),
nsString(),
UnspecifiedNaN<double>(),
UnspecifiedNaN<double>(),
UnspecifiedNaN<double>(),
UnspecifiedNaN<double>(),
nsTArray<Attribute>()));
}

ipcDoc->SendBatch(eBatch_BoundsUpdate, boundsData);
} else if (SessionAccessibility* sessionAcc = SessionAccessibility::GetInstanceFor(this)) {
nsTArray<AccessibleWrap*> accessibles(mFocusPath.Count());
for (auto iter = mFocusPath.Iter(); !iter.Done(); iter.Next()) {
accessibles.AppendElement(static_cast<AccessibleWrap*>(iter.Data().get()));
}

sessionAcc->UpdateCachedBounds(accessibles);
}
}
5 changes: 5 additions & 0 deletions accessible/android/DocAccessibleWrap.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class DocAccessibleWrap : public DocAccessible
enum {
eBatch_Viewport = 0,
eBatch_FocusPath = 1,
eBatch_BoundsUpdate = 2,
};

protected:
Expand All @@ -50,9 +51,13 @@ class DocAccessibleWrap : public DocAccessible
private:
void CacheViewport();

void UpdateFocusPathBounds();

static void CacheViewportCallback(nsITimer* aTimer, void* aDocAccParam);

nsCOMPtr<nsITimer> mCacheRefreshTimer;

AccessibleHashtable mFocusPath;
};

} // namespace a11y
Expand Down
3 changes: 3 additions & 0 deletions accessible/android/Platform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,9 @@ a11y::ProxyBatch(ProxyAccessible* aDocument,
case DocAccessibleWrap::eBatch_FocusPath:
sessionAcc->ReplaceFocusPathCache(accWraps, aData);
break;
case DocAccessibleWrap::eBatch_BoundsUpdate:
sessionAcc->UpdateCachedBounds(accWraps, aData);
break;
default:
MOZ_ASSERT_UNREACHABLE("Unknown batch type.");
break;
Expand Down
19 changes: 19 additions & 0 deletions accessible/android/SessionAccessibility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -373,3 +373,22 @@ SessionAccessibility::ReplaceFocusPathCache(const nsTArray<AccessibleWrap*>& aAc

mSessionAccessibility->ReplaceFocusPathCache(infos);
}

void
SessionAccessibility::UpdateCachedBounds(const nsTArray<AccessibleWrap*>& aAccessibles,
const nsTArray<BatchData>& aData)
{
auto infos = jni::ObjectArray::New<java::GeckoBundle>(aAccessibles.Length());
for (size_t i = 0; i < aAccessibles.Length(); i++) {
AccessibleWrap* acc = aAccessibles.ElementAt(i);
if (aData.Length() == aAccessibles.Length()) {
const BatchData& data = aData.ElementAt(i);
auto bundle = acc->ToSmallBundle(data.State(), data.Bounds());
infos->SetElement(i, bundle);
} else {
infos->SetElement(i, acc->ToSmallBundle());
}
}

mSessionAccessibility->UpdateCachedBounds(infos);
}
3 changes: 3 additions & 0 deletions accessible/android/SessionAccessibility.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ class SessionAccessibility final
void ReplaceFocusPathCache(const nsTArray<AccessibleWrap*>& aAccessibles,
const nsTArray<BatchData>& aData = nsTArray<BatchData>());

void UpdateCachedBounds(const nsTArray<AccessibleWrap*>& aAccessibles,
const nsTArray<BatchData>& aData = nsTArray<BatchData>());

NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SessionAccessibility)

private:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import android.view.accessibility.AccessibilityNodeInfo.CollectionInfo;
import android.view.accessibility.AccessibilityNodeProvider;

import java.util.Iterator;
import java.util.LinkedList;

public class SessionAccessibility {
Expand Down Expand Up @@ -250,10 +251,6 @@ private AccessibilityNodeInfo getNodeFromGecko(final int virtualViewId) {
return node;
}

private boolean isNodeCached(final int virtualViewId) {
return mViewportCache.get(virtualViewId) != null || mFocusPathCache.get(virtualViewId) != null;
}

private synchronized AccessibilityNodeInfo getNodeFromCache(final int virtualViewId) {
AccessibilityNodeInfo node = null;
for (SparseArray<GeckoBundle> cache : mCaches) {
Expand Down Expand Up @@ -352,7 +349,7 @@ private void populateNodeFromBundle(final AccessibilityNodeInfo node, final Geck
int[] children = nodeInfo.getIntArray("children");
if (children != null) {
for (int childId : children) {
if (!fromCache || isNodeCached(childId)) {
if (!fromCache || getMostRecentBundle(childId) != null) {
// If this node is from cache, only populate with children that are cached as well.
node.addChild(mView, childId);
}
Expand Down Expand Up @@ -664,6 +661,18 @@ public boolean onMotionEvent(final MotionEvent event) {
((ViewParent) mView).requestSendAccessibilityEvent(mView, event);
}

private synchronized GeckoBundle getMostRecentBundle(final int virtualViewId) {
Iterator<SparseArray<GeckoBundle>> iter = mCaches.descendingIterator();
while (iter.hasNext()) {
GeckoBundle bundle = iter.next().get(virtualViewId);
if (bundle != null) {
return bundle;
}
}

return null;
}

/* package */ final class NativeProvider extends JNIObject {
@WrapForJNI(calledFrom = "ui")
private void setAttached(final boolean attached) {
Expand Down Expand Up @@ -713,5 +722,17 @@ private synchronized void replaceFocusPathCache(final GeckoBundle[] bundles) {
mCaches.remove(mFocusPathCache);
mCaches.add(mFocusPathCache);
}

@WrapForJNI(calledFrom = "gecko")
private synchronized void updateCachedBounds(final GeckoBundle[] bundles) {
for (GeckoBundle bundle : bundles) {
GeckoBundle cachedBundle = getMostRecentBundle(bundle.getInt("id"));
if (cachedBundle == null) {
Log.e(LOGTAG, "Can't update bounds of uncached node " + bundle.getInt("id"));
continue;
}
cachedBundle.putIntArray("bounds", bundle.getIntArray("bounds"));
}
}
}
}

0 comments on commit 1738380

Please sign in to comment.