[BOT.2] Create a coordinator and stats provider to provide tether stats
Make BPF tethering offload coordinator, BpfCoordinator, registers a network stats provider, BpfTetherStatsProvider, and provide the tethering stats from the BPF map. Bug: 150736748 Test: new test BpfCoordinatorTest Change-Id: I22e71f87b67668f7e733e4f215d93bf5b2c9380d
This commit is contained in:
@@ -65,6 +65,7 @@ import androidx.annotation.Nullable;
|
|||||||
import com.android.internal.util.MessageUtils;
|
import com.android.internal.util.MessageUtils;
|
||||||
import com.android.internal.util.State;
|
import com.android.internal.util.State;
|
||||||
import com.android.internal.util.StateMachine;
|
import com.android.internal.util.StateMachine;
|
||||||
|
import com.android.networkstack.tethering.BpfCoordinator;
|
||||||
import com.android.networkstack.tethering.PrivateAddressCoordinator;
|
import com.android.networkstack.tethering.PrivateAddressCoordinator;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -225,6 +226,8 @@ public class IpServer extends StateMachine {
|
|||||||
|
|
||||||
private final SharedLog mLog;
|
private final SharedLog mLog;
|
||||||
private final INetd mNetd;
|
private final INetd mNetd;
|
||||||
|
@NonNull
|
||||||
|
private final BpfCoordinator mBpfCoordinator;
|
||||||
private final Callback mCallback;
|
private final Callback mCallback;
|
||||||
private final InterfaceController mInterfaceCtrl;
|
private final InterfaceController mInterfaceCtrl;
|
||||||
private final PrivateAddressCoordinator mPrivateAddressCoordinator;
|
private final PrivateAddressCoordinator mPrivateAddressCoordinator;
|
||||||
@@ -314,11 +317,13 @@ public class IpServer extends StateMachine {
|
|||||||
// object. It helps to reduce the arguments of the constructor.
|
// object. It helps to reduce the arguments of the constructor.
|
||||||
public IpServer(
|
public IpServer(
|
||||||
String ifaceName, Looper looper, int interfaceType, SharedLog log,
|
String ifaceName, Looper looper, int interfaceType, SharedLog log,
|
||||||
INetd netd, Callback callback, boolean usingLegacyDhcp, boolean usingBpfOffload,
|
INetd netd, @NonNull BpfCoordinator coordinator, Callback callback,
|
||||||
|
boolean usingLegacyDhcp, boolean usingBpfOffload,
|
||||||
PrivateAddressCoordinator addressCoordinator, Dependencies deps) {
|
PrivateAddressCoordinator addressCoordinator, Dependencies deps) {
|
||||||
super(ifaceName, looper);
|
super(ifaceName, looper);
|
||||||
mLog = log.forSubComponent(ifaceName);
|
mLog = log.forSubComponent(ifaceName);
|
||||||
mNetd = netd;
|
mNetd = netd;
|
||||||
|
mBpfCoordinator = coordinator;
|
||||||
mCallback = callback;
|
mCallback = callback;
|
||||||
mInterfaceCtrl = new InterfaceController(ifaceName, mNetd, mLog);
|
mInterfaceCtrl = new InterfaceController(ifaceName, mNetd, mLog);
|
||||||
mIfaceName = ifaceName;
|
mIfaceName = ifaceName;
|
||||||
@@ -754,6 +759,14 @@ public class IpServer extends StateMachine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
upstreamIfindex = mDeps.getIfindex(upstreamIface);
|
upstreamIfindex = mDeps.getIfindex(upstreamIface);
|
||||||
|
|
||||||
|
// Add upstream index to name mapping for the tether stats usage in the coordinator.
|
||||||
|
// Although this mapping could be added by both class Tethering and IpServer, adding
|
||||||
|
// mapping from IpServer guarantees that the mapping is added before the adding
|
||||||
|
// forwarding rules. That is because there are different state machines in both
|
||||||
|
// classes. It is hard to guarantee the link property update order between multiple
|
||||||
|
// state machines.
|
||||||
|
mBpfCoordinator.addUpstreamNameToLookupTable(upstreamIfindex, upstreamIface);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If v6only is null, we pass in null to setRaParams(), which handles
|
// If v6only is null, we pass in null to setRaParams(), which handles
|
||||||
|
|||||||
@@ -0,0 +1,280 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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 com.android.networkstack.tethering;
|
||||||
|
|
||||||
|
import static android.net.NetworkStats.DEFAULT_NETWORK_NO;
|
||||||
|
import static android.net.NetworkStats.METERED_NO;
|
||||||
|
import static android.net.NetworkStats.ROAMING_NO;
|
||||||
|
import static android.net.NetworkStats.SET_DEFAULT;
|
||||||
|
import static android.net.NetworkStats.TAG_NONE;
|
||||||
|
import static android.net.NetworkStats.UID_ALL;
|
||||||
|
import static android.net.NetworkStats.UID_TETHERING;
|
||||||
|
|
||||||
|
import android.app.usage.NetworkStatsManager;
|
||||||
|
import android.net.INetd;
|
||||||
|
import android.net.NetworkStats;
|
||||||
|
import android.net.NetworkStats.Entry;
|
||||||
|
import android.net.TetherStatsParcel;
|
||||||
|
import android.net.netstats.provider.NetworkStatsProvider;
|
||||||
|
import android.net.util.SharedLog;
|
||||||
|
import android.net.util.TetheringUtils.ForwardedStats;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
import android.os.ServiceSpecificException;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.util.SparseArray;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This coordinator is responsible for providing BPF offload relevant functionality.
|
||||||
|
* - Get tethering stats.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public class BpfCoordinator {
|
||||||
|
private static final String TAG = BpfCoordinator.class.getSimpleName();
|
||||||
|
// TODO: Make it customizable.
|
||||||
|
private static final int DEFAULT_PERFORM_POLL_INTERVAL_MS = 5000;
|
||||||
|
|
||||||
|
private enum StatsType {
|
||||||
|
STATS_PER_IFACE,
|
||||||
|
STATS_PER_UID,
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private final Handler mHandler;
|
||||||
|
@NonNull
|
||||||
|
private final INetd mNetd;
|
||||||
|
@NonNull
|
||||||
|
private final SharedLog mLog;
|
||||||
|
@NonNull
|
||||||
|
private final Dependencies mDeps;
|
||||||
|
@Nullable
|
||||||
|
private final BpfTetherStatsProvider mStatsProvider;
|
||||||
|
private boolean mStarted = false;
|
||||||
|
|
||||||
|
// Maps upstream interface index to offloaded traffic statistics.
|
||||||
|
// Always contains the latest total bytes/packets, since each upstream was started, received
|
||||||
|
// from the BPF maps for each interface.
|
||||||
|
private SparseArray<ForwardedStats> mStats = new SparseArray<>();
|
||||||
|
|
||||||
|
// Maps upstream interface index to interface names.
|
||||||
|
// Store all interface name since boot. Used for lookup what interface name it is from the
|
||||||
|
// tether stats got from netd because netd reports interface index to present an interface.
|
||||||
|
// TODO: Remove the unused interface name.
|
||||||
|
private SparseArray<String> mInterfaceNames = new SparseArray<>();
|
||||||
|
|
||||||
|
// Runnable that used by scheduling next polling of stats.
|
||||||
|
private final Runnable mScheduledPollingTask = () -> {
|
||||||
|
updateForwardedStatsFromNetd();
|
||||||
|
maybeSchedulePollingStats();
|
||||||
|
};
|
||||||
|
|
||||||
|
static class Dependencies {
|
||||||
|
int getPerformPollInterval() {
|
||||||
|
// TODO: Consider make this configurable.
|
||||||
|
return DEFAULT_PERFORM_POLL_INTERVAL_MS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BpfCoordinator(@NonNull Handler handler, @NonNull INetd netd,
|
||||||
|
@NonNull NetworkStatsManager nsm, @NonNull SharedLog log, @NonNull Dependencies deps) {
|
||||||
|
mHandler = handler;
|
||||||
|
mNetd = netd;
|
||||||
|
mLog = log.forSubComponent(TAG);
|
||||||
|
BpfTetherStatsProvider provider = new BpfTetherStatsProvider();
|
||||||
|
try {
|
||||||
|
nsm.registerNetworkStatsProvider(getClass().getSimpleName(), provider);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
// TODO: Perhaps not allow to use BPF offload because the reregistration failure
|
||||||
|
// implied that no data limit could be applies on a metered upstream if any.
|
||||||
|
Log.wtf(TAG, "Cannot register offload stats provider: " + e);
|
||||||
|
provider = null;
|
||||||
|
}
|
||||||
|
mStatsProvider = provider;
|
||||||
|
mDeps = deps;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start BPF tethering offload stats polling when the first upstream is started.
|
||||||
|
* Note that this can be only called on handler thread.
|
||||||
|
* TODO: Perhaps check BPF support before starting.
|
||||||
|
* TODO: Start the stats polling only if there is any client on the downstream.
|
||||||
|
*/
|
||||||
|
public void start() {
|
||||||
|
if (mStarted) return;
|
||||||
|
|
||||||
|
mStarted = true;
|
||||||
|
maybeSchedulePollingStats();
|
||||||
|
|
||||||
|
mLog.i("BPF tethering coordinator started");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop BPF tethering offload stats polling and cleanup upstream parameters.
|
||||||
|
* Note that this can be only called on handler thread.
|
||||||
|
*/
|
||||||
|
public void stop() {
|
||||||
|
if (!mStarted) return;
|
||||||
|
|
||||||
|
// Stop scheduled polling tasks and poll the latest stats from BPF maps.
|
||||||
|
if (mHandler.hasCallbacks(mScheduledPollingTask)) {
|
||||||
|
mHandler.removeCallbacks(mScheduledPollingTask);
|
||||||
|
}
|
||||||
|
updateForwardedStatsFromNetd();
|
||||||
|
|
||||||
|
mStarted = false;
|
||||||
|
|
||||||
|
mLog.i("BPF tethering coordinator stopped");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add upstream name to lookup table. The lookup table is used for tether stats interface name
|
||||||
|
* lookup because the netd only reports interface index in BPF tether stats but the service
|
||||||
|
* expects the interface name in NetworkStats object.
|
||||||
|
* Note that this can be only called on handler thread.
|
||||||
|
*/
|
||||||
|
public void addUpstreamNameToLookupTable(int upstreamIfindex, String upstreamIface) {
|
||||||
|
if (upstreamIfindex == 0) return;
|
||||||
|
|
||||||
|
// The same interface index to name mapping may be added by different IpServer objects or
|
||||||
|
// re-added by reconnection on the same upstream interface. Ignore the duplicate one.
|
||||||
|
final String iface = mInterfaceNames.get(upstreamIfindex);
|
||||||
|
if (iface == null) {
|
||||||
|
mInterfaceNames.put(upstreamIfindex, upstreamIface);
|
||||||
|
} else if (iface != upstreamIface) {
|
||||||
|
Log.wtf(TAG, "The upstream interface name " + upstreamIface
|
||||||
|
+ " is different from the existing interface name "
|
||||||
|
+ iface + " for index " + upstreamIfindex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A BPF tethering stats provider to provide network statistics to the system.
|
||||||
|
* Note that this class's data may only be accessed on the handler thread.
|
||||||
|
*/
|
||||||
|
private class BpfTetherStatsProvider extends NetworkStatsProvider {
|
||||||
|
// The offloaded traffic statistics per interface that has not been reported since the
|
||||||
|
// last call to pushTetherStats. Only the interfaces that were ever tethering upstreams
|
||||||
|
// and has pending tether stats delta are included in this NetworkStats object.
|
||||||
|
private NetworkStats mIfaceStats = new NetworkStats(0L, 0);
|
||||||
|
|
||||||
|
// The same stats as above, but counts network stats per uid.
|
||||||
|
private NetworkStats mUidStats = new NetworkStats(0L, 0);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRequestStatsUpdate(int token) {
|
||||||
|
mHandler.post(() -> pushTetherStats());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSetAlert(long quotaBytes) {
|
||||||
|
// no-op
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSetLimit(@NonNull String iface, long quotaBytes) {
|
||||||
|
// no-op
|
||||||
|
}
|
||||||
|
|
||||||
|
private void pushTetherStats() {
|
||||||
|
try {
|
||||||
|
// The token is not used for now. See b/153606961.
|
||||||
|
notifyStatsUpdated(0 /* token */, mIfaceStats, mUidStats);
|
||||||
|
|
||||||
|
// Clear the accumulated tether stats delta after reported. Note that create a new
|
||||||
|
// empty object because NetworkStats#clear is @hide.
|
||||||
|
mIfaceStats = new NetworkStats(0L, 0);
|
||||||
|
mUidStats = new NetworkStats(0L, 0);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
mLog.e("Cannot report network stats: ", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void accumulateDiff(@NonNull NetworkStats ifaceDiff,
|
||||||
|
@NonNull NetworkStats uidDiff) {
|
||||||
|
mIfaceStats = mIfaceStats.add(ifaceDiff);
|
||||||
|
mUidStats = mUidStats.add(uidDiff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private NetworkStats buildNetworkStats(@NonNull StatsType type, int ifIndex,
|
||||||
|
@NonNull ForwardedStats diff) {
|
||||||
|
NetworkStats stats = new NetworkStats(0L, 0);
|
||||||
|
final String iface = mInterfaceNames.get(ifIndex);
|
||||||
|
if (iface == null) {
|
||||||
|
// TODO: Use Log.wtf once the coordinator owns full control of tether stats from netd.
|
||||||
|
// For now, netd may add the empty stats for the upstream which is not monitored by
|
||||||
|
// the coordinator. Silently ignore it.
|
||||||
|
return stats;
|
||||||
|
}
|
||||||
|
final int uid = (type == StatsType.STATS_PER_UID) ? UID_TETHERING : UID_ALL;
|
||||||
|
// Note that the argument 'metered', 'roaming' and 'defaultNetwork' are not recorded for
|
||||||
|
// network stats snapshot. See NetworkStatsRecorder#recordSnapshotLocked.
|
||||||
|
return stats.addEntry(new Entry(iface, uid, SET_DEFAULT, TAG_NONE, METERED_NO,
|
||||||
|
ROAMING_NO, DEFAULT_NETWORK_NO, diff.rxBytes, diff.rxPackets,
|
||||||
|
diff.txBytes, diff.txPackets, 0L /* operations */));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateForwardedStatsFromNetd() {
|
||||||
|
final TetherStatsParcel[] tetherStatsList;
|
||||||
|
try {
|
||||||
|
// The reported tether stats are total data usage for all currently-active upstream
|
||||||
|
// interfaces since tethering start.
|
||||||
|
tetherStatsList = mNetd.tetherOffloadGetStats();
|
||||||
|
} catch (RemoteException | ServiceSpecificException e) {
|
||||||
|
mLog.e("Problem fetching tethering stats: ", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (TetherStatsParcel tetherStats : tetherStatsList) {
|
||||||
|
final Integer ifIndex = tetherStats.ifIndex;
|
||||||
|
final ForwardedStats curr = new ForwardedStats(tetherStats);
|
||||||
|
final ForwardedStats base = mStats.get(ifIndex);
|
||||||
|
final ForwardedStats diff = (base != null) ? curr.subtract(base) : curr;
|
||||||
|
|
||||||
|
// Update the local cache for counting tether stats delta.
|
||||||
|
mStats.put(ifIndex, curr);
|
||||||
|
|
||||||
|
// Update the accumulated tether stats delta to the stats provider for the service
|
||||||
|
// querying.
|
||||||
|
if (mStatsProvider != null) {
|
||||||
|
try {
|
||||||
|
mStatsProvider.accumulateDiff(
|
||||||
|
buildNetworkStats(StatsType.STATS_PER_IFACE, ifIndex, diff),
|
||||||
|
buildNetworkStats(StatsType.STATS_PER_UID, ifIndex, diff));
|
||||||
|
} catch (ArrayIndexOutOfBoundsException e) {
|
||||||
|
Log.wtf("Fail to update the accumulated stats delta for interface index "
|
||||||
|
+ ifIndex + " : ", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void maybeSchedulePollingStats() {
|
||||||
|
if (!mStarted) return;
|
||||||
|
|
||||||
|
if (mHandler.hasCallbacks(mScheduledPollingTask)) {
|
||||||
|
mHandler.removeCallbacks(mScheduledPollingTask);
|
||||||
|
}
|
||||||
|
|
||||||
|
mHandler.postDelayed(mScheduledPollingTask, mDeps.getPerformPollInterval());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -232,6 +232,7 @@ public class Tethering {
|
|||||||
private final TetheringThreadExecutor mExecutor;
|
private final TetheringThreadExecutor mExecutor;
|
||||||
private final TetheringNotificationUpdater mNotificationUpdater;
|
private final TetheringNotificationUpdater mNotificationUpdater;
|
||||||
private final UserManager mUserManager;
|
private final UserManager mUserManager;
|
||||||
|
private final BpfCoordinator mBpfCoordinator;
|
||||||
private final PrivateAddressCoordinator mPrivateAddressCoordinator;
|
private final PrivateAddressCoordinator mPrivateAddressCoordinator;
|
||||||
private int mActiveDataSubId = INVALID_SUBSCRIPTION_ID;
|
private int mActiveDataSubId = INVALID_SUBSCRIPTION_ID;
|
||||||
// All the usage of mTetheringEventCallback should run in the same thread.
|
// All the usage of mTetheringEventCallback should run in the same thread.
|
||||||
@@ -284,6 +285,8 @@ public class Tethering {
|
|||||||
mUpstreamNetworkMonitor = mDeps.getUpstreamNetworkMonitor(mContext, mTetherMasterSM, mLog,
|
mUpstreamNetworkMonitor = mDeps.getUpstreamNetworkMonitor(mContext, mTetherMasterSM, mLog,
|
||||||
TetherMasterSM.EVENT_UPSTREAM_CALLBACK);
|
TetherMasterSM.EVENT_UPSTREAM_CALLBACK);
|
||||||
mForwardedDownstreams = new LinkedHashSet<>();
|
mForwardedDownstreams = new LinkedHashSet<>();
|
||||||
|
mBpfCoordinator = mDeps.getBpfCoordinator(
|
||||||
|
mHandler, mNetd, mLog, new BpfCoordinator.Dependencies());
|
||||||
|
|
||||||
IntentFilter filter = new IntentFilter();
|
IntentFilter filter = new IntentFilter();
|
||||||
filter.addAction(ACTION_CARRIER_CONFIG_CHANGED);
|
filter.addAction(ACTION_CARRIER_CONFIG_CHANGED);
|
||||||
@@ -1704,6 +1707,9 @@ public class Tethering {
|
|||||||
chooseUpstreamType(true);
|
chooseUpstreamType(true);
|
||||||
mTryCell = false;
|
mTryCell = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Check the upstream interface if it is managed by BPF offload.
|
||||||
|
mBpfCoordinator.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1716,6 +1722,7 @@ public class Tethering {
|
|||||||
mTetherUpstream = null;
|
mTetherUpstream = null;
|
||||||
reportUpstreamChanged(null);
|
reportUpstreamChanged(null);
|
||||||
}
|
}
|
||||||
|
mBpfCoordinator.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean updateUpstreamWanted() {
|
private boolean updateUpstreamWanted() {
|
||||||
@@ -2341,7 +2348,7 @@ public class Tethering {
|
|||||||
|
|
||||||
mLog.log("adding TetheringInterfaceStateMachine for: " + iface);
|
mLog.log("adding TetheringInterfaceStateMachine for: " + iface);
|
||||||
final TetherState tetherState = new TetherState(
|
final TetherState tetherState = new TetherState(
|
||||||
new IpServer(iface, mLooper, interfaceType, mLog, mNetd,
|
new IpServer(iface, mLooper, interfaceType, mLog, mNetd, mBpfCoordinator,
|
||||||
makeControlCallback(), mConfig.enableLegacyDhcpServer,
|
makeControlCallback(), mConfig.enableLegacyDhcpServer,
|
||||||
mConfig.enableBpfOffload, mPrivateAddressCoordinator,
|
mConfig.enableBpfOffload, mPrivateAddressCoordinator,
|
||||||
mDeps.getIpServerDependencies()));
|
mDeps.getIpServerDependencies()));
|
||||||
|
|||||||
@@ -40,6 +40,17 @@ import java.util.ArrayList;
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public abstract class TetheringDependencies {
|
public abstract class TetheringDependencies {
|
||||||
|
/**
|
||||||
|
* Get a reference to the BpfCoordinator to be used by tethering.
|
||||||
|
*/
|
||||||
|
public @NonNull BpfCoordinator getBpfCoordinator(
|
||||||
|
@NonNull Handler handler, @NonNull INetd netd, @NonNull SharedLog log,
|
||||||
|
@NonNull BpfCoordinator.Dependencies deps) {
|
||||||
|
final NetworkStatsManager statsManager =
|
||||||
|
(NetworkStatsManager) getContext().getSystemService(Context.NETWORK_STATS_SERVICE);
|
||||||
|
return new BpfCoordinator(handler, netd, statsManager, log, deps);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a reference to the offload hardware interface to be used by tethering.
|
* Get a reference to the offload hardware interface to be used by tethering.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ import android.text.TextUtils;
|
|||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
import androidx.test.runner.AndroidJUnit4;
|
import androidx.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
|
import com.android.networkstack.tethering.BpfCoordinator;
|
||||||
import com.android.networkstack.tethering.PrivateAddressCoordinator;
|
import com.android.networkstack.tethering.PrivateAddressCoordinator;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -126,6 +127,7 @@ public class IpServerTest {
|
|||||||
private final IpPrefix mBluetoothPrefix = new IpPrefix("192.168.44.0/24");
|
private final IpPrefix mBluetoothPrefix = new IpPrefix("192.168.44.0/24");
|
||||||
|
|
||||||
@Mock private INetd mNetd;
|
@Mock private INetd mNetd;
|
||||||
|
@Mock private BpfCoordinator mBpfCoordinator;
|
||||||
@Mock private IpServer.Callback mCallback;
|
@Mock private IpServer.Callback mCallback;
|
||||||
@Mock private SharedLog mSharedLog;
|
@Mock private SharedLog mSharedLog;
|
||||||
@Mock private IDhcpServer mDhcpServer;
|
@Mock private IDhcpServer mDhcpServer;
|
||||||
@@ -179,7 +181,7 @@ public class IpServerTest {
|
|||||||
neighborCaptor.capture());
|
neighborCaptor.capture());
|
||||||
|
|
||||||
mIpServer = new IpServer(
|
mIpServer = new IpServer(
|
||||||
IFACE_NAME, mLooper.getLooper(), interfaceType, mSharedLog, mNetd,
|
IFACE_NAME, mLooper.getLooper(), interfaceType, mSharedLog, mNetd, mBpfCoordinator,
|
||||||
mCallback, usingLegacyDhcp, usingBpfOffload, mAddressCoordinator, mDependencies);
|
mCallback, usingLegacyDhcp, usingBpfOffload, mAddressCoordinator, mDependencies);
|
||||||
mIpServer.start();
|
mIpServer.start();
|
||||||
mNeighborEventConsumer = neighborCaptor.getValue();
|
mNeighborEventConsumer = neighborCaptor.getValue();
|
||||||
@@ -222,8 +224,8 @@ public class IpServerTest {
|
|||||||
when(mDependencies.getIpNeighborMonitor(any(), any(), any()))
|
when(mDependencies.getIpNeighborMonitor(any(), any(), any()))
|
||||||
.thenReturn(mIpNeighborMonitor);
|
.thenReturn(mIpNeighborMonitor);
|
||||||
mIpServer = new IpServer(IFACE_NAME, mLooper.getLooper(), TETHERING_BLUETOOTH, mSharedLog,
|
mIpServer = new IpServer(IFACE_NAME, mLooper.getLooper(), TETHERING_BLUETOOTH, mSharedLog,
|
||||||
mNetd, mCallback, false /* usingLegacyDhcp */, DEFAULT_USING_BPF_OFFLOAD,
|
mNetd, mBpfCoordinator, mCallback, false /* usingLegacyDhcp */,
|
||||||
mAddressCoordinator, mDependencies);
|
DEFAULT_USING_BPF_OFFLOAD, mAddressCoordinator, mDependencies);
|
||||||
mIpServer.start();
|
mIpServer.start();
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
verify(mCallback).updateInterfaceState(
|
verify(mCallback).updateInterfaceState(
|
||||||
|
|||||||
@@ -203,6 +203,7 @@ public class TetheringTest {
|
|||||||
@Mock private ConnectivityManager mCm;
|
@Mock private ConnectivityManager mCm;
|
||||||
@Mock private EthernetManager mEm;
|
@Mock private EthernetManager mEm;
|
||||||
@Mock private TetheringNotificationUpdater mNotificationUpdater;
|
@Mock private TetheringNotificationUpdater mNotificationUpdater;
|
||||||
|
@Mock private BpfCoordinator mBpfCoordinator;
|
||||||
|
|
||||||
private final MockIpServerDependencies mIpServerDependencies =
|
private final MockIpServerDependencies mIpServerDependencies =
|
||||||
spy(new MockIpServerDependencies());
|
spy(new MockIpServerDependencies());
|
||||||
@@ -336,6 +337,12 @@ public class TetheringTest {
|
|||||||
mIpv6CoordinatorNotifyList = null;
|
mIpv6CoordinatorNotifyList = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BpfCoordinator getBpfCoordinator(Handler handler, INetd netd,
|
||||||
|
SharedLog log, BpfCoordinator.Dependencies deps) {
|
||||||
|
return mBpfCoordinator;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OffloadHardwareInterface getOffloadHardwareInterface(Handler h, SharedLog log) {
|
public OffloadHardwareInterface getOffloadHardwareInterface(Handler h, SharedLog log) {
|
||||||
return mOffloadHardwareInterface;
|
return mOffloadHardwareInterface;
|
||||||
|
|||||||
Reference in New Issue
Block a user