Loading src/com/android/settings/slices/SliceBackgroundWorker.java +7 −6 Original line number Diff line number Diff line Loading @@ -68,16 +68,17 @@ public abstract class SliceBackgroundWorker<E> implements Closeable { } /** * Returns the singleton instance of the {@link SliceBackgroundWorker} for specified {@link Uri} * if exists * Returns the singleton instance of {@link SliceBackgroundWorker} for specified {@link Uri} if * exists */ @Nullable public static SliceBackgroundWorker getInstance(Uri uri) { return LIVE_WORKERS.get(uri); @SuppressWarnings("TypeParameterUnusedInFormals") public static <T extends SliceBackgroundWorker> T getInstance(Uri uri) { return (T) LIVE_WORKERS.get(uri); } /** * Returns the singleton instance of the {@link SliceBackgroundWorker} for specified {@link * Returns the singleton instance of {@link SliceBackgroundWorker} for specified {@link * CustomSliceable} */ static SliceBackgroundWorker getInstance(Context context, Sliceable sliceable, Uri uri) { Loading src/com/android/settings/wifi/slice/ConnectToWifiHandler.java +8 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ package com.android.settings.wifi.slice; import android.app.Activity; import android.net.ConnectivityManager; import android.net.Network; import android.net.wifi.WifiManager; import android.os.Bundle; Loading @@ -36,10 +38,15 @@ public class ConnectToWifiHandler extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); final Network network = getIntent().getParcelableExtra(ConnectivityManager.EXTRA_NETWORK); final Bundle accessPointState = getIntent().getBundleExtra( WifiDialogActivity.KEY_ACCESS_POINT_STATE); if (accessPointState != null) { if (network != null) { final ConnectivityManager cm = getSystemService(ConnectivityManager.class); // start captive portal app to sign in to network cm.startCaptivePortalApp(network); } else if (accessPointState != null) { connect(new AccessPoint(this, accessPointState)); } finish(); Loading src/com/android/settings/wifi/slice/ContextualWifiSlice.java +5 −1 Original line number Diff line number Diff line Loading @@ -57,7 +57,7 @@ public class ContextualWifiSlice extends WifiSlice { sActiveUiSession = currentUiSession; sPreviouslyDisplayed = false; } if (!sPreviouslyDisplayed && !TextUtils.equals(getActiveSSID(), WifiSsid.NONE)) { if (!sPreviouslyDisplayed && hasWorkingNetwork()) { Log.d(TAG, "Wifi is connected, no point showing any suggestion."); return null; } Loading @@ -67,4 +67,8 @@ public class ContextualWifiSlice extends WifiSlice { return super.getSlice(); } private boolean hasWorkingNetwork() { return !TextUtils.equals(getActiveSSID(), WifiSsid.NONE) && !isCaptivePortal(); } } src/com/android/settings/wifi/slice/WifiScanWorker.java +91 −3 Original line number Diff line number Diff line Loading @@ -16,14 +16,27 @@ package com.android.settings.wifi.slice; import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static com.android.settings.wifi.slice.WifiSlice.DEFAULT_EXPANDED_ROW_COUNT; import android.content.Context; import android.net.ConnectivityManager; import android.net.ConnectivityManager.NetworkCallback; import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.NetworkRequest; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.util.Log; import androidx.annotation.VisibleForTesting; import com.android.internal.util.Preconditions; import com.android.settings.slices.SliceBackgroundWorker; import com.android.settings.wifi.WifiUtils; import com.android.settingslib.wifi.AccessPoint; import com.android.settingslib.wifi.WifiTracker; Loading @@ -33,16 +46,23 @@ import java.util.List; /** * {@link SliceBackgroundWorker} for Wi-Fi, used by WifiSlice. */ public class WifiScanWorker extends SliceBackgroundWorker<AccessPoint> implements WifiTracker.WifiListener { public class WifiScanWorker extends SliceBackgroundWorker<AccessPoint> implements WifiTracker.WifiListener { private static final String TAG = "WifiScanWorker"; @VisibleForTesting CaptivePortalNetworkCallback mCaptivePortalNetworkCallback; private final Context mContext; private WifiTracker mWifiTracker; private ConnectivityManager mConnectivityManager; public WifiScanWorker(Context context, Uri uri) { super(context, uri); mContext = context; mConnectivityManager = context.getSystemService(ConnectivityManager.class); } @Override Loading @@ -58,6 +78,7 @@ public class WifiScanWorker extends SliceBackgroundWorker<AccessPoint> @Override protected void onSliceUnpinned() { mWifiTracker.onStop(); unregisterCaptivePortalNetworkCallback(); } @Override Loading Loading @@ -124,4 +145,71 @@ public class WifiScanWorker extends SliceBackgroundWorker<AccessPoint> } return null; } public void registerCaptivePortalNetworkCallback(Network wifiNetwork) { if (wifiNetwork == null) { return; } if (mCaptivePortalNetworkCallback != null && mCaptivePortalNetworkCallback.isSameNetwork(wifiNetwork)) { return; } unregisterCaptivePortalNetworkCallback(); mCaptivePortalNetworkCallback = new CaptivePortalNetworkCallback(wifiNetwork); mConnectivityManager.registerNetworkCallback( new NetworkRequest.Builder() .clearCapabilities() .addTransportType(TRANSPORT_WIFI) .build(), mCaptivePortalNetworkCallback, new Handler(Looper.getMainLooper())); } public void unregisterCaptivePortalNetworkCallback() { if (mCaptivePortalNetworkCallback != null) { try { mConnectivityManager.unregisterNetworkCallback(mCaptivePortalNetworkCallback); } catch (RuntimeException e) { Log.e(TAG, "Unregistering CaptivePortalNetworkCallback failed.", e); } mCaptivePortalNetworkCallback = null; } } class CaptivePortalNetworkCallback extends NetworkCallback { private final Network mNetwork; private boolean mIsCaptivePortal; CaptivePortalNetworkCallback(Network network) { mNetwork = Preconditions.checkNotNull(network); } @Override public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) { if (!mNetwork.equals(network)) { return; } final boolean isCaptivePortal = WifiUtils.canSignIntoNetwork(networkCapabilities); if (mIsCaptivePortal == isCaptivePortal) { return; } mIsCaptivePortal = isCaptivePortal; notifySliceChange(); } /** * Returns true if the supplied network is not null and is the same as the originally * supplied value. */ public boolean isSameNetwork(Network network) { return mNetwork.equals(network); } } } src/com/android/settings/wifi/slice/WifiSlice.java +55 −10 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.net.ConnectivityManager; import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.NetworkInfo.State; import android.net.NetworkInfo.DetailedState; Loading Loading @@ -78,10 +80,12 @@ public class WifiSlice implements CustomSliceable { protected final Context mContext; protected final WifiManager mWifiManager; protected final ConnectivityManager mConnectivityManager; public WifiSlice(Context context) { mContext = context; mWifiManager = mContext.getSystemService(WifiManager.class); mConnectivityManager = mContext.getSystemService(ConnectivityManager.class); } @Override Loading @@ -100,13 +104,16 @@ public class WifiSlice implements CustomSliceable { return listBuilder.build(); } final SliceBackgroundWorker worker = SliceBackgroundWorker.getInstance(getUri()); final WifiScanWorker worker = SliceBackgroundWorker.getInstance(getUri()); final List<AccessPoint> results = worker != null ? worker.getResults() : null; final int apCount = results == null ? 0 : results.size(); final boolean isFirstApActive = apCount > 0 && results.get(0).isActive(); handleCaptivePortalCallback(worker, isFirstApActive); // Need a loading text when results are not ready or out of date. boolean needLoadingRow = true; int index = apCount > 0 && results.get(0).isActive() ? 1 : 0; // 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++) { Loading Loading @@ -159,20 +166,36 @@ public class WifiSlice implements CustomSliceable { .setPrimaryAction(primarySliceAction)); } private void handleCaptivePortalCallback(WifiScanWorker worker, boolean isFirstApActive) { if (worker == null) { return; } if (isFirstApActive) { worker.registerCaptivePortalNetworkCallback(mWifiManager.getCurrentNetwork()); } else { worker.unregisterCaptivePortalNetworkCallback(); } } private ListBuilder.RowBuilder getAccessPointRow(AccessPoint accessPoint) { final CharSequence title = getAccessPointName(accessPoint); final IconCompat levelIcon = getAccessPointLevelIcon(accessPoint); final boolean isCaptivePortal = accessPoint.isActive() && isCaptivePortal(); final ListBuilder.RowBuilder rowBuilder = new ListBuilder.RowBuilder() .setTitleItem(levelIcon, ListBuilder.ICON_IMAGE) .setSubtitle(title) .setPrimaryAction(SliceAction.create( getAccessPointAction(accessPoint), levelIcon, ListBuilder.ICON_IMAGE, title)); .setPrimaryAction(SliceAction.createDeeplink( getAccessPointAction(accessPoint, isCaptivePortal), levelIcon, ListBuilder.ICON_IMAGE, title)); if (isCaptivePortal) { rowBuilder.addEndItem(getCaptivePortalEndAction(accessPoint, title)); } else { final IconCompat endIcon = getEndIcon(accessPoint); if (endIcon != null) { rowBuilder.addEndItem(endIcon, ListBuilder.ICON_IMAGE); } } return rowBuilder; } Loading Loading @@ -218,12 +241,22 @@ public class WifiSlice implements CustomSliceable { return null; } private PendingIntent getAccessPointAction(AccessPoint accessPoint) { private SliceAction getCaptivePortalEndAction(AccessPoint accessPoint, CharSequence title) { return SliceAction.createDeeplink( getAccessPointAction(accessPoint, false /* isCaptivePortal */), IconCompat.createWithResource(mContext, R.drawable.ic_settings_accent), ListBuilder.ICON_IMAGE, title); } private PendingIntent getAccessPointAction(AccessPoint accessPoint, boolean isCaptivePortal) { final Bundle extras = new Bundle(); accessPoint.saveWifiState(extras); Intent intent; if (accessPoint.isActive()) { if (isCaptivePortal) { intent = new Intent(mContext, ConnectToWifiHandler.class); intent.putExtra(ConnectivityManager.EXTRA_NETWORK, mWifiManager.getCurrentNetwork()); } else if (accessPoint.isActive()) { intent = new SubSettingLauncher(mContext) .setTitleRes(R.string.pref_title_network_details) .setDestination(WifiNetworkDetailsFragment.class.getName()) Loading Loading @@ -253,6 +286,12 @@ public class WifiSlice implements CustomSliceable { .setSubtitle(title); } protected boolean isCaptivePortal() { final NetworkCapabilities nc = mConnectivityManager.getNetworkCapabilities( mWifiManager.getCurrentNetwork()); return WifiUtils.canSignIntoNetwork(nc); } /** * Update the current wifi status to the boolean value keyed by * {@link android.app.slice.Slice#EXTRA_TOGGLE_STATE} on {@param intent}. Loading Loading @@ -317,6 +356,12 @@ public class WifiSlice implements CustomSliceable { } private CharSequence getSummary(AccessPoint accessPoint) { if (isCaptivePortal()) { final int id = mContext.getResources() .getIdentifier("network_available_sign_in", "string", "android"); return mContext.getText(id); } if (accessPoint == null) { return getSummary(); } Loading Loading
src/com/android/settings/slices/SliceBackgroundWorker.java +7 −6 Original line number Diff line number Diff line Loading @@ -68,16 +68,17 @@ public abstract class SliceBackgroundWorker<E> implements Closeable { } /** * Returns the singleton instance of the {@link SliceBackgroundWorker} for specified {@link Uri} * if exists * Returns the singleton instance of {@link SliceBackgroundWorker} for specified {@link Uri} if * exists */ @Nullable public static SliceBackgroundWorker getInstance(Uri uri) { return LIVE_WORKERS.get(uri); @SuppressWarnings("TypeParameterUnusedInFormals") public static <T extends SliceBackgroundWorker> T getInstance(Uri uri) { return (T) LIVE_WORKERS.get(uri); } /** * Returns the singleton instance of the {@link SliceBackgroundWorker} for specified {@link * Returns the singleton instance of {@link SliceBackgroundWorker} for specified {@link * CustomSliceable} */ static SliceBackgroundWorker getInstance(Context context, Sliceable sliceable, Uri uri) { Loading
src/com/android/settings/wifi/slice/ConnectToWifiHandler.java +8 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ package com.android.settings.wifi.slice; import android.app.Activity; import android.net.ConnectivityManager; import android.net.Network; import android.net.wifi.WifiManager; import android.os.Bundle; Loading @@ -36,10 +38,15 @@ public class ConnectToWifiHandler extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); final Network network = getIntent().getParcelableExtra(ConnectivityManager.EXTRA_NETWORK); final Bundle accessPointState = getIntent().getBundleExtra( WifiDialogActivity.KEY_ACCESS_POINT_STATE); if (accessPointState != null) { if (network != null) { final ConnectivityManager cm = getSystemService(ConnectivityManager.class); // start captive portal app to sign in to network cm.startCaptivePortalApp(network); } else if (accessPointState != null) { connect(new AccessPoint(this, accessPointState)); } finish(); Loading
src/com/android/settings/wifi/slice/ContextualWifiSlice.java +5 −1 Original line number Diff line number Diff line Loading @@ -57,7 +57,7 @@ public class ContextualWifiSlice extends WifiSlice { sActiveUiSession = currentUiSession; sPreviouslyDisplayed = false; } if (!sPreviouslyDisplayed && !TextUtils.equals(getActiveSSID(), WifiSsid.NONE)) { if (!sPreviouslyDisplayed && hasWorkingNetwork()) { Log.d(TAG, "Wifi is connected, no point showing any suggestion."); return null; } Loading @@ -67,4 +67,8 @@ public class ContextualWifiSlice extends WifiSlice { return super.getSlice(); } private boolean hasWorkingNetwork() { return !TextUtils.equals(getActiveSSID(), WifiSsid.NONE) && !isCaptivePortal(); } }
src/com/android/settings/wifi/slice/WifiScanWorker.java +91 −3 Original line number Diff line number Diff line Loading @@ -16,14 +16,27 @@ package com.android.settings.wifi.slice; import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static com.android.settings.wifi.slice.WifiSlice.DEFAULT_EXPANDED_ROW_COUNT; import android.content.Context; import android.net.ConnectivityManager; import android.net.ConnectivityManager.NetworkCallback; import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.NetworkRequest; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.util.Log; import androidx.annotation.VisibleForTesting; import com.android.internal.util.Preconditions; import com.android.settings.slices.SliceBackgroundWorker; import com.android.settings.wifi.WifiUtils; import com.android.settingslib.wifi.AccessPoint; import com.android.settingslib.wifi.WifiTracker; Loading @@ -33,16 +46,23 @@ import java.util.List; /** * {@link SliceBackgroundWorker} for Wi-Fi, used by WifiSlice. */ public class WifiScanWorker extends SliceBackgroundWorker<AccessPoint> implements WifiTracker.WifiListener { public class WifiScanWorker extends SliceBackgroundWorker<AccessPoint> implements WifiTracker.WifiListener { private static final String TAG = "WifiScanWorker"; @VisibleForTesting CaptivePortalNetworkCallback mCaptivePortalNetworkCallback; private final Context mContext; private WifiTracker mWifiTracker; private ConnectivityManager mConnectivityManager; public WifiScanWorker(Context context, Uri uri) { super(context, uri); mContext = context; mConnectivityManager = context.getSystemService(ConnectivityManager.class); } @Override Loading @@ -58,6 +78,7 @@ public class WifiScanWorker extends SliceBackgroundWorker<AccessPoint> @Override protected void onSliceUnpinned() { mWifiTracker.onStop(); unregisterCaptivePortalNetworkCallback(); } @Override Loading Loading @@ -124,4 +145,71 @@ public class WifiScanWorker extends SliceBackgroundWorker<AccessPoint> } return null; } public void registerCaptivePortalNetworkCallback(Network wifiNetwork) { if (wifiNetwork == null) { return; } if (mCaptivePortalNetworkCallback != null && mCaptivePortalNetworkCallback.isSameNetwork(wifiNetwork)) { return; } unregisterCaptivePortalNetworkCallback(); mCaptivePortalNetworkCallback = new CaptivePortalNetworkCallback(wifiNetwork); mConnectivityManager.registerNetworkCallback( new NetworkRequest.Builder() .clearCapabilities() .addTransportType(TRANSPORT_WIFI) .build(), mCaptivePortalNetworkCallback, new Handler(Looper.getMainLooper())); } public void unregisterCaptivePortalNetworkCallback() { if (mCaptivePortalNetworkCallback != null) { try { mConnectivityManager.unregisterNetworkCallback(mCaptivePortalNetworkCallback); } catch (RuntimeException e) { Log.e(TAG, "Unregistering CaptivePortalNetworkCallback failed.", e); } mCaptivePortalNetworkCallback = null; } } class CaptivePortalNetworkCallback extends NetworkCallback { private final Network mNetwork; private boolean mIsCaptivePortal; CaptivePortalNetworkCallback(Network network) { mNetwork = Preconditions.checkNotNull(network); } @Override public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) { if (!mNetwork.equals(network)) { return; } final boolean isCaptivePortal = WifiUtils.canSignIntoNetwork(networkCapabilities); if (mIsCaptivePortal == isCaptivePortal) { return; } mIsCaptivePortal = isCaptivePortal; notifySliceChange(); } /** * Returns true if the supplied network is not null and is the same as the originally * supplied value. */ public boolean isSameNetwork(Network network) { return mNetwork.equals(network); } } }
src/com/android/settings/wifi/slice/WifiSlice.java +55 −10 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.net.ConnectivityManager; import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.NetworkInfo.State; import android.net.NetworkInfo.DetailedState; Loading Loading @@ -78,10 +80,12 @@ public class WifiSlice implements CustomSliceable { protected final Context mContext; protected final WifiManager mWifiManager; protected final ConnectivityManager mConnectivityManager; public WifiSlice(Context context) { mContext = context; mWifiManager = mContext.getSystemService(WifiManager.class); mConnectivityManager = mContext.getSystemService(ConnectivityManager.class); } @Override Loading @@ -100,13 +104,16 @@ public class WifiSlice implements CustomSliceable { return listBuilder.build(); } final SliceBackgroundWorker worker = SliceBackgroundWorker.getInstance(getUri()); final WifiScanWorker worker = SliceBackgroundWorker.getInstance(getUri()); final List<AccessPoint> results = worker != null ? worker.getResults() : null; final int apCount = results == null ? 0 : results.size(); final boolean isFirstApActive = apCount > 0 && results.get(0).isActive(); handleCaptivePortalCallback(worker, isFirstApActive); // Need a loading text when results are not ready or out of date. boolean needLoadingRow = true; int index = apCount > 0 && results.get(0).isActive() ? 1 : 0; // 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++) { Loading Loading @@ -159,20 +166,36 @@ public class WifiSlice implements CustomSliceable { .setPrimaryAction(primarySliceAction)); } private void handleCaptivePortalCallback(WifiScanWorker worker, boolean isFirstApActive) { if (worker == null) { return; } if (isFirstApActive) { worker.registerCaptivePortalNetworkCallback(mWifiManager.getCurrentNetwork()); } else { worker.unregisterCaptivePortalNetworkCallback(); } } private ListBuilder.RowBuilder getAccessPointRow(AccessPoint accessPoint) { final CharSequence title = getAccessPointName(accessPoint); final IconCompat levelIcon = getAccessPointLevelIcon(accessPoint); final boolean isCaptivePortal = accessPoint.isActive() && isCaptivePortal(); final ListBuilder.RowBuilder rowBuilder = new ListBuilder.RowBuilder() .setTitleItem(levelIcon, ListBuilder.ICON_IMAGE) .setSubtitle(title) .setPrimaryAction(SliceAction.create( getAccessPointAction(accessPoint), levelIcon, ListBuilder.ICON_IMAGE, title)); .setPrimaryAction(SliceAction.createDeeplink( getAccessPointAction(accessPoint, isCaptivePortal), levelIcon, ListBuilder.ICON_IMAGE, title)); if (isCaptivePortal) { rowBuilder.addEndItem(getCaptivePortalEndAction(accessPoint, title)); } else { final IconCompat endIcon = getEndIcon(accessPoint); if (endIcon != null) { rowBuilder.addEndItem(endIcon, ListBuilder.ICON_IMAGE); } } return rowBuilder; } Loading Loading @@ -218,12 +241,22 @@ public class WifiSlice implements CustomSliceable { return null; } private PendingIntent getAccessPointAction(AccessPoint accessPoint) { private SliceAction getCaptivePortalEndAction(AccessPoint accessPoint, CharSequence title) { return SliceAction.createDeeplink( getAccessPointAction(accessPoint, false /* isCaptivePortal */), IconCompat.createWithResource(mContext, R.drawable.ic_settings_accent), ListBuilder.ICON_IMAGE, title); } private PendingIntent getAccessPointAction(AccessPoint accessPoint, boolean isCaptivePortal) { final Bundle extras = new Bundle(); accessPoint.saveWifiState(extras); Intent intent; if (accessPoint.isActive()) { if (isCaptivePortal) { intent = new Intent(mContext, ConnectToWifiHandler.class); intent.putExtra(ConnectivityManager.EXTRA_NETWORK, mWifiManager.getCurrentNetwork()); } else if (accessPoint.isActive()) { intent = new SubSettingLauncher(mContext) .setTitleRes(R.string.pref_title_network_details) .setDestination(WifiNetworkDetailsFragment.class.getName()) Loading Loading @@ -253,6 +286,12 @@ public class WifiSlice implements CustomSliceable { .setSubtitle(title); } protected boolean isCaptivePortal() { final NetworkCapabilities nc = mConnectivityManager.getNetworkCapabilities( mWifiManager.getCurrentNetwork()); return WifiUtils.canSignIntoNetwork(nc); } /** * Update the current wifi status to the boolean value keyed by * {@link android.app.slice.Slice#EXTRA_TOGGLE_STATE} on {@param intent}. Loading Loading @@ -317,6 +356,12 @@ public class WifiSlice implements CustomSliceable { } private CharSequence getSummary(AccessPoint accessPoint) { if (isCaptivePortal()) { final int id = mContext.getResources() .getIdentifier("network_available_sign_in", "string", "android"); return mContext.getText(id); } if (accessPoint == null) { return getSummary(); } Loading