Loading services/java/com/android/server/connectivity/Vpn.java +199 −45 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.UserInfo; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.drawable.Drawable; Loading @@ -57,12 +58,14 @@ import android.os.RemoteException; import android.os.SystemClock; import android.os.SystemService; import android.os.UserHandle; import android.os.RemoteException; import android.os.UserManager; import android.security.Credentials; import android.security.KeyStore; import android.util.Log; import android.util.SparseBooleanArray; import android.widget.Toast; import com.android.internal.annotations.GuardedBy; import com.android.internal.R; import com.android.internal.net.LegacyVpnInfo; import com.android.internal.net.VpnConfig; Loading Loading @@ -103,6 +106,13 @@ public class Vpn extends BaseNetworkStateTracker { private volatile boolean mEnableNotif = true; private volatile boolean mEnableTeardown = true; private final IConnectivityManager mConnService; private VpnConfig mConfig; /* list of users using this VPN. */ @GuardedBy("this") private SparseBooleanArray mVpnUsers = null; private BroadcastReceiver mUserIntentReceiver = null; private final int mUserId; public Vpn(Context context, VpnCallback callback, INetworkManagementService netService, Loading @@ -119,6 +129,30 @@ public class Vpn extends BaseNetworkStateTracker { } catch (RemoteException e) { Log.wtf(TAG, "Problem registering observer", e); } if (userId == UserHandle.USER_OWNER) { // Owner's VPN also needs to handle restricted users mUserIntentReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); if (userId == UserHandle.USER_NULL) return; if (Intent.ACTION_USER_ADDED.equals(action)) { onUserAdded(userId); } else if (Intent.ACTION_USER_REMOVED.equals(action)) { onUserRemoved(userId); } } }; IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_USER_ADDED); intentFilter.addAction(Intent.ACTION_USER_REMOVED); mContext.registerReceiverAsUser( mUserIntentReceiver, UserHandle.ALL, intentFilter, null, null); } } /** Loading Loading @@ -207,15 +241,20 @@ public class Vpn extends BaseNetworkStateTracker { final long token = Binder.clearCallingIdentity(); try { mCallback.restore(); mCallback.clearUserForwarding(mInterface, mUserId); final int size = mVpnUsers.size(); for (int i = 0; i < size; i++) { int user = mVpnUsers.keyAt(i); mCallback.clearUserForwarding(mInterface, user); hideNotification(user); } mCallback.clearMarkedForwarding(mInterface); hideNotification(); } finally { Binder.restoreCallingIdentity(token); } jniReset(mInterface); mInterface = null; mVpnUsers = null; } // Revoke the connection or stop LegacyVpnRunner. Loading @@ -235,6 +274,7 @@ public class Vpn extends BaseNetworkStateTracker { Log.i(TAG, "Switched from " + mPackage + " to " + newPackage); mPackage = newPackage; mConfig = null; updateState(DetailedState.IDLE, "prepare"); return true; } Loading Loading @@ -275,6 +315,7 @@ public class Vpn extends BaseNetworkStateTracker { */ public synchronized ParcelFileDescriptor establish(VpnConfig config) { // Check if the caller is already prepared. UserManager mgr = UserManager.get(mContext); PackageManager pm = mContext.getPackageManager(); ApplicationInfo app = null; try { Loading @@ -285,12 +326,17 @@ public class Vpn extends BaseNetworkStateTracker { } catch (Exception e) { return null; } // Check if the service is properly declared. Intent intent = new Intent(VpnConfig.SERVICE_INTERFACE); intent.setClassName(mPackage, config.user); long token = Binder.clearCallingIdentity(); try { // Restricted users are not allowed to create VPNs, they are tied to Owner UserInfo user = mgr.getUserInfo(mUserId); if (user.isRestricted()) { throw new SecurityException("Restricted users cannot establish VPNs"); } ResolveInfo info = AppGlobals.getPackageManager().resolveService(intent, null, 0, mUserId); if (info == null) { Loading @@ -305,24 +351,6 @@ public class Vpn extends BaseNetworkStateTracker { Binder.restoreCallingIdentity(token); } // Load the label. String label = app.loadLabel(pm).toString(); // Load the icon and convert it into a bitmap. Drawable icon = app.loadIcon(pm); Bitmap bitmap = null; if (icon.getIntrinsicWidth() > 0 && icon.getIntrinsicHeight() > 0) { int width = mContext.getResources().getDimensionPixelSize( android.R.dimen.notification_large_icon_width); int height = mContext.getResources().getDimensionPixelSize( android.R.dimen.notification_large_icon_height); icon.setBounds(0, 0, width, height); bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); Canvas c = new Canvas(bitmap); icon.draw(c); c.setBitmap(null); } // Configure the interface. Abort if any of these steps fails. ParcelFileDescriptor tun = ParcelFileDescriptor.adoptFd(jniCreate(config.mtu)); try { Loading Loading @@ -354,14 +382,16 @@ public class Vpn extends BaseNetworkStateTracker { // Fill more values. config.user = mPackage; config.interfaze = mInterface; config.startTime = SystemClock.elapsedRealtime(); mConfig = config; // Set up forwarding and DNS rules. mVpnUsers = new SparseBooleanArray(); token = Binder.clearCallingIdentity(); try { mCallback.setMarkedForwarding(mInterface); mCallback.setRoutes(interfaze, config.routes); mCallback.override(mInterface, config.dnsServers, config.searchDomains); mCallback.addUserForwarding(mInterface, mUserId); showNotification(config, label, bitmap); addVpnUserLocked(mUserId); } finally { Binder.restoreCallingIdentity(token); Loading @@ -381,11 +411,114 @@ public class Vpn extends BaseNetworkStateTracker { Log.i(TAG, "Established by " + config.user + " on " + mInterface); // If we are owner assign all Restricted Users to this VPN if (mUserId == UserHandle.USER_OWNER) { token = Binder.clearCallingIdentity(); try { for (UserInfo user : mgr.getUsers()) { if (user.isRestricted()) { try { addVpnUserLocked(user.id); } catch (Exception e) { Log.wtf(TAG, "Failed to add user " + user.id + " to owner's VPN"); } } } } finally { Binder.restoreCallingIdentity(token); } } // TODO: ensure that contract class eventually marks as connected updateState(DetailedState.AUTHENTICATING, "establish"); return tun; } private boolean isRunningLocked() { return mVpnUsers != null; } private void addVpnUserLocked(int user) { enforceControlPermission(); if (!isRunningLocked()) { throw new IllegalStateException("VPN is not active"); } // add the user mCallback.addUserForwarding(mInterface, user); mVpnUsers.put(user, true); // show the notification if (!mPackage.equals(VpnConfig.LEGACY_VPN)) { // Load everything for the user's notification PackageManager pm = mContext.getPackageManager(); ApplicationInfo app = null; try { app = AppGlobals.getPackageManager().getApplicationInfo(mPackage, 0, mUserId); } catch (RemoteException e) { throw new IllegalStateException("Invalid application"); } String label = app.loadLabel(pm).toString(); // Load the icon and convert it into a bitmap. Drawable icon = app.loadIcon(pm); Bitmap bitmap = null; if (icon.getIntrinsicWidth() > 0 && icon.getIntrinsicHeight() > 0) { int width = mContext.getResources().getDimensionPixelSize( android.R.dimen.notification_large_icon_width); int height = mContext.getResources().getDimensionPixelSize( android.R.dimen.notification_large_icon_height); icon.setBounds(0, 0, width, height); bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); Canvas c = new Canvas(bitmap); icon.draw(c); c.setBitmap(null); } showNotification(label, bitmap, user); } else { showNotification(null, null, user); } } private void removeVpnUserLocked(int user) { enforceControlPermission(); if (!isRunningLocked()) { throw new IllegalStateException("VPN is not active"); } mCallback.clearUserForwarding(mInterface, user); mVpnUsers.delete(user); hideNotification(user); } private void onUserAdded(int userId) { // If the user is restricted tie them to the owner's VPN synchronized(Vpn.this) { UserManager mgr = UserManager.get(mContext); UserInfo user = mgr.getUserInfo(userId); if (user.isRestricted()) { try { addVpnUserLocked(userId); } catch (Exception e) { Log.wtf(TAG, "Failed to add restricted user to owner", e); } } } } private void onUserRemoved(int userId) { // clean up if restricted synchronized(Vpn.this) { UserManager mgr = UserManager.get(mContext); UserInfo user = mgr.getUserInfo(userId); if (user.isRestricted()) { try { removeVpnUserLocked(userId); } catch (Exception e) { Log.wtf(TAG, "Failed to remove restricted user to owner", e); } } } } @Deprecated public synchronized void interfaceStatusChanged(String iface, boolean up) { try { Loading @@ -411,11 +544,16 @@ public class Vpn extends BaseNetworkStateTracker { if (interfaze.equals(mInterface) && jniCheck(interfaze) == 0) { final long token = Binder.clearCallingIdentity(); try { mCallback.clearUserForwarding(mInterface, mUserId); final int size = mVpnUsers.size(); for (int i = 0; i < size; i++) { int user = mVpnUsers.keyAt(i); mCallback.clearUserForwarding(mInterface, user); hideNotification(user); } mVpnUsers = null; mCallback.clearMarkedForwarding(mInterface); mCallback.restore(); hideNotification(); } finally { Binder.restoreCallingIdentity(token); } Loading Loading @@ -470,9 +608,9 @@ public class Vpn extends BaseNetworkStateTracker { } } private void showNotification(VpnConfig config, String label, Bitmap icon) { private void showNotification(String label, Bitmap icon, int user) { if (!mEnableNotif) return; mStatusIntent = VpnConfig.getIntentForStatusPanel(mContext, config); mStatusIntent = VpnConfig.getIntentForStatusPanel(mContext, mConfig); NotificationManager nm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); Loading @@ -480,9 +618,8 @@ public class Vpn extends BaseNetworkStateTracker { if (nm != null) { String title = (label == null) ? mContext.getString(R.string.vpn_title) : mContext.getString(R.string.vpn_title_long, label); String text = (config.session == null) ? mContext.getString(R.string.vpn_text) : mContext.getString(R.string.vpn_text_long, config.session); config.startTime = SystemClock.elapsedRealtime(); String text = (mConfig.session == null) ? mContext.getString(R.string.vpn_text) : mContext.getString(R.string.vpn_text_long, mConfig.session); Notification notification = new Notification.Builder(mContext) .setSmallIcon(R.drawable.vpn_connected) Loading @@ -493,11 +630,11 @@ public class Vpn extends BaseNetworkStateTracker { .setDefaults(0) .setOngoing(true) .build(); nm.notifyAsUser(null, R.drawable.vpn_connected, notification,new UserHandle(mUserId)); nm.notifyAsUser(null, R.drawable.vpn_connected, notification, new UserHandle(user)); } } private void hideNotification() { private void hideNotification(int user) { if (!mEnableNotif) return; mStatusIntent = null; Loading @@ -505,7 +642,7 @@ public class Vpn extends BaseNetworkStateTracker { mContext.getSystemService(Context.NOTIFICATION_SERVICE); if (nm != null) { nm.cancelAsUser(null, R.drawable.vpn_connected, new UserHandle(mUserId)); nm.cancelAsUser(null, R.drawable.vpn_connected, new UserHandle(user)); } } Loading Loading @@ -671,7 +808,7 @@ public class Vpn extends BaseNetworkStateTracker { if (mLegacyVpnRunner == null) return null; final LegacyVpnInfo info = new LegacyVpnInfo(); info.key = mLegacyVpnRunner.mConfig.user; info.key = mConfig.user; info.state = LegacyVpnInfo.stateFromNetworkInfo(mNetworkInfo); if (mNetworkInfo.isConnected()) { info.intent = mStatusIntent; Loading @@ -681,7 +818,7 @@ public class Vpn extends BaseNetworkStateTracker { public VpnConfig getLegacyVpnConfig() { if (mLegacyVpnRunner != null) { return mLegacyVpnRunner.mConfig; return mConfig; } else { return null; } Loading @@ -697,7 +834,6 @@ public class Vpn extends BaseNetworkStateTracker { private class LegacyVpnRunner extends Thread { private static final String TAG = "LegacyVpnRunner"; private final VpnConfig mConfig; private final String[] mDaemons; private final String[][] mArguments; private final LocalSocket[] mSockets; Loading Loading @@ -962,16 +1098,34 @@ public class Vpn extends BaseNetworkStateTracker { // Now INetworkManagementEventObserver is watching our back. mInterface = mConfig.interfaze; mVpnUsers = new SparseBooleanArray(); token = Binder.clearCallingIdentity(); try { mCallback.override(mInterface, mConfig.dnsServers, mConfig.searchDomains); mCallback.addUserForwarding(mInterface, mUserId); showNotification(mConfig, null, null); addVpnUserLocked(mUserId); } finally { Binder.restoreCallingIdentity(token); } // Assign all restircted users to this VPN // (Legacy VPNs are Owner only) UserManager mgr = UserManager.get(mContext); token = Binder.clearCallingIdentity(); try { for (UserInfo user : mgr.getUsers()) { if (user.isRestricted()) { try { addVpnUserLocked(user.id); } catch (Exception e) { Log.wtf(TAG, "Failed to add user " + user.id + " to owner's VPN"); } } } } finally { Binder.restoreCallingIdentity(token); } Log.i(TAG, "Connected!"); updateState(DetailedState.CONNECTED, "execute"); } Loading Loading
services/java/com/android/server/connectivity/Vpn.java +199 −45 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.UserInfo; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.drawable.Drawable; Loading @@ -57,12 +58,14 @@ import android.os.RemoteException; import android.os.SystemClock; import android.os.SystemService; import android.os.UserHandle; import android.os.RemoteException; import android.os.UserManager; import android.security.Credentials; import android.security.KeyStore; import android.util.Log; import android.util.SparseBooleanArray; import android.widget.Toast; import com.android.internal.annotations.GuardedBy; import com.android.internal.R; import com.android.internal.net.LegacyVpnInfo; import com.android.internal.net.VpnConfig; Loading Loading @@ -103,6 +106,13 @@ public class Vpn extends BaseNetworkStateTracker { private volatile boolean mEnableNotif = true; private volatile boolean mEnableTeardown = true; private final IConnectivityManager mConnService; private VpnConfig mConfig; /* list of users using this VPN. */ @GuardedBy("this") private SparseBooleanArray mVpnUsers = null; private BroadcastReceiver mUserIntentReceiver = null; private final int mUserId; public Vpn(Context context, VpnCallback callback, INetworkManagementService netService, Loading @@ -119,6 +129,30 @@ public class Vpn extends BaseNetworkStateTracker { } catch (RemoteException e) { Log.wtf(TAG, "Problem registering observer", e); } if (userId == UserHandle.USER_OWNER) { // Owner's VPN also needs to handle restricted users mUserIntentReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); if (userId == UserHandle.USER_NULL) return; if (Intent.ACTION_USER_ADDED.equals(action)) { onUserAdded(userId); } else if (Intent.ACTION_USER_REMOVED.equals(action)) { onUserRemoved(userId); } } }; IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_USER_ADDED); intentFilter.addAction(Intent.ACTION_USER_REMOVED); mContext.registerReceiverAsUser( mUserIntentReceiver, UserHandle.ALL, intentFilter, null, null); } } /** Loading Loading @@ -207,15 +241,20 @@ public class Vpn extends BaseNetworkStateTracker { final long token = Binder.clearCallingIdentity(); try { mCallback.restore(); mCallback.clearUserForwarding(mInterface, mUserId); final int size = mVpnUsers.size(); for (int i = 0; i < size; i++) { int user = mVpnUsers.keyAt(i); mCallback.clearUserForwarding(mInterface, user); hideNotification(user); } mCallback.clearMarkedForwarding(mInterface); hideNotification(); } finally { Binder.restoreCallingIdentity(token); } jniReset(mInterface); mInterface = null; mVpnUsers = null; } // Revoke the connection or stop LegacyVpnRunner. Loading @@ -235,6 +274,7 @@ public class Vpn extends BaseNetworkStateTracker { Log.i(TAG, "Switched from " + mPackage + " to " + newPackage); mPackage = newPackage; mConfig = null; updateState(DetailedState.IDLE, "prepare"); return true; } Loading Loading @@ -275,6 +315,7 @@ public class Vpn extends BaseNetworkStateTracker { */ public synchronized ParcelFileDescriptor establish(VpnConfig config) { // Check if the caller is already prepared. UserManager mgr = UserManager.get(mContext); PackageManager pm = mContext.getPackageManager(); ApplicationInfo app = null; try { Loading @@ -285,12 +326,17 @@ public class Vpn extends BaseNetworkStateTracker { } catch (Exception e) { return null; } // Check if the service is properly declared. Intent intent = new Intent(VpnConfig.SERVICE_INTERFACE); intent.setClassName(mPackage, config.user); long token = Binder.clearCallingIdentity(); try { // Restricted users are not allowed to create VPNs, they are tied to Owner UserInfo user = mgr.getUserInfo(mUserId); if (user.isRestricted()) { throw new SecurityException("Restricted users cannot establish VPNs"); } ResolveInfo info = AppGlobals.getPackageManager().resolveService(intent, null, 0, mUserId); if (info == null) { Loading @@ -305,24 +351,6 @@ public class Vpn extends BaseNetworkStateTracker { Binder.restoreCallingIdentity(token); } // Load the label. String label = app.loadLabel(pm).toString(); // Load the icon and convert it into a bitmap. Drawable icon = app.loadIcon(pm); Bitmap bitmap = null; if (icon.getIntrinsicWidth() > 0 && icon.getIntrinsicHeight() > 0) { int width = mContext.getResources().getDimensionPixelSize( android.R.dimen.notification_large_icon_width); int height = mContext.getResources().getDimensionPixelSize( android.R.dimen.notification_large_icon_height); icon.setBounds(0, 0, width, height); bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); Canvas c = new Canvas(bitmap); icon.draw(c); c.setBitmap(null); } // Configure the interface. Abort if any of these steps fails. ParcelFileDescriptor tun = ParcelFileDescriptor.adoptFd(jniCreate(config.mtu)); try { Loading Loading @@ -354,14 +382,16 @@ public class Vpn extends BaseNetworkStateTracker { // Fill more values. config.user = mPackage; config.interfaze = mInterface; config.startTime = SystemClock.elapsedRealtime(); mConfig = config; // Set up forwarding and DNS rules. mVpnUsers = new SparseBooleanArray(); token = Binder.clearCallingIdentity(); try { mCallback.setMarkedForwarding(mInterface); mCallback.setRoutes(interfaze, config.routes); mCallback.override(mInterface, config.dnsServers, config.searchDomains); mCallback.addUserForwarding(mInterface, mUserId); showNotification(config, label, bitmap); addVpnUserLocked(mUserId); } finally { Binder.restoreCallingIdentity(token); Loading @@ -381,11 +411,114 @@ public class Vpn extends BaseNetworkStateTracker { Log.i(TAG, "Established by " + config.user + " on " + mInterface); // If we are owner assign all Restricted Users to this VPN if (mUserId == UserHandle.USER_OWNER) { token = Binder.clearCallingIdentity(); try { for (UserInfo user : mgr.getUsers()) { if (user.isRestricted()) { try { addVpnUserLocked(user.id); } catch (Exception e) { Log.wtf(TAG, "Failed to add user " + user.id + " to owner's VPN"); } } } } finally { Binder.restoreCallingIdentity(token); } } // TODO: ensure that contract class eventually marks as connected updateState(DetailedState.AUTHENTICATING, "establish"); return tun; } private boolean isRunningLocked() { return mVpnUsers != null; } private void addVpnUserLocked(int user) { enforceControlPermission(); if (!isRunningLocked()) { throw new IllegalStateException("VPN is not active"); } // add the user mCallback.addUserForwarding(mInterface, user); mVpnUsers.put(user, true); // show the notification if (!mPackage.equals(VpnConfig.LEGACY_VPN)) { // Load everything for the user's notification PackageManager pm = mContext.getPackageManager(); ApplicationInfo app = null; try { app = AppGlobals.getPackageManager().getApplicationInfo(mPackage, 0, mUserId); } catch (RemoteException e) { throw new IllegalStateException("Invalid application"); } String label = app.loadLabel(pm).toString(); // Load the icon and convert it into a bitmap. Drawable icon = app.loadIcon(pm); Bitmap bitmap = null; if (icon.getIntrinsicWidth() > 0 && icon.getIntrinsicHeight() > 0) { int width = mContext.getResources().getDimensionPixelSize( android.R.dimen.notification_large_icon_width); int height = mContext.getResources().getDimensionPixelSize( android.R.dimen.notification_large_icon_height); icon.setBounds(0, 0, width, height); bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); Canvas c = new Canvas(bitmap); icon.draw(c); c.setBitmap(null); } showNotification(label, bitmap, user); } else { showNotification(null, null, user); } } private void removeVpnUserLocked(int user) { enforceControlPermission(); if (!isRunningLocked()) { throw new IllegalStateException("VPN is not active"); } mCallback.clearUserForwarding(mInterface, user); mVpnUsers.delete(user); hideNotification(user); } private void onUserAdded(int userId) { // If the user is restricted tie them to the owner's VPN synchronized(Vpn.this) { UserManager mgr = UserManager.get(mContext); UserInfo user = mgr.getUserInfo(userId); if (user.isRestricted()) { try { addVpnUserLocked(userId); } catch (Exception e) { Log.wtf(TAG, "Failed to add restricted user to owner", e); } } } } private void onUserRemoved(int userId) { // clean up if restricted synchronized(Vpn.this) { UserManager mgr = UserManager.get(mContext); UserInfo user = mgr.getUserInfo(userId); if (user.isRestricted()) { try { removeVpnUserLocked(userId); } catch (Exception e) { Log.wtf(TAG, "Failed to remove restricted user to owner", e); } } } } @Deprecated public synchronized void interfaceStatusChanged(String iface, boolean up) { try { Loading @@ -411,11 +544,16 @@ public class Vpn extends BaseNetworkStateTracker { if (interfaze.equals(mInterface) && jniCheck(interfaze) == 0) { final long token = Binder.clearCallingIdentity(); try { mCallback.clearUserForwarding(mInterface, mUserId); final int size = mVpnUsers.size(); for (int i = 0; i < size; i++) { int user = mVpnUsers.keyAt(i); mCallback.clearUserForwarding(mInterface, user); hideNotification(user); } mVpnUsers = null; mCallback.clearMarkedForwarding(mInterface); mCallback.restore(); hideNotification(); } finally { Binder.restoreCallingIdentity(token); } Loading Loading @@ -470,9 +608,9 @@ public class Vpn extends BaseNetworkStateTracker { } } private void showNotification(VpnConfig config, String label, Bitmap icon) { private void showNotification(String label, Bitmap icon, int user) { if (!mEnableNotif) return; mStatusIntent = VpnConfig.getIntentForStatusPanel(mContext, config); mStatusIntent = VpnConfig.getIntentForStatusPanel(mContext, mConfig); NotificationManager nm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); Loading @@ -480,9 +618,8 @@ public class Vpn extends BaseNetworkStateTracker { if (nm != null) { String title = (label == null) ? mContext.getString(R.string.vpn_title) : mContext.getString(R.string.vpn_title_long, label); String text = (config.session == null) ? mContext.getString(R.string.vpn_text) : mContext.getString(R.string.vpn_text_long, config.session); config.startTime = SystemClock.elapsedRealtime(); String text = (mConfig.session == null) ? mContext.getString(R.string.vpn_text) : mContext.getString(R.string.vpn_text_long, mConfig.session); Notification notification = new Notification.Builder(mContext) .setSmallIcon(R.drawable.vpn_connected) Loading @@ -493,11 +630,11 @@ public class Vpn extends BaseNetworkStateTracker { .setDefaults(0) .setOngoing(true) .build(); nm.notifyAsUser(null, R.drawable.vpn_connected, notification,new UserHandle(mUserId)); nm.notifyAsUser(null, R.drawable.vpn_connected, notification, new UserHandle(user)); } } private void hideNotification() { private void hideNotification(int user) { if (!mEnableNotif) return; mStatusIntent = null; Loading @@ -505,7 +642,7 @@ public class Vpn extends BaseNetworkStateTracker { mContext.getSystemService(Context.NOTIFICATION_SERVICE); if (nm != null) { nm.cancelAsUser(null, R.drawable.vpn_connected, new UserHandle(mUserId)); nm.cancelAsUser(null, R.drawable.vpn_connected, new UserHandle(user)); } } Loading Loading @@ -671,7 +808,7 @@ public class Vpn extends BaseNetworkStateTracker { if (mLegacyVpnRunner == null) return null; final LegacyVpnInfo info = new LegacyVpnInfo(); info.key = mLegacyVpnRunner.mConfig.user; info.key = mConfig.user; info.state = LegacyVpnInfo.stateFromNetworkInfo(mNetworkInfo); if (mNetworkInfo.isConnected()) { info.intent = mStatusIntent; Loading @@ -681,7 +818,7 @@ public class Vpn extends BaseNetworkStateTracker { public VpnConfig getLegacyVpnConfig() { if (mLegacyVpnRunner != null) { return mLegacyVpnRunner.mConfig; return mConfig; } else { return null; } Loading @@ -697,7 +834,6 @@ public class Vpn extends BaseNetworkStateTracker { private class LegacyVpnRunner extends Thread { private static final String TAG = "LegacyVpnRunner"; private final VpnConfig mConfig; private final String[] mDaemons; private final String[][] mArguments; private final LocalSocket[] mSockets; Loading Loading @@ -962,16 +1098,34 @@ public class Vpn extends BaseNetworkStateTracker { // Now INetworkManagementEventObserver is watching our back. mInterface = mConfig.interfaze; mVpnUsers = new SparseBooleanArray(); token = Binder.clearCallingIdentity(); try { mCallback.override(mInterface, mConfig.dnsServers, mConfig.searchDomains); mCallback.addUserForwarding(mInterface, mUserId); showNotification(mConfig, null, null); addVpnUserLocked(mUserId); } finally { Binder.restoreCallingIdentity(token); } // Assign all restircted users to this VPN // (Legacy VPNs are Owner only) UserManager mgr = UserManager.get(mContext); token = Binder.clearCallingIdentity(); try { for (UserInfo user : mgr.getUsers()) { if (user.isRestricted()) { try { addVpnUserLocked(user.id); } catch (Exception e) { Log.wtf(TAG, "Failed to add user " + user.id + " to owner's VPN"); } } } } finally { Binder.restoreCallingIdentity(token); } Log.i(TAG, "Connected!"); updateState(DetailedState.CONNECTED, "execute"); } Loading