Merge tag 'android-13.0.0_r8' into staging/lineage-20.0_merge-android-13.0.0_r8

Android 13.0.0 Release 8 (TP1A.221005.003)

# -----BEGIN PGP SIGNATURE-----
#
# iF0EABECAB0WIQRDQNE1cO+UXoOBCWTorT+BmrEOeAUCYzModwAKCRDorT+BmrEO
# eLxhAJ9+bLtHHlnGTSxx7ntvlkWFWpEf+gCfQevDy3/nWpABNveubJsNA9FdzFY=
# =rcNk
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue Sep 27 19:44:39 2022 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 1313 signatures in the past
#      11 months.  Encrypted 4 messages in the past 8 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 lucaslin
# Via Android Build Coastguard Worker
* tag 'android-13.0.0_r8':
  Test that VpnManager events will never be sent to Settings VPNs

Change-Id: Ifb0dad2d0f547eaaf0cd59b42c56cc20e5c49fdd
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/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/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);