Loading core/java/com/android/internal/net/VpnConfig.java +28 −0 Original line number Diff line number Diff line Loading @@ -16,8 +16,12 @@ package com.android.internal.net; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.os.Parcel; import android.os.Parcelable; import android.os.SystemClock; /** * A simple container used to carry information in VpnBuilder, VpnDialogs, Loading @@ -27,6 +31,30 @@ import android.os.Parcelable; */ public class VpnConfig implements Parcelable { public static final String ACTION_VPN_REVOKED = "android.net.vpn.action.REVOKED"; public static void enforceCallingPackage(String packageName) { if (!"com.android.vpndialogs".equals(packageName)) { throw new SecurityException("Unauthorized Caller"); } } public static Intent getIntentForConfirmation() { Intent intent = new Intent(); intent.setClassName("com.android.vpndialogs", "com.android.vpndialogs.ConfirmDialog"); return intent; } public static PendingIntent getIntentForNotification(Context context, VpnConfig config) { config.startTime = SystemClock.elapsedRealtime(); Intent intent = new Intent(); intent.setClassName("com.android.vpndialogs", "com.android.vpndialogs.ManageDialog"); intent.putExtra("config", config); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); } public String packageName; public String sessionName; public String interfaceName; Loading services/java/com/android/server/connectivity/Vpn.java +28 −27 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.server.connectivity; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; Loading Loading @@ -64,29 +63,40 @@ public class Vpn extends INetworkManagementEventObserver.Stub { * @return The name of the current prepared package. */ public synchronized String prepare(String packageName) { // TODO: Check if the caller is VpnDialogs. // Return the current prepared package if the new one is null. if (packageName == null) { return mPackageName; } // Check the permission of the given application. // Check the permission of the caller. PackageManager pm = mContext.getPackageManager(); if (pm.checkPermission(VPN, packageName) != PackageManager.PERMISSION_GRANTED) { VpnConfig.enforceCallingPackage(pm.getNameForUid(Binder.getCallingUid())); // Check the permission of the given package. if (packageName.isEmpty()) { packageName = null; } else if (pm.checkPermission(VPN, packageName) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException(packageName + " does not have " + VPN); } // Reset the interface and hide the notification. if (mInterfaceName != null) { nativeReset(mInterfaceName); mInterfaceName = null; mCallback.restore(); hideNotification(); // TODO: Send out a broadcast. mInterfaceName = null; } // Notify the package being revoked. if (mPackageName != null) { Intent intent = new Intent(VpnConfig.ACTION_VPN_REVOKED); intent.setPackage(mPackageName); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); mContext.sendBroadcast(intent); } Log.i(TAG, "Switched from " + mPackageName + " to " + packageName); mPackageName = packageName; Log.i(TAG, "Prepared for " + packageName); return mPackageName; } Loading Loading @@ -118,10 +128,10 @@ public class Vpn extends INetworkManagementEventObserver.Stub { try { app = pm.getApplicationInfo(mPackageName, 0); } catch (Exception e) { throw new SecurityException("Not prepared"); return null; } if (Binder.getCallingUid() != app.uid) { throw new SecurityException("Not prepared"); return null; } // Create and configure the interface. Loading @@ -148,7 +158,9 @@ public class Vpn extends INetworkManagementEventObserver.Stub { String dnsServers = (config.dnsServers == null) ? "" : config.dnsServers.trim(); mCallback.override(dnsServers.isEmpty() ? null : dnsServers.split(" ")); showNotification(pm, app, config.sessionName); config.packageName = mPackageName; config.interfaceName = mInterfaceName; showNotification(pm, app, config); return descriptor; } Loading @@ -169,7 +181,7 @@ public class Vpn extends INetworkManagementEventObserver.Stub { } } private void showNotification(PackageManager pm, ApplicationInfo app, String sessionName) { private void showNotification(PackageManager pm, ApplicationInfo app, VpnConfig config) { NotificationManager nm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); Loading @@ -190,20 +202,9 @@ public class Vpn extends INetworkManagementEventObserver.Stub { // Load the label. String label = app.loadLabel(pm).toString(); // Build the intent. // TODO: move these into VpnBuilder. Intent intent = new Intent(); intent.setClassName("com.android.vpndialogs", "com.android.vpndialogs.ManageDialog"); intent.putExtra("packageName", mPackageName); intent.putExtra("interfaceName", mInterfaceName); intent.putExtra("session", sessionName); intent.putExtra("startTime", android.os.SystemClock.elapsedRealtime()); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); // Build the notification. String text = (sessionName == null) ? mContext.getString(R.string.vpn_text) : mContext.getString(R.string.vpn_text_long, sessionName); String text = (config.sessionName == null) ? mContext.getString(R.string.vpn_text) : mContext.getString(R.string.vpn_text_long, config.sessionName); long identity = Binder.clearCallingIdentity(); Notification notification = new Notification.Builder(mContext) .setSmallIcon(R.drawable.vpn_connected) Loading @@ -211,7 +212,7 @@ public class Vpn extends INetworkManagementEventObserver.Stub { .setTicker(mContext.getString(R.string.vpn_ticker, label)) .setContentTitle(mContext.getString(R.string.vpn_title, label)) .setContentText(text) .setContentIntent(PendingIntent.getActivity(mContext, 0, intent, 0)) .setContentIntent(VpnConfig.getIntentForNotification(mContext, config)) .setDefaults(Notification.DEFAULT_ALL) .setOngoing(true) .getNotification(); Loading Loading
core/java/com/android/internal/net/VpnConfig.java +28 −0 Original line number Diff line number Diff line Loading @@ -16,8 +16,12 @@ package com.android.internal.net; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.os.Parcel; import android.os.Parcelable; import android.os.SystemClock; /** * A simple container used to carry information in VpnBuilder, VpnDialogs, Loading @@ -27,6 +31,30 @@ import android.os.Parcelable; */ public class VpnConfig implements Parcelable { public static final String ACTION_VPN_REVOKED = "android.net.vpn.action.REVOKED"; public static void enforceCallingPackage(String packageName) { if (!"com.android.vpndialogs".equals(packageName)) { throw new SecurityException("Unauthorized Caller"); } } public static Intent getIntentForConfirmation() { Intent intent = new Intent(); intent.setClassName("com.android.vpndialogs", "com.android.vpndialogs.ConfirmDialog"); return intent; } public static PendingIntent getIntentForNotification(Context context, VpnConfig config) { config.startTime = SystemClock.elapsedRealtime(); Intent intent = new Intent(); intent.setClassName("com.android.vpndialogs", "com.android.vpndialogs.ManageDialog"); intent.putExtra("config", config); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); } public String packageName; public String sessionName; public String interfaceName; Loading
services/java/com/android/server/connectivity/Vpn.java +28 −27 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.server.connectivity; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; Loading Loading @@ -64,29 +63,40 @@ public class Vpn extends INetworkManagementEventObserver.Stub { * @return The name of the current prepared package. */ public synchronized String prepare(String packageName) { // TODO: Check if the caller is VpnDialogs. // Return the current prepared package if the new one is null. if (packageName == null) { return mPackageName; } // Check the permission of the given application. // Check the permission of the caller. PackageManager pm = mContext.getPackageManager(); if (pm.checkPermission(VPN, packageName) != PackageManager.PERMISSION_GRANTED) { VpnConfig.enforceCallingPackage(pm.getNameForUid(Binder.getCallingUid())); // Check the permission of the given package. if (packageName.isEmpty()) { packageName = null; } else if (pm.checkPermission(VPN, packageName) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException(packageName + " does not have " + VPN); } // Reset the interface and hide the notification. if (mInterfaceName != null) { nativeReset(mInterfaceName); mInterfaceName = null; mCallback.restore(); hideNotification(); // TODO: Send out a broadcast. mInterfaceName = null; } // Notify the package being revoked. if (mPackageName != null) { Intent intent = new Intent(VpnConfig.ACTION_VPN_REVOKED); intent.setPackage(mPackageName); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); mContext.sendBroadcast(intent); } Log.i(TAG, "Switched from " + mPackageName + " to " + packageName); mPackageName = packageName; Log.i(TAG, "Prepared for " + packageName); return mPackageName; } Loading Loading @@ -118,10 +128,10 @@ public class Vpn extends INetworkManagementEventObserver.Stub { try { app = pm.getApplicationInfo(mPackageName, 0); } catch (Exception e) { throw new SecurityException("Not prepared"); return null; } if (Binder.getCallingUid() != app.uid) { throw new SecurityException("Not prepared"); return null; } // Create and configure the interface. Loading @@ -148,7 +158,9 @@ public class Vpn extends INetworkManagementEventObserver.Stub { String dnsServers = (config.dnsServers == null) ? "" : config.dnsServers.trim(); mCallback.override(dnsServers.isEmpty() ? null : dnsServers.split(" ")); showNotification(pm, app, config.sessionName); config.packageName = mPackageName; config.interfaceName = mInterfaceName; showNotification(pm, app, config); return descriptor; } Loading @@ -169,7 +181,7 @@ public class Vpn extends INetworkManagementEventObserver.Stub { } } private void showNotification(PackageManager pm, ApplicationInfo app, String sessionName) { private void showNotification(PackageManager pm, ApplicationInfo app, VpnConfig config) { NotificationManager nm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); Loading @@ -190,20 +202,9 @@ public class Vpn extends INetworkManagementEventObserver.Stub { // Load the label. String label = app.loadLabel(pm).toString(); // Build the intent. // TODO: move these into VpnBuilder. Intent intent = new Intent(); intent.setClassName("com.android.vpndialogs", "com.android.vpndialogs.ManageDialog"); intent.putExtra("packageName", mPackageName); intent.putExtra("interfaceName", mInterfaceName); intent.putExtra("session", sessionName); intent.putExtra("startTime", android.os.SystemClock.elapsedRealtime()); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); // Build the notification. String text = (sessionName == null) ? mContext.getString(R.string.vpn_text) : mContext.getString(R.string.vpn_text_long, sessionName); String text = (config.sessionName == null) ? mContext.getString(R.string.vpn_text) : mContext.getString(R.string.vpn_text_long, config.sessionName); long identity = Binder.clearCallingIdentity(); Notification notification = new Notification.Builder(mContext) .setSmallIcon(R.drawable.vpn_connected) Loading @@ -211,7 +212,7 @@ public class Vpn extends INetworkManagementEventObserver.Stub { .setTicker(mContext.getString(R.string.vpn_ticker, label)) .setContentTitle(mContext.getString(R.string.vpn_title, label)) .setContentText(text) .setContentIntent(PendingIntent.getActivity(mContext, 0, intent, 0)) .setContentIntent(VpnConfig.getIntentForNotification(mContext, config)) .setDefaults(Notification.DEFAULT_ALL) .setOngoing(true) .getNotification(); Loading