Merge changes from topic "mdns-subtype-discovery" into main
* changes:
[mdns] add service-side impl for subtypes discovery
[mdns] add API for discovery with subtype
diff --git a/framework/src/android/net/BpfNetMapsUtils.java b/framework/src/android/net/BpfNetMapsUtils.java
index 11d610c..0be30bb 100644
--- a/framework/src/android/net/BpfNetMapsUtils.java
+++ b/framework/src/android/net/BpfNetMapsUtils.java
@@ -125,13 +125,11 @@
return sj.toString();
}
- public static final boolean PRE_T = !SdkLevel.isAtLeastT();
-
/**
* Throw UnsupportedOperationException if SdkLevel is before T.
*/
public static void throwIfPreT(final String msg) {
- if (PRE_T) {
+ if (!SdkLevel.isAtLeastT()) {
throw new UnsupportedOperationException(msg);
}
}
diff --git a/service-t/lint-baseline.xml b/service-t/lint-baseline.xml
index 7f05b8c..e4b92d6 100644
--- a/service-t/lint-baseline.xml
+++ b/service-t/lint-baseline.xml
@@ -3,17 +3,6 @@
<issue
id="NewApi"
- message="Call requires API level 31 (current min is 30): `BpfMap`"
- errorLine1=" return new BpfMap<>(IFACE_INDEX_NAME_MAP_PATH, BpfMap.BPF_F_RDWR,"
- errorLine2=" ~~~~~~~~~~~~">
- <location
- file="packages/modules/Connectivity/service-t/src/com/android/server/net/BpfInterfaceMapUpdater.java"
- line="69"
- column="24"/>
- </issue>
-
- <issue
- id="NewApi"
message="Call requires API level 31 (current min is 30): `new android.net.EthernetNetworkSpecifier`"
errorLine1=" .setNetworkSpecifier(new EthernetNetworkSpecifier(ifaceName))"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
diff --git a/service-t/native/libs/libnetworkstats/BpfNetworkStats.cpp b/service-t/native/libs/libnetworkstats/BpfNetworkStats.cpp
index 8a58e56..def5f88 100644
--- a/service-t/native/libs/libnetworkstats/BpfNetworkStats.cpp
+++ b/service-t/native/libs/libnetworkstats/BpfNetworkStats.cpp
@@ -85,12 +85,12 @@
[iface, stats, &ifaceNameMap, &unknownIfaceBytesTotal](
const uint32_t& key,
const BpfMapRO<uint32_t, StatsValue>& ifaceStatsMap) -> Result<void> {
- IfaceValue ifname;
- if (getIfaceNameFromMap(ifaceNameMap, ifaceStatsMap, key, ifname, key,
- &unknownIfaceBytesTotal)) {
+ Result<IfaceValue> ifname = ifaceNameMap.readValue(key);
+ if (!ifname.ok()) {
+ maybeLogUnknownIface(key, ifaceStatsMap, key, &unknownIfaceBytesTotal);
return Result<void>();
}
- if (!iface || !strcmp(iface, ifname.name)) {
+ if (!iface || !strcmp(iface, ifname.value().name)) {
Result<StatsValue> statsEntry = ifaceStatsMap.readValue(key);
if (!statsEntry.ok()) {
return statsEntry.error();
@@ -144,16 +144,16 @@
[&lines, &unknownIfaceBytesTotal, &ifaceMap](
const StatsKey& key,
const BpfMapRO<StatsKey, StatsValue>& statsMap) -> Result<void> {
- IfaceValue ifname;
- if (getIfaceNameFromMap(ifaceMap, statsMap, key.ifaceIndex, ifname, key,
- &unknownIfaceBytesTotal)) {
+ Result<IfaceValue> ifname = ifaceMap.readValue(key.ifaceIndex);
+ if (!ifname.ok()) {
+ maybeLogUnknownIface(key.ifaceIndex, statsMap, key, &unknownIfaceBytesTotal);
return Result<void>();
}
Result<StatsValue> statsEntry = statsMap.readValue(key);
if (!statsEntry.ok()) {
return base::ResultError(statsEntry.error().message(), statsEntry.error().code());
}
- stats_line newLine = populateStatsEntry(key, statsEntry.value(), ifname);
+ stats_line newLine = populateStatsEntry(key, statsEntry.value(), ifname.value());
lines.push_back(newLine);
if (newLine.tag) {
// account tagged traffic in the untagged stats (for historical reasons?)
@@ -234,8 +234,9 @@
const auto processDetailIfaceStats = [&lines, &unknownIfaceBytesTotal, &ifaceMap, &statsMap](
const uint32_t& key, const StatsValue& value,
const BpfMapRO<uint32_t, StatsValue>&) {
- IfaceValue ifname;
- if (getIfaceNameFromMap(ifaceMap, statsMap, key, ifname, key, &unknownIfaceBytesTotal)) {
+ Result<IfaceValue> ifname = ifaceMap.readValue(key);
+ if (!ifname.ok()) {
+ maybeLogUnknownIface(key, statsMap, key, &unknownIfaceBytesTotal);
return Result<void>();
}
StatsKey fakeKey = {
@@ -243,7 +244,7 @@
.tag = (uint32_t)TAG_NONE,
.counterSet = (uint32_t)SET_ALL,
};
- lines.push_back(populateStatsEntry(fakeKey, value, ifname));
+ lines.push_back(populateStatsEntry(fakeKey, value, ifname.value()));
return Result<void>();
};
Result<void> res = statsMap.iterateWithValue(processDetailIfaceStats);
diff --git a/service-t/native/libs/libnetworkstats/BpfNetworkStatsTest.cpp b/service-t/native/libs/libnetworkstats/BpfNetworkStatsTest.cpp
index 2c01904..57822fc 100644
--- a/service-t/native/libs/libnetworkstats/BpfNetworkStatsTest.cpp
+++ b/service-t/native/libs/libnetworkstats/BpfNetworkStatsTest.cpp
@@ -352,14 +352,16 @@
.counterSet = TEST_COUNTERSET0,
.ifaceIndex = ifaceIndex,
};
- IfaceValue ifname;
int64_t unknownIfaceBytesTotal = 0;
- ASSERT_EQ(-ENODEV, getIfaceNameFromMap(mFakeIfaceIndexNameMap, mFakeStatsMap, ifaceIndex,
- ifname, curKey, &unknownIfaceBytesTotal));
+ ASSERT_EQ(false, mFakeIfaceIndexNameMap.readValue(ifaceIndex).ok());
+ maybeLogUnknownIface(ifaceIndex, mFakeStatsMap, curKey, &unknownIfaceBytesTotal);
+
ASSERT_EQ(((int64_t)(TEST_BYTES0 * 20 + TEST_BYTES1 * 20)), unknownIfaceBytesTotal);
curKey.ifaceIndex = IFACE_INDEX2;
- ASSERT_EQ(-ENODEV, getIfaceNameFromMap(mFakeIfaceIndexNameMap, mFakeStatsMap, ifaceIndex,
- ifname, curKey, &unknownIfaceBytesTotal));
+
+ ASSERT_EQ(false, mFakeIfaceIndexNameMap.readValue(ifaceIndex).ok());
+ maybeLogUnknownIface(ifaceIndex, mFakeStatsMap, curKey, &unknownIfaceBytesTotal);
+
ASSERT_EQ(-1, unknownIfaceBytesTotal);
std::vector<stats_line> lines;
// TODO: find a way to test the total of unknown Iface Bytes go above limit.
diff --git a/service-t/native/libs/libnetworkstats/include/netdbpf/BpfNetworkStats.h b/service-t/native/libs/libnetworkstats/include/netdbpf/BpfNetworkStats.h
index 0f28c1d..173dee4 100644
--- a/service-t/native/libs/libnetworkstats/include/netdbpf/BpfNetworkStats.h
+++ b/service-t/native/libs/libnetworkstats/include/netdbpf/BpfNetworkStats.h
@@ -71,20 +71,6 @@
const BpfMapRO<uint32_t, IfaceValue>& ifaceMap);
// For test only
int cleanStatsMapInternal(const base::unique_fd& cookieTagMap, const base::unique_fd& tagStatsMap);
-// For test only
-template <class Key>
-int getIfaceNameFromMap(const BpfMapRO<uint32_t, IfaceValue>& ifaceMap,
- const BpfMapRO<Key, StatsValue>& statsMap,
- uint32_t ifaceIndex, IfaceValue& ifname,
- const Key& curKey, int64_t* unknownIfaceBytesTotal) {
- auto iface = ifaceMap.readValue(ifaceIndex);
- if (!iface.ok()) {
- maybeLogUnknownIface(ifaceIndex, statsMap, curKey, unknownIfaceBytesTotal);
- return -ENODEV;
- }
- ifname = iface.value();
- return 0;
-}
template <class Key>
void maybeLogUnknownIface(int ifaceIndex, const BpfMapRO<Key, StatsValue>& statsMap,
diff --git a/service/lint-baseline.xml b/service/lint-baseline.xml
index a091a2b..b09589c 100644
--- a/service/lint-baseline.xml
+++ b/service/lint-baseline.xml
@@ -3,72 +3,6 @@
<issue
id="NewApi"
- message="Call requires API level 31 (current min is 30): `BpfMap`"
- errorLine1=" return new BpfMap<>("
- errorLine2=" ~~~~~~~~~~~~">
- <location
- file="packages/modules/Connectivity/service/src/com/android/server/BpfNetMaps.java"
- line="189"
- column="20"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 30): `BpfMap`"
- errorLine1=" return new BpfMap<>("
- errorLine2=" ~~~~~~~~~~~~">
- <location
- file="packages/modules/Connectivity/service/src/com/android/server/BpfNetMaps.java"
- line="198"
- column="20"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 30): `BpfMap`"
- errorLine1=" return new BpfMap<>("
- errorLine2=" ~~~~~~~~~~~~">
- <location
- file="packages/modules/Connectivity/service/src/com/android/server/BpfNetMaps.java"
- line="207"
- column="20"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 30): `BpfMap`"
- errorLine1=" return new BpfMap<>(COOKIE_TAG_MAP_PATH, BpfMap.BPF_F_RDWR,"
- errorLine2=" ~~~~~~~~~~~~">
- <location
- file="packages/modules/Connectivity/service/src/com/android/server/BpfNetMaps.java"
- line="216"
- column="20"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 30): `BpfMap`"
- errorLine1=" return new BpfMap<>("
- errorLine2=" ~~~~~~~~~~~~">
- <location
- file="packages/modules/Connectivity/service/src/com/android/server/BpfNetMaps.java"
- line="225"
- column="20"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 30): `BpfMap`"
- errorLine1=" return new BpfMap<>(INGRESS_DISCARD_MAP_PATH, BpfMap.BPF_F_RDWR,"
- errorLine2=" ~~~~~~~~~~~~">
- <location
- file="packages/modules/Connectivity/service/src/com/android/server/BpfNetMaps.java"
- line="234"
- column="20"/>
- </issue>
-
- <issue
- id="NewApi"
message="Call requires API level 31 (current min is 30): `BpfBitmap`"
errorLine1=" return new BpfBitmap(BLOCKED_PORTS_MAP_PATH);"
errorLine2=" ~~~~~~~~~~~~~">
diff --git a/service/src/com/android/server/BpfNetMaps.java b/service/src/com/android/server/BpfNetMaps.java
index aa40285..a7fddd0 100644
--- a/service/src/com/android/server/BpfNetMaps.java
+++ b/service/src/com/android/server/BpfNetMaps.java
@@ -31,7 +31,6 @@
import static android.net.BpfNetMapsConstants.UID_OWNER_MAP_PATH;
import static android.net.BpfNetMapsConstants.UID_PERMISSION_MAP_PATH;
import static android.net.BpfNetMapsConstants.UID_RULES_CONFIGURATION_KEY;
-import static android.net.BpfNetMapsUtils.PRE_T;
import static android.net.BpfNetMapsUtils.getMatchByFirewallChain;
import static android.net.BpfNetMapsUtils.isFirewallAllowList;
import static android.net.BpfNetMapsUtils.matchToString;
@@ -68,6 +67,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.modules.utils.BackgroundThread;
+import com.android.modules.utils.build.SdkLevel;
import com.android.net.module.util.BpfDump;
import com.android.net.module.util.BpfMap;
import com.android.net.module.util.IBpfMap;
@@ -95,7 +95,7 @@
*/
public class BpfNetMaps {
static {
- if (!PRE_T) {
+ if (SdkLevel.isAtLeastT()) {
System.loadLibrary("service-connectivity");
}
}
@@ -184,6 +184,7 @@
sIngressDiscardMap = ingressDiscardMap;
}
+ @RequiresApi(Build.VERSION_CODES.TIRAMISU)
private static IBpfMap<S32, U32> getConfigurationMap() {
try {
return new BpfMap<>(
@@ -193,6 +194,7 @@
}
}
+ @RequiresApi(Build.VERSION_CODES.TIRAMISU)
private static IBpfMap<S32, UidOwnerValue> getUidOwnerMap() {
try {
return new BpfMap<>(
@@ -202,6 +204,7 @@
}
}
+ @RequiresApi(Build.VERSION_CODES.TIRAMISU)
private static IBpfMap<S32, U8> getUidPermissionMap() {
try {
return new BpfMap<>(
@@ -211,6 +214,7 @@
}
}
+ @RequiresApi(Build.VERSION_CODES.TIRAMISU)
private static IBpfMap<CookieTagMapKey, CookieTagMapValue> getCookieTagMap() {
try {
return new BpfMap<>(COOKIE_TAG_MAP_PATH,
@@ -220,6 +224,7 @@
}
}
+ @RequiresApi(Build.VERSION_CODES.TIRAMISU)
private static IBpfMap<S32, U8> getDataSaverEnabledMap() {
try {
return new BpfMap<>(
@@ -229,6 +234,7 @@
}
}
+ @RequiresApi(Build.VERSION_CODES.TIRAMISU)
private static IBpfMap<IngressDiscardKey, IngressDiscardValue> getIngressDiscardMap() {
try {
return new BpfMap<>(INGRESS_DISCARD_MAP_PATH,
@@ -238,6 +244,7 @@
}
}
+ @RequiresApi(Build.VERSION_CODES.TIRAMISU)
private static void initBpfMaps() {
if (sConfigurationMap == null) {
sConfigurationMap = getConfigurationMap();
@@ -295,6 +302,7 @@
* Initializes the class if it is not already initialized. This method will open maps but not
* cause any other effects. This method may be called multiple times on any thread.
*/
+ @RequiresApi(Build.VERSION_CODES.TIRAMISU)
private static synchronized void ensureInitialized(final Context context) {
if (sInitialized) return;
initBpfMaps();
@@ -348,7 +356,7 @@
public BpfNetMaps(final Context context) {
this(context, null);
- if (PRE_T) throw new IllegalArgumentException("BpfNetMaps need to use netd before T");
+ if (!SdkLevel.isAtLeastT()) throw new IllegalArgumentException("BpfNetMaps need to use netd before T");
}
public BpfNetMaps(final Context context, final INetd netd) {
@@ -357,7 +365,7 @@
@VisibleForTesting
public BpfNetMaps(final Context context, final INetd netd, final Dependencies deps) {
- if (!PRE_T) {
+ if (SdkLevel.isAtLeastT()) {
ensureInitialized(context);
}
mNetd = netd;
@@ -371,7 +379,7 @@
}
private void throwIfPreT(final String msg) {
- if (PRE_T) {
+ if (!SdkLevel.isAtLeastT()) {
throw new UnsupportedOperationException(msg);
}
}
@@ -712,7 +720,7 @@
* cause of the failure.
*/
public void addUidInterfaceRules(final String ifName, final int[] uids) throws RemoteException {
- if (PRE_T) {
+ if (!SdkLevel.isAtLeastT()) {
mNetd.firewallAddUidInterfaceRules(ifName, uids);
return;
}
@@ -750,7 +758,7 @@
* cause of the failure.
*/
public void removeUidInterfaceRules(final int[] uids) throws RemoteException {
- if (PRE_T) {
+ if (!SdkLevel.isAtLeastT()) {
mNetd.firewallRemoveUidInterfaceRules(uids);
return;
}
@@ -829,7 +837,7 @@
* @throws RemoteException when netd has crashed.
*/
public void setNetPermForUids(final int permissions, final int[] uids) throws RemoteException {
- if (PRE_T) {
+ if (!SdkLevel.isAtLeastT()) {
mNetd.trafficSetNetPermForUids(permissions, uids);
return;
}
@@ -1019,7 +1027,7 @@
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
public void dump(final IndentingPrintWriter pw, final FileDescriptor fd, boolean verbose)
throws IOException, ServiceSpecificException {
- if (PRE_T) {
+ if (!SdkLevel.isAtLeastT()) {
throw new ServiceSpecificException(
EOPNOTSUPP, "dumpsys connectivity trafficcontroller dump not available on pre-T"
+ " devices, use dumpsys netd trafficcontroller instead.");
diff --git a/thread/framework/java/android/net/thread/ThreadNetworkException.java b/thread/framework/java/android/net/thread/ThreadNetworkException.java
index 4fd445b..af0a84b 100644
--- a/thread/framework/java/android/net/thread/ThreadNetworkException.java
+++ b/thread/framework/java/android/net/thread/ThreadNetworkException.java
@@ -124,8 +124,8 @@
public static final int ERROR_RESOURCE_EXHAUSTED = 10;
/**
- * The operation failed because of an unknown error in the system. This typically indicates
- * that the caller doesn't understand error codes added in newer Android versions.
+ * The operation failed because of an unknown error in the system. This typically indicates that
+ * the caller doesn't understand error codes added in newer Android versions.
*/
public static final int ERROR_UNKNOWN = 11;
diff --git a/thread/service/java/com/android/server/thread/ThreadNetworkCountryCode.java b/thread/service/java/com/android/server/thread/ThreadNetworkCountryCode.java
index b7b6233..23aeb93 100644
--- a/thread/service/java/com/android/server/thread/ThreadNetworkCountryCode.java
+++ b/thread/service/java/com/android/server/thread/ThreadNetworkCountryCode.java
@@ -31,6 +31,7 @@
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.ActiveCountryCodeChangedCallback;
import android.os.Build;
+import android.sysprop.ThreadNetworkProperties;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
@@ -53,8 +54,8 @@
/**
* Provide functions for making changes to Thread Network country code. This Country Code is from
- * location, WiFi or telephony configuration. This class sends Country Code to Thread Network native
- * layer.
+ * location, WiFi, telephony or OEM configuration. This class sends Country Code to Thread Network
+ * native layer.
*
* <p>This class is thread-safe.
*/
@@ -77,6 +78,7 @@
value = {
COUNTRY_CODE_SOURCE_DEFAULT,
COUNTRY_CODE_SOURCE_LOCATION,
+ COUNTRY_CODE_SOURCE_OEM,
COUNTRY_CODE_SOURCE_OVERRIDE,
COUNTRY_CODE_SOURCE_TELEPHONY,
COUNTRY_CODE_SOURCE_TELEPHONY_LAST,
@@ -86,6 +88,7 @@
private static final String COUNTRY_CODE_SOURCE_DEFAULT = "Default";
private static final String COUNTRY_CODE_SOURCE_LOCATION = "Location";
+ private static final String COUNTRY_CODE_SOURCE_OEM = "Oem";
private static final String COUNTRY_CODE_SOURCE_OVERRIDE = "Override";
private static final String COUNTRY_CODE_SOURCE_TELEPHONY = "Telephony";
private static final String COUNTRY_CODE_SOURCE_TELEPHONY_LAST = "TelephonyLast";
@@ -111,6 +114,7 @@
@Nullable private CountryCodeInfo mWifiCountryCodeInfo;
@Nullable private CountryCodeInfo mTelephonyCountryCodeInfo;
@Nullable private CountryCodeInfo mTelephonyLastCountryCodeInfo;
+ @Nullable private CountryCodeInfo mOemCountryCodeInfo;
/** Container class to store Thread country code information. */
private static final class CountryCodeInfo {
@@ -118,13 +122,35 @@
@CountryCodeSource private String mSource;
private final Instant mUpdatedTimestamp;
+ /**
+ * Constructs a new {@code CountryCodeInfo} from the given country code, country code source
+ * and country coode created time.
+ *
+ * @param countryCode a String representation of the country code as defined in ISO 3166.
+ * @param countryCodeSource a String representation of country code source.
+ * @param instant a Instant representation of the time when the country code was created.
+ * @throws IllegalArgumentException if {@code countryCode} contains invalid country code.
+ */
public CountryCodeInfo(
String countryCode, @CountryCodeSource String countryCodeSource, Instant instant) {
+ if (!isValidCountryCode(countryCode)) {
+ throw new IllegalArgumentException("Country code is invalid: " + countryCode);
+ }
+
mCountryCode = countryCode;
mSource = countryCodeSource;
mUpdatedTimestamp = instant;
}
+ /**
+ * Constructs a new {@code CountryCodeInfo} from the given country code, country code
+ * source. The updated timestamp of the country code will be set to the time when {@code
+ * CountryCodeInfo} was constructed.
+ *
+ * @param countryCode a String representation of the country code as defined in ISO 3166.
+ * @param countryCodeSource a String representation of country code source.
+ * @throws IllegalArgumentException if {@code countryCode} contains invalid country code.
+ */
public CountryCodeInfo(String countryCode, @CountryCodeSource String countryCodeSource) {
this(countryCode, countryCodeSource, Instant.now());
}
@@ -188,7 +214,8 @@
WifiManager wifiManager,
Context context,
TelephonyManager telephonyManager,
- SubscriptionManager subscriptionManager) {
+ SubscriptionManager subscriptionManager,
+ @Nullable String oemCountryCode) {
mLocationManager = locationManager;
mThreadNetworkControllerService = threadNetworkControllerService;
mGeocoder = geocoder;
@@ -197,6 +224,10 @@
mContext = context;
mTelephonyManager = telephonyManager;
mSubscriptionManager = subscriptionManager;
+
+ if (oemCountryCode != null) {
+ mOemCountryCodeInfo = new CountryCodeInfo(oemCountryCode, COUNTRY_CODE_SOURCE_OEM);
+ }
}
public static ThreadNetworkCountryCode newInstance(
@@ -209,7 +240,8 @@
context.getSystemService(WifiManager.class),
context,
context.getSystemService(TelephonyManager.class),
- context.getSystemService(SubscriptionManager.class));
+ context.getSystemService(SubscriptionManager.class),
+ ThreadNetworkProperties.country_code().orElse(null));
}
/** Sets up this country code module to listen to location country code changes. */
@@ -418,6 +450,9 @@
* number will be used.
* <li>5. Location country code - Country code retrieved from LocationManager passive location
* provider.
+ * <li>6. OEM country code - Country code retrieved from the system property
+ * `ro.boot.threadnetwork.country_code`.
+ * <li>7. Default country code `WW`.
* </ul>
*
* @return the selected country code information.
@@ -443,6 +478,10 @@
return mLocationCountryCodeInfo;
}
+ if (mOemCountryCodeInfo != null) {
+ return mOemCountryCodeInfo;
+ }
+
return DEFAULT_COUNTRY_CODE_INFO;
}
@@ -531,13 +570,14 @@
/** Dumps the current state of this ThreadNetworkCountryCode object. */
public synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("---- Dump of ThreadNetworkCountryCode begin ----");
- pw.println("mOverrideCountryCodeInfo: " + mOverrideCountryCodeInfo);
+ pw.println("mOverrideCountryCodeInfo : " + mOverrideCountryCodeInfo);
pw.println("mTelephonyCountryCodeSlotInfoMap: " + mTelephonyCountryCodeSlotInfoMap);
- pw.println("mTelephonyCountryCodeInfo: " + mTelephonyCountryCodeInfo);
- pw.println("mWifiCountryCodeInfo: " + mWifiCountryCodeInfo);
- pw.println("mTelephonyLastCountryCodeInfo: " + mTelephonyLastCountryCodeInfo);
- pw.println("mLocationCountryCodeInfo: " + mLocationCountryCodeInfo);
- pw.println("mCurrentCountryCodeInfo: " + mCurrentCountryCodeInfo);
+ pw.println("mTelephonyCountryCodeInfo : " + mTelephonyCountryCodeInfo);
+ pw.println("mWifiCountryCodeInfo : " + mWifiCountryCodeInfo);
+ pw.println("mTelephonyLastCountryCodeInfo : " + mTelephonyLastCountryCodeInfo);
+ pw.println("mLocationCountryCodeInfo : " + mLocationCountryCodeInfo);
+ pw.println("mOemCountryCodeInfo : " + mOemCountryCodeInfo);
+ pw.println("mCurrentCountryCodeInfo : " + mCurrentCountryCodeInfo);
pw.println("---- Dump of ThreadNetworkCountryCode end ------");
}
}
diff --git a/thread/tests/unit/src/com/android/server/thread/ThreadNetworkCountryCodeTest.java b/thread/tests/unit/src/com/android/server/thread/ThreadNetworkCountryCodeTest.java
index 17cdd01..670449d 100644
--- a/thread/tests/unit/src/com/android/server/thread/ThreadNetworkCountryCodeTest.java
+++ b/thread/tests/unit/src/com/android/server/thread/ThreadNetworkCountryCodeTest.java
@@ -22,6 +22,7 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyDouble;
@@ -55,6 +56,7 @@
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import androidx.annotation.Nullable;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -70,6 +72,9 @@
import org.mockito.MockitoAnnotations;
import org.mockito.stubbing.Answer;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.io.StringWriter;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
@@ -80,6 +85,7 @@
public class ThreadNetworkCountryCodeTest {
private static final String TEST_COUNTRY_CODE_US = "US";
private static final String TEST_COUNTRY_CODE_CN = "CN";
+ private static final String TEST_COUNTRY_CODE_INVALID = "INVALID";
private static final int TEST_SIM_SLOT_INDEX_0 = 0;
private static final int TEST_SIM_SLOT_INDEX_1 = 1;
@@ -144,16 +150,20 @@
.when(mThreadNetworkControllerService)
.setCountryCode(any(), any(IOperationReceiver.class));
- mThreadNetworkCountryCode =
- new ThreadNetworkCountryCode(
- mLocationManager,
- mThreadNetworkControllerService,
- mGeocoder,
- mConnectivityResources,
- mWifiManager,
- mContext,
- mTelephonyManager,
- mSubscriptionManager);
+ mThreadNetworkCountryCode = newCountryCodeWithOemSource(null);
+ }
+
+ private ThreadNetworkCountryCode newCountryCodeWithOemSource(@Nullable String oemCountryCode) {
+ return new ThreadNetworkCountryCode(
+ mLocationManager,
+ mThreadNetworkControllerService,
+ mGeocoder,
+ mConnectivityResources,
+ mWifiManager,
+ mContext,
+ mTelephonyManager,
+ mSubscriptionManager,
+ oemCountryCode);
}
private static Address newAddress(String countryCode) {
@@ -163,6 +173,13 @@
}
@Test
+ public void threadNetworkCountryCode_invalidOemCountryCode_illegalArgumentExceptionIsThrown() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> newCountryCodeWithOemSource(TEST_COUNTRY_CODE_INVALID));
+ }
+
+ @Test
public void initialize_defaultCountryCodeIsUsed() {
mThreadNetworkCountryCode.initialize();
@@ -170,6 +187,15 @@
}
@Test
+ public void initialize_oemCountryCodeAvailable_oemCountryCodeIsUsed() {
+ mThreadNetworkCountryCode = newCountryCodeWithOemSource(TEST_COUNTRY_CODE_US);
+
+ mThreadNetworkCountryCode.initialize();
+
+ assertThat(mThreadNetworkCountryCode.getCountryCode()).isEqualTo(TEST_COUNTRY_CODE_US);
+ }
+
+ @Test
public void initialize_locationUseIsDisabled_locationFunctionIsNotCalled() {
when(mResources.getBoolean(R.bool.config_thread_location_use_for_country_code_enabled))
.thenReturn(false);
@@ -406,4 +432,22 @@
.setCountryCode(eq(TEST_COUNTRY_CODE_CN), mOperationReceiverCaptor.capture());
assertThat(mThreadNetworkCountryCode.getCountryCode()).isEqualTo(DEFAULT_COUNTRY_CODE);
}
+
+ @Test
+ public void dump_allCountryCodeInfoAreDumped() {
+ StringWriter stringWriter = new StringWriter();
+ PrintWriter printWriter = new PrintWriter(stringWriter);
+
+ mThreadNetworkCountryCode.dump(new FileDescriptor(), printWriter, null);
+ String outputString = stringWriter.toString();
+
+ assertThat(outputString).contains("mOverrideCountryCodeInfo");
+ assertThat(outputString).contains("mTelephonyCountryCodeSlotInfoMap");
+ assertThat(outputString).contains("mTelephonyCountryCodeInfo");
+ assertThat(outputString).contains("mWifiCountryCodeInfo");
+ assertThat(outputString).contains("mTelephonyLastCountryCodeInfo");
+ assertThat(outputString).contains("mLocationCountryCodeInfo");
+ assertThat(outputString).contains("mOemCountryCodeInfo");
+ assertThat(outputString).contains("mCurrentCountryCodeInfo");
+ }
}