Merge changes I19c2370e,I85f17cfd,I88e73cbd,Ife95ecdf,I83903596, ...
* changes:
gn2bp: Set out arg for build/util/version.py
gn2bp: Add required file to tool_files
gn2bp: format EVAL arg for build/util/version.py
gn2bp: Update input arg for build/util/version.py
gn2bp: add android:cronet to the TARGETS
gn2bp: Add genrule_header for make_dafsa.py
gn2bp: Update desc.json
diff --git a/framework/api/module-lib-current.txt b/framework/api/module-lib-current.txt
index a2a1ac0..073cca2 100644
--- a/framework/api/module-lib-current.txt
+++ b/framework/api/module-lib-current.txt
@@ -15,7 +15,7 @@
method @Nullable @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public android.net.LinkProperties getRedactedLinkPropertiesForPackage(@NonNull android.net.LinkProperties, int, @NonNull String);
method @Nullable @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public android.net.NetworkCapabilities getRedactedNetworkCapabilitiesForPackage(@NonNull android.net.NetworkCapabilities, int, @NonNull String);
method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerDefaultNetworkCallbackForUid(int, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
- method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerSystemDefaultNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
+ method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS}) public void registerSystemDefaultNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void removeUidFromMeteredNetworkAllowList(int);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void removeUidFromMeteredNetworkDenyList(int);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void replaceFirewallChain(int, @NonNull int[]);
diff --git a/framework/src/android/net/ConnectivityManager.java b/framework/src/android/net/ConnectivityManager.java
index b5c3c64..39c5af2 100644
--- a/framework/src/android/net/ConnectivityManager.java
+++ b/framework/src/android/net/ConnectivityManager.java
@@ -4789,7 +4789,8 @@
@SuppressLint({"ExecutorRegistration", "PairedRegistration"})
@RequiresPermission(anyOf = {
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
- android.Manifest.permission.NETWORK_SETTINGS})
+ android.Manifest.permission.NETWORK_SETTINGS,
+ android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS})
public void registerSystemDefaultNetworkCallback(@NonNull NetworkCallback networkCallback,
@NonNull Handler handler) {
CallbackHandler cbHandler = new CallbackHandler(handler);
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsConfigs.java b/service/mdns/com/android/server/connectivity/mdns/MdnsConfigs.java
index 41abba7..75c7e6c 100644
--- a/service/mdns/com/android/server/connectivity/mdns/MdnsConfigs.java
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsConfigs.java
@@ -101,4 +101,8 @@
public static boolean allowNetworkInterfaceIndexPropagation() {
return true;
}
+
+ public static boolean allowMultipleSrvRecordsPerHost() {
+ return true;
+ }
}
\ No newline at end of file
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsResponseDecoder.java b/service/mdns/com/android/server/connectivity/mdns/MdnsResponseDecoder.java
index 57b241e..e73de55 100644
--- a/service/mdns/com/android/server/connectivity/mdns/MdnsResponseDecoder.java
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsResponseDecoder.java
@@ -25,6 +25,7 @@
import java.io.EOFException;
import java.io.IOException;
import java.net.DatagramPacket;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
@@ -37,6 +38,8 @@
public static final int SUCCESS = 0;
private static final String TAG = "MdnsResponseDecoder";
private static final MdnsLogger LOGGER = new MdnsLogger(TAG);
+ private final boolean allowMultipleSrvRecordsPerHost =
+ MdnsConfigs.allowMultipleSrvRecordsPerHost();
private final String[] serviceType;
private final Clock clock;
@@ -281,13 +284,18 @@
for (MdnsRecord record : records) {
if (record instanceof MdnsInetAddressRecord) {
MdnsInetAddressRecord inetRecord = (MdnsInetAddressRecord) record;
- MdnsResponse response = findResponseWithHostName(responses, inetRecord.getName());
- if (inetRecord.getInet4Address() != null && response != null) {
- response.setInet4AddressRecord(inetRecord);
- response.setInterfaceIndex(interfaceIndex);
- } else if (inetRecord.getInet6Address() != null && response != null) {
- response.setInet6AddressRecord(inetRecord);
- response.setInterfaceIndex(interfaceIndex);
+ if (allowMultipleSrvRecordsPerHost) {
+ List<MdnsResponse> matchingResponses =
+ findResponsesWithHostName(responses, inetRecord.getName());
+ for (MdnsResponse response : matchingResponses) {
+ assignInetRecord(response, inetRecord, interfaceIndex);
+ }
+ } else {
+ MdnsResponse response =
+ findResponseWithHostName(responses, inetRecord.getName());
+ if (response != null) {
+ assignInetRecord(response, inetRecord, interfaceIndex);
+ }
}
}
}
@@ -295,6 +303,39 @@
return SUCCESS;
}
+ private static void assignInetRecord(
+ MdnsResponse response, MdnsInetAddressRecord inetRecord, int interfaceIndex) {
+ if (inetRecord.getInet4Address() != null) {
+ response.setInet4AddressRecord(inetRecord);
+ response.setInterfaceIndex(interfaceIndex);
+ } else if (inetRecord.getInet6Address() != null) {
+ response.setInet6AddressRecord(inetRecord);
+ response.setInterfaceIndex(interfaceIndex);
+ }
+ }
+
+ private static List<MdnsResponse> findResponsesWithHostName(
+ @Nullable List<MdnsResponse> responses, String[] hostName) {
+ if (responses == null || responses.isEmpty()) {
+ return List.of();
+ }
+
+ List<MdnsResponse> result = null;
+ for (MdnsResponse response : responses) {
+ MdnsServiceRecord serviceRecord = response.getServiceRecord();
+ if (serviceRecord == null) {
+ continue;
+ }
+ if (Arrays.equals(serviceRecord.getServiceHost(), hostName)) {
+ if (result == null) {
+ result = new ArrayList<>(/* initialCapacity= */ responses.size());
+ }
+ result.add(response);
+ }
+ }
+ return result == null ? List.of() : result;
+ }
+
public static class Clock {
public long elapsedRealtime() {
return SystemClock.elapsedRealtime();
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index 3efd5e5..1b16b72 100755
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -2810,6 +2810,13 @@
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
}
+ private void enforceSettingsOrUseRestrictedNetworksPermission() {
+ enforceAnyPermissionOf(mContext,
+ android.Manifest.permission.NETWORK_SETTINGS,
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+ Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS);
+ }
+
private void enforceNetworkFactoryPermission() {
// TODO: Check for the BLUETOOTH_STACK permission once that is in the API surface.
if (UserHandle.getAppId(getCallingUid()) == Process.BLUETOOTH_UID) return;
@@ -6656,7 +6663,7 @@
enforceAccessPermission();
break;
case TRACK_SYSTEM_DEFAULT:
- enforceSettingsPermission();
+ enforceSettingsOrUseRestrictedNetworksPermission();
networkCapabilities = new NetworkCapabilities(defaultNc);
break;
case BACKGROUND_REQUEST:
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index 218eb04..c9899a2 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -1047,12 +1047,22 @@
final TestNetworkCallback bestMatchingCallback = new TestNetworkCallback();
final Handler h = new Handler(Looper.getMainLooper());
if (TestUtils.shouldTestSApis()) {
+ assertThrows(SecurityException.class, () ->
+ registerSystemDefaultNetworkCallback(systemDefaultCallback, h));
runWithShellPermissionIdentity(() -> {
registerSystemDefaultNetworkCallback(systemDefaultCallback, h);
registerDefaultNetworkCallbackForUid(Process.myUid(), perUidCallback, h);
}, NETWORK_SETTINGS);
registerBestMatchingNetworkCallback(makeDefaultRequest(), bestMatchingCallback, h);
}
+ if (TestUtils.shouldTestTApis()) {
+ // Verify registerSystemDefaultNetworkCallback can be accessed via
+ // CONNECTIVITY_USE_RESTRICTED_NETWORKS permission.
+ final TestNetworkCallback systemDefaultCallback2 = new TestNetworkCallback();
+ runWithShellPermissionIdentity(() ->
+ registerSystemDefaultNetworkCallback(systemDefaultCallback2, h),
+ CONNECTIVITY_USE_RESTRICTED_NETWORKS);
+ }
Network wifiNetwork = null;
mCtsNetUtils.ensureWifiConnected();
diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
index 6cc622f..6687f76 100755
--- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
@@ -5181,9 +5181,10 @@
}
@Test
- public void testRegisterPrivilegedDefaultCallbacksRequireNetworkSettings() throws Exception {
+ public void testRegisterPrivilegedDefaultCallbacksRequirePermissions() throws Exception {
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
mCellNetworkAgent.connect(false /* validated */);
+ mServiceContext.setPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERMISSION_DENIED);
final Handler handler = new Handler(ConnectivityThread.getInstanceLooper());
final TestNetworkCallback callback = new TestNetworkCallback();
@@ -5194,6 +5195,12 @@
() -> mCm.registerDefaultNetworkCallbackForUid(APP1_UID, callback, handler));
callback.assertNoCallback();
+ mServiceContext.setPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERMISSION_GRANTED);
+ mCm.registerSystemDefaultNetworkCallback(callback, handler);
+ mServiceContext.setPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERMISSION_DENIED);
+ callback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
+ mCm.unregisterNetworkCallback(callback);
+
mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED);
mCm.registerSystemDefaultNetworkCallback(callback, handler);
callback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseDecoderTests.java b/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseDecoderTests.java
index 8d0ace5..02e00c2 100644
--- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseDecoderTests.java
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseDecoderTests.java
@@ -26,11 +26,14 @@
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
+import android.net.InetAddresses;
+
import com.android.net.module.util.HexDump;
import com.android.testutils.DevSdkIgnoreRule;
import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -106,9 +109,49 @@
+ "63616C0000018001000000780004C0A8010A000001800100000078"
+ "0004C0A8010A00000000000000");
+ // Expected to contain two SRV records which point to the same hostname.
+ private static final byte[] matterDuplicateHostname = HexDump.hexStringToByteArray(
+ "00008000000000080000000A095F7365727669636573075F646E732D73"
+ + "64045F756470056C6F63616C00000C000100000078000F075F6D61"
+ + "74746572045F746370C023C00C000C000100000078001A125F4943"
+ + "324639453337374632454139463430045F737562C034C034000C00"
+ + "0100000078002421433246394533373746324541394634302D3030"
+ + "3030303030304534443041334641C034C04F000C00010000007800"
+ + "02C075C00C000C0001000000780002C034C00C000C000100000078"
+ + "0015125F4941413035363731333439334135343144C062C034000C"
+ + "000100000078002421414130353637313334393341353431442D30"
+ + "303030303030304331324446303344C034C0C1000C000100000078"
+ + "0002C0E2C075002100010000007800150000000015A40C33433631"
+ + "3035304338394638C023C07500100001000011940015084352493D"
+ + "35303030074352413D33303003543D31C126001C00010000007800"
+ + "10FE800000000000003E6105FFFE0C89F8C126001C000100000078"
+ + "00102605A601A84657003E6105FFFE0C89F8C12600010001000000"
+ + "780004C0A8018AC0E2002100010000007800080000000015A4C126"
+ + "C0E200100001000011940015084352493D35303030074352413D33"
+ + "303003543D31C126001C0001000000780010FE800000000000003E"
+ + "6105FFFE0C89F8C126001C00010000007800102605A601A8465700"
+ + "3E6105FFFE0C89F8C12600010001000000780004C0A8018A313035"
+ + "304338394638C02300010001000000780004C0A8018AC0A0001000"
+ + "0100001194003A0E56503D36353532312B3332373639084352493D"
+ + "35303030074352413D33303003543D3106443D3236353704434D3D"
+ + "320550483D33360350493D21433246394533373746324541394634"
+ + "302D30303030303030304534443041334641C0F700210001000000"
+ + "7800150000000015A40C334336313035304338394638C023214332"
+ + "46394533373746324541394634302D303030303030303045344430"
+ + "41334641C0F700100001000011940015084352493D353030300743"
+ + "52413D33303003543D310C334336313035304338394638C023001C"
+ + "0001000000780010FE800000000000003E6105FFFE0C89F80C3343"
+ + "36313035304338394638C023001C00010000007800102605A601A8"
+ + "4657003E6105FFFE0C89F80C334336313035304338394638C02300"
+ + "010001000000780004C0A8018A0000000000000000000000000000"
+ + "000000");
+
private static final String CAST_SERVICE_NAME = "_googlecast";
private static final String[] CAST_SERVICE_TYPE =
new String[] {CAST_SERVICE_NAME, "_tcp", "local"};
+ private static final String MATTER_SERVICE_NAME = "_matter";
+ private static final String[] MATTER_SERVICE_TYPE =
+ new String[] {MATTER_SERVICE_NAME, "_tcp", "local"};
private final List<MdnsResponse> responses = new LinkedList<>();
@@ -249,4 +292,62 @@
assertEquals(responses.size(), 1);
assertEquals(responses.get(0).getInterfaceIndex(), 10);
}
+
+ @Test
+ public void decode_singleHostname_multipleSrvRecords_flagEnabled_multipleCompleteResponses() {
+ //MdnsScannerConfigsFlagsImpl.allowMultipleSrvRecordsPerHost.override(true);
+ MdnsResponseDecoder decoder = new MdnsResponseDecoder(mClock, MATTER_SERVICE_TYPE);
+ assertNotNull(matterDuplicateHostname);
+
+ DatagramPacket packet =
+ new DatagramPacket(matterDuplicateHostname, matterDuplicateHostname.length);
+
+ packet.setSocketAddress(
+ new InetSocketAddress(MdnsConstants.getMdnsIPv6Address(), MdnsConstants.MDNS_PORT));
+
+ responses.clear();
+ int errorCode = decoder.decode(packet, responses, /* interfaceIndex= */ 0);
+ assertEquals(MdnsResponseDecoder.SUCCESS, errorCode);
+
+ // This should emit two records:
+ assertEquals(2, responses.size());
+
+ MdnsResponse response1 = responses.get(0);
+ MdnsResponse response2 = responses.get(0);
+
+ // Both of which are complete:
+ assertTrue(response1.isComplete());
+ assertTrue(response2.isComplete());
+
+ // And should both have the same IPv6 address:
+ assertEquals(InetAddresses.parseNumericAddress("2605:a601:a846:5700:3e61:5ff:fe0c:89f8"),
+ response1.getInet6AddressRecord().getInet6Address());
+ assertEquals(InetAddresses.parseNumericAddress("2605:a601:a846:5700:3e61:5ff:fe0c:89f8"),
+ response2.getInet6AddressRecord().getInet6Address());
+ }
+
+ @Test
+ @Ignore("MdnsConfigs is not configurable currently.")
+ public void decode_singleHostname_multipleSrvRecords_flagDisabled_singleCompleteResponse() {
+ //MdnsScannerConfigsFlagsImpl.allowMultipleSrvRecordsPerHost.override(false);
+ MdnsResponseDecoder decoder = new MdnsResponseDecoder(mClock, MATTER_SERVICE_TYPE);
+ assertNotNull(matterDuplicateHostname);
+
+ DatagramPacket packet =
+ new DatagramPacket(matterDuplicateHostname, matterDuplicateHostname.length);
+
+ packet.setSocketAddress(
+ new InetSocketAddress(MdnsConstants.getMdnsIPv6Address(), MdnsConstants.MDNS_PORT));
+
+ responses.clear();
+ int errorCode = decoder.decode(packet, responses, /* interfaceIndex= */ 0);
+ assertEquals(MdnsResponseDecoder.SUCCESS, errorCode);
+
+ // This should emit only two records:
+ assertEquals(2, responses.size());
+
+ // But only the first is complete:
+ assertTrue(responses.get(0).isComplete());
+ assertFalse(responses.get(1).isComplete());
+ }
}
\ No newline at end of file