Merge "Replace inexact alarm setRepeasting with setExact alarm"
diff --git a/Tethering/bpf_progs/offload.c b/Tethering/bpf_progs/offload.c
index 336d27a..51fed76 100644
--- a/Tethering/bpf_progs/offload.c
+++ b/Tethering/bpf_progs/offload.c
@@ -80,7 +80,7 @@
} while(0)
#define TC_DROP(counter) COUNT_AND_RETURN(counter, TC_ACT_SHOT)
-#define TC_PUNT(counter) COUNT_AND_RETURN(counter, TC_ACT_OK)
+#define TC_PUNT(counter) COUNT_AND_RETURN(counter, TC_ACT_PIPE)
#define XDP_DROP(counter) COUNT_AND_RETURN(counter, XDP_DROP)
#define XDP_PUNT(counter) COUNT_AND_RETURN(counter, XDP_PASS)
@@ -108,10 +108,10 @@
static inline __always_inline int do_forward6(struct __sk_buff* skb, const bool is_ethernet,
const bool downstream) {
// Must be meta-ethernet IPv6 frame
- if (skb->protocol != htons(ETH_P_IPV6)) return TC_ACT_OK;
+ if (skb->protocol != htons(ETH_P_IPV6)) return TC_ACT_PIPE;
// Require ethernet dst mac address to be our unicast address.
- if (is_ethernet && (skb->pkt_type != PACKET_HOST)) return TC_ACT_OK;
+ if (is_ethernet && (skb->pkt_type != PACKET_HOST)) return TC_ACT_PIPE;
const int l2_header_size = is_ethernet ? sizeof(struct ethhdr) : 0;
@@ -127,10 +127,10 @@
struct ipv6hdr* ip6 = is_ethernet ? (void*)(eth + 1) : data;
// Must have (ethernet and) ipv6 header
- if (data + l2_header_size + sizeof(*ip6) > data_end) return TC_ACT_OK;
+ if (data + l2_header_size + sizeof(*ip6) > data_end) return TC_ACT_PIPE;
// Ethertype - if present - must be IPv6
- if (is_ethernet && (eth->h_proto != htons(ETH_P_IPV6))) return TC_ACT_OK;
+ if (is_ethernet && (eth->h_proto != htons(ETH_P_IPV6))) return TC_ACT_PIPE;
// IP version must be 6
if (ip6->version != 6) TC_PUNT(INVALID_IP_VERSION);
@@ -182,7 +182,7 @@
: bpf_tether_upstream6_map_lookup_elem(&ku);
// If we don't find any offload information then simply let the core stack handle it...
- if (!v) return TC_ACT_OK;
+ if (!v) return TC_ACT_PIPE;
uint32_t stat_and_limit_k = downstream ? skb->ifindex : v->oif;
@@ -337,13 +337,13 @@
DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_downstream6_rawip$stub", AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_downstream6_rawip_stub, KVER_NONE, KVER(5, 4, 0))
(struct __sk_buff* skb) {
- return TC_ACT_OK;
+ return TC_ACT_PIPE;
}
DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_upstream6_rawip$stub", AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_upstream6_rawip_stub, KVER_NONE, KVER(5, 4, 0))
(struct __sk_buff* skb) {
- return TC_ACT_OK;
+ return TC_ACT_PIPE;
}
// ----- IPv4 Support -----
@@ -355,10 +355,10 @@
static inline __always_inline int do_forward4(struct __sk_buff* skb, const bool is_ethernet,
const bool downstream, const bool updatetime) {
// Require ethernet dst mac address to be our unicast address.
- if (is_ethernet && (skb->pkt_type != PACKET_HOST)) return TC_ACT_OK;
+ if (is_ethernet && (skb->pkt_type != PACKET_HOST)) return TC_ACT_PIPE;
// Must be meta-ethernet IPv4 frame
- if (skb->protocol != htons(ETH_P_IP)) return TC_ACT_OK;
+ if (skb->protocol != htons(ETH_P_IP)) return TC_ACT_PIPE;
const int l2_header_size = is_ethernet ? sizeof(struct ethhdr) : 0;
@@ -374,10 +374,10 @@
struct iphdr* ip = is_ethernet ? (void*)(eth + 1) : data;
// Must have (ethernet and) ipv4 header
- if (data + l2_header_size + sizeof(*ip) > data_end) return TC_ACT_OK;
+ if (data + l2_header_size + sizeof(*ip) > data_end) return TC_ACT_PIPE;
// Ethertype - if present - must be IPv4
- if (is_ethernet && (eth->h_proto != htons(ETH_P_IP))) return TC_ACT_OK;
+ if (is_ethernet && (eth->h_proto != htons(ETH_P_IP))) return TC_ACT_PIPE;
// IP version must be 4
if (ip->version != 4) TC_PUNT(INVALID_IP_VERSION);
@@ -495,7 +495,7 @@
: bpf_tether_upstream4_map_lookup_elem(&k);
// If we don't find any offload information then simply let the core stack handle it...
- if (!v) return TC_ACT_OK;
+ if (!v) return TC_ACT_PIPE;
uint32_t stat_and_limit_k = downstream ? skb->ifindex : v->oif;
@@ -749,13 +749,13 @@
DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_downstream4_rawip$stub", AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_downstream4_rawip_stub, KVER_NONE, KVER(5, 4, 0))
(struct __sk_buff* skb) {
- return TC_ACT_OK;
+ return TC_ACT_PIPE;
}
DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_upstream4_rawip$stub", AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_upstream4_rawip_stub, KVER_NONE, KVER(5, 4, 0))
(struct __sk_buff* skb) {
- return TC_ACT_OK;
+ return TC_ACT_PIPE;
}
// ETHER: 4.9-P/Q kernel
@@ -763,13 +763,13 @@
DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_downstream4_ether$stub", AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_downstream4_ether_stub, KVER_NONE, KVER(4, 14, 0))
(struct __sk_buff* skb) {
- return TC_ACT_OK;
+ return TC_ACT_PIPE;
}
DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_upstream4_ether$stub", AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_upstream4_ether_stub, KVER_NONE, KVER(4, 14, 0))
(struct __sk_buff* skb) {
- return TC_ACT_OK;
+ return TC_ACT_PIPE;
}
// ----- XDP Support -----
diff --git a/Tethering/src/android/net/ip/IpServer.java b/Tethering/src/android/net/ip/IpServer.java
index 859f23a..cf49683 100644
--- a/Tethering/src/android/net/ip/IpServer.java
+++ b/Tethering/src/android/net/ip/IpServer.java
@@ -52,7 +52,6 @@
import android.net.util.InterfaceSet;
import android.net.util.PrefixUtils;
import android.net.util.SharedLog;
-import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -67,6 +66,7 @@
import com.android.internal.util.MessageUtils;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
+import com.android.modules.utils.build.SdkLevel;
import com.android.networkstack.tethering.BpfCoordinator;
import com.android.networkstack.tethering.BpfCoordinator.ClientInfo;
import com.android.networkstack.tethering.BpfCoordinator.Ipv6ForwardingRule;
@@ -676,9 +676,7 @@
return false;
}
- // TODO: use ShimUtils instead of explicitly checking the version here.
- if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R || "S".equals(Build.VERSION.CODENAME)
- || "T".equals(Build.VERSION.CODENAME)) {
+ if (SdkLevel.isAtLeastS()) {
// DAD Proxy starts forwarding packets after IPv6 upstream is present.
mDadProxy = mDeps.getDadProxy(getHandler(), mInterfaceParams);
}
diff --git a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
index 5b39a23..1df3e58 100644
--- a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
+++ b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
@@ -61,6 +61,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IndentingPrintWriter;
import com.android.modules.utils.build.SdkLevel;
+import com.android.net.module.util.CollectionUtils;
import com.android.net.module.util.NetworkStackConstants;
import com.android.net.module.util.Struct;
import com.android.net.module.util.netlink.ConntrackMessage;
@@ -131,6 +132,12 @@
@VisibleForTesting
static final int NF_CONNTRACK_UDP_TIMEOUT_STREAM = 180;
+ // List of TCP port numbers which aren't offloaded because the packets require the netfilter
+ // conntrack helper. See also TetherController::setForwardRules in netd.
+ @VisibleForTesting
+ static final short [] NON_OFFLOADED_UPSTREAM_IPV4_TCP_PORTS = new short [] {
+ 21 /* ftp */, 1723 /* pptp */};
+
@VisibleForTesting
enum StatsType {
STATS_PER_IFACE,
@@ -1556,7 +1563,15 @@
0 /* lastUsed, filled by bpf prog only */);
}
+ private boolean allowOffload(ConntrackEvent e) {
+ if (e.tupleOrig.protoNum != OsConstants.IPPROTO_TCP) return true;
+ return !CollectionUtils.contains(
+ NON_OFFLOADED_UPSTREAM_IPV4_TCP_PORTS, e.tupleOrig.dstPort);
+ }
+
public void accept(ConntrackEvent e) {
+ if (!allowOffload(e)) return;
+
final ClientInfo tetherClient = getClientInfo(e.tupleOrig.srcIp);
if (tetherClient == null) return;
diff --git a/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java b/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
index f1ddc6d..26297a2 100644
--- a/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
+++ b/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
@@ -17,6 +17,7 @@
package android.net;
import static android.Manifest.permission.ACCESS_NETWORK_STATE;
+import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS;
import static android.Manifest.permission.MANAGE_TEST_NETWORKS;
import static android.Manifest.permission.NETWORK_SETTINGS;
import static android.Manifest.permission.TETHER_PRIVILEGED;
@@ -121,9 +122,12 @@
@Before
public void setUp() throws Exception {
// Needed to create a TestNetworkInterface, to call requestTetheredInterface, and to receive
- // tethered client callbacks.
+ // tethered client callbacks. The restricted networks permission is needed to ensure that
+ // EthernetManager#isAvailable will correctly return true on devices where Ethernet is
+ // marked restricted, like cuttlefish.
mUiAutomation.adoptShellPermissionIdentity(
- MANAGE_TEST_NETWORKS, NETWORK_SETTINGS, TETHER_PRIVILEGED, ACCESS_NETWORK_STATE);
+ MANAGE_TEST_NETWORKS, NETWORK_SETTINGS, TETHER_PRIVILEGED, ACCESS_NETWORK_STATE,
+ CONNECTIVITY_USE_RESTRICTED_NETWORKS);
mRunTests = mTm.isTetheringSupported() && mEm != null;
assumeTrue(mRunTests);
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
index 6e96085..acc042b 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
@@ -43,6 +43,7 @@
import static com.android.networkstack.tethering.BpfCoordinator.CONNTRACK_TIMEOUT_UPDATE_INTERVAL_MS;
import static com.android.networkstack.tethering.BpfCoordinator.NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED;
import static com.android.networkstack.tethering.BpfCoordinator.NF_CONNTRACK_UDP_TIMEOUT_STREAM;
+import static com.android.networkstack.tethering.BpfCoordinator.NON_OFFLOADED_UPSTREAM_IPV4_TCP_PORTS;
import static com.android.networkstack.tethering.BpfCoordinator.StatsType;
import static com.android.networkstack.tethering.BpfCoordinator.StatsType.STATS_PER_IFACE;
import static com.android.networkstack.tethering.BpfCoordinator.StatsType.STATS_PER_UID;
@@ -51,6 +52,7 @@
import static com.android.networkstack.tethering.TetheringConfiguration.DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -95,6 +97,7 @@
import androidx.test.runner.AndroidJUnit4;
import com.android.dx.mockito.inline.extended.ExtendedMockito;
+import com.android.net.module.util.CollectionUtils;
import com.android.net.module.util.NetworkStackConstants;
import com.android.net.module.util.Struct;
import com.android.net.module.util.netlink.ConntrackMessage;
@@ -1369,7 +1372,7 @@
}
@NonNull
- private ConntrackEvent makeTestConntrackEvent(short msgType, int proto) {
+ private ConntrackEvent makeTestConntrackEvent(short msgType, int proto, short remotePort) {
if (msgType != IPCTNL_MSG_CT_NEW && msgType != IPCTNL_MSG_CT_DELETE) {
fail("Not support message type " + msgType);
}
@@ -1383,13 +1386,18 @@
return new ConntrackEvent(
(short) (NetlinkConstants.NFNL_SUBSYS_CTNETLINK << 8 | msgType),
new Tuple(new TupleIpv4(PRIVATE_ADDR, REMOTE_ADDR),
- new TupleProto((byte) proto, PRIVATE_PORT, REMOTE_PORT)),
+ new TupleProto((byte) proto, PRIVATE_PORT, remotePort)),
new Tuple(new TupleIpv4(REMOTE_ADDR, PUBLIC_ADDR),
- new TupleProto((byte) proto, REMOTE_PORT, PUBLIC_PORT)),
+ new TupleProto((byte) proto, remotePort, PUBLIC_PORT)),
status,
timeoutSec);
}
+ @NonNull
+ private ConntrackEvent makeTestConntrackEvent(short msgType, int proto) {
+ return makeTestConntrackEvent(msgType, proto, REMOTE_PORT);
+ }
+
private void setUpstreamInformationTo(final BpfCoordinator coordinator) {
final LinkProperties lp = new LinkProperties();
lp.setInterfaceName(UPSTREAM_IFACE);
@@ -1563,14 +1571,14 @@
bpfMap.insertEntry(tcpKey, tcpValue);
bpfMap.insertEntry(udpKey, udpValue);
- // [1] Don't refresh contrack timeout.
+ // [1] Don't refresh conntrack timeout.
setElapsedRealtimeNanos(expiredTime);
mTestLooper.moveTimeForward(CONNTRACK_TIMEOUT_UPDATE_INTERVAL_MS);
waitForIdle();
ExtendedMockito.verifyNoMoreInteractions(staticMockMarker(NetlinkSocket.class));
ExtendedMockito.clearInvocations(staticMockMarker(NetlinkSocket.class));
- // [2] Refresh contrack timeout.
+ // [2] Refresh conntrack timeout.
setElapsedRealtimeNanos(validTime);
mTestLooper.moveTimeForward(CONNTRACK_TIMEOUT_UPDATE_INTERVAL_MS);
waitForIdle();
@@ -1587,7 +1595,7 @@
ExtendedMockito.verifyNoMoreInteractions(staticMockMarker(NetlinkSocket.class));
ExtendedMockito.clearInvocations(staticMockMarker(NetlinkSocket.class));
- // [3] Don't refresh contrack timeout if polling stopped.
+ // [3] Don't refresh conntrack timeout if polling stopped.
coordinator.stopPolling();
mTestLooper.moveTimeForward(CONNTRACK_TIMEOUT_UPDATE_INTERVAL_MS);
waitForIdle();
@@ -1629,4 +1637,39 @@
checkRefreshConntrackTimeout(bpfDownstream4Map, tcpKey, tcpValue, udpKey, udpValue);
}
+
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.R)
+ public void testNotAllowOffloadByConntrackMessageDestinationPort() throws Exception {
+ final BpfCoordinator coordinator = makeBpfCoordinator();
+ initBpfCoordinatorForRule4(coordinator);
+
+ final short offloadedPort = 42;
+ assertFalse(CollectionUtils.contains(NON_OFFLOADED_UPSTREAM_IPV4_TCP_PORTS,
+ offloadedPort));
+ mConsumer.accept(makeTestConntrackEvent(IPCTNL_MSG_CT_NEW, IPPROTO_TCP, offloadedPort));
+ verify(mBpfUpstream4Map).insertEntry(any(), any());
+ verify(mBpfDownstream4Map).insertEntry(any(), any());
+ clearInvocations(mBpfUpstream4Map, mBpfDownstream4Map);
+
+ for (final short port : NON_OFFLOADED_UPSTREAM_IPV4_TCP_PORTS) {
+ mConsumer.accept(makeTestConntrackEvent(IPCTNL_MSG_CT_NEW, IPPROTO_TCP, port));
+ verify(mBpfUpstream4Map, never()).insertEntry(any(), any());
+ verify(mBpfDownstream4Map, never()).insertEntry(any(), any());
+
+ mConsumer.accept(makeTestConntrackEvent(IPCTNL_MSG_CT_DELETE, IPPROTO_TCP, port));
+ verify(mBpfUpstream4Map, never()).deleteEntry(any());
+ verify(mBpfDownstream4Map, never()).deleteEntry(any());
+
+ mConsumer.accept(makeTestConntrackEvent(IPCTNL_MSG_CT_NEW, IPPROTO_UDP, port));
+ verify(mBpfUpstream4Map).insertEntry(any(), any());
+ verify(mBpfDownstream4Map).insertEntry(any(), any());
+ clearInvocations(mBpfUpstream4Map, mBpfDownstream4Map);
+
+ mConsumer.accept(makeTestConntrackEvent(IPCTNL_MSG_CT_DELETE, IPPROTO_UDP, port));
+ verify(mBpfUpstream4Map).deleteEntry(any());
+ verify(mBpfDownstream4Map).deleteEntry(any());
+ clearInvocations(mBpfUpstream4Map, mBpfDownstream4Map);
+ }
+ }
}
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
deleted file mode 100644
index ff90e78..0000000
--- a/core/java/android/net/ConnectivityManager.java
+++ /dev/null
@@ -1,2416 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.net;
-
-import static com.android.internal.util.Preconditions.checkNotNull;
-
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-import android.net.NetworkUtils;
-import android.os.Binder;
-import android.os.Build.VERSION_CODES;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.INetworkActivityListener;
-import android.os.INetworkManagementService;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.provider.Settings;
-import android.telephony.TelephonyManager;
-import android.util.ArrayMap;
-import android.util.Log;
-
-import com.android.internal.telephony.ITelephony;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.util.Protocol;
-
-import java.net.InetAddress;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.HashMap;
-
-/**
- * Class that answers queries about the state of network connectivity. It also
- * notifies applications when network connectivity changes. Get an instance
- * of this class by calling
- * {@link android.content.Context#getSystemService(String) Context.getSystemService(Context.CONNECTIVITY_SERVICE)}.
- * <p>
- * The primary responsibilities of this class are to:
- * <ol>
- * <li>Monitor network connections (Wi-Fi, GPRS, UMTS, etc.)</li>
- * <li>Send broadcast intents when network connectivity changes</li>
- * <li>Attempt to "fail over" to another network when connectivity to a network
- * is lost</li>
- * <li>Provide an API that allows applications to query the coarse-grained or fine-grained
- * state of the available networks</li>
- * <li>Provide an API that allows applications to request and select networks for their data
- * traffic</li>
- * </ol>
- */
-public class ConnectivityManager {
- private static final String TAG = "ConnectivityManager";
-
- /**
- * A change in network connectivity has occurred. A default connection has either
- * been established or lost. The NetworkInfo for the affected network is
- * sent as an extra; it should be consulted to see what kind of
- * connectivity event occurred.
- * <p/>
- * If this is a connection that was the result of failing over from a
- * disconnected network, then the FAILOVER_CONNECTION boolean extra is
- * set to true.
- * <p/>
- * For a loss of connectivity, if the connectivity manager is attempting
- * to connect (or has already connected) to another network, the
- * NetworkInfo for the new network is also passed as an extra. This lets
- * any receivers of the broadcast know that they should not necessarily
- * tell the user that no data traffic will be possible. Instead, the
- * receiver should expect another broadcast soon, indicating either that
- * the failover attempt succeeded (and so there is still overall data
- * connectivity), or that the failover attempt failed, meaning that all
- * connectivity has been lost.
- * <p/>
- * For a disconnect event, the boolean extra EXTRA_NO_CONNECTIVITY
- * is set to {@code true} if there are no connected networks at all.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
-
- /**
- * Identical to {@link #CONNECTIVITY_ACTION} broadcast, but sent without any
- * applicable {@link Settings.Global#CONNECTIVITY_CHANGE_DELAY}.
- *
- * @hide
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String CONNECTIVITY_ACTION_IMMEDIATE =
- "android.net.conn.CONNECTIVITY_CHANGE_IMMEDIATE";
-
- /**
- * The lookup key for a {@link NetworkInfo} object. Retrieve with
- * {@link android.content.Intent#getParcelableExtra(String)}.
- *
- * @deprecated Since {@link NetworkInfo} can vary based on UID, applications
- * should always obtain network information through
- * {@link #getActiveNetworkInfo()} or
- * {@link #getAllNetworkInfo()}.
- * @see #EXTRA_NETWORK_TYPE
- */
- @Deprecated
- public static final String EXTRA_NETWORK_INFO = "networkInfo";
-
- /**
- * Network type which triggered a {@link #CONNECTIVITY_ACTION} broadcast.
- * Can be used with {@link #getNetworkInfo(int)} to get {@link NetworkInfo}
- * state based on the calling application.
- *
- * @see android.content.Intent#getIntExtra(String, int)
- */
- public static final String EXTRA_NETWORK_TYPE = "networkType";
-
- /**
- * The lookup key for a boolean that indicates whether a connect event
- * is for a network to which the connectivity manager was failing over
- * following a disconnect on another network.
- * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}.
- */
- public static final String EXTRA_IS_FAILOVER = "isFailover";
- /**
- * The lookup key for a {@link NetworkInfo} object. This is supplied when
- * there is another network that it may be possible to connect to. Retrieve with
- * {@link android.content.Intent#getParcelableExtra(String)}.
- */
- public static final String EXTRA_OTHER_NETWORK_INFO = "otherNetwork";
- /**
- * The lookup key for a boolean that indicates whether there is a
- * complete lack of connectivity, i.e., no network is available.
- * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}.
- */
- public static final String EXTRA_NO_CONNECTIVITY = "noConnectivity";
- /**
- * The lookup key for a string that indicates why an attempt to connect
- * to a network failed. The string has no particular structure. It is
- * intended to be used in notifications presented to users. Retrieve
- * it with {@link android.content.Intent#getStringExtra(String)}.
- */
- public static final String EXTRA_REASON = "reason";
- /**
- * The lookup key for a string that provides optionally supplied
- * extra information about the network state. The information
- * may be passed up from the lower networking layers, and its
- * meaning may be specific to a particular network type. Retrieve
- * it with {@link android.content.Intent#getStringExtra(String)}.
- */
- public static final String EXTRA_EXTRA_INFO = "extraInfo";
- /**
- * The lookup key for an int that provides information about
- * our connection to the internet at large. 0 indicates no connection,
- * 100 indicates a great connection. Retrieve it with
- * {@link android.content.Intent#getIntExtra(String, int)}.
- * {@hide}
- */
- public static final String EXTRA_INET_CONDITION = "inetCondition";
-
- /**
- * Broadcast action to indicate the change of data activity status
- * (idle or active) on a network in a recent period.
- * The network becomes active when data transmission is started, or
- * idle if there is no data transmission for a period of time.
- * {@hide}
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_DATA_ACTIVITY_CHANGE = "android.net.conn.DATA_ACTIVITY_CHANGE";
- /**
- * The lookup key for an enum that indicates the network device type on which this data activity
- * change happens.
- * {@hide}
- */
- public static final String EXTRA_DEVICE_TYPE = "deviceType";
- /**
- * The lookup key for a boolean that indicates the device is active or not. {@code true} means
- * it is actively sending or receiving data and {@code false} means it is idle.
- * {@hide}
- */
- public static final String EXTRA_IS_ACTIVE = "isActive";
- /**
- * The lookup key for a long that contains the timestamp (nanos) of the radio state change.
- * {@hide}
- */
- public static final String EXTRA_REALTIME_NS = "tsNanos";
-
- /**
- * Broadcast Action: The setting for background data usage has changed
- * values. Use {@link #getBackgroundDataSetting()} to get the current value.
- * <p>
- * If an application uses the network in the background, it should listen
- * for this broadcast and stop using the background data if the value is
- * {@code false}.
- * <p>
- *
- * @deprecated As of {@link VERSION_CODES#ICE_CREAM_SANDWICH}, availability
- * of background data depends on several combined factors, and
- * this broadcast is no longer sent. Instead, when background
- * data is unavailable, {@link #getActiveNetworkInfo()} will now
- * appear disconnected. During first boot after a platform
- * upgrade, this broadcast will be sent once if
- * {@link #getBackgroundDataSetting()} was {@code false} before
- * the upgrade.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- @Deprecated
- public static final String ACTION_BACKGROUND_DATA_SETTING_CHANGED =
- "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED";
-
- /**
- * Broadcast Action: The network connection may not be good
- * uses {@code ConnectivityManager.EXTRA_INET_CONDITION} and
- * {@code ConnectivityManager.EXTRA_NETWORK_INFO} to specify
- * the network and it's condition.
- * @hide
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String INET_CONDITION_ACTION =
- "android.net.conn.INET_CONDITION_ACTION";
-
- /**
- * Broadcast Action: A tetherable connection has come or gone.
- * Uses {@code ConnectivityManager.EXTRA_AVAILABLE_TETHER},
- * {@code ConnectivityManager.EXTRA_ACTIVE_TETHER} and
- * {@code ConnectivityManager.EXTRA_ERRORED_TETHER} to indicate
- * the current state of tethering. Each include a list of
- * interface names in that state (may be empty).
- * @hide
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_TETHER_STATE_CHANGED =
- "android.net.conn.TETHER_STATE_CHANGED";
-
- /**
- * @hide
- * gives a String[] listing all the interfaces configured for
- * tethering and currently available for tethering.
- */
- public static final String EXTRA_AVAILABLE_TETHER = "availableArray";
-
- /**
- * @hide
- * gives a String[] listing all the interfaces currently tethered
- * (ie, has dhcp support and packets potentially forwarded/NATed)
- */
- public static final String EXTRA_ACTIVE_TETHER = "activeArray";
-
- /**
- * @hide
- * gives a String[] listing all the interfaces we tried to tether and
- * failed. Use {@link #getLastTetherError} to find the error code
- * for any interfaces listed here.
- */
- public static final String EXTRA_ERRORED_TETHER = "erroredArray";
-
- /**
- * Broadcast Action: The captive portal tracker has finished its test.
- * Sent only while running Setup Wizard, in lieu of showing a user
- * notification.
- * @hide
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_CAPTIVE_PORTAL_TEST_COMPLETED =
- "android.net.conn.CAPTIVE_PORTAL_TEST_COMPLETED";
- /**
- * The lookup key for a boolean that indicates whether a captive portal was detected.
- * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}.
- * @hide
- */
- public static final String EXTRA_IS_CAPTIVE_PORTAL = "captivePortal";
-
- /**
- * The absence of a connection type.
- * @hide
- */
- public static final int TYPE_NONE = -1;
-
- /**
- * The Mobile data connection. When active, all data traffic
- * will use this network type's interface by default
- * (it has a default route)
- */
- public static final int TYPE_MOBILE = 0;
- /**
- * The WIFI data connection. When active, all data traffic
- * will use this network type's interface by default
- * (it has a default route).
- */
- public static final int TYPE_WIFI = 1;
- /**
- * An MMS-specific Mobile data connection. This network type may use the
- * same network interface as {@link #TYPE_MOBILE} or it may use a different
- * one. This is used by applications needing to talk to the carrier's
- * Multimedia Messaging Service servers.
- */
- public static final int TYPE_MOBILE_MMS = 2;
- /**
- * A SUPL-specific Mobile data connection. This network type may use the
- * same network interface as {@link #TYPE_MOBILE} or it may use a different
- * one. This is used by applications needing to talk to the carrier's
- * Secure User Plane Location servers for help locating the device.
- */
- public static final int TYPE_MOBILE_SUPL = 3;
- /**
- * A DUN-specific Mobile data connection. This network type may use the
- * same network interface as {@link #TYPE_MOBILE} or it may use a different
- * one. This is sometimes by the system when setting up an upstream connection
- * for tethering so that the carrier is aware of DUN traffic.
- */
- public static final int TYPE_MOBILE_DUN = 4;
- /**
- * A High Priority Mobile data connection. This network type uses the
- * same network interface as {@link #TYPE_MOBILE} but the routing setup
- * is different. Only requesting processes will have access to the
- * Mobile DNS servers and only IP's explicitly requested via {@link #requestRouteToHost}
- * will route over this interface if no default route exists.
- */
- public static final int TYPE_MOBILE_HIPRI = 5;
- /**
- * The WiMAX data connection. When active, all data traffic
- * will use this network type's interface by default
- * (it has a default route).
- */
- public static final int TYPE_WIMAX = 6;
-
- /**
- * The Bluetooth data connection. When active, all data traffic
- * will use this network type's interface by default
- * (it has a default route).
- */
- public static final int TYPE_BLUETOOTH = 7;
-
- /**
- * Dummy data connection. This should not be used on shipping devices.
- */
- public static final int TYPE_DUMMY = 8;
-
- /**
- * The Ethernet data connection. When active, all data traffic
- * will use this network type's interface by default
- * (it has a default route).
- */
- public static final int TYPE_ETHERNET = 9;
-
- /**
- * Over the air Administration.
- * {@hide}
- */
- public static final int TYPE_MOBILE_FOTA = 10;
-
- /**
- * IP Multimedia Subsystem.
- * {@hide}
- */
- public static final int TYPE_MOBILE_IMS = 11;
-
- /**
- * Carrier Branded Services.
- * {@hide}
- */
- public static final int TYPE_MOBILE_CBS = 12;
-
- /**
- * A Wi-Fi p2p connection. Only requesting processes will have access to
- * the peers connected.
- * {@hide}
- */
- public static final int TYPE_WIFI_P2P = 13;
-
- /**
- * The network to use for initially attaching to the network
- * {@hide}
- */
- public static final int TYPE_MOBILE_IA = 14;
-
- /**
- * The network that uses proxy to achieve connectivity.
- * {@hide}
- */
- public static final int TYPE_PROXY = 16;
-
- /** {@hide} */
- public static final int MAX_RADIO_TYPE = TYPE_PROXY;
-
- /** {@hide} */
- public static final int MAX_NETWORK_TYPE = TYPE_PROXY;
-
- /**
- * If you want to set the default network preference,you can directly
- * change the networkAttributes array in framework's config.xml.
- *
- * @deprecated Since we support so many more networks now, the single
- * network default network preference can't really express
- * the hierarchy. Instead, the default is defined by the
- * networkAttributes in config.xml. You can determine
- * the current value by calling {@link #getNetworkPreference()}
- * from an App.
- */
- @Deprecated
- public static final int DEFAULT_NETWORK_PREFERENCE = TYPE_WIFI;
-
- /**
- * Default value for {@link Settings.Global#CONNECTIVITY_CHANGE_DELAY} in
- * milliseconds. This was introduced because IPv6 routes seem to take a
- * moment to settle - trying network activity before the routes are adjusted
- * can lead to packets using the wrong interface or having the wrong IP address.
- * This delay is a bit crude, but in the future hopefully we will have kernel
- * notifications letting us know when it's safe to use the new network.
- *
- * @hide
- */
- public static final int CONNECTIVITY_CHANGE_DELAY_DEFAULT = 3000;
-
- /**
- * @hide
- */
- public final static int INVALID_NET_ID = 0;
-
- /**
- * @hide
- */
- public final static int REQUEST_ID_UNSET = 0;
-
- private final IConnectivityManager mService;
-
- private final String mPackageName;
-
- private INetworkManagementService mNMService;
-
- /**
- * Tests if a given integer represents a valid network type.
- * @param networkType the type to be tested
- * @return a boolean. {@code true} if the type is valid, else {@code false}
- */
- public static boolean isNetworkTypeValid(int networkType) {
- return networkType >= 0 && networkType <= MAX_NETWORK_TYPE;
- }
-
- /**
- * Returns a non-localized string representing a given network type.
- * ONLY used for debugging output.
- * @param type the type needing naming
- * @return a String for the given type, or a string version of the type ("87")
- * if no name is known.
- * {@hide}
- */
- public static String getNetworkTypeName(int type) {
- switch (type) {
- case TYPE_MOBILE:
- return "MOBILE";
- case TYPE_WIFI:
- return "WIFI";
- case TYPE_MOBILE_MMS:
- return "MOBILE_MMS";
- case TYPE_MOBILE_SUPL:
- return "MOBILE_SUPL";
- case TYPE_MOBILE_DUN:
- return "MOBILE_DUN";
- case TYPE_MOBILE_HIPRI:
- return "MOBILE_HIPRI";
- case TYPE_WIMAX:
- return "WIMAX";
- case TYPE_BLUETOOTH:
- return "BLUETOOTH";
- case TYPE_DUMMY:
- return "DUMMY";
- case TYPE_ETHERNET:
- return "ETHERNET";
- case TYPE_MOBILE_FOTA:
- return "MOBILE_FOTA";
- case TYPE_MOBILE_IMS:
- return "MOBILE_IMS";
- case TYPE_MOBILE_CBS:
- return "MOBILE_CBS";
- case TYPE_WIFI_P2P:
- return "WIFI_P2P";
- case TYPE_MOBILE_IA:
- return "MOBILE_IA";
- case TYPE_PROXY:
- return "PROXY";
- default:
- return Integer.toString(type);
- }
- }
-
- /**
- * Checks if a given type uses the cellular data connection.
- * This should be replaced in the future by a network property.
- * @param networkType the type to check
- * @return a boolean - {@code true} if uses cellular network, else {@code false}
- * {@hide}
- */
- public static boolean isNetworkTypeMobile(int networkType) {
- switch (networkType) {
- case TYPE_MOBILE:
- case TYPE_MOBILE_MMS:
- case TYPE_MOBILE_SUPL:
- case TYPE_MOBILE_DUN:
- case TYPE_MOBILE_HIPRI:
- case TYPE_MOBILE_FOTA:
- case TYPE_MOBILE_IMS:
- case TYPE_MOBILE_CBS:
- case TYPE_MOBILE_IA:
- return true;
- default:
- return false;
- }
- }
-
- /**
- * Checks if the given network type is backed by a Wi-Fi radio.
- *
- * @hide
- */
- public static boolean isNetworkTypeWifi(int networkType) {
- switch (networkType) {
- case TYPE_WIFI:
- case TYPE_WIFI_P2P:
- return true;
- default:
- return false;
- }
- }
-
- /**
- * Checks if the given network type should be exempt from VPN routing rules
- *
- * @hide
- */
- public static boolean isNetworkTypeExempt(int networkType) {
- switch (networkType) {
- case TYPE_MOBILE_MMS:
- case TYPE_MOBILE_SUPL:
- case TYPE_MOBILE_HIPRI:
- case TYPE_MOBILE_IA:
- return true;
- default:
- return false;
- }
- }
-
- /**
- * Specifies the preferred network type. When the device has more
- * than one type available the preferred network type will be used.
- *
- * @param preference the network type to prefer over all others. It is
- * unspecified what happens to the old preferred network in the
- * overall ordering.
- * @deprecated Functionality has been removed as it no longer makes sense,
- * with many more than two networks - we'd need an array to express
- * preference. Instead we use dynamic network properties of
- * the networks to describe their precedence.
- */
- public void setNetworkPreference(int preference) {
- }
-
- /**
- * Retrieves the current preferred network type.
- *
- * @return an integer representing the preferred network type
- *
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
- * @deprecated Functionality has been removed as it no longer makes sense,
- * with many more than two networks - we'd need an array to express
- * preference. Instead we use dynamic network properties of
- * the networks to describe their precedence.
- */
- public int getNetworkPreference() {
- return TYPE_NONE;
- }
-
- /**
- * Returns details about the currently active default data network. When
- * connected, this network is the default route for outgoing connections.
- * You should always check {@link NetworkInfo#isConnected()} before initiating
- * network traffic. This may return {@code null} when there is no default
- * network.
- *
- * @return a {@link NetworkInfo} object for the current default network
- * or {@code null} if no network default network is currently active
- *
- * <p>This method requires the call to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
- */
- public NetworkInfo getActiveNetworkInfo() {
- try {
- return mService.getActiveNetworkInfo();
- } catch (RemoteException e) {
- return null;
- }
- }
-
- /**
- * Returns details about the currently active default data network
- * for a given uid. This is for internal use only to avoid spying
- * other apps.
- *
- * @return a {@link NetworkInfo} object for the current default network
- * for the given uid or {@code null} if no default network is
- * available for the specified uid.
- *
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}
- * {@hide}
- */
- public NetworkInfo getActiveNetworkInfoForUid(int uid) {
- try {
- return mService.getActiveNetworkInfoForUid(uid);
- } catch (RemoteException e) {
- return null;
- }
- }
-
- /**
- * Returns connection status information about a particular
- * network type.
- *
- * @param networkType integer specifying which networkType in
- * which you're interested.
- * @return a {@link NetworkInfo} object for the requested
- * network type or {@code null} if the type is not
- * supported by the device.
- *
- * <p>This method requires the call to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
- */
- public NetworkInfo getNetworkInfo(int networkType) {
- try {
- return mService.getNetworkInfo(networkType);
- } catch (RemoteException e) {
- return null;
- }
- }
-
- /**
- * Returns connection status information about all network
- * types supported by the device.
- *
- * @return an array of {@link NetworkInfo} objects. Check each
- * {@link NetworkInfo#getType} for which type each applies.
- *
- * <p>This method requires the call to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
- */
- public NetworkInfo[] getAllNetworkInfo() {
- try {
- return mService.getAllNetworkInfo();
- } catch (RemoteException e) {
- return null;
- }
- }
-
- /**
- * Returns details about the Provisioning or currently active default data network. When
- * connected, this network is the default route for outgoing connections.
- * You should always check {@link NetworkInfo#isConnected()} before initiating
- * network traffic. This may return {@code null} when there is no default
- * network.
- *
- * @return a {@link NetworkInfo} object for the current default network
- * or {@code null} if no network default network is currently active
- *
- * <p>This method requires the call to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
- *
- * {@hide}
- */
- public NetworkInfo getProvisioningOrActiveNetworkInfo() {
- try {
- return mService.getProvisioningOrActiveNetworkInfo();
- } catch (RemoteException e) {
- return null;
- }
- }
-
- /**
- * Returns the IP information for the current default network.
- *
- * @return a {@link LinkProperties} object describing the IP info
- * for the current default network, or {@code null} if there
- * is no current default network.
- *
- * <p>This method requires the call to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
- * {@hide}
- */
- public LinkProperties getActiveLinkProperties() {
- try {
- return mService.getActiveLinkProperties();
- } catch (RemoteException e) {
- return null;
- }
- }
-
- /**
- * Returns the IP information for a given network type.
- *
- * @param networkType the network type of interest.
- * @return a {@link LinkProperties} object describing the IP info
- * for the given networkType, or {@code null} if there is
- * no current default network.
- *
- * <p>This method requires the call to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
- * {@hide}
- */
- public LinkProperties getLinkProperties(int networkType) {
- try {
- return mService.getLinkPropertiesForType(networkType);
- } catch (RemoteException e) {
- return null;
- }
- }
-
- /**
- * Get the {@link LinkProperties} for the given {@link Network}. This
- * will return {@code null} if the network is unknown.
- *
- * @param network The {@link Network} object identifying the network in question.
- * @return The {@link LinkProperties} for the network, or {@code null}.
- **/
- public LinkProperties getLinkProperties(Network network) {
- try {
- return mService.getLinkProperties(network);
- } catch (RemoteException e) {
- return null;
- }
- }
-
- /**
- * Get the {@link NetworkCapabilities} for the given {@link Network}. This
- * will return {@code null} if the network is unknown.
- *
- * @param network The {@link Network} object identifying the network in question.
- * @return The {@link NetworkCapabilities} for the network, or {@code null}.
- */
- public NetworkCapabilities getNetworkCapabilities(Network network) {
- try {
- return mService.getNetworkCapabilities(network);
- } catch (RemoteException e) {
- return null;
- }
- }
-
- /**
- * Tells each network type to set its radio power state as directed.
- *
- * @param turnOn a boolean, {@code true} to turn the radios on,
- * {@code false} to turn them off.
- * @return a boolean, {@code true} indicating success. All network types
- * will be tried, even if some fail.
- *
- * <p>This method requires the call to hold the permission
- * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
- * {@hide}
- */
-// TODO - check for any callers and remove
-// public boolean setRadios(boolean turnOn) {
-// try {
-// return mService.setRadios(turnOn);
-// } catch (RemoteException e) {
-// return false;
-// }
-// }
-
- /**
- * Tells a given networkType to set its radio power state as directed.
- *
- * @param networkType the int networkType of interest.
- * @param turnOn a boolean, {@code true} to turn the radio on,
- * {@code} false to turn it off.
- * @return a boolean, {@code true} indicating success.
- *
- * <p>This method requires the call to hold the permission
- * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
- * {@hide}
- */
-// TODO - check for any callers and remove
-// public boolean setRadio(int networkType, boolean turnOn) {
-// try {
-// return mService.setRadio(networkType, turnOn);
-// } catch (RemoteException e) {
-// return false;
-// }
-// }
-
- /**
- * Tells the underlying networking system that the caller wants to
- * begin using the named feature. The interpretation of {@code feature}
- * is completely up to each networking implementation.
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
- * @param networkType specifies which network the request pertains to
- * @param feature the name of the feature to be used
- * @return an integer value representing the outcome of the request.
- * The interpretation of this value is specific to each networking
- * implementation+feature combination, except that the value {@code -1}
- * always indicates failure.
- *
- * @deprecated Deprecated in favor of the cleaner {@link #requestNetwork} api.
- */
- public int startUsingNetworkFeature(int networkType, String feature) {
- NetworkCapabilities netCap = networkCapabilitiesForFeature(networkType, feature);
- if (netCap == null) {
- Log.d(TAG, "Can't satisfy startUsingNetworkFeature for " + networkType + ", " +
- feature);
- return PhoneConstants.APN_REQUEST_FAILED;
- }
-
- NetworkRequest request = null;
- synchronized (sLegacyRequests) {
- LegacyRequest l = sLegacyRequests.get(netCap);
- if (l != null) {
- Log.d(TAG, "renewing startUsingNetworkFeature request " + l.networkRequest);
- renewRequestLocked(l);
- if (l.currentNetwork != null) {
- return PhoneConstants.APN_ALREADY_ACTIVE;
- } else {
- return PhoneConstants.APN_REQUEST_STARTED;
- }
- }
-
- request = requestNetworkForFeatureLocked(netCap);
- }
- if (request != null) {
- Log.d(TAG, "starting startUsingNeworkFeature for request " + request);
- return PhoneConstants.APN_REQUEST_STARTED;
- } else {
- Log.d(TAG, " request Failed");
- return PhoneConstants.APN_REQUEST_FAILED;
- }
- }
-
- /**
- * Tells the underlying networking system that the caller is finished
- * using the named feature. The interpretation of {@code feature}
- * is completely up to each networking implementation.
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
- * @param networkType specifies which network the request pertains to
- * @param feature the name of the feature that is no longer needed
- * @return an integer value representing the outcome of the request.
- * The interpretation of this value is specific to each networking
- * implementation+feature combination, except that the value {@code -1}
- * always indicates failure.
- *
- * @deprecated Deprecated in favor of the cleaner {@link #requestNetwork} api.
- */
- public int stopUsingNetworkFeature(int networkType, String feature) {
- NetworkCapabilities netCap = networkCapabilitiesForFeature(networkType, feature);
- if (netCap == null) {
- Log.d(TAG, "Can't satisfy stopUsingNetworkFeature for " + networkType + ", " +
- feature);
- return -1;
- }
-
- NetworkRequest request = removeRequestForFeature(netCap);
- if (request != null) {
- Log.d(TAG, "stopUsingNetworkFeature for " + networkType + ", " + feature);
- releaseNetworkRequest(request);
- }
- return 1;
- }
-
- /**
- * Removes the NET_CAPABILITY_NOT_RESTRICTED capability from the given
- * NetworkCapabilities object if all the capabilities it provides are
- * typically provided by restricted networks.
- *
- * TODO: consider:
- * - Moving to NetworkCapabilities
- * - Renaming it to guessRestrictedCapability and make it set the
- * restricted capability bit in addition to clearing it.
- * @hide
- */
- public static void maybeMarkCapabilitiesRestricted(NetworkCapabilities nc) {
- for (int capability : nc.getCapabilities()) {
- switch (capability) {
- case NetworkCapabilities.NET_CAPABILITY_CBS:
- case NetworkCapabilities.NET_CAPABILITY_DUN:
- case NetworkCapabilities.NET_CAPABILITY_EIMS:
- case NetworkCapabilities.NET_CAPABILITY_FOTA:
- case NetworkCapabilities.NET_CAPABILITY_IA:
- case NetworkCapabilities.NET_CAPABILITY_IMS:
- case NetworkCapabilities.NET_CAPABILITY_RCS:
- case NetworkCapabilities.NET_CAPABILITY_XCAP:
- case NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED: //there by default
- continue;
- default:
- // At least one capability usually provided by unrestricted
- // networks. Conclude that this network is unrestricted.
- return;
- }
- }
- // All the capabilities are typically provided by restricted networks.
- // Conclude that this network is restricted.
- nc.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
- }
-
- private NetworkCapabilities networkCapabilitiesForFeature(int networkType, String feature) {
- if (networkType == TYPE_MOBILE) {
- int cap = -1;
- if ("enableMMS".equals(feature)) {
- cap = NetworkCapabilities.NET_CAPABILITY_MMS;
- } else if ("enableSUPL".equals(feature)) {
- cap = NetworkCapabilities.NET_CAPABILITY_SUPL;
- } else if ("enableDUN".equals(feature) || "enableDUNAlways".equals(feature)) {
- cap = NetworkCapabilities.NET_CAPABILITY_DUN;
- } else if ("enableHIPRI".equals(feature)) {
- cap = NetworkCapabilities.NET_CAPABILITY_INTERNET;
- } else if ("enableFOTA".equals(feature)) {
- cap = NetworkCapabilities.NET_CAPABILITY_FOTA;
- } else if ("enableIMS".equals(feature)) {
- cap = NetworkCapabilities.NET_CAPABILITY_IMS;
- } else if ("enableCBS".equals(feature)) {
- cap = NetworkCapabilities.NET_CAPABILITY_CBS;
- } else {
- return null;
- }
- NetworkCapabilities netCap = new NetworkCapabilities();
- netCap.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR).addCapability(cap);
- maybeMarkCapabilitiesRestricted(netCap);
- return netCap;
- } else if (networkType == TYPE_WIFI) {
- if ("p2p".equals(feature)) {
- NetworkCapabilities netCap = new NetworkCapabilities();
- netCap.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
- netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P);
- maybeMarkCapabilitiesRestricted(netCap);
- return netCap;
- }
- }
- return null;
- }
-
- private int legacyTypeForNetworkCapabilities(NetworkCapabilities netCap) {
- if (netCap == null) return TYPE_NONE;
- if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
- return TYPE_MOBILE_CBS;
- }
- if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
- return TYPE_MOBILE_IMS;
- }
- if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) {
- return TYPE_MOBILE_FOTA;
- }
- if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) {
- return TYPE_MOBILE_DUN;
- }
- if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
- return TYPE_MOBILE_SUPL;
- }
- if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) {
- return TYPE_MOBILE_MMS;
- }
- if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
- return TYPE_MOBILE_HIPRI;
- }
- if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P)) {
- return TYPE_WIFI_P2P;
- }
- return TYPE_NONE;
- }
-
- private static class LegacyRequest {
- NetworkCapabilities networkCapabilities;
- NetworkRequest networkRequest;
- int expireSequenceNumber;
- Network currentNetwork;
- int delay = -1;
- NetworkCallbackListener networkCallbackListener = new NetworkCallbackListener() {
- @Override
- public void onAvailable(NetworkRequest request, Network network) {
- currentNetwork = network;
- Log.d(TAG, "startUsingNetworkFeature got Network:" + network);
- setProcessDefaultNetworkForHostResolution(network);
- }
- @Override
- public void onLost(NetworkRequest request, Network network) {
- if (network.equals(currentNetwork)) {
- currentNetwork = null;
- setProcessDefaultNetworkForHostResolution(null);
- }
- Log.d(TAG, "startUsingNetworkFeature lost Network:" + network);
- }
- };
- }
-
- private HashMap<NetworkCapabilities, LegacyRequest> sLegacyRequests =
- new HashMap<NetworkCapabilities, LegacyRequest>();
-
- private NetworkRequest findRequestForFeature(NetworkCapabilities netCap) {
- synchronized (sLegacyRequests) {
- LegacyRequest l = sLegacyRequests.get(netCap);
- if (l != null) return l.networkRequest;
- }
- return null;
- }
-
- private void renewRequestLocked(LegacyRequest l) {
- l.expireSequenceNumber++;
- Log.d(TAG, "renewing request to seqNum " + l.expireSequenceNumber);
- sendExpireMsgForFeature(l.networkCapabilities, l.expireSequenceNumber, l.delay);
- }
-
- private void expireRequest(NetworkCapabilities netCap, int sequenceNum) {
- int ourSeqNum = -1;
- synchronized (sLegacyRequests) {
- LegacyRequest l = sLegacyRequests.get(netCap);
- if (l == null) return;
- ourSeqNum = l.expireSequenceNumber;
- if (l.expireSequenceNumber == sequenceNum) {
- releaseNetworkRequest(l.networkRequest);
- sLegacyRequests.remove(netCap);
- }
- }
- Log.d(TAG, "expireRequest with " + ourSeqNum + ", " + sequenceNum);
- }
-
- private NetworkRequest requestNetworkForFeatureLocked(NetworkCapabilities netCap) {
- int delay = -1;
- int type = legacyTypeForNetworkCapabilities(netCap);
- try {
- delay = mService.getRestoreDefaultNetworkDelay(type);
- } catch (RemoteException e) {}
- LegacyRequest l = new LegacyRequest();
- l.networkCapabilities = netCap;
- l.delay = delay;
- l.expireSequenceNumber = 0;
- l.networkRequest = sendRequestForNetwork(netCap, l.networkCallbackListener, 0,
- REQUEST, type);
- if (l.networkRequest == null) return null;
- sLegacyRequests.put(netCap, l);
- sendExpireMsgForFeature(netCap, l.expireSequenceNumber, delay);
- return l.networkRequest;
- }
-
- private void sendExpireMsgForFeature(NetworkCapabilities netCap, int seqNum, int delay) {
- if (delay >= 0) {
- Log.d(TAG, "sending expire msg with seqNum " + seqNum + " and delay " + delay);
- Message msg = sCallbackHandler.obtainMessage(EXPIRE_LEGACY_REQUEST, seqNum, 0, netCap);
- sCallbackHandler.sendMessageDelayed(msg, delay);
- }
- }
-
- private NetworkRequest removeRequestForFeature(NetworkCapabilities netCap) {
- synchronized (sLegacyRequests) {
- LegacyRequest l = sLegacyRequests.remove(netCap);
- if (l == null) return null;
- return l.networkRequest;
- }
- }
-
- /**
- * Ensure that a network route exists to deliver traffic to the specified
- * host via the specified network interface. An attempt to add a route that
- * already exists is ignored, but treated as successful.
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
- * @param networkType the type of the network over which traffic to the specified
- * host is to be routed
- * @param hostAddress the IP address of the host to which the route is desired
- * @return {@code true} on success, {@code false} on failure
- *
- * @deprecated Deprecated in favor of the {@link #requestNetwork},
- * {@link #setProcessDefaultNetwork} and {@link Network#getSocketFactory} api.
- */
- public boolean requestRouteToHost(int networkType, int hostAddress) {
- InetAddress inetAddress = NetworkUtils.intToInetAddress(hostAddress);
-
- if (inetAddress == null) {
- return false;
- }
-
- return requestRouteToHostAddress(networkType, inetAddress);
- }
-
- /**
- * Ensure that a network route exists to deliver traffic to the specified
- * host via the specified network interface. An attempt to add a route that
- * already exists is ignored, but treated as successful.
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
- * @param networkType the type of the network over which traffic to the specified
- * host is to be routed
- * @param hostAddress the IP address of the host to which the route is desired
- * @return {@code true} on success, {@code false} on failure
- * @hide
- * @deprecated Deprecated in favor of the {@link #requestNetwork} and
- * {@link #setProcessDefaultNetwork} api.
- */
- public boolean requestRouteToHostAddress(int networkType, InetAddress hostAddress) {
- byte[] address = hostAddress.getAddress();
- try {
- return mService.requestRouteToHostAddress(networkType, address, mPackageName);
- } catch (RemoteException e) {
- return false;
- }
- }
-
- /**
- * Returns the value of the setting for background data usage. If false,
- * applications should not use the network if the application is not in the
- * foreground. Developers should respect this setting, and check the value
- * of this before performing any background data operations.
- * <p>
- * All applications that have background services that use the network
- * should listen to {@link #ACTION_BACKGROUND_DATA_SETTING_CHANGED}.
- * <p>
- * @deprecated As of {@link VERSION_CODES#ICE_CREAM_SANDWICH}, availability of
- * background data depends on several combined factors, and this method will
- * always return {@code true}. Instead, when background data is unavailable,
- * {@link #getActiveNetworkInfo()} will now appear disconnected.
- *
- * @return Whether background data usage is allowed.
- */
- @Deprecated
- public boolean getBackgroundDataSetting() {
- // assume that background data is allowed; final authority is
- // NetworkInfo which may be blocked.
- return true;
- }
-
- /**
- * Sets the value of the setting for background data usage.
- *
- * @param allowBackgroundData Whether an application should use data while
- * it is in the background.
- *
- * @attr ref android.Manifest.permission#CHANGE_BACKGROUND_DATA_SETTING
- * @see #getBackgroundDataSetting()
- * @hide
- */
- @Deprecated
- public void setBackgroundDataSetting(boolean allowBackgroundData) {
- // ignored
- }
-
- /**
- * Return quota status for the current active network, or {@code null} if no
- * network is active. Quota status can change rapidly, so these values
- * shouldn't be cached.
- *
- * <p>This method requires the call to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
- *
- * @hide
- */
- public NetworkQuotaInfo getActiveNetworkQuotaInfo() {
- try {
- return mService.getActiveNetworkQuotaInfo();
- } catch (RemoteException e) {
- return null;
- }
- }
-
- /**
- * @hide
- * @deprecated Talk to TelephonyManager directly
- */
- public boolean getMobileDataEnabled() {
- IBinder b = ServiceManager.getService(Context.TELEPHONY_SERVICE);
- if (b != null) {
- try {
- ITelephony it = ITelephony.Stub.asInterface(b);
- return it.getDataEnabled();
- } catch (RemoteException e) { }
- }
- return false;
- }
-
- /**
- * Callback for use with {@link ConnectivityManager#registerNetworkActiveListener} to
- * find out when the current network has gone in to a high power state.
- */
- public interface OnNetworkActiveListener {
- /**
- * Called on the main thread of the process to report that the current data network
- * has become active, and it is now a good time to perform any pending network
- * operations. Note that this listener only tells you when the network becomes
- * active; if at any other time you want to know whether it is active (and thus okay
- * to initiate network traffic), you can retrieve its instantaneous state with
- * {@link ConnectivityManager#isNetworkActive}.
- */
- public void onNetworkActive();
- }
-
- private INetworkManagementService getNetworkManagementService() {
- synchronized (this) {
- if (mNMService != null) {
- return mNMService;
- }
- IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
- mNMService = INetworkManagementService.Stub.asInterface(b);
- return mNMService;
- }
- }
-
- private final ArrayMap<OnNetworkActiveListener, INetworkActivityListener>
- mNetworkActivityListeners
- = new ArrayMap<OnNetworkActiveListener, INetworkActivityListener>();
-
- /**
- * Start listening to reports when the data network is active, meaning it is
- * a good time to perform network traffic. Use {@link #isNetworkActive()}
- * to determine the current state of the network after registering the listener.
- *
- * @param l The listener to be told when the network is active.
- */
- public void registerNetworkActiveListener(final OnNetworkActiveListener l) {
- INetworkActivityListener rl = new INetworkActivityListener.Stub() {
- @Override
- public void onNetworkActive() throws RemoteException {
- l.onNetworkActive();
- }
- };
-
- try {
- getNetworkManagementService().registerNetworkActivityListener(rl);
- mNetworkActivityListeners.put(l, rl);
- } catch (RemoteException e) {
- }
- }
-
- /**
- * Remove network active listener previously registered with
- * {@link #registerNetworkActiveListener}.
- *
- * @param l Previously registered listener.
- */
- public void unregisterNetworkActiveListener(OnNetworkActiveListener l) {
- INetworkActivityListener rl = mNetworkActivityListeners.get(l);
- if (rl == null) {
- throw new IllegalArgumentException("Listener not registered: " + l);
- }
- try {
- getNetworkManagementService().unregisterNetworkActivityListener(rl);
- } catch (RemoteException e) {
- }
- }
-
- /**
- * Return whether the data network is currently active. An active network means that
- * it is currently in a high power state for performing data transmission. On some
- * types of networks, it may be expensive to move and stay in such a state, so it is
- * more power efficient to batch network traffic together when the radio is already in
- * this state. This method tells you whether right now is currently a good time to
- * initiate network traffic, as the network is already active.
- */
- public boolean isNetworkActive() {
- try {
- return getNetworkManagementService().isNetworkActive();
- } catch (RemoteException e) {
- }
- return false;
- }
-
- /**
- * {@hide}
- */
- public ConnectivityManager(IConnectivityManager service, String packageName) {
- mService = checkNotNull(service, "missing IConnectivityManager");
- mPackageName = checkNotNull(packageName, "missing package name");
- }
-
- /** {@hide} */
- public static ConnectivityManager from(Context context) {
- return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
- }
-
- /**
- * Get the set of tetherable, available interfaces. This list is limited by
- * device configuration and current interface existence.
- *
- * @return an array of 0 or more Strings of tetherable interface names.
- *
- * <p>This method requires the call to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
- * {@hide}
- */
- public String[] getTetherableIfaces() {
- try {
- return mService.getTetherableIfaces();
- } catch (RemoteException e) {
- return new String[0];
- }
- }
-
- /**
- * Get the set of tethered interfaces.
- *
- * @return an array of 0 or more String of currently tethered interface names.
- *
- * <p>This method requires the call to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
- * {@hide}
- */
- public String[] getTetheredIfaces() {
- try {
- return mService.getTetheredIfaces();
- } catch (RemoteException e) {
- return new String[0];
- }
- }
-
- /**
- * Get the set of interface names which attempted to tether but
- * failed. Re-attempting to tether may cause them to reset to the Tethered
- * state. Alternatively, causing the interface to be destroyed and recreated
- * may cause them to reset to the available state.
- * {@link ConnectivityManager#getLastTetherError} can be used to get more
- * information on the cause of the errors.
- *
- * @return an array of 0 or more String indicating the interface names
- * which failed to tether.
- *
- * <p>This method requires the call to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
- * {@hide}
- */
- public String[] getTetheringErroredIfaces() {
- try {
- return mService.getTetheringErroredIfaces();
- } catch (RemoteException e) {
- return new String[0];
- }
- }
-
- /**
- * Attempt to tether the named interface. This will setup a dhcp server
- * on the interface, forward and NAT IP packets and forward DNS requests
- * to the best active upstream network interface. Note that if no upstream
- * IP network interface is available, dhcp will still run and traffic will be
- * allowed between the tethered devices and this device, though upstream net
- * access will of course fail until an upstream network interface becomes
- * active.
- *
- * @param iface the interface name to tether.
- * @return error a {@code TETHER_ERROR} value indicating success or failure type
- *
- * <p>This method requires the call to hold the permission
- * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
- * {@hide}
- */
- public int tether(String iface) {
- try {
- return mService.tether(iface);
- } catch (RemoteException e) {
- return TETHER_ERROR_SERVICE_UNAVAIL;
- }
- }
-
- /**
- * Stop tethering the named interface.
- *
- * @param iface the interface name to untether.
- * @return error a {@code TETHER_ERROR} value indicating success or failure type
- *
- * <p>This method requires the call to hold the permission
- * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
- * {@hide}
- */
- public int untether(String iface) {
- try {
- return mService.untether(iface);
- } catch (RemoteException e) {
- return TETHER_ERROR_SERVICE_UNAVAIL;
- }
- }
-
- /**
- * Check if the device allows for tethering. It may be disabled via
- * {@code ro.tether.denied} system property, Settings.TETHER_SUPPORTED or
- * due to device configuration.
- *
- * @return a boolean - {@code true} indicating Tethering is supported.
- *
- * <p>This method requires the call to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
- * {@hide}
- */
- public boolean isTetheringSupported() {
- try {
- return mService.isTetheringSupported();
- } catch (RemoteException e) {
- return false;
- }
- }
-
- /**
- * Get the list of regular expressions that define any tetherable
- * USB network interfaces. If USB tethering is not supported by the
- * device, this list should be empty.
- *
- * @return an array of 0 or more regular expression Strings defining
- * what interfaces are considered tetherable usb interfaces.
- *
- * <p>This method requires the call to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
- * {@hide}
- */
- public String[] getTetherableUsbRegexs() {
- try {
- return mService.getTetherableUsbRegexs();
- } catch (RemoteException e) {
- return new String[0];
- }
- }
-
- /**
- * Get the list of regular expressions that define any tetherable
- * Wifi network interfaces. If Wifi tethering is not supported by the
- * device, this list should be empty.
- *
- * @return an array of 0 or more regular expression Strings defining
- * what interfaces are considered tetherable wifi interfaces.
- *
- * <p>This method requires the call to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
- * {@hide}
- */
- public String[] getTetherableWifiRegexs() {
- try {
- return mService.getTetherableWifiRegexs();
- } catch (RemoteException e) {
- return new String[0];
- }
- }
-
- /**
- * Get the list of regular expressions that define any tetherable
- * Bluetooth network interfaces. If Bluetooth tethering is not supported by the
- * device, this list should be empty.
- *
- * @return an array of 0 or more regular expression Strings defining
- * what interfaces are considered tetherable bluetooth interfaces.
- *
- * <p>This method requires the call to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
- * {@hide}
- */
- public String[] getTetherableBluetoothRegexs() {
- try {
- return mService.getTetherableBluetoothRegexs();
- } catch (RemoteException e) {
- return new String[0];
- }
- }
-
- /**
- * Attempt to both alter the mode of USB and Tethering of USB. A
- * utility method to deal with some of the complexity of USB - will
- * attempt to switch to Rndis and subsequently tether the resulting
- * interface on {@code true} or turn off tethering and switch off
- * Rndis on {@code false}.
- *
- * @param enable a boolean - {@code true} to enable tethering
- * @return error a {@code TETHER_ERROR} value indicating success or failure type
- *
- * <p>This method requires the call to hold the permission
- * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
- * {@hide}
- */
- public int setUsbTethering(boolean enable) {
- try {
- return mService.setUsbTethering(enable);
- } catch (RemoteException e) {
- return TETHER_ERROR_SERVICE_UNAVAIL;
- }
- }
-
- /** {@hide} */
- public static final int TETHER_ERROR_NO_ERROR = 0;
- /** {@hide} */
- public static final int TETHER_ERROR_UNKNOWN_IFACE = 1;
- /** {@hide} */
- public static final int TETHER_ERROR_SERVICE_UNAVAIL = 2;
- /** {@hide} */
- public static final int TETHER_ERROR_UNSUPPORTED = 3;
- /** {@hide} */
- public static final int TETHER_ERROR_UNAVAIL_IFACE = 4;
- /** {@hide} */
- public static final int TETHER_ERROR_MASTER_ERROR = 5;
- /** {@hide} */
- public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6;
- /** {@hide} */
- public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7;
- /** {@hide} */
- public static final int TETHER_ERROR_ENABLE_NAT_ERROR = 8;
- /** {@hide} */
- public static final int TETHER_ERROR_DISABLE_NAT_ERROR = 9;
- /** {@hide} */
- public static final int TETHER_ERROR_IFACE_CFG_ERROR = 10;
-
- /**
- * Get a more detailed error code after a Tethering or Untethering
- * request asynchronously failed.
- *
- * @param iface The name of the interface of interest
- * @return error The error code of the last error tethering or untethering the named
- * interface
- *
- * <p>This method requires the call to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
- * {@hide}
- */
- public int getLastTetherError(String iface) {
- try {
- return mService.getLastTetherError(iface);
- } catch (RemoteException e) {
- return TETHER_ERROR_SERVICE_UNAVAIL;
- }
- }
-
- /**
- * Try to ensure the device stays awake until we connect with the next network.
- * Actually just holds a wakelock for a number of seconds while we try to connect
- * to any default networks. This will expire if the timeout passes or if we connect
- * to a default after this is called. For internal use only.
- *
- * @param forWhom the name of the network going down for logging purposes
- * @return {@code true} on success, {@code false} on failure
- *
- * <p>This method requires the call to hold the permission
- * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
- * {@hide}
- */
- public boolean requestNetworkTransitionWakelock(String forWhom) {
- try {
- mService.requestNetworkTransitionWakelock(forWhom);
- return true;
- } catch (RemoteException e) {
- return false;
- }
- }
-
- /**
- * Report network connectivity status. This is currently used only
- * to alter status bar UI.
- *
- * @param networkType The type of network you want to report on
- * @param percentage The quality of the connection 0 is bad, 100 is good
- *
- * <p>This method requires the call to hold the permission
- * {@link android.Manifest.permission#STATUS_BAR}.
- * {@hide}
- */
- public void reportInetCondition(int networkType, int percentage) {
- try {
- mService.reportInetCondition(networkType, percentage);
- } catch (RemoteException e) {
- }
- }
-
- /**
- * Report a problem network to the framework. This provides a hint to the system
- * that there might be connectivity problems on this network and may cause
- * the framework to re-evaluate network connectivity and/or switch to another
- * network.
- *
- * @param network The {@link Network} the application was attempting to use
- * or {@code null} to indicate the current default network.
- */
- public void reportBadNetwork(Network network) {
- try {
- mService.reportBadNetwork(network);
- } catch (RemoteException e) {
- }
- }
-
- /**
- * Set a network-independent global http proxy. This is not normally what you want
- * for typical HTTP proxies - they are general network dependent. However if you're
- * doing something unusual like general internal filtering this may be useful. On
- * a private network where the proxy is not accessible, you may break HTTP using this.
- *
- * @param p The a {@link ProxyInfo} object defining the new global
- * HTTP proxy. A {@code null} value will clear the global HTTP proxy.
- *
- * <p>This method requires the call to hold the permission
- * android.Manifest.permission#CONNECTIVITY_INTERNAL.
- * @hide
- */
- public void setGlobalProxy(ProxyInfo p) {
- try {
- mService.setGlobalProxy(p);
- } catch (RemoteException e) {
- }
- }
-
- /**
- * Retrieve any network-independent global HTTP proxy.
- *
- * @return {@link ProxyInfo} for the current global HTTP proxy or {@code null}
- * if no global HTTP proxy is set.
- *
- * <p>This method requires the call to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
- * @hide
- */
- public ProxyInfo getGlobalProxy() {
- try {
- return mService.getGlobalProxy();
- } catch (RemoteException e) {
- return null;
- }
- }
-
- /**
- * Get the HTTP proxy settings for the current default network. Note that
- * if a global proxy is set, it will override any per-network setting.
- *
- * @return the {@link ProxyInfo} for the current HTTP proxy, or {@code null} if no
- * HTTP proxy is active.
- *
- * <p>This method requires the call to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
- * {@hide}
- * @deprecated Deprecated in favor of {@link #getLinkProperties}
- */
- public ProxyInfo getProxy() {
- try {
- return mService.getProxy();
- } catch (RemoteException e) {
- return null;
- }
- }
-
- /**
- * Sets a secondary requirement bit for the given networkType.
- * This requirement bit is generally under the control of the carrier
- * or its agents and is not directly controlled by the user.
- *
- * @param networkType The network who's dependence has changed
- * @param met Boolean - true if network use is OK, false if not
- *
- * <p>This method requires the call to hold the permission
- * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
- * {@hide}
- */
- public void setDataDependency(int networkType, boolean met) {
- try {
- mService.setDataDependency(networkType, met);
- } catch (RemoteException e) {
- }
- }
-
- /**
- * Returns true if the hardware supports the given network type
- * else it returns false. This doesn't indicate we have coverage
- * or are authorized onto a network, just whether or not the
- * hardware supports it. For example a GSM phone without a SIM
- * should still return {@code true} for mobile data, but a wifi only
- * tablet would return {@code false}.
- *
- * @param networkType The network type we'd like to check
- * @return {@code true} if supported, else {@code false}
- *
- * <p>This method requires the call to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
- * @hide
- */
- public boolean isNetworkSupported(int networkType) {
- try {
- return mService.isNetworkSupported(networkType);
- } catch (RemoteException e) {}
- return false;
- }
-
- /**
- * Returns if the currently active data network is metered. A network is
- * classified as metered when the user is sensitive to heavy data usage on
- * that connection due to monetary costs, data limitations or
- * battery/performance issues. You should check this before doing large
- * data transfers, and warn the user or delay the operation until another
- * network is available.
- *
- * @return {@code true} if large transfers should be avoided, otherwise
- * {@code false}.
- *
- * <p>This method requires the call to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
- */
- public boolean isActiveNetworkMetered() {
- try {
- return mService.isActiveNetworkMetered();
- } catch (RemoteException e) {
- return false;
- }
- }
-
- /**
- * If the LockdownVpn mechanism is enabled, updates the vpn
- * with a reload of its profile.
- *
- * @return a boolean with {@code} indicating success
- *
- * <p>This method can only be called by the system UID
- * {@hide}
- */
- public boolean updateLockdownVpn() {
- try {
- return mService.updateLockdownVpn();
- } catch (RemoteException e) {
- return false;
- }
- }
-
- /**
- * Signal that the captive portal check on the indicated network
- * is complete and whether its a captive portal or not.
- *
- * @param info the {@link NetworkInfo} object for the networkType
- * in question.
- * @param isCaptivePortal true/false.
- *
- * <p>This method requires the call to hold the permission
- * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
- * {@hide}
- */
- public void captivePortalCheckCompleted(NetworkInfo info, boolean isCaptivePortal) {
- try {
- mService.captivePortalCheckCompleted(info, isCaptivePortal);
- } catch (RemoteException e) {
- }
- }
-
- /**
- * Supply the backend messenger for a network tracker
- *
- * @param networkType NetworkType to set
- * @param messenger {@link Messenger}
- * {@hide}
- */
- public void supplyMessenger(int networkType, Messenger messenger) {
- try {
- mService.supplyMessenger(networkType, messenger);
- } catch (RemoteException e) {
- }
- }
-
- /**
- * Check mobile provisioning.
- *
- * @param suggestedTimeOutMs, timeout in milliseconds
- *
- * @return time out that will be used, maybe less that suggestedTimeOutMs
- * -1 if an error.
- *
- * {@hide}
- */
- public int checkMobileProvisioning(int suggestedTimeOutMs) {
- int timeOutMs = -1;
- try {
- timeOutMs = mService.checkMobileProvisioning(suggestedTimeOutMs);
- } catch (RemoteException e) {
- }
- return timeOutMs;
- }
-
- /**
- * Get the mobile provisioning url.
- * {@hide}
- */
- public String getMobileProvisioningUrl() {
- try {
- return mService.getMobileProvisioningUrl();
- } catch (RemoteException e) {
- }
- return null;
- }
-
- /**
- * Get the mobile redirected provisioning url.
- * {@hide}
- */
- public String getMobileRedirectedProvisioningUrl() {
- try {
- return mService.getMobileRedirectedProvisioningUrl();
- } catch (RemoteException e) {
- }
- return null;
- }
-
- /**
- * get the information about a specific network link
- * @hide
- */
- public LinkQualityInfo getLinkQualityInfo(int networkType) {
- try {
- LinkQualityInfo li = mService.getLinkQualityInfo(networkType);
- return li;
- } catch (RemoteException e) {
- return null;
- }
- }
-
- /**
- * get the information of currently active network link
- * @hide
- */
- public LinkQualityInfo getActiveLinkQualityInfo() {
- try {
- LinkQualityInfo li = mService.getActiveLinkQualityInfo();
- return li;
- } catch (RemoteException e) {
- return null;
- }
- }
-
- /**
- * get the information of all network links
- * @hide
- */
- public LinkQualityInfo[] getAllLinkQualityInfo() {
- try {
- LinkQualityInfo[] li = mService.getAllLinkQualityInfo();
- return li;
- } catch (RemoteException e) {
- return null;
- }
- }
-
- /**
- * Set sign in error notification to visible or in visible
- *
- * @param visible
- * @param networkType
- *
- * {@hide}
- */
- public void setProvisioningNotificationVisible(boolean visible, int networkType,
- String extraInfo, String url) {
- try {
- mService.setProvisioningNotificationVisible(visible, networkType, extraInfo, url);
- } catch (RemoteException e) {
- }
- }
-
- /**
- * Set the value for enabling/disabling airplane mode
- *
- * @param enable whether to enable airplane mode or not
- *
- * <p>This method requires the call to hold the permission
- * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
- * @hide
- */
- public void setAirplaneMode(boolean enable) {
- try {
- mService.setAirplaneMode(enable);
- } catch (RemoteException e) {
- }
- }
-
- /** {@hide} */
- public void registerNetworkFactory(Messenger messenger, String name) {
- try {
- mService.registerNetworkFactory(messenger, name);
- } catch (RemoteException e) { }
- }
-
- /** {@hide} */
- public void unregisterNetworkFactory(Messenger messenger) {
- try {
- mService.unregisterNetworkFactory(messenger);
- } catch (RemoteException e) { }
- }
-
- /** {@hide} */
- public void registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp,
- NetworkCapabilities nc, int score) {
- try {
- mService.registerNetworkAgent(messenger, ni, lp, nc, score);
- } catch (RemoteException e) { }
- }
-
- /**
- * Base class for NetworkRequest callbacks. Used for notifications about network
- * changes. Should be extended by applications wanting notifications.
- */
- public static class NetworkCallbackListener {
- /** @hide */
- public static final int PRECHECK = 1;
- /** @hide */
- public static final int AVAILABLE = 2;
- /** @hide */
- public static final int LOSING = 3;
- /** @hide */
- public static final int LOST = 4;
- /** @hide */
- public static final int UNAVAIL = 5;
- /** @hide */
- public static final int CAP_CHANGED = 6;
- /** @hide */
- public static final int PROP_CHANGED = 7;
- /** @hide */
- public static final int CANCELED = 8;
-
- /**
- * @hide
- * Called whenever the framework connects to a network that it may use to
- * satisfy this request
- */
- public void onPreCheck(NetworkRequest networkRequest, Network network) {}
-
- /**
- * Called when the framework connects and has declared new network ready for use.
- *
- * @param networkRequest The {@link NetworkRequest} used to initiate the request.
- * @param network The {@link Network} of the satisfying network.
- */
- public void onAvailable(NetworkRequest networkRequest, Network network) {}
-
- /**
- * Called when the network is about to be disconnected. Often paired with an
- * {@link NetworkCallbackListener#onAvailable} call with the new replacement network
- * for graceful handover. This may not be called if we have a hard loss
- * (loss without warning). This may be followed by either a
- * {@link NetworkCallbackListener#onLost} call or a
- * {@link NetworkCallbackListener#onAvailable} call for this network depending
- * on whether we lose or regain it.
- *
- * @param networkRequest The {@link NetworkRequest} used to initiate the request.
- * @param network The {@link Network} of the failing network.
- * @param maxSecToLive The time in seconds the framework will attempt to keep the
- * network connected. Note that the network may suffers a
- * hard loss at any time.
- */
- public void onLosing(NetworkRequest networkRequest, Network network, int maxSecToLive) {}
-
- /**
- * Called when the framework has a hard loss of the network or when the
- * graceful failure ends.
- *
- * @param networkRequest The {@link NetworkRequest} used to initiate the request.
- * @param network The {@link Network} lost.
- */
- public void onLost(NetworkRequest networkRequest, Network network) {}
-
- /**
- * Called if no network is found in the given timeout time. If no timeout is given,
- * this will not be called.
- * @hide
- */
- public void onUnavailable(NetworkRequest networkRequest) {}
-
- /**
- * Called when the network the framework connected to for this request
- * changes capabilities but still satisfies the stated need.
- *
- * @param networkRequest The {@link NetworkRequest} used to initiate the request.
- * @param network The {@link Network} whose capabilities have changed.
- * @param networkCapabilities The new {@link NetworkCapabilities} for this network.
- */
- public void onNetworkCapabilitiesChanged(NetworkRequest networkRequest, Network network,
- NetworkCapabilities networkCapabilities) {}
-
- /**
- * Called when the network the framework connected to for this request
- * changes {@link LinkProperties}.
- *
- * @param networkRequest The {@link NetworkRequest} used to initiate the request.
- * @param network The {@link Network} whose link properties have changed.
- * @param linkProperties The new {@link LinkProperties} for this network.
- */
- public void onLinkPropertiesChanged(NetworkRequest networkRequest, Network network,
- LinkProperties linkProperties) {}
-
- /**
- * Called when a {@link #releaseNetworkRequest} call concludes and the registered
- * callbacks will no longer be used.
- *
- * @param networkRequest The {@link NetworkRequest} used to initiate the request.
- */
- public void onReleased(NetworkRequest networkRequest) {}
- }
-
- private static final int BASE = Protocol.BASE_CONNECTIVITY_MANAGER;
- /** @hide obj = pair(NetworkRequest, Network) */
- public static final int CALLBACK_PRECHECK = BASE + 1;
- /** @hide obj = pair(NetworkRequest, Network) */
- public static final int CALLBACK_AVAILABLE = BASE + 2;
- /** @hide obj = pair(NetworkRequest, Network), arg1 = ttl */
- public static final int CALLBACK_LOSING = BASE + 3;
- /** @hide obj = pair(NetworkRequest, Network) */
- public static final int CALLBACK_LOST = BASE + 4;
- /** @hide obj = NetworkRequest */
- public static final int CALLBACK_UNAVAIL = BASE + 5;
- /** @hide obj = pair(NetworkRequest, Network) */
- public static final int CALLBACK_CAP_CHANGED = BASE + 6;
- /** @hide obj = pair(NetworkRequest, Network) */
- public static final int CALLBACK_IP_CHANGED = BASE + 7;
- /** @hide obj = NetworkRequest */
- public static final int CALLBACK_RELEASED = BASE + 8;
- /** @hide */
- public static final int CALLBACK_EXIT = BASE + 9;
- /** @hide obj = NetworkCapabilities, arg1 = seq number */
- private static final int EXPIRE_LEGACY_REQUEST = BASE + 10;
-
- private class CallbackHandler extends Handler {
- private final HashMap<NetworkRequest, NetworkCallbackListener>mCallbackMap;
- private final AtomicInteger mRefCount;
- private static final String TAG = "ConnectivityManager.CallbackHandler";
- private final ConnectivityManager mCm;
-
- CallbackHandler(Looper looper, HashMap<NetworkRequest, NetworkCallbackListener>callbackMap,
- AtomicInteger refCount, ConnectivityManager cm) {
- super(looper);
- mCallbackMap = callbackMap;
- mRefCount = refCount;
- mCm = cm;
- }
-
- @Override
- public void handleMessage(Message message) {
- Log.d(TAG, "CM callback handler got msg " + message.what);
- switch (message.what) {
- case CALLBACK_PRECHECK: {
- NetworkRequest request = getNetworkRequest(message);
- NetworkCallbackListener callbacks = getCallbacks(request);
- if (callbacks != null) {
- callbacks.onPreCheck(request, getNetwork(message));
- } else {
- Log.e(TAG, "callback not found for PRECHECK message");
- }
- break;
- }
- case CALLBACK_AVAILABLE: {
- NetworkRequest request = getNetworkRequest(message);
- NetworkCallbackListener callbacks = getCallbacks(request);
- if (callbacks != null) {
- callbacks.onAvailable(request, getNetwork(message));
- } else {
- Log.e(TAG, "callback not found for AVAILABLE message");
- }
- break;
- }
- case CALLBACK_LOSING: {
- NetworkRequest request = getNetworkRequest(message);
- NetworkCallbackListener callbacks = getCallbacks(request);
- if (callbacks != null) {
- callbacks.onLosing(request, getNetwork(message), message.arg1);
- } else {
- Log.e(TAG, "callback not found for LOSING message");
- }
- break;
- }
- case CALLBACK_LOST: {
- NetworkRequest request = getNetworkRequest(message);
- NetworkCallbackListener callbacks = getCallbacks(request);
- if (callbacks != null) {
- callbacks.onLost(request, getNetwork(message));
- } else {
- Log.e(TAG, "callback not found for LOST message");
- }
- break;
- }
- case CALLBACK_UNAVAIL: {
- NetworkRequest req = (NetworkRequest)message.obj;
- NetworkCallbackListener callbacks = null;
- synchronized(mCallbackMap) {
- callbacks = mCallbackMap.get(req);
- }
- if (callbacks != null) {
- callbacks.onUnavailable(req);
- } else {
- Log.e(TAG, "callback not found for UNAVAIL message");
- }
- break;
- }
- case CALLBACK_CAP_CHANGED: {
- NetworkRequest request = getNetworkRequest(message);
- NetworkCallbackListener callbacks = getCallbacks(request);
- if (callbacks != null) {
- Network network = getNetwork(message);
- NetworkCapabilities cap = mCm.getNetworkCapabilities(network);
-
- callbacks.onNetworkCapabilitiesChanged(request, network, cap);
- } else {
- Log.e(TAG, "callback not found for CHANGED message");
- }
- break;
- }
- case CALLBACK_IP_CHANGED: {
- NetworkRequest request = getNetworkRequest(message);
- NetworkCallbackListener callbacks = getCallbacks(request);
- if (callbacks != null) {
- Network network = getNetwork(message);
- LinkProperties lp = mCm.getLinkProperties(network);
-
- callbacks.onLinkPropertiesChanged(request, network, lp);
- } else {
- Log.e(TAG, "callback not found for CHANGED message");
- }
- break;
- }
- case CALLBACK_RELEASED: {
- NetworkRequest req = (NetworkRequest)message.obj;
- NetworkCallbackListener callbacks = null;
- synchronized(mCallbackMap) {
- callbacks = mCallbackMap.remove(req);
- }
- if (callbacks != null) {
- callbacks.onReleased(req);
- } else {
- Log.e(TAG, "callback not found for CANCELED message");
- }
- synchronized(mRefCount) {
- if (mRefCount.decrementAndGet() == 0) {
- getLooper().quit();
- }
- }
- break;
- }
- case CALLBACK_EXIT: {
- Log.d(TAG, "Listener quiting");
- getLooper().quit();
- break;
- }
- case EXPIRE_LEGACY_REQUEST: {
- expireRequest((NetworkCapabilities)message.obj, message.arg1);
- break;
- }
- }
- }
-
- private NetworkRequest getNetworkRequest(Message msg) {
- return (NetworkRequest)(msg.obj);
- }
- private NetworkCallbackListener getCallbacks(NetworkRequest req) {
- synchronized(mCallbackMap) {
- return mCallbackMap.get(req);
- }
- }
- private Network getNetwork(Message msg) {
- return new Network(msg.arg2);
- }
- private NetworkCallbackListener removeCallbacks(Message msg) {
- NetworkRequest req = (NetworkRequest)msg.obj;
- synchronized(mCallbackMap) {
- return mCallbackMap.remove(req);
- }
- }
- }
-
- private void addCallbackListener() {
- synchronized(sCallbackRefCount) {
- if (sCallbackRefCount.incrementAndGet() == 1) {
- // TODO - switch this over to a ManagerThread or expire it when done
- HandlerThread callbackThread = new HandlerThread("ConnectivityManager");
- callbackThread.start();
- sCallbackHandler = new CallbackHandler(callbackThread.getLooper(),
- sNetworkCallbackListener, sCallbackRefCount, this);
- }
- }
- }
-
- private void removeCallbackListener() {
- synchronized(sCallbackRefCount) {
- if (sCallbackRefCount.decrementAndGet() == 0) {
- sCallbackHandler.obtainMessage(CALLBACK_EXIT).sendToTarget();
- sCallbackHandler = null;
- }
- }
- }
-
- static final HashMap<NetworkRequest, NetworkCallbackListener> sNetworkCallbackListener =
- new HashMap<NetworkRequest, NetworkCallbackListener>();
- static final AtomicInteger sCallbackRefCount = new AtomicInteger(0);
- static CallbackHandler sCallbackHandler = null;
-
- private final static int LISTEN = 1;
- private final static int REQUEST = 2;
-
- private NetworkRequest sendRequestForNetwork(NetworkCapabilities need,
- NetworkCallbackListener networkCallbackListener, int timeoutSec, int action,
- int legacyType) {
- NetworkRequest networkRequest = null;
- if (networkCallbackListener == null) {
- throw new IllegalArgumentException("null NetworkCallbackListener");
- }
- if (need == null) throw new IllegalArgumentException("null NetworkCapabilities");
- try {
- addCallbackListener();
- if (action == LISTEN) {
- networkRequest = mService.listenForNetwork(need, new Messenger(sCallbackHandler),
- new Binder());
- } else {
- networkRequest = mService.requestNetwork(need, new Messenger(sCallbackHandler),
- timeoutSec, new Binder(), legacyType);
- }
- if (networkRequest != null) {
- synchronized(sNetworkCallbackListener) {
- sNetworkCallbackListener.put(networkRequest, networkCallbackListener);
- }
- }
- } catch (RemoteException e) {}
- if (networkRequest == null) removeCallbackListener();
- return networkRequest;
- }
-
- /**
- * Request a network to satisfy a set of {@link NetworkCapabilities}.
- *
- * This {@link NetworkRequest} will live until released via
- * {@link #releaseNetworkRequest} or the calling application exits.
- * Status of the request can be followed by listening to the various
- * callbacks described in {@link NetworkCallbackListener}. The {@link Network}
- * can be used to direct traffic to the network.
- *
- * @param need {@link NetworkCapabilities} required by this request.
- * @param networkCallbackListener The {@link NetworkCallbackListener} to be utilized for this
- * request. Note the callbacks can be shared by multiple
- * requests and the NetworkRequest token utilized to
- * determine to which request the callback relates.
- * @return A {@link NetworkRequest} object identifying the request.
- */
- public NetworkRequest requestNetwork(NetworkCapabilities need,
- NetworkCallbackListener networkCallbackListener) {
- return sendRequestForNetwork(need, networkCallbackListener, 0, REQUEST, TYPE_NONE);
- }
-
- /**
- * Request a network to satisfy a set of {@link NetworkCapabilities}, limited
- * by a timeout.
- *
- * This function behaves identically to the non-timedout version, but if a suitable
- * network is not found within the given time (in Seconds) the
- * {@link NetworkCallbackListener#unavailable} callback is called. The request must
- * still be released normally by calling {@link releaseNetworkRequest}.
- * @param need {@link NetworkCapabilities} required by this request.
- * @param networkCallbackListener The callbacks to be utilized for this request. Note
- * the callbacks can be shared by multiple requests and
- * the NetworkRequest token utilized to determine to which
- * request the callback relates.
- * @param timeoutSec The time in seconds to attempt looking for a suitable network
- * before {@link NetworkCallbackListener#unavailable} is called.
- * @return A {@link NetworkRequest} object identifying the request.
- * @hide
- */
- public NetworkRequest requestNetwork(NetworkCapabilities need,
- NetworkCallbackListener networkCallbackListener, int timeoutSec) {
- return sendRequestForNetwork(need, networkCallbackListener, timeoutSec, REQUEST,
- TYPE_NONE);
- }
-
- /**
- * The maximum number of seconds the framework will look for a suitable network
- * during a timeout-equiped call to {@link requestNetwork}.
- * {@hide}
- */
- public final static int MAX_NETWORK_REQUEST_TIMEOUT_SEC = 100 * 60;
-
- /**
- * The lookup key for a {@link Network} object included with the intent after
- * succesfully finding a network for the applications request. Retrieve it with
- * {@link android.content.Intent#getParcelableExtra(String)}.
- */
- public static final String EXTRA_NETWORK_REQUEST_NETWORK = "networkRequestNetwork";
-
- /**
- * The lookup key for a {@link NetworkCapabilities} object included with the intent after
- * succesfully finding a network for the applications request. Retrieve it with
- * {@link android.content.Intent#getParcelableExtra(String)}.
- */
- public static final String EXTRA_NETWORK_REQUEST_NETWORK_CAPABILITIES =
- "networkRequestNetworkCapabilities";
-
-
- /**
- * Request a network to satisfy a set of {@link NetworkCapabilities}.
- *
- * This function behavies identically to the callback-equiped version, but instead
- * of {@link NetworkCallbackListener} a {@link PendingIntent} is used. This means
- * the request may outlive the calling application and get called back when a suitable
- * network is found.
- * <p>
- * The operation is an Intent broadcast that goes to a broadcast receiver that
- * you registered with {@link Context#registerReceiver} or through the
- * <receiver> tag in an AndroidManifest.xml file
- * <p>
- * The operation Intent is delivered with two extras, a {@link Network} typed
- * extra called {@link #EXTRA_NETWORK_REQUEST_NETWORK} and a {@link NetworkCapabilities}
- * typed extra called {@link #EXTRA_NETWORK_REQUEST_NETWORK_CAPABILITIES} containing
- * the original requests parameters. It is important to create a new,
- * {@link NetworkCallbackListener} based request before completing the processing of the
- * Intent to reserve the network or it will be released shortly after the Intent
- * is processed.
- * <p>
- * If there is already an request for this Intent registered (with the equality of
- * two Intents defined by {@link Intent#filterEquals}), then it will be removed and
- * replaced by this one, effectively releasing the previous {@link NetworkRequest}.
- * <p>
- * The request may be released normally by calling {@link #releaseNetworkRequest}.
- *
- * @param need {@link NetworkCapabilities} required by this request.
- * @param operation Action to perform when the network is available (corresponds
- * to the {@link NetworkCallbackListener#onAvailable} call. Typically
- * comes from {@link PendingIntent#getBroadcast}.
- * @return A {@link NetworkRequest} object identifying the request.
- */
- public NetworkRequest requestNetwork(NetworkCapabilities need, PendingIntent operation) {
- try {
- return mService.pendingRequestForNetwork(need, operation);
- } catch (RemoteException e) {}
- return null;
- }
-
- /**
- * Registers to receive notifications about all networks which satisfy the given
- * {@link NetworkCapabilities}. The callbacks will continue to be called until
- * either the application exits or the request is released using
- * {@link #releaseNetworkRequest}.
- *
- * @param need {@link NetworkCapabilities} required by this request.
- * @param networkCallbackListener The {@link NetworkCallbackListener} to be called as suitable
- * networks change state.
- * @return A {@link NetworkRequest} object identifying the request.
- */
- public NetworkRequest listenForNetwork(NetworkCapabilities need,
- NetworkCallbackListener networkCallbackListener) {
- return sendRequestForNetwork(need, networkCallbackListener, 0, LISTEN, TYPE_NONE);
- }
-
- /**
- * Releases a {@link NetworkRequest} generated either through a {@link #requestNetwork}
- * or a {@link #listenForNetwork} call. The {@link NetworkCallbackListener} given in the
- * earlier call may continue receiving calls until the
- * {@link NetworkCallbackListener#onReleased} function is called, signifying the end
- * of the request.
- *
- * @param networkRequest The {@link NetworkRequest} generated by an earlier call to
- * {@link #requestNetwork} or {@link #listenForNetwork}.
- */
- public void releaseNetworkRequest(NetworkRequest networkRequest) {
- if (networkRequest == null) throw new IllegalArgumentException("null NetworkRequest");
- try {
- mService.releaseNetworkRequest(networkRequest);
- } catch (RemoteException e) {}
- }
-
- /**
- * Binds the current process to {@code network}. All Sockets created in the future
- * (and not explicitly bound via a bound SocketFactory from
- * {@link Network#getSocketFactory() Network.getSocketFactory()}) will be bound to
- * {@code network}. All host name resolutions will be limited to {@code network} as well.
- * Note that if {@code network} ever disconnects, all Sockets created in this way will cease to
- * work and all host name resolutions will fail. This is by design so an application doesn't
- * accidentally use Sockets it thinks are still bound to a particular {@link Network}.
- * To clear binding pass {@code null} for {@code network}. Using individually bound
- * Sockets created by Network.getSocketFactory().createSocket() and
- * performing network-specific host name resolutions via
- * {@link Network#getAllByName Network.getAllByName} is preferred to calling
- * {@code setProcessDefaultNetwork}.
- *
- * @param network The {@link Network} to bind the current process to, or {@code null} to clear
- * the current binding.
- * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
- */
- public static boolean setProcessDefaultNetwork(Network network) {
- if (network == null) {
- NetworkUtils.unbindProcessToNetwork();
- } else {
- NetworkUtils.bindProcessToNetwork(network.netId);
- }
- // TODO fix return value
- return true;
- }
-
- /**
- * Returns the {@link Network} currently bound to this process via
- * {@link #setProcessDefaultNetwork}, or {@code null} if no {@link Network} is explicitly bound.
- *
- * @return {@code Network} to which this process is bound, or {@code null}.
- */
- public static Network getProcessDefaultNetwork() {
- int netId = NetworkUtils.getNetworkBoundToProcess();
- if (netId == 0) return null;
- return new Network(netId);
- }
-
- /**
- * Binds host resolutions performed by this process to {@code network}.
- * {@link #setProcessDefaultNetwork} takes precedence over this setting.
- *
- * @param network The {@link Network} to bind host resolutions from the current process to, or
- * {@code null} to clear the current binding.
- * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
- * @hide
- * @deprecated This is strictly for legacy usage to support {@link #startUsingNetworkFeature}.
- */
- public static boolean setProcessDefaultNetworkForHostResolution(Network network) {
- if (network == null) {
- NetworkUtils.unbindProcessToNetworkForHostResolution();
- } else {
- NetworkUtils.bindProcessToNetworkForHostResolution(network.netId);
- }
- // TODO hook up the return value.
- return true;
- }
-}
diff --git a/core/java/android/net/DhcpInfo.java b/core/java/android/net/DhcpInfo.java
deleted file mode 100644
index 788d7d9..0000000
--- a/core/java/android/net/DhcpInfo.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.os.Parcelable;
-import android.os.Parcel;
-
-/**
- * A simple object for retrieving the results of a DHCP request.
- */
-public class DhcpInfo implements Parcelable {
- public int ipAddress;
- public int gateway;
- public int netmask;
- public int dns1;
- public int dns2;
- public int serverAddress;
-
- public int leaseDuration;
-
- public DhcpInfo() {
- super();
- }
-
- /** copy constructor {@hide} */
- public DhcpInfo(DhcpInfo source) {
- if (source != null) {
- ipAddress = source.ipAddress;
- gateway = source.gateway;
- netmask = source.netmask;
- dns1 = source.dns1;
- dns2 = source.dns2;
- serverAddress = source.serverAddress;
- leaseDuration = source.leaseDuration;
- }
- }
-
- public String toString() {
- StringBuffer str = new StringBuffer();
-
- str.append("ipaddr "); putAddress(str, ipAddress);
- str.append(" gateway "); putAddress(str, gateway);
- str.append(" netmask "); putAddress(str, netmask);
- str.append(" dns1 "); putAddress(str, dns1);
- str.append(" dns2 "); putAddress(str, dns2);
- str.append(" DHCP server "); putAddress(str, serverAddress);
- str.append(" lease ").append(leaseDuration).append(" seconds");
-
- return str.toString();
- }
-
- private static void putAddress(StringBuffer buf, int addr) {
- buf.append(NetworkUtils.intToInetAddress(addr).getHostAddress());
- }
-
- /** Implement the Parcelable interface {@hide} */
- public int describeContents() {
- return 0;
- }
-
- /** Implement the Parcelable interface {@hide} */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(ipAddress);
- dest.writeInt(gateway);
- dest.writeInt(netmask);
- dest.writeInt(dns1);
- dest.writeInt(dns2);
- dest.writeInt(serverAddress);
- dest.writeInt(leaseDuration);
- }
-
- /** Implement the Parcelable interface {@hide} */
- public static final Creator<DhcpInfo> CREATOR =
- new Creator<DhcpInfo>() {
- public DhcpInfo createFromParcel(Parcel in) {
- DhcpInfo info = new DhcpInfo();
- info.ipAddress = in.readInt();
- info.gateway = in.readInt();
- info.netmask = in.readInt();
- info.dns1 = in.readInt();
- info.dns2 = in.readInt();
- info.serverAddress = in.readInt();
- info.leaseDuration = in.readInt();
- return info;
- }
-
- public DhcpInfo[] newArray(int size) {
- return new DhcpInfo[size];
- }
- };
-}
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
deleted file mode 100644
index 5f1ff3e..0000000
--- a/core/java/android/net/IConnectivityManager.aidl
+++ /dev/null
@@ -1,175 +0,0 @@
-/**
- * Copyright (c) 2008, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.app.PendingIntent;
-import android.net.LinkQualityInfo;
-import android.net.LinkProperties;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkInfo;
-import android.net.NetworkQuotaInfo;
-import android.net.NetworkRequest;
-import android.net.NetworkState;
-import android.net.ProxyInfo;
-import android.os.IBinder;
-import android.os.Messenger;
-import android.os.ParcelFileDescriptor;
-import android.os.ResultReceiver;
-
-import com.android.internal.net.LegacyVpnInfo;
-import com.android.internal.net.VpnConfig;
-import com.android.internal.net.VpnProfile;
-
-/**
- * Interface that answers queries about, and allows changing, the
- * state of network connectivity.
- */
-/** {@hide} */
-interface IConnectivityManager
-{
- // Keep this in sync with framework/native/services/connectivitymanager/ConnectivityManager.h
- void markSocketAsUser(in ParcelFileDescriptor socket, int uid);
-
- NetworkInfo getActiveNetworkInfo();
- NetworkInfo getActiveNetworkInfoForUid(int uid);
- NetworkInfo getNetworkInfo(int networkType);
- NetworkInfo[] getAllNetworkInfo();
-
- NetworkInfo getProvisioningOrActiveNetworkInfo();
-
- boolean isNetworkSupported(int networkType);
-
- LinkProperties getActiveLinkProperties();
- LinkProperties getLinkPropertiesForType(int networkType);
- LinkProperties getLinkProperties(in Network network);
-
- NetworkCapabilities getNetworkCapabilities(in Network network);
-
- NetworkState[] getAllNetworkState();
-
- NetworkQuotaInfo getActiveNetworkQuotaInfo();
- boolean isActiveNetworkMetered();
-
- int startUsingNetworkFeature(int networkType, in String feature,
- in IBinder binder);
-
- int stopUsingNetworkFeature(int networkType, in String feature);
-
- boolean requestRouteToHost(int networkType, int hostAddress, String packageName);
-
- boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress, String packageName);
-
- /** Policy control over specific {@link NetworkStateTracker}. */
- void setPolicyDataEnable(int networkType, boolean enabled);
-
- int tether(String iface);
-
- int untether(String iface);
-
- int getLastTetherError(String iface);
-
- boolean isTetheringSupported();
-
- String[] getTetherableIfaces();
-
- String[] getTetheredIfaces();
-
- String[] getTetheringErroredIfaces();
-
- String[] getTetherableUsbRegexs();
-
- String[] getTetherableWifiRegexs();
-
- String[] getTetherableBluetoothRegexs();
-
- int setUsbTethering(boolean enable);
-
- void requestNetworkTransitionWakelock(in String forWhom);
-
- void reportInetCondition(int networkType, int percentage);
-
- void reportBadNetwork(in Network network);
-
- ProxyInfo getGlobalProxy();
-
- void setGlobalProxy(in ProxyInfo p);
-
- ProxyInfo getProxy();
-
- void setDataDependency(int networkType, boolean met);
-
- boolean protectVpn(in ParcelFileDescriptor socket);
-
- boolean prepareVpn(String oldPackage, String newPackage);
-
- ParcelFileDescriptor establishVpn(in VpnConfig config);
-
- VpnConfig getVpnConfig();
-
- void startLegacyVpn(in VpnProfile profile);
-
- LegacyVpnInfo getLegacyVpnInfo();
-
- boolean updateLockdownVpn();
-
- void captivePortalCheckCompleted(in NetworkInfo info, boolean isCaptivePortal);
-
- void supplyMessenger(int networkType, in Messenger messenger);
-
- int findConnectionTypeForIface(in String iface);
-
- int checkMobileProvisioning(int suggestedTimeOutMs);
-
- String getMobileProvisioningUrl();
-
- String getMobileRedirectedProvisioningUrl();
-
- LinkQualityInfo getLinkQualityInfo(int networkType);
-
- LinkQualityInfo getActiveLinkQualityInfo();
-
- LinkQualityInfo[] getAllLinkQualityInfo();
-
- void setProvisioningNotificationVisible(boolean visible, int networkType, in String extraInfo,
- in String url);
-
- void setAirplaneMode(boolean enable);
-
- void registerNetworkFactory(in Messenger messenger, in String name);
-
- void unregisterNetworkFactory(in Messenger messenger);
-
- void registerNetworkAgent(in Messenger messenger, in NetworkInfo ni, in LinkProperties lp,
- in NetworkCapabilities nc, int score);
-
- NetworkRequest requestNetwork(in NetworkCapabilities networkCapabilities,
- in Messenger messenger, int timeoutSec, in IBinder binder, int legacy);
-
- NetworkRequest pendingRequestForNetwork(in NetworkCapabilities networkCapabilities,
- in PendingIntent operation);
-
- NetworkRequest listenForNetwork(in NetworkCapabilities networkCapabilities,
- in Messenger messenger, in IBinder binder);
-
- void pendingListenForNetwork(in NetworkCapabilities networkCapabilities,
- in PendingIntent operation);
-
- void releaseNetworkRequest(in NetworkRequest networkRequest);
-
- int getRestoreDefaultNetworkDelay(int networkType);
-}
diff --git a/core/java/android/net/IpConfiguration.java b/core/java/android/net/IpConfiguration.java
deleted file mode 100644
index 4730bab..0000000
--- a/core/java/android/net/IpConfiguration.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.net.LinkProperties;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Objects;
-
-/**
- * A class representing a configured network.
- * @hide
- */
-public class IpConfiguration implements Parcelable {
- private static final String TAG = "IpConfiguration";
-
- public enum IpAssignment {
- /* Use statically configured IP settings. Configuration can be accessed
- * with linkProperties */
- STATIC,
- /* Use dynamically configured IP settigns */
- DHCP,
- /* no IP details are assigned, this is used to indicate
- * that any existing IP settings should be retained */
- UNASSIGNED
- }
-
- public IpAssignment ipAssignment;
-
- public enum ProxySettings {
- /* No proxy is to be used. Any existing proxy settings
- * should be cleared. */
- NONE,
- /* Use statically configured proxy. Configuration can be accessed
- * with linkProperties */
- STATIC,
- /* no proxy details are assigned, this is used to indicate
- * that any existing proxy settings should be retained */
- UNASSIGNED,
- /* Use a Pac based proxy.
- */
- PAC
- }
-
- public ProxySettings proxySettings;
-
- public LinkProperties linkProperties;
-
- public IpConfiguration(IpConfiguration source) {
- if (source != null) {
- ipAssignment = source.ipAssignment;
- proxySettings = source.proxySettings;
- linkProperties = new LinkProperties(source.linkProperties);
- } else {
- ipAssignment = IpAssignment.UNASSIGNED;
- proxySettings = ProxySettings.UNASSIGNED;
- linkProperties = new LinkProperties();
- }
- }
-
- public IpConfiguration() {
- this(null);
- }
-
- public IpConfiguration(IpAssignment ipAssignment,
- ProxySettings proxySettings,
- LinkProperties linkProperties) {
- this.ipAssignment = ipAssignment;
- this.proxySettings = proxySettings;
- this.linkProperties = new LinkProperties(linkProperties);
- }
-
- @Override
- public String toString() {
- StringBuilder sbuf = new StringBuilder();
- sbuf.append("IP assignment: " + ipAssignment.toString());
- sbuf.append("\n");
- sbuf.append("Proxy settings: " + proxySettings.toString());
- sbuf.append("\n");
- sbuf.append(linkProperties.toString());
- sbuf.append("\n");
-
- return sbuf.toString();
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
-
- if (!(o instanceof IpConfiguration)) {
- return false;
- }
-
- IpConfiguration other = (IpConfiguration) o;
- return this.ipAssignment == other.ipAssignment &&
- this.proxySettings == other.proxySettings &&
- Objects.equals(this.linkProperties, other.linkProperties);
- }
-
- @Override
- public int hashCode() {
- return 13 + (linkProperties != null ? linkProperties.hashCode() : 0) +
- 17 * ipAssignment.ordinal() +
- 47 * proxySettings.ordinal();
- }
-
- /** Implement the Parcelable interface */
- public int describeContents() {
- return 0;
- }
-
- /** Implement the Parcelable interface */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(ipAssignment.name());
- dest.writeString(proxySettings.name());
- dest.writeParcelable(linkProperties, flags);
- }
-
- /** Implement the Parcelable interface */
- public static final Creator<IpConfiguration> CREATOR =
- new Creator<IpConfiguration>() {
- public IpConfiguration createFromParcel(Parcel in) {
- IpConfiguration config = new IpConfiguration();
- config.ipAssignment = IpAssignment.valueOf(in.readString());
- config.proxySettings = ProxySettings.valueOf(in.readString());
- config.linkProperties = in.readParcelable(null);
- return config;
- }
-
- public IpConfiguration[] newArray(int size) {
- return new IpConfiguration[size];
- }
- };
-}
diff --git a/core/java/android/net/IpPrefix.java b/core/java/android/net/IpPrefix.java
deleted file mode 100644
index dfe0384..0000000
--- a/core/java/android/net/IpPrefix.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.Arrays;
-
-/**
- * This class represents an IP prefix, i.e., a contiguous block of IP addresses aligned on a
- * power of two boundary (also known as an "IP subnet"). A prefix is specified by two pieces of
- * information:
- *
- * <ul>
- * <li>A starting IP address (IPv4 or IPv6). This is the first IP address of the prefix.
- * <li>A prefix length. This specifies the length of the prefix by specifing the number of bits
- * in the IP address, starting from the most significant bit in network byte order, that
- * are constant for all addresses in the prefix.
- * </ul>
- *
- * For example, the prefix <code>192.0.2.0/24</code> covers the 256 IPv4 addresses from
- * <code>192.0.2.0</code> to <code>192.0.2.255</code>, inclusive, and the prefix
- * <code>2001:db8:1:2</code> covers the 2^64 IPv6 addresses from <code>2001:db8:1:2::</code> to
- * <code>2001:db8:1:2:ffff:ffff:ffff:ffff</code>, inclusive.
- *
- * Objects of this class are immutable.
- */
-public class IpPrefix implements Parcelable {
- private final byte[] address; // network byte order
- private final int prefixLength;
-
- /**
- * Constructs a new {@code IpPrefix} from a byte array containing an IPv4 or IPv6 address in
- * network byte order and a prefix length.
- *
- * @param address the IP address. Must be non-null and exactly 4 or 16 bytes long.
- * @param prefixLength the prefix length. Must be >= 0 and <= (32 or 128) (IPv4 or IPv6).
- *
- * @hide
- */
- public IpPrefix(byte[] address, int prefixLength) {
- if (address.length != 4 && address.length != 16) {
- throw new IllegalArgumentException(
- "IpPrefix has " + address.length + " bytes which is neither 4 nor 16");
- }
- if (prefixLength < 0 || prefixLength > (address.length * 8)) {
- throw new IllegalArgumentException("IpPrefix with " + address.length +
- " bytes has invalid prefix length " + prefixLength);
- }
- this.address = address.clone();
- this.prefixLength = prefixLength;
- // TODO: Validate that the non-prefix bits are zero
- }
-
- /**
- * @hide
- */
- public IpPrefix(InetAddress address, int prefixLength) {
- this(address.getAddress(), prefixLength);
- }
-
- /**
- * Compares this {@code IpPrefix} object against the specified object in {@code obj}. Two
- * objects are equal if they have the same startAddress and prefixLength.
- *
- * @param obj the object to be tested for equality.
- * @return {@code true} if both objects are equal, {@code false} otherwise.
- */
- @Override
- public boolean equals(Object obj) {
- if (!(obj instanceof IpPrefix)) {
- return false;
- }
- IpPrefix that = (IpPrefix) obj;
- return Arrays.equals(this.address, that.address) && this.prefixLength == that.prefixLength;
- }
-
- /**
- * Gets the hashcode of the represented IP prefix.
- *
- * @return the appropriate hashcode value.
- */
- @Override
- public int hashCode() {
- return Arrays.hashCode(address) + 11 * prefixLength;
- }
-
- /**
- * Returns a copy of the first IP address in the prefix. Modifying the returned object does not
- * change this object's contents.
- *
- * @return the address in the form of a byte array.
- */
- public InetAddress getAddress() {
- try {
- return InetAddress.getByAddress(address);
- } catch (UnknownHostException e) {
- // Cannot happen. InetAddress.getByAddress can only throw an exception if the byte
- // array is the wrong length, but we check that in the constructor.
- return null;
- }
- }
-
- /**
- * Returns a copy of the IP address bytes in network order (the highest order byte is the zeroth
- * element). Modifying the returned array does not change this object's contents.
- *
- * @return the address in the form of a byte array.
- */
- public byte[] getRawAddress() {
- return address.clone();
- }
-
- /**
- * Returns the prefix length of this {@code IpAddress}.
- *
- * @return the prefix length.
- */
- public int getPrefixLength() {
- return prefixLength;
- }
-
- /**
- * Implement the Parcelable interface.
- * @hide
- */
- public int describeContents() {
- return 0;
- }
-
- /**
- * Implement the Parcelable interface.
- * @hide
- */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeByteArray(address);
- dest.writeInt(prefixLength);
- }
-
- /**
- * Implement the Parcelable interface.
- * @hide
- */
- public static final Creator<IpPrefix> CREATOR =
- new Creator<IpPrefix>() {
- public IpPrefix createFromParcel(Parcel in) {
- byte[] address = in.createByteArray();
- int prefixLength = in.readInt();
- return new IpPrefix(address, prefixLength);
- }
-
- public IpPrefix[] newArray(int size) {
- return new IpPrefix[size];
- }
- };
-}
diff --git a/core/java/android/net/LinkAddress.java b/core/java/android/net/LinkAddress.java
deleted file mode 100644
index 5246078..0000000
--- a/core/java/android/net/LinkAddress.java
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.net.InterfaceAddress;
-import java.net.UnknownHostException;
-
-import static android.system.OsConstants.IFA_F_DADFAILED;
-import static android.system.OsConstants.IFA_F_DEPRECATED;
-import static android.system.OsConstants.IFA_F_TENTATIVE;
-import static android.system.OsConstants.RT_SCOPE_HOST;
-import static android.system.OsConstants.RT_SCOPE_LINK;
-import static android.system.OsConstants.RT_SCOPE_SITE;
-import static android.system.OsConstants.RT_SCOPE_UNIVERSE;
-
-/**
- * Identifies an IP address on a network link.
- *
- * A {@code LinkAddress} consists of:
- * <ul>
- * <li>An IP address and prefix length (e.g., {@code 2001:db8::1/64} or {@code 192.0.2.1/24}).
- * The address must be unicast, as multicast addresses cannot be assigned to interfaces.
- * <li>Address flags: A bitmask of {@code OsConstants.IFA_F_*} values representing properties
- * of the address (e.g., {@code android.system.OsConstants.IFA_F_OPTIMISTIC}).
- * <li>Address scope: One of the {@code OsConstants.IFA_F_*} values; defines the scope in which
- * the address is unique (e.g.,
- * {@code android.system.OsConstants.RT_SCOPE_LINK} or
- * {@code android.system.OsConstants.RT_SCOPE_UNIVERSE}).
- * </ul>
- */
-public class LinkAddress implements Parcelable {
- /**
- * IPv4 or IPv6 address.
- */
- private InetAddress address;
-
- /**
- * Prefix length.
- */
- private int prefixLength;
-
- /**
- * Address flags. A bitmask of IFA_F_* values.
- */
- private int flags;
-
- /**
- * Address scope. One of the RT_SCOPE_* constants.
- */
- private int scope;
-
- /**
- * Utility function to determines the scope of a unicast address. Per RFC 4291 section 2.5 and
- * RFC 6724 section 3.2.
- * @hide
- */
- static int scopeForUnicastAddress(InetAddress addr) {
- if (addr.isAnyLocalAddress()) {
- return RT_SCOPE_HOST;
- }
-
- if (addr.isLoopbackAddress() || addr.isLinkLocalAddress()) {
- return RT_SCOPE_LINK;
- }
-
- // isSiteLocalAddress() returns true for private IPv4 addresses, but RFC 6724 section 3.2
- // says that they are assigned global scope.
- if (!(addr instanceof Inet4Address) && addr.isSiteLocalAddress()) {
- return RT_SCOPE_SITE;
- }
-
- return RT_SCOPE_UNIVERSE;
- }
-
- /**
- * Utility function for the constructors.
- */
- private void init(InetAddress address, int prefixLength, int flags, int scope) {
- if (address == null ||
- address.isMulticastAddress() ||
- prefixLength < 0 ||
- ((address instanceof Inet4Address) && prefixLength > 32) ||
- (prefixLength > 128)) {
- throw new IllegalArgumentException("Bad LinkAddress params " + address +
- "/" + prefixLength);
- }
- this.address = address;
- this.prefixLength = prefixLength;
- this.flags = flags;
- this.scope = scope;
- }
-
- /**
- * Constructs a new {@code LinkAddress} from an {@code InetAddress} and prefix length, with
- * the specified flags and scope. Flags and scope are not checked for validity.
- * @param address The IP address.
- * @param prefixLength The prefix length.
- * @param flags A bitmask of {@code IFA_F_*} values representing properties of the address.
- * @param scope An integer defining the scope in which the address is unique (e.g.,
- * {@link OsConstants#RT_SCOPE_LINK} or {@link OsConstants#RT_SCOPE_SITE}).
- * @hide
- */
- public LinkAddress(InetAddress address, int prefixLength, int flags, int scope) {
- init(address, prefixLength, flags, scope);
- }
-
- /**
- * Constructs a new {@code LinkAddress} from an {@code InetAddress} and a prefix length.
- * The flags are set to zero and the scope is determined from the address.
- * @param address The IP address.
- * @param prefixLength The prefix length.
- * @hide
- */
- public LinkAddress(InetAddress address, int prefixLength) {
- this(address, prefixLength, 0, 0);
- this.scope = scopeForUnicastAddress(address);
- }
-
- /**
- * Constructs a new {@code LinkAddress} from an {@code InterfaceAddress}.
- * The flags are set to zero and the scope is determined from the address.
- * @param interfaceAddress The interface address.
- * @hide
- */
- public LinkAddress(InterfaceAddress interfaceAddress) {
- this(interfaceAddress.getAddress(),
- interfaceAddress.getNetworkPrefixLength());
- }
-
- /**
- * Constructs a new {@code LinkAddress} from a string such as "192.0.2.5/24" or
- * "2001:db8::1/64". The flags are set to zero and the scope is determined from the address.
- * @param string The string to parse.
- * @hide
- */
- public LinkAddress(String address) {
- this(address, 0, 0);
- this.scope = scopeForUnicastAddress(this.address);
- }
-
- /**
- * Constructs a new {@code LinkAddress} from a string such as "192.0.2.5/24" or
- * "2001:db8::1/64", with the specified flags and scope.
- * @param string The string to parse.
- * @param flags The address flags.
- * @param scope The address scope.
- * @hide
- */
- public LinkAddress(String address, int flags, int scope) {
- InetAddress inetAddress = null;
- int prefixLength = -1;
- try {
- String [] pieces = address.split("/", 2);
- prefixLength = Integer.parseInt(pieces[1]);
- inetAddress = InetAddress.parseNumericAddress(pieces[0]);
- } catch (NullPointerException e) { // Null string.
- } catch (ArrayIndexOutOfBoundsException e) { // No prefix length.
- } catch (NumberFormatException e) { // Non-numeric prefix.
- } catch (IllegalArgumentException e) { // Invalid IP address.
- }
-
- if (inetAddress == null || prefixLength == -1) {
- throw new IllegalArgumentException("Bad LinkAddress params " + address);
- }
-
- init(inetAddress, prefixLength, flags, scope);
- }
-
- /**
- * Returns a string representation of this address, such as "192.0.2.1/24" or "2001:db8::1/64".
- * The string representation does not contain the flags and scope, just the address and prefix
- * length.
- */
- @Override
- public String toString() {
- return address.getHostAddress() + "/" + prefixLength;
- }
-
- /**
- * Compares this {@code LinkAddress} instance against {@code obj}. Two addresses are equal if
- * their address, prefix length, flags and scope are equal. Thus, for example, two addresses
- * that have the same address and prefix length are not equal if one of them is deprecated and
- * the other is not.
- *
- * @param obj the object to be tested for equality.
- * @return {@code true} if both objects are equal, {@code false} otherwise.
- */
- @Override
- public boolean equals(Object obj) {
- if (!(obj instanceof LinkAddress)) {
- return false;
- }
- LinkAddress linkAddress = (LinkAddress) obj;
- return this.address.equals(linkAddress.address) &&
- this.prefixLength == linkAddress.prefixLength &&
- this.flags == linkAddress.flags &&
- this.scope == linkAddress.scope;
- }
-
- /**
- * Returns a hashcode for this address.
- */
- @Override
- public int hashCode() {
- return address.hashCode() + 11 * prefixLength + 19 * flags + 43 * scope;
- }
-
- /**
- * Determines whether this {@code LinkAddress} and the provided {@code LinkAddress}
- * represent the same address. Two {@code LinkAddresses} represent the same address
- * if they have the same IP address and prefix length, even if their properties are
- * different.
- *
- * @param other the {@code LinkAddress} to compare to.
- * @return {@code true} if both objects have the same address and prefix length, {@code false}
- * otherwise.
- * @hide
- */
- public boolean isSameAddressAs(LinkAddress other) {
- return address.equals(other.address) && prefixLength == other.prefixLength;
- }
-
- /**
- * Returns the {@link InetAddress} of this {@code LinkAddress}.
- */
- public InetAddress getAddress() {
- return address;
- }
-
- /**
- * Returns the prefix length of this {@code LinkAddress}.
- */
- public int getPrefixLength() {
- return prefixLength;
- }
-
- /**
- * Returns the prefix length of this {@code LinkAddress}.
- * TODO: Delete all callers and remove in favour of getPrefixLength().
- * @hide
- */
- public int getNetworkPrefixLength() {
- return getPrefixLength();
- }
-
- /**
- * Returns the flags of this {@code LinkAddress}.
- */
- public int getFlags() {
- return flags;
- }
-
- /**
- * Returns the scope of this {@code LinkAddress}.
- */
- public int getScope() {
- return scope;
- }
-
- /**
- * Returns true if this {@code LinkAddress} is global scope and preferred.
- * @hide
- */
- public boolean isGlobalPreferred() {
- return (scope == RT_SCOPE_UNIVERSE &&
- (flags & (IFA_F_DADFAILED | IFA_F_DEPRECATED | IFA_F_TENTATIVE)) == 0L);
- }
-
- /**
- * Implement the Parcelable interface.
- * @hide
- */
- public int describeContents() {
- return 0;
- }
-
- /**
- * Implement the Parcelable interface.
- * @hide
- */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeByteArray(address.getAddress());
- dest.writeInt(prefixLength);
- dest.writeInt(this.flags);
- dest.writeInt(scope);
- }
-
- /**
- * Implement the Parcelable interface.
- * @hide
- */
- public static final Creator<LinkAddress> CREATOR =
- new Creator<LinkAddress>() {
- public LinkAddress createFromParcel(Parcel in) {
- InetAddress address = null;
- try {
- address = InetAddress.getByAddress(in.createByteArray());
- } catch (UnknownHostException e) {
- // Nothing we can do here. When we call the constructor, we'll throw an
- // IllegalArgumentException, because a LinkAddress can't have a null
- // InetAddress.
- }
- int prefixLength = in.readInt();
- int flags = in.readInt();
- int scope = in.readInt();
- return new LinkAddress(address, prefixLength, flags, scope);
- }
-
- public LinkAddress[] newArray(int size) {
- return new LinkAddress[size];
- }
- };
-}
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
deleted file mode 100644
index bb05936..0000000
--- a/core/java/android/net/LinkProperties.java
+++ /dev/null
@@ -1,880 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.net.ProxyInfo;
-import android.os.Parcelable;
-import android.os.Parcel;
-import android.text.TextUtils;
-
-import java.net.InetAddress;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Hashtable;
-import java.util.List;
-
-/**
- * Describes the properties of a network link.
- *
- * A link represents a connection to a network.
- * It may have multiple addresses and multiple gateways,
- * multiple dns servers but only one http proxy and one
- * network interface.
- *
- * Note that this is just a holder of data. Modifying it
- * does not affect live networks.
- *
- */
-public class LinkProperties implements Parcelable {
- // The interface described by the network link.
- private String mIfaceName;
- private ArrayList<LinkAddress> mLinkAddresses = new ArrayList<LinkAddress>();
- private ArrayList<InetAddress> mDnses = new ArrayList<InetAddress>();
- private String mDomains;
- private ArrayList<RouteInfo> mRoutes = new ArrayList<RouteInfo>();
- private ProxyInfo mHttpProxy;
- private int mMtu;
-
- // Stores the properties of links that are "stacked" above this link.
- // Indexed by interface name to allow modification and to prevent duplicates being added.
- private Hashtable<String, LinkProperties> mStackedLinks =
- new Hashtable<String, LinkProperties>();
-
- /**
- * @hide
- */
- public static class CompareResult<T> {
- public List<T> removed = new ArrayList<T>();
- public List<T> added = new ArrayList<T>();
-
- @Override
- public String toString() {
- String retVal = "removed=[";
- for (T addr : removed) retVal += addr.toString() + ",";
- retVal += "] added=[";
- for (T addr : added) retVal += addr.toString() + ",";
- retVal += "]";
- return retVal;
- }
- }
-
- /**
- * @hide
- */
- public LinkProperties() {
- }
-
- /**
- * @hide
- */
- public LinkProperties(LinkProperties source) {
- if (source != null) {
- mIfaceName = source.getInterfaceName();
- for (LinkAddress l : source.getLinkAddresses()) mLinkAddresses.add(l);
- for (InetAddress i : source.getDnsServers()) mDnses.add(i);
- mDomains = source.getDomains();
- for (RouteInfo r : source.getRoutes()) mRoutes.add(r);
- mHttpProxy = (source.getHttpProxy() == null) ?
- null : new ProxyInfo(source.getHttpProxy());
- for (LinkProperties l: source.mStackedLinks.values()) {
- addStackedLink(l);
- }
- setMtu(source.getMtu());
- }
- }
-
- /**
- * Sets the interface name for this link. All {@link RouteInfo} already set for this
- * will have their interface changed to match this new value.
- *
- * @param iface The name of the network interface used for this link.
- * @hide
- */
- public void setInterfaceName(String iface) {
- mIfaceName = iface;
- ArrayList<RouteInfo> newRoutes = new ArrayList<RouteInfo>(mRoutes.size());
- for (RouteInfo route : mRoutes) {
- newRoutes.add(routeWithInterface(route));
- }
- mRoutes = newRoutes;
- }
-
- /**
- * Gets the interface name for this link. May be {@code null} if not set.
- *
- * @return The interface name set for this link or {@code null}.
- */
- public String getInterfaceName() {
- return mIfaceName;
- }
-
- /**
- * @hide
- */
- public List<String> getAllInterfaceNames() {
- List<String> interfaceNames = new ArrayList<String>(mStackedLinks.size() + 1);
- if (mIfaceName != null) interfaceNames.add(new String(mIfaceName));
- for (LinkProperties stacked: mStackedLinks.values()) {
- interfaceNames.addAll(stacked.getAllInterfaceNames());
- }
- return interfaceNames;
- }
-
- /**
- * Returns all the addresses on this link. We often think of a link having a single address,
- * however, particularly with Ipv6 several addresses are typical. Note that the
- * {@code LinkProperties} actually contains {@link LinkAddress} objects which also include
- * prefix lengths for each address. This is a simplified utility alternative to
- * {@link LinkProperties#getLinkAddresses}.
- *
- * @return An umodifiable {@link List} of {@link InetAddress} for this link.
- * @hide
- */
- public List<InetAddress> getAddresses() {
- List<InetAddress> addresses = new ArrayList<InetAddress>();
- for (LinkAddress linkAddress : mLinkAddresses) {
- addresses.add(linkAddress.getAddress());
- }
- return Collections.unmodifiableList(addresses);
- }
-
- /**
- * Returns all the addresses on this link and all the links stacked above it.
- * @hide
- */
- public List<InetAddress> getAllAddresses() {
- List<InetAddress> addresses = new ArrayList<InetAddress>();
- for (LinkAddress linkAddress : mLinkAddresses) {
- addresses.add(linkAddress.getAddress());
- }
- for (LinkProperties stacked: mStackedLinks.values()) {
- addresses.addAll(stacked.getAllAddresses());
- }
- return addresses;
- }
-
- private int findLinkAddressIndex(LinkAddress address) {
- for (int i = 0; i < mLinkAddresses.size(); i++) {
- if (mLinkAddresses.get(i).isSameAddressAs(address)) {
- return i;
- }
- }
- return -1;
- }
-
- /**
- * Adds a {@link LinkAddress} to this {@code LinkProperties} if a {@link LinkAddress} of the
- * same address/prefix does not already exist. If it does exist it is replaced.
- * @param address The {@code LinkAddress} to add.
- * @return true if {@code address} was added or updated, false otherwise.
- * @hide
- */
- public boolean addLinkAddress(LinkAddress address) {
- if (address == null) {
- return false;
- }
- int i = findLinkAddressIndex(address);
- if (i < 0) {
- // Address was not present. Add it.
- mLinkAddresses.add(address);
- return true;
- } else if (mLinkAddresses.get(i).equals(address)) {
- // Address was present and has same properties. Do nothing.
- return false;
- } else {
- // Address was present and has different properties. Update it.
- mLinkAddresses.set(i, address);
- return true;
- }
- }
-
- /**
- * Removes a {@link LinkAddress} from this {@code LinkProperties}. Specifically, matches
- * and {@link LinkAddress} with the same address and prefix.
- *
- * @param toRemove A {@link LinkAddress} specifying the address to remove.
- * @return true if the address was removed, false if it did not exist.
- * @hide
- */
- public boolean removeLinkAddress(LinkAddress toRemove) {
- int i = findLinkAddressIndex(toRemove);
- if (i >= 0) {
- mLinkAddresses.remove(i);
- return true;
- }
- return false;
- }
-
- /**
- * Returns all the {@link LinkAddress} on this link. Typically a link will have
- * one IPv4 address and one or more IPv6 addresses.
- *
- * @return An unmodifiable {@link List} of {@link LinkAddress} for this link.
- */
- public List<LinkAddress> getLinkAddresses() {
- return Collections.unmodifiableList(mLinkAddresses);
- }
-
- /**
- * Returns all the addresses on this link and all the links stacked above it.
- * @hide
- */
- public List<LinkAddress> getAllLinkAddresses() {
- List<LinkAddress> addresses = new ArrayList<LinkAddress>();
- addresses.addAll(mLinkAddresses);
- for (LinkProperties stacked: mStackedLinks.values()) {
- addresses.addAll(stacked.getAllLinkAddresses());
- }
- return addresses;
- }
-
- /**
- * Replaces the {@link LinkAddress} in this {@code LinkProperties} with
- * the given {@link Collection} of {@link LinkAddress}.
- *
- * @param addresses The {@link Collection} of {@link LinkAddress} to set in this
- * object.
- * @hide
- */
- public void setLinkAddresses(Collection<LinkAddress> addresses) {
- mLinkAddresses.clear();
- for (LinkAddress address: addresses) {
- addLinkAddress(address);
- }
- }
-
- /**
- * Adds the given {@link InetAddress} to the list of DNS servers.
- *
- * @param dnsServer The {@link InetAddress} to add to the list of DNS servers.
- * @hide
- */
- public void addDnsServer(InetAddress dnsServer) {
- if (dnsServer != null) mDnses.add(dnsServer);
- }
-
- /**
- * Returns all the {@link InetAddress} for DNS servers on this link.
- *
- * @return An umodifiable {@link List} of {@link InetAddress} for DNS servers on
- * this link.
- */
- public List<InetAddress> getDnsServers() {
- return Collections.unmodifiableList(mDnses);
- }
-
- /**
- * Sets the DNS domain search path used on this link.
- *
- * @param domains A {@link String} listing in priority order the comma separated
- * domains to search when resolving host names on this link.
- * @hide
- */
- public void setDomains(String domains) {
- mDomains = domains;
- }
-
- /**
- * Get the DNS domains search path set for this link.
- *
- * @return A {@link String} containing the comma separated domains to search when resolving
- * host names on this link.
- */
- public String getDomains() {
- return mDomains;
- }
-
- /**
- * Sets the Maximum Transmission Unit size to use on this link. This should not be used
- * unless the system default (1500) is incorrect. Values less than 68 or greater than
- * 10000 will be ignored.
- *
- * @param mtu The MTU to use for this link.
- * @hide
- */
- public void setMtu(int mtu) {
- mMtu = mtu;
- }
-
- /**
- * Gets any non-default MTU size set for this link. Note that if the default is being used
- * this will return 0.
- *
- * @return The mtu value set for this link.
- * @hide
- */
- public int getMtu() {
- return mMtu;
- }
-
- private RouteInfo routeWithInterface(RouteInfo route) {
- return new RouteInfo(
- route.getDestination(),
- route.getGateway(),
- mIfaceName);
- }
-
- /**
- * Adds a {@link RouteInfo} to this {@code LinkProperties}. If the {@link RouteInfo}
- * had an interface name set and that differs from the interface set for this
- * {@code LinkProperties} an {@link IllegalArgumentException} will be thrown. The
- * proper course is to add either un-named or properly named {@link RouteInfo}.
- *
- * @param route A {@link RouteInfo} to add to this object.
- * @hide
- */
- public void addRoute(RouteInfo route) {
- if (route != null) {
- String routeIface = route.getInterface();
- if (routeIface != null && !routeIface.equals(mIfaceName)) {
- throw new IllegalArgumentException(
- "Route added with non-matching interface: " + routeIface +
- " vs. " + mIfaceName);
- }
- mRoutes.add(routeWithInterface(route));
- }
- }
-
- /**
- * Returns all the {@link RouteInfo} set on this link.
- *
- * @return An unmodifiable {@link List} of {@link RouteInfo} for this link.
- */
- public List<RouteInfo> getRoutes() {
- return Collections.unmodifiableList(mRoutes);
- }
-
- /**
- * Returns all the routes on this link and all the links stacked above it.
- * @hide
- */
- public List<RouteInfo> getAllRoutes() {
- List<RouteInfo> routes = new ArrayList();
- routes.addAll(mRoutes);
- for (LinkProperties stacked: mStackedLinks.values()) {
- routes.addAll(stacked.getAllRoutes());
- }
- return routes;
- }
-
- /**
- * Sets the recommended {@link ProxyInfo} to use on this link, or {@code null} for none.
- * Note that Http Proxies are only a hint - the system recommends their use, but it does
- * not enforce it and applications may ignore them.
- *
- * @param proxy A {@link ProxyInfo} defining the Http Proxy to use on this link.
- * @hide
- */
- public void setHttpProxy(ProxyInfo proxy) {
- mHttpProxy = proxy;
- }
-
- /**
- * Gets the recommended {@link ProxyInfo} (or {@code null}) set on this link.
- *
- * @return The {@link ProxyInfo} set on this link
- */
- public ProxyInfo getHttpProxy() {
- return mHttpProxy;
- }
-
- /**
- * Adds a stacked link.
- *
- * If there is already a stacked link with the same interfacename as link,
- * that link is replaced with link. Otherwise, link is added to the list
- * of stacked links. If link is null, nothing changes.
- *
- * @param link The link to add.
- * @return true if the link was stacked, false otherwise.
- * @hide
- */
- public boolean addStackedLink(LinkProperties link) {
- if (link != null && link.getInterfaceName() != null) {
- mStackedLinks.put(link.getInterfaceName(), link);
- return true;
- }
- return false;
- }
-
- /**
- * Removes a stacked link.
- *
- * If there a stacked link with the same interfacename as link, it is
- * removed. Otherwise, nothing changes.
- *
- * @param link The link to remove.
- * @return true if the link was removed, false otherwise.
- * @hide
- */
- public boolean removeStackedLink(LinkProperties link) {
- if (link != null && link.getInterfaceName() != null) {
- LinkProperties removed = mStackedLinks.remove(link.getInterfaceName());
- return removed != null;
- }
- return false;
- }
-
- /**
- * Returns all the links stacked on top of this link.
- * @hide
- */
- public List<LinkProperties> getStackedLinks() {
- List<LinkProperties> stacked = new ArrayList<LinkProperties>();
- for (LinkProperties link : mStackedLinks.values()) {
- stacked.add(new LinkProperties(link));
- }
- return Collections.unmodifiableList(stacked);
- }
-
- /**
- * Clears this object to its initial state.
- * @hide
- */
- public void clear() {
- mIfaceName = null;
- mLinkAddresses.clear();
- mDnses.clear();
- mDomains = null;
- mRoutes.clear();
- mHttpProxy = null;
- mStackedLinks.clear();
- mMtu = 0;
- }
-
- /**
- * Implement the Parcelable interface
- * @hide
- */
- public int describeContents() {
- return 0;
- }
-
- @Override
- public String toString() {
- String ifaceName = (mIfaceName == null ? "" : "InterfaceName: " + mIfaceName + " ");
-
- String linkAddresses = "LinkAddresses: [";
- for (LinkAddress addr : mLinkAddresses) linkAddresses += addr.toString() + ",";
- linkAddresses += "] ";
-
- String dns = "DnsAddresses: [";
- for (InetAddress addr : mDnses) dns += addr.getHostAddress() + ",";
- dns += "] ";
-
- String domainName = "Domains: " + mDomains;
-
- String mtu = " MTU: " + mMtu;
-
- String routes = " Routes: [";
- for (RouteInfo route : mRoutes) routes += route.toString() + ",";
- routes += "] ";
- String proxy = (mHttpProxy == null ? "" : " HttpProxy: " + mHttpProxy.toString() + " ");
-
- String stacked = "";
- if (mStackedLinks.values().size() > 0) {
- stacked += " Stacked: [";
- for (LinkProperties link: mStackedLinks.values()) {
- stacked += " [" + link.toString() + " ],";
- }
- stacked += "] ";
- }
- return "{" + ifaceName + linkAddresses + routes + dns + domainName + mtu
- + proxy + stacked + "}";
- }
-
- /**
- * Returns true if this link has an IPv4 address.
- *
- * @return {@code true} if there is an IPv4 address, {@code false} otherwise.
- * @hide
- */
- public boolean hasIPv4Address() {
- for (LinkAddress address : mLinkAddresses) {
- if (address.getAddress() instanceof Inet4Address) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Returns true if this link has an IPv6 address.
- *
- * @return {@code true} if there is an IPv6 address, {@code false} otherwise.
- * @hide
- */
- public boolean hasIPv6Address() {
- for (LinkAddress address : mLinkAddresses) {
- if (address.getAddress() instanceof Inet6Address) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Compares this {@code LinkProperties} interface name against the target
- *
- * @param target LinkProperties to compare.
- * @return {@code true} if both are identical, {@code false} otherwise.
- * @hide
- */
- public boolean isIdenticalInterfaceName(LinkProperties target) {
- return TextUtils.equals(getInterfaceName(), target.getInterfaceName());
- }
-
- /**
- * Compares this {@code LinkProperties} interface addresses against the target
- *
- * @param target LinkProperties to compare.
- * @return {@code true} if both are identical, {@code false} otherwise.
- * @hide
- */
- public boolean isIdenticalAddresses(LinkProperties target) {
- Collection<InetAddress> targetAddresses = target.getAddresses();
- Collection<InetAddress> sourceAddresses = getAddresses();
- return (sourceAddresses.size() == targetAddresses.size()) ?
- sourceAddresses.containsAll(targetAddresses) : false;
- }
-
- /**
- * Compares this {@code LinkProperties} DNS addresses against the target
- *
- * @param target LinkProperties to compare.
- * @return {@code true} if both are identical, {@code false} otherwise.
- * @hide
- */
- public boolean isIdenticalDnses(LinkProperties target) {
- Collection<InetAddress> targetDnses = target.getDnsServers();
- String targetDomains = target.getDomains();
- if (mDomains == null) {
- if (targetDomains != null) return false;
- } else {
- if (mDomains.equals(targetDomains) == false) return false;
- }
- return (mDnses.size() == targetDnses.size()) ?
- mDnses.containsAll(targetDnses) : false;
- }
-
- /**
- * Compares this {@code LinkProperties} Routes against the target
- *
- * @param target LinkProperties to compare.
- * @return {@code true} if both are identical, {@code false} otherwise.
- * @hide
- */
- public boolean isIdenticalRoutes(LinkProperties target) {
- Collection<RouteInfo> targetRoutes = target.getRoutes();
- return (mRoutes.size() == targetRoutes.size()) ?
- mRoutes.containsAll(targetRoutes) : false;
- }
-
- /**
- * Compares this {@code LinkProperties} HttpProxy against the target
- *
- * @param target LinkProperties to compare.
- * @return {@code true} if both are identical, {@code false} otherwise.
- * @hide
- */
- public boolean isIdenticalHttpProxy(LinkProperties target) {
- return getHttpProxy() == null ? target.getHttpProxy() == null :
- getHttpProxy().equals(target.getHttpProxy());
- }
-
- /**
- * Compares this {@code LinkProperties} stacked links against the target
- *
- * @param target LinkProperties to compare.
- * @return {@code true} if both are identical, {@code false} otherwise.
- * @hide
- */
- public boolean isIdenticalStackedLinks(LinkProperties target) {
- if (!mStackedLinks.keySet().equals(target.mStackedLinks.keySet())) {
- return false;
- }
- for (LinkProperties stacked : mStackedLinks.values()) {
- // Hashtable values can never be null.
- String iface = stacked.getInterfaceName();
- if (!stacked.equals(target.mStackedLinks.get(iface))) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Compares this {@code LinkProperties} MTU against the target
- *
- * @param target LinkProperties to compare.
- * @return {@code true} if both are identical, {@code false} otherwise.
- * @hide
- */
- public boolean isIdenticalMtu(LinkProperties target) {
- return getMtu() == target.getMtu();
- }
-
- @Override
- /**
- * Compares this {@code LinkProperties} instance against the target
- * LinkProperties in {@code obj}. Two LinkPropertieses are equal if
- * all their fields are equal in values.
- *
- * For collection fields, such as mDnses, containsAll() is used to check
- * if two collections contains the same elements, independent of order.
- * There are two thoughts regarding containsAll()
- * 1. Duplicated elements. eg, (A, B, B) and (A, A, B) are equal.
- * 2. Worst case performance is O(n^2).
- *
- * @param obj the object to be tested for equality.
- * @return {@code true} if both objects are equal, {@code false} otherwise.
- */
- public boolean equals(Object obj) {
- if (this == obj) return true;
-
- if (!(obj instanceof LinkProperties)) return false;
-
- LinkProperties target = (LinkProperties) obj;
- /**
- * This method does not check that stacked interfaces are equal, because
- * stacked interfaces are not so much a property of the link as a
- * description of connections between links.
- */
- return isIdenticalInterfaceName(target) &&
- isIdenticalAddresses(target) &&
- isIdenticalDnses(target) &&
- isIdenticalRoutes(target) &&
- isIdenticalHttpProxy(target) &&
- isIdenticalStackedLinks(target) &&
- isIdenticalMtu(target);
- }
-
- /**
- * Compares the addresses in this LinkProperties with another
- * LinkProperties, examining only addresses on the base link.
- *
- * @param target a LinkProperties with the new list of addresses
- * @return the differences between the addresses.
- * @hide
- */
- public CompareResult<LinkAddress> compareAddresses(LinkProperties target) {
- /*
- * Duplicate the LinkAddresses into removed, we will be removing
- * address which are common between mLinkAddresses and target
- * leaving the addresses that are different. And address which
- * are in target but not in mLinkAddresses are placed in the
- * addedAddresses.
- */
- CompareResult<LinkAddress> result = new CompareResult<LinkAddress>();
- result.removed = new ArrayList<LinkAddress>(mLinkAddresses);
- result.added.clear();
- if (target != null) {
- for (LinkAddress newAddress : target.getLinkAddresses()) {
- if (! result.removed.remove(newAddress)) {
- result.added.add(newAddress);
- }
- }
- }
- return result;
- }
-
- /**
- * Compares the DNS addresses in this LinkProperties with another
- * LinkProperties, examining only DNS addresses on the base link.
- *
- * @param target a LinkProperties with the new list of dns addresses
- * @return the differences between the DNS addresses.
- * @hide
- */
- public CompareResult<InetAddress> compareDnses(LinkProperties target) {
- /*
- * Duplicate the InetAddresses into removed, we will be removing
- * dns address which are common between mDnses and target
- * leaving the addresses that are different. And dns address which
- * are in target but not in mDnses are placed in the
- * addedAddresses.
- */
- CompareResult<InetAddress> result = new CompareResult<InetAddress>();
-
- result.removed = new ArrayList<InetAddress>(mDnses);
- result.added.clear();
- if (target != null) {
- for (InetAddress newAddress : target.getDnsServers()) {
- if (! result.removed.remove(newAddress)) {
- result.added.add(newAddress);
- }
- }
- }
- return result;
- }
-
- /**
- * Compares all routes in this LinkProperties with another LinkProperties,
- * examining both the the base link and all stacked links.
- *
- * @param target a LinkProperties with the new list of routes
- * @return the differences between the routes.
- * @hide
- */
- public CompareResult<RouteInfo> compareAllRoutes(LinkProperties target) {
- /*
- * Duplicate the RouteInfos into removed, we will be removing
- * routes which are common between mRoutes and target
- * leaving the routes that are different. And route address which
- * are in target but not in mRoutes are placed in added.
- */
- CompareResult<RouteInfo> result = new CompareResult<RouteInfo>();
-
- result.removed = getAllRoutes();
- result.added.clear();
- if (target != null) {
- for (RouteInfo r : target.getAllRoutes()) {
- if (! result.removed.remove(r)) {
- result.added.add(r);
- }
- }
- }
- return result;
- }
-
- /**
- * Compares all interface names in this LinkProperties with another
- * LinkProperties, examining both the the base link and all stacked links.
- *
- * @param target a LinkProperties with the new list of interface names
- * @return the differences between the interface names.
- * @hide
- */
- public CompareResult<String> compareAllInterfaceNames(LinkProperties target) {
- /*
- * Duplicate the interface names into removed, we will be removing
- * interface names which are common between this and target
- * leaving the interface names that are different. And interface names which
- * are in target but not in this are placed in added.
- */
- CompareResult<String> result = new CompareResult<String>();
-
- result.removed = getAllInterfaceNames();
- result.added.clear();
- if (target != null) {
- for (String r : target.getAllInterfaceNames()) {
- if (! result.removed.remove(r)) {
- result.added.add(r);
- }
- }
- }
- return result;
- }
-
-
- @Override
- /**
- * generate hashcode based on significant fields
- * Equal objects must produce the same hash code, while unequal objects
- * may have the same hash codes.
- */
- public int hashCode() {
- return ((null == mIfaceName) ? 0 : mIfaceName.hashCode()
- + mLinkAddresses.size() * 31
- + mDnses.size() * 37
- + ((null == mDomains) ? 0 : mDomains.hashCode())
- + mRoutes.size() * 41
- + ((null == mHttpProxy) ? 0 : mHttpProxy.hashCode())
- + mStackedLinks.hashCode() * 47)
- + mMtu * 51;
- }
-
- /**
- * Implement the Parcelable interface.
- */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(getInterfaceName());
- dest.writeInt(mLinkAddresses.size());
- for(LinkAddress linkAddress : mLinkAddresses) {
- dest.writeParcelable(linkAddress, flags);
- }
-
- dest.writeInt(mDnses.size());
- for(InetAddress d : mDnses) {
- dest.writeByteArray(d.getAddress());
- }
- dest.writeString(mDomains);
- dest.writeInt(mMtu);
- dest.writeInt(mRoutes.size());
- for(RouteInfo route : mRoutes) {
- dest.writeParcelable(route, flags);
- }
-
- if (mHttpProxy != null) {
- dest.writeByte((byte)1);
- dest.writeParcelable(mHttpProxy, flags);
- } else {
- dest.writeByte((byte)0);
- }
- ArrayList<LinkProperties> stackedLinks = new ArrayList(mStackedLinks.values());
- dest.writeList(stackedLinks);
- }
-
- /**
- * Implement the Parcelable interface.
- */
- public static final Creator<LinkProperties> CREATOR =
- new Creator<LinkProperties>() {
- public LinkProperties createFromParcel(Parcel in) {
- LinkProperties netProp = new LinkProperties();
-
- String iface = in.readString();
- if (iface != null) {
- netProp.setInterfaceName(iface);
- }
- int addressCount = in.readInt();
- for (int i=0; i<addressCount; i++) {
- netProp.addLinkAddress((LinkAddress)in.readParcelable(null));
- }
- addressCount = in.readInt();
- for (int i=0; i<addressCount; i++) {
- try {
- netProp.addDnsServer(InetAddress.getByAddress(in.createByteArray()));
- } catch (UnknownHostException e) { }
- }
- netProp.setDomains(in.readString());
- netProp.setMtu(in.readInt());
- addressCount = in.readInt();
- for (int i=0; i<addressCount; i++) {
- netProp.addRoute((RouteInfo)in.readParcelable(null));
- }
- if (in.readByte() == 1) {
- netProp.setHttpProxy((ProxyInfo)in.readParcelable(null));
- }
- ArrayList<LinkProperties> stackedLinks = new ArrayList<LinkProperties>();
- in.readList(stackedLinks, LinkProperties.class.getClassLoader());
- for (LinkProperties stackedLink: stackedLinks) {
- netProp.addStackedLink(stackedLink);
- }
- return netProp;
- }
-
- public LinkProperties[] newArray(int size) {
- return new LinkProperties[size];
- }
- };
-}
diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java
deleted file mode 100644
index d933f26..0000000
--- a/core/java/android/net/Network.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.net.NetworkUtils;
-import android.os.Parcelable;
-import android.os.Parcel;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.net.UnknownHostException;
-import javax.net.SocketFactory;
-
-/**
- * Identifies a {@code Network}. This is supplied to applications via
- * {@link ConnectivityManager.NetworkCallbackListener} in response to
- * {@link ConnectivityManager#requestNetwork} or {@link ConnectivityManager#listenForNetwork}.
- * It is used to direct traffic to the given {@code Network}, either on a {@link Socket} basis
- * through a targeted {@link SocketFactory} or process-wide via
- * {@link ConnectivityManager#setProcessDefaultNetwork}.
- */
-public class Network implements Parcelable {
-
- /**
- * @hide
- */
- public final int netId;
-
- private NetworkBoundSocketFactory mNetworkBoundSocketFactory = null;
-
- /**
- * @hide
- */
- public Network(int netId) {
- this.netId = netId;
- }
-
- /**
- * @hide
- */
- public Network(Network that) {
- this.netId = that.netId;
- }
-
- /**
- * Operates the same as {@code InetAddress.getAllByName} except that host
- * resolution is done on this network.
- *
- * @param host the hostname or literal IP string to be resolved.
- * @return the array of addresses associated with the specified host.
- * @throws UnknownHostException if the address lookup fails.
- */
- public InetAddress[] getAllByName(String host) throws UnknownHostException {
- return InetAddress.getAllByNameOnNet(host, netId);
- }
-
- /**
- * Operates the same as {@code InetAddress.getByName} except that host
- * resolution is done on this network.
- *
- * @param host
- * the hostName to be resolved to an address or {@code null}.
- * @return the {@code InetAddress} instance representing the host.
- * @throws UnknownHostException
- * if the address lookup fails.
- */
- public InetAddress getByName(String host) throws UnknownHostException {
- return InetAddress.getByNameOnNet(host, netId);
- }
-
- /**
- * A {@code SocketFactory} that produces {@code Socket}'s bound to this network.
- */
- private class NetworkBoundSocketFactory extends SocketFactory {
- private final int mNetId;
-
- public NetworkBoundSocketFactory(int netId) {
- super();
- mNetId = netId;
- }
-
- private void connectToHost(Socket socket, String host, int port) throws IOException {
- // Lookup addresses only on this Network.
- InetAddress[] hostAddresses = getAllByName(host);
- // Try all but last address ignoring exceptions.
- for (int i = 0; i < hostAddresses.length - 1; i++) {
- try {
- socket.connect(new InetSocketAddress(hostAddresses[i], port));
- return;
- } catch (IOException e) {
- }
- }
- // Try last address. Do throw exceptions.
- socket.connect(new InetSocketAddress(hostAddresses[hostAddresses.length - 1], port));
- }
-
- @Override
- public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {
- Socket socket = createSocket();
- socket.bind(new InetSocketAddress(localHost, localPort));
- connectToHost(socket, host, port);
- return socket;
- }
-
- @Override
- public Socket createSocket(InetAddress address, int port, InetAddress localAddress,
- int localPort) throws IOException {
- Socket socket = createSocket();
- socket.bind(new InetSocketAddress(localAddress, localPort));
- socket.connect(new InetSocketAddress(address, port));
- return socket;
- }
-
- @Override
- public Socket createSocket(InetAddress host, int port) throws IOException {
- Socket socket = createSocket();
- socket.connect(new InetSocketAddress(host, port));
- return socket;
- }
-
- @Override
- public Socket createSocket(String host, int port) throws IOException {
- Socket socket = createSocket();
- connectToHost(socket, host, port);
- return socket;
- }
-
- @Override
- public Socket createSocket() throws IOException {
- Socket socket = new Socket();
- // Query a property of the underlying socket to ensure the underlying
- // socket exists so a file descriptor is available to bind to a network.
- socket.getReuseAddress();
- NetworkUtils.bindSocketToNetwork(socket.getFileDescriptor$().getInt$(), mNetId);
- return socket;
- }
- }
-
- /**
- * Returns a {@link SocketFactory} bound to this network. Any {@link Socket} created by
- * this factory will have its traffic sent over this {@code Network}. Note that if this
- * {@code Network} ever disconnects, this factory and any {@link Socket} it produced in the
- * past or future will cease to work.
- *
- * @return a {@link SocketFactory} which produces {@link Socket} instances bound to this
- * {@code Network}.
- */
- public SocketFactory getSocketFactory() {
- if (mNetworkBoundSocketFactory == null) {
- mNetworkBoundSocketFactory = new NetworkBoundSocketFactory(netId);
- }
- return mNetworkBoundSocketFactory;
- }
-
- // implement the Parcelable interface
- public int describeContents() {
- return 0;
- }
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(netId);
- }
-
- public static final Creator<Network> CREATOR =
- new Creator<Network>() {
- public Network createFromParcel(Parcel in) {
- int netId = in.readInt();
-
- return new Network(netId);
- }
-
- public Network[] newArray(int size) {
- return new Network[size];
- }
- };
-
- public boolean equals(Object obj) {
- if (obj instanceof Network == false) return false;
- Network other = (Network)obj;
- return this.netId == other.netId;
- }
-
- public int hashCode() {
- return netId * 11;
- }
-}
diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java
deleted file mode 100644
index 3d0874b..0000000
--- a/core/java/android/net/NetworkAgent.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.content.Context;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Log;
-
-import com.android.internal.util.AsyncChannel;
-import com.android.internal.util.Protocol;
-
-import java.util.ArrayList;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * A Utility class for handling for communicating between bearer-specific
- * code and ConnectivityService.
- *
- * A bearer may have more than one NetworkAgent if it can simultaneously
- * support separate networks (IMS / Internet / MMS Apns on cellular, or
- * perhaps connections with different SSID or P2P for Wi-Fi).
- *
- * @hide
- */
-public abstract class NetworkAgent extends Handler {
- private volatile AsyncChannel mAsyncChannel;
- private final String LOG_TAG;
- private static final boolean DBG = true;
- private static final boolean VDBG = true;
- private final Context mContext;
- private final ArrayList<Message>mPreConnectedQueue = new ArrayList<Message>();
-
- private static final int BASE = Protocol.BASE_NETWORK_AGENT;
-
- /**
- * Sent by ConnectivityService to the NetworkAgent to inform it of
- * suspected connectivity problems on its network. The NetworkAgent
- * should take steps to verify and correct connectivity.
- */
- public static final int CMD_SUSPECT_BAD = BASE;
-
- /**
- * Sent by the NetworkAgent (note the EVENT vs CMD prefix) to
- * ConnectivityService to pass the current NetworkInfo (connection state).
- * Sent when the NetworkInfo changes, mainly due to change of state.
- * obj = NetworkInfo
- */
- public static final int EVENT_NETWORK_INFO_CHANGED = BASE + 1;
-
- /**
- * Sent by the NetworkAgent to ConnectivityService to pass the current
- * NetworkCapabilties.
- * obj = NetworkCapabilities
- */
- public static final int EVENT_NETWORK_CAPABILITIES_CHANGED = BASE + 2;
-
- /**
- * Sent by the NetworkAgent to ConnectivityService to pass the current
- * NetworkProperties.
- * obj = NetworkProperties
- */
- public static final int EVENT_NETWORK_PROPERTIES_CHANGED = BASE + 3;
-
- /* centralize place where base network score, and network score scaling, will be
- * stored, so as we can consistently compare apple and oranges, or wifi, ethernet and LTE
- */
- public static final int WIFI_BASE_SCORE = 60;
-
- /**
- * Sent by the NetworkAgent to ConnectivityService to pass the current
- * network score.
- * obj = network score Integer
- */
- public static final int EVENT_NETWORK_SCORE_CHANGED = BASE + 4;
-
- public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
- NetworkCapabilities nc, LinkProperties lp, int score) {
- super(looper);
- LOG_TAG = logTag;
- mContext = context;
- if (ni == null || nc == null || lp == null) {
- throw new IllegalArgumentException();
- }
-
- if (DBG) log("Registering NetworkAgent");
- ConnectivityManager cm = (ConnectivityManager)mContext.getSystemService(
- Context.CONNECTIVITY_SERVICE);
- cm.registerNetworkAgent(new Messenger(this), new NetworkInfo(ni),
- new LinkProperties(lp), new NetworkCapabilities(nc), score);
- }
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION: {
- if (mAsyncChannel != null) {
- log("Received new connection while already connected!");
- } else {
- if (DBG) log("NetworkAgent fully connected");
- AsyncChannel ac = new AsyncChannel();
- ac.connected(null, this, msg.replyTo);
- ac.replyToMessage(msg, AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED,
- AsyncChannel.STATUS_SUCCESSFUL);
- synchronized (mPreConnectedQueue) {
- mAsyncChannel = ac;
- for (Message m : mPreConnectedQueue) {
- ac.sendMessage(m);
- }
- mPreConnectedQueue.clear();
- }
- }
- break;
- }
- case AsyncChannel.CMD_CHANNEL_DISCONNECT: {
- if (DBG) log("CMD_CHANNEL_DISCONNECT");
- if (mAsyncChannel != null) mAsyncChannel.disconnect();
- break;
- }
- case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
- if (DBG) log("NetworkAgent channel lost");
- // let the client know CS is done with us.
- unwanted();
- synchronized (mPreConnectedQueue) {
- mAsyncChannel = null;
- }
- break;
- }
- case CMD_SUSPECT_BAD: {
- log("Unhandled Message " + msg);
- break;
- }
- }
- }
-
- private void queueOrSendMessage(int what, Object obj) {
- synchronized (mPreConnectedQueue) {
- if (mAsyncChannel != null) {
- mAsyncChannel.sendMessage(what, obj);
- } else {
- Message msg = Message.obtain();
- msg.what = what;
- msg.obj = obj;
- mPreConnectedQueue.add(msg);
- }
- }
- }
-
- /**
- * Called by the bearer code when it has new LinkProperties data.
- */
- public void sendLinkProperties(LinkProperties linkProperties) {
- queueOrSendMessage(EVENT_NETWORK_PROPERTIES_CHANGED, new LinkProperties(linkProperties));
- }
-
- /**
- * Called by the bearer code when it has new NetworkInfo data.
- */
- public void sendNetworkInfo(NetworkInfo networkInfo) {
- queueOrSendMessage(EVENT_NETWORK_INFO_CHANGED, new NetworkInfo(networkInfo));
- }
-
- /**
- * Called by the bearer code when it has new NetworkCapabilities data.
- */
- public void sendNetworkCapabilities(NetworkCapabilities networkCapabilities) {
- queueOrSendMessage(EVENT_NETWORK_CAPABILITIES_CHANGED,
- new NetworkCapabilities(networkCapabilities));
- }
-
- /**
- * Called by the bearer code when it has a new score for this network.
- */
- public void sendNetworkScore(int score) {
- queueOrSendMessage(EVENT_NETWORK_SCORE_CHANGED, new Integer(score));
- }
-
- /**
- * Called when ConnectivityService has indicated they no longer want this network.
- * The parent factory should (previously) have received indication of the change
- * as well, either canceling NetworkRequests or altering their score such that this
- * network won't be immediately requested again.
- */
- abstract protected void unwanted();
-
- protected void log(String s) {
- Log.d(LOG_TAG, "NetworkAgent: " + s);
- }
-}
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
deleted file mode 100644
index fe96287..0000000
--- a/core/java/android/net/NetworkCapabilities.java
+++ /dev/null
@@ -1,526 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Log;
-
-import java.lang.IllegalArgumentException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-/**
- * This class represents the capabilities of a network. This is used both to specify
- * needs to {@link ConnectivityManager} and when inspecting a network.
- *
- * Note that this replaces the old {@link ConnectivityManager#TYPE_MOBILE} method
- * of network selection. Rather than indicate a need for Wi-Fi because an application
- * needs high bandwidth and risk obselence when a new, fast network appears (like LTE),
- * the application should specify it needs high bandwidth. Similarly if an application
- * needs an unmetered network for a bulk transfer it can specify that rather than assuming
- * all cellular based connections are metered and all Wi-Fi based connections are not.
- */
-public final class NetworkCapabilities implements Parcelable {
- private static final String TAG = "NetworkCapabilities";
- private static final boolean DBG = false;
-
- /**
- * @hide
- */
- public NetworkCapabilities() {
- }
-
- public NetworkCapabilities(NetworkCapabilities nc) {
- if (nc != null) {
- mNetworkCapabilities = nc.mNetworkCapabilities;
- mTransportTypes = nc.mTransportTypes;
- mLinkUpBandwidthKbps = nc.mLinkUpBandwidthKbps;
- mLinkDownBandwidthKbps = nc.mLinkDownBandwidthKbps;
- }
- }
-
- /**
- * Represents the network's capabilities. If any are specified they will be satisfied
- * by any Network that matches all of them.
- */
- private long mNetworkCapabilities = (1 << NET_CAPABILITY_NOT_RESTRICTED);
-
- /**
- * Indicates this is a network that has the ability to reach the
- * carrier's MMSC for sending and receiving MMS messages.
- */
- public static final int NET_CAPABILITY_MMS = 0;
-
- /**
- * Indicates this is a network that has the ability to reach the carrier's
- * SUPL server, used to retrieve GPS information.
- */
- public static final int NET_CAPABILITY_SUPL = 1;
-
- /**
- * Indicates this is a network that has the ability to reach the carrier's
- * DUN or tethering gateway.
- */
- public static final int NET_CAPABILITY_DUN = 2;
-
- /**
- * Indicates this is a network that has the ability to reach the carrier's
- * FOTA portal, used for over the air updates.
- */
- public static final int NET_CAPABILITY_FOTA = 3;
-
- /**
- * Indicates this is a network that has the ability to reach the carrier's
- * IMS servers, used for network registration and signaling.
- */
- public static final int NET_CAPABILITY_IMS = 4;
-
- /**
- * Indicates this is a network that has the ability to reach the carrier's
- * CBS servers, used for carrier specific services.
- */
- public static final int NET_CAPABILITY_CBS = 5;
-
- /**
- * Indicates this is a network that has the ability to reach a Wi-Fi direct
- * peer.
- */
- public static final int NET_CAPABILITY_WIFI_P2P = 6;
-
- /**
- * Indicates this is a network that has the ability to reach a carrier's
- * Initial Attach servers.
- */
- public static final int NET_CAPABILITY_IA = 7;
-
- /**
- * Indicates this is a network that has the ability to reach a carrier's
- * RCS servers, used for Rich Communication Services.
- */
- public static final int NET_CAPABILITY_RCS = 8;
-
- /**
- * Indicates this is a network that has the ability to reach a carrier's
- * XCAP servers, used for configuration and control.
- */
- public static final int NET_CAPABILITY_XCAP = 9;
-
- /**
- * Indicates this is a network that has the ability to reach a carrier's
- * Emergency IMS servers, used for network signaling during emergency calls.
- */
- public static final int NET_CAPABILITY_EIMS = 10;
-
- /**
- * Indicates that this network is unmetered.
- */
- public static final int NET_CAPABILITY_NOT_METERED = 11;
-
- /**
- * Indicates that this network should be able to reach the internet.
- */
- public static final int NET_CAPABILITY_INTERNET = 12;
-
- /**
- * Indicates that this network is available for general use. If this is not set
- * applications should not attempt to communicate on this network. Note that this
- * is simply informative and not enforcement - enforcement is handled via other means.
- * Set by default.
- */
- public static final int NET_CAPABILITY_NOT_RESTRICTED = 13;
-
- private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS;
- private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_NOT_RESTRICTED;
-
- /**
- * Adds the given capability to this {@code NetworkCapability} instance.
- * Multiple capabilities may be applied sequentially. Note that when searching
- * for a network to satisfy a request, all capabilities requested must be satisfied.
- *
- * @param capability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be added.
- * @return This NetworkCapability to facilitate chaining.
- * @hide
- */
- public NetworkCapabilities addCapability(int capability) {
- if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) {
- throw new IllegalArgumentException("NetworkCapability out of range");
- }
- mNetworkCapabilities |= 1 << capability;
- return this;
- }
-
- /**
- * Removes (if found) the given capability from this {@code NetworkCapability} instance.
- *
- * @param capability the {@code NetworkCapabilities.NET_CAPABILTIY_*} to be removed.
- * @return This NetworkCapability to facilitate chaining.
- * @hide
- */
- public NetworkCapabilities removeCapability(int capability) {
- if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) {
- throw new IllegalArgumentException("NetworkCapability out of range");
- }
- mNetworkCapabilities &= ~(1 << capability);
- return this;
- }
-
- /**
- * Gets all the capabilities set on this {@code NetworkCapability} instance.
- *
- * @return an array of {@code NetworkCapabilities.NET_CAPABILITY_*} values
- * for this instance.
- * @hide
- */
- public int[] getCapabilities() {
- return enumerateBits(mNetworkCapabilities);
- }
-
- /**
- * Tests for the presence of a capabilitity on this instance.
- *
- * @param capability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be tested for.
- * @return {@code true} if set on this instance.
- */
- public boolean hasCapability(int capability) {
- if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) {
- return false;
- }
- return ((mNetworkCapabilities & (1 << capability)) != 0);
- }
-
- private int[] enumerateBits(long val) {
- int size = Long.bitCount(val);
- int[] result = new int[size];
- int index = 0;
- int resource = 0;
- while (val > 0) {
- if ((val & 1) == 1) result[index++] = resource;
- val = val >> 1;
- resource++;
- }
- return result;
- }
-
- private void combineNetCapabilities(NetworkCapabilities nc) {
- this.mNetworkCapabilities |= nc.mNetworkCapabilities;
- }
-
- private boolean satisfiedByNetCapabilities(NetworkCapabilities nc) {
- return ((nc.mNetworkCapabilities & this.mNetworkCapabilities) == this.mNetworkCapabilities);
- }
-
- private boolean equalsNetCapabilities(NetworkCapabilities nc) {
- return (nc.mNetworkCapabilities == this.mNetworkCapabilities);
- }
-
- /**
- * Representing the transport type. Apps should generally not care about transport. A
- * request for a fast internet connection could be satisfied by a number of different
- * transports. If any are specified here it will be satisfied a Network that matches
- * any of them. If a caller doesn't care about the transport it should not specify any.
- */
- private long mTransportTypes;
-
- /**
- * Indicates this network uses a Cellular transport.
- */
- public static final int TRANSPORT_CELLULAR = 0;
-
- /**
- * Indicates this network uses a Wi-Fi transport.
- */
- public static final int TRANSPORT_WIFI = 1;
-
- /**
- * Indicates this network uses a Bluetooth transport.
- */
- public static final int TRANSPORT_BLUETOOTH = 2;
-
- /**
- * Indicates this network uses an Ethernet transport.
- */
- public static final int TRANSPORT_ETHERNET = 3;
-
- private static final int MIN_TRANSPORT = TRANSPORT_CELLULAR;
- private static final int MAX_TRANSPORT = TRANSPORT_ETHERNET;
-
- /**
- * Adds the given transport type to this {@code NetworkCapability} instance.
- * Multiple transports may be applied sequentially. Note that when searching
- * for a network to satisfy a request, any listed in the request will satisfy the request.
- * For example {@code TRANSPORT_WIFI} and {@code TRANSPORT_ETHERNET} added to a
- * {@code NetworkCapabilities} would cause either a Wi-Fi network or an Ethernet network
- * to be selected. This is logically different than
- * {@code NetworkCapabilities.NET_CAPABILITY_*} listed above.
- *
- * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be added.
- * @return This NetworkCapability to facilitate chaining.
- * @hide
- */
- public NetworkCapabilities addTransportType(int transportType) {
- if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) {
- throw new IllegalArgumentException("TransportType out of range");
- }
- mTransportTypes |= 1 << transportType;
- return this;
- }
-
- /**
- * Removes (if found) the given transport from this {@code NetworkCapability} instance.
- *
- * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be removed.
- * @return This NetworkCapability to facilitate chaining.
- * @hide
- */
- public NetworkCapabilities removeTransportType(int transportType) {
- if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) {
- throw new IllegalArgumentException("TransportType out of range");
- }
- mTransportTypes &= ~(1 << transportType);
- return this;
- }
-
- /**
- * Gets all the transports set on this {@code NetworkCapability} instance.
- *
- * @return an array of {@code NetworkCapabilities.TRANSPORT_*} values
- * for this instance.
- * @hide
- */
- public int[] getTransportTypes() {
- return enumerateBits(mTransportTypes);
- }
-
- /**
- * Tests for the presence of a transport on this instance.
- *
- * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be tested for.
- * @return {@code true} if set on this instance.
- */
- public boolean hasTransport(int transportType) {
- if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) {
- return false;
- }
- return ((mTransportTypes & (1 << transportType)) != 0);
- }
-
- private void combineTransportTypes(NetworkCapabilities nc) {
- this.mTransportTypes |= nc.mTransportTypes;
- }
- private boolean satisfiedByTransportTypes(NetworkCapabilities nc) {
- return ((this.mTransportTypes == 0) ||
- ((this.mTransportTypes & nc.mTransportTypes) != 0));
- }
- private boolean equalsTransportTypes(NetworkCapabilities nc) {
- return (nc.mTransportTypes == this.mTransportTypes);
- }
-
- /**
- * Passive link bandwidth. This is a rough guide of the expected peak bandwidth
- * for the first hop on the given transport. It is not measured, but may take into account
- * link parameters (Radio technology, allocated channels, etc).
- */
- private int mLinkUpBandwidthKbps;
- private int mLinkDownBandwidthKbps;
-
- /**
- * Sets the upstream bandwidth for this network in Kbps. This always only refers to
- * the estimated first hop transport bandwidth.
- * <p>
- * Note that when used to request a network, this specifies the minimum acceptable.
- * When received as the state of an existing network this specifies the typical
- * first hop bandwidth expected. This is never measured, but rather is inferred
- * from technology type and other link parameters. It could be used to differentiate
- * between very slow 1xRTT cellular links and other faster networks or even between
- * 802.11b vs 802.11AC wifi technologies. It should not be used to differentiate between
- * fast backhauls and slow backhauls.
- *
- * @param upKbps the estimated first hop upstream (device to network) bandwidth.
- * @hide
- */
- public void setLinkUpstreamBandwidthKbps(int upKbps) {
- mLinkUpBandwidthKbps = upKbps;
- }
-
- /**
- * Retrieves the upstream bandwidth for this network in Kbps. This always only refers to
- * the estimated first hop transport bandwidth.
- *
- * @return The estimated first hop upstream (device to network) bandwidth.
- */
- public int getLinkUpstreamBandwidthKbps() {
- return mLinkUpBandwidthKbps;
- }
-
- /**
- * Sets the downstream bandwidth for this network in Kbps. This always only refers to
- * the estimated first hop transport bandwidth.
- * <p>
- * Note that when used to request a network, this specifies the minimum acceptable.
- * When received as the state of an existing network this specifies the typical
- * first hop bandwidth expected. This is never measured, but rather is inferred
- * from technology type and other link parameters. It could be used to differentiate
- * between very slow 1xRTT cellular links and other faster networks or even between
- * 802.11b vs 802.11AC wifi technologies. It should not be used to differentiate between
- * fast backhauls and slow backhauls.
- *
- * @param downKbps the estimated first hop downstream (network to device) bandwidth.
- * @hide
- */
- public void setLinkDownstreamBandwidthKbps(int downKbps) {
- mLinkDownBandwidthKbps = downKbps;
- }
-
- /**
- * Retrieves the downstream bandwidth for this network in Kbps. This always only refers to
- * the estimated first hop transport bandwidth.
- *
- * @return The estimated first hop downstream (network to device) bandwidth.
- */
- public int getLinkDownstreamBandwidthKbps() {
- return mLinkDownBandwidthKbps;
- }
-
- private void combineLinkBandwidths(NetworkCapabilities nc) {
- this.mLinkUpBandwidthKbps =
- Math.max(this.mLinkUpBandwidthKbps, nc.mLinkUpBandwidthKbps);
- this.mLinkDownBandwidthKbps =
- Math.max(this.mLinkDownBandwidthKbps, nc.mLinkDownBandwidthKbps);
- }
- private boolean satisfiedByLinkBandwidths(NetworkCapabilities nc) {
- return !(this.mLinkUpBandwidthKbps > nc.mLinkUpBandwidthKbps ||
- this.mLinkDownBandwidthKbps > nc.mLinkDownBandwidthKbps);
- }
- private boolean equalsLinkBandwidths(NetworkCapabilities nc) {
- return (this.mLinkUpBandwidthKbps == nc.mLinkUpBandwidthKbps &&
- this.mLinkDownBandwidthKbps == nc.mLinkDownBandwidthKbps);
- }
-
- /**
- * Combine a set of Capabilities to this one. Useful for coming up with the complete set
- * {@hide}
- */
- public void combineCapabilities(NetworkCapabilities nc) {
- combineNetCapabilities(nc);
- combineTransportTypes(nc);
- combineLinkBandwidths(nc);
- }
-
- /**
- * Check if our requirements are satisfied by the given Capabilities.
- * {@hide}
- */
- public boolean satisfiedByNetworkCapabilities(NetworkCapabilities nc) {
- return (nc != null &&
- satisfiedByNetCapabilities(nc) &&
- satisfiedByTransportTypes(nc) &&
- satisfiedByLinkBandwidths(nc));
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || (obj instanceof NetworkCapabilities == false)) return false;
- NetworkCapabilities that = (NetworkCapabilities)obj;
- return (equalsNetCapabilities(that) &&
- equalsTransportTypes(that) &&
- equalsLinkBandwidths(that));
- }
-
- @Override
- public int hashCode() {
- return ((int)(mNetworkCapabilities & 0xFFFFFFFF) +
- ((int)(mNetworkCapabilities >> 32) * 3) +
- ((int)(mTransportTypes & 0xFFFFFFFF) * 5) +
- ((int)(mTransportTypes >> 32) * 7) +
- (mLinkUpBandwidthKbps * 11) +
- (mLinkDownBandwidthKbps * 13));
- }
-
- public int describeContents() {
- return 0;
- }
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeLong(mNetworkCapabilities);
- dest.writeLong(mTransportTypes);
- dest.writeInt(mLinkUpBandwidthKbps);
- dest.writeInt(mLinkDownBandwidthKbps);
- }
- public static final Creator<NetworkCapabilities> CREATOR =
- new Creator<NetworkCapabilities>() {
- public NetworkCapabilities createFromParcel(Parcel in) {
- NetworkCapabilities netCap = new NetworkCapabilities();
-
- netCap.mNetworkCapabilities = in.readLong();
- netCap.mTransportTypes = in.readLong();
- netCap.mLinkUpBandwidthKbps = in.readInt();
- netCap.mLinkDownBandwidthKbps = in.readInt();
- return netCap;
- }
- public NetworkCapabilities[] newArray(int size) {
- return new NetworkCapabilities[size];
- }
- };
-
- public String toString() {
- int[] types = getTransportTypes();
- String transports = (types.length > 0 ? " Transports: " : "");
- for (int i = 0; i < types.length;) {
- switch (types[i]) {
- case TRANSPORT_CELLULAR: transports += "CELLULAR"; break;
- case TRANSPORT_WIFI: transports += "WIFI"; break;
- case TRANSPORT_BLUETOOTH: transports += "BLUETOOTH"; break;
- case TRANSPORT_ETHERNET: transports += "ETHERNET"; break;
- }
- if (++i < types.length) transports += "|";
- }
-
- types = getCapabilities();
- String capabilities = (types.length > 0 ? " Capabilities: " : "");
- for (int i = 0; i < types.length; ) {
- switch (types[i]) {
- case NET_CAPABILITY_MMS: capabilities += "MMS"; break;
- case NET_CAPABILITY_SUPL: capabilities += "SUPL"; break;
- case NET_CAPABILITY_DUN: capabilities += "DUN"; break;
- case NET_CAPABILITY_FOTA: capabilities += "FOTA"; break;
- case NET_CAPABILITY_IMS: capabilities += "IMS"; break;
- case NET_CAPABILITY_CBS: capabilities += "CBS"; break;
- case NET_CAPABILITY_WIFI_P2P: capabilities += "WIFI_P2P"; break;
- case NET_CAPABILITY_IA: capabilities += "IA"; break;
- case NET_CAPABILITY_RCS: capabilities += "RCS"; break;
- case NET_CAPABILITY_XCAP: capabilities += "XCAP"; break;
- case NET_CAPABILITY_EIMS: capabilities += "EIMS"; break;
- case NET_CAPABILITY_NOT_METERED: capabilities += "NOT_METERED"; break;
- case NET_CAPABILITY_INTERNET: capabilities += "INTERNET"; break;
- case NET_CAPABILITY_NOT_RESTRICTED: capabilities += "NOT_RESTRICTED"; break;
- }
- if (++i < types.length) capabilities += "&";
- }
-
- String upBand = ((mLinkUpBandwidthKbps > 0) ? " LinkUpBandwidth>=" +
- mLinkUpBandwidthKbps + "Kbps" : "");
- String dnBand = ((mLinkDownBandwidthKbps > 0) ? " LinkDnBandwidth>=" +
- mLinkDownBandwidthKbps + "Kbps" : "");
-
- return "[" + transports + capabilities + upBand + dnBand + "]";
- }
-}
diff --git a/core/java/android/net/NetworkConfig.java b/core/java/android/net/NetworkConfig.java
deleted file mode 100644
index 32a2cda..0000000
--- a/core/java/android/net/NetworkConfig.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import java.util.Locale;
-
-/**
- * Describes the buildtime configuration of a network.
- * Holds settings read from resources.
- * @hide
- */
-public class NetworkConfig {
- /**
- * Human readable string
- */
- public String name;
-
- /**
- * Type from ConnectivityManager
- */
- public int type;
-
- /**
- * the radio number from radio attributes config
- */
- public int radio;
-
- /**
- * higher number == higher priority when turning off connections
- */
- public int priority;
-
- /**
- * indicates the boot time dependencyMet setting
- */
- public boolean dependencyMet;
-
- /**
- * indicates the default restoral timer in seconds
- * if the network is used as a special network feature
- * -1 indicates no restoration of default
- */
- public int restoreTime;
-
- /**
- * input string from config.xml resource. Uses the form:
- * [Connection name],[ConnectivityManager connection type],
- * [associated radio-type],[priority],[dependencyMet]
- */
- public NetworkConfig(String init) {
- String fragments[] = init.split(",");
- name = fragments[0].trim().toLowerCase(Locale.ROOT);
- type = Integer.parseInt(fragments[1]);
- radio = Integer.parseInt(fragments[2]);
- priority = Integer.parseInt(fragments[3]);
- restoreTime = Integer.parseInt(fragments[4]);
- dependencyMet = Boolean.parseBoolean(fragments[5]);
- }
-
- /**
- * Indicates if this network is supposed to be default-routable
- */
- public boolean isDefault() {
- return (type == radio);
- }
-}
diff --git a/core/java/android/net/NetworkInfo.java b/core/java/android/net/NetworkInfo.java
deleted file mode 100644
index d279412..0000000
--- a/core/java/android/net/NetworkInfo.java
+++ /dev/null
@@ -1,506 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.os.Parcelable;
-import android.os.Parcel;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.EnumMap;
-
-/**
- * Describes the status of a network interface.
- * <p>Use {@link ConnectivityManager#getActiveNetworkInfo()} to get an instance that represents
- * the current network connection.
- */
-public class NetworkInfo implements Parcelable {
-
- /**
- * Coarse-grained network state. This is probably what most applications should
- * use, rather than {@link android.net.NetworkInfo.DetailedState DetailedState}.
- * The mapping between the two is as follows:
- * <br/><br/>
- * <table>
- * <tr><td><b>Detailed state</b></td><td><b>Coarse-grained state</b></td></tr>
- * <tr><td><code>IDLE</code></td><td><code>DISCONNECTED</code></td></tr>
- * <tr><td><code>SCANNING</code></td><td><code>CONNECTING</code></td></tr>
- * <tr><td><code>CONNECTING</code></td><td><code>CONNECTING</code></td></tr>
- * <tr><td><code>AUTHENTICATING</code></td><td><code>CONNECTING</code></td></tr>
- * <tr><td><code>CONNECTED</code></td><td><code>CONNECTED</code></td></tr>
- * <tr><td><code>DISCONNECTING</code></td><td><code>DISCONNECTING</code></td></tr>
- * <tr><td><code>DISCONNECTED</code></td><td><code>DISCONNECTED</code></td></tr>
- * <tr><td><code>UNAVAILABLE</code></td><td><code>DISCONNECTED</code></td></tr>
- * <tr><td><code>FAILED</code></td><td><code>DISCONNECTED</code></td></tr>
- * </table>
- */
- public enum State {
- CONNECTING, CONNECTED, SUSPENDED, DISCONNECTING, DISCONNECTED, UNKNOWN
- }
-
- /**
- * The fine-grained state of a network connection. This level of detail
- * is probably of interest to few applications. Most should use
- * {@link android.net.NetworkInfo.State State} instead.
- */
- public enum DetailedState {
- /** Ready to start data connection setup. */
- IDLE,
- /** Searching for an available access point. */
- SCANNING,
- /** Currently setting up data connection. */
- CONNECTING,
- /** Network link established, performing authentication. */
- AUTHENTICATING,
- /** Awaiting response from DHCP server in order to assign IP address information. */
- OBTAINING_IPADDR,
- /** IP traffic should be available. */
- CONNECTED,
- /** IP traffic is suspended */
- SUSPENDED,
- /** Currently tearing down data connection. */
- DISCONNECTING,
- /** IP traffic not available. */
- DISCONNECTED,
- /** Attempt to connect failed. */
- FAILED,
- /** Access to this network is blocked. */
- BLOCKED,
- /** Link has poor connectivity. */
- VERIFYING_POOR_LINK,
- /** Checking if network is a captive portal */
- CAPTIVE_PORTAL_CHECK
- }
-
- /**
- * This is the map described in the Javadoc comment above. The positions
- * of the elements of the array must correspond to the ordinal values
- * of <code>DetailedState</code>.
- */
- private static final EnumMap<DetailedState, State> stateMap =
- new EnumMap<DetailedState, State>(DetailedState.class);
-
- static {
- stateMap.put(DetailedState.IDLE, State.DISCONNECTED);
- stateMap.put(DetailedState.SCANNING, State.DISCONNECTED);
- stateMap.put(DetailedState.CONNECTING, State.CONNECTING);
- stateMap.put(DetailedState.AUTHENTICATING, State.CONNECTING);
- stateMap.put(DetailedState.OBTAINING_IPADDR, State.CONNECTING);
- stateMap.put(DetailedState.VERIFYING_POOR_LINK, State.CONNECTING);
- stateMap.put(DetailedState.CAPTIVE_PORTAL_CHECK, State.CONNECTING);
- stateMap.put(DetailedState.CONNECTED, State.CONNECTED);
- stateMap.put(DetailedState.SUSPENDED, State.SUSPENDED);
- stateMap.put(DetailedState.DISCONNECTING, State.DISCONNECTING);
- stateMap.put(DetailedState.DISCONNECTED, State.DISCONNECTED);
- stateMap.put(DetailedState.FAILED, State.DISCONNECTED);
- stateMap.put(DetailedState.BLOCKED, State.DISCONNECTED);
- }
-
- private int mNetworkType;
- private int mSubtype;
- private String mTypeName;
- private String mSubtypeName;
- private State mState;
- private DetailedState mDetailedState;
- private String mReason;
- private String mExtraInfo;
- private boolean mIsFailover;
- private boolean mIsRoaming;
- private boolean mIsConnectedToProvisioningNetwork;
-
- /**
- * Indicates whether network connectivity is possible:
- */
- private boolean mIsAvailable;
-
- /**
- * @param type network type
- * @deprecated
- * @hide because this constructor was only meant for internal use (and
- * has now been superseded by the package-private constructor below).
- */
- public NetworkInfo(int type) {}
-
- /**
- * @hide
- */
- public NetworkInfo(int type, int subtype, String typeName, String subtypeName) {
- if (!ConnectivityManager.isNetworkTypeValid(type)) {
- throw new IllegalArgumentException("Invalid network type: " + type);
- }
- mNetworkType = type;
- mSubtype = subtype;
- mTypeName = typeName;
- mSubtypeName = subtypeName;
- setDetailedState(DetailedState.IDLE, null, null);
- mState = State.UNKNOWN;
- mIsAvailable = false; // until we're told otherwise, assume unavailable
- mIsRoaming = false;
- mIsConnectedToProvisioningNetwork = false;
- }
-
- /** {@hide} */
- public NetworkInfo(NetworkInfo source) {
- if (source != null) {
- synchronized (source) {
- mNetworkType = source.mNetworkType;
- mSubtype = source.mSubtype;
- mTypeName = source.mTypeName;
- mSubtypeName = source.mSubtypeName;
- mState = source.mState;
- mDetailedState = source.mDetailedState;
- mReason = source.mReason;
- mExtraInfo = source.mExtraInfo;
- mIsFailover = source.mIsFailover;
- mIsRoaming = source.mIsRoaming;
- mIsAvailable = source.mIsAvailable;
- mIsConnectedToProvisioningNetwork = source.mIsConnectedToProvisioningNetwork;
- }
- }
- }
-
- /**
- * Reports the type of network to which the
- * info in this {@code NetworkInfo} pertains.
- * @return one of {@link ConnectivityManager#TYPE_MOBILE}, {@link
- * ConnectivityManager#TYPE_WIFI}, {@link ConnectivityManager#TYPE_WIMAX}, {@link
- * ConnectivityManager#TYPE_ETHERNET}, {@link ConnectivityManager#TYPE_BLUETOOTH}, or other
- * types defined by {@link ConnectivityManager}
- */
- public int getType() {
- synchronized (this) {
- return mNetworkType;
- }
- }
-
- /**
- * @hide
- */
- public void setType(int type) {
- synchronized (this) {
- mNetworkType = type;
- }
- }
-
- /**
- * Return a network-type-specific integer describing the subtype
- * of the network.
- * @return the network subtype
- */
- public int getSubtype() {
- synchronized (this) {
- return mSubtype;
- }
- }
-
- /**
- * @hide
- */
- public void setSubtype(int subtype, String subtypeName) {
- synchronized (this) {
- mSubtype = subtype;
- mSubtypeName = subtypeName;
- }
- }
-
- /**
- * Return a human-readable name describe the type of the network,
- * for example "WIFI" or "MOBILE".
- * @return the name of the network type
- */
- public String getTypeName() {
- synchronized (this) {
- return mTypeName;
- }
- }
-
- /**
- * Return a human-readable name describing the subtype of the network.
- * @return the name of the network subtype
- */
- public String getSubtypeName() {
- synchronized (this) {
- return mSubtypeName;
- }
- }
-
- /**
- * Indicates whether network connectivity exists or is in the process
- * of being established. This is good for applications that need to
- * do anything related to the network other than read or write data.
- * For the latter, call {@link #isConnected()} instead, which guarantees
- * that the network is fully usable.
- * @return {@code true} if network connectivity exists or is in the process
- * of being established, {@code false} otherwise.
- */
- public boolean isConnectedOrConnecting() {
- synchronized (this) {
- return mState == State.CONNECTED || mState == State.CONNECTING;
- }
- }
-
- /**
- * Indicates whether network connectivity exists and it is possible to establish
- * connections and pass data.
- * <p>Always call this before attempting to perform data transactions.
- * @return {@code true} if network connectivity exists, {@code false} otherwise.
- */
- public boolean isConnected() {
- synchronized (this) {
- return mState == State.CONNECTED;
- }
- }
-
- /**
- * Indicates whether network connectivity is possible. A network is unavailable
- * when a persistent or semi-persistent condition prevents the possibility
- * of connecting to that network. Examples include
- * <ul>
- * <li>The device is out of the coverage area for any network of this type.</li>
- * <li>The device is on a network other than the home network (i.e., roaming), and
- * data roaming has been disabled.</li>
- * <li>The device's radio is turned off, e.g., because airplane mode is enabled.</li>
- * </ul>
- * @return {@code true} if the network is available, {@code false} otherwise
- */
- public boolean isAvailable() {
- synchronized (this) {
- return mIsAvailable;
- }
- }
-
- /**
- * Sets if the network is available, ie, if the connectivity is possible.
- * @param isAvailable the new availability value.
- *
- * @hide
- */
- public void setIsAvailable(boolean isAvailable) {
- synchronized (this) {
- mIsAvailable = isAvailable;
- }
- }
-
- /**
- * Indicates whether the current attempt to connect to the network
- * resulted from the ConnectivityManager trying to fail over to this
- * network following a disconnect from another network.
- * @return {@code true} if this is a failover attempt, {@code false}
- * otherwise.
- */
- public boolean isFailover() {
- synchronized (this) {
- return mIsFailover;
- }
- }
-
- /**
- * Set the failover boolean.
- * @param isFailover {@code true} to mark the current connection attempt
- * as a failover.
- * @hide
- */
- public void setFailover(boolean isFailover) {
- synchronized (this) {
- mIsFailover = isFailover;
- }
- }
-
- /**
- * Indicates whether the device is currently roaming on this network.
- * When {@code true}, it suggests that use of data on this network
- * may incur extra costs.
- * @return {@code true} if roaming is in effect, {@code false} otherwise.
- */
- public boolean isRoaming() {
- synchronized (this) {
- return mIsRoaming;
- }
- }
-
- /** {@hide} */
- @VisibleForTesting
- public void setRoaming(boolean isRoaming) {
- synchronized (this) {
- mIsRoaming = isRoaming;
- }
- }
-
- /** {@hide} */
- @VisibleForTesting
- public boolean isConnectedToProvisioningNetwork() {
- synchronized (this) {
- return mIsConnectedToProvisioningNetwork;
- }
- }
-
- /** {@hide} */
- @VisibleForTesting
- public void setIsConnectedToProvisioningNetwork(boolean val) {
- synchronized (this) {
- mIsConnectedToProvisioningNetwork = val;
- }
- }
-
- /**
- * Reports the current coarse-grained state of the network.
- * @return the coarse-grained state
- */
- public State getState() {
- synchronized (this) {
- return mState;
- }
- }
-
- /**
- * Reports the current fine-grained state of the network.
- * @return the fine-grained state
- */
- public DetailedState getDetailedState() {
- synchronized (this) {
- return mDetailedState;
- }
- }
-
- /**
- * Sets the fine-grained state of the network.
- * @param detailedState the {@link DetailedState}.
- * @param reason a {@code String} indicating the reason for the state change,
- * if one was supplied. May be {@code null}.
- * @param extraInfo an optional {@code String} providing addditional network state
- * information passed up from the lower networking layers.
- * @hide
- */
- public void setDetailedState(DetailedState detailedState, String reason, String extraInfo) {
- synchronized (this) {
- this.mDetailedState = detailedState;
- this.mState = stateMap.get(detailedState);
- this.mReason = reason;
- this.mExtraInfo = extraInfo;
- }
- }
-
- /**
- * Set the extraInfo field.
- * @param extraInfo an optional {@code String} providing addditional network state
- * information passed up from the lower networking layers.
- * @hide
- */
- public void setExtraInfo(String extraInfo) {
- synchronized (this) {
- this.mExtraInfo = extraInfo;
- }
- }
-
- /**
- * Report the reason an attempt to establish connectivity failed,
- * if one is available.
- * @return the reason for failure, or null if not available
- */
- public String getReason() {
- synchronized (this) {
- return mReason;
- }
- }
-
- /**
- * Report the extra information about the network state, if any was
- * provided by the lower networking layers.,
- * if one is available.
- * @return the extra information, or null if not available
- */
- public String getExtraInfo() {
- synchronized (this) {
- return mExtraInfo;
- }
- }
-
- @Override
- public String toString() {
- synchronized (this) {
- StringBuilder builder = new StringBuilder("[");
- builder.append("type: ").append(getTypeName()).append("[").append(getSubtypeName()).
- append("], state: ").append(mState).append("/").append(mDetailedState).
- append(", reason: ").append(mReason == null ? "(unspecified)" : mReason).
- append(", extra: ").append(mExtraInfo == null ? "(none)" : mExtraInfo).
- append(", roaming: ").append(mIsRoaming).
- append(", failover: ").append(mIsFailover).
- append(", isAvailable: ").append(mIsAvailable).
- append(", isConnectedToProvisioningNetwork: ").
- append(mIsConnectedToProvisioningNetwork).
- append("]");
- return builder.toString();
- }
- }
-
- /**
- * Implement the Parcelable interface
- * @hide
- */
- public int describeContents() {
- return 0;
- }
-
- /**
- * Implement the Parcelable interface.
- * @hide
- */
- public void writeToParcel(Parcel dest, int flags) {
- synchronized (this) {
- dest.writeInt(mNetworkType);
- dest.writeInt(mSubtype);
- dest.writeString(mTypeName);
- dest.writeString(mSubtypeName);
- dest.writeString(mState.name());
- dest.writeString(mDetailedState.name());
- dest.writeInt(mIsFailover ? 1 : 0);
- dest.writeInt(mIsAvailable ? 1 : 0);
- dest.writeInt(mIsRoaming ? 1 : 0);
- dest.writeInt(mIsConnectedToProvisioningNetwork ? 1 : 0);
- dest.writeString(mReason);
- dest.writeString(mExtraInfo);
- }
- }
-
- /**
- * Implement the Parcelable interface.
- * @hide
- */
- public static final Creator<NetworkInfo> CREATOR =
- new Creator<NetworkInfo>() {
- public NetworkInfo createFromParcel(Parcel in) {
- int netType = in.readInt();
- int subtype = in.readInt();
- String typeName = in.readString();
- String subtypeName = in.readString();
- NetworkInfo netInfo = new NetworkInfo(netType, subtype, typeName, subtypeName);
- netInfo.mState = State.valueOf(in.readString());
- netInfo.mDetailedState = DetailedState.valueOf(in.readString());
- netInfo.mIsFailover = in.readInt() != 0;
- netInfo.mIsAvailable = in.readInt() != 0;
- netInfo.mIsRoaming = in.readInt() != 0;
- netInfo.mIsConnectedToProvisioningNetwork = in.readInt() != 0;
- netInfo.mReason = in.readString();
- netInfo.mExtraInfo = in.readString();
- return netInfo;
- }
-
- public NetworkInfo[] newArray(int size) {
- return new NetworkInfo[size];
- }
- };
-}
diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java
deleted file mode 100644
index 7911c72..0000000
--- a/core/java/android/net/NetworkRequest.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * Defines a request for a network, made through {@link NetworkRequest.Builder} and used
- * to request a network via {@link ConnectivityManager#requestNetwork} or listen for changes
- * via {@link ConnectivityManager#listenForNetwork}.
- */
-public class NetworkRequest implements Parcelable {
- /**
- * The {@link NetworkCapabilities} that define this request.
- * @hide
- */
- public final NetworkCapabilities networkCapabilities;
-
- /**
- * Identifies the request. NetworkRequests should only be constructed by
- * the Framework and given out to applications as tokens to be used to identify
- * the request.
- * @hide
- */
- public final int requestId;
-
- /**
- * Set for legacy requests and the default. Set to TYPE_NONE for none.
- * Causes CONNECTIVITY_ACTION broadcasts to be sent.
- * @hide
- */
- public final int legacyType;
-
- /**
- * @hide
- */
- public NetworkRequest(NetworkCapabilities nc, int legacyType, int rId) {
- requestId = rId;
- networkCapabilities = nc;
- this.legacyType = legacyType;
- }
-
- /**
- * @hide
- */
- public NetworkRequest(NetworkRequest that) {
- networkCapabilities = new NetworkCapabilities(that.networkCapabilities);
- requestId = that.requestId;
- this.legacyType = that.legacyType;
- }
-
- /**
- * Builder used to create {@link NetworkRequest} objects. Specify the Network features
- * needed in terms of {@link NetworkCapabilities} features
- */
- public static class Builder {
- private final NetworkCapabilities mNetworkCapabilities = new NetworkCapabilities();
-
- /**
- * Default constructor for Builder.
- */
- public Builder() {}
-
- /**
- * Build {@link NetworkRequest} give the current set of capabilities.
- */
- public NetworkRequest build() {
- return new NetworkRequest(mNetworkCapabilities, ConnectivityManager.TYPE_NONE,
- ConnectivityManager.REQUEST_ID_UNSET);
- }
-
- /**
- * Add the given capability requirement to this builder. These represent
- * the requested network's required capabilities. Note that when searching
- * for a network to satisfy a request, all capabilities requested must be
- * satisfied. See {@link NetworkCapabilities} for {@code NET_CAPABILITIY_*}
- * definitions.
- *
- * @param capability The {@code NetworkCapabilities.NET_CAPABILITY_*} to add.
- * @return The builder to facilitate chaining
- * {@code builder.addCapability(...).addCapability();}.
- */
- public Builder addCapability(int capability) {
- mNetworkCapabilities.addCapability(capability);
- return this;
- }
-
- /**
- * Removes (if found) the given capability from this builder instance.
- *
- * @param capability The {@code NetworkCapabilities.NET_CAPABILITY_*} to remove.
- * @return The builder to facilitate chaining.
- */
- public Builder removeCapability(int capability) {
- mNetworkCapabilities.removeCapability(capability);
- return this;
- }
-
- /**
- * Adds the given transport requirement to this builder. These represent
- * the set of allowed transports for the request. Only networks using one
- * of these transports will satisfy the request. If no particular transports
- * are required, none should be specified here. See {@link NetworkCapabilities}
- * for {@code TRANSPORT_*} definitions.
- *
- * @param transportType The {@code NetworkCapabilities.TRANSPORT_*} to add.
- * @return The builder to facilitate chaining.
- */
- public Builder addTransportType(int transportType) {
- mNetworkCapabilities.addTransportType(transportType);
- return this;
- }
-
- /**
- * Removes (if found) the given transport from this builder instance.
- *
- * @param transportType The {@code NetworkCapabilities.TRANSPORT_*} to remove.
- * @return The builder to facilitate chaining.
- */
- public Builder removeTransportType(int transportType) {
- mNetworkCapabilities.removeTransportType(transportType);
- return this;
- }
-
- /**
- * @hide
- */
- public Builder setLinkUpstreamBandwidthKbps(int upKbps) {
- mNetworkCapabilities.setLinkUpstreamBandwidthKbps(upKbps);
- return this;
- }
- /**
- * @hide
- */
- public Builder setLinkDownstreamBandwidthKbps(int downKbps) {
- mNetworkCapabilities.setLinkDownstreamBandwidthKbps(downKbps);
- return this;
- }
- }
-
- // implement the Parcelable interface
- public int describeContents() {
- return 0;
- }
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeParcelable(networkCapabilities, flags);
- dest.writeInt(legacyType);
- dest.writeInt(requestId);
- }
- public static final Creator<NetworkRequest> CREATOR =
- new Creator<NetworkRequest>() {
- public NetworkRequest createFromParcel(Parcel in) {
- NetworkCapabilities nc = (NetworkCapabilities)in.readParcelable(null);
- int legacyType = in.readInt();
- int requestId = in.readInt();
- NetworkRequest result = new NetworkRequest(nc, legacyType, requestId);
- return result;
- }
- public NetworkRequest[] newArray(int size) {
- return new NetworkRequest[size];
- }
- };
-
- public String toString() {
- return "NetworkRequest [ id=" + requestId + ", legacyType=" + legacyType +
- ", " + networkCapabilities.toString() + " ]";
- }
-
- public boolean equals(Object obj) {
- if (obj instanceof NetworkRequest == false) return false;
- NetworkRequest that = (NetworkRequest)obj;
- return (that.legacyType == this.legacyType &&
- that.requestId == this.requestId &&
- ((that.networkCapabilities == null && this.networkCapabilities == null) ||
- (that.networkCapabilities != null &&
- that.networkCapabilities.equals(this.networkCapabilities))));
- }
-
- public int hashCode() {
- return requestId + (legacyType * 1013) +
- (networkCapabilities.hashCode() * 1051);
- }
-}
diff --git a/core/java/android/net/NetworkState.java b/core/java/android/net/NetworkState.java
deleted file mode 100644
index 2e0e9e4..0000000
--- a/core/java/android/net/NetworkState.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Snapshot of network state.
- *
- * @hide
- */
-public class NetworkState implements Parcelable {
-
- public final NetworkInfo networkInfo;
- public final LinkProperties linkProperties;
- public final NetworkCapabilities networkCapabilities;
- /** Currently only used by testing. */
- public final String subscriberId;
- public final String networkId;
-
- public NetworkState(NetworkInfo networkInfo, LinkProperties linkProperties,
- NetworkCapabilities networkCapabilities) {
- this(networkInfo, linkProperties, networkCapabilities, null, null);
- }
-
- public NetworkState(NetworkInfo networkInfo, LinkProperties linkProperties,
- NetworkCapabilities networkCapabilities, String subscriberId, String networkId) {
- this.networkInfo = networkInfo;
- this.linkProperties = linkProperties;
- this.networkCapabilities = networkCapabilities;
- this.subscriberId = subscriberId;
- this.networkId = networkId;
- }
-
- public NetworkState(Parcel in) {
- networkInfo = in.readParcelable(null);
- linkProperties = in.readParcelable(null);
- networkCapabilities = in.readParcelable(null);
- subscriberId = in.readString();
- networkId = in.readString();
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeParcelable(networkInfo, flags);
- out.writeParcelable(linkProperties, flags);
- out.writeParcelable(networkCapabilities, flags);
- out.writeString(subscriberId);
- out.writeString(networkId);
- }
-
- public static final Creator<NetworkState> CREATOR = new Creator<NetworkState>() {
- @Override
- public NetworkState createFromParcel(Parcel in) {
- return new NetworkState(in);
- }
-
- @Override
- public NetworkState[] newArray(int size) {
- return new NetworkState[size];
- }
- };
-
-}
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
deleted file mode 100644
index b02f88e..0000000
--- a/core/java/android/net/NetworkUtils.java
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import java.net.InetAddress;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.UnknownHostException;
-import java.util.Collection;
-import java.util.Locale;
-
-import android.util.Log;
-
-/**
- * Native methods for managing network interfaces.
- *
- * {@hide}
- */
-public class NetworkUtils {
-
- private static final String TAG = "NetworkUtils";
-
- /** Bring the named network interface up. */
- public native static int enableInterface(String interfaceName);
-
- /** Bring the named network interface down. */
- public native static int disableInterface(String interfaceName);
-
- /** Setting bit 0 indicates reseting of IPv4 addresses required */
- public static final int RESET_IPV4_ADDRESSES = 0x01;
-
- /** Setting bit 1 indicates reseting of IPv4 addresses required */
- public static final int RESET_IPV6_ADDRESSES = 0x02;
-
- /** Reset all addresses */
- public static final int RESET_ALL_ADDRESSES = RESET_IPV4_ADDRESSES | RESET_IPV6_ADDRESSES;
-
- /**
- * Reset IPv6 or IPv4 sockets that are connected via the named interface.
- *
- * @param interfaceName is the interface to reset
- * @param mask {@see #RESET_IPV4_ADDRESSES} and {@see #RESET_IPV6_ADDRESSES}
- */
- public native static int resetConnections(String interfaceName, int mask);
-
- /**
- * Start the DHCP client daemon, in order to have it request addresses
- * for the named interface, and then configure the interface with those
- * addresses. This call blocks until it obtains a result (either success
- * or failure) from the daemon.
- * @param interfaceName the name of the interface to configure
- * @param dhcpResults if the request succeeds, this object is filled in with
- * the IP address information.
- * @return {@code true} for success, {@code false} for failure
- */
- public native static boolean runDhcp(String interfaceName, DhcpResults dhcpResults);
-
- /**
- * Initiate renewal on the Dhcp client daemon. This call blocks until it obtains
- * a result (either success or failure) from the daemon.
- * @param interfaceName the name of the interface to configure
- * @param dhcpResults if the request succeeds, this object is filled in with
- * the IP address information.
- * @return {@code true} for success, {@code false} for failure
- */
- public native static boolean runDhcpRenew(String interfaceName, DhcpResults dhcpResults);
-
- /**
- * Shut down the DHCP client daemon.
- * @param interfaceName the name of the interface for which the daemon
- * should be stopped
- * @return {@code true} for success, {@code false} for failure
- */
- public native static boolean stopDhcp(String interfaceName);
-
- /**
- * Release the current DHCP lease.
- * @param interfaceName the name of the interface for which the lease should
- * be released
- * @return {@code true} for success, {@code false} for failure
- */
- public native static boolean releaseDhcpLease(String interfaceName);
-
- /**
- * Return the last DHCP-related error message that was recorded.
- * <p/>NOTE: This string is not localized, but currently it is only
- * used in logging.
- * @return the most recent error message, if any
- */
- public native static String getDhcpError();
-
- /**
- * Set the SO_MARK of {@code socketfd} to {@code mark}
- */
- public native static void markSocket(int socketfd, int mark);
-
- /**
- * Binds the current process to the network designated by {@code netId}. All sockets created
- * in the future (and not explicitly bound via a bound {@link SocketFactory} (see
- * {@link Network#getSocketFactory}) will be bound to this network. Note that if this
- * {@code Network} ever disconnects all sockets created in this way will cease to work. This
- * is by design so an application doesn't accidentally use sockets it thinks are still bound to
- * a particular {@code Network}.
- */
- public native static void bindProcessToNetwork(int netId);
-
- /**
- * Clear any process specific {@code Network} binding. This reverts a call to
- * {@link #bindProcessToNetwork}.
- */
- public native static void unbindProcessToNetwork();
-
- /**
- * Return the netId last passed to {@link #bindProcessToNetwork}, or NETID_UNSET if
- * {@link #unbindProcessToNetwork} has been called since {@link #bindProcessToNetwork}.
- */
- public native static int getNetworkBoundToProcess();
-
- /**
- * Binds host resolutions performed by this process to the network designated by {@code netId}.
- * {@link #bindProcessToNetwork} takes precedence over this setting.
- *
- * @deprecated This is strictly for legacy usage to support startUsingNetworkFeature().
- */
- public native static void bindProcessToNetworkForHostResolution(int netId);
-
- /**
- * Clears any process specific {@link Network} binding for host resolution. This does
- * not clear bindings enacted via {@link #bindProcessToNetwork}.
- *
- * @deprecated This is strictly for legacy usage to support startUsingNetworkFeature().
- */
- public native static void unbindProcessToNetworkForHostResolution();
-
- /**
- * Explicitly binds {@code socketfd} to the network designated by {@code netId}. This
- * overrides any binding via {@link #bindProcessToNetwork}.
- */
- public native static void bindSocketToNetwork(int socketfd, int netId);
-
- /**
- * Convert a IPv4 address from an integer to an InetAddress.
- * @param hostAddress an int corresponding to the IPv4 address in network byte order
- */
- public static InetAddress intToInetAddress(int hostAddress) {
- byte[] addressBytes = { (byte)(0xff & hostAddress),
- (byte)(0xff & (hostAddress >> 8)),
- (byte)(0xff & (hostAddress >> 16)),
- (byte)(0xff & (hostAddress >> 24)) };
-
- try {
- return InetAddress.getByAddress(addressBytes);
- } catch (UnknownHostException e) {
- throw new AssertionError();
- }
- }
-
- /**
- * Convert a IPv4 address from an InetAddress to an integer
- * @param inetAddr is an InetAddress corresponding to the IPv4 address
- * @return the IP address as an integer in network byte order
- */
- public static int inetAddressToInt(Inet4Address inetAddr)
- throws IllegalArgumentException {
- byte [] addr = inetAddr.getAddress();
- return ((addr[3] & 0xff) << 24) | ((addr[2] & 0xff) << 16) |
- ((addr[1] & 0xff) << 8) | (addr[0] & 0xff);
- }
-
- /**
- * Convert a network prefix length to an IPv4 netmask integer
- * @param prefixLength
- * @return the IPv4 netmask as an integer in network byte order
- */
- public static int prefixLengthToNetmaskInt(int prefixLength)
- throws IllegalArgumentException {
- if (prefixLength < 0 || prefixLength > 32) {
- throw new IllegalArgumentException("Invalid prefix length (0 <= prefix <= 32)");
- }
- int value = 0xffffffff << (32 - prefixLength);
- return Integer.reverseBytes(value);
- }
-
- /**
- * Convert a IPv4 netmask integer to a prefix length
- * @param netmask as an integer in network byte order
- * @return the network prefix length
- */
- public static int netmaskIntToPrefixLength(int netmask) {
- return Integer.bitCount(netmask);
- }
-
- /**
- * Create an InetAddress from a string where the string must be a standard
- * representation of a V4 or V6 address. Avoids doing a DNS lookup on failure
- * but it will throw an IllegalArgumentException in that case.
- * @param addrString
- * @return the InetAddress
- * @hide
- */
- public static InetAddress numericToInetAddress(String addrString)
- throws IllegalArgumentException {
- return InetAddress.parseNumericAddress(addrString);
- }
-
- /**
- * Get InetAddress masked with prefixLength. Will never return null.
- * @param IP address which will be masked with specified prefixLength
- * @param prefixLength the prefixLength used to mask the IP
- */
- public static InetAddress getNetworkPart(InetAddress address, int prefixLength) {
- if (address == null) {
- throw new RuntimeException("getNetworkPart doesn't accept null address");
- }
-
- byte[] array = address.getAddress();
-
- if (prefixLength < 0 || prefixLength > array.length * 8) {
- throw new RuntimeException("getNetworkPart - bad prefixLength");
- }
-
- int offset = prefixLength / 8;
- int reminder = prefixLength % 8;
- byte mask = (byte)(0xFF << (8 - reminder));
-
- if (offset < array.length) array[offset] = (byte)(array[offset] & mask);
-
- offset++;
-
- for (; offset < array.length; offset++) {
- array[offset] = 0;
- }
-
- InetAddress netPart = null;
- try {
- netPart = InetAddress.getByAddress(array);
- } catch (UnknownHostException e) {
- throw new RuntimeException("getNetworkPart error - " + e.toString());
- }
- return netPart;
- }
-
- /**
- * Check if IP address type is consistent between two InetAddress.
- * @return true if both are the same type. False otherwise.
- */
- public static boolean addressTypeMatches(InetAddress left, InetAddress right) {
- return (((left instanceof Inet4Address) && (right instanceof Inet4Address)) ||
- ((left instanceof Inet6Address) && (right instanceof Inet6Address)));
- }
-
- /**
- * Convert a 32 char hex string into a Inet6Address.
- * throws a runtime exception if the string isn't 32 chars, isn't hex or can't be
- * made into an Inet6Address
- * @param addrHexString a 32 character hex string representing an IPv6 addr
- * @return addr an InetAddress representation for the string
- */
- public static InetAddress hexToInet6Address(String addrHexString)
- throws IllegalArgumentException {
- try {
- return numericToInetAddress(String.format(Locale.US, "%s:%s:%s:%s:%s:%s:%s:%s",
- addrHexString.substring(0,4), addrHexString.substring(4,8),
- addrHexString.substring(8,12), addrHexString.substring(12,16),
- addrHexString.substring(16,20), addrHexString.substring(20,24),
- addrHexString.substring(24,28), addrHexString.substring(28,32)));
- } catch (Exception e) {
- Log.e("NetworkUtils", "error in hexToInet6Address(" + addrHexString + "): " + e);
- throw new IllegalArgumentException(e);
- }
- }
-
- /**
- * Create a string array of host addresses from a collection of InetAddresses
- * @param addrs a Collection of InetAddresses
- * @return an array of Strings containing their host addresses
- */
- public static String[] makeStrings(Collection<InetAddress> addrs) {
- String[] result = new String[addrs.size()];
- int i = 0;
- for (InetAddress addr : addrs) {
- result[i++] = addr.getHostAddress();
- }
- return result;
- }
-
- /**
- * Trim leading zeros from IPv4 address strings
- * Our base libraries will interpret that as octel..
- * Must leave non v4 addresses and host names alone.
- * For example, 192.168.000.010 -> 192.168.0.10
- * TODO - fix base libraries and remove this function
- * @param addr a string representing an ip addr
- * @return a string propertly trimmed
- */
- public static String trimV4AddrZeros(String addr) {
- if (addr == null) return null;
- String[] octets = addr.split("\\.");
- if (octets.length != 4) return addr;
- StringBuilder builder = new StringBuilder(16);
- String result = null;
- for (int i = 0; i < 4; i++) {
- try {
- if (octets[i].length() > 3) return addr;
- builder.append(Integer.parseInt(octets[i]));
- } catch (NumberFormatException e) {
- return addr;
- }
- if (i < 3) builder.append('.');
- }
- result = builder.toString();
- return result;
- }
-}
diff --git a/core/java/android/net/ProxyInfo.java b/core/java/android/net/ProxyInfo.java
deleted file mode 100644
index 7ea6bae..0000000
--- a/core/java/android/net/ProxyInfo.java
+++ /dev/null
@@ -1,366 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-
-import org.apache.http.client.HttpClient;
-
-import java.net.InetSocketAddress;
-import java.net.URLConnection;
-import java.util.List;
-import java.util.Locale;
-
-/**
- * Describes a proxy configuration.
- *
- * Proxy configurations are already integrated within the Apache HTTP stack.
- * So {@link URLConnection} and {@link HttpClient} will use them automatically.
- *
- * Other HTTP stacks will need to obtain the proxy info from
- * {@link Proxy#PROXY_CHANGE_ACTION} broadcast as the extra {@link Proxy#EXTRA_PROXY_INFO}.
- */
-public class ProxyInfo implements Parcelable {
-
- private String mHost;
- private int mPort;
- private String mExclusionList;
- private String[] mParsedExclusionList;
-
- private Uri mPacFileUrl;
- /**
- *@hide
- */
- public static final String LOCAL_EXCL_LIST = "";
- /**
- *@hide
- */
- public static final int LOCAL_PORT = -1;
- /**
- *@hide
- */
- public static final String LOCAL_HOST = "localhost";
-
- /**
- * Constructs a {@link ProxyInfo} object that points at a Direct proxy
- * on the specified host and port.
- */
- public static ProxyInfo buildDirectProxy(String host, int port) {
- return new ProxyInfo(host, port, null);
- }
-
- /**
- * Constructs a {@link ProxyInfo} object that points at a Direct proxy
- * on the specified host and port.
- *
- * The proxy will not be used to access any host in exclusion list, exclList.
- *
- * @param exclList Hosts to exclude using the proxy on connections for. These
- * hosts can use wildcards such as *.example.com.
- */
- public static ProxyInfo buildDirectProxy(String host, int port, List<String> exclList) {
- String[] array = exclList.toArray(new String[exclList.size()]);
- return new ProxyInfo(host, port, TextUtils.join(",", array), array);
- }
-
- /**
- * Construct a {@link ProxyInfo} that will download and run the PAC script
- * at the specified URL.
- */
- public static ProxyInfo buildPacProxy(Uri pacUri) {
- return new ProxyInfo(pacUri);
- }
-
- /**
- * Create a ProxyProperties that points at a HTTP Proxy.
- * @hide
- */
- public ProxyInfo(String host, int port, String exclList) {
- mHost = host;
- mPort = port;
- setExclusionList(exclList);
- mPacFileUrl = Uri.EMPTY;
- }
-
- /**
- * Create a ProxyProperties that points at a PAC URL.
- * @hide
- */
- public ProxyInfo(Uri pacFileUrl) {
- mHost = LOCAL_HOST;
- mPort = LOCAL_PORT;
- setExclusionList(LOCAL_EXCL_LIST);
- if (pacFileUrl == null) {
- throw new NullPointerException();
- }
- mPacFileUrl = pacFileUrl;
- }
-
- /**
- * Create a ProxyProperties that points at a PAC URL.
- * @hide
- */
- public ProxyInfo(String pacFileUrl) {
- mHost = LOCAL_HOST;
- mPort = LOCAL_PORT;
- setExclusionList(LOCAL_EXCL_LIST);
- mPacFileUrl = Uri.parse(pacFileUrl);
- }
-
- /**
- * Only used in PacManager after Local Proxy is bound.
- * @hide
- */
- public ProxyInfo(Uri pacFileUrl, int localProxyPort) {
- mHost = LOCAL_HOST;
- mPort = localProxyPort;
- setExclusionList(LOCAL_EXCL_LIST);
- if (pacFileUrl == null) {
- throw new NullPointerException();
- }
- mPacFileUrl = pacFileUrl;
- }
-
- private ProxyInfo(String host, int port, String exclList, String[] parsedExclList) {
- mHost = host;
- mPort = port;
- mExclusionList = exclList;
- mParsedExclusionList = parsedExclList;
- mPacFileUrl = Uri.EMPTY;
- }
-
- // copy constructor instead of clone
- /**
- * @hide
- */
- public ProxyInfo(ProxyInfo source) {
- if (source != null) {
- mHost = source.getHost();
- mPort = source.getPort();
- mPacFileUrl = source.mPacFileUrl;
- mExclusionList = source.getExclusionListAsString();
- mParsedExclusionList = source.mParsedExclusionList;
- } else {
- mPacFileUrl = Uri.EMPTY;
- }
- }
-
- /**
- * @hide
- */
- public InetSocketAddress getSocketAddress() {
- InetSocketAddress inetSocketAddress = null;
- try {
- inetSocketAddress = new InetSocketAddress(mHost, mPort);
- } catch (IllegalArgumentException e) { }
- return inetSocketAddress;
- }
-
- /**
- * Returns the URL of the current PAC script or null if there is
- * no PAC script.
- */
- public Uri getPacFileUrl() {
- return mPacFileUrl;
- }
-
- /**
- * When configured to use a Direct Proxy this returns the host
- * of the proxy.
- */
- public String getHost() {
- return mHost;
- }
-
- /**
- * When configured to use a Direct Proxy this returns the port
- * of the proxy
- */
- public int getPort() {
- return mPort;
- }
-
- /**
- * When configured to use a Direct Proxy this returns the list
- * of hosts for which the proxy is ignored.
- */
- public String[] getExclusionList() {
- return mParsedExclusionList;
- }
-
- /**
- * comma separated
- * @hide
- */
- public String getExclusionListAsString() {
- return mExclusionList;
- }
-
- // comma separated
- private void setExclusionList(String exclusionList) {
- mExclusionList = exclusionList;
- if (mExclusionList == null) {
- mParsedExclusionList = new String[0];
- } else {
- mParsedExclusionList = exclusionList.toLowerCase(Locale.ROOT).split(",");
- }
- }
-
- /**
- * @hide
- */
- public boolean isValid() {
- if (!Uri.EMPTY.equals(mPacFileUrl)) return true;
- return Proxy.PROXY_VALID == Proxy.validate(mHost == null ? "" : mHost,
- mPort == 0 ? "" : Integer.toString(mPort),
- mExclusionList == null ? "" : mExclusionList);
- }
-
- /**
- * @hide
- */
- public java.net.Proxy makeProxy() {
- java.net.Proxy proxy = java.net.Proxy.NO_PROXY;
- if (mHost != null) {
- try {
- InetSocketAddress inetSocketAddress = new InetSocketAddress(mHost, mPort);
- proxy = new java.net.Proxy(java.net.Proxy.Type.HTTP, inetSocketAddress);
- } catch (IllegalArgumentException e) {
- }
- }
- return proxy;
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- if (!Uri.EMPTY.equals(mPacFileUrl)) {
- sb.append("PAC Script: ");
- sb.append(mPacFileUrl);
- } else if (mHost != null) {
- sb.append("[");
- sb.append(mHost);
- sb.append("] ");
- sb.append(Integer.toString(mPort));
- if (mExclusionList != null) {
- sb.append(" xl=").append(mExclusionList);
- }
- } else {
- sb.append("[ProxyProperties.mHost == null]");
- }
- return sb.toString();
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof ProxyInfo)) return false;
- ProxyInfo p = (ProxyInfo)o;
- // If PAC URL is present in either then they must be equal.
- // Other parameters will only be for fall back.
- if (!Uri.EMPTY.equals(mPacFileUrl)) {
- return mPacFileUrl.equals(p.getPacFileUrl()) && mPort == p.mPort;
- }
- if (!Uri.EMPTY.equals(p.mPacFileUrl)) {
- return false;
- }
- if (mExclusionList != null && !mExclusionList.equals(p.getExclusionListAsString())) {
- return false;
- }
- if (mHost != null && p.getHost() != null && mHost.equals(p.getHost()) == false) {
- return false;
- }
- if (mHost != null && p.mHost == null) return false;
- if (mHost == null && p.mHost != null) return false;
- if (mPort != p.mPort) return false;
- return true;
- }
-
- /**
- * Implement the Parcelable interface
- * @hide
- */
- public int describeContents() {
- return 0;
- }
-
- @Override
- /*
- * generate hashcode based on significant fields
- */
- public int hashCode() {
- return ((null == mHost) ? 0 : mHost.hashCode())
- + ((null == mExclusionList) ? 0 : mExclusionList.hashCode())
- + mPort;
- }
-
- /**
- * Implement the Parcelable interface.
- * @hide
- */
- public void writeToParcel(Parcel dest, int flags) {
- if (!Uri.EMPTY.equals(mPacFileUrl)) {
- dest.writeByte((byte)1);
- mPacFileUrl.writeToParcel(dest, 0);
- dest.writeInt(mPort);
- return;
- } else {
- dest.writeByte((byte)0);
- }
- if (mHost != null) {
- dest.writeByte((byte)1);
- dest.writeString(mHost);
- dest.writeInt(mPort);
- } else {
- dest.writeByte((byte)0);
- }
- dest.writeString(mExclusionList);
- dest.writeStringArray(mParsedExclusionList);
- }
-
- /**
- * Implement the Parcelable interface.
- * @hide
- */
- public static final Creator<ProxyInfo> CREATOR =
- new Creator<ProxyInfo>() {
- public ProxyInfo createFromParcel(Parcel in) {
- String host = null;
- int port = 0;
- if (in.readByte() != 0) {
- Uri url = Uri.CREATOR.createFromParcel(in);
- int localPort = in.readInt();
- return new ProxyInfo(url, localPort);
- }
- if (in.readByte() != 0) {
- host = in.readString();
- port = in.readInt();
- }
- String exclList = in.readString();
- String[] parsedExclList = in.readStringArray();
- ProxyInfo proxyProperties =
- new ProxyInfo(host, port, exclList, parsedExclList);
- return proxyProperties;
- }
-
- public ProxyInfo[] newArray(int size) {
- return new ProxyInfo[size];
- }
- };
-}
diff --git a/core/java/android/net/RouteInfo.java b/core/java/android/net/RouteInfo.java
deleted file mode 100644
index 8b42bcd..0000000
--- a/core/java/android/net/RouteInfo.java
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.net.UnknownHostException;
-import java.net.InetAddress;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-
-import java.util.Collection;
-import java.util.Objects;
-
-/**
- * Represents a network route.
- * <p>
- * This is used both to describe static network configuration and live network
- * configuration information.
- *
- * A route contains three pieces of information:
- * <ul>
- * <li>a destination {@link IpPrefix} specifying the network destinations covered by this route.
- * If this is {@code null} it indicates a default route of the address family (IPv4 or IPv6)
- * implied by the gateway IP address.
- * <li>a gateway {@link InetAddress} indicating the next hop to use. If this is {@code null} it
- * indicates a directly-connected route.
- * <li>an interface (which may be unspecified).
- * </ul>
- * Either the destination or the gateway may be {@code null}, but not both. If the
- * destination and gateway are both specified, they must be of the same address family
- * (IPv4 or IPv6).
- */
-public class RouteInfo implements Parcelable {
- /**
- * The IP destination address for this route.
- * TODO: Make this an IpPrefix.
- */
- private final LinkAddress mDestination;
-
- /**
- * The gateway address for this route.
- */
- private final InetAddress mGateway;
-
- /**
- * The interface for this route.
- */
- private final String mInterface;
-
- private final boolean mIsDefault;
- private final boolean mIsHost;
- private final boolean mHasGateway;
-
- /**
- * Constructs a RouteInfo object.
- *
- * If destination is null, then gateway must be specified and the
- * constructed route is either the IPv4 default route <code>0.0.0.0</code>
- * if the gateway is an instance of {@link Inet4Address}, or the IPv6 default
- * route <code>::/0</code> if gateway is an instance of
- * {@link Inet6Address}.
- * <p>
- * destination and gateway may not both be null.
- *
- * @param destination the destination prefix
- * @param gateway the IP address to route packets through
- * @param iface the interface name to send packets on
- *
- * TODO: Convert to use IpPrefix.
- *
- * @hide
- */
- public RouteInfo(IpPrefix destination, InetAddress gateway, String iface) {
- this(destination == null ? null :
- new LinkAddress(destination.getAddress(), destination.getPrefixLength()),
- gateway, iface);
- }
-
- /**
- * @hide
- */
- public RouteInfo(LinkAddress destination, InetAddress gateway, String iface) {
- if (destination == null) {
- if (gateway != null) {
- if (gateway instanceof Inet4Address) {
- destination = new LinkAddress(Inet4Address.ANY, 0);
- } else {
- destination = new LinkAddress(Inet6Address.ANY, 0);
- }
- } else {
- // no destination, no gateway. invalid.
- throw new IllegalArgumentException("Invalid arguments passed in: " + gateway + "," +
- destination);
- }
- }
- if (gateway == null) {
- if (destination.getAddress() instanceof Inet4Address) {
- gateway = Inet4Address.ANY;
- } else {
- gateway = Inet6Address.ANY;
- }
- }
- mHasGateway = (!gateway.isAnyLocalAddress());
-
- mDestination = new LinkAddress(NetworkUtils.getNetworkPart(destination.getAddress(),
- destination.getPrefixLength()), destination.getPrefixLength());
- if ((destination.getAddress() instanceof Inet4Address &&
- (gateway instanceof Inet4Address == false)) ||
- (destination.getAddress() instanceof Inet6Address &&
- (gateway instanceof Inet6Address == false))) {
- throw new IllegalArgumentException("address family mismatch in RouteInfo constructor");
- }
- mGateway = gateway;
- mInterface = iface;
- mIsDefault = isDefault();
- mIsHost = isHost();
- }
-
- /**
- * Constructs a {@code RouteInfo} object.
- *
- * If destination is null, then gateway must be specified and the
- * constructed route is either the IPv4 default route <code>0.0.0.0</code>
- * if the gateway is an instance of {@link Inet4Address}, or the IPv6 default
- * route <code>::/0</code> if gateway is an instance of {@link Inet6Address}.
- * <p>
- * Destination and gateway may not both be null.
- *
- * @param destination the destination address and prefix in an {@link IpPrefix}
- * @param gateway the {@link InetAddress} to route packets through
- *
- * @hide
- */
- public RouteInfo(IpPrefix destination, InetAddress gateway) {
- this(destination, gateway, null);
- }
-
- /**
- * @hide
- */
- public RouteInfo(LinkAddress destination, InetAddress gateway) {
- this(destination, gateway, null);
- }
-
- /**
- * Constructs a default {@code RouteInfo} object.
- *
- * @param gateway the {@link InetAddress} to route packets through
- *
- * @hide
- */
- public RouteInfo(InetAddress gateway) {
- this((LinkAddress) null, gateway, null);
- }
-
- /**
- * Constructs a {@code RouteInfo} object representing a direct connected subnet.
- *
- * @param destination the {@link IpPrefix} describing the address and prefix
- * length of the subnet.
- *
- * @hide
- */
- public RouteInfo(IpPrefix destination) {
- this(destination, null, null);
- }
-
- /**
- * @hide
- */
- public RouteInfo(LinkAddress destination) {
- this(destination, null, null);
- }
-
- /**
- * @hide
- */
- public static RouteInfo makeHostRoute(InetAddress host, String iface) {
- return makeHostRoute(host, null, iface);
- }
-
- /**
- * @hide
- */
- public static RouteInfo makeHostRoute(InetAddress host, InetAddress gateway, String iface) {
- if (host == null) return null;
-
- if (host instanceof Inet4Address) {
- return new RouteInfo(new LinkAddress(host, 32), gateway, iface);
- } else {
- return new RouteInfo(new LinkAddress(host, 128), gateway, iface);
- }
- }
-
- private boolean isHost() {
- return (mDestination.getAddress() instanceof Inet4Address &&
- mDestination.getPrefixLength() == 32) ||
- (mDestination.getAddress() instanceof Inet6Address &&
- mDestination.getPrefixLength() == 128);
- }
-
- private boolean isDefault() {
- boolean val = false;
- if (mGateway != null) {
- if (mGateway instanceof Inet4Address) {
- val = (mDestination == null || mDestination.getPrefixLength() == 0);
- } else {
- val = (mDestination == null || mDestination.getPrefixLength() == 0);
- }
- }
- return val;
- }
-
- /**
- * Retrieves the destination address and prefix length in the form of an {@link IpPrefix}.
- *
- * @return {@link IpPrefix} specifying the destination. This is never {@code null}.
- */
- public IpPrefix getDestination() {
- return new IpPrefix(mDestination.getAddress(), mDestination.getPrefixLength());
- }
-
- /**
- * TODO: Convert callers to use IpPrefix and then remove.
- * @hide
- */
- public LinkAddress getDestinationLinkAddress() {
- return mDestination;
- }
-
- /**
- * Retrieves the gateway or next hop {@link InetAddress} for this route.
- *
- * @return {@link InetAddress} specifying the gateway or next hop. This may be
- & {@code null} for a directly-connected route."
- */
- public InetAddress getGateway() {
- return mGateway;
- }
-
- /**
- * Retrieves the interface used for this route if specified, else {@code null}.
- *
- * @return The name of the interface used for this route.
- */
- public String getInterface() {
- return mInterface;
- }
-
- /**
- * Indicates if this route is a default route (ie, has no destination specified).
- *
- * @return {@code true} if the destination has a prefix length of 0.
- */
- public boolean isDefaultRoute() {
- return mIsDefault;
- }
-
- /**
- * Indicates if this route is a host route (ie, matches only a single host address).
- *
- * @return {@code true} if the destination has a prefix length of 32 or 128 for IPv4 or IPv6,
- * respectively.
- * @hide
- */
- public boolean isHostRoute() {
- return mIsHost;
- }
-
- /**
- * Indicates if this route has a next hop ({@code true}) or is directly-connected
- * ({@code false}).
- *
- * @return {@code true} if a gateway is specified
- * @hide
- */
- public boolean hasGateway() {
- return mHasGateway;
- }
-
- /**
- * Determines whether the destination and prefix of this route includes the specified
- * address.
- *
- * @param destination A {@link InetAddress} to test to see if it would match this route.
- * @return {@code true} if the destination and prefix length cover the given address.
- */
- public boolean matches(InetAddress destination) {
- if (destination == null) return false;
-
- // match the route destination and destination with prefix length
- InetAddress dstNet = NetworkUtils.getNetworkPart(destination,
- mDestination.getPrefixLength());
-
- return mDestination.getAddress().equals(dstNet);
- }
-
- /**
- * Find the route from a Collection of routes that best matches a given address.
- * May return null if no routes are applicable.
- * @param routes a Collection of RouteInfos to chose from
- * @param dest the InetAddress your trying to get to
- * @return the RouteInfo from the Collection that best fits the given address
- *
- * @hide
- */
- public static RouteInfo selectBestRoute(Collection<RouteInfo> routes, InetAddress dest) {
- if ((routes == null) || (dest == null)) return null;
-
- RouteInfo bestRoute = null;
- // pick a longest prefix match under same address type
- for (RouteInfo route : routes) {
- if (NetworkUtils.addressTypeMatches(route.mDestination.getAddress(), dest)) {
- if ((bestRoute != null) &&
- (bestRoute.mDestination.getPrefixLength() >=
- route.mDestination.getPrefixLength())) {
- continue;
- }
- if (route.matches(dest)) bestRoute = route;
- }
- }
- return bestRoute;
- }
-
- /**
- * Returns a human-readable description of this object.
- */
- public String toString() {
- String val = "";
- if (mDestination != null) val = mDestination.toString();
- val += " ->";
- if (mGateway != null) val += " " + mGateway.getHostAddress();
- if (mInterface != null) val += " " + mInterface;
- return val;
- }
-
- /**
- * Compares this RouteInfo object against the specified object and indicates if they are equal.
- * @return {@code true} if the objects are equal, {@code false} otherwise.
- */
- public boolean equals(Object obj) {
- if (this == obj) return true;
-
- if (!(obj instanceof RouteInfo)) return false;
-
- RouteInfo target = (RouteInfo) obj;
-
- return Objects.equals(mDestination, target.getDestinationLinkAddress()) &&
- Objects.equals(mGateway, target.getGateway()) &&
- Objects.equals(mInterface, target.getInterface());
- }
-
- /**
- * Returns a hashcode for this <code>RouteInfo</code> object.
- */
- public int hashCode() {
- return (mDestination == null ? 0 : mDestination.hashCode() * 41)
- + (mGateway == null ? 0 :mGateway.hashCode() * 47)
- + (mInterface == null ? 0 :mInterface.hashCode() * 67)
- + (mIsDefault ? 3 : 7);
- }
-
- /**
- * Implement the Parcelable interface
- * @hide
- */
- public int describeContents() {
- return 0;
- }
-
- /**
- * Implement the Parcelable interface
- * @hide
- */
- public void writeToParcel(Parcel dest, int flags) {
- if (mDestination == null) {
- dest.writeByte((byte) 0);
- } else {
- dest.writeByte((byte) 1);
- dest.writeByteArray(mDestination.getAddress().getAddress());
- dest.writeInt(mDestination.getPrefixLength());
- }
-
- if (mGateway == null) {
- dest.writeByte((byte) 0);
- } else {
- dest.writeByte((byte) 1);
- dest.writeByteArray(mGateway.getAddress());
- }
-
- dest.writeString(mInterface);
- }
-
- /**
- * Implement the Parcelable interface.
- * @hide
- */
- public static final Creator<RouteInfo> CREATOR =
- new Creator<RouteInfo>() {
- public RouteInfo createFromParcel(Parcel in) {
- InetAddress destAddr = null;
- int prefix = 0;
- InetAddress gateway = null;
-
- if (in.readByte() == 1) {
- byte[] addr = in.createByteArray();
- prefix = in.readInt();
-
- try {
- destAddr = InetAddress.getByAddress(addr);
- } catch (UnknownHostException e) {}
- }
-
- if (in.readByte() == 1) {
- byte[] addr = in.createByteArray();
-
- try {
- gateway = InetAddress.getByAddress(addr);
- } catch (UnknownHostException e) {}
- }
-
- String iface = in.readString();
-
- LinkAddress dest = null;
-
- if (destAddr != null) {
- dest = new LinkAddress(destAddr, prefix);
- }
-
- return new RouteInfo(dest, gateway, iface);
- }
-
- public RouteInfo[] newArray(int size) {
- return new RouteInfo[size];
- }
- };
-}
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
deleted file mode 100644
index bc5e1b3..0000000
--- a/core/jni/android_net_NetUtils.cpp
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * Copyright 2008, 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.
- */
-
-#define LOG_TAG "NetUtils"
-
-#include "jni.h"
-#include "JNIHelp.h"
-#include "NetdClient.h"
-#include "resolv_netid.h"
-#include <utils/misc.h>
-#include <android_runtime/AndroidRuntime.h>
-#include <utils/Log.h>
-#include <arpa/inet.h>
-#include <cutils/properties.h>
-
-extern "C" {
-int ifc_enable(const char *ifname);
-int ifc_disable(const char *ifname);
-int ifc_reset_connections(const char *ifname, int reset_mask);
-
-int dhcp_do_request(const char * const ifname,
- const char *ipaddr,
- const char *gateway,
- uint32_t *prefixLength,
- const char *dns[],
- const char *server,
- uint32_t *lease,
- const char *vendorInfo,
- const char *domains,
- const char *mtu);
-
-int dhcp_do_request_renew(const char * const ifname,
- const char *ipaddr,
- const char *gateway,
- uint32_t *prefixLength,
- const char *dns[],
- const char *server,
- uint32_t *lease,
- const char *vendorInfo,
- const char *domains,
- const char *mtu);
-
-int dhcp_stop(const char *ifname);
-int dhcp_release_lease(const char *ifname);
-char *dhcp_get_errmsg();
-}
-
-#define NETUTILS_PKG_NAME "android/net/NetworkUtils"
-
-namespace android {
-
-/*
- * The following remembers the jfieldID's of the fields
- * of the DhcpInfo Java object, so that we don't have
- * to look them up every time.
- */
-static struct fieldIds {
- jmethodID clear;
- jmethodID setInterfaceName;
- jmethodID addLinkAddress;
- jmethodID addGateway;
- jmethodID addDns;
- jmethodID setDomains;
- jmethodID setServerAddress;
- jmethodID setLeaseDuration;
- jmethodID setVendorInfo;
-} dhcpResultsFieldIds;
-
-static jint android_net_utils_enableInterface(JNIEnv* env, jobject clazz, jstring ifname)
-{
- int result;
-
- const char *nameStr = env->GetStringUTFChars(ifname, NULL);
- result = ::ifc_enable(nameStr);
- env->ReleaseStringUTFChars(ifname, nameStr);
- return (jint)result;
-}
-
-static jint android_net_utils_disableInterface(JNIEnv* env, jobject clazz, jstring ifname)
-{
- int result;
-
- const char *nameStr = env->GetStringUTFChars(ifname, NULL);
- result = ::ifc_disable(nameStr);
- env->ReleaseStringUTFChars(ifname, nameStr);
- return (jint)result;
-}
-
-static jint android_net_utils_resetConnections(JNIEnv* env, jobject clazz,
- jstring ifname, jint mask)
-{
- int result;
-
- const char *nameStr = env->GetStringUTFChars(ifname, NULL);
-
- ALOGD("android_net_utils_resetConnections in env=%p clazz=%p iface=%s mask=0x%x\n",
- env, clazz, nameStr, mask);
-
- result = ::ifc_reset_connections(nameStr, mask);
- env->ReleaseStringUTFChars(ifname, nameStr);
- return (jint)result;
-}
-
-static jboolean android_net_utils_runDhcpCommon(JNIEnv* env, jobject clazz, jstring ifname,
- jobject dhcpResults, bool renew)
-{
- int result;
- char ipaddr[PROPERTY_VALUE_MAX];
- uint32_t prefixLength;
- char gateway[PROPERTY_VALUE_MAX];
- char dns1[PROPERTY_VALUE_MAX];
- char dns2[PROPERTY_VALUE_MAX];
- char dns3[PROPERTY_VALUE_MAX];
- char dns4[PROPERTY_VALUE_MAX];
- const char *dns[5] = {dns1, dns2, dns3, dns4, NULL};
- char server[PROPERTY_VALUE_MAX];
- uint32_t lease;
- char vendorInfo[PROPERTY_VALUE_MAX];
- char domains[PROPERTY_VALUE_MAX];
- char mtu[PROPERTY_VALUE_MAX];
-
- const char *nameStr = env->GetStringUTFChars(ifname, NULL);
- if (nameStr == NULL) return (jboolean)false;
-
- if (renew) {
- result = ::dhcp_do_request_renew(nameStr, ipaddr, gateway, &prefixLength,
- dns, server, &lease, vendorInfo, domains, mtu);
- } else {
- result = ::dhcp_do_request(nameStr, ipaddr, gateway, &prefixLength,
- dns, server, &lease, vendorInfo, domains, mtu);
- }
- if (result != 0) {
- ALOGD("dhcp_do_request failed : %s (%s)", nameStr, renew ? "renew" : "new");
- }
-
- env->ReleaseStringUTFChars(ifname, nameStr);
- if (result == 0) {
- env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.clear);
-
- // set mIfaceName
- // dhcpResults->setInterfaceName(ifname)
- env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.setInterfaceName, ifname);
-
- // set the linkAddress
- // dhcpResults->addLinkAddress(inetAddress, prefixLength)
- result = env->CallBooleanMethod(dhcpResults, dhcpResultsFieldIds.addLinkAddress,
- env->NewStringUTF(ipaddr), prefixLength);
- }
-
- if (result == 0) {
- // set the gateway
- // dhcpResults->addGateway(gateway)
- result = env->CallBooleanMethod(dhcpResults,
- dhcpResultsFieldIds.addGateway, env->NewStringUTF(gateway));
- }
-
- if (result == 0) {
- // dhcpResults->addDns(new InetAddress(dns1))
- result = env->CallBooleanMethod(dhcpResults,
- dhcpResultsFieldIds.addDns, env->NewStringUTF(dns1));
- }
-
- if (result == 0) {
- env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.setDomains,
- env->NewStringUTF(domains));
-
- result = env->CallBooleanMethod(dhcpResults,
- dhcpResultsFieldIds.addDns, env->NewStringUTF(dns2));
-
- if (result == 0) {
- result = env->CallBooleanMethod(dhcpResults,
- dhcpResultsFieldIds.addDns, env->NewStringUTF(dns3));
- if (result == 0) {
- result = env->CallBooleanMethod(dhcpResults,
- dhcpResultsFieldIds.addDns, env->NewStringUTF(dns4));
- }
- }
- }
-
- if (result == 0) {
- // dhcpResults->setServerAddress(new InetAddress(server))
- result = env->CallBooleanMethod(dhcpResults, dhcpResultsFieldIds.setServerAddress,
- env->NewStringUTF(server));
- }
-
- if (result == 0) {
- // dhcpResults->setLeaseDuration(lease)
- env->CallVoidMethod(dhcpResults,
- dhcpResultsFieldIds.setLeaseDuration, lease);
-
- // dhcpResults->setVendorInfo(vendorInfo)
- env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.setVendorInfo,
- env->NewStringUTF(vendorInfo));
- }
- return (jboolean)(result == 0);
-}
-
-
-static jboolean android_net_utils_runDhcp(JNIEnv* env, jobject clazz, jstring ifname, jobject info)
-{
- return android_net_utils_runDhcpCommon(env, clazz, ifname, info, false);
-}
-
-static jboolean android_net_utils_runDhcpRenew(JNIEnv* env, jobject clazz, jstring ifname, jobject info)
-{
- return android_net_utils_runDhcpCommon(env, clazz, ifname, info, true);
-}
-
-
-static jboolean android_net_utils_stopDhcp(JNIEnv* env, jobject clazz, jstring ifname)
-{
- int result;
-
- const char *nameStr = env->GetStringUTFChars(ifname, NULL);
- result = ::dhcp_stop(nameStr);
- env->ReleaseStringUTFChars(ifname, nameStr);
- return (jboolean)(result == 0);
-}
-
-static jboolean android_net_utils_releaseDhcpLease(JNIEnv* env, jobject clazz, jstring ifname)
-{
- int result;
-
- const char *nameStr = env->GetStringUTFChars(ifname, NULL);
- result = ::dhcp_release_lease(nameStr);
- env->ReleaseStringUTFChars(ifname, nameStr);
- return (jboolean)(result == 0);
-}
-
-static jstring android_net_utils_getDhcpError(JNIEnv* env, jobject clazz)
-{
- return env->NewStringUTF(::dhcp_get_errmsg());
-}
-
-static void android_net_utils_markSocket(JNIEnv *env, jobject thiz, jint socket, jint mark)
-{
- if (setsockopt(socket, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) < 0) {
- jniThrowException(env, "java/lang/IllegalStateException", "Error marking socket");
- }
-}
-
-static void android_net_utils_bindProcessToNetwork(JNIEnv *env, jobject thiz, jint netId)
-{
- setNetworkForProcess(netId);
-}
-
-static void android_net_utils_unbindProcessToNetwork(JNIEnv *env, jobject thiz)
-{
- setNetworkForProcess(NETID_UNSET);
-}
-
-static jint android_net_utils_getNetworkBoundToProcess(JNIEnv *env, jobject thiz)
-{
- return getNetworkForProcess();
-}
-
-static void android_net_utils_bindProcessToNetworkForHostResolution(JNIEnv *env, jobject thiz, jint netId)
-{
- setNetworkForResolv(netId);
-}
-
-static void android_net_utils_unbindProcessToNetworkForHostResolution(JNIEnv *env, jobject thiz)
-{
- setNetworkForResolv(NETID_UNSET);
-}
-
-static void android_net_utils_bindSocketToNetwork(JNIEnv *env, jobject thiz, jint socket, jint netId)
-{
- setNetworkForSocket(netId, socket);
-}
-
-// ----------------------------------------------------------------------------
-
-/*
- * JNI registration.
- */
-static JNINativeMethod gNetworkUtilMethods[] = {
- /* name, signature, funcPtr */
-
- { "enableInterface", "(Ljava/lang/String;)I", (void *)android_net_utils_enableInterface },
- { "disableInterface", "(Ljava/lang/String;)I", (void *)android_net_utils_disableInterface },
- { "resetConnections", "(Ljava/lang/String;I)I", (void *)android_net_utils_resetConnections },
- { "runDhcp", "(Ljava/lang/String;Landroid/net/DhcpResults;)Z", (void *)android_net_utils_runDhcp },
- { "runDhcpRenew", "(Ljava/lang/String;Landroid/net/DhcpResults;)Z", (void *)android_net_utils_runDhcpRenew },
- { "stopDhcp", "(Ljava/lang/String;)Z", (void *)android_net_utils_stopDhcp },
- { "releaseDhcpLease", "(Ljava/lang/String;)Z", (void *)android_net_utils_releaseDhcpLease },
- { "getDhcpError", "()Ljava/lang/String;", (void*) android_net_utils_getDhcpError },
- { "markSocket", "(II)V", (void*) android_net_utils_markSocket },
- { "bindProcessToNetwork", "(I)V", (void*) android_net_utils_bindProcessToNetwork },
- { "getNetworkBoundToProcess", "()I", (void*) android_net_utils_getNetworkBoundToProcess },
- { "unbindProcessToNetwork", "()V", (void*) android_net_utils_unbindProcessToNetwork },
- { "bindProcessToNetworkForHostResolution", "(I)V", (void*) android_net_utils_bindProcessToNetworkForHostResolution },
- { "unbindProcessToNetworkForHostResolution", "()V", (void*) android_net_utils_unbindProcessToNetworkForHostResolution },
- { "bindSocketToNetwork", "(II)V", (void*) android_net_utils_bindSocketToNetwork },
-};
-
-int register_android_net_NetworkUtils(JNIEnv* env)
-{
- jclass dhcpResultsClass = env->FindClass("android/net/DhcpResults");
- LOG_FATAL_IF(dhcpResultsClass == NULL, "Unable to find class android/net/DhcpResults");
- dhcpResultsFieldIds.clear =
- env->GetMethodID(dhcpResultsClass, "clear", "()V");
- dhcpResultsFieldIds.setInterfaceName =
- env->GetMethodID(dhcpResultsClass, "setInterfaceName", "(Ljava/lang/String;)V");
- dhcpResultsFieldIds.addLinkAddress =
- env->GetMethodID(dhcpResultsClass, "addLinkAddress", "(Ljava/lang/String;I)Z");
- dhcpResultsFieldIds.addGateway =
- env->GetMethodID(dhcpResultsClass, "addGateway", "(Ljava/lang/String;)Z");
- dhcpResultsFieldIds.addDns =
- env->GetMethodID(dhcpResultsClass, "addDns", "(Ljava/lang/String;)Z");
- dhcpResultsFieldIds.setDomains =
- env->GetMethodID(dhcpResultsClass, "setDomains", "(Ljava/lang/String;)V");
- dhcpResultsFieldIds.setServerAddress =
- env->GetMethodID(dhcpResultsClass, "setServerAddress", "(Ljava/lang/String;)Z");
- dhcpResultsFieldIds.setLeaseDuration =
- env->GetMethodID(dhcpResultsClass, "setLeaseDuration", "(I)V");
- dhcpResultsFieldIds.setVendorInfo =
- env->GetMethodID(dhcpResultsClass, "setVendorInfo", "(Ljava/lang/String;)V");
-
- return AndroidRuntime::registerNativeMethods(env,
- NETUTILS_PKG_NAME, gNetworkUtilMethods, NELEM(gNetworkUtilMethods));
-}
-
-}; // namespace android
diff --git a/core/tests/coretests/res/raw/xt_qtaguid_iface_fmt_typical b/core/tests/coretests/res/raw/xt_qtaguid_iface_fmt_typical
deleted file mode 100644
index 656d5bb..0000000
--- a/core/tests/coretests/res/raw/xt_qtaguid_iface_fmt_typical
+++ /dev/null
@@ -1,4 +0,0 @@
-ifname total_skb_rx_bytes total_skb_rx_packets total_skb_tx_bytes total_skb_tx_packets
-rmnet2 4968 35 3081 39
-rmnet1 11153922 8051 190226 2468
-rmnet0 6824 16 5692 10
diff --git a/core/tests/coretests/res/raw/xt_qtaguid_iface_typical b/core/tests/coretests/res/raw/xt_qtaguid_iface_typical
deleted file mode 100644
index 610723a..0000000
--- a/core/tests/coretests/res/raw/xt_qtaguid_iface_typical
+++ /dev/null
@@ -1,6 +0,0 @@
-rmnet3 1 0 0 0 0 20822 501 1149991 815
-rmnet2 1 0 0 0 0 1594 15 1313 15
-rmnet1 1 0 0 0 0 207398 458 166918 565
-rmnet0 1 0 0 0 0 2112 24 700 10
-test1 1 1 2 3 4 5 6 7 8
-test2 0 1 2 3 4 5 6 7 8
diff --git a/core/tests/coretests/res/raw/xt_qtaguid_typical b/core/tests/coretests/res/raw/xt_qtaguid_typical
deleted file mode 100644
index c1b0d25..0000000
--- a/core/tests/coretests/res/raw/xt_qtaguid_typical
+++ /dev/null
@@ -1,71 +0,0 @@
-idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets
-2 wlan0 0x0 0 0 18621 96 2898 44 312 6 15897 58 2412 32 312 6 1010 16 1576 22
-3 wlan0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-4 wlan0 0x0 1000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-5 wlan0 0x0 1000 1 1949 13 1078 14 0 0 1600 10 349 3 0 0 600 10 478 4
-6 wlan0 0x0 10005 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-7 wlan0 0x0 10005 1 32081 38 5315 50 32081 38 0 0 0 0 5315 50 0 0 0 0
-8 wlan0 0x0 10011 0 35777 53 5718 57 0 0 0 0 35777 53 0 0 0 0 5718 57
-9 wlan0 0x0 10011 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-10 wlan0 0x0 10014 0 0 0 1098 13 0 0 0 0 0 0 0 0 0 0 1098 13
-11 wlan0 0x0 10014 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-12 wlan0 0x0 10021 0 562386 573 49228 549 0 0 0 0 562386 573 0 0 0 0 49228 549
-13 wlan0 0x0 10021 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-14 wlan0 0x0 10031 0 3425 5 586 6 0 0 0 0 3425 5 0 0 0 0 586 6
-15 wlan0 0x0 10031 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-16 wlan0 0x7fffff0100000000 10021 0 562386 573 49228 549 0 0 0 0 562386 573 0 0 0 0 49228 549
-17 wlan0 0x7fffff0100000000 10021 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-18 wlan0 0x7fffff0100000000 10031 0 3425 5 586 6 0 0 0 0 3425 5 0 0 0 0 586 6
-19 wlan0 0x7fffff0100000000 10031 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-20 rmnet2 0x0 0 0 547 5 118 2 40 1 243 1 264 3 0 0 62 1 56 1
-21 rmnet2 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-22 rmnet2 0x0 10001 0 1125899906842624 5 984 11 632 5 0 0 0 0 984 11 0 0 0 0
-23 rmnet2 0x0 10001 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-24 rmnet1 0x0 0 0 26736 174 7098 130 7210 97 18382 64 1144 13 2932 64 4054 64 112 2
-25 rmnet1 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-26 rmnet1 0x0 1000 0 75774 77 18038 78 75335 72 439 5 0 0 17668 73 370 5 0 0
-27 rmnet1 0x0 1000 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-28 rmnet1 0x0 10007 0 269945 578 111632 586 269945 578 0 0 0 0 111632 586 0 0 0 0
-29 rmnet1 0x0 10007 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-30 rmnet1 0x0 10011 0 1741256 6918 769778 7019 1741256 6918 0 0 0 0 769778 7019 0 0 0 0
-31 rmnet1 0x0 10011 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-32 rmnet1 0x0 10014 0 0 0 786 12 0 0 0 0 0 0 786 12 0 0 0 0
-33 rmnet1 0x0 10014 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-34 rmnet1 0x0 10021 0 433533 1454 393420 1604 433533 1454 0 0 0 0 393420 1604 0 0 0 0
-35 rmnet1 0x0 10021 1 21215 33 10278 33 21215 33 0 0 0 0 10278 33 0 0 0 0
-36 rmnet1 0x0 10036 0 6310 25 3284 29 6310 25 0 0 0 0 3284 29 0 0 0 0
-37 rmnet1 0x0 10036 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-38 rmnet1 0x0 10047 0 34264 47 3936 34 34264 47 0 0 0 0 3936 34 0 0 0 0
-39 rmnet1 0x0 10047 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-40 rmnet1 0x4e7700000000 10011 0 9187 27 4248 33 9187 27 0 0 0 0 4248 33 0 0 0 0
-41 rmnet1 0x4e7700000000 10011 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-42 rmnet1 0x1000000000000000 10007 0 2109 4 791 4 2109 4 0 0 0 0 791 4 0 0 0 0
-43 rmnet1 0x1000000000000000 10007 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-44 rmnet1 0x1000000400000000 10007 0 9811 22 6286 22 9811 22 0 0 0 0 6286 22 0 0 0 0
-45 rmnet1 0x1000000400000000 10007 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-46 rmnet1 0x1010000000000000 10021 0 164833 426 135392 527 164833 426 0 0 0 0 135392 527 0 0 0 0
-47 rmnet1 0x1010000000000000 10021 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-48 rmnet1 0x1144000400000000 10011 0 10112 18 3334 17 10112 18 0 0 0 0 3334 17 0 0 0 0
-49 rmnet1 0x1144000400000000 10011 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-50 rmnet1 0x1244000400000000 10011 0 1300 3 848 2 1300 3 0 0 0 0 848 2 0 0 0 0
-51 rmnet1 0x1244000400000000 10011 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-52 rmnet1 0x3000000000000000 10007 0 10389 14 1521 12 10389 14 0 0 0 0 1521 12 0 0 0 0
-53 rmnet1 0x3000000000000000 10007 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-54 rmnet1 0x3000000400000000 10007 0 238070 380 93938 404 238070 380 0 0 0 0 93938 404 0 0 0 0
-55 rmnet1 0x3000000400000000 10007 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-56 rmnet1 0x3010000000000000 10021 0 219110 578 227423 676 219110 578 0 0 0 0 227423 676 0 0 0 0
-57 rmnet1 0x3010000000000000 10021 1 742 3 1265 3 742 3 0 0 0 0 1265 3 0 0 0 0
-58 rmnet1 0x3020000000000000 10021 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-59 rmnet1 0x3020000000000000 10021 1 20473 30 9013 30 20473 30 0 0 0 0 9013 30 0 0 0 0
-60 rmnet1 0x3144000400000000 10011 0 43963 92 34414 116 43963 92 0 0 0 0 34414 116 0 0 0 0
-61 rmnet1 0x3144000400000000 10011 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-62 rmnet1 0x3244000400000000 10011 0 3486 8 1520 9 3486 8 0 0 0 0 1520 9 0 0 0 0
-63 rmnet1 0x3244000400000000 10011 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-64 rmnet1 0x7fffff0100000000 10021 0 29102 56 8865 60 29102 56 0 0 0 0 8865 60 0 0 0 0
-65 rmnet1 0x7fffff0100000000 10021 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-66 rmnet1 0x7fffff0300000000 1000 0 995 13 14145 14 995 13 0 0 0 0 14145 14 0 0 0 0
-67 rmnet1 0x7fffff0300000000 1000 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-68 rmnet0 0x0 0 0 4312 49 1288 23 0 0 0 0 4312 49 0 0 0 0 1288 23
-69 rmnet0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-70 rmnet0 0x0 10080 0 22266 30 20976 30 0 0 0 0 22266 30 0 0 0 0 20976 30
-71 rmnet0 0x0 10080 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
diff --git a/core/tests/coretests/src/android/net/LinkAddressTest.java b/core/tests/coretests/src/android/net/LinkAddressTest.java
deleted file mode 100644
index 814ecdd..0000000
--- a/core/tests/coretests/src/android/net/LinkAddressTest.java
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.InterfaceAddress;
-import java.net.NetworkInterface;
-import java.net.SocketException;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-import android.net.LinkAddress;
-import android.os.Parcel;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import static android.system.OsConstants.IFA_F_DEPRECATED;
-import static android.system.OsConstants.IFA_F_PERMANENT;
-import static android.system.OsConstants.IFA_F_TENTATIVE;
-import static android.system.OsConstants.RT_SCOPE_HOST;
-import static android.system.OsConstants.RT_SCOPE_LINK;
-import static android.system.OsConstants.RT_SCOPE_SITE;
-import static android.system.OsConstants.RT_SCOPE_UNIVERSE;
-
-/**
- * Tests for {@link LinkAddress}.
- */
-public class LinkAddressTest extends AndroidTestCase {
-
- private static final String V4 = "192.0.2.1";
- private static final String V6 = "2001:db8::1";
- private static final InetAddress V4_ADDRESS = NetworkUtils.numericToInetAddress(V4);
- private static final InetAddress V6_ADDRESS = NetworkUtils.numericToInetAddress(V6);
-
- public void testConstructors() throws SocketException {
- LinkAddress address;
-
- // Valid addresses work as expected.
- address = new LinkAddress(V4_ADDRESS, 25);
- assertEquals(V4_ADDRESS, address.getAddress());
- assertEquals(25, address.getPrefixLength());
- assertEquals(0, address.getFlags());
- assertEquals(RT_SCOPE_UNIVERSE, address.getScope());
-
- address = new LinkAddress(V6_ADDRESS, 127);
- assertEquals(V6_ADDRESS, address.getAddress());
- assertEquals(127, address.getPrefixLength());
- assertEquals(0, address.getFlags());
- assertEquals(RT_SCOPE_UNIVERSE, address.getScope());
-
- // Nonsensical flags/scopes or combinations thereof are acceptable.
- address = new LinkAddress(V6 + "/64", IFA_F_DEPRECATED | IFA_F_PERMANENT, RT_SCOPE_LINK);
- assertEquals(V6_ADDRESS, address.getAddress());
- assertEquals(64, address.getPrefixLength());
- assertEquals(IFA_F_DEPRECATED | IFA_F_PERMANENT, address.getFlags());
- assertEquals(RT_SCOPE_LINK, address.getScope());
-
- address = new LinkAddress(V4 + "/23", 123, 456);
- assertEquals(V4_ADDRESS, address.getAddress());
- assertEquals(23, address.getPrefixLength());
- assertEquals(123, address.getFlags());
- assertEquals(456, address.getScope());
-
- // InterfaceAddress doesn't have a constructor. Fetch some from an interface.
- List<InterfaceAddress> addrs = NetworkInterface.getByName("lo").getInterfaceAddresses();
-
- // We expect to find 127.0.0.1/8 and ::1/128, in any order.
- LinkAddress ipv4Loopback, ipv6Loopback;
- assertEquals(2, addrs.size());
- if (addrs.get(0).getAddress() instanceof Inet4Address) {
- ipv4Loopback = new LinkAddress(addrs.get(0));
- ipv6Loopback = new LinkAddress(addrs.get(1));
- } else {
- ipv4Loopback = new LinkAddress(addrs.get(1));
- ipv6Loopback = new LinkAddress(addrs.get(0));
- }
-
- assertEquals(NetworkUtils.numericToInetAddress("127.0.0.1"), ipv4Loopback.getAddress());
- assertEquals(8, ipv4Loopback.getPrefixLength());
-
- assertEquals(NetworkUtils.numericToInetAddress("::1"), ipv6Loopback.getAddress());
- assertEquals(128, ipv6Loopback.getPrefixLength());
-
- // Null addresses are rejected.
- try {
- address = new LinkAddress(null, 24);
- fail("Null InetAddress should cause IllegalArgumentException");
- } catch(IllegalArgumentException expected) {}
-
- try {
- address = new LinkAddress((String) null, IFA_F_PERMANENT, RT_SCOPE_UNIVERSE);
- fail("Null string should cause IllegalArgumentException");
- } catch(IllegalArgumentException expected) {}
-
- try {
- address = new LinkAddress((InterfaceAddress) null);
- fail("Null string should cause NullPointerException");
- } catch(NullPointerException expected) {}
-
- // Invalid prefix lengths are rejected.
- try {
- address = new LinkAddress(V4_ADDRESS, -1);
- fail("Negative IPv4 prefix length should cause IllegalArgumentException");
- } catch(IllegalArgumentException expected) {}
-
- try {
- address = new LinkAddress(V6_ADDRESS, -1);
- fail("Negative IPv6 prefix length should cause IllegalArgumentException");
- } catch(IllegalArgumentException expected) {}
-
- try {
- address = new LinkAddress(V4_ADDRESS, 33);
- fail("/33 IPv4 prefix length should cause IllegalArgumentException");
- } catch(IllegalArgumentException expected) {}
-
- try {
- address = new LinkAddress(V4 + "/33", IFA_F_PERMANENT, RT_SCOPE_UNIVERSE);
- fail("/33 IPv4 prefix length should cause IllegalArgumentException");
- } catch(IllegalArgumentException expected) {}
-
-
- try {
- address = new LinkAddress(V6_ADDRESS, 129, IFA_F_PERMANENT, RT_SCOPE_UNIVERSE);
- fail("/129 IPv6 prefix length should cause IllegalArgumentException");
- } catch(IllegalArgumentException expected) {}
-
- try {
- address = new LinkAddress(V6 + "/129", IFA_F_PERMANENT, RT_SCOPE_UNIVERSE);
- fail("/129 IPv6 prefix length should cause IllegalArgumentException");
- } catch(IllegalArgumentException expected) {}
-
- // Multicast addresses are rejected.
- try {
- address = new LinkAddress("224.0.0.2/32");
- fail("IPv4 multicast address should cause IllegalArgumentException");
- } catch(IllegalArgumentException expected) {}
-
- try {
- address = new LinkAddress("ff02::1/128");
- fail("IPv6 multicast address should cause IllegalArgumentException");
- } catch(IllegalArgumentException expected) {}
- }
-
- public void testAddressScopes() {
- assertEquals(RT_SCOPE_HOST, new LinkAddress("::/128").getScope());
- assertEquals(RT_SCOPE_HOST, new LinkAddress("0.0.0.0/32").getScope());
-
- assertEquals(RT_SCOPE_LINK, new LinkAddress("::1/128").getScope());
- assertEquals(RT_SCOPE_LINK, new LinkAddress("127.0.0.5/8").getScope());
- assertEquals(RT_SCOPE_LINK, new LinkAddress("fe80::ace:d00d/64").getScope());
- assertEquals(RT_SCOPE_LINK, new LinkAddress("169.254.5.12/16").getScope());
-
- assertEquals(RT_SCOPE_SITE, new LinkAddress("fec0::dead/64").getScope());
-
- assertEquals(RT_SCOPE_UNIVERSE, new LinkAddress("10.1.2.3/21").getScope());
- assertEquals(RT_SCOPE_UNIVERSE, new LinkAddress("192.0.2.1/25").getScope());
- assertEquals(RT_SCOPE_UNIVERSE, new LinkAddress("2001:db8::/64").getScope());
- assertEquals(RT_SCOPE_UNIVERSE, new LinkAddress("5000::/127").getScope());
- }
-
- private void assertIsSameAddressAs(LinkAddress l1, LinkAddress l2) {
- assertTrue(l1 + " unexpectedly does not have same address as " + l2,
- l1.isSameAddressAs(l2));
- assertTrue(l2 + " unexpectedly does not have same address as " + l1,
- l2.isSameAddressAs(l1));
- }
-
- private void assertIsNotSameAddressAs(LinkAddress l1, LinkAddress l2) {
- assertFalse(l1 + " unexpectedly has same address as " + l2,
- l1.isSameAddressAs(l2));
- assertFalse(l2 + " unexpectedly has same address as " + l1,
- l1.isSameAddressAs(l2));
- }
-
- private void assertLinkAddressesEqual(LinkAddress l1, LinkAddress l2) {
- assertTrue(l1 + " unexpectedly not equal to " + l2, l1.equals(l2));
- assertTrue(l2 + " unexpectedly not equal to " + l1, l2.equals(l1));
- assertEquals(l1.hashCode(), l2.hashCode());
- }
-
- private void assertLinkAddressesNotEqual(LinkAddress l1, LinkAddress l2) {
- assertFalse(l1 + " unexpectedly equal to " + l2, l1.equals(l2));
- assertFalse(l2 + " unexpectedly equal to " + l1, l2.equals(l1));
- }
-
- public void testEqualsAndSameAddressAs() {
- LinkAddress l1, l2, l3;
-
- l1 = new LinkAddress("2001:db8::1/64");
- l2 = new LinkAddress("2001:db8::1/64");
- assertLinkAddressesEqual(l1, l2);
- assertIsSameAddressAs(l1, l2);
-
- l2 = new LinkAddress("2001:db8::1/65");
- assertLinkAddressesNotEqual(l1, l2);
- assertIsNotSameAddressAs(l1, l2);
-
- l2 = new LinkAddress("2001:db8::2/64");
- assertLinkAddressesNotEqual(l1, l2);
- assertIsNotSameAddressAs(l1, l2);
-
-
- l1 = new LinkAddress("192.0.2.1/24");
- l2 = new LinkAddress("192.0.2.1/24");
- assertLinkAddressesEqual(l1, l2);
- assertIsSameAddressAs(l1, l2);
-
- l2 = new LinkAddress("192.0.2.1/23");
- assertLinkAddressesNotEqual(l1, l2);
- assertIsNotSameAddressAs(l1, l2);
-
- l2 = new LinkAddress("192.0.2.2/24");
- assertLinkAddressesNotEqual(l1, l2);
- assertIsNotSameAddressAs(l1, l2);
-
-
- // Check equals() and isSameAddressAs() on identical addresses with different flags.
- l1 = new LinkAddress(V6_ADDRESS, 64);
- l2 = new LinkAddress(V6_ADDRESS, 64, 0, RT_SCOPE_UNIVERSE);
- assertLinkAddressesEqual(l1, l2);
- assertIsSameAddressAs(l1, l2);
-
- l2 = new LinkAddress(V6_ADDRESS, 64, IFA_F_DEPRECATED, RT_SCOPE_UNIVERSE);
- assertLinkAddressesNotEqual(l1, l2);
- assertIsSameAddressAs(l1, l2);
-
- // Check equals() and isSameAddressAs() on identical addresses with different scope.
- l1 = new LinkAddress(V4_ADDRESS, 24);
- l2 = new LinkAddress(V4_ADDRESS, 24, 0, RT_SCOPE_UNIVERSE);
- assertLinkAddressesEqual(l1, l2);
- assertIsSameAddressAs(l1, l2);
-
- l2 = new LinkAddress(V4_ADDRESS, 24, 0, RT_SCOPE_HOST);
- assertLinkAddressesNotEqual(l1, l2);
- assertIsSameAddressAs(l1, l2);
-
- // Addresses with the same start or end bytes aren't equal between families.
- l1 = new LinkAddress("32.1.13.184/24");
- l2 = new LinkAddress("2001:db8::1/24");
- l3 = new LinkAddress("::2001:db8/24");
-
- byte[] ipv4Bytes = l1.getAddress().getAddress();
- byte[] l2FirstIPv6Bytes = Arrays.copyOf(l2.getAddress().getAddress(), 4);
- byte[] l3LastIPv6Bytes = Arrays.copyOfRange(l3.getAddress().getAddress(), 12, 16);
- assertTrue(Arrays.equals(ipv4Bytes, l2FirstIPv6Bytes));
- assertTrue(Arrays.equals(ipv4Bytes, l3LastIPv6Bytes));
-
- assertLinkAddressesNotEqual(l1, l2);
- assertIsNotSameAddressAs(l1, l2);
-
- assertLinkAddressesNotEqual(l1, l3);
- assertIsNotSameAddressAs(l1, l3);
-
- // Because we use InetAddress, an IPv4 address is equal to its IPv4-mapped address.
- // TODO: Investigate fixing this.
- String addressString = V4 + "/24";
- l1 = new LinkAddress(addressString);
- l2 = new LinkAddress("::ffff:" + addressString);
- assertLinkAddressesEqual(l1, l2);
- assertIsSameAddressAs(l1, l2);
- }
-
- public void testHashCode() {
- LinkAddress l;
-
- l = new LinkAddress(V4_ADDRESS, 23);
- assertEquals(-982787, l.hashCode());
-
- l = new LinkAddress(V4_ADDRESS, 23, 0, RT_SCOPE_HOST);
- assertEquals(-971865, l.hashCode());
-
- l = new LinkAddress(V4_ADDRESS, 27);
- assertEquals(-982743, l.hashCode());
-
- l = new LinkAddress(V6_ADDRESS, 64);
- assertEquals(1076522926, l.hashCode());
-
- l = new LinkAddress(V6_ADDRESS, 128);
- assertEquals(1076523630, l.hashCode());
-
- l = new LinkAddress(V6_ADDRESS, 128, IFA_F_TENTATIVE, RT_SCOPE_UNIVERSE);
- assertEquals(1076524846, l.hashCode());
- }
-
- private LinkAddress passThroughParcel(LinkAddress l) {
- Parcel p = Parcel.obtain();
- LinkAddress l2 = null;
- try {
- l.writeToParcel(p, 0);
- p.setDataPosition(0);
- l2 = LinkAddress.CREATOR.createFromParcel(p);
- } finally {
- p.recycle();
- }
- assertNotNull(l2);
- return l2;
- }
-
- private void assertParcelingIsLossless(LinkAddress l) {
- LinkAddress l2 = passThroughParcel(l);
- assertEquals(l, l2);
- }
-
- public void testParceling() {
- LinkAddress l;
-
- l = new LinkAddress(V6_ADDRESS, 64, 123, 456);
- assertParcelingIsLossless(l);
-
- l = new LinkAddress(V4 + "/28", IFA_F_PERMANENT, RT_SCOPE_LINK);
- assertParcelingIsLossless(l);
- }
-}
diff --git a/core/tests/coretests/src/android/net/LinkPropertiesTest.java b/core/tests/coretests/src/android/net/LinkPropertiesTest.java
deleted file mode 100644
index e649baa..0000000
--- a/core/tests/coretests/src/android/net/LinkPropertiesTest.java
+++ /dev/null
@@ -1,440 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.net.LinkProperties;
-import android.net.RouteInfo;
-import android.system.OsConstants;
-import android.test.suitebuilder.annotation.SmallTest;
-import junit.framework.TestCase;
-
-import java.net.InetAddress;
-import java.util.ArrayList;
-
-public class LinkPropertiesTest extends TestCase {
- private static InetAddress ADDRV4 = NetworkUtils.numericToInetAddress("75.208.6.1");
- private static InetAddress ADDRV6 = NetworkUtils.numericToInetAddress(
- "2001:0db8:85a3:0000:0000:8a2e:0370:7334");
- private static InetAddress DNS1 = NetworkUtils.numericToInetAddress("75.208.7.1");
- private static InetAddress DNS2 = NetworkUtils.numericToInetAddress("69.78.7.1");
- private static InetAddress GATEWAY1 = NetworkUtils.numericToInetAddress("75.208.8.1");
- private static InetAddress GATEWAY2 = NetworkUtils.numericToInetAddress("69.78.8.1");
- private static String NAME = "qmi0";
- private static int MTU = 1500;
-
- private static LinkAddress LINKADDRV4 = new LinkAddress(ADDRV4, 32);
- private static LinkAddress LINKADDRV6 = new LinkAddress(ADDRV6, 128);
-
- public void assertLinkPropertiesEqual(LinkProperties source, LinkProperties target) {
- // Check implementation of equals(), element by element.
- assertTrue(source.isIdenticalInterfaceName(target));
- assertTrue(target.isIdenticalInterfaceName(source));
-
- assertTrue(source.isIdenticalAddresses(target));
- assertTrue(target.isIdenticalAddresses(source));
-
- assertTrue(source.isIdenticalDnses(target));
- assertTrue(target.isIdenticalDnses(source));
-
- assertTrue(source.isIdenticalRoutes(target));
- assertTrue(target.isIdenticalRoutes(source));
-
- assertTrue(source.isIdenticalHttpProxy(target));
- assertTrue(target.isIdenticalHttpProxy(source));
-
- assertTrue(source.isIdenticalStackedLinks(target));
- assertTrue(target.isIdenticalStackedLinks(source));
-
- assertTrue(source.isIdenticalMtu(target));
- assertTrue(target.isIdenticalMtu(source));
-
- // Check result of equals().
- assertTrue(source.equals(target));
- assertTrue(target.equals(source));
-
- // Check hashCode.
- assertEquals(source.hashCode(), target.hashCode());
- }
-
- @SmallTest
- public void testEqualsNull() {
- LinkProperties source = new LinkProperties();
- LinkProperties target = new LinkProperties();
-
- assertFalse(source == target);
- assertLinkPropertiesEqual(source, target);
- }
-
- @SmallTest
- public void testEqualsSameOrder() {
- try {
- LinkProperties source = new LinkProperties();
- source.setInterfaceName(NAME);
- // set 2 link addresses
- source.addLinkAddress(LINKADDRV4);
- source.addLinkAddress(LINKADDRV6);
- // set 2 dnses
- source.addDnsServer(DNS1);
- source.addDnsServer(DNS2);
- // set 2 gateways
- source.addRoute(new RouteInfo(GATEWAY1));
- source.addRoute(new RouteInfo(GATEWAY2));
- source.setMtu(MTU);
-
- LinkProperties target = new LinkProperties();
-
- // All fields are same
- target.setInterfaceName(NAME);
- target.addLinkAddress(LINKADDRV4);
- target.addLinkAddress(LINKADDRV6);
- target.addDnsServer(DNS1);
- target.addDnsServer(DNS2);
- target.addRoute(new RouteInfo(GATEWAY1));
- target.addRoute(new RouteInfo(GATEWAY2));
- target.setMtu(MTU);
-
- assertLinkPropertiesEqual(source, target);
-
- target.clear();
- // change Interface Name
- target.setInterfaceName("qmi1");
- target.addLinkAddress(LINKADDRV4);
- target.addLinkAddress(LINKADDRV6);
- target.addDnsServer(DNS1);
- target.addDnsServer(DNS2);
- target.addRoute(new RouteInfo(GATEWAY1));
- target.addRoute(new RouteInfo(GATEWAY2));
- target.setMtu(MTU);
- assertFalse(source.equals(target));
-
- target.clear();
- target.setInterfaceName(NAME);
- // change link addresses
- target.addLinkAddress(new LinkAddress(
- NetworkUtils.numericToInetAddress("75.208.6.2"), 32));
- target.addLinkAddress(LINKADDRV6);
- target.addDnsServer(DNS1);
- target.addDnsServer(DNS2);
- target.addRoute(new RouteInfo(GATEWAY1));
- target.addRoute(new RouteInfo(GATEWAY2));
- target.setMtu(MTU);
- assertFalse(source.equals(target));
-
- target.clear();
- target.setInterfaceName(NAME);
- target.addLinkAddress(LINKADDRV4);
- target.addLinkAddress(LINKADDRV6);
- // change dnses
- target.addDnsServer(NetworkUtils.numericToInetAddress("75.208.7.2"));
- target.addDnsServer(DNS2);
- target.addRoute(new RouteInfo(GATEWAY1));
- target.addRoute(new RouteInfo(GATEWAY2));
- target.setMtu(MTU);
- assertFalse(source.equals(target));
-
- target.clear();
- target.setInterfaceName(NAME);
- target.addLinkAddress(LINKADDRV4);
- target.addLinkAddress(LINKADDRV6);
- target.addDnsServer(DNS1);
- target.addDnsServer(DNS2);
- // change gateway
- target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress("75.208.8.2")));
- target.addRoute(new RouteInfo(GATEWAY2));
- target.setMtu(MTU);
- assertFalse(source.equals(target));
-
- target.clear();
- target.setInterfaceName(NAME);
- target.addLinkAddress(LINKADDRV4);
- target.addLinkAddress(LINKADDRV6);
- target.addDnsServer(DNS1);
- target.addDnsServer(DNS2);
- target.addRoute(new RouteInfo(GATEWAY1));
- target.addRoute(new RouteInfo(GATEWAY2));
- // change mtu
- target.setMtu(1440);
- assertFalse(source.equals(target));
-
- } catch (Exception e) {
- throw new RuntimeException(e.toString());
- //fail();
- }
- }
-
- @SmallTest
- public void testEqualsDifferentOrder() {
- try {
- LinkProperties source = new LinkProperties();
- source.setInterfaceName(NAME);
- // set 2 link addresses
- source.addLinkAddress(LINKADDRV4);
- source.addLinkAddress(LINKADDRV6);
- // set 2 dnses
- source.addDnsServer(DNS1);
- source.addDnsServer(DNS2);
- // set 2 gateways
- source.addRoute(new RouteInfo(GATEWAY1));
- source.addRoute(new RouteInfo(GATEWAY2));
- source.setMtu(MTU);
-
- LinkProperties target = new LinkProperties();
- // Exchange order
- target.setInterfaceName(NAME);
- target.addLinkAddress(LINKADDRV6);
- target.addLinkAddress(LINKADDRV4);
- target.addDnsServer(DNS2);
- target.addDnsServer(DNS1);
- target.addRoute(new RouteInfo(GATEWAY2));
- target.addRoute(new RouteInfo(GATEWAY1));
- target.setMtu(MTU);
-
- assertLinkPropertiesEqual(source, target);
- } catch (Exception e) {
- fail();
- }
- }
-
- @SmallTest
- public void testEqualsDuplicated() {
- try {
- LinkProperties source = new LinkProperties();
- // set 3 link addresses, eg, [A, A, B]
- source.addLinkAddress(LINKADDRV4);
- source.addLinkAddress(LINKADDRV4);
- source.addLinkAddress(LINKADDRV6);
-
- LinkProperties target = new LinkProperties();
- // set 3 link addresses, eg, [A, B, B]
- target.addLinkAddress(LINKADDRV4);
- target.addLinkAddress(LINKADDRV6);
- target.addLinkAddress(LINKADDRV6);
-
- assertLinkPropertiesEqual(source, target);
- } catch (Exception e) {
- fail();
- }
- }
-
- private void assertAllRoutesHaveInterface(String iface, LinkProperties lp) {
- for (RouteInfo r : lp.getRoutes()) {
- assertEquals(iface, r.getInterface());
- }
- }
-
- @SmallTest
- public void testRouteInterfaces() {
- LinkAddress prefix = new LinkAddress(
- NetworkUtils.numericToInetAddress("2001:db8::"), 32);
- InetAddress address = ADDRV6;
-
- // Add a route with no interface to a LinkProperties with no interface. No errors.
- LinkProperties lp = new LinkProperties();
- RouteInfo r = new RouteInfo(prefix, address, null);
- lp.addRoute(r);
- assertEquals(1, lp.getRoutes().size());
- assertAllRoutesHaveInterface(null, lp);
-
- // Add a route with an interface. Except an exception.
- r = new RouteInfo(prefix, address, "wlan0");
- try {
- lp.addRoute(r);
- fail("Adding wlan0 route to LP with no interface, expect exception");
- } catch (IllegalArgumentException expected) {}
-
- // Change the interface name. All the routes should change their interface name too.
- lp.setInterfaceName("rmnet0");
- assertAllRoutesHaveInterface("rmnet0", lp);
-
- // Now add a route with the wrong interface. This causes an exception too.
- try {
- lp.addRoute(r);
- fail("Adding wlan0 route to rmnet0 LP, expect exception");
- } catch (IllegalArgumentException expected) {}
-
- // If the interface name matches, the route is added.
- lp.setInterfaceName("wlan0");
- lp.addRoute(r);
- assertEquals(2, lp.getRoutes().size());
- assertAllRoutesHaveInterface("wlan0", lp);
-
- // Routes with null interfaces are converted to wlan0.
- r = RouteInfo.makeHostRoute(ADDRV6, null);
- lp.addRoute(r);
- assertEquals(3, lp.getRoutes().size());
- assertAllRoutesHaveInterface("wlan0", lp);
-
- // Check comparisons work.
- LinkProperties lp2 = new LinkProperties(lp);
- assertAllRoutesHaveInterface("wlan0", lp);
- assertEquals(0, lp.compareAllRoutes(lp2).added.size());
- assertEquals(0, lp.compareAllRoutes(lp2).removed.size());
-
- lp2.setInterfaceName("p2p0");
- assertAllRoutesHaveInterface("p2p0", lp2);
- assertEquals(3, lp.compareAllRoutes(lp2).added.size());
- assertEquals(3, lp.compareAllRoutes(lp2).removed.size());
- }
-
- @SmallTest
- public void testStackedInterfaces() {
- LinkProperties rmnet0 = new LinkProperties();
- rmnet0.setInterfaceName("rmnet0");
- rmnet0.addLinkAddress(LINKADDRV6);
-
- LinkProperties clat4 = new LinkProperties();
- clat4.setInterfaceName("clat4");
- clat4.addLinkAddress(LINKADDRV4);
-
- assertEquals(0, rmnet0.getStackedLinks().size());
- assertEquals(1, rmnet0.getAddresses().size());
- assertEquals(1, rmnet0.getLinkAddresses().size());
- assertEquals(1, rmnet0.getAllAddresses().size());
- assertEquals(1, rmnet0.getAllLinkAddresses().size());
-
- rmnet0.addStackedLink(clat4);
- assertEquals(1, rmnet0.getStackedLinks().size());
- assertEquals(1, rmnet0.getAddresses().size());
- assertEquals(1, rmnet0.getLinkAddresses().size());
- assertEquals(2, rmnet0.getAllAddresses().size());
- assertEquals(2, rmnet0.getAllLinkAddresses().size());
-
- rmnet0.addStackedLink(clat4);
- assertEquals(1, rmnet0.getStackedLinks().size());
- assertEquals(1, rmnet0.getAddresses().size());
- assertEquals(1, rmnet0.getLinkAddresses().size());
- assertEquals(2, rmnet0.getAllAddresses().size());
- assertEquals(2, rmnet0.getAllLinkAddresses().size());
-
- assertEquals(0, clat4.getStackedLinks().size());
-
- // Modify an item in the returned collection to see what happens.
- for (LinkProperties link : rmnet0.getStackedLinks()) {
- if (link.getInterfaceName().equals("clat4")) {
- link.setInterfaceName("newname");
- }
- }
- for (LinkProperties link : rmnet0.getStackedLinks()) {
- assertFalse("newname".equals(link.getInterfaceName()));
- }
-
- assertTrue(rmnet0.removeStackedLink(clat4));
- assertEquals(0, rmnet0.getStackedLinks().size());
- assertEquals(1, rmnet0.getAddresses().size());
- assertEquals(1, rmnet0.getLinkAddresses().size());
- assertEquals(1, rmnet0.getAllAddresses().size());
- assertEquals(1, rmnet0.getAllLinkAddresses().size());
-
- assertFalse(rmnet0.removeStackedLink(clat4));
- }
-
- private LinkAddress getFirstLinkAddress(LinkProperties lp) {
- return lp.getLinkAddresses().iterator().next();
- }
-
- @SmallTest
- public void testAddressMethods() {
- LinkProperties lp = new LinkProperties();
-
- // No addresses.
- assertFalse(lp.hasIPv4Address());
- assertFalse(lp.hasIPv6Address());
-
- // Addresses on stacked links don't count.
- LinkProperties stacked = new LinkProperties();
- stacked.setInterfaceName("stacked");
- lp.addStackedLink(stacked);
- stacked.addLinkAddress(LINKADDRV4);
- stacked.addLinkAddress(LINKADDRV6);
- assertTrue(stacked.hasIPv4Address());
- assertTrue(stacked.hasIPv6Address());
- assertFalse(lp.hasIPv4Address());
- assertFalse(lp.hasIPv6Address());
- lp.removeStackedLink(stacked);
- assertFalse(lp.hasIPv4Address());
- assertFalse(lp.hasIPv6Address());
-
- // Addresses on the base link.
- // Check the return values of hasIPvXAddress and ensure the add/remove methods return true
- // iff something changes.
- assertEquals(0, lp.getLinkAddresses().size());
- assertTrue(lp.addLinkAddress(LINKADDRV6));
- assertEquals(1, lp.getLinkAddresses().size());
- assertFalse(lp.hasIPv4Address());
- assertTrue(lp.hasIPv6Address());
-
- assertTrue(lp.removeLinkAddress(LINKADDRV6));
- assertEquals(0, lp.getLinkAddresses().size());
- assertTrue(lp.addLinkAddress(LINKADDRV4));
- assertEquals(1, lp.getLinkAddresses().size());
- assertTrue(lp.hasIPv4Address());
- assertFalse(lp.hasIPv6Address());
-
- assertTrue(lp.addLinkAddress(LINKADDRV6));
- assertEquals(2, lp.getLinkAddresses().size());
- assertTrue(lp.hasIPv4Address());
- assertTrue(lp.hasIPv6Address());
-
- // Adding an address twice has no effect.
- // Removing an address that's not present has no effect.
- assertFalse(lp.addLinkAddress(LINKADDRV4));
- assertEquals(2, lp.getLinkAddresses().size());
- assertTrue(lp.hasIPv4Address());
- assertTrue(lp.removeLinkAddress(LINKADDRV4));
- assertEquals(1, lp.getLinkAddresses().size());
- assertFalse(lp.hasIPv4Address());
- assertFalse(lp.removeLinkAddress(LINKADDRV4));
- assertEquals(1, lp.getLinkAddresses().size());
-
- // Adding an address that's already present but with different properties causes the
- // existing address to be updated and returns true.
- // Start with only LINKADDRV6.
- assertEquals(1, lp.getLinkAddresses().size());
- assertEquals(LINKADDRV6, getFirstLinkAddress(lp));
-
- // Create a LinkAddress object for the same address, but with different flags.
- LinkAddress deprecated = new LinkAddress(ADDRV6, 128,
- OsConstants.IFA_F_DEPRECATED, OsConstants.RT_SCOPE_UNIVERSE);
- assertTrue(deprecated.isSameAddressAs(LINKADDRV6));
- assertFalse(deprecated.equals(LINKADDRV6));
-
- // Check that adding it updates the existing address instead of adding a new one.
- assertTrue(lp.addLinkAddress(deprecated));
- assertEquals(1, lp.getLinkAddresses().size());
- assertEquals(deprecated, getFirstLinkAddress(lp));
- assertFalse(LINKADDRV6.equals(getFirstLinkAddress(lp)));
-
- // Removing LINKADDRV6 removes deprecated, because removing addresses ignores properties.
- assertTrue(lp.removeLinkAddress(LINKADDRV6));
- assertEquals(0, lp.getLinkAddresses().size());
- }
-
- @SmallTest
- public void testSetLinkAddresses() {
- LinkProperties lp = new LinkProperties();
- lp.addLinkAddress(LINKADDRV4);
- lp.addLinkAddress(LINKADDRV6);
-
- LinkProperties lp2 = new LinkProperties();
- lp2.addLinkAddress(LINKADDRV6);
-
- assertFalse(lp.equals(lp2));
-
- lp2.setLinkAddresses(lp.getLinkAddresses());
- assertTrue(lp.equals(lp));
- }
-}
diff --git a/core/tests/coretests/src/android/net/NetworkStatsHistoryTest.java b/core/tests/coretests/src/android/net/NetworkStatsHistoryTest.java
deleted file mode 100644
index b181122..0000000
--- a/core/tests/coretests/src/android/net/NetworkStatsHistoryTest.java
+++ /dev/null
@@ -1,521 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import static android.net.NetworkStatsHistory.FIELD_ALL;
-import static android.net.NetworkStatsHistory.FIELD_OPERATIONS;
-import static android.net.NetworkStatsHistory.FIELD_RX_BYTES;
-import static android.net.NetworkStatsHistory.FIELD_RX_PACKETS;
-import static android.net.NetworkStatsHistory.FIELD_TX_BYTES;
-import static android.net.NetworkStatsHistory.DataStreamUtils.readVarLong;
-import static android.net.NetworkStatsHistory.DataStreamUtils.writeVarLong;
-import static android.net.NetworkStatsHistory.Entry.UNKNOWN;
-import static android.net.TrafficStats.GB_IN_BYTES;
-import static android.net.TrafficStats.MB_IN_BYTES;
-import static android.text.format.DateUtils.DAY_IN_MILLIS;
-import static android.text.format.DateUtils.HOUR_IN_MILLIS;
-import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
-import static android.text.format.DateUtils.SECOND_IN_MILLIS;
-import static android.text.format.DateUtils.WEEK_IN_MILLIS;
-import static android.text.format.DateUtils.YEAR_IN_MILLIS;
-
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.test.suitebuilder.annotation.Suppress;
-import android.util.Log;
-
-import com.android.frameworks.coretests.R;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.util.Random;
-
-@SmallTest
-public class NetworkStatsHistoryTest extends AndroidTestCase {
- private static final String TAG = "NetworkStatsHistoryTest";
-
- private static final long TEST_START = 1194220800000L;
-
- private NetworkStatsHistory stats;
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- if (stats != null) {
- assertConsistent(stats);
- }
- }
-
- public void testReadOriginalVersion() throws Exception {
- final DataInputStream in = new DataInputStream(
- getContext().getResources().openRawResource(R.raw.history_v1));
-
- NetworkStatsHistory.Entry entry = null;
- try {
- final NetworkStatsHistory history = new NetworkStatsHistory(in);
- assertEquals(15 * SECOND_IN_MILLIS, history.getBucketDuration());
-
- entry = history.getValues(0, entry);
- assertEquals(29143L, entry.rxBytes);
- assertEquals(6223L, entry.txBytes);
-
- entry = history.getValues(history.size() - 1, entry);
- assertEquals(1476L, entry.rxBytes);
- assertEquals(838L, entry.txBytes);
-
- entry = history.getValues(Long.MIN_VALUE, Long.MAX_VALUE, entry);
- assertEquals(332401L, entry.rxBytes);
- assertEquals(64314L, entry.txBytes);
-
- } finally {
- in.close();
- }
- }
-
- public void testRecordSingleBucket() throws Exception {
- final long BUCKET_SIZE = HOUR_IN_MILLIS;
- stats = new NetworkStatsHistory(BUCKET_SIZE);
-
- // record data into narrow window to get single bucket
- stats.recordData(TEST_START, TEST_START + SECOND_IN_MILLIS,
- new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 2L));
-
- assertEquals(1, stats.size());
- assertValues(stats, 0, SECOND_IN_MILLIS, 1024L, 10L, 2048L, 20L, 2L);
- }
-
- public void testRecordEqualBuckets() throws Exception {
- final long bucketDuration = HOUR_IN_MILLIS;
- stats = new NetworkStatsHistory(bucketDuration);
-
- // split equally across two buckets
- final long recordStart = TEST_START + (bucketDuration / 2);
- stats.recordData(recordStart, recordStart + bucketDuration,
- new NetworkStats.Entry(1024L, 10L, 128L, 2L, 2L));
-
- assertEquals(2, stats.size());
- assertValues(stats, 0, HOUR_IN_MILLIS / 2, 512L, 5L, 64L, 1L, 1L);
- assertValues(stats, 1, HOUR_IN_MILLIS / 2, 512L, 5L, 64L, 1L, 1L);
- }
-
- public void testRecordTouchingBuckets() throws Exception {
- final long BUCKET_SIZE = 15 * MINUTE_IN_MILLIS;
- stats = new NetworkStatsHistory(BUCKET_SIZE);
-
- // split almost completely into middle bucket, but with a few minutes
- // overlap into neighboring buckets. total record is 20 minutes.
- final long recordStart = (TEST_START + BUCKET_SIZE) - MINUTE_IN_MILLIS;
- final long recordEnd = (TEST_START + (BUCKET_SIZE * 2)) + (MINUTE_IN_MILLIS * 4);
- stats.recordData(recordStart, recordEnd,
- new NetworkStats.Entry(1000L, 2000L, 5000L, 10000L, 100L));
-
- assertEquals(3, stats.size());
- // first bucket should have (1/20 of value)
- assertValues(stats, 0, MINUTE_IN_MILLIS, 50L, 100L, 250L, 500L, 5L);
- // second bucket should have (15/20 of value)
- assertValues(stats, 1, 15 * MINUTE_IN_MILLIS, 750L, 1500L, 3750L, 7500L, 75L);
- // final bucket should have (4/20 of value)
- assertValues(stats, 2, 4 * MINUTE_IN_MILLIS, 200L, 400L, 1000L, 2000L, 20L);
- }
-
- public void testRecordGapBuckets() throws Exception {
- final long BUCKET_SIZE = HOUR_IN_MILLIS;
- stats = new NetworkStatsHistory(BUCKET_SIZE);
-
- // record some data today and next week with large gap
- final long firstStart = TEST_START;
- final long lastStart = TEST_START + WEEK_IN_MILLIS;
- stats.recordData(firstStart, firstStart + SECOND_IN_MILLIS,
- new NetworkStats.Entry(128L, 2L, 256L, 4L, 1L));
- stats.recordData(lastStart, lastStart + SECOND_IN_MILLIS,
- new NetworkStats.Entry(64L, 1L, 512L, 8L, 2L));
-
- // we should have two buckets, far apart from each other
- assertEquals(2, stats.size());
- assertValues(stats, 0, SECOND_IN_MILLIS, 128L, 2L, 256L, 4L, 1L);
- assertValues(stats, 1, SECOND_IN_MILLIS, 64L, 1L, 512L, 8L, 2L);
-
- // now record something in middle, spread across two buckets
- final long middleStart = TEST_START + DAY_IN_MILLIS;
- final long middleEnd = middleStart + (HOUR_IN_MILLIS * 2);
- stats.recordData(middleStart, middleEnd,
- new NetworkStats.Entry(2048L, 4L, 2048L, 4L, 2L));
-
- // now should have four buckets, with new record in middle two buckets
- assertEquals(4, stats.size());
- assertValues(stats, 0, SECOND_IN_MILLIS, 128L, 2L, 256L, 4L, 1L);
- assertValues(stats, 1, HOUR_IN_MILLIS, 1024L, 2L, 1024L, 2L, 1L);
- assertValues(stats, 2, HOUR_IN_MILLIS, 1024L, 2L, 1024L, 2L, 1L);
- assertValues(stats, 3, SECOND_IN_MILLIS, 64L, 1L, 512L, 8L, 2L);
- }
-
- public void testRecordOverlapBuckets() throws Exception {
- final long BUCKET_SIZE = HOUR_IN_MILLIS;
- stats = new NetworkStatsHistory(BUCKET_SIZE);
-
- // record some data in one bucket, and another overlapping buckets
- stats.recordData(TEST_START, TEST_START + SECOND_IN_MILLIS,
- new NetworkStats.Entry(256L, 2L, 256L, 2L, 1L));
- final long midStart = TEST_START + (HOUR_IN_MILLIS / 2);
- stats.recordData(midStart, midStart + HOUR_IN_MILLIS,
- new NetworkStats.Entry(1024L, 10L, 1024L, 10L, 10L));
-
- // should have two buckets, with some data mixed together
- assertEquals(2, stats.size());
- assertValues(stats, 0, SECOND_IN_MILLIS + (HOUR_IN_MILLIS / 2), 768L, 7L, 768L, 7L, 6L);
- assertValues(stats, 1, (HOUR_IN_MILLIS / 2), 512L, 5L, 512L, 5L, 5L);
- }
-
- public void testRecordEntireGapIdentical() throws Exception {
- // first, create two separate histories far apart
- final NetworkStatsHistory stats1 = new NetworkStatsHistory(HOUR_IN_MILLIS);
- stats1.recordData(TEST_START, TEST_START + 2 * HOUR_IN_MILLIS, 2000L, 1000L);
-
- final long TEST_START_2 = TEST_START + DAY_IN_MILLIS;
- final NetworkStatsHistory stats2 = new NetworkStatsHistory(HOUR_IN_MILLIS);
- stats2.recordData(TEST_START_2, TEST_START_2 + 2 * HOUR_IN_MILLIS, 1000L, 500L);
-
- // combine together with identical bucket size
- stats = new NetworkStatsHistory(HOUR_IN_MILLIS);
- stats.recordEntireHistory(stats1);
- stats.recordEntireHistory(stats2);
-
- // first verify that totals match up
- assertValues(stats, TEST_START - WEEK_IN_MILLIS, TEST_START + WEEK_IN_MILLIS, 3000L, 1500L);
-
- // now inspect internal buckets
- assertValues(stats, 0, 1000L, 500L);
- assertValues(stats, 1, 1000L, 500L);
- assertValues(stats, 2, 500L, 250L);
- assertValues(stats, 3, 500L, 250L);
- }
-
- public void testRecordEntireOverlapVaryingBuckets() throws Exception {
- // create history just over hour bucket boundary
- final NetworkStatsHistory stats1 = new NetworkStatsHistory(HOUR_IN_MILLIS);
- stats1.recordData(TEST_START, TEST_START + MINUTE_IN_MILLIS * 60, 600L, 600L);
-
- final long TEST_START_2 = TEST_START + MINUTE_IN_MILLIS;
- final NetworkStatsHistory stats2 = new NetworkStatsHistory(MINUTE_IN_MILLIS);
- stats2.recordData(TEST_START_2, TEST_START_2 + MINUTE_IN_MILLIS * 5, 50L, 50L);
-
- // combine together with minute bucket size
- stats = new NetworkStatsHistory(MINUTE_IN_MILLIS);
- stats.recordEntireHistory(stats1);
- stats.recordEntireHistory(stats2);
-
- // first verify that totals match up
- assertValues(stats, TEST_START - WEEK_IN_MILLIS, TEST_START + WEEK_IN_MILLIS, 650L, 650L);
-
- // now inspect internal buckets
- assertValues(stats, 0, 10L, 10L);
- assertValues(stats, 1, 20L, 20L);
- assertValues(stats, 2, 20L, 20L);
- assertValues(stats, 3, 20L, 20L);
- assertValues(stats, 4, 20L, 20L);
- assertValues(stats, 5, 20L, 20L);
- assertValues(stats, 6, 10L, 10L);
-
- // now combine using 15min buckets
- stats = new NetworkStatsHistory(HOUR_IN_MILLIS / 4);
- stats.recordEntireHistory(stats1);
- stats.recordEntireHistory(stats2);
-
- // first verify that totals match up
- assertValues(stats, TEST_START - WEEK_IN_MILLIS, TEST_START + WEEK_IN_MILLIS, 650L, 650L);
-
- // and inspect buckets
- assertValues(stats, 0, 200L, 200L);
- assertValues(stats, 1, 150L, 150L);
- assertValues(stats, 2, 150L, 150L);
- assertValues(stats, 3, 150L, 150L);
- }
-
- public void testRemove() throws Exception {
- stats = new NetworkStatsHistory(HOUR_IN_MILLIS);
-
- // record some data across 24 buckets
- stats.recordData(TEST_START, TEST_START + DAY_IN_MILLIS, 24L, 24L);
- assertEquals(24, stats.size());
-
- // try removing invalid data; should be no change
- stats.removeBucketsBefore(0 - DAY_IN_MILLIS);
- assertEquals(24, stats.size());
-
- // try removing far before buckets; should be no change
- stats.removeBucketsBefore(TEST_START - YEAR_IN_MILLIS);
- assertEquals(24, stats.size());
-
- // try removing just moments into first bucket; should be no change
- // since that bucket contains data beyond the cutoff
- stats.removeBucketsBefore(TEST_START + SECOND_IN_MILLIS);
- assertEquals(24, stats.size());
-
- // try removing single bucket
- stats.removeBucketsBefore(TEST_START + HOUR_IN_MILLIS);
- assertEquals(23, stats.size());
-
- // try removing multiple buckets
- stats.removeBucketsBefore(TEST_START + (4 * HOUR_IN_MILLIS));
- assertEquals(20, stats.size());
-
- // try removing all buckets
- stats.removeBucketsBefore(TEST_START + YEAR_IN_MILLIS);
- assertEquals(0, stats.size());
- }
-
- public void testTotalData() throws Exception {
- final long BUCKET_SIZE = HOUR_IN_MILLIS;
- stats = new NetworkStatsHistory(BUCKET_SIZE);
-
- // record uniform data across day
- stats.recordData(TEST_START, TEST_START + DAY_IN_MILLIS, 2400L, 4800L);
-
- // verify that total outside range is 0
- assertValues(stats, TEST_START - WEEK_IN_MILLIS, TEST_START - DAY_IN_MILLIS, 0L, 0L);
-
- // verify total in first hour
- assertValues(stats, TEST_START, TEST_START + HOUR_IN_MILLIS, 100L, 200L);
-
- // verify total across 1.5 hours
- assertValues(stats, TEST_START, TEST_START + (long) (1.5 * HOUR_IN_MILLIS), 150L, 300L);
-
- // verify total beyond end
- assertValues(stats, TEST_START + (23 * HOUR_IN_MILLIS), TEST_START + WEEK_IN_MILLIS, 100L, 200L);
-
- // verify everything total
- assertValues(stats, TEST_START - WEEK_IN_MILLIS, TEST_START + WEEK_IN_MILLIS, 2400L, 4800L);
-
- }
-
- @Suppress
- public void testFuzzing() throws Exception {
- try {
- // fuzzing with random events, looking for crashes
- final NetworkStats.Entry entry = new NetworkStats.Entry();
- final Random r = new Random();
- for (int i = 0; i < 500; i++) {
- stats = new NetworkStatsHistory(r.nextLong());
- for (int j = 0; j < 10000; j++) {
- if (r.nextBoolean()) {
- // add range
- final long start = r.nextLong();
- final long end = start + r.nextInt();
- entry.rxBytes = nextPositiveLong(r);
- entry.rxPackets = nextPositiveLong(r);
- entry.txBytes = nextPositiveLong(r);
- entry.txPackets = nextPositiveLong(r);
- entry.operations = nextPositiveLong(r);
- stats.recordData(start, end, entry);
- } else {
- // trim something
- stats.removeBucketsBefore(r.nextLong());
- }
- }
- assertConsistent(stats);
- }
- } catch (Throwable e) {
- Log.e(TAG, String.valueOf(stats));
- throw new RuntimeException(e);
- }
- }
-
- private static long nextPositiveLong(Random r) {
- final long value = r.nextLong();
- return value < 0 ? -value : value;
- }
-
- public void testIgnoreFields() throws Exception {
- final NetworkStatsHistory history = new NetworkStatsHistory(
- MINUTE_IN_MILLIS, 0, FIELD_RX_BYTES | FIELD_TX_BYTES);
-
- history.recordData(0, MINUTE_IN_MILLIS,
- new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 4L));
- history.recordData(0, 2 * MINUTE_IN_MILLIS,
- new NetworkStats.Entry(2L, 2L, 2L, 2L, 2L));
-
- assertFullValues(history, UNKNOWN, 1026L, UNKNOWN, 2050L, UNKNOWN, UNKNOWN);
- }
-
- public void testIgnoreFieldsRecordIn() throws Exception {
- final NetworkStatsHistory full = new NetworkStatsHistory(MINUTE_IN_MILLIS, 0, FIELD_ALL);
- final NetworkStatsHistory partial = new NetworkStatsHistory(
- MINUTE_IN_MILLIS, 0, FIELD_RX_PACKETS | FIELD_OPERATIONS);
-
- full.recordData(0, MINUTE_IN_MILLIS,
- new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 4L));
- partial.recordEntireHistory(full);
-
- assertFullValues(partial, UNKNOWN, UNKNOWN, 10L, UNKNOWN, UNKNOWN, 4L);
- }
-
- public void testIgnoreFieldsRecordOut() throws Exception {
- final NetworkStatsHistory full = new NetworkStatsHistory(MINUTE_IN_MILLIS, 0, FIELD_ALL);
- final NetworkStatsHistory partial = new NetworkStatsHistory(
- MINUTE_IN_MILLIS, 0, FIELD_RX_PACKETS | FIELD_OPERATIONS);
-
- partial.recordData(0, MINUTE_IN_MILLIS,
- new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 4L));
- full.recordEntireHistory(partial);
-
- assertFullValues(full, MINUTE_IN_MILLIS, 0L, 10L, 0L, 0L, 4L);
- }
-
- public void testSerialize() throws Exception {
- final NetworkStatsHistory before = new NetworkStatsHistory(MINUTE_IN_MILLIS, 40, FIELD_ALL);
- before.recordData(0, 4 * MINUTE_IN_MILLIS,
- new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 4L));
- before.recordData(DAY_IN_MILLIS, DAY_IN_MILLIS + MINUTE_IN_MILLIS,
- new NetworkStats.Entry(10L, 20L, 30L, 40L, 50L));
-
- final ByteArrayOutputStream out = new ByteArrayOutputStream();
- before.writeToStream(new DataOutputStream(out));
- out.close();
-
- final ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
- final NetworkStatsHistory after = new NetworkStatsHistory(new DataInputStream(in));
-
- // must have identical totals before and after
- assertFullValues(before, 5 * MINUTE_IN_MILLIS, 1034L, 30L, 2078L, 60L, 54L);
- assertFullValues(after, 5 * MINUTE_IN_MILLIS, 1034L, 30L, 2078L, 60L, 54L);
- }
-
- public void testVarLong() throws Exception {
- assertEquals(0L, performVarLong(0L));
- assertEquals(-1L, performVarLong(-1L));
- assertEquals(1024L, performVarLong(1024L));
- assertEquals(-1024L, performVarLong(-1024L));
- assertEquals(40 * MB_IN_BYTES, performVarLong(40 * MB_IN_BYTES));
- assertEquals(512 * GB_IN_BYTES, performVarLong(512 * GB_IN_BYTES));
- assertEquals(Long.MIN_VALUE, performVarLong(Long.MIN_VALUE));
- assertEquals(Long.MAX_VALUE, performVarLong(Long.MAX_VALUE));
- assertEquals(Long.MIN_VALUE + 40, performVarLong(Long.MIN_VALUE + 40));
- assertEquals(Long.MAX_VALUE - 40, performVarLong(Long.MAX_VALUE - 40));
- }
-
- public void testIndexBeforeAfter() throws Exception {
- final long BUCKET_SIZE = HOUR_IN_MILLIS;
- stats = new NetworkStatsHistory(BUCKET_SIZE);
-
- final long FIRST_START = TEST_START;
- final long FIRST_END = FIRST_START + (2 * HOUR_IN_MILLIS);
- final long SECOND_START = TEST_START + WEEK_IN_MILLIS;
- final long SECOND_END = SECOND_START + HOUR_IN_MILLIS;
- final long THIRD_START = TEST_START + (2 * WEEK_IN_MILLIS);
- final long THIRD_END = THIRD_START + (2 * HOUR_IN_MILLIS);
-
- stats.recordData(FIRST_START, FIRST_END,
- new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 2L));
- stats.recordData(SECOND_START, SECOND_END,
- new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 2L));
- stats.recordData(THIRD_START, THIRD_END,
- new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 2L));
-
- // should have buckets: 2+1+2
- assertEquals(5, stats.size());
-
- assertIndexBeforeAfter(stats, 0, 0, Long.MIN_VALUE);
- assertIndexBeforeAfter(stats, 0, 1, FIRST_START);
- assertIndexBeforeAfter(stats, 0, 1, FIRST_START + MINUTE_IN_MILLIS);
- assertIndexBeforeAfter(stats, 0, 2, FIRST_START + HOUR_IN_MILLIS);
- assertIndexBeforeAfter(stats, 1, 2, FIRST_START + HOUR_IN_MILLIS + MINUTE_IN_MILLIS);
- assertIndexBeforeAfter(stats, 1, 2, FIRST_END - MINUTE_IN_MILLIS);
- assertIndexBeforeAfter(stats, 1, 2, FIRST_END);
- assertIndexBeforeAfter(stats, 1, 2, FIRST_END + MINUTE_IN_MILLIS);
- assertIndexBeforeAfter(stats, 1, 2, SECOND_START - MINUTE_IN_MILLIS);
- assertIndexBeforeAfter(stats, 1, 3, SECOND_START);
- assertIndexBeforeAfter(stats, 2, 3, SECOND_END);
- assertIndexBeforeAfter(stats, 2, 3, SECOND_END + MINUTE_IN_MILLIS);
- assertIndexBeforeAfter(stats, 2, 3, THIRD_START - MINUTE_IN_MILLIS);
- assertIndexBeforeAfter(stats, 2, 4, THIRD_START);
- assertIndexBeforeAfter(stats, 3, 4, THIRD_START + MINUTE_IN_MILLIS);
- assertIndexBeforeAfter(stats, 3, 4, THIRD_START + HOUR_IN_MILLIS);
- assertIndexBeforeAfter(stats, 4, 4, THIRD_END);
- assertIndexBeforeAfter(stats, 4, 4, THIRD_END + MINUTE_IN_MILLIS);
- assertIndexBeforeAfter(stats, 4, 4, Long.MAX_VALUE);
- }
-
- private static void assertIndexBeforeAfter(
- NetworkStatsHistory stats, int before, int after, long time) {
- assertEquals("unexpected before", before, stats.getIndexBefore(time));
- assertEquals("unexpected after", after, stats.getIndexAfter(time));
- }
-
- private static long performVarLong(long before) throws Exception {
- final ByteArrayOutputStream out = new ByteArrayOutputStream();
- writeVarLong(new DataOutputStream(out), before);
-
- final ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
- return readVarLong(new DataInputStream(in));
- }
-
- private static void assertConsistent(NetworkStatsHistory stats) {
- // verify timestamps are monotonic
- long lastStart = Long.MIN_VALUE;
- NetworkStatsHistory.Entry entry = null;
- for (int i = 0; i < stats.size(); i++) {
- entry = stats.getValues(i, entry);
- assertTrue(lastStart < entry.bucketStart);
- lastStart = entry.bucketStart;
- }
- }
-
- private static void assertValues(
- NetworkStatsHistory stats, int index, long rxBytes, long txBytes) {
- final NetworkStatsHistory.Entry entry = stats.getValues(index, null);
- assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
- assertEquals("unexpected txBytes", txBytes, entry.txBytes);
- }
-
- private static void assertValues(
- NetworkStatsHistory stats, long start, long end, long rxBytes, long txBytes) {
- final NetworkStatsHistory.Entry entry = stats.getValues(start, end, null);
- assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
- assertEquals("unexpected txBytes", txBytes, entry.txBytes);
- }
-
- private static void assertValues(NetworkStatsHistory stats, int index, long activeTime,
- long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) {
- final NetworkStatsHistory.Entry entry = stats.getValues(index, null);
- assertEquals("unexpected activeTime", activeTime, entry.activeTime);
- assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
- assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
- assertEquals("unexpected txBytes", txBytes, entry.txBytes);
- assertEquals("unexpected txPackets", txPackets, entry.txPackets);
- assertEquals("unexpected operations", operations, entry.operations);
- }
-
- private static void assertFullValues(NetworkStatsHistory stats, long activeTime, long rxBytes,
- long rxPackets, long txBytes, long txPackets, long operations) {
- assertValues(stats, Long.MIN_VALUE, Long.MAX_VALUE, activeTime, rxBytes, rxPackets, txBytes,
- txPackets, operations);
- }
-
- private static void assertValues(NetworkStatsHistory stats, long start, long end,
- long activeTime, long rxBytes, long rxPackets, long txBytes, long txPackets,
- long operations) {
- final NetworkStatsHistory.Entry entry = stats.getValues(start, end, null);
- assertEquals("unexpected activeTime", activeTime, entry.activeTime);
- assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
- assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
- assertEquals("unexpected txBytes", txBytes, entry.txBytes);
- assertEquals("unexpected txPackets", txPackets, entry.txPackets);
- assertEquals("unexpected operations", operations, entry.operations);
- }
-}
diff --git a/core/tests/coretests/src/android/net/NetworkStatsTest.java b/core/tests/coretests/src/android/net/NetworkStatsTest.java
deleted file mode 100644
index 6331964..0000000
--- a/core/tests/coretests/src/android/net/NetworkStatsTest.java
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import static android.net.NetworkStats.SET_DEFAULT;
-import static android.net.NetworkStats.SET_FOREGROUND;
-import static android.net.NetworkStats.SET_ALL;
-import static android.net.NetworkStats.IFACE_ALL;
-import static android.net.NetworkStats.TAG_NONE;
-import static android.net.NetworkStats.UID_ALL;
-
-import android.test.suitebuilder.annotation.SmallTest;
-
-import com.google.android.collect.Sets;
-
-import junit.framework.TestCase;
-
-import java.util.HashSet;
-
-@SmallTest
-public class NetworkStatsTest extends TestCase {
-
- private static final String TEST_IFACE = "test0";
- private static final String TEST_IFACE2 = "test2";
- private static final int TEST_UID = 1001;
- private static final long TEST_START = 1194220800000L;
-
- public void testFindIndex() throws Exception {
- final NetworkStats stats = new NetworkStats(TEST_START, 3)
- .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 10)
- .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 11)
- .addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 12);
-
- assertEquals(2, stats.findIndex(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE));
- assertEquals(2, stats.findIndex(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE));
- assertEquals(0, stats.findIndex(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE));
- assertEquals(-1, stats.findIndex(TEST_IFACE, 6, SET_DEFAULT, TAG_NONE));
- }
-
- public void testFindIndexHinted() {
- final NetworkStats stats = new NetworkStats(TEST_START, 3)
- .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 10)
- .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 11)
- .addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 12)
- .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 1024L, 8L, 0L, 0L, 10)
- .addValues(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, 0L, 0L, 1024L, 8L, 11)
- .addValues(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 12);
-
- // verify that we correctly find across regardless of hinting
- for (int hint = 0; hint < stats.size(); hint++) {
- assertEquals(0, stats.findIndexHinted(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, hint));
- assertEquals(1, stats.findIndexHinted(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, hint));
- assertEquals(2, stats.findIndexHinted(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, hint));
- assertEquals(3, stats.findIndexHinted(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, hint));
- assertEquals(4, stats.findIndexHinted(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, hint));
- assertEquals(5, stats.findIndexHinted(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, hint));
- assertEquals(-1, stats.findIndexHinted(TEST_IFACE, 6, SET_DEFAULT, TAG_NONE, hint));
- }
- }
-
- public void testAddEntryGrow() throws Exception {
- final NetworkStats stats = new NetworkStats(TEST_START, 2);
-
- assertEquals(0, stats.size());
- assertEquals(2, stats.internalSize());
-
- stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, 1L, 1L, 2L, 2L, 3);
- stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, 2L, 2L, 2L, 2L, 4);
-
- assertEquals(2, stats.size());
- assertEquals(2, stats.internalSize());
-
- stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, 3L, 30L, 4L, 40L, 7);
- stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, 4L, 40L, 4L, 40L, 8);
- stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, 5L, 50L, 5L, 50L, 10);
-
- assertEquals(5, stats.size());
- assertTrue(stats.internalSize() >= 5);
-
- assertValues(stats, 0, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, 1L, 1L, 2L, 2L, 3);
- assertValues(stats, 1, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, 2L, 2L, 2L, 2L, 4);
- assertValues(stats, 2, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, 3L, 30L, 4L, 40L, 7);
- assertValues(stats, 3, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, 4L, 40L, 4L, 40L, 8);
- assertValues(stats, 4, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, 5L, 50L, 5L, 50L, 10);
- }
-
- public void testCombineExisting() throws Exception {
- final NetworkStats stats = new NetworkStats(TEST_START, 10);
-
- stats.addValues(TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 10);
- stats.addValues(TEST_IFACE, 1001, SET_DEFAULT, 0xff, 128L, 1L, 128L, 1L, 2);
- stats.combineValues(TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, -128L, -1L, -128L, -1L, -1);
-
- assertValues(stats, 0, TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, 384L, 3L, 128L, 1L, 9);
- assertValues(stats, 1, TEST_IFACE, 1001, SET_DEFAULT, 0xff, 128L, 1L, 128L, 1L, 2);
-
- // now try combining that should create row
- stats.combineValues(TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 3);
- assertValues(stats, 2, TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 3);
- stats.combineValues(TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 3);
- assertValues(stats, 2, TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, 256L, 2L, 256L, 2L, 6);
- }
-
- public void testSubtractIdenticalData() throws Exception {
- final NetworkStats before = new NetworkStats(TEST_START, 2)
- .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
- .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
-
- final NetworkStats after = new NetworkStats(TEST_START, 2)
- .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
- .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
-
- final NetworkStats result = after.subtract(before);
-
- // identical data should result in zero delta
- assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0);
- assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0);
- }
-
- public void testSubtractIdenticalRows() throws Exception {
- final NetworkStats before = new NetworkStats(TEST_START, 2)
- .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
- .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
-
- final NetworkStats after = new NetworkStats(TEST_START, 2)
- .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1025L, 9L, 2L, 1L, 15)
- .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 3L, 1L, 1028L, 9L, 20);
-
- final NetworkStats result = after.subtract(before);
-
- // expect delta between measurements
- assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1L, 1L, 2L, 1L, 4);
- assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 3L, 1L, 4L, 1L, 8);
- }
-
- public void testSubtractNewRows() throws Exception {
- final NetworkStats before = new NetworkStats(TEST_START, 2)
- .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
- .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
-
- final NetworkStats after = new NetworkStats(TEST_START, 3)
- .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
- .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12)
- .addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 20);
-
- final NetworkStats result = after.subtract(before);
-
- // its okay to have new rows
- assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0);
- assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0);
- assertValues(result, 2, TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 20);
- }
-
- public void testSubtractMissingRows() throws Exception {
- final NetworkStats before = new NetworkStats(TEST_START, 2)
- .addValues(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, 1024L, 0L, 0L, 0L, 0)
- .addValues(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 2048L, 0L, 0L, 0L, 0);
-
- final NetworkStats after = new NetworkStats(TEST_START, 1)
- .addValues(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 2049L, 2L, 3L, 4L, 0);
-
- final NetworkStats result = after.subtract(before);
-
- // should silently drop omitted rows
- assertEquals(1, result.size());
- assertValues(result, 0, TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 1L, 2L, 3L, 4L, 0);
- assertEquals(4L, result.getTotalBytes());
- }
-
- public void testTotalBytes() throws Exception {
- final NetworkStats iface = new NetworkStats(TEST_START, 2)
- .addValues(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, 128L, 0L, 0L, 0L, 0L)
- .addValues(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 256L, 0L, 0L, 0L, 0L);
- assertEquals(384L, iface.getTotalBytes());
-
- final NetworkStats uidSet = new NetworkStats(TEST_START, 3)
- .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L)
- .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L)
- .addValues(TEST_IFACE, 101, SET_FOREGROUND, TAG_NONE, 32L, 0L, 0L, 0L, 0L);
- assertEquals(96L, uidSet.getTotalBytes());
-
- final NetworkStats uidTag = new NetworkStats(TEST_START, 3)
- .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
- .addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
- .addValues(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L)
- .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
- .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
- .addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L);
- assertEquals(64L, uidTag.getTotalBytes());
- }
-
- public void testGroupedByIfaceEmpty() throws Exception {
- final NetworkStats uidStats = new NetworkStats(TEST_START, 3);
- final NetworkStats grouped = uidStats.groupedByIface();
-
- assertEquals(0, uidStats.size());
- assertEquals(0, grouped.size());
- }
-
- public void testGroupedByIfaceAll() throws Exception {
- final NetworkStats uidStats = new NetworkStats(TEST_START, 3)
- .addValues(IFACE_ALL, 100, SET_ALL, TAG_NONE, 128L, 8L, 0L, 2L, 20L)
- .addValues(IFACE_ALL, 101, SET_FOREGROUND, TAG_NONE, 128L, 8L, 0L, 2L, 20L);
- final NetworkStats grouped = uidStats.groupedByIface();
-
- assertEquals(2, uidStats.size());
- assertEquals(1, grouped.size());
-
- assertValues(grouped, 0, IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE, 256L, 16L, 0L, 4L, 0L);
- }
-
- public void testGroupedByIface() throws Exception {
- final NetworkStats uidStats = new NetworkStats(TEST_START, 3)
- .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L)
- .addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 512L, 32L, 0L, 0L, 0L)
- .addValues(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 64L, 4L, 0L, 0L, 0L)
- .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 512L, 32L, 0L, 0L, 0L)
- .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 0L, 0L)
- .addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 128L, 8L, 0L, 0L, 0L);
-
- final NetworkStats grouped = uidStats.groupedByIface();
-
- assertEquals(6, uidStats.size());
-
- assertEquals(2, grouped.size());
- assertValues(grouped, 0, TEST_IFACE, UID_ALL, SET_ALL, TAG_NONE, 256L, 16L, 0L, 2L, 0L);
- assertValues(grouped, 1, TEST_IFACE2, UID_ALL, SET_ALL, TAG_NONE, 1024L, 64L, 0L, 0L, 0L);
- }
-
- public void testAddAllValues() {
- final NetworkStats first = new NetworkStats(TEST_START, 5)
- .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L)
- .addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, 32L, 0L, 0L, 0L, 0L);
-
- final NetworkStats second = new NetworkStats(TEST_START, 2)
- .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L)
- .addValues(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L);
-
- first.combineAllValues(second);
-
- assertEquals(3, first.size());
- assertValues(first, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 64L, 0L, 0L, 0L, 0L);
- assertValues(first, 1, TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, 32L, 0L, 0L, 0L, 0L);
- assertValues(first, 2, TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L);
- }
-
- public void testGetTotal() {
- final NetworkStats stats = new NetworkStats(TEST_START, 3)
- .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L)
- .addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 512L, 32L, 0L, 0L, 0L)
- .addValues(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 64L, 4L, 0L, 0L, 0L)
- .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 512L, 32L, 0L, 0L, 0L)
- .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 0L, 0L)
- .addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 128L, 8L, 0L, 0L, 0L);
-
- assertValues(stats.getTotal(null), 1280L, 80L, 0L, 2L, 20L);
- assertValues(stats.getTotal(null, 100), 1152L, 72L, 0L, 2L, 20L);
- assertValues(stats.getTotal(null, 101), 128L, 8L, 0L, 0L, 0L);
-
- final HashSet<String> ifaces = Sets.newHashSet();
- assertValues(stats.getTotal(null, ifaces), 0L, 0L, 0L, 0L, 0L);
-
- ifaces.add(TEST_IFACE2);
- assertValues(stats.getTotal(null, ifaces), 1024L, 64L, 0L, 0L, 0L);
- }
-
- public void testWithoutUid() throws Exception {
- final NetworkStats before = new NetworkStats(TEST_START, 3)
- .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L)
- .addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 512L, 32L, 0L, 0L, 0L)
- .addValues(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 64L, 4L, 0L, 0L, 0L)
- .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 512L, 32L, 0L, 0L, 0L)
- .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 0L, 0L)
- .addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 128L, 8L, 0L, 0L, 0L);
-
- final NetworkStats after = before.withoutUids(new int[] { 100 });
- assertEquals(6, before.size());
- assertEquals(2, after.size());
- assertValues(after, 0, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 0L, 0L);
- assertValues(after, 1, TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 128L, 8L, 0L, 0L, 0L);
- }
-
- public void testClone() throws Exception {
- final NetworkStats original = new NetworkStats(TEST_START, 5)
- .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L)
- .addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 512L, 32L, 0L, 0L, 0L);
-
- // make clone and mutate original
- final NetworkStats clone = original.clone();
- original.addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 0L, 0L);
-
- assertEquals(3, original.size());
- assertEquals(2, clone.size());
-
- assertEquals(128L + 512L + 128L, original.getTotalBytes());
- assertEquals(128L + 512L, clone.getTotalBytes());
- }
-
- private static void assertValues(NetworkStats stats, int index, String iface, int uid, int set,
- int tag, long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) {
- final NetworkStats.Entry entry = stats.getValues(index, null);
- assertValues(entry, iface, uid, set, tag);
- assertValues(entry, rxBytes, rxPackets, txBytes, txPackets, operations);
- }
-
- private static void assertValues(
- NetworkStats.Entry entry, String iface, int uid, int set, int tag) {
- assertEquals(iface, entry.iface);
- assertEquals(uid, entry.uid);
- assertEquals(set, entry.set);
- assertEquals(tag, entry.tag);
- }
-
- private static void assertValues(NetworkStats.Entry entry, long rxBytes, long rxPackets,
- long txBytes, long txPackets, long operations) {
- assertEquals(rxBytes, entry.rxBytes);
- assertEquals(rxPackets, entry.rxPackets);
- assertEquals(txBytes, entry.txBytes);
- assertEquals(txPackets, entry.txPackets);
- assertEquals(operations, entry.operations);
- }
-
-}
diff --git a/core/tests/coretests/src/android/net/RouteInfoTest.java b/core/tests/coretests/src/android/net/RouteInfoTest.java
deleted file mode 100644
index 01283a6..0000000
--- a/core/tests/coretests/src/android/net/RouteInfoTest.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import java.lang.reflect.Method;
-import java.net.InetAddress;
-
-import android.net.LinkAddress;
-import android.net.RouteInfo;
-import android.os.Parcel;
-
-import junit.framework.TestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-public class RouteInfoTest extends TestCase {
-
- private InetAddress Address(String addr) {
- return InetAddress.parseNumericAddress(addr);
- }
-
- private LinkAddress Prefix(String prefix) {
- String[] parts = prefix.split("/");
- return new LinkAddress(Address(parts[0]), Integer.parseInt(parts[1]));
- }
-
- @SmallTest
- public void testConstructor() {
- RouteInfo r;
-
- // Invalid input.
- try {
- r = new RouteInfo((LinkAddress) null, null, "rmnet0");
- fail("Expected RuntimeException: destination and gateway null");
- } catch(RuntimeException e) {}
-
- // Null destination is default route.
- r = new RouteInfo((LinkAddress) null, Address("2001:db8::1"), null);
- assertEquals(Prefix("::/0"), r.getDestination());
- assertEquals(Address("2001:db8::1"), r.getGateway());
- assertNull(r.getInterface());
-
- r = new RouteInfo((LinkAddress) null, Address("192.0.2.1"), "wlan0");
- assertEquals(Prefix("0.0.0.0/0"), r.getDestination());
- assertEquals(Address("192.0.2.1"), r.getGateway());
- assertEquals("wlan0", r.getInterface());
-
- // Null gateway sets gateway to unspecified address (why?).
- r = new RouteInfo(Prefix("2001:db8:beef:cafe::/48"), null, "lo");
- assertEquals(Prefix("2001:db8:beef::/48"), r.getDestination());
- assertEquals(Address("::"), r.getGateway());
- assertEquals("lo", r.getInterface());
-
- r = new RouteInfo(Prefix("192.0.2.5/24"), null);
- assertEquals(Prefix("192.0.2.0/24"), r.getDestination());
- assertEquals(Address("0.0.0.0"), r.getGateway());
- assertNull(r.getInterface());
- }
-
- public void testMatches() {
- class PatchedRouteInfo extends RouteInfo {
- public PatchedRouteInfo(LinkAddress destination, InetAddress gateway, String iface) {
- super(destination, gateway, iface);
- }
-
- public boolean matches(InetAddress destination) {
- return super.matches(destination);
- }
- }
-
- RouteInfo r;
-
- r = new PatchedRouteInfo(Prefix("2001:db8:f00::ace:d00d/127"), null, "rmnet0");
- assertTrue(r.matches(Address("2001:db8:f00::ace:d00c")));
- assertTrue(r.matches(Address("2001:db8:f00::ace:d00d")));
- assertFalse(r.matches(Address("2001:db8:f00::ace:d00e")));
- assertFalse(r.matches(Address("2001:db8:f00::bad:d00d")));
- assertFalse(r.matches(Address("2001:4868:4860::8888")));
-
- r = new PatchedRouteInfo(Prefix("192.0.2.0/23"), null, "wlan0");
- assertTrue(r.matches(Address("192.0.2.43")));
- assertTrue(r.matches(Address("192.0.3.21")));
- assertFalse(r.matches(Address("192.0.0.21")));
- assertFalse(r.matches(Address("8.8.8.8")));
-
- RouteInfo ipv6Default = new PatchedRouteInfo(Prefix("::/0"), null, "rmnet0");
- assertTrue(ipv6Default.matches(Address("2001:db8::f00")));
- assertFalse(ipv6Default.matches(Address("192.0.2.1")));
-
- RouteInfo ipv4Default = new PatchedRouteInfo(Prefix("0.0.0.0/0"), null, "rmnet0");
- assertTrue(ipv4Default.matches(Address("255.255.255.255")));
- assertTrue(ipv4Default.matches(Address("192.0.2.1")));
- assertFalse(ipv4Default.matches(Address("2001:db8::f00")));
- }
-
- private void assertAreEqual(Object o1, Object o2) {
- assertTrue(o1.equals(o2));
- assertTrue(o2.equals(o1));
- }
-
- private void assertAreNotEqual(Object o1, Object o2) {
- assertFalse(o1.equals(o2));
- assertFalse(o2.equals(o1));
- }
-
- public void testEquals() {
- // IPv4
- RouteInfo r1 = new RouteInfo(Prefix("2001:db8:ace::/48"), Address("2001:db8::1"), "wlan0");
- RouteInfo r2 = new RouteInfo(Prefix("2001:db8:ace::/48"), Address("2001:db8::1"), "wlan0");
- assertAreEqual(r1, r2);
-
- RouteInfo r3 = new RouteInfo(Prefix("2001:db8:ace::/49"), Address("2001:db8::1"), "wlan0");
- RouteInfo r4 = new RouteInfo(Prefix("2001:db8:ace::/48"), Address("2001:db8::2"), "wlan0");
- RouteInfo r5 = new RouteInfo(Prefix("2001:db8:ace::/48"), Address("2001:db8::1"), "rmnet0");
- assertAreNotEqual(r1, r3);
- assertAreNotEqual(r1, r4);
- assertAreNotEqual(r1, r5);
-
- // IPv6
- r1 = new RouteInfo(Prefix("192.0.2.0/25"), Address("192.0.2.1"), "wlan0");
- r2 = new RouteInfo(Prefix("192.0.2.0/25"), Address("192.0.2.1"), "wlan0");
- assertAreEqual(r1, r2);
-
- r3 = new RouteInfo(Prefix("192.0.2.0/24"), Address("192.0.2.1"), "wlan0");
- r4 = new RouteInfo(Prefix("192.0.2.0/25"), Address("192.0.2.2"), "wlan0");
- r5 = new RouteInfo(Prefix("192.0.2.0/25"), Address("192.0.2.1"), "rmnet0");
- assertAreNotEqual(r1, r3);
- assertAreNotEqual(r1, r4);
- assertAreNotEqual(r1, r5);
-
- // Interfaces (but not destinations or gateways) can be null.
- r1 = new RouteInfo(Prefix("192.0.2.0/25"), Address("192.0.2.1"), null);
- r2 = new RouteInfo(Prefix("192.0.2.0/25"), Address("192.0.2.1"), null);
- r3 = new RouteInfo(Prefix("192.0.2.0/24"), Address("192.0.2.1"), "wlan0");
- assertAreEqual(r1, r2);
- assertAreNotEqual(r1, r3);
- }
-
- public void testHostRoute() {
- RouteInfo r;
-
- r = new RouteInfo(Prefix("0.0.0.0/0"), Address("0.0.0.0"), "wlan0");
- assertFalse(r.isHostRoute());
-
- r = new RouteInfo(Prefix("::/0"), Address("::"), "wlan0");
- assertFalse(r.isHostRoute());
-
- r = new RouteInfo(Prefix("192.0.2.0/24"), null, "wlan0");
- assertFalse(r.isHostRoute());
-
- r = new RouteInfo(Prefix("2001:db8::/48"), null, "wlan0");
- assertFalse(r.isHostRoute());
-
- r = new RouteInfo(Prefix("192.0.2.0/32"), Address("0.0.0.0"), "wlan0");
- assertTrue(r.isHostRoute());
-
- r = new RouteInfo(Prefix("2001:db8::/128"), Address("::"), "wlan0");
- assertTrue(r.isHostRoute());
-
- r = new RouteInfo(Prefix("192.0.2.0/32"), null, "wlan0");
- assertTrue(r.isHostRoute());
-
- r = new RouteInfo(Prefix("2001:db8::/128"), null, "wlan0");
- assertTrue(r.isHostRoute());
-
- r = new RouteInfo(Prefix("::/128"), Address("fe80::"), "wlan0");
- assertTrue(r.isHostRoute());
-
- r = new RouteInfo(Prefix("0.0.0.0/32"), Address("192.0.2.1"), "wlan0");
- assertTrue(r.isHostRoute());
- }
-
- public RouteInfo passThroughParcel(RouteInfo r) {
- Parcel p = Parcel.obtain();
- RouteInfo r2 = null;
- try {
- r.writeToParcel(p, 0);
- p.setDataPosition(0);
- r2 = RouteInfo.CREATOR.createFromParcel(p);
- } finally {
- p.recycle();
- }
- assertNotNull(r2);
- return r2;
- }
-
- public void assertParcelingIsLossless(RouteInfo r) {
- RouteInfo r2 = passThroughParcel(r);
- assertEquals(r, r2);
- }
-
- public void testParceling() {
- RouteInfo r;
-
- r = new RouteInfo(Prefix("::/0"), Address("2001:db8::"), null);
- assertParcelingIsLossless(r);
-
- r = new RouteInfo(Prefix("192.0.2.0/24"), null, "wlan0");
- assertParcelingIsLossless(r);
- }
-}
diff --git a/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java b/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java
deleted file mode 100644
index d3dd01a..0000000
--- a/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2011 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.internal.net;
-
-import static android.net.NetworkStats.SET_ALL;
-import static android.net.NetworkStats.SET_DEFAULT;
-import static android.net.NetworkStats.SET_FOREGROUND;
-import static android.net.NetworkStats.TAG_NONE;
-import static android.net.NetworkStats.UID_ALL;
-import static com.android.server.NetworkManagementSocketTagger.kernelToTag;
-
-import android.content.res.Resources;
-import android.net.NetworkStats;
-import android.net.TrafficStats;
-import android.test.AndroidTestCase;
-
-import com.android.frameworks.coretests.R;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-import libcore.io.IoUtils;
-import libcore.io.Streams;
-
-/**
- * Tests for {@link NetworkStatsFactory}.
- */
-public class NetworkStatsFactoryTest extends AndroidTestCase {
- private File mTestProc;
- private NetworkStatsFactory mFactory;
-
- @Override
- public void setUp() throws Exception {
- super.setUp();
-
- mTestProc = new File(getContext().getFilesDir(), "proc");
- if (mTestProc.exists()) {
- IoUtils.deleteContents(mTestProc);
- }
-
- mFactory = new NetworkStatsFactory(mTestProc);
- }
-
- @Override
- public void tearDown() throws Exception {
- mFactory = null;
-
- if (mTestProc.exists()) {
- IoUtils.deleteContents(mTestProc);
- }
-
- super.tearDown();
- }
-
- public void testNetworkStatsDetail() throws Exception {
- stageFile(R.raw.xt_qtaguid_typical, new File(mTestProc, "net/xt_qtaguid/stats"));
-
- final NetworkStats stats = mFactory.readNetworkStatsDetail();
- assertEquals(70, stats.size());
- assertStatsEntry(stats, "wlan0", 0, SET_DEFAULT, 0x0, 18621L, 2898L);
- assertStatsEntry(stats, "wlan0", 10011, SET_DEFAULT, 0x0, 35777L, 5718L);
- assertStatsEntry(stats, "wlan0", 10021, SET_DEFAULT, 0x7fffff01, 562386L, 49228L);
- assertStatsEntry(stats, "rmnet1", 10021, SET_DEFAULT, 0x30100000, 219110L, 227423L);
- assertStatsEntry(stats, "rmnet2", 10001, SET_DEFAULT, 0x0, 1125899906842624L, 984L);
- }
-
- public void testKernelTags() throws Exception {
- assertEquals(0, kernelToTag("0x0000000000000000"));
- assertEquals(0x32, kernelToTag("0x0000003200000000"));
- assertEquals(2147483647, kernelToTag("0x7fffffff00000000"));
- assertEquals(0, kernelToTag("0x0000000000000000"));
- assertEquals(2147483136, kernelToTag("0x7FFFFE0000000000"));
-
- assertEquals(0, kernelToTag("0x0"));
- assertEquals(0, kernelToTag("0xf00d"));
- assertEquals(1, kernelToTag("0x100000000"));
- assertEquals(14438007, kernelToTag("0xdc4e7700000000"));
- assertEquals(TrafficStats.TAG_SYSTEM_DOWNLOAD, kernelToTag("0xffffff0100000000"));
- }
-
- public void testNetworkStatsWithSet() throws Exception {
- stageFile(R.raw.xt_qtaguid_typical, new File(mTestProc, "net/xt_qtaguid/stats"));
-
- final NetworkStats stats = mFactory.readNetworkStatsDetail();
- assertEquals(70, stats.size());
- assertStatsEntry(stats, "rmnet1", 10021, SET_DEFAULT, 0x30100000, 219110L, 578L, 227423L, 676L);
- assertStatsEntry(stats, "rmnet1", 10021, SET_FOREGROUND, 0x30100000, 742L, 3L, 1265L, 3L);
- }
-
- public void testNetworkStatsSingle() throws Exception {
- stageFile(R.raw.xt_qtaguid_iface_typical, new File(mTestProc, "net/xt_qtaguid/iface_stat_all"));
-
- final NetworkStats stats = mFactory.readNetworkStatsSummaryDev();
- assertEquals(6, stats.size());
- assertStatsEntry(stats, "rmnet0", UID_ALL, SET_ALL, TAG_NONE, 2112L, 24L, 700L, 10L);
- assertStatsEntry(stats, "test1", UID_ALL, SET_ALL, TAG_NONE, 6L, 8L, 10L, 12L);
- assertStatsEntry(stats, "test2", UID_ALL, SET_ALL, TAG_NONE, 1L, 2L, 3L, 4L);
- }
-
- public void testNetworkStatsXt() throws Exception {
- stageFile(R.raw.xt_qtaguid_iface_fmt_typical,
- new File(mTestProc, "net/xt_qtaguid/iface_stat_fmt"));
-
- final NetworkStats stats = mFactory.readNetworkStatsSummaryXt();
- assertEquals(3, stats.size());
- assertStatsEntry(stats, "rmnet0", UID_ALL, SET_ALL, TAG_NONE, 6824L, 16L, 5692L, 10L);
- assertStatsEntry(stats, "rmnet1", UID_ALL, SET_ALL, TAG_NONE, 11153922L, 8051L, 190226L, 2468L);
- assertStatsEntry(stats, "rmnet2", UID_ALL, SET_ALL, TAG_NONE, 4968L, 35L, 3081L, 39L);
- }
-
- /**
- * Copy a {@link Resources#openRawResource(int)} into {@link File} for
- * testing purposes.
- */
- private void stageFile(int rawId, File file) throws Exception {
- new File(file.getParent()).mkdirs();
- InputStream in = null;
- OutputStream out = null;
- try {
- in = getContext().getResources().openRawResource(rawId);
- out = new FileOutputStream(file);
- Streams.copy(in, out);
- } finally {
- IoUtils.closeQuietly(in);
- IoUtils.closeQuietly(out);
- }
- }
-
- private void stageLong(long value, File file) throws Exception {
- new File(file.getParent()).mkdirs();
- FileWriter out = null;
- try {
- out = new FileWriter(file);
- out.write(Long.toString(value));
- } finally {
- IoUtils.closeQuietly(out);
- }
- }
-
- private static void assertStatsEntry(NetworkStats stats, String iface, int uid, int set,
- int tag, long rxBytes, long txBytes) {
- final int i = stats.findIndex(iface, uid, set, tag);
- final NetworkStats.Entry entry = stats.getValues(i, null);
- assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
- assertEquals("unexpected txBytes", txBytes, entry.txBytes);
- }
-
- private static void assertStatsEntry(NetworkStats stats, String iface, int uid, int set,
- int tag, long rxBytes, long rxPackets, long txBytes, long txPackets) {
- final int i = stats.findIndex(iface, uid, set, tag);
- final NetworkStats.Entry entry = stats.getValues(i, null);
- assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
- assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
- assertEquals("unexpected txBytes", txBytes, entry.txBytes);
- assertEquals("unexpected txPackets", txPackets, entry.txPackets);
- }
-
-}
diff --git a/framework/src/android/net/NetworkCapabilities.java b/framework/src/android/net/NetworkCapabilities.java
index ec71d3d..447f626 100644
--- a/framework/src/android/net/NetworkCapabilities.java
+++ b/framework/src/android/net/NetworkCapabilities.java
@@ -814,11 +814,24 @@
}
/**
+ * @see #restrictCapabilitiesForTestNetwork(int)
+ * @deprecated Use {@link #restrictCapabilitiesForTestNetwork(int)} (without the typo) instead.
+ * @hide
+ */
+ @Deprecated
+ public void restrictCapabilitesForTestNetwork(int creatorUid) {
+ // Do not remove without careful consideration: this method has a typo in its name but is
+ // called by the first S CTS releases, therefore it cannot be removed from the connectivity
+ // module as long as such CTS releases are valid for testing S devices.
+ restrictCapabilitiesForTestNetwork(creatorUid);
+ }
+
+ /**
* Test networks have strong restrictions on what capabilities they can have. Enforce these
* restrictions.
* @hide
*/
- public void restrictCapabilitesForTestNetwork(int creatorUid) {
+ public void restrictCapabilitiesForTestNetwork(int creatorUid) {
final long originalCapabilities = mNetworkCapabilities;
final long originalTransportTypes = mTransportTypes;
final NetworkSpecifier originalSpecifier = mNetworkSpecifier;
@@ -828,7 +841,7 @@
final TransportInfo originalTransportInfo = getTransportInfo();
final Set<Integer> originalSubIds = getSubscriptionIds();
clearAll();
- if (0 != (originalCapabilities & NET_CAPABILITY_NOT_RESTRICTED)) {
+ if (0 != (originalCapabilities & (1 << NET_CAPABILITY_NOT_RESTRICTED))) {
// If the test network is not restricted, then it is only allowed to declare some
// specific transports. This is to minimize impact on running apps in case an app
// run from the shell creates a test a network.
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index 34e15ca..1d5d8af 100644
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -3255,7 +3255,7 @@
// the Messenger, but if this ever changes, not making a defensive copy
// here will give attack vectors to clients using this code path.
networkCapabilities = new NetworkCapabilities(networkCapabilities);
- networkCapabilities.restrictCapabilitesForTestNetwork(nai.creatorUid);
+ networkCapabilities.restrictCapabilitiesForTestNetwork(nai.creatorUid);
}
processCapabilitiesFromAgent(nai, networkCapabilities);
updateCapabilities(nai.getCurrentScore(), nai, networkCapabilities);
@@ -4622,9 +4622,16 @@
}
private void updateAvoidBadWifi() {
+ ensureRunningOnConnectivityServiceThread();
+ // Agent info scores and offer scores depend on whether cells yields to bad wifi.
for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
nai.updateScoreForNetworkAgentUpdate();
}
+ // UpdateOfferScore will update mNetworkOffers inline, so make a copy first.
+ final ArrayList<NetworkOfferInfo> offersToUpdate = new ArrayList<>(mNetworkOffers);
+ for (final NetworkOfferInfo noi : offersToUpdate) {
+ updateOfferScore(noi.offer);
+ }
rematchAllNetworksAndRequests();
}
@@ -6413,11 +6420,23 @@
Objects.requireNonNull(score);
Objects.requireNonNull(caps);
Objects.requireNonNull(callback);
+ final boolean yieldToBadWiFi = caps.hasTransport(TRANSPORT_CELLULAR) && !avoidBadWifi();
final NetworkOffer offer = new NetworkOffer(
- FullScore.makeProspectiveScore(score, caps), caps, callback, providerId);
+ FullScore.makeProspectiveScore(score, caps, yieldToBadWiFi),
+ caps, callback, providerId);
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_OFFER, offer));
}
+ private void updateOfferScore(final NetworkOffer offer) {
+ final boolean yieldToBadWiFi =
+ offer.caps.hasTransport(TRANSPORT_CELLULAR) && !avoidBadWifi();
+ final NetworkOffer newOffer = new NetworkOffer(
+ offer.score.withYieldToBadWiFi(yieldToBadWiFi),
+ offer.caps, offer.callback, offer.providerId);
+ if (offer.equals(newOffer)) return;
+ handleRegisterNetworkOffer(newOffer);
+ }
+
@Override
public void unofferNetwork(@NonNull final INetworkOfferCallback callback) {
mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_OFFER, callback));
@@ -6764,7 +6783,7 @@
// the call to mixInCapabilities below anyway, but sanitizing here means the NAI never
// sees capabilities that may be malicious, which might prevent mistakes in the future.
networkCapabilities = new NetworkCapabilities(networkCapabilities);
- networkCapabilities.restrictCapabilitesForTestNetwork(uid);
+ networkCapabilities.restrictCapabilitiesForTestNetwork(uid);
}
LinkProperties lp = new LinkProperties(linkProperties);
@@ -6838,6 +6857,7 @@
* @param newOffer The new offer. If the callback member is the same as an existing
* offer, it is an update of that offer.
*/
+ // TODO : rename this to handleRegisterOrUpdateNetworkOffer
private void handleRegisterNetworkOffer(@NonNull final NetworkOffer newOffer) {
ensureRunningOnConnectivityServiceThread();
if (!isNetworkProviderWithIdRegistered(newOffer.providerId)) {
@@ -6852,6 +6872,14 @@
if (null != existingOffer) {
handleUnregisterNetworkOffer(existingOffer);
newOffer.migrateFrom(existingOffer.offer);
+ if (DBG) {
+ // handleUnregisterNetworkOffer has already logged the old offer
+ log("update offer from providerId " + newOffer.providerId + " new : " + newOffer);
+ }
+ } else {
+ if (DBG) {
+ log("register offer from providerId " + newOffer.providerId + " : " + newOffer);
+ }
}
final NetworkOfferInfo noi = new NetworkOfferInfo(newOffer);
try {
@@ -6866,6 +6894,9 @@
private void handleUnregisterNetworkOffer(@NonNull final NetworkOfferInfo noi) {
ensureRunningOnConnectivityServiceThread();
+ if (DBG) {
+ log("unregister offer from providerId " + noi.offer.providerId + " : " + noi.offer);
+ }
mNetworkOffers.remove(noi);
noi.offer.callback.asBinder().unlinkToDeath(noi, 0 /* flags */);
}
@@ -9525,6 +9556,10 @@
@NonNull IConnectivityDiagnosticsCallback callback,
@NonNull NetworkRequest request,
@NonNull String callingPackageName) {
+ Objects.requireNonNull(callback, "callback must not be null");
+ Objects.requireNonNull(request, "request must not be null");
+ Objects.requireNonNull(callingPackageName, "callingPackageName must not be null");
+
if (request.legacyType != TYPE_NONE) {
throw new IllegalArgumentException("ConnectivityManager.TYPE_* are deprecated."
+ " Please use NetworkCapabilities instead.");
@@ -9573,6 +9608,9 @@
@Override
public void simulateDataStall(int detectionMethod, long timestampMillis,
@NonNull Network network, @NonNull PersistableBundle extras) {
+ Objects.requireNonNull(network, "network must not be null");
+ Objects.requireNonNull(extras, "extras must not be null");
+
enforceAnyPermissionOf(android.Manifest.permission.MANAGE_TEST_NETWORKS,
android.Manifest.permission.NETWORK_STACK);
final NetworkCapabilities nc = getNetworkCapabilitiesInternal(network);
diff --git a/service/src/com/android/server/connectivity/FullScore.java b/service/src/com/android/server/connectivity/FullScore.java
index 14cec09..aebb80d 100644
--- a/service/src/com/android/server/connectivity/FullScore.java
+++ b/service/src/com/android/server/connectivity/FullScore.java
@@ -183,7 +183,7 @@
* @return a FullScore appropriate for comparing to actual network's scores.
*/
public static FullScore makeProspectiveScore(@NonNull final NetworkScore score,
- @NonNull final NetworkCapabilities caps) {
+ @NonNull final NetworkCapabilities caps, final boolean yieldToBadWiFi) {
// If the network offers Internet access, it may validate.
final boolean mayValidate = caps.hasCapability(NET_CAPABILITY_INTERNET);
// VPN transports are known in advance.
@@ -197,8 +197,6 @@
final boolean everUserSelected = false;
// Don't assume the user will accept unvalidated connectivity.
final boolean acceptUnvalidated = false;
- // Don't assume clinging to bad wifi
- final boolean yieldToBadWiFi = false;
// A prospective score is invincible if the legacy int in the filter is over the maximum
// score.
final boolean invincible = score.getLegacyInt() > NetworkRanker.LEGACY_INT_MAX;
@@ -259,6 +257,16 @@
}
/**
+ * Returns this score but with the specified yield to bad wifi policy.
+ */
+ public FullScore withYieldToBadWiFi(final boolean newYield) {
+ return new FullScore(mLegacyInt,
+ newYield ? mPolicies | (1L << POLICY_YIELD_TO_BAD_WIFI)
+ : mPolicies & ~(1L << POLICY_YIELD_TO_BAD_WIFI),
+ mKeepConnectedReason);
+ }
+
+ /**
* Returns this score but validated.
*/
public FullScore asValidated() {
diff --git a/service/src/com/android/server/connectivity/NetworkAgentInfo.java b/service/src/com/android/server/connectivity/NetworkAgentInfo.java
index bbf523a..6426f86 100644
--- a/service/src/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/service/src/com/android/server/connectivity/NetworkAgentInfo.java
@@ -1187,6 +1187,7 @@
? " underlying{" + Arrays.toString(declaredUnderlyingNetworks) + "}" : "")
+ " lp{" + linkProperties + "}"
+ " nc{" + networkCapabilities + "}"
+ + " factorySerialNumber=" + factorySerialNumber
+ "}";
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
deleted file mode 100644
index 657d5ec..0000000
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ /dev/null
@@ -1,6047 +0,0 @@
-/*
- * Copyright (C) 2008 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.server;
-
-import static android.Manifest.permission.MANAGE_NETWORK_POLICY;
-import static android.Manifest.permission.RECEIVE_DATA_ACTIVITY_CHANGE;
-import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
-import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE;
-import static android.net.ConnectivityManager.NetworkCallbackListener;
-import static android.net.ConnectivityManager.TYPE_BLUETOOTH;
-import static android.net.ConnectivityManager.TYPE_DUMMY;
-import static android.net.ConnectivityManager.TYPE_MOBILE;
-import static android.net.ConnectivityManager.TYPE_MOBILE_MMS;
-import static android.net.ConnectivityManager.TYPE_MOBILE_SUPL;
-import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
-import static android.net.ConnectivityManager.TYPE_MOBILE_FOTA;
-import static android.net.ConnectivityManager.TYPE_MOBILE_IMS;
-import static android.net.ConnectivityManager.TYPE_MOBILE_CBS;
-import static android.net.ConnectivityManager.TYPE_MOBILE_IA;
-import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
-import static android.net.ConnectivityManager.TYPE_NONE;
-import static android.net.ConnectivityManager.TYPE_WIFI;
-import static android.net.ConnectivityManager.TYPE_WIMAX;
-import static android.net.ConnectivityManager.TYPE_PROXY;
-import static android.net.ConnectivityManager.getNetworkTypeName;
-import static android.net.ConnectivityManager.isNetworkTypeValid;
-import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
-import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
-
-import android.app.AlarmManager;
-import android.app.AppOpsManager;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.bluetooth.BluetoothTetheringDataTracker;
-import android.content.ActivityNotFoundException;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.database.ContentObserver;
-import android.net.CaptivePortalTracker;
-import android.net.ConnectivityManager;
-import android.net.DummyDataStateTracker;
-import android.net.IConnectivityManager;
-import android.net.INetworkManagementEventObserver;
-import android.net.INetworkPolicyListener;
-import android.net.INetworkPolicyManager;
-import android.net.INetworkStatsService;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.LinkProperties.CompareResult;
-import android.net.LinkQualityInfo;
-import android.net.MobileDataStateTracker;
-import android.net.Network;
-import android.net.NetworkAgent;
-import android.net.NetworkCapabilities;
-import android.net.NetworkConfig;
-import android.net.NetworkInfo;
-import android.net.NetworkInfo.DetailedState;
-import android.net.NetworkFactory;
-import android.net.NetworkQuotaInfo;
-import android.net.NetworkRequest;
-import android.net.NetworkState;
-import android.net.NetworkStateTracker;
-import android.net.NetworkUtils;
-import android.net.Proxy;
-import android.net.ProxyDataTracker;
-import android.net.ProxyInfo;
-import android.net.RouteInfo;
-import android.net.SamplingDataTracker;
-import android.net.Uri;
-import android.net.wimax.WimaxManagerConstants;
-import android.os.AsyncTask;
-import android.os.Binder;
-import android.os.Build;
-import android.os.FileUtils;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.INetworkManagementService;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.ParcelFileDescriptor;
-import android.os.PowerManager;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.security.Credentials;
-import android.security.KeyStore;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-import android.util.Slog;
-import android.util.SparseArray;
-import android.util.SparseIntArray;
-import android.util.Xml;
-
-import com.android.internal.R;
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.net.LegacyVpnInfo;
-import com.android.internal.net.VpnConfig;
-import com.android.internal.net.VpnProfile;
-import com.android.internal.telephony.DctConstants;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.TelephonyIntents;
-import com.android.internal.util.AsyncChannel;
-import com.android.internal.util.IndentingPrintWriter;
-import com.android.internal.util.XmlUtils;
-import com.android.server.am.BatteryStatsService;
-import com.android.server.connectivity.DataConnectionStats;
-import com.android.server.connectivity.Nat464Xlat;
-import com.android.server.connectivity.NetworkAgentInfo;
-import com.android.server.connectivity.NetworkMonitor;
-import com.android.server.connectivity.PacManager;
-import com.android.server.connectivity.Tethering;
-import com.android.server.connectivity.Vpn;
-import com.android.server.net.BaseNetworkObserver;
-import com.android.server.net.LockdownVpnTracker;
-import com.google.android.collect.Lists;
-import com.google.android.collect.Sets;
-
-import dalvik.system.DexClassLoader;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.lang.reflect.Constructor;
-import java.net.HttpURLConnection;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.URL;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.GregorianCalendar;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLSession;
-
-import static android.net.ConnectivityManager.INVALID_NET_ID;
-
-/**
- * @hide
- */
-public class ConnectivityService extends IConnectivityManager.Stub {
- private static final String TAG = "ConnectivityService";
-
- private static final boolean DBG = true;
- private static final boolean VDBG = true; // STOPSHIP
-
- // network sampling debugging
- private static final boolean SAMPLE_DBG = false;
-
- private static final boolean LOGD_RULES = false;
-
- // TODO: create better separation between radio types and network types
-
- // how long to wait before switching back to a radio's default network
- private static final int RESTORE_DEFAULT_NETWORK_DELAY = 1 * 60 * 1000;
- // system property that can override the above value
- private static final String NETWORK_RESTORE_DELAY_PROP_NAME =
- "android.telephony.apn-restore";
-
- // Default value if FAIL_FAST_TIME_MS is not set
- private static final int DEFAULT_FAIL_FAST_TIME_MS = 1 * 60 * 1000;
- // system property that can override DEFAULT_FAIL_FAST_TIME_MS
- private static final String FAIL_FAST_TIME_MS =
- "persist.radio.fail_fast_time_ms";
-
- private static final String ACTION_PKT_CNT_SAMPLE_INTERVAL_ELAPSED =
- "android.net.ConnectivityService.action.PKT_CNT_SAMPLE_INTERVAL_ELAPSED";
-
- private static final int SAMPLE_INTERVAL_ELAPSED_REQUEST_CODE = 0;
-
- private PendingIntent mSampleIntervalElapsedIntent;
-
- // Set network sampling interval at 12 minutes, this way, even if the timers get
- // aggregated, it will fire at around 15 minutes, which should allow us to
- // aggregate this timer with other timers (specially the socket keep alive timers)
- private static final int DEFAULT_SAMPLING_INTERVAL_IN_SECONDS = (SAMPLE_DBG ? 30 : 12 * 60);
-
- // start network sampling a minute after booting ...
- private static final int DEFAULT_START_SAMPLING_INTERVAL_IN_SECONDS = (SAMPLE_DBG ? 30 : 60);
-
- AlarmManager mAlarmManager;
-
- // used in recursive route setting to add gateways for the host for which
- // a host route was requested.
- private static final int MAX_HOSTROUTE_CYCLE_COUNT = 10;
-
- private Tethering mTethering;
-
- private KeyStore mKeyStore;
-
- @GuardedBy("mVpns")
- private final SparseArray<Vpn> mVpns = new SparseArray<Vpn>();
- private VpnCallback mVpnCallback = new VpnCallback();
-
- private boolean mLockdownEnabled;
- private LockdownVpnTracker mLockdownTracker;
-
- private Nat464Xlat mClat;
-
- /** Lock around {@link #mUidRules} and {@link #mMeteredIfaces}. */
- private Object mRulesLock = new Object();
- /** Currently active network rules by UID. */
- private SparseIntArray mUidRules = new SparseIntArray();
- /** Set of ifaces that are costly. */
- private HashSet<String> mMeteredIfaces = Sets.newHashSet();
-
- /**
- * Sometimes we want to refer to the individual network state
- * trackers separately, and sometimes we just want to treat them
- * abstractly.
- */
- private NetworkStateTracker mNetTrackers[];
-
- /* Handles captive portal check on a network */
- private CaptivePortalTracker mCaptivePortalTracker;
-
- /**
- * The link properties that define the current links
- */
- private LinkProperties mCurrentLinkProperties[];
-
- /**
- * A per Net list of the PID's that requested access to the net
- * used both as a refcount and for per-PID DNS selection
- */
- private List<Integer> mNetRequestersPids[];
-
- // priority order of the nettrackers
- // (excluding dynamically set mNetworkPreference)
- // TODO - move mNetworkTypePreference into this
- private int[] mPriorityList;
-
- private Context mContext;
- private int mNetworkPreference;
- private int mActiveDefaultNetwork = -1;
- // 0 is full bad, 100 is full good
- private int mDefaultInetCondition = 0;
- private int mDefaultInetConditionPublished = 0;
- private boolean mInetConditionChangeInFlight = false;
- private int mDefaultConnectionSequence = 0;
-
- private Object mDnsLock = new Object();
- private int mNumDnsEntries;
-
- private boolean mTestMode;
- private static ConnectivityService sServiceInstance;
-
- private INetworkManagementService mNetd;
- private INetworkPolicyManager mPolicyManager;
-
- private static final int ENABLED = 1;
- private static final int DISABLED = 0;
-
- private static final boolean ADD = true;
- private static final boolean REMOVE = false;
-
- private static final boolean TO_DEFAULT_TABLE = true;
- private static final boolean TO_SECONDARY_TABLE = false;
-
- private static final boolean EXEMPT = true;
- private static final boolean UNEXEMPT = false;
-
- /**
- * used internally as a delayed event to make us switch back to the
- * default network
- */
- private static final int EVENT_RESTORE_DEFAULT_NETWORK = 1;
-
- /**
- * used internally to change our mobile data enabled flag
- */
- private static final int EVENT_CHANGE_MOBILE_DATA_ENABLED = 2;
-
- /**
- * used internally to synchronize inet condition reports
- * arg1 = networkType
- * arg2 = condition (0 bad, 100 good)
- */
- private static final int EVENT_INET_CONDITION_CHANGE = 4;
-
- /**
- * used internally to mark the end of inet condition hold periods
- * arg1 = networkType
- */
- private static final int EVENT_INET_CONDITION_HOLD_END = 5;
-
- /**
- * used internally to clear a wakelock when transitioning
- * from one net to another
- */
- private static final int EVENT_CLEAR_NET_TRANSITION_WAKELOCK = 8;
-
- /**
- * used internally to reload global proxy settings
- */
- private static final int EVENT_APPLY_GLOBAL_HTTP_PROXY = 9;
-
- /**
- * used internally to set external dependency met/unmet
- * arg1 = ENABLED (met) or DISABLED (unmet)
- * arg2 = NetworkType
- */
- private static final int EVENT_SET_DEPENDENCY_MET = 10;
-
- /**
- * used internally to send a sticky broadcast delayed.
- */
- private static final int EVENT_SEND_STICKY_BROADCAST_INTENT = 11;
-
- /**
- * Used internally to
- * {@link NetworkStateTracker#setPolicyDataEnable(boolean)}.
- */
- private static final int EVENT_SET_POLICY_DATA_ENABLE = 12;
-
- private static final int EVENT_VPN_STATE_CHANGED = 13;
-
- /**
- * Used internally to disable fail fast of mobile data
- */
- private static final int EVENT_ENABLE_FAIL_FAST_MOBILE_DATA = 14;
-
- /**
- * used internally to indicate that data sampling interval is up
- */
- private static final int EVENT_SAMPLE_INTERVAL_ELAPSED = 15;
-
- /**
- * PAC manager has received new port.
- */
- private static final int EVENT_PROXY_HAS_CHANGED = 16;
-
- /**
- * used internally when registering NetworkFactories
- * obj = NetworkFactoryInfo
- */
- private static final int EVENT_REGISTER_NETWORK_FACTORY = 17;
-
- /**
- * used internally when registering NetworkAgents
- * obj = Messenger
- */
- private static final int EVENT_REGISTER_NETWORK_AGENT = 18;
-
- /**
- * used to add a network request
- * includes a NetworkRequestInfo
- */
- private static final int EVENT_REGISTER_NETWORK_REQUEST = 19;
-
- /**
- * indicates a timeout period is over - check if we had a network yet or not
- * and if not, call the timeout calback (but leave the request live until they
- * cancel it.
- * includes a NetworkRequestInfo
- */
- private static final int EVENT_TIMEOUT_NETWORK_REQUEST = 20;
-
- /**
- * used to add a network listener - no request
- * includes a NetworkRequestInfo
- */
- private static final int EVENT_REGISTER_NETWORK_LISTENER = 21;
-
- /**
- * used to remove a network request, either a listener or a real request
- * includes a NetworkRequest
- */
- private static final int EVENT_RELEASE_NETWORK_REQUEST = 22;
-
- /**
- * used internally when registering NetworkFactories
- * obj = Messenger
- */
- private static final int EVENT_UNREGISTER_NETWORK_FACTORY = 23;
-
-
- /** Handler used for internal events. */
- final private InternalHandler mHandler;
- /** Handler used for incoming {@link NetworkStateTracker} events. */
- final private NetworkStateTrackerHandler mTrackerHandler;
-
- // list of DeathRecipients used to make sure features are turned off when
- // a process dies
- private List<FeatureUser> mFeatureUsers;
-
- private boolean mSystemReady;
- private Intent mInitialBroadcast;
-
- private PowerManager.WakeLock mNetTransitionWakeLock;
- private String mNetTransitionWakeLockCausedBy = "";
- private int mNetTransitionWakeLockSerialNumber;
- private int mNetTransitionWakeLockTimeout;
-
- private InetAddress mDefaultDns;
-
- // Lock for protecting access to mAddedRoutes and mExemptAddresses
- private final Object mRoutesLock = new Object();
-
- // this collection is used to refcount the added routes - if there are none left
- // it's time to remove the route from the route table
- @GuardedBy("mRoutesLock")
- private Collection<RouteInfo> mAddedRoutes = new ArrayList<RouteInfo>();
-
- // this collection corresponds to the entries of mAddedRoutes that have routing exemptions
- // used to handle cleanup of exempt rules
- @GuardedBy("mRoutesLock")
- private Collection<LinkAddress> mExemptAddresses = new ArrayList<LinkAddress>();
-
- // used in DBG mode to track inet condition reports
- private static final int INET_CONDITION_LOG_MAX_SIZE = 15;
- private ArrayList mInetLog;
-
- // track the current default http proxy - tell the world if we get a new one (real change)
- private ProxyInfo mDefaultProxy = null;
- private Object mProxyLock = new Object();
- private boolean mDefaultProxyDisabled = false;
-
- // track the global proxy.
- private ProxyInfo mGlobalProxy = null;
-
- private PacManager mPacManager = null;
-
- private SettingsObserver mSettingsObserver;
-
- private AppOpsManager mAppOpsManager;
-
- NetworkConfig[] mNetConfigs;
- int mNetworksDefined;
-
- private static class RadioAttributes {
- public int mSimultaneity;
- public int mType;
- public RadioAttributes(String init) {
- String fragments[] = init.split(",");
- mType = Integer.parseInt(fragments[0]);
- mSimultaneity = Integer.parseInt(fragments[1]);
- }
- }
- RadioAttributes[] mRadioAttributes;
-
- // the set of network types that can only be enabled by system/sig apps
- List mProtectedNetworks;
-
- private DataConnectionStats mDataConnectionStats;
-
- private AtomicInteger mEnableFailFastMobileDataTag = new AtomicInteger(0);
-
- TelephonyManager mTelephonyManager;
-
- // sequence number for Networks
- private final static int MIN_NET_ID = 10; // some reserved marks
- private final static int MAX_NET_ID = 65535;
- private int mNextNetId = MIN_NET_ID;
-
- // sequence number of NetworkRequests
- private int mNextNetworkRequestId = 1;
-
- private static final int UID_UNUSED = -1;
-
- /**
- * Implements support for the legacy "one network per network type" model.
- *
- * We used to have a static array of NetworkStateTrackers, one for each
- * network type, but that doesn't work any more now that we can have,
- * for example, more that one wifi network. This class stores all the
- * NetworkAgentInfo objects that support a given type, but the legacy
- * API will only see the first one.
- *
- * It serves two main purposes:
- *
- * 1. Provide information about "the network for a given type" (since this
- * API only supports one).
- * 2. Send legacy connectivity change broadcasts. Broadcasts are sent if
- * the first network for a given type changes, or if the default network
- * changes.
- */
- private class LegacyTypeTracker {
- /**
- * Array of lists, one per legacy network type (e.g., TYPE_MOBILE_MMS).
- * Each list holds references to all NetworkAgentInfos that are used to
- * satisfy requests for that network type.
- *
- * This array is built out at startup such that an unsupported network
- * doesn't get an ArrayList instance, making this a tristate:
- * unsupported, supported but not active and active.
- *
- * The actual lists are populated when we scan the network types that
- * are supported on this device.
- */
- private ArrayList<NetworkAgentInfo> mTypeLists[];
-
- public LegacyTypeTracker() {
- mTypeLists = (ArrayList<NetworkAgentInfo>[])
- new ArrayList[ConnectivityManager.MAX_NETWORK_TYPE + 1];
- }
-
- public void addSupportedType(int type) {
- if (mTypeLists[type] != null) {
- throw new IllegalStateException(
- "legacy list for type " + type + "already initialized");
- }
- mTypeLists[type] = new ArrayList<NetworkAgentInfo>();
- }
-
- private boolean isDefaultNetwork(NetworkAgentInfo nai) {
- return mNetworkForRequestId.get(mDefaultRequest.requestId) == nai;
- }
-
- public boolean isTypeSupported(int type) {
- return isNetworkTypeValid(type) && mTypeLists[type] != null;
- }
-
- public NetworkAgentInfo getNetworkForType(int type) {
- if (isTypeSupported(type) && !mTypeLists[type].isEmpty()) {
- return mTypeLists[type].get(0);
- } else {
- return null;
- }
- }
-
- public void add(int type, NetworkAgentInfo nai) {
- if (!isTypeSupported(type)) {
- return; // Invalid network type.
- }
- if (VDBG) log("Adding agent " + nai + " for legacy network type " + type);
-
- ArrayList<NetworkAgentInfo> list = mTypeLists[type];
- if (list.contains(nai)) {
- loge("Attempting to register duplicate agent for type " + type + ": " + nai);
- return;
- }
-
- if (list.isEmpty() || isDefaultNetwork(nai)) {
- if (VDBG) log("Sending connected broadcast for type " + type +
- "isDefaultNetwork=" + isDefaultNetwork(nai));
- sendLegacyNetworkBroadcast(nai, true, type);
- }
- list.add(nai);
- }
-
- public void remove(NetworkAgentInfo nai) {
- if (VDBG) log("Removing agent " + nai);
- for (int type = 0; type < mTypeLists.length; type++) {
- ArrayList<NetworkAgentInfo> list = mTypeLists[type];
- if (list == null || list.isEmpty()) {
- continue;
- }
-
- boolean wasFirstNetwork = false;
- if (list.get(0).equals(nai)) {
- // This network was the first in the list. Send broadcast.
- wasFirstNetwork = true;
- }
- list.remove(nai);
-
- if (wasFirstNetwork || isDefaultNetwork(nai)) {
- if (VDBG) log("Sending disconnected broadcast for type " + type +
- "isDefaultNetwork=" + isDefaultNetwork(nai));
- sendLegacyNetworkBroadcast(nai, false, type);
- }
-
- if (!list.isEmpty() && wasFirstNetwork) {
- if (VDBG) log("Other network available for type " + type +
- ", sending connected broadcast");
- sendLegacyNetworkBroadcast(list.get(0), false, type);
- }
- }
- }
- }
- private LegacyTypeTracker mLegacyTypeTracker = new LegacyTypeTracker();
-
- public ConnectivityService(Context context, INetworkManagementService netd,
- INetworkStatsService statsService, INetworkPolicyManager policyManager) {
- // Currently, omitting a NetworkFactory will create one internally
- // TODO: create here when we have cleaner WiMAX support
- this(context, netd, statsService, policyManager, null);
- }
-
- public ConnectivityService(Context context, INetworkManagementService netManager,
- INetworkStatsService statsService, INetworkPolicyManager policyManager,
- NetworkFactory netFactory) {
- if (DBG) log("ConnectivityService starting up");
-
- NetworkCapabilities netCap = new NetworkCapabilities();
- netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
- netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
- mDefaultRequest = new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId());
- NetworkRequestInfo nri = new NetworkRequestInfo(null, mDefaultRequest, new Binder(),
- NetworkRequestInfo.REQUEST);
- mNetworkRequests.put(mDefaultRequest, nri);
-
- HandlerThread handlerThread = new HandlerThread("ConnectivityServiceThread");
- handlerThread.start();
- mHandler = new InternalHandler(handlerThread.getLooper());
- mTrackerHandler = new NetworkStateTrackerHandler(handlerThread.getLooper());
-
- if (netFactory == null) {
- netFactory = new DefaultNetworkFactory(context, mTrackerHandler);
- }
-
- // setup our unique device name
- if (TextUtils.isEmpty(SystemProperties.get("net.hostname"))) {
- String id = Settings.Secure.getString(context.getContentResolver(),
- Settings.Secure.ANDROID_ID);
- if (id != null && id.length() > 0) {
- String name = new String("android-").concat(id);
- SystemProperties.set("net.hostname", name);
- }
- }
-
- // read our default dns server ip
- String dns = Settings.Global.getString(context.getContentResolver(),
- Settings.Global.DEFAULT_DNS_SERVER);
- if (dns == null || dns.length() == 0) {
- dns = context.getResources().getString(
- com.android.internal.R.string.config_default_dns_server);
- }
- try {
- mDefaultDns = NetworkUtils.numericToInetAddress(dns);
- } catch (IllegalArgumentException e) {
- loge("Error setting defaultDns using " + dns);
- }
-
- mContext = checkNotNull(context, "missing Context");
- mNetd = checkNotNull(netManager, "missing INetworkManagementService");
- mPolicyManager = checkNotNull(policyManager, "missing INetworkPolicyManager");
- mKeyStore = KeyStore.getInstance();
- mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
-
- try {
- mPolicyManager.registerListener(mPolicyListener);
- } catch (RemoteException e) {
- // ouch, no rules updates means some processes may never get network
- loge("unable to register INetworkPolicyListener" + e.toString());
- }
-
- final PowerManager powerManager = (PowerManager) context.getSystemService(
- Context.POWER_SERVICE);
- mNetTransitionWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
- mNetTransitionWakeLockTimeout = mContext.getResources().getInteger(
- com.android.internal.R.integer.config_networkTransitionTimeout);
-
- mNetTrackers = new NetworkStateTracker[
- ConnectivityManager.MAX_NETWORK_TYPE+1];
- mCurrentLinkProperties = new LinkProperties[ConnectivityManager.MAX_NETWORK_TYPE+1];
-
- mRadioAttributes = new RadioAttributes[ConnectivityManager.MAX_RADIO_TYPE+1];
- mNetConfigs = new NetworkConfig[ConnectivityManager.MAX_NETWORK_TYPE+1];
-
- // Load device network attributes from resources
- String[] raStrings = context.getResources().getStringArray(
- com.android.internal.R.array.radioAttributes);
- for (String raString : raStrings) {
- RadioAttributes r = new RadioAttributes(raString);
- if (VDBG) log("raString=" + raString + " r=" + r);
- if (r.mType > ConnectivityManager.MAX_RADIO_TYPE) {
- loge("Error in radioAttributes - ignoring attempt to define type " + r.mType);
- continue;
- }
- if (mRadioAttributes[r.mType] != null) {
- loge("Error in radioAttributes - ignoring attempt to redefine type " +
- r.mType);
- continue;
- }
- mRadioAttributes[r.mType] = r;
- }
-
- // TODO: What is the "correct" way to do determine if this is a wifi only device?
- boolean wifiOnly = SystemProperties.getBoolean("ro.radio.noril", false);
- log("wifiOnly=" + wifiOnly);
- String[] naStrings = context.getResources().getStringArray(
- com.android.internal.R.array.networkAttributes);
- for (String naString : naStrings) {
- try {
- NetworkConfig n = new NetworkConfig(naString);
- if (VDBG) log("naString=" + naString + " config=" + n);
- if (n.type > ConnectivityManager.MAX_NETWORK_TYPE) {
- loge("Error in networkAttributes - ignoring attempt to define type " +
- n.type);
- continue;
- }
- if (wifiOnly && ConnectivityManager.isNetworkTypeMobile(n.type)) {
- log("networkAttributes - ignoring mobile as this dev is wifiOnly " +
- n.type);
- continue;
- }
- if (mNetConfigs[n.type] != null) {
- loge("Error in networkAttributes - ignoring attempt to redefine type " +
- n.type);
- continue;
- }
- if (mRadioAttributes[n.radio] == null) {
- loge("Error in networkAttributes - ignoring attempt to use undefined " +
- "radio " + n.radio + " in network type " + n.type);
- continue;
- }
- mLegacyTypeTracker.addSupportedType(n.type);
-
- mNetConfigs[n.type] = n;
- mNetworksDefined++;
- } catch(Exception e) {
- // ignore it - leave the entry null
- }
- }
- if (VDBG) log("mNetworksDefined=" + mNetworksDefined);
-
- mProtectedNetworks = new ArrayList<Integer>();
- int[] protectedNetworks = context.getResources().getIntArray(
- com.android.internal.R.array.config_protectedNetworks);
- for (int p : protectedNetworks) {
- if ((mNetConfigs[p] != null) && (mProtectedNetworks.contains(p) == false)) {
- mProtectedNetworks.add(p);
- } else {
- if (DBG) loge("Ignoring protectedNetwork " + p);
- }
- }
-
- // high priority first
- mPriorityList = new int[mNetworksDefined];
- {
- int insertionPoint = mNetworksDefined-1;
- int currentLowest = 0;
- int nextLowest = 0;
- while (insertionPoint > -1) {
- for (NetworkConfig na : mNetConfigs) {
- if (na == null) continue;
- if (na.priority < currentLowest) continue;
- if (na.priority > currentLowest) {
- if (na.priority < nextLowest || nextLowest == 0) {
- nextLowest = na.priority;
- }
- continue;
- }
- mPriorityList[insertionPoint--] = na.type;
- }
- currentLowest = nextLowest;
- nextLowest = 0;
- }
- }
-
- mNetRequestersPids =
- (List<Integer> [])new ArrayList[ConnectivityManager.MAX_NETWORK_TYPE+1];
- for (int i : mPriorityList) {
- mNetRequestersPids[i] = new ArrayList<Integer>();
- }
-
- mFeatureUsers = new ArrayList<FeatureUser>();
-
- mTestMode = SystemProperties.get("cm.test.mode").equals("true")
- && SystemProperties.get("ro.build.type").equals("eng");
-
- // Create and start trackers for hard-coded networks
- for (int targetNetworkType : mPriorityList) {
- final NetworkConfig config = mNetConfigs[targetNetworkType];
- final NetworkStateTracker tracker;
- try {
- tracker = netFactory.createTracker(targetNetworkType, config);
- mNetTrackers[targetNetworkType] = tracker;
- } catch (IllegalArgumentException e) {
- Slog.e(TAG, "Problem creating " + getNetworkTypeName(targetNetworkType)
- + " tracker: " + e);
- continue;
- }
-
- tracker.startMonitoring(context, mTrackerHandler);
- if (config.isDefault()) {
- tracker.reconnect();
- }
- }
-
- mTethering = new Tethering(mContext, mNetd, statsService, this, mHandler.getLooper());
-
- //set up the listener for user state for creating user VPNs
- IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(Intent.ACTION_USER_STARTING);
- intentFilter.addAction(Intent.ACTION_USER_STOPPING);
- mContext.registerReceiverAsUser(
- mUserIntentReceiver, UserHandle.ALL, intentFilter, null, null);
- mClat = new Nat464Xlat(mContext, mNetd, this, mTrackerHandler);
-
- try {
- mNetd.registerObserver(mTethering);
- mNetd.registerObserver(mDataActivityObserver);
- mNetd.registerObserver(mClat);
- } catch (RemoteException e) {
- loge("Error registering observer :" + e);
- }
-
- if (DBG) {
- mInetLog = new ArrayList();
- }
-
- mSettingsObserver = new SettingsObserver(mHandler, EVENT_APPLY_GLOBAL_HTTP_PROXY);
- mSettingsObserver.observe(mContext);
-
- mDataConnectionStats = new DataConnectionStats(mContext);
- mDataConnectionStats.startMonitoring();
-
- // start network sampling ..
- Intent intent = new Intent(ACTION_PKT_CNT_SAMPLE_INTERVAL_ELAPSED, null);
- mSampleIntervalElapsedIntent = PendingIntent.getBroadcast(mContext,
- SAMPLE_INTERVAL_ELAPSED_REQUEST_CODE, intent, 0);
-
- mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
- setAlarm(DEFAULT_START_SAMPLING_INTERVAL_IN_SECONDS * 1000, mSampleIntervalElapsedIntent);
-
- IntentFilter filter = new IntentFilter();
- filter.addAction(ACTION_PKT_CNT_SAMPLE_INTERVAL_ELAPSED);
- mContext.registerReceiver(
- new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (action.equals(ACTION_PKT_CNT_SAMPLE_INTERVAL_ELAPSED)) {
- mHandler.sendMessage(mHandler.obtainMessage
- (EVENT_SAMPLE_INTERVAL_ELAPSED));
- }
- }
- },
- new IntentFilter(filter));
-
- mPacManager = new PacManager(mContext, mHandler, EVENT_PROXY_HAS_CHANGED);
-
- filter = new IntentFilter();
- filter.addAction(CONNECTED_TO_PROVISIONING_NETWORK_ACTION);
- mContext.registerReceiver(mProvisioningReceiver, filter);
-
- mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
- }
-
- private synchronized int nextNetworkRequestId() {
- return mNextNetworkRequestId++;
- }
-
- private synchronized int nextNetId() {
- int netId = mNextNetId;
- if (++mNextNetId > MAX_NET_ID) mNextNetId = MIN_NET_ID;
- return netId;
- }
-
- /**
- * Factory that creates {@link NetworkStateTracker} instances using given
- * {@link NetworkConfig}.
- *
- * TODO - this is obsolete and will be deleted. It's replaced by the
- * registerNetworkFactory call and protocol.
- * @Deprecated in favor of registerNetworkFactory dynamic bindings
- */
- public interface NetworkFactory {
- public NetworkStateTracker createTracker(int targetNetworkType, NetworkConfig config);
- }
-
- private static class DefaultNetworkFactory implements NetworkFactory {
- private final Context mContext;
- private final Handler mTrackerHandler;
-
- public DefaultNetworkFactory(Context context, Handler trackerHandler) {
- mContext = context;
- mTrackerHandler = trackerHandler;
- }
-
- @Override
- public NetworkStateTracker createTracker(int targetNetworkType, NetworkConfig config) {
- switch (config.radio) {
- case TYPE_DUMMY:
- return new DummyDataStateTracker(targetNetworkType, config.name);
- case TYPE_BLUETOOTH:
- return BluetoothTetheringDataTracker.getInstance();
- case TYPE_WIMAX:
- return makeWimaxStateTracker(mContext, mTrackerHandler);
- case TYPE_PROXY:
- return new ProxyDataTracker();
- default:
- throw new IllegalArgumentException(
- "Trying to create a NetworkStateTracker for an unknown radio type: "
- + config.radio);
- }
- }
- }
-
- /**
- * Loads external WiMAX library and registers as system service, returning a
- * {@link NetworkStateTracker} for WiMAX. Caller is still responsible for
- * invoking {@link NetworkStateTracker#startMonitoring(Context, Handler)}.
- */
- private static NetworkStateTracker makeWimaxStateTracker(
- Context context, Handler trackerHandler) {
- // Initialize Wimax
- DexClassLoader wimaxClassLoader;
- Class wimaxStateTrackerClass = null;
- Class wimaxServiceClass = null;
- Class wimaxManagerClass;
- String wimaxJarLocation;
- String wimaxLibLocation;
- String wimaxManagerClassName;
- String wimaxServiceClassName;
- String wimaxStateTrackerClassName;
-
- NetworkStateTracker wimaxStateTracker = null;
-
- boolean isWimaxEnabled = context.getResources().getBoolean(
- com.android.internal.R.bool.config_wimaxEnabled);
-
- if (isWimaxEnabled) {
- try {
- wimaxJarLocation = context.getResources().getString(
- com.android.internal.R.string.config_wimaxServiceJarLocation);
- wimaxLibLocation = context.getResources().getString(
- com.android.internal.R.string.config_wimaxNativeLibLocation);
- wimaxManagerClassName = context.getResources().getString(
- com.android.internal.R.string.config_wimaxManagerClassname);
- wimaxServiceClassName = context.getResources().getString(
- com.android.internal.R.string.config_wimaxServiceClassname);
- wimaxStateTrackerClassName = context.getResources().getString(
- com.android.internal.R.string.config_wimaxStateTrackerClassname);
-
- if (DBG) log("wimaxJarLocation: " + wimaxJarLocation);
- wimaxClassLoader = new DexClassLoader(wimaxJarLocation,
- new ContextWrapper(context).getCacheDir().getAbsolutePath(),
- wimaxLibLocation, ClassLoader.getSystemClassLoader());
-
- try {
- wimaxManagerClass = wimaxClassLoader.loadClass(wimaxManagerClassName);
- wimaxStateTrackerClass = wimaxClassLoader.loadClass(wimaxStateTrackerClassName);
- wimaxServiceClass = wimaxClassLoader.loadClass(wimaxServiceClassName);
- } catch (ClassNotFoundException ex) {
- loge("Exception finding Wimax classes: " + ex.toString());
- return null;
- }
- } catch(Resources.NotFoundException ex) {
- loge("Wimax Resources does not exist!!! ");
- return null;
- }
-
- try {
- if (DBG) log("Starting Wimax Service... ");
-
- Constructor wmxStTrkrConst = wimaxStateTrackerClass.getConstructor
- (new Class[] {Context.class, Handler.class});
- wimaxStateTracker = (NetworkStateTracker) wmxStTrkrConst.newInstance(
- context, trackerHandler);
-
- Constructor wmxSrvConst = wimaxServiceClass.getDeclaredConstructor
- (new Class[] {Context.class, wimaxStateTrackerClass});
- wmxSrvConst.setAccessible(true);
- IBinder svcInvoker = (IBinder)wmxSrvConst.newInstance(context, wimaxStateTracker);
- wmxSrvConst.setAccessible(false);
-
- ServiceManager.addService(WimaxManagerConstants.WIMAX_SERVICE, svcInvoker);
-
- } catch(Exception ex) {
- loge("Exception creating Wimax classes: " + ex.toString());
- return null;
- }
- } else {
- loge("Wimax is not enabled or not added to the network attributes!!! ");
- return null;
- }
-
- return wimaxStateTracker;
- }
-
- private int getConnectivityChangeDelay() {
- final ContentResolver cr = mContext.getContentResolver();
-
- /** Check system properties for the default value then use secure settings value, if any. */
- int defaultDelay = SystemProperties.getInt(
- "conn." + Settings.Global.CONNECTIVITY_CHANGE_DELAY,
- ConnectivityManager.CONNECTIVITY_CHANGE_DELAY_DEFAULT);
- return Settings.Global.getInt(cr, Settings.Global.CONNECTIVITY_CHANGE_DELAY,
- defaultDelay);
- }
-
- private boolean teardown(NetworkStateTracker netTracker) {
- if (netTracker.teardown()) {
- netTracker.setTeardownRequested(true);
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * Check if UID should be blocked from using the network represented by the
- * given {@link NetworkStateTracker}.
- */
- private boolean isNetworkBlocked(int networkType, int uid) {
- final boolean networkCostly;
- final int uidRules;
-
- LinkProperties lp = getLinkPropertiesForType(networkType);
- final String iface = (lp == null ? "" : lp.getInterfaceName());
- synchronized (mRulesLock) {
- networkCostly = mMeteredIfaces.contains(iface);
- uidRules = mUidRules.get(uid, RULE_ALLOW_ALL);
- }
-
- if (networkCostly && (uidRules & RULE_REJECT_METERED) != 0) {
- return true;
- }
-
- // no restrictive rules; network is visible
- return false;
- }
-
- /**
- * Return a filtered {@link NetworkInfo}, potentially marked
- * {@link DetailedState#BLOCKED} based on
- * {@link #isNetworkBlocked}.
- */
- private NetworkInfo getFilteredNetworkInfo(int networkType, int uid) {
- NetworkInfo info = getNetworkInfoForType(networkType);
- if (isNetworkBlocked(networkType, uid)) {
- // network is blocked; clone and override state
- info = new NetworkInfo(info);
- info.setDetailedState(DetailedState.BLOCKED, null, null);
- }
- if (mLockdownTracker != null) {
- info = mLockdownTracker.augmentNetworkInfo(info);
- }
- return info;
- }
-
- /**
- * Return NetworkInfo for the active (i.e., connected) network interface.
- * It is assumed that at most one network is active at a time. If more
- * than one is active, it is indeterminate which will be returned.
- * @return the info for the active network, or {@code null} if none is
- * active
- */
- @Override
- public NetworkInfo getActiveNetworkInfo() {
- enforceAccessPermission();
- final int uid = Binder.getCallingUid();
- return getNetworkInfo(mActiveDefaultNetwork, uid);
- }
-
- // only called when the default request is satisfied
- private void updateActiveDefaultNetwork(NetworkAgentInfo nai) {
- if (nai != null) {
- mActiveDefaultNetwork = nai.networkInfo.getType();
- } else {
- mActiveDefaultNetwork = TYPE_NONE;
- }
- }
-
- /**
- * Find the first Provisioning network.
- *
- * @return NetworkInfo or null if none.
- */
- private NetworkInfo getProvisioningNetworkInfo() {
- enforceAccessPermission();
-
- // Find the first Provisioning Network
- NetworkInfo provNi = null;
- for (NetworkInfo ni : getAllNetworkInfo()) {
- if (ni.isConnectedToProvisioningNetwork()) {
- provNi = ni;
- break;
- }
- }
- if (DBG) log("getProvisioningNetworkInfo: X provNi=" + provNi);
- return provNi;
- }
-
- /**
- * Find the first Provisioning network or the ActiveDefaultNetwork
- * if there is no Provisioning network
- *
- * @return NetworkInfo or null if none.
- */
- @Override
- public NetworkInfo getProvisioningOrActiveNetworkInfo() {
- enforceAccessPermission();
-
- NetworkInfo provNi = getProvisioningNetworkInfo();
- if (provNi == null) {
- final int uid = Binder.getCallingUid();
- provNi = getNetworkInfo(mActiveDefaultNetwork, uid);
- }
- if (DBG) log("getProvisioningOrActiveNetworkInfo: X provNi=" + provNi);
- return provNi;
- }
-
- public NetworkInfo getActiveNetworkInfoUnfiltered() {
- enforceAccessPermission();
- if (isNetworkTypeValid(mActiveDefaultNetwork)) {
- return getNetworkInfoForType(mActiveDefaultNetwork);
- }
- return null;
- }
-
- @Override
- public NetworkInfo getActiveNetworkInfoForUid(int uid) {
- enforceConnectivityInternalPermission();
- return getNetworkInfo(mActiveDefaultNetwork, uid);
- }
-
- @Override
- public NetworkInfo getNetworkInfo(int networkType) {
- enforceAccessPermission();
- final int uid = Binder.getCallingUid();
- return getNetworkInfo(networkType, uid);
- }
-
- private NetworkInfo getNetworkInfo(int networkType, int uid) {
- NetworkInfo info = null;
- if (isNetworkTypeValid(networkType)) {
- if (getNetworkInfoForType(networkType) != null) {
- info = getFilteredNetworkInfo(networkType, uid);
- }
- }
- return info;
- }
-
- @Override
- public NetworkInfo[] getAllNetworkInfo() {
- enforceAccessPermission();
- final int uid = Binder.getCallingUid();
- final ArrayList<NetworkInfo> result = Lists.newArrayList();
- synchronized (mRulesLock) {
- for (int networkType = 0; networkType <= ConnectivityManager.MAX_NETWORK_TYPE;
- networkType++) {
- if (getNetworkInfoForType(networkType) != null) {
- result.add(getFilteredNetworkInfo(networkType, uid));
- }
- }
- }
- return result.toArray(new NetworkInfo[result.size()]);
- }
-
- @Override
- public boolean isNetworkSupported(int networkType) {
- enforceAccessPermission();
- return (isNetworkTypeValid(networkType) && (getNetworkInfoForType(networkType) != null));
- }
-
- /**
- * Return LinkProperties for the active (i.e., connected) default
- * network interface. It is assumed that at most one default network
- * is active at a time. If more than one is active, it is indeterminate
- * which will be returned.
- * @return the ip properties for the active network, or {@code null} if
- * none is active
- */
- @Override
- public LinkProperties getActiveLinkProperties() {
- return getLinkPropertiesForType(mActiveDefaultNetwork);
- }
-
- @Override
- public LinkProperties getLinkPropertiesForType(int networkType) {
- enforceAccessPermission();
- if (isNetworkTypeValid(networkType)) {
- return getLinkPropertiesForTypeInternal(networkType);
- }
- return null;
- }
-
- // TODO - this should be ALL networks
- @Override
- public LinkProperties getLinkProperties(Network network) {
- enforceAccessPermission();
- NetworkAgentInfo nai = mNetworkForNetId.get(network.netId);
- if (nai != null) return new LinkProperties(nai.linkProperties);
- return null;
- }
-
- @Override
- public NetworkCapabilities getNetworkCapabilities(Network network) {
- enforceAccessPermission();
- NetworkAgentInfo nai = mNetworkForNetId.get(network.netId);
- if (nai != null) return new NetworkCapabilities(nai.networkCapabilities);
- return null;
- }
-
- @Override
- public NetworkState[] getAllNetworkState() {
- enforceAccessPermission();
- final int uid = Binder.getCallingUid();
- final ArrayList<NetworkState> result = Lists.newArrayList();
- synchronized (mRulesLock) {
- for (int networkType = 0; networkType <= ConnectivityManager.MAX_NETWORK_TYPE;
- networkType++) {
- if (getNetworkInfoForType(networkType) != null) {
- final NetworkInfo info = getFilteredNetworkInfo(networkType, uid);
- final LinkProperties lp = getLinkPropertiesForTypeInternal(networkType);
- final NetworkCapabilities netcap = getNetworkCapabilitiesForType(networkType);
- result.add(new NetworkState(info, lp, netcap));
- }
- }
- }
- return result.toArray(new NetworkState[result.size()]);
- }
-
- private NetworkState getNetworkStateUnchecked(int networkType) {
- if (isNetworkTypeValid(networkType)) {
- NetworkInfo info = getNetworkInfoForType(networkType);
- if (info != null) {
- return new NetworkState(info,
- getLinkPropertiesForTypeInternal(networkType),
- getNetworkCapabilitiesForType(networkType));
- }
- }
- return null;
- }
-
- @Override
- public NetworkQuotaInfo getActiveNetworkQuotaInfo() {
- enforceAccessPermission();
-
- final long token = Binder.clearCallingIdentity();
- try {
- final NetworkState state = getNetworkStateUnchecked(mActiveDefaultNetwork);
- if (state != null) {
- try {
- return mPolicyManager.getNetworkQuotaInfo(state);
- } catch (RemoteException e) {
- }
- }
- return null;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- @Override
- public boolean isActiveNetworkMetered() {
- enforceAccessPermission();
- final long token = Binder.clearCallingIdentity();
- try {
- return isNetworkMeteredUnchecked(mActiveDefaultNetwork);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- private boolean isNetworkMeteredUnchecked(int networkType) {
- final NetworkState state = getNetworkStateUnchecked(networkType);
- if (state != null) {
- try {
- return mPolicyManager.isNetworkMetered(state);
- } catch (RemoteException e) {
- }
- }
- return false;
- }
-
- private INetworkManagementEventObserver mDataActivityObserver = new BaseNetworkObserver() {
- @Override
- public void interfaceClassDataActivityChanged(String label, boolean active, long tsNanos) {
- int deviceType = Integer.parseInt(label);
- sendDataActivityBroadcast(deviceType, active, tsNanos);
- }
- };
-
- /**
- * Used to notice when the calling process dies so we can self-expire
- *
- * Also used to know if the process has cleaned up after itself when
- * our auto-expire timer goes off. The timer has a link to an object.
- *
- */
- private class FeatureUser implements IBinder.DeathRecipient {
- int mNetworkType;
- String mFeature;
- IBinder mBinder;
- int mPid;
- int mUid;
- long mCreateTime;
-
- FeatureUser(int type, String feature, IBinder binder) {
- super();
- mNetworkType = type;
- mFeature = feature;
- mBinder = binder;
- mPid = getCallingPid();
- mUid = getCallingUid();
- mCreateTime = System.currentTimeMillis();
-
- try {
- mBinder.linkToDeath(this, 0);
- } catch (RemoteException e) {
- binderDied();
- }
- }
-
- void unlinkDeathRecipient() {
- mBinder.unlinkToDeath(this, 0);
- }
-
- public void binderDied() {
- log("ConnectivityService FeatureUser binderDied(" +
- mNetworkType + ", " + mFeature + ", " + mBinder + "), created " +
- (System.currentTimeMillis() - mCreateTime) + " mSec ago");
- stopUsingNetworkFeature(this, false);
- }
-
- public void expire() {
- if (VDBG) {
- log("ConnectivityService FeatureUser expire(" +
- mNetworkType + ", " + mFeature + ", " + mBinder +"), created " +
- (System.currentTimeMillis() - mCreateTime) + " mSec ago");
- }
- stopUsingNetworkFeature(this, false);
- }
-
- public boolean isSameUser(FeatureUser u) {
- if (u == null) return false;
-
- return isSameUser(u.mPid, u.mUid, u.mNetworkType, u.mFeature);
- }
-
- public boolean isSameUser(int pid, int uid, int networkType, String feature) {
- if ((mPid == pid) && (mUid == uid) && (mNetworkType == networkType) &&
- TextUtils.equals(mFeature, feature)) {
- return true;
- }
- return false;
- }
-
- public String toString() {
- return "FeatureUser("+mNetworkType+","+mFeature+","+mPid+","+mUid+"), created " +
- (System.currentTimeMillis() - mCreateTime) + " mSec ago";
- }
- }
-
- // javadoc from interface
- public int startUsingNetworkFeature(int networkType, String feature,
- IBinder binder) {
- long startTime = 0;
- if (DBG) {
- startTime = SystemClock.elapsedRealtime();
- }
- if (VDBG) {
- log("startUsingNetworkFeature for net " + networkType + ": " + feature + ", uid="
- + Binder.getCallingUid());
- }
- enforceChangePermission();
- try {
- if (!ConnectivityManager.isNetworkTypeValid(networkType) ||
- mNetConfigs[networkType] == null) {
- return PhoneConstants.APN_REQUEST_FAILED;
- }
-
- FeatureUser f = new FeatureUser(networkType, feature, binder);
-
- // TODO - move this into individual networktrackers
- int usedNetworkType = convertFeatureToNetworkType(networkType, feature);
-
- if (mLockdownEnabled) {
- // Since carrier APNs usually aren't available from VPN
- // endpoint, mark them as unavailable.
- return PhoneConstants.APN_TYPE_NOT_AVAILABLE;
- }
-
- if (mProtectedNetworks.contains(usedNetworkType)) {
- enforceConnectivityInternalPermission();
- }
-
- // if UID is restricted, don't allow them to bring up metered APNs
- final boolean networkMetered = isNetworkMeteredUnchecked(usedNetworkType);
- final int uidRules;
- synchronized (mRulesLock) {
- uidRules = mUidRules.get(Binder.getCallingUid(), RULE_ALLOW_ALL);
- }
- if (networkMetered && (uidRules & RULE_REJECT_METERED) != 0) {
- return PhoneConstants.APN_REQUEST_FAILED;
- }
-
- NetworkStateTracker network = mNetTrackers[usedNetworkType];
- if (network != null) {
- Integer currentPid = new Integer(getCallingPid());
- if (usedNetworkType != networkType) {
- NetworkInfo ni = network.getNetworkInfo();
-
- if (ni.isAvailable() == false) {
- if (!TextUtils.equals(feature,Phone.FEATURE_ENABLE_DUN_ALWAYS)) {
- if (DBG) log("special network not available ni=" + ni.getTypeName());
- return PhoneConstants.APN_TYPE_NOT_AVAILABLE;
- } else {
- // else make the attempt anyway - probably giving REQUEST_STARTED below
- if (DBG) {
- log("special network not available, but try anyway ni=" +
- ni.getTypeName());
- }
- }
- }
-
- int restoreTimer = getRestoreDefaultNetworkDelay(usedNetworkType);
-
- synchronized(this) {
- boolean addToList = true;
- if (restoreTimer < 0) {
- // In case there is no timer is specified for the feature,
- // make sure we don't add duplicate entry with the same request.
- for (FeatureUser u : mFeatureUsers) {
- if (u.isSameUser(f)) {
- // Duplicate user is found. Do not add.
- addToList = false;
- break;
- }
- }
- }
-
- if (addToList) mFeatureUsers.add(f);
- if (!mNetRequestersPids[usedNetworkType].contains(currentPid)) {
- // this gets used for per-pid dns when connected
- mNetRequestersPids[usedNetworkType].add(currentPid);
- }
- }
-
- if (restoreTimer >= 0) {
- mHandler.sendMessageDelayed(mHandler.obtainMessage(
- EVENT_RESTORE_DEFAULT_NETWORK, f), restoreTimer);
- }
-
- if ((ni.isConnectedOrConnecting() == true) &&
- !network.isTeardownRequested()) {
- if (ni.isConnected() == true) {
- final long token = Binder.clearCallingIdentity();
- try {
- // add the pid-specific dns
- handleDnsConfigurationChange(usedNetworkType);
- if (VDBG) log("special network already active");
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- return PhoneConstants.APN_ALREADY_ACTIVE;
- }
- if (VDBG) log("special network already connecting");
- return PhoneConstants.APN_REQUEST_STARTED;
- }
-
- // check if the radio in play can make another contact
- // assume if cannot for now
-
- if (DBG) {
- log("startUsingNetworkFeature reconnecting to " + networkType + ": " +
- feature);
- }
- if (network.reconnect()) {
- if (DBG) log("startUsingNetworkFeature X: return APN_REQUEST_STARTED");
- return PhoneConstants.APN_REQUEST_STARTED;
- } else {
- if (DBG) log("startUsingNetworkFeature X: return APN_REQUEST_FAILED");
- return PhoneConstants.APN_REQUEST_FAILED;
- }
- } else {
- // need to remember this unsupported request so we respond appropriately on stop
- synchronized(this) {
- mFeatureUsers.add(f);
- if (!mNetRequestersPids[usedNetworkType].contains(currentPid)) {
- // this gets used for per-pid dns when connected
- mNetRequestersPids[usedNetworkType].add(currentPid);
- }
- }
- if (DBG) log("startUsingNetworkFeature X: return -1 unsupported feature.");
- return -1;
- }
- }
- if (DBG) log("startUsingNetworkFeature X: return APN_TYPE_NOT_AVAILABLE");
- return PhoneConstants.APN_TYPE_NOT_AVAILABLE;
- } finally {
- if (DBG) {
- final long execTime = SystemClock.elapsedRealtime() - startTime;
- if (execTime > 250) {
- loge("startUsingNetworkFeature took too long: " + execTime + "ms");
- } else {
- if (VDBG) log("startUsingNetworkFeature took " + execTime + "ms");
- }
- }
- }
- }
-
- // javadoc from interface
- public int stopUsingNetworkFeature(int networkType, String feature) {
- enforceChangePermission();
-
- int pid = getCallingPid();
- int uid = getCallingUid();
-
- FeatureUser u = null;
- boolean found = false;
-
- synchronized(this) {
- for (FeatureUser x : mFeatureUsers) {
- if (x.isSameUser(pid, uid, networkType, feature)) {
- u = x;
- found = true;
- break;
- }
- }
- }
- if (found && u != null) {
- if (VDBG) log("stopUsingNetworkFeature: X");
- // stop regardless of how many other time this proc had called start
- return stopUsingNetworkFeature(u, true);
- } else {
- // none found!
- if (VDBG) log("stopUsingNetworkFeature: X not a live request, ignoring");
- return 1;
- }
- }
-
- private int stopUsingNetworkFeature(FeatureUser u, boolean ignoreDups) {
- int networkType = u.mNetworkType;
- String feature = u.mFeature;
- int pid = u.mPid;
- int uid = u.mUid;
-
- NetworkStateTracker tracker = null;
- boolean callTeardown = false; // used to carry our decision outside of sync block
-
- if (VDBG) {
- log("stopUsingNetworkFeature: net " + networkType + ": " + feature);
- }
-
- if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
- if (DBG) {
- log("stopUsingNetworkFeature: net " + networkType + ": " + feature +
- ", net is invalid");
- }
- return -1;
- }
-
- // need to link the mFeatureUsers list with the mNetRequestersPids state in this
- // sync block
- synchronized(this) {
- // check if this process still has an outstanding start request
- if (!mFeatureUsers.contains(u)) {
- if (VDBG) {
- log("stopUsingNetworkFeature: this process has no outstanding requests" +
- ", ignoring");
- }
- return 1;
- }
- u.unlinkDeathRecipient();
- mFeatureUsers.remove(mFeatureUsers.indexOf(u));
- // If we care about duplicate requests, check for that here.
- //
- // This is done to support the extension of a request - the app
- // can request we start the network feature again and renew the
- // auto-shutoff delay. Normal "stop" calls from the app though
- // do not pay attention to duplicate requests - in effect the
- // API does not refcount and a single stop will counter multiple starts.
- if (ignoreDups == false) {
- for (FeatureUser x : mFeatureUsers) {
- if (x.isSameUser(u)) {
- if (VDBG) log("stopUsingNetworkFeature: dup is found, ignoring");
- return 1;
- }
- }
- }
-
- // TODO - move to individual network trackers
- int usedNetworkType = convertFeatureToNetworkType(networkType, feature);
-
- tracker = mNetTrackers[usedNetworkType];
- if (tracker == null) {
- if (DBG) {
- log("stopUsingNetworkFeature: net " + networkType + ": " + feature +
- " no known tracker for used net type " + usedNetworkType);
- }
- return -1;
- }
- if (usedNetworkType != networkType) {
- Integer currentPid = new Integer(pid);
- mNetRequestersPids[usedNetworkType].remove(currentPid);
-
- final long token = Binder.clearCallingIdentity();
- try {
- reassessPidDns(pid, true);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- flushVmDnsCache();
- if (mNetRequestersPids[usedNetworkType].size() != 0) {
- if (VDBG) {
- log("stopUsingNetworkFeature: net " + networkType + ": " + feature +
- " others still using it");
- }
- return 1;
- }
- callTeardown = true;
- } else {
- if (DBG) {
- log("stopUsingNetworkFeature: net " + networkType + ": " + feature +
- " not a known feature - dropping");
- }
- }
- }
-
- if (callTeardown) {
- if (DBG) {
- log("stopUsingNetworkFeature: teardown net " + networkType + ": " + feature);
- }
- tracker.teardown();
- return 1;
- } else {
- return -1;
- }
- }
-
- /**
- * Check if the address falls into any of currently running VPN's route's.
- */
- private boolean isAddressUnderVpn(InetAddress address) {
- synchronized (mVpns) {
- synchronized (mRoutesLock) {
- int uid = UserHandle.getCallingUserId();
- Vpn vpn = mVpns.get(uid);
- if (vpn == null) {
- return false;
- }
-
- // Check if an exemption exists for this address.
- for (LinkAddress destination : mExemptAddresses) {
- if (!NetworkUtils.addressTypeMatches(address, destination.getAddress())) {
- continue;
- }
-
- int prefix = destination.getPrefixLength();
- InetAddress addrMasked = NetworkUtils.getNetworkPart(address, prefix);
- InetAddress destMasked = NetworkUtils.getNetworkPart(destination.getAddress(),
- prefix);
-
- if (addrMasked.equals(destMasked)) {
- return false;
- }
- }
-
- // Finally check if the address is covered by the VPN.
- return vpn.isAddressCovered(address);
- }
- }
- }
-
- /**
- * @deprecated use requestRouteToHostAddress instead
- *
- * Ensure that a network route exists to deliver traffic to the specified
- * host via the specified network interface.
- * @param networkType the type of the network over which traffic to the
- * specified host is to be routed
- * @param hostAddress the IP address of the host to which the route is
- * desired
- * @return {@code true} on success, {@code false} on failure
- */
- public boolean requestRouteToHost(int networkType, int hostAddress, String packageName) {
- InetAddress inetAddress = NetworkUtils.intToInetAddress(hostAddress);
-
- if (inetAddress == null) {
- return false;
- }
-
- return requestRouteToHostAddress(networkType, inetAddress.getAddress(), packageName);
- }
-
- /**
- * Ensure that a network route exists to deliver traffic to the specified
- * host via the specified network interface.
- * @param networkType the type of the network over which traffic to the
- * specified host is to be routed
- * @param hostAddress the IP address of the host to which the route is
- * desired
- * @return {@code true} on success, {@code false} on failure
- */
- public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress,
- String packageName) {
- enforceChangePermission();
- if (mProtectedNetworks.contains(networkType)) {
- enforceConnectivityInternalPermission();
- }
- boolean exempt;
- InetAddress addr;
- try {
- addr = InetAddress.getByAddress(hostAddress);
- } catch (UnknownHostException e) {
- if (DBG) log("requestRouteToHostAddress got " + e.toString());
- return false;
- }
- // System apps may request routes bypassing the VPN to keep other networks working.
- if (Binder.getCallingUid() == Process.SYSTEM_UID) {
- exempt = true;
- } else {
- mAppOpsManager.checkPackage(Binder.getCallingUid(), packageName);
- try {
- ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(packageName,
- 0);
- exempt = (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
- } catch (NameNotFoundException e) {
- throw new IllegalArgumentException("Failed to find calling package details", e);
- }
- }
-
- // Non-exempt routeToHost's can only be added if the host is not covered by the VPN.
- // This can be either because the VPN's routes do not cover the destination or a
- // system application added an exemption that covers this destination.
- if (!exempt && isAddressUnderVpn(addr)) {
- return false;
- }
-
- if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
- if (DBG) log("requestRouteToHostAddress on invalid network: " + networkType);
- return false;
- }
-
- NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
- if (nai == null) {
- if (mLegacyTypeTracker.isTypeSupported(networkType) == false) {
- if (DBG) log("requestRouteToHostAddress on unsupported network: " + networkType);
- } else {
- if (DBG) log("requestRouteToHostAddress on down network: " + networkType);
- }
- return false;
- }
-
- DetailedState netState = nai.networkInfo.getDetailedState();
-
- if ((netState != DetailedState.CONNECTED &&
- netState != DetailedState.CAPTIVE_PORTAL_CHECK)) {
- if (VDBG) {
- log("requestRouteToHostAddress on down network "
- + "(" + networkType + ") - dropped"
- + " netState=" + netState);
- }
- return false;
- }
- final int uid = Binder.getCallingUid();
- final long token = Binder.clearCallingIdentity();
- try {
- LinkProperties lp = nai.linkProperties;
- boolean ok = modifyRouteToAddress(lp, addr, ADD, TO_DEFAULT_TABLE, exempt,
- nai.network.netId, uid);
- if (DBG) log("requestRouteToHostAddress ok=" + ok);
- return ok;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- private boolean addRoute(LinkProperties p, RouteInfo r, boolean toDefaultTable,
- boolean exempt, int netId) {
- return modifyRoute(p, r, 0, ADD, toDefaultTable, exempt, netId, false, UID_UNUSED);
- }
-
- private boolean removeRoute(LinkProperties p, RouteInfo r, boolean toDefaultTable, int netId) {
- return modifyRoute(p, r, 0, REMOVE, toDefaultTable, UNEXEMPT, netId, false, UID_UNUSED);
- }
-
- private boolean modifyRouteToAddress(LinkProperties lp, InetAddress addr, boolean doAdd,
- boolean toDefaultTable, boolean exempt, int netId, int uid) {
- RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getAllRoutes(), addr);
- if (bestRoute == null) {
- bestRoute = RouteInfo.makeHostRoute(addr, lp.getInterfaceName());
- } else {
- String iface = bestRoute.getInterface();
- if (bestRoute.getGateway().equals(addr)) {
- // if there is no better route, add the implied hostroute for our gateway
- bestRoute = RouteInfo.makeHostRoute(addr, iface);
- } else {
- // if we will connect to this through another route, add a direct route
- // to it's gateway
- bestRoute = RouteInfo.makeHostRoute(addr, bestRoute.getGateway(), iface);
- }
- }
- return modifyRoute(lp, bestRoute, 0, doAdd, toDefaultTable, exempt, netId, true, uid);
- }
-
- /*
- * TODO: Clean all this stuff up. Once we have UID-based routing, stuff will break due to
- * incorrect tracking of mAddedRoutes, so a cleanup becomes necessary and urgent. But at
- * the same time, there'll be no more need to track mAddedRoutes or mExemptAddresses,
- * or even have the concept of an exempt address, or do things like "selectBestRoute", or
- * determine "default" vs "secondary" table, etc., so the cleanup becomes possible.
- */
- private boolean modifyRoute(LinkProperties lp, RouteInfo r, int cycleCount, boolean doAdd,
- boolean toDefaultTable, boolean exempt, int netId, boolean legacy, int uid) {
- if ((lp == null) || (r == null)) {
- if (DBG) log("modifyRoute got unexpected null: " + lp + ", " + r);
- return false;
- }
-
- if (cycleCount > MAX_HOSTROUTE_CYCLE_COUNT) {
- loge("Error modifying route - too much recursion");
- return false;
- }
-
- String ifaceName = r.getInterface();
- if(ifaceName == null) {
- loge("Error modifying route - no interface name");
- return false;
- }
- if (r.hasGateway()) {
- RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getAllRoutes(), r.getGateway());
- if (bestRoute != null) {
- if (bestRoute.getGateway().equals(r.getGateway())) {
- // if there is no better route, add the implied hostroute for our gateway
- bestRoute = RouteInfo.makeHostRoute(r.getGateway(), ifaceName);
- } else {
- // if we will connect to our gateway through another route, add a direct
- // route to it's gateway
- bestRoute = RouteInfo.makeHostRoute(r.getGateway(),
- bestRoute.getGateway(),
- ifaceName);
- }
- modifyRoute(lp, bestRoute, cycleCount+1, doAdd, toDefaultTable, exempt, netId,
- legacy, uid);
- }
- }
- if (doAdd) {
- if (VDBG) log("Adding " + r + " for interface " + ifaceName);
- try {
- if (toDefaultTable) {
- synchronized (mRoutesLock) {
- // only track default table - only one apps can effect
- mAddedRoutes.add(r);
- if (legacy) {
- mNetd.addLegacyRouteForNetId(netId, r, uid);
- } else {
- mNetd.addRoute(netId, r);
- }
- if (exempt) {
- LinkAddress dest = r.getDestinationLinkAddress();
- if (!mExemptAddresses.contains(dest)) {
- mNetd.setHostExemption(dest);
- mExemptAddresses.add(dest);
- }
- }
- }
- } else {
- if (legacy) {
- mNetd.addLegacyRouteForNetId(netId, r, uid);
- } else {
- mNetd.addRoute(netId, r);
- }
- }
- } catch (Exception e) {
- // never crash - catch them all
- if (DBG) loge("Exception trying to add a route: " + e);
- return false;
- }
- } else {
- // if we remove this one and there are no more like it, then refcount==0 and
- // we can remove it from the table
- if (toDefaultTable) {
- synchronized (mRoutesLock) {
- mAddedRoutes.remove(r);
- if (mAddedRoutes.contains(r) == false) {
- if (VDBG) log("Removing " + r + " for interface " + ifaceName);
- try {
- if (legacy) {
- mNetd.removeLegacyRouteForNetId(netId, r, uid);
- } else {
- mNetd.removeRoute(netId, r);
- }
- LinkAddress dest = r.getDestinationLinkAddress();
- if (mExemptAddresses.contains(dest)) {
- mNetd.clearHostExemption(dest);
- mExemptAddresses.remove(dest);
- }
- } catch (Exception e) {
- // never crash - catch them all
- if (VDBG) loge("Exception trying to remove a route: " + e);
- return false;
- }
- } else {
- if (VDBG) log("not removing " + r + " as it's still in use");
- }
- }
- } else {
- if (VDBG) log("Removing " + r + " for interface " + ifaceName);
- try {
- if (legacy) {
- mNetd.removeLegacyRouteForNetId(netId, r, uid);
- } else {
- mNetd.removeRoute(netId, r);
- }
- } catch (Exception e) {
- // never crash - catch them all
- if (VDBG) loge("Exception trying to remove a route: " + e);
- return false;
- }
- }
- }
- return true;
- }
-
- public void setDataDependency(int networkType, boolean met) {
- enforceConnectivityInternalPermission();
-
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_DEPENDENCY_MET,
- (met ? ENABLED : DISABLED), networkType));
- }
-
- private void handleSetDependencyMet(int networkType, boolean met) {
- if (mNetTrackers[networkType] != null) {
- if (DBG) {
- log("handleSetDependencyMet(" + networkType + ", " + met + ")");
- }
- mNetTrackers[networkType].setDependencyMet(met);
- }
- }
-
- private INetworkPolicyListener mPolicyListener = new INetworkPolicyListener.Stub() {
- @Override
- public void onUidRulesChanged(int uid, int uidRules) {
- // caller is NPMS, since we only register with them
- if (LOGD_RULES) {
- log("onUidRulesChanged(uid=" + uid + ", uidRules=" + uidRules + ")");
- }
-
- synchronized (mRulesLock) {
- // skip update when we've already applied rules
- final int oldRules = mUidRules.get(uid, RULE_ALLOW_ALL);
- if (oldRules == uidRules) return;
-
- mUidRules.put(uid, uidRules);
- }
-
- // TODO: notify UID when it has requested targeted updates
- }
-
- @Override
- public void onMeteredIfacesChanged(String[] meteredIfaces) {
- // caller is NPMS, since we only register with them
- if (LOGD_RULES) {
- log("onMeteredIfacesChanged(ifaces=" + Arrays.toString(meteredIfaces) + ")");
- }
-
- synchronized (mRulesLock) {
- mMeteredIfaces.clear();
- for (String iface : meteredIfaces) {
- mMeteredIfaces.add(iface);
- }
- }
- }
-
- @Override
- public void onRestrictBackgroundChanged(boolean restrictBackground) {
- // caller is NPMS, since we only register with them
- if (LOGD_RULES) {
- log("onRestrictBackgroundChanged(restrictBackground=" + restrictBackground + ")");
- }
-
- // kick off connectivity change broadcast for active network, since
- // global background policy change is radical.
- final int networkType = mActiveDefaultNetwork;
- if (isNetworkTypeValid(networkType)) {
- final NetworkStateTracker tracker = mNetTrackers[networkType];
- if (tracker != null) {
- final NetworkInfo info = tracker.getNetworkInfo();
- if (info != null && info.isConnected()) {
- sendConnectedBroadcast(info);
- }
- }
- }
- }
- };
-
- @Override
- public void setPolicyDataEnable(int networkType, boolean enabled) {
- // only someone like NPMS should only be calling us
- mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
-
- mHandler.sendMessage(mHandler.obtainMessage(
- EVENT_SET_POLICY_DATA_ENABLE, networkType, (enabled ? ENABLED : DISABLED)));
- }
-
- private void handleSetPolicyDataEnable(int networkType, boolean enabled) {
- // TODO - handle this passing to factories
-// if (isNetworkTypeValid(networkType)) {
-// final NetworkStateTracker tracker = mNetTrackers[networkType];
-// if (tracker != null) {
-// tracker.setPolicyDataEnable(enabled);
-// }
-// }
- }
-
- private void enforceAccessPermission() {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.ACCESS_NETWORK_STATE,
- "ConnectivityService");
- }
-
- private void enforceChangePermission() {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.CHANGE_NETWORK_STATE,
- "ConnectivityService");
- }
-
- // TODO Make this a special check when it goes public
- private void enforceTetherChangePermission() {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.CHANGE_NETWORK_STATE,
- "ConnectivityService");
- }
-
- private void enforceTetherAccessPermission() {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.ACCESS_NETWORK_STATE,
- "ConnectivityService");
- }
-
- private void enforceConnectivityInternalPermission() {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.CONNECTIVITY_INTERNAL,
- "ConnectivityService");
- }
-
- private void enforceMarkNetworkSocketPermission() {
- //Media server special case
- if (Binder.getCallingUid() == Process.MEDIA_UID) {
- return;
- }
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.MARK_NETWORK_SOCKET,
- "ConnectivityService");
- }
-
- /**
- * Handle a {@code DISCONNECTED} event. If this pertains to the non-active
- * network, we ignore it. If it is for the active network, we send out a
- * broadcast. But first, we check whether it might be possible to connect
- * to a different network.
- * @param info the {@code NetworkInfo} for the network
- */
- private void handleDisconnect(NetworkInfo info) {
-
- int prevNetType = info.getType();
-
- mNetTrackers[prevNetType].setTeardownRequested(false);
- int thisNetId = mNetTrackers[prevNetType].getNetwork().netId;
-
- // Remove idletimer previously setup in {@code handleConnect}
-// Already in place in new function. This is dead code.
-// if (mNetConfigs[prevNetType].isDefault()) {
-// removeDataActivityTracking(prevNetType);
-// }
-
- /*
- * If the disconnected network is not the active one, then don't report
- * this as a loss of connectivity. What probably happened is that we're
- * getting the disconnect for a network that we explicitly disabled
- * in accordance with network preference policies.
- */
- if (!mNetConfigs[prevNetType].isDefault()) {
- List<Integer> pids = mNetRequestersPids[prevNetType];
- for (Integer pid : pids) {
- // will remove them because the net's no longer connected
- // need to do this now as only now do we know the pids and
- // can properly null things that are no longer referenced.
- reassessPidDns(pid.intValue(), false);
- }
- }
-
- Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION);
- intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, new NetworkInfo(info));
- intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType());
- if (info.isFailover()) {
- intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
- info.setFailover(false);
- }
- if (info.getReason() != null) {
- intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason());
- }
- if (info.getExtraInfo() != null) {
- intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO,
- info.getExtraInfo());
- }
-
- if (mNetConfigs[prevNetType].isDefault()) {
- tryFailover(prevNetType);
- if (mActiveDefaultNetwork != -1) {
- NetworkInfo switchTo = mNetTrackers[mActiveDefaultNetwork].getNetworkInfo();
- intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO, switchTo);
- } else {
- mDefaultInetConditionPublished = 0; // we're not connected anymore
- intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
- }
- }
- intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished);
-
- // Reset interface if no other connections are using the same interface
- boolean doReset = true;
- LinkProperties linkProperties = mNetTrackers[prevNetType].getLinkProperties();
- if (linkProperties != null) {
- String oldIface = linkProperties.getInterfaceName();
- if (TextUtils.isEmpty(oldIface) == false) {
- for (NetworkStateTracker networkStateTracker : mNetTrackers) {
- if (networkStateTracker == null) continue;
- NetworkInfo networkInfo = networkStateTracker.getNetworkInfo();
- if (networkInfo.isConnected() && networkInfo.getType() != prevNetType) {
- LinkProperties l = networkStateTracker.getLinkProperties();
- if (l == null) continue;
- if (oldIface.equals(l.getInterfaceName())) {
- doReset = false;
- break;
- }
- }
- }
- }
- }
-
- // do this before we broadcast the change
-// Already done in new function. This is dead code.
-// handleConnectivityChange(prevNetType, doReset);
-
- final Intent immediateIntent = new Intent(intent);
- immediateIntent.setAction(CONNECTIVITY_ACTION_IMMEDIATE);
- sendStickyBroadcast(immediateIntent);
- sendStickyBroadcastDelayed(intent, getConnectivityChangeDelay());
- /*
- * If the failover network is already connected, then immediately send
- * out a followup broadcast indicating successful failover
- */
- if (mActiveDefaultNetwork != -1) {
- sendConnectedBroadcastDelayed(mNetTrackers[mActiveDefaultNetwork].getNetworkInfo(),
- getConnectivityChangeDelay());
- }
- try {
-// mNetd.removeNetwork(thisNetId);
- } catch (Exception e) {
- loge("Exception removing network: " + e);
- } finally {
- mNetTrackers[prevNetType].setNetId(INVALID_NET_ID);
- }
- }
-
- private void tryFailover(int prevNetType) {
- /*
- * If this is a default network, check if other defaults are available.
- * Try to reconnect on all available and let them hash it out when
- * more than one connects.
- */
- if (mNetConfigs[prevNetType].isDefault()) {
- if (mActiveDefaultNetwork == prevNetType) {
- if (DBG) {
- log("tryFailover: set mActiveDefaultNetwork=-1, prevNetType=" + prevNetType);
- }
- mActiveDefaultNetwork = -1;
- try {
- mNetd.clearDefaultNetId();
- } catch (Exception e) {
- loge("Exception clearing default network :" + e);
- }
- }
-
- // don't signal a reconnect for anything lower or equal priority than our
- // current connected default
- // TODO - don't filter by priority now - nice optimization but risky
-// int currentPriority = -1;
-// if (mActiveDefaultNetwork != -1) {
-// currentPriority = mNetConfigs[mActiveDefaultNetwork].mPriority;
-// }
-
- for (int checkType=0; checkType <= ConnectivityManager.MAX_NETWORK_TYPE; checkType++) {
- if (checkType == prevNetType) continue;
- if (mNetConfigs[checkType] == null) continue;
- if (!mNetConfigs[checkType].isDefault()) continue;
- if (mNetTrackers[checkType] == null) continue;
-
-// Enabling the isAvailable() optimization caused mobile to not get
-// selected if it was in the middle of error handling. Specifically
-// a moble connection that took 30 seconds to complete the DEACTIVATE_DATA_CALL
-// would not be available and we wouldn't get connected to anything.
-// So removing the isAvailable() optimization below for now. TODO: This
-// optimization should work and we need to investigate why it doesn't work.
-// This could be related to how DEACTIVATE_DATA_CALL is reporting its
-// complete before it is really complete.
-
-// if (!mNetTrackers[checkType].isAvailable()) continue;
-
-// if (currentPriority >= mNetConfigs[checkType].mPriority) continue;
-
- NetworkStateTracker checkTracker = mNetTrackers[checkType];
- NetworkInfo checkInfo = checkTracker.getNetworkInfo();
- if (!checkInfo.isConnectedOrConnecting() || checkTracker.isTeardownRequested()) {
- checkInfo.setFailover(true);
- checkTracker.reconnect();
- }
- if (DBG) log("Attempting to switch to " + checkInfo.getTypeName());
- }
- }
- }
-
- public void sendConnectedBroadcast(NetworkInfo info) {
- enforceConnectivityInternalPermission();
- sendGeneralBroadcast(info, CONNECTIVITY_ACTION_IMMEDIATE);
- sendGeneralBroadcast(info, CONNECTIVITY_ACTION);
- }
-
- private void sendConnectedBroadcastDelayed(NetworkInfo info, int delayMs) {
- sendGeneralBroadcast(info, CONNECTIVITY_ACTION_IMMEDIATE);
- sendGeneralBroadcastDelayed(info, CONNECTIVITY_ACTION, delayMs);
- }
-
- private void sendInetConditionBroadcast(NetworkInfo info) {
- sendGeneralBroadcast(info, ConnectivityManager.INET_CONDITION_ACTION);
- }
-
- private Intent makeGeneralIntent(NetworkInfo info, String bcastType) {
- if (mLockdownTracker != null) {
- info = mLockdownTracker.augmentNetworkInfo(info);
- }
-
- Intent intent = new Intent(bcastType);
- intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, new NetworkInfo(info));
- intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType());
- if (info.isFailover()) {
- intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
- info.setFailover(false);
- }
- if (info.getReason() != null) {
- intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason());
- }
- if (info.getExtraInfo() != null) {
- intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO,
- info.getExtraInfo());
- }
- intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished);
- return intent;
- }
-
- private void sendGeneralBroadcast(NetworkInfo info, String bcastType) {
- sendStickyBroadcast(makeGeneralIntent(info, bcastType));
- }
-
- private void sendGeneralBroadcastDelayed(NetworkInfo info, String bcastType, int delayMs) {
- sendStickyBroadcastDelayed(makeGeneralIntent(info, bcastType), delayMs);
- }
-
- private void sendDataActivityBroadcast(int deviceType, boolean active, long tsNanos) {
- Intent intent = new Intent(ConnectivityManager.ACTION_DATA_ACTIVITY_CHANGE);
- intent.putExtra(ConnectivityManager.EXTRA_DEVICE_TYPE, deviceType);
- intent.putExtra(ConnectivityManager.EXTRA_IS_ACTIVE, active);
- intent.putExtra(ConnectivityManager.EXTRA_REALTIME_NS, tsNanos);
- final long ident = Binder.clearCallingIdentity();
- try {
- mContext.sendOrderedBroadcastAsUser(intent, UserHandle.ALL,
- RECEIVE_DATA_ACTIVITY_CHANGE, null, null, 0, null, null);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- private void sendStickyBroadcast(Intent intent) {
- synchronized(this) {
- if (!mSystemReady) {
- mInitialBroadcast = new Intent(intent);
- }
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- if (VDBG) {
- log("sendStickyBroadcast: action=" + intent.getAction());
- }
-
- final long ident = Binder.clearCallingIdentity();
- try {
- mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
- }
-
- private void sendStickyBroadcastDelayed(Intent intent, int delayMs) {
- if (delayMs <= 0) {
- sendStickyBroadcast(intent);
- } else {
- if (VDBG) {
- log("sendStickyBroadcastDelayed: delayMs=" + delayMs + ", action="
- + intent.getAction());
- }
- mHandler.sendMessageDelayed(mHandler.obtainMessage(
- EVENT_SEND_STICKY_BROADCAST_INTENT, intent), delayMs);
- }
- }
-
- void systemReady() {
- mCaptivePortalTracker = CaptivePortalTracker.makeCaptivePortalTracker(mContext, this);
- loadGlobalProxy();
-
- synchronized(this) {
- mSystemReady = true;
- if (mInitialBroadcast != null) {
- mContext.sendStickyBroadcastAsUser(mInitialBroadcast, UserHandle.ALL);
- mInitialBroadcast = null;
- }
- }
- // load the global proxy at startup
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_APPLY_GLOBAL_HTTP_PROXY));
-
- // Try bringing up tracker, but if KeyStore isn't ready yet, wait
- // for user to unlock device.
- if (!updateLockdownVpn()) {
- final IntentFilter filter = new IntentFilter(Intent.ACTION_USER_PRESENT);
- mContext.registerReceiver(mUserPresentReceiver, filter);
- }
- }
-
- private BroadcastReceiver mUserPresentReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- // Try creating lockdown tracker, since user present usually means
- // unlocked keystore.
- if (updateLockdownVpn()) {
- mContext.unregisterReceiver(this);
- }
- }
- };
-
- private boolean isNewNetTypePreferredOverCurrentNetType(int type) {
- if (((type != mNetworkPreference)
- && (mNetConfigs[mActiveDefaultNetwork].priority > mNetConfigs[type].priority))
- || (mNetworkPreference == mActiveDefaultNetwork)) {
- return false;
- }
- return true;
- }
-
- private void handleConnect(NetworkInfo info) {
- final int newNetType = info.getType();
-
- // snapshot isFailover, because sendConnectedBroadcast() resets it
- boolean isFailover = info.isFailover();
- final NetworkStateTracker thisNet = mNetTrackers[newNetType];
- final String thisIface = thisNet.getLinkProperties().getInterfaceName();
-
- if (VDBG) {
- log("handleConnect: E newNetType=" + newNetType + " thisIface=" + thisIface
- + " isFailover" + isFailover);
- }
-
- // if this is a default net and other default is running
- // kill the one not preferred
- if (mNetConfigs[newNetType].isDefault()) {
- if (mActiveDefaultNetwork != -1 && mActiveDefaultNetwork != newNetType) {
- if (isNewNetTypePreferredOverCurrentNetType(newNetType)) {
- String teardownPolicy = SystemProperties.get("net.teardownPolicy");
- if (TextUtils.equals(teardownPolicy, "keep") == false) {
- // tear down the other
- NetworkStateTracker otherNet =
- mNetTrackers[mActiveDefaultNetwork];
- if (DBG) {
- log("Policy requires " + otherNet.getNetworkInfo().getTypeName() +
- " teardown");
- }
- if (!teardown(otherNet)) {
- loge("Network declined teardown request");
- teardown(thisNet);
- return;
- }
- } else {
- //TODO - remove
- loge("network teardown skipped due to net.teardownPolicy setting");
- }
- } else {
- // don't accept this one
- if (VDBG) {
- log("Not broadcasting CONNECT_ACTION " +
- "to torn down network " + info.getTypeName());
- }
- teardown(thisNet);
- return;
- }
- }
- int thisNetId = nextNetId();
- thisNet.setNetId(thisNetId);
- try {
-// mNetd.createNetwork(thisNetId, thisIface);
- } catch (Exception e) {
- loge("Exception creating network :" + e);
- teardown(thisNet);
- return;
- }
-// Already in place in new function. This is dead code.
-// setupDataActivityTracking(newNetType);
- synchronized (ConnectivityService.this) {
- // have a new default network, release the transition wakelock in a second
- // if it's held. The second pause is to allow apps to reconnect over the
- // new network
- if (mNetTransitionWakeLock.isHeld()) {
- mHandler.sendMessageDelayed(mHandler.obtainMessage(
- EVENT_CLEAR_NET_TRANSITION_WAKELOCK,
- mNetTransitionWakeLockSerialNumber, 0),
- 1000);
- }
- }
- mActiveDefaultNetwork = newNetType;
- try {
- mNetd.setDefaultNetId(thisNetId);
- } catch (Exception e) {
- loge("Exception setting default network :" + e);
- }
- // this will cause us to come up initially as unconnected and switching
- // to connected after our normal pause unless somebody reports us as reall
- // disconnected
- mDefaultInetConditionPublished = 0;
- mDefaultConnectionSequence++;
- mInetConditionChangeInFlight = false;
- // Don't do this - if we never sign in stay, grey
- //reportNetworkCondition(mActiveDefaultNetwork, 100);
- updateNetworkSettings(thisNet);
- } else {
- int thisNetId = nextNetId();
- thisNet.setNetId(thisNetId);
- try {
-// mNetd.createNetwork(thisNetId, thisIface);
- } catch (Exception e) {
- loge("Exception creating network :" + e);
- teardown(thisNet);
- return;
- }
- }
- thisNet.setTeardownRequested(false);
-// Already in place in new function. This is dead code.
-// updateMtuSizeSettings(thisNet);
-// handleConnectivityChange(newNetType, false);
- sendConnectedBroadcastDelayed(info, getConnectivityChangeDelay());
-
- // notify battery stats service about this network
- if (thisIface != null) {
- try {
- BatteryStatsService.getService().noteNetworkInterfaceType(thisIface, newNetType);
- } catch (RemoteException e) {
- // ignored; service lives in system_server
- }
- }
- }
-
- /** @hide */
- @Override
- public void captivePortalCheckCompleted(NetworkInfo info, boolean isCaptivePortal) {
- enforceConnectivityInternalPermission();
- if (DBG) log("captivePortalCheckCompleted: ni=" + info + " captive=" + isCaptivePortal);
-// mNetTrackers[info.getType()].captivePortalCheckCompleted(isCaptivePortal);
- }
-
- /**
- * Setup data activity tracking for the given network.
- *
- * Every {@code setupDataActivityTracking} should be paired with a
- * {@link #removeDataActivityTracking} for cleanup.
- */
- private void setupDataActivityTracking(NetworkAgentInfo networkAgent) {
- final String iface = networkAgent.linkProperties.getInterfaceName();
-
- final int timeout;
- int type = ConnectivityManager.TYPE_NONE;
-
- if (networkAgent.networkCapabilities.hasTransport(
- NetworkCapabilities.TRANSPORT_CELLULAR)) {
- timeout = Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.DATA_ACTIVITY_TIMEOUT_MOBILE,
- 5);
- type = ConnectivityManager.TYPE_MOBILE;
- } else if (networkAgent.networkCapabilities.hasTransport(
- NetworkCapabilities.TRANSPORT_WIFI)) {
- timeout = Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.DATA_ACTIVITY_TIMEOUT_WIFI,
- 0);
- type = ConnectivityManager.TYPE_WIFI;
- } else {
- // do not track any other networks
- timeout = 0;
- }
-
- if (timeout > 0 && iface != null && type != ConnectivityManager.TYPE_NONE) {
- try {
- mNetd.addIdleTimer(iface, timeout, type);
- } catch (Exception e) {
- // You shall not crash!
- loge("Exception in setupDataActivityTracking " + e);
- }
- }
- }
-
- /**
- * Remove data activity tracking when network disconnects.
- */
- private void removeDataActivityTracking(NetworkAgentInfo networkAgent) {
- final String iface = networkAgent.linkProperties.getInterfaceName();
- final NetworkCapabilities caps = networkAgent.networkCapabilities;
-
- if (iface != null && (caps.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) ||
- caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI))) {
- try {
- // the call fails silently if no idletimer setup for this interface
- mNetd.removeIdleTimer(iface);
- } catch (Exception e) {
- loge("Exception in removeDataActivityTracking " + e);
- }
- }
- }
-
- /**
- * After a change in the connectivity state of a network. We're mainly
- * concerned with making sure that the list of DNS servers is set up
- * according to which networks are connected, and ensuring that the
- * right routing table entries exist.
- *
- * TODO - delete when we're sure all this functionallity is captured.
- */
- private void handleConnectivityChange(int netType, LinkProperties curLp, boolean doReset) {
- int resetMask = doReset ? NetworkUtils.RESET_ALL_ADDRESSES : 0;
- boolean exempt = ConnectivityManager.isNetworkTypeExempt(netType);
- if (VDBG) {
- log("handleConnectivityChange: netType=" + netType + " doReset=" + doReset
- + " resetMask=" + resetMask);
- }
-
- /*
- * If a non-default network is enabled, add the host routes that
- * will allow it's DNS servers to be accessed.
- */
- handleDnsConfigurationChange(netType);
-
- LinkProperties newLp = null;
-
- if (mNetTrackers[netType].getNetworkInfo().isConnected()) {
- newLp = mNetTrackers[netType].getLinkProperties();
- if (VDBG) {
- log("handleConnectivityChange: changed linkProperty[" + netType + "]:" +
- " doReset=" + doReset + " resetMask=" + resetMask +
- "\n curLp=" + curLp +
- "\n newLp=" + newLp);
- }
-
- if (curLp != null) {
- if (curLp.isIdenticalInterfaceName(newLp)) {
- CompareResult<LinkAddress> car = curLp.compareAddresses(newLp);
- if ((car.removed.size() != 0) || (car.added.size() != 0)) {
- for (LinkAddress linkAddr : car.removed) {
- if (linkAddr.getAddress() instanceof Inet4Address) {
- resetMask |= NetworkUtils.RESET_IPV4_ADDRESSES;
- }
- if (linkAddr.getAddress() instanceof Inet6Address) {
- resetMask |= NetworkUtils.RESET_IPV6_ADDRESSES;
- }
- }
- if (DBG) {
- log("handleConnectivityChange: addresses changed" +
- " linkProperty[" + netType + "]:" + " resetMask=" + resetMask +
- "\n car=" + car);
- }
- } else {
- if (VDBG) {
- log("handleConnectivityChange: addresses are the same reset per" +
- " doReset linkProperty[" + netType + "]:" +
- " resetMask=" + resetMask);
- }
- }
- } else {
- resetMask = NetworkUtils.RESET_ALL_ADDRESSES;
- if (DBG) {
- log("handleConnectivityChange: interface not not equivalent reset both" +
- " linkProperty[" + netType + "]:" +
- " resetMask=" + resetMask);
- }
- }
- }
- if (mNetConfigs[netType].isDefault()) {
- handleApplyDefaultProxy(newLp.getHttpProxy());
- }
- } else {
- if (VDBG) {
- log("handleConnectivityChange: changed linkProperty[" + netType + "]:" +
- " doReset=" + doReset + " resetMask=" + resetMask +
- "\n curLp=" + curLp +
- "\n newLp= null");
- }
- }
- mCurrentLinkProperties[netType] = newLp;
- boolean resetDns = updateRoutes(newLp, curLp, mNetConfigs[netType].isDefault(), exempt,
- mNetTrackers[netType].getNetwork().netId);
-
- if (resetMask != 0 || resetDns) {
- if (VDBG) log("handleConnectivityChange: resetting");
- if (curLp != null) {
- if (VDBG) log("handleConnectivityChange: resetting curLp=" + curLp);
- for (String iface : curLp.getAllInterfaceNames()) {
- if (TextUtils.isEmpty(iface) == false) {
- if (resetMask != 0) {
- if (DBG) log("resetConnections(" + iface + ", " + resetMask + ")");
- NetworkUtils.resetConnections(iface, resetMask);
-
- // Tell VPN the interface is down. It is a temporary
- // but effective fix to make VPN aware of the change.
- if ((resetMask & NetworkUtils.RESET_IPV4_ADDRESSES) != 0) {
- synchronized(mVpns) {
- for (int i = 0; i < mVpns.size(); i++) {
- mVpns.valueAt(i).interfaceStatusChanged(iface, false);
- }
- }
- }
- }
- } else {
- loge("Can't reset connection for type "+netType);
- }
- }
- if (resetDns) {
- flushVmDnsCache();
- if (VDBG) log("resetting DNS cache for type " + netType);
- try {
- mNetd.flushNetworkDnsCache(mNetTrackers[netType].getNetwork().netId);
- } catch (Exception e) {
- // never crash - catch them all
- if (DBG) loge("Exception resetting dns cache: " + e);
- }
- }
- }
- }
-
- // TODO: Temporary notifying upstread change to Tethering.
- // @see bug/4455071
- /** Notify TetheringService if interface name has been changed. */
- if (TextUtils.equals(mNetTrackers[netType].getNetworkInfo().getReason(),
- PhoneConstants.REASON_LINK_PROPERTIES_CHANGED)) {
- if (isTetheringSupported()) {
- mTethering.handleTetherIfaceChange();
- }
- }
- }
-
- /**
- * Add and remove routes using the old properties (null if not previously connected),
- * new properties (null if becoming disconnected). May even be double null, which
- * is a noop.
- * Uses isLinkDefault to determine if default routes should be set or conversely if
- * host routes should be set to the dns servers
- * returns a boolean indicating the routes changed
- */
- private boolean updateRoutes(LinkProperties newLp, LinkProperties curLp,
- boolean isLinkDefault, boolean exempt, int netId) {
- Collection<RouteInfo> routesToAdd = null;
- CompareResult<InetAddress> dnsDiff = new CompareResult<InetAddress>();
- CompareResult<RouteInfo> routeDiff = new CompareResult<RouteInfo>();
- if (curLp != null) {
- // check for the delta between the current set and the new
- routeDiff = curLp.compareAllRoutes(newLp);
- dnsDiff = curLp.compareDnses(newLp);
- } else if (newLp != null) {
- routeDiff.added = newLp.getAllRoutes();
- dnsDiff.added = newLp.getDnsServers();
- }
-
- boolean routesChanged = (routeDiff.removed.size() != 0 || routeDiff.added.size() != 0);
-
- for (RouteInfo r : routeDiff.removed) {
- if (isLinkDefault || ! r.isDefaultRoute()) {
- if (VDBG) log("updateRoutes: default remove route r=" + r);
- removeRoute(curLp, r, TO_DEFAULT_TABLE, netId);
- }
- if (isLinkDefault == false) {
- // remove from a secondary route table
- removeRoute(curLp, r, TO_SECONDARY_TABLE, netId);
- }
- }
-
- for (RouteInfo r : routeDiff.added) {
- if (isLinkDefault || ! r.isDefaultRoute()) {
- addRoute(newLp, r, TO_DEFAULT_TABLE, exempt, netId);
- } else {
- // add to a secondary route table
- addRoute(newLp, r, TO_SECONDARY_TABLE, UNEXEMPT, netId);
-
- // many radios add a default route even when we don't want one.
- // remove the default route unless somebody else has asked for it
- String ifaceName = newLp.getInterfaceName();
- synchronized (mRoutesLock) {
- if (!TextUtils.isEmpty(ifaceName) && !mAddedRoutes.contains(r)) {
- if (VDBG) log("Removing " + r + " for interface " + ifaceName);
- try {
- mNetd.removeRoute(netId, r);
- } catch (Exception e) {
- // never crash - catch them all
- if (DBG) loge("Exception trying to remove a route: " + e);
- }
- }
- }
- }
- }
-
- return routesChanged;
- }
-
- /**
- * Reads the network specific MTU size from reources.
- * and set it on it's iface.
- */
- private void updateMtu(LinkProperties newLp, LinkProperties oldLp) {
- final String iface = newLp.getInterfaceName();
- final int mtu = newLp.getMtu();
- if (oldLp != null && newLp.isIdenticalMtu(oldLp)) {
- if (VDBG) log("identical MTU - not setting");
- return;
- }
-
- if (mtu < 68 || mtu > 10000) {
- loge("Unexpected mtu value: " + mtu + ", " + iface);
- return;
- }
-
- try {
- if (VDBG) log("Setting MTU size: " + iface + ", " + mtu);
- mNetd.setMtu(iface, mtu);
- } catch (Exception e) {
- Slog.e(TAG, "exception in setMtu()" + e);
- }
- }
-
- /**
- * Reads the network specific TCP buffer sizes from SystemProperties
- * net.tcp.buffersize.[default|wifi|umts|edge|gprs] and set them for system
- * wide use
- */
- private void updateNetworkSettings(NetworkStateTracker nt) {
- String key = nt.getTcpBufferSizesPropName();
- String bufferSizes = key == null ? null : SystemProperties.get(key);
-
- if (TextUtils.isEmpty(bufferSizes)) {
- if (VDBG) log(key + " not found in system properties. Using defaults");
-
- // Setting to default values so we won't be stuck to previous values
- key = "net.tcp.buffersize.default";
- bufferSizes = SystemProperties.get(key);
- }
-
- // Set values in kernel
- if (bufferSizes.length() != 0) {
- if (VDBG) {
- log("Setting TCP values: [" + bufferSizes
- + "] which comes from [" + key + "]");
- }
- setBufferSize(bufferSizes);
- }
-
- final String defaultRwndKey = "net.tcp.default_init_rwnd";
- int defaultRwndValue = SystemProperties.getInt(defaultRwndKey, 0);
- Integer rwndValue = Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.TCP_DEFAULT_INIT_RWND, defaultRwndValue);
- final String sysctlKey = "sys.sysctl.tcp_def_init_rwnd";
- if (rwndValue != 0) {
- SystemProperties.set(sysctlKey, rwndValue.toString());
- }
- }
-
- /**
- * Writes TCP buffer sizes to /sys/kernel/ipv4/tcp_[r/w]mem_[min/def/max]
- * which maps to /proc/sys/net/ipv4/tcp_rmem and tcpwmem
- *
- * @param bufferSizes in the format of "readMin, readInitial, readMax,
- * writeMin, writeInitial, writeMax"
- */
- private void setBufferSize(String bufferSizes) {
- try {
- String[] values = bufferSizes.split(",");
-
- if (values.length == 6) {
- final String prefix = "/sys/kernel/ipv4/tcp_";
- FileUtils.stringToFile(prefix + "rmem_min", values[0]);
- FileUtils.stringToFile(prefix + "rmem_def", values[1]);
- FileUtils.stringToFile(prefix + "rmem_max", values[2]);
- FileUtils.stringToFile(prefix + "wmem_min", values[3]);
- FileUtils.stringToFile(prefix + "wmem_def", values[4]);
- FileUtils.stringToFile(prefix + "wmem_max", values[5]);
- } else {
- loge("Invalid buffersize string: " + bufferSizes);
- }
- } catch (IOException e) {
- loge("Can't set tcp buffer sizes:" + e);
- }
- }
-
- /**
- * Adjust the per-process dns entries (net.dns<x>.<pid>) based
- * on the highest priority active net which this process requested.
- * If there aren't any, clear it out
- */
- private void reassessPidDns(int pid, boolean doBump)
- {
- if (VDBG) log("reassessPidDns for pid " + pid);
- Integer myPid = new Integer(pid);
- for(int i : mPriorityList) {
- if (mNetConfigs[i].isDefault()) {
- continue;
- }
- NetworkStateTracker nt = mNetTrackers[i];
- if (nt.getNetworkInfo().isConnected() &&
- !nt.isTeardownRequested()) {
- LinkProperties p = nt.getLinkProperties();
- if (p == null) continue;
- if (mNetRequestersPids[i].contains(myPid)) {
- try {
- // TODO: Reimplement this via local variable in bionic.
- // mNetd.setDnsNetworkForPid(nt.getNetwork().netId, pid);
- } catch (Exception e) {
- Slog.e(TAG, "exception reasseses pid dns: " + e);
- }
- return;
- }
- }
- }
- // nothing found - delete
- try {
- // TODO: Reimplement this via local variable in bionic.
- // mNetd.clearDnsNetworkForPid(pid);
- } catch (Exception e) {
- Slog.e(TAG, "exception clear interface from pid: " + e);
- }
- }
-
- private void flushVmDnsCache() {
- /*
- * Tell the VMs to toss their DNS caches
- */
- Intent intent = new Intent(Intent.ACTION_CLEAR_DNS_CACHE);
- intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
- /*
- * Connectivity events can happen before boot has completed ...
- */
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- final long ident = Binder.clearCallingIdentity();
- try {
- mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- // Caller must grab mDnsLock.
- private void updateDnsLocked(String network, int netId,
- Collection<InetAddress> dnses, String domains) {
- int last = 0;
- if (dnses.size() == 0 && mDefaultDns != null) {
- dnses = new ArrayList();
- dnses.add(mDefaultDns);
- if (DBG) {
- loge("no dns provided for " + network + " - using " + mDefaultDns.getHostAddress());
- }
- }
-
- try {
- mNetd.setDnsServersForNetwork(netId, NetworkUtils.makeStrings(dnses), domains);
-
- for (InetAddress dns : dnses) {
- ++last;
- String key = "net.dns" + last;
- String value = dns.getHostAddress();
- SystemProperties.set(key, value);
- }
- for (int i = last + 1; i <= mNumDnsEntries; ++i) {
- String key = "net.dns" + i;
- SystemProperties.set(key, "");
- }
- mNumDnsEntries = last;
- } catch (Exception e) {
- loge("exception setting default dns interface: " + e);
- }
- }
-
- private void handleDnsConfigurationChange(int netType) {
- // add default net's dns entries
- NetworkStateTracker nt = mNetTrackers[netType];
- if (nt != null && nt.getNetworkInfo().isConnected() && !nt.isTeardownRequested()) {
- LinkProperties p = nt.getLinkProperties();
- if (p == null) return;
- Collection<InetAddress> dnses = p.getDnsServers();
- int netId = nt.getNetwork().netId;
- if (mNetConfigs[netType].isDefault()) {
- String network = nt.getNetworkInfo().getTypeName();
- synchronized (mDnsLock) {
- updateDnsLocked(network, netId, dnses, p.getDomains());
- }
- } else {
- try {
- mNetd.setDnsServersForNetwork(netId,
- NetworkUtils.makeStrings(dnses), p.getDomains());
- } catch (Exception e) {
- if (DBG) loge("exception setting dns servers: " + e);
- }
- // set per-pid dns for attached secondary nets
- List<Integer> pids = mNetRequestersPids[netType];
- for (Integer pid : pids) {
- try {
- // TODO: Reimplement this via local variable in bionic.
- // mNetd.setDnsNetworkForPid(netId, pid);
- } catch (Exception e) {
- Slog.e(TAG, "exception setting interface for pid: " + e);
- }
- }
- }
- flushVmDnsCache();
- }
- }
-
- @Override
- public int getRestoreDefaultNetworkDelay(int networkType) {
- String restoreDefaultNetworkDelayStr = SystemProperties.get(
- NETWORK_RESTORE_DELAY_PROP_NAME);
- if(restoreDefaultNetworkDelayStr != null &&
- restoreDefaultNetworkDelayStr.length() != 0) {
- try {
- return Integer.valueOf(restoreDefaultNetworkDelayStr);
- } catch (NumberFormatException e) {
- }
- }
- // if the system property isn't set, use the value for the apn type
- int ret = RESTORE_DEFAULT_NETWORK_DELAY;
-
- if ((networkType <= ConnectivityManager.MAX_NETWORK_TYPE) &&
- (mNetConfigs[networkType] != null)) {
- ret = mNetConfigs[networkType].restoreTime;
- }
- return ret;
- }
-
- @Override
- protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
- final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
- if (mContext.checkCallingOrSelfPermission(
- android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump ConnectivityService " +
- "from from pid=" + Binder.getCallingPid() + ", uid=" +
- Binder.getCallingUid());
- return;
- }
-
- pw.println("NetworkFactories for:");
- pw.increaseIndent();
- for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
- pw.println(nfi.name);
- }
- pw.decreaseIndent();
- pw.println();
-
- NetworkAgentInfo defaultNai = mNetworkForRequestId.get(mDefaultRequest.requestId);
- pw.print("Active default network: ");
- if (defaultNai == null) {
- pw.println("none");
- } else {
- pw.println(defaultNai.network.netId);
- }
- pw.println();
-
- pw.println("Current Networks:");
- pw.increaseIndent();
- for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
- pw.println(nai.toString());
- pw.increaseIndent();
- pw.println("Requests:");
- pw.increaseIndent();
- for (int i = 0; i < nai.networkRequests.size(); i++) {
- pw.println(nai.networkRequests.valueAt(i).toString());
- }
- pw.decreaseIndent();
- pw.println("Lingered:");
- pw.increaseIndent();
- for (NetworkRequest nr : nai.networkLingered) pw.println(nr.toString());
- pw.decreaseIndent();
- pw.decreaseIndent();
- }
- pw.decreaseIndent();
- pw.println();
-
- pw.println("Network Requests:");
- pw.increaseIndent();
- for (NetworkRequestInfo nri : mNetworkRequests.values()) {
- pw.println(nri.toString());
- }
- pw.println();
- pw.decreaseIndent();
-
- synchronized (this) {
- pw.println("NetworkTranstionWakeLock is currently " +
- (mNetTransitionWakeLock.isHeld() ? "" : "not ") + "held.");
- pw.println("It was last requested for "+mNetTransitionWakeLockCausedBy);
- }
- pw.println();
-
- mTethering.dump(fd, pw, args);
-
- if (mInetLog != null) {
- pw.println();
- pw.println("Inet condition reports:");
- pw.increaseIndent();
- for(int i = 0; i < mInetLog.size(); i++) {
- pw.println(mInetLog.get(i));
- }
- pw.decreaseIndent();
- }
- }
-
- // must be stateless - things change under us.
- private class NetworkStateTrackerHandler extends Handler {
- public NetworkStateTrackerHandler(Looper looper) {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message msg) {
- NetworkInfo info;
- switch (msg.what) {
- case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: {
- handleAsyncChannelHalfConnect(msg);
- break;
- }
- case AsyncChannel.CMD_CHANNEL_DISCONNECT: {
- NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
- if (nai != null) nai.asyncChannel.disconnect();
- break;
- }
- case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
- handleAsyncChannelDisconnected(msg);
- break;
- }
- case NetworkAgent.EVENT_NETWORK_CAPABILITIES_CHANGED: {
- NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
- if (nai == null) {
- loge("EVENT_NETWORK_CAPABILITIES_CHANGED from unknown NetworkAgent");
- } else {
- updateCapabilities(nai, (NetworkCapabilities)msg.obj);
- }
- break;
- }
- case NetworkAgent.EVENT_NETWORK_PROPERTIES_CHANGED: {
- NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
- if (nai == null) {
- loge("NetworkAgent not found for EVENT_NETWORK_PROPERTIES_CHANGED");
- } else {
- if (VDBG) log("Update of Linkproperties for " + nai.name());
- LinkProperties oldLp = nai.linkProperties;
- nai.linkProperties = (LinkProperties)msg.obj;
- updateLinkProperties(nai, oldLp);
- }
- break;
- }
- case NetworkAgent.EVENT_NETWORK_INFO_CHANGED: {
- NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
- if (nai == null) {
- loge("EVENT_NETWORK_INFO_CHANGED from unknown NetworkAgent");
- break;
- }
- info = (NetworkInfo) msg.obj;
- updateNetworkInfo(nai, info);
- break;
- }
- case NetworkAgent.EVENT_NETWORK_SCORE_CHANGED: {
- NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
- if (nai == null) {
- loge("EVENT_NETWORK_SCORE_CHANGED from unknown NetworkAgent");
- break;
- }
- Integer score = (Integer) msg.obj;
- if (score != null) updateNetworkScore(nai, score.intValue());
- break;
- }
- case NetworkMonitor.EVENT_NETWORK_VALIDATED: {
- NetworkAgentInfo nai = (NetworkAgentInfo)msg.obj;
- handleConnectionValidated(nai);
- break;
- }
- case NetworkMonitor.EVENT_NETWORK_LINGER_COMPLETE: {
- NetworkAgentInfo nai = (NetworkAgentInfo)msg.obj;
- handleLingerComplete(nai);
- break;
- }
- case NetworkStateTracker.EVENT_STATE_CHANGED: {
- info = (NetworkInfo) msg.obj;
- NetworkInfo.State state = info.getState();
-
- if (VDBG || (state == NetworkInfo.State.CONNECTED) ||
- (state == NetworkInfo.State.DISCONNECTED) ||
- (state == NetworkInfo.State.SUSPENDED)) {
- log("ConnectivityChange for " +
- info.getTypeName() + ": " +
- state + "/" + info.getDetailedState());
- }
-
- // Since mobile has the notion of a network/apn that can be used for
- // provisioning we need to check every time we're connected as
- // CaptiveProtalTracker won't detected it because DCT doesn't report it
- // as connected as ACTION_ANY_DATA_CONNECTION_STATE_CHANGED instead its
- // reported as ACTION_DATA_CONNECTION_CONNECTED_TO_PROVISIONING_APN. Which
- // is received by MDST and sent here as EVENT_STATE_CHANGED.
- if (ConnectivityManager.isNetworkTypeMobile(info.getType())
- && (0 != Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.DEVICE_PROVISIONED, 0))
- && (((state == NetworkInfo.State.CONNECTED)
- && (info.getType() == ConnectivityManager.TYPE_MOBILE))
- || info.isConnectedToProvisioningNetwork())) {
- log("ConnectivityChange checkMobileProvisioning for"
- + " TYPE_MOBILE or ProvisioningNetwork");
- checkMobileProvisioning(CheckMp.MAX_TIMEOUT_MS);
- }
-
- EventLogTags.writeConnectivityStateChanged(
- info.getType(), info.getSubtype(), info.getDetailedState().ordinal());
-
- if (info.isConnectedToProvisioningNetwork()) {
- /**
- * TODO: Create ConnectivityManager.TYPE_MOBILE_PROVISIONING
- * for now its an in between network, its a network that
- * is actually a default network but we don't want it to be
- * announced as such to keep background applications from
- * trying to use it. It turns out that some still try so we
- * take the additional step of clearing any default routes
- * to the link that may have incorrectly setup by the lower
- * levels.
- */
- LinkProperties lp = getLinkPropertiesForTypeInternal(info.getType());
- if (DBG) {
- log("EVENT_STATE_CHANGED: connected to provisioning network, lp=" + lp);
- }
-
- // Clear any default routes setup by the radio so
- // any activity by applications trying to use this
- // connection will fail until the provisioning network
- // is enabled.
- for (RouteInfo r : lp.getRoutes()) {
- removeRoute(lp, r, TO_DEFAULT_TABLE,
- mNetTrackers[info.getType()].getNetwork().netId);
- }
- } else if (state == NetworkInfo.State.DISCONNECTED) {
- } else if (state == NetworkInfo.State.SUSPENDED) {
- } else if (state == NetworkInfo.State.CONNECTED) {
- // handleConnect(info);
- }
- if (mLockdownTracker != null) {
- mLockdownTracker.onNetworkInfoChanged(info);
- }
- break;
- }
- case NetworkStateTracker.EVENT_CONFIGURATION_CHANGED: {
- info = (NetworkInfo) msg.obj;
- // TODO: Temporary allowing network configuration
- // change not resetting sockets.
- // @see bug/4455071
- handleConnectivityChange(info.getType(), mCurrentLinkProperties[info.getType()],
- false);
- break;
- }
- case NetworkStateTracker.EVENT_NETWORK_SUBTYPE_CHANGED: {
- info = (NetworkInfo) msg.obj;
- int type = info.getType();
- if (mNetConfigs[type].isDefault()) updateNetworkSettings(mNetTrackers[type]);
- break;
- }
- }
- }
- }
-
- private void handleAsyncChannelHalfConnect(Message msg) {
- AsyncChannel ac = (AsyncChannel) msg.obj;
- if (mNetworkFactoryInfos.containsKey(msg.replyTo)) {
- if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
- if (VDBG) log("NetworkFactory connected");
- // A network factory has connected. Send it all current NetworkRequests.
- for (NetworkRequestInfo nri : mNetworkRequests.values()) {
- if (nri.isRequest == false) continue;
- NetworkAgentInfo nai = mNetworkForRequestId.get(nri.request.requestId);
- ac.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK,
- (nai != null ? nai.currentScore : 0), 0, nri.request);
- }
- } else {
- loge("Error connecting NetworkFactory");
- mNetworkFactoryInfos.remove(msg.obj);
- }
- } else if (mNetworkAgentInfos.containsKey(msg.replyTo)) {
- if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
- if (VDBG) log("NetworkAgent connected");
- // A network agent has requested a connection. Establish the connection.
- mNetworkAgentInfos.get(msg.replyTo).asyncChannel.
- sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
- } else {
- loge("Error connecting NetworkAgent");
- NetworkAgentInfo nai = mNetworkAgentInfos.remove(msg.replyTo);
- if (nai != null) {
- mNetworkForNetId.remove(nai.network.netId);
- mLegacyTypeTracker.remove(nai);
- }
- }
- }
- }
- private void handleAsyncChannelDisconnected(Message msg) {
- NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
- if (nai != null) {
- if (DBG) {
- log(nai.name() + " got DISCONNECTED, was satisfying " + nai.networkRequests.size());
- }
- // A network agent has disconnected.
- // Tell netd to clean up the configuration for this network
- // (routing rules, DNS, etc).
- try {
- mNetd.removeNetwork(nai.network.netId);
- } catch (Exception e) {
- loge("Exception removing network: " + e);
- }
- // TODO - if we move the logic to the network agent (have them disconnect
- // because they lost all their requests or because their score isn't good)
- // then they would disconnect organically, report their new state and then
- // disconnect the channel.
- if (nai.networkInfo.isConnected()) {
- nai.networkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED,
- null, null);
- }
- notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOST);
- nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_DISCONNECTED);
- mNetworkAgentInfos.remove(msg.replyTo);
- updateClat(null, nai.linkProperties, nai);
- mLegacyTypeTracker.remove(nai);
- mNetworkForNetId.remove(nai.network.netId);
- // Since we've lost the network, go through all the requests that
- // it was satisfying and see if any other factory can satisfy them.
- final ArrayList<NetworkAgentInfo> toActivate = new ArrayList<NetworkAgentInfo>();
- for (int i = 0; i < nai.networkRequests.size(); i++) {
- NetworkRequest request = nai.networkRequests.valueAt(i);
- NetworkAgentInfo currentNetwork = mNetworkForRequestId.get(request.requestId);
- if (VDBG) {
- log(" checking request " + request + ", currentNetwork = " +
- (currentNetwork != null ? currentNetwork.name() : "null"));
- }
- if (currentNetwork != null && currentNetwork.network.netId == nai.network.netId) {
- mNetworkForRequestId.remove(request.requestId);
- sendUpdatedScoreToFactories(request, 0);
- NetworkAgentInfo alternative = null;
- for (Map.Entry entry : mNetworkAgentInfos.entrySet()) {
- NetworkAgentInfo existing = (NetworkAgentInfo)entry.getValue();
- if (existing.networkInfo.isConnected() &&
- request.networkCapabilities.satisfiedByNetworkCapabilities(
- existing.networkCapabilities) &&
- (alternative == null ||
- alternative.currentScore < existing.currentScore)) {
- alternative = existing;
- }
- }
- if (alternative != null && !toActivate.contains(alternative)) {
- toActivate.add(alternative);
- }
- }
- }
- if (nai.networkRequests.get(mDefaultRequest.requestId) != null) {
- removeDataActivityTracking(nai);
- mActiveDefaultNetwork = ConnectivityManager.TYPE_NONE;
- }
- for (NetworkAgentInfo networkToActivate : toActivate) {
- networkToActivate.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_CONNECTED);
- }
- }
- }
-
- private void handleRegisterNetworkRequest(Message msg) {
- final NetworkRequestInfo nri = (NetworkRequestInfo) (msg.obj);
- final NetworkCapabilities newCap = nri.request.networkCapabilities;
- int score = 0;
-
- // Check for the best currently alive network that satisfies this request
- NetworkAgentInfo bestNetwork = null;
- for (NetworkAgentInfo network : mNetworkAgentInfos.values()) {
- if (VDBG) log("handleRegisterNetworkRequest checking " + network.name());
- if (newCap.satisfiedByNetworkCapabilities(network.networkCapabilities)) {
- if (VDBG) log("apparently satisfied. currentScore=" + network.currentScore);
- if ((bestNetwork == null) || bestNetwork.currentScore < network.currentScore) {
- bestNetwork = network;
- }
- }
- }
- if (bestNetwork != null) {
- if (VDBG) log("using " + bestNetwork.name());
- bestNetwork.addRequest(nri.request);
- mNetworkForRequestId.put(nri.request.requestId, bestNetwork);
- int legacyType = nri.request.legacyType;
- if (legacyType != TYPE_NONE) {
- mLegacyTypeTracker.add(legacyType, bestNetwork);
- }
- notifyNetworkCallback(bestNetwork, nri);
- score = bestNetwork.currentScore;
- }
- mNetworkRequests.put(nri.request, nri);
- if (msg.what == EVENT_REGISTER_NETWORK_REQUEST) {
- if (DBG) log("sending new NetworkRequest to factories");
- for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
- nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, score,
- 0, nri.request);
- }
- }
- }
-
- private void handleReleaseNetworkRequest(NetworkRequest request) {
- if (DBG) log("releasing NetworkRequest " + request);
- NetworkRequestInfo nri = mNetworkRequests.remove(request);
- if (nri != null) {
- // tell the network currently servicing this that it's no longer interested
- NetworkAgentInfo affectedNetwork = mNetworkForRequestId.get(nri.request.requestId);
- if (affectedNetwork != null) {
- mNetworkForRequestId.remove(nri.request.requestId);
- affectedNetwork.networkRequests.remove(nri.request.requestId);
- if (VDBG) {
- log(" Removing from current network " + affectedNetwork.name() + ", leaving " +
- affectedNetwork.networkRequests.size() + " requests.");
- }
- }
-
- if (nri.isRequest) {
- for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
- nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_CANCEL_REQUEST,
- nri.request);
- }
-
- if (affectedNetwork != null) {
- // check if this network still has live requests - otherwise, tear down
- // TODO - probably push this to the NF/NA
- boolean keep = false;
- for (int i = 0; i < affectedNetwork.networkRequests.size(); i++) {
- NetworkRequest r = affectedNetwork.networkRequests.valueAt(i);
- if (mNetworkRequests.get(r).isRequest) {
- keep = true;
- break;
- }
- }
- if (keep == false) {
- if (DBG) log("no live requests for " + affectedNetwork.name() +
- "; disconnecting");
- affectedNetwork.asyncChannel.disconnect();
- }
- }
- }
- callCallbackForRequest(nri, null, ConnectivityManager.CALLBACK_RELEASED);
- }
- }
-
- private class InternalHandler extends Handler {
- public InternalHandler(Looper looper) {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message msg) {
- NetworkInfo info;
- switch (msg.what) {
- case EVENT_CLEAR_NET_TRANSITION_WAKELOCK: {
- String causedBy = null;
- synchronized (ConnectivityService.this) {
- if (msg.arg1 == mNetTransitionWakeLockSerialNumber &&
- mNetTransitionWakeLock.isHeld()) {
- mNetTransitionWakeLock.release();
- causedBy = mNetTransitionWakeLockCausedBy;
- }
- }
- if (causedBy != null) {
- log("NetTransition Wakelock for " + causedBy + " released by timeout");
- }
- break;
- }
- case EVENT_RESTORE_DEFAULT_NETWORK: {
- FeatureUser u = (FeatureUser)msg.obj;
- u.expire();
- break;
- }
- case EVENT_INET_CONDITION_CHANGE: {
- int netType = msg.arg1;
- int condition = msg.arg2;
- handleInetConditionChange(netType, condition);
- break;
- }
- case EVENT_INET_CONDITION_HOLD_END: {
- int netType = msg.arg1;
- int sequence = msg.arg2;
- handleInetConditionHoldEnd(netType, sequence);
- break;
- }
- case EVENT_APPLY_GLOBAL_HTTP_PROXY: {
- handleDeprecatedGlobalHttpProxy();
- break;
- }
- case EVENT_SET_DEPENDENCY_MET: {
- boolean met = (msg.arg1 == ENABLED);
- handleSetDependencyMet(msg.arg2, met);
- break;
- }
- case EVENT_SEND_STICKY_BROADCAST_INTENT: {
- Intent intent = (Intent)msg.obj;
- sendStickyBroadcast(intent);
- break;
- }
- case EVENT_SET_POLICY_DATA_ENABLE: {
- final int networkType = msg.arg1;
- final boolean enabled = msg.arg2 == ENABLED;
- handleSetPolicyDataEnable(networkType, enabled);
- break;
- }
- case EVENT_VPN_STATE_CHANGED: {
- if (mLockdownTracker != null) {
- mLockdownTracker.onVpnStateChanged((NetworkInfo) msg.obj);
- }
- break;
- }
- case EVENT_ENABLE_FAIL_FAST_MOBILE_DATA: {
- int tag = mEnableFailFastMobileDataTag.get();
- if (msg.arg1 == tag) {
- MobileDataStateTracker mobileDst =
- (MobileDataStateTracker) mNetTrackers[ConnectivityManager.TYPE_MOBILE];
- if (mobileDst != null) {
- mobileDst.setEnableFailFastMobileData(msg.arg2);
- }
- } else {
- log("EVENT_ENABLE_FAIL_FAST_MOBILE_DATA: stale arg1:" + msg.arg1
- + " != tag:" + tag);
- }
- break;
- }
- case EVENT_SAMPLE_INTERVAL_ELAPSED: {
- handleNetworkSamplingTimeout();
- break;
- }
- case EVENT_PROXY_HAS_CHANGED: {
- handleApplyDefaultProxy((ProxyInfo)msg.obj);
- break;
- }
- case EVENT_REGISTER_NETWORK_FACTORY: {
- handleRegisterNetworkFactory((NetworkFactoryInfo)msg.obj);
- break;
- }
- case EVENT_UNREGISTER_NETWORK_FACTORY: {
- handleUnregisterNetworkFactory((Messenger)msg.obj);
- break;
- }
- case EVENT_REGISTER_NETWORK_AGENT: {
- handleRegisterNetworkAgent((NetworkAgentInfo)msg.obj);
- break;
- }
- case EVENT_REGISTER_NETWORK_REQUEST:
- case EVENT_REGISTER_NETWORK_LISTENER: {
- handleRegisterNetworkRequest(msg);
- break;
- }
- case EVENT_RELEASE_NETWORK_REQUEST: {
- handleReleaseNetworkRequest((NetworkRequest) msg.obj);
- break;
- }
- }
- }
- }
-
- // javadoc from interface
- public int tether(String iface) {
- enforceTetherChangePermission();
-
- if (isTetheringSupported()) {
- return mTethering.tether(iface);
- } else {
- return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
- }
- }
-
- // javadoc from interface
- public int untether(String iface) {
- enforceTetherChangePermission();
-
- if (isTetheringSupported()) {
- return mTethering.untether(iface);
- } else {
- return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
- }
- }
-
- // javadoc from interface
- public int getLastTetherError(String iface) {
- enforceTetherAccessPermission();
-
- if (isTetheringSupported()) {
- return mTethering.getLastTetherError(iface);
- } else {
- return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
- }
- }
-
- // TODO - proper iface API for selection by property, inspection, etc
- public String[] getTetherableUsbRegexs() {
- enforceTetherAccessPermission();
- if (isTetheringSupported()) {
- return mTethering.getTetherableUsbRegexs();
- } else {
- return new String[0];
- }
- }
-
- public String[] getTetherableWifiRegexs() {
- enforceTetherAccessPermission();
- if (isTetheringSupported()) {
- return mTethering.getTetherableWifiRegexs();
- } else {
- return new String[0];
- }
- }
-
- public String[] getTetherableBluetoothRegexs() {
- enforceTetherAccessPermission();
- if (isTetheringSupported()) {
- return mTethering.getTetherableBluetoothRegexs();
- } else {
- return new String[0];
- }
- }
-
- public int setUsbTethering(boolean enable) {
- enforceTetherChangePermission();
- if (isTetheringSupported()) {
- return mTethering.setUsbTethering(enable);
- } else {
- return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
- }
- }
-
- // TODO - move iface listing, queries, etc to new module
- // javadoc from interface
- public String[] getTetherableIfaces() {
- enforceTetherAccessPermission();
- return mTethering.getTetherableIfaces();
- }
-
- public String[] getTetheredIfaces() {
- enforceTetherAccessPermission();
- return mTethering.getTetheredIfaces();
- }
-
- public String[] getTetheringErroredIfaces() {
- enforceTetherAccessPermission();
- return mTethering.getErroredIfaces();
- }
-
- // if ro.tether.denied = true we default to no tethering
- // gservices could set the secure setting to 1 though to enable it on a build where it
- // had previously been turned off.
- public boolean isTetheringSupported() {
- enforceTetherAccessPermission();
- int defaultVal = (SystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1);
- boolean tetherEnabledInSettings = (Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.TETHER_SUPPORTED, defaultVal) != 0);
- return tetherEnabledInSettings && ((mTethering.getTetherableUsbRegexs().length != 0 ||
- mTethering.getTetherableWifiRegexs().length != 0 ||
- mTethering.getTetherableBluetoothRegexs().length != 0) &&
- mTethering.getUpstreamIfaceTypes().length != 0);
- }
-
- // An API NetworkStateTrackers can call when they lose their network.
- // This will automatically be cleared after X seconds or a network becomes CONNECTED,
- // whichever happens first. The timer is started by the first caller and not
- // restarted by subsequent callers.
- public void requestNetworkTransitionWakelock(String forWhom) {
- enforceConnectivityInternalPermission();
- synchronized (this) {
- if (mNetTransitionWakeLock.isHeld()) return;
- mNetTransitionWakeLockSerialNumber++;
- mNetTransitionWakeLock.acquire();
- mNetTransitionWakeLockCausedBy = forWhom;
- }
- mHandler.sendMessageDelayed(mHandler.obtainMessage(
- EVENT_CLEAR_NET_TRANSITION_WAKELOCK,
- mNetTransitionWakeLockSerialNumber, 0),
- mNetTransitionWakeLockTimeout);
- return;
- }
-
- // 100 percent is full good, 0 is full bad.
- public void reportInetCondition(int networkType, int percentage) {
- if (VDBG) log("reportNetworkCondition(" + networkType + ", " + percentage + ")");
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.STATUS_BAR,
- "ConnectivityService");
-
- if (DBG) {
- int pid = getCallingPid();
- int uid = getCallingUid();
- String s = pid + "(" + uid + ") reports inet is " +
- (percentage > 50 ? "connected" : "disconnected") + " (" + percentage + ") on " +
- "network Type " + networkType + " at " + GregorianCalendar.getInstance().getTime();
- mInetLog.add(s);
- while(mInetLog.size() > INET_CONDITION_LOG_MAX_SIZE) {
- mInetLog.remove(0);
- }
- }
- mHandler.sendMessage(mHandler.obtainMessage(
- EVENT_INET_CONDITION_CHANGE, networkType, percentage));
- }
-
- public void reportBadNetwork(Network network) {
- //TODO
- }
-
- private void handleInetConditionChange(int netType, int condition) {
- if (mActiveDefaultNetwork == -1) {
- if (DBG) log("handleInetConditionChange: no active default network - ignore");
- return;
- }
- if (mActiveDefaultNetwork != netType) {
- if (DBG) log("handleInetConditionChange: net=" + netType +
- " != default=" + mActiveDefaultNetwork + " - ignore");
- return;
- }
- if (VDBG) {
- log("handleInetConditionChange: net=" +
- netType + ", condition=" + condition +
- ",mActiveDefaultNetwork=" + mActiveDefaultNetwork);
- }
- mDefaultInetCondition = condition;
- int delay;
- if (mInetConditionChangeInFlight == false) {
- if (VDBG) log("handleInetConditionChange: starting a change hold");
- // setup a new hold to debounce this
- if (mDefaultInetCondition > 50) {
- delay = Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.INET_CONDITION_DEBOUNCE_UP_DELAY, 500);
- } else {
- delay = Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.INET_CONDITION_DEBOUNCE_DOWN_DELAY, 3000);
- }
- mInetConditionChangeInFlight = true;
- mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_INET_CONDITION_HOLD_END,
- mActiveDefaultNetwork, mDefaultConnectionSequence), delay);
- } else {
- // we've set the new condition, when this hold ends that will get picked up
- if (VDBG) log("handleInetConditionChange: currently in hold - not setting new end evt");
- }
- }
-
- private void handleInetConditionHoldEnd(int netType, int sequence) {
- if (DBG) {
- log("handleInetConditionHoldEnd: net=" + netType +
- ", condition=" + mDefaultInetCondition +
- ", published condition=" + mDefaultInetConditionPublished);
- }
- mInetConditionChangeInFlight = false;
-
- if (mActiveDefaultNetwork == -1) {
- if (DBG) log("handleInetConditionHoldEnd: no active default network - ignoring");
- return;
- }
- if (mDefaultConnectionSequence != sequence) {
- if (DBG) log("handleInetConditionHoldEnd: event hold for obsolete network - ignoring");
- return;
- }
- // TODO: Figure out why this optimization sometimes causes a
- // change in mDefaultInetCondition to be missed and the
- // UI to not be updated.
- //if (mDefaultInetConditionPublished == mDefaultInetCondition) {
- // if (DBG) log("no change in condition - aborting");
- // return;
- //}
- NetworkInfo networkInfo = getNetworkInfoForType(mActiveDefaultNetwork);
- if (networkInfo.isConnected() == false) {
- if (DBG) log("handleInetConditionHoldEnd: default network not connected - ignoring");
- return;
- }
- mDefaultInetConditionPublished = mDefaultInetCondition;
- sendInetConditionBroadcast(networkInfo);
- return;
- }
-
- public ProxyInfo getProxy() {
- // this information is already available as a world read/writable jvm property
- // so this API change wouldn't have a benifit. It also breaks the passing
- // of proxy info to all the JVMs.
- // enforceAccessPermission();
- synchronized (mProxyLock) {
- ProxyInfo ret = mGlobalProxy;
- if ((ret == null) && !mDefaultProxyDisabled) ret = mDefaultProxy;
- return ret;
- }
- }
-
- public void setGlobalProxy(ProxyInfo proxyProperties) {
- enforceConnectivityInternalPermission();
-
- synchronized (mProxyLock) {
- if (proxyProperties == mGlobalProxy) return;
- if (proxyProperties != null && proxyProperties.equals(mGlobalProxy)) return;
- if (mGlobalProxy != null && mGlobalProxy.equals(proxyProperties)) return;
-
- String host = "";
- int port = 0;
- String exclList = "";
- String pacFileUrl = "";
- if (proxyProperties != null && (!TextUtils.isEmpty(proxyProperties.getHost()) ||
- (proxyProperties.getPacFileUrl() != null))) {
- if (!proxyProperties.isValid()) {
- if (DBG)
- log("Invalid proxy properties, ignoring: " + proxyProperties.toString());
- return;
- }
- mGlobalProxy = new ProxyInfo(proxyProperties);
- host = mGlobalProxy.getHost();
- port = mGlobalProxy.getPort();
- exclList = mGlobalProxy.getExclusionListAsString();
- if (proxyProperties.getPacFileUrl() != null) {
- pacFileUrl = proxyProperties.getPacFileUrl().toString();
- }
- } else {
- mGlobalProxy = null;
- }
- ContentResolver res = mContext.getContentResolver();
- final long token = Binder.clearCallingIdentity();
- try {
- Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_HOST, host);
- Settings.Global.putInt(res, Settings.Global.GLOBAL_HTTP_PROXY_PORT, port);
- Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST,
- exclList);
- Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_PAC, pacFileUrl);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- if (mGlobalProxy == null) {
- proxyProperties = mDefaultProxy;
- }
- sendProxyBroadcast(proxyProperties);
- }
-
- private void loadGlobalProxy() {
- ContentResolver res = mContext.getContentResolver();
- String host = Settings.Global.getString(res, Settings.Global.GLOBAL_HTTP_PROXY_HOST);
- int port = Settings.Global.getInt(res, Settings.Global.GLOBAL_HTTP_PROXY_PORT, 0);
- String exclList = Settings.Global.getString(res,
- Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST);
- String pacFileUrl = Settings.Global.getString(res, Settings.Global.GLOBAL_HTTP_PROXY_PAC);
- if (!TextUtils.isEmpty(host) || !TextUtils.isEmpty(pacFileUrl)) {
- ProxyInfo proxyProperties;
- if (!TextUtils.isEmpty(pacFileUrl)) {
- proxyProperties = new ProxyInfo(pacFileUrl);
- } else {
- proxyProperties = new ProxyInfo(host, port, exclList);
- }
- if (!proxyProperties.isValid()) {
- if (DBG) log("Invalid proxy properties, ignoring: " + proxyProperties.toString());
- return;
- }
-
- synchronized (mProxyLock) {
- mGlobalProxy = proxyProperties;
- }
- }
- }
-
- public ProxyInfo getGlobalProxy() {
- // this information is already available as a world read/writable jvm property
- // so this API change wouldn't have a benifit. It also breaks the passing
- // of proxy info to all the JVMs.
- // enforceAccessPermission();
- synchronized (mProxyLock) {
- return mGlobalProxy;
- }
- }
-
- private void handleApplyDefaultProxy(ProxyInfo proxy) {
- if (proxy != null && TextUtils.isEmpty(proxy.getHost())
- && (proxy.getPacFileUrl() == null)) {
- proxy = null;
- }
- synchronized (mProxyLock) {
- if (mDefaultProxy != null && mDefaultProxy.equals(proxy)) return;
- if (mDefaultProxy == proxy) return; // catches repeated nulls
- if (proxy != null && !proxy.isValid()) {
- if (DBG) log("Invalid proxy properties, ignoring: " + proxy.toString());
- return;
- }
-
- // This call could be coming from the PacManager, containing the port of the local
- // proxy. If this new proxy matches the global proxy then copy this proxy to the
- // global (to get the correct local port), and send a broadcast.
- // TODO: Switch PacManager to have its own message to send back rather than
- // reusing EVENT_HAS_CHANGED_PROXY and this call to handleApplyDefaultProxy.
- if ((mGlobalProxy != null) && (proxy != null) && (proxy.getPacFileUrl() != null)
- && proxy.getPacFileUrl().equals(mGlobalProxy.getPacFileUrl())) {
- mGlobalProxy = proxy;
- sendProxyBroadcast(mGlobalProxy);
- return;
- }
- mDefaultProxy = proxy;
-
- if (mGlobalProxy != null) return;
- if (!mDefaultProxyDisabled) {
- sendProxyBroadcast(proxy);
- }
- }
- }
-
- private void handleDeprecatedGlobalHttpProxy() {
- String proxy = Settings.Global.getString(mContext.getContentResolver(),
- Settings.Global.HTTP_PROXY);
- if (!TextUtils.isEmpty(proxy)) {
- String data[] = proxy.split(":");
- if (data.length == 0) {
- return;
- }
-
- String proxyHost = data[0];
- int proxyPort = 8080;
- if (data.length > 1) {
- try {
- proxyPort = Integer.parseInt(data[1]);
- } catch (NumberFormatException e) {
- return;
- }
- }
- ProxyInfo p = new ProxyInfo(data[0], proxyPort, "");
- setGlobalProxy(p);
- }
- }
-
- private void sendProxyBroadcast(ProxyInfo proxy) {
- if (proxy == null) proxy = new ProxyInfo("", 0, "");
- if (mPacManager.setCurrentProxyScriptUrl(proxy)) return;
- if (DBG) log("sending Proxy Broadcast for " + proxy);
- Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
- intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING |
- Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- intent.putExtra(Proxy.EXTRA_PROXY_INFO, proxy);
- final long ident = Binder.clearCallingIdentity();
- try {
- mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- private static class SettingsObserver extends ContentObserver {
- private int mWhat;
- private Handler mHandler;
- SettingsObserver(Handler handler, int what) {
- super(handler);
- mHandler = handler;
- mWhat = what;
- }
-
- void observe(Context context) {
- ContentResolver resolver = context.getContentResolver();
- resolver.registerContentObserver(Settings.Global.getUriFor(
- Settings.Global.HTTP_PROXY), false, this);
- }
-
- @Override
- public void onChange(boolean selfChange) {
- mHandler.obtainMessage(mWhat).sendToTarget();
- }
- }
-
- private static void log(String s) {
- Slog.d(TAG, s);
- }
-
- private static void loge(String s) {
- Slog.e(TAG, s);
- }
-
- int convertFeatureToNetworkType(int networkType, String feature) {
- int usedNetworkType = networkType;
-
- if(networkType == ConnectivityManager.TYPE_MOBILE) {
- if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_MMS)) {
- usedNetworkType = ConnectivityManager.TYPE_MOBILE_MMS;
- } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_SUPL)) {
- usedNetworkType = ConnectivityManager.TYPE_MOBILE_SUPL;
- } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_DUN) ||
- TextUtils.equals(feature, Phone.FEATURE_ENABLE_DUN_ALWAYS)) {
- usedNetworkType = ConnectivityManager.TYPE_MOBILE_DUN;
- } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_HIPRI)) {
- usedNetworkType = ConnectivityManager.TYPE_MOBILE_HIPRI;
- } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_FOTA)) {
- usedNetworkType = ConnectivityManager.TYPE_MOBILE_FOTA;
- } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_IMS)) {
- usedNetworkType = ConnectivityManager.TYPE_MOBILE_IMS;
- } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_CBS)) {
- usedNetworkType = ConnectivityManager.TYPE_MOBILE_CBS;
- } else {
- Slog.e(TAG, "Can't match any mobile netTracker!");
- }
- } else if (networkType == ConnectivityManager.TYPE_WIFI) {
- if (TextUtils.equals(feature, "p2p")) {
- usedNetworkType = ConnectivityManager.TYPE_WIFI_P2P;
- } else {
- Slog.e(TAG, "Can't match any wifi netTracker!");
- }
- } else {
- Slog.e(TAG, "Unexpected network type");
- }
- return usedNetworkType;
- }
-
- private static <T> T checkNotNull(T value, String message) {
- if (value == null) {
- throw new NullPointerException(message);
- }
- return value;
- }
-
- /**
- * Protect a socket from VPN routing rules. This method is used by
- * VpnBuilder and not available in ConnectivityManager. Permissions
- * are checked in Vpn class.
- * @hide
- */
- @Override
- public boolean protectVpn(ParcelFileDescriptor socket) {
- throwIfLockdownEnabled();
- try {
- int type = mActiveDefaultNetwork;
- int user = UserHandle.getUserId(Binder.getCallingUid());
- if (ConnectivityManager.isNetworkTypeValid(type) && mNetTrackers[type] != null) {
- synchronized(mVpns) {
- mVpns.get(user).protect(socket);
- }
- return true;
- }
- } catch (Exception e) {
- // ignore
- } finally {
- try {
- socket.close();
- } catch (Exception e) {
- // ignore
- }
- }
- return false;
- }
-
- /**
- * Prepare for a VPN application. This method is used by VpnDialogs
- * and not available in ConnectivityManager. Permissions are checked
- * in Vpn class.
- * @hide
- */
- @Override
- public boolean prepareVpn(String oldPackage, String newPackage) {
- throwIfLockdownEnabled();
- int user = UserHandle.getUserId(Binder.getCallingUid());
- synchronized(mVpns) {
- return mVpns.get(user).prepare(oldPackage, newPackage);
- }
- }
-
- @Override
- public void markSocketAsUser(ParcelFileDescriptor socket, int uid) {
- enforceMarkNetworkSocketPermission();
- final long token = Binder.clearCallingIdentity();
- try {
- int mark = mNetd.getMarkForUid(uid);
- // Clear the mark on the socket if no mark is needed to prevent socket reuse issues
- if (mark == -1) {
- mark = 0;
- }
- NetworkUtils.markSocket(socket.getFd(), mark);
- } catch (RemoteException e) {
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- /**
- * Configure a TUN interface and return its file descriptor. Parameters
- * are encoded and opaque to this class. This method is used by VpnBuilder
- * and not available in ConnectivityManager. Permissions are checked in
- * Vpn class.
- * @hide
- */
- @Override
- public ParcelFileDescriptor establishVpn(VpnConfig config) {
- throwIfLockdownEnabled();
- int user = UserHandle.getUserId(Binder.getCallingUid());
- synchronized(mVpns) {
- return mVpns.get(user).establish(config);
- }
- }
-
- /**
- * Start legacy VPN, controlling native daemons as needed. Creates a
- * secondary thread to perform connection work, returning quickly.
- */
- @Override
- public void startLegacyVpn(VpnProfile profile) {
- throwIfLockdownEnabled();
- final LinkProperties egress = getActiveLinkProperties();
- if (egress == null) {
- throw new IllegalStateException("Missing active network connection");
- }
- int user = UserHandle.getUserId(Binder.getCallingUid());
- synchronized(mVpns) {
- mVpns.get(user).startLegacyVpn(profile, mKeyStore, egress);
- }
- }
-
- /**
- * Return the information of the ongoing legacy VPN. This method is used
- * by VpnSettings and not available in ConnectivityManager. Permissions
- * are checked in Vpn class.
- * @hide
- */
- @Override
- public LegacyVpnInfo getLegacyVpnInfo() {
- throwIfLockdownEnabled();
- int user = UserHandle.getUserId(Binder.getCallingUid());
- synchronized(mVpns) {
- return mVpns.get(user).getLegacyVpnInfo();
- }
- }
-
- /**
- * Returns the information of the ongoing VPN. This method is used by VpnDialogs and
- * not available in ConnectivityManager.
- * Permissions are checked in Vpn class.
- * @hide
- */
- @Override
- public VpnConfig getVpnConfig() {
- int user = UserHandle.getUserId(Binder.getCallingUid());
- synchronized(mVpns) {
- return mVpns.get(user).getVpnConfig();
- }
- }
-
- /**
- * Callback for VPN subsystem. Currently VPN is not adapted to the service
- * through NetworkStateTracker since it works differently. For example, it
- * needs to override DNS servers but never takes the default routes. It
- * relies on another data network, and it could keep existing connections
- * alive after reconnecting, switching between networks, or even resuming
- * from deep sleep. Calls from applications should be done synchronously
- * to avoid race conditions. As these are all hidden APIs, refactoring can
- * be done whenever a better abstraction is developed.
- */
- public class VpnCallback {
- private VpnCallback() {
- }
-
- public void onStateChanged(NetworkInfo info) {
- mHandler.obtainMessage(EVENT_VPN_STATE_CHANGED, info).sendToTarget();
- }
-
- public void override(String iface, List<String> dnsServers, List<String> searchDomains) {
- if (dnsServers == null) {
- restore();
- return;
- }
-
- // Convert DNS servers into addresses.
- List<InetAddress> addresses = new ArrayList<InetAddress>();
- for (String address : dnsServers) {
- // Double check the addresses and remove invalid ones.
- try {
- addresses.add(InetAddress.parseNumericAddress(address));
- } catch (Exception e) {
- // ignore
- }
- }
- if (addresses.isEmpty()) {
- restore();
- return;
- }
-
- // Concatenate search domains into a string.
- StringBuilder buffer = new StringBuilder();
- if (searchDomains != null) {
- for (String domain : searchDomains) {
- buffer.append(domain).append(' ');
- }
- }
- String domains = buffer.toString().trim();
-
- // Apply DNS changes.
- synchronized (mDnsLock) {
- // TODO: Re-enable this when the netId of the VPN is known.
- // updateDnsLocked("VPN", netId, addresses, domains);
- }
-
- // Temporarily disable the default proxy (not global).
- synchronized (mProxyLock) {
- mDefaultProxyDisabled = true;
- if (mGlobalProxy == null && mDefaultProxy != null) {
- sendProxyBroadcast(null);
- }
- }
-
- // TODO: support proxy per network.
- }
-
- public void restore() {
- synchronized (mProxyLock) {
- mDefaultProxyDisabled = false;
- if (mGlobalProxy == null && mDefaultProxy != null) {
- sendProxyBroadcast(mDefaultProxy);
- }
- }
- }
-
- public void protect(ParcelFileDescriptor socket) {
- try {
- final int mark = mNetd.getMarkForProtect();
- NetworkUtils.markSocket(socket.getFd(), mark);
- } catch (RemoteException e) {
- }
- }
-
- public void setRoutes(String interfaze, List<RouteInfo> routes) {
- for (RouteInfo route : routes) {
- try {
- mNetd.setMarkedForwardingRoute(interfaze, route);
- } catch (RemoteException e) {
- }
- }
- }
-
- public void setMarkedForwarding(String interfaze) {
- try {
- mNetd.setMarkedForwarding(interfaze);
- } catch (RemoteException e) {
- }
- }
-
- public void clearMarkedForwarding(String interfaze) {
- try {
- mNetd.clearMarkedForwarding(interfaze);
- } catch (RemoteException e) {
- }
- }
-
- public void addUserForwarding(String interfaze, int uid, boolean forwardDns) {
- int uidStart = uid * UserHandle.PER_USER_RANGE;
- int uidEnd = uidStart + UserHandle.PER_USER_RANGE - 1;
- addUidForwarding(interfaze, uidStart, uidEnd, forwardDns);
- }
-
- public void clearUserForwarding(String interfaze, int uid, boolean forwardDns) {
- int uidStart = uid * UserHandle.PER_USER_RANGE;
- int uidEnd = uidStart + UserHandle.PER_USER_RANGE - 1;
- clearUidForwarding(interfaze, uidStart, uidEnd, forwardDns);
- }
-
- public void addUidForwarding(String interfaze, int uidStart, int uidEnd,
- boolean forwardDns) {
- // TODO: Re-enable this when the netId of the VPN is known.
- // try {
- // mNetd.setUidRangeRoute(netId, uidStart, uidEnd, forwardDns);
- // } catch (RemoteException e) {
- // }
-
- }
-
- public void clearUidForwarding(String interfaze, int uidStart, int uidEnd,
- boolean forwardDns) {
- // TODO: Re-enable this when the netId of the VPN is known.
- // try {
- // mNetd.clearUidRangeRoute(interfaze, uidStart, uidEnd);
- // } catch (RemoteException e) {
- // }
-
- }
- }
-
- @Override
- public boolean updateLockdownVpn() {
- if (Binder.getCallingUid() != Process.SYSTEM_UID) {
- Slog.w(TAG, "Lockdown VPN only available to AID_SYSTEM");
- return false;
- }
-
- // Tear down existing lockdown if profile was removed
- mLockdownEnabled = LockdownVpnTracker.isEnabled();
- if (mLockdownEnabled) {
- if (!mKeyStore.isUnlocked()) {
- Slog.w(TAG, "KeyStore locked; unable to create LockdownTracker");
- return false;
- }
-
- final String profileName = new String(mKeyStore.get(Credentials.LOCKDOWN_VPN));
- final VpnProfile profile = VpnProfile.decode(
- profileName, mKeyStore.get(Credentials.VPN + profileName));
- int user = UserHandle.getUserId(Binder.getCallingUid());
- synchronized(mVpns) {
- setLockdownTracker(new LockdownVpnTracker(mContext, mNetd, this, mVpns.get(user),
- profile));
- }
- } else {
- setLockdownTracker(null);
- }
-
- return true;
- }
-
- /**
- * Internally set new {@link LockdownVpnTracker}, shutting down any existing
- * {@link LockdownVpnTracker}. Can be {@code null} to disable lockdown.
- */
- private void setLockdownTracker(LockdownVpnTracker tracker) {
- // Shutdown any existing tracker
- final LockdownVpnTracker existing = mLockdownTracker;
- mLockdownTracker = null;
- if (existing != null) {
- existing.shutdown();
- }
-
- try {
- if (tracker != null) {
- mNetd.setFirewallEnabled(true);
- mNetd.setFirewallInterfaceRule("lo", true);
- mLockdownTracker = tracker;
- mLockdownTracker.init();
- } else {
- mNetd.setFirewallEnabled(false);
- }
- } catch (RemoteException e) {
- // ignored; NMS lives inside system_server
- }
- }
-
- private void throwIfLockdownEnabled() {
- if (mLockdownEnabled) {
- throw new IllegalStateException("Unavailable in lockdown mode");
- }
- }
-
- public void supplyMessenger(int networkType, Messenger messenger) {
- enforceConnectivityInternalPermission();
-
- if (isNetworkTypeValid(networkType) && mNetTrackers[networkType] != null) {
- mNetTrackers[networkType].supplyMessenger(messenger);
- }
- }
-
- public int findConnectionTypeForIface(String iface) {
- enforceConnectivityInternalPermission();
-
- if (TextUtils.isEmpty(iface)) return ConnectivityManager.TYPE_NONE;
- for (NetworkStateTracker tracker : mNetTrackers) {
- if (tracker != null) {
- LinkProperties lp = tracker.getLinkProperties();
- if (lp != null && iface.equals(lp.getInterfaceName())) {
- return tracker.getNetworkInfo().getType();
- }
- }
- }
- return ConnectivityManager.TYPE_NONE;
- }
-
- /**
- * Have mobile data fail fast if enabled.
- *
- * @param enabled DctConstants.ENABLED/DISABLED
- */
- private void setEnableFailFastMobileData(int enabled) {
- int tag;
-
- if (enabled == DctConstants.ENABLED) {
- tag = mEnableFailFastMobileDataTag.incrementAndGet();
- } else {
- tag = mEnableFailFastMobileDataTag.get();
- }
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_ENABLE_FAIL_FAST_MOBILE_DATA, tag,
- enabled));
- }
-
- private boolean isMobileDataStateTrackerReady() {
- MobileDataStateTracker mdst =
- (MobileDataStateTracker) mNetTrackers[ConnectivityManager.TYPE_MOBILE_HIPRI];
- return (mdst != null) && (mdst.isReady());
- }
-
- /**
- * The ResultReceiver resultCode for checkMobileProvisioning (CMP_RESULT_CODE)
- */
-
- /**
- * No connection was possible to the network.
- * This is NOT a warm sim.
- */
- private static final int CMP_RESULT_CODE_NO_CONNECTION = 0;
-
- /**
- * A connection was made to the internet, all is well.
- * This is NOT a warm sim.
- */
- private static final int CMP_RESULT_CODE_CONNECTABLE = 1;
-
- /**
- * A connection was made but no dns server was available to resolve a name to address.
- * This is NOT a warm sim since provisioning network is supported.
- */
- private static final int CMP_RESULT_CODE_NO_DNS = 2;
-
- /**
- * A connection was made but could not open a TCP connection.
- * This is NOT a warm sim since provisioning network is supported.
- */
- private static final int CMP_RESULT_CODE_NO_TCP_CONNECTION = 3;
-
- /**
- * A connection was made but there was a redirection, we appear to be in walled garden.
- * This is an indication of a warm sim on a mobile network such as T-Mobile.
- */
- private static final int CMP_RESULT_CODE_REDIRECTED = 4;
-
- /**
- * The mobile network is a provisioning network.
- * This is an indication of a warm sim on a mobile network such as AT&T.
- */
- private static final int CMP_RESULT_CODE_PROVISIONING_NETWORK = 5;
-
- /**
- * The mobile network is provisioning
- */
- private static final int CMP_RESULT_CODE_IS_PROVISIONING = 6;
-
- private AtomicBoolean mIsProvisioningNetwork = new AtomicBoolean(false);
- private AtomicBoolean mIsStartingProvisioning = new AtomicBoolean(false);
-
- private AtomicBoolean mIsCheckingMobileProvisioning = new AtomicBoolean(false);
-
- @Override
- public int checkMobileProvisioning(int suggestedTimeOutMs) {
- int timeOutMs = -1;
- if (DBG) log("checkMobileProvisioning: E suggestedTimeOutMs=" + suggestedTimeOutMs);
- enforceConnectivityInternalPermission();
-
- final long token = Binder.clearCallingIdentity();
- try {
- timeOutMs = suggestedTimeOutMs;
- if (suggestedTimeOutMs > CheckMp.MAX_TIMEOUT_MS) {
- timeOutMs = CheckMp.MAX_TIMEOUT_MS;
- }
-
- // Check that mobile networks are supported
- if (!isNetworkSupported(ConnectivityManager.TYPE_MOBILE)
- || !isNetworkSupported(ConnectivityManager.TYPE_MOBILE_HIPRI)) {
- if (DBG) log("checkMobileProvisioning: X no mobile network");
- return timeOutMs;
- }
-
- // If we're already checking don't do it again
- // TODO: Add a queue of results...
- if (mIsCheckingMobileProvisioning.getAndSet(true)) {
- if (DBG) log("checkMobileProvisioning: X already checking ignore for the moment");
- return timeOutMs;
- }
-
- // Start off with mobile notification off
- setProvNotificationVisible(false, ConnectivityManager.TYPE_MOBILE_HIPRI, null, null);
-
- CheckMp checkMp = new CheckMp(mContext, this);
- CheckMp.CallBack cb = new CheckMp.CallBack() {
- @Override
- void onComplete(Integer result) {
- if (DBG) log("CheckMp.onComplete: result=" + result);
- NetworkInfo ni =
- mNetTrackers[ConnectivityManager.TYPE_MOBILE_HIPRI].getNetworkInfo();
- switch(result) {
- case CMP_RESULT_CODE_CONNECTABLE:
- case CMP_RESULT_CODE_NO_CONNECTION:
- case CMP_RESULT_CODE_NO_DNS:
- case CMP_RESULT_CODE_NO_TCP_CONNECTION: {
- if (DBG) log("CheckMp.onComplete: ignore, connected or no connection");
- break;
- }
- case CMP_RESULT_CODE_REDIRECTED: {
- if (DBG) log("CheckMp.onComplete: warm sim");
- String url = getMobileProvisioningUrl();
- if (TextUtils.isEmpty(url)) {
- url = getMobileRedirectedProvisioningUrl();
- }
- if (TextUtils.isEmpty(url) == false) {
- if (DBG) log("CheckMp.onComplete: warm (redirected), url=" + url);
- setProvNotificationVisible(true,
- ConnectivityManager.TYPE_MOBILE_HIPRI, ni.getExtraInfo(),
- url);
- } else {
- if (DBG) log("CheckMp.onComplete: warm (redirected), no url");
- }
- break;
- }
- case CMP_RESULT_CODE_PROVISIONING_NETWORK: {
- String url = getMobileProvisioningUrl();
- if (TextUtils.isEmpty(url) == false) {
- if (DBG) log("CheckMp.onComplete: warm (no dns/tcp), url=" + url);
- setProvNotificationVisible(true,
- ConnectivityManager.TYPE_MOBILE_HIPRI, ni.getExtraInfo(),
- url);
- // Mark that we've got a provisioning network and
- // Disable Mobile Data until user actually starts provisioning.
- mIsProvisioningNetwork.set(true);
- MobileDataStateTracker mdst = (MobileDataStateTracker)
- mNetTrackers[ConnectivityManager.TYPE_MOBILE];
-
- // Disable radio until user starts provisioning
- mdst.setRadio(false);
- } else {
- if (DBG) log("CheckMp.onComplete: warm (no dns/tcp), no url");
- }
- break;
- }
- case CMP_RESULT_CODE_IS_PROVISIONING: {
- // FIXME: Need to know when provisioning is done. Probably we can
- // check the completion status if successful we're done if we
- // "timedout" or still connected to provisioning APN turn off data?
- if (DBG) log("CheckMp.onComplete: provisioning started");
- mIsStartingProvisioning.set(false);
- break;
- }
- default: {
- loge("CheckMp.onComplete: ignore unexpected result=" + result);
- break;
- }
- }
- mIsCheckingMobileProvisioning.set(false);
- }
- };
- CheckMp.Params params =
- new CheckMp.Params(checkMp.getDefaultUrl(), timeOutMs, cb);
- if (DBG) log("checkMobileProvisioning: params=" + params);
- // TODO: Reenable when calls to the now defunct
- // MobileDataStateTracker.isProvisioningNetwork() are removed.
- // This code should be moved to the Telephony code.
- // checkMp.execute(params);
- } finally {
- Binder.restoreCallingIdentity(token);
- if (DBG) log("checkMobileProvisioning: X");
- }
- return timeOutMs;
- }
-
- static class CheckMp extends
- AsyncTask<CheckMp.Params, Void, Integer> {
- private static final String CHECKMP_TAG = "CheckMp";
-
- // adb shell setprop persist.checkmp.testfailures 1 to enable testing failures
- private static boolean mTestingFailures;
-
- // Choosing 4 loops as half of them will use HTTPS and the other half HTTP
- private static final int MAX_LOOPS = 4;
-
- // Number of milli-seconds to complete all of the retires
- public static final int MAX_TIMEOUT_MS = 60000;
-
- // The socket should retry only 5 seconds, the default is longer
- private static final int SOCKET_TIMEOUT_MS = 5000;
-
- // Sleep time for network errors
- private static final int NET_ERROR_SLEEP_SEC = 3;
-
- // Sleep time for network route establishment
- private static final int NET_ROUTE_ESTABLISHMENT_SLEEP_SEC = 3;
-
- // Short sleep time for polling :(
- private static final int POLLING_SLEEP_SEC = 1;
-
- private Context mContext;
- private ConnectivityService mCs;
- private TelephonyManager mTm;
- private Params mParams;
-
- /**
- * Parameters for AsyncTask.execute
- */
- static class Params {
- private String mUrl;
- private long mTimeOutMs;
- private CallBack mCb;
-
- Params(String url, long timeOutMs, CallBack cb) {
- mUrl = url;
- mTimeOutMs = timeOutMs;
- mCb = cb;
- }
-
- @Override
- public String toString() {
- return "{" + " url=" + mUrl + " mTimeOutMs=" + mTimeOutMs + " mCb=" + mCb + "}";
- }
- }
-
- // As explained to me by Brian Carlstrom and Kenny Root, Certificates can be
- // issued by name or ip address, for Google its by name so when we construct
- // this HostnameVerifier we'll pass the original Uri and use it to verify
- // the host. If the host name in the original uril fails we'll test the
- // hostname parameter just incase things change.
- static class CheckMpHostnameVerifier implements HostnameVerifier {
- Uri mOrgUri;
-
- CheckMpHostnameVerifier(Uri orgUri) {
- mOrgUri = orgUri;
- }
-
- @Override
- public boolean verify(String hostname, SSLSession session) {
- HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();
- String orgUriHost = mOrgUri.getHost();
- boolean retVal = hv.verify(orgUriHost, session) || hv.verify(hostname, session);
- if (DBG) {
- log("isMobileOk: hostnameVerify retVal=" + retVal + " hostname=" + hostname
- + " orgUriHost=" + orgUriHost);
- }
- return retVal;
- }
- }
-
- /**
- * The call back object passed in Params. onComplete will be called
- * on the main thread.
- */
- abstract static class CallBack {
- // Called on the main thread.
- abstract void onComplete(Integer result);
- }
-
- public CheckMp(Context context, ConnectivityService cs) {
- if (Build.IS_DEBUGGABLE) {
- mTestingFailures =
- SystemProperties.getInt("persist.checkmp.testfailures", 0) == 1;
- } else {
- mTestingFailures = false;
- }
-
- mContext = context;
- mCs = cs;
-
- // Setup access to TelephonyService we'll be using.
- mTm = (TelephonyManager) mContext.getSystemService(
- Context.TELEPHONY_SERVICE);
- }
-
- /**
- * Get the default url to use for the test.
- */
- public String getDefaultUrl() {
- // See http://go/clientsdns for usage approval
- String server = Settings.Global.getString(mContext.getContentResolver(),
- Settings.Global.CAPTIVE_PORTAL_SERVER);
- if (server == null) {
- server = "clients3.google.com";
- }
- return "http://" + server + "/generate_204";
- }
-
- /**
- * Detect if its possible to connect to the http url. DNS based detection techniques
- * do not work at all hotspots. The best way to check is to perform a request to
- * a known address that fetches the data we expect.
- */
- private synchronized Integer isMobileOk(Params params) {
- Integer result = CMP_RESULT_CODE_NO_CONNECTION;
- Uri orgUri = Uri.parse(params.mUrl);
- Random rand = new Random();
- mParams = params;
-
- if (mCs.isNetworkSupported(ConnectivityManager.TYPE_MOBILE) == false) {
- result = CMP_RESULT_CODE_NO_CONNECTION;
- log("isMobileOk: X not mobile capable result=" + result);
- return result;
- }
-
- if (mCs.mIsStartingProvisioning.get()) {
- result = CMP_RESULT_CODE_IS_PROVISIONING;
- log("isMobileOk: X is provisioning result=" + result);
- return result;
- }
-
- // See if we've already determined we've got a provisioning connection,
- // if so we don't need to do anything active.
- MobileDataStateTracker mdstDefault = (MobileDataStateTracker)
- mCs.mNetTrackers[ConnectivityManager.TYPE_MOBILE];
- boolean isDefaultProvisioning = mdstDefault.isProvisioningNetwork();
- log("isMobileOk: isDefaultProvisioning=" + isDefaultProvisioning);
-
- MobileDataStateTracker mdstHipri = (MobileDataStateTracker)
- mCs.mNetTrackers[ConnectivityManager.TYPE_MOBILE_HIPRI];
- boolean isHipriProvisioning = mdstHipri.isProvisioningNetwork();
- log("isMobileOk: isHipriProvisioning=" + isHipriProvisioning);
-
- if (isDefaultProvisioning || isHipriProvisioning) {
- result = CMP_RESULT_CODE_PROVISIONING_NETWORK;
- log("isMobileOk: X default || hipri is provisioning result=" + result);
- return result;
- }
-
- try {
- // Continue trying to connect until time has run out
- long endTime = SystemClock.elapsedRealtime() + params.mTimeOutMs;
-
- if (!mCs.isMobileDataStateTrackerReady()) {
- // Wait for MobileDataStateTracker to be ready.
- if (DBG) log("isMobileOk: mdst is not ready");
- while(SystemClock.elapsedRealtime() < endTime) {
- if (mCs.isMobileDataStateTrackerReady()) {
- // Enable fail fast as we'll do retries here and use a
- // hipri connection so the default connection stays active.
- if (DBG) log("isMobileOk: mdst ready, enable fail fast of mobile data");
- mCs.setEnableFailFastMobileData(DctConstants.ENABLED);
- break;
- }
- sleep(POLLING_SLEEP_SEC);
- }
- }
-
- log("isMobileOk: start hipri url=" + params.mUrl);
-
- // First wait until we can start using hipri
- Binder binder = new Binder();
- while(SystemClock.elapsedRealtime() < endTime) {
- int ret = mCs.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
- Phone.FEATURE_ENABLE_HIPRI, binder);
- if ((ret == PhoneConstants.APN_ALREADY_ACTIVE)
- || (ret == PhoneConstants.APN_REQUEST_STARTED)) {
- log("isMobileOk: hipri started");
- break;
- }
- if (VDBG) log("isMobileOk: hipri not started yet");
- result = CMP_RESULT_CODE_NO_CONNECTION;
- sleep(POLLING_SLEEP_SEC);
- }
-
- // Continue trying to connect until time has run out
- while(SystemClock.elapsedRealtime() < endTime) {
- try {
- // Wait for hipri to connect.
- // TODO: Don't poll and handle situation where hipri fails
- // because default is retrying. See b/9569540
- NetworkInfo.State state = mCs
- .getNetworkInfo(ConnectivityManager.TYPE_MOBILE_HIPRI).getState();
- if (state != NetworkInfo.State.CONNECTED) {
- if (true/*VDBG*/) {
- log("isMobileOk: not connected ni=" +
- mCs.getNetworkInfo(ConnectivityManager.TYPE_MOBILE_HIPRI));
- }
- sleep(POLLING_SLEEP_SEC);
- result = CMP_RESULT_CODE_NO_CONNECTION;
- continue;
- }
-
- // Hipri has started check if this is a provisioning url
- MobileDataStateTracker mdst = (MobileDataStateTracker)
- mCs.mNetTrackers[ConnectivityManager.TYPE_MOBILE_HIPRI];
- if (mdst.isProvisioningNetwork()) {
- result = CMP_RESULT_CODE_PROVISIONING_NETWORK;
- if (DBG) log("isMobileOk: X isProvisioningNetwork result=" + result);
- return result;
- } else {
- if (DBG) log("isMobileOk: isProvisioningNetwork is false, continue");
- }
-
- // Get of the addresses associated with the url host. We need to use the
- // address otherwise HttpURLConnection object will use the name to get
- // the addresses and will try every address but that will bypass the
- // route to host we setup and the connection could succeed as the default
- // interface might be connected to the internet via wifi or other interface.
- InetAddress[] addresses;
- try {
- addresses = InetAddress.getAllByName(orgUri.getHost());
- } catch (UnknownHostException e) {
- result = CMP_RESULT_CODE_NO_DNS;
- log("isMobileOk: X UnknownHostException result=" + result);
- return result;
- }
- log("isMobileOk: addresses=" + inetAddressesToString(addresses));
-
- // Get the type of addresses supported by this link
- LinkProperties lp = mCs.getLinkPropertiesForTypeInternal(
- ConnectivityManager.TYPE_MOBILE_HIPRI);
- boolean linkHasIpv4 = lp.hasIPv4Address();
- boolean linkHasIpv6 = lp.hasIPv6Address();
- log("isMobileOk: linkHasIpv4=" + linkHasIpv4
- + " linkHasIpv6=" + linkHasIpv6);
-
- final ArrayList<InetAddress> validAddresses =
- new ArrayList<InetAddress>(addresses.length);
-
- for (InetAddress addr : addresses) {
- if (((addr instanceof Inet4Address) && linkHasIpv4) ||
- ((addr instanceof Inet6Address) && linkHasIpv6)) {
- validAddresses.add(addr);
- }
- }
-
- if (validAddresses.size() == 0) {
- return CMP_RESULT_CODE_NO_CONNECTION;
- }
-
- int addrTried = 0;
- while (true) {
- // Loop through at most MAX_LOOPS valid addresses or until
- // we run out of time
- if (addrTried++ >= MAX_LOOPS) {
- log("isMobileOk: too many loops tried - giving up");
- break;
- }
- if (SystemClock.elapsedRealtime() >= endTime) {
- log("isMobileOk: spend too much time - giving up");
- break;
- }
-
- InetAddress hostAddr = validAddresses.get(rand.nextInt(
- validAddresses.size()));
-
- // Make a route to host so we check the specific interface.
- if (mCs.requestRouteToHostAddress(ConnectivityManager.TYPE_MOBILE_HIPRI,
- hostAddr.getAddress(), null)) {
- // Wait a short time to be sure the route is established ??
- log("isMobileOk:"
- + " wait to establish route to hostAddr=" + hostAddr);
- sleep(NET_ROUTE_ESTABLISHMENT_SLEEP_SEC);
- } else {
- log("isMobileOk:"
- + " could not establish route to hostAddr=" + hostAddr);
- // Wait a short time before the next attempt
- sleep(NET_ERROR_SLEEP_SEC);
- continue;
- }
-
- // Rewrite the url to have numeric address to use the specific route
- // using http for half the attempts and https for the other half.
- // Doing https first and http second as on a redirected walled garden
- // such as t-mobile uses we get a SocketTimeoutException: "SSL
- // handshake timed out" which we declare as
- // CMP_RESULT_CODE_NO_TCP_CONNECTION. We could change this, but by
- // having http second we will be using logic used for some time.
- URL newUrl;
- String scheme = (addrTried <= (MAX_LOOPS/2)) ? "https" : "http";
- newUrl = new URL(scheme, hostAddr.getHostAddress(),
- orgUri.getPath());
- log("isMobileOk: newUrl=" + newUrl);
-
- HttpURLConnection urlConn = null;
- try {
- // Open the connection set the request headers and get the response
- urlConn = (HttpURLConnection)newUrl.openConnection(
- java.net.Proxy.NO_PROXY);
- if (scheme.equals("https")) {
- ((HttpsURLConnection)urlConn).setHostnameVerifier(
- new CheckMpHostnameVerifier(orgUri));
- }
- urlConn.setInstanceFollowRedirects(false);
- urlConn.setConnectTimeout(SOCKET_TIMEOUT_MS);
- urlConn.setReadTimeout(SOCKET_TIMEOUT_MS);
- urlConn.setUseCaches(false);
- urlConn.setAllowUserInteraction(false);
- // Set the "Connection" to "Close" as by default "Keep-Alive"
- // is used which is useless in this case.
- urlConn.setRequestProperty("Connection", "close");
- int responseCode = urlConn.getResponseCode();
-
- // For debug display the headers
- Map<String, List<String>> headers = urlConn.getHeaderFields();
- log("isMobileOk: headers=" + headers);
-
- // Close the connection
- urlConn.disconnect();
- urlConn = null;
-
- if (mTestingFailures) {
- // Pretend no connection, this tests using http and https
- result = CMP_RESULT_CODE_NO_CONNECTION;
- log("isMobileOk: TESTING_FAILURES, pretend no connction");
- continue;
- }
-
- if (responseCode == 204) {
- // Return
- result = CMP_RESULT_CODE_CONNECTABLE;
- log("isMobileOk: X got expected responseCode=" + responseCode
- + " result=" + result);
- return result;
- } else {
- // Retry to be sure this was redirected, we've gotten
- // occasions where a server returned 200 even though
- // the device didn't have a "warm" sim.
- log("isMobileOk: not expected responseCode=" + responseCode);
- // TODO - it would be nice in the single-address case to do
- // another DNS resolve here, but flushing the cache is a bit
- // heavy-handed.
- result = CMP_RESULT_CODE_REDIRECTED;
- }
- } catch (Exception e) {
- log("isMobileOk: HttpURLConnection Exception" + e);
- result = CMP_RESULT_CODE_NO_TCP_CONNECTION;
- if (urlConn != null) {
- urlConn.disconnect();
- urlConn = null;
- }
- sleep(NET_ERROR_SLEEP_SEC);
- continue;
- }
- }
- log("isMobileOk: X loops|timed out result=" + result);
- return result;
- } catch (Exception e) {
- log("isMobileOk: Exception e=" + e);
- continue;
- }
- }
- log("isMobileOk: timed out");
- } finally {
- log("isMobileOk: F stop hipri");
- mCs.setEnableFailFastMobileData(DctConstants.DISABLED);
- mCs.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
- Phone.FEATURE_ENABLE_HIPRI);
-
- // Wait for hipri to disconnect.
- long endTime = SystemClock.elapsedRealtime() + 5000;
-
- while(SystemClock.elapsedRealtime() < endTime) {
- NetworkInfo.State state = mCs
- .getNetworkInfo(ConnectivityManager.TYPE_MOBILE_HIPRI).getState();
- if (state != NetworkInfo.State.DISCONNECTED) {
- if (VDBG) {
- log("isMobileOk: connected ni=" +
- mCs.getNetworkInfo(ConnectivityManager.TYPE_MOBILE_HIPRI));
- }
- sleep(POLLING_SLEEP_SEC);
- continue;
- }
- }
-
- log("isMobileOk: X result=" + result);
- }
- return result;
- }
-
- @Override
- protected Integer doInBackground(Params... params) {
- return isMobileOk(params[0]);
- }
-
- @Override
- protected void onPostExecute(Integer result) {
- log("onPostExecute: result=" + result);
- if ((mParams != null) && (mParams.mCb != null)) {
- mParams.mCb.onComplete(result);
- }
- }
-
- private String inetAddressesToString(InetAddress[] addresses) {
- StringBuffer sb = new StringBuffer();
- boolean firstTime = true;
- for(InetAddress addr : addresses) {
- if (firstTime) {
- firstTime = false;
- } else {
- sb.append(",");
- }
- sb.append(addr);
- }
- return sb.toString();
- }
-
- private void printNetworkInfo() {
- boolean hasIccCard = mTm.hasIccCard();
- int simState = mTm.getSimState();
- log("hasIccCard=" + hasIccCard
- + " simState=" + simState);
- NetworkInfo[] ni = mCs.getAllNetworkInfo();
- if (ni != null) {
- log("ni.length=" + ni.length);
- for (NetworkInfo netInfo: ni) {
- log("netInfo=" + netInfo.toString());
- }
- } else {
- log("no network info ni=null");
- }
- }
-
- /**
- * Sleep for a few seconds then return.
- * @param seconds
- */
- private static void sleep(int seconds) {
- long stopTime = System.nanoTime() + (seconds * 1000000000);
- long sleepTime;
- while ((sleepTime = stopTime - System.nanoTime()) > 0) {
- try {
- Thread.sleep(sleepTime / 1000000);
- } catch (InterruptedException ignored) {
- }
- }
- }
-
- private static void log(String s) {
- Slog.d(ConnectivityService.TAG, "[" + CHECKMP_TAG + "] " + s);
- }
- }
-
- // TODO: Move to ConnectivityManager and make public?
- private static final String CONNECTED_TO_PROVISIONING_NETWORK_ACTION =
- "com.android.server.connectivityservice.CONNECTED_TO_PROVISIONING_NETWORK_ACTION";
-
- private BroadcastReceiver mProvisioningReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (intent.getAction().equals(CONNECTED_TO_PROVISIONING_NETWORK_ACTION)) {
- handleMobileProvisioningAction(intent.getStringExtra("EXTRA_URL"));
- }
- }
- };
-
- private void handleMobileProvisioningAction(String url) {
- // Mark notification as not visible
- setProvNotificationVisible(false, ConnectivityManager.TYPE_MOBILE_HIPRI, null, null);
-
- // Check airplane mode
- boolean isAirplaneModeOn = Settings.System.getInt(mContext.getContentResolver(),
- Settings.Global.AIRPLANE_MODE_ON, 0) == 1;
- // If provisioning network and not in airplane mode handle as a special case,
- // otherwise launch browser with the intent directly.
- if (mIsProvisioningNetwork.get() && !isAirplaneModeOn) {
- if (DBG) log("handleMobileProvisioningAction: on prov network enable then launch");
- mIsProvisioningNetwork.set(false);
-// mIsStartingProvisioning.set(true);
-// MobileDataStateTracker mdst = (MobileDataStateTracker)
-// mNetTrackers[ConnectivityManager.TYPE_MOBILE];
- // Radio was disabled on CMP_RESULT_CODE_PROVISIONING_NETWORK, enable it here
-// mdst.setRadio(true);
-// mdst.setEnableFailFastMobileData(DctConstants.ENABLED);
-// mdst.enableMobileProvisioning(url);
- } else {
- if (DBG) log("handleMobileProvisioningAction: not prov network");
- mIsProvisioningNetwork.set(false);
- // Check for apps that can handle provisioning first
- Intent provisioningIntent = new Intent(TelephonyIntents.ACTION_CARRIER_SETUP);
- provisioningIntent.addCategory(TelephonyIntents.CATEGORY_MCCMNC_PREFIX
- + mTelephonyManager.getSimOperator());
- if (mContext.getPackageManager().resolveActivity(provisioningIntent, 0 /* flags */)
- != null) {
- provisioningIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |
- Intent.FLAG_ACTIVITY_NEW_TASK);
- mContext.startActivity(provisioningIntent);
- } else {
- // If no apps exist, use standard URL ACTION_VIEW method
- Intent newIntent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN,
- Intent.CATEGORY_APP_BROWSER);
- newIntent.setData(Uri.parse(url));
- newIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |
- Intent.FLAG_ACTIVITY_NEW_TASK);
- try {
- mContext.startActivity(newIntent);
- } catch (ActivityNotFoundException e) {
- loge("handleMobileProvisioningAction: startActivity failed" + e);
- }
- }
- }
- }
-
- private static final String NOTIFICATION_ID = "CaptivePortal.Notification";
- private volatile boolean mIsNotificationVisible = false;
-
- private void setProvNotificationVisible(boolean visible, int networkType, String extraInfo,
- String url) {
- if (DBG) {
- log("setProvNotificationVisible: E visible=" + visible + " networkType=" + networkType
- + " extraInfo=" + extraInfo + " url=" + url);
- }
-
- Resources r = Resources.getSystem();
- NotificationManager notificationManager = (NotificationManager) mContext
- .getSystemService(Context.NOTIFICATION_SERVICE);
-
- if (visible) {
- CharSequence title;
- CharSequence details;
- int icon;
- Intent intent;
- Notification notification = new Notification();
- switch (networkType) {
- case ConnectivityManager.TYPE_WIFI:
- title = r.getString(R.string.wifi_available_sign_in, 0);
- details = r.getString(R.string.network_available_sign_in_detailed,
- extraInfo);
- icon = R.drawable.stat_notify_wifi_in_range;
- intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
- intent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |
- Intent.FLAG_ACTIVITY_NEW_TASK);
- notification.contentIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
- break;
- case ConnectivityManager.TYPE_MOBILE:
- case ConnectivityManager.TYPE_MOBILE_HIPRI:
- title = r.getString(R.string.network_available_sign_in, 0);
- // TODO: Change this to pull from NetworkInfo once a printable
- // name has been added to it
- details = mTelephonyManager.getNetworkOperatorName();
- icon = R.drawable.stat_notify_rssi_in_range;
- intent = new Intent(CONNECTED_TO_PROVISIONING_NETWORK_ACTION);
- intent.putExtra("EXTRA_URL", url);
- intent.setFlags(0);
- notification.contentIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
- break;
- default:
- title = r.getString(R.string.network_available_sign_in, 0);
- details = r.getString(R.string.network_available_sign_in_detailed,
- extraInfo);
- icon = R.drawable.stat_notify_rssi_in_range;
- intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
- intent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |
- Intent.FLAG_ACTIVITY_NEW_TASK);
- notification.contentIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
- break;
- }
-
- notification.when = 0;
- notification.icon = icon;
- notification.flags = Notification.FLAG_AUTO_CANCEL;
- notification.tickerText = title;
- notification.setLatestEventInfo(mContext, title, details, notification.contentIntent);
-
- try {
- notificationManager.notify(NOTIFICATION_ID, networkType, notification);
- } catch (NullPointerException npe) {
- loge("setNotificaitionVisible: visible notificationManager npe=" + npe);
- npe.printStackTrace();
- }
- } else {
- try {
- notificationManager.cancel(NOTIFICATION_ID, networkType);
- } catch (NullPointerException npe) {
- loge("setNotificaitionVisible: cancel notificationManager npe=" + npe);
- npe.printStackTrace();
- }
- }
- mIsNotificationVisible = visible;
- }
-
- /** Location to an updatable file listing carrier provisioning urls.
- * An example:
- *
- * <?xml version="1.0" encoding="utf-8"?>
- * <provisioningUrls>
- * <provisioningUrl mcc="310" mnc="4">http://myserver.com/foo?mdn=%3$s&iccid=%1$s&imei=%2$s</provisioningUrl>
- * <redirectedUrl mcc="310" mnc="4">http://www.google.com</redirectedUrl>
- * </provisioningUrls>
- */
- private static final String PROVISIONING_URL_PATH =
- "/data/misc/radio/provisioning_urls.xml";
- private final File mProvisioningUrlFile = new File(PROVISIONING_URL_PATH);
-
- /** XML tag for root element. */
- private static final String TAG_PROVISIONING_URLS = "provisioningUrls";
- /** XML tag for individual url */
- private static final String TAG_PROVISIONING_URL = "provisioningUrl";
- /** XML tag for redirected url */
- private static final String TAG_REDIRECTED_URL = "redirectedUrl";
- /** XML attribute for mcc */
- private static final String ATTR_MCC = "mcc";
- /** XML attribute for mnc */
- private static final String ATTR_MNC = "mnc";
-
- private static final int REDIRECTED_PROVISIONING = 1;
- private static final int PROVISIONING = 2;
-
- private String getProvisioningUrlBaseFromFile(int type) {
- FileReader fileReader = null;
- XmlPullParser parser = null;
- Configuration config = mContext.getResources().getConfiguration();
- String tagType;
-
- switch (type) {
- case PROVISIONING:
- tagType = TAG_PROVISIONING_URL;
- break;
- case REDIRECTED_PROVISIONING:
- tagType = TAG_REDIRECTED_URL;
- break;
- default:
- throw new RuntimeException("getProvisioningUrlBaseFromFile: Unexpected parameter " +
- type);
- }
-
- try {
- fileReader = new FileReader(mProvisioningUrlFile);
- parser = Xml.newPullParser();
- parser.setInput(fileReader);
- XmlUtils.beginDocument(parser, TAG_PROVISIONING_URLS);
-
- while (true) {
- XmlUtils.nextElement(parser);
-
- String element = parser.getName();
- if (element == null) break;
-
- if (element.equals(tagType)) {
- String mcc = parser.getAttributeValue(null, ATTR_MCC);
- try {
- if (mcc != null && Integer.parseInt(mcc) == config.mcc) {
- String mnc = parser.getAttributeValue(null, ATTR_MNC);
- if (mnc != null && Integer.parseInt(mnc) == config.mnc) {
- parser.next();
- if (parser.getEventType() == XmlPullParser.TEXT) {
- return parser.getText();
- }
- }
- }
- } catch (NumberFormatException e) {
- loge("NumberFormatException in getProvisioningUrlBaseFromFile: " + e);
- }
- }
- }
- return null;
- } catch (FileNotFoundException e) {
- loge("Carrier Provisioning Urls file not found");
- } catch (XmlPullParserException e) {
- loge("Xml parser exception reading Carrier Provisioning Urls file: " + e);
- } catch (IOException e) {
- loge("I/O exception reading Carrier Provisioning Urls file: " + e);
- } finally {
- if (fileReader != null) {
- try {
- fileReader.close();
- } catch (IOException e) {}
- }
- }
- return null;
- }
-
- @Override
- public String getMobileRedirectedProvisioningUrl() {
- enforceConnectivityInternalPermission();
- String url = getProvisioningUrlBaseFromFile(REDIRECTED_PROVISIONING);
- if (TextUtils.isEmpty(url)) {
- url = mContext.getResources().getString(R.string.mobile_redirected_provisioning_url);
- }
- return url;
- }
-
- @Override
- public String getMobileProvisioningUrl() {
- enforceConnectivityInternalPermission();
- String url = getProvisioningUrlBaseFromFile(PROVISIONING);
- if (TextUtils.isEmpty(url)) {
- url = mContext.getResources().getString(R.string.mobile_provisioning_url);
- log("getMobileProvisioningUrl: mobile_provisioining_url from resource =" + url);
- } else {
- log("getMobileProvisioningUrl: mobile_provisioning_url from File =" + url);
- }
- // populate the iccid, imei and phone number in the provisioning url.
- if (!TextUtils.isEmpty(url)) {
- String phoneNumber = mTelephonyManager.getLine1Number();
- if (TextUtils.isEmpty(phoneNumber)) {
- phoneNumber = "0000000000";
- }
- url = String.format(url,
- mTelephonyManager.getSimSerialNumber() /* ICCID */,
- mTelephonyManager.getDeviceId() /* IMEI */,
- phoneNumber /* Phone numer */);
- }
-
- return url;
- }
-
- @Override
- public void setProvisioningNotificationVisible(boolean visible, int networkType,
- String extraInfo, String url) {
- enforceConnectivityInternalPermission();
- setProvNotificationVisible(visible, networkType, extraInfo, url);
- }
-
- @Override
- public void setAirplaneMode(boolean enable) {
- enforceConnectivityInternalPermission();
- final long ident = Binder.clearCallingIdentity();
- try {
- final ContentResolver cr = mContext.getContentResolver();
- Settings.Global.putInt(cr, Settings.Global.AIRPLANE_MODE_ON, enable ? 1 : 0);
- Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
- intent.putExtra("state", enable);
- mContext.sendBroadcast(intent);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- private void onUserStart(int userId) {
- synchronized(mVpns) {
- Vpn userVpn = mVpns.get(userId);
- if (userVpn != null) {
- loge("Starting user already has a VPN");
- return;
- }
- userVpn = new Vpn(mContext, mVpnCallback, mNetd, this, userId);
- mVpns.put(userId, userVpn);
- userVpn.startMonitoring(mContext, mTrackerHandler);
- }
- }
-
- private void onUserStop(int userId) {
- synchronized(mVpns) {
- Vpn userVpn = mVpns.get(userId);
- if (userVpn == null) {
- loge("Stopping user has no VPN");
- return;
- }
- mVpns.delete(userId);
- }
- }
-
- private BroadcastReceiver mUserIntentReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- final String action = intent.getAction();
- final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
- if (userId == UserHandle.USER_NULL) return;
-
- if (Intent.ACTION_USER_STARTING.equals(action)) {
- onUserStart(userId);
- } else if (Intent.ACTION_USER_STOPPING.equals(action)) {
- onUserStop(userId);
- }
- }
- };
-
- @Override
- public LinkQualityInfo getLinkQualityInfo(int networkType) {
- enforceAccessPermission();
- if (isNetworkTypeValid(networkType) && mNetTrackers[networkType] != null) {
- return mNetTrackers[networkType].getLinkQualityInfo();
- } else {
- return null;
- }
- }
-
- @Override
- public LinkQualityInfo getActiveLinkQualityInfo() {
- enforceAccessPermission();
- if (isNetworkTypeValid(mActiveDefaultNetwork) &&
- mNetTrackers[mActiveDefaultNetwork] != null) {
- return mNetTrackers[mActiveDefaultNetwork].getLinkQualityInfo();
- } else {
- return null;
- }
- }
-
- @Override
- public LinkQualityInfo[] getAllLinkQualityInfo() {
- enforceAccessPermission();
- final ArrayList<LinkQualityInfo> result = Lists.newArrayList();
- for (NetworkStateTracker tracker : mNetTrackers) {
- if (tracker != null) {
- LinkQualityInfo li = tracker.getLinkQualityInfo();
- if (li != null) {
- result.add(li);
- }
- }
- }
-
- return result.toArray(new LinkQualityInfo[result.size()]);
- }
-
- /* Infrastructure for network sampling */
-
- private void handleNetworkSamplingTimeout() {
-
- log("Sampling interval elapsed, updating statistics ..");
-
- // initialize list of interfaces ..
- Map<String, SamplingDataTracker.SamplingSnapshot> mapIfaceToSample =
- new HashMap<String, SamplingDataTracker.SamplingSnapshot>();
- for (NetworkStateTracker tracker : mNetTrackers) {
- if (tracker != null) {
- String ifaceName = tracker.getNetworkInterfaceName();
- if (ifaceName != null) {
- mapIfaceToSample.put(ifaceName, null);
- }
- }
- }
-
- // Read samples for all interfaces
- SamplingDataTracker.getSamplingSnapshots(mapIfaceToSample);
-
- // process samples for all networks
- for (NetworkStateTracker tracker : mNetTrackers) {
- if (tracker != null) {
- String ifaceName = tracker.getNetworkInterfaceName();
- SamplingDataTracker.SamplingSnapshot ss = mapIfaceToSample.get(ifaceName);
- if (ss != null) {
- // end the previous sampling cycle
- tracker.stopSampling(ss);
- // start a new sampling cycle ..
- tracker.startSampling(ss);
- }
- }
- }
-
- log("Done.");
-
- int samplingIntervalInSeconds = Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.CONNECTIVITY_SAMPLING_INTERVAL_IN_SECONDS,
- DEFAULT_SAMPLING_INTERVAL_IN_SECONDS);
-
- if (DBG) log("Setting timer for " + String.valueOf(samplingIntervalInSeconds) + "seconds");
-
- setAlarm(samplingIntervalInSeconds * 1000, mSampleIntervalElapsedIntent);
- }
-
- void setAlarm(int timeoutInMilliseconds, PendingIntent intent) {
- long wakeupTime = SystemClock.elapsedRealtime() + timeoutInMilliseconds;
- mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, wakeupTime, intent);
- }
-
- private final HashMap<Messenger, NetworkFactoryInfo> mNetworkFactoryInfos =
- new HashMap<Messenger, NetworkFactoryInfo>();
- private final HashMap<NetworkRequest, NetworkRequestInfo> mNetworkRequests =
- new HashMap<NetworkRequest, NetworkRequestInfo>();
-
- private static class NetworkFactoryInfo {
- public final String name;
- public final Messenger messenger;
- public final AsyncChannel asyncChannel;
-
- public NetworkFactoryInfo(String name, Messenger messenger, AsyncChannel asyncChannel) {
- this.name = name;
- this.messenger = messenger;
- this.asyncChannel = asyncChannel;
- }
- }
-
- private class NetworkRequestInfo implements IBinder.DeathRecipient {
- static final boolean REQUEST = true;
- static final boolean LISTEN = false;
-
- final NetworkRequest request;
- IBinder mBinder;
- final int mPid;
- final int mUid;
- final Messenger messenger;
- final boolean isRequest;
-
- NetworkRequestInfo(Messenger m, NetworkRequest r, IBinder binder, boolean isRequest) {
- super();
- messenger = m;
- request = r;
- mBinder = binder;
- mPid = getCallingPid();
- mUid = getCallingUid();
- this.isRequest = isRequest;
-
- try {
- mBinder.linkToDeath(this, 0);
- } catch (RemoteException e) {
- binderDied();
- }
- }
-
- void unlinkDeathRecipient() {
- mBinder.unlinkToDeath(this, 0);
- }
-
- public void binderDied() {
- log("ConnectivityService NetworkRequestInfo binderDied(" +
- request + ", " + mBinder + ")");
- releaseNetworkRequest(request);
- }
-
- public String toString() {
- return (isRequest ? "Request" : "Listen") + " from uid/pid:" + mUid + "/" +
- mPid + " for " + request;
- }
- }
-
- @Override
- public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities,
- Messenger messenger, int timeoutSec, IBinder binder, int legacyType) {
- if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
- == false) {
- enforceConnectivityInternalPermission();
- } else {
- enforceChangePermission();
- }
-
- if (timeoutSec < 0 || timeoutSec > ConnectivityManager.MAX_NETWORK_REQUEST_TIMEOUT_SEC) {
- throw new IllegalArgumentException("Bad timeout specified");
- }
- NetworkRequest networkRequest = new NetworkRequest(new NetworkCapabilities(
- networkCapabilities), legacyType, nextNetworkRequestId());
- if (DBG) log("requestNetwork for " + networkRequest);
- NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder,
- NetworkRequestInfo.REQUEST);
-
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST, nri));
- if (timeoutSec > 0) {
- mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_TIMEOUT_NETWORK_REQUEST,
- nri), timeoutSec * 1000);
- }
- return networkRequest;
- }
-
- @Override
- public NetworkRequest pendingRequestForNetwork(NetworkCapabilities networkCapabilities,
- PendingIntent operation) {
- // TODO
- return null;
- }
-
- @Override
- public NetworkRequest listenForNetwork(NetworkCapabilities networkCapabilities,
- Messenger messenger, IBinder binder) {
- enforceAccessPermission();
-
- NetworkRequest networkRequest = new NetworkRequest(new NetworkCapabilities(
- networkCapabilities), TYPE_NONE, nextNetworkRequestId());
- if (DBG) log("listenForNetwork for " + networkRequest);
- NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder,
- NetworkRequestInfo.LISTEN);
-
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri));
- return networkRequest;
- }
-
- @Override
- public void pendingListenForNetwork(NetworkCapabilities networkCapabilities,
- PendingIntent operation) {
- }
-
- @Override
- public void releaseNetworkRequest(NetworkRequest networkRequest) {
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST,
- networkRequest));
- }
-
- @Override
- public void registerNetworkFactory(Messenger messenger, String name) {
- enforceConnectivityInternalPermission();
- NetworkFactoryInfo nfi = new NetworkFactoryInfo(name, messenger, new AsyncChannel());
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_FACTORY, nfi));
- }
-
- private void handleRegisterNetworkFactory(NetworkFactoryInfo nfi) {
- if (VDBG) log("Got NetworkFactory Messenger for " + nfi.name);
- mNetworkFactoryInfos.put(nfi.messenger, nfi);
- nfi.asyncChannel.connect(mContext, mTrackerHandler, nfi.messenger);
- }
-
- @Override
- public void unregisterNetworkFactory(Messenger messenger) {
- enforceConnectivityInternalPermission();
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_FACTORY, messenger));
- }
-
- private void handleUnregisterNetworkFactory(Messenger messenger) {
- NetworkFactoryInfo nfi = mNetworkFactoryInfos.remove(messenger);
- if (nfi == null) {
- if (VDBG) log("Failed to find Messenger in unregisterNetworkFactory");
- return;
- }
- if (VDBG) log("unregisterNetworkFactory for " + nfi.name);
- }
-
- /**
- * NetworkAgentInfo supporting a request by requestId.
- * These have already been vetted (their Capabilities satisfy the request)
- * and the are the highest scored network available.
- * the are keyed off the Requests requestId.
- */
- private final SparseArray<NetworkAgentInfo> mNetworkForRequestId =
- new SparseArray<NetworkAgentInfo>();
-
- private final SparseArray<NetworkAgentInfo> mNetworkForNetId =
- new SparseArray<NetworkAgentInfo>();
-
- // NetworkAgentInfo keyed off its connecting messenger
- // TODO - eval if we can reduce the number of lists/hashmaps/sparsearrays
- private final HashMap<Messenger, NetworkAgentInfo> mNetworkAgentInfos =
- new HashMap<Messenger, NetworkAgentInfo>();
-
- private final NetworkRequest mDefaultRequest;
-
- public void registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo,
- LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
- int currentScore) {
- enforceConnectivityInternalPermission();
-
- NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(), nextNetId(),
- new NetworkInfo(networkInfo), new LinkProperties(linkProperties),
- new NetworkCapabilities(networkCapabilities), currentScore, mContext, mTrackerHandler);
- if (VDBG) log("registerNetworkAgent " + nai);
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_AGENT, nai));
- }
-
- private void handleRegisterNetworkAgent(NetworkAgentInfo na) {
- if (VDBG) log("Got NetworkAgent Messenger");
- mNetworkAgentInfos.put(na.messenger, na);
- mNetworkForNetId.put(na.network.netId, na);
- na.asyncChannel.connect(mContext, mTrackerHandler, na.messenger);
- NetworkInfo networkInfo = na.networkInfo;
- na.networkInfo = null;
- updateNetworkInfo(na, networkInfo);
- }
-
- private void updateLinkProperties(NetworkAgentInfo networkAgent, LinkProperties oldLp) {
- LinkProperties newLp = networkAgent.linkProperties;
- int netId = networkAgent.network.netId;
-
- updateInterfaces(newLp, oldLp, netId);
- updateMtu(newLp, oldLp);
- // TODO - figure out what to do for clat
-// for (LinkProperties lp : newLp.getStackedLinks()) {
-// updateMtu(lp, null);
-// }
- updateRoutes(newLp, oldLp, netId);
- updateDnses(newLp, oldLp, netId);
- updateClat(newLp, oldLp, networkAgent);
- }
-
- private void updateClat(LinkProperties newLp, LinkProperties oldLp, NetworkAgentInfo na) {
- // Update 464xlat state.
- if (mClat.requiresClat(na)) {
-
- // If the connection was previously using clat, but is not using it now, stop the clat
- // daemon. Normally, this happens automatically when the connection disconnects, but if
- // the disconnect is not reported, or if the connection's LinkProperties changed for
- // some other reason (e.g., handoff changes the IP addresses on the link), it would
- // still be running. If it's not running, then stopping it is a no-op.
- if (Nat464Xlat.isRunningClat(oldLp) && !Nat464Xlat.isRunningClat(newLp)) {
- mClat.stopClat();
- }
- // If the link requires clat to be running, then start the daemon now.
- if (na.networkInfo.isConnected()) {
- mClat.startClat(na);
- } else {
- mClat.stopClat();
- }
- }
- }
-
- private void updateInterfaces(LinkProperties newLp, LinkProperties oldLp, int netId) {
- CompareResult<String> interfaceDiff = new CompareResult<String>();
- if (oldLp != null) {
- interfaceDiff = oldLp.compareAllInterfaceNames(newLp);
- } else if (newLp != null) {
- interfaceDiff.added = newLp.getAllInterfaceNames();
- }
- for (String iface : interfaceDiff.added) {
- try {
- mNetd.addInterfaceToNetwork(iface, netId);
- } catch (Exception e) {
- loge("Exception adding interface: " + e);
- }
- }
- for (String iface : interfaceDiff.removed) {
- try {
- mNetd.removeInterfaceFromNetwork(iface, netId);
- } catch (Exception e) {
- loge("Exception removing interface: " + e);
- }
- }
- }
-
- private void updateRoutes(LinkProperties newLp, LinkProperties oldLp, int netId) {
- CompareResult<RouteInfo> routeDiff = new CompareResult<RouteInfo>();
- if (oldLp != null) {
- routeDiff = oldLp.compareAllRoutes(newLp);
- } else if (newLp != null) {
- routeDiff.added = newLp.getAllRoutes();
- }
-
- // add routes before removing old in case it helps with continuous connectivity
-
- // do this twice, adding non-nexthop routes first, then routes they are dependent on
- for (RouteInfo route : routeDiff.added) {
- if (route.hasGateway()) continue;
- try {
- mNetd.addRoute(netId, route);
- } catch (Exception e) {
- loge("Exception in addRoute for non-gateway: " + e);
- }
- }
- for (RouteInfo route : routeDiff.added) {
- if (route.hasGateway() == false) continue;
- try {
- mNetd.addRoute(netId, route);
- } catch (Exception e) {
- loge("Exception in addRoute for gateway: " + e);
- }
- }
-
- for (RouteInfo route : routeDiff.removed) {
- try {
- mNetd.removeRoute(netId, route);
- } catch (Exception e) {
- loge("Exception in removeRoute: " + e);
- }
- }
- }
- private void updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId) {
- if (oldLp == null || (newLp.isIdenticalDnses(oldLp) == false)) {
- Collection<InetAddress> dnses = newLp.getDnsServers();
- if (dnses.size() == 0 && mDefaultDns != null) {
- dnses = new ArrayList();
- dnses.add(mDefaultDns);
- if (DBG) {
- loge("no dns provided for netId " + netId + ", so using defaults");
- }
- }
- try {
- mNetd.setDnsServersForNetwork(netId, NetworkUtils.makeStrings(dnses),
- newLp.getDomains());
- } catch (Exception e) {
- loge("Exception in setDnsServersForNetwork: " + e);
- }
- NetworkAgentInfo defaultNai = mNetworkForRequestId.get(mDefaultRequest.requestId);
- if (defaultNai != null && defaultNai.network.netId == netId) {
- setDefaultDnsSystemProperties(dnses);
- }
- }
- }
-
- private void setDefaultDnsSystemProperties(Collection<InetAddress> dnses) {
- int last = 0;
- for (InetAddress dns : dnses) {
- ++last;
- String key = "net.dns" + last;
- String value = dns.getHostAddress();
- SystemProperties.set(key, value);
- }
- for (int i = last + 1; i <= mNumDnsEntries; ++i) {
- String key = "net.dns" + i;
- SystemProperties.set(key, "");
- }
- mNumDnsEntries = last;
- }
-
-
- private void updateCapabilities(NetworkAgentInfo networkAgent,
- NetworkCapabilities networkCapabilities) {
- // TODO - what else here? Verify still satisfies everybody?
- // Check if satisfies somebody new? call callbacks?
- networkAgent.networkCapabilities = networkCapabilities;
- }
-
- private void sendUpdatedScoreToFactories(NetworkRequest networkRequest, int score) {
- if (VDBG) log("sending new Min Network Score(" + score + "): " + networkRequest.toString());
- for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
- nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, score, 0,
- networkRequest);
- }
- }
-
- private void callCallbackForRequest(NetworkRequestInfo nri,
- NetworkAgentInfo networkAgent, int notificationType) {
- if (nri.messenger == null) return; // Default request has no msgr
- Object o;
- int a1 = 0;
- int a2 = 0;
- switch (notificationType) {
- case ConnectivityManager.CALLBACK_LOSING:
- a1 = 30; // TODO - read this from NetworkMonitor
- // fall through
- case ConnectivityManager.CALLBACK_PRECHECK:
- case ConnectivityManager.CALLBACK_AVAILABLE:
- case ConnectivityManager.CALLBACK_LOST:
- case ConnectivityManager.CALLBACK_CAP_CHANGED:
- case ConnectivityManager.CALLBACK_IP_CHANGED: {
- o = new NetworkRequest(nri.request);
- a2 = networkAgent.network.netId;
- break;
- }
- case ConnectivityManager.CALLBACK_UNAVAIL:
- case ConnectivityManager.CALLBACK_RELEASED: {
- o = new NetworkRequest(nri.request);
- break;
- }
- default: {
- loge("Unknown notificationType " + notificationType);
- return;
- }
- }
- Message msg = Message.obtain();
- msg.arg1 = a1;
- msg.arg2 = a2;
- msg.obj = o;
- msg.what = notificationType;
- try {
- if (VDBG) log("sending notification " + notificationType + " for " + nri.request);
- nri.messenger.send(msg);
- } catch (RemoteException e) {
- // may occur naturally in the race of binder death.
- loge("RemoteException caught trying to send a callback msg for " + nri.request);
- }
- }
-
- private void handleLingerComplete(NetworkAgentInfo oldNetwork) {
- if (oldNetwork == null) {
- loge("Unknown NetworkAgentInfo in handleLingerComplete");
- return;
- }
- if (DBG) log("handleLingerComplete for " + oldNetwork.name());
- if (DBG) {
- if (oldNetwork.networkRequests.size() != 0) {
- loge("Dead network still had " + oldNetwork.networkRequests.size() + " requests");
- }
- }
- oldNetwork.asyncChannel.disconnect();
- }
-
- private void handleConnectionValidated(NetworkAgentInfo newNetwork) {
- if (newNetwork == null) {
- loge("Unknown NetworkAgentInfo in handleConnectionValidated");
- return;
- }
- boolean keep = false;
- boolean isNewDefault = false;
- if (DBG) log("handleConnectionValidated for "+newNetwork.name());
- // check if any NetworkRequest wants this NetworkAgent
- ArrayList<NetworkAgentInfo> affectedNetworks = new ArrayList<NetworkAgentInfo>();
- if (VDBG) log(" new Network has: " + newNetwork.networkCapabilities);
- for (NetworkRequestInfo nri : mNetworkRequests.values()) {
- NetworkAgentInfo currentNetwork = mNetworkForRequestId.get(nri.request.requestId);
- if (newNetwork == currentNetwork) {
- if (VDBG) log("Network " + newNetwork.name() + " was already satisfying" +
- " request " + nri.request.requestId + ". No change.");
- keep = true;
- continue;
- }
-
- // check if it satisfies the NetworkCapabilities
- if (VDBG) log(" checking if request is satisfied: " + nri.request);
- if (nri.request.networkCapabilities.satisfiedByNetworkCapabilities(
- newNetwork.networkCapabilities)) {
- // next check if it's better than any current network we're using for
- // this request
- if (VDBG) {
- log("currentScore = " +
- (currentNetwork != null ? currentNetwork.currentScore : 0) +
- ", newScore = " + newNetwork.currentScore);
- }
- if (currentNetwork == null ||
- currentNetwork.currentScore < newNetwork.currentScore) {
- if (currentNetwork != null) {
- if (VDBG) log(" accepting network in place of " + currentNetwork.name());
- currentNetwork.networkRequests.remove(nri.request.requestId);
- currentNetwork.networkLingered.add(nri.request);
- affectedNetworks.add(currentNetwork);
- } else {
- if (VDBG) log(" accepting network in place of null");
- }
- mNetworkForRequestId.put(nri.request.requestId, newNetwork);
- newNetwork.addRequest(nri.request);
- int legacyType = nri.request.legacyType;
- if (legacyType != TYPE_NONE) {
- mLegacyTypeTracker.add(legacyType, newNetwork);
- }
- keep = true;
- // TODO - this could get expensive if we have alot of requests for this
- // network. Think about if there is a way to reduce this. Push
- // netid->request mapping to each factory?
- sendUpdatedScoreToFactories(nri.request, newNetwork.currentScore);
- if (mDefaultRequest.requestId == nri.request.requestId) {
- isNewDefault = true;
- updateActiveDefaultNetwork(newNetwork);
- if (newNetwork.linkProperties != null) {
- setDefaultDnsSystemProperties(
- newNetwork.linkProperties.getDnsServers());
- } else {
- setDefaultDnsSystemProperties(new ArrayList<InetAddress>());
- }
- mLegacyTypeTracker.add(newNetwork.networkInfo.getType(), newNetwork);
- }
- }
- }
- }
- for (NetworkAgentInfo nai : affectedNetworks) {
- boolean teardown = true;
- for (int i = 0; i < nai.networkRequests.size(); i++) {
- NetworkRequest nr = nai.networkRequests.valueAt(i);
- try {
- if (mNetworkRequests.get(nr).isRequest) {
- teardown = false;
- }
- } catch (Exception e) {
- loge("Request " + nr + " not found in mNetworkRequests.");
- loge(" it came from request list of " + nai.name());
- }
- }
- if (teardown) {
- nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_LINGER);
- notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOSING);
- } else {
- // not going to linger, so kill the list of linger networks.. only
- // notify them of linger if it happens as the result of gaining another,
- // but if they transition and old network stays up, don't tell them of linger
- // or very delayed loss
- nai.networkLingered.clear();
- if (VDBG) log("Lingered for " + nai.name() + " cleared");
- }
- }
- if (keep) {
- if (isNewDefault) {
- if (VDBG) log("Switching to new default network: " + newNetwork);
- setupDataActivityTracking(newNetwork);
- try {
- mNetd.setDefaultNetId(newNetwork.network.netId);
- } catch (Exception e) {
- loge("Exception setting default network :" + e);
- }
- if (newNetwork.equals(mNetworkForRequestId.get(mDefaultRequest.requestId))) {
- handleApplyDefaultProxy(newNetwork.linkProperties.getHttpProxy());
- }
- synchronized (ConnectivityService.this) {
- // have a new default network, release the transition wakelock in
- // a second if it's held. The second pause is to allow apps
- // to reconnect over the new network
- if (mNetTransitionWakeLock.isHeld()) {
- mHandler.sendMessageDelayed(mHandler.obtainMessage(
- EVENT_CLEAR_NET_TRANSITION_WAKELOCK,
- mNetTransitionWakeLockSerialNumber, 0),
- 1000);
- }
- }
-
- // this will cause us to come up initially as unconnected and switching
- // to connected after our normal pause unless somebody reports us as
- // really disconnected
- mDefaultInetConditionPublished = 0;
- mDefaultConnectionSequence++;
- mInetConditionChangeInFlight = false;
- // TODO - read the tcp buffer size config string from somewhere
- // updateNetworkSettings();
- }
- // notify battery stats service about this network
- try {
- BatteryStatsService.getService().noteNetworkInterfaceType(
- newNetwork.linkProperties.getInterfaceName(),
- newNetwork.networkInfo.getType());
- } catch (RemoteException e) { }
- notifyNetworkCallbacks(newNetwork, ConnectivityManager.CALLBACK_AVAILABLE);
- } else {
- if (DBG && newNetwork.networkRequests.size() != 0) {
- loge("tearing down network with live requests:");
- for (int i=0; i < newNetwork.networkRequests.size(); i++) {
- loge(" " + newNetwork.networkRequests.valueAt(i));
- }
- }
- if (VDBG) log("Validated network turns out to be unwanted. Tear it down.");
- newNetwork.asyncChannel.disconnect();
- }
- }
-
-
- private void updateNetworkInfo(NetworkAgentInfo networkAgent, NetworkInfo newInfo) {
- NetworkInfo.State state = newInfo.getState();
- NetworkInfo oldInfo = networkAgent.networkInfo;
- networkAgent.networkInfo = newInfo;
-
- if (oldInfo != null && oldInfo.getState() == state) {
- if (VDBG) log("ignoring duplicate network state non-change");
- return;
- }
- if (DBG) {
- log(networkAgent.name() + " EVENT_NETWORK_INFO_CHANGED, going from " +
- (oldInfo == null ? "null" : oldInfo.getState()) +
- " to " + state);
- }
-
- if (state == NetworkInfo.State.CONNECTED) {
- try {
- // This is likely caused by the fact that this network already
- // exists. An example is when a network goes from CONNECTED to
- // CONNECTING and back (like wifi on DHCP renew).
- // TODO: keep track of which networks we've created, or ask netd
- // to tell us whether we've already created this network or not.
- mNetd.createNetwork(networkAgent.network.netId);
- } catch (Exception e) {
- loge("Error creating network " + networkAgent.network.netId + ": "
- + e.getMessage());
- return;
- }
-
- updateLinkProperties(networkAgent, null);
- notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_PRECHECK);
- networkAgent.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_CONNECTED);
- } else if (state == NetworkInfo.State.DISCONNECTED ||
- state == NetworkInfo.State.SUSPENDED) {
- networkAgent.asyncChannel.disconnect();
- }
- }
-
- private void updateNetworkScore(NetworkAgentInfo nai, int score) {
- if (DBG) log("updateNetworkScore for " + nai.name() + " to " + score);
-
- nai.currentScore = score;
-
- // TODO - This will not do the right thing if this network is lowering
- // its score and has requests that can be served by other
- // currently-active networks, or if the network is increasing its
- // score and other networks have requests that can be better served
- // by this network.
- //
- // Really we want to see if any of our requests migrate to other
- // active/lingered networks and if any other requests migrate to us (depending
- // on increasing/decreasing currentScore. That's a bit of work and probably our
- // score checking/network allocation code needs to be modularized so we can understand
- // (see handleConnectionValided for an example).
- //
- // As a first order approx, lets just advertise the new score to factories. If
- // somebody can beat it they will nominate a network and our normal net replacement
- // code will fire.
- for (int i = 0; i < nai.networkRequests.size(); i++) {
- NetworkRequest nr = nai.networkRequests.valueAt(i);
- sendUpdatedScoreToFactories(nr, score);
- }
- }
-
- // notify only this one new request of the current state
- protected void notifyNetworkCallback(NetworkAgentInfo nai, NetworkRequestInfo nri) {
- int notifyType = ConnectivityManager.CALLBACK_AVAILABLE;
- // TODO - read state from monitor to decide what to send.
-// if (nai.networkMonitor.isLingering()) {
-// notifyType = NetworkCallbacks.LOSING;
-// } else if (nai.networkMonitor.isEvaluating()) {
-// notifyType = NetworkCallbacks.callCallbackForRequest(request, nai, notifyType);
-// }
- callCallbackForRequest(nri, nai, notifyType);
- }
-
- private void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, boolean connected, int type) {
- if (connected) {
- NetworkInfo info = new NetworkInfo(nai.networkInfo);
- info.setType(type);
- sendConnectedBroadcastDelayed(info, getConnectivityChangeDelay());
- } else {
- NetworkInfo info = new NetworkInfo(nai.networkInfo);
- info.setType(type);
- Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION);
- intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info);
- intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType());
- if (info.isFailover()) {
- intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
- nai.networkInfo.setFailover(false);
- }
- if (info.getReason() != null) {
- intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason());
- }
- if (info.getExtraInfo() != null) {
- intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, info.getExtraInfo());
- }
- NetworkAgentInfo newDefaultAgent = null;
- if (nai.networkRequests.get(mDefaultRequest.requestId) != null) {
- newDefaultAgent = mNetworkForRequestId.get(mDefaultRequest.requestId);
- if (newDefaultAgent != null) {
- intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO,
- newDefaultAgent.networkInfo);
- } else {
- intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
- }
- }
- intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION,
- mDefaultInetConditionPublished);
- final Intent immediateIntent = new Intent(intent);
- immediateIntent.setAction(CONNECTIVITY_ACTION_IMMEDIATE);
- sendStickyBroadcast(immediateIntent);
- sendStickyBroadcastDelayed(intent, getConnectivityChangeDelay());
- if (newDefaultAgent != null) {
- sendConnectedBroadcastDelayed(newDefaultAgent.networkInfo,
- getConnectivityChangeDelay());
- }
- }
- }
-
- protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType) {
- if (VDBG) log("notifyType " + notifyType + " for " + networkAgent.name());
- for (int i = 0; i < networkAgent.networkRequests.size(); i++) {
- NetworkRequest nr = networkAgent.networkRequests.valueAt(i);
- NetworkRequestInfo nri = mNetworkRequests.get(nr);
- if (VDBG) log(" sending notification for " + nr);
- callCallbackForRequest(nri, networkAgent, notifyType);
- }
- }
-
- private LinkProperties getLinkPropertiesForTypeInternal(int networkType) {
- NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
- return (nai != null) ?
- new LinkProperties(nai.linkProperties) :
- new LinkProperties();
- }
-
- private NetworkInfo getNetworkInfoForType(int networkType) {
- if (!mLegacyTypeTracker.isTypeSupported(networkType))
- return null;
-
- NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
- if (nai != null) {
- NetworkInfo result = new NetworkInfo(nai.networkInfo);
- result.setType(networkType);
- return result;
- } else {
- return new NetworkInfo(networkType, 0, "Unknown", "");
- }
- }
-
- private NetworkCapabilities getNetworkCapabilitiesForType(int networkType) {
- NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
- return (nai != null) ?
- new NetworkCapabilities(nai.networkCapabilities) :
- new NetworkCapabilities();
- }
-}
diff --git a/services/core/java/com/android/server/connectivity/Nat464Xlat.java b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
deleted file mode 100644
index 096ab66..0000000
--- a/services/core/java/com/android/server/connectivity/Nat464Xlat.java
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (C) 2012 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.server.connectivity;
-
-import static android.net.ConnectivityManager.TYPE_MOBILE;
-
-import java.net.Inet4Address;
-
-import android.content.Context;
-import android.net.IConnectivityManager;
-import android.net.InterfaceConfiguration;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.NetworkAgent;
-import android.net.NetworkUtils;
-import android.net.RouteInfo;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.INetworkManagementService;
-import android.os.RemoteException;
-import android.util.Slog;
-
-import com.android.server.net.BaseNetworkObserver;
-
-/**
- * @hide
- *
- * Class to manage a 464xlat CLAT daemon.
- */
-public class Nat464Xlat extends BaseNetworkObserver {
- private Context mContext;
- private INetworkManagementService mNMService;
- private IConnectivityManager mConnService;
- // Whether we started clatd and expect it to be running.
- private boolean mIsStarted;
- // Whether the clatd interface exists (i.e., clatd is running).
- private boolean mIsRunning;
- // The LinkProperties of the clat interface.
- private LinkProperties mLP;
- // Current LinkProperties of the network. Includes mLP as a stacked link when clat is active.
- private LinkProperties mBaseLP;
- // ConnectivityService Handler for LinkProperties updates.
- private Handler mHandler;
- // Marker to connote which network we're augmenting.
- private Messenger mNetworkMessenger;
-
- // This must match the interface name in clatd.conf.
- private static final String CLAT_INTERFACE_NAME = "clat4";
-
- private static final String TAG = "Nat464Xlat";
-
- public Nat464Xlat(Context context, INetworkManagementService nmService,
- IConnectivityManager connService, Handler handler) {
- mContext = context;
- mNMService = nmService;
- mConnService = connService;
- mHandler = handler;
-
- mIsStarted = false;
- mIsRunning = false;
- mLP = new LinkProperties();
-
- // If this is a runtime restart, it's possible that clatd is already
- // running, but we don't know about it. If so, stop it.
- try {
- if (mNMService.isClatdStarted()) {
- mNMService.stopClatd();
- }
- } catch(RemoteException e) {} // Well, we tried.
- }
-
- /**
- * Determines whether a network requires clat.
- * @param network the NetworkAgentInfo corresponding to the network.
- * @return true if the network requires clat, false otherwise.
- */
- public boolean requiresClat(NetworkAgentInfo network) {
- int netType = network.networkInfo.getType();
- LinkProperties lp = network.linkProperties;
- // Only support clat on mobile for now.
- Slog.d(TAG, "requiresClat: netType=" + netType + ", hasIPv4Address=" +
- lp.hasIPv4Address());
- return netType == TYPE_MOBILE && !lp.hasIPv4Address();
- }
-
- public static boolean isRunningClat(LinkProperties lp) {
- return lp != null && lp.getAllInterfaceNames().contains(CLAT_INTERFACE_NAME);
- }
-
- /**
- * Starts the clat daemon.
- * @param lp The link properties of the interface to start clatd on.
- */
- public void startClat(NetworkAgentInfo network) {
- if (mNetworkMessenger != null && mNetworkMessenger != network.messenger) {
- Slog.e(TAG, "startClat: too many networks requesting clat");
- return;
- }
- mNetworkMessenger = network.messenger;
- LinkProperties lp = network.linkProperties;
- mBaseLP = new LinkProperties(lp);
- if (mIsStarted) {
- Slog.e(TAG, "startClat: already started");
- return;
- }
- String iface = lp.getInterfaceName();
- Slog.i(TAG, "Starting clatd on " + iface + ", lp=" + lp);
- try {
- mNMService.startClatd(iface);
- } catch(RemoteException e) {
- Slog.e(TAG, "Error starting clat daemon: " + e);
- }
- mIsStarted = true;
- }
-
- /**
- * Stops the clat daemon.
- */
- public void stopClat() {
- if (mIsStarted) {
- Slog.i(TAG, "Stopping clatd");
- try {
- mNMService.stopClatd();
- } catch(RemoteException e) {
- Slog.e(TAG, "Error stopping clat daemon: " + e);
- }
- mIsStarted = false;
- mIsRunning = false;
- mNetworkMessenger = null;
- mBaseLP = null;
- mLP.clear();
- } else {
- Slog.e(TAG, "stopClat: already stopped");
- }
- }
-
- public boolean isStarted() {
- return mIsStarted;
- }
-
- public boolean isRunning() {
- return mIsRunning;
- }
-
- private void updateConnectivityService() {
- Message msg = mHandler.obtainMessage(
- NetworkAgent.EVENT_NETWORK_PROPERTIES_CHANGED, mBaseLP);
- msg.replyTo = mNetworkMessenger;
- Slog.i(TAG, "sending message to ConnectivityService: " + msg);
- msg.sendToTarget();
- }
-
- @Override
- public void interfaceAdded(String iface) {
- if (iface.equals(CLAT_INTERFACE_NAME)) {
- Slog.i(TAG, "interface " + CLAT_INTERFACE_NAME +
- " added, mIsRunning = " + mIsRunning + " -> true");
- mIsRunning = true;
-
- // Create the LinkProperties for the clat interface by fetching the
- // IPv4 address for the interface and adding an IPv4 default route,
- // then stack the LinkProperties on top of the link it's running on.
- // Although the clat interface is a point-to-point tunnel, we don't
- // point the route directly at the interface because some apps don't
- // understand routes without gateways (see, e.g., http://b/9597256
- // http://b/9597516). Instead, set the next hop of the route to the
- // clat IPv4 address itself (for those apps, it doesn't matter what
- // the IP of the gateway is, only that there is one).
- try {
- InterfaceConfiguration config = mNMService.getInterfaceConfig(iface);
- LinkAddress clatAddress = config.getLinkAddress();
- mLP.clear();
- mLP.setInterfaceName(iface);
- RouteInfo ipv4Default = new RouteInfo(new LinkAddress(Inet4Address.ANY, 0),
- clatAddress.getAddress(), iface);
- mLP.addRoute(ipv4Default);
- mLP.addLinkAddress(clatAddress);
- mBaseLP.addStackedLink(mLP);
- Slog.i(TAG, "Adding stacked link. tracker LP: " + mBaseLP);
- updateConnectivityService();
- } catch(RemoteException e) {
- Slog.e(TAG, "Error getting link properties: " + e);
- }
- }
- }
-
- @Override
- public void interfaceRemoved(String iface) {
- if (iface == CLAT_INTERFACE_NAME) {
- if (mIsRunning) {
- NetworkUtils.resetConnections(
- CLAT_INTERFACE_NAME,
- NetworkUtils.RESET_IPV4_ADDRESSES);
- mBaseLP.removeStackedLink(mLP);
- updateConnectivityService();
- }
- Slog.i(TAG, "interface " + CLAT_INTERFACE_NAME +
- " removed, mIsRunning = " + mIsRunning + " -> false");
- mIsRunning = false;
- mLP.clear();
- Slog.i(TAG, "mLP = " + mLP);
- }
- }
-};
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
deleted file mode 100644
index b03c247..0000000
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2014 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.server.connectivity;
-
-import android.content.Context;
-import android.net.LinkProperties;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkInfo;
-import android.net.NetworkRequest;
-import android.os.Handler;
-import android.os.Messenger;
-import android.util.SparseArray;
-
-import com.android.internal.util.AsyncChannel;
-import com.android.server.connectivity.NetworkMonitor;
-
-import java.util.ArrayList;
-
-/**
- * A bag class used by ConnectivityService for holding a collection of most recent
- * information published by a particular NetworkAgent as well as the
- * AsyncChannel/messenger for reaching that NetworkAgent and lists of NetworkRequests
- * interested in using it.
- */
-public class NetworkAgentInfo {
- public NetworkInfo networkInfo;
- public final Network network;
- public LinkProperties linkProperties;
- public NetworkCapabilities networkCapabilities;
- public int currentScore;
- public final NetworkMonitor networkMonitor;
-
- // The list of NetworkRequests being satisfied by this Network.
- public final SparseArray<NetworkRequest> networkRequests = new SparseArray<NetworkRequest>();
- public final ArrayList<NetworkRequest> networkLingered = new ArrayList<NetworkRequest>();
-
- public final Messenger messenger;
- public final AsyncChannel asyncChannel;
-
- public NetworkAgentInfo(Messenger messenger, AsyncChannel ac, int netId, NetworkInfo info,
- LinkProperties lp, NetworkCapabilities nc, int score, Context context,
- Handler handler) {
- this.messenger = messenger;
- asyncChannel = ac;
- network = new Network(netId);
- networkInfo = info;
- linkProperties = lp;
- networkCapabilities = nc;
- currentScore = score;
- networkMonitor = new NetworkMonitor(context, handler, this);
- }
-
- public void addRequest(NetworkRequest networkRequest) {
- networkRequests.put(networkRequest.requestId, networkRequest);
- }
-
- public String toString() {
- return "NetworkAgentInfo{ ni{" + networkInfo + "} network{" +
- network + "} lp{" +
- linkProperties + "} nc{" +
- networkCapabilities + "} Score{" + currentScore + "} }";
- }
-
- public String name() {
- return "NetworkAgentInfo [" + networkInfo.getTypeName() + " (" +
- networkInfo.getSubtypeName() + ")]";
- }
-}
diff --git a/services/tests/servicestests/res/raw/netstats_uid_v4 b/services/tests/servicestests/res/raw/netstats_uid_v4
deleted file mode 100644
index e75fc1c..0000000
--- a/services/tests/servicestests/res/raw/netstats_uid_v4
+++ /dev/null
Binary files differ
diff --git a/services/tests/servicestests/res/raw/netstats_v1 b/services/tests/servicestests/res/raw/netstats_v1
deleted file mode 100644
index e80860a..0000000
--- a/services/tests/servicestests/res/raw/netstats_v1
+++ /dev/null
Binary files differ
diff --git a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
deleted file mode 100644
index 88aaafc..0000000
--- a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Copyright (C) 2012 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.server;
-
-import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE;
-import static android.net.ConnectivityManager.TYPE_MOBILE;
-import static android.net.ConnectivityManager.TYPE_WIFI;
-import static android.net.ConnectivityManager.getNetworkTypeName;
-import static android.net.NetworkStateTracker.EVENT_STATE_CHANGED;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Matchers.isA;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-import android.net.INetworkPolicyManager;
-import android.net.INetworkStatsService;
-import android.net.LinkProperties;
-import android.net.NetworkConfig;
-import android.net.NetworkInfo;
-import android.net.NetworkInfo.DetailedState;
-import android.net.NetworkStateTracker;
-import android.net.RouteInfo;
-import android.os.Handler;
-import android.os.INetworkManagementService;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.util.Log;
-import android.util.LogPrinter;
-
-import org.mockito.ArgumentCaptor;
-
-import java.net.InetAddress;
-import java.util.concurrent.Future;
-
-/**
- * Tests for {@link ConnectivityService}.
- */
-@LargeTest
-public class ConnectivityServiceTest extends AndroidTestCase {
- private static final String TAG = "ConnectivityServiceTest";
-
- private static final String MOBILE_IFACE = "rmnet3";
- private static final String WIFI_IFACE = "wlan6";
-
- private static final RouteInfo MOBILE_ROUTE_V4 = RouteInfo.makeHostRoute(parse("10.0.0.33"),
- MOBILE_IFACE);
- private static final RouteInfo MOBILE_ROUTE_V6 = RouteInfo.makeHostRoute(parse("fd00::33"),
- MOBILE_IFACE);
-
- private static final RouteInfo WIFI_ROUTE_V4 = RouteInfo.makeHostRoute(parse("192.168.0.66"),
- parse("192.168.0.1"),
- WIFI_IFACE);
- private static final RouteInfo WIFI_ROUTE_V6 = RouteInfo.makeHostRoute(parse("fd00::66"),
- parse("fd00::"),
- WIFI_IFACE);
-
- private INetworkManagementService mNetManager;
- private INetworkStatsService mStatsService;
- private INetworkPolicyManager mPolicyService;
- private ConnectivityService.NetworkFactory mNetFactory;
-
- private BroadcastInterceptingContext mServiceContext;
- private ConnectivityService mService;
-
- private MockNetwork mMobile;
- private MockNetwork mWifi;
-
- private Handler mTrackerHandler;
-
- private static class MockNetwork {
- public NetworkStateTracker tracker;
- public NetworkInfo info;
- public LinkProperties link;
-
- public MockNetwork(int type) {
- tracker = mock(NetworkStateTracker.class);
- info = new NetworkInfo(type, -1, getNetworkTypeName(type), null);
- link = new LinkProperties();
- }
-
- public void doReturnDefaults() {
- // TODO: eventually CS should make defensive copies
- doReturn(new NetworkInfo(info)).when(tracker).getNetworkInfo();
- doReturn(new LinkProperties(link)).when(tracker).getLinkProperties();
-
- // fallback to default TCP buffers
- doReturn("").when(tracker).getTcpBufferSizesPropName();
- }
- }
-
- @Override
- public void setUp() throws Exception {
- super.setUp();
-
- mServiceContext = new BroadcastInterceptingContext(getContext());
-
- mNetManager = mock(INetworkManagementService.class);
- mStatsService = mock(INetworkStatsService.class);
- mPolicyService = mock(INetworkPolicyManager.class);
- mNetFactory = mock(ConnectivityService.NetworkFactory.class);
-
- mMobile = new MockNetwork(TYPE_MOBILE);
- mWifi = new MockNetwork(TYPE_WIFI);
-
- // omit most network trackers
- doThrow(new IllegalArgumentException("Not supported in test environment"))
- .when(mNetFactory).createTracker(anyInt(), isA(NetworkConfig.class));
-
- doReturn(mMobile.tracker)
- .when(mNetFactory).createTracker(eq(TYPE_MOBILE), isA(NetworkConfig.class));
- doReturn(mWifi.tracker)
- .when(mNetFactory).createTracker(eq(TYPE_WIFI), isA(NetworkConfig.class));
-
- final ArgumentCaptor<Handler> trackerHandler = ArgumentCaptor.forClass(Handler.class);
- doNothing().when(mMobile.tracker)
- .startMonitoring(isA(Context.class), trackerHandler.capture());
-
- mService = new ConnectivityService(
- mServiceContext, mNetManager, mStatsService, mPolicyService, mNetFactory);
- mService.systemReady();
-
- mTrackerHandler = trackerHandler.getValue();
- mTrackerHandler.getLooper().setMessageLogging(new LogPrinter(Log.INFO, TAG));
- }
-
- @Override
- public void tearDown() throws Exception {
- super.tearDown();
- }
-
- public void testMobileConnectedAddedRoutes() throws Exception {
- Future<?> nextConnBroadcast;
-
- // bring up mobile network
- mMobile.info.setDetailedState(DetailedState.CONNECTED, null, null);
- mMobile.link.setInterfaceName(MOBILE_IFACE);
- mMobile.link.addRoute(MOBILE_ROUTE_V4);
- mMobile.link.addRoute(MOBILE_ROUTE_V6);
- mMobile.doReturnDefaults();
-
- nextConnBroadcast = mServiceContext.nextBroadcastIntent(CONNECTIVITY_ACTION_IMMEDIATE);
- mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mMobile.info).sendToTarget();
- nextConnBroadcast.get();
-
- // verify that both routes were added and DNS was flushed
- int mobileNetId = mMobile.tracker.getNetwork().netId;
- verify(mNetManager).addRoute(eq(mobileNetId), eq(MOBILE_ROUTE_V4));
- verify(mNetManager).addRoute(eq(mobileNetId), eq(MOBILE_ROUTE_V6));
- verify(mNetManager).flushNetworkDnsCache(mobileNetId);
-
- }
-
- public void testMobileWifiHandoff() throws Exception {
- Future<?> nextConnBroadcast;
-
- // bring up mobile network
- mMobile.info.setDetailedState(DetailedState.CONNECTED, null, null);
- mMobile.link.setInterfaceName(MOBILE_IFACE);
- mMobile.link.addRoute(MOBILE_ROUTE_V4);
- mMobile.link.addRoute(MOBILE_ROUTE_V6);
- mMobile.doReturnDefaults();
-
- nextConnBroadcast = mServiceContext.nextBroadcastIntent(CONNECTIVITY_ACTION_IMMEDIATE);
- mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mMobile.info).sendToTarget();
- nextConnBroadcast.get();
-
- reset(mNetManager);
-
- // now bring up wifi network
- mWifi.info.setDetailedState(DetailedState.CONNECTED, null, null);
- mWifi.link.setInterfaceName(WIFI_IFACE);
- mWifi.link.addRoute(WIFI_ROUTE_V4);
- mWifi.link.addRoute(WIFI_ROUTE_V6);
- mWifi.doReturnDefaults();
-
- // expect that mobile will be torn down
- doReturn(true).when(mMobile.tracker).teardown();
-
- nextConnBroadcast = mServiceContext.nextBroadcastIntent(CONNECTIVITY_ACTION_IMMEDIATE);
- mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mWifi.info).sendToTarget();
- nextConnBroadcast.get();
-
- // verify that wifi routes added, and teardown requested
- int wifiNetId = mWifi.tracker.getNetwork().netId;
- verify(mNetManager).addRoute(eq(wifiNetId), eq(WIFI_ROUTE_V4));
- verify(mNetManager).addRoute(eq(wifiNetId), eq(WIFI_ROUTE_V6));
- verify(mNetManager).flushNetworkDnsCache(wifiNetId);
- verify(mMobile.tracker).teardown();
-
- int mobileNetId = mMobile.tracker.getNetwork().netId;
-
- reset(mNetManager, mMobile.tracker);
-
- // tear down mobile network, as requested
- mMobile.info.setDetailedState(DetailedState.DISCONNECTED, null, null);
- mMobile.link.clear();
- mMobile.doReturnDefaults();
-
- nextConnBroadcast = mServiceContext.nextBroadcastIntent(CONNECTIVITY_ACTION_IMMEDIATE);
- mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mMobile.info).sendToTarget();
- nextConnBroadcast.get();
-
- verify(mNetManager).removeRoute(eq(mobileNetId), eq(MOBILE_ROUTE_V4));
- verify(mNetManager).removeRoute(eq(mobileNetId), eq(MOBILE_ROUTE_V6));
-
- }
-
- private static InetAddress parse(String addr) {
- return InetAddress.parseNumericAddress(addr);
- }
-}
diff --git a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
deleted file mode 100644
index 0d5daa5..0000000
--- a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (C) 2012 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.server;
-
-import android.content.Context;
-import android.net.LinkAddress;
-import android.net.LocalSocket;
-import android.net.LocalServerSocket;
-import android.os.Binder;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
-import com.android.server.net.BaseNetworkObserver;
-
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * Tests for {@link NetworkManagementService}.
- */
-@LargeTest
-public class NetworkManagementServiceTest extends AndroidTestCase {
-
- private static final String SOCKET_NAME = "__test__NetworkManagementServiceTest";
- private NetworkManagementService mNMService;
- private LocalServerSocket mServerSocket;
- private LocalSocket mSocket;
- private OutputStream mOutputStream;
-
- @Override
- public void setUp() throws Exception {
- super.setUp();
- // TODO: make this unnecessary. runtest might already make it unnecessary.
- System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString());
-
- // Set up a sheltered test environment.
- BroadcastInterceptingContext context = new BroadcastInterceptingContext(getContext());
- mServerSocket = new LocalServerSocket(SOCKET_NAME);
-
- // Start the service and wait until it connects to our socket.
- mNMService = NetworkManagementService.create(context, SOCKET_NAME);
- mSocket = mServerSocket.accept();
- mOutputStream = mSocket.getOutputStream();
- }
-
- @Override
- public void tearDown() throws Exception {
- if (mSocket != null) mSocket.close();
- if (mServerSocket != null) mServerSocket.close();
- super.tearDown();
- }
-
- /**
- * Sends a message on the netd socket and gives the events some time to make it back.
- */
- private void sendMessage(String message) throws IOException {
- // Strings are null-terminated, so add "\0" at the end.
- mOutputStream.write((message + "\0").getBytes());
- }
-
- private static <T> T expectSoon(T mock) {
- return verify(mock, timeout(100));
- }
-
- /**
- * Tests that network observers work properly.
- */
- public void testNetworkObservers() throws Exception {
- BaseNetworkObserver observer = mock(BaseNetworkObserver.class);
- doReturn(new Binder()).when(observer).asBinder(); // Used by registerObserver.
- mNMService.registerObserver(observer);
-
- // Forget everything that happened to the mock so far, so we can explicitly verify
- // everything that happens and does not happen to it from now on.
- reset(observer);
-
- // Now send NetworkManagementService messages and ensure that the observer methods are
- // called. After every valid message we expect a callback soon after; to ensure that
- // invalid messages don't cause any callbacks, we call verifyNoMoreInteractions at the end.
-
- /**
- * Interface changes.
- */
- sendMessage("600 Iface added rmnet12");
- expectSoon(observer).interfaceAdded("rmnet12");
-
- sendMessage("600 Iface removed eth1");
- expectSoon(observer).interfaceRemoved("eth1");
-
- sendMessage("607 Iface removed eth1");
- // Invalid code.
-
- sendMessage("600 Iface borked lo down");
- // Invalid event.
-
- sendMessage("600 Iface changed clat4 up again");
- // Extra tokens.
-
- sendMessage("600 Iface changed clat4 up");
- expectSoon(observer).interfaceStatusChanged("clat4", true);
-
- sendMessage("600 Iface linkstate rmnet0 down");
- expectSoon(observer).interfaceLinkStateChanged("rmnet0", false);
-
- sendMessage("600 IFACE linkstate clat4 up");
- // Invalid group.
-
- /**
- * Bandwidth control events.
- */
- sendMessage("601 limit alert data rmnet_usb0");
- expectSoon(observer).limitReached("data", "rmnet_usb0");
-
- sendMessage("601 invalid alert data rmnet0");
- // Invalid group.
-
- sendMessage("601 limit increased data rmnet0");
- // Invalid event.
-
-
- /**
- * Interface class activity.
- */
-
- sendMessage("613 IfaceClass active rmnet0");
- expectSoon(observer).interfaceClassDataActivityChanged("rmnet0", true, 0);
-
- sendMessage("613 IfaceClass active rmnet0 1234");
- expectSoon(observer).interfaceClassDataActivityChanged("rmnet0", true, 1234);
-
- sendMessage("613 IfaceClass idle eth0");
- expectSoon(observer).interfaceClassDataActivityChanged("eth0", false, 0);
-
- sendMessage("613 IfaceClass idle eth0 1234");
- expectSoon(observer).interfaceClassDataActivityChanged("eth0", false, 1234);
-
- sendMessage("613 IfaceClass reallyactive rmnet0 1234");
- expectSoon(observer).interfaceClassDataActivityChanged("rmnet0", false, 1234);
-
- sendMessage("613 InterfaceClass reallyactive rmnet0");
- // Invalid group.
-
-
- /**
- * IP address changes.
- */
- sendMessage("614 Address updated fe80::1/64 wlan0 128 253");
- expectSoon(observer).addressUpdated("wlan0", new LinkAddress("fe80::1/64", 128, 253));
-
- // There is no "added", so we take this as "removed".
- sendMessage("614 Address added fe80::1/64 wlan0 128 253");
- expectSoon(observer).addressRemoved("wlan0", new LinkAddress("fe80::1/64", 128, 253));
-
- sendMessage("614 Address removed 2001:db8::1/64 wlan0 1 0");
- expectSoon(observer).addressRemoved("wlan0", new LinkAddress("2001:db8::1/64", 1, 0));
-
- sendMessage("614 Address removed 2001:db8::1/64 wlan0 1");
- // Not enough arguments.
-
- sendMessage("666 Address removed 2001:db8::1/64 wlan0 1 0");
- // Invalid code.
-
-
- /**
- * DNS information broadcasts.
- */
- sendMessage("615 DnsInfo servers rmnet_usb0 3600 2001:db8::1");
- expectSoon(observer).interfaceDnsServerInfo("rmnet_usb0", 3600,
- new String[]{"2001:db8::1"});
-
- sendMessage("615 DnsInfo servers wlan0 14400 2001:db8::1,2001:db8::2");
- expectSoon(observer).interfaceDnsServerInfo("wlan0", 14400,
- new String[]{"2001:db8::1", "2001:db8::2"});
-
- // We don't check for negative lifetimes, only for parse errors.
- sendMessage("615 DnsInfo servers wlan0 -3600 ::1");
- expectSoon(observer).interfaceDnsServerInfo("wlan0", -3600,
- new String[]{"::1"});
-
- sendMessage("615 DnsInfo servers wlan0 SIXHUNDRED ::1");
- // Non-numeric lifetime.
-
- sendMessage("615 DnsInfo servers wlan0 2001:db8::1");
- // Missing lifetime.
-
- sendMessage("615 DnsInfo servers wlan0 3600");
- // No servers.
-
- sendMessage("615 DnsInfo servers 3600 wlan0 2001:db8::1,2001:db8::2");
- // Non-numeric lifetime.
-
- sendMessage("615 DnsInfo wlan0 7200 2001:db8::1,2001:db8::2");
- // Invalid tokens.
-
- sendMessage("666 DnsInfo servers wlan0 5400 2001:db8::1");
- // Invalid code.
-
- // No syntax checking on the addresses.
- sendMessage("615 DnsInfo servers wlan0 600 ,::,,foo,::1,");
- expectSoon(observer).interfaceDnsServerInfo("wlan0", 600,
- new String[]{"", "::", "", "foo", "::1"});
-
- // Make sure nothing else was called.
- verifyNoMoreInteractions(observer);
- }
-}
diff --git a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
deleted file mode 100644
index a1af8cb..0000000
--- a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
+++ /dev/null
@@ -1,1057 +0,0 @@
-/*
- * Copyright (C) 2011 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.server;
-
-import static android.content.Intent.ACTION_UID_REMOVED;
-import static android.content.Intent.EXTRA_UID;
-import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE;
-import static android.net.ConnectivityManager.TYPE_MOBILE;
-import static android.net.ConnectivityManager.TYPE_WIFI;
-import static android.net.ConnectivityManager.TYPE_WIMAX;
-import static android.net.NetworkStats.IFACE_ALL;
-import static android.net.NetworkStats.SET_ALL;
-import static android.net.NetworkStats.SET_DEFAULT;
-import static android.net.NetworkStats.SET_FOREGROUND;
-import static android.net.NetworkStats.TAG_NONE;
-import static android.net.NetworkStats.UID_ALL;
-import static android.net.NetworkStatsHistory.FIELD_ALL;
-import static android.net.NetworkTemplate.buildTemplateMobileAll;
-import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
-import static android.net.TrafficStats.MB_IN_BYTES;
-import static android.net.TrafficStats.UID_REMOVED;
-import static android.net.TrafficStats.UID_TETHERING;
-import static android.text.format.DateUtils.DAY_IN_MILLIS;
-import static android.text.format.DateUtils.HOUR_IN_MILLIS;
-import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
-import static android.text.format.DateUtils.WEEK_IN_MILLIS;
-import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_POLL;
-import static org.easymock.EasyMock.anyLong;
-import static org.easymock.EasyMock.capture;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.eq;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.expectLastCall;
-import static org.easymock.EasyMock.isA;
-
-import android.app.AlarmManager;
-import android.app.IAlarmManager;
-import android.app.PendingIntent;
-import android.content.Intent;
-import android.net.IConnectivityManager;
-import android.net.INetworkManagementEventObserver;
-import android.net.INetworkStatsSession;
-import android.net.LinkProperties;
-import android.net.NetworkInfo;
-import android.net.NetworkInfo.DetailedState;
-import android.net.NetworkState;
-import android.net.NetworkStats;
-import android.net.NetworkStatsHistory;
-import android.net.NetworkTemplate;
-import android.os.INetworkManagementService;
-import android.os.WorkSource;
-import android.telephony.TelephonyManager;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.Suppress;
-import android.util.TrustedTime;
-
-import com.android.server.net.NetworkStatsService;
-import com.android.server.net.NetworkStatsService.NetworkStatsSettings;
-import com.android.server.net.NetworkStatsService.NetworkStatsSettings.Config;
-
-import libcore.io.IoUtils;
-
-import org.easymock.Capture;
-import org.easymock.EasyMock;
-
-import java.io.File;
-
-/**
- * Tests for {@link NetworkStatsService}.
- */
-@LargeTest
-public class NetworkStatsServiceTest extends AndroidTestCase {
- private static final String TAG = "NetworkStatsServiceTest";
-
- private static final String TEST_IFACE = "test0";
- private static final String TEST_IFACE2 = "test1";
- private static final long TEST_START = 1194220800000L;
-
- private static final String IMSI_1 = "310004";
- private static final String IMSI_2 = "310260";
- private static final String TEST_SSID = "AndroidAP";
-
- private static NetworkTemplate sTemplateWifi = buildTemplateWifiWildcard();
- private static NetworkTemplate sTemplateImsi1 = buildTemplateMobileAll(IMSI_1);
- private static NetworkTemplate sTemplateImsi2 = buildTemplateMobileAll(IMSI_2);
-
- private static final int UID_RED = 1001;
- private static final int UID_BLUE = 1002;
- private static final int UID_GREEN = 1003;
-
- private long mElapsedRealtime;
-
- private BroadcastInterceptingContext mServiceContext;
- private File mStatsDir;
-
- private INetworkManagementService mNetManager;
- private IAlarmManager mAlarmManager;
- private TrustedTime mTime;
- private NetworkStatsSettings mSettings;
- private IConnectivityManager mConnManager;
-
- private NetworkStatsService mService;
- private INetworkStatsSession mSession;
- private INetworkManagementEventObserver mNetworkObserver;
-
- @Override
- public void setUp() throws Exception {
- super.setUp();
-
- mServiceContext = new BroadcastInterceptingContext(getContext());
- mStatsDir = getContext().getFilesDir();
- if (mStatsDir.exists()) {
- IoUtils.deleteContents(mStatsDir);
- }
-
- mNetManager = createMock(INetworkManagementService.class);
- mAlarmManager = createMock(IAlarmManager.class);
- mTime = createMock(TrustedTime.class);
- mSettings = createMock(NetworkStatsSettings.class);
- mConnManager = createMock(IConnectivityManager.class);
-
- mService = new NetworkStatsService(
- mServiceContext, mNetManager, mAlarmManager, mTime, mStatsDir, mSettings);
- mService.bindConnectivityManager(mConnManager);
-
- mElapsedRealtime = 0L;
-
- expectCurrentTime();
- expectDefaultSettings();
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
- expectSystemReady();
-
- // catch INetworkManagementEventObserver during systemReady()
- final Capture<INetworkManagementEventObserver> networkObserver = new Capture<
- INetworkManagementEventObserver>();
- mNetManager.registerObserver(capture(networkObserver));
- expectLastCall().atLeastOnce();
-
- replay();
- mService.systemReady();
- mSession = mService.openSession();
- verifyAndReset();
-
- mNetworkObserver = networkObserver.getValue();
-
- }
-
- @Override
- public void tearDown() throws Exception {
- IoUtils.deleteContents(mStatsDir);
-
- mServiceContext = null;
- mStatsDir = null;
-
- mNetManager = null;
- mAlarmManager = null;
- mTime = null;
- mSettings = null;
- mConnManager = null;
-
- mSession.close();
- mService = null;
-
- super.tearDown();
- }
-
- public void testNetworkStatsWifi() throws Exception {
- // pretend that wifi network comes online; service should ask about full
- // network state, and poll any existing interfaces before updating.
- expectCurrentTime();
- expectDefaultSettings();
- expectNetworkState(buildWifiState());
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
- expectNetworkStatsPoll();
-
- replay();
- mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
-
- // verify service has empty history for wifi
- assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
- verifyAndReset();
-
- // modify some number on wifi, and trigger poll event
- incrementCurrentTime(HOUR_IN_MILLIS);
- expectCurrentTime();
- expectDefaultSettings();
- expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
- .addIfaceValues(TEST_IFACE, 1024L, 1L, 2048L, 2L));
- expectNetworkStatsUidDetail(buildEmptyStats());
- expectNetworkStatsPoll();
-
- replay();
- mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
-
- // verify service recorded history
- assertNetworkTotal(sTemplateWifi, 1024L, 1L, 2048L, 2L, 0);
- verifyAndReset();
-
- // and bump forward again, with counters going higher. this is
- // important, since polling should correctly subtract last snapshot.
- incrementCurrentTime(DAY_IN_MILLIS);
- expectCurrentTime();
- expectDefaultSettings();
- expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
- .addIfaceValues(TEST_IFACE, 4096L, 4L, 8192L, 8L));
- expectNetworkStatsUidDetail(buildEmptyStats());
- expectNetworkStatsPoll();
-
- replay();
- mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
-
- // verify service recorded history
- assertNetworkTotal(sTemplateWifi, 4096L, 4L, 8192L, 8L, 0);
- verifyAndReset();
-
- }
-
- public void testStatsRebootPersist() throws Exception {
- assertStatsFilesExist(false);
-
- // pretend that wifi network comes online; service should ask about full
- // network state, and poll any existing interfaces before updating.
- expectCurrentTime();
- expectDefaultSettings();
- expectNetworkState(buildWifiState());
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
- expectNetworkStatsPoll();
-
- replay();
- mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
-
- // verify service has empty history for wifi
- assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
- verifyAndReset();
-
- // modify some number on wifi, and trigger poll event
- incrementCurrentTime(HOUR_IN_MILLIS);
- expectCurrentTime();
- expectDefaultSettings();
- expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
- .addIfaceValues(TEST_IFACE, 1024L, 8L, 2048L, 16L));
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 2)
- .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
- .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 256L, 2L, 128L, 1L, 0L)
- .addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
- .addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 256L, 2L, 128L, 1L, 0L)
- .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 0L));
- expectNetworkStatsPoll();
-
- mService.setUidForeground(UID_RED, false);
- mService.incrementOperationCount(UID_RED, 0xFAAD, 4);
- mService.setUidForeground(UID_RED, true);
- mService.incrementOperationCount(UID_RED, 0xFAAD, 6);
-
- replay();
- mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
-
- // verify service recorded history
- assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0);
- assertUidTotal(sTemplateWifi, UID_RED, 1024L, 8L, 512L, 4L, 10);
- assertUidTotal(sTemplateWifi, UID_RED, SET_DEFAULT, 512L, 4L, 256L, 2L, 4);
- assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, 512L, 4L, 256L, 2L, 6);
- assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 0);
- verifyAndReset();
-
- // graceful shutdown system, which should trigger persist of stats, and
- // clear any values in memory.
- expectCurrentTime();
- expectDefaultSettings();
- replay();
- mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SHUTDOWN));
- verifyAndReset();
-
- assertStatsFilesExist(true);
-
- // boot through serviceReady() again
- expectCurrentTime();
- expectDefaultSettings();
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
- expectSystemReady();
-
- // catch INetworkManagementEventObserver during systemReady()
- final Capture<INetworkManagementEventObserver> networkObserver = new Capture<
- INetworkManagementEventObserver>();
- mNetManager.registerObserver(capture(networkObserver));
- expectLastCall().atLeastOnce();
-
- replay();
- mService.systemReady();
-
- mNetworkObserver = networkObserver.getValue();
-
- // after systemReady(), we should have historical stats loaded again
- assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0);
- assertUidTotal(sTemplateWifi, UID_RED, 1024L, 8L, 512L, 4L, 10);
- assertUidTotal(sTemplateWifi, UID_RED, SET_DEFAULT, 512L, 4L, 256L, 2L, 4);
- assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, 512L, 4L, 256L, 2L, 6);
- assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 0);
- verifyAndReset();
-
- }
-
- // TODO: simulate reboot to test bucket resize
- @Suppress
- public void testStatsBucketResize() throws Exception {
- NetworkStatsHistory history = null;
-
- assertStatsFilesExist(false);
-
- // pretend that wifi network comes online; service should ask about full
- // network state, and poll any existing interfaces before updating.
- expectCurrentTime();
- expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
- expectNetworkState(buildWifiState());
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
- expectNetworkStatsPoll();
-
- replay();
- mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
- verifyAndReset();
-
- // modify some number on wifi, and trigger poll event
- incrementCurrentTime(2 * HOUR_IN_MILLIS);
- expectCurrentTime();
- expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
- expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
- .addIfaceValues(TEST_IFACE, 512L, 4L, 512L, 4L));
- expectNetworkStatsUidDetail(buildEmptyStats());
- expectNetworkStatsPoll();
-
- replay();
- mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
-
- // verify service recorded history
- history = mSession.getHistoryForNetwork(sTemplateWifi, FIELD_ALL);
- assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, 512L, 4L, 512L, 4L, 0);
- assertEquals(HOUR_IN_MILLIS, history.getBucketDuration());
- assertEquals(2, history.size());
- verifyAndReset();
-
- // now change bucket duration setting and trigger another poll with
- // exact same values, which should resize existing buckets.
- expectCurrentTime();
- expectSettings(0L, 30 * MINUTE_IN_MILLIS, WEEK_IN_MILLIS);
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
- expectNetworkStatsPoll();
-
- replay();
- mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
-
- // verify identical stats, but spread across 4 buckets now
- history = mSession.getHistoryForNetwork(sTemplateWifi, FIELD_ALL);
- assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, 512L, 4L, 512L, 4L, 0);
- assertEquals(30 * MINUTE_IN_MILLIS, history.getBucketDuration());
- assertEquals(4, history.size());
- verifyAndReset();
-
- }
-
- public void testUidStatsAcrossNetworks() throws Exception {
- // pretend first mobile network comes online
- expectCurrentTime();
- expectDefaultSettings();
- expectNetworkState(buildMobile3gState(IMSI_1));
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
- expectNetworkStatsPoll();
-
- replay();
- mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
- verifyAndReset();
-
- // create some traffic on first network
- incrementCurrentTime(HOUR_IN_MILLIS);
- expectCurrentTime();
- expectDefaultSettings();
- expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
- .addIfaceValues(TEST_IFACE, 2048L, 16L, 512L, 4L));
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
- .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
- .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
- .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
- expectNetworkStatsPoll();
-
- mService.incrementOperationCount(UID_RED, 0xF00D, 10);
-
- replay();
- mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
-
- // verify service recorded history
- assertNetworkTotal(sTemplateImsi1, 2048L, 16L, 512L, 4L, 0);
- assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
- assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 512L, 4L, 10);
- assertUidTotal(sTemplateImsi1, UID_BLUE, 512L, 4L, 0L, 0L, 0);
- verifyAndReset();
-
- // now switch networks; this also tests that we're okay with interfaces
- // disappearing, to verify we don't count backwards.
- incrementCurrentTime(HOUR_IN_MILLIS);
- expectCurrentTime();
- expectDefaultSettings();
- expectNetworkState(buildMobile3gState(IMSI_2));
- expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
- .addIfaceValues(TEST_IFACE, 2048L, 16L, 512L, 4L));
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
- .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
- .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
- .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
- expectNetworkStatsPoll();
-
- replay();
- mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
- mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
- verifyAndReset();
-
- // create traffic on second network
- incrementCurrentTime(HOUR_IN_MILLIS);
- expectCurrentTime();
- expectDefaultSettings();
- expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
- .addIfaceValues(TEST_IFACE, 2176L, 17L, 1536L, 12L));
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
- .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
- .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
- .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 640L, 5L, 1024L, 8L, 0L)
- .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, 0xFAAD, 128L, 1L, 1024L, 8L, 0L));
- expectNetworkStatsPoll();
-
- mService.incrementOperationCount(UID_BLUE, 0xFAAD, 10);
-
- replay();
- mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
-
- // verify original history still intact
- assertNetworkTotal(sTemplateImsi1, 2048L, 16L, 512L, 4L, 0);
- assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 512L, 4L, 10);
- assertUidTotal(sTemplateImsi1, UID_BLUE, 512L, 4L, 0L, 0L, 0);
-
- // and verify new history also recorded under different template, which
- // verifies that we didn't cross the streams.
- assertNetworkTotal(sTemplateImsi2, 128L, 1L, 1024L, 8L, 0);
- assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
- assertUidTotal(sTemplateImsi2, UID_BLUE, 128L, 1L, 1024L, 8L, 10);
- verifyAndReset();
-
- }
-
- public void testUidRemovedIsMoved() throws Exception {
- // pretend that network comes online
- expectCurrentTime();
- expectDefaultSettings();
- expectNetworkState(buildWifiState());
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
- expectNetworkStatsPoll();
-
- replay();
- mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
- verifyAndReset();
-
- // create some traffic
- incrementCurrentTime(HOUR_IN_MILLIS);
- expectCurrentTime();
- expectDefaultSettings();
- expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
- .addIfaceValues(TEST_IFACE, 4128L, 258L, 544L, 34L));
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
- .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)
- .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L)
- .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 4096L, 258L, 512L, 32L, 0L)
- .addValues(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L));
- expectNetworkStatsPoll();
-
- mService.incrementOperationCount(UID_RED, 0xFAAD, 10);
-
- replay();
- mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
-
- // verify service recorded history
- assertNetworkTotal(sTemplateWifi, 4128L, 258L, 544L, 34L, 0);
- assertUidTotal(sTemplateWifi, UID_RED, 16L, 1L, 16L, 1L, 10);
- assertUidTotal(sTemplateWifi, UID_BLUE, 4096L, 258L, 512L, 32L, 0);
- assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 1L, 16L, 1L, 0);
- verifyAndReset();
-
- // now pretend two UIDs are uninstalled, which should migrate stats to
- // special "removed" bucket.
- expectCurrentTime();
- expectDefaultSettings();
- expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
- .addIfaceValues(TEST_IFACE, 4128L, 258L, 544L, 34L));
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
- .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)
- .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L)
- .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 4096L, 258L, 512L, 32L, 0L)
- .addValues(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L));
- expectNetworkStatsPoll();
-
- replay();
- final Intent intent = new Intent(ACTION_UID_REMOVED);
- intent.putExtra(EXTRA_UID, UID_BLUE);
- mServiceContext.sendBroadcast(intent);
- intent.putExtra(EXTRA_UID, UID_RED);
- mServiceContext.sendBroadcast(intent);
-
- // existing uid and total should remain unchanged; but removed UID
- // should be gone completely.
- assertNetworkTotal(sTemplateWifi, 4128L, 258L, 544L, 34L, 0);
- assertUidTotal(sTemplateWifi, UID_RED, 0L, 0L, 0L, 0L, 0);
- assertUidTotal(sTemplateWifi, UID_BLUE, 0L, 0L, 0L, 0L, 0);
- assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 1L, 16L, 1L, 0);
- assertUidTotal(sTemplateWifi, UID_REMOVED, 4112L, 259L, 528L, 33L, 10);
- verifyAndReset();
-
- }
-
- public void testUid3g4gCombinedByTemplate() throws Exception {
- // pretend that network comes online
- expectCurrentTime();
- expectDefaultSettings();
- expectNetworkState(buildMobile3gState(IMSI_1));
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
- expectNetworkStatsPoll();
-
- replay();
- mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
- verifyAndReset();
-
- // create some traffic
- incrementCurrentTime(HOUR_IN_MILLIS);
- expectCurrentTime();
- expectDefaultSettings();
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
- .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
- .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L));
- expectNetworkStatsPoll();
-
- mService.incrementOperationCount(UID_RED, 0xF00D, 5);
-
- replay();
- mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
-
- // verify service recorded history
- assertUidTotal(sTemplateImsi1, UID_RED, 1024L, 8L, 1024L, 8L, 5);
- verifyAndReset();
-
- // now switch over to 4g network
- incrementCurrentTime(HOUR_IN_MILLIS);
- expectCurrentTime();
- expectDefaultSettings();
- expectNetworkState(buildMobile4gState(TEST_IFACE2));
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
- .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
- .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L));
- expectNetworkStatsPoll();
-
- replay();
- mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
- mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
- verifyAndReset();
-
- // create traffic on second network
- incrementCurrentTime(HOUR_IN_MILLIS);
- expectCurrentTime();
- expectDefaultSettings();
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
- .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
- .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
- .addValues(TEST_IFACE2, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
- .addValues(TEST_IFACE2, UID_RED, SET_DEFAULT, 0xFAAD, 512L, 4L, 256L, 2L, 0L));
- expectNetworkStatsPoll();
-
- mService.incrementOperationCount(UID_RED, 0xFAAD, 5);
-
- replay();
- mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
-
- // verify that ALL_MOBILE template combines both
- assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 1280L, 10L, 10);
-
- verifyAndReset();
- }
-
- public void testSummaryForAllUid() throws Exception {
- // pretend that network comes online
- expectCurrentTime();
- expectDefaultSettings();
- expectNetworkState(buildWifiState());
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
- expectNetworkStatsPoll();
-
- replay();
- mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
- verifyAndReset();
-
- // create some traffic for two apps
- incrementCurrentTime(HOUR_IN_MILLIS);
- expectCurrentTime();
- expectDefaultSettings();
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
- .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L)
- .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L)
- .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 1024L, 8L, 512L, 4L, 0L));
- expectNetworkStatsPoll();
-
- mService.incrementOperationCount(UID_RED, 0xF00D, 1);
-
- replay();
- mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
-
- // verify service recorded history
- assertUidTotal(sTemplateWifi, UID_RED, 50L, 5L, 50L, 5L, 1);
- assertUidTotal(sTemplateWifi, UID_BLUE, 1024L, 8L, 512L, 4L, 0);
- verifyAndReset();
-
- // now create more traffic in next hour, but only for one app
- incrementCurrentTime(HOUR_IN_MILLIS);
- expectCurrentTime();
- expectDefaultSettings();
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
- .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L)
- .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L)
- .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 2048L, 16L, 1024L, 8L, 0L));
- expectNetworkStatsPoll();
-
- replay();
- mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
-
- // first verify entire history present
- NetworkStats stats = mSession.getSummaryForAllUid(
- sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true);
- assertEquals(3, stats.size());
- assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 1);
- assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 1);
- assertValues(stats, IFACE_ALL, UID_BLUE, SET_DEFAULT, TAG_NONE, 2048L, 16L, 1024L, 8L, 0);
-
- // now verify that recent history only contains one uid
- final long currentTime = currentTimeMillis();
- stats = mSession.getSummaryForAllUid(
- sTemplateWifi, currentTime - HOUR_IN_MILLIS, currentTime, true);
- assertEquals(1, stats.size());
- assertValues(stats, IFACE_ALL, UID_BLUE, SET_DEFAULT, TAG_NONE, 1024L, 8L, 512L, 4L, 0);
-
- verifyAndReset();
- }
-
- public void testForegroundBackground() throws Exception {
- // pretend that network comes online
- expectCurrentTime();
- expectDefaultSettings();
- expectNetworkState(buildWifiState());
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
- expectNetworkStatsPoll();
-
- replay();
- mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
- verifyAndReset();
-
- // create some initial traffic
- incrementCurrentTime(HOUR_IN_MILLIS);
- expectCurrentTime();
- expectDefaultSettings();
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
- .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L)
- .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L));
- expectNetworkStatsPoll();
-
- mService.incrementOperationCount(UID_RED, 0xF00D, 1);
-
- replay();
- mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
-
- // verify service recorded history
- assertUidTotal(sTemplateWifi, UID_RED, 128L, 2L, 128L, 2L, 1);
- verifyAndReset();
-
- // now switch to foreground
- incrementCurrentTime(HOUR_IN_MILLIS);
- expectCurrentTime();
- expectDefaultSettings();
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
- .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L)
- .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L)
- .addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 32L, 2L, 32L, 2L, 0L)
- .addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 1L, 1L, 1L, 1L, 0L));
- expectNetworkStatsPoll();
-
- mService.setUidForeground(UID_RED, true);
- mService.incrementOperationCount(UID_RED, 0xFAAD, 1);
-
- replay();
- mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
-
- // test that we combined correctly
- assertUidTotal(sTemplateWifi, UID_RED, 160L, 4L, 160L, 4L, 2);
-
- // verify entire history present
- final NetworkStats stats = mSession.getSummaryForAllUid(
- sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true);
- assertEquals(4, stats.size());
- assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 1);
- assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 1);
- assertValues(stats, IFACE_ALL, UID_RED, SET_FOREGROUND, TAG_NONE, 32L, 2L, 32L, 2L, 1);
- assertValues(stats, IFACE_ALL, UID_RED, SET_FOREGROUND, 0xFAAD, 1L, 1L, 1L, 1L, 1);
-
- verifyAndReset();
- }
-
- public void testTethering() throws Exception {
- // pretend first mobile network comes online
- expectCurrentTime();
- expectDefaultSettings();
- expectNetworkState(buildMobile3gState(IMSI_1));
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
- expectNetworkStatsPoll();
-
- replay();
- mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
- verifyAndReset();
-
- // create some tethering traffic
- incrementCurrentTime(HOUR_IN_MILLIS);
- expectCurrentTime();
- expectDefaultSettings();
- expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
- .addIfaceValues(TEST_IFACE, 2048L, 16L, 512L, 4L));
-
- final NetworkStats uidStats = new NetworkStats(getElapsedRealtime(), 1)
- .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L);
- final String[] tetherIfacePairs = new String[] { TEST_IFACE, "wlan0" };
- final NetworkStats tetherStats = new NetworkStats(getElapsedRealtime(), 1)
- .addValues(TEST_IFACE, UID_TETHERING, SET_DEFAULT, TAG_NONE, 1920L, 14L, 384L, 2L, 0L);
-
- expectNetworkStatsUidDetail(uidStats, tetherIfacePairs, tetherStats);
- expectNetworkStatsPoll();
-
- replay();
- mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
-
- // verify service recorded history
- assertNetworkTotal(sTemplateImsi1, 2048L, 16L, 512L, 4L, 0);
- assertUidTotal(sTemplateImsi1, UID_RED, 128L, 2L, 128L, 2L, 0);
- assertUidTotal(sTemplateImsi1, UID_TETHERING, 1920L, 14L, 384L, 2L, 0);
- verifyAndReset();
-
- }
-
- public void testReportXtOverDev() throws Exception {
- // bring mobile network online
- expectCurrentTime();
- expectDefaultSettings();
- expectNetworkState(buildMobile3gState(IMSI_1));
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
- expectNetworkStatsPoll();
-
- replay();
- mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
- verifyAndReset();
-
- // create some traffic, but only for DEV, and across 1.5 buckets
- incrementCurrentTime(90 * MINUTE_IN_MILLIS);
- expectCurrentTime();
- expectDefaultSettings();
- expectNetworkStatsSummaryDev(new NetworkStats(getElapsedRealtime(), 1)
- .addIfaceValues(TEST_IFACE, 6000L, 60L, 3000L, 30L));
- expectNetworkStatsSummaryXt(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
- expectNetworkStatsPoll();
-
- replay();
- mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
-
- // verify service recorded history:
- // 4000(dev) + 2000(dev)
- assertNetworkTotal(sTemplateImsi1, 6000L, 60L, 3000L, 30L, 0);
- verifyAndReset();
-
- // create traffic on both DEV and XT, across two buckets
- incrementCurrentTime(2 * HOUR_IN_MILLIS);
- expectCurrentTime();
- expectDefaultSettings();
- expectNetworkStatsSummaryDev(new NetworkStats(getElapsedRealtime(), 1)
- .addIfaceValues(TEST_IFACE, 6004L, 64L, 3004L, 34L));
- expectNetworkStatsSummaryXt(new NetworkStats(getElapsedRealtime(), 1)
- .addIfaceValues(TEST_IFACE, 10240L, 0L, 0L, 0L));
- expectNetworkStatsUidDetail(buildEmptyStats());
- expectNetworkStatsPoll();
-
- replay();
- mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
-
- // verify that we switching reporting at the first atomic XT bucket,
- // which should give us:
- // 4000(dev) + 2000(dev) + 1(dev) + 5120(xt) + 2560(xt)
- assertNetworkTotal(sTemplateImsi1, 13681L, 61L, 3001L, 31L, 0);
-
- // also test pure-DEV and pure-XT ranges
- assertNetworkTotal(sTemplateImsi1, startTimeMillis(),
- startTimeMillis() + 2 * HOUR_IN_MILLIS, 6001L, 61L, 3001L, 31L, 0);
- assertNetworkTotal(sTemplateImsi1, startTimeMillis() + 2 * HOUR_IN_MILLIS,
- startTimeMillis() + 4 * HOUR_IN_MILLIS, 7680L, 0L, 0L, 0L, 0);
-
- verifyAndReset();
- }
-
- private void assertNetworkTotal(NetworkTemplate template, long rxBytes, long rxPackets,
- long txBytes, long txPackets, int operations) throws Exception {
- assertNetworkTotal(template, Long.MIN_VALUE, Long.MAX_VALUE, rxBytes, rxPackets, txBytes,
- txPackets, operations);
- }
-
- private void assertNetworkTotal(NetworkTemplate template, long start, long end, long rxBytes,
- long rxPackets, long txBytes, long txPackets, int operations) throws Exception {
- // verify history API
- final NetworkStatsHistory history = mSession.getHistoryForNetwork(template, FIELD_ALL);
- assertValues(history, start, end, rxBytes, rxPackets, txBytes, txPackets, operations);
-
- // verify summary API
- final NetworkStats stats = mSession.getSummaryForNetwork(template, start, end);
- assertValues(stats, IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, rxBytes, rxPackets, txBytes,
- txPackets, operations);
- }
-
- private void assertUidTotal(NetworkTemplate template, int uid, long rxBytes, long rxPackets,
- long txBytes, long txPackets, int operations) throws Exception {
- assertUidTotal(template, uid, SET_ALL, rxBytes, rxPackets, txBytes, txPackets, operations);
- }
-
- private void assertUidTotal(NetworkTemplate template, int uid, int set, long rxBytes,
- long rxPackets, long txBytes, long txPackets, int operations) throws Exception {
- // verify history API
- final NetworkStatsHistory history = mSession.getHistoryForUid(
- template, uid, set, TAG_NONE, FIELD_ALL);
- assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, rxBytes, rxPackets, txBytes,
- txPackets, operations);
-
- // verify summary API
- final NetworkStats stats = mSession.getSummaryForAllUid(
- template, Long.MIN_VALUE, Long.MAX_VALUE, false);
- assertValues(stats, IFACE_ALL, uid, set, TAG_NONE, rxBytes, rxPackets, txBytes, txPackets,
- operations);
- }
-
- private void expectSystemReady() throws Exception {
- mAlarmManager.remove(isA(PendingIntent.class));
- expectLastCall().anyTimes();
-
- mAlarmManager.set(eq(AlarmManager.ELAPSED_REALTIME), anyLong(), anyLong(), anyLong(),
- isA(PendingIntent.class), isA(WorkSource.class));
- expectLastCall().atLeastOnce();
-
- mNetManager.setGlobalAlert(anyLong());
- expectLastCall().atLeastOnce();
-
- expect(mNetManager.isBandwidthControlEnabled()).andReturn(true).atLeastOnce();
- }
-
- private void expectNetworkState(NetworkState... state) throws Exception {
- expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
-
- final LinkProperties linkProp = state.length > 0 ? state[0].linkProperties : null;
- expect(mConnManager.getActiveLinkProperties()).andReturn(linkProp).atLeastOnce();
- }
-
- private void expectNetworkStatsSummary(NetworkStats summary) throws Exception {
- expectNetworkStatsSummaryDev(summary);
- expectNetworkStatsSummaryXt(summary);
- }
-
- private void expectNetworkStatsSummaryDev(NetworkStats summary) throws Exception {
- expect(mNetManager.getNetworkStatsSummaryDev()).andReturn(summary).atLeastOnce();
- }
-
- private void expectNetworkStatsSummaryXt(NetworkStats summary) throws Exception {
- expect(mNetManager.getNetworkStatsSummaryXt()).andReturn(summary).atLeastOnce();
- }
-
- private void expectNetworkStatsUidDetail(NetworkStats detail) throws Exception {
- expectNetworkStatsUidDetail(detail, new String[0], new NetworkStats(0L, 0));
- }
-
- private void expectNetworkStatsUidDetail(
- NetworkStats detail, String[] tetherIfacePairs, NetworkStats tetherStats)
- throws Exception {
- expect(mNetManager.getNetworkStatsUidDetail(eq(UID_ALL))).andReturn(detail).atLeastOnce();
-
- // also include tethering details, since they are folded into UID
- expect(mNetManager.getNetworkStatsTethering())
- .andReturn(tetherStats).atLeastOnce();
- }
-
- private void expectDefaultSettings() throws Exception {
- expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
- }
-
- private void expectSettings(long persistBytes, long bucketDuration, long deleteAge)
- throws Exception {
- expect(mSettings.getPollInterval()).andReturn(HOUR_IN_MILLIS).anyTimes();
- expect(mSettings.getTimeCacheMaxAge()).andReturn(DAY_IN_MILLIS).anyTimes();
- expect(mSettings.getSampleEnabled()).andReturn(true).anyTimes();
- expect(mSettings.getReportXtOverDev()).andReturn(true).anyTimes();
-
- final Config config = new Config(bucketDuration, deleteAge, deleteAge);
- expect(mSettings.getDevConfig()).andReturn(config).anyTimes();
- expect(mSettings.getXtConfig()).andReturn(config).anyTimes();
- expect(mSettings.getUidConfig()).andReturn(config).anyTimes();
- expect(mSettings.getUidTagConfig()).andReturn(config).anyTimes();
-
- expect(mSettings.getGlobalAlertBytes(anyLong())).andReturn(MB_IN_BYTES).anyTimes();
- expect(mSettings.getDevPersistBytes(anyLong())).andReturn(MB_IN_BYTES).anyTimes();
- expect(mSettings.getXtPersistBytes(anyLong())).andReturn(MB_IN_BYTES).anyTimes();
- expect(mSettings.getUidPersistBytes(anyLong())).andReturn(MB_IN_BYTES).anyTimes();
- expect(mSettings.getUidTagPersistBytes(anyLong())).andReturn(MB_IN_BYTES).anyTimes();
- }
-
- private void expectCurrentTime() throws Exception {
- expect(mTime.forceRefresh()).andReturn(false).anyTimes();
- expect(mTime.hasCache()).andReturn(true).anyTimes();
- expect(mTime.currentTimeMillis()).andReturn(currentTimeMillis()).anyTimes();
- expect(mTime.getCacheAge()).andReturn(0L).anyTimes();
- expect(mTime.getCacheCertainty()).andReturn(0L).anyTimes();
- }
-
- private void expectNetworkStatsPoll() throws Exception {
- mNetManager.setGlobalAlert(anyLong());
- expectLastCall().anyTimes();
- }
-
- private void assertStatsFilesExist(boolean exist) {
- final File basePath = new File(mStatsDir, "netstats");
- if (exist) {
- assertTrue(basePath.list().length > 0);
- } else {
- assertTrue(basePath.list().length == 0);
- }
- }
-
- private static void assertValues(NetworkStats stats, String iface, int uid, int set,
- int tag, long rxBytes, long rxPackets, long txBytes, long txPackets, int operations) {
- final NetworkStats.Entry entry = new NetworkStats.Entry();
- if (set == SET_DEFAULT || set == SET_ALL) {
- final int i = stats.findIndex(iface, uid, SET_DEFAULT, tag);
- if (i != -1) {
- entry.add(stats.getValues(i, null));
- }
- }
- if (set == SET_FOREGROUND || set == SET_ALL) {
- final int i = stats.findIndex(iface, uid, SET_FOREGROUND, tag);
- if (i != -1) {
- entry.add(stats.getValues(i, null));
- }
- }
-
- assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
- assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
- assertEquals("unexpected txBytes", txBytes, entry.txBytes);
- assertEquals("unexpected txPackets", txPackets, entry.txPackets);
- assertEquals("unexpected operations", operations, entry.operations);
- }
-
- private static void assertValues(NetworkStatsHistory stats, long start, long end, long rxBytes,
- long rxPackets, long txBytes, long txPackets, int operations) {
- final NetworkStatsHistory.Entry entry = stats.getValues(start, end, null);
- assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
- assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
- assertEquals("unexpected txBytes", txBytes, entry.txBytes);
- assertEquals("unexpected txPackets", txPackets, entry.txPackets);
- assertEquals("unexpected operations", operations, entry.operations);
- }
-
- private static NetworkState buildWifiState() {
- final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0, null, null);
- info.setDetailedState(DetailedState.CONNECTED, null, null);
- final LinkProperties prop = new LinkProperties();
- prop.setInterfaceName(TEST_IFACE);
- return new NetworkState(info, prop, null, null, TEST_SSID);
- }
-
- private static NetworkState buildMobile3gState(String subscriberId) {
- final NetworkInfo info = new NetworkInfo(
- TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UMTS, null, null);
- info.setDetailedState(DetailedState.CONNECTED, null, null);
- final LinkProperties prop = new LinkProperties();
- prop.setInterfaceName(TEST_IFACE);
- return new NetworkState(info, prop, null, subscriberId, null);
- }
-
- private static NetworkState buildMobile4gState(String iface) {
- final NetworkInfo info = new NetworkInfo(TYPE_WIMAX, 0, null, null);
- info.setDetailedState(DetailedState.CONNECTED, null, null);
- final LinkProperties prop = new LinkProperties();
- prop.setInterfaceName(iface);
- return new NetworkState(info, prop, null);
- }
-
- private NetworkStats buildEmptyStats() {
- return new NetworkStats(getElapsedRealtime(), 0);
- }
-
- private long getElapsedRealtime() {
- return mElapsedRealtime;
- }
-
- private long startTimeMillis() {
- return TEST_START;
- }
-
- private long currentTimeMillis() {
- return startTimeMillis() + mElapsedRealtime;
- }
-
- private void incrementCurrentTime(long duration) {
- mElapsedRealtime += duration;
- }
-
- private void replay() {
- EasyMock.replay(mNetManager, mAlarmManager, mTime, mSettings, mConnManager);
- }
-
- private void verifyAndReset() {
- EasyMock.verify(mNetManager, mAlarmManager, mTime, mSettings, mConnManager);
- EasyMock.reset(mNetManager, mAlarmManager, mTime, mSettings, mConnManager);
- }
-}
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkStatsCollectionTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkStatsCollectionTest.java
deleted file mode 100644
index 1a6c289..0000000
--- a/services/tests/servicestests/src/com/android/server/net/NetworkStatsCollectionTest.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (C) 2012 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.server.net;
-
-import static android.net.NetworkStats.SET_DEFAULT;
-import static android.net.NetworkStats.TAG_NONE;
-import static android.net.NetworkStats.UID_ALL;
-import static android.net.NetworkTemplate.buildTemplateMobileAll;
-import static android.text.format.DateUtils.HOUR_IN_MILLIS;
-import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
-
-import android.content.res.Resources;
-import android.net.NetworkStats;
-import android.net.NetworkTemplate;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
-
-import com.android.frameworks.servicestests.R;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-import libcore.io.IoUtils;
-import libcore.io.Streams;
-
-/**
- * Tests for {@link NetworkStatsCollection}.
- */
-@MediumTest
-public class NetworkStatsCollectionTest extends AndroidTestCase {
-
- private static final String TEST_FILE = "test.bin";
- private static final String TEST_IMSI = "310260000000000";
-
- @Override
- public void setUp() throws Exception {
- super.setUp();
-
- // ignore any device overlay while testing
- NetworkTemplate.forceAllNetworkTypes();
- }
-
- public void testReadLegacyNetwork() throws Exception {
- final File testFile = new File(getContext().getFilesDir(), TEST_FILE);
- stageFile(R.raw.netstats_v1, testFile);
-
- final NetworkStatsCollection collection = new NetworkStatsCollection(30 * MINUTE_IN_MILLIS);
- collection.readLegacyNetwork(testFile);
-
- // verify that history read correctly
- assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI),
- 636016770L, 709306L, 88038768L, 518836L);
-
- // now export into a unified format
- final ByteArrayOutputStream bos = new ByteArrayOutputStream();
- collection.write(new DataOutputStream(bos));
-
- // clear structure completely
- collection.reset();
- assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI),
- 0L, 0L, 0L, 0L);
-
- // and read back into structure, verifying that totals are same
- collection.read(new ByteArrayInputStream(bos.toByteArray()));
- assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI),
- 636016770L, 709306L, 88038768L, 518836L);
- }
-
- public void testReadLegacyUid() throws Exception {
- final File testFile = new File(getContext().getFilesDir(), TEST_FILE);
- stageFile(R.raw.netstats_uid_v4, testFile);
-
- final NetworkStatsCollection collection = new NetworkStatsCollection(30 * MINUTE_IN_MILLIS);
- collection.readLegacyUid(testFile, false);
-
- // verify that history read correctly
- assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI),
- 637076152L, 711413L, 88343717L, 521022L);
-
- // now export into a unified format
- final ByteArrayOutputStream bos = new ByteArrayOutputStream();
- collection.write(new DataOutputStream(bos));
-
- // clear structure completely
- collection.reset();
- assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI),
- 0L, 0L, 0L, 0L);
-
- // and read back into structure, verifying that totals are same
- collection.read(new ByteArrayInputStream(bos.toByteArray()));
- assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI),
- 637076152L, 711413L, 88343717L, 521022L);
- }
-
- public void testReadLegacyUidTags() throws Exception {
- final File testFile = new File(getContext().getFilesDir(), TEST_FILE);
- stageFile(R.raw.netstats_uid_v4, testFile);
-
- final NetworkStatsCollection collection = new NetworkStatsCollection(30 * MINUTE_IN_MILLIS);
- collection.readLegacyUid(testFile, true);
-
- // verify that history read correctly
- assertSummaryTotalIncludingTags(collection, buildTemplateMobileAll(TEST_IMSI),
- 77017831L, 100995L, 35436758L, 92344L);
-
- // now export into a unified format
- final ByteArrayOutputStream bos = new ByteArrayOutputStream();
- collection.write(new DataOutputStream(bos));
-
- // clear structure completely
- collection.reset();
- assertSummaryTotalIncludingTags(collection, buildTemplateMobileAll(TEST_IMSI),
- 0L, 0L, 0L, 0L);
-
- // and read back into structure, verifying that totals are same
- collection.read(new ByteArrayInputStream(bos.toByteArray()));
- assertSummaryTotalIncludingTags(collection, buildTemplateMobileAll(TEST_IMSI),
- 77017831L, 100995L, 35436758L, 92344L);
- }
-
- public void testStartEndAtomicBuckets() throws Exception {
- final NetworkStatsCollection collection = new NetworkStatsCollection(HOUR_IN_MILLIS);
-
- // record empty data straddling between buckets
- final NetworkStats.Entry entry = new NetworkStats.Entry();
- entry.rxBytes = 32;
- collection.recordData(null, UID_ALL, SET_DEFAULT, TAG_NONE, 30 * MINUTE_IN_MILLIS,
- 90 * MINUTE_IN_MILLIS, entry);
-
- // assert that we report boundary in atomic buckets
- assertEquals(0, collection.getStartMillis());
- assertEquals(2 * HOUR_IN_MILLIS, collection.getEndMillis());
- }
-
- /**
- * Copy a {@link Resources#openRawResource(int)} into {@link File} for
- * testing purposes.
- */
- private void stageFile(int rawId, File file) throws Exception {
- new File(file.getParent()).mkdirs();
- InputStream in = null;
- OutputStream out = null;
- try {
- in = getContext().getResources().openRawResource(rawId);
- out = new FileOutputStream(file);
- Streams.copy(in, out);
- } finally {
- IoUtils.closeQuietly(in);
- IoUtils.closeQuietly(out);
- }
- }
-
- private static void assertSummaryTotal(NetworkStatsCollection collection,
- NetworkTemplate template, long rxBytes, long rxPackets, long txBytes, long txPackets) {
- final NetworkStats.Entry entry = collection.getSummary(
- template, Long.MIN_VALUE, Long.MAX_VALUE).getTotal(null);
- assertEntry(entry, rxBytes, rxPackets, txBytes, txPackets);
- }
-
- private static void assertSummaryTotalIncludingTags(NetworkStatsCollection collection,
- NetworkTemplate template, long rxBytes, long rxPackets, long txBytes, long txPackets) {
- final NetworkStats.Entry entry = collection.getSummary(
- template, Long.MIN_VALUE, Long.MAX_VALUE).getTotalIncludingTags(null);
- assertEntry(entry, rxBytes, rxPackets, txBytes, txPackets);
- }
-
- private static void assertEntry(
- NetworkStats.Entry entry, long rxBytes, long rxPackets, long txBytes, long txPackets) {
- assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
- assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
- assertEquals("unexpected txBytes", txBytes, entry.txBytes);
- assertEquals("unexpected txPackets", txPackets, entry.txPackets);
- }
-}
diff --git a/tests/CoreTests/android/core/NsdServiceInfoTest.java b/tests/CoreTests/android/core/NsdServiceInfoTest.java
deleted file mode 100644
index 5bf0167..0000000
--- a/tests/CoreTests/android/core/NsdServiceInfoTest.java
+++ /dev/null
@@ -1,163 +0,0 @@
-package android.core;
-
-import android.test.AndroidTestCase;
-
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.StrictMode;
-import android.net.nsd.NsdServiceInfo;
-import android.util.Log;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-
-
-public class NsdServiceInfoTest extends AndroidTestCase {
-
- public final static InetAddress LOCALHOST;
- static {
- // Because test.
- StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
- StrictMode.setThreadPolicy(policy);
-
- InetAddress _host = null;
- try {
- _host = InetAddress.getLocalHost();
- } catch (UnknownHostException e) { }
- LOCALHOST = _host;
- }
-
- public void testLimits() throws Exception {
- NsdServiceInfo info = new NsdServiceInfo();
-
- // Non-ASCII keys.
- boolean exceptionThrown = false;
- try {
- info.setAttribute("猫", "meow");
- } catch (IllegalArgumentException e) {
- exceptionThrown = true;
- }
- assertTrue(exceptionThrown);
- assertEmptyServiceInfo(info);
-
- // ASCII keys with '=' character.
- exceptionThrown = false;
- try {
- info.setAttribute("kitten=", "meow");
- } catch (IllegalArgumentException e) {
- exceptionThrown = true;
- }
- assertTrue(exceptionThrown);
- assertEmptyServiceInfo(info);
-
- // Single key + value length too long.
- exceptionThrown = false;
- try {
- String longValue = "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo" +
- "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo" +
- "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo" +
- "ooooooooooooooooooooooooooooong"; // 248 characters.
- info.setAttribute("longcat", longValue); // Key + value == 255 characters.
- } catch (IllegalArgumentException e) {
- exceptionThrown = true;
- }
- assertTrue(exceptionThrown);
- assertEmptyServiceInfo(info);
-
- // Total TXT record length too long.
- exceptionThrown = false;
- int recordsAdded = 0;
- try {
- for (int i = 100; i < 300; ++i) {
- // 6 char key + 5 char value + 2 bytes overhead = 13 byte record length.
- String key = String.format("key%d", i);
- info.setAttribute(key, "12345");
- recordsAdded++;
- }
- } catch (IllegalArgumentException e) {
- exceptionThrown = true;
- }
- assertTrue(exceptionThrown);
- assertTrue(100 == recordsAdded);
- assertTrue(info.getTxtRecord().length == 1300);
- }
-
- public void testParcel() throws Exception {
- NsdServiceInfo emptyInfo = new NsdServiceInfo();
- checkParcelable(emptyInfo);
-
- NsdServiceInfo fullInfo = new NsdServiceInfo();
- fullInfo.setServiceName("kitten");
- fullInfo.setServiceType("_kitten._tcp");
- fullInfo.setPort(4242);
- fullInfo.setHost(LOCALHOST);
- checkParcelable(fullInfo);
-
- NsdServiceInfo noHostInfo = new NsdServiceInfo();
- noHostInfo.setServiceName("kitten");
- noHostInfo.setServiceType("_kitten._tcp");
- noHostInfo.setPort(4242);
- checkParcelable(noHostInfo);
-
- NsdServiceInfo attributedInfo = new NsdServiceInfo();
- attributedInfo.setServiceName("kitten");
- attributedInfo.setServiceType("_kitten._tcp");
- attributedInfo.setPort(4242);
- attributedInfo.setHost(LOCALHOST);
- attributedInfo.setAttribute("color", "pink");
- attributedInfo.setAttribute("sound", (new String("にゃあ")).getBytes("UTF-8"));
- attributedInfo.setAttribute("adorable", (String) null);
- attributedInfo.setAttribute("sticky", "yes");
- attributedInfo.setAttribute("siblings", new byte[] {});
- attributedInfo.setAttribute("edge cases", new byte[] {0, -1, 127, -128});
- attributedInfo.removeAttribute("sticky");
- checkParcelable(attributedInfo);
-
- // Sanity check that we actually wrote attributes to attributedInfo.
- assertTrue(attributedInfo.getAttributes().keySet().contains("adorable"));
- String sound = new String(attributedInfo.getAttributes().get("sound"), "UTF-8");
- assertTrue(sound.equals("にゃあ"));
- byte[] edgeCases = attributedInfo.getAttributes().get("edge cases");
- assertTrue(Arrays.equals(edgeCases, new byte[] {0, -1, 127, -128}));
- assertFalse(attributedInfo.getAttributes().keySet().contains("sticky"));
- }
-
- public void checkParcelable(NsdServiceInfo original) {
- // Write to parcel.
- Parcel p = Parcel.obtain();
- Bundle writer = new Bundle();
- writer.putParcelable("test_info", original);
- writer.writeToParcel(p, 0);
-
- // Extract from parcel.
- p.setDataPosition(0);
- Bundle reader = p.readBundle();
- reader.setClassLoader(NsdServiceInfo.class.getClassLoader());
- NsdServiceInfo result = reader.getParcelable("test_info");
-
- // Assert equality of base fields.
- assertEquality(original.getServiceName(), result.getServiceName());
- assertEquality(original.getServiceType(), result.getServiceType());
- assertEquality(original.getHost(), result.getHost());
- assertTrue(original.getPort() == result.getPort());
-
- // Assert equality of attribute map.
- Map<String, byte[]> originalMap = original.getAttributes();
- Map<String, byte[]> resultMap = result.getAttributes();
- assertEquality(originalMap.keySet(), resultMap.keySet());
- for (String key : originalMap.keySet()) {
- assertTrue(Arrays.equals(originalMap.get(key), resultMap.get(key)));
- }
- }
-
- public void assertEquality(Object expected, Object result) {
- assertTrue(expected == result || expected.equals(result));
- }
-
- public void assertEmptyServiceInfo(NsdServiceInfo shouldBeEmpty) {
- assertTrue(null == shouldBeEmpty.getTxtRecord());
- }
-}
diff --git a/tests/common/java/android/net/NetworkCapabilitiesTest.java b/tests/common/java/android/net/NetworkCapabilitiesTest.java
index 493a201..382fa1f 100644
--- a/tests/common/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/common/java/android/net/NetworkCapabilitiesTest.java
@@ -75,6 +75,7 @@
import androidx.test.runner.AndroidJUnit4;
import com.android.testutils.CompatUtil;
+import com.android.testutils.ConnectivityModuleTest;
import com.android.testutils.DevSdkIgnoreRule;
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
@@ -1167,4 +1168,48 @@
// Ensure test case fails if new net cap is added into default cap but no update here.
assertEquals(0, nc.getCapabilities().length);
}
+
+ @Test @IgnoreUpTo(Build.VERSION_CODES.R) @ConnectivityModuleTest
+ public void testRestrictCapabilitiesForTestNetwork() {
+ final int ownerUid = 1234;
+ final int[] administratorUids = {1001, ownerUid};
+ final NetworkCapabilities nonRestrictedNc = new NetworkCapabilities.Builder()
+ .addTransportType(TRANSPORT_CELLULAR)
+ .addTransportType(TRANSPORT_VPN)
+ .addCapability(NET_CAPABILITY_MMS)
+ .addCapability(NET_CAPABILITY_NOT_METERED)
+ .setAdministratorUids(administratorUids)
+ .setOwnerUid(ownerUid)
+ .setSubscriptionIds(Set.of(TEST_SUBID1)).build();
+
+ nonRestrictedNc.restrictCapabilitiesForTestNetwork(ownerUid);
+ // TRANSPORT_TEST will be appended
+ assertTrue(nonRestrictedNc.hasTransport(TRANSPORT_TEST));
+ assertEquals(Set.of(TEST_SUBID1), nonRestrictedNc.getSubscriptionIds());
+ // Non-UNRESTRICTED_TEST_NETWORKS_ALLOWED_TRANSPORTS will be removed
+ assertFalse(nonRestrictedNc.hasTransport(TRANSPORT_CELLULAR));
+ assertTrue(nonRestrictedNc.hasTransport(TRANSPORT_VPN));
+ // Only TEST_NETWORKS_ALLOWED_CAPABILITIES will be kept
+ assertFalse(nonRestrictedNc.hasCapability(NET_CAPABILITY_MMS));
+ assertTrue(nonRestrictedNc.hasCapability(NET_CAPABILITY_NOT_METERED));
+
+ final NetworkCapabilities restrictedNc = new NetworkCapabilities.Builder(nonRestrictedNc)
+ .removeCapability(NET_CAPABILITY_NOT_RESTRICTED)
+ .addTransportType(TRANSPORT_CELLULAR)
+ .addCapability(NET_CAPABILITY_MMS).build();
+ restrictedNc.restrictCapabilitiesForTestNetwork(ownerUid);
+ // It may declare any transport if the net cap is restricted
+ assertTrue(restrictedNc.hasTransport(TRANSPORT_CELLULAR));
+ // SubIds will be cleared.
+ assertEquals(new ArraySet<>(), restrictedNc.getSubscriptionIds());
+ // Only retain the owner and administrator UIDs if they match the app registering the remote
+ // caller that registered the network.
+ assertEquals(ownerUid, restrictedNc.getOwnerUid());
+ assertArrayEquals(new int[] {ownerUid}, restrictedNc.getAdministratorUids());
+ // The creator UID does not match the owner and administrator UIDs will clear the owner and
+ // administrator UIDs.
+ restrictedNc.restrictCapabilitiesForTestNetwork(5678);
+ assertEquals(INVALID_UID, restrictedNc.getOwnerUid());
+ assertArrayEquals(new int[0], restrictedNc.getAdministratorUids());
+ }
}
diff --git a/tests/cts/net/src/android/net/cts/BatteryStatsManagerTest.java b/tests/cts/net/src/android/net/cts/BatteryStatsManagerTest.java
index 4d60279..80951ca 100644
--- a/tests/cts/net/src/android/net/cts/BatteryStatsManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/BatteryStatsManagerTest.java
@@ -17,6 +17,7 @@
package android.net.cts;
import static android.Manifest.permission.UPDATE_DEVICE_STATS;
+import static android.content.pm.PackageManager.FEATURE_TELEPHONY;
import static androidx.test.InstrumentationRegistry.getContext;
@@ -28,9 +29,11 @@
import static org.junit.Assert.fail;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.cts.util.CtsNetUtils;
+import android.net.wifi.WifiManager;
import android.os.BatteryStatsManager;
import android.os.Build;
import android.os.connectivity.CellularBatteryStats;
@@ -72,6 +75,8 @@
private Context mContext;
private BatteryStatsManager mBsm;
private ConnectivityManager mCm;
+ private WifiManager mWm;
+ private PackageManager mPm;
private CtsNetUtils mCtsNetUtils;
@Before
@@ -79,9 +84,14 @@
mContext = getContext();
mBsm = mContext.getSystemService(BatteryStatsManager.class);
mCm = mContext.getSystemService(ConnectivityManager.class);
+ mWm = mContext.getSystemService(WifiManager.class);
+ mPm = mContext.getPackageManager();
mCtsNetUtils = new CtsNetUtils(mContext);
}
+ // reportNetworkInterfaceForTransports classifies one network interface as wifi or mobile, so
+ // check that the interface is classified properly by checking the data usage is reported
+ // properly.
@Test
@AppModeFull(reason = "Cannot get CHANGE_NETWORK_STATE to request wifi/cell in instant mode")
@SkipPresubmit(reason = "Virtual hardware does not support wifi battery stats")
@@ -108,42 +118,9 @@
// Make sure wifi is disabled.
mCtsNetUtils.ensureWifiDisconnected(null /* wifiNetworkToCheck */);
- final Network cellNetwork = mCtsNetUtils.connectToCell();
- final URL url = new URL(TEST_URL);
+ verifyGetCellBatteryStats();
+ verifyGetWifiBatteryStats();
- // Get cellular battery stats
- CellularBatteryStats cellularStatsBefore = runAsShell(UPDATE_DEVICE_STATS,
- mBsm::getCellularBatteryStats);
-
- // Generate traffic on cellular network.
- Log.d(TAG, "Generate traffic on cellular network.");
- generateNetworkTraffic(cellNetwork, url);
-
- // The mobile battery stats are updated when a network stops being the default network.
- // ConnectivityService will call BatteryStatsManager.reportMobileRadioPowerState when
- // removing data activity tracking.
- final Network wifiNetwork = mCtsNetUtils.ensureWifiConnected();
-
- // Check cellular battery stats are updated.
- runAsShell(UPDATE_DEVICE_STATS,
- () -> assertStatsEventually(mBsm::getCellularBatteryStats,
- cellularStatsAfter -> cellularBatteryStatsIncreased(
- cellularStatsBefore, cellularStatsAfter)));
-
- WifiBatteryStats wifiStatsBefore = runAsShell(UPDATE_DEVICE_STATS,
- mBsm::getWifiBatteryStats);
-
- // Generate traffic on wifi network.
- Log.d(TAG, "Generate traffic on wifi network.");
- generateNetworkTraffic(wifiNetwork, url);
- // Wifi battery stats are updated when wifi on.
- mCtsNetUtils.toggleWifi();
-
- // Check wifi battery stats are updated.
- runAsShell(UPDATE_DEVICE_STATS,
- () -> assertStatsEventually(mBsm::getWifiBatteryStats,
- wifiStatsAfter -> wifiBatteryStatsIncreased(wifiStatsBefore,
- wifiStatsAfter)));
} finally {
// Reset battery settings.
executeShellCommand("dumpsys batterystats disable no-auto-reset");
@@ -151,6 +128,62 @@
}
}
+ private void verifyGetCellBatteryStats() throws Exception {
+ final boolean isTelephonySupported = mPm.hasSystemFeature(FEATURE_TELEPHONY);
+
+ if (!isTelephonySupported) {
+ Log.d(TAG, "Skip cell battery stats test because device does not support telephony.");
+ return;
+ }
+
+ final Network cellNetwork = mCtsNetUtils.connectToCell();
+ final URL url = new URL(TEST_URL);
+
+ // Get cellular battery stats
+ CellularBatteryStats cellularStatsBefore = runAsShell(UPDATE_DEVICE_STATS,
+ mBsm::getCellularBatteryStats);
+
+ // Generate traffic on cellular network.
+ Log.d(TAG, "Generate traffic on cellular network.");
+ generateNetworkTraffic(cellNetwork, url);
+
+ // The mobile battery stats are updated when a network stops being the default network.
+ // ConnectivityService will call BatteryStatsManager.reportMobileRadioPowerState when
+ // removing data activity tracking.
+ mCtsNetUtils.ensureWifiConnected();
+
+ // Check cellular battery stats are updated.
+ runAsShell(UPDATE_DEVICE_STATS,
+ () -> assertStatsEventually(mBsm::getCellularBatteryStats,
+ cellularStatsAfter -> cellularBatteryStatsIncreased(
+ cellularStatsBefore, cellularStatsAfter)));
+ }
+
+ private void verifyGetWifiBatteryStats() throws Exception {
+ final Network wifiNetwork = mCtsNetUtils.ensureWifiConnected();
+ final URL url = new URL(TEST_URL);
+
+ if (!mWm.isEnhancedPowerReportingSupported()) {
+ Log.d(TAG, "Skip wifi stats test because wifi does not support link layer stats.");
+ return;
+ }
+
+ WifiBatteryStats wifiStatsBefore = runAsShell(UPDATE_DEVICE_STATS,
+ mBsm::getWifiBatteryStats);
+
+ // Generate traffic on wifi network.
+ Log.d(TAG, "Generate traffic on wifi network.");
+ generateNetworkTraffic(wifiNetwork, url);
+ // Wifi battery stats are updated when wifi on.
+ mCtsNetUtils.toggleWifi();
+
+ // Check wifi battery stats are updated.
+ runAsShell(UPDATE_DEVICE_STATS,
+ () -> assertStatsEventually(mBsm::getWifiBatteryStats,
+ wifiStatsAfter -> wifiBatteryStatsIncreased(wifiStatsBefore,
+ wifiStatsAfter)));
+ }
+
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
@AppModeFull(reason = "Cannot get WifiManager in instant app mode")
@Test
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java
index a40c92d..721ad82 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java
@@ -73,6 +73,7 @@
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import android.util.ArraySet;
import android.util.Pair;
import androidx.test.InstrumentationRegistry;
@@ -92,7 +93,9 @@
import java.security.MessageDigest;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
@@ -293,7 +296,7 @@
final String interfaceName =
mConnectivityManager.getLinkProperties(network).getInterfaceName();
- connDiagsCallback.expectOnConnectivityReportAvailable(
+ connDiagsCallback.maybeVerifyConnectivityReportAvailable(
network, interfaceName, TRANSPORT_CELLULAR, NETWORK_VALIDATION_RESULT_VALID);
connDiagsCallback.assertNoCallback();
}
@@ -426,10 +429,15 @@
cb.expectOnNetworkConnectivityReported(mTestNetwork, hasConnectivity);
// All calls to #onNetworkConnectivityReported are expected to be accompanied by a call to
- // #onConnectivityReportAvailable for S+ (for R, ConnectivityReports were only sent when the
- // Network was re-validated - when reported connectivity != known connectivity).
- if (SdkLevel.isAtLeastS() || !hasConnectivity) {
+ // #onConnectivityReportAvailable for T+ (for R, ConnectivityReports were only sent when the
+ // Network was re-validated - when reported connectivity != known connectivity). On S,
+ // recent module versions will have the callback, but not the earliest ones.
+ if (!hasConnectivity) {
cb.expectOnConnectivityReportAvailable(mTestNetwork, interfaceName);
+ } else if (SdkLevel.isAtLeastS()) {
+ cb.maybeVerifyConnectivityReportAvailable(mTestNetwork, interfaceName, TRANSPORT_TEST,
+ getPossibleDiagnosticsValidationResults(),
+ SdkLevel.isAtLeastT() /* requireCallbackFired */);
}
cb.assertNoCallback();
@@ -485,18 +493,25 @@
// Test Networks both do not require validation and are not tested for validation. This
// results in the validation result being reported as SKIPPED for S+ (for R, the
// platform marked these Networks as VALID).
- final int expectedNetworkValidationResult =
- SdkLevel.isAtLeastS()
- ? NETWORK_VALIDATION_RESULT_SKIPPED
- : NETWORK_VALIDATION_RESULT_VALID;
- expectOnConnectivityReportAvailable(
- network, interfaceName, TRANSPORT_TEST, expectedNetworkValidationResult);
+
+ maybeVerifyConnectivityReportAvailable(network, interfaceName, TRANSPORT_TEST,
+ getPossibleDiagnosticsValidationResults(), true);
}
- public void expectOnConnectivityReportAvailable(@NonNull Network network,
+ public void maybeVerifyConnectivityReportAvailable(@NonNull Network network,
@NonNull String interfaceName, int transportType, int expectedValidationResult) {
+ maybeVerifyConnectivityReportAvailable(network, interfaceName, transportType,
+ new ArraySet<>(Collections.singletonList(expectedValidationResult)), true);
+ }
+
+ public void maybeVerifyConnectivityReportAvailable(@NonNull Network network,
+ @NonNull String interfaceName, int transportType,
+ Set<Integer> possibleValidationResults, boolean requireCallbackFired) {
final ConnectivityReport result =
(ConnectivityReport) mHistory.poll(CALLBACK_TIMEOUT_MILLIS, x -> true);
+ if (!requireCallbackFired && result == null) {
+ return;
+ }
assertEquals(network, result.getNetwork());
final NetworkCapabilities nc = result.getNetworkCapabilities();
@@ -508,8 +523,8 @@
final PersistableBundle extras = result.getAdditionalInfo();
assertTrue(extras.containsKey(KEY_NETWORK_VALIDATION_RESULT));
final int actualValidationResult = extras.getInt(KEY_NETWORK_VALIDATION_RESULT);
- assertEquals("Network validation result is incorrect",
- expectedValidationResult, actualValidationResult);
+ assertTrue("Network validation result is incorrect: " + actualValidationResult,
+ possibleValidationResults.contains(actualValidationResult));
assertTrue(extras.containsKey(KEY_NETWORK_PROBES_SUCCEEDED_BITMASK));
final int probesSucceeded = extras.getInt(KEY_NETWORK_VALIDATION_RESULT);
@@ -556,6 +571,19 @@
}
}
+ private static Set<Integer> getPossibleDiagnosticsValidationResults() {
+ final Set<Integer> possibleValidationResults = new ArraySet<>();
+ possibleValidationResults.add(NETWORK_VALIDATION_RESULT_SKIPPED);
+
+ // In S, some early module versions will return NETWORK_VALIDATION_RESULT_VALID.
+ // Starting from T, all module versions should only return SKIPPED. For platform < T,
+ // accept both values.
+ if (!SdkLevel.isAtLeastT()) {
+ possibleValidationResults.add(NETWORK_VALIDATION_RESULT_VALID);
+ }
+ return possibleValidationResults;
+ }
+
private class CarrierConfigReceiver extends BroadcastReceiver {
// CountDownLatch used to wait for this BroadcastReceiver to be notified of a CarrierConfig
// change. This latch will be counted down if a broadcast indicates this package has carrier
diff --git a/tests/integration/Android.bp b/tests/integration/Android.bp
index 7c42811..2bc985a 100644
--- a/tests/integration/Android.bp
+++ b/tests/integration/Android.bp
@@ -29,6 +29,7 @@
],
libs: [
"android.test.mock",
+ "ServiceConnectivityResources",
],
static_libs: [
"NetworkStackApiStableLib",
diff --git a/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt b/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
index e039ef0..80338aa 100644
--- a/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
+++ b/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
@@ -23,7 +23,9 @@
import android.content.Context.BIND_IMPORTANT
import android.content.Intent
import android.content.ServiceConnection
+import android.content.res.Resources
import android.net.ConnectivityManager
+import android.net.ConnectivityResources
import android.net.IDnsResolver
import android.net.INetd
import android.net.LinkProperties
@@ -35,6 +37,7 @@
import android.net.TestNetworkStackClient
import android.net.Uri
import android.net.metrics.IpConnectivityLog
+import android.net.util.MultinetworkPolicyTracker
import android.os.ConditionVariable
import android.os.IBinder
import android.os.SystemConfigManager
@@ -43,6 +46,7 @@
import android.util.Log
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
+import com.android.connectivity.resources.R
import com.android.server.ConnectivityService
import com.android.server.NetworkAgentWrapper
import com.android.server.TestNetIdManager
@@ -59,6 +63,7 @@
import org.mockito.Mock
import org.mockito.Mockito.any
import org.mockito.Mockito.anyInt
+import org.mockito.Mockito.doAnswer
import org.mockito.Mockito.doNothing
import org.mockito.Mockito.doReturn
import org.mockito.Mockito.eq
@@ -93,6 +98,10 @@
private lateinit var dnsResolver: IDnsResolver
@Mock
private lateinit var systemConfigManager: SystemConfigManager
+ @Mock
+ private lateinit var resources: Resources
+ @Mock
+ private lateinit var resourcesContext: Context
@Spy
private var context = TestableContext(realContext)
@@ -110,9 +119,11 @@
private val realContext get() = InstrumentationRegistry.getInstrumentation().context
private val httpProbeUrl get() =
- realContext.getResources().getString(R.string.config_captive_portal_http_url)
+ realContext.getResources().getString(com.android.server.net.integrationtests.R.string
+ .config_captive_portal_http_url)
private val httpsProbeUrl get() =
- realContext.getResources().getString(R.string.config_captive_portal_https_url)
+ realContext.getResources().getString(com.android.server.net.integrationtests.R.string
+ .config_captive_portal_https_url)
private class InstrumentationServiceConnection : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
@@ -156,6 +167,27 @@
.getSystemService(Context.SYSTEM_CONFIG_SERVICE)
doReturn(IntArray(0)).`when`(systemConfigManager).getSystemPermissionUids(anyString())
+ doReturn(60000).`when`(resources).getInteger(R.integer.config_networkTransitionTimeout)
+ doReturn("").`when`(resources).getString(R.string.config_networkCaptivePortalServerUrl)
+ doReturn(arrayOf<String>("test_wlan_wol")).`when`(resources)
+ .getStringArray(R.array.config_wakeonlan_supported_interfaces)
+ doReturn(arrayOf("0,1", "1,3")).`when`(resources)
+ .getStringArray(R.array.config_networkSupportedKeepaliveCount)
+ doReturn(emptyArray<String>()).`when`(resources)
+ .getStringArray(R.array.config_networkNotifySwitches)
+ doReturn(intArrayOf(10, 11, 12, 14, 15)).`when`(resources)
+ .getIntArray(R.array.config_protectedNetworks)
+ // We don't test the actual notification value strings, so just return an empty array.
+ // It doesn't matter what the values are as long as it's not null.
+ doReturn(emptyArray<String>()).`when`(resources).getStringArray(
+ R.array.network_switch_type_name)
+ doReturn(1).`when`(resources).getInteger(R.integer.config_networkAvoidBadWifi)
+ doReturn(R.array.config_networkSupportedKeepaliveCount).`when`(resources)
+ .getIdentifier(eq("config_networkSupportedKeepaliveCount"), eq("array"), any())
+
+ doReturn(resources).`when`(resourcesContext).getResources()
+ ConnectivityResources.setResourcesContextForTest(resourcesContext)
+
networkStackClient = TestNetworkStackClient(realContext)
networkStackClient.start()
@@ -176,12 +208,19 @@
doReturn(mock(ProxyTracker::class.java)).`when`(deps).makeProxyTracker(any(), any())
doReturn(mock(MockableSystemProperties::class.java)).`when`(deps).systemProperties
doReturn(TestNetIdManager()).`when`(deps).makeNetIdManager()
+ doAnswer { inv ->
+ object : MultinetworkPolicyTracker(inv.getArgument(0), inv.getArgument(1),
+ inv.getArgument(2)) {
+ override fun getResourcesForActiveSubId() = resources
+ }
+ }.`when`(deps).makeMultinetworkPolicyTracker(any(), any(), any())
return deps
}
@After
fun tearDown() {
nsInstrumentation.clearAllState()
+ ConnectivityResources.setResourcesContextForTest(null)
}
@Test
diff --git a/tests/integration/util/com/android/server/NetworkAgentWrapper.java b/tests/integration/util/com/android/server/NetworkAgentWrapper.java
index 95ea401..970b7d2 100644
--- a/tests/integration/util/com/android/server/NetworkAgentWrapper.java
+++ b/tests/integration/util/com/android/server/NetworkAgentWrapper.java
@@ -83,6 +83,12 @@
public NetworkAgentWrapper(int transport, LinkProperties linkProperties,
NetworkCapabilities ncTemplate, Context context) throws Exception {
+ this(transport, linkProperties, ncTemplate, null /* provider */, context);
+ }
+
+ public NetworkAgentWrapper(int transport, LinkProperties linkProperties,
+ NetworkCapabilities ncTemplate, NetworkProvider provider,
+ Context context) throws Exception {
final int type = transportToLegacyType(transport);
final String typeName = ConnectivityManager.getNetworkTypeName(type);
mNetworkCapabilities = (ncTemplate != null) ? ncTemplate : new NetworkCapabilities();
@@ -124,12 +130,12 @@
.setLegacyTypeName(typeName)
.setLegacyExtraInfo(extraInfo)
.build();
- mNetworkAgent = makeNetworkAgent(linkProperties, mNetworkAgentConfig);
+ mNetworkAgent = makeNetworkAgent(linkProperties, mNetworkAgentConfig, provider);
}
protected InstrumentedNetworkAgent makeNetworkAgent(LinkProperties linkProperties,
- final NetworkAgentConfig nac) throws Exception {
- return new InstrumentedNetworkAgent(this, linkProperties, nac);
+ final NetworkAgentConfig nac, NetworkProvider provider) throws Exception {
+ return new InstrumentedNetworkAgent(this, linkProperties, nac, provider);
}
public static class InstrumentedNetworkAgent extends NetworkAgent {
@@ -138,10 +144,15 @@
public InstrumentedNetworkAgent(NetworkAgentWrapper wrapper, LinkProperties lp,
NetworkAgentConfig nac) {
+ this(wrapper, lp, nac, null /* provider */);
+ }
+
+ public InstrumentedNetworkAgent(NetworkAgentWrapper wrapper, LinkProperties lp,
+ NetworkAgentConfig nac, NetworkProvider provider) {
super(wrapper.mContext, wrapper.mHandlerThread.getLooper(), wrapper.mLogTag,
wrapper.mNetworkCapabilities, lp, wrapper.mScore, nac,
- new NetworkProvider(wrapper.mContext, wrapper.mHandlerThread.getLooper(),
- PROVIDER_NAME));
+ null != provider ? provider : new NetworkProvider(wrapper.mContext,
+ wrapper.mHandlerThread.getLooper(), PROVIDER_NAME));
mWrapper = wrapper;
register();
}
diff --git a/tests/unit/java/android/net/IpSecAlgorithmTest.java b/tests/unit/java/android/net/IpSecAlgorithmTest.java
index c2a759b..c473e82 100644
--- a/tests/unit/java/android/net/IpSecAlgorithmTest.java
+++ b/tests/unit/java/android/net/IpSecAlgorithmTest.java
@@ -217,8 +217,11 @@
final Set<String> optionalAlgoSet = getOptionalAlgos();
final String[] optionalAlgos = optionalAlgoSet.toArray(new String[0]);
- doReturn(optionalAlgos).when(mMockResources)
- .getStringArray(com.android.internal.R.array.config_optionalIpSecAlgorithms);
+ // Query the identifier instead of using the R.array constant, as the test may be built
+ // separately from the platform and they may not match.
+ final int resId = Resources.getSystem().getIdentifier("config_optionalIpSecAlgorithms",
+ "array", "android");
+ doReturn(optionalAlgos).when(mMockResources).getStringArray(resId);
final Set<String> enabledAlgos = new HashSet<>(IpSecAlgorithm.loadAlgos(mMockResources));
final Set<String> expectedAlgos = ALGO_TO_REQUIRED_FIRST_SDK.keySet();
diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
index 7034c92..814d799 100644
--- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
@@ -204,6 +204,7 @@
import android.location.LocationManager;
import android.net.CaptivePortalData;
import android.net.ConnectionInfo;
+import android.net.ConnectivityDiagnosticsManager.DataStallReport;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback;
import android.net.ConnectivityManager.PacketKeepalive;
@@ -240,6 +241,7 @@
import android.net.NetworkInfo.DetailedState;
import android.net.NetworkPolicyManager;
import android.net.NetworkPolicyManager.NetworkPolicyCallback;
+import android.net.NetworkProvider;
import android.net.NetworkRequest;
import android.net.NetworkScore;
import android.net.NetworkSpecifier;
@@ -285,6 +287,7 @@
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
+import android.os.PersistableBundle;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
@@ -336,6 +339,7 @@
import com.android.testutils.HandlerUtils;
import com.android.testutils.RecorderCallback.CallbackEntry;
import com.android.testutils.TestableNetworkCallback;
+import com.android.testutils.TestableNetworkOfferCallback;
import org.junit.After;
import org.junit.Before;
@@ -814,17 +818,22 @@
private String mRedirectUrl;
TestNetworkAgentWrapper(int transport) throws Exception {
- this(transport, new LinkProperties(), null);
+ this(transport, new LinkProperties(), null /* ncTemplate */, null /* provider */);
}
TestNetworkAgentWrapper(int transport, LinkProperties linkProperties)
throws Exception {
- this(transport, linkProperties, null);
+ this(transport, linkProperties, null /* ncTemplate */, null /* provider */);
}
private TestNetworkAgentWrapper(int transport, LinkProperties linkProperties,
NetworkCapabilities ncTemplate) throws Exception {
- super(transport, linkProperties, ncTemplate, mServiceContext);
+ this(transport, linkProperties, ncTemplate, null /* provider */);
+ }
+
+ private TestNetworkAgentWrapper(int transport, LinkProperties linkProperties,
+ NetworkCapabilities ncTemplate, NetworkProvider provider) throws Exception {
+ super(transport, linkProperties, ncTemplate, provider, mServiceContext);
// Waits for the NetworkAgent to be registered, which includes the creation of the
// NetworkMonitor.
@@ -833,9 +842,40 @@
HandlerUtils.waitForIdle(ConnectivityThread.get(), TIMEOUT_MS);
}
+ class TestInstrumentedNetworkAgent extends InstrumentedNetworkAgent {
+ TestInstrumentedNetworkAgent(NetworkAgentWrapper wrapper, LinkProperties lp,
+ NetworkAgentConfig nac, NetworkProvider provider) {
+ super(wrapper, lp, nac, provider);
+ }
+
+ @Override
+ public void networkStatus(int status, String redirectUrl) {
+ mRedirectUrl = redirectUrl;
+ mNetworkStatusReceived.open();
+ }
+
+ @Override
+ public void onNetworkCreated() {
+ super.onNetworkCreated();
+ if (mCreatedCallback != null) mCreatedCallback.run();
+ }
+
+ @Override
+ public void onNetworkUnwanted() {
+ super.onNetworkUnwanted();
+ if (mUnwantedCallback != null) mUnwantedCallback.run();
+ }
+
+ @Override
+ public void onNetworkDestroyed() {
+ super.onNetworkDestroyed();
+ if (mDisconnectedCallback != null) mDisconnectedCallback.run();
+ }
+ }
+
@Override
protected InstrumentedNetworkAgent makeNetworkAgent(LinkProperties linkProperties,
- NetworkAgentConfig nac) throws Exception {
+ NetworkAgentConfig nac, NetworkProvider provider) throws Exception {
mNetworkMonitor = mock(INetworkMonitor.class);
final Answer validateAnswer = inv -> {
@@ -855,31 +895,7 @@
nmCbCaptor.capture());
final InstrumentedNetworkAgent na =
- new InstrumentedNetworkAgent(this, linkProperties, nac) {
- @Override
- public void networkStatus(int status, String redirectUrl) {
- mRedirectUrl = redirectUrl;
- mNetworkStatusReceived.open();
- }
-
- @Override
- public void onNetworkCreated() {
- super.onNetworkCreated();
- if (mCreatedCallback != null) mCreatedCallback.run();
- }
-
- @Override
- public void onNetworkUnwanted() {
- super.onNetworkUnwanted();
- if (mUnwantedCallback != null) mUnwantedCallback.run();
- }
-
- @Override
- public void onNetworkDestroyed() {
- super.onNetworkDestroyed();
- if (mDisconnectedCallback != null) mDisconnectedCallback.run();
- }
- };
+ new TestInstrumentedNetworkAgent(this, linkProperties, nac, provider);
assertEquals(na.getNetwork().netId, nmNetworkCaptor.getValue().netId);
mNmCallbacks = nmCbCaptor.getValue();
@@ -4796,6 +4812,124 @@
}
@Test
+ public void testOffersAvoidsBadWifi() throws Exception {
+ // Normal mode : the carrier doesn't restrict moving away from bad wifi.
+ // This has getAvoidBadWifi return true.
+ doReturn(1).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi);
+ // Don't request cell separately for the purposes of this test.
+ setAlwaysOnNetworks(false);
+
+ final NetworkProvider cellProvider = new NetworkProvider(mServiceContext,
+ mCsHandlerThread.getLooper(), "Cell provider");
+ final NetworkProvider wifiProvider = new NetworkProvider(mServiceContext,
+ mCsHandlerThread.getLooper(), "Wifi provider");
+
+ mCm.registerNetworkProvider(cellProvider);
+ mCm.registerNetworkProvider(wifiProvider);
+
+ final NetworkScore cellScore = new NetworkScore.Builder().build();
+ final NetworkScore wifiScore = new NetworkScore.Builder().build();
+ final NetworkCapabilities defaultCaps = new NetworkCapabilities.Builder()
+ .addCapability(NET_CAPABILITY_INTERNET)
+ .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
+ .build();
+ final NetworkCapabilities cellCaps = new NetworkCapabilities.Builder()
+ .addTransportType(TRANSPORT_CELLULAR)
+ .addCapability(NET_CAPABILITY_INTERNET)
+ .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
+ .build();
+ final NetworkCapabilities wifiCaps = new NetworkCapabilities.Builder()
+ .addTransportType(TRANSPORT_WIFI)
+ .addCapability(NET_CAPABILITY_INTERNET)
+ .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
+ .build();
+ final TestableNetworkOfferCallback cellCallback = new TestableNetworkOfferCallback(
+ TIMEOUT_MS /* timeout */, TEST_CALLBACK_TIMEOUT_MS /* noCallbackTimeout */);
+ final TestableNetworkOfferCallback wifiCallback = new TestableNetworkOfferCallback(
+ TIMEOUT_MS /* timeout */, TEST_CALLBACK_TIMEOUT_MS /* noCallbackTimeout */);
+
+ Log.e("ConnectivityService", "test registering " + cellProvider);
+ // Offer callbacks will run on the CS handler thread in this test.
+ cellProvider.registerNetworkOffer(cellScore, cellCaps, r -> r.run(), cellCallback);
+ wifiProvider.registerNetworkOffer(wifiScore, wifiCaps, r -> r.run(), wifiCallback);
+
+ // Both providers see the default request.
+ cellCallback.expectOnNetworkNeeded(defaultCaps);
+ wifiCallback.expectOnNetworkNeeded(defaultCaps);
+
+ // Listen to cell and wifi to know when agents are finished processing
+ final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
+ final NetworkRequest cellRequest = new NetworkRequest.Builder()
+ .addTransportType(TRANSPORT_CELLULAR).build();
+ mCm.registerNetworkCallback(cellRequest, cellNetworkCallback);
+ final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback();
+ final NetworkRequest wifiRequest = new NetworkRequest.Builder()
+ .addTransportType(TRANSPORT_WIFI).build();
+ mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback);
+
+ // Cell connects and validates.
+ mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR,
+ new LinkProperties(), null /* ncTemplate */, cellProvider);
+ mCellNetworkAgent.connect(true);
+ cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+ cellCallback.assertNoCallback();
+ wifiCallback.assertNoCallback();
+
+ // Bring up wifi. At first it's invalidated, so cell is still needed.
+ mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI,
+ new LinkProperties(), null /* ncTemplate */, wifiProvider);
+ mWiFiNetworkAgent.connect(false);
+ wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+ cellCallback.assertNoCallback();
+ wifiCallback.assertNoCallback();
+
+ // Wifi validates. Cell is no longer needed, because it's outscored.
+ mWiFiNetworkAgent.setNetworkValid(true /* isStrictMode */);
+ // Have CS reconsider the network (see testPartialConnectivity)
+ mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
+ wifiNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
+ cellCallback.expectOnNetworkUnneeded(defaultCaps);
+ wifiCallback.assertNoCallback();
+
+ // Wifi is no longer validated. Cell is needed again.
+ mWiFiNetworkAgent.setNetworkInvalid(true /* isStrictMode */);
+ mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), false);
+ wifiNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
+ cellCallback.expectOnNetworkNeeded(defaultCaps);
+ wifiCallback.assertNoCallback();
+
+ // Disconnect wifi and pretend the carrier restricts moving away from bad wifi.
+ mWiFiNetworkAgent.disconnect();
+ wifiNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ // This has getAvoidBadWifi return false. This test doesn't change the value of the
+ // associated setting.
+ doReturn(0).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi);
+ mPolicyTracker.reevaluate();
+ waitForIdle();
+
+ // Connect wifi again, cell is needed until wifi validates.
+ mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI,
+ new LinkProperties(), null /* ncTemplate */, wifiProvider);
+ mWiFiNetworkAgent.connect(false);
+ wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+ cellCallback.assertNoCallback();
+ wifiCallback.assertNoCallback();
+ mWiFiNetworkAgent.setNetworkValid(true /* isStrictMode */);
+ mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
+ wifiNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
+ cellCallback.expectOnNetworkUnneeded(defaultCaps);
+ wifiCallback.assertNoCallback();
+
+ // Wifi loses validation. Because the device doesn't avoid bad wifis, cell is
+ // not needed.
+ mWiFiNetworkAgent.setNetworkInvalid(true /* isStrictMode */);
+ mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), false);
+ wifiNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
+ cellCallback.assertNoCallback();
+ wifiCallback.assertNoCallback();
+ }
+
+ @Test
public void testAvoidBadWifi() throws Exception {
final ContentResolver cr = mServiceContext.getContentResolver();
@@ -7737,8 +7871,8 @@
mMockVpn.disconnect();
}
- @Test
- public void testIsActiveNetworkMeteredOverVpnSpecifyingUnderlyingNetworks() throws Exception {
+ @Test
+ public void testIsActiveNetworkMeteredOverVpnSpecifyingUnderlyingNetworks() throws Exception {
// Returns true by default when no network is available.
assertTrue(mCm.isActiveNetworkMetered());
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
@@ -8303,6 +8437,52 @@
mCm.unregisterNetworkCallback(vpnDefaultCallbackAsUid);
}
+ @Test
+ public void testVpnExcludesOwnUid() throws Exception {
+ // required for registerDefaultNetworkCallbackForUid.
+ mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED);
+
+ // Connect Wi-Fi.
+ mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
+ mWiFiNetworkAgent.connect(true /* validated */);
+
+ // Connect a VPN that excludes its UID from its UID ranges.
+ final LinkProperties lp = new LinkProperties();
+ lp.setInterfaceName(VPN_IFNAME);
+ final int myUid = Process.myUid();
+ final Set<UidRange> ranges = new ArraySet<>();
+ ranges.add(new UidRange(0, myUid - 1));
+ ranges.add(new UidRange(myUid + 1, UserHandle.PER_USER_RANGE - 1));
+ mMockVpn.setUnderlyingNetworks(new Network[]{mWiFiNetworkAgent.getNetwork()});
+ mMockVpn.establish(lp, myUid, ranges);
+
+ // Wait for validation before registering callbacks.
+ waitForIdle();
+
+ final int otherUid = myUid + 1;
+ final Handler h = new Handler(ConnectivityThread.getInstanceLooper());
+ final TestNetworkCallback otherUidCb = new TestNetworkCallback();
+ final TestNetworkCallback defaultCb = new TestNetworkCallback();
+ final TestNetworkCallback perUidCb = new TestNetworkCallback();
+ registerDefaultNetworkCallbackAsUid(otherUidCb, otherUid);
+ mCm.registerDefaultNetworkCallback(defaultCb, h);
+ doAsUid(Process.SYSTEM_UID,
+ () -> mCm.registerDefaultNetworkCallbackForUid(myUid, perUidCb, h));
+
+ otherUidCb.expectAvailableCallbacksValidated(mMockVpn);
+ // BUG (b/195265065): the default network for the VPN app is actually Wi-Fi, not the VPN.
+ defaultCb.expectAvailableCallbacksValidated(mMockVpn);
+ perUidCb.expectAvailableCallbacksValidated(mMockVpn);
+ // getActiveNetwork is not affected by this bug.
+ assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetworkForUid(myUid + 1));
+ assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+ assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(myUid));
+
+ doAsUid(otherUid, () -> mCm.unregisterNetworkCallback(otherUidCb));
+ mCm.unregisterNetworkCallback(defaultCb);
+ doAsUid(Process.SYSTEM_UID, () -> mCm.unregisterNetworkCallback(perUidCb));
+ }
+
private void setupLegacyLockdownVpn() {
final String profileName = "testVpnProfile";
final byte[] profileTag = profileName.getBytes(StandardCharsets.UTF_8);
@@ -10126,6 +10306,35 @@
assertTrue(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder));
}
+ @Test(expected = NullPointerException.class)
+ public void testRegisterConnectivityDiagnosticsCallbackNullCallback() {
+ mService.registerConnectivityDiagnosticsCallback(
+ null /* callback */,
+ new NetworkRequest.Builder().build(),
+ mContext.getPackageName());
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void testRegisterConnectivityDiagnosticsCallbackNullNetworkRequest() {
+ mService.registerConnectivityDiagnosticsCallback(
+ mConnectivityDiagnosticsCallback,
+ null /* request */,
+ mContext.getPackageName());
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void testRegisterConnectivityDiagnosticsCallbackNullPackageName() {
+ mService.registerConnectivityDiagnosticsCallback(
+ mConnectivityDiagnosticsCallback,
+ new NetworkRequest.Builder().build(),
+ null /* callingPackageName */);
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void testUnregisterConnectivityDiagnosticsCallbackNullPackageName() {
+ mService.unregisterConnectivityDiagnosticsCallback(null /* callback */);
+ }
+
public NetworkAgentInfo fakeMobileNai(NetworkCapabilities nc) {
final NetworkCapabilities cellNc = new NetworkCapabilities.Builder(nc)
.addTransportType(TRANSPORT_CELLULAR).build();
@@ -10328,6 +10537,12 @@
mCellNetworkAgent.connect(true);
callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
callback.assertNoCallback();
+
+ // Make sure a report is sent and that the caps are suitably redacted.
+ verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS))
+ .onConnectivityReportAvailable(argThat(report ->
+ areConnDiagCapsRedacted(report.getNetworkCapabilities())));
+ reset(mConnectivityDiagnosticsCallback);
}
private boolean areConnDiagCapsRedacted(NetworkCapabilities nc) {
@@ -10341,17 +10556,6 @@
}
@Test
- public void testConnectivityDiagnosticsCallbackOnConnectivityReportAvailable()
- throws Exception {
- setUpConnectivityDiagnosticsCallback();
-
- // Verify onConnectivityReport fired
- verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS))
- .onConnectivityReportAvailable(argThat(report ->
- areConnDiagCapsRedacted(report.getNetworkCapabilities())));
- }
-
- @Test
public void testConnectivityDiagnosticsCallbackOnDataStallSuspected() throws Exception {
setUpConnectivityDiagnosticsCallback();
@@ -10368,9 +10572,6 @@
public void testConnectivityDiagnosticsCallbackOnConnectivityReported() throws Exception {
setUpConnectivityDiagnosticsCallback();
- // reset to ignore callbacks from setup
- reset(mConnectivityDiagnosticsCallback);
-
final Network n = mCellNetworkAgent.getNetwork();
final boolean hasConnectivity = true;
mService.reportNetworkConnectivity(n, hasConnectivity);
@@ -10402,9 +10603,6 @@
throws Exception {
setUpConnectivityDiagnosticsCallback();
- // reset to ignore callbacks from setup
- reset(mConnectivityDiagnosticsCallback);
-
// report known Connectivity from a different uid. Verify that network is not re-validated
// and this callback is not notified.
final Network n = mCellNetworkAgent.getNetwork();
@@ -10436,6 +10634,24 @@
areConnDiagCapsRedacted(report.getNetworkCapabilities())));
}
+ @Test(expected = NullPointerException.class)
+ public void testSimulateDataStallNullNetwork() {
+ mService.simulateDataStall(
+ DataStallReport.DETECTION_METHOD_DNS_EVENTS,
+ 0L /* timestampMillis */,
+ null /* network */,
+ new PersistableBundle());
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void testSimulateDataStallNullPersistableBundle() {
+ mService.simulateDataStall(
+ DataStallReport.DETECTION_METHOD_DNS_EVENTS,
+ 0L /* timestampMillis */,
+ mock(Network.class),
+ null /* extras */);
+ }
+
@Test
public void testRouteAddDeleteUpdate() throws Exception {
final NetworkRequest request = new NetworkRequest.Builder().build();