diff options
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. + } } } |
