From 0c4828c25de258e0c30e6b9ac2cb154fbea005ac Mon Sep 17 00:00:00 2001 From: Robert Greenwalt Date: Tue, 26 Jan 2010 11:40:34 -0800 Subject: [PATCH] First pass at USB Tethering. bug:2281900 --- .../java/android/net/ConnectivityManager.java | 62 +++++++++++++++++++ .../android/net/IConnectivityManager.aidl | 8 +++ .../android/server/ConnectivityService.java | 38 ++++++++++++ 3 files changed, 108 insertions(+) diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 30799ec9f3..d435df5842 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -115,6 +115,24 @@ public class ConnectivityManager public static final String ACTION_BACKGROUND_DATA_SETTING_CHANGED = "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED"; + /** + * Broadcast Action: A tetherable connection has come or gone + * TODO - finish the doc + * @hide + */ + public static final String ACTION_TETHER_STATE_CHANGED = + "android.net.conn.TETHER_STATE_CHANGED"; + + /** + * @hide + */ + public static final String EXTRA_AVAILABLE_TETHER_COUNT = "availableCount"; + + /** + * @hide + */ + public static final String EXTRA_ACTIVE_TETHER_COUNT = "activeCount"; + /** * The Default Mobile data connection. When active, all data traffic * will use this connection by default. Should not coexist with other @@ -338,4 +356,48 @@ public class ConnectivityManager } mService = service; } + + /** + * {@hide} + */ + public String[] getTetherableIfaces() { + try { + return mService.getTetherableIfaces(); + } catch (RemoteException e) { + return new String[0]; + } + } + + /** + * {@hide} + */ + public String[] getTetheredIfaces() { + try { + return mService.getTetheredIfaces(); + } catch (RemoteException e) { + return new String[0]; + } + } + + /** + * {@hide} + */ + public boolean tether(String iface) { + try { + return mService.tether(iface); + } catch (RemoteException e) { + return false; + } + } + + /** + * {@hide} + */ + public boolean untether(String iface) { + try { + return mService.untether(iface); + } catch (RemoteException e) { + return false; + } + } } diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index 9f59ccede4..caa3f2bbc7 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -50,4 +50,12 @@ interface IConnectivityManager boolean getBackgroundDataSetting(); void setBackgroundDataSetting(boolean allowBackgroundData); + + boolean tether(String iface); + + boolean untether(String iface); + + String[] getTetherableIfaces(); + + String[] getTetheredIfaces(); } diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index aa4956f157..42590160d9 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -43,6 +43,8 @@ import android.util.Log; import com.android.internal.telephony.Phone; +import com.android.server.connectivity.Tethering; + import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; @@ -62,6 +64,9 @@ public class ConnectivityService extends IConnectivityManager.Stub { private static final String NETWORK_RESTORE_DELAY_PROP_NAME = "android.telephony.apn-restore"; + + private Tethering mTethering; + /** * Sometimes we want to refer to the individual network state * trackers separately, and sometimes we just want to treat them @@ -308,6 +313,8 @@ public class ConnectivityService extends IConnectivityManager.Stub { continue; } } + + mTethering = new Tethering(mContext); } @@ -784,6 +791,13 @@ public class ConnectivityService extends IConnectivityManager.Stub { "ConnectivityService"); } + // TODO Make this a special check when it goes public + private void enforceTetherChangePermission() { + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.CHANGE_NETWORK_STATE, + "ConnectivityService"); + } + /** * Handle a {@code DISCONNECTED} event. If this pertains to the non-active * network, we ignore it. If it is for the active network, we send out a @@ -1368,4 +1382,28 @@ public class ConnectivityService extends IConnectivityManager.Stub { } } } + + // javadoc from interface + public boolean tether(String iface) { + enforceTetherChangePermission(); + return mTethering.tether(iface); + } + + // javadoc from interface + public boolean untether(String iface) { + enforceTetherChangePermission(); + return mTethering.untether(iface); + } + + // TODO - move iface listing, queries, etc to new module + // javadoc from interface + public String[] getTetherableIfaces() { + enforceAccessPermission(); + return mTethering.getTetherableIfaces(); + } + + public String[] getTetheredIfaces() { + enforceAccessPermission(); + return mTethering.getTetheredIfaces(); + } }