diff options
author | Svetoslav Ganov <svetoslavganov@google.com> | 2012-01-30 16:37:33 -0800 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-01-30 16:37:33 -0800 |
commit | 12df3cf156885a421beccfa6b6e20fd1a188847a (patch) | |
tree | b72fe4d32ebffbadf5006e525a1027aeb3c380fb /core/tests | |
parent | f68af846d472e59f1a8280f250a1f0b9ac13abd9 (diff) | |
parent | c6fd88e213703a581fe4680259981f09ae0444f2 (diff) | |
download | frameworks_base-12df3cf156885a421beccfa6b6e20fd1a188847a.zip frameworks_base-12df3cf156885a421beccfa6b6e20fd1a188847a.tar.gz frameworks_base-12df3cf156885a421beccfa6b6e20fd1a188847a.tar.bz2 |
Merge "Incorrect behavior of View clear focus."
Diffstat (limited to 'core/tests')
-rw-r--r-- | core/tests/coretests/src/android/widget/focus/RequestFocus.java | 2 | ||||
-rw-r--r-- | core/tests/coretests/src/android/widget/focus/RequestFocusTest.java | 161 |
2 files changed, 154 insertions, 9 deletions
diff --git a/core/tests/coretests/src/android/widget/focus/RequestFocus.java b/core/tests/coretests/src/android/widget/focus/RequestFocus.java index af9ee17..21d762a 100644 --- a/core/tests/coretests/src/android/widget/focus/RequestFocus.java +++ b/core/tests/coretests/src/android/widget/focus/RequestFocus.java @@ -21,9 +21,7 @@ import com.android.frameworks.coretests.R; import android.app.Activity; import android.os.Bundle; import android.os.Handler; -import android.widget.LinearLayout; import android.widget.Button; -import android.view.View; /** * Exercises cases where elements of the UI are requestFocus()ed. diff --git a/core/tests/coretests/src/android/widget/focus/RequestFocusTest.java b/core/tests/coretests/src/android/widget/focus/RequestFocusTest.java index a78b0c9..baf587e 100644 --- a/core/tests/coretests/src/android/widget/focus/RequestFocusTest.java +++ b/core/tests/coretests/src/android/widget/focus/RequestFocusTest.java @@ -16,21 +16,27 @@ package android.widget.focus; -import android.widget.focus.RequestFocus; -import com.android.frameworks.coretests.R; - import android.os.Handler; -import android.test.ActivityInstrumentationTestCase; +import android.test.ActivityInstrumentationTestCase2; +import android.test.UiThreadTest; import android.test.suitebuilder.annotation.LargeTest; import android.test.suitebuilder.annotation.MediumTest; -import android.widget.Button; import android.util.AndroidRuntimeException; +import android.view.View; +import android.view.View.OnFocusChangeListener; +import android.view.ViewTreeObserver.OnGlobalFocusChangeListener; +import android.widget.Button; + +import com.android.frameworks.coretests.R; + +import java.util.ArrayList; +import java.util.List; /** * {@link RequestFocusTest} is set up to exercise cases where the views that * have focus become invisible or GONE. */ -public class RequestFocusTest extends ActivityInstrumentationTestCase<RequestFocus> { +public class RequestFocusTest extends ActivityInstrumentationTestCase2<RequestFocus> { private Button mTopLeftButton; private Button mBottomLeftButton; @@ -39,7 +45,7 @@ public class RequestFocusTest extends ActivityInstrumentationTestCase<RequestFoc private Handler mHandler; public RequestFocusTest() { - super("com.android.frameworks.coretests", RequestFocus.class); + super(RequestFocus.class); } @Override @@ -94,4 +100,145 @@ public class RequestFocusTest extends ActivityInstrumentationTestCase<RequestFoc e.getClass().getName()); } } + + /** + * This tests checks the case in which the first focusable View clears focus. + * In such a case the framework tries to give the focus to another View starting + * from the top. Hence, the framework will try to give focus to the view that + * wants to clear its focus. From a client perspective, the view does not loose + * focus after the call, therefore no callback for focus change should be invoked. + * + * @throws Exception If an error occurs. + */ + @UiThreadTest + public void testOnFocusChangeNotCalledIfFocusDoesNotMove() throws Exception { + // Get the first focusable. + Button button = mTopLeftButton; + + // Make sure that the button is the first focusable and focus it. + button.getRootView().requestFocus(View.FOCUS_DOWN); + assertTrue(button.hasFocus()); + + // Attach on focus change listener that should not be called. + button.setOnFocusChangeListener(new OnFocusChangeListener() { + @Override + public void onFocusChange(View v, boolean hasFocus) { + throw new IllegalStateException("Unexpeced call to" + + "OnFocusChangeListener#onFocusChange"); + } + }); + + // Attach on global focus change listener that should not be called. + button.getViewTreeObserver().addOnGlobalFocusChangeListener( + new OnGlobalFocusChangeListener() { + @Override + public void onGlobalFocusChanged(View oldFocus, View newFocus) { + throw new IllegalStateException("Unexpeced call to" + + "OnFocusChangeListener#onFocusChange"); + } + }); + + // Try to clear focus. + button.clearFocus(); + } + + /** + * This tests check whether the on focus change callbacks are invoked in + * the proper order when a View loses focus and the framework gives it to + * the fist focusable one. + * + * @throws Exception + */ + @UiThreadTest + public void testOnFocusChangeCallbackOrder() throws Exception { + // Get the first focusable. + Button clearingFocusButton = mTopRightButton; + Button gainingFocusButton = mTopLeftButton; + + // Make sure that the clearing focus is not the first focusable. + View focusCandidate = clearingFocusButton.getRootView().getParent().focusSearch(null, + View.FOCUS_FORWARD); + assertNotSame("The clearing focus button is not the first focusable.", + clearingFocusButton, focusCandidate); + assertSame("The gaining focus button is the first focusable.", + gainingFocusButton, focusCandidate); + + // Focus the clearing focus button. + clearingFocusButton.requestFocus(); + assertTrue(clearingFocusButton.hasFocus()); + + // Register the invocation order checker. + CallbackOrderChecker checker = new CallbackOrderChecker(clearingFocusButton, + gainingFocusButton); + clearingFocusButton.setOnFocusChangeListener(checker); + gainingFocusButton.setOnFocusChangeListener(checker); + clearingFocusButton.getViewTreeObserver().addOnGlobalFocusChangeListener(checker); + + // Try to clear focus. + clearingFocusButton.clearFocus(); + + // Check that no callback was invoked since focus did not move. + checker.verify(); + } + + /** + * This class check whether the focus change callback are invoked in order. + */ + private class CallbackOrderChecker implements OnFocusChangeListener, + OnGlobalFocusChangeListener { + + private class CallbackInvocation { + final String mMethodName; + final Object[] mArguments; + + CallbackInvocation(String methodName, Object[] arguments) { + mMethodName = methodName; + mArguments = arguments; + } + } + + private final View mClearingFocusView; + private final View mGainingFocusView; + + private final List<CallbackInvocation> mInvocations = new ArrayList<CallbackInvocation>(); + + public CallbackOrderChecker(View clearingFocusView, View gainingFocusView) { + mClearingFocusView = clearingFocusView; + mGainingFocusView = gainingFocusView; + } + + @Override + public void onFocusChange(View view, boolean hasFocus) { + CallbackInvocation invocation = new CallbackInvocation( + "OnFocusChangeListener#onFocusChange", new Object[] {view, hasFocus}); + mInvocations.add(invocation); + } + + @Override + public void onGlobalFocusChanged(View oldFocus, View newFocus) { + CallbackInvocation invocation = new CallbackInvocation( + "OnFocusChangeListener#onFocusChange", new Object[] {oldFocus, newFocus}); + mInvocations.add(invocation); + } + + public void verify() { + assertSame("All focus change callback should be invoked.", 3, mInvocations.size()); + assertInvioked("Callback for View clearing focus explected.", 0, + "OnFocusChangeListener#onFocusChange", + new Object[] {mClearingFocusView, false}); + assertInvioked("Callback for View global focus change explected.", 1, + "OnFocusChangeListener#onFocusChange", new Object[] {mClearingFocusView, + mGainingFocusView}); + assertInvioked("Callback for View gaining focus explected.", 2, + "OnFocusChangeListener#onFocusChange", new Object[] {mGainingFocusView, true}); + } + + private void assertInvioked(String message, int order, String methodName, + Object[] arguments) { + CallbackInvocation invocation = mInvocations.get(order); + assertEquals(message, methodName, invocation.mMethodName); + assertEquals(message, arguments[0], invocation.mArguments[0]); + assertEquals(message, arguments[1], invocation.mArguments[1]); + } + } } |