From 9a7ead8962723692181012c3c7b73476190707a9 Mon Sep 17 00:00:00 2001 From: Yi-Ling Chuang Date: Mon, 15 Apr 2019 14:52:08 +0800 Subject: [PATCH] Hide filter spinner when data is loading. When the filter spinner is initialized, set GONE to its visibility. Only make it visible after network cycle data finishes loading to avoid presenting an empty filter spinner. Fixes: 130397929 Test: robotests Change-Id: I740fdad35ec82bc0be386c24e53348917bf6bfba --- .../settings/datausage/DataUsageList.java | 21 +++-- .../settings/datausage/DataUsageListTest.java | 82 ++++++++++++++++--- 2 files changed, 82 insertions(+), 21 deletions(-) diff --git a/src/com/android/settings/datausage/DataUsageList.java b/src/com/android/settings/datausage/DataUsageList.java index e5158ffd63a..96a1e22c6a0 100644 --- a/src/com/android/settings/datausage/DataUsageList.java +++ b/src/com/android/settings/datausage/DataUsageList.java @@ -99,22 +99,23 @@ public class DataUsageList extends DataUsageBaseFragment { } }; - private ChartDataUsagePreference mChart; - private TelephonyManager mTelephonyManager; - @VisibleForTesting NetworkTemplate mTemplate; @VisibleForTesting int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; @VisibleForTesting int mNetworkType; + @VisibleForTesting + Spinner mCycleSpinner; + @VisibleForTesting + LoadingViewController mLoadingViewController; + + private ChartDataUsagePreference mChart; + private TelephonyManager mTelephonyManager; private List mCycleData; private ArrayList mCycles; - - private LoadingViewController mLoadingViewController; private UidDetailProvider mUidDetailProvider; private CycleAdapter mCycleAdapter; - private Spinner mCycleSpinner; private Preference mUsageAmount; private PreferenceGroup mApps; private View mHeader; @@ -158,6 +159,7 @@ public class DataUsageList extends DataUsageBaseFragment { .launch(); }); mCycleSpinner = mHeader.findViewById(R.id.filter_spinner); + mCycleSpinner.setVisibility(View.GONE); mCycleAdapter = new CycleAdapter(mCycleSpinner.getContext(), new SpinnerInterface() { @Override public void setAdapter(CycleAdapter cycleAdapter) { @@ -276,7 +278,8 @@ public class DataUsageList extends DataUsageBaseFragment { * Update chart sweeps and cycle list to reflect {@link NetworkPolicy} for * current {@link #mTemplate}. */ - private void updatePolicy() { + @VisibleForTesting + void updatePolicy() { final NetworkPolicy policy = services.mPolicyEditor.getPolicy(mTemplate); final View configureButton = mHeader.findViewById(R.id.filter_settings); //SUB SELECT @@ -486,7 +489,8 @@ public class DataUsageList extends DataUsageBaseFragment { } }; - private final LoaderCallbacks> mNetworkCycleDataCallbacks = + @VisibleForTesting + final LoaderCallbacks> mNetworkCycleDataCallbacks = new LoaderCallbacks>() { @Override public Loader> onCreateLoader(int id, Bundle args) { @@ -503,6 +507,7 @@ public class DataUsageList extends DataUsageBaseFragment { mCycleData = data; // calculate policy cycles based on available data updatePolicy(); + mCycleSpinner.setVisibility(View.VISIBLE); } @Override diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.java b/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.java index 7d042ce3c44..9aa1c6f1497 100644 --- a/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.java +++ b/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.java @@ -18,22 +18,32 @@ package com.android.settings.datausage; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import android.content.Context; +import android.app.Activity; import android.content.Intent; import android.net.ConnectivityManager; import android.net.NetworkTemplate; import android.os.Bundle; import android.provider.Settings; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.FrameLayout; import android.widget.Spinner; +import androidx.fragment.app.FragmentActivity; +import androidx.preference.PreferenceManager; + +import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.testutils.FakeFeatureFactory; +import com.android.settings.widget.LoadingViewController; import com.android.settingslib.AppItem; import com.android.settingslib.NetworkPolicyEditor; import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin; @@ -45,15 +55,14 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.robolectric.Robolectric; import org.robolectric.RobolectricTestRunner; +import org.robolectric.android.controller.ActivityController; import org.robolectric.util.ReflectionHelpers; import java.util.ArrayList; import java.util.List; -import androidx.fragment.app.FragmentActivity; -import androidx.preference.PreferenceManager; - @RunWith(RobolectricTestRunner.class) public class DataUsageListTest { @@ -61,18 +70,21 @@ public class DataUsageListTest { private CellDataPreference.DataStateListener mListener; @Mock private TemplatePreference.NetworkServices mNetworkServices; - @Mock - private Context mContext; + + private Activity mActivity; private DataUsageList mDataUsageList; @Before public void setUp() { MockitoAnnotations.initMocks(this); FakeFeatureFactory.setupForTest(); + final ActivityController mActivityController = + Robolectric.buildActivity(Activity.class); + mActivity = spy(mActivityController.get()); mNetworkServices.mPolicyEditor = mock(NetworkPolicyEditor.class); mDataUsageList = spy(DataUsageList.class); - doReturn(mContext).when(mDataUsageList).getContext(); + doReturn(mActivity).when(mDataUsageList).getContext(); ReflectionHelpers.setField(mDataUsageList, "mDataStateListener", mListener); ReflectionHelpers.setField(mDataUsageList, "services", mNetworkServices); } @@ -86,11 +98,11 @@ public class DataUsageListTest { mDataUsageList.onResume(); - verify(mListener).setListener(true, mDataUsageList.mSubId, mContext); + verify(mListener).setListener(true, mDataUsageList.mSubId, mActivity); mDataUsageList.onPause(); - verify(mListener).setListener(false, mDataUsageList.mSubId, mContext); + verify(mListener).setListener(false, mDataUsageList.mSubId, mActivity); } @Test @@ -140,7 +152,7 @@ public class DataUsageListTest { final List data = new ArrayList<>(); final NetworkCycleChartData.Builder builder = new NetworkCycleChartData.Builder(); builder.setStartTime(startTime) - .setEndTime(endTime); + .setEndTime(endTime); data.add(builder.build()); ReflectionHelpers.setField(mDataUsageList, "mCycleData", data); final Spinner spinner = mock(Spinner.class); @@ -150,14 +162,58 @@ public class DataUsageListTest { mDataUsageList.startAppDataUsage(new AppItem()); - verify(mContext).startActivity(intent.capture()); + verify(mActivity).startActivity(intent.capture()); final Bundle arguments = - intent.getValue().getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS); + intent.getValue().getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS); assertThat(arguments.getLong(AppDataUsage.ARG_SELECTED_CYCLE)).isEqualTo(endTime); final ArrayList cycles = - (ArrayList) arguments.getSerializable(AppDataUsage.ARG_NETWORK_CYCLES); + (ArrayList) arguments.getSerializable(AppDataUsage.ARG_NETWORK_CYCLES); assertThat(cycles).hasSize(2); assertThat(cycles.get(0)).isEqualTo(endTime); assertThat(cycles.get(1)).isEqualTo(startTime); } + + @Test + public void onViewCreated_shouldHideCycleSpinner() { + final View view = new View(mActivity); + final View header = getHeader(); + final Spinner spinner = getSpinner(header); + spinner.setVisibility(View.VISIBLE); + doReturn(header).when(mDataUsageList).setPinnedHeaderView(anyInt()); + doReturn(view).when(mDataUsageList).getView(); + + mDataUsageList.onViewCreated(view, null); + + assertThat(spinner.getVisibility()).isEqualTo(View.GONE); + } + + @Test + public void onLoadFinished_networkCycleDataCallback_shouldShowCycleSpinner() { + final LoadingViewController loadingViewController = mock(LoadingViewController.class); + mDataUsageList.mLoadingViewController = loadingViewController; + final Spinner spinner = getSpinner(getHeader()); + spinner.setVisibility(View.INVISIBLE); + mDataUsageList.mCycleSpinner = spinner; + assertThat(spinner.getVisibility()).isEqualTo(View.INVISIBLE); + doNothing().when(mDataUsageList).updatePolicy(); + + mDataUsageList.mNetworkCycleDataCallbacks.onLoadFinished(null, null); + + assertThat(spinner.getVisibility()).isEqualTo(View.VISIBLE); + } + + private View getHeader() { + final View rootView = LayoutInflater.from(mActivity) + .inflate(R.layout.preference_list_fragment, null, false); + final FrameLayout pinnedHeader = rootView.findViewById(R.id.pinned_header); + final View header = mActivity.getLayoutInflater() + .inflate(R.layout.apps_filter_spinner, pinnedHeader, false); + + return header; + } + + private Spinner getSpinner(View header) { + final Spinner spinner = header.findViewById(R.id.filter_spinner); + return spinner; + } }