diff options
-rw-r--r-- | services/core/java/com/android/server/ConnectivityService.java | 43 | ||||
-rw-r--r-- | services/core/java/com/android/server/connectivity/Vpn.java | 66 |
2 files changed, 41 insertions, 68 deletions
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 14503f9d7379..eda9fe15fe36 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -902,6 +902,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // Listen to package add and removal events for all users. intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED); + intentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED); intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); intentFilter.addDataScheme("package"); mContext.registerReceiverAsUser( @@ -4203,12 +4204,46 @@ public class ConnectivityService extends IConnectivityManager.Stub mPermissionMonitor.onPackageAdded(packageName, uid); } - private void onPackageRemoved(String packageName, int uid) { + private void onPackageReplaced(String packageName, int uid) { + if (TextUtils.isEmpty(packageName) || uid < 0) { + Slog.wtf(TAG, "Invalid package in onPackageReplaced: " + packageName + " | " + uid); + return; + } + final int userId = UserHandle.getUserId(uid); + synchronized (mVpns) { + final Vpn vpn = mVpns.get(userId); + if (vpn == null) { + return; + } + // Legacy always-on VPN won't be affected since the package name is not set. + if (TextUtils.equals(vpn.getAlwaysOnPackage(), packageName)) { + Slog.d(TAG, "Restarting always-on VPN package " + packageName + " for user " + + userId); + vpn.startAlwaysOnVpn(); + } + } + } + + private void onPackageRemoved(String packageName, int uid, boolean isReplacing) { if (TextUtils.isEmpty(packageName) || uid < 0) { Slog.wtf(TAG, "Invalid package in onPackageRemoved: " + packageName + " | " + uid); return; } mPermissionMonitor.onPackageRemoved(uid); + + final int userId = UserHandle.getUserId(uid); + synchronized (mVpns) { + final Vpn vpn = mVpns.get(userId); + if (vpn == null) { + return; + } + // Legacy always-on VPN won't be affected since the package name is not set. + if (TextUtils.equals(vpn.getAlwaysOnPackage(), packageName) && !isReplacing) { + Slog.d(TAG, "Removing always-on VPN package " + packageName + " for user " + + userId); + vpn.setAlwaysOnPackage(null, false); + } + } } private void onUserUnlocked(int userId) { @@ -4245,8 +4280,12 @@ public class ConnectivityService extends IConnectivityManager.Stub onUserUnlocked(userId); } else if (Intent.ACTION_PACKAGE_ADDED.equals(action)) { onPackageAdded(packageName, uid); + } else if (Intent.ACTION_PACKAGE_REPLACED.equals(action)) { + onPackageReplaced(packageName, uid); } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) { - onPackageRemoved(packageName, uid); + final boolean isReplacing = intent.getBooleanExtra( + Intent.EXTRA_REPLACING, false); + onPackageRemoved(packageName, uid, isReplacing); } } }; diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index b7ed2f9bd473..602aedbc2d00 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -206,45 +206,6 @@ public class Vpn { // Handle of the user initiating VPN. private final int mUserHandle; - // Listen to package removal and change events (update/uninstall) for this user - private final BroadcastReceiver mPackageIntentReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - final Uri data = intent.getData(); - final String packageName = data == null ? null : data.getSchemeSpecificPart(); - if (packageName == null) { - return; - } - - synchronized (Vpn.this) { - // Avoid race where always-on package has been unset - if (!packageName.equals(getAlwaysOnPackage())) { - return; - } - - final String action = intent.getAction(); - Log.i(TAG, "Received broadcast " + action + " for always-on VPN package " - + packageName + " in user " + mUserHandle); - - switch(action) { - case Intent.ACTION_PACKAGE_REPLACED: - // Start vpn after app upgrade - startAlwaysOnVpn(); - break; - case Intent.ACTION_PACKAGE_REMOVED: - final boolean isPackageRemoved = !intent.getBooleanExtra( - Intent.EXTRA_REPLACING, false); - if (isPackageRemoved) { - setAlwaysOnPackage(null, false); - } - break; - } - } - } - }; - - private boolean mIsPackageIntentReceiverRegistered = false; - public Vpn(Looper looper, Context context, INetworkManagementService netService, @UserIdInt int userHandle) { this(looper, context, netService, userHandle, new SystemServices(context)); @@ -500,7 +461,6 @@ public class Vpn { // Prepare this app. The notification will update as a side-effect of updateState(). prepareInternal(packageName); } - maybeRegisterPackageChangeReceiverLocked(packageName); setVpnForcedLocked(mLockdown); return true; } @@ -509,31 +469,6 @@ public class Vpn { return packageName == null || VpnConfig.LEGACY_VPN.equals(packageName); } - private void unregisterPackageChangeReceiverLocked() { - if (mIsPackageIntentReceiverRegistered) { - mContext.unregisterReceiver(mPackageIntentReceiver); - mIsPackageIntentReceiverRegistered = false; - } - } - - private void maybeRegisterPackageChangeReceiverLocked(String packageName) { - // Unregister IntentFilter listening for previous always-on package change - unregisterPackageChangeReceiverLocked(); - - if (!isNullOrLegacyVpn(packageName)) { - mIsPackageIntentReceiverRegistered = true; - - IntentFilter intentFilter = new IntentFilter(); - // Protected intent can only be sent by system. No permission required in register. - intentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED); - intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); - intentFilter.addDataScheme("package"); - intentFilter.addDataSchemeSpecificPart(packageName, PatternMatcher.PATTERN_LITERAL); - mContext.registerReceiverAsUser( - mPackageIntentReceiver, UserHandle.of(mUserHandle), intentFilter, null, null); - } - } - /** * @return the package name of the VPN controller responsible for always-on VPN, * or {@code null} if none is set or always-on VPN is controlled through @@ -1302,7 +1237,6 @@ public class Vpn { setLockdown(false); mAlwaysOn = false; - unregisterPackageChangeReceiverLocked(); // Quit any active connections agentDisconnect(); } |