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) {