Merge "Fix some @hide usage in Tethering"

This commit is contained in:
Mark Chien
2020-01-08 00:37:43 +00:00
committed by Gerrit Code Review
19 changed files with 219 additions and 144 deletions

View File

@@ -13,3 +13,5 @@ rule com.android.internal.util.State* com.android.networkstack.tethering.util.St
rule com.android.internal.util.StateMachine* com.android.networkstack.tethering.util.StateMachine@1 rule com.android.internal.util.StateMachine* com.android.networkstack.tethering.util.StateMachine@1
rule android.net.LocalLog* com.android.networkstack.tethering.LocalLog@1 rule android.net.LocalLog* com.android.networkstack.tethering.LocalLog@1
rule android.net.shared.Inet4AddressUtils* com.android.networkstack.tethering.shared.Inet4AddressUtils@1

View File

@@ -20,11 +20,11 @@ import static android.net.shared.Inet4AddressUtils.inet4AddressToIntHTH;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.net.LinkAddress; import android.net.LinkAddress;
import android.util.ArraySet;
import com.google.android.collect.Sets;
import java.net.Inet4Address; import java.net.Inet4Address;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.Set; import java.util.Set;
/** /**
@@ -68,7 +68,7 @@ public class DhcpServingParamsParcelExt extends DhcpServingParamsParcel {
* but it must always be set explicitly. * but it must always be set explicitly.
*/ */
public DhcpServingParamsParcelExt setDefaultRouters(@NonNull Inet4Address... defaultRouters) { public DhcpServingParamsParcelExt setDefaultRouters(@NonNull Inet4Address... defaultRouters) {
return setDefaultRouters(Sets.newArraySet(defaultRouters)); return setDefaultRouters(newArraySet(defaultRouters));
} }
/** /**
@@ -96,7 +96,7 @@ public class DhcpServingParamsParcelExt extends DhcpServingParamsParcel {
* <p>This may be an empty list of servers, but it must always be set explicitly. * <p>This may be an empty list of servers, but it must always be set explicitly.
*/ */
public DhcpServingParamsParcelExt setDnsServers(@NonNull Inet4Address... dnsServers) { public DhcpServingParamsParcelExt setDnsServers(@NonNull Inet4Address... dnsServers) {
return setDnsServers(Sets.newArraySet(dnsServers)); return setDnsServers(newArraySet(dnsServers));
} }
/** /**
@@ -126,7 +126,7 @@ public class DhcpServingParamsParcelExt extends DhcpServingParamsParcel {
* and do not need to be set here. * and do not need to be set here.
*/ */
public DhcpServingParamsParcelExt setExcludedAddrs(@NonNull Inet4Address... excludedAddrs) { public DhcpServingParamsParcelExt setExcludedAddrs(@NonNull Inet4Address... excludedAddrs) {
return setExcludedAddrs(Sets.newArraySet(excludedAddrs)); return setExcludedAddrs(newArraySet(excludedAddrs));
} }
/** /**
@@ -169,4 +169,10 @@ public class DhcpServingParamsParcelExt extends DhcpServingParamsParcel {
} }
return res; return res;
} }
private static ArraySet<Inet4Address> newArraySet(Inet4Address... addrs) {
ArraySet<Inet4Address> addrSet = new ArraySet<>(addrs.length);
Collections.addAll(addrSet, addrs);
return addrSet;
}
} }

View File

@@ -17,10 +17,12 @@
package android.net.ip; package android.net.ip;
import static android.net.InetAddresses.parseNumericAddress; import static android.net.InetAddresses.parseNumericAddress;
import static android.net.RouteInfo.RTN_UNICAST;
import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS; import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
import static android.net.util.NetworkConstants.FF; import static android.net.util.NetworkConstants.FF;
import static android.net.util.NetworkConstants.RFC7421_PREFIX_LENGTH; import static android.net.util.NetworkConstants.RFC7421_PREFIX_LENGTH;
import static android.net.util.NetworkConstants.asByte; import static android.net.util.NetworkConstants.asByte;
import static android.net.util.TetheringMessageBase.BASE_IPSERVER;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.net.INetd; import android.net.INetd;
@@ -46,11 +48,9 @@ import android.os.Message;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.ServiceSpecificException; import android.os.ServiceSpecificException;
import android.util.Log; import android.util.Log;
import android.util.Slog;
import android.util.SparseArray; import android.util.SparseArray;
import com.android.internal.util.MessageUtils; import com.android.internal.util.MessageUtils;
import com.android.internal.util.Protocol;
import com.android.internal.util.State; import com.android.internal.util.State;
import com.android.internal.util.StateMachine; import com.android.internal.util.StateMachine;
@@ -153,27 +153,26 @@ public class IpServer extends StateMachine {
DhcpServerCallbacks cb); DhcpServerCallbacks cb);
} }
private static final int BASE_IFACE = Protocol.BASE_TETHERING + 100;
// request from the user that it wants to tether // request from the user that it wants to tether
public static final int CMD_TETHER_REQUESTED = BASE_IFACE + 2; public static final int CMD_TETHER_REQUESTED = BASE_IPSERVER + 1;
// request from the user that it wants to untether // request from the user that it wants to untether
public static final int CMD_TETHER_UNREQUESTED = BASE_IFACE + 3; public static final int CMD_TETHER_UNREQUESTED = BASE_IPSERVER + 2;
// notification that this interface is down // notification that this interface is down
public static final int CMD_INTERFACE_DOWN = BASE_IFACE + 4; public static final int CMD_INTERFACE_DOWN = BASE_IPSERVER + 3;
// notification from the master SM that it had trouble enabling IP Forwarding // notification from the master SM that it had trouble enabling IP Forwarding
public static final int CMD_IP_FORWARDING_ENABLE_ERROR = BASE_IFACE + 7; public static final int CMD_IP_FORWARDING_ENABLE_ERROR = BASE_IPSERVER + 4;
// notification from the master SM that it had trouble disabling IP Forwarding // notification from the master SM that it had trouble disabling IP Forwarding
public static final int CMD_IP_FORWARDING_DISABLE_ERROR = BASE_IFACE + 8; public static final int CMD_IP_FORWARDING_DISABLE_ERROR = BASE_IPSERVER + 5;
// notification from the master SM that it had trouble starting tethering // notification from the master SM that it had trouble starting tethering
public static final int CMD_START_TETHERING_ERROR = BASE_IFACE + 9; public static final int CMD_START_TETHERING_ERROR = BASE_IPSERVER + 6;
// notification from the master SM that it had trouble stopping tethering // notification from the master SM that it had trouble stopping tethering
public static final int CMD_STOP_TETHERING_ERROR = BASE_IFACE + 10; public static final int CMD_STOP_TETHERING_ERROR = BASE_IPSERVER + 7;
// notification from the master SM that it had trouble setting the DNS forwarders // notification from the master SM that it had trouble setting the DNS forwarders
public static final int CMD_SET_DNS_FORWARDERS_ERROR = BASE_IFACE + 11; public static final int CMD_SET_DNS_FORWARDERS_ERROR = BASE_IPSERVER + 8;
// the upstream connection has changed // the upstream connection has changed
public static final int CMD_TETHER_CONNECTION_CHANGED = BASE_IFACE + 12; public static final int CMD_TETHER_CONNECTION_CHANGED = BASE_IPSERVER + 9;
// new IPv6 tethering parameters need to be processed // new IPv6 tethering parameters need to be processed
public static final int CMD_IPV6_TETHER_UPDATE = BASE_IFACE + 13; public static final int CMD_IPV6_TETHER_UPDATE = BASE_IPSERVER + 10;
private final State mInitialState; private final State mInitialState;
private final State mLocalHotspotState; private final State mLocalHotspotState;
@@ -486,7 +485,9 @@ public class IpServer extends StateMachine {
} }
// Directly-connected route. // Directly-connected route.
final RouteInfo route = new RouteInfo(linkAddr); final IpPrefix ipv4Prefix = new IpPrefix(linkAddr.getAddress(),
linkAddr.getPrefixLength());
final RouteInfo route = new RouteInfo(ipv4Prefix, null, null, RTN_UNICAST);
if (enabled) { if (enabled) {
mLinkProperties.addLinkAddress(linkAddr); mLinkProperties.addLinkAddress(linkAddr);
mLinkProperties.addRoute(route); mLinkProperties.addRoute(route);
@@ -1007,7 +1008,7 @@ public class IpServer extends StateMachine {
String ifname, HashSet<IpPrefix> prefixes) { String ifname, HashSet<IpPrefix> prefixes) {
final ArrayList<RouteInfo> localRoutes = new ArrayList<RouteInfo>(); final ArrayList<RouteInfo> localRoutes = new ArrayList<RouteInfo>();
for (IpPrefix ipp : prefixes) { for (IpPrefix ipp : prefixes) {
localRoutes.add(new RouteInfo(ipp, null, ifname)); localRoutes.add(new RouteInfo(ipp, null, ifname, RTN_UNICAST));
} }
return localRoutes; return localRoutes;
} }
@@ -1019,7 +1020,7 @@ public class IpServer extends StateMachine {
try { try {
return Inet6Address.getByAddress(null, dnsBytes, 0); return Inet6Address.getByAddress(null, dnsBytes, 0);
} catch (UnknownHostException e) { } catch (UnknownHostException e) {
Slog.wtf(TAG, "Failed to construct Inet6Address from: " + localPrefix); Log.wtf(TAG, "Failed to construct Inet6Address from: " + localPrefix);
return null; return null;
} }
} }

View File

@@ -22,14 +22,13 @@ import static android.system.OsConstants.AF_INET6;
import static android.system.OsConstants.IPPROTO_ICMPV6; import static android.system.OsConstants.IPPROTO_ICMPV6;
import static android.system.OsConstants.SOCK_RAW; import static android.system.OsConstants.SOCK_RAW;
import static android.system.OsConstants.SOL_SOCKET; import static android.system.OsConstants.SOL_SOCKET;
import static android.system.OsConstants.SO_BINDTODEVICE;
import static android.system.OsConstants.SO_SNDTIMEO; import static android.system.OsConstants.SO_SNDTIMEO;
import android.net.IpPrefix; import android.net.IpPrefix;
import android.net.LinkAddress; import android.net.LinkAddress;
import android.net.NetworkUtils;
import android.net.TrafficStats; import android.net.TrafficStats;
import android.net.util.InterfaceParams; import android.net.util.InterfaceParams;
import android.net.util.SocketUtils;
import android.net.util.TetheringUtils; import android.net.util.TetheringUtils;
import android.system.ErrnoException; import android.system.ErrnoException;
import android.system.Os; import android.system.Os;
@@ -39,8 +38,6 @@ import android.util.Log;
import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.TrafficStatsConstants; import com.android.internal.util.TrafficStatsConstants;
import libcore.io.IoBridge;
import java.io.FileDescriptor; import java.io.FileDescriptor;
import java.io.IOException; import java.io.IOException;
import java.net.Inet6Address; import java.net.Inet6Address;
@@ -612,8 +609,7 @@ public class RouterAdvertisementDaemon {
// Setting SNDTIMEO is purely for defensive purposes. // Setting SNDTIMEO is purely for defensive purposes.
Os.setsockoptTimeval( Os.setsockoptTimeval(
mSocket, SOL_SOCKET, SO_SNDTIMEO, StructTimeval.fromMillis(send_timout_ms)); mSocket, SOL_SOCKET, SO_SNDTIMEO, StructTimeval.fromMillis(send_timout_ms));
Os.setsockoptIfreq(mSocket, SOL_SOCKET, SO_BINDTODEVICE, mInterface.name); SocketUtils.bindSocketToInterface(mSocket, mInterface.name);
NetworkUtils.protectFromVpn(mSocket);
TetheringUtils.setupRaSocket(mSocket, mInterface.index); TetheringUtils.setupRaSocket(mSocket, mInterface.index);
} catch (ErrnoException | IOException e) { } catch (ErrnoException | IOException e) {
Log.e(TAG, "Failed to create RA daemon socket: " + e); Log.e(TAG, "Failed to create RA daemon socket: " + e);
@@ -628,7 +624,7 @@ public class RouterAdvertisementDaemon {
private void closeSocket() { private void closeSocket() {
if (mSocket != null) { if (mSocket != null) {
try { try {
IoBridge.closeAndSignalBlockedThreads(mSocket); SocketUtils.closeSocket(mSocket);
} catch (IOException ignored) { } } catch (IOException ignored) { }
} }
mSocket = null; mSocket = null;

View File

@@ -0,0 +1,25 @@
/*
* 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 android.net.util;
/**
* This class defines Message.what base addresses for various state machine.
*/
public class TetheringMessageBase {
public static final int BASE_MASTER = 0;
public static final int BASE_IPSERVER = 100;
}

View File

@@ -39,4 +39,11 @@ public class TetheringUtils {
*/ */
public static native void setupRaSocket(FileDescriptor fd, int ifIndex) public static native void setupRaSocket(FileDescriptor fd, int ifIndex)
throws SocketException; throws SocketException;
/**
* Read s as an unsigned 16-bit integer.
*/
public static int uint16(short s) {
return s & 0xffff;
}
} }

View File

@@ -38,7 +38,6 @@ import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.res.Resources; import android.content.res.Resources;
import android.net.util.SharedLog; import android.net.util.SharedLog;
import android.os.Binder;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
@@ -48,7 +47,6 @@ import android.os.PersistableBundle;
import android.os.ResultReceiver; import android.os.ResultReceiver;
import android.os.SystemClock; import android.os.SystemClock;
import android.os.SystemProperties; import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.Settings; import android.provider.Settings;
import android.telephony.CarrierConfigManager; import android.telephony.CarrierConfigManager;
import android.util.ArraySet; import android.util.ArraySet;
@@ -196,9 +194,9 @@ public class EntitlementManager {
// till upstream change to cellular. // till upstream change to cellular.
if (mUsingCellularAsUpstream) { if (mUsingCellularAsUpstream) {
if (showProvisioningUi) { if (showProvisioningUi) {
runUiTetherProvisioning(type, config.subId); runUiTetherProvisioning(type, config.activeDataSubId);
} else { } else {
runSilentTetherProvisioning(type, config.subId); runSilentTetherProvisioning(type, config.activeDataSubId);
} }
mNeedReRunProvisioningUi = false; mNeedReRunProvisioningUi = false;
} else { } else {
@@ -270,9 +268,9 @@ public class EntitlementManager {
if (mCellularPermitted.indexOfKey(downstream) < 0) { if (mCellularPermitted.indexOfKey(downstream) < 0) {
if (mNeedReRunProvisioningUi) { if (mNeedReRunProvisioningUi) {
mNeedReRunProvisioningUi = false; mNeedReRunProvisioningUi = false;
runUiTetherProvisioning(downstream, config.subId); runUiTetherProvisioning(downstream, config.activeDataSubId);
} else { } else {
runSilentTetherProvisioning(downstream, config.subId); runSilentTetherProvisioning(downstream, config.activeDataSubId);
} }
} }
} }
@@ -336,7 +334,8 @@ public class EntitlementManager {
.getSystemService(Context.CARRIER_CONFIG_SERVICE); .getSystemService(Context.CARRIER_CONFIG_SERVICE);
if (configManager == null) return null; if (configManager == null) return null;
final PersistableBundle carrierConfig = configManager.getConfigForSubId(config.subId); final PersistableBundle carrierConfig = configManager.getConfigForSubId(
config.activeDataSubId);
if (CarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfig)) { if (CarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfig)) {
return carrierConfig; return carrierConfig;
@@ -379,12 +378,9 @@ public class EntitlementManager {
intent.putExtra(EXTRA_PROVISION_CALLBACK, receiver); intent.putExtra(EXTRA_PROVISION_CALLBACK, receiver);
intent.putExtra(EXTRA_SUBID, subId); intent.putExtra(EXTRA_SUBID, subId);
intent.setComponent(TETHER_SERVICE); intent.setComponent(TETHER_SERVICE);
final long ident = Binder.clearCallingIdentity(); // Only admin user can change tethering and SilentTetherProvisioning don't need to
try { // show UI, it is fine to always start setting's background service as system user.
mContext.startServiceAsUser(intent, UserHandle.CURRENT); mContext.startService(intent);
} finally {
Binder.restoreCallingIdentity(ident);
}
} }
private void runUiTetherProvisioning(int type, int subId) { private void runUiTetherProvisioning(int type, int subId) {
@@ -407,12 +403,9 @@ public class EntitlementManager {
intent.putExtra(EXTRA_PROVISION_CALLBACK, receiver); intent.putExtra(EXTRA_PROVISION_CALLBACK, receiver);
intent.putExtra(EXTRA_SUBID, subId); intent.putExtra(EXTRA_SUBID, subId);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
final long ident = Binder.clearCallingIdentity(); // Only launch entitlement UI for system user. Entitlement UI should not appear for other
try { // user because only admin user is allowed to change tethering.
mContext.startActivityAsUser(intent, UserHandle.CURRENT); mContext.startActivity(intent);
} finally {
Binder.restoreCallingIdentity(ident);
}
} }
// Not needed to check if this don't run on the handler thread because it's private. // Not needed to check if this don't run on the handler thread because it's private.
@@ -671,7 +664,7 @@ public class EntitlementManager {
receiver.send(cacheValue, null); receiver.send(cacheValue, null);
} else { } else {
ResultReceiver proxy = buildProxyReceiver(downstream, false/* notifyFail */, receiver); ResultReceiver proxy = buildProxyReceiver(downstream, false/* notifyFail */, receiver);
runUiTetherProvisioning(downstream, config.subId, proxy); runUiTetherProvisioning(downstream, config.activeDataSubId, proxy);
} }
} }
} }

View File

@@ -29,6 +29,7 @@ import android.util.Log;
import java.net.Inet6Address; import java.net.Inet6Address;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.LinkedList; import java.util.LinkedList;
@@ -257,7 +258,7 @@ public class IPv6TetheringCoordinator {
final LinkProperties lp = new LinkProperties(); final LinkProperties lp = new LinkProperties();
final IpPrefix local48 = makeUniqueLocalPrefix(ulp, (short) 0, 48); final IpPrefix local48 = makeUniqueLocalPrefix(ulp, (short) 0, 48);
lp.addRoute(new RouteInfo(local48, null, null)); lp.addRoute(new RouteInfo(local48, null, null, RouteInfo.RTN_UNICAST));
final IpPrefix local64 = makeUniqueLocalPrefix(ulp, subnetId, 64); final IpPrefix local64 = makeUniqueLocalPrefix(ulp, subnetId, 64);
// Because this is a locally-generated ULA, we don't have an upstream // Because this is a locally-generated ULA, we don't have an upstream
@@ -273,7 +274,13 @@ public class IPv6TetheringCoordinator {
final byte[] bytes = Arrays.copyOf(in6addr, in6addr.length); final byte[] bytes = Arrays.copyOf(in6addr, in6addr.length);
bytes[7] = (byte) (subnetId >> 8); bytes[7] = (byte) (subnetId >> 8);
bytes[8] = (byte) subnetId; bytes[8] = (byte) subnetId;
return new IpPrefix(bytes, prefixlen); final InetAddress addr;
try {
addr = InetAddress.getByAddress(bytes);
} catch (UnknownHostException e) {
throw new IllegalStateException("Invalid address length: " + bytes.length, e);
}
return new IpPrefix(addr, prefixlen);
} }
// Generates a Unique Locally-assigned Prefix: // Generates a Unique Locally-assigned Prefix:

View File

@@ -25,6 +25,7 @@ import static android.provider.Settings.Global.TETHER_OFFLOAD_DISABLED;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.net.ITetheringStatsProvider; import android.net.ITetheringStatsProvider;
import android.net.InetAddresses;
import android.net.IpPrefix; import android.net.IpPrefix;
import android.net.LinkAddress; import android.net.LinkAddress;
import android.net.LinkProperties; import android.net.LinkProperties;
@@ -33,7 +34,6 @@ import android.net.RouteInfo;
import android.net.netlink.ConntrackMessage; import android.net.netlink.ConntrackMessage;
import android.net.netlink.NetlinkConstants; import android.net.netlink.NetlinkConstants;
import android.net.netlink.NetlinkSocket; import android.net.netlink.NetlinkSocket;
import android.net.util.IpUtils;
import android.net.util.SharedLog; import android.net.util.SharedLog;
import android.os.Handler; import android.os.Handler;
import android.os.INetworkManagementService; import android.os.INetworkManagementService;
@@ -477,9 +477,10 @@ public class OffloadController {
if (!ri.hasGateway()) continue; if (!ri.hasGateway()) continue;
final String gateway = ri.getGateway().getHostAddress(); final String gateway = ri.getGateway().getHostAddress();
if (ri.isIPv4Default()) { final InetAddress address = ri.getDestination().getAddress();
if (ri.isDefaultRoute() && address instanceof Inet4Address) {
v4gateway = gateway; v4gateway = gateway;
} else if (ri.isIPv6Default()) { } else if (ri.isDefaultRoute() && address instanceof Inet6Address) {
v6gateways.add(gateway); v6gateways.add(gateway);
} }
} }
@@ -547,7 +548,10 @@ public class OffloadController {
private static boolean shouldIgnoreDownstreamRoute(RouteInfo route) { private static boolean shouldIgnoreDownstreamRoute(RouteInfo route) {
// Ignore any link-local routes. // Ignore any link-local routes.
if (!route.getDestinationLinkAddress().isGlobalPreferred()) return true; final IpPrefix destination = route.getDestination();
final LinkAddress linkAddr = new LinkAddress(destination.getAddress(),
destination.getPrefixLength());
if (!linkAddr.isGlobalPreferred()) return true;
return false; return false;
} }
@@ -588,7 +592,7 @@ public class OffloadController {
return; return;
} }
if (!IpUtils.isValidUdpOrTcpPort(srcPort)) { if (!isValidUdpOrTcpPort(srcPort)) {
mLog.e("Invalid src port: " + srcPort); mLog.e("Invalid src port: " + srcPort);
return; return;
} }
@@ -599,7 +603,7 @@ public class OffloadController {
return; return;
} }
if (!IpUtils.isValidUdpOrTcpPort(dstPort)) { if (!isValidUdpOrTcpPort(dstPort)) {
mLog.e("Invalid dst port: " + dstPort); mLog.e("Invalid dst port: " + dstPort);
return; return;
} }
@@ -628,7 +632,7 @@ public class OffloadController {
private static Inet4Address parseIPv4Address(String addrString) { private static Inet4Address parseIPv4Address(String addrString) {
try { try {
final InetAddress ip = InetAddress.parseNumericAddress(addrString); final InetAddress ip = InetAddresses.parseNumericAddress(addrString);
// TODO: Consider other sanitization steps here, including perhaps: // TODO: Consider other sanitization steps here, including perhaps:
// not eql to 0.0.0.0 // not eql to 0.0.0.0
// not within 169.254.0.0/16 // not within 169.254.0.0/16
@@ -668,4 +672,8 @@ public class OffloadController {
return 180; return 180;
} }
} }
private static boolean isValidUdpOrTcpPort(int port) {
return port > 0 && port < 65536;
}
} }

View File

@@ -16,7 +16,7 @@
package com.android.server.connectivity.tethering; package com.android.server.connectivity.tethering;
import static com.android.internal.util.BitUtils.uint16; import static android.net.util.TetheringUtils.uint16;
import android.hardware.tetheroffload.control.V1_0.IOffloadControl; import android.hardware.tetheroffload.control.V1_0.IOffloadControl;
import android.hardware.tetheroffload.control.V1_0.ITetheringOffloadCallback; import android.hardware.tetheroffload.control.V1_0.ITetheringOffloadCallback;

View File

@@ -37,6 +37,7 @@ import static android.net.ConnectivityManager.TETHER_ERROR_NO_ERROR;
import static android.net.ConnectivityManager.TETHER_ERROR_SERVICE_UNAVAIL; import static android.net.ConnectivityManager.TETHER_ERROR_SERVICE_UNAVAIL;
import static android.net.ConnectivityManager.TETHER_ERROR_UNAVAIL_IFACE; import static android.net.ConnectivityManager.TETHER_ERROR_UNAVAIL_IFACE;
import static android.net.ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE; import static android.net.ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE;
import static android.net.util.TetheringMessageBase.BASE_MASTER;
import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME; import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE; import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE; import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
@@ -106,7 +107,6 @@ import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.MessageUtils; import com.android.internal.util.MessageUtils;
import com.android.internal.util.Protocol;
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.R; import com.android.networkstack.tethering.R;
@@ -120,6 +120,8 @@ import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.Set; import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionException;
/** /**
* *
@@ -185,10 +187,10 @@ public class Tethering {
private final TetheringDependencies mDeps; private final TetheringDependencies mDeps;
private final EntitlementManager mEntitlementMgr; private final EntitlementManager mEntitlementMgr;
private final Handler mHandler; private final Handler mHandler;
private final PhoneStateListener mPhoneStateListener;
private final INetd mNetd; private final INetd mNetd;
private final NetdCallback mNetdCallback; private final NetdCallback mNetdCallback;
private final UserRestrictionActionListener mTetheringRestriction; private final UserRestrictionActionListener mTetheringRestriction;
private final ActiveDataSubIdListener mActiveDataSubIdListener;
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.
private ITetheringEventCallback mTetheringEventCallback = null; private ITetheringEventCallback mTetheringEventCallback = null;
@@ -252,26 +254,6 @@ public class Tethering {
mEntitlementMgr.reevaluateSimCardProvisioning(mConfig); mEntitlementMgr.reevaluateSimCardProvisioning(mConfig);
}); });
mPhoneStateListener = new PhoneStateListener(mLooper) {
@Override
public void onActiveDataSubscriptionIdChanged(int subId) {
mLog.log("OBSERVED active data subscription change, from " + mActiveDataSubId
+ " to " + subId);
if (subId == mActiveDataSubId) return;
mActiveDataSubId = subId;
updateConfiguration();
// To avoid launching unexpected provisioning checks, ignore re-provisioning when
// no CarrierConfig loaded yet. Assume reevaluateSimCardProvisioning() will be
// triggered again when CarrierConfig is loaded.
if (mEntitlementMgr.getCarrierConfig(mConfig) != null) {
mEntitlementMgr.reevaluateSimCardProvisioning(mConfig);
} else {
mLog.log("IGNORED reevaluate provisioning due to no carrier config loaded");
}
}
};
mStateReceiver = new StateReceiver(); mStateReceiver = new StateReceiver();
mNetdCallback = new NetdCallback(); mNetdCallback = new NetdCallback();
@@ -284,6 +266,8 @@ public class Tethering {
final UserManager userManager = (UserManager) mContext.getSystemService( final UserManager userManager = (UserManager) mContext.getSystemService(
Context.USER_SERVICE); Context.USER_SERVICE);
mTetheringRestriction = new UserRestrictionActionListener(userManager, this); mTetheringRestriction = new UserRestrictionActionListener(userManager, this);
final TetheringThreadExecutor executor = new TetheringThreadExecutor(mHandler);
mActiveDataSubIdListener = new ActiveDataSubIdListener(executor);
// Load tethering configuration. // Load tethering configuration.
updateConfiguration(); updateConfiguration();
@@ -294,8 +278,8 @@ public class Tethering {
private void startStateMachineUpdaters(Handler handler) { private void startStateMachineUpdaters(Handler handler) {
mCarrierConfigChange.startListening(); mCarrierConfigChange.startListening();
mContext.getSystemService(TelephonyManager.class).listen( mContext.getSystemService(TelephonyManager.class).listen(mActiveDataSubIdListener,
mPhoneStateListener, PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE); PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
IntentFilter filter = new IntentFilter(); IntentFilter filter = new IntentFilter();
filter.addAction(UsbManager.ACTION_USB_STATE); filter.addAction(UsbManager.ACTION_USB_STATE);
@@ -314,6 +298,43 @@ public class Tethering {
} }
private class TetheringThreadExecutor implements Executor {
private final Handler mTetherHandler;
TetheringThreadExecutor(Handler handler) {
mTetherHandler = handler;
}
@Override
public void execute(Runnable command) {
if (!mTetherHandler.post(command)) {
throw new RejectedExecutionException(mTetherHandler + " is shutting down");
}
}
}
private class ActiveDataSubIdListener extends PhoneStateListener {
ActiveDataSubIdListener(Executor executor) {
super(executor);
}
@Override
public void onActiveDataSubscriptionIdChanged(int subId) {
mLog.log("OBSERVED active data subscription change, from " + mActiveDataSubId
+ " to " + subId);
if (subId == mActiveDataSubId) return;
mActiveDataSubId = subId;
updateConfiguration();
// To avoid launching unexpected provisioning checks, ignore re-provisioning
// when no CarrierConfig loaded yet. Assume reevaluateSimCardProvisioning()
// ill be triggered again when CarrierConfig is loaded.
if (mEntitlementMgr.getCarrierConfig(mConfig) != null) {
mEntitlementMgr.reevaluateSimCardProvisioning(mConfig);
} else {
mLog.log("IGNORED reevaluate provisioning, no carrier config loaded");
}
}
}
private WifiManager getWifiManager() { private WifiManager getWifiManager() {
return (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); return (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
} }
@@ -326,8 +347,7 @@ public class Tethering {
} }
private void maybeDunSettingChanged() { private void maybeDunSettingChanged() {
final boolean isDunRequired = TetheringConfiguration.checkDunRequired( final boolean isDunRequired = TetheringConfiguration.checkDunRequired(mContext);
mContext, mActiveDataSubId);
if (isDunRequired == mConfig.isDunRequired) return; if (isDunRequired == mConfig.isDunRequired) return;
updateConfiguration(); updateConfiguration();
} }
@@ -1162,7 +1182,6 @@ public class Tethering {
} }
class TetherMasterSM extends StateMachine { class TetherMasterSM extends StateMachine {
private static final int BASE_MASTER = Protocol.BASE_TETHERING;
// an interface SM has requested Tethering/Local Hotspot // an interface SM has requested Tethering/Local Hotspot
static final int EVENT_IFACE_SERVING_STATE_ACTIVE = BASE_MASTER + 1; static final int EVENT_IFACE_SERVING_STATE_ACTIVE = BASE_MASTER + 1;
// an interface SM has unrequested Tethering/Local Hotspot // an interface SM has unrequested Tethering/Local Hotspot
@@ -1179,7 +1198,6 @@ public class Tethering {
static final int EVENT_IFACE_UPDATE_LINKPROPERTIES = BASE_MASTER + 7; static final int EVENT_IFACE_UPDATE_LINKPROPERTIES = BASE_MASTER + 7;
// Events from EntitlementManager to choose upstream again. // Events from EntitlementManager to choose upstream again.
static final int EVENT_UPSTREAM_PERMISSION_CHANGED = BASE_MASTER + 8; static final int EVENT_UPSTREAM_PERMISSION_CHANGED = BASE_MASTER + 8;
private final State mInitialState; private final State mInitialState;
private final State mTetherModeAliveState; private final State mTetherModeAliveState;

View File

@@ -100,13 +100,13 @@ public class TetheringConfiguration {
public final String provisioningAppNoUi; public final String provisioningAppNoUi;
public final int provisioningCheckPeriod; public final int provisioningCheckPeriod;
public final int subId; public final int activeDataSubId;
public TetheringConfiguration(Context ctx, SharedLog log, int id) { public TetheringConfiguration(Context ctx, SharedLog log, int id) {
final SharedLog configLog = log.forSubComponent("config"); final SharedLog configLog = log.forSubComponent("config");
subId = id; activeDataSubId = id;
Resources res = getResources(ctx, subId); Resources res = getResources(ctx, activeDataSubId);
tetherableUsbRegexs = getResourceStringArray(res, config_tether_usb_regexs); tetherableUsbRegexs = getResourceStringArray(res, config_tether_usb_regexs);
// TODO: Evaluate deleting this altogether now that Wi-Fi always passes // TODO: Evaluate deleting this altogether now that Wi-Fi always passes
@@ -116,7 +116,7 @@ public class TetheringConfiguration {
tetherableWifiP2pRegexs = getResourceStringArray(res, config_tether_wifi_p2p_regexs); tetherableWifiP2pRegexs = getResourceStringArray(res, config_tether_wifi_p2p_regexs);
tetherableBluetoothRegexs = getResourceStringArray(res, config_tether_bluetooth_regexs); tetherableBluetoothRegexs = getResourceStringArray(res, config_tether_bluetooth_regexs);
isDunRequired = checkDunRequired(ctx, subId); isDunRequired = checkDunRequired(ctx);
chooseUpstreamAutomatically = getResourceBoolean(res, config_tether_upstream_automatic); chooseUpstreamAutomatically = getResourceBoolean(res, config_tether_upstream_automatic);
preferredUpstreamIfaceTypes = getUpstreamIfaceTypes(res, isDunRequired); preferredUpstreamIfaceTypes = getUpstreamIfaceTypes(res, isDunRequired);
@@ -166,8 +166,8 @@ public class TetheringConfiguration {
/** Does the dumping.*/ /** Does the dumping.*/
public void dump(PrintWriter pw) { public void dump(PrintWriter pw) {
pw.print("subId: "); pw.print("activeDataSubId: ");
pw.println(subId); pw.println(activeDataSubId);
dumpStringArray(pw, "tetherableUsbRegexs", tetherableUsbRegexs); dumpStringArray(pw, "tetherableUsbRegexs", tetherableUsbRegexs);
dumpStringArray(pw, "tetherableWifiRegexs", tetherableWifiRegexs); dumpStringArray(pw, "tetherableWifiRegexs", tetherableWifiRegexs);
@@ -196,7 +196,7 @@ public class TetheringConfiguration {
/** Returns the string representation of this object.*/ /** Returns the string representation of this object.*/
public String toString() { public String toString() {
final StringJoiner sj = new StringJoiner(" "); final StringJoiner sj = new StringJoiner(" ");
sj.add(String.format("subId:%d", subId)); sj.add(String.format("activeDataSubId:%d", activeDataSubId));
sj.add(String.format("tetherableUsbRegexs:%s", makeString(tetherableUsbRegexs))); sj.add(String.format("tetherableUsbRegexs:%s", makeString(tetherableUsbRegexs)));
sj.add(String.format("tetherableWifiRegexs:%s", makeString(tetherableWifiRegexs))); sj.add(String.format("tetherableWifiRegexs:%s", makeString(tetherableWifiRegexs)));
sj.add(String.format("tetherableWifiP2pRegexs:%s", makeString(tetherableWifiP2pRegexs))); sj.add(String.format("tetherableWifiP2pRegexs:%s", makeString(tetherableWifiP2pRegexs)));
@@ -250,9 +250,11 @@ public class TetheringConfiguration {
} }
/** Check whether dun is required. */ /** Check whether dun is required. */
public static boolean checkDunRequired(Context ctx, int id) { public static boolean checkDunRequired(Context ctx) {
final TelephonyManager tm = (TelephonyManager) ctx.getSystemService(TELEPHONY_SERVICE); final TelephonyManager tm = (TelephonyManager) ctx.getSystemService(TELEPHONY_SERVICE);
return (tm != null) ? tm.isTetheringApnRequired(id) : false; // TelephonyManager would uses the active data subscription, which should be the one used
// by tethering.
return (tm != null) ? tm.isTetheringApnRequired() : false;
} }
private static Collection<Integer> getUpstreamIfaceTypes(Resources res, boolean dunRequired) { private static Collection<Integer> getUpstreamIfaceTypes(Resources res, boolean dunRequired) {
@@ -391,7 +393,7 @@ public class TetheringConfiguration {
*/ */
public TetheringConfigurationParcel toStableParcelable() { public TetheringConfigurationParcel toStableParcelable() {
final TetheringConfigurationParcel parcel = new TetheringConfigurationParcel(); final TetheringConfigurationParcel parcel = new TetheringConfigurationParcel();
parcel.subId = subId; parcel.subId = activeDataSubId;
parcel.tetherableUsbRegexs = tetherableUsbRegexs; parcel.tetherableUsbRegexs = tetherableUsbRegexs;
parcel.tetherableWifiRegexs = tetherableWifiRegexs; parcel.tetherableWifiRegexs = tetherableWifiRegexs;
parcel.tetherableBluetoothRegexs = tetherableBluetoothRegexs; parcel.tetherableBluetoothRegexs = tetherableBluetoothRegexs;

View File

@@ -21,6 +21,7 @@ import static android.net.TetheringManager.TETHER_ERROR_NO_ACCESS_TETHERING_PERM
import static android.net.TetheringManager.TETHER_ERROR_NO_CHANGE_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_NO_ERROR;
import static android.net.TetheringManager.TETHER_ERROR_UNSUPPORTED; import static android.net.TetheringManager.TETHER_ERROR_UNSUPPORTED;
import static android.net.dhcp.IDhcpServer.STATUS_UNKNOWN_ERROR;
import android.app.Service; import android.app.Service;
import android.content.Context; import android.content.Context;
@@ -340,7 +341,10 @@ public class TetheringService extends Service {
service.makeDhcpServer(ifName, params, cb); service.makeDhcpServer(ifName, params, cb);
} catch (RemoteException e) { } catch (RemoteException e) {
e.rethrowFromSystemServer(); Log.e(TAG, "Fail to make dhcp server");
try {
cb.onDhcpServerCreated(STATUS_UNKNOWN_ERROR, null);
} catch (RemoteException re) { }
} }
} }
}; };

View File

@@ -328,13 +328,6 @@ public class UpstreamNetworkMonitor {
network, newNc)); network, newNc));
} }
// Log changes in upstream network signal strength, if available.
if (network.equals(mTetheringUpstreamNetwork) && newNc.hasSignalStrength()) {
final int newSignal = newNc.getSignalStrength();
final String prevSignal = getSignalStrength(prev.networkCapabilities);
mLog.logf("upstream network signal strength: %s -> %s", prevSignal, newSignal);
}
mNetworkMap.put(network, new UpstreamNetworkState( mNetworkMap.put(network, new UpstreamNetworkState(
prev.linkProperties, newNc, network)); prev.linkProperties, newNc, network));
// TODO: If sufficient information is available to select a more // TODO: If sufficient information is available to select a more
@@ -557,11 +550,6 @@ public class UpstreamNetworkMonitor {
return prefixSet; return prefixSet;
} }
private static String getSignalStrength(NetworkCapabilities nc) {
if (nc == null || !nc.hasSignalStrength()) return "unknown";
return Integer.toString(nc.getSignalStrength());
}
private static boolean isCellular(UpstreamNetworkState ns) { private static boolean isCellular(UpstreamNetworkState ns) {
return (ns != null) && isCellular(ns.networkCapabilities); return (ns != null) && isCellular(ns.networkCapabilities);
} }

View File

@@ -18,8 +18,6 @@ package android.net.dhcp;
import static android.net.InetAddresses.parseNumericAddress; import static android.net.InetAddresses.parseNumericAddress;
import static com.google.android.collect.Sets.newHashSet;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
@@ -34,6 +32,8 @@ import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import java.net.Inet4Address; import java.net.Inet4Address;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.IntStream; import java.util.stream.IntStream;
@@ -47,9 +47,10 @@ public class DhcpServingParamsParcelExtTest {
private static final int TEST_LEASE_TIME_SECS = 120; private static final int TEST_LEASE_TIME_SECS = 120;
private static final int TEST_MTU = 1000; private static final int TEST_MTU = 1000;
private static final Set<Inet4Address> TEST_ADDRESS_SET = private static final Set<Inet4Address> TEST_ADDRESS_SET =
newHashSet(inet4Addr("192.168.1.123"), inet4Addr("192.168.1.124")); new HashSet<Inet4Address>(Arrays.asList(
new Inet4Address[] {inet4Addr("192.168.1.123"), inet4Addr("192.168.1.124")}));
private static final Set<Integer> TEST_ADDRESS_SET_PARCELED = private static final Set<Integer> TEST_ADDRESS_SET_PARCELED =
newHashSet(0xc0a8017b, 0xc0a8017c); new HashSet<Integer>(Arrays.asList(new Integer[] {0xc0a8017b, 0xc0a8017c}));
private DhcpServingParamsParcelExt mParcel; private DhcpServingParamsParcelExt mParcel;

View File

@@ -510,8 +510,10 @@ public class IpServerTest {
} }
assertNotNull("missing IPv4 address", addr4); assertNotNull("missing IPv4 address", addr4);
final IpPrefix destination = new IpPrefix(addr4.getAddress(), addr4.getPrefixLength());
// Assert the presence of the associated directly connected route. // Assert the presence of the associated directly connected route.
final RouteInfo directlyConnected = new RouteInfo(addr4, null, lp.getInterfaceName()); final RouteInfo directlyConnected = new RouteInfo(destination, null, lp.getInterfaceName(),
RouteInfo.RTN_UNICAST);
assertTrue("missing directly connected route: '" + directlyConnected.toString() + "'", assertTrue("missing directly connected route: '" + directlyConnected.toString() + "'",
lp.getRoutes().contains(directlyConnected)); lp.getRoutes().contains(directlyConnected));
} }

View File

@@ -21,6 +21,7 @@ import static android.net.NetworkStats.STATS_PER_IFACE;
import static android.net.NetworkStats.STATS_PER_UID; import static android.net.NetworkStats.STATS_PER_UID;
import static android.net.NetworkStats.TAG_NONE; import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL; import static android.net.NetworkStats.UID_ALL;
import static android.net.RouteInfo.RTN_UNICAST;
import static android.net.TrafficStats.UID_TETHERING; import static android.net.TrafficStats.UID_TETHERING;
import static android.provider.Settings.Global.TETHER_OFFLOAD_DISABLED; import static android.provider.Settings.Global.TETHER_OFFLOAD_DISABLED;
@@ -269,7 +270,7 @@ public class OffloadControllerTest {
final String ipv4Addr = "192.0.2.5"; final String ipv4Addr = "192.0.2.5";
final String linkAddr = ipv4Addr + "/24"; final String linkAddr = ipv4Addr + "/24";
lp.addLinkAddress(new LinkAddress(linkAddr)); lp.addLinkAddress(new LinkAddress(linkAddr));
lp.addRoute(new RouteInfo(new IpPrefix("192.0.2.0/24"))); lp.addRoute(new RouteInfo(new IpPrefix("192.0.2.0/24"), null, null, RTN_UNICAST));
offload.setUpstreamLinkProperties(lp); offload.setUpstreamLinkProperties(lp);
// IPv4 prefixes and addresses on the upstream are simply left as whole // IPv4 prefixes and addresses on the upstream are simply left as whole
// prefixes (already passed in from UpstreamNetworkMonitor code). If a // prefixes (already passed in from UpstreamNetworkMonitor code). If a
@@ -285,7 +286,7 @@ public class OffloadControllerTest {
inOrder.verifyNoMoreInteractions(); inOrder.verifyNoMoreInteractions();
final String ipv4Gateway = "192.0.2.1"; final String ipv4Gateway = "192.0.2.1";
lp.addRoute(new RouteInfo(InetAddress.getByName(ipv4Gateway))); lp.addRoute(new RouteInfo(null, InetAddress.getByName(ipv4Gateway), null, RTN_UNICAST));
offload.setUpstreamLinkProperties(lp); offload.setUpstreamLinkProperties(lp);
// No change in local addresses means no call to setLocalPrefixes(). // No change in local addresses means no call to setLocalPrefixes().
inOrder.verify(mHardware, never()).setLocalPrefixes(mStringArrayCaptor.capture()); inOrder.verify(mHardware, never()).setLocalPrefixes(mStringArrayCaptor.capture());
@@ -296,7 +297,7 @@ public class OffloadControllerTest {
inOrder.verifyNoMoreInteractions(); inOrder.verifyNoMoreInteractions();
final String ipv6Gw1 = "fe80::cafe"; final String ipv6Gw1 = "fe80::cafe";
lp.addRoute(new RouteInfo(InetAddress.getByName(ipv6Gw1))); lp.addRoute(new RouteInfo(null, InetAddress.getByName(ipv6Gw1), null, RTN_UNICAST));
offload.setUpstreamLinkProperties(lp); offload.setUpstreamLinkProperties(lp);
// No change in local addresses means no call to setLocalPrefixes(). // No change in local addresses means no call to setLocalPrefixes().
inOrder.verify(mHardware, never()).setLocalPrefixes(mStringArrayCaptor.capture()); inOrder.verify(mHardware, never()).setLocalPrefixes(mStringArrayCaptor.capture());
@@ -310,7 +311,7 @@ public class OffloadControllerTest {
inOrder.verifyNoMoreInteractions(); inOrder.verifyNoMoreInteractions();
final String ipv6Gw2 = "fe80::d00d"; final String ipv6Gw2 = "fe80::d00d";
lp.addRoute(new RouteInfo(InetAddress.getByName(ipv6Gw2))); lp.addRoute(new RouteInfo(null, InetAddress.getByName(ipv6Gw2), null, RTN_UNICAST));
offload.setUpstreamLinkProperties(lp); offload.setUpstreamLinkProperties(lp);
// No change in local addresses means no call to setLocalPrefixes(). // No change in local addresses means no call to setLocalPrefixes().
inOrder.verify(mHardware, never()).setLocalPrefixes(mStringArrayCaptor.capture()); inOrder.verify(mHardware, never()).setLocalPrefixes(mStringArrayCaptor.capture());
@@ -327,8 +328,10 @@ public class OffloadControllerTest {
final LinkProperties stacked = new LinkProperties(); final LinkProperties stacked = new LinkProperties();
stacked.setInterfaceName("stacked"); stacked.setInterfaceName("stacked");
stacked.addLinkAddress(new LinkAddress("192.0.2.129/25")); stacked.addLinkAddress(new LinkAddress("192.0.2.129/25"));
stacked.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254"))); stacked.addRoute(new RouteInfo(null, InetAddress.getByName("192.0.2.254"), null,
stacked.addRoute(new RouteInfo(InetAddress.getByName("fe80::bad:f00"))); RTN_UNICAST));
stacked.addRoute(new RouteInfo(null, InetAddress.getByName("fe80::bad:f00"), null,
RTN_UNICAST));
assertTrue(lp.addStackedLink(stacked)); assertTrue(lp.addStackedLink(stacked));
offload.setUpstreamLinkProperties(lp); offload.setUpstreamLinkProperties(lp);
// No change in local addresses means no call to setLocalPrefixes(). // No change in local addresses means no call to setLocalPrefixes().
@@ -348,7 +351,7 @@ public class OffloadControllerTest {
// removed from "local prefixes" and /128s added for the upstream IPv6 // removed from "local prefixes" and /128s added for the upstream IPv6
// addresses. This is not yet implemented, and for now we simply // addresses. This is not yet implemented, and for now we simply
// expect to see these /128s. // expect to see these /128s.
lp.addRoute(new RouteInfo(new IpPrefix("2001:db8::/64"))); lp.addRoute(new RouteInfo(new IpPrefix("2001:db8::/64"), null, null, RTN_UNICAST));
// "2001:db8::/64" plus "assigned" ASCII in hex // "2001:db8::/64" plus "assigned" ASCII in hex
lp.addLinkAddress(new LinkAddress("2001:db8::6173:7369:676e:6564/64")); lp.addLinkAddress(new LinkAddress("2001:db8::6173:7369:676e:6564/64"));
// "2001:db8::/64" plus "random" ASCII in hex // "2001:db8::/64" plus "random" ASCII in hex
@@ -574,13 +577,15 @@ public class OffloadControllerTest {
final LinkProperties usbLinkProperties = new LinkProperties(); final LinkProperties usbLinkProperties = new LinkProperties();
usbLinkProperties.setInterfaceName(RNDIS0); usbLinkProperties.setInterfaceName(RNDIS0);
usbLinkProperties.addLinkAddress(new LinkAddress("192.168.42.1/24")); usbLinkProperties.addLinkAddress(new LinkAddress("192.168.42.1/24"));
usbLinkProperties.addRoute(new RouteInfo(new IpPrefix(USB_PREFIX))); usbLinkProperties.addRoute(
new RouteInfo(new IpPrefix(USB_PREFIX), null, null, RTN_UNICAST));
offload.notifyDownstreamLinkProperties(usbLinkProperties); offload.notifyDownstreamLinkProperties(usbLinkProperties);
inOrder.verify(mHardware, times(1)).addDownstreamPrefix(RNDIS0, USB_PREFIX); inOrder.verify(mHardware, times(1)).addDownstreamPrefix(RNDIS0, USB_PREFIX);
inOrder.verifyNoMoreInteractions(); inOrder.verifyNoMoreInteractions();
// [2] Routes for IPv6 link-local prefixes should never be added. // [2] Routes for IPv6 link-local prefixes should never be added.
usbLinkProperties.addRoute(new RouteInfo(new IpPrefix(IPV6_LINKLOCAL))); usbLinkProperties.addRoute(
new RouteInfo(new IpPrefix(IPV6_LINKLOCAL), null, null, RTN_UNICAST));
offload.notifyDownstreamLinkProperties(usbLinkProperties); offload.notifyDownstreamLinkProperties(usbLinkProperties);
inOrder.verify(mHardware, never()).addDownstreamPrefix(eq(RNDIS0), anyString()); inOrder.verify(mHardware, never()).addDownstreamPrefix(eq(RNDIS0), anyString());
inOrder.verifyNoMoreInteractions(); inOrder.verifyNoMoreInteractions();
@@ -588,7 +593,8 @@ public class OffloadControllerTest {
// [3] Add an IPv6 prefix for good measure. Only new offload-able // [3] Add an IPv6 prefix for good measure. Only new offload-able
// prefixes should be passed to the HAL. // prefixes should be passed to the HAL.
usbLinkProperties.addLinkAddress(new LinkAddress("2001:db8::1/64")); usbLinkProperties.addLinkAddress(new LinkAddress("2001:db8::1/64"));
usbLinkProperties.addRoute(new RouteInfo(new IpPrefix(IPV6_DOC_PREFIX))); usbLinkProperties.addRoute(
new RouteInfo(new IpPrefix(IPV6_DOC_PREFIX), null, null, RTN_UNICAST));
offload.notifyDownstreamLinkProperties(usbLinkProperties); offload.notifyDownstreamLinkProperties(usbLinkProperties);
inOrder.verify(mHardware, times(1)).addDownstreamPrefix(RNDIS0, IPV6_DOC_PREFIX); inOrder.verify(mHardware, times(1)).addDownstreamPrefix(RNDIS0, IPV6_DOC_PREFIX);
inOrder.verifyNoMoreInteractions(); inOrder.verifyNoMoreInteractions();
@@ -601,8 +607,10 @@ public class OffloadControllerTest {
// [5] Differences in local routes are converted into addDownstream() // [5] Differences in local routes are converted into addDownstream()
// and removeDownstream() invocations accordingly. // and removeDownstream() invocations accordingly.
usbLinkProperties.removeRoute(new RouteInfo(new IpPrefix(IPV6_DOC_PREFIX), null, RNDIS0)); usbLinkProperties.removeRoute(
usbLinkProperties.addRoute(new RouteInfo(new IpPrefix(IPV6_DISCARD_PREFIX))); new RouteInfo(new IpPrefix(IPV6_DOC_PREFIX), null, RNDIS0, RTN_UNICAST));
usbLinkProperties.addRoute(
new RouteInfo(new IpPrefix(IPV6_DISCARD_PREFIX), null, null, RTN_UNICAST));
offload.notifyDownstreamLinkProperties(usbLinkProperties); offload.notifyDownstreamLinkProperties(usbLinkProperties);
inOrder.verify(mHardware, times(1)).removeDownstreamPrefix(RNDIS0, IPV6_DOC_PREFIX); inOrder.verify(mHardware, times(1)).removeDownstreamPrefix(RNDIS0, IPV6_DOC_PREFIX);
inOrder.verify(mHardware, times(1)).addDownstreamPrefix(RNDIS0, IPV6_DISCARD_PREFIX); inOrder.verify(mHardware, times(1)).addDownstreamPrefix(RNDIS0, IPV6_DISCARD_PREFIX);
@@ -680,19 +688,23 @@ public class OffloadControllerTest {
final LinkProperties usbLinkProperties = new LinkProperties(); final LinkProperties usbLinkProperties = new LinkProperties();
usbLinkProperties.setInterfaceName(RNDIS0); usbLinkProperties.setInterfaceName(RNDIS0);
usbLinkProperties.addLinkAddress(new LinkAddress("192.168.42.1/24")); usbLinkProperties.addLinkAddress(new LinkAddress("192.168.42.1/24"));
usbLinkProperties.addRoute(new RouteInfo(new IpPrefix(USB_PREFIX))); usbLinkProperties.addRoute(
new RouteInfo(new IpPrefix(USB_PREFIX), null, null, RTN_UNICAST));
offload.notifyDownstreamLinkProperties(usbLinkProperties); offload.notifyDownstreamLinkProperties(usbLinkProperties);
final LinkProperties wifiLinkProperties = new LinkProperties(); final LinkProperties wifiLinkProperties = new LinkProperties();
wifiLinkProperties.setInterfaceName(WLAN0); wifiLinkProperties.setInterfaceName(WLAN0);
wifiLinkProperties.addLinkAddress(new LinkAddress("192.168.43.1/24")); wifiLinkProperties.addLinkAddress(new LinkAddress("192.168.43.1/24"));
wifiLinkProperties.addRoute(new RouteInfo(new IpPrefix(WIFI_PREFIX))); wifiLinkProperties.addRoute(
wifiLinkProperties.addRoute(new RouteInfo(new IpPrefix(IPV6_LINKLOCAL))); new RouteInfo(new IpPrefix(WIFI_PREFIX), null, null, RTN_UNICAST));
wifiLinkProperties.addRoute(
new RouteInfo(new IpPrefix(IPV6_LINKLOCAL), null, null, RTN_UNICAST));
// Use a benchmark prefix (RFC 5180 + erratum), since the documentation // Use a benchmark prefix (RFC 5180 + erratum), since the documentation
// prefix is included in the excluded prefix list. // prefix is included in the excluded prefix list.
wifiLinkProperties.addLinkAddress(new LinkAddress("2001:2::1/64")); wifiLinkProperties.addLinkAddress(new LinkAddress("2001:2::1/64"));
wifiLinkProperties.addLinkAddress(new LinkAddress("2001:2::2/64")); wifiLinkProperties.addLinkAddress(new LinkAddress("2001:2::2/64"));
wifiLinkProperties.addRoute(new RouteInfo(new IpPrefix("2001:2::/64"))); wifiLinkProperties.addRoute(
new RouteInfo(new IpPrefix("2001:2::/64"), null, null, RTN_UNICAST));
offload.notifyDownstreamLinkProperties(wifiLinkProperties); offload.notifyDownstreamLinkProperties(wifiLinkProperties);
offload.removeDownstreamInterface(RNDIS0); offload.removeDownstreamInterface(RNDIS0);

View File

@@ -34,7 +34,6 @@ import static com.android.internal.R.array.config_tether_wifi_regexs;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.content.ContentResolver; import android.content.ContentResolver;
@@ -145,7 +144,7 @@ public class TetheringConfigurationTest {
@Test @Test
public void testDunFromTelephonyManagerMeansDun() { public void testDunFromTelephonyManagerMeansDun() {
when(mTelephonyManager.isTetheringApnRequired(anyInt())).thenReturn(true); when(mTelephonyManager.isTetheringApnRequired()).thenReturn(true);
final TetheringConfiguration cfgWifi = getTetheringConfiguration(TYPE_WIFI); final TetheringConfiguration cfgWifi = getTetheringConfiguration(TYPE_WIFI);
final TetheringConfiguration cfgMobileWifiHipri = getTetheringConfiguration( final TetheringConfiguration cfgMobileWifiHipri = getTetheringConfiguration(
@@ -169,7 +168,7 @@ public class TetheringConfigurationTest {
@Test @Test
public void testDunNotRequiredFromTelephonyManagerMeansNoDun() { public void testDunNotRequiredFromTelephonyManagerMeansNoDun() {
when(mTelephonyManager.isTetheringApnRequired(anyInt())).thenReturn(false); when(mTelephonyManager.isTetheringApnRequired()).thenReturn(false);
final TetheringConfiguration cfgWifi = getTetheringConfiguration(TYPE_WIFI); final TetheringConfiguration cfgWifi = getTetheringConfiguration(TYPE_WIFI);
final TetheringConfiguration cfgMobileWifiHipri = getTetheringConfiguration( final TetheringConfiguration cfgMobileWifiHipri = getTetheringConfiguration(
@@ -212,7 +211,7 @@ public class TetheringConfigurationTest {
@Test @Test
public void testNoDefinedUpstreamTypesAddsEthernet() { public void testNoDefinedUpstreamTypesAddsEthernet() {
when(mResources.getIntArray(config_tether_upstream_types)).thenReturn(new int[]{}); when(mResources.getIntArray(config_tether_upstream_types)).thenReturn(new int[]{});
when(mTelephonyManager.isTetheringApnRequired(anyInt())).thenReturn(false); when(mTelephonyManager.isTetheringApnRequired()).thenReturn(false);
final TetheringConfiguration cfg = new TetheringConfiguration( final TetheringConfiguration cfg = new TetheringConfiguration(
mMockContext, mLog, INVALID_SUBSCRIPTION_ID); mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
@@ -235,7 +234,7 @@ public class TetheringConfigurationTest {
public void testDefinedUpstreamTypesSansEthernetAddsEthernet() { public void testDefinedUpstreamTypesSansEthernetAddsEthernet() {
when(mResources.getIntArray(config_tether_upstream_types)).thenReturn( when(mResources.getIntArray(config_tether_upstream_types)).thenReturn(
new int[]{TYPE_WIFI, TYPE_MOBILE_HIPRI}); new int[]{TYPE_WIFI, TYPE_MOBILE_HIPRI});
when(mTelephonyManager.isTetheringApnRequired(anyInt())).thenReturn(false); when(mTelephonyManager.isTetheringApnRequired()).thenReturn(false);
final TetheringConfiguration cfg = new TetheringConfiguration( final TetheringConfiguration cfg = new TetheringConfiguration(
mMockContext, mLog, INVALID_SUBSCRIPTION_ID); mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
@@ -253,7 +252,7 @@ public class TetheringConfigurationTest {
public void testDefinedUpstreamTypesWithEthernetDoesNotAddEthernet() { public void testDefinedUpstreamTypesWithEthernetDoesNotAddEthernet() {
when(mResources.getIntArray(config_tether_upstream_types)) when(mResources.getIntArray(config_tether_upstream_types))
.thenReturn(new int[]{TYPE_WIFI, TYPE_ETHERNET, TYPE_MOBILE_HIPRI}); .thenReturn(new int[]{TYPE_WIFI, TYPE_ETHERNET, TYPE_MOBILE_HIPRI});
when(mTelephonyManager.isTetheringApnRequired(anyInt())).thenReturn(false); when(mTelephonyManager.isTetheringApnRequired()).thenReturn(false);
final TetheringConfiguration cfg = new TetheringConfiguration( final TetheringConfiguration cfg = new TetheringConfiguration(
mMockContext, mLog, INVALID_SUBSCRIPTION_ID); mMockContext, mLog, INVALID_SUBSCRIPTION_ID);

View File

@@ -28,6 +28,7 @@ import static android.net.ConnectivityManager.TETHERING_WIFI;
import static android.net.ConnectivityManager.TETHER_ERROR_NO_ERROR; import static android.net.ConnectivityManager.TETHER_ERROR_NO_ERROR;
import static android.net.ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE; import static android.net.ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE;
import static android.net.ConnectivityManager.TYPE_WIFI_P2P; import static android.net.ConnectivityManager.TYPE_WIFI_P2P;
import static android.net.RouteInfo.RTN_UNICAST;
import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS; import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME; import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE; import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
@@ -72,6 +73,7 @@ import android.net.INetd;
import android.net.INetworkPolicyManager; import android.net.INetworkPolicyManager;
import android.net.INetworkStatsService; import android.net.INetworkStatsService;
import android.net.ITetheringEventCallback; import android.net.ITetheringEventCallback;
import android.net.InetAddresses;
import android.net.InterfaceConfiguration; import android.net.InterfaceConfiguration;
import android.net.IpPrefix; import android.net.IpPrefix;
import android.net.LinkAddress; import android.net.LinkAddress;
@@ -81,7 +83,6 @@ import android.net.Network;
import android.net.NetworkCapabilities; import android.net.NetworkCapabilities;
import android.net.NetworkInfo; import android.net.NetworkInfo;
import android.net.NetworkRequest; import android.net.NetworkRequest;
import android.net.NetworkUtils;
import android.net.RouteInfo; import android.net.RouteInfo;
import android.net.TetherStatesParcel; import android.net.TetherStatesParcel;
import android.net.TetheringConfigurationParcel; import android.net.TetheringConfigurationParcel;
@@ -365,23 +366,26 @@ public class TetheringTest {
if (withIPv4) { if (withIPv4) {
prop.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), prop.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0),
NetworkUtils.numericToInetAddress("10.0.0.1"), TEST_MOBILE_IFNAME)); InetAddresses.parseNumericAddress("10.0.0.1"),
TEST_MOBILE_IFNAME, RTN_UNICAST));
} }
if (withIPv6) { if (withIPv6) {
prop.addDnsServer(NetworkUtils.numericToInetAddress("2001:db8::2")); prop.addDnsServer(InetAddresses.parseNumericAddress("2001:db8::2"));
prop.addLinkAddress( prop.addLinkAddress(
new LinkAddress(NetworkUtils.numericToInetAddress("2001:db8::"), new LinkAddress(InetAddresses.parseNumericAddress("2001:db8::"),
NetworkConstants.RFC7421_PREFIX_LENGTH)); NetworkConstants.RFC7421_PREFIX_LENGTH));
prop.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), prop.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0),
NetworkUtils.numericToInetAddress("2001:db8::1"), TEST_MOBILE_IFNAME)); InetAddresses.parseNumericAddress("2001:db8::1"),
TEST_MOBILE_IFNAME, RTN_UNICAST));
} }
if (with464xlat) { if (with464xlat) {
final LinkProperties stackedLink = new LinkProperties(); final LinkProperties stackedLink = new LinkProperties();
stackedLink.setInterfaceName(TEST_XLAT_MOBILE_IFNAME); stackedLink.setInterfaceName(TEST_XLAT_MOBILE_IFNAME);
stackedLink.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), stackedLink.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0),
NetworkUtils.numericToInetAddress("192.0.0.1"), TEST_XLAT_MOBILE_IFNAME)); InetAddresses.parseNumericAddress("192.0.0.1"),
TEST_XLAT_MOBILE_IFNAME, RTN_UNICAST));
prop.addStackedLink(stackedLink); prop.addStackedLink(stackedLink);
} }
@@ -1210,12 +1214,12 @@ public class TetheringTest {
@Test @Test
public void testMultiSimAware() throws Exception { public void testMultiSimAware() throws Exception {
final TetheringConfiguration initailConfig = mTethering.getTetheringConfiguration(); final TetheringConfiguration initailConfig = mTethering.getTetheringConfiguration();
assertEquals(INVALID_SUBSCRIPTION_ID, initailConfig.subId); assertEquals(INVALID_SUBSCRIPTION_ID, initailConfig.activeDataSubId);
final int fakeSubId = 1234; final int fakeSubId = 1234;
mPhoneStateListener.onActiveDataSubscriptionIdChanged(fakeSubId); mPhoneStateListener.onActiveDataSubscriptionIdChanged(fakeSubId);
final TetheringConfiguration newConfig = mTethering.getTetheringConfiguration(); final TetheringConfiguration newConfig = mTethering.getTetheringConfiguration();
assertEquals(fakeSubId, newConfig.subId); assertEquals(fakeSubId, newConfig.activeDataSubId);
} }
private void workingWifiP2pGroupOwner( private void workingWifiP2pGroupOwner(