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

Commit 5ca66d52 authored by Lorenzo Colitti's avatar Lorenzo Colitti Committed by Gerrit Code Review
Browse files

Merge "Move frameworks/base depedencies into NetworkStack."

parents 46f51659 2ff6ee41
Loading
Loading
Loading
Loading
+0 −7
Original line number Diff line number Diff line
@@ -25,15 +25,8 @@ filegroup {
    name: "net-module-utils-srcs",
    srcs: [
        "src/android/net/util/SharedLog.java",
        "src/android/net/shared/InitialConfiguration.java",
        "src/android/net/shared/Layer2Information.java",
        "src/android/net/shared/LinkPropertiesParcelableUtil.java",
        "src/android/net/shared/ParcelableUtil.java",
        "src/android/net/shared/NetdUtils.java",
        "src/android/net/shared/NetworkMonitorUtils.java",
        "src/android/net/shared/ParcelableUtil.java",
        "src/android/net/shared/PrivateDnsConfig.java",
        "src/android/net/shared/ProvisioningConfiguration.java",
        "src/android/net/shared/RouteUtils.java",
        "src/android/net/util/InterfaceParams.java",
    ],
+10 −1
Original line number Diff line number Diff line
@@ -145,15 +145,22 @@ aidl_interface {
java_library {
    name: "networkstack-client",
    sdk_version: "system_current",
    // this is part of updatable modules(NetworkStack) which targets 29(Q)
    // this is part of updatable modules(NetworkStack) which runs on Q and above
    min_sdk_version: "29",
    srcs: [
        ":framework-annotations",
        "src/android/net/ip/**/*.java",
        "src/android/net/IpMemoryStore.java",
        "src/android/net/IpMemoryStoreClient.java",
        "src/android/net/ipmemorystore/**/*.java",
        "src/android/net/NetworkMonitorManager.java",
        "src/android/net/networkstack/**/*.java",
        "src/android/net/networkstack/aidl/quirks/**/*.java",
        "src/android/net/shared/**/*.java",
        "src/android/net/util/**/*.java",
    ],
    libs: [
        "net-utils-framework-common",  // XXX for IpUtils.java only
    ],
    static_libs: [
        "ipmemorystore-aidl-interfaces-V10-java",
@@ -164,6 +171,8 @@ java_library {
        "//packages/modules/Connectivity/Tethering",
        "//packages/modules/Connectivity/service",
        "//frameworks/base/services/net",
        "//frameworks/opt/net/wifi/service",
        "//packages/apps/Bluetooth",
        "//packages/modules/NetworkStack",
    ],
    apex_available: [
+98 −0
Original line number Diff line number Diff line
/*
 * 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 android.annotation.NonNull;
import android.content.Context;
import android.net.networkstack.ModuleNetworkStackClient;
import android.util.Log;

import com.android.internal.annotations.VisibleForTesting;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;

/**
 * Manager class used to communicate with the ip memory store service in the network stack,
 * which is running in a separate module.
 * @hide
*/
public class IpMemoryStore extends IpMemoryStoreClient {
    private static final String TAG = IpMemoryStore.class.getSimpleName();
    @NonNull private final CompletableFuture<IIpMemoryStore> mService;
    @NonNull private final AtomicReference<CompletableFuture<IIpMemoryStore>> mTailNode;

    public IpMemoryStore(@NonNull final Context context) {
        super(context);
        mService = new CompletableFuture<>();
        mTailNode = new AtomicReference<CompletableFuture<IIpMemoryStore>>(mService);
        getModuleNetworkStackClient(context).fetchIpMemoryStore(
                new IIpMemoryStoreCallbacks.Stub() {
                    @Override
                    public void onIpMemoryStoreFetched(@NonNull final IIpMemoryStore memoryStore) {
                        mService.complete(memoryStore);
                    }

                    @Override
                    public int getInterfaceVersion() {
                        return this.VERSION;
                    }

                    @Override
                    public String getInterfaceHash() {
                        return this.HASH;
                    }
                });
    }

    /*
     *  If the IpMemoryStore is ready, this function will run the request synchronously.
     *  Otherwise, it will enqueue the requests for execution immediately after the
     *  service becomes ready. The requests are guaranteed to be executed in the order
     *  they are sumbitted.
     */
    @Override
    protected void runWhenServiceReady(Consumer<IIpMemoryStore> cb) throws ExecutionException {
        mTailNode.getAndUpdate(future -> future.handle((store, exception) -> {
            if (exception != null) {
                // this should never happens since we also catch the exception below
                Log.wtf(TAG, "Error fetching IpMemoryStore", exception);
                return store;
            }

            try {
                cb.accept(store);
            } catch (Exception e) {
                Log.wtf(TAG, "Exception occurred: " + e.getMessage());
            }
            return store;
        }));
    }

    @VisibleForTesting
    protected ModuleNetworkStackClient getModuleNetworkStackClient(Context context) {
        return ModuleNetworkStackClient.getInstance(context);
    }

    /** Gets an instance of the memory store */
    @NonNull
    public static IpMemoryStore getMemoryStore(final Context context) {
        return new IpMemoryStore(context);
    }
}
+203 −0
Original line number Diff line number Diff line
/*
 * 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 android.annotation.Hide;
import android.annotation.NonNull;
import android.os.Binder;
import android.os.RemoteException;
import android.util.Log;

/**
 * A convenience wrapper for INetworkMonitor.
 *
 * Wraps INetworkMonitor calls, making them a bit more friendly to use. Currently handles:
 * - Clearing calling identity
 * - Ignoring RemoteExceptions
 * - Converting to stable parcelables
 *
 * By design, all methods on INetworkMonitor are asynchronous oneway IPCs and are thus void. All the
 * wrapper methods in this class return a boolean that callers can use to determine whether
 * RemoteException was thrown.
 */
@Hide
public class NetworkMonitorManager {

    @NonNull private final INetworkMonitor mNetworkMonitor;
    @NonNull private final String mTag;

    public NetworkMonitorManager(@NonNull INetworkMonitor networkMonitorManager,
            @NonNull String tag) {
        mNetworkMonitor = networkMonitorManager;
        mTag = tag;
    }

    public NetworkMonitorManager(@NonNull INetworkMonitor networkMonitorManager) {
        this(networkMonitorManager, NetworkMonitorManager.class.getSimpleName());
    }

    private void log(String s, Throwable e) {
        Log.e(mTag, s, e);
    }

    // CHECKSTYLE:OFF Generated code

    public boolean start() {
        final long token = Binder.clearCallingIdentity();
        try {
            mNetworkMonitor.start();
            return true;
        } catch (RemoteException e) {
            log("Error in start", e);
            return false;
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    public boolean launchCaptivePortalApp() {
        final long token = Binder.clearCallingIdentity();
        try {
            mNetworkMonitor.launchCaptivePortalApp();
            return true;
        } catch (RemoteException e) {
            log("Error in launchCaptivePortalApp", e);
            return false;
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    public boolean notifyCaptivePortalAppFinished(int response) {
        final long token = Binder.clearCallingIdentity();
        try {
            mNetworkMonitor.notifyCaptivePortalAppFinished(response);
            return true;
        } catch (RemoteException e) {
            log("Error in notifyCaptivePortalAppFinished", e);
            return false;
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    public boolean setAcceptPartialConnectivity() {
        final long token = Binder.clearCallingIdentity();
        try {
            mNetworkMonitor.setAcceptPartialConnectivity();
            return true;
        } catch (RemoteException e) {
            log("Error in setAcceptPartialConnectivity", e);
            return false;
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    public boolean forceReevaluation(int uid) {
        final long token = Binder.clearCallingIdentity();
        try {
            mNetworkMonitor.forceReevaluation(uid);
            return true;
        } catch (RemoteException e) {
            log("Error in forceReevaluation", e);
            return false;
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    public boolean notifyPrivateDnsChanged(PrivateDnsConfigParcel config) {
        final long token = Binder.clearCallingIdentity();
        try {
            mNetworkMonitor.notifyPrivateDnsChanged(config);
            return true;
        } catch (RemoteException e) {
            log("Error in notifyPrivateDnsChanged", e);
            return false;
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    public boolean notifyDnsResponse(int returnCode) {
        final long token = Binder.clearCallingIdentity();
        try {
            mNetworkMonitor.notifyDnsResponse(returnCode);
            return true;
        } catch (RemoteException e) {
            log("Error in notifyDnsResponse", e);
            return false;
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    public boolean notifyNetworkConnected(LinkProperties lp, NetworkCapabilities nc) {
        final long token = Binder.clearCallingIdentity();
        try {
            mNetworkMonitor.notifyNetworkConnected(lp, nc);
            return true;
        } catch (RemoteException e) {
            log("Error in notifyNetworkConnected", e);
            return false;
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    public boolean notifyNetworkDisconnected() {
        final long token = Binder.clearCallingIdentity();
        try {
            mNetworkMonitor.notifyNetworkDisconnected();
            return true;
        } catch (RemoteException e) {
            log("Error in notifyNetworkDisconnected", e);
            return false;
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    public boolean notifyLinkPropertiesChanged(LinkProperties lp) {
        final long token = Binder.clearCallingIdentity();
        try {
            mNetworkMonitor.notifyLinkPropertiesChanged(lp);
            return true;
        } catch (RemoteException e) {
            log("Error in notifyLinkPropertiesChanged", e);
            return false;
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    public boolean notifyNetworkCapabilitiesChanged(NetworkCapabilities nc) {
        final long token = Binder.clearCallingIdentity();
        try {
            mNetworkMonitor.notifyNetworkCapabilitiesChanged(nc);
            return true;
        } catch (RemoteException e) {
            log("Error in notifyNetworkCapabilitiesChanged", e);
            return false;
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    // CHECKSTYLE:ON Generated code
}
+136 −0
Original line number Diff line number Diff line
/*
 * 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.ip;

import android.net.DhcpResultsParcelable;
import android.net.Layer2PacketParcelable;
import android.net.LinkProperties;

import java.util.List;

/**
 * Callbacks for handling IpClient events.
 *
 * This is a convenience class to allow clients not to override all methods of IIpClientCallbacks,
 * and avoid unparceling arguments.
 * These methods are called asynchronously on a Binder thread, as IpClient lives in a different
 * process.
 * @hide
 */
public class IpClientCallbacks {

    /**
     * Callback called upon IpClient creation.
     *
     * @param ipClient The Binder token to communicate with IpClient.
     */
    public void onIpClientCreated(IIpClient ipClient) {}

    /**
     * Callback called prior to DHCP discovery/renewal.
     *
     * <p>In order to receive onPreDhcpAction(), call #withPreDhcpAction() when constructing a
     * ProvisioningConfiguration.
     *
     * <p>Implementations of onPreDhcpAction() must call IpClient#completedPreDhcpAction() to
     * indicate that DHCP is clear to proceed.
      */
    public void onPreDhcpAction() {}

    /**
     * Callback called after DHCP discovery/renewal.
     */
    public void onPostDhcpAction() {}

    /**
     * Callback called when new DHCP results are available.
     *
     * <p>This is purely advisory and not an indication of provisioning success or failure.  This is
     * only here for callers that want to expose DHCPv4 results to other APIs
     * (e.g., WifiInfo#setInetAddress).
     *
     * <p>DHCPv4 or static IPv4 configuration failure or success can be determined by whether or not
     * the passed-in DhcpResults object is null.
     */
    public void onNewDhcpResults(DhcpResultsParcelable dhcpResults) {
        // In general callbacks would not use a parcelable directly (DhcpResultsParcelable), and
        // would use a wrapper instead, because of the lack of safety of stable parcelables. But
        // there are already two classes in the tree for DHCP information: DhcpInfo and DhcpResults,
        // and neither of them exposes an appropriate API (they are bags of mutable fields and can't
        // be changed because they are public API and @UnsupportedAppUsage, being no better than the
        // stable parcelable). Adding a third class would cost more than the gain considering that
        // the only client of this callback is WiFi, which will end up converting the results to
        // DhcpInfo anyway.
    }

    /**
     * Indicates that provisioning was successful.
     */
    public void onProvisioningSuccess(LinkProperties newLp) {}

    /**
     * Indicates that provisioning failed.
     */
    public void onProvisioningFailure(LinkProperties newLp) {}

    /**
     * Invoked on LinkProperties changes.
     */
    public void onLinkPropertiesChange(LinkProperties newLp) {}

    /**Called when the internal IpReachabilityMonitor (if enabled) has
     * detected the loss of a critical number of required neighbors.
     */
    public void onReachabilityLost(String logMsg) {}

    /**
     * Called when the IpClient state machine terminates.
     */
    public void onQuit() {}

    /**
     * Called to indicate that a new APF program must be installed to filter incoming packets.
     */
    public void installPacketFilter(byte[] filter) {}

    /**
     * Called to indicate that the APF Program & data buffer must be read asynchronously from the
     * wifi driver.
     *
     * <p>Due to Wifi HAL limitations, the current implementation only supports dumping the entire
     * buffer. In response to this request, the driver returns the data buffer asynchronously
     * by sending an IpClient#EVENT_READ_PACKET_FILTER_COMPLETE message.
     */
    public void startReadPacketFilter() {}

    /**
     * If multicast filtering cannot be accomplished with APF, this function will be called to
     * actuate multicast filtering using another means.
     */
    public void setFallbackMulticastFilter(boolean enabled) {}

    /**
     * Enabled/disable Neighbor Discover offload functionality. This is called, for example,
     * whenever 464xlat is being started or stopped.
     */
    public void setNeighborDiscoveryOffload(boolean enable) {}

    /**
     * Invoked on starting preconnection process.
     */
    public void onPreconnectionStart(List<Layer2PacketParcelable> packets) {}
}
Loading