Loading src/com/android/settings/wifi/slice/ContextualWifiScanWorker.java +5 −0 Original line number Diff line number Diff line Loading @@ -62,4 +62,9 @@ public class ContextualWifiScanWorker extends WifiScanWorker { } return true; } @Override protected int getApRowCount() { return ContextualWifiSlice.getApRowCount(); } } No newline at end of file src/com/android/settings/wifi/slice/ContextualWifiSlice.java +81 −11 Original line number Diff line number Diff line Loading @@ -17,30 +17,42 @@ package com.android.settings.wifi.slice; import android.content.Context; import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.graphics.drawable.Drawable; import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.State; import android.net.Uri; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.text.TextUtils; import android.util.Log; import androidx.annotation.VisibleForTesting; import androidx.core.graphics.drawable.IconCompat; import androidx.slice.Slice; import androidx.slice.builders.ListBuilder; import com.android.settings.R; import com.android.settings.Utils; import com.android.settings.overlay.FeatureFactory; import com.android.settings.slices.CustomSliceRegistry; import com.android.settings.slices.CustomSliceable; import com.android.settingslib.wifi.AccessPoint; /** * {@link CustomSliceable} for Wi-Fi, used by contextual homepage. */ public class ContextualWifiSlice extends WifiSlice { private static final String TAG = "ContextualWifiSlice"; @VisibleForTesting static final int COLLAPSED_ROW_COUNT = 0; @VisibleForTesting static long sActiveUiSession = -1000; @VisibleForTesting static boolean sPreviouslyDisplayed; static boolean sToggleNeeded = true; public ContextualWifiSlice(Context context) { super(context); Loading @@ -57,17 +69,75 @@ public class ContextualWifiSlice extends WifiSlice { .getSlicesFeatureProvider().getUiSessionToken(); if (currentUiSession != sActiveUiSession) { sActiveUiSession = currentUiSession; sPreviouslyDisplayed = false; sToggleNeeded = !hasWorkingNetwork(); } else if (!mWifiManager.isWifiEnabled()) { sToggleNeeded = true; } if (!sPreviouslyDisplayed && hasWorkingNetwork()) { Log.d(TAG, "Wifi is connected, no point showing any suggestion."); return null; return super.getSlice(); } // Set sPreviouslyDisplayed to true - we will show *something* on the screen. So we should // keep showing this card to keep UI stable, even if wifi connects to a network later. sPreviouslyDisplayed = true; return super.getSlice(); static int getApRowCount() { return sToggleNeeded ? DEFAULT_EXPANDED_ROW_COUNT : COLLAPSED_ROW_COUNT; } @Override protected boolean isToggleNeeded() { return sToggleNeeded; } @Override protected ListBuilder.RowBuilder getHeaderRow(AccessPoint accessPoint) { final ListBuilder.RowBuilder builder = super.getHeaderRow(accessPoint); if (!sToggleNeeded) { builder.setTitleItem(getLevelIcon(accessPoint), ListBuilder.ICON_IMAGE) .setSubtitle(getSubtitle(accessPoint)); } return builder; } private IconCompat getLevelIcon(AccessPoint accessPoint) { if (accessPoint != null) { return getAccessPointLevelIcon(accessPoint); } final Drawable drawable = mContext.getDrawable( com.android.settingslib.Utils.getWifiIconResource(0)); final int color = Utils.getColorAttrDefaultColor(mContext, android.R.attr.colorControlNormal); drawable.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN)); return Utils.createIconWithDrawable(drawable); } private CharSequence getSubtitle(AccessPoint accessPoint) { if (isCaptivePortal()) { final int id = mContext.getResources() .getIdentifier("network_available_sign_in", "string", "android"); return mContext.getText(id); } if (accessPoint == null) { return mContext.getText(R.string.disconnected); } final NetworkInfo networkInfo = accessPoint.getNetworkInfo(); if (networkInfo == null) { return mContext.getText(R.string.disconnected); } final State state = networkInfo.getState(); DetailedState detailedState; if (state == State.CONNECTING) { detailedState = DetailedState.CONNECTING; } else if (state == State.CONNECTED) { detailedState = DetailedState.CONNECTED; } else { detailedState = networkInfo.getDetailedState(); } final String[] formats = mContext.getResources().getStringArray( R.array.wifi_status_with_ssid); final int index = detailedState.ordinal(); return String.format(formats[index], accessPoint.getTitle()); } private boolean hasWorkingNetwork() { Loading src/com/android/settings/wifi/slice/WifiScanWorker.java +6 −1 Original line number Diff line number Diff line Loading @@ -111,10 +111,11 @@ public class WifiScanWorker extends SliceBackgroundWorker<AccessPoint> implement // AccessPoints are sorted by the WifiTracker final List<AccessPoint> accessPoints = mWifiTracker.getAccessPoints(); final List<AccessPoint> resultList = new ArrayList<>(); final int apRowCount = getApRowCount(); for (AccessPoint ap : accessPoints) { if (ap.isReachable()) { resultList.add(clone(ap)); if (resultList.size() >= DEFAULT_EXPANDED_ROW_COUNT) { if (resultList.size() >= apRowCount) { break; } } Loading @@ -122,6 +123,10 @@ public class WifiScanWorker extends SliceBackgroundWorker<AccessPoint> implement updateResults(resultList); } protected int getApRowCount() { return DEFAULT_EXPANDED_ROW_COUNT; } private AccessPoint clone(AccessPoint accessPoint) { final Bundle savedState = new Bundle(); accessPoint.saveWifiState(savedState); Loading src/com/android/settings/wifi/slice/WifiSlice.java +35 −39 Original line number Diff line number Diff line Loading @@ -95,7 +95,7 @@ public class WifiSlice implements CustomSliceable { mContext.getTheme().applyStyle(R.style.Theme_Settings_Home, true /* force */); final boolean isWifiEnabled = isWifiEnabled(); ListBuilder listBuilder = getHeaderRow(isWifiEnabled); ListBuilder listBuilder = getListBuilder(isWifiEnabled, null /* accessPoint */); if (!isWifiEnabled) { WifiScanWorker.clearClickedWifi(); return listBuilder.build(); Loading @@ -107,17 +107,12 @@ public class WifiSlice implements CustomSliceable { final boolean isFirstApActive = apCount > 0 && apList.get(0).isActive(); handleNetworkCallback(worker, isFirstApActive); // Need a loading text when results are not ready or out of date. boolean needLoadingRow = true; // Skip checking the existence of the first access point if it's active int index = isFirstApActive ? 1 : 0; // This loop checks the existence of reachable APs to determine the validity of the current // AP list. for (; index < apCount; index++) { if (apList.get(index).isReachable()) { needLoadingRow = false; break; if (!isToggleNeeded()) { if (isFirstApActive) { // refresh header subtext listBuilder = getListBuilder(true /* isWifiEnabled */, apList.get(0)); } return listBuilder.build(); } // Add AP rows Loading @@ -125,9 +120,8 @@ public class WifiSlice implements CustomSliceable { for (int i = 0; i < DEFAULT_EXPANDED_ROW_COUNT; i++) { if (i < apCount) { listBuilder.addRow(getAccessPointRow(apList.get(i))); } else if (needLoadingRow) { } else if (i == apCount) { listBuilder.addRow(getLoadingRow(placeholder)); needLoadingRow = false; } else { listBuilder.addRow(new ListBuilder.RowBuilder() .setTitle(placeholder) Loading @@ -148,24 +142,34 @@ public class WifiSlice implements CustomSliceable { } } private ListBuilder getHeaderRow(boolean isWifiEnabled) { protected boolean isToggleNeeded() { return true; } protected ListBuilder.RowBuilder getHeaderRow(AccessPoint accessPoint) { final IconCompat icon = IconCompat.createWithResource(mContext, R.drawable.ic_settings_wireless); final String title = mContext.getString(R.string.wifi_settings); final PendingIntent toggleAction = getBroadcastIntent(mContext); final PendingIntent primaryAction = getPrimaryAction(); final SliceAction primarySliceAction = SliceAction.createDeeplink(primaryAction, icon, ListBuilder.ICON_IMAGE, title); final SliceAction toggleSliceAction = SliceAction.createToggle(toggleAction, null /* actionTitle */, isWifiEnabled); return new ListBuilder(mContext, getUri(), ListBuilder.INFINITY) return new ListBuilder.RowBuilder() .setTitle(title) .setPrimaryAction(primarySliceAction); } private ListBuilder getListBuilder(boolean isWifiEnabled, AccessPoint accessPoint) { final ListBuilder builder = new ListBuilder(mContext, getUri(), ListBuilder.INFINITY) .setAccentColor(COLOR_NOT_TINTED) .setKeywords(getKeywords()) .addRow(new ListBuilder.RowBuilder() .setTitle(title) .addEndItem(toggleSliceAction) .setPrimaryAction(primarySliceAction)); .addRow(getHeaderRow(accessPoint)); if (isToggleNeeded()) { final PendingIntent toggleAction = getBroadcastIntent(mContext); builder.addAction(SliceAction.createToggle(toggleAction, null /* actionTitle */, isWifiEnabled)); } return builder; } private ListBuilder.RowBuilder getAccessPointRow(AccessPoint accessPoint) { Loading Loading @@ -200,7 +204,7 @@ public class WifiSlice implements CustomSliceable { return TextUtils.isEmpty(summary) ? mContext.getText(R.string.disconnected) : summary; } private IconCompat getAccessPointLevelIcon(AccessPoint accessPoint) { protected IconCompat getAccessPointLevelIcon(AccessPoint accessPoint) { final Drawable d = mContext.getDrawable( com.android.settingslib.Utils.getWifiIconResource(accessPoint.getLevel())); Loading Loading @@ -250,24 +254,16 @@ public class WifiSlice implements CustomSliceable { accessPoint.saveWifiState(extras); if (accessPoint.isActive()) { Intent intent; if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_WIFITRACKER2)) { intent = new SubSettingLauncher(mContext) final SubSettingLauncher launcher = new SubSettingLauncher(mContext) .setTitleRes(R.string.pref_title_network_details) .setDestination(WifiNetworkDetailsFragment2.class.getName()) .setArguments(extras) .setSourceMetricsCategory(SettingsEnums.WIFI) .toIntent(); return getActivityAction(requestCode, intent, icon, title); .setSourceMetricsCategory(SettingsEnums.WIFI); if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_WIFITRACKER2)) { launcher.setDestination(WifiNetworkDetailsFragment2.class.getName()); } else { intent = new SubSettingLauncher(mContext) .setTitleRes(R.string.pref_title_network_details) .setDestination(WifiNetworkDetailsFragment.class.getName()) .setArguments(extras) .setSourceMetricsCategory(SettingsEnums.WIFI) .toIntent(); return getActivityAction(requestCode, intent, icon, title); launcher.setDestination(WifiNetworkDetailsFragment.class.getName()); } return getActivityAction(requestCode, launcher.toIntent(), icon, title); } else if (WifiUtils.getConnectingType(accessPoint) != WifiUtils.CONNECT_TYPE_OTHERS) { final Intent intent = new Intent(mContext, ConnectToWifiHandler.class) .putExtra(WifiDialogActivity.KEY_ACCESS_POINT_STATE, extras); Loading Loading @@ -307,7 +303,7 @@ public class WifiSlice implements CustomSliceable { .setSubtitle(title); } private boolean isCaptivePortal() { protected boolean isCaptivePortal() { final NetworkCapabilities nc = mConnectivityManager.getNetworkCapabilities( mWifiManager.getCurrentNetwork()); return WifiUtils.canSignIntoNetwork(nc); Loading tests/robotests/src/com/android/settings/wifi/slice/ContextualWifiSliceTest.java +69 −32 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ package com.android.settings.wifi.slice; import static com.android.settings.wifi.slice.ContextualWifiSlice.COLLAPSED_ROW_COUNT; import static com.android.settings.wifi.slice.WifiSlice.DEFAULT_EXPANDED_ROW_COUNT; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.doReturn; Loading Loading @@ -75,75 +78,87 @@ public class ContextualWifiSliceTest { mWifiManager.setWifiEnabled(true); mWifiSlice = new ContextualWifiSlice(mContext); mWifiSlice.sPreviouslyDisplayed = false; } @Test public void getWifiSlice_hasActiveConnection_shouldReturnNull() { mWifiSlice.sPreviouslyDisplayed = false; public void getWifiSlice_newSession_hasActiveConnection_shouldCollapseSlice() { mWifiSlice.sActiveUiSession = ~mFeatureFactory.slicesFeatureProvider.getUiSessionToken(); connectToWifi(makeValidatedNetworkCapabilities()); final Slice wifiSlice = mWifiSlice.getSlice(); assertThat(wifiSlice).isNull(); assertTitleAndIcon(wifiSlice); assertNoToggle(wifiSlice); assertThat(ContextualWifiSlice.getApRowCount()).isEqualTo(COLLAPSED_ROW_COUNT); } @Test public void getWifiSlice_newSession_hasActiveConnection_shouldReturnNull() { // Session: use a non-active value // previous displayed: yes mWifiSlice.sPreviouslyDisplayed = true; public void getWifiSlice_newSession_noConnection_shouldExpandSlice() { mWifiSlice.sActiveUiSession = ~mFeatureFactory.slicesFeatureProvider.getUiSessionToken(); connectToWifi(makeValidatedNetworkCapabilities()); final Slice wifiSlice = mWifiSlice.getSlice(); assertThat(wifiSlice).isNull(); assertTitleAndIcon(wifiSlice); assertToggle(wifiSlice); assertThat(ContextualWifiSlice.getApRowCount()).isEqualTo(DEFAULT_EXPANDED_ROW_COUNT); } @Test public void getWifiSlice_previousDisplayed_hasActiveConnection_shouldHaveTitleAndToggle() { public void getWifiSlice_previousExpanded_hasActiveConnection_shouldExpandSlice() { mWifiSlice.sActiveUiSession = mFeatureFactory.slicesFeatureProvider.getUiSessionToken(); mWifiSlice.sPreviouslyDisplayed = true; mWifiSlice.sToggleNeeded = true; connectToWifi(makeValidatedNetworkCapabilities()); final Slice wifiSlice = mWifiSlice.getSlice(); final SliceMetadata metadata = SliceMetadata.from(mContext, wifiSlice); assertThat(metadata.getTitle()).isEqualTo(mContext.getString(R.string.wifi_settings)); assertTitleAndIcon(wifiSlice); assertToggle(wifiSlice); assertThat(ContextualWifiSlice.getApRowCount()).isEqualTo(DEFAULT_EXPANDED_ROW_COUNT); } final List<SliceAction> toggles = metadata.getToggles(); assertThat(toggles).hasSize(1); @Test public void getWifiSlice_previousExpanded_disableWifi_shouldHaveToggle() { mWifiSlice.sActiveUiSession = mFeatureFactory.slicesFeatureProvider.getUiSessionToken(); mWifiSlice.sToggleNeeded = true; connectToWifi(makeValidatedNetworkCapabilities()); final SliceAction primaryAction = metadata.getPrimaryAction(); final IconCompat expectedToggleIcon = IconCompat.createWithResource(mContext, R.drawable.ic_settings_wireless); assertThat(primaryAction.getIcon().toString()).isEqualTo(expectedToggleIcon.toString()); mWifiManager.setWifiEnabled(false); final Slice wifiSlice = mWifiSlice.getSlice(); assertTitleAndIcon(wifiSlice); assertToggle(wifiSlice); } @Test public void getWifiSlice_isCaptivePortal_shouldHaveTitleAndToggle() { mWifiSlice.sPreviouslyDisplayed = false; connectToWifi(WifiSliceTest.makeCaptivePortalNetworkCapabilities()); public void getWifiSlice_previousCollapsed_disableWifi_shouldHaveToggle() { mWifiSlice.sActiveUiSession = mFeatureFactory.slicesFeatureProvider.getUiSessionToken(); mWifiSlice.sToggleNeeded = false; connectToWifi(makeValidatedNetworkCapabilities()); mWifiManager.setWifiEnabled(false); final Slice wifiSlice = mWifiSlice.getSlice(); final SliceMetadata metadata = SliceMetadata.from(mContext, wifiSlice); assertThat(metadata.getTitle()).isEqualTo(mContext.getString(R.string.wifi_settings)); assertTitleAndIcon(wifiSlice); assertToggle(wifiSlice); } final List<SliceAction> toggles = metadata.getToggles(); assertThat(toggles).hasSize(1); @Test public void getWifiSlice_previousCollapsed_connectionLoss_shouldCollapseSlice() { mWifiSlice.sActiveUiSession = mFeatureFactory.slicesFeatureProvider.getUiSessionToken(); mWifiSlice.sToggleNeeded = false; connectToWifi(makeValidatedNetworkCapabilities()); final SliceAction primaryAction = metadata.getPrimaryAction(); final IconCompat expectedToggleIcon = IconCompat.createWithResource(mContext, R.drawable.ic_settings_wireless); assertThat(primaryAction.getIcon().toString()).isEqualTo(expectedToggleIcon.toString()); mWifiManager.disconnect(); final Slice wifiSlice = mWifiSlice.getSlice(); assertTitleAndIcon(wifiSlice); assertNoToggle(wifiSlice); assertThat(ContextualWifiSlice.getApRowCount()).isEqualTo(COLLAPSED_ROW_COUNT); } @Test public void getWifiSlice_contextualWifiSlice_shouldReturnContextualWifiSliceUri() { mWifiSlice.sActiveUiSession = mFeatureFactory.slicesFeatureProvider.getUiSessionToken(); mWifiSlice.sPreviouslyDisplayed = true; final Slice wifiSlice = mWifiSlice.getSlice(); Loading @@ -165,4 +180,26 @@ public class ContextualWifiSliceTest { nc.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED); return nc; } private void assertTitleAndIcon(Slice slice) { final SliceMetadata metadata = SliceMetadata.from(mContext, slice); assertThat(metadata.getTitle()).isEqualTo(mContext.getString(R.string.wifi_settings)); final SliceAction primaryAction = metadata.getPrimaryAction(); final IconCompat expectedToggleIcon = IconCompat.createWithResource(mContext, R.drawable.ic_settings_wireless); assertThat(primaryAction.getIcon().toString()).isEqualTo(expectedToggleIcon.toString()); } private void assertToggle(Slice slice) { final SliceMetadata metadata = SliceMetadata.from(mContext, slice); final List<SliceAction> toggles = metadata.getToggles(); assertThat(toggles).hasSize(1); } private void assertNoToggle(Slice slice) { final SliceMetadata metadata = SliceMetadata.from(mContext, slice); final List<SliceAction> toggles = metadata.getToggles(); assertThat(toggles).isEmpty(); } } Loading
src/com/android/settings/wifi/slice/ContextualWifiScanWorker.java +5 −0 Original line number Diff line number Diff line Loading @@ -62,4 +62,9 @@ public class ContextualWifiScanWorker extends WifiScanWorker { } return true; } @Override protected int getApRowCount() { return ContextualWifiSlice.getApRowCount(); } } No newline at end of file
src/com/android/settings/wifi/slice/ContextualWifiSlice.java +81 −11 Original line number Diff line number Diff line Loading @@ -17,30 +17,42 @@ package com.android.settings.wifi.slice; import android.content.Context; import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.graphics.drawable.Drawable; import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.State; import android.net.Uri; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.text.TextUtils; import android.util.Log; import androidx.annotation.VisibleForTesting; import androidx.core.graphics.drawable.IconCompat; import androidx.slice.Slice; import androidx.slice.builders.ListBuilder; import com.android.settings.R; import com.android.settings.Utils; import com.android.settings.overlay.FeatureFactory; import com.android.settings.slices.CustomSliceRegistry; import com.android.settings.slices.CustomSliceable; import com.android.settingslib.wifi.AccessPoint; /** * {@link CustomSliceable} for Wi-Fi, used by contextual homepage. */ public class ContextualWifiSlice extends WifiSlice { private static final String TAG = "ContextualWifiSlice"; @VisibleForTesting static final int COLLAPSED_ROW_COUNT = 0; @VisibleForTesting static long sActiveUiSession = -1000; @VisibleForTesting static boolean sPreviouslyDisplayed; static boolean sToggleNeeded = true; public ContextualWifiSlice(Context context) { super(context); Loading @@ -57,17 +69,75 @@ public class ContextualWifiSlice extends WifiSlice { .getSlicesFeatureProvider().getUiSessionToken(); if (currentUiSession != sActiveUiSession) { sActiveUiSession = currentUiSession; sPreviouslyDisplayed = false; sToggleNeeded = !hasWorkingNetwork(); } else if (!mWifiManager.isWifiEnabled()) { sToggleNeeded = true; } if (!sPreviouslyDisplayed && hasWorkingNetwork()) { Log.d(TAG, "Wifi is connected, no point showing any suggestion."); return null; return super.getSlice(); } // Set sPreviouslyDisplayed to true - we will show *something* on the screen. So we should // keep showing this card to keep UI stable, even if wifi connects to a network later. sPreviouslyDisplayed = true; return super.getSlice(); static int getApRowCount() { return sToggleNeeded ? DEFAULT_EXPANDED_ROW_COUNT : COLLAPSED_ROW_COUNT; } @Override protected boolean isToggleNeeded() { return sToggleNeeded; } @Override protected ListBuilder.RowBuilder getHeaderRow(AccessPoint accessPoint) { final ListBuilder.RowBuilder builder = super.getHeaderRow(accessPoint); if (!sToggleNeeded) { builder.setTitleItem(getLevelIcon(accessPoint), ListBuilder.ICON_IMAGE) .setSubtitle(getSubtitle(accessPoint)); } return builder; } private IconCompat getLevelIcon(AccessPoint accessPoint) { if (accessPoint != null) { return getAccessPointLevelIcon(accessPoint); } final Drawable drawable = mContext.getDrawable( com.android.settingslib.Utils.getWifiIconResource(0)); final int color = Utils.getColorAttrDefaultColor(mContext, android.R.attr.colorControlNormal); drawable.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN)); return Utils.createIconWithDrawable(drawable); } private CharSequence getSubtitle(AccessPoint accessPoint) { if (isCaptivePortal()) { final int id = mContext.getResources() .getIdentifier("network_available_sign_in", "string", "android"); return mContext.getText(id); } if (accessPoint == null) { return mContext.getText(R.string.disconnected); } final NetworkInfo networkInfo = accessPoint.getNetworkInfo(); if (networkInfo == null) { return mContext.getText(R.string.disconnected); } final State state = networkInfo.getState(); DetailedState detailedState; if (state == State.CONNECTING) { detailedState = DetailedState.CONNECTING; } else if (state == State.CONNECTED) { detailedState = DetailedState.CONNECTED; } else { detailedState = networkInfo.getDetailedState(); } final String[] formats = mContext.getResources().getStringArray( R.array.wifi_status_with_ssid); final int index = detailedState.ordinal(); return String.format(formats[index], accessPoint.getTitle()); } private boolean hasWorkingNetwork() { Loading
src/com/android/settings/wifi/slice/WifiScanWorker.java +6 −1 Original line number Diff line number Diff line Loading @@ -111,10 +111,11 @@ public class WifiScanWorker extends SliceBackgroundWorker<AccessPoint> implement // AccessPoints are sorted by the WifiTracker final List<AccessPoint> accessPoints = mWifiTracker.getAccessPoints(); final List<AccessPoint> resultList = new ArrayList<>(); final int apRowCount = getApRowCount(); for (AccessPoint ap : accessPoints) { if (ap.isReachable()) { resultList.add(clone(ap)); if (resultList.size() >= DEFAULT_EXPANDED_ROW_COUNT) { if (resultList.size() >= apRowCount) { break; } } Loading @@ -122,6 +123,10 @@ public class WifiScanWorker extends SliceBackgroundWorker<AccessPoint> implement updateResults(resultList); } protected int getApRowCount() { return DEFAULT_EXPANDED_ROW_COUNT; } private AccessPoint clone(AccessPoint accessPoint) { final Bundle savedState = new Bundle(); accessPoint.saveWifiState(savedState); Loading
src/com/android/settings/wifi/slice/WifiSlice.java +35 −39 Original line number Diff line number Diff line Loading @@ -95,7 +95,7 @@ public class WifiSlice implements CustomSliceable { mContext.getTheme().applyStyle(R.style.Theme_Settings_Home, true /* force */); final boolean isWifiEnabled = isWifiEnabled(); ListBuilder listBuilder = getHeaderRow(isWifiEnabled); ListBuilder listBuilder = getListBuilder(isWifiEnabled, null /* accessPoint */); if (!isWifiEnabled) { WifiScanWorker.clearClickedWifi(); return listBuilder.build(); Loading @@ -107,17 +107,12 @@ public class WifiSlice implements CustomSliceable { final boolean isFirstApActive = apCount > 0 && apList.get(0).isActive(); handleNetworkCallback(worker, isFirstApActive); // Need a loading text when results are not ready or out of date. boolean needLoadingRow = true; // Skip checking the existence of the first access point if it's active int index = isFirstApActive ? 1 : 0; // This loop checks the existence of reachable APs to determine the validity of the current // AP list. for (; index < apCount; index++) { if (apList.get(index).isReachable()) { needLoadingRow = false; break; if (!isToggleNeeded()) { if (isFirstApActive) { // refresh header subtext listBuilder = getListBuilder(true /* isWifiEnabled */, apList.get(0)); } return listBuilder.build(); } // Add AP rows Loading @@ -125,9 +120,8 @@ public class WifiSlice implements CustomSliceable { for (int i = 0; i < DEFAULT_EXPANDED_ROW_COUNT; i++) { if (i < apCount) { listBuilder.addRow(getAccessPointRow(apList.get(i))); } else if (needLoadingRow) { } else if (i == apCount) { listBuilder.addRow(getLoadingRow(placeholder)); needLoadingRow = false; } else { listBuilder.addRow(new ListBuilder.RowBuilder() .setTitle(placeholder) Loading @@ -148,24 +142,34 @@ public class WifiSlice implements CustomSliceable { } } private ListBuilder getHeaderRow(boolean isWifiEnabled) { protected boolean isToggleNeeded() { return true; } protected ListBuilder.RowBuilder getHeaderRow(AccessPoint accessPoint) { final IconCompat icon = IconCompat.createWithResource(mContext, R.drawable.ic_settings_wireless); final String title = mContext.getString(R.string.wifi_settings); final PendingIntent toggleAction = getBroadcastIntent(mContext); final PendingIntent primaryAction = getPrimaryAction(); final SliceAction primarySliceAction = SliceAction.createDeeplink(primaryAction, icon, ListBuilder.ICON_IMAGE, title); final SliceAction toggleSliceAction = SliceAction.createToggle(toggleAction, null /* actionTitle */, isWifiEnabled); return new ListBuilder(mContext, getUri(), ListBuilder.INFINITY) return new ListBuilder.RowBuilder() .setTitle(title) .setPrimaryAction(primarySliceAction); } private ListBuilder getListBuilder(boolean isWifiEnabled, AccessPoint accessPoint) { final ListBuilder builder = new ListBuilder(mContext, getUri(), ListBuilder.INFINITY) .setAccentColor(COLOR_NOT_TINTED) .setKeywords(getKeywords()) .addRow(new ListBuilder.RowBuilder() .setTitle(title) .addEndItem(toggleSliceAction) .setPrimaryAction(primarySliceAction)); .addRow(getHeaderRow(accessPoint)); if (isToggleNeeded()) { final PendingIntent toggleAction = getBroadcastIntent(mContext); builder.addAction(SliceAction.createToggle(toggleAction, null /* actionTitle */, isWifiEnabled)); } return builder; } private ListBuilder.RowBuilder getAccessPointRow(AccessPoint accessPoint) { Loading Loading @@ -200,7 +204,7 @@ public class WifiSlice implements CustomSliceable { return TextUtils.isEmpty(summary) ? mContext.getText(R.string.disconnected) : summary; } private IconCompat getAccessPointLevelIcon(AccessPoint accessPoint) { protected IconCompat getAccessPointLevelIcon(AccessPoint accessPoint) { final Drawable d = mContext.getDrawable( com.android.settingslib.Utils.getWifiIconResource(accessPoint.getLevel())); Loading Loading @@ -250,24 +254,16 @@ public class WifiSlice implements CustomSliceable { accessPoint.saveWifiState(extras); if (accessPoint.isActive()) { Intent intent; if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_WIFITRACKER2)) { intent = new SubSettingLauncher(mContext) final SubSettingLauncher launcher = new SubSettingLauncher(mContext) .setTitleRes(R.string.pref_title_network_details) .setDestination(WifiNetworkDetailsFragment2.class.getName()) .setArguments(extras) .setSourceMetricsCategory(SettingsEnums.WIFI) .toIntent(); return getActivityAction(requestCode, intent, icon, title); .setSourceMetricsCategory(SettingsEnums.WIFI); if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_WIFITRACKER2)) { launcher.setDestination(WifiNetworkDetailsFragment2.class.getName()); } else { intent = new SubSettingLauncher(mContext) .setTitleRes(R.string.pref_title_network_details) .setDestination(WifiNetworkDetailsFragment.class.getName()) .setArguments(extras) .setSourceMetricsCategory(SettingsEnums.WIFI) .toIntent(); return getActivityAction(requestCode, intent, icon, title); launcher.setDestination(WifiNetworkDetailsFragment.class.getName()); } return getActivityAction(requestCode, launcher.toIntent(), icon, title); } else if (WifiUtils.getConnectingType(accessPoint) != WifiUtils.CONNECT_TYPE_OTHERS) { final Intent intent = new Intent(mContext, ConnectToWifiHandler.class) .putExtra(WifiDialogActivity.KEY_ACCESS_POINT_STATE, extras); Loading Loading @@ -307,7 +303,7 @@ public class WifiSlice implements CustomSliceable { .setSubtitle(title); } private boolean isCaptivePortal() { protected boolean isCaptivePortal() { final NetworkCapabilities nc = mConnectivityManager.getNetworkCapabilities( mWifiManager.getCurrentNetwork()); return WifiUtils.canSignIntoNetwork(nc); Loading
tests/robotests/src/com/android/settings/wifi/slice/ContextualWifiSliceTest.java +69 −32 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ package com.android.settings.wifi.slice; import static com.android.settings.wifi.slice.ContextualWifiSlice.COLLAPSED_ROW_COUNT; import static com.android.settings.wifi.slice.WifiSlice.DEFAULT_EXPANDED_ROW_COUNT; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.doReturn; Loading Loading @@ -75,75 +78,87 @@ public class ContextualWifiSliceTest { mWifiManager.setWifiEnabled(true); mWifiSlice = new ContextualWifiSlice(mContext); mWifiSlice.sPreviouslyDisplayed = false; } @Test public void getWifiSlice_hasActiveConnection_shouldReturnNull() { mWifiSlice.sPreviouslyDisplayed = false; public void getWifiSlice_newSession_hasActiveConnection_shouldCollapseSlice() { mWifiSlice.sActiveUiSession = ~mFeatureFactory.slicesFeatureProvider.getUiSessionToken(); connectToWifi(makeValidatedNetworkCapabilities()); final Slice wifiSlice = mWifiSlice.getSlice(); assertThat(wifiSlice).isNull(); assertTitleAndIcon(wifiSlice); assertNoToggle(wifiSlice); assertThat(ContextualWifiSlice.getApRowCount()).isEqualTo(COLLAPSED_ROW_COUNT); } @Test public void getWifiSlice_newSession_hasActiveConnection_shouldReturnNull() { // Session: use a non-active value // previous displayed: yes mWifiSlice.sPreviouslyDisplayed = true; public void getWifiSlice_newSession_noConnection_shouldExpandSlice() { mWifiSlice.sActiveUiSession = ~mFeatureFactory.slicesFeatureProvider.getUiSessionToken(); connectToWifi(makeValidatedNetworkCapabilities()); final Slice wifiSlice = mWifiSlice.getSlice(); assertThat(wifiSlice).isNull(); assertTitleAndIcon(wifiSlice); assertToggle(wifiSlice); assertThat(ContextualWifiSlice.getApRowCount()).isEqualTo(DEFAULT_EXPANDED_ROW_COUNT); } @Test public void getWifiSlice_previousDisplayed_hasActiveConnection_shouldHaveTitleAndToggle() { public void getWifiSlice_previousExpanded_hasActiveConnection_shouldExpandSlice() { mWifiSlice.sActiveUiSession = mFeatureFactory.slicesFeatureProvider.getUiSessionToken(); mWifiSlice.sPreviouslyDisplayed = true; mWifiSlice.sToggleNeeded = true; connectToWifi(makeValidatedNetworkCapabilities()); final Slice wifiSlice = mWifiSlice.getSlice(); final SliceMetadata metadata = SliceMetadata.from(mContext, wifiSlice); assertThat(metadata.getTitle()).isEqualTo(mContext.getString(R.string.wifi_settings)); assertTitleAndIcon(wifiSlice); assertToggle(wifiSlice); assertThat(ContextualWifiSlice.getApRowCount()).isEqualTo(DEFAULT_EXPANDED_ROW_COUNT); } final List<SliceAction> toggles = metadata.getToggles(); assertThat(toggles).hasSize(1); @Test public void getWifiSlice_previousExpanded_disableWifi_shouldHaveToggle() { mWifiSlice.sActiveUiSession = mFeatureFactory.slicesFeatureProvider.getUiSessionToken(); mWifiSlice.sToggleNeeded = true; connectToWifi(makeValidatedNetworkCapabilities()); final SliceAction primaryAction = metadata.getPrimaryAction(); final IconCompat expectedToggleIcon = IconCompat.createWithResource(mContext, R.drawable.ic_settings_wireless); assertThat(primaryAction.getIcon().toString()).isEqualTo(expectedToggleIcon.toString()); mWifiManager.setWifiEnabled(false); final Slice wifiSlice = mWifiSlice.getSlice(); assertTitleAndIcon(wifiSlice); assertToggle(wifiSlice); } @Test public void getWifiSlice_isCaptivePortal_shouldHaveTitleAndToggle() { mWifiSlice.sPreviouslyDisplayed = false; connectToWifi(WifiSliceTest.makeCaptivePortalNetworkCapabilities()); public void getWifiSlice_previousCollapsed_disableWifi_shouldHaveToggle() { mWifiSlice.sActiveUiSession = mFeatureFactory.slicesFeatureProvider.getUiSessionToken(); mWifiSlice.sToggleNeeded = false; connectToWifi(makeValidatedNetworkCapabilities()); mWifiManager.setWifiEnabled(false); final Slice wifiSlice = mWifiSlice.getSlice(); final SliceMetadata metadata = SliceMetadata.from(mContext, wifiSlice); assertThat(metadata.getTitle()).isEqualTo(mContext.getString(R.string.wifi_settings)); assertTitleAndIcon(wifiSlice); assertToggle(wifiSlice); } final List<SliceAction> toggles = metadata.getToggles(); assertThat(toggles).hasSize(1); @Test public void getWifiSlice_previousCollapsed_connectionLoss_shouldCollapseSlice() { mWifiSlice.sActiveUiSession = mFeatureFactory.slicesFeatureProvider.getUiSessionToken(); mWifiSlice.sToggleNeeded = false; connectToWifi(makeValidatedNetworkCapabilities()); final SliceAction primaryAction = metadata.getPrimaryAction(); final IconCompat expectedToggleIcon = IconCompat.createWithResource(mContext, R.drawable.ic_settings_wireless); assertThat(primaryAction.getIcon().toString()).isEqualTo(expectedToggleIcon.toString()); mWifiManager.disconnect(); final Slice wifiSlice = mWifiSlice.getSlice(); assertTitleAndIcon(wifiSlice); assertNoToggle(wifiSlice); assertThat(ContextualWifiSlice.getApRowCount()).isEqualTo(COLLAPSED_ROW_COUNT); } @Test public void getWifiSlice_contextualWifiSlice_shouldReturnContextualWifiSliceUri() { mWifiSlice.sActiveUiSession = mFeatureFactory.slicesFeatureProvider.getUiSessionToken(); mWifiSlice.sPreviouslyDisplayed = true; final Slice wifiSlice = mWifiSlice.getSlice(); Loading @@ -165,4 +180,26 @@ public class ContextualWifiSliceTest { nc.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED); return nc; } private void assertTitleAndIcon(Slice slice) { final SliceMetadata metadata = SliceMetadata.from(mContext, slice); assertThat(metadata.getTitle()).isEqualTo(mContext.getString(R.string.wifi_settings)); final SliceAction primaryAction = metadata.getPrimaryAction(); final IconCompat expectedToggleIcon = IconCompat.createWithResource(mContext, R.drawable.ic_settings_wireless); assertThat(primaryAction.getIcon().toString()).isEqualTo(expectedToggleIcon.toString()); } private void assertToggle(Slice slice) { final SliceMetadata metadata = SliceMetadata.from(mContext, slice); final List<SliceAction> toggles = metadata.getToggles(); assertThat(toggles).hasSize(1); } private void assertNoToggle(Slice slice) { final SliceMetadata metadata = SliceMetadata.from(mContext, slice); final List<SliceAction> toggles = metadata.getToggles(); assertThat(toggles).isEmpty(); } }