Commit 92bfb8c2 authored by Wenyu Fu's avatar Wenyu Fu Committed by Commit Bot

[CCTToSFRE] Add a11y support for loading spinner

Add the content description for the loading spinner so that the screen
reader can read out the loading status correctly.

Change-Id: Ifa46b4b1c2d8255a592751132d56f66edb8b1257
Bug: 1119587
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2368445
Commit-Queue: Wenyu Fu <wenyufu@chromium.org>
Reviewed-by: default avatarSky Malice <skym@chromium.org>
Reviewed-by: default avatarTheresa  <twellington@chromium.org>
Cr-Commit-Position: refs/heads/master@{#805951}
parent bbc08d6a
...@@ -46,13 +46,26 @@ ...@@ -46,13 +46,26 @@
android:text="@string/fre_welcome" android:text="@string/fre_welcome"
style="@style/FreTitle" /> style="@style/FreTitle" />
<org.chromium.components.browser_ui.widget.LoadingView <!-- The FrameLayout here is to facilitate adding a proper content description for
android:id="@+id/progress_spinner_large" the loading view. During development, it didn't seem possible to override the
style="@style/Widget.AppCompat.ProgressBar" LoadingView contentDescription in XML, but if there's support for this at some
point then we can remove the FrameLayout. -->
<FrameLayout
android:id="@+id/loading_view_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:layout_height="@dimen/fre_loading_spinner_size" android:visibility="gone"
android:layout_width="@dimen/fre_loading_spinner_size" android:contentDescription="@string/sync_loading">
android:visibility="gone"/>
<org.chromium.components.browser_ui.widget.LoadingView
android:id="@+id/progress_spinner_large"
style="@style/Widget.AppCompat.ProgressBar"
android:layout_height="@dimen/fre_loading_spinner_size"
android:layout_width="@dimen/fre_loading_spinner_size"
android:visibility="gone"/>
</FrameLayout>
<LinearLayout <LinearLayout
android:id="@+id/fre_content_wrapper" android:id="@+id/fre_content_wrapper"
......
...@@ -201,6 +201,10 @@ public class ToSAndUMAFirstRunFragment extends Fragment implements FirstRunFragm ...@@ -201,6 +201,10 @@ public class ToSAndUMAFirstRunFragment extends Fragment implements FirstRunFragm
} }
} }
protected View getToSAndPrivacyText() {
return mTosAndPrivacy;
}
/** /**
* @return Whether the check box for Uma metrics can be shown. It should be used in conjunction * @return Whether the check box for Uma metrics can be shown. It should be used in conjunction
* with whether other non-spinner elements can generally be shown. * with whether other non-spinner elements can generally be shown.
......
...@@ -8,6 +8,7 @@ import android.content.Context; ...@@ -8,6 +8,7 @@ import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.os.SystemClock; import android.os.SystemClock;
import android.view.View; import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
...@@ -46,6 +47,7 @@ public class TosAndUmaFirstRunFragmentWithEnterpriseSupport ...@@ -46,6 +47,7 @@ public class TosAndUmaFirstRunFragmentWithEnterpriseSupport
} }
private boolean mViewCreated; private boolean mViewCreated;
private View mLoadingSpinnerContainer;
private LoadingView mLoadingSpinner; private LoadingView mLoadingSpinner;
private CallbackController mCallbackController; private CallbackController mCallbackController;
private PolicyService.Observer mPolicyServiceObserver; private PolicyService.Observer mPolicyServiceObserver;
...@@ -109,6 +111,7 @@ public class TosAndUmaFirstRunFragmentWithEnterpriseSupport ...@@ -109,6 +111,7 @@ public class TosAndUmaFirstRunFragmentWithEnterpriseSupport
public void onViewCreated(View view, Bundle savedInstanceState) { public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState); super.onViewCreated(view, savedInstanceState);
mLoadingSpinnerContainer = view.findViewById(R.id.loading_view_container);
mLoadingSpinner = view.findViewById(R.id.progress_spinner_large); mLoadingSpinner = view.findViewById(R.id.progress_spinner_large);
mViewCreated = true; mViewCreated = true;
mViewCreatedTimeMs = SystemClock.elapsedRealtime(); mViewCreatedTimeMs = SystemClock.elapsedRealtime();
...@@ -137,6 +140,11 @@ public class TosAndUmaFirstRunFragmentWithEnterpriseSupport ...@@ -137,6 +140,11 @@ public class TosAndUmaFirstRunFragmentWithEnterpriseSupport
return super.canShowUmaCheckBox() && confirmedToShowUmaAndTos(); return super.canShowUmaCheckBox() && confirmedToShowUmaAndTos();
} }
@Override
public void onShowLoadingUIComplete() {
mLoadingSpinnerContainer.setVisibility(View.VISIBLE);
}
@Override @Override
public void onHideLoadingUIComplete() { public void onHideLoadingUIComplete() {
RecordHistogram.recordTimesHistogram("MobileFre.CctTos.LoadingDuration", RecordHistogram.recordTimesHistogram("MobileFre.CctTos.LoadingDuration",
...@@ -147,7 +155,14 @@ public class TosAndUmaFirstRunFragmentWithEnterpriseSupport ...@@ -147,7 +155,14 @@ public class TosAndUmaFirstRunFragmentWithEnterpriseSupport
} else { } else {
// Else, show the UMA as the loading spinner is GONE. // Else, show the UMA as the loading spinner is GONE.
assert confirmedToShowUmaAndTos(); assert confirmedToShowUmaAndTos();
boolean hasAccessibilityFocus = mLoadingSpinnerContainer.isAccessibilityFocused();
mLoadingSpinnerContainer.setVisibility(View.GONE);
setTosAndUmaVisible(true); setTosAndUmaVisible(true);
if (hasAccessibilityFocus) {
getToSAndPrivacyText().sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
}
} }
} }
......
...@@ -36,7 +36,7 @@ public class TosAndUmaFragmentView extends FrameLayout { ...@@ -36,7 +36,7 @@ public class TosAndUmaFragmentView extends FrameLayout {
private View mTitle; private View mTitle;
private View mLogo; private View mLogo;
private View mLoadingSpinner; private View mLoadingSpinnerContainer;
private View mShadow; private View mShadow;
private int mLastHeight; private int mLastHeight;
...@@ -72,7 +72,7 @@ public class TosAndUmaFragmentView extends FrameLayout { ...@@ -72,7 +72,7 @@ public class TosAndUmaFragmentView extends FrameLayout {
mTitle = findViewById(R.id.title); mTitle = findViewById(R.id.title);
mLogo = findViewById(R.id.image); mLogo = findViewById(R.id.image);
mLoadingSpinner = findViewById(R.id.progress_spinner_large); mLoadingSpinnerContainer = findViewById(R.id.loading_view_container);
mShadow = findViewById(R.id.shadow); mShadow = findViewById(R.id.shadow);
// Set up shadow. // Set up shadow.
...@@ -146,7 +146,7 @@ public class TosAndUmaFragmentView extends FrameLayout { ...@@ -146,7 +146,7 @@ public class TosAndUmaFragmentView extends FrameLayout {
private void setSpinnerLayoutParams(boolean useWideScreen, int width, int height) { private void setSpinnerLayoutParams(boolean useWideScreen, int width, int height) {
LinearLayout.LayoutParams spinnerParams = LinearLayout.LayoutParams spinnerParams =
(LinearLayout.LayoutParams) mLoadingSpinner.getLayoutParams(); (LinearLayout.LayoutParams) mLoadingSpinnerContainer.getLayoutParams();
// Adjust the spinner placement. If in portrait mode, the spinner is centered in the region // Adjust the spinner placement. If in portrait mode, the spinner is centered in the region
// below the title; If in wide screen mode, the spinner is placed in the center of // below the title; If in wide screen mode, the spinner is placed in the center of
...@@ -175,7 +175,7 @@ public class TosAndUmaFragmentView extends FrameLayout { ...@@ -175,7 +175,7 @@ public class TosAndUmaFragmentView extends FrameLayout {
spinnerParams.topMargin = spinnerTopMargin; spinnerParams.topMargin = spinnerTopMargin;
} }
mLoadingSpinner.setLayoutParams(spinnerParams); mLoadingSpinnerContainer.setLayoutParams(spinnerParams);
} }
private void setLogoLayoutParams(boolean useWideScreen, int height) { private void setLogoLayoutParams(boolean useWideScreen, int height) {
......
...@@ -144,7 +144,7 @@ public class TosAndUmaFirstRunFragmentWithEnterpriseSupportTest { ...@@ -144,7 +144,7 @@ public class TosAndUmaFirstRunFragmentWithEnterpriseSupportTest {
launchFirstRunThroughCustomTab(); launchFirstRunThroughCustomTab();
assertUIState(FragmentState.LOADING); assertUIState(FragmentState.LOADING);
setAppRestrictiosnMockInitialized(false); setAppRestrictionsMockInitialized(false);
assertUIState(FragmentState.NO_POLICY); assertUIState(FragmentState.NO_POLICY);
Assert.assertEquals(1, Assert.assertEquals(1,
...@@ -157,7 +157,7 @@ public class TosAndUmaFirstRunFragmentWithEnterpriseSupportTest { ...@@ -157,7 +157,7 @@ public class TosAndUmaFirstRunFragmentWithEnterpriseSupportTest {
// TODO(crbug.com/1120859): Test the policy check when native initializes before inflation. // TODO(crbug.com/1120859): Test the policy check when native initializes before inflation.
// This will be possible when FragmentScenario is available. // This will be possible when FragmentScenario is available.
public void testDialogEnabled() { public void testDialogEnabled() {
setAppRestrictiosnMockInitialized(true); setAppRestrictionsMockInitialized(true);
launchFirstRunThroughCustomTab(); launchFirstRunThroughCustomTab();
assertUIState(FragmentState.LOADING); assertUIState(FragmentState.LOADING);
...@@ -174,7 +174,7 @@ public class TosAndUmaFirstRunFragmentWithEnterpriseSupportTest { ...@@ -174,7 +174,7 @@ public class TosAndUmaFirstRunFragmentWithEnterpriseSupportTest {
@Test @Test
@SmallTest @SmallTest
public void testNotOwnedDevice() { public void testNotOwnedDevice() {
setAppRestrictiosnMockInitialized(true); setAppRestrictionsMockInitialized(true);
launchFirstRunThroughCustomTab(); launchFirstRunThroughCustomTab();
assertUIState(FragmentState.LOADING); assertUIState(FragmentState.LOADING);
...@@ -191,7 +191,7 @@ public class TosAndUmaFirstRunFragmentWithEnterpriseSupportTest { ...@@ -191,7 +191,7 @@ public class TosAndUmaFirstRunFragmentWithEnterpriseSupportTest {
@Test @Test
@SmallTest @SmallTest
public void testNotOwnedDevice_beforeInflation() { public void testNotOwnedDevice_beforeInflation() {
setAppRestrictiosnMockInitialized(true); setAppRestrictionsMockInitialized(true);
setEnterpriseInfoInitializedWithDeviceOwner(false); setEnterpriseInfoInitializedWithDeviceOwner(false);
launchFirstRunThroughCustomTab(); launchFirstRunThroughCustomTab();
...@@ -208,7 +208,7 @@ public class TosAndUmaFirstRunFragmentWithEnterpriseSupportTest { ...@@ -208,7 +208,7 @@ public class TosAndUmaFirstRunFragmentWithEnterpriseSupportTest {
@Test @Test
@SmallTest @SmallTest
public void testSkip_DeviceOwnedThenDialogPolicy() { public void testSkip_DeviceOwnedThenDialogPolicy() {
setAppRestrictiosnMockInitialized(true); setAppRestrictionsMockInitialized(true);
launchFirstRunThroughCustomTab(); launchFirstRunThroughCustomTab();
assertUIState(FragmentState.LOADING); assertUIState(FragmentState.LOADING);
...@@ -232,7 +232,7 @@ public class TosAndUmaFirstRunFragmentWithEnterpriseSupportTest { ...@@ -232,7 +232,7 @@ public class TosAndUmaFirstRunFragmentWithEnterpriseSupportTest {
@Test @Test
@SmallTest @SmallTest
public void testSkip_DialogPolicyThenDeviceOwned() { public void testSkip_DialogPolicyThenDeviceOwned() {
setAppRestrictiosnMockInitialized(true); setAppRestrictionsMockInitialized(true);
launchFirstRunThroughCustomTab(); launchFirstRunThroughCustomTab();
assertUIState(FragmentState.LOADING); assertUIState(FragmentState.LOADING);
...@@ -267,7 +267,7 @@ public class TosAndUmaFirstRunFragmentWithEnterpriseSupportTest { ...@@ -267,7 +267,7 @@ public class TosAndUmaFirstRunFragmentWithEnterpriseSupportTest {
assertUIState(FragmentState.HAS_POLICY); assertUIState(FragmentState.HAS_POLICY);
// assertUIState will verify that exit was not called a second time. // assertUIState will verify that exit was not called a second time.
setAppRestrictiosnMockInitialized(true); setAppRestrictionsMockInitialized(true);
assertUIState(FragmentState.HAS_POLICY); assertUIState(FragmentState.HAS_POLICY);
Assert.assertEquals(1, Assert.assertEquals(1,
...@@ -284,7 +284,7 @@ public class TosAndUmaFirstRunFragmentWithEnterpriseSupportTest { ...@@ -284,7 +284,7 @@ public class TosAndUmaFirstRunFragmentWithEnterpriseSupportTest {
@Test @Test
@SmallTest @SmallTest
public void testNullOwnedState() { public void testNullOwnedState() {
setAppRestrictiosnMockInitialized(true); setAppRestrictionsMockInitialized(true);
setPolicyServiceMockInitializedWithDialogEnabled(false); setPolicyServiceMockInitializedWithDialogEnabled(false);
launchFirstRunThroughCustomTab(); launchFirstRunThroughCustomTab();
assertUIState(FragmentState.LOADING); assertUIState(FragmentState.LOADING);
...@@ -367,7 +367,7 @@ public class TosAndUmaFirstRunFragmentWithEnterpriseSupportTest { ...@@ -367,7 +367,7 @@ public class TosAndUmaFirstRunFragmentWithEnterpriseSupportTest {
.getHasAppRestriction(any()); .getHasAppRestriction(any());
} }
private void setAppRestrictiosnMockInitialized(boolean hasAppRestrictons) { private void setAppRestrictionsMockInitialized(boolean hasAppRestrictons) {
Mockito.doAnswer(invocation -> { Mockito.doAnswer(invocation -> {
Callback<Boolean> callback = invocation.getArgument(0); Callback<Boolean> callback = invocation.getArgument(0);
callback.onResult(hasAppRestrictons); callback.onResult(hasAppRestrictons);
......
...@@ -30,6 +30,12 @@ public class LoadingView extends ProgressBar { ...@@ -30,6 +30,12 @@ public class LoadingView extends ProgressBar {
* A observer interface that will be notified when the progress bar is hidden. * A observer interface that will be notified when the progress bar is hidden.
*/ */
public interface Observer { public interface Observer {
/**
* Notify the listener a call to {@link #showLoadingUI()} is complete and loading view
* is VISIBLE.
*/
void onShowLoadingUIComplete();
/** /**
* Notify the listener a call to {@link #hideLoadingUI()} is complete and loading view is * Notify the listener a call to {@link #hideLoadingUI()} is complete and loading view is
* GONE. * GONE.
...@@ -40,7 +46,7 @@ public class LoadingView extends ProgressBar { ...@@ -40,7 +46,7 @@ public class LoadingView extends ProgressBar {
private long mStartTime = -1; private long mStartTime = -1;
private boolean mDisableAnimationForTest; private boolean mDisableAnimationForTest;
private final List<Observer> mListeners = new ArrayList<>(); private final List<Observer> mObservers = new ArrayList<>();
private final Runnable mDelayedShow = new Runnable() { private final Runnable mDelayedShow = new Runnable() {
@Override @Override
...@@ -49,6 +55,10 @@ public class LoadingView extends ProgressBar { ...@@ -49,6 +55,10 @@ public class LoadingView extends ProgressBar {
mStartTime = SystemClock.elapsedRealtime(); mStartTime = SystemClock.elapsedRealtime();
setVisibility(View.VISIBLE); setVisibility(View.VISIBLE);
setAlpha(1.0f); setAlpha(1.0f);
for (Observer observer : mObservers) {
observer.onShowLoadingUIComplete();
}
} }
}; };
...@@ -132,7 +142,7 @@ public class LoadingView extends ProgressBar { ...@@ -132,7 +142,7 @@ public class LoadingView extends ProgressBar {
public void destroy() { public void destroy() {
removeCallbacks(mDelayedShow); removeCallbacks(mDelayedShow);
removeCallbacks(mDelayedHide); removeCallbacks(mDelayedHide);
mListeners.clear(); mObservers.clear();
} }
/** /**
...@@ -142,12 +152,12 @@ public class LoadingView extends ProgressBar { ...@@ -142,12 +152,12 @@ public class LoadingView extends ProgressBar {
* completely hidden with {@link #hideLoadingUI()}. * completely hidden with {@link #hideLoadingUI()}.
*/ */
public void addObserver(Observer listener) { public void addObserver(Observer listener) {
mListeners.add(listener); mObservers.add(listener);
} }
private void onHideLoadingFinished() { private void onHideLoadingFinished() {
setVisibility(GONE); setVisibility(GONE);
for (Observer observer : mListeners) { for (Observer observer : mObservers) {
observer.onHideLoadingUIComplete(); observer.onHideLoadingUIComplete();
} }
} }
......
...@@ -30,11 +30,25 @@ import java.util.concurrent.TimeUnit; ...@@ -30,11 +30,25 @@ import java.util.concurrent.TimeUnit;
@RunWith(BaseRobolectricTestRunner.class) @RunWith(BaseRobolectricTestRunner.class)
@Config(manifest = Config.NONE, shadows = {ShadowView.class}) @Config(manifest = Config.NONE, shadows = {ShadowView.class})
public class LoadingViewTest { public class LoadingViewTest {
static class TestObserver implements LoadingView.Observer {
public final CallbackHelper showLoadingCallback = new CallbackHelper();
public final CallbackHelper hideLoadingCallback = new CallbackHelper();
@Override
public void onShowLoadingUIComplete() {
showLoadingCallback.notifyCalled();
}
@Override
public void onHideLoadingUIComplete() {
hideLoadingCallback.notifyCalled();
}
}
private LoadingView mLoadingView; private LoadingView mLoadingView;
private Activity mActivity; private Activity mActivity;
private final TestObserver mTestObserver1 = new TestObserver();
private final CallbackHelper mCallback1 = new CallbackHelper(); private final TestObserver mTestObserver2 = new TestObserver();
private final CallbackHelper mCallback2 = new CallbackHelper();
@Before @Before
public void setUpTest() throws Exception { public void setUpTest() throws Exception {
...@@ -47,26 +61,36 @@ public class LoadingViewTest { ...@@ -47,26 +61,36 @@ public class LoadingViewTest {
mLoadingView.setDisableAnimationForTest(true); mLoadingView.setDisableAnimationForTest(true);
content.addView(mLoadingView); content.addView(mLoadingView);
mLoadingView.addObserver(mCallback1::notifyCalled); mLoadingView.addObserver(mTestObserver1);
mLoadingView.addObserver(mCallback2::notifyCalled); mLoadingView.addObserver(mTestObserver2);
} }
@Test @Test
@SmallTest @SmallTest
public void testLoadingFast() { public void testLoadingFast() {
mLoadingView.showLoadingUI(); mLoadingView.showLoadingUI();
Assert.assertEquals(
"showLoadingCallback1 should not be executed as soon as showLoadingUI is called.",
0, mTestObserver1.showLoadingCallback.getCallCount());
Assert.assertEquals(
"showLoadingCallback2 should not be executed as soon as showLoadingUI is called.",
0, mTestObserver2.showLoadingCallback.getCallCount());
ShadowLooper.idleMainLooper(100, TimeUnit.MILLISECONDS); ShadowLooper.idleMainLooper(100, TimeUnit.MILLISECONDS);
Assert.assertEquals("Progress bar should be hidden before 500ms.", View.GONE, Assert.assertEquals("Progress bar should be hidden before 500ms.", View.GONE,
mLoadingView.getVisibility()); mLoadingView.getVisibility());
Assert.assertEquals("showLoadingCallback1 should not be executed with loading fast.", 0,
mTestObserver1.showLoadingCallback.getCallCount());
Assert.assertEquals("showLoadingCallback2 should not be executed with loading fast.", 0,
mTestObserver2.showLoadingCallback.getCallCount());
mLoadingView.hideLoadingUI(); mLoadingView.hideLoadingUI();
Assert.assertEquals( Assert.assertEquals(
"Progress bar should never be visible.", View.GONE, mLoadingView.getVisibility()); "Progress bar should never be visible.", View.GONE, mLoadingView.getVisibility());
Assert.assertEquals("Callback1 should be executed after loading finishes.", 1, Assert.assertEquals("hideLoadingCallback1 should be executed after loading finishes.", 1,
mCallback1.getCallCount()); mTestObserver1.hideLoadingCallback.getCallCount());
Assert.assertEquals("Callback2 should be executed after loading finishes.", 1, Assert.assertEquals("hideLoadingCallback2 should be executed after loading finishes.", 1,
mCallback2.getCallCount()); mTestObserver2.hideLoadingCallback.getCallCount());
} }
@Test @Test
...@@ -74,26 +98,36 @@ public class LoadingViewTest { ...@@ -74,26 +98,36 @@ public class LoadingViewTest {
public void testLoadingSlow() { public void testLoadingSlow() {
long sleepTime = 500; long sleepTime = 500;
mLoadingView.showLoadingUI(); mLoadingView.showLoadingUI();
Assert.assertEquals(
"showLoadingCallback1 should not be executed as soon as showLoadingUI is called.",
0, mTestObserver1.showLoadingCallback.getCallCount());
Assert.assertEquals(
"showLoadingCallback2 should not be executed as soon as showLoadingUI is called.",
0, mTestObserver2.showLoadingCallback.getCallCount());
ShadowLooper.idleMainLooper(sleepTime, TimeUnit.MILLISECONDS); ShadowLooper.idleMainLooper(sleepTime, TimeUnit.MILLISECONDS);
Assert.assertEquals("Progress bar should be visible after 500ms.", View.VISIBLE, Assert.assertEquals("Progress bar should be visible after 500ms.", View.VISIBLE,
mLoadingView.getVisibility()); mLoadingView.getVisibility());
Assert.assertEquals("showLoadingCallback1 should be executed when spinner is visible.", 1,
mTestObserver1.showLoadingCallback.getCallCount());
Assert.assertEquals("showLoadingCallback2 should be executed when spinner is visible.", 1,
mTestObserver2.showLoadingCallback.getCallCount());
mLoadingView.hideLoadingUI(); mLoadingView.hideLoadingUI();
Assert.assertEquals("Progress bar should still be visible until showing for 500ms.", Assert.assertEquals("Progress bar should still be visible until showing for 500ms.",
View.VISIBLE, mLoadingView.getVisibility()); View.VISIBLE, mLoadingView.getVisibility());
Assert.assertEquals("Callback1 should not be executed before loading finishes.", 0, Assert.assertEquals("hideLoadingCallback1 should not be executed before loading finishes.",
mCallback1.getCallCount()); 0, mTestObserver1.hideLoadingCallback.getCallCount());
Assert.assertEquals("Callback2 should not be executed before loading finishes.", 0, Assert.assertEquals("hideLoadingCallback2 should not be executed before loading finishes.",
mCallback2.getCallCount()); 0, mTestObserver2.hideLoadingCallback.getCallCount());
// The spinner should be displayed for at least 500ms. // The spinner should be displayed for at least 500ms.
ShadowLooper.idleMainLooper(sleepTime, TimeUnit.MILLISECONDS); ShadowLooper.idleMainLooper(sleepTime, TimeUnit.MILLISECONDS);
Assert.assertEquals("Progress bar should be hidden after 500ms.", View.GONE, Assert.assertEquals("Progress bar should be hidden after 500ms.", View.GONE,
mLoadingView.getVisibility()); mLoadingView.getVisibility());
Assert.assertEquals("Callback1 should be executed after loading finishes.", 1, Assert.assertEquals("hideLoadingCallback1 should be executed after loading finishes.", 1,
mCallback1.getCallCount()); mTestObserver1.hideLoadingCallback.getCallCount());
Assert.assertEquals("Callback2 should be executed after loading finishes.", 1, Assert.assertEquals("hideLoadingCallback2 should be executed after loading finishes.", 1,
mCallback2.getCallCount()); mTestObserver2.hideLoadingCallback.getCallCount());
} }
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment