diff options
| author | 2019-02-14 18:04:20 +0900 | |
|---|---|---|
| committer | 2019-02-15 12:20:17 +0900 | |
| commit | 5db454c28d3ddf724be3f6a697267f7f58d94e2d (patch) | |
| tree | d1ca0b863c669aa3db022ad222aab607bc0801de | |
| parent | cfff01e2dbece7fd6a45f0352c4ab292cf59b89e (diff) | |
Move NetworkStack to services.net
NetworkStack is only used in services.net or clients of services.net. It
cannot stay in framework.jar because it needs to depend on AIDL
interfaces, which would conflict with app implementations if they were
in framework.jar.
Test: atest FrameworksNetTests NetworkStackTests
Bug: 124033493
Change-Id: Ib1d08a3669983640119d008db7e2990fa798724f
Merged-In: I501b125a388c1100c2182bde4670944c2f0d7a02
13 files changed, 322 insertions, 320 deletions
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index 4bbc12fbe63b..e92efde236c4 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -88,7 +88,6 @@ import android.net.IpMemoryStore; import android.net.IpSecManager; import android.net.NetworkPolicyManager; import android.net.NetworkScoreManager; -import android.net.NetworkStack; import android.net.NetworkWatchlistManager; import android.net.lowpan.ILowpanManager; import android.net.lowpan.LowpanManager; @@ -296,13 +295,6 @@ final class SystemServiceRegistry { } }); - registerService(Context.NETWORK_STACK_SERVICE, NetworkStack.class, - new StaticServiceFetcher<NetworkStack>() { - @Override - public NetworkStack createService() { - return new NetworkStack(); - }}); - registerService(Context.IP_MEMORY_STORE_SERVICE, IpMemoryStore.class, new CachedServiceFetcher<IpMemoryStore>() { @Override diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 493aac6e5c40..b072740ccfdf 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -49,7 +49,6 @@ import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.graphics.Bitmap; import android.graphics.drawable.Drawable; -import android.net.NetworkStack; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -3514,11 +3513,10 @@ public abstract class Context { public static final String NETD_SERVICE = "netd"; /** - * Use with {@link #getSystemService(String)} to retrieve a - * {@link NetworkStack} for communicating with the network stack + * Use with {@link android.os.ServiceManager.getService()} to retrieve a + * {@link NetworkStackClient} IBinder for communicating with the network stack * @hide - * @see #getSystemService(String) - * @see NetworkStack + * @see NetworkStackClient */ public static final String NETWORK_STACK_SERVICE = "network_stack"; diff --git a/core/java/android/net/NetworkStack.java b/core/java/android/net/NetworkStack.java index ca49438390e9..dbb894f92f55 100644 --- a/core/java/android/net/NetworkStack.java +++ b/core/java/android/net/NetworkStack.java @@ -15,46 +15,17 @@ */ package android.net; -import static android.content.pm.PackageManager.PERMISSION_GRANTED; -import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH; -import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL; - -import android.annotation.NonNull; -import android.annotation.Nullable; import android.annotation.SystemApi; -import android.annotation.SystemService; import android.annotation.TestApi; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.content.pm.PackageManager; -import android.net.dhcp.DhcpServingParamsParcel; -import android.net.dhcp.IDhcpServerCallbacks; -import android.net.ip.IIpClientCallbacks; -import android.os.Binder; -import android.os.IBinder; -import android.os.Process; -import android.os.RemoteException; -import android.os.ServiceManager; -import android.os.UserHandle; -import android.util.Slog; - -import com.android.internal.annotations.GuardedBy; - -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; /** - * Service used to communicate with the network stack, which is running in a separate module. + * + * Constants for client code communicating with the network stack service. * @hide */ -@SystemService(Context.NETWORK_STACK_SERVICE) @SystemApi @TestApi public class NetworkStack { - private static final String TAG = NetworkStack.class.getSimpleName(); - /** * Permission granted only to the NetworkStack APK, defined in NetworkStackStub with signature * protection level. @@ -65,235 +36,5 @@ public class NetworkStack { public static final String PERMISSION_MAINLINE_NETWORK_STACK = "android.permission.MAINLINE_NETWORK_STACK"; - private static final int NETWORKSTACK_TIMEOUT_MS = 10_000; - - @NonNull - @GuardedBy("mPendingNetStackRequests") - private final ArrayList<NetworkStackCallback> mPendingNetStackRequests = new ArrayList<>(); - @Nullable - @GuardedBy("mPendingNetStackRequests") - private INetworkStackConnector mConnector; - - private volatile boolean mNetworkStackStartRequested = false; - - private interface NetworkStackCallback { - void onNetworkStackConnected(INetworkStackConnector connector); - } - - /** @hide */ - public NetworkStack() { } - - /** - * Create a DHCP server according to the specified parameters. - * - * <p>The server will be returned asynchronously through the provided callbacks. - * @hide - */ - public void makeDhcpServer(final String ifName, final DhcpServingParamsParcel params, - final IDhcpServerCallbacks cb) { - requestConnector(connector -> { - try { - connector.makeDhcpServer(ifName, params, cb); - } catch (RemoteException e) { - e.rethrowFromSystemServer(); - } - }); - } - - /** - * Create an IpClient on the specified interface. - * - * <p>The IpClient will be returned asynchronously through the provided callbacks. - * @hide - */ - public void makeIpClient(String ifName, IIpClientCallbacks cb) { - requestConnector(connector -> { - try { - connector.makeIpClient(ifName, cb); - } catch (RemoteException e) { - e.rethrowFromSystemServer(); - } - }); - } - - /** - * Create a NetworkMonitor. - * - * <p>The INetworkMonitor will be returned asynchronously through the provided callbacks. - * @hide - */ - public void makeNetworkMonitor( - NetworkParcelable network, String name, INetworkMonitorCallbacks cb) { - requestConnector(connector -> { - try { - connector.makeNetworkMonitor(network, name, cb); - } catch (RemoteException e) { - e.rethrowFromSystemServer(); - } - }); - } - - private class NetworkStackConnection implements ServiceConnection { - @Override - public void onServiceConnected(ComponentName name, IBinder service) { - registerNetworkStackService(service); - } - - @Override - public void onServiceDisconnected(ComponentName name) { - // TODO: crash/reboot the system ? - Slog.wtf(TAG, "Lost network stack connector"); - } - }; - - private void registerNetworkStackService(@NonNull IBinder service) { - final INetworkStackConnector connector = INetworkStackConnector.Stub.asInterface(service); - - ServiceManager.addService(Context.NETWORK_STACK_SERVICE, service, false /* allowIsolated */, - DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL); - - final ArrayList<NetworkStackCallback> requests; - synchronized (mPendingNetStackRequests) { - requests = new ArrayList<>(mPendingNetStackRequests); - mPendingNetStackRequests.clear(); - mConnector = connector; - } - - for (NetworkStackCallback r : requests) { - r.onNetworkStackConnected(connector); - } - } - - /** - * Start the network stack. Should be called only once on device startup. - * - * <p>This method will start the network stack either in the network stack process, or inside - * the system server on devices that do not support the network stack module. The network stack - * connector will then be delivered asynchronously to clients that requested it before it was - * started. - * @hide - */ - public void start(Context context) { - mNetworkStackStartRequested = true; - // Try to bind in-process if the library is available - IBinder connector = null; - try { - final Class service = Class.forName( - "com.android.server.NetworkStackService", - true /* initialize */, - context.getClassLoader()); - connector = (IBinder) service.getMethod("makeConnector", Context.class) - .invoke(null, context); - } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { - Slog.wtf(TAG, "Could not create network stack connector from NetworkStackService"); - // TODO: crash/reboot system here ? - return; - } catch (ClassNotFoundException e) { - // Normal behavior if stack is provided by the app: fall through - } - - // In-process network stack. Add the service to the service manager here. - if (connector != null) { - registerNetworkStackService(connector); - return; - } - // Start the network stack process. The service will be added to the service manager in - // NetworkStackConnection.onServiceConnected(). - final Intent intent = new Intent(INetworkStackConnector.class.getName()); - final ComponentName comp = intent.resolveSystemService(context.getPackageManager(), 0); - intent.setComponent(comp); - - if (comp == null) { - Slog.wtf(TAG, "Could not resolve the network stack with " + intent); - // TODO: crash/reboot system server ? - return; - } - - final PackageManager pm = context.getPackageManager(); - int uid = -1; - try { - uid = pm.getPackageUid(comp.getPackageName(), UserHandle.USER_SYSTEM); - } catch (PackageManager.NameNotFoundException e) { - Slog.wtf("Network stack package not found", e); - // Fall through - } - - if (uid != Process.NETWORK_STACK_UID) { - throw new SecurityException("Invalid network stack UID: " + uid); - } - - final int hasPermission = - pm.checkPermission(PERMISSION_MAINLINE_NETWORK_STACK, comp.getPackageName()); - if (hasPermission != PERMISSION_GRANTED) { - throw new SecurityException( - "Network stack does not have permission " + PERMISSION_MAINLINE_NETWORK_STACK); - } - - if (!context.bindServiceAsUser(intent, new NetworkStackConnection(), - Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, UserHandle.SYSTEM)) { - Slog.wtf(TAG, - "Could not bind to network stack in-process, or in app with " + intent); - // TODO: crash/reboot system server if no network stack after a timeout ? - } - } - - /** - * For non-system server clients, get the connector registered by the system server. - */ - private INetworkStackConnector getRemoteConnector() { - // Block until the NetworkStack connector is registered in ServiceManager. - // <p>This is only useful for non-system processes that do not have a way to be notified of - // registration completion. Adding a callback system would be too heavy weight considering - // that the connector is registered on boot, so it is unlikely that a client would request - // it before it is registered. - // TODO: consider blocking boot on registration and simplify much of the logic in this class - IBinder connector; - try { - final long before = System.currentTimeMillis(); - while ((connector = ServiceManager.getService(Context.NETWORK_STACK_SERVICE)) == null) { - Thread.sleep(20); - if (System.currentTimeMillis() - before > NETWORKSTACK_TIMEOUT_MS) { - Slog.e(TAG, "Timeout waiting for NetworkStack connector"); - return null; - } - } - } catch (InterruptedException e) { - Slog.e(TAG, "Error waiting for NetworkStack connector", e); - return null; - } - - return INetworkStackConnector.Stub.asInterface(connector); - } - - private void requestConnector(@NonNull NetworkStackCallback request) { - // TODO: PID check. - final int caller = Binder.getCallingUid(); - if (caller != Process.SYSTEM_UID && !UserHandle.isSameApp(caller, Process.BLUETOOTH_UID)) { - // Don't even attempt to obtain the connector and give a nice error message - throw new SecurityException( - "Only the system server should try to bind to the network stack."); - } - - if (!mNetworkStackStartRequested) { - // The network stack is not being started in this process, e.g. this process is not - // the system server. Get a remote connector registered by the system server. - final INetworkStackConnector connector = getRemoteConnector(); - synchronized (mPendingNetStackRequests) { - mConnector = connector; - } - request.onNetworkStackConnected(connector); - return; - } - - final INetworkStackConnector connector; - synchronized (mPendingNetStackRequests) { - connector = mConnector; - if (connector == null) { - mPendingNetStackRequests.add(request); - return; - } - } - - request.onNetworkStackConnected(connector); - } + private NetworkStack() {} } diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 2cd25e443a20..0f1f8940edc6 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -87,6 +87,7 @@ import android.net.NetworkQuotaInfo; import android.net.NetworkRequest; import android.net.NetworkSpecifier; import android.net.NetworkStack; +import android.net.NetworkStackClient; import android.net.NetworkState; import android.net.NetworkUtils; import android.net.NetworkWatchlistManager; @@ -5093,7 +5094,7 @@ public class ConnectivityService extends IConnectivityManager.Stub if (DBG) log("registerNetworkAgent " + nai); final long token = Binder.clearCallingIdentity(); try { - mContext.getSystemService(NetworkStack.class).makeNetworkMonitor( + getNetworkStack().makeNetworkMonitor( toStableParcelable(nai.network), name, new NetworkMonitorCallbacks(nai)); } finally { Binder.restoreCallingIdentity(token); @@ -5105,6 +5106,11 @@ public class ConnectivityService extends IConnectivityManager.Stub return nai.network.netId; } + @VisibleForTesting + protected NetworkStackClient getNetworkStack() { + return NetworkStackClient.getInstance(); + } + private void handleRegisterNetworkAgent(NetworkAgentInfo nai, INetworkMonitor networkMonitor) { nai.onNetworkMonitorCreated(networkMonitor); if (VDBG) log("Got NetworkAgent Messenger"); diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java index 19bdc0969e6d..c91e1a12078e 100644 --- a/services/core/java/com/android/server/connectivity/Tethering.java +++ b/services/core/java/com/android/server/connectivity/Tethering.java @@ -1859,7 +1859,7 @@ public class Tethering extends BaseNetworkObserver { final TetherState tetherState = new TetherState( new IpServer(iface, mLooper, interfaceType, mLog, mNMService, mStatsService, makeControlCallback(), mConfig.enableLegacyDhcpServer, - mDeps.getIpServerDependencies(mContext))); + mDeps.getIpServerDependencies())); mTetherStates.put(iface, tetherState); tetherState.ipServer.start(); } diff --git a/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java b/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java index 3fddac111ec5..173d7860e4ac 100644 --- a/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java +++ b/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java @@ -61,8 +61,8 @@ public class TetheringDependencies { /** * Get dependencies to be used by IpServer. */ - public IpServer.Dependencies getIpServerDependencies(Context context) { - return new IpServer.Dependencies(context); + public IpServer.Dependencies getIpServerDependencies() { + return new IpServer.Dependencies(); } /** diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 2338fffbf26a..406822c774ca 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -37,6 +37,7 @@ import android.content.res.Resources.Theme; import android.database.sqlite.SQLiteCompatibilityWalFlags; import android.database.sqlite.SQLiteGlobal; import android.hardware.display.DisplayManagerInternal; +import android.net.NetworkStackClient; import android.os.BaseBundle; import android.os.Binder; import android.os.Build; @@ -1240,9 +1241,7 @@ public final class SystemServer { traceBeginAndSlog("StartNetworkStack"); try { - final android.net.NetworkStack networkStack = - context.getSystemService(android.net.NetworkStack.class); - networkStack.start(context); + NetworkStackClient.getInstance().start(context); } catch (Throwable e) { reportWtf("starting Network Stack", e); } diff --git a/services/net/java/android/net/NetworkStackClient.java b/services/net/java/android/net/NetworkStackClient.java new file mode 100644 index 000000000000..1eb7b98d801a --- /dev/null +++ b/services/net/java/android/net/NetworkStackClient.java @@ -0,0 +1,289 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.net; + +import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK; +import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH; +import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; +import android.content.pm.PackageManager; +import android.net.dhcp.DhcpServingParamsParcel; +import android.net.dhcp.IDhcpServerCallbacks; +import android.net.ip.IIpClientCallbacks; +import android.os.Binder; +import android.os.IBinder; +import android.os.Process; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.os.UserHandle; +import android.util.Slog; + +import com.android.internal.annotations.GuardedBy; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; + +/** + * Service used to communicate with the network stack, which is running in a separate module. + * @hide + */ +public class NetworkStackClient { + private static final String TAG = NetworkStackClient.class.getSimpleName(); + + private static final int NETWORKSTACK_TIMEOUT_MS = 10_000; + + private static NetworkStackClient sInstance; + + @NonNull + @GuardedBy("mPendingNetStackRequests") + private final ArrayList<NetworkStackCallback> mPendingNetStackRequests = new ArrayList<>(); + @Nullable + @GuardedBy("mPendingNetStackRequests") + private INetworkStackConnector mConnector; + + private volatile boolean mNetworkStackStartRequested = false; + + private interface NetworkStackCallback { + void onNetworkStackConnected(INetworkStackConnector connector); + } + + private NetworkStackClient() { } + + /** + * Get the NetworkStackClient singleton instance. + */ + public static synchronized NetworkStackClient getInstance() { + if (sInstance == null) { + sInstance = new NetworkStackClient(); + } + return sInstance; + } + + /** + * Create a DHCP server according to the specified parameters. + * + * <p>The server will be returned asynchronously through the provided callbacks. + */ + public void makeDhcpServer(final String ifName, final DhcpServingParamsParcel params, + final IDhcpServerCallbacks cb) { + requestConnector(connector -> { + try { + connector.makeDhcpServer(ifName, params, cb); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + }); + } + + /** + * Create an IpClient on the specified interface. + * + * <p>The IpClient will be returned asynchronously through the provided callbacks. + */ + public void makeIpClient(String ifName, IIpClientCallbacks cb) { + requestConnector(connector -> { + try { + connector.makeIpClient(ifName, cb); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + }); + } + + /** + * Create a NetworkMonitor. + * + * <p>The INetworkMonitor will be returned asynchronously through the provided callbacks. + */ + public void makeNetworkMonitor( + NetworkParcelable network, String name, INetworkMonitorCallbacks cb) { + requestConnector(connector -> { + try { + connector.makeNetworkMonitor(network, name, cb); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + }); + } + + private class NetworkStackConnection implements ServiceConnection { + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + registerNetworkStackService(service); + } + + @Override + public void onServiceDisconnected(ComponentName name) { + // TODO: crash/reboot the system ? + Slog.wtf(TAG, "Lost network stack connector"); + } + }; + + private void registerNetworkStackService(@NonNull IBinder service) { + final INetworkStackConnector connector = INetworkStackConnector.Stub.asInterface(service); + + ServiceManager.addService(Context.NETWORK_STACK_SERVICE, service, false /* allowIsolated */, + DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL); + + final ArrayList<NetworkStackCallback> requests; + synchronized (mPendingNetStackRequests) { + requests = new ArrayList<>(mPendingNetStackRequests); + mPendingNetStackRequests.clear(); + mConnector = connector; + } + + for (NetworkStackCallback r : requests) { + r.onNetworkStackConnected(connector); + } + } + + /** + * Start the network stack. Should be called only once on device startup. + * + * <p>This method will start the network stack either in the network stack process, or inside + * the system server on devices that do not support the network stack module. The network stack + * connector will then be delivered asynchronously to clients that requested it before it was + * started. + */ + public void start(Context context) { + mNetworkStackStartRequested = true; + // Try to bind in-process if the library is available + IBinder connector = null; + try { + final Class service = Class.forName( + "com.android.server.NetworkStackService", + true /* initialize */, + context.getClassLoader()); + connector = (IBinder) service.getMethod("makeConnector", Context.class) + .invoke(null, context); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + Slog.wtf(TAG, "Could not create network stack connector from NetworkStackService"); + // TODO: crash/reboot system here ? + return; + } catch (ClassNotFoundException e) { + // Normal behavior if stack is provided by the app: fall through + } + + // In-process network stack. Add the service to the service manager here. + if (connector != null) { + registerNetworkStackService(connector); + return; + } + // Start the network stack process. The service will be added to the service manager in + // NetworkStackConnection.onServiceConnected(). + final Intent intent = new Intent(INetworkStackConnector.class.getName()); + final ComponentName comp = intent.resolveSystemService(context.getPackageManager(), 0); + intent.setComponent(comp); + + if (comp == null) { + Slog.wtf(TAG, "Could not resolve the network stack with " + intent); + // TODO: crash/reboot system server ? + return; + } + final PackageManager pm = context.getPackageManager(); + int uid = -1; + try { + uid = pm.getPackageUid(comp.getPackageName(), UserHandle.USER_SYSTEM); + } catch (PackageManager.NameNotFoundException e) { + Slog.wtf("Network stack package not found", e); + // Fall through + } + if (uid != Process.NETWORK_STACK_UID) { + throw new SecurityException("Invalid network stack UID: " + uid); + } + + final int hasPermission = + pm.checkPermission(PERMISSION_MAINLINE_NETWORK_STACK, comp.getPackageName()); + if (hasPermission != PERMISSION_GRANTED) { + throw new SecurityException( + "Network stack does not have permission " + PERMISSION_MAINLINE_NETWORK_STACK); + } + + if (!context.bindServiceAsUser(intent, new NetworkStackConnection(), + Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, UserHandle.SYSTEM)) { + Slog.wtf(TAG, + "Could not bind to network stack in-process, or in app with " + intent); + // TODO: crash/reboot system server if no network stack after a timeout ? + } + } + + /** + * For non-system server clients, get the connector registered by the system server. + */ + private INetworkStackConnector getRemoteConnector() { + // Block until the NetworkStack connector is registered in ServiceManager. + // <p>This is only useful for non-system processes that do not have a way to be notified of + // registration completion. Adding a callback system would be too heavy weight considering + // that the connector is registered on boot, so it is unlikely that a client would request + // it before it is registered. + // TODO: consider blocking boot on registration and simplify much of the logic in this class + IBinder connector; + try { + final long before = System.currentTimeMillis(); + while ((connector = ServiceManager.getService(Context.NETWORK_STACK_SERVICE)) == null) { + Thread.sleep(20); + if (System.currentTimeMillis() - before > NETWORKSTACK_TIMEOUT_MS) { + Slog.e(TAG, "Timeout waiting for NetworkStack connector"); + return null; + } + } + } catch (InterruptedException e) { + Slog.e(TAG, "Error waiting for NetworkStack connector", e); + return null; + } + + return INetworkStackConnector.Stub.asInterface(connector); + } + + private void requestConnector(@NonNull NetworkStackCallback request) { + // TODO: PID check. + final int caller = Binder.getCallingUid(); + if (caller != Process.SYSTEM_UID && !UserHandle.isSameApp(caller, Process.BLUETOOTH_UID)) { + // Don't even attempt to obtain the connector and give a nice error message + throw new SecurityException( + "Only the system server should try to bind to the network stack."); + } + + if (!mNetworkStackStartRequested) { + // The network stack is not being started in this process, e.g. this process is not + // the system server. Get a remote connector registered by the system server. + final INetworkStackConnector connector = getRemoteConnector(); + synchronized (mPendingNetStackRequests) { + mConnector = connector; + } + request.onNetworkStackConnected(connector); + return; + } + + final INetworkStackConnector connector; + synchronized (mPendingNetStackRequests) { + connector = mConnector; + if (connector == null) { + mPendingNetStackRequests.add(request); + return; + } + } + + request.onNetworkStackConnected(connector); + } +} diff --git a/services/net/java/android/net/ip/IpClientUtil.java b/services/net/java/android/net/ip/IpClientUtil.java index 2a2a67a92a86..bf917bf88b2d 100644 --- a/services/net/java/android/net/ip/IpClientUtil.java +++ b/services/net/java/android/net/ip/IpClientUtil.java @@ -23,8 +23,7 @@ import android.content.Context; import android.net.DhcpResultsParcelable; import android.net.LinkProperties; import android.net.LinkPropertiesParcelable; -import android.net.NetworkStack; -import android.net.ip.IIpClientCallbacks; +import android.net.NetworkStackClient; import android.os.ConditionVariable; import java.io.FileDescriptor; @@ -76,30 +75,17 @@ public class IpClientUtil { * * <p>This is a convenience method to allow clients to use {@link IpClientCallbacks} instead of * {@link IIpClientCallbacks}. - * @see {@link NetworkStack#makeIpClient(String, IIpClientCallbacks)} + * @see {@link NetworkStackClient#makeIpClient(String, IIpClientCallbacks)} */ public static void makeIpClient(Context context, String ifName, IpClientCallbacks callback) { - context.getSystemService(NetworkStack.class) - .makeIpClient(ifName, new IpClientCallbacksProxy(callback)); - } - - /** - * Create a new IpClient. - * - * <p>This is a convenience method to allow clients to use {@link IpClientCallbacksProxy} - * instead of {@link IIpClientCallbacks}. - * @see {@link NetworkStack#makeIpClient(String, IIpClientCallbacks)} - */ - public static void makeIpClient( - Context context, String ifName, IpClientCallbacksProxy callback) { - context.getSystemService(NetworkStack.class) - .makeIpClient(ifName, callback); + // TODO: migrate clients and remove context argument + NetworkStackClient.getInstance().makeIpClient(ifName, new IpClientCallbacksProxy(callback)); } /** * Wrapper to relay calls from {@link IIpClientCallbacks} to {@link IpClientCallbacks}. */ - public static class IpClientCallbacksProxy extends IIpClientCallbacks.Stub { + private static class IpClientCallbacksProxy extends IIpClientCallbacks.Stub { protected final IpClientCallbacks mCb; /** diff --git a/services/net/java/android/net/ip/IpServer.java b/services/net/java/android/net/ip/IpServer.java index 7910c9a69310..34fc7354d63e 100644 --- a/services/net/java/android/net/ip/IpServer.java +++ b/services/net/java/android/net/ip/IpServer.java @@ -22,7 +22,6 @@ import static android.net.util.NetworkConstants.FF; import static android.net.util.NetworkConstants.RFC7421_PREFIX_LENGTH; import static android.net.util.NetworkConstants.asByte; -import android.content.Context; import android.net.ConnectivityManager; import android.net.INetd; import android.net.INetworkStackStatusCallback; @@ -31,7 +30,7 @@ import android.net.InterfaceConfiguration; import android.net.IpPrefix; import android.net.LinkAddress; import android.net.LinkProperties; -import android.net.NetworkStack; +import android.net.NetworkStackClient; import android.net.RouteInfo; import android.net.dhcp.DhcpServerCallbacks; import android.net.dhcp.DhcpServingParamsParcel; @@ -132,10 +131,6 @@ public class IpServer extends StateMachine { } public static class Dependencies { - private final Context mContext; - public Dependencies(Context context) { - mContext = context; - } public RouterAdvertisementDaemon getRouterAdvertisementDaemon(InterfaceParams ifParams) { return new RouterAdvertisementDaemon(ifParams); } @@ -153,7 +148,7 @@ public class IpServer extends StateMachine { */ public void makeDhcpServer(String ifName, DhcpServingParamsParcel params, DhcpServerCallbacks cb) { - mContext.getSystemService(NetworkStack.class).makeDhcpServer(ifName, params, cb); + NetworkStackClient.getInstance().makeDhcpServer(ifName, params, cb); } } diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 963b6851efea..59df4a005ab0 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -123,7 +123,7 @@ import android.net.NetworkMisc; import android.net.NetworkParcelable; import android.net.NetworkRequest; import android.net.NetworkSpecifier; -import android.net.NetworkStack; +import android.net.NetworkStackClient; import android.net.NetworkUtils; import android.net.ProxyInfo; import android.net.RouteInfo; @@ -245,7 +245,7 @@ public class ConnectivityServiceTest { @Mock INetworkStatsService mStatsService; @Mock INetworkPolicyManager mNpm; @Mock INetd mMockNetd; - @Mock NetworkStack mNetworkStack; + @Mock NetworkStackClient mNetworkStack; private ArgumentCaptor<String[]> mStringArrayCaptor = ArgumentCaptor.forClass(String[].class); @@ -1061,6 +1061,11 @@ public class ConnectivityServiceTest { } @Override + protected NetworkStackClient getNetworkStack() { + return mNetworkStack; + } + + @Override public WakeupMessage makeWakeupMessage( Context context, Handler handler, String cmdName, int cmd, Object obj) { return new FakeWakeupMessage(context, handler, cmdName, cmd, 0, 0, obj); diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java index 9578ded1a089..aa6cbda0479d 100644 --- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java +++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java @@ -37,7 +37,6 @@ import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.NetworkMisc; -import android.net.NetworkStack; import android.os.INetworkManagementService; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; @@ -74,16 +73,12 @@ public class LingerMonitorTest { @Mock NetworkMisc mMisc; @Mock NetworkNotificationManager mNotifier; @Mock Resources mResources; - @Mock NetworkStack mNetworkStack; @Before public void setUp() { MockitoAnnotations.initMocks(this); when(mCtx.getResources()).thenReturn(mResources); when(mCtx.getPackageName()).thenReturn("com.android.server.connectivity"); - when(mCtx.getSystemServiceName(NetworkStack.class)) - .thenReturn(Context.NETWORK_STACK_SERVICE); - when(mCtx.getSystemService(Context.NETWORK_STACK_SERVICE)).thenReturn(mNetworkStack); mMonitor = new TestableLingerMonitor(mCtx, mNotifier, HIGH_DAILY_LIMIT, HIGH_RATE_LIMIT); } diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java index a4a735d1a89d..533d7ad2a472 100644 --- a/tests/net/java/com/android/server/connectivity/TetheringTest.java +++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java @@ -195,10 +195,6 @@ public class TetheringTest { } public class MockIpServerDependencies extends IpServer.Dependencies { - MockIpServerDependencies() { - super(null); - } - @Override public RouterAdvertisementDaemon getRouterAdvertisementDaemon( InterfaceParams ifParams) { @@ -266,7 +262,7 @@ public class TetheringTest { } @Override - public IpServer.Dependencies getIpServerDependencies(Context context) { + public IpServer.Dependencies getIpServerDependencies() { return mIpServerDependencies; } |