diff options
17 files changed, 418 insertions, 3 deletions
diff --git a/framework/aidl-export/android/net/wifi/BlockingOption.aidl b/framework/aidl-export/android/net/wifi/BlockingOption.aidl new file mode 100644 index 0000000000..47d4627114 --- /dev/null +++ b/framework/aidl-export/android/net/wifi/BlockingOption.aidl @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2024, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi; + +parcelable BlockingOption; diff --git a/framework/api/current.txt b/framework/api/current.txt index 451f907e19..41062f1c6b 100644 --- a/framework/api/current.txt +++ b/framework/api/current.txt @@ -1,6 +1,20 @@ // Signature format: 2.0 package android.net.wifi { + @FlaggedApi("com.android.wifi.flags.bssid_blocklist_for_suggestion") public final class BlockingOption implements android.os.Parcelable { + method public int describeContents(); + method public int getBlockingTimeSeconds(); + method public boolean isBlockingBssidOnly(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.BlockingOption> CREATOR; + } + + @FlaggedApi("com.android.wifi.flags.bssid_blocklist_for_suggestion") public static final class BlockingOption.Builder { + ctor public BlockingOption.Builder(@IntRange(from=1, to=86400) int); + method @NonNull public android.net.wifi.BlockingOption build(); + method @NonNull public android.net.wifi.BlockingOption.Builder setBlockingBssidOnly(boolean); + } + public abstract class EasyConnectStatusCallback { field public static final int EASY_CONNECT_EVENT_FAILURE_AUTHENTICATION = -2; // 0xfffffffe field public static final int EASY_CONNECT_EVENT_FAILURE_BUSY = -5; // 0xfffffffb @@ -465,6 +479,7 @@ package android.net.wifi { method public android.net.wifi.WifiManager.WifiLock createWifiLock(int, String); method @Deprecated public android.net.wifi.WifiManager.WifiLock createWifiLock(String); method @Deprecated public boolean disableNetwork(int); + method @FlaggedApi("com.android.wifi.flags.bssid_blocklist_for_suggestion") @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public void disallowCurrentSuggestedNetwork(@NonNull android.net.wifi.BlockingOption); method @Deprecated public boolean disconnect(); method @Deprecated public boolean enableNetwork(int, boolean); method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_MANAGED_PROVISIONING, android.Manifest.permission.NETWORK_CARRIER_PROVISIONING}, conditional=true) public void flushPasspointAnqpCache(); diff --git a/framework/java/android/net/wifi/BlockingOption.java b/framework/java/android/net/wifi/BlockingOption.java new file mode 100644 index 0000000000..ee152d4398 --- /dev/null +++ b/framework/java/android/net/wifi/BlockingOption.java @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.net.wifi; + +import android.annotation.FlaggedApi; +import android.annotation.IntRange; +import android.os.Parcel; +import android.os.Parcelable; + +import androidx.annotation.NonNull; + +import com.android.wifi.flags.Flags; + +import java.util.Objects; + +/** + * Options for blocking a network through + * {@link WifiManager#disallowCurrentSuggestedNetwork(BlockingOption)} + */ +@FlaggedApi(Flags.FLAG_BSSID_BLOCKLIST_FOR_SUGGESTION) +public final class BlockingOption implements Parcelable { + private final int mDisableTime; + private final boolean mBSSIDOnly; + + /** + * @hide + */ + public BlockingOption(int disableTime, boolean bssidOnly) { + mDisableTime = disableTime; + mBSSIDOnly = bssidOnly; + } + + /** + * @hide + */ + public BlockingOption(Parcel in) { + mDisableTime = in.readInt(); + mBSSIDOnly = in.readBoolean(); + } + + /** + * Get the blocking time which is set by {@link Builder#Builder(int)} + * @return Blocking time in seconds + */ + public int getBlockingTimeSeconds() { + return mDisableTime; + } + + /** + * Return whether or not a single BSSID is being blocked, which is set by + * {@link Builder#setBlockingBssidOnly(boolean)} + * @return True for blocking single BSSID, false otherwise. + */ + public boolean isBlockingBssidOnly() { + return mBSSIDOnly; + } + + /** + * Builder used to create {@link BlockingOption} objects. + */ + @FlaggedApi(Flags.FLAG_BSSID_BLOCKLIST_FOR_SUGGESTION) + public static final class Builder { + private int mDisableTime; + private boolean mBSSIDOnly; + + /** + * Create a {@link Builder} with blocking time for the network + * + * @param blockingTimeSec Time period to block the network in seconds + * @throws IllegalArgumentException if input is invalid. + */ + public Builder(@IntRange(from = 1, to = 86400) int blockingTimeSec) { + if (blockingTimeSec < 1 || blockingTimeSec > 86400) { + throw new IllegalArgumentException("blockingTimeSec should between 1 to 86400"); + } + mDisableTime = blockingTimeSec; + mBSSIDOnly = false; + } + + /** + * Set to configure blocking the whole network or a single BSSID. By default, the whole + * network will be blocked. + * @param bssidOnly True for a single BSSID, otherwise the whole network will be blocked + * @return Instance of {@link Builder} to enable chaining of the builder method. + */ + @NonNull public Builder setBlockingBssidOnly(boolean bssidOnly) { + mBSSIDOnly = bssidOnly; + return this; + } + + /** + * Create a BlockingOption object for use in + * {@link WifiManager#disallowCurrentSuggestedNetwork(BlockingOption)}. + */ + @NonNull public BlockingOption build() { + return new BlockingOption(mDisableTime, mBSSIDOnly); + } + } + + @NonNull + public static final Creator<BlockingOption> CREATOR = new Creator<BlockingOption>() { + @Override + public BlockingOption createFromParcel(Parcel in) { + return new BlockingOption(in); + } + + @Override + public BlockingOption[] newArray(int size) { + return new BlockingOption[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeInt(mDisableTime); + dest.writeBoolean(mBSSIDOnly); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof BlockingOption lhs)) { + return false; + } + return mBSSIDOnly == lhs.mBSSIDOnly && mDisableTime == lhs.mDisableTime; + } + + @Override + public int hashCode() { + return Objects.hash(mBSSIDOnly, mDisableTime); + } + + @Override + public String toString() { + return "BlockingOption[ " + + "DisableTime=" + mDisableTime + + ", BSSIDOnly=" + mBSSIDOnly; + } +} diff --git a/framework/java/android/net/wifi/IWifiManager.aidl b/framework/java/android/net/wifi/IWifiManager.aidl index e5f89d6a15..18576c894e 100644 --- a/framework/java/android/net/wifi/IWifiManager.aidl +++ b/framework/java/android/net/wifi/IWifiManager.aidl @@ -20,6 +20,7 @@ import android.net.DhcpInfo; import android.net.DhcpOption; import android.net.Network; import android.net.TetheringManager.TetheringRequest; +import android.net.wifi.BlockingOption; import android.net.wifi.CoexUnsafeChannel; import android.net.wifi.IActionListener; import android.net.wifi.IBooleanListener; @@ -550,6 +551,8 @@ interface IWifiManager { void getAutojoinDisallowedSecurityTypes(in IIntegerListener listener, in Bundle extras); + void disallowCurrentSuggestedNetwork(in BlockingOption option, String packageName); + void storeCapturedData(int triggerType, boolean isFullCapture, long triggerStartTimeMillis, long triggerStopTimeMillis, in IIntegerListener listener); } diff --git a/framework/java/android/net/wifi/WifiManager.java b/framework/java/android/net/wifi/WifiManager.java index 7f4030c906..ce7a3f0807 100644 --- a/framework/java/android/net/wifi/WifiManager.java +++ b/framework/java/android/net/wifi/WifiManager.java @@ -13220,4 +13220,25 @@ public class WifiManager { } return features; } + + /** + * When the device is connected to a network suggested by calling app + * {@link #addNetworkSuggestions(List)}, this API provide a way to avoid the current connection + * without {@link #removeNetworkSuggestions(List)}. The disallowed network will be disconnected + * or roam to other networks. + * App can only use this API to control the current connected network + * which was suggested by this app. + * + * @param blockingOption Option to change for the network blocking {@link BlockingOption} + */ + @FlaggedApi(Flags.FLAG_BSSID_BLOCKLIST_FOR_SUGGESTION) + @RequiresPermission(CHANGE_WIFI_STATE) + public void disallowCurrentSuggestedNetwork(@NonNull BlockingOption blockingOption) { + Objects.requireNonNull(blockingOption, "blockingOption cannot be null"); + try { + mService.disallowCurrentSuggestedNetwork(blockingOption, mContext.getOpPackageName()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } } diff --git a/framework/tests/src/android/net/wifi/BlockingOptionTest.java b/framework/tests/src/android/net/wifi/BlockingOptionTest.java new file mode 100644 index 0000000000..99f0e54f51 --- /dev/null +++ b/framework/tests/src/android/net/wifi/BlockingOptionTest.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.net.wifi; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; + +import android.os.Parcel; + +import androidx.test.filters.SmallTest; + +import org.junit.Test; + +@SmallTest +public class BlockingOptionTest { + + @Test + public void testBuilderWithValidInput() { + BlockingOption option = new BlockingOption.Builder(100) + .setBlockingBssidOnly(true) + .build(); + assertEquals(100, option.getBlockingTimeSeconds()); + assertTrue(option.isBlockingBssidOnly()); + } + + @Test + public void testBuilderWithInValidInput() { + assertThrows(IllegalArgumentException.class, () -> { + new BlockingOption.Builder(0) + .setBlockingBssidOnly(true) + .build(); + }); + assertThrows(IllegalArgumentException.class, () -> { + new BlockingOption.Builder(1000000) + .setBlockingBssidOnly(true) + .build(); + }); + } + + @Test + public void testParcel() { + BlockingOption option = new BlockingOption.Builder(100) + .setBlockingBssidOnly(true) + .build(); + Parcel parcelW = Parcel.obtain(); + option.writeToParcel(parcelW, 0); + byte[] bytes = parcelW.marshall(); + parcelW.recycle(); + + Parcel parcelR = Parcel.obtain(); + parcelR.unmarshall(bytes, 0, bytes.length); + parcelR.setDataPosition(0); + BlockingOption parcelOption = BlockingOption.CREATOR.createFromParcel(parcelR); + assertEquals(option, parcelOption); + } +} diff --git a/framework/tests/src/android/net/wifi/WifiManagerTest.java b/framework/tests/src/android/net/wifi/WifiManagerTest.java index b752f9f6e4..a029be2267 100644 --- a/framework/tests/src/android/net/wifi/WifiManagerTest.java +++ b/framework/tests/src/android/net/wifi/WifiManagerTest.java @@ -4560,4 +4560,13 @@ public class WifiManagerTest { public void testRemoveWifiStateChangedListenerWithNullListener() throws Exception { mWifiManager.removeWifiStateChangedListener(null); } + + @Test + public void testDisallowCurrentSuggestedNetwork() throws RemoteException { + assertThrows(NullPointerException.class, + () -> mWifiManager.disallowCurrentSuggestedNetwork(null)); + BlockingOption option = new BlockingOption.Builder(100).build(); + mWifiManager.disallowCurrentSuggestedNetwork(option); + verify(mWifiService).disallowCurrentSuggestedNetwork(eq(option), eq(TEST_PACKAGE_NAME)); + } } diff --git a/service/java/com/android/server/wifi/ClientMode.java b/service/java/com/android/server/wifi/ClientMode.java index 7d3308469c..d5c7c82e8a 100644 --- a/service/java/com/android/server/wifi/ClientMode.java +++ b/service/java/com/android/server/wifi/ClientMode.java @@ -22,6 +22,7 @@ import android.annotation.Nullable; import android.net.DhcpResultsParcelable; import android.net.MacAddress; import android.net.Network; +import android.net.wifi.BlockingOption; import android.net.wifi.IWifiConnectedNetworkScorer; import android.net.wifi.WifiAnnotations; import android.net.wifi.WifiConfiguration; @@ -370,4 +371,9 @@ public interface ClientMode { * Notify changes in PowerManager#isDeviceIdleMode */ void onIdleModeChanged(boolean isIdle); + + /** + * Block current connect network and add to blocklist + */ + void blockNetwork(BlockingOption option); } diff --git a/service/java/com/android/server/wifi/ClientModeDefaults.java b/service/java/com/android/server/wifi/ClientModeDefaults.java index f526f2dc6a..6a9d1ae409 100644 --- a/service/java/com/android/server/wifi/ClientModeDefaults.java +++ b/service/java/com/android/server/wifi/ClientModeDefaults.java @@ -21,6 +21,7 @@ import android.annotation.Nullable; import android.net.DhcpResultsParcelable; import android.net.MacAddress; import android.net.Network; +import android.net.wifi.BlockingOption; import android.net.wifi.IWifiConnectedNetworkScorer; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; @@ -284,4 +285,7 @@ public interface ClientModeDefaults extends ClientMode { @Override default void onIdleModeChanged(boolean isIdle) { } + + @Override + default void blockNetwork(BlockingOption option) { } } diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java index 4bc7c04c47..ba671d0218 100644 --- a/service/java/com/android/server/wifi/ClientModeImpl.java +++ b/service/java/com/android/server/wifi/ClientModeImpl.java @@ -33,6 +33,8 @@ import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_PRIMARY; import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SCAN_ONLY; import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SECONDARY_LONG_LIVED; import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SECONDARY_TRANSIENT; +import static com.android.server.wifi.WifiBlocklistMonitor.REASON_APP_DISALLOW; +import static com.android.server.wifi.WifiConfigManager.LINK_CONFIGURATION_BSSID_MATCH_LENGTH; import static com.android.server.wifi.WifiSettingsConfigStore.SECONDARY_WIFI_STA_FACTORY_MAC_ADDRESS; import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_STA_FACTORY_MAC_ADDRESS; import static com.android.server.wifi.proto.WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_LOCAL_ONLY; @@ -85,6 +87,7 @@ import android.net.shared.ProvisioningConfiguration; import android.net.shared.ProvisioningConfiguration.ScanResultInfo; import android.net.vcn.VcnManager; import android.net.vcn.VcnNetworkPolicyResult; +import android.net.wifi.BlockingOption; import android.net.wifi.IWifiConnectedNetworkScorer; import android.net.wifi.MloLink; import android.net.wifi.ScanResult; @@ -8897,4 +8900,38 @@ public class ClientModeImpl extends StateMachine implements ClientMode { mWifiInjector.getActiveModeWarden().updateCurrentConnectionInfo(); } } + + @Override + public void blockNetwork(BlockingOption option) { + if (mLastNetworkId == WifiConfiguration.INVALID_NETWORK_ID) { + Log.e(TAG, "Calling blockNetwork when disconnected"); + return; + } + WifiConfiguration configuration = mWifiConfigManager.getConfiguredNetwork(mLastNetworkId); + if (configuration == null) { + Log.e(TAG, "No available config for networkId: " + mLastNetworkId); + return; + } + if (mLastBssid == null) { + Log.e(TAG, "No available BSSID for networkId: " + mLastNetworkId); + return; + } + if (option.isBlockingBssidOnly()) { + mWifiBlocklistMonitor.blockBssidForDurationMs(mLastBssid, + mWifiConfigManager.getConfiguredNetwork(mLastNetworkId), + option.getBlockingTimeSeconds() * 1000L, REASON_APP_DISALLOW, 0); + } else { + ScanDetailCache scanDetailCache = mWifiConfigManager + .getScanDetailCacheForNetwork(mLastNetworkId); + for (String bssid : scanDetailCache.keySet()) { + if (bssid.regionMatches(true, 0, mLastBssid, 0, + LINK_CONFIGURATION_BSSID_MATCH_LENGTH)) { + mWifiBlocklistMonitor.blockBssidForDurationMs(bssid, + mWifiConfigManager.getConfiguredNetwork(mLastNetworkId), + option.getBlockingTimeSeconds() * 1000L, REASON_APP_DISALLOW, 0); + } + } + } + mWifiBlocklistMonitor.updateAndGetBssidBlocklistForSsids(Set.of(configuration.SSID)); + } } diff --git a/service/java/com/android/server/wifi/ConcreteClientModeManager.java b/service/java/com/android/server/wifi/ConcreteClientModeManager.java index a7c67031f1..36a43a5526 100644 --- a/service/java/com/android/server/wifi/ConcreteClientModeManager.java +++ b/service/java/com/android/server/wifi/ConcreteClientModeManager.java @@ -30,6 +30,7 @@ import android.net.MacAddress; import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkRequest; +import android.net.wifi.BlockingOption; import android.net.wifi.IWifiConnectedNetworkScorer; import android.net.wifi.WifiAnnotations; import android.net.wifi.WifiConfiguration; @@ -1725,4 +1726,9 @@ public class ConcreteClientModeManager implements ClientModeManager { public void onIdleModeChanged(boolean isIdle) { getClientMode().onIdleModeChanged(isIdle); } + + @Override + public void blockNetwork(BlockingOption option) { + getClientMode().blockNetwork(option); + } } diff --git a/service/java/com/android/server/wifi/WifiBlocklistMonitor.java b/service/java/com/android/server/wifi/WifiBlocklistMonitor.java index 179f7f32c0..4e3a0ce3c8 100644 --- a/service/java/com/android/server/wifi/WifiBlocklistMonitor.java +++ b/service/java/com/android/server/wifi/WifiBlocklistMonitor.java @@ -89,8 +89,9 @@ public class WifiBlocklistMonitor { public static final int REASON_NONLOCAL_DISCONNECT_CONNECTING = 12; // Connection attempt aborted by the watchdog because the AP didn't respond. public static final int REASON_FAILURE_NO_RESPONSE = 13; + public static final int REASON_APP_DISALLOW = 14; // Constant being used to keep track of how many failure reasons there are. - public static final int NUMBER_REASON_CODES = 14; + public static final int NUMBER_REASON_CODES = 15; public static final int INVALID_REASON = -1; @IntDef(prefix = { "REASON_" }, value = { @@ -107,7 +108,8 @@ public class WifiBlocklistMonitor { REASON_FRAMEWORK_DISCONNECT_FAST_RECONNECT, REASON_FRAMEWORK_DISCONNECT_CONNECTED_SCORE, REASON_NONLOCAL_DISCONNECT_CONNECTING, - REASON_FAILURE_NO_RESPONSE + REASON_FAILURE_NO_RESPONSE, + REASON_APP_DISALLOW }) @Retention(RetentionPolicy.SOURCE) public @interface FailureReason {} @@ -186,6 +188,8 @@ public class WifiBlocklistMonitor { "REASON_NONLOCAL_DISCONNECT_CONNECTING", true, false)); result.put(REASON_FAILURE_NO_RESPONSE, new BssidDisableReason( "REASON_FAILURE_NO_RESPONSE", true, true)); + result.put(REASON_APP_DISALLOW, new BssidDisableReason( + "REASON_APP_DISALLOW", false, false)); return result; } diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java index b08fbc27cd..b476fe0294 100644 --- a/service/java/com/android/server/wifi/WifiConfigManager.java +++ b/service/java/com/android/server/wifi/WifiConfigManager.java @@ -229,7 +229,6 @@ public class WifiConfigManager { * Link networks only if the bssid in scan results for the networks match in the first * 16 ASCII chars in the bssid string. For example = "af:de:56;34:15:7" */ - @VisibleForTesting public static final int LINK_CONFIGURATION_BSSID_MATCH_LENGTH = 16; /** * Log tag for this class. diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java index 19a6c4a6c4..7b3c7c75e6 100644 --- a/service/java/com/android/server/wifi/WifiServiceImpl.java +++ b/service/java/com/android/server/wifi/WifiServiceImpl.java @@ -103,6 +103,7 @@ import android.net.Uri; import android.net.ip.IpClientUtil; import android.net.thread.ThreadNetworkController; import android.net.thread.ThreadNetworkManager; +import android.net.wifi.BlockingOption; import android.net.wifi.CoexUnsafeChannel; import android.net.wifi.IActionListener; import android.net.wifi.IBooleanListener; @@ -9137,4 +9138,29 @@ public class WifiServiceImpl extends IWifiManager.Stub { } }, TAG + "#getAutojoinDisallowedSecurityTypes"); } + + @Override + public void disallowCurrentSuggestedNetwork(@NonNull BlockingOption option, + @NonNull String packageName) { + Objects.requireNonNull(option, "blockingOption cannot be null"); + int callingUid = Binder.getCallingUid(); + mWifiPermissionsUtil.checkPackage(callingUid, packageName); + if (enforceChangePermission(packageName) != MODE_ALLOWED) { + throw new SecurityException("Caller does not hold CHANGE_WIFI_STATE permission"); + } + if (mVerboseLoggingEnabled) { + mLog.info("disallowCurrentSuggestedNetwork: Uid=% Package Name=%").c( + callingUid).c(option.toString()).flush(); + } + if (mActiveModeWarden.getWifiState() != WIFI_STATE_ENABLED) { + return; + } + WifiInfo info = mActiveModeWarden.getConnectionInfo(); + if (!packageName.equals(info.getRequestingPackageName())) { + return; + } + mWifiThreadRunner.post( + () -> mActiveModeWarden.getPrimaryClientModeManager().blockNetwork(option), + "disallowCurrentSuggestedNetwork"); + } } diff --git a/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java index 0b98979e64..8b705f0991 100644 --- a/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java +++ b/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java @@ -44,6 +44,7 @@ import static com.android.server.wifi.ClientModeImpl.CMD_PRE_DHCP_ACTION; import static com.android.server.wifi.ClientModeImpl.CMD_PRE_DHCP_ACTION_COMPLETE; import static com.android.server.wifi.ClientModeImpl.CMD_UNWANTED_NETWORK; import static com.android.server.wifi.ClientModeImpl.WIFI_WORK_SOURCE; +import static com.android.server.wifi.WifiBlocklistMonitor.REASON_APP_DISALLOW; import static com.android.server.wifi.WifiSettingsConfigStore.SECONDARY_WIFI_STA_FACTORY_MAC_ADDRESS; import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_STA_FACTORY_MAC_ADDRESS; import static com.android.server.wifi.TestUtil.createCapabilityBitset; @@ -124,6 +125,7 @@ import android.net.networkstack.aidl.ip.ReachabilityLossInfoParcelable; import android.net.networkstack.aidl.ip.ReachabilityLossReason; import android.net.vcn.VcnManager; import android.net.vcn.VcnNetworkPolicyResult; +import android.net.wifi.BlockingOption; import android.net.wifi.IActionListener; import android.net.wifi.MloLink; import android.net.wifi.ScanResult; @@ -11278,4 +11280,15 @@ public class ClientModeImplTest extends WifiBaseTest { verify(mWifiGlobals, never()).enableWpa3SaeH2eSupport(); } } + + @Test + public void testBlockNetwork() throws Exception { + connect(); + BlockingOption option = new BlockingOption.Builder(100) + .setBlockingBssidOnly(true).build(); + mCmi.blockNetwork(option); + verify(mWifiBlocklistMonitor).blockBssidForDurationMs(eq(TEST_BSSID_STR), any(), + eq(100 * 1000L), eq(REASON_APP_DISALLOW), eq(0)); + verify(mWifiBlocklistMonitor).updateAndGetBssidBlocklistForSsids(any()); + } } diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java index 2c240530c0..522967a856 100644 --- a/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java +++ b/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java @@ -149,6 +149,7 @@ import android.net.Network; import android.net.NetworkStack; import android.net.TetheringManager; import android.net.Uri; +import android.net.wifi.BlockingOption; import android.net.wifi.CoexUnsafeChannel; import android.net.wifi.IActionListener; import android.net.wifi.IBooleanListener; @@ -13121,6 +13122,18 @@ public class WifiServiceImplTest extends WifiBaseTest { customConfig, mExtras, false); } + @Test + public void testDisallowCurrentSuggestedNetwork() { + BlockingOption blockingOption = new BlockingOption.Builder(100).build(); + WifiInfo info = new WifiInfo(); + info.setRequestingPackageName(TEST_PACKAGE_NAME); + when(mActiveModeWarden.getWifiState()).thenReturn(WIFI_STATE_ENABLED); + when(mActiveModeWarden.getConnectionInfo()).thenReturn(info); + mWifiServiceImpl.disallowCurrentSuggestedNetwork(blockingOption, TEST_PACKAGE_NAME); + mLooper.dispatchAll(); + verify(mClientModeManager).blockNetwork(eq(blockingOption)); + } + /** * Test add and remove listener will go to ActiveModeWarden. */ diff --git a/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java index 809fa1a915..681db5b3d2 100644 --- a/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java +++ b/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java @@ -88,6 +88,8 @@ import android.os.test.TestLooper; import androidx.test.filters.SmallTest; +import com.android.dx.mockito.inline.extended.ExtendedMockito; +import com.android.dx.mockito.inline.extended.StaticMockitoSession; import com.android.modules.utils.build.SdkLevel; import com.android.server.wifi.Clock; import com.android.server.wifi.DeviceConfigFacade; @@ -117,6 +119,7 @@ import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.Spy; +import org.mockito.quality.Strictness; import java.nio.ByteOrder; import java.util.ArrayList; @@ -172,6 +175,7 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest { public ErrorCollector collector = new ErrorCollector(); private MockResources mResources; private Bundle mExtras = new Bundle(); + private StaticMockitoSession mSession; /** * Initialize mocks. @@ -179,6 +183,12 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest { @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); + mSession = ExtendedMockito.mockitoSession() + .strictness(Strictness.LENIENT) + .mockStatic(WifiInjector.class) + .startMocking(); + + when(WifiInjector.getInstance()).thenReturn(mWifiInjector); mAlarmManager = new TestAlarmManager(); when(mMockContext.getSystemService(Context.ALARM_SERVICE)) @@ -244,6 +254,7 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest { @After public void tearDown() throws Exception { mMockNative.validateUniqueTransactionIds(); + mSession.finishMocking(); } /** |