summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Tethering/src/com/android/networkstack/tethering/Tethering.java18
-rw-r--r--Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java9
-rw-r--r--Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java20
-rw-r--r--framework/api/system-current.txt1
-rw-r--r--framework/src/android/net/ConnectivityManager.java29
-rw-r--r--framework/src/android/net/ConnectivitySettingsManager.java2
-rw-r--r--framework/src/android/net/IConnectivityManager.aidl2
-rw-r--r--framework/src/android/net/util/DnsUtils.java4
-rw-r--r--service/src/com/android/server/ConnectivityService.java6
-rw-r--r--service/src/com/android/server/connectivity/NetworkDiagnostics.java4
-rwxr-xr-xservice/src/com/android/server/connectivity/PermissionMonitor.java145
11 files changed, 155 insertions, 85 deletions
diff --git a/Tethering/src/com/android/networkstack/tethering/Tethering.java b/Tethering/src/com/android/networkstack/tethering/Tethering.java
index c39fe3ec68..54288956fc 100644
--- a/Tethering/src/com/android/networkstack/tethering/Tethering.java
+++ b/Tethering/src/com/android/networkstack/tethering/Tethering.java
@@ -27,6 +27,7 @@ import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS;
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;
@@ -428,6 +429,17 @@ public class Tethering {
}
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(Settings.Secure.getUriFor(
+ Settings.Secure.TETHERING_ALLOW_VPN_UPSTREAMS), false, vpnSettingObserver);
}
private class TetheringThreadExecutor implements Executor {
@@ -2106,6 +2118,12 @@ public class Tethering {
}
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 b6240c4561..0ba43af9b7 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;
@@ -31,7 +30,6 @@ import android.net.util.SharedLog;
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
import android.text.TextUtils;
import com.android.internal.annotations.VisibleForTesting;
@@ -75,7 +73,7 @@ public class TetheringConfiguration {
"192.168.48.2", "192.168.48.254", "192.168.49.2", "192.168.49.254",
};
- private static final String[] DEFAULT_IPV4_DNS = {"8.8.4.4", "8.8.8.8"};
+ private static final String[] DEFAULT_IPV4_DNS = {"1.0.0.1", "1.1.1.1"};
@VisibleForTesting
public static final int TETHER_USB_RNDIS_FUNCTION = 0;
@@ -370,10 +368,7 @@ public class TetheringConfiguration {
/** 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 69471a1516..91be427102 100644
--- a/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java
+++ b/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java
@@ -39,6 +39,7 @@ import android.net.NetworkRequest;
import android.net.util.PrefixUtils;
import android.net.util.SharedLog;
import android.os.Handler;
+import android.provider.Settings;
import android.util.Log;
import android.util.SparseIntArray;
@@ -136,6 +137,8 @@ public class UpstreamNetworkMonitor {
private Network mDefaultInternetNetwork;
// The current upstream network used for tethering.
private Network mTetheringUpstreamNetwork;
+ // 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;
@@ -197,6 +200,7 @@ public class UpstreamNetworkMonitor {
mListenAllCallback = null;
mTetheringUpstreamNetwork = null;
+ mVpnInternetNetwork = null;
mNetworkMap.clear();
}
@@ -328,6 +332,12 @@ public class UpstreamNetworkMonitor {
* Returns null if no current upstream is available.
*/
public UpstreamNetworkState getCurrentPreferredUpstream() {
+ // Use VPN upstreams if hotspot settings allow.
+ if (mVpnInternetNetwork != null &&
+ Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.TETHERING_ALLOW_VPN_UPSTREAMS, 0) == 1) {
+ return mNetworkMap.get(mVpnInternetNetwork);
+ }
final UpstreamNetworkState dfltState = (mDefaultInternetNetwork != null)
? mNetworkMap.get(mDefaultInternetNetwork)
: null;
@@ -369,6 +379,7 @@ public class UpstreamNetworkMonitor {
}
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 +444,10 @@ public class UpstreamNetworkMonitor {
// - 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 +668,11 @@ public class UpstreamNetworkMonitor {
&& !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/api/system-current.txt b/framework/api/system-current.txt
index d1d51da151..09a678d9be 100644
--- a/framework/api/system-current.txt
+++ b/framework/api/system-current.txt
@@ -51,6 +51,7 @@ package android.net {
method @Deprecated @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public String getCaptivePortalServerUrl();
method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void getLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEntitlementResultListener);
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public boolean isTetheringSupported();
+ method public void onPackagePermissionChanged(int);
method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_FACTORY}) public int registerNetworkProvider(@NonNull android.net.NetworkProvider);
method public void registerQosCallback(@NonNull android.net.QosSocketInfo, @NonNull java.util.concurrent.Executor, @NonNull android.net.QosCallback);
method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEventCallback);
diff --git a/framework/src/android/net/ConnectivityManager.java b/framework/src/android/net/ConnectivityManager.java
index 2eb5fb72a6..1a0d8c8029 100644
--- a/framework/src/android/net/ConnectivityManager.java
+++ b/framework/src/android/net/ConnectivityManager.java
@@ -16,6 +16,7 @@
package android.net;
import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
+import static android.annotation.SystemApi.Client.SYSTEM_SERVER;
import static android.net.NetworkRequest.Type.BACKGROUND_REQUEST;
import static android.net.NetworkRequest.Type.LISTEN;
import static android.net.NetworkRequest.Type.LISTEN_FOR_BEST;
@@ -24,6 +25,7 @@ import static android.net.NetworkRequest.Type.TRACK_DEFAULT;
import static android.net.NetworkRequest.Type.TRACK_SYSTEM_DEFAULT;
import static android.net.QosCallback.QosCallbackRegistrationException;
+import android.Manifest;
import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -34,12 +36,15 @@ import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.SystemService;
+import android.annotation.UserIdInt;
import android.app.PendingIntent;
import android.app.admin.DevicePolicyManager;
+import android.app.compat.gms.GmsCompat;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.net.ConnectivityDiagnosticsManager.DataStallReport.DetectionMethod;
import android.net.IpSecManager.UdpEncapsulationSocket;
import android.net.SocketKeepalive.Callback;
@@ -2605,6 +2610,10 @@ public class ConnectivityManager {
@RequiresPermission(anyOf = {android.Manifest.permission.TETHER_PRIVILEGED,
android.Manifest.permission.WRITE_SETTINGS})
public boolean isTetheringSupported() {
+ if (GmsCompat.isEnabled()) {
+ return false;
+ }
+
return getTetheringManager().isTetheringSupported();
}
@@ -3137,6 +3146,12 @@ public class ConnectivityManager {
*/
public void reportNetworkConnectivity(@Nullable Network network, boolean hasConnectivity) {
printStackTrace();
+ if (mContext.checkSelfPermission(Manifest.permission.INTERNET) != PackageManager.PERMISSION_GRANTED) {
+ // ConnectivityService enforces this by throwing an unexpected SecurityException,
+ // which puts GMS into a crash loop. Also useful for other apps that don't expect that
+ // INTERNET permission might get revoked.
+ return;
+ }
try {
mService.reportNetworkConnectivity(network, hasConnectivity);
} catch (RemoteException e) {
@@ -5499,4 +5514,18 @@ public class ConnectivityManager {
public static Range<Integer> getIpSecNetIdRange() {
return new Range(TUN_INTF_NETID_START, TUN_INTF_NETID_START + TUN_INTF_NETID_RANGE - 1);
}
+
+ /**
+ * Notify ConnectivityService of a runtime permission change for the given package and user ID.
+ *
+ * @hide
+ */
+ @SystemApi
+ public void onPackagePermissionChanged(int uid) {
+ try {
+ mService.onPackagePermissionChanged(uid);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
}
diff --git a/framework/src/android/net/ConnectivitySettingsManager.java b/framework/src/android/net/ConnectivitySettingsManager.java
index 8fc0065347..9c8d08fb1a 100644
--- a/framework/src/android/net/ConnectivitySettingsManager.java
+++ b/framework/src/android/net/ConnectivitySettingsManager.java
@@ -1042,7 +1042,7 @@ public class ConnectivitySettingsManager {
}
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/framework/src/android/net/IConnectivityManager.aidl b/framework/src/android/net/IConnectivityManager.aidl
index 50ec78120f..2d09c04229 100644
--- a/framework/src/android/net/IConnectivityManager.aidl
+++ b/framework/src/android/net/IConnectivityManager.aidl
@@ -228,4 +228,6 @@ interface IConnectivityManager
void unofferNetwork(in INetworkOfferCallback callback);
void setTestAllowBadWifiUntil(long timeMs);
+
+ void onPackagePermissionChanged(int uid);
}
diff --git a/framework/src/android/net/util/DnsUtils.java b/framework/src/android/net/util/DnsUtils.java
index 3fe245edb9..d3e2f66105 100644
--- a/framework/src/android/net/util/DnsUtils.java
+++ b/framework/src/android/net/util/DnsUtils.java
@@ -342,7 +342,7 @@ public class DnsUtils {
*/
public static boolean haveIpv4(@Nullable Network network) {
final SocketAddress addrIpv4 =
- new InetSocketAddress(InetAddresses.parseNumericAddress("8.8.8.8"), 0);
+ new InetSocketAddress(InetAddresses.parseNumericAddress("1.1.1.1"), 0);
return checkConnectivity(network, AF_INET, addrIpv4);
}
@@ -352,7 +352,7 @@ public class DnsUtils {
*/
public static boolean haveIpv6(@Nullable Network network) {
final SocketAddress addrIpv6 =
- new InetSocketAddress(InetAddresses.parseNumericAddress("2000::"), 0);
+ new InetSocketAddress(InetAddresses.parseNumericAddress("2606:4700:4700::1001"), 0);
return checkConnectivity(network, AF_INET6, addrIpv6);
}
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index 418e9e33b8..d4da9a42a6 100644
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -93,6 +93,7 @@ import static java.util.Map.Entry;
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UserIdInt;
import android.app.AppOpsManager;
import android.app.BroadcastOptions;
import android.app.PendingIntent;
@@ -10346,4 +10347,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
return createNetworkRequest(NetworkRequest.Type.REQUEST, netcap);
}
}
+
+ @Override
+ public void onPackagePermissionChanged(int uid) {
+ mPermissionMonitor.onInternetPermissionChanged(uid);
+ }
}
diff --git a/service/src/com/android/server/connectivity/NetworkDiagnostics.java b/service/src/com/android/server/connectivity/NetworkDiagnostics.java
index 2e51be39bf..9aa754ea36 100644
--- a/service/src/com/android/server/connectivity/NetworkDiagnostics.java
+++ b/service/src/com/android/server/connectivity/NetworkDiagnostics.java
@@ -97,9 +97,9 @@ import javax.net.ssl.SSLSocketFactory;
public class NetworkDiagnostics {
private static final String TAG = "NetworkDiagnostics";
- private static final InetAddress TEST_DNS4 = InetAddresses.parseNumericAddress("8.8.8.8");
+ private static final InetAddress TEST_DNS4 = InetAddresses.parseNumericAddress("1.1.1.1");
private static final InetAddress TEST_DNS6 = InetAddresses.parseNumericAddress(
- "2001:4860:4860::8888");
+ "2606:4700:4700::1001");
// For brevity elsewhere.
private static final long now() {
diff --git a/service/src/com/android/server/connectivity/PermissionMonitor.java b/service/src/com/android/server/connectivity/PermissionMonitor.java
index a49c0a6e8e..8625f3c803 100755
--- a/service/src/com/android/server/connectivity/PermissionMonitor.java
+++ b/service/src/com/android/server/connectivity/PermissionMonitor.java
@@ -32,6 +32,7 @@ import static android.os.Process.SYSTEM_UID;
import static com.android.net.module.util.CollectionUtils.toIntArray;
import android.annotation.NonNull;
+import android.annotation.UserIdInt;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -224,42 +225,44 @@ public class PermissionMonitor {
// mUidsAllowedOnRestrictedNetworks.
updateUidsAllowedOnRestrictedNetworks(mDeps.getUidsAllowedOnRestrictedNetworks(mContext));
- List<PackageInfo> apps = mPackageManager.getInstalledPackages(GET_PERMISSIONS
- | MATCH_ANY_USER);
- if (apps == null) {
- loge("No apps");
- return;
- }
-
SparseIntArray netdPermsUids = new SparseIntArray();
- for (PackageInfo app : apps) {
- int uid = app.applicationInfo != null ? app.applicationInfo.uid : INVALID_UID;
- if (uid < 0) {
+ mUsers.addAll(mUserManager.getUserHandles(true /* excludeDying */));
+
+ for(UserHandle user : mUsers){
+ PackageManager pmUser = mContext.createContextAsUser(user,0).getPackageManager();
+ List<PackageInfo> apps = pmUser.getInstalledPackages(GET_PERMISSIONS);
+ if (apps == null) {
+ loge("No apps");
continue;
}
- mAllApps.add(UserHandle.getAppId(uid));
- boolean isNetwork = hasNetworkPermission(app);
- boolean hasRestrictedPermission = hasRestrictedNetworkPermission(app);
+ for (PackageInfo app : apps) {
+ int uid = app.applicationInfo != null ? app.applicationInfo.uid : INVALID_UID;
+ if (uid < 0) {
+ continue;
+ }
+ mAllApps.add(uid);
- if (isNetwork || hasRestrictedPermission) {
- Boolean permission = mApps.get(UserHandle.getAppId(uid));
- // If multiple packages share a UID (cf: android:sharedUserId) and ask for different
- // permissions, don't downgrade (i.e., if it's already SYSTEM, leave it as is).
- if (permission == null || permission == NETWORK) {
- mApps.put(UserHandle.getAppId(uid), hasRestrictedPermission);
+ boolean isNetwork = hasNetworkPermission(app);
+ boolean hasRestrictedPermission = hasRestrictedNetworkPermission(app);
+
+ if (isNetwork || hasRestrictedPermission) {
+ Boolean permission = mApps.get(uid);
+ // If multiple packages share a UID (cf: android:sharedUserId) and ask for different
+ // permissions, don't downgrade (i.e., if it's already SYSTEM, leave it as is).
+ if (permission == null || permission == NETWORK) {
+ mApps.put(uid, hasRestrictedPermission);
+ }
}
- }
- //TODO: unify the management of the permissions into one codepath.
- int otherNetdPerms = getNetdPermissionMask(app.requestedPermissions,
- app.requestedPermissionsFlags);
- netdPermsUids.put(uid, netdPermsUids.get(uid) | otherNetdPerms);
+ //TODO: unify the management of the permissions into one codepath.
+ int otherNetdPerms = getNetdPermissionMask(app.requestedPermissions,
+ app.requestedPermissionsFlags);
+ netdPermsUids.put(uid, netdPermsUids.get(uid) | otherNetdPerms);
+ }
}
- mUsers.addAll(mUserManager.getUserHandles(true /* excludeDying */));
-
final SparseArray<String> netdPermToSystemPerm = new SparseArray<>();
netdPermToSystemPerm.put(INetd.PERMISSION_INTERNET, INTERNET);
netdPermToSystemPerm.put(INetd.PERMISSION_UPDATE_DEVICE_STATS, UPDATE_DEVICE_STATS);
@@ -278,6 +281,10 @@ public class PermissionMonitor {
sendPackagePermissionsToNetd(netdPermsUids);
}
+ public void onInternetPermissionChanged(int uid) {
+ sendPackagePermissionsForUid(uid, getPermissionForUid(uid));
+ }
+
@VisibleForTesting
synchronized void updateUidsAllowedOnRestrictedNetworks(final Set<Integer> uids) {
mUidsAllowedOnRestrictedNetworks.clear();
@@ -286,9 +293,7 @@ public class PermissionMonitor {
// is only installed on some users because the uid cannot match some other app – this uid is
// in effect not installed and can't be run.
// TODO (b/192431153): Change appIds back to uids.
- for (int uid : uids) {
- mUidsAllowedOnRestrictedNetworks.add(UserHandle.getAppId(uid));
- }
+ mUidsAllowedOnRestrictedNetworks.addAll(uids);
}
@VisibleForTesting
@@ -310,7 +315,7 @@ public class PermissionMonitor {
if (appInfo == null) return false;
// Check whether package's uid is in allowed on restricted networks uid list. If so, this
// uid can have netd system permission.
- return mUidsAllowedOnRestrictedNetworks.contains(UserHandle.getAppId(appInfo.uid));
+ return mUidsAllowedOnRestrictedNetworks.contains(appInfo.uid);
}
@VisibleForTesting
@@ -346,14 +351,14 @@ public class PermissionMonitor {
// networks. mApps contains the result of checks for both hasNetworkPermission and
// hasRestrictedNetworkPermission. If uid is in the mApps list that means uid has one of
// permissions at least.
- return mApps.containsKey(UserHandle.getAppId(uid));
+ return mApps.containsKey(uid);
}
/**
* Returns whether the given uid has permission to use restricted networks.
*/
public synchronized boolean hasRestrictedNetworksPermission(int uid) {
- return Boolean.TRUE.equals(mApps.get(UserHandle.getAppId(uid)));
+ return Boolean.TRUE.equals(mApps.get(uid));
}
private void update(Set<UserHandle> users, Map<Integer, Boolean> apps, boolean add) {
@@ -419,21 +424,17 @@ public class PermissionMonitor {
* permission.
*/
@VisibleForTesting
- protected Boolean highestPermissionForUid(Boolean currentPermission, String name) {
+ protected Boolean highestPermissionForUid(Boolean currentPermission, String name, int uid) {
if (currentPermission == SYSTEM) {
return currentPermission;
}
- try {
- final PackageInfo app = mPackageManager.getPackageInfo(name,
- GET_PERMISSIONS | MATCH_ANY_USER);
+ final PackageInfo app = getPackageInfo(name, UserHandle.getUserHandleForUid(uid));
+ if(app != null){
final boolean isNetwork = hasNetworkPermission(app);
final boolean hasRestrictedPermission = hasRestrictedNetworkPermission(app);
if (isNetwork || hasRestrictedPermission) {
currentPermission = hasRestrictedPermission;
}
- } catch (NameNotFoundException e) {
- // App not found.
- loge("NameNotFoundException " + name);
}
return currentPermission;
}
@@ -445,7 +446,7 @@ public class PermissionMonitor {
final String[] packages = mPackageManager.getPackagesForUid(uid);
if (packages != null && packages.length > 0) {
for (String name : packages) {
- final PackageInfo app = getPackageInfo(name);
+ PackageInfo app = getPackageInfo(name, UserHandle.getUserHandleForUid(uid));
if (app != null && app.requestedPermissions != null) {
permission |= getNetdPermissionMask(app.requestedPermissions,
app.requestedPermissionsFlags);
@@ -469,17 +470,16 @@ public class PermissionMonitor {
public synchronized void onPackageAdded(@NonNull final String packageName, final int uid) {
// TODO: Netd is using appId for checking traffic permission. Correct the methods that are
// using appId instead of uid actually
- sendPackagePermissionsForUid(UserHandle.getAppId(uid), getPermissionForUid(uid));
+ sendPackagePermissionsForUid(uid, getPermissionForUid(uid));
// If multiple packages share a UID (cf: android:sharedUserId) and ask for different
// permissions, don't downgrade (i.e., if it's already SYSTEM, leave it as is).
- final int appId = UserHandle.getAppId(uid);
- final Boolean permission = highestPermissionForUid(mApps.get(appId), packageName);
- if (permission != mApps.get(appId)) {
- mApps.put(appId, permission);
+ final Boolean permission = highestPermissionForUid(mApps.get(uid), packageName, uid);
+ if (permission != mApps.get(uid)) {
+ mApps.put(uid, permission);
Map<Integer, Boolean> apps = new HashMap<>();
- apps.put(appId, permission);
+ apps.put(uid, permission);
update(mUsers, apps, true);
}
@@ -494,7 +494,7 @@ public class PermissionMonitor {
updateVpnUids(vpn.getKey(), changedUids, true);
}
}
- mAllApps.add(appId);
+ mAllApps.add(uid);
}
private Boolean highestUidNetworkPermission(int uid) {
@@ -504,7 +504,7 @@ public class PermissionMonitor {
for (String name : packages) {
// If multiple packages have the same UID, give the UID all permissions that
// any package in that UID has.
- permission = highestPermissionForUid(permission, name);
+ permission = highestPermissionForUid(permission, name, uid);
if (permission == SYSTEM) {
break;
}
@@ -524,7 +524,7 @@ public class PermissionMonitor {
public synchronized void onPackageRemoved(@NonNull final String packageName, final int uid) {
// TODO: Netd is using appId for checking traffic permission. Correct the methods that are
// using appId instead of uid actually
- sendPackagePermissionsForUid(UserHandle.getAppId(uid), getPermissionForUid(uid));
+ sendPackagePermissionsForUid(uid, getPermissionForUid(uid));
// If the newly-removed package falls within some VPN's uid range, update Netd with it.
// This needs to happen before the mApps update below, since removeBypassingUids() depends
@@ -539,11 +539,11 @@ public class PermissionMonitor {
}
// If the package has been removed from all users on the device, clear it form mAllApps.
if (mPackageManager.getNameForUid(uid) == null) {
- mAllApps.remove(UserHandle.getAppId(uid));
+ mAllApps.remove(uid);
}
Map<Integer, Boolean> apps = new HashMap<>();
- final Boolean permission = highestUidNetworkPermission(uid);
+ final Boolean permission = highestPermissionForUid(null, packageName,uid);
if (permission == SYSTEM) {
// An app with this UID still has the SYSTEM permission.
// Therefore, this UID must already have the SYSTEM permission.
@@ -551,23 +551,22 @@ public class PermissionMonitor {
return;
}
- final int appId = UserHandle.getAppId(uid);
- if (permission == mApps.get(appId)) {
+ if (permission == mApps.get(uid)) {
// The permissions of this UID have not changed. Nothing to do.
return;
} else if (permission != null) {
- mApps.put(appId, permission);
- apps.put(appId, permission);
+ mApps.put(uid, permission);
+ apps.put(uid, permission);
update(mUsers, apps, true);
} else {
- mApps.remove(appId);
- apps.put(appId, NETWORK); // doesn't matter which permission we pick here
+ mApps.remove(uid);
+ apps.put(uid, NETWORK); // doesn't matter which permission we pick here
update(mUsers, apps, false);
}
}
private static int getNetdPermissionMask(String[] requestedPermissions,
- int[] requestedPermissionsFlags) {
+ int[] requestedPermissionsFlags) {
int permissions = 0;
if (requestedPermissions == null || requestedPermissionsFlags == null) return permissions;
for (int i = 0; i < requestedPermissions.length; i++) {
@@ -583,11 +582,10 @@ public class PermissionMonitor {
return permissions;
}
- private PackageInfo getPackageInfo(String packageName) {
+ private PackageInfo getPackageInfo(String packageName, UserHandle user) {
try {
- PackageInfo app = mPackageManager.getPackageInfo(packageName, GET_PERMISSIONS
- | MATCH_ANY_USER);
- return app;
+ return mContext.createContextAsUser(user, 0).getPackageManager()
+ .getPackageInfo(packageName, GET_PERMISSIONS);
} catch (NameNotFoundException e) {
return null;
}
@@ -676,7 +674,7 @@ public class PermissionMonitor {
*/
private void removeBypassingUids(Set<Integer> uids, int vpnAppUid) {
uids.remove(vpnAppUid);
- uids.removeIf(uid -> mApps.getOrDefault(UserHandle.getAppId(uid), NETWORK) == SYSTEM);
+ uids.removeIf(uid -> mApps.getOrDefault(uid, NETWORK) == SYSTEM);
}
/**
@@ -818,13 +816,12 @@ public class PermissionMonitor {
for (Integer uid : uidsToUpdate) {
final Boolean permission = highestUidNetworkPermission(uid);
- final int appId = UserHandle.getAppId(uid);
if (null == permission) {
- removedUids.put(appId, NETWORK); // Doesn't matter which permission is set here.
- mApps.remove(appId);
+ removedUids.put(uid, NETWORK); // Doesn't matter which permission is set here.
+ mApps.remove(uid);
} else {
- updatedUids.put(appId, permission);
- mApps.put(appId, permission);
+ updatedUids.put(uid, permission);
+ mApps.put(uid, permission);
}
}
@@ -839,12 +836,14 @@ public class PermissionMonitor {
return;
}
- for (String app : pkgList) {
- final PackageInfo info = getPackageInfo(app);
- if (info == null || info.applicationInfo == null) continue;
+ for (UserHandle user : mUsers){
+ for (String app : pkgList) {
+ final PackageInfo info = getPackageInfo(app, user);
+ if (info == null || info.applicationInfo == null) continue;
- final int appId = info.applicationInfo.uid;
- onPackageAdded(app, appId); // Use onPackageAdded to add package one by one.
+ final int appId = info.applicationInfo.uid;
+ onPackageAdded(app, appId); // Use onPackageAdded to add package one by one.
+ }
}
}