diff options
author | Svetoslav Ganov <svetoslavganov@google.com> | 2011-08-23 13:40:30 -0700 |
---|---|---|
committer | Svetoslav Ganov <svetoslavganov@google.com> | 2011-08-24 16:26:43 -0700 |
commit | 8bd69610aafc6995126965d1d23b771fe02a9084 (patch) | |
tree | 13d160fbe865f3febd084c9935e38b1f5360ee84 /core/tests | |
parent | 69314e72941c86734c12476d1e61459811159b74 (diff) | |
download | frameworks_base-8bd69610aafc6995126965d1d23b771fe02a9084.zip frameworks_base-8bd69610aafc6995126965d1d23b771fe02a9084.tar.gz frameworks_base-8bd69610aafc6995126965d1d23b771fe02a9084.tar.bz2 |
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
Diffstat (limited to 'core/tests')
-rw-r--r-- | core/tests/coretests/res/layout/interrogation_activity.xml | 36 | ||||
-rw-r--r-- | core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java | 59 |
2 files changed, 51 insertions, 44 deletions
diff --git a/core/tests/coretests/res/layout/interrogation_activity.xml b/core/tests/coretests/res/layout/interrogation_activity.xml index 28d965b..44ed75c 100644 --- a/core/tests/coretests/res/layout/interrogation_activity.xml +++ b/core/tests/coretests/res/layout/interrogation_activity.xml @@ -30,20 +30,20 @@ > <Button android:id="@+id/button1" - android:layout_width="wrap_content" - android:layout_height="wrap_content" + android:layout_width="160px" + android:layout_height="100px" android:text="@string/button1" /> <Button android:id="@+id/button2" - android:layout_width="wrap_content" - android:layout_height="wrap_content" + android:layout_width="160px" + android:layout_height="100px" android:text="@string/button2" /> <Button android:id="@+id/button3" - android:layout_width="wrap_content" - android:layout_height="wrap_content" + android:layout_width="160px" + android:layout_height="100px" android:text="@string/button3" /> </LinearLayout> @@ -55,20 +55,20 @@ > <Button android:id="@+id/button4" - android:layout_width="wrap_content" - android:layout_height="wrap_content" + android:layout_width="160px" + android:layout_height="100px" android:text="@string/button4" /> <Button android:id="@+id/button5" - android:layout_width="wrap_content" - android:layout_height="wrap_content" + android:layout_width="160px" + android:layout_height="100px" android:text="@string/button5" /> <Button android:id="@+id/button6" - android:layout_width="wrap_content" - android:layout_height="wrap_content" + android:layout_width="160px" + android:layout_height="100px" android:text="@string/button6" /> </LinearLayout> @@ -80,20 +80,20 @@ > <Button android:id="@+id/button7" - android:layout_width="wrap_content" - android:layout_height="wrap_content" + android:layout_width="160px" + android:layout_height="100px" android:text="@string/button7" /> <Button android:id="@+id/button8" - android:layout_width="wrap_content" - android:layout_height="wrap_content" + android:layout_width="160px" + android:layout_height="100px" android:text="@string/button8" /> <Button android:id="@+id/button9" - android:layout_width="wrap_content" - android:layout_height="wrap_content" + android:layout_width="160px" + android:layout_height="100px" android:text="@string/button9" /> </LinearLayout> diff --git a/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java b/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java index 99d534c..a542a1b 100644 --- a/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java +++ b/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java @@ -31,6 +31,7 @@ import android.test.ActivityInstrumentationTestCase2; import android.test.suitebuilder.annotation.LargeTest; import android.util.Log; import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityInteractionClient; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.IAccessibilityManager; @@ -81,8 +82,8 @@ public class InterrogationActivityTest // bring up the activity getActivity(); - AccessibilityNodeInfo button = - getConnection().findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5); + AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance() + .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5); assertNotNull(button); assertEquals(0, button.getChildCount()); @@ -91,8 +92,8 @@ public class InterrogationActivityTest button.getBoundsInParent(bounds); assertEquals(0, bounds.left); assertEquals(0, bounds.top); - assertEquals(73, bounds.right); - assertEquals(48, bounds.bottom); + assertEquals(160, bounds.right); + assertEquals(100, bounds.bottom); // char sequence attributes assertEquals("com.android.frameworks.coretests", button.getPackageName()); @@ -133,8 +134,8 @@ public class InterrogationActivityTest getActivity(); // find a view by text - List<AccessibilityNodeInfo> buttons = - getConnection().findAccessibilityNodeInfosByViewTextInActiveWindow("butto"); + List<AccessibilityNodeInfo> buttons = AccessibilityInteractionClient.getInstance() + .findAccessibilityNodeInfosByViewTextInActiveWindow(getConnection(), "butto"); assertEquals(9, buttons.size()); } finally { afterClassIfNeeded(); @@ -170,8 +171,8 @@ public class InterrogationActivityTest classNameAndTextList.add("android.widget.ButtonButton8"); classNameAndTextList.add("android.widget.ButtonButton9"); - AccessibilityNodeInfo root = - getConnection().findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.root); + AccessibilityNodeInfo root = AccessibilityInteractionClient.getInstance() + .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.root); assertNotNull("We must find the existing root.", root); Queue<AccessibilityNodeInfo> fringe = new LinkedList<AccessibilityNodeInfo>(); @@ -214,15 +215,16 @@ public class InterrogationActivityTest getActivity(); // find a view and make sure it is not focused - AccessibilityNodeInfo button = - getConnection().findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5); + AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance() + .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5); assertFalse(button.isFocused()); // focus the view assertTrue(button.performAction(ACTION_FOCUS)); // find the view again and make sure it is focused - button = getConnection().findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5); + button = AccessibilityInteractionClient.getInstance() + .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5); assertTrue(button.isFocused()); } finally { afterClassIfNeeded(); @@ -242,22 +244,24 @@ public class InterrogationActivityTest getActivity(); // find a view and make sure it is not focused - AccessibilityNodeInfo button = - getConnection().findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5); + AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance() + .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5); assertFalse(button.isFocused()); // focus the view assertTrue(button.performAction(ACTION_FOCUS)); // find the view again and make sure it is focused - button = getConnection().findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5); + button = AccessibilityInteractionClient.getInstance() + .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5); assertTrue(button.isFocused()); // unfocus the view assertTrue(button.performAction(ACTION_CLEAR_FOCUS)); // find the view again and make sure it is not focused - button = getConnection().findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5); + button = AccessibilityInteractionClient.getInstance() + .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5); assertFalse(button.isFocused()); } finally { afterClassIfNeeded(); @@ -278,15 +282,16 @@ public class InterrogationActivityTest getActivity(); // find a view and make sure it is not selected - AccessibilityNodeInfo button = - getConnection().findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5); + AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance() + .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5); assertFalse(button.isSelected()); // select the view assertTrue(button.performAction(ACTION_SELECT)); // find the view again and make sure it is selected - button = getConnection().findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5); + button = AccessibilityInteractionClient.getInstance() + .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5); assertTrue(button.isSelected()); } finally { afterClassIfNeeded(); @@ -306,22 +311,24 @@ public class InterrogationActivityTest getActivity(); // find a view and make sure it is not selected - AccessibilityNodeInfo button = - getConnection().findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5); + AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance() + .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5); assertFalse(button.isSelected()); // select the view assertTrue(button.performAction(ACTION_SELECT)); // find the view again and make sure it is selected - button = getConnection().findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5); + button = AccessibilityInteractionClient.getInstance() + .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5); assertTrue(button.isSelected()); // unselect the view assertTrue(button.performAction(ACTION_CLEAR_SELECTION)); // find the view again and make sure it is not selected - button = getConnection().findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5); + button = AccessibilityInteractionClient.getInstance() + .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5); assertFalse(button.isSelected()); } finally { afterClassIfNeeded(); @@ -342,8 +349,8 @@ public class InterrogationActivityTest getActivity(); // find a view and make sure it is not focused - AccessibilityNodeInfo button = - getConnection().findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5); + AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance() + .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5); assertFalse(button.isSelected()); // focus the view @@ -406,8 +413,8 @@ public class InterrogationActivityTest getActivity(); // find a view and make sure it is not focused - AccessibilityNodeInfo button = - getConnection().findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5); + AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance() + .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5); AccessibilityNodeInfo parent = button.getParent(); final int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { |