History log of /frameworks/base/core/java/android/view/accessibility/AccessibilityInteractionClient.java
Revision Date Author Comments (<<< Hide modified files) (Show modified files >>>)
4528b4e882584745f48263fa6626987e63832a2a 16-May-2012 Svetoslav Ganov <svetoslavganov@google.com> Prefetching of accessibility node infos getting incorrect views.

1. The prefetcher of accessibility nodes infos was not folloing
the childForAccessibility relationship when finding the views
whose node infos to prefetch.

2. NumberPicker was not reporting the correct parent.

bug:6471710

Change-Id: Ia7ad5dd031fb4b3816dfe630d5212201cfafa236
/frameworks/base/core/java/android/view/accessibility/AccessibilityInteractionClient.java
c406be9036643ebe41bafcd94fe4aa861b4e4f4f 12-May-2012 Svetoslav Ganov <svetoslavganov@google.com> Fix inconsitency in aAccessibilityNodeInfo cache.

1. Fixed errors in the accessibility node cache.

A. The cache was not catching the case when the current window changes as a
result the user touch exploring it. As a result the cache had nodes from
more that one window but the node ids are not unique thus causing a mess.

B. The node info tree was prefetched regardless if a prefetched node is root
name space (i.e. view ids - not accessibility ids - are namespaced) while
the prefetched nodes were taking this into account. As a result there can
get disconnected subtrees in the cache.

C. When an event for a property change such as focus was received the cache
we were removing the source node. As a result there may be disconnected nodes.

D. When a node was added to the cache and an older version exists there was
no check if it will point to the same children and parent. As a result if
the state of the node has fewer children the subtrees rooted at the no
longer present children will stay disconnected in the cache.

E. When a node got accessibility or input focus the old one in the cache was
not removed. As a result you may have a state with more than one access
or input focus.

2. Added integrity check enabled only on user builds when a specific flag is set
for the cache which checks whether:

A. All nodes are from the same window.

B. All nodes are connected.

C. There are no duplicates.

D. There is only one input focus.

E. There is only one accessibility focus.

3. The reported accessibility node info tree was stopping at the root namespace
boundary which is not correct. The reported tree has to reflect everything
on the screen that the user can see such a workspace with widgets. The root
namespace is added to avoid clash of view id but the accessibility ids are
unique no matter if the view is inflated from a remote view.

4. Added calls to notify the accessibility layer when a preoprty that is interesting
for accessibiliy has changed.

bug:6471710

Change-Id: I069470d91f209ba16313fa6539787a55efa3512e
/frameworks/base/core/java/android/view/accessibility/AccessibilityInteractionClient.java
aa780c110922148a6a4ba06734bb2b0bb8c98f93 20-Apr-2012 Svetoslav Ganov <svetoslavganov@google.com> Adding support for traversing the content of a node info at granularity.

1. A view that creates an accessibility node info may add to the info
a list of granularity labels. These are granularities by which the
source view can iterate over its content. For example a text view
may support character, word link while a web view may additionally
support buttons, tables, etc. There are actions on accessibility
node info to go to the next/previous at a given granularity which
is passesed as an argument.

2. Added Bundle argument to the APIs for performing accessibility
actions. This is generic and extensible.

bug:5932640

Change-Id: I328cbbb4cddfdee082ab2a8b7ff1bd7477d8d6f9
/frameworks/base/core/java/android/view/accessibility/AccessibilityInteractionClient.java
fefd20e927b7252d63acb7bb1852c5188e3c1b2e 20-Apr-2012 Svetoslav Ganov <svetoslavganov@google.com> Adding an opt-in mechanism for gesture detection in AccessibilityService.

1. An accessibility service has to explicitly opt in to be notified
for gestures by the system. There is only one accessibility service
that handles gestures and in case it does not handle a gesture
the system performs default handling. This default handling ensures
that we have gesture navigation even if no accessibility service
would like to participate/customize the interaction model.

bug:5932640

Change-Id: Id8194293bd94097b455e9388b68134a45dc3b8fa
/frameworks/base/core/java/android/view/accessibility/AccessibilityInteractionClient.java
4213804541a8b05cd0587b138a2fd9a3b7fd9350 20-Mar-2012 Svetoslav Ganov <svetoslavganov@google.com> Accessibility focus - framework

Usefulness: Keep track of the current user location in the screen when
traversing the it. Enabling structural and directional
navigation over all elements on the screen. This enables
blind users that know the application layout to efficiently
locate desired elements as opposed to try touch exploring the
region where the the element should be - very tedious.

Rationale: There are two ways to implement accessibility focus One is
to let accessibility services keep track of it since they
have access to the screen content, and another to let the view
hierarchy keep track of it. While the first approach would
require almost no work on our part it poses several challenges
which make it a sub-optimal choice. Having the accessibility focus
in the accessibility service would require that service to scrape
the window content every time it changes to sync the view tree
state and the accessibility focus location. Pretty much the service
will have to keep an off screen model of the screen content. This
could be quite challenging to get right and would incur performance
cost for the multiple IPCs to repeatedly fetch the screen content.
Further, keeping virtual accessibility focus (i.e. in the service)
would require sync of the input and accessibility focus. This could
be challenging to implement right as well. Also, having an unlimited
number of accessibility services we cannot guarantee that they will
have a proper implementation, if any, to allow users to perform structural
navigation of the screen content. Assuming two accessibility
services implement structural navigation via accessibility focus,
there is not guarantee that they will behave similarly by default,
i.e. provide some standard way to navigate the screen content.
Also feedback from experienced accessibility researchers, specifically
T.V Raman, provides evidence that having virtual accessibility focus
creates many issues and it is very hard to get right.
Therefore, keeping accessibility focus in the system will avoid
keeping an off-screen model in accessibility services, it will always
be in sync with the state of the view hierarchy and the input focus.
Also this will allow having a default behavior for traversing the
screen via this accessibility focus that is consistent in all
accessibility services. We provide accessibility services with APIs to
override this behavior but all of them will perform screen traversal
in a consistent way by default.

Behavior: If accessibility is enabled the accessibility focus is the leading one
and the input follows it. Putting accessibility focus on a view moves
the input focus there. Clearing the accessibility focus of a view, clears
the input focus of this view. If accessibility focus is on a view that
cannot take input focus, then no other view should have input focus.
In accessibility mode we initially give accessibility focus to the topmost
view and no view has input focus. This ensures consistent behavior accross
all apps. Note that accessibility focus can move hierarchically in the
view tree and having it at the root is better than putting it where the
input focus would be - at the first input focusable which could be at
an arbitrary depth in the view tree. By default not all views are reported
for accessibility, only the important ones. A view may be explicitly labeled
as important or not for accessibility, or the system determines which one
is such - default. Important views for accessibility are all views that are
not dumb layout managers used only to arrange their chidren. Since the same
content arrangement can be obtained via different combintation of layout
managers, such managers cannot be used to reliably determine the application
structure. For example, a user should see a list as a list view with several
list items and each list item as a text view and a button as opposed to seeing
all the layout managers used to arrange the list item's content.
By default only important for accessibility views are regared for accessibility
purposes. View not regarded for accessibility neither fire accessibility events,
nor are reported being on the screen. An accessibility service may request the
system to regard all views. If the target SDK of an accessibility services is
less than JellyBean, then all views are regarded for accessibility.
Note that an accessibility service that requires all view to be ragarded for
accessibility may put accessibility focus on any view. Hence, it may implement
any navigational paradigm if desired. Especially considering the fact that
the system is detecting some standard gestures and delegates their processing
to an accessibility service. The default implementation of an accessibility
services performs the defualt navigation.

bug:5932640
bug:5605641

Change-Id: Ieac461d480579d706a847b9325720cb254736ebe
/frameworks/base/core/java/android/view/accessibility/AccessibilityInteractionClient.java
57c7fd5a43237afc5e8ef31a076e862c0c16c328 24-Feb-2012 Svetoslav Ganov <svetoslavganov@google.com> Fixing issues with the AccessibilityNodeInfo cache.

1. Before there were two caches one in the app process that
kept track only the ids of infos that were given to a
querying client and one in the querying client that
holds the infos. This design requires precise sync
between the caches. Doing that is somehow complicated
since the app has cache for each window and it has
to intercept all accessibility events from that window
to manage the cache. Each app has to have a cache for
each querying client. This approach would guarantee that
no infos are fetched twice but due to its stateful nature
and the two caches is tricky to implement and adds
unnecessary complexity. Now there is only one cache in
the client and the apps are stateless. The client is
passing flags to the app that are a clue what nodes to
prefetch. This approach may occasionally fetch a node
twice but it is considerably simpler and stateless
from the app perspective - there is only one cache.
Fetching a node more than once does not cause much
overhead compared to the IPC.

Change-Id: Ia02f6fe4f82cff9a9c2e21f4a36747de0f414c6f
/frameworks/base/core/java/android/view/accessibility/AccessibilityInteractionClient.java
0d04e245534cf777dfaf16dce3c51553837c14ff 21-Feb-2012 Svetoslav Ganov <svetoslavganov@google.com> Improving accessibility APIs used for UI automation.

1. UiTestAutomationBridge was accessing the root node in the
active window by tracking the accessibility event stream
and keeping the last active window changing event. Now
the bridge is stateless and the root node is fetched by
passing special window and view id with the request to
the system.

2. AccessibilityNodeInfos that are cached were not finished,
i.e. not sealed, causing exception when trying to access
their children or rpedecessors.

3. AccessibilityManagerService was not properly restoring its
state after the UI automation bridge disconnects from it.
I particular the devices was still in explore by touch mode
event if no services are enabled and the sutomation bridge
is disconnected.

4. ViewRootImpl for the focused window now fires accessibility
events when accessibility is enabled to allow accessibility
services to determine the current user location.

5. Several missing null checks in ViewRootImpl are fixed since
there were scenraios in which a NPE can occur.

6. Update the internal window content querying tests.

7. ViewRootImpl was firing one extra focus event.
bug:6009813
bug:6026952

Change-Id: Ib2e058d64538ecc268f9ef7a8f36ead047868a05
/frameworks/base/core/java/android/view/accessibility/AccessibilityInteractionClient.java
79311c4af8b54d3cd47ab37a120c648bfc990511 18-Jan-2012 Svetoslav Ganov <svetoslavganov@google.com> Speedup the accessibility window querying APIs and clean up.

1. Now when an interrogating client requires an AccessibilibtyNodeInfo
we aggressively prefetch all the predecessors of that node and its
descendants. The number of fetched nodes in one call is limited to
keep the APIs responsive. The prefetched nodes infos are cached in
the client process. The node info cache is invalidated partially or
completely based on the fired accessibility events. For example,
TYPE_WINDOW_STATE_CHANGED event clears the cache while
TYPE_VIEW_FOCUSED removed the focused node from the cache, etc.
Note that the cache is only for the currently active window.
The ViewRootImple also keeps track of only the ids of the node
infos it has sent to each querying process to avoid duplicating
work. Usually only one process will query the screen content
but we support the general case. Also all the caches are
automatically invalidated so not additional bookkeeping is
required. This simple strategy leads to 10X improving the
speed of the querying APIs.

2. The Monkey and UI test automation framework were registering a
raw event listener for accessibility events and hence perform
connection and cache management in similar way to an AccessibilityService.
This is fragile and requires the implementer to know internal framework
stuff. Now the functionality required by the Monkey and the UI automation
is encapsulated in a new UiTestAutomationBridge class. To enable this
was requited some refactoring of AccessibilityService.

3. Removed the *doSomethiong*InActiveWindow methods from the
AccessibilityInteractionClient and the AccessibilityInteractionConnection.
The function of these methods is implemented by the not *InActiveWindow
version while passing appropriate constants.

4. Updated the internal window Querying tests to use the new
UiTestAutomationBridge.

5. If the ViewRootImple was not initialized the querying APIs of
the IAccessibilityInteractionConnection implementation were
returning immediately without calling the callback with null.
This was causing the client side to wait until it times out. Now
the client is notified as soon as the call fails.

6. Added a check to guarantee that Views with AccessibilityNodeProvider
do not have children.

bug:5879530

Change-Id: I3ee43718748fec6e570992c7073c8f6f1fc269b3
/frameworks/base/core/java/android/view/accessibility/AccessibilityInteractionClient.java
55cdacb9ba22ce0e40918fd54acca7df62637ca6 01-Dec-2011 Svetoslav Ganov <svetoslavganov@google.com> am 0bfdd7c2: am e9f24a43: Merge "Fix memory leaks in the accessibility layer." into ics-mr1

* commit '0bfdd7c2927fb683b89fdd52befe643e8e069e77':
Fix memory leaks in the accessibility layer.
36bcdb535e14a8a2e2c8643fb577569f7a2b6aed 01-Dec-2011 Svetoslav Ganov <svetoslavganov@google.com> Fix memory leaks in the accessibility layer.

The AccessibilityServiceConnection chache should be shared
between all interrogating threads.

bug:5664337

Change-Id: I151041d0b358e87ac47ea5c1c258f90a8b252420
/frameworks/base/core/java/android/view/accessibility/AccessibilityInteractionClient.java
786e54dd13111b6a2f75f4f37dd20353cf613e97 01-Dec-2011 Svetoslav Ganov <svetoslavganov@google.com> Fixing the build

Change-Id: I125956773dd364b14f8d328e625df3c852001dbf
/frameworks/base/core/java/android/view/accessibility/AccessibilityInteractionClient.java
66922db828eab153c15bf3ca0b007313d9376e5e 01-Dec-2011 Svetoslav Ganov <svetoslavganov@google.com> Fixing the build - for real

Change-Id: I9628f2da8876b85f9c8ce94cc876b10e083980f6
/frameworks/base/core/java/android/view/accessibility/AccessibilityInteractionClient.java
8b5a814f6a36045b06bee36f44703503c03714d4 01-Dec-2011 Svetoslav Ganov <svetoslavganov@google.com> Fixing the build

Change-Id: I7b2270843123b252098ca798c03284fb089f1b8a
/frameworks/base/core/java/android/view/accessibility/AccessibilityInteractionClient.java
f3b4f3163b5b4c0a54a2643f07c97c47b14a1eb7 01-Dec-2011 Svetoslav Ganov <svetoslavganov@google.com> resolved conflicts for merge of 26f7a81f to master

Change-Id: I6bf5fd7c0de7945cef84602dbe3a7bbed587700f
d116d7c78a9c53f30a73bf273bd7618312cf3847 22-Nov-2011 Svetoslav Ganov <svetoslavganov@google.com> Fixing memory leaks in the accessiiblity layer.

1. AccessibilityInteractionConnections were removed from the
AccessiiblityManagerService but their DeathRecipents were
not unregistered, thus every removed interaction connection
was essentially leaking. Such connection is registered in
the system for every ViewRootImpl when accessiiblity is
enabled and inregistered when disabled.

2. Every AccessibilityEvent and AccessiilbityEventInfo obtained
from a widnow content querying accessibility service had a
handle to a binder proxy over which to make queries. Hoewever,
holding a proxy to a remote binder prevents the latter from
being garbage collected. Therefore, now the events and infos
have a connection id insteand and the hindden singleton
AccessiiblityInteaction client via which queries are made
has a registry with the connections. This class looks up
the connection given its id before making an IPC. Now the
connection is stored in one place and when an accessibility
service is disconnected the system sets the connection to
null so the binder object in the system process can be GCed.
Note that before this change a bad implemented accessibility
service could cache events or infos causing a leak in the
system process. This should never happen.

3. SparseArray was not clearing the reference to the last moved
element while garbage collecting thus causing a leak.

bug:5664337

Change-Id: Id397f614b026d43bd7b57bb7f8186bca5cdfcff9
/frameworks/base/core/java/android/view/accessibility/AccessibilityInteractionClient.java
021078554b902179442a345a9d080a165c3b5139 04-Oct-2011 Svetoslav Ganov <svetoslavganov@google.com> Adding APIs to enable reporting virtual view hierarchies to accessibility serivces.

Added an interface that is the contract for a client to expose a virtual
view hierarchy to accessibility services. Clients impement this interface
and set it in the View that is the root of the virtual sub-tree. Adding
this finctionality via compostion as opposed to inheritance enables apps
to maintain backwards compatibility by setting the accessibility virtual
hierarchy provider on the View only if the API version is high enough.

bug:5382859

Change-Id: I7e3927b71a5517943c6cb071be2e87fba23132bf
/frameworks/base/core/java/android/view/accessibility/AccessibilityInteractionClient.java
6bc5e530016928027c7b390a8368ecdd5bff072f 10-Sep-2011 Svetoslav Ganov <svetoslavganov@google.com> Inter process interrogation ocassionally gets stuck.

1. There was a bug that was not handling correctly the
case for which the interrogator requests an accessibility
node info and the message describing how to fetch the
latter for the same process case was delivered after the
code that checks whether the message is there in order to
dispatch it is executed. Now the message handling is done
correctly - the caller checks if the message is present and
if so processes it, otherwise the caller sleeps and is
interrupted if such a message arrives.

bug:5138933

Change-Id: I4c2940b46c9a52a51c5ee48b83ca6811489765d6
/frameworks/base/core/java/android/view/accessibility/AccessibilityInteractionClient.java
8bd69610aafc6995126965d1d23b771fe02a9084 23-Aug-2011 Svetoslav Ganov <svetoslavganov@google.com> Intra-process view hierarchy interrogation does not work.

The content retrieval APIs are synchronous from a client's
perspective but internally they are asynchronous. The client thread
calls into the system requesting an action and providing a callback
to receive the result after which it waits up to a timeout for that
result. The system enforces security and then delegates the request
to a given view hierarchy where a message is posted (from a binder
thread) describing what to be performed by the main UI thread the
result of which it delivered via the mentioned callback. However,
the blocked client thread and the main UI thread of the target view
hierarchy can be the same one, for example an accessibility service
and an activity run in the same process, thus they are executed on the
same main thread. In such a case the retrieval will fail since the UI
thread that has to process the message describing the work to be done
is blocked waiting for a result is has to compute! To avoid this scenario
when making a call the client also passes its process and thread ids so
the accessed view hierarchy can detect if the client making the request
is running in its main UI thread. In such a case the view hierarchy,
specifically the binder thread performing the IPC to it, does not post a
message to be run on the UI thread but passes it to the singleton
interaction client through which all interactions occur and the latter is
responsible to execute the message before starting to wait for the
asynchronous result delivered via the callback. In this case the expected
result is already received so no waiting is performed.

bug:5138933

Change-Id: I382e2d8689f5189110226613c2387f553df98bd3
/frameworks/base/core/java/android/view/accessibility/AccessibilityInteractionClient.java