Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0d49d386 authored by Remi NGUYEN VAN's avatar Remi NGUYEN VAN Committed by android-build-merger
Browse files

Merge "Move NetworkStack to services.net" am: 762f9f0c

am: 51490ad0

Change-Id: I6a0ddc23bf95039d9d51a4fde9dd87d2f5bf71ee
parents 5e91ce2f 51490ad0
Loading
Loading
Loading
Loading
+0 −8
Original line number Original line Diff line number Diff line
@@ -88,7 +88,6 @@ import android.net.IpMemoryStore;
import android.net.IpSecManager;
import android.net.IpSecManager;
import android.net.NetworkPolicyManager;
import android.net.NetworkPolicyManager;
import android.net.NetworkScoreManager;
import android.net.NetworkScoreManager;
import android.net.NetworkStack;
import android.net.NetworkWatchlistManager;
import android.net.NetworkWatchlistManager;
import android.net.lowpan.ILowpanManager;
import android.net.lowpan.ILowpanManager;
import android.net.lowpan.LowpanManager;
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,
        registerService(Context.IP_MEMORY_STORE_SERVICE, IpMemoryStore.class,
                new CachedServiceFetcher<IpMemoryStore>() {
                new CachedServiceFetcher<IpMemoryStore>() {
                    @Override
                    @Override
+3 −5
Original line number Original line Diff line number Diff line
@@ -49,7 +49,6 @@ import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.graphics.Bitmap;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Drawable;
import android.net.NetworkStack;
import android.net.Uri;
import android.net.Uri;
import android.os.Build;
import android.os.Build;
import android.os.Bundle;
import android.os.Bundle;
@@ -3514,11 +3513,10 @@ public abstract class Context {
    public static final String NETD_SERVICE = "netd";
    public static final String NETD_SERVICE = "netd";


    /**
    /**
     * Use with {@link #getSystemService(String)} to retrieve a
     * Use with {@link android.os.ServiceManager.getService()} to retrieve a
     * {@link NetworkStack} for communicating with the network stack
     * {@link NetworkStackClient} IBinder for communicating with the network stack
     * @hide
     * @hide
     * @see #getSystemService(String)
     * @see NetworkStackClient
     * @see NetworkStack
     */
     */
    public static final String NETWORK_STACK_SERVICE = "network_stack";
    public static final String NETWORK_STACK_SERVICE = "network_stack";


+3 −262
Original line number Original line Diff line number Diff line
@@ -15,46 +15,17 @@
 */
 */
package android.net;
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.SystemApi;
import android.annotation.SystemService;
import android.annotation.TestApi;
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
 * @hide
 */
 */
@SystemService(Context.NETWORK_STACK_SERVICE)
@SystemApi
@SystemApi
@TestApi
@TestApi
public class NetworkStack {
public class NetworkStack {
    private static final String TAG = NetworkStack.class.getSimpleName();

    /**
    /**
     * Permission granted only to the NetworkStack APK, defined in NetworkStackStub with signature
     * Permission granted only to the NetworkStack APK, defined in NetworkStackStub with signature
     * protection level.
     * protection level.
@@ -65,235 +36,5 @@ public class NetworkStack {
    public static final String PERMISSION_MAINLINE_NETWORK_STACK =
    public static final String PERMISSION_MAINLINE_NETWORK_STACK =
            "android.permission.MAINLINE_NETWORK_STACK";
            "android.permission.MAINLINE_NETWORK_STACK";


    private static final int NETWORKSTACK_TIMEOUT_MS = 10_000;
    private NetworkStack() {}

    @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);
    }
}
}
+7 −1
Original line number Original line Diff line number Diff line
@@ -87,6 +87,7 @@ import android.net.NetworkQuotaInfo;
import android.net.NetworkRequest;
import android.net.NetworkRequest;
import android.net.NetworkSpecifier;
import android.net.NetworkSpecifier;
import android.net.NetworkStack;
import android.net.NetworkStack;
import android.net.NetworkStackClient;
import android.net.NetworkState;
import android.net.NetworkState;
import android.net.NetworkUtils;
import android.net.NetworkUtils;
import android.net.NetworkWatchlistManager;
import android.net.NetworkWatchlistManager;
@@ -5095,7 +5096,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
        if (DBG) log("registerNetworkAgent " + nai);
        if (DBG) log("registerNetworkAgent " + nai);
        final long token = Binder.clearCallingIdentity();
        final long token = Binder.clearCallingIdentity();
        try {
        try {
            mContext.getSystemService(NetworkStack.class).makeNetworkMonitor(
            getNetworkStack().makeNetworkMonitor(
                    toStableParcelable(nai.network), name, new NetworkMonitorCallbacks(nai));
                    toStableParcelable(nai.network), name, new NetworkMonitorCallbacks(nai));
        } finally {
        } finally {
            Binder.restoreCallingIdentity(token);
            Binder.restoreCallingIdentity(token);
@@ -5107,6 +5108,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
        return nai.network.netId;
        return nai.network.netId;
    }
    }


    @VisibleForTesting
    protected NetworkStackClient getNetworkStack() {
        return NetworkStackClient.getInstance();
    }

    private void handleRegisterNetworkAgent(NetworkAgentInfo nai, INetworkMonitor networkMonitor) {
    private void handleRegisterNetworkAgent(NetworkAgentInfo nai, INetworkMonitor networkMonitor) {
        nai.onNetworkMonitorCreated(networkMonitor);
        nai.onNetworkMonitorCreated(networkMonitor);
        if (VDBG) log("Got NetworkAgent Messenger");
        if (VDBG) log("Got NetworkAgent Messenger");
+1 −1
Original line number Original line Diff line number Diff line
@@ -1859,7 +1859,7 @@ public class Tethering extends BaseNetworkObserver {
        final TetherState tetherState = new TetherState(
        final TetherState tetherState = new TetherState(
                new IpServer(iface, mLooper, interfaceType, mLog, mNMService, mStatsService,
                new IpServer(iface, mLooper, interfaceType, mLog, mNMService, mStatsService,
                             makeControlCallback(), mConfig.enableLegacyDhcpServer,
                             makeControlCallback(), mConfig.enableLegacyDhcpServer,
                             mDeps.getIpServerDependencies(mContext)));
                             mDeps.getIpServerDependencies()));
        mTetherStates.put(iface, tetherState);
        mTetherStates.put(iface, tetherState);
        tetherState.ipServer.start();
        tetherState.ipServer.start();
    }
    }
Loading