[NetworkSuggestion] Allow app to set subId for the suggestion
SubId will be used to identify which SIM/subscription to use for this
suggestion. Same network with different SubIds will be consider
different suggestions.
Also add a system API in WifiConfiguration to help data calculation for
different SIM.
Bug: 169275787
Test: atest android.net.wifi
Change-Id: I093c0661e28cc2df5e97391342101e8ecc331a0f
diff --git a/wifi/api/current.txt b/wifi/api/current.txt
index 6928618..2d48a83 100644
--- a/wifi/api/current.txt
+++ b/wifi/api/current.txt
@@ -492,6 +492,7 @@
method @IntRange(from=0) public int getPriority();
method public int getPriorityGroup();
method @Nullable public String getSsid();
+ method public int getSubscriptionId();
method public boolean isAppInteractionRequired();
method public boolean isCredentialSharedWithUser();
method public boolean isEnhancedOpen();
@@ -520,6 +521,7 @@
method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setPriority(@IntRange(from=0) int);
method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setPriorityGroup(int);
method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setSsid(@NonNull String);
+ method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setSubscriptionId(int);
method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setUntrusted(boolean);
method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWapiEnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWapiPassphrase(@NonNull String);
diff --git a/wifi/api/system-current.txt b/wifi/api/system-current.txt
index bf7003c..98cb849 100644
--- a/wifi/api/system-current.txt
+++ b/wifi/api/system-current.txt
@@ -350,6 +350,7 @@
field @Deprecated public int numScorerOverrideAndSwitchedNetwork;
field @Deprecated public boolean requirePmf;
field @Deprecated public boolean shared;
+ field @Deprecated public int subscriptionId;
field @Deprecated public boolean useExternalScores;
}
diff --git a/wifi/api/system-lint-baseline.txt b/wifi/api/system-lint-baseline.txt
index 6547ee8..a5f3f7c 100644
--- a/wifi/api/system-lint-baseline.txt
+++ b/wifi/api/system-lint-baseline.txt
@@ -1,6 +1,11 @@
// Baseline format: 1.0
MissingGetterMatchingBuilder: android.net.wifi.rtt.RangingRequest.Builder#addResponder(android.net.wifi.rtt.ResponderConfig):
- android.net.wifi.rtt.RangingRequest does not declare a `getResponders()` method matching method android.net.wifi.rtt.RangingRequest.Builder.addResponder(android.net.wifi.rtt.ResponderConfig)
+
+
MissingNullability: android.net.wifi.rtt.RangingRequest.Builder#addResponder(android.net.wifi.rtt.ResponderConfig):
+
+
+MutableBareField: android.net.wifi.WifiConfiguration#subscriptionId:
+ Bare field subscriptionId must be marked final, or moved behind accessors if mutable
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index fc6c59a..5208bcf 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -35,6 +35,8 @@
import android.os.Parcelable;
import android.os.SystemClock;
import android.os.UserHandle;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
@@ -881,6 +883,14 @@
public int carrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
/**
+ * The subscription ID identifies the SIM card for which this network configuration is valid.
+ * See {@link SubscriptionInfo#getSubscriptionId()}
+ * @hide
+ */
+ @SystemApi
+ public int subscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+
+ /**
* @hide
* Auto-join is allowed by user for this network.
* Default true.
@@ -2871,6 +2881,7 @@
requirePmf = source.requirePmf;
updateIdentifier = source.updateIdentifier;
carrierId = source.carrierId;
+ subscriptionId = source.subscriptionId;
mPasspointUniqueId = source.mPasspointUniqueId;
}
}
@@ -2946,6 +2957,7 @@
dest.writeLong(randomizedMacLastModifiedTimeMs);
dest.writeInt(carrierId);
dest.writeString(mPasspointUniqueId);
+ dest.writeInt(subscriptionId);
}
/** Implement the Parcelable interface {@hide} */
@@ -3022,6 +3034,7 @@
config.randomizedMacLastModifiedTimeMs = in.readLong();
config.carrierId = in.readInt();
config.mPasspointUniqueId = in.readString();
+ config.subscriptionId = in.readInt();
return config;
}
diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
index 9162c5f..c1f9005 100644
--- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
+++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
@@ -29,6 +29,8 @@
import android.net.wifi.util.SdkLevelUtil;
import android.os.Parcel;
import android.os.Parcelable;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
@@ -121,6 +123,12 @@
private int mCarrierId;
/**
+ * The Subscription ID identifies the SIM card for which this network configuration is
+ * valid.
+ */
+ private int mSubscriptionId;
+
+ /**
* Whether this network is shared credential with user to allow user manually connect.
*/
private boolean mIsSharedWithUser;
@@ -185,6 +193,7 @@
mIsNetworkOemPaid = false;
mPriorityGroup = 0;
mIsEnhancedMacRandomizationEnabled = false;
+ mSubscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
}
/**
@@ -353,6 +362,27 @@
}
/**
+ * Set the subscription ID of the SIM card for which this suggestion is targeted.
+ * The suggestion will only apply to that SIM card.
+ * <p>
+ * The subscription ID must belong to a carrier ID which meets either of the following
+ * conditions:
+ * <li>The carrier ID specified by the cross carrier provider, or</li>
+ * <li>The carrier ID which is used to validate the suggesting carrier-privileged app, see
+ * {@link TelephonyManager#hasCarrierPrivileges()}</li>
+ *
+ * @param subId subscription ID see {@link SubscriptionInfo#getSubscriptionId()}
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ */
+ public @NonNull Builder setSubscriptionId(int subId) {
+ if (!SdkLevelUtil.isAtLeastS()) {
+ throw new UnsupportedOperationException();
+ }
+ mSubscriptionId = subId;
+ return this;
+ }
+
+ /**
* Set the priority group ID, {@link #setPriority(int)} will only impact the network
* suggestions from the same priority group within the same app.
*
@@ -360,6 +390,9 @@
* @return Instance of {@link Builder} to enable chaining of the builder method.
*/
public @NonNull Builder setPriorityGroup(int priorityGroup) {
+ if (!SdkLevelUtil.isAtLeastS()) {
+ throw new UnsupportedOperationException();
+ }
mPriorityGroup = priorityGroup;
return this;
}
@@ -675,6 +708,7 @@
wifiConfiguration.macRandomizationSetting = mIsEnhancedMacRandomizationEnabled
? WifiConfiguration.RANDOMIZATION_ENHANCED
: WifiConfiguration.RANDOMIZATION_PERSISTENT;
+ wifiConfiguration.subscriptionId = mSubscriptionId;
return wifiConfiguration;
}
@@ -704,7 +738,9 @@
wifiConfiguration.meteredOverride = mMeteredOverride;
wifiConfiguration.trusted = !mIsNetworkUntrusted;
wifiConfiguration.oemPaid = mIsNetworkOemPaid;
+ wifiConfiguration.subscriptionId = mSubscriptionId;
mPasspointConfiguration.setCarrierId(mCarrierId);
+ mPasspointConfiguration.setSubscriptionId(mSubscriptionId);
mPasspointConfiguration.setMeteredOverride(wifiConfiguration.meteredOverride);
wifiConfiguration.macRandomizationSetting = mIsEnhancedMacRandomizationEnabled
? WifiConfiguration.RANDOMIZATION_ENHANCED
@@ -946,7 +982,8 @@
@Override
public int hashCode() {
return Objects.hash(wifiConfiguration.SSID, wifiConfiguration.BSSID,
- wifiConfiguration.allowedKeyManagement, wifiConfiguration.getKey());
+ wifiConfiguration.allowedKeyManagement, wifiConfiguration.getKey(),
+ wifiConfiguration.subscriptionId, wifiConfiguration.carrierId);
}
/**
@@ -970,7 +1007,9 @@
&& Objects.equals(this.wifiConfiguration.allowedKeyManagement,
lhs.wifiConfiguration.allowedKeyManagement)
&& TextUtils.equals(this.wifiConfiguration.getKey(),
- lhs.wifiConfiguration.getKey());
+ lhs.wifiConfiguration.getKey())
+ && this.wifiConfiguration.carrierId == lhs.wifiConfiguration.carrierId
+ && this.wifiConfiguration.subscriptionId == lhs.wifiConfiguration.subscriptionId;
}
@Override
@@ -1123,6 +1162,19 @@
* @see Builder#setPriorityGroup(int)
*/
public int getPriorityGroup() {
+ if (!SdkLevelUtil.isAtLeastS()) {
+ throw new UnsupportedOperationException();
+ }
return priorityGroup;
}
+
+ /**
+ * @see Builder#setSubscriptionId(int)
+ */
+ public int getSubscriptionId() {
+ if (!SdkLevelUtil.isAtLeastS()) {
+ throw new UnsupportedOperationException();
+ }
+ return wifiConfiguration.subscriptionId;
+ }
}
diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
index 61a6e16..357c5bc 100644
--- a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
+++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
@@ -30,6 +30,8 @@
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
@@ -412,6 +414,12 @@
private int mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
/**
+ * The subscription ID identifies the SIM card who provides this network configuration.
+ * See {@link SubscriptionInfo#getSubscriptionId()}
+ */
+ private int mSubscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+
+ /**
* Set the carrier ID associated with current configuration.
* @param carrierId {@code mCarrierId}
* @hide
@@ -430,6 +438,24 @@
}
/**
+ * Set the subscription ID associated with current configuration.
+ * @param subscriptionId {@code mSubscriptionId}
+ * @hide
+ */
+ public void setSubscriptionId(int subscriptionId) {
+ this.mSubscriptionId = subscriptionId;
+ }
+
+ /**
+ * Get the carrier ID associated with current configuration.
+ * @return {@code mSubscriptionId}
+ * @hide
+ */
+ public int getSubscriptionId() {
+ return mSubscriptionId;
+ }
+
+ /**
* The auto-join configuration specifies whether or not the Passpoint Configuration is
* considered for auto-connection. If true then yes, if false then it isn't considered as part
* of auto-connection - but can still be manually connected to.
@@ -604,6 +630,7 @@
mServiceFriendlyNames = source.mServiceFriendlyNames;
mAaaServerTrustedNames = source.mAaaServerTrustedNames;
mCarrierId = source.mCarrierId;
+ mSubscriptionId = source.mSubscriptionId;
mIsAutojoinEnabled = source.mIsAutojoinEnabled;
mIsMacRandomizationEnabled = source.mIsMacRandomizationEnabled;
mIsEnhancedMacRandomizationEnabled = source.mIsEnhancedMacRandomizationEnabled;
@@ -641,6 +668,7 @@
dest.writeBoolean(mIsMacRandomizationEnabled);
dest.writeBoolean(mIsEnhancedMacRandomizationEnabled);
dest.writeInt(mMeteredOverride);
+ dest.writeInt(mSubscriptionId);
}
@Override
@@ -671,6 +699,7 @@
&& mUsageLimitDataLimit == that.mUsageLimitDataLimit
&& mUsageLimitTimeLimitInMinutes == that.mUsageLimitTimeLimitInMinutes
&& mCarrierId == that.mCarrierId
+ && mSubscriptionId == that.mSubscriptionId
&& mIsAutojoinEnabled == that.mIsAutojoinEnabled
&& mIsMacRandomizationEnabled == that.mIsMacRandomizationEnabled
&& mIsEnhancedMacRandomizationEnabled == that.mIsEnhancedMacRandomizationEnabled
@@ -686,7 +715,7 @@
mSubscriptionExpirationTimeMillis, mUsageLimitUsageTimePeriodInMinutes,
mUsageLimitStartTimeInMillis, mUsageLimitDataLimit, mUsageLimitTimeLimitInMinutes,
mServiceFriendlyNames, mCarrierId, mIsAutojoinEnabled, mIsMacRandomizationEnabled,
- mIsEnhancedMacRandomizationEnabled, mMeteredOverride);
+ mIsEnhancedMacRandomizationEnabled, mMeteredOverride, mSubscriptionId);
}
@Override
@@ -740,6 +769,7 @@
builder.append("ServiceFriendlyNames: ").append(mServiceFriendlyNames);
}
builder.append("CarrierId:" + mCarrierId);
+ builder.append("SubscriptionId:" + mSubscriptionId);
builder.append("IsAutojoinEnabled:" + mIsAutojoinEnabled);
builder.append("mIsMacRandomizationEnabled:" + mIsMacRandomizationEnabled);
builder.append("mIsEnhancedMacRandomizationEnabled:" + mIsEnhancedMacRandomizationEnabled);
@@ -853,6 +883,7 @@
config.mIsMacRandomizationEnabled = in.readBoolean();
config.mIsEnhancedMacRandomizationEnabled = in.readBoolean();
config.mMeteredOverride = in.readInt();
+ config.mSubscriptionId = in.readInt();
return config;
}
diff --git a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java
index 8af7500..54f0c0f 100644
--- a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java
@@ -73,6 +73,8 @@
config.fromWifiNetworkSuggestion = true;
config.setRandomizedMacAddress(MacAddressUtils.createRandomUnicastAddress());
MacAddress macBeforeParcel = config.getRandomizedMacAddress();
+ config.subscriptionId = 1;
+ config.carrierId = 1189;
Parcel parcelW = Parcel.obtain();
config.writeToParcel(parcelW, 0);
byte[] bytes = parcelW.marshall();
diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
index 6e08ca4..3f9ce5b 100644
--- a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
@@ -764,6 +764,32 @@
}
/**
+ * Verify that the builder creates the appropriate SIM credential suggestion with SubId, also
+ * verify {@link WifiNetworkSuggestion#equals(Object)} consider suggestion with different SubId
+ * as different suggestions.
+ */
+ @Test
+ public void testSimCredentialNetworkWithSubId() {
+ assumeTrue(SdkLevelUtil.isAtLeastS());
+ WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
+ enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.SIM);
+ enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.NONE);
+ WifiNetworkSuggestion suggestion1 = new WifiNetworkSuggestion.Builder()
+ .setSsid(TEST_SSID)
+ .setWpa2EnterpriseConfig(enterpriseConfig)
+ .setSubscriptionId(1)
+ .build();
+ assertEquals(1, suggestion1.getSubscriptionId());
+ WifiNetworkSuggestion suggestion2 = new WifiNetworkSuggestion.Builder()
+ .setSsid(TEST_SSID)
+ .setWpa2EnterpriseConfig(enterpriseConfig)
+ .setSubscriptionId(2)
+ .build();
+ assertEquals(2, suggestion2.getSubscriptionId());
+ assertNotEquals(suggestion1, suggestion2);
+ }
+
+ /**
* Check that parcel marshalling/unmarshalling works
*/
@Test
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/PasspointTestUtils.java b/wifi/tests/src/android/net/wifi/hotspot2/PasspointTestUtils.java
index 8d55acb..5830a1e 100644
--- a/wifi/tests/src/android/net/wifi/hotspot2/PasspointTestUtils.java
+++ b/wifi/tests/src/android/net/wifi/hotspot2/PasspointTestUtils.java
@@ -30,6 +30,7 @@
public class PasspointTestUtils {
private static final int CERTIFICATE_FINGERPRINT_BYTES = 32;
+ private static final int TEST_SUB_ID = 1;
/**
* Utility function for creating a {@link android.net.wifi.hotspot2.pps.HomeSP}.
@@ -156,6 +157,7 @@
friendlyNames.put("en", "ServiceName1");
friendlyNames.put("kr", "ServiceName2");
config.setServiceFriendlyNames(friendlyNames);
+ config.setSubscriptionId(TEST_SUB_ID);
return config;
}