Merge changes from topic "tethering_metrics"
* changes: Add tethering stats into statsd Injecting tethering stats into statsd
This commit is contained in:
@@ -33,6 +33,7 @@ java_defaults {
|
|||||||
":framework-connectivity-shared-srcs",
|
":framework-connectivity-shared-srcs",
|
||||||
":tethering-module-utils-srcs",
|
":tethering-module-utils-srcs",
|
||||||
":services-tethering-shared-srcs",
|
":services-tethering-shared-srcs",
|
||||||
|
":statslog-tethering-java-gen",
|
||||||
],
|
],
|
||||||
static_libs: [
|
static_libs: [
|
||||||
"androidx.annotation_annotation",
|
"androidx.annotation_annotation",
|
||||||
@@ -223,3 +224,11 @@ java_library_static {
|
|||||||
apex_available: ["com.android.tethering"],
|
apex_available: ["com.android.tethering"],
|
||||||
min_sdk_version: "30",
|
min_sdk_version: "30",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
genrule {
|
||||||
|
name: "statslog-tethering-java-gen",
|
||||||
|
tools: ["stats-log-api-gen"],
|
||||||
|
cmd: "$(location stats-log-api-gen) --java $(out) --module network_tethering" +
|
||||||
|
" --javaPackage com.android.networkstack.tethering.metrics --javaClass TetheringStatsLog",
|
||||||
|
out: ["com/android/networkstack/tethering/metrics/TetheringStatsLog.java"],
|
||||||
|
}
|
||||||
@@ -69,6 +69,7 @@ import com.android.networkstack.tethering.BpfCoordinator.ClientInfo;
|
|||||||
import com.android.networkstack.tethering.BpfCoordinator.Ipv6ForwardingRule;
|
import com.android.networkstack.tethering.BpfCoordinator.Ipv6ForwardingRule;
|
||||||
import com.android.networkstack.tethering.PrivateAddressCoordinator;
|
import com.android.networkstack.tethering.PrivateAddressCoordinator;
|
||||||
import com.android.networkstack.tethering.TetheringConfiguration;
|
import com.android.networkstack.tethering.TetheringConfiguration;
|
||||||
|
import com.android.networkstack.tethering.metrics.TetheringMetrics;
|
||||||
import com.android.networkstack.tethering.util.InterfaceSet;
|
import com.android.networkstack.tethering.util.InterfaceSet;
|
||||||
import com.android.networkstack.tethering.util.PrefixUtils;
|
import com.android.networkstack.tethering.util.PrefixUtils;
|
||||||
|
|
||||||
@@ -282,13 +283,15 @@ public class IpServer extends StateMachine {
|
|||||||
|
|
||||||
private LinkAddress mIpv4Address;
|
private LinkAddress mIpv4Address;
|
||||||
|
|
||||||
|
private final TetheringMetrics mTetheringMetrics;
|
||||||
|
|
||||||
// TODO: Add a dependency object to pass the data members or variables from the tethering
|
// TODO: Add a dependency object to pass the data members or variables from the tethering
|
||||||
// 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, @NonNull BpfCoordinator coordinator, Callback callback,
|
INetd netd, @NonNull BpfCoordinator coordinator, Callback callback,
|
||||||
TetheringConfiguration config, PrivateAddressCoordinator addressCoordinator,
|
TetheringConfiguration config, PrivateAddressCoordinator addressCoordinator,
|
||||||
Dependencies deps) {
|
TetheringMetrics tetheringMetrics, Dependencies deps) {
|
||||||
super(ifaceName, looper);
|
super(ifaceName, looper);
|
||||||
mLog = log.forSubComponent(ifaceName);
|
mLog = log.forSubComponent(ifaceName);
|
||||||
mNetd = netd;
|
mNetd = netd;
|
||||||
@@ -303,6 +306,7 @@ public class IpServer extends StateMachine {
|
|||||||
mP2pLeasesSubnetPrefixLength = config.getP2pLeasesSubnetPrefixLength();
|
mP2pLeasesSubnetPrefixLength = config.getP2pLeasesSubnetPrefixLength();
|
||||||
mPrivateAddressCoordinator = addressCoordinator;
|
mPrivateAddressCoordinator = addressCoordinator;
|
||||||
mDeps = deps;
|
mDeps = deps;
|
||||||
|
mTetheringMetrics = tetheringMetrics;
|
||||||
resetLinkProperties();
|
resetLinkProperties();
|
||||||
mLastError = TetheringManager.TETHER_ERROR_NO_ERROR;
|
mLastError = TetheringManager.TETHER_ERROR_NO_ERROR;
|
||||||
mServingMode = STATE_AVAILABLE;
|
mServingMode = STATE_AVAILABLE;
|
||||||
@@ -1201,6 +1205,9 @@ public class IpServer extends StateMachine {
|
|||||||
stopConntrackMonitoring();
|
stopConntrackMonitoring();
|
||||||
|
|
||||||
resetLinkProperties();
|
resetLinkProperties();
|
||||||
|
|
||||||
|
mTetheringMetrics.updateErrorCode(mInterfaceType, mLastError);
|
||||||
|
mTetheringMetrics.sendReport(mInterfaceType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -140,6 +140,7 @@ import com.android.networkstack.apishim.common.BluetoothPanShim;
|
|||||||
import com.android.networkstack.apishim.common.BluetoothPanShim.TetheredInterfaceCallbackShim;
|
import com.android.networkstack.apishim.common.BluetoothPanShim.TetheredInterfaceCallbackShim;
|
||||||
import com.android.networkstack.apishim.common.BluetoothPanShim.TetheredInterfaceRequestShim;
|
import com.android.networkstack.apishim.common.BluetoothPanShim.TetheredInterfaceRequestShim;
|
||||||
import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
|
import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
|
||||||
|
import com.android.networkstack.tethering.metrics.TetheringMetrics;
|
||||||
import com.android.networkstack.tethering.util.InterfaceSet;
|
import com.android.networkstack.tethering.util.InterfaceSet;
|
||||||
import com.android.networkstack.tethering.util.PrefixUtils;
|
import com.android.networkstack.tethering.util.PrefixUtils;
|
||||||
import com.android.networkstack.tethering.util.TetheringUtils;
|
import com.android.networkstack.tethering.util.TetheringUtils;
|
||||||
@@ -254,6 +255,7 @@ public class Tethering {
|
|||||||
private final UserManager mUserManager;
|
private final UserManager mUserManager;
|
||||||
private final BpfCoordinator mBpfCoordinator;
|
private final BpfCoordinator mBpfCoordinator;
|
||||||
private final PrivateAddressCoordinator mPrivateAddressCoordinator;
|
private final PrivateAddressCoordinator mPrivateAddressCoordinator;
|
||||||
|
private final TetheringMetrics mTetheringMetrics;
|
||||||
private int mActiveDataSubId = INVALID_SUBSCRIPTION_ID;
|
private int mActiveDataSubId = INVALID_SUBSCRIPTION_ID;
|
||||||
|
|
||||||
private volatile TetheringConfiguration mConfig;
|
private volatile TetheringConfiguration mConfig;
|
||||||
@@ -292,6 +294,7 @@ public class Tethering {
|
|||||||
mNetd = mDeps.getINetd(mContext);
|
mNetd = mDeps.getINetd(mContext);
|
||||||
mLooper = mDeps.getTetheringLooper();
|
mLooper = mDeps.getTetheringLooper();
|
||||||
mNotificationUpdater = mDeps.getNotificationUpdater(mContext, mLooper);
|
mNotificationUpdater = mDeps.getNotificationUpdater(mContext, mLooper);
|
||||||
|
mTetheringMetrics = mDeps.getTetheringMetrics();
|
||||||
|
|
||||||
// This is intended to ensrure that if something calls startTethering(bluetooth) just after
|
// This is intended to ensrure that if something calls startTethering(bluetooth) just after
|
||||||
// bluetooth is enabled. Before onServiceConnected is called, store the calls into this
|
// bluetooth is enabled. Before onServiceConnected is called, store the calls into this
|
||||||
@@ -616,7 +619,8 @@ public class Tethering {
|
|||||||
processInterfaceStateChange(iface, false /* enabled */);
|
processInterfaceStateChange(iface, false /* enabled */);
|
||||||
}
|
}
|
||||||
|
|
||||||
void startTethering(final TetheringRequestParcel request, final IIntResultListener listener) {
|
void startTethering(final TetheringRequestParcel request, final String callerPkg,
|
||||||
|
final IIntResultListener listener) {
|
||||||
mHandler.post(() -> {
|
mHandler.post(() -> {
|
||||||
final TetheringRequestParcel unfinishedRequest = mActiveTetheringRequests.get(
|
final TetheringRequestParcel unfinishedRequest = mActiveTetheringRequests.get(
|
||||||
request.tetheringType);
|
request.tetheringType);
|
||||||
@@ -636,6 +640,7 @@ public class Tethering {
|
|||||||
request.showProvisioningUi);
|
request.showProvisioningUi);
|
||||||
}
|
}
|
||||||
enableTetheringInternal(request.tetheringType, true /* enabled */, listener);
|
enableTetheringInternal(request.tetheringType, true /* enabled */, listener);
|
||||||
|
mTetheringMetrics.createBuilder(request.tetheringType, callerPkg);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -695,7 +700,11 @@ public class Tethering {
|
|||||||
|
|
||||||
// If changing tethering fail, remove corresponding request
|
// If changing tethering fail, remove corresponding request
|
||||||
// no matter who trigger the start/stop.
|
// no matter who trigger the start/stop.
|
||||||
if (result != TETHER_ERROR_NO_ERROR) mActiveTetheringRequests.remove(type);
|
if (result != TETHER_ERROR_NO_ERROR) {
|
||||||
|
mActiveTetheringRequests.remove(type);
|
||||||
|
mTetheringMetrics.updateErrorCode(type, result);
|
||||||
|
mTetheringMetrics.sendReport(type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int setWifiTethering(final boolean enable) {
|
private int setWifiTethering(final boolean enable) {
|
||||||
@@ -2749,7 +2758,7 @@ public class Tethering {
|
|||||||
final TetherState tetherState = new TetherState(
|
final TetherState tetherState = new TetherState(
|
||||||
new IpServer(iface, mLooper, interfaceType, mLog, mNetd, mBpfCoordinator,
|
new IpServer(iface, mLooper, interfaceType, mLog, mNetd, mBpfCoordinator,
|
||||||
makeControlCallback(), mConfig, mPrivateAddressCoordinator,
|
makeControlCallback(), mConfig, mPrivateAddressCoordinator,
|
||||||
mDeps.getIpServerDependencies()), isNcm);
|
mTetheringMetrics, mDeps.getIpServerDependencies()), isNcm);
|
||||||
mTetherStates.put(iface, tetherState);
|
mTetherStates.put(iface, tetherState);
|
||||||
tetherState.ipServer.start();
|
tetherState.ipServer.start();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import androidx.annotation.NonNull;
|
|||||||
import com.android.internal.util.StateMachine;
|
import com.android.internal.util.StateMachine;
|
||||||
import com.android.networkstack.apishim.BluetoothPanShimImpl;
|
import com.android.networkstack.apishim.BluetoothPanShimImpl;
|
||||||
import com.android.networkstack.apishim.common.BluetoothPanShim;
|
import com.android.networkstack.apishim.common.BluetoothPanShim;
|
||||||
|
import com.android.networkstack.tethering.metrics.TetheringMetrics;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
@@ -163,4 +164,11 @@ public abstract class TetheringDependencies {
|
|||||||
public BluetoothPanShim getBluetoothPanShim(BluetoothPan pan) {
|
public BluetoothPanShim getBluetoothPanShim(BluetoothPan pan) {
|
||||||
return BluetoothPanShimImpl.newInstance(pan);
|
return BluetoothPanShimImpl.newInstance(pan);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a reference to the TetheringMetrics to be used by tethering.
|
||||||
|
*/
|
||||||
|
public TetheringMetrics getTetheringMetrics() {
|
||||||
|
return new TetheringMetrics();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ public class TetheringService extends Service {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mTethering.startTethering(request, listener);
|
mTethering.startTethering(request, callerPkg, listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,195 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2022 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.metrics;
|
||||||
|
|
||||||
|
import static android.net.TetheringManager.TETHERING_BLUETOOTH;
|
||||||
|
import static android.net.TetheringManager.TETHERING_ETHERNET;
|
||||||
|
import static android.net.TetheringManager.TETHERING_NCM;
|
||||||
|
import static android.net.TetheringManager.TETHERING_USB;
|
||||||
|
import static android.net.TetheringManager.TETHERING_WIFI;
|
||||||
|
import static android.net.TetheringManager.TETHERING_WIFI_P2P;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_DHCPSERVER_ERROR;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_DISABLE_FORWARDING_ERROR;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_ENABLE_FORWARDING_ERROR;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_ENTITLEMENT_UNKNOWN;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_IFACE_CFG_ERROR;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_INTERNAL_ERROR;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_PROVISIONING_FAILED;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_SERVICE_UNAVAIL;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_TETHER_IFACE_ERROR;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_UNAVAIL_IFACE;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_IFACE;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_UNSUPPORTED;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_UNTETHER_IFACE_ERROR;
|
||||||
|
|
||||||
|
import android.stats.connectivity.DownstreamType;
|
||||||
|
import android.stats.connectivity.ErrorCode;
|
||||||
|
import android.stats.connectivity.UpstreamType;
|
||||||
|
import android.stats.connectivity.UserType;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.util.SparseArray;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collection of utilities for tethering metrics.
|
||||||
|
*
|
||||||
|
* To see if the logs are properly sent to statsd, execute following commands
|
||||||
|
*
|
||||||
|
* $ adb shell cmd stats print-logs
|
||||||
|
* $ adb logcat | grep statsd OR $ adb logcat -b stats
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public class TetheringMetrics {
|
||||||
|
private static final String TAG = TetheringMetrics.class.getSimpleName();
|
||||||
|
private static final boolean DBG = false;
|
||||||
|
private static final String SETTINGS_PKG_NAME = "com.android.settings";
|
||||||
|
private static final String SYSTEMUI_PKG_NAME = "com.android.systemui";
|
||||||
|
private static final String GMS_PKG_NAME = "com.google.android.gms";
|
||||||
|
private final SparseArray<NetworkTetheringReported.Builder> mBuilderMap = new SparseArray<>();
|
||||||
|
|
||||||
|
/** Update Tethering stats about caller's package name and downstream type. */
|
||||||
|
public void createBuilder(final int downstreamType, final String callerPkg) {
|
||||||
|
mBuilderMap.clear();
|
||||||
|
NetworkTetheringReported.Builder statsBuilder =
|
||||||
|
NetworkTetheringReported.newBuilder();
|
||||||
|
statsBuilder.setDownstreamType(downstreamTypeToEnum(downstreamType))
|
||||||
|
.setUserType(userTypeToEnum(callerPkg))
|
||||||
|
.setUpstreamType(UpstreamType.UT_UNKNOWN)
|
||||||
|
.setErrorCode(ErrorCode.EC_NO_ERROR)
|
||||||
|
.build();
|
||||||
|
mBuilderMap.put(downstreamType, statsBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Update error code of given downstreamType. */
|
||||||
|
public void updateErrorCode(final int downstreamType, final int errCode) {
|
||||||
|
NetworkTetheringReported.Builder statsBuilder = mBuilderMap.get(downstreamType);
|
||||||
|
if (statsBuilder == null) {
|
||||||
|
Log.e(TAG, "Given downstreamType does not exist, this is a bug!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
statsBuilder.setErrorCode(errorCodeToEnum(errCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Remove Tethering stats.
|
||||||
|
* If Tethering stats is ready to write then write it before removing.
|
||||||
|
*/
|
||||||
|
public void sendReport(final int downstreamType) {
|
||||||
|
final NetworkTetheringReported.Builder statsBuilder =
|
||||||
|
mBuilderMap.get(downstreamType);
|
||||||
|
if (statsBuilder == null) {
|
||||||
|
Log.e(TAG, "Given downstreamType does not exist, this is a bug!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
write(statsBuilder.build());
|
||||||
|
mBuilderMap.remove(downstreamType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Collect Tethering stats and write metrics data to statsd pipeline. */
|
||||||
|
@VisibleForTesting
|
||||||
|
public void write(@NonNull final NetworkTetheringReported reported) {
|
||||||
|
TetheringStatsLog.write(TetheringStatsLog.NETWORK_TETHERING_REPORTED,
|
||||||
|
reported.getErrorCode().getNumber(),
|
||||||
|
reported.getDownstreamType().getNumber(),
|
||||||
|
reported.getUpstreamType().getNumber(),
|
||||||
|
reported.getUserType().getNumber());
|
||||||
|
if (DBG) {
|
||||||
|
Log.d(TAG, "Write errorCode: " + reported.getErrorCode().getNumber()
|
||||||
|
+ ", downstreamType: " + reported.getDownstreamType().getNumber()
|
||||||
|
+ ", upstreamType: " + reported.getUpstreamType().getNumber()
|
||||||
|
+ ", userType: " + reported.getUserType().getNumber());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Map {@link TetheringType} to {@link DownstreamType} */
|
||||||
|
private DownstreamType downstreamTypeToEnum(final int ifaceType) {
|
||||||
|
switch(ifaceType) {
|
||||||
|
case TETHERING_WIFI:
|
||||||
|
return DownstreamType.DS_TETHERING_WIFI;
|
||||||
|
case TETHERING_WIFI_P2P:
|
||||||
|
return DownstreamType.DS_TETHERING_WIFI_P2P;
|
||||||
|
case TETHERING_USB:
|
||||||
|
return DownstreamType.DS_TETHERING_USB;
|
||||||
|
case TETHERING_BLUETOOTH:
|
||||||
|
return DownstreamType.DS_TETHERING_BLUETOOTH;
|
||||||
|
case TETHERING_NCM:
|
||||||
|
return DownstreamType.DS_TETHERING_NCM;
|
||||||
|
case TETHERING_ETHERNET:
|
||||||
|
return DownstreamType.DS_TETHERING_ETHERNET;
|
||||||
|
default:
|
||||||
|
return DownstreamType.DS_UNSPECIFIED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Map {@link StartTetheringError} to {@link ErrorCode} */
|
||||||
|
private ErrorCode errorCodeToEnum(final int lastError) {
|
||||||
|
switch(lastError) {
|
||||||
|
case TETHER_ERROR_NO_ERROR:
|
||||||
|
return ErrorCode.EC_NO_ERROR;
|
||||||
|
case TETHER_ERROR_UNKNOWN_IFACE:
|
||||||
|
return ErrorCode.EC_UNKNOWN_IFACE;
|
||||||
|
case TETHER_ERROR_SERVICE_UNAVAIL:
|
||||||
|
return ErrorCode.EC_SERVICE_UNAVAIL;
|
||||||
|
case TETHER_ERROR_UNSUPPORTED:
|
||||||
|
return ErrorCode.EC_UNSUPPORTED;
|
||||||
|
case TETHER_ERROR_UNAVAIL_IFACE:
|
||||||
|
return ErrorCode.EC_UNAVAIL_IFACE;
|
||||||
|
case TETHER_ERROR_INTERNAL_ERROR:
|
||||||
|
return ErrorCode.EC_INTERNAL_ERROR;
|
||||||
|
case TETHER_ERROR_TETHER_IFACE_ERROR:
|
||||||
|
return ErrorCode.EC_TETHER_IFACE_ERROR;
|
||||||
|
case TETHER_ERROR_UNTETHER_IFACE_ERROR:
|
||||||
|
return ErrorCode.EC_UNTETHER_IFACE_ERROR;
|
||||||
|
case TETHER_ERROR_ENABLE_FORWARDING_ERROR:
|
||||||
|
return ErrorCode.EC_ENABLE_FORWARDING_ERROR;
|
||||||
|
case TETHER_ERROR_DISABLE_FORWARDING_ERROR:
|
||||||
|
return ErrorCode.EC_DISABLE_FORWARDING_ERROR;
|
||||||
|
case TETHER_ERROR_IFACE_CFG_ERROR:
|
||||||
|
return ErrorCode.EC_IFACE_CFG_ERROR;
|
||||||
|
case TETHER_ERROR_PROVISIONING_FAILED:
|
||||||
|
return ErrorCode.EC_PROVISIONING_FAILED;
|
||||||
|
case TETHER_ERROR_DHCPSERVER_ERROR:
|
||||||
|
return ErrorCode.EC_DHCPSERVER_ERROR;
|
||||||
|
case TETHER_ERROR_ENTITLEMENT_UNKNOWN:
|
||||||
|
return ErrorCode.EC_ENTITLEMENT_UNKNOWN;
|
||||||
|
case TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION:
|
||||||
|
return ErrorCode.EC_NO_CHANGE_TETHERING_PERMISSION;
|
||||||
|
case TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION:
|
||||||
|
return ErrorCode.EC_NO_ACCESS_TETHERING_PERMISSION;
|
||||||
|
default:
|
||||||
|
return ErrorCode.EC_UNKNOWN_TYPE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Map callerPkg to {@link UserType} */
|
||||||
|
private UserType userTypeToEnum(final String callerPkg) {
|
||||||
|
if (callerPkg.equals(SETTINGS_PKG_NAME)) {
|
||||||
|
return UserType.USER_SETTINGS;
|
||||||
|
} else if (callerPkg.equals(SYSTEMUI_PKG_NAME)) {
|
||||||
|
return UserType.USER_SYSTEMUI;
|
||||||
|
} else if (callerPkg.equals(GMS_PKG_NAME)) {
|
||||||
|
return UserType.USER_GMS;
|
||||||
|
} else {
|
||||||
|
return UserType.USER_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -116,6 +116,7 @@ import com.android.networkstack.tethering.TetherLimitKey;
|
|||||||
import com.android.networkstack.tethering.TetherLimitValue;
|
import com.android.networkstack.tethering.TetherLimitValue;
|
||||||
import com.android.networkstack.tethering.TetherUpstream6Key;
|
import com.android.networkstack.tethering.TetherUpstream6Key;
|
||||||
import com.android.networkstack.tethering.TetheringConfiguration;
|
import com.android.networkstack.tethering.TetheringConfiguration;
|
||||||
|
import com.android.networkstack.tethering.metrics.TetheringMetrics;
|
||||||
import com.android.networkstack.tethering.util.InterfaceSet;
|
import com.android.networkstack.tethering.util.InterfaceSet;
|
||||||
import com.android.networkstack.tethering.util.PrefixUtils;
|
import com.android.networkstack.tethering.util.PrefixUtils;
|
||||||
import com.android.testutils.DevSdkIgnoreRule;
|
import com.android.testutils.DevSdkIgnoreRule;
|
||||||
@@ -186,6 +187,7 @@ public class IpServerTest {
|
|||||||
@Mock private NetworkStatsManager mStatsManager;
|
@Mock private NetworkStatsManager mStatsManager;
|
||||||
@Mock private TetheringConfiguration mTetherConfig;
|
@Mock private TetheringConfiguration mTetherConfig;
|
||||||
@Mock private ConntrackMonitor mConntrackMonitor;
|
@Mock private ConntrackMonitor mConntrackMonitor;
|
||||||
|
@Mock private TetheringMetrics mTetheringMetrics;
|
||||||
@Mock private BpfMap<Tether4Key, Tether4Value> mBpfDownstream4Map;
|
@Mock private BpfMap<Tether4Key, Tether4Value> mBpfDownstream4Map;
|
||||||
@Mock private BpfMap<Tether4Key, Tether4Value> mBpfUpstream4Map;
|
@Mock private BpfMap<Tether4Key, Tether4Value> mBpfUpstream4Map;
|
||||||
@Mock private BpfMap<TetherDownstream6Key, Tether6Value> mBpfDownstream6Map;
|
@Mock private BpfMap<TetherDownstream6Key, Tether6Value> mBpfDownstream6Map;
|
||||||
@@ -235,7 +237,7 @@ public class IpServerTest {
|
|||||||
when(mTetherConfig.getP2pLeasesSubnetPrefixLength()).thenReturn(P2P_SUBNET_PREFIX_LENGTH);
|
when(mTetherConfig.getP2pLeasesSubnetPrefixLength()).thenReturn(P2P_SUBNET_PREFIX_LENGTH);
|
||||||
mIpServer = new IpServer(
|
mIpServer = new IpServer(
|
||||||
IFACE_NAME, mLooper.getLooper(), interfaceType, mSharedLog, mNetd, mBpfCoordinator,
|
IFACE_NAME, mLooper.getLooper(), interfaceType, mSharedLog, mNetd, mBpfCoordinator,
|
||||||
mCallback, mTetherConfig, mAddressCoordinator, mDependencies);
|
mCallback, mTetherConfig, mAddressCoordinator, mTetheringMetrics, mDependencies);
|
||||||
mIpServer.start();
|
mIpServer.start();
|
||||||
mNeighborEventConsumer = neighborCaptor.getValue();
|
mNeighborEventConsumer = neighborCaptor.getValue();
|
||||||
|
|
||||||
@@ -367,7 +369,7 @@ public class IpServerTest {
|
|||||||
.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, mBpfCoordinator, mCallback, mTetherConfig, mAddressCoordinator,
|
mNetd, mBpfCoordinator, mCallback, mTetherConfig, mAddressCoordinator,
|
||||||
mDependencies);
|
mTetheringMetrics, mDependencies);
|
||||||
mIpServer.start();
|
mIpServer.start();
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
verify(mCallback).updateInterfaceState(
|
verify(mCallback).updateInterfaceState(
|
||||||
@@ -451,6 +453,9 @@ public class IpServerTest {
|
|||||||
mIpServer, STATE_AVAILABLE, TETHER_ERROR_NO_ERROR);
|
mIpServer, STATE_AVAILABLE, TETHER_ERROR_NO_ERROR);
|
||||||
inOrder.verify(mCallback).updateLinkProperties(
|
inOrder.verify(mCallback).updateLinkProperties(
|
||||||
eq(mIpServer), any(LinkProperties.class));
|
eq(mIpServer), any(LinkProperties.class));
|
||||||
|
verify(mTetheringMetrics).updateErrorCode(eq(TETHERING_BLUETOOTH),
|
||||||
|
eq(TETHER_ERROR_NO_ERROR));
|
||||||
|
verify(mTetheringMetrics).sendReport(eq(TETHERING_BLUETOOTH));
|
||||||
verifyNoMoreInteractions(mNetd, mCallback, mAddressCoordinator);
|
verifyNoMoreInteractions(mNetd, mCallback, mAddressCoordinator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -658,6 +663,9 @@ public class IpServerTest {
|
|||||||
usbTeardownOrder.verify(mCallback).updateLinkProperties(
|
usbTeardownOrder.verify(mCallback).updateLinkProperties(
|
||||||
eq(mIpServer), mLinkPropertiesCaptor.capture());
|
eq(mIpServer), mLinkPropertiesCaptor.capture());
|
||||||
assertNoAddressesNorRoutes(mLinkPropertiesCaptor.getValue());
|
assertNoAddressesNorRoutes(mLinkPropertiesCaptor.getValue());
|
||||||
|
verify(mTetheringMetrics).updateErrorCode(eq(TETHERING_USB),
|
||||||
|
eq(TETHER_ERROR_TETHER_IFACE_ERROR));
|
||||||
|
verify(mTetheringMetrics).sendReport(eq(TETHERING_USB));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -676,6 +684,9 @@ public class IpServerTest {
|
|||||||
usbTeardownOrder.verify(mCallback).updateLinkProperties(
|
usbTeardownOrder.verify(mCallback).updateLinkProperties(
|
||||||
eq(mIpServer), mLinkPropertiesCaptor.capture());
|
eq(mIpServer), mLinkPropertiesCaptor.capture());
|
||||||
assertNoAddressesNorRoutes(mLinkPropertiesCaptor.getValue());
|
assertNoAddressesNorRoutes(mLinkPropertiesCaptor.getValue());
|
||||||
|
verify(mTetheringMetrics).updateErrorCode(eq(TETHERING_USB),
|
||||||
|
eq(TETHER_ERROR_ENABLE_FORWARDING_ERROR));
|
||||||
|
verify(mTetheringMetrics).sendReport(eq(TETHERING_USB));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -275,7 +275,7 @@ public final class TetheringServiceTest {
|
|||||||
mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
||||||
result);
|
result);
|
||||||
verify(mTethering).isTetheringSupported();
|
verify(mTethering).isTetheringSupported();
|
||||||
verify(mTethering).startTethering(eq(request), eq(result));
|
verify(mTethering).startTethering(eq(request), eq(TEST_CALLER_PKG), eq(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ import static android.net.TetheringManager.TETHERING_USB;
|
|||||||
import static android.net.TetheringManager.TETHERING_WIFI;
|
import static android.net.TetheringManager.TETHERING_WIFI;
|
||||||
import static android.net.TetheringManager.TETHERING_WIFI_P2P;
|
import static android.net.TetheringManager.TETHERING_WIFI_P2P;
|
||||||
import static android.net.TetheringManager.TETHER_ERROR_IFACE_CFG_ERROR;
|
import static android.net.TetheringManager.TETHER_ERROR_IFACE_CFG_ERROR;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_INTERNAL_ERROR;
|
||||||
import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
|
import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
|
||||||
import static android.net.TetheringManager.TETHER_ERROR_SERVICE_UNAVAIL;
|
import static android.net.TetheringManager.TETHER_ERROR_SERVICE_UNAVAIL;
|
||||||
import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_IFACE;
|
import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_IFACE;
|
||||||
@@ -192,6 +193,7 @@ import com.android.networkstack.apishim.common.BluetoothPanShim.TetheredInterfac
|
|||||||
import com.android.networkstack.apishim.common.BluetoothPanShim.TetheredInterfaceRequestShim;
|
import com.android.networkstack.apishim.common.BluetoothPanShim.TetheredInterfaceRequestShim;
|
||||||
import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
|
import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
|
||||||
import com.android.networkstack.tethering.TestConnectivityManager.TestNetworkAgent;
|
import com.android.networkstack.tethering.TestConnectivityManager.TestNetworkAgent;
|
||||||
|
import com.android.networkstack.tethering.metrics.TetheringMetrics;
|
||||||
import com.android.testutils.MiscAsserts;
|
import com.android.testutils.MiscAsserts;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
@@ -239,6 +241,7 @@ public class TetheringTest {
|
|||||||
private static final String TEST_WIFI_REGEX = "test_wlan\\d";
|
private static final String TEST_WIFI_REGEX = "test_wlan\\d";
|
||||||
private static final String TEST_P2P_REGEX = "test_p2p-p2p\\d-.*";
|
private static final String TEST_P2P_REGEX = "test_p2p-p2p\\d-.*";
|
||||||
private static final String TEST_BT_REGEX = "test_pan\\d";
|
private static final String TEST_BT_REGEX = "test_pan\\d";
|
||||||
|
private static final String TEST_CALLER_PKG = "com.test.tethering";
|
||||||
|
|
||||||
private static final int CELLULAR_NETID = 100;
|
private static final int CELLULAR_NETID = 100;
|
||||||
private static final int WIFI_NETID = 101;
|
private static final int WIFI_NETID = 101;
|
||||||
@@ -273,6 +276,7 @@ public class TetheringTest {
|
|||||||
@Mock private BluetoothPan mBluetoothPan;
|
@Mock private BluetoothPan mBluetoothPan;
|
||||||
@Mock private BluetoothPanShim mBluetoothPanShim;
|
@Mock private BluetoothPanShim mBluetoothPanShim;
|
||||||
@Mock private TetheredInterfaceRequestShim mTetheredInterfaceRequestShim;
|
@Mock private TetheredInterfaceRequestShim mTetheredInterfaceRequestShim;
|
||||||
|
@Mock private TetheringMetrics mTetheringMetrics;
|
||||||
|
|
||||||
private final MockIpServerDependencies mIpServerDependencies =
|
private final MockIpServerDependencies mIpServerDependencies =
|
||||||
spy(new MockIpServerDependencies());
|
spy(new MockIpServerDependencies());
|
||||||
@@ -496,6 +500,11 @@ public class TetheringTest {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TetheringMetrics getTetheringMetrics() {
|
||||||
|
return mTetheringMetrics;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PrivateAddressCoordinator getPrivateAddressCoordinator(Context ctx,
|
public PrivateAddressCoordinator getPrivateAddressCoordinator(Context ctx,
|
||||||
TetheringConfiguration cfg) {
|
TetheringConfiguration cfg) {
|
||||||
@@ -855,7 +864,8 @@ public class TetheringTest {
|
|||||||
|
|
||||||
private void prepareNcmTethering() {
|
private void prepareNcmTethering() {
|
||||||
// Emulate startTethering(TETHERING_NCM) called
|
// Emulate startTethering(TETHERING_NCM) called
|
||||||
mTethering.startTethering(createTetheringRequestParcel(TETHERING_NCM), null);
|
mTethering.startTethering(createTetheringRequestParcel(TETHERING_NCM), TEST_CALLER_PKG,
|
||||||
|
null);
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NCM);
|
verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NCM);
|
||||||
}
|
}
|
||||||
@@ -863,7 +873,7 @@ public class TetheringTest {
|
|||||||
private void prepareUsbTethering() {
|
private void prepareUsbTethering() {
|
||||||
// Emulate pressing the USB tethering button in Settings UI.
|
// Emulate pressing the USB tethering button in Settings UI.
|
||||||
final TetheringRequestParcel request = createTetheringRequestParcel(TETHERING_USB);
|
final TetheringRequestParcel request = createTetheringRequestParcel(TETHERING_USB);
|
||||||
mTethering.startTethering(request, null);
|
mTethering.startTethering(request, TEST_CALLER_PKG, null);
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
|
|
||||||
assertEquals(1, mTethering.getActiveTetheringRequests().size());
|
assertEquals(1, mTethering.getActiveTetheringRequests().size());
|
||||||
@@ -1433,7 +1443,8 @@ public class TetheringTest {
|
|||||||
when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true);
|
when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true);
|
||||||
|
|
||||||
// Emulate pressing the WiFi tethering button.
|
// Emulate pressing the WiFi tethering button.
|
||||||
mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null);
|
mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), TEST_CALLER_PKG,
|
||||||
|
null);
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
verify(mWifiManager, times(1)).startTetheredHotspot(null);
|
verify(mWifiManager, times(1)).startTetheredHotspot(null);
|
||||||
verifyNoMoreInteractions(mWifiManager);
|
verifyNoMoreInteractions(mWifiManager);
|
||||||
@@ -1460,7 +1471,8 @@ public class TetheringTest {
|
|||||||
when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true);
|
when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true);
|
||||||
|
|
||||||
// Emulate pressing the WiFi tethering button.
|
// Emulate pressing the WiFi tethering button.
|
||||||
mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null);
|
mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), TEST_CALLER_PKG,
|
||||||
|
null);
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
verify(mWifiManager, times(1)).startTetheredHotspot(null);
|
verify(mWifiManager, times(1)).startTetheredHotspot(null);
|
||||||
verifyNoMoreInteractions(mWifiManager);
|
verifyNoMoreInteractions(mWifiManager);
|
||||||
@@ -1536,11 +1548,13 @@ public class TetheringTest {
|
|||||||
doThrow(new RemoteException()).when(mNetd).ipfwdEnableForwarding(TETHERING_NAME);
|
doThrow(new RemoteException()).when(mNetd).ipfwdEnableForwarding(TETHERING_NAME);
|
||||||
|
|
||||||
// Emulate pressing the WiFi tethering button.
|
// Emulate pressing the WiFi tethering button.
|
||||||
mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null);
|
mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), TEST_CALLER_PKG,
|
||||||
|
null);
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
verify(mWifiManager, times(1)).startTetheredHotspot(null);
|
verify(mWifiManager, times(1)).startTetheredHotspot(null);
|
||||||
verifyNoMoreInteractions(mWifiManager);
|
verifyNoMoreInteractions(mWifiManager);
|
||||||
verifyNoMoreInteractions(mNetd);
|
verifyNoMoreInteractions(mNetd);
|
||||||
|
verify(mTetheringMetrics).createBuilder(eq(TETHERING_WIFI), anyString());
|
||||||
|
|
||||||
// Emulate externally-visible WifiManager effects, causing the
|
// Emulate externally-visible WifiManager effects, causing the
|
||||||
// per-interface state machine to start up, and telling us that
|
// per-interface state machine to start up, and telling us that
|
||||||
@@ -1579,6 +1593,10 @@ public class TetheringTest {
|
|||||||
verify(mWifiManager).updateInterfaceIpState(
|
verify(mWifiManager).updateInterfaceIpState(
|
||||||
TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR);
|
TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR);
|
||||||
|
|
||||||
|
verify(mTetheringMetrics, times(2)).updateErrorCode(eq(TETHERING_WIFI),
|
||||||
|
eq(TETHER_ERROR_INTERNAL_ERROR));
|
||||||
|
verify(mTetheringMetrics, times(2)).sendReport(eq(TETHERING_WIFI));
|
||||||
|
|
||||||
verifyNoMoreInteractions(mWifiManager);
|
verifyNoMoreInteractions(mWifiManager);
|
||||||
verifyNoMoreInteractions(mNetd);
|
verifyNoMoreInteractions(mNetd);
|
||||||
}
|
}
|
||||||
@@ -1881,7 +1899,8 @@ public class TetheringTest {
|
|||||||
tetherState = callback.pollTetherStatesChanged();
|
tetherState = callback.pollTetherStatesChanged();
|
||||||
assertArrayEquals(tetherState.availableList, new TetheringInterface[] {wifiIface});
|
assertArrayEquals(tetherState.availableList, new TetheringInterface[] {wifiIface});
|
||||||
|
|
||||||
mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null);
|
mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), TEST_CALLER_PKG,
|
||||||
|
null);
|
||||||
sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
|
sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
|
||||||
tetherState = callback.pollTetherStatesChanged();
|
tetherState = callback.pollTetherStatesChanged();
|
||||||
assertArrayEquals(tetherState.tetheredList, new TetheringInterface[] {wifiIface});
|
assertArrayEquals(tetherState.tetheredList, new TetheringInterface[] {wifiIface});
|
||||||
@@ -1978,10 +1997,12 @@ public class TetheringTest {
|
|||||||
public void testNoDuplicatedEthernetRequest() throws Exception {
|
public void testNoDuplicatedEthernetRequest() throws Exception {
|
||||||
final TetheredInterfaceRequest mockRequest = mock(TetheredInterfaceRequest.class);
|
final TetheredInterfaceRequest mockRequest = mock(TetheredInterfaceRequest.class);
|
||||||
when(mEm.requestTetheredInterface(any(), any())).thenReturn(mockRequest);
|
when(mEm.requestTetheredInterface(any(), any())).thenReturn(mockRequest);
|
||||||
mTethering.startTethering(createTetheringRequestParcel(TETHERING_ETHERNET), null);
|
mTethering.startTethering(createTetheringRequestParcel(TETHERING_ETHERNET), TEST_CALLER_PKG,
|
||||||
|
null);
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
verify(mEm, times(1)).requestTetheredInterface(any(), any());
|
verify(mEm, times(1)).requestTetheredInterface(any(), any());
|
||||||
mTethering.startTethering(createTetheringRequestParcel(TETHERING_ETHERNET), null);
|
mTethering.startTethering(createTetheringRequestParcel(TETHERING_ETHERNET), TEST_CALLER_PKG,
|
||||||
|
null);
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
verifyNoMoreInteractions(mEm);
|
verifyNoMoreInteractions(mEm);
|
||||||
mTethering.stopTethering(TETHERING_ETHERNET);
|
mTethering.stopTethering(TETHERING_ETHERNET);
|
||||||
@@ -2185,14 +2206,16 @@ public class TetheringTest {
|
|||||||
final ResultListener thirdResult = new ResultListener(TETHER_ERROR_NO_ERROR);
|
final ResultListener thirdResult = new ResultListener(TETHER_ERROR_NO_ERROR);
|
||||||
|
|
||||||
// Enable USB tethering and check that Tethering starts USB.
|
// Enable USB tethering and check that Tethering starts USB.
|
||||||
mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB), firstResult);
|
mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB), TEST_CALLER_PKG,
|
||||||
|
firstResult);
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
firstResult.assertHasResult();
|
firstResult.assertHasResult();
|
||||||
verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
|
verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
|
||||||
verifyNoMoreInteractions(mUsbManager);
|
verifyNoMoreInteractions(mUsbManager);
|
||||||
|
|
||||||
// Enable USB tethering again with the same request and expect no change to USB.
|
// Enable USB tethering again with the same request and expect no change to USB.
|
||||||
mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB), secondResult);
|
mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB), TEST_CALLER_PKG,
|
||||||
|
secondResult);
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
secondResult.assertHasResult();
|
secondResult.assertHasResult();
|
||||||
verify(mUsbManager, never()).setCurrentFunctions(UsbManager.FUNCTION_NONE);
|
verify(mUsbManager, never()).setCurrentFunctions(UsbManager.FUNCTION_NONE);
|
||||||
@@ -2201,7 +2224,8 @@ public class TetheringTest {
|
|||||||
// Enable USB tethering with a different request and expect that USB is stopped and
|
// Enable USB tethering with a different request and expect that USB is stopped and
|
||||||
// started.
|
// started.
|
||||||
mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB,
|
mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB,
|
||||||
serverLinkAddr, clientLinkAddr, false, CONNECTIVITY_SCOPE_GLOBAL), thirdResult);
|
serverLinkAddr, clientLinkAddr, false, CONNECTIVITY_SCOPE_GLOBAL),
|
||||||
|
TEST_CALLER_PKG, thirdResult);
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
thirdResult.assertHasResult();
|
thirdResult.assertHasResult();
|
||||||
verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NONE);
|
verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NONE);
|
||||||
@@ -2230,7 +2254,8 @@ public class TetheringTest {
|
|||||||
final ArgumentCaptor<DhcpServingParamsParcel> dhcpParamsCaptor =
|
final ArgumentCaptor<DhcpServingParamsParcel> dhcpParamsCaptor =
|
||||||
ArgumentCaptor.forClass(DhcpServingParamsParcel.class);
|
ArgumentCaptor.forClass(DhcpServingParamsParcel.class);
|
||||||
mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB,
|
mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB,
|
||||||
serverLinkAddr, clientLinkAddr, false, CONNECTIVITY_SCOPE_GLOBAL), null);
|
serverLinkAddr, clientLinkAddr, false, CONNECTIVITY_SCOPE_GLOBAL),
|
||||||
|
TEST_CALLER_PKG, null);
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NCM);
|
verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NCM);
|
||||||
mTethering.interfaceStatusChanged(TEST_NCM_IFNAME, true);
|
mTethering.interfaceStatusChanged(TEST_NCM_IFNAME, true);
|
||||||
@@ -2298,7 +2323,7 @@ public class TetheringTest {
|
|||||||
final TetheringRequestParcel wifiNotExemptRequest =
|
final TetheringRequestParcel wifiNotExemptRequest =
|
||||||
createTetheringRequestParcel(TETHERING_WIFI, null, null, false,
|
createTetheringRequestParcel(TETHERING_WIFI, null, null, false,
|
||||||
CONNECTIVITY_SCOPE_GLOBAL);
|
CONNECTIVITY_SCOPE_GLOBAL);
|
||||||
mTethering.startTethering(wifiNotExemptRequest, null);
|
mTethering.startTethering(wifiNotExemptRequest, TEST_CALLER_PKG, null);
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
verify(mEntitleMgr).startProvisioningIfNeeded(TETHERING_WIFI, false);
|
verify(mEntitleMgr).startProvisioningIfNeeded(TETHERING_WIFI, false);
|
||||||
verify(mEntitleMgr, never()).setExemptedDownstreamType(TETHERING_WIFI);
|
verify(mEntitleMgr, never()).setExemptedDownstreamType(TETHERING_WIFI);
|
||||||
@@ -2312,7 +2337,7 @@ public class TetheringTest {
|
|||||||
final TetheringRequestParcel wifiExemptRequest =
|
final TetheringRequestParcel wifiExemptRequest =
|
||||||
createTetheringRequestParcel(TETHERING_WIFI, null, null, true,
|
createTetheringRequestParcel(TETHERING_WIFI, null, null, true,
|
||||||
CONNECTIVITY_SCOPE_GLOBAL);
|
CONNECTIVITY_SCOPE_GLOBAL);
|
||||||
mTethering.startTethering(wifiExemptRequest, null);
|
mTethering.startTethering(wifiExemptRequest, TEST_CALLER_PKG, null);
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
verify(mEntitleMgr, never()).startProvisioningIfNeeded(TETHERING_WIFI, false);
|
verify(mEntitleMgr, never()).startProvisioningIfNeeded(TETHERING_WIFI, false);
|
||||||
verify(mEntitleMgr).setExemptedDownstreamType(TETHERING_WIFI);
|
verify(mEntitleMgr).setExemptedDownstreamType(TETHERING_WIFI);
|
||||||
@@ -2325,14 +2350,14 @@ public class TetheringTest {
|
|||||||
// If one app enables tethering without provisioning check first, then another app enables
|
// If one app enables tethering without provisioning check first, then another app enables
|
||||||
// tethering of the same type but does not disable the provisioning check.
|
// tethering of the same type but does not disable the provisioning check.
|
||||||
setupForRequiredProvisioning();
|
setupForRequiredProvisioning();
|
||||||
mTethering.startTethering(wifiExemptRequest, null);
|
mTethering.startTethering(wifiExemptRequest, TEST_CALLER_PKG, null);
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
verify(mEntitleMgr, never()).startProvisioningIfNeeded(TETHERING_WIFI, false);
|
verify(mEntitleMgr, never()).startProvisioningIfNeeded(TETHERING_WIFI, false);
|
||||||
verify(mEntitleMgr).setExemptedDownstreamType(TETHERING_WIFI);
|
verify(mEntitleMgr).setExemptedDownstreamType(TETHERING_WIFI);
|
||||||
assertTrue(mEntitleMgr.isCellularUpstreamPermitted());
|
assertTrue(mEntitleMgr.isCellularUpstreamPermitted());
|
||||||
reset(mEntitleMgr);
|
reset(mEntitleMgr);
|
||||||
setupForRequiredProvisioning();
|
setupForRequiredProvisioning();
|
||||||
mTethering.startTethering(wifiNotExemptRequest, null);
|
mTethering.startTethering(wifiNotExemptRequest, TEST_CALLER_PKG, null);
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
verify(mEntitleMgr).startProvisioningIfNeeded(TETHERING_WIFI, false);
|
verify(mEntitleMgr).startProvisioningIfNeeded(TETHERING_WIFI, false);
|
||||||
verify(mEntitleMgr, never()).setExemptedDownstreamType(TETHERING_WIFI);
|
verify(mEntitleMgr, never()).setExemptedDownstreamType(TETHERING_WIFI);
|
||||||
@@ -2422,7 +2447,8 @@ public class TetheringTest {
|
|||||||
when(mEm.requestTetheredInterface(any(), any())).thenReturn(mockRequest);
|
when(mEm.requestTetheredInterface(any(), any())).thenReturn(mockRequest);
|
||||||
final ArgumentCaptor<TetheredInterfaceCallback> callbackCaptor =
|
final ArgumentCaptor<TetheredInterfaceCallback> callbackCaptor =
|
||||||
ArgumentCaptor.forClass(TetheredInterfaceCallback.class);
|
ArgumentCaptor.forClass(TetheredInterfaceCallback.class);
|
||||||
mTethering.startTethering(createTetheringRequestParcel(TETHERING_ETHERNET), null);
|
mTethering.startTethering(createTetheringRequestParcel(TETHERING_ETHERNET),
|
||||||
|
TEST_CALLER_PKG, null);
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
verify(mEm).requestTetheredInterface(any(), callbackCaptor.capture());
|
verify(mEm).requestTetheredInterface(any(), callbackCaptor.capture());
|
||||||
TetheredInterfaceCallback ethCallback = callbackCaptor.getValue();
|
TetheredInterfaceCallback ethCallback = callbackCaptor.getValue();
|
||||||
@@ -2597,7 +2623,8 @@ public class TetheringTest {
|
|||||||
|
|
||||||
final ResultListener result = new ResultListener(TETHER_ERROR_NO_ERROR);
|
final ResultListener result = new ResultListener(TETHER_ERROR_NO_ERROR);
|
||||||
mockBluetoothSettings(true /* bluetoothOn */, true /* tetheringOn */);
|
mockBluetoothSettings(true /* bluetoothOn */, true /* tetheringOn */);
|
||||||
mTethering.startTethering(createTetheringRequestParcel(TETHERING_BLUETOOTH), result);
|
mTethering.startTethering(createTetheringRequestParcel(TETHERING_BLUETOOTH),
|
||||||
|
TEST_CALLER_PKG, result);
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
verifySetBluetoothTethering(true /* enable */, true /* bindToPanService */);
|
verifySetBluetoothTethering(true /* enable */, true /* bindToPanService */);
|
||||||
result.assertHasResult();
|
result.assertHasResult();
|
||||||
@@ -2632,7 +2659,8 @@ public class TetheringTest {
|
|||||||
|
|
||||||
final ResultListener result = new ResultListener(TETHER_ERROR_NO_ERROR);
|
final ResultListener result = new ResultListener(TETHER_ERROR_NO_ERROR);
|
||||||
mockBluetoothSettings(true /* bluetoothOn */, true /* tetheringOn */);
|
mockBluetoothSettings(true /* bluetoothOn */, true /* tetheringOn */);
|
||||||
mTethering.startTethering(createTetheringRequestParcel(TETHERING_BLUETOOTH), result);
|
mTethering.startTethering(createTetheringRequestParcel(TETHERING_BLUETOOTH),
|
||||||
|
TEST_CALLER_PKG, result);
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
verifySetBluetoothTethering(true /* enable */, true /* bindToPanService */);
|
verifySetBluetoothTethering(true /* enable */, true /* bindToPanService */);
|
||||||
result.assertHasResult();
|
result.assertHasResult();
|
||||||
@@ -2653,7 +2681,8 @@ public class TetheringTest {
|
|||||||
// already bound.
|
// already bound.
|
||||||
mockBluetoothSettings(true /* bluetoothOn */, true /* tetheringOn */);
|
mockBluetoothSettings(true /* bluetoothOn */, true /* tetheringOn */);
|
||||||
final ResultListener secondResult = new ResultListener(TETHER_ERROR_NO_ERROR);
|
final ResultListener secondResult = new ResultListener(TETHER_ERROR_NO_ERROR);
|
||||||
mTethering.startTethering(createTetheringRequestParcel(TETHERING_BLUETOOTH), secondResult);
|
mTethering.startTethering(createTetheringRequestParcel(TETHERING_BLUETOOTH),
|
||||||
|
TEST_CALLER_PKG, secondResult);
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
verifySetBluetoothTethering(true /* enable */, false /* bindToPanService */);
|
verifySetBluetoothTethering(true /* enable */, false /* bindToPanService */);
|
||||||
secondResult.assertHasResult();
|
secondResult.assertHasResult();
|
||||||
@@ -2674,7 +2703,8 @@ public class TetheringTest {
|
|||||||
public void testBluetoothServiceDisconnects() throws Exception {
|
public void testBluetoothServiceDisconnects() throws Exception {
|
||||||
final ResultListener result = new ResultListener(TETHER_ERROR_NO_ERROR);
|
final ResultListener result = new ResultListener(TETHER_ERROR_NO_ERROR);
|
||||||
mockBluetoothSettings(true /* bluetoothOn */, true /* tetheringOn */);
|
mockBluetoothSettings(true /* bluetoothOn */, true /* tetheringOn */);
|
||||||
mTethering.startTethering(createTetheringRequestParcel(TETHERING_BLUETOOTH), result);
|
mTethering.startTethering(createTetheringRequestParcel(TETHERING_BLUETOOTH),
|
||||||
|
TEST_CALLER_PKG, result);
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
ServiceListener panListener = verifySetBluetoothTethering(true /* enable */,
|
ServiceListener panListener = verifySetBluetoothTethering(true /* enable */,
|
||||||
true /* bindToPanService */);
|
true /* bindToPanService */);
|
||||||
@@ -2825,18 +2855,26 @@ public class TetheringTest {
|
|||||||
runNcmTethering();
|
runNcmTethering();
|
||||||
verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
|
verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
|
||||||
any(), any());
|
any(), any());
|
||||||
|
verify(mTetheringMetrics).createBuilder(eq(TETHERING_NCM), anyString());
|
||||||
|
|
||||||
// Change the USB tethering function to NCM. Because the USB tethering function was set to
|
// Change the USB tethering function to NCM. Because the USB tethering function was set to
|
||||||
// RNDIS (the default), tethering is stopped.
|
// RNDIS (the default), tethering is stopped.
|
||||||
forceUsbTetheringUse(TETHER_USB_NCM_FUNCTION);
|
forceUsbTetheringUse(TETHER_USB_NCM_FUNCTION);
|
||||||
verifyUsbTetheringStopDueToSettingChange(TEST_NCM_IFNAME);
|
verifyUsbTetheringStopDueToSettingChange(TEST_NCM_IFNAME);
|
||||||
|
verify(mTetheringMetrics).updateErrorCode(anyInt(), eq(TETHER_ERROR_NO_ERROR));
|
||||||
|
verify(mTetheringMetrics).sendReport(eq(TETHERING_NCM));
|
||||||
|
|
||||||
// If TETHERING_USB is forced to use ncm function, TETHERING_NCM would no longer be
|
// If TETHERING_USB is forced to use ncm function, TETHERING_NCM would no longer be
|
||||||
// available.
|
// available.
|
||||||
final ResultListener ncmResult = new ResultListener(TETHER_ERROR_SERVICE_UNAVAIL);
|
final ResultListener ncmResult = new ResultListener(TETHER_ERROR_SERVICE_UNAVAIL);
|
||||||
mTethering.startTethering(createTetheringRequestParcel(TETHERING_NCM), ncmResult);
|
mTethering.startTethering(createTetheringRequestParcel(TETHERING_NCM), TEST_CALLER_PKG,
|
||||||
|
ncmResult);
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
ncmResult.assertHasResult();
|
ncmResult.assertHasResult();
|
||||||
|
verify(mTetheringMetrics, times(2)).createBuilder(eq(TETHERING_NCM), anyString());
|
||||||
|
verify(mTetheringMetrics).updateErrorCode(eq(TETHERING_NCM),
|
||||||
|
eq(TETHER_ERROR_SERVICE_UNAVAIL));
|
||||||
|
verify(mTetheringMetrics, times(2)).sendReport(eq(TETHERING_NCM));
|
||||||
|
|
||||||
// Run TETHERING_USB with ncm configuration.
|
// Run TETHERING_USB with ncm configuration.
|
||||||
runDualStackUsbTethering(TEST_NCM_IFNAME);
|
runDualStackUsbTethering(TEST_NCM_IFNAME);
|
||||||
|
|||||||
@@ -0,0 +1,186 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2022 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.metrics;
|
||||||
|
|
||||||
|
import static android.net.TetheringManager.TETHERING_BLUETOOTH;
|
||||||
|
import static android.net.TetheringManager.TETHERING_ETHERNET;
|
||||||
|
import static android.net.TetheringManager.TETHERING_NCM;
|
||||||
|
import static android.net.TetheringManager.TETHERING_USB;
|
||||||
|
import static android.net.TetheringManager.TETHERING_WIFI;
|
||||||
|
import static android.net.TetheringManager.TETHERING_WIFI_P2P;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_DHCPSERVER_ERROR;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_DISABLE_FORWARDING_ERROR;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_ENABLE_FORWARDING_ERROR;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_ENTITLEMENT_UNKNOWN;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_IFACE_CFG_ERROR;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_INTERNAL_ERROR;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_PROVISIONING_FAILED;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_SERVICE_UNAVAIL;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_TETHER_IFACE_ERROR;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_UNAVAIL_IFACE;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_IFACE;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_TYPE;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_UNSUPPORTED;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_UNTETHER_IFACE_ERROR;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.reset;
|
||||||
|
import static org.mockito.Mockito.spy;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
|
import android.stats.connectivity.DownstreamType;
|
||||||
|
import android.stats.connectivity.ErrorCode;
|
||||||
|
import android.stats.connectivity.UpstreamType;
|
||||||
|
import android.stats.connectivity.UserType;
|
||||||
|
import android.util.Pair;
|
||||||
|
|
||||||
|
import androidx.test.filters.SmallTest;
|
||||||
|
import androidx.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
@SmallTest
|
||||||
|
public final class TetheringMetricsTest {
|
||||||
|
private static final String TEST_CALLER_PKG = "com.test.caller.pkg";
|
||||||
|
private static final String SETTINGS_PKG = "com.android.settings";
|
||||||
|
private static final String SYSTEMUI_PKG = "com.android.systemui";
|
||||||
|
private static final String GMS_PKG = "com.google.android.gms";
|
||||||
|
private TetheringMetrics mTetheringMetrics;
|
||||||
|
|
||||||
|
private final NetworkTetheringReported.Builder mStatsBuilder =
|
||||||
|
NetworkTetheringReported.newBuilder();
|
||||||
|
|
||||||
|
private class MockTetheringMetrics extends TetheringMetrics {
|
||||||
|
@Override
|
||||||
|
public void write(final NetworkTetheringReported reported) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
mTetheringMetrics = spy(new MockTetheringMetrics());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runDownstreamTypesTest(final Pair<Integer, DownstreamType>... testPairs)
|
||||||
|
throws Exception {
|
||||||
|
for (Pair<Integer, DownstreamType> testPair : testPairs) {
|
||||||
|
final int type = testPair.first;
|
||||||
|
final DownstreamType expectedResult = testPair.second;
|
||||||
|
|
||||||
|
mTetheringMetrics.createBuilder(type, TEST_CALLER_PKG);
|
||||||
|
mTetheringMetrics.updateErrorCode(type, TETHER_ERROR_NO_ERROR);
|
||||||
|
mTetheringMetrics.sendReport(type);
|
||||||
|
NetworkTetheringReported expectedReport =
|
||||||
|
mStatsBuilder.setDownstreamType(expectedResult)
|
||||||
|
.setUserType(UserType.USER_UNKNOWN)
|
||||||
|
.setUpstreamType(UpstreamType.UT_UNKNOWN)
|
||||||
|
.setErrorCode(ErrorCode.EC_NO_ERROR)
|
||||||
|
.build();
|
||||||
|
verify(mTetheringMetrics).write(expectedReport);
|
||||||
|
reset(mTetheringMetrics);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDownstreamTypes() throws Exception {
|
||||||
|
runDownstreamTypesTest(new Pair<>(TETHERING_WIFI, DownstreamType.DS_TETHERING_WIFI),
|
||||||
|
new Pair<>(TETHERING_WIFI_P2P, DownstreamType.DS_TETHERING_WIFI_P2P),
|
||||||
|
new Pair<>(TETHERING_BLUETOOTH, DownstreamType.DS_TETHERING_BLUETOOTH),
|
||||||
|
new Pair<>(TETHERING_USB, DownstreamType.DS_TETHERING_USB),
|
||||||
|
new Pair<>(TETHERING_NCM, DownstreamType.DS_TETHERING_NCM),
|
||||||
|
new Pair<>(TETHERING_ETHERNET, DownstreamType.DS_TETHERING_ETHERNET));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runErrorCodesTest(final Pair<Integer, ErrorCode>... testPairs)
|
||||||
|
throws Exception {
|
||||||
|
for (Pair<Integer, ErrorCode> testPair : testPairs) {
|
||||||
|
final int errorCode = testPair.first;
|
||||||
|
final ErrorCode expectedResult = testPair.second;
|
||||||
|
|
||||||
|
mTetheringMetrics.createBuilder(TETHERING_WIFI, TEST_CALLER_PKG);
|
||||||
|
mTetheringMetrics.updateErrorCode(TETHERING_WIFI, errorCode);
|
||||||
|
mTetheringMetrics.sendReport(TETHERING_WIFI);
|
||||||
|
NetworkTetheringReported expectedReport =
|
||||||
|
mStatsBuilder.setDownstreamType(DownstreamType.DS_TETHERING_WIFI)
|
||||||
|
.setUserType(UserType.USER_UNKNOWN)
|
||||||
|
.setUpstreamType(UpstreamType.UT_UNKNOWN)
|
||||||
|
.setErrorCode(expectedResult)
|
||||||
|
.build();
|
||||||
|
verify(mTetheringMetrics).write(expectedReport);
|
||||||
|
reset(mTetheringMetrics);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testErrorCodes() throws Exception {
|
||||||
|
runErrorCodesTest(new Pair<>(TETHER_ERROR_NO_ERROR, ErrorCode.EC_NO_ERROR),
|
||||||
|
new Pair<>(TETHER_ERROR_UNKNOWN_IFACE, ErrorCode.EC_UNKNOWN_IFACE),
|
||||||
|
new Pair<>(TETHER_ERROR_SERVICE_UNAVAIL, ErrorCode.EC_SERVICE_UNAVAIL),
|
||||||
|
new Pair<>(TETHER_ERROR_UNSUPPORTED, ErrorCode.EC_UNSUPPORTED),
|
||||||
|
new Pair<>(TETHER_ERROR_UNAVAIL_IFACE, ErrorCode.EC_UNAVAIL_IFACE),
|
||||||
|
new Pair<>(TETHER_ERROR_INTERNAL_ERROR, ErrorCode.EC_INTERNAL_ERROR),
|
||||||
|
new Pair<>(TETHER_ERROR_TETHER_IFACE_ERROR, ErrorCode.EC_TETHER_IFACE_ERROR),
|
||||||
|
new Pair<>(TETHER_ERROR_UNTETHER_IFACE_ERROR, ErrorCode.EC_UNTETHER_IFACE_ERROR),
|
||||||
|
new Pair<>(TETHER_ERROR_ENABLE_FORWARDING_ERROR,
|
||||||
|
ErrorCode.EC_ENABLE_FORWARDING_ERROR),
|
||||||
|
new Pair<>(TETHER_ERROR_DISABLE_FORWARDING_ERROR,
|
||||||
|
ErrorCode.EC_DISABLE_FORWARDING_ERROR),
|
||||||
|
new Pair<>(TETHER_ERROR_IFACE_CFG_ERROR, ErrorCode.EC_IFACE_CFG_ERROR),
|
||||||
|
new Pair<>(TETHER_ERROR_PROVISIONING_FAILED, ErrorCode.EC_PROVISIONING_FAILED),
|
||||||
|
new Pair<>(TETHER_ERROR_DHCPSERVER_ERROR, ErrorCode.EC_DHCPSERVER_ERROR),
|
||||||
|
new Pair<>(TETHER_ERROR_ENTITLEMENT_UNKNOWN, ErrorCode.EC_ENTITLEMENT_UNKNOWN),
|
||||||
|
new Pair<>(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION,
|
||||||
|
ErrorCode.EC_NO_CHANGE_TETHERING_PERMISSION),
|
||||||
|
new Pair<>(TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION,
|
||||||
|
ErrorCode.EC_NO_ACCESS_TETHERING_PERMISSION),
|
||||||
|
new Pair<>(TETHER_ERROR_UNKNOWN_TYPE, ErrorCode.EC_UNKNOWN_TYPE));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runUserTypesTest(final Pair<String, UserType>... testPairs)
|
||||||
|
throws Exception {
|
||||||
|
for (Pair<String, UserType> testPair : testPairs) {
|
||||||
|
final String callerPkg = testPair.first;
|
||||||
|
final UserType expectedResult = testPair.second;
|
||||||
|
|
||||||
|
mTetheringMetrics.createBuilder(TETHERING_WIFI, callerPkg);
|
||||||
|
mTetheringMetrics.updateErrorCode(TETHERING_WIFI, TETHER_ERROR_NO_ERROR);
|
||||||
|
mTetheringMetrics.sendReport(TETHERING_WIFI);
|
||||||
|
NetworkTetheringReported expectedReport =
|
||||||
|
mStatsBuilder.setDownstreamType(DownstreamType.DS_TETHERING_WIFI)
|
||||||
|
.setUserType(expectedResult)
|
||||||
|
.setUpstreamType(UpstreamType.UT_UNKNOWN)
|
||||||
|
.setErrorCode(ErrorCode.EC_NO_ERROR)
|
||||||
|
.build();
|
||||||
|
verify(mTetheringMetrics).write(expectedReport);
|
||||||
|
reset(mTetheringMetrics);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUserTypes() throws Exception {
|
||||||
|
runUserTypesTest(new Pair<>(TEST_CALLER_PKG, UserType.USER_UNKNOWN),
|
||||||
|
new Pair<>(SETTINGS_PKG, UserType.USER_SETTINGS),
|
||||||
|
new Pair<>(SYSTEMUI_PKG, UserType.USER_SYSTEMUI),
|
||||||
|
new Pair<>(GMS_PKG, UserType.USER_GMS));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user