diff options
author | Robert Greenwalt <rgreenwalt@google.com> | 2013-04-22 21:33:28 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2013-04-22 21:33:29 +0000 |
commit | d020294572f591007de1fe0aa9e4927dae72c0c9 (patch) | |
tree | 670c6b51722cac7f675ee89668ab9bab4f710a00 /services | |
parent | 3acb320fcb6ee03aec64220b09283a3c4efa4bb5 (diff) | |
parent | 1b0ca9dace3fb3b84f8a87e539c0179e6093b423 (diff) | |
download | frameworks_base-d020294572f591007de1fe0aa9e4927dae72c0c9.zip frameworks_base-d020294572f591007de1fe0aa9e4927dae72c0c9.tar.gz frameworks_base-d020294572f591007de1fe0aa9e4927dae72c0c9.tar.bz2 |
Merge "Listen for network disconnect." into jb-mr2-dev
Diffstat (limited to 'services')
-rw-r--r-- | services/java/com/android/server/ConnectivityService.java | 17 | ||||
-rw-r--r-- | services/java/com/android/server/connectivity/Vpn.java | 51 |
2 files changed, 65 insertions, 3 deletions
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index 01625dd..c2f4a2c 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -544,7 +544,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { mTethering.getTetherableBluetoothRegexs().length != 0) && mTethering.getUpstreamIfaceTypes().length != 0); - mVpn = new Vpn(mContext, mVpnCallback, mNetd); + mVpn = new Vpn(mContext, mVpnCallback, mNetd, this); mVpn.startMonitoring(mContext, mTrackerHandler); mClat = new Nat464Xlat(mContext, mNetd, this, mTrackerHandler); @@ -3448,4 +3448,19 @@ public class ConnectivityService extends IConnectivityManager.Stub { mNetTrackers[networkType].supplyMessenger(messenger); } } + + public int findConnectionTypeForIface(String iface) { + enforceConnectivityInternalPermission(); + + if (TextUtils.isEmpty(iface)) return ConnectivityManager.TYPE_NONE; + for (NetworkStateTracker tracker : mNetTrackers) { + if (tracker != null) { + LinkProperties lp = tracker.getLinkProperties(); + if (lp != null && iface.equals(lp.getInterfaceName())) { + return tracker.getNetworkInfo().getType(); + } + } + } + return ConnectivityManager.TYPE_NONE; + } } diff --git a/services/java/com/android/server/connectivity/Vpn.java b/services/java/com/android/server/connectivity/Vpn.java index 533db46..10c7e27 100644 --- a/services/java/com/android/server/connectivity/Vpn.java +++ b/services/java/com/android/server/connectivity/Vpn.java @@ -21,9 +21,11 @@ import static android.Manifest.permission.BIND_VPN_SERVICE; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; +import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.content.ServiceConnection; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; @@ -33,6 +35,7 @@ import android.graphics.Canvas; import android.graphics.drawable.Drawable; import android.net.BaseNetworkStateTracker; import android.net.ConnectivityManager; +import android.net.IConnectivityManager; import android.net.INetworkManagementEventObserver; import android.net.LinkProperties; import android.net.LocalSocket; @@ -71,6 +74,7 @@ import java.net.Inet4Address; import java.net.InetAddress; import java.nio.charset.Charsets; import java.util.Arrays; +import java.util.concurrent.atomic.AtomicInteger; import libcore.io.IoUtils; @@ -92,12 +96,15 @@ public class Vpn extends BaseNetworkStateTracker { private LegacyVpnRunner mLegacyVpnRunner; private PendingIntent mStatusIntent; private boolean mEnableNotif = true; + private final IConnectivityManager mConnService; - public Vpn(Context context, VpnCallback callback, INetworkManagementService netService) { + public Vpn(Context context, VpnCallback callback, INetworkManagementService netService, + IConnectivityManager connService) { // TODO: create dedicated TYPE_VPN network type super(ConnectivityManager.TYPE_DUMMY); mContext = context; mCallback = callback; + mConnService = connService; try { netService.registerObserver(mObserver); @@ -562,7 +569,6 @@ public class Vpn extends BaseNetworkStateTracker { if (!profile.searchDomains.isEmpty()) { config.searchDomains = Arrays.asList(profile.searchDomains.split(" +")); } - startLegacyVpn(config, racoon, mtpd); } @@ -630,9 +636,32 @@ public class Vpn extends BaseNetworkStateTracker { private final String[][] mArguments; private final LocalSocket[] mSockets; private final String mOuterInterface; + private final AtomicInteger mOuterConnection = + new AtomicInteger(ConnectivityManager.TYPE_NONE); private long mTimer = -1; + /** + * Watch for the outer connection (passing in the constructor) going away. + */ + private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) { + if (intent.getIntExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, + ConnectivityManager.TYPE_NONE) == mOuterConnection.get()) { + NetworkInfo info = (NetworkInfo)intent.getExtra( + ConnectivityManager.EXTRA_NETWORK_INFO); + if (info != null && !info.isConnectedOrConnecting()) { + try { + mObserver.interfaceStatusChanged(mOuterInterface, false); + } catch (RemoteException e) {} + } + } + } + } + }; + public LegacyVpnRunner(VpnConfig config, String[] racoon, String[] mtpd) { super(TAG); mConfig = config; @@ -644,7 +673,22 @@ public class Vpn extends BaseNetworkStateTracker { // This is the interface which VPN is running on, // mConfig.interfaze will change to point to OUR // internal interface soon. TODO - add inner/outer to mconfig + // TODO - we have a race - if the outer iface goes away/disconnects before we hit this + // we will leave the VPN up. We should check that it's still there/connected after + // registering mOuterInterface = mConfig.interfaze; + + try { + mOuterConnection.set( + mConnService.findConnectionTypeForIface(mOuterInterface)); + } catch (Exception e) { + mOuterConnection.set(ConnectivityManager.TYPE_NONE); + } + + IntentFilter filter = new IntentFilter(); + filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); + mContext.registerReceiver(mBroadcastReceiver, filter); + } public void check(String interfaze) { @@ -661,6 +705,9 @@ public class Vpn extends BaseNetworkStateTracker { IoUtils.closeQuietly(socket); } updateState(DetailedState.DISCONNECTED, "exit"); + try { + mContext.unregisterReceiver(mBroadcastReceiver); + } catch (IllegalArgumentException e) {} } @Override |