From c407a2d9f89143f239e5c2ac4c2daf6a3d6a13aa Mon Sep 17 00:00:00 2001 From: Weng Su Date: Thu, 29 Apr 2021 10:20:11 +0800 Subject: [PATCH] [Provider Model] Add progress bar to internet panel - Show progress bar when Wi-Fi scanning - Show "Searching for networks..." sub-title when Wi-Fi scanning - Remove "Wi-Fi" from searching networks string Bug: 178774497 Test: manual test atest -c InternetConnectivityPanelTest make RunSettingsRoboTests ROBOTEST_FILTER=PanelFragmentTest Change-Id: Ic05b939bef3b106845fe90db41eb09f0e15756f4 --- res/layout/panel_layout.xml | 14 +++- res/values/strings.xml | 2 +- .../panel/InternetConnectivityPanel.java | 58 +++++++++++++++- .../android/settings/panel/PanelContent.java | 7 ++ .../settings/panel/PanelContentCallback.java | 5 ++ .../android/settings/panel/PanelFragment.java | 24 +++++++ .../settings/panel/FakePanelContent.java | 10 +++ .../settings/panel/PanelFragmentTest.java | 22 ++++++ .../panel/InternetConnectivityPanelTest.java | 67 +++++++++++++++++++ 9 files changed, 204 insertions(+), 5 deletions(-) diff --git a/res/layout/panel_layout.xml b/res/layout/panel_layout.xml index ac7a72b3268..2a55b58916a 100644 --- a/res/layout/panel_layout.xml +++ b/res/layout/panel_layout.xml @@ -83,7 +83,19 @@ android:textColor="?android:attr/textColorPrimary" android:textSize="20sp"/> - + + + diff --git a/res/values/strings.xml b/res/values/strings.xml index 8368b4647e8..4aa690c8110 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -2120,7 +2120,7 @@ To see available networks, turn Wi\u2011Fi on. - Searching for Wi\u2011Fi networks\u2026 + Searching for networks\u2026 You don\u2019t have permission to change the Wi\u2011Fi network. diff --git a/src/com/android/settings/panel/InternetConnectivityPanel.java b/src/com/android/settings/panel/InternetConnectivityPanel.java index f1b9f16e1f8..d057e2fe697 100644 --- a/src/com/android/settings/panel/InternetConnectivityPanel.java +++ b/src/com/android/settings/panel/InternetConnectivityPanel.java @@ -65,6 +65,8 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve private static final String TAG = "InternetConnectivityPanel"; private static final int SUBTITLE_TEXT_NONE = -1; private static final int SUBTITLE_TEXT_WIFI_IS_TURNED_ON = R.string.wifi_is_turned_on_subtitle; + private static final int SUBTITLE_TEXT_SEARCHING_FOR_NETWORKS = + R.string.wifi_empty_list_wifi_on; private static final int SUBTITLE_TEXT_NON_CARRIER_NETWORK_UNAVAILABLE = R.string.non_carrier_network_unavailable; private static final int SUBTITLE_TEXT_ALL_CARRIER_NETWORK_UNAVAILABLE = @@ -80,9 +82,14 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve if (intent == null) { return; } - if (TextUtils.equals(intent.getAction(), WifiManager.NETWORK_STATE_CHANGED_ACTION) - || TextUtils.equals(intent.getAction(), - WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { + + if (TextUtils.equals(intent.getAction(), WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { + showProgressBar(); + updatePanelTitle(); + return; + } + + if (TextUtils.equals(intent.getAction(), WifiManager.NETWORK_STATE_CHANGED_ACTION)) { updatePanelTitle(); } } @@ -102,6 +109,12 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve private DataConnectivityListener mConnectivityListener; private int mDefaultDataSubid = SubscriptionManager.INVALID_SUBSCRIPTION_ID; + // Wi-Fi scanning progress bar + protected boolean mIsProgressBarVisible; + protected final Runnable mHideProgressBarRunnable = () -> { + setProgressBarVisible(false); + }; + private InternetConnectivityPanel(Context context) { mContext = context.getApplicationContext(); mIsProviderModelEnabled = Utils.isProviderModelEnabled(mContext); @@ -137,6 +150,7 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve mTelephonyManager.registerTelephonyCallback( new HandlerExecutor(new Handler(Looper.getMainLooper())), mTelephonyCallback); mContext.registerReceiver(mWifiStateReceiver, mWifiStateFilter); + showProgressBar(); updatePanelTitle(); } @@ -151,6 +165,7 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve mConnectivityListener.stop(); mTelephonyManager.unregisterTelephonyCallback(mTelephonyCallback); mContext.unregisterReceiver(mWifiStateReceiver); + mContext.getMainThreadHandler().removeCallbacks(mHideProgressBarRunnable); } /** @@ -215,6 +230,11 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve mContext.startActivity(getSeeMoreIntent()); } + @Override + public boolean isProgressBarVisible() { + return mIsProgressBarVisible; + } + @Override public int getMetricsCategory() { return SettingsEnums.PANEL_INTERNET_CONNECTIVITY; @@ -302,6 +322,11 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve final List wifiList = mWifiManager.getScanResults(); if (wifiList != null && wifiList.size() != 0) { + if (mIsProgressBarVisible) { + // When the Wi-Fi scan result callback is received + // Sub-Title: Searching for networks... + mSubtitle = SUBTITLE_TEXT_SEARCHING_FOR_NETWORKS; + } return; } @@ -334,6 +359,33 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve mSubtitle = SUBTITLE_TEXT_NON_CARRIER_NETWORK_UNAVAILABLE; } + protected void showProgressBar() { + if (mWifiManager == null || !mInternetUpdater.isWifiEnabled()) { + setProgressBarVisible(false); + return; + } + + setProgressBarVisible(true); + List wifiScanResults = mWifiManager.getScanResults(); + if (wifiScanResults != null && wifiScanResults.size() > 0) { + mContext.getMainThreadHandler().postDelayed(mHideProgressBarRunnable, + 2000 /* delay millis */); + } + } + + protected void setProgressBarVisible(boolean visible) { + if (mIsProgressBarVisible == visible) { + return; + } + mIsProgressBarVisible = visible; + + if (mCallback == null) { + return; + } + mCallback.onProgressBarVisibleChanged(); + updatePanelTitle(); + } + private class NetworkProviderTelephonyCallback extends TelephonyCallback implements TelephonyCallback.DataConnectionStateListener, TelephonyCallback.ServiceStateListener { diff --git a/src/com/android/settings/panel/PanelContent.java b/src/com/android/settings/panel/PanelContent.java index 6c271fd11d9..4c24182559d 100644 --- a/src/com/android/settings/panel/PanelContent.java +++ b/src/com/android/settings/panel/PanelContent.java @@ -110,4 +110,11 @@ public interface PanelContent extends Instrumentable { default int getViewType() { return 0; } + + /** + * @return {@code true} to enable progress bar visibility, {@code false} otherwise. + */ + default boolean isProgressBarVisible() { + return false; + } } diff --git a/src/com/android/settings/panel/PanelContentCallback.java b/src/com/android/settings/panel/PanelContentCallback.java index f0e68a303ce..e59d69913db 100644 --- a/src/com/android/settings/panel/PanelContentCallback.java +++ b/src/com/android/settings/panel/PanelContentCallback.java @@ -42,4 +42,9 @@ public interface PanelContentCallback { * It will be called when panel requests to change the title. */ void onTitleChanged(); + + /** + * It will be called when panel requests to change the progress bar visibility. + */ + void onProgressBarVisibleChanged(); } diff --git a/src/com/android/settings/panel/PanelFragment.java b/src/com/android/settings/panel/PanelFragment.java index 73d0976ceff..31cb7b8d0ac 100644 --- a/src/com/android/settings/panel/PanelFragment.java +++ b/src/com/android/settings/panel/PanelFragment.java @@ -35,6 +35,7 @@ import android.view.animation.DecelerateInterpolator; import android.widget.Button; import android.widget.ImageView; import android.widget.LinearLayout; +import android.widget.ProgressBar; import android.widget.TextView; import androidx.annotation.NonNull; @@ -101,6 +102,8 @@ public class PanelFragment extends Fragment { private int mMaxHeight; private View mFooterDivider; private boolean mPanelCreating; + private ProgressBar mProgressBar; + private View mHeaderDivider; private final Map> mSliceLiveData = new LinkedHashMap<>(); @@ -208,6 +211,8 @@ public class PanelFragment extends Fragment { mHeaderTitle = mLayoutView.findViewById(R.id.header_title); mHeaderSubtitle = mLayoutView.findViewById(R.id.header_subtitle); mFooterDivider = mLayoutView.findViewById(R.id.footer_divider); + mProgressBar = mLayoutView.findViewById(R.id.progress_bar); + mHeaderDivider = mLayoutView.findViewById(R.id.header_divider); // Make the panel layout gone here, to avoid janky animation when updating from old panel. // We will make it visible once the panel is ready to load. @@ -233,6 +238,8 @@ public class PanelFragment extends Fragment { mMetricsProvider = FeatureFactory.getFactory(activity).getMetricsFeatureProvider(); + updateProgressBar(); + mPanelSlices.setLayoutManager(new LinearLayoutManager((activity))); // Add predraw listener to remove the animation and while we wait for Slices to load. mLayoutView.getViewTreeObserver().addOnPreDrawListener(mOnPreDrawListener); @@ -314,6 +321,16 @@ public class PanelFragment extends Fragment { } } + private void updateProgressBar() { + if (mPanel.isProgressBarVisible()) { + mProgressBar.setVisibility(View.VISIBLE); + mHeaderDivider.setVisibility(View.GONE); + } else { + mProgressBar.setVisibility(View.GONE); + mHeaderDivider.setVisibility(View.VISIBLE); + } + } + private void loadAllSlices() { mSliceLiveData.clear(); final List sliceUris = mPanel.getSlices(); @@ -531,6 +548,13 @@ public class PanelFragment extends Fragment { }); } + @Override + public void onProgressBarVisibleChanged() { + ThreadUtils.postOnMainThread(() -> { + updateProgressBar(); + }); + } + @VisibleForTesting FragmentActivity getFragmentActivity() { return getActivity(); diff --git a/tests/robotests/src/com/android/settings/panel/FakePanelContent.java b/tests/robotests/src/com/android/settings/panel/FakePanelContent.java index 0f1889c6e6c..06beb3ecf51 100644 --- a/tests/robotests/src/com/android/settings/panel/FakePanelContent.java +++ b/tests/robotests/src/com/android/settings/panel/FakePanelContent.java @@ -48,6 +48,7 @@ public class FakePanelContent implements PanelContent { private int mViewType; private boolean mIsCustomizedButtonUsed = false; private CharSequence mCustomizedButtonTitle; + private boolean mIsProgressBarVisible; @Override public IconCompat getIcon() { @@ -117,4 +118,13 @@ public class FakePanelContent implements PanelContent { public void setCustomizedButtonTitle(CharSequence title) { mCustomizedButtonTitle = title; } + + @Override + public boolean isProgressBarVisible() { + return mIsProgressBarVisible; + } + + public void setIsProgressBarVisible(boolean isProgressBarVisible) { + mIsProgressBarVisible = isProgressBarVisible; + } } diff --git a/tests/robotests/src/com/android/settings/panel/PanelFragmentTest.java b/tests/robotests/src/com/android/settings/panel/PanelFragmentTest.java index 41935c4c875..1333d27fa2a 100644 --- a/tests/robotests/src/com/android/settings/panel/PanelFragmentTest.java +++ b/tests/robotests/src/com/android/settings/panel/PanelFragmentTest.java @@ -35,6 +35,7 @@ import android.view.LayoutInflater; import android.view.View; import android.widget.Button; import android.widget.LinearLayout; +import android.widget.ProgressBar; import android.widget.TextView; import androidx.core.graphics.drawable.IconCompat; @@ -308,4 +309,25 @@ public class PanelFragmentTest { assertThat(seeMoreButton.getVisibility()).isEqualTo(View.VISIBLE); assertThat(seeMoreButton.getText()).isEqualTo("test_title"); } + + @Test + public void onProgressBarVisibleChanged_isProgressBarVisible_showProgressBar() { + final ActivityController activityController = + Robolectric.buildActivity(FakeSettingsPanelActivity.class); + activityController.setup(); + final PanelFragment panelFragment = (PanelFragment) + Objects.requireNonNull(activityController + .get() + .getSupportFragmentManager() + .findFragmentById(R.id.main_content)); + + final ProgressBar progressBar = panelFragment.mLayoutView.findViewById(R.id.progress_bar); + + mFakePanelContent.setIsProgressBarVisible(true); + verify(mFakePanelContent).registerCallback(mPanelContentCbs.capture()); + final PanelContentCallback panelContentCallbacks = mPanelContentCbs.getValue(); + panelContentCallbacks.onProgressBarVisibleChanged(); + + assertThat(progressBar.getVisibility()).isEqualTo(View.VISIBLE); + } } \ No newline at end of file diff --git a/tests/unit/src/com/android/settings/panel/InternetConnectivityPanelTest.java b/tests/unit/src/com/android/settings/panel/InternetConnectivityPanelTest.java index 0da8464d95c..d2ef4519b63 100644 --- a/tests/unit/src/com/android/settings/panel/InternetConnectivityPanelTest.java +++ b/tests/unit/src/com/android/settings/panel/InternetConnectivityPanelTest.java @@ -18,8 +18,12 @@ package com.android.settings.panel; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -28,6 +32,7 @@ import android.content.Context; import android.net.Uri; import android.net.wifi.ScanResult; import android.net.wifi.WifiManager; +import android.os.Handler; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -70,6 +75,8 @@ public class InternetConnectivityPanelTest { @Rule public final MockitoRule mMocks = MockitoJUnit.rule(); @Mock + Handler mMainThreadHandler; + @Mock PanelContentCallback mPanelContentCallback; @Mock InternetUpdater mInternetUpdater; @@ -85,6 +92,7 @@ public class InternetConnectivityPanelTest { public void setUp() { mContext = spy(ApplicationProvider.getApplicationContext()); when(mContext.getApplicationContext()).thenReturn(mContext); + when(mContext.getMainThreadHandler()).thenReturn(mMainThreadHandler); when(mContext.getSystemService(WifiManager.class)).thenReturn(mWifiManager); mPanel = InternetConnectivityPanel.create(mContext); @@ -310,6 +318,65 @@ public class InternetConnectivityPanelTest { verify(mPanelContentCallback).onCustomizedButtonStateChanged(); } + @Test + public void showProgressBar_wifiDisabled_hideProgress() { + mPanel.mIsProgressBarVisible = true; + doReturn(false).when(mInternetUpdater).isWifiEnabled(); + clearInvocations(mPanelContentCallback); + + mPanel.showProgressBar(); + + assertThat(mPanel.isProgressBarVisible()).isFalse(); + verify(mPanelContentCallback).onProgressBarVisibleChanged(); + } + + @Test + public void showProgressBar_noWifiScanResults_showProgressForever() { + mPanel.mIsProgressBarVisible = false; + doReturn(true).when(mInternetUpdater).isWifiEnabled(); + List noWifiScanResults = new ArrayList<>(); + doReturn(noWifiScanResults).when(mWifiManager).getScanResults(); + clearInvocations(mPanelContentCallback); + + mPanel.showProgressBar(); + + assertThat(mPanel.isProgressBarVisible()).isTrue(); + verify(mPanelContentCallback).onProgressBarVisibleChanged(); + verify(mPanelContentCallback).onHeaderChanged(); + verify(mMainThreadHandler, never()) + .postDelayed(any() /* mHideProgressBarRunnable */, anyLong()); + } + + @Test + public void showProgressBar_hasWifiScanResults_showProgressDelayedHide() { + mPanel.mIsProgressBarVisible = false; + doReturn(true).when(mInternetUpdater).isWifiEnabled(); + List hasWifiScanResults = mock(ArrayList.class); + doReturn(1).when(hasWifiScanResults).size(); + doReturn(hasWifiScanResults).when(mWifiManager).getScanResults(); + clearInvocations(mPanelContentCallback); + + mPanel.showProgressBar(); + + assertThat(mPanel.isProgressBarVisible()).isTrue(); + verify(mPanelContentCallback).onProgressBarVisibleChanged(); + verify(mPanelContentCallback).onHeaderChanged(); + verify(mMainThreadHandler).postDelayed(any() /* mHideProgressBarRunnable */, anyLong()); + } + + @Test + public void setProgressBarVisible_onProgressBarVisibleChanged() { + mPanel.mIsProgressBarVisible = false; + doReturn(true).when(mInternetUpdater).isWifiEnabled(); + clearInvocations(mPanelContentCallback); + + mPanel.setProgressBarVisible(true); + + assertThat(mPanel.mIsProgressBarVisible).isTrue(); + verify(mPanelContentCallback).onProgressBarVisibleChanged(); + verify(mPanelContentCallback).onHeaderChanged(); + } + private void mockCondition(boolean airplaneMode, boolean hasCarrier, boolean isDataSimActive, boolean isMobileDataEnabled, boolean isServiceInService, boolean isWifiEnabled, List wifiItems) {