Loading core/java/android/app/SystemServiceRegistry.java +30 −3 Original line number Diff line number Diff line Loading @@ -220,11 +220,12 @@ final class SystemServiceRegistry { SYSTEM_SERVICE_NAMES.put(android.text.ClipboardManager.class, Context.CLIPBOARD_SERVICE); registerService(Context.CONNECTIVITY_SERVICE, ConnectivityManager.class, new StaticServiceFetcher<ConnectivityManager>() { new StaticOuterContextServiceFetcher<ConnectivityManager>() { @Override public ConnectivityManager createService() { public ConnectivityManager createService(Context context) { IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b)); IConnectivityManager service = IConnectivityManager.Stub.asInterface(b); return new ConnectivityManager(context, service); }}); registerService(Context.COUNTRY_DETECTOR, CountryDetector.class, Loading Loading @@ -793,4 +794,30 @@ final class SystemServiceRegistry { public abstract T createService(); } /** * Like StaticServiceFetcher, creates only one instance of the service per process, but when * creating the service for the first time, passes it the outer context of the creating * component. * * TODO: Is this safe in the case where multiple applications share the same process? * TODO: Delete this once its only user (ConnectivityManager) is known to work well in the * case where multiple application components each have their own ConnectivityManager object. */ static abstract class StaticOuterContextServiceFetcher<T> implements ServiceFetcher<T> { private T mCachedInstance; @Override public final T getService(ContextImpl ctx) { synchronized (StaticOuterContextServiceFetcher.this) { if (mCachedInstance == null) { mCachedInstance = createService(ctx.getOuterContext()); } return mCachedInstance; } } public abstract T createService(Context applicationContext); } } core/java/android/net/ConnectivityManager.java +43 −1 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.annotation.SdkConstant.SdkConstantType; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.net.NetworkUtils; import android.os.Binder; import android.os.Build.VERSION_CODES; Loading @@ -33,6 +34,7 @@ import android.os.INetworkManagementService; import android.os.Looper; import android.os.Message; import android.os.Messenger; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.provider.Settings; Loading Loading @@ -490,6 +492,8 @@ public class ConnectivityManager { */ private static ConnectivityManager sInstance; private final Context mContext; private INetworkManagementService mNMService; /** Loading Loading @@ -892,8 +896,11 @@ public class ConnectivityManager { * * @deprecated Deprecated in favor of the cleaner * {@link #requestNetwork(NetworkRequest, NetworkCallback)} API. * In {@link VERSION_CODES#MNC}, and above, this method is unsupported and will * throw {@code UnsupportedOperationException} if called. */ public int startUsingNetworkFeature(int networkType, String feature) { checkLegacyRoutingApiAccess(); NetworkCapabilities netCap = networkCapabilitiesForFeature(networkType, feature); if (netCap == null) { Log.d(TAG, "Can't satisfy startUsingNetworkFeature for " + networkType + ", " + Loading Loading @@ -939,8 +946,11 @@ public class ConnectivityManager { * always indicates failure. * * @deprecated Deprecated in favor of the cleaner {@link #unregisterNetworkCallback} API. * In {@link VERSION_CODES#MNC}, and above, this method is unsupported and will * throw {@code UnsupportedOperationException} if called. */ public int stopUsingNetworkFeature(int networkType, String feature) { checkLegacyRoutingApiAccess(); NetworkCapabilities netCap = networkCapabilitiesForFeature(networkType, feature); if (netCap == null) { Log.d(TAG, "Can't satisfy stopUsingNetworkFeature for " + networkType + ", " + Loading Loading @@ -1218,6 +1228,8 @@ public class ConnectivityManager { * @deprecated Deprecated in favor of the * {@link #requestNetwork(NetworkRequest, NetworkCallback)}, * {@link #bindProcessToNetwork} and {@link Network#getSocketFactory} API. * In {@link VERSION_CODES#MNC}, and above, this method is unsupported and will * throw {@code UnsupportedOperationException} if called. */ public boolean requestRouteToHost(int networkType, int hostAddress) { return requestRouteToHostAddress(networkType, NetworkUtils.intToInetAddress(hostAddress)); Loading @@ -1238,6 +1250,7 @@ public class ConnectivityManager { * {@link #bindProcessToNetwork} API. */ public boolean requestRouteToHostAddress(int networkType, InetAddress hostAddress) { checkLegacyRoutingApiAccess(); try { return mService.requestRouteToHostAddress(networkType, hostAddress.getAddress()); } catch (RemoteException e) { Loading Loading @@ -1416,7 +1429,8 @@ public class ConnectivityManager { /** * {@hide} */ public ConnectivityManager(IConnectivityManager service) { public ConnectivityManager(Context context, IConnectivityManager service) { mContext = checkNotNull(context, "missing context"); mService = checkNotNull(service, "missing IConnectivityManager"); sInstance = this; } Loading Loading @@ -2703,6 +2717,34 @@ public class ConnectivityManager { return new Network(netId); } private void unsupportedStartingFrom(int version) { if (Process.myUid() == Process.SYSTEM_UID) { // The getApplicationInfo() call we make below is not supported in system context, and // we want to allow the system to use these APIs anyway. return; } if (mContext.getApplicationInfo().targetSdkVersion >= version) { throw new UnsupportedOperationException( "This method is not supported in target SDK version " + version + " and above"); } } // Checks whether the calling app can use the legacy routing API (startUsingNetworkFeature, // stopUsingNetworkFeature, requestRouteToHost), and if not throw UnsupportedOperationException. // TODO: convert the existing system users (Tethering, GpsLocationProvider) to the new APIs and // remove these exemptions. Note that this check is not secure, and apps can still access these // functions by accessing ConnectivityService directly. However, it should be clear that doing // so is unsupported and may break in the future. http://b/22728205 private void checkLegacyRoutingApiAccess() { if (mContext.checkCallingOrSelfPermission("com.android.permission.INJECT_OMADM_SETTINGS") == PackageManager.PERMISSION_GRANTED) { return; } unsupportedStartingFrom(VERSION_CODES.MNC); } /** * Binds host resolutions performed by this process to {@code network}. * {@link #bindProcessToNetwork} takes precedence over this setting. Loading services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -463,7 +463,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { mService = new WrappedConnectivityService( mServiceContext, mNetManager, mStatsService, mPolicyService); mService.systemReady(); mCm = new ConnectivityManager(mService); mCm = new ConnectivityManager(getContext(), mService); } private int transportToLegacyType(int transport) { Loading Loading
core/java/android/app/SystemServiceRegistry.java +30 −3 Original line number Diff line number Diff line Loading @@ -220,11 +220,12 @@ final class SystemServiceRegistry { SYSTEM_SERVICE_NAMES.put(android.text.ClipboardManager.class, Context.CLIPBOARD_SERVICE); registerService(Context.CONNECTIVITY_SERVICE, ConnectivityManager.class, new StaticServiceFetcher<ConnectivityManager>() { new StaticOuterContextServiceFetcher<ConnectivityManager>() { @Override public ConnectivityManager createService() { public ConnectivityManager createService(Context context) { IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b)); IConnectivityManager service = IConnectivityManager.Stub.asInterface(b); return new ConnectivityManager(context, service); }}); registerService(Context.COUNTRY_DETECTOR, CountryDetector.class, Loading Loading @@ -793,4 +794,30 @@ final class SystemServiceRegistry { public abstract T createService(); } /** * Like StaticServiceFetcher, creates only one instance of the service per process, but when * creating the service for the first time, passes it the outer context of the creating * component. * * TODO: Is this safe in the case where multiple applications share the same process? * TODO: Delete this once its only user (ConnectivityManager) is known to work well in the * case where multiple application components each have their own ConnectivityManager object. */ static abstract class StaticOuterContextServiceFetcher<T> implements ServiceFetcher<T> { private T mCachedInstance; @Override public final T getService(ContextImpl ctx) { synchronized (StaticOuterContextServiceFetcher.this) { if (mCachedInstance == null) { mCachedInstance = createService(ctx.getOuterContext()); } return mCachedInstance; } } public abstract T createService(Context applicationContext); } }
core/java/android/net/ConnectivityManager.java +43 −1 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.annotation.SdkConstant.SdkConstantType; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.net.NetworkUtils; import android.os.Binder; import android.os.Build.VERSION_CODES; Loading @@ -33,6 +34,7 @@ import android.os.INetworkManagementService; import android.os.Looper; import android.os.Message; import android.os.Messenger; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.provider.Settings; Loading Loading @@ -490,6 +492,8 @@ public class ConnectivityManager { */ private static ConnectivityManager sInstance; private final Context mContext; private INetworkManagementService mNMService; /** Loading Loading @@ -892,8 +896,11 @@ public class ConnectivityManager { * * @deprecated Deprecated in favor of the cleaner * {@link #requestNetwork(NetworkRequest, NetworkCallback)} API. * In {@link VERSION_CODES#MNC}, and above, this method is unsupported and will * throw {@code UnsupportedOperationException} if called. */ public int startUsingNetworkFeature(int networkType, String feature) { checkLegacyRoutingApiAccess(); NetworkCapabilities netCap = networkCapabilitiesForFeature(networkType, feature); if (netCap == null) { Log.d(TAG, "Can't satisfy startUsingNetworkFeature for " + networkType + ", " + Loading Loading @@ -939,8 +946,11 @@ public class ConnectivityManager { * always indicates failure. * * @deprecated Deprecated in favor of the cleaner {@link #unregisterNetworkCallback} API. * In {@link VERSION_CODES#MNC}, and above, this method is unsupported and will * throw {@code UnsupportedOperationException} if called. */ public int stopUsingNetworkFeature(int networkType, String feature) { checkLegacyRoutingApiAccess(); NetworkCapabilities netCap = networkCapabilitiesForFeature(networkType, feature); if (netCap == null) { Log.d(TAG, "Can't satisfy stopUsingNetworkFeature for " + networkType + ", " + Loading Loading @@ -1218,6 +1228,8 @@ public class ConnectivityManager { * @deprecated Deprecated in favor of the * {@link #requestNetwork(NetworkRequest, NetworkCallback)}, * {@link #bindProcessToNetwork} and {@link Network#getSocketFactory} API. * In {@link VERSION_CODES#MNC}, and above, this method is unsupported and will * throw {@code UnsupportedOperationException} if called. */ public boolean requestRouteToHost(int networkType, int hostAddress) { return requestRouteToHostAddress(networkType, NetworkUtils.intToInetAddress(hostAddress)); Loading @@ -1238,6 +1250,7 @@ public class ConnectivityManager { * {@link #bindProcessToNetwork} API. */ public boolean requestRouteToHostAddress(int networkType, InetAddress hostAddress) { checkLegacyRoutingApiAccess(); try { return mService.requestRouteToHostAddress(networkType, hostAddress.getAddress()); } catch (RemoteException e) { Loading Loading @@ -1416,7 +1429,8 @@ public class ConnectivityManager { /** * {@hide} */ public ConnectivityManager(IConnectivityManager service) { public ConnectivityManager(Context context, IConnectivityManager service) { mContext = checkNotNull(context, "missing context"); mService = checkNotNull(service, "missing IConnectivityManager"); sInstance = this; } Loading Loading @@ -2703,6 +2717,34 @@ public class ConnectivityManager { return new Network(netId); } private void unsupportedStartingFrom(int version) { if (Process.myUid() == Process.SYSTEM_UID) { // The getApplicationInfo() call we make below is not supported in system context, and // we want to allow the system to use these APIs anyway. return; } if (mContext.getApplicationInfo().targetSdkVersion >= version) { throw new UnsupportedOperationException( "This method is not supported in target SDK version " + version + " and above"); } } // Checks whether the calling app can use the legacy routing API (startUsingNetworkFeature, // stopUsingNetworkFeature, requestRouteToHost), and if not throw UnsupportedOperationException. // TODO: convert the existing system users (Tethering, GpsLocationProvider) to the new APIs and // remove these exemptions. Note that this check is not secure, and apps can still access these // functions by accessing ConnectivityService directly. However, it should be clear that doing // so is unsupported and may break in the future. http://b/22728205 private void checkLegacyRoutingApiAccess() { if (mContext.checkCallingOrSelfPermission("com.android.permission.INJECT_OMADM_SETTINGS") == PackageManager.PERMISSION_GRANTED) { return; } unsupportedStartingFrom(VERSION_CODES.MNC); } /** * Binds host resolutions performed by this process to {@code network}. * {@link #bindProcessToNetwork} takes precedence over this setting. Loading
services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -463,7 +463,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { mService = new WrappedConnectivityService( mServiceContext, mNetManager, mStatsService, mPolicyService); mService.systemReady(); mCm = new ConnectivityManager(mService); mCm = new ConnectivityManager(getContext(), mService); } private int transportToLegacyType(int transport) { Loading