NetworkAgent.java revision 49f63fbed4cd84f5da182c85e8b999037dc64f3b
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.net; 18 19import android.content.Context; 20import android.os.Handler; 21import android.os.Looper; 22import android.os.Message; 23import android.os.Messenger; 24import android.os.Parcel; 25import android.os.Parcelable; 26import android.util.Log; 27 28import com.android.internal.util.AsyncChannel; 29import com.android.internal.util.Protocol; 30 31import java.util.ArrayList; 32import java.util.concurrent.atomic.AtomicBoolean; 33 34/** 35 * A Utility class for handling for communicating between bearer-specific 36 * code and ConnectivityService. 37 * 38 * A bearer may have more than one NetworkAgent if it can simultaneously 39 * support separate networks (IMS / Internet / MMS Apns on cellular, or 40 * perhaps connections with different SSID or P2P for Wi-Fi). 41 * 42 * @hide 43 */ 44public abstract class NetworkAgent extends Handler { 45 private volatile AsyncChannel mAsyncChannel; 46 private final String LOG_TAG; 47 private static final boolean DBG = true; 48 private static final boolean VDBG = false; 49 private final Context mContext; 50 private final ArrayList<Message>mPreConnectedQueue = new ArrayList<Message>(); 51 52 private static final int BASE = Protocol.BASE_NETWORK_AGENT; 53 54 /** 55 * Sent by ConnectivityService to the NetworkAgent to inform it of 56 * suspected connectivity problems on its network. The NetworkAgent 57 * should take steps to verify and correct connectivity. 58 */ 59 public static final int CMD_SUSPECT_BAD = BASE; 60 61 /** 62 * Sent by the NetworkAgent (note the EVENT vs CMD prefix) to 63 * ConnectivityService to pass the current NetworkInfo (connection state). 64 * Sent when the NetworkInfo changes, mainly due to change of state. 65 * obj = NetworkInfo 66 */ 67 public static final int EVENT_NETWORK_INFO_CHANGED = BASE + 1; 68 69 /** 70 * Sent by the NetworkAgent to ConnectivityService to pass the current 71 * NetworkCapabilties. 72 * obj = NetworkCapabilities 73 */ 74 public static final int EVENT_NETWORK_CAPABILITIES_CHANGED = BASE + 2; 75 76 /** 77 * Sent by the NetworkAgent to ConnectivityService to pass the current 78 * NetworkProperties. 79 * obj = NetworkProperties 80 */ 81 public static final int EVENT_NETWORK_PROPERTIES_CHANGED = BASE + 3; 82 83 /* centralize place where base network score, and network score scaling, will be 84 * stored, so as we can consistently compare apple and oranges, or wifi, ethernet and LTE 85 */ 86 public static final int WIFI_BASE_SCORE = 60; 87 88 /** 89 * Sent by the NetworkAgent to ConnectivityService to pass the current 90 * network score. 91 * obj = network score Integer 92 */ 93 public static final int EVENT_NETWORK_SCORE_CHANGED = BASE + 4; 94 95 /** 96 * Sent by the NetworkAgent to ConnectivityService to add new UID ranges 97 * to be forced into this Network. For VPNs only. 98 * obj = UidRange[] to forward 99 */ 100 public static final int EVENT_UID_RANGES_ADDED = BASE + 5; 101 102 /** 103 * Sent by the NetworkAgent to ConnectivityService to remove UID ranges 104 * from being forced into this Network. For VPNs only. 105 * obj = UidRange[] to stop forwarding 106 */ 107 public static final int EVENT_UID_RANGES_REMOVED = BASE + 6; 108 109 /** 110 * Sent by the NetworkAgent to ConnectivityService to block all routes for a certain address 111 * family (AF_INET or AF_INET6) on this Network. For VPNs only. 112 * obj = Integer representing the family (AF_INET or AF_INET6) 113 */ 114 public static final int EVENT_BLOCK_ADDRESS_FAMILY = BASE + 7; 115 116 /** 117 * Sent by the NetworkAgent to ConnectivityService to unblock routes for a certain address 118 * family (AF_INET or AF_INET6) on this Network. For VPNs only. 119 * obj = Integer representing the family (AF_INET or AF_INET6) 120 */ 121 public static final int EVENT_UNBLOCK_ADDRESS_FAMILY = BASE + 8; 122 123 /** 124 * Sent by ConnectivitySerice to the NetworkAgent to inform the agent of the 125 * networks status - whether we could use the network or could not, due to 126 * either a bad network configuration (no internet link) or captive portal. 127 * 128 * arg1 = either {@code VALID_NETWORK} or {@code INVALID_NETWORK} 129 */ 130 public static final int CMD_REPORT_NETWORK_STATUS = BASE + 9; 131 132 public static final int VALID_NETWORK = 1; 133 public static final int INVALID_NETWORK = 2; 134 135 public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni, 136 NetworkCapabilities nc, LinkProperties lp, int score) { 137 this(looper, context, logTag, ni, nc, lp, score, null); 138 } 139 140 public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni, 141 NetworkCapabilities nc, LinkProperties lp, int score, NetworkMisc misc) { 142 super(looper); 143 LOG_TAG = logTag; 144 mContext = context; 145 if (ni == null || nc == null || lp == null) { 146 throw new IllegalArgumentException(); 147 } 148 149 if (VDBG) log("Registering NetworkAgent"); 150 ConnectivityManager cm = (ConnectivityManager)mContext.getSystemService( 151 Context.CONNECTIVITY_SERVICE); 152 cm.registerNetworkAgent(new Messenger(this), new NetworkInfo(ni), 153 new LinkProperties(lp), new NetworkCapabilities(nc), score, misc); 154 } 155 156 @Override 157 public void handleMessage(Message msg) { 158 switch (msg.what) { 159 case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION: { 160 if (mAsyncChannel != null) { 161 log("Received new connection while already connected!"); 162 } else { 163 if (VDBG) log("NetworkAgent fully connected"); 164 AsyncChannel ac = new AsyncChannel(); 165 ac.connected(null, this, msg.replyTo); 166 ac.replyToMessage(msg, AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED, 167 AsyncChannel.STATUS_SUCCESSFUL); 168 synchronized (mPreConnectedQueue) { 169 mAsyncChannel = ac; 170 for (Message m : mPreConnectedQueue) { 171 ac.sendMessage(m); 172 } 173 mPreConnectedQueue.clear(); 174 } 175 } 176 break; 177 } 178 case AsyncChannel.CMD_CHANNEL_DISCONNECT: { 179 if (VDBG) log("CMD_CHANNEL_DISCONNECT"); 180 if (mAsyncChannel != null) mAsyncChannel.disconnect(); 181 break; 182 } 183 case AsyncChannel.CMD_CHANNEL_DISCONNECTED: { 184 if (DBG) log("NetworkAgent channel lost"); 185 // let the client know CS is done with us. 186 unwanted(); 187 synchronized (mPreConnectedQueue) { 188 mAsyncChannel = null; 189 } 190 break; 191 } 192 case CMD_SUSPECT_BAD: { 193 log("Unhandled Message " + msg); 194 break; 195 } 196 case CMD_REPORT_NETWORK_STATUS: { 197 if (VDBG) { 198 log("CMD_REPORT_NETWORK_STATUS(" + 199 (msg.arg1 == VALID_NETWORK ? "VALID)" : "INVALID)")); 200 } 201 networkStatus(msg.arg1); 202 break; 203 } 204 } 205 } 206 207 private void queueOrSendMessage(int what, Object obj) { 208 synchronized (mPreConnectedQueue) { 209 if (mAsyncChannel != null) { 210 mAsyncChannel.sendMessage(what, obj); 211 } else { 212 Message msg = Message.obtain(); 213 msg.what = what; 214 msg.obj = obj; 215 mPreConnectedQueue.add(msg); 216 } 217 } 218 } 219 220 /** 221 * Called by the bearer code when it has new LinkProperties data. 222 */ 223 public void sendLinkProperties(LinkProperties linkProperties) { 224 queueOrSendMessage(EVENT_NETWORK_PROPERTIES_CHANGED, new LinkProperties(linkProperties)); 225 } 226 227 /** 228 * Called by the bearer code when it has new NetworkInfo data. 229 */ 230 public void sendNetworkInfo(NetworkInfo networkInfo) { 231 queueOrSendMessage(EVENT_NETWORK_INFO_CHANGED, new NetworkInfo(networkInfo)); 232 } 233 234 /** 235 * Called by the bearer code when it has new NetworkCapabilities data. 236 */ 237 public void sendNetworkCapabilities(NetworkCapabilities networkCapabilities) { 238 queueOrSendMessage(EVENT_NETWORK_CAPABILITIES_CHANGED, 239 new NetworkCapabilities(networkCapabilities)); 240 } 241 242 /** 243 * Called by the bearer code when it has a new score for this network. 244 */ 245 public void sendNetworkScore(int score) { 246 if (score < 0) { 247 throw new IllegalArgumentException("Score must be >= 0"); 248 } 249 queueOrSendMessage(EVENT_NETWORK_SCORE_CHANGED, new Integer(score)); 250 } 251 252 /** 253 * Called by the VPN code when it wants to add ranges of UIDs to be routed 254 * through the VPN network. 255 */ 256 public void addUidRanges(UidRange[] ranges) { 257 queueOrSendMessage(EVENT_UID_RANGES_ADDED, ranges); 258 } 259 260 /** 261 * Called by the VPN code when it wants to remove ranges of UIDs from being routed 262 * through the VPN network. 263 */ 264 public void removeUidRanges(UidRange[] ranges) { 265 queueOrSendMessage(EVENT_UID_RANGES_REMOVED, ranges); 266 } 267 268 /** 269 * Called by the VPN code when it wants to block an address family from being routed, typically 270 * because the VPN network doesn't support that family. 271 */ 272 public void blockAddressFamily(int family) { 273 queueOrSendMessage(EVENT_BLOCK_ADDRESS_FAMILY, family); 274 } 275 276 /** 277 * Called by the VPN code when it wants to unblock an address family from being routed. 278 */ 279 public void unblockAddressFamily(int family) { 280 queueOrSendMessage(EVENT_UNBLOCK_ADDRESS_FAMILY, family); 281 } 282 283 /** 284 * Called when ConnectivityService has indicated they no longer want this network. 285 * The parent factory should (previously) have received indication of the change 286 * as well, either canceling NetworkRequests or altering their score such that this 287 * network won't be immediately requested again. 288 */ 289 abstract protected void unwanted(); 290 291 /** 292 * Called when the system determines the usefulness of this network. 293 * 294 * Networks claiming internet connectivity will have their internet 295 * connectivity verified. 296 * 297 * Currently there are two possible values: 298 * {@code VALID_NETWORK} if the system is happy with the connection, 299 * {@code INVALID_NETWORK} if the system is not happy. 300 * TODO - add indications of captive portal-ness and related success/failure, 301 * ie, CAPTIVE_SUCCESS_NETWORK, CAPTIVE_NETWORK for successful login and detection 302 * 303 * This may be called multiple times as the network status changes and may 304 * generate false negatives if we lose ip connectivity before the link is torn down. 305 */ 306 protected void networkStatus(int status) { 307 } 308 309 protected void log(String s) { 310 Log.d(LOG_TAG, "NetworkAgent: " + s); 311 } 312} 313