зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1479039 - Implement java portion of focus path cache. r=snorp,yzen
Differential Revision: https://phabricator.services.mozilla.com/D11215 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
970933ad81
Коммит
956b93179f
|
@ -226,7 +226,13 @@ DocAccessibleWrap::CacheFocusPath(AccessibleWrap* aAccessible)
|
|||
}
|
||||
|
||||
ipcDoc->SendBatch(eBatch_FocusPath, cacheData);
|
||||
} else {
|
||||
// XXX: Local codepath, next patch
|
||||
} else if (SessionAccessibility* sessionAcc = SessionAccessibility::GetInstanceFor(this)) {
|
||||
nsTArray<AccessibleWrap*> accessibles;
|
||||
for (AccessibleWrap* acc = aAccessible; acc && acc != this->Parent();
|
||||
acc = static_cast<AccessibleWrap*>(acc->Parent())) {
|
||||
accessibles.AppendElement(acc);
|
||||
}
|
||||
|
||||
sessionAcc->ReplaceFocusPathCache(accessibles);
|
||||
}
|
||||
}
|
|
@ -222,7 +222,7 @@ a11y::ProxyBatch(ProxyAccessible* aDocument,
|
|||
sessionAcc->ReplaceViewportCache(accWraps, aData);
|
||||
break;
|
||||
case DocAccessibleWrap::eBatch_FocusPath:
|
||||
// XXX: Next patch
|
||||
sessionAcc->ReplaceFocusPathCache(accWraps, aData);
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Unknown batch type.");
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "RootAccessibleWrap.h"
|
||||
#include "nsAccessibilityService.h"
|
||||
#include "nsViewManager.h"
|
||||
#include "nsIPersistentProperties2.h"
|
||||
|
||||
#include "mozilla/dom/TabParent.h"
|
||||
#include "mozilla/a11y/DocAccessibleParent.h"
|
||||
|
@ -340,7 +341,8 @@ SessionAccessibility::ReplaceViewportCache(const nsTArray<AccessibleWrap*>& aAcc
|
|||
AccessibleWrap* acc = aAccessibles.ElementAt(i);
|
||||
if (aData.Length() == aAccessibles.Length()) {
|
||||
const BatchData& data = aData.ElementAt(i);
|
||||
infos->SetElement(i, acc->ToSmallBundle(data.State(), data.Bounds()));
|
||||
auto bundle = acc->ToSmallBundle(data.State(), data.Bounds());
|
||||
infos->SetElement(i, bundle);
|
||||
} else {
|
||||
infos->SetElement(i, acc->ToSmallBundle());
|
||||
}
|
||||
|
@ -348,3 +350,33 @@ SessionAccessibility::ReplaceViewportCache(const nsTArray<AccessibleWrap*>& aAcc
|
|||
|
||||
mSessionAccessibility->ReplaceViewportCache(infos);
|
||||
}
|
||||
|
||||
void
|
||||
SessionAccessibility::ReplaceFocusPathCache(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);
|
||||
nsCOMPtr<nsIPersistentProperties> props =
|
||||
AccessibleWrap::AttributeArrayToProperties(data.Attributes());
|
||||
auto bundle = acc->ToBundle(data.State(),
|
||||
data.Bounds(),
|
||||
data.Name(),
|
||||
data.TextValue(),
|
||||
data.DOMNodeID(),
|
||||
data.CurValue(),
|
||||
data.MinValue(),
|
||||
data.MaxValue(),
|
||||
data.Step(),
|
||||
props);
|
||||
infos->SetElement(i, bundle);
|
||||
} else {
|
||||
infos->SetElement(i, acc->ToBundle());
|
||||
}
|
||||
}
|
||||
|
||||
mSessionAccessibility->ReplaceFocusPathCache(infos);
|
||||
}
|
||||
|
|
|
@ -109,6 +109,9 @@ public:
|
|||
void ReplaceViewportCache(const nsTArray<AccessibleWrap*>& aAccessibles,
|
||||
const nsTArray<BatchData>& aData = nsTArray<BatchData>());
|
||||
|
||||
void ReplaceFocusPathCache(const nsTArray<AccessibleWrap*>& aAccessibles,
|
||||
const nsTArray<BatchData>& aData = nsTArray<BatchData>());
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SessionAccessibility)
|
||||
|
||||
private:
|
||||
|
|
|
@ -34,6 +34,8 @@ import android.view.accessibility.AccessibilityNodeInfo.CollectionItemInfo;
|
|||
import android.view.accessibility.AccessibilityNodeInfo.CollectionInfo;
|
||||
import android.view.accessibility.AccessibilityNodeProvider;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class SessionAccessibility {
|
||||
private static final String LOGTAG = "GeckoAccessibility";
|
||||
|
||||
|
@ -250,20 +252,28 @@ public class SessionAccessibility {
|
|||
}
|
||||
|
||||
private boolean isNodeCached(final int virtualViewId) {
|
||||
return mViewportCache.get(virtualViewId) != null;
|
||||
return mViewportCache.get(virtualViewId) != null || mFocusPathCache.get(virtualViewId) != null;
|
||||
}
|
||||
|
||||
private AccessibilityNodeInfo getNodeFromCache(final int virtualViewId) {
|
||||
GeckoBundle bundle = mViewportCache.get(virtualViewId);
|
||||
if (bundle == null) {
|
||||
Log.e(LOGTAG, "No node for " + virtualViewId + " cache size: " + mViewportCache.size());
|
||||
return null;
|
||||
private synchronized AccessibilityNodeInfo getNodeFromCache(final int virtualViewId) {
|
||||
AccessibilityNodeInfo node = null;
|
||||
for (SparseArray<GeckoBundle> cache : mCaches) {
|
||||
GeckoBundle bundle = cache.get(virtualViewId);
|
||||
if (bundle == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (node == null) {
|
||||
node = AccessibilityNodeInfo.obtain(mView, virtualViewId);
|
||||
}
|
||||
populateNodeFromBundle(node, bundle, true);
|
||||
}
|
||||
|
||||
AccessibilityNodeInfo node = AccessibilityNodeInfo.obtain(mView, virtualViewId);
|
||||
populateNodeFromBundle(node, bundle, true);
|
||||
return node;
|
||||
if (node == null) {
|
||||
Log.e(LOGTAG, "No cached node for " + virtualViewId);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
private void populateNodeFromBundle(final AccessibilityNodeInfo node, final GeckoBundle nodeInfo, final boolean fromCache) {
|
||||
|
@ -288,7 +298,10 @@ public class SessionAccessibility {
|
|||
// The basics
|
||||
node.setPackageName(GeckoAppShell.getApplicationContext().getPackageName());
|
||||
node.setClassName(getClassName(nodeInfo.getInt("className")));
|
||||
node.setText(nodeInfo.getString("text", ""));
|
||||
|
||||
if (nodeInfo.containsKey("text")) {
|
||||
node.setText(nodeInfo.getString("text"));
|
||||
}
|
||||
|
||||
// Add actions
|
||||
node.addAction(AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT);
|
||||
|
@ -451,6 +464,10 @@ public class SessionAccessibility {
|
|||
private int mAccessibilityFocusedNode = 0;
|
||||
// Viewport cache
|
||||
final SparseArray<GeckoBundle> mViewportCache = new SparseArray<>();
|
||||
// Focus cache
|
||||
final SparseArray<GeckoBundle> mFocusPathCache = new SparseArray<>();
|
||||
// List of caches in descending order from last updated.
|
||||
LinkedList<SparseArray<GeckoBundle>> mCaches = new LinkedList<>();
|
||||
|
||||
/* package */ SessionAccessibility(final GeckoSession session) {
|
||||
mSession = session;
|
||||
|
@ -680,12 +697,25 @@ public class SessionAccessibility {
|
|||
}
|
||||
|
||||
@WrapForJNI(calledFrom = "gecko")
|
||||
private void replaceViewportCache(final GeckoBundle[] bundles) {
|
||||
private synchronized void replaceViewportCache(final GeckoBundle[] bundles) {
|
||||
mViewportCache.clear();
|
||||
for (GeckoBundle bundle : bundles) {
|
||||
if (bundle == null) { continue; }
|
||||
mViewportCache.append(bundle.getInt("id"), bundle);
|
||||
}
|
||||
mCaches.remove(mViewportCache);
|
||||
mCaches.add(mViewportCache);
|
||||
}
|
||||
|
||||
@WrapForJNI(calledFrom = "gecko")
|
||||
private synchronized void replaceFocusPathCache(final GeckoBundle[] bundles) {
|
||||
mFocusPathCache.clear();
|
||||
for (GeckoBundle bundle : bundles) {
|
||||
if (bundle == null) { continue; }
|
||||
mFocusPathCache.append(bundle.getInt("id"), bundle);
|
||||
}
|
||||
mCaches.remove(mFocusPathCache);
|
||||
mCaches.add(mFocusPathCache);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче