From 28d5d220cc66eb4263aaae083a8496950258642b Mon Sep 17 00:00:00 2001 From: Jason Monk Date: Thu, 2 Feb 2017 13:08:31 -0500 Subject: [PATCH] Switch fragment tests to use TestableLooper Test: runtest systemui Change-Id: Iccbbaca2ef02cb3f5b08eef66c6c939e4ec2a5eb --- .../android/systemui/FragmentTestCase.java | 99 +++++++++++-------- .../android/systemui/qs/QSFragmentTest.java | 26 +++-- .../statusbar/NotificationMenuRowTest.java | 8 ++ .../phone/CollapsedStatusBarFragmentTest.java | 14 ++- .../phone/NavigationBarFragmentTest.java | 8 +- .../com/android/systemui/utils/ViewUtils.java | 2 - 6 files changed, 99 insertions(+), 58 deletions(-) diff --git a/packages/SystemUI/tests/src/com/android/systemui/FragmentTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/FragmentTestCase.java index f8f67bb15c29c..1678d92326529 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/FragmentTestCase.java +++ b/packages/SystemUI/tests/src/com/android/systemui/FragmentTestCase.java @@ -29,6 +29,7 @@ import android.view.WindowManager; import android.view.WindowManager.LayoutParams; import android.widget.FrameLayout; +import com.android.systemui.utils.TestableLooper; import com.android.systemui.utils.ViewUtils; import com.android.systemui.utils.leaks.LeakCheckedTest; @@ -59,12 +60,14 @@ public abstract class FragmentTestCase extends LeakCheckedTest { } @Before - public void setupFragment() throws IllegalAccessException, InstantiationException { + public void setupFragment() throws Exception { mView = new FrameLayout(mContext); mView.setId(VIEW_ID); - mHandler = new Handler(Looper.getMainLooper()); - mFragment = mCls.newInstance(); - postAndWait(() -> { + + TestableLooper.get(this).runWithLooper(() -> { + mHandler = new Handler(); + + mFragment = mCls.newInstance(); mFragments = FragmentController.createController(new HostCallbacks()); mFragments.attachHost(null); mFragments.getFragmentManager().beginTransaction() @@ -73,30 +76,39 @@ public abstract class FragmentTestCase extends LeakCheckedTest { }); } + private String hex(Looper looper) { + return Integer.toHexString(System.identityHashCode(looper)); + } + @After - public void tearDown() { + public void tearDown() throws Exception { if (mFragments != null) { // Set mFragments to null to let it know not to destroy. - postAndWait(() -> mFragments.dispatchDestroy()); + TestableLooper.get(this).runWithLooper(() -> mFragments.dispatchDestroy()); } } @Test public void testCreateDestroy() { - postAndWait(() -> mFragments.dispatchCreate()); + mFragments.dispatchCreate(); + processAllMessages(); destroyFragments(); } @Test public void testStartStop() { - postAndWait(() -> mFragments.dispatchStart()); - postAndWait(() -> mFragments.dispatchStop()); + mFragments.dispatchStart(); + processAllMessages(); + mFragments.dispatchStop(); + processAllMessages(); } @Test public void testResumePause() { - postAndWait(() -> mFragments.dispatchResume()); - postAndWait(() -> mFragments.dispatchPause()); + mFragments.dispatchResume(); + processAllMessages(); + mFragments.dispatchPause(); + processAllMessages(); } @Test @@ -105,54 +117,57 @@ public abstract class FragmentTestCase extends LeakCheckedTest { LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, LayoutParams.TYPE_SYSTEM_ALERT, 0, PixelFormat.TRANSLUCENT); - postAndWait(() -> mFragments.dispatchResume()); + mFragments.dispatchResume(); + processAllMessages(); attachFragmentToWindow(); detachFragmentToWindow(); - postAndWait(() -> mFragments.dispatchPause()); - } - - protected void attachFragmentToWindow() { - ViewUtils.attachView(mView); - } - - protected void detachFragmentToWindow() { - ViewUtils.detachView(mView); + mFragments.dispatchPause(); + processAllMessages(); } @Test public void testRecreate() { - postAndWait(() -> mFragments.dispatchResume()); - postAndWait(() -> { - mFragments.dispatchPause(); - Parcelable p = mFragments.saveAllState(); - mFragments.dispatchDestroy(); + mFragments.dispatchResume(); + processAllMessages(); + mFragments.dispatchPause(); + Parcelable p = mFragments.saveAllState(); + mFragments.dispatchDestroy(); - mFragments = FragmentController.createController(new HostCallbacks()); - mFragments.attachHost(null); - mFragments.restoreAllState(p, (FragmentManagerNonConfig) null); - mFragments.dispatchResume(); - }); + mFragments = FragmentController.createController(new HostCallbacks()); + mFragments.attachHost(null); + mFragments.restoreAllState(p, (FragmentManagerNonConfig) null); + mFragments.dispatchResume(); + processAllMessages(); } @Test public void testMultipleResumes() { - postAndWait(() -> mFragments.dispatchResume()); - postAndWait(() -> mFragments.dispatchStop()); - postAndWait(() -> mFragments.dispatchResume()); + mFragments.dispatchResume(); + processAllMessages(); + mFragments.dispatchStop(); + processAllMessages(); + mFragments.dispatchResume(); + processAllMessages(); + } + + protected void attachFragmentToWindow() { + ViewUtils.attachView(mView); + TestableLooper.get(this).processMessages(1); + } + + protected void detachFragmentToWindow() { + ViewUtils.detachView(mView); + TestableLooper.get(this).processMessages(1); } protected void destroyFragments() { - postAndWait(() -> mFragments.dispatchDestroy()); + mFragments.dispatchDestroy(); + processAllMessages(); mFragments = null; } - protected void postAndWait(Runnable r) { - mHandler.post(r); - waitForFragments(); - } - - protected void waitForFragments() { - waitForIdleSync(mHandler); + protected void processAllMessages() { + TestableLooper.get(this).processAllMessages(); } private View findViewById(int id) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java index 9eac0a0d8b041..e7fa7998350db 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java @@ -14,17 +14,23 @@ package com.android.systemui.qs; +import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; +import android.os.Looper; + import com.android.systemui.Dependency; import com.android.systemui.FragmentTestCase; import com.android.systemui.R; +import com.android.systemui.SysUIRunner; import com.android.systemui.statusbar.phone.QSTileHost; import com.android.systemui.statusbar.phone.QuickStatusBarHeader; import com.android.systemui.statusbar.phone.StatusBarIconController; import com.android.systemui.statusbar.policy.UserSwitcherController; import com.android.systemui.tuner.TunerService; import com.android.systemui.util.LayoutInflaterBuilder; +import com.android.systemui.utils.TestableLooper; +import com.android.systemui.utils.TestableLooper.RunWithLooper; import org.junit.Before; import org.junit.Test; @@ -37,7 +43,8 @@ import android.support.test.runner.AndroidJUnit4; import android.view.View; import android.widget.FrameLayout; -@RunWith(AndroidJUnit4.class) +@RunWith(SysUIRunner.class) +@RunWithLooper(setAsMainLooper = true) public class QSFragmentTest extends FragmentTestCase { public QSFragmentTest() { @@ -53,32 +60,31 @@ public class QSFragmentTest extends FragmentTestCase { .replace("TextClock", View.class) .build()); - injectTestDependency(Dependency.BG_LOOPER, Looper.getMainLooper()); + injectTestDependency(Dependency.BG_LOOPER, TestableLooper.get(this).getLooper()); injectMockDependency(UserSwitcherController.class); injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES); } @Test public void testListening() { + assertEquals(Looper.myLooper(), Looper.getMainLooper()); QSFragment qs = (QSFragment) mFragment; - postAndWait(() -> mFragments.dispatchResume()); - QSTileHost host = new QSTileHost(mContext, null, - mock(StatusBarIconController.class)); + mFragments.dispatchResume(); + processAllMessages(); + QSTileHost host = new QSTileHost(mContext, null, mock(StatusBarIconController.class)); qs.setHost(host); - Handler h = new Handler((Looper) Dependency.get(Dependency.BG_LOOPER)); qs.setListening(true); - waitForIdleSync(h); + processAllMessages(); qs.setListening(false); - waitForIdleSync(h); + processAllMessages(); // Manually push header through detach so it can handle standard cleanup it does on // removed from window. ((QuickStatusBarHeader) qs.getView().findViewById(R.id.header)).onDetachedFromWindow(); host.destroy(); - // Ensure the tuner cleans up its persistent listeners. - Dependency.get(TunerService.class).destroy(); + processAllMessages(); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java index 71411706c4a9d..72f6ca8ec7304 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java @@ -14,12 +14,18 @@ package com.android.systemui.statusbar; +import com.android.systemui.SysUIRunner; +import com.android.systemui.utils.TestableLooper; +import com.android.systemui.utils.TestableLooper.RunWithLooper; import com.android.systemui.utils.ViewUtils; import com.android.systemui.utils.leaks.LeakCheckedTest; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; +@RunWith(SysUIRunner.class) +@RunWithLooper public class NotificationMenuRowTest extends LeakCheckedTest { @Before @@ -31,6 +37,8 @@ public class NotificationMenuRowTest extends LeakCheckedTest { public void testAttachDetach() { NotificationMenuRow row = new NotificationMenuRow(mContext); ViewUtils.attachView(row); + TestableLooper.get(this).processAllMessages(); ViewUtils.detachView(row); + TestableLooper.get(this).processAllMessages(); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java index cb30df4b2f9d8..f55115e005b2d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java @@ -25,16 +25,21 @@ import android.view.ViewPropertyAnimator; import com.android.systemui.FragmentTestCase; import com.android.systemui.R; +import com.android.systemui.SysUIRunner; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.policy.KeyguardMonitor; import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.statusbar.policy.SecurityController; import com.android.systemui.tuner.TunerService; +import com.android.systemui.utils.TestableLooper.RunWithLooper; import org.junit.Before; +import org.junit.runner.RunWith; import org.junit.Test; import org.mockito.Mockito; +@RunWith(SysUIRunner.class) +@RunWithLooper(setAsMainLooper = true) public class CollapsedStatusBarFragmentTest extends FragmentTestCase { private NotificationIconAreaController mMockNotificiationAreaController; @@ -59,7 +64,8 @@ public class CollapsedStatusBarFragmentTest extends FragmentTestCase { @Test public void testDisableNone() throws Exception { - postAndWait(() -> mFragments.dispatchResume()); + mFragments.dispatchResume(); + processAllMessages(); CollapsedStatusBarFragment fragment = (CollapsedStatusBarFragment) mFragment; fragment.initNotificationIconArea(mMockNotificiationAreaController); @@ -71,7 +77,8 @@ public class CollapsedStatusBarFragmentTest extends FragmentTestCase { @Test public void testDisableSystemInfo() throws Exception { - postAndWait(() -> mFragments.dispatchResume()); + mFragments.dispatchResume(); + processAllMessages(); CollapsedStatusBarFragment fragment = (CollapsedStatusBarFragment) mFragment; fragment.initNotificationIconArea(mMockNotificiationAreaController); @@ -88,7 +95,8 @@ public class CollapsedStatusBarFragmentTest extends FragmentTestCase { @Test public void testDisableNotifications() throws Exception { - postAndWait(() -> mFragments.dispatchResume()); + mFragments.dispatchResume(); + processAllMessages(); CollapsedStatusBarFragment fragment = (CollapsedStatusBarFragment) mFragment; fragment.initNotificationIconArea(mMockNotificiationAreaController); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java index 3bce64fe1f202..1fa98461d02d5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java @@ -24,13 +24,18 @@ import android.view.WindowManager; import com.android.systemui.Dependency; import com.android.systemui.FragmentTestCase; +import com.android.systemui.SysUIRunner; import com.android.systemui.recents.Recents; import com.android.systemui.stackdivider.Divider; import com.android.systemui.statusbar.CommandQueue; +import com.android.systemui.utils.TestableLooper.RunWithLooper; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; +@RunWith(SysUIRunner.class) +@RunWithLooper(setAsMainLooper = true) public class NavigationBarFragmentTest extends FragmentTestCase { public NavigationBarFragmentTest() { @@ -56,7 +61,8 @@ public class NavigationBarFragmentTest extends FragmentTestCase { public void testHomeLongPress() { NavigationBarFragment navigationBarFragment = (NavigationBarFragment) mFragment; - postAndWait(() -> mFragments.dispatchResume()); + mFragments.dispatchResume(); + processAllMessages(); navigationBarFragment.onHomeLongClick(navigationBarFragment.getView()); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/ViewUtils.java b/packages/SystemUI/tests/src/com/android/systemui/utils/ViewUtils.java index 202c4cfda7825..07e5f6663a3f2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/ViewUtils.java +++ b/packages/SystemUI/tests/src/com/android/systemui/utils/ViewUtils.java @@ -34,13 +34,11 @@ public class ViewUtils { Handler handler = new Handler(Looper.getMainLooper()); handler.post(() -> InstrumentationRegistry.getContext() .getSystemService(WindowManager.class).addView(view, lp)); - SysuiTestCase.waitForIdleSync(handler); } public static void detachView(View view) { Handler handler = new Handler(Looper.getMainLooper()); handler.post(() -> InstrumentationRegistry.getContext() .getSystemService(WindowManager.class).removeView(view)); - SysuiTestCase.waitForIdleSync(handler); } }