Merge tag 'android-13.0.0_r52' into staging/lineage-20.0_merge-android-13.0.0_r52
Android 13.0.0 Release 52 (TQ3A.230605.012)
# -----BEGIN PGP SIGNATURE-----
#
# iF0EABECAB0WIQRDQNE1cO+UXoOBCWTorT+BmrEOeAUCZIi36wAKCRDorT+BmrEO
# eLn3AKCHopz4Zv4j/CzUTfwO+NVaMUUlAwCggAUKFIFt1DTl+gopp49WsGkJF6M=
# =mDLa
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue Jun 13 21:39:39 2023 EEST
# gpg: using DSA key 4340D13570EF945E83810964E8AD3F819AB10E78
# gpg: Good signature from "The Android Open Source Project <initial-contribution@android.com>" [marginal]
# gpg: initial-contribution@android.com: Verified 1716 signatures in the past
# 19 months. Encrypted 4 messages in the past 17 months.
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg: It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 4340 D135 70EF 945E 8381 0964 E8AD 3F81 9AB1 0E78
# By Bill Yi (1) and Yichun Li (1)
# Via Android Build Coastguard Worker (3) and Yichun Li (1)
* tag 'android-13.0.0_r52':
Update UiAutomator Condition
Import translations. DO NOT MERGE ANYWHERE
Change-Id: I8a59dd2b6e1e7f3c9c49533ac51626ca9c37e876
diff --git a/Tethering/Android.bp b/Tethering/Android.bp
index 2c7b868..4cff456 100644
--- a/Tethering/Android.bp
+++ b/Tethering/Android.bp
@@ -48,6 +48,7 @@
"net-utils-device-common-netlink",
"netd-client",
"tetheringstatsprotos",
+ "org.lineageos.platform.lineagesettings",
],
libs: [
"framework-connectivity",
diff --git a/Tethering/src/com/android/networkstack/tethering/Tethering.java b/Tethering/src/com/android/networkstack/tethering/Tethering.java
index 35a394d..81baa8e 100644
--- a/Tethering/src/com/android/networkstack/tethering/Tethering.java
+++ b/Tethering/src/com/android/networkstack/tethering/Tethering.java
@@ -26,6 +26,7 @@
import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED;
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
import static android.net.ConnectivityManager.EXTRA_NETWORK_INFO;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
import static android.net.TetheringManager.ACTION_TETHER_STATE_CHANGED;
import static android.net.TetheringManager.CONNECTIVITY_SCOPE_LOCAL;
@@ -161,6 +162,8 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
+import lineageos.providers.LineageSettings;
+
/**
*
* This class holds much of the business logic to allow Android devices
@@ -450,6 +453,17 @@
}
startTrackDefaultNetwork();
+
+ // Listen for allowing tethering upstream via VPN settings changes
+ final ContentObserver vpnSettingObserver = new ContentObserver(mHandler) {
+ @Override
+ public void onChange(boolean self) {
+ // Reconsider tethering upstream
+ mTetherMainSM.sendMessage(TetherMainSM.CMD_UPSTREAM_CHANGED);
+ }
+ };
+ mContext.getContentResolver().registerContentObserver(LineageSettings.Secure.getUriFor(
+ LineageSettings.Secure.TETHERING_ALLOW_VPN_UPSTREAMS), false, vpnSettingObserver);
}
private class TetheringThreadExecutor implements Executor {
@@ -2244,6 +2258,12 @@
}
public void updateUpstreamNetworkState(UpstreamNetworkState ns) {
+ // Disable hw offload on vpn upstream interfaces.
+ // setUpstreamLinkProperties() interprets null as disable.
+ if (ns != null && ns.networkCapabilities != null
+ && !ns.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_VPN)) {
+ ns = null;
+ }
mOffloadController.setUpstreamLinkProperties(
(ns != null) ? ns.linkProperties : null);
}
diff --git a/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java b/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
index 7c36054..705a052 100644
--- a/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
+++ b/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
@@ -16,7 +16,6 @@
package com.android.networkstack.tethering;
-import static android.content.Context.TELEPHONY_SERVICE;
import static android.net.ConnectivityManager.TYPE_ETHERNET;
import static android.net.ConnectivityManager.TYPE_MOBILE;
import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
@@ -36,7 +35,6 @@
import android.provider.Settings;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
import android.text.TextUtils;
import com.android.internal.annotations.VisibleForTesting;
@@ -408,10 +406,7 @@
/** Check whether dun is required. */
public static boolean checkDunRequired(Context ctx) {
- final TelephonyManager tm = (TelephonyManager) ctx.getSystemService(TELEPHONY_SERVICE);
- // TelephonyManager would uses the active data subscription, which should be the one used
- // by tethering.
- return (tm != null) ? tm.isTetheringApnRequired() : false;
+ return false;
}
public int getOffloadPollInterval() {
diff --git a/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java b/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java
index f8dd673..da9f8c9 100644
--- a/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java
+++ b/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java
@@ -55,6 +55,8 @@
import java.util.Objects;
import java.util.Set;
+import lineageos.providers.LineageSettings;
+
/**
* A class to centralize all the network and link properties information
@@ -136,6 +138,8 @@
// The current upstream network used for tethering.
private Network mTetheringUpstreamNetwork;
private boolean mPreferTestNetworks;
+ // Set if the Internet is considered reachable via a VPN network
+ private Network mVpnInternetNetwork;
public UpstreamNetworkMonitor(Context ctx, StateMachine tgt, SharedLog log, int what) {
mContext = ctx;
@@ -192,6 +196,7 @@
mListenAllCallback = null;
mTetheringUpstreamNetwork = null;
+ mVpnInternetNetwork = null;
mNetworkMap.clear();
}
@@ -323,6 +328,12 @@
* Returns null if no current upstream is available.
*/
public UpstreamNetworkState getCurrentPreferredUpstream() {
+ // Use VPN upstreams if hotspot settings allow.
+ if (mVpnInternetNetwork != null &&
+ LineageSettings.Secure.getInt(mContext.getContentResolver(),
+ LineageSettings.Secure.TETHERING_ALLOW_VPN_UPSTREAMS, 0) == 1) {
+ return mNetworkMap.get(mVpnInternetNetwork);
+ }
final UpstreamNetworkState dfltState = (mDefaultInternetNetwork != null)
? mNetworkMap.get(mDefaultInternetNetwork)
: null;
@@ -369,6 +380,7 @@
}
private void handleNetCap(Network network, NetworkCapabilities newNc) {
+ if (isVpnInternetNetwork(newNc)) mVpnInternetNetwork = network;
final UpstreamNetworkState prev = mNetworkMap.get(network);
if (prev == null || newNc.equals(prev.networkCapabilities)) {
// Ignore notifications about networks for which we have not yet
@@ -433,6 +445,10 @@
// - deletes the entry from the map only when the LISTEN_ALL
// callback gets notified.
+ if (network.equals(mVpnInternetNetwork)) {
+ mVpnInternetNetwork = null;
+ }
+
if (!mNetworkMap.containsKey(network)) {
// Ignore loss of networks about which we had not previously
// learned any information or for which we have already processed
@@ -653,6 +669,11 @@
&& !isCellular(ns.networkCapabilities);
}
+ private static boolean isVpnInternetNetwork(NetworkCapabilities nc) {
+ return (nc != null) && !nc.hasCapability(NET_CAPABILITY_NOT_VPN) &&
+ nc.hasCapability(NET_CAPABILITY_INTERNET);
+ }
+
private static UpstreamNetworkState findFirstDunNetwork(
Iterable<UpstreamNetworkState> netStates) {
for (UpstreamNetworkState ns : netStates) {
diff --git a/bpf_progs/bpf_shared.h b/bpf_progs/bpf_shared.h
index fd449a3..dbf0a9f 100644
--- a/bpf_progs/bpf_shared.h
+++ b/bpf_progs/bpf_shared.h
@@ -95,13 +95,13 @@
// 'static' - otherwise these constants end up in .rodata in the resulting .o post compilation
static const int COOKIE_UID_MAP_SIZE = 10000;
-static const int UID_COUNTERSET_MAP_SIZE = 2000;
+static const int UID_COUNTERSET_MAP_SIZE = 4000;
static const int APP_STATS_MAP_SIZE = 10000;
static const int STATS_MAP_SIZE = 5000;
static const int IFACE_INDEX_NAME_MAP_SIZE = 1000;
static const int IFACE_STATS_MAP_SIZE = 1000;
static const int CONFIGURATION_MAP_SIZE = 2;
-static const int UID_OWNER_MAP_SIZE = 2000;
+static const int UID_OWNER_MAP_SIZE = 4000;
#ifdef __cplusplus
diff --git a/framework/src/android/net/ConnectivitySettingsManager.java b/framework/src/android/net/ConnectivitySettingsManager.java
index 822e67d..32f8319 100644
--- a/framework/src/android/net/ConnectivitySettingsManager.java
+++ b/framework/src/android/net/ConnectivitySettingsManager.java
@@ -1050,7 +1050,7 @@
}
private static boolean isCallingFromSystem() {
- final int uid = Binder.getCallingUid();
+ final int uid = UserHandle.getAppId(Binder.getCallingUid());
final int pid = Binder.getCallingPid();
if (uid == Process.SYSTEM_UID && pid == Process.myPid()) {
return true;
diff --git a/service/jni/com_android_server_connectivity_ClatCoordinator.cpp b/service/jni/com_android_server_connectivity_ClatCoordinator.cpp
index ba836b2..cfe8171 100644
--- a/service/jni/com_android_server_connectivity_ClatCoordinator.cpp
+++ b/service/jni/com_android_server_connectivity_ClatCoordinator.cpp
@@ -87,7 +87,8 @@
// Picks a random interface ID that is checksum neutral with the IPv4 address and the NAT64 prefix.
jstring com_android_server_connectivity_ClatCoordinator_generateIpv6Address(
- JNIEnv* env, jobject clazz, jstring ifaceStr, jstring v4Str, jstring prefix64Str) {
+ JNIEnv* env, jobject clazz, jstring ifaceStr, jstring v4Str, jstring prefix64Str,
+ jint mark) {
ScopedUtfChars iface(env, ifaceStr);
ScopedUtfChars addr4(env, v4Str);
ScopedUtfChars prefix64(env, prefix64Str);
@@ -111,7 +112,7 @@
}
in6_addr v6;
- if (net::clat::generateIpv6Address(iface.c_str(), v4, nat64Prefix, &v6)) {
+ if (net::clat::generateIpv6Address(iface.c_str(), v4, nat64Prefix, &v6, mark)) {
jniThrowExceptionFmt(env, "java/io/IOException",
"Unable to find global source address on %s for %s", iface.c_str(),
prefix64.c_str());
@@ -498,7 +499,7 @@
{"native_selectIpv4Address", "(Ljava/lang/String;I)Ljava/lang/String;",
(void*)com_android_server_connectivity_ClatCoordinator_selectIpv4Address},
{"native_generateIpv6Address",
- "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)Ljava/lang/String;",
(void*)com_android_server_connectivity_ClatCoordinator_generateIpv6Address},
{"native_createTunInterface", "(Ljava/lang/String;)I",
(void*)com_android_server_connectivity_ClatCoordinator_createTunInterface},
diff --git a/service/native/libs/libclat/clatutils.cpp b/service/native/libs/libclat/clatutils.cpp
index 4a125ba..be86612 100644
--- a/service/native/libs/libclat/clatutils.cpp
+++ b/service/native/libs/libclat/clatutils.cpp
@@ -126,10 +126,19 @@
// Picks a random interface ID that is checksum neutral with the IPv4 address and the NAT64 prefix.
int generateIpv6Address(const char* iface, const in_addr v4, const in6_addr& nat64Prefix,
- in6_addr* v6) {
+ in6_addr* v6, uint32_t mark) {
int s = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (s == -1) return -errno;
+ // Socket's mark affects routing decisions (network selection)
+ // An fwmark is necessary for clat to bypass the VPN during initialization.
+ if ((mark != MARK_UNSET) && setsockopt(s, SOL_SOCKET, SO_MARK, &mark, sizeof(mark))) {
+ int ret = errno;
+ ALOGE("setsockopt(SOL_SOCKET, SO_MARK) failed: %s", strerror(errno));
+ close(s);
+ return -ret;
+ }
+
if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, iface, strlen(iface) + 1) == -1) {
close(s);
return -errno;
diff --git a/service/native/libs/libclat/include/libclat/clatutils.h b/service/native/libs/libclat/include/libclat/clatutils.h
index 812c86e..991b193 100644
--- a/service/native/libs/libclat/include/libclat/clatutils.h
+++ b/service/native/libs/libclat/include/libclat/clatutils.h
@@ -24,7 +24,7 @@
in_addr_t selectIpv4Address(const in_addr ip, int16_t prefixlen);
void makeChecksumNeutral(in6_addr* v6, const in_addr v4, const in6_addr& nat64Prefix);
int generateIpv6Address(const char* iface, const in_addr v4, const in6_addr& nat64Prefix,
- in6_addr* v6);
+ in6_addr* v6, uint32_t mark);
int detect_mtu(const struct in6_addr* plat_subnet, uint32_t plat_suffix, uint32_t mark);
int configure_packet_socket(int sock, in6_addr* addr, int ifindex);
diff --git a/service/src/com/android/server/connectivity/ClatCoordinator.java b/service/src/com/android/server/connectivity/ClatCoordinator.java
index 3272075..08c1fce 100644
--- a/service/src/com/android/server/connectivity/ClatCoordinator.java
+++ b/service/src/com/android/server/connectivity/ClatCoordinator.java
@@ -173,8 +173,8 @@
*/
@NonNull
public String generateIpv6Address(@NonNull String iface, @NonNull String v4,
- @NonNull String prefix64) throws IOException {
- return native_generateIpv6Address(iface, v4, prefix64);
+ @NonNull String prefix64, int mark) throws IOException {
+ return native_generateIpv6Address(iface, v4, prefix64, mark);
}
/**
@@ -529,10 +529,11 @@
}
// [2] Generate a checksum-neutral IID.
+ final Integer fwmark = getFwmark(netId);
final String pfx96Str = nat64Prefix.getAddress().getHostAddress();
final String v6Str;
try {
- v6Str = mDeps.generateIpv6Address(iface, v4Str, pfx96Str);
+ v6Str = mDeps.generateIpv6Address(iface, v4Str, pfx96Str, fwmark);
} catch (IOException e) {
throw new IOException("no IPv6 addresses were available for clat: " + e);
}
@@ -570,7 +571,6 @@
}
// Detect ipv4 mtu.
- final Integer fwmark = getFwmark(netId);
final int detectedMtu = mDeps.detectMtu(pfx96Str,
ByteBuffer.wrap(GOOGLE_DNS_4.getAddress()).getInt(), fwmark);
final int mtu = adjustMtu(detectedMtu);
@@ -819,7 +819,7 @@
private static native String native_selectIpv4Address(String v4addr, int prefixlen)
throws IOException;
private static native String native_generateIpv6Address(String iface, String v4,
- String prefix64) throws IOException;
+ String prefix64, int mark) throws IOException;
private static native int native_createTunInterface(String tuniface) throws IOException;
private static native int native_detectMtu(String platSubnet, int platSuffix, int mark)
throws IOException;
diff --git a/service/src/com/android/server/connectivity/PermissionMonitor.java b/service/src/com/android/server/connectivity/PermissionMonitor.java
index e4a2c20..0e265f9 100755
--- a/service/src/com/android/server/connectivity/PermissionMonitor.java
+++ b/service/src/com/android/server/connectivity/PermissionMonitor.java
@@ -495,7 +495,6 @@
// TODO : remove carryover package check in the future(b/31479477). All apps should just
// request the appropriate permission for their use case since android Q.
return isCarryoverPackage(app.applicationInfo)
- || isUidAllowedOnRestrictedNetworks(app.applicationInfo)
|| hasPermission(app, PERMISSION_MAINLINE_NETWORK_STACK)
|| hasPermission(app, NETWORK_STACK)
|| hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS);
diff --git a/tests/unit/java/com/android/server/connectivity/ClatCoordinatorTest.java b/tests/unit/java/com/android/server/connectivity/ClatCoordinatorTest.java
index 7c18ecb..5f0703f 100644
--- a/tests/unit/java/com/android/server/connectivity/ClatCoordinatorTest.java
+++ b/tests/unit/java/com/android/server/connectivity/ClatCoordinatorTest.java
@@ -202,12 +202,12 @@
*/
@Override
public String generateIpv6Address(@NonNull String iface, @NonNull String v4,
- @NonNull String prefix64) throws IOException {
+ @NonNull String prefix64, int mark) throws IOException {
if (BASE_IFACE.equals(iface) && XLAT_LOCAL_IPV4ADDR_STRING.equals(v4)
&& NAT64_PREFIX_STRING.equals(prefix64)) {
return XLAT_LOCAL_IPV6ADDR_STRING;
}
- fail("unsupported args: " + iface + ", " + v4 + ", " + prefix64);
+ fail("unsupported args: " + iface + ", " + v4 + ", " + prefix64 + ", " + mark);
return null;
}
@@ -408,7 +408,7 @@
// Generate a checksum-neutral IID.
inOrder.verify(mDeps).generateIpv6Address(eq(BASE_IFACE),
- eq(XLAT_LOCAL_IPV4ADDR_STRING), eq(NAT64_PREFIX_STRING));
+ eq(XLAT_LOCAL_IPV4ADDR_STRING), eq(NAT64_PREFIX_STRING), eq(MARK));
// Open, configure and bring up the tun interface.
inOrder.verify(mDeps).createTunInterface(eq(STACKED_IFACE));