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

Commit d01eaecb authored by Remi NGUYEN VAN's avatar Remi NGUYEN VAN Committed by Gerrit Code Review
Browse files

Merge "Add NetworkStack app"

parents f9bb1a99 c094a540
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -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",
@@ -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 {
+8 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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
+10 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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
+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
+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