Loading Android.bp +11 −0 Original line number Diff line number Diff line Loading @@ -679,6 +679,7 @@ java_defaults { static_libs: [ "apex_aidl_interface-java", "networkstack-aidl-interfaces-java", "framework-protos", "android.hidl.base-V1.0-java", "android.hardware.cas-V1.0-java", Loading Loading @@ -818,6 +819,16 @@ gensrcs { output_extension: "srcjar", } // AIDL interfaces between the core system and the networking mainline module. aidl_interface { name: "networkstack-aidl-interfaces", local_include_dir: "core/java", srcs: [ "core/java/android/net/INetworkStackConnector.aidl", ], api_dir: "aidl/networkstack", } // Build ext.jar // ============================================================ java_library { Loading core/java/android/app/SystemServiceRegistry.java +8 −0 Original line number Diff line number Diff line Loading @@ -87,6 +87,7 @@ import android.net.INetworkPolicyManager; 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; Loading Loading @@ -283,6 +284,13 @@ final class SystemServiceRegistry { return new ConnectivityManager(context, service); }}); registerService(Context.NETWORK_STACK_SERVICE, NetworkStack.class, new StaticServiceFetcher<NetworkStack>() { @Override public NetworkStack createService() { return new NetworkStack(); }}); registerService(Context.IPSEC_SERVICE, IpSecManager.class, new CachedServiceFetcher<IpSecManager>() { @Override Loading core/java/android/content/Context.java +10 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ 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; Loading Loading @@ -3502,6 +3503,15 @@ public abstract class Context { */ public static final String CONNECTIVITY_SERVICE = "connectivity"; /** * Use with {@link #getSystemService(String)} to retrieve a * {@link NetworkStack} for communicating with the network stack * @hide * @see #getSystemService(String) * @see NetworkStack */ public static final String NETWORK_STACK_SERVICE = "network_stack"; /** * Use with {@link #getSystemService(String)} to retrieve a * {@link android.net.IpSecManager} for encrypting Sockets or Networks with Loading core/java/android/net/INetworkStackConnector.aidl 0 → 100644 +21 −0 Original line number Diff line number Diff line /** * Copyright (c) 2018, 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 perNmissions and * limitations under the License. */ package android.net; /** @hide */ oneway interface INetworkStackConnector { // TODO: requestDhcpServer(), etc. will go here } No newline at end of file core/java/android/net/NetworkStack.java 0 → 100644 +156 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 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.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.SystemService; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Binder; import android.os.IBinder; import android.os.Process; 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 */ @SystemService(Context.NETWORK_STACK_SERVICE) public class NetworkStack { private static final String TAG = NetworkStack.class.getSimpleName(); @NonNull @GuardedBy("mPendingNetStackRequests") private final ArrayList<NetworkStackRequest> mPendingNetStackRequests = new ArrayList<>(); @Nullable @GuardedBy("mPendingNetStackRequests") private INetworkStackConnector mConnector; private interface NetworkStackRequest { void onNetworkStackConnected(INetworkStackConnector connector); } public NetworkStack() { } 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<NetworkStackRequest> requests; synchronized (mPendingNetStackRequests) { requests = new ArrayList<>(mPendingNetStackRequests); mPendingNetStackRequests.clear(); mConnector = connector; } for (NetworkStackRequest 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) { // 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").invoke(null); } 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 || !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 ? } } // TODO: use this method to obtain the connector when implementing network stack operations private void requestConnector(@NonNull NetworkStackRequest request) { // TODO: PID check. if (Binder.getCallingUid() != Process.SYSTEM_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."); } final INetworkStackConnector connector; synchronized (mPendingNetStackRequests) { connector = mConnector; if (connector == null) { mPendingNetStackRequests.add(request); return; } } request.onNetworkStackConnected(connector); } } Loading
Android.bp +11 −0 Original line number Diff line number Diff line Loading @@ -679,6 +679,7 @@ java_defaults { static_libs: [ "apex_aidl_interface-java", "networkstack-aidl-interfaces-java", "framework-protos", "android.hidl.base-V1.0-java", "android.hardware.cas-V1.0-java", Loading Loading @@ -818,6 +819,16 @@ gensrcs { output_extension: "srcjar", } // AIDL interfaces between the core system and the networking mainline module. aidl_interface { name: "networkstack-aidl-interfaces", local_include_dir: "core/java", srcs: [ "core/java/android/net/INetworkStackConnector.aidl", ], api_dir: "aidl/networkstack", } // Build ext.jar // ============================================================ java_library { Loading
core/java/android/app/SystemServiceRegistry.java +8 −0 Original line number Diff line number Diff line Loading @@ -87,6 +87,7 @@ import android.net.INetworkPolicyManager; 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; Loading Loading @@ -283,6 +284,13 @@ final class SystemServiceRegistry { return new ConnectivityManager(context, service); }}); registerService(Context.NETWORK_STACK_SERVICE, NetworkStack.class, new StaticServiceFetcher<NetworkStack>() { @Override public NetworkStack createService() { return new NetworkStack(); }}); registerService(Context.IPSEC_SERVICE, IpSecManager.class, new CachedServiceFetcher<IpSecManager>() { @Override Loading
core/java/android/content/Context.java +10 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ 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; Loading Loading @@ -3502,6 +3503,15 @@ public abstract class Context { */ public static final String CONNECTIVITY_SERVICE = "connectivity"; /** * Use with {@link #getSystemService(String)} to retrieve a * {@link NetworkStack} for communicating with the network stack * @hide * @see #getSystemService(String) * @see NetworkStack */ public static final String NETWORK_STACK_SERVICE = "network_stack"; /** * Use with {@link #getSystemService(String)} to retrieve a * {@link android.net.IpSecManager} for encrypting Sockets or Networks with Loading
core/java/android/net/INetworkStackConnector.aidl 0 → 100644 +21 −0 Original line number Diff line number Diff line /** * Copyright (c) 2018, 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 perNmissions and * limitations under the License. */ package android.net; /** @hide */ oneway interface INetworkStackConnector { // TODO: requestDhcpServer(), etc. will go here } No newline at end of file
core/java/android/net/NetworkStack.java 0 → 100644 +156 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 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.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.SystemService; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Binder; import android.os.IBinder; import android.os.Process; 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 */ @SystemService(Context.NETWORK_STACK_SERVICE) public class NetworkStack { private static final String TAG = NetworkStack.class.getSimpleName(); @NonNull @GuardedBy("mPendingNetStackRequests") private final ArrayList<NetworkStackRequest> mPendingNetStackRequests = new ArrayList<>(); @Nullable @GuardedBy("mPendingNetStackRequests") private INetworkStackConnector mConnector; private interface NetworkStackRequest { void onNetworkStackConnected(INetworkStackConnector connector); } public NetworkStack() { } 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<NetworkStackRequest> requests; synchronized (mPendingNetStackRequests) { requests = new ArrayList<>(mPendingNetStackRequests); mPendingNetStackRequests.clear(); mConnector = connector; } for (NetworkStackRequest 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) { // 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").invoke(null); } 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 || !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 ? } } // TODO: use this method to obtain the connector when implementing network stack operations private void requestConnector(@NonNull NetworkStackRequest request) { // TODO: PID check. if (Binder.getCallingUid() != Process.SYSTEM_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."); } final INetworkStackConnector connector; synchronized (mPendingNetStackRequests) { connector = mConnector; if (connector == null) { mPendingNetStackRequests.add(request); return; } } request.onNetworkStackConnected(connector); } }