Add Multinetwork API
Change-Id: I3a9cef0d416db96d05098dd989ee3fef3b1e9274 (cherry picked from commit cc5e6afa1ba0bef099bcb21a64a36bc2bf7951db)
This commit is contained in:
@@ -13,26 +13,35 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package android.net;
|
package android.net;
|
||||||
|
|
||||||
import static com.android.internal.util.Preconditions.checkNotNull;
|
import static com.android.internal.util.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import android.annotation.SdkConstant;
|
import android.annotation.SdkConstant;
|
||||||
import android.annotation.SdkConstant.SdkConstantType;
|
import android.annotation.SdkConstant.SdkConstantType;
|
||||||
|
import android.app.PendingIntent;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Build.VERSION_CODES;
|
import android.os.Build.VERSION_CODES;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.HandlerThread;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.INetworkActivityListener;
|
import android.os.INetworkActivityListener;
|
||||||
import android.os.INetworkManagementService;
|
import android.os.INetworkManagementService;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.os.Message;
|
||||||
import android.os.Messenger;
|
import android.os.Messenger;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ServiceManager;
|
import android.os.ServiceManager;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import com.android.internal.util.Protocol;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class that answers queries about the state of network connectivity. It also
|
* Class that answers queries about the state of network connectivity. It also
|
||||||
@@ -699,7 +708,25 @@ public class ConnectivityManager {
|
|||||||
*/
|
*/
|
||||||
public LinkProperties getLinkProperties(int networkType) {
|
public LinkProperties getLinkProperties(int networkType) {
|
||||||
try {
|
try {
|
||||||
return mService.getLinkProperties(networkType);
|
return mService.getLinkPropertiesForType(networkType);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@hide} */
|
||||||
|
public LinkProperties getLinkProperties(Network network) {
|
||||||
|
try {
|
||||||
|
return mService.getLinkProperties(network);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@hide} */
|
||||||
|
public NetworkCapabilities getNetworkCapabilities(Network network) {
|
||||||
|
try {
|
||||||
|
return mService.getNetworkCapabilities(network);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -1302,6 +1329,22 @@ public class ConnectivityManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report a problem network to the framework. This will cause the framework
|
||||||
|
* to evaluate the situation and try to fix any problems. Note that false
|
||||||
|
* may be subsequently ignored.
|
||||||
|
*
|
||||||
|
* @param network The Network the application was attempting to use or null
|
||||||
|
* to indicate the current default network.
|
||||||
|
* {@hide}
|
||||||
|
*/
|
||||||
|
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
|
* 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
|
* for typical HTTP proxies - they are general network dependent. However if you're
|
||||||
@@ -1599,15 +1642,27 @@ public class ConnectivityManager {
|
|||||||
} catch (RemoteException e) { }
|
} catch (RemoteException e) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Interface for NetworkRequest callbacks {@hide} */
|
/**
|
||||||
|
* Interface for NetworkRequest callbacks. Used for notifications about network
|
||||||
|
* changes.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
public static class NetworkCallbacks {
|
public static class NetworkCallbacks {
|
||||||
|
/** @hide */
|
||||||
public static final int PRECHECK = 1;
|
public static final int PRECHECK = 1;
|
||||||
|
/** @hide */
|
||||||
public static final int AVAILABLE = 2;
|
public static final int AVAILABLE = 2;
|
||||||
|
/** @hide */
|
||||||
public static final int LOSING = 3;
|
public static final int LOSING = 3;
|
||||||
|
/** @hide */
|
||||||
public static final int LOST = 4;
|
public static final int LOST = 4;
|
||||||
|
/** @hide */
|
||||||
public static final int UNAVAIL = 5;
|
public static final int UNAVAIL = 5;
|
||||||
|
/** @hide */
|
||||||
public static final int CAP_CHANGED = 6;
|
public static final int CAP_CHANGED = 6;
|
||||||
|
/** @hide */
|
||||||
public static final int PROP_CHANGED = 7;
|
public static final int PROP_CHANGED = 7;
|
||||||
|
/** @hide */
|
||||||
public static final int CANCELED = 8;
|
public static final int CANCELED = 8;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1650,21 +1705,361 @@ public class ConnectivityManager {
|
|||||||
* Called when the network the framework connected to for this request
|
* Called when the network the framework connected to for this request
|
||||||
* changes capabilities but still satisfies the stated need.
|
* changes capabilities but still satisfies the stated need.
|
||||||
*/
|
*/
|
||||||
public void onCapabilitiesChanged(NetworkRequest networkRequest, Network network,
|
public void onNetworkCapabilitiesChanged(NetworkRequest networkRequest, Network network,
|
||||||
NetworkCapabilities networkCapabilities) {}
|
NetworkCapabilities networkCapabilities) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the network the framework connected to for this request
|
* Called when the network the framework connected to for this request
|
||||||
* changes properties.
|
* changes LinkProperties.
|
||||||
*/
|
*/
|
||||||
public void onPropertiesChanged(NetworkRequest networkRequest, Network network,
|
public void onLinkPropertiesChanged(NetworkRequest networkRequest, Network network,
|
||||||
LinkProperties linkProperties) {}
|
LinkProperties linkProperties) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when a CancelRequest call concludes and the registered callbacks will
|
* Called when a releaseNetworkRequest call concludes and the registered callbacks will
|
||||||
* no longer be used.
|
* no longer be used.
|
||||||
*/
|
*/
|
||||||
public void onCanceled(NetworkRequest networkRequest) {}
|
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;
|
||||||
|
|
||||||
|
private static class CallbackHandler extends Handler {
|
||||||
|
private final HashMap<NetworkRequest, NetworkCallbacks>mCallbackMap;
|
||||||
|
private final AtomicInteger mRefCount;
|
||||||
|
private static final String TAG = "ConnectivityManager.CallbackHandler";
|
||||||
|
private final ConnectivityManager mCm;
|
||||||
|
|
||||||
|
CallbackHandler(Looper looper, HashMap<NetworkRequest, NetworkCallbacks>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);
|
||||||
|
NetworkCallbacks 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);
|
||||||
|
NetworkCallbacks 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);
|
||||||
|
NetworkCallbacks 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);
|
||||||
|
NetworkCallbacks 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;
|
||||||
|
NetworkCallbacks 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);
|
||||||
|
NetworkCallbacks 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);
|
||||||
|
NetworkCallbacks 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;
|
||||||
|
NetworkCallbacks 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private NetworkRequest getNetworkRequest(Message msg) {
|
||||||
|
return (NetworkRequest)(msg.obj);
|
||||||
|
}
|
||||||
|
private NetworkCallbacks getCallbacks(NetworkRequest req) {
|
||||||
|
synchronized(mCallbackMap) {
|
||||||
|
return mCallbackMap.get(req);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private Network getNetwork(Message msg) {
|
||||||
|
return new Network(msg.arg2);
|
||||||
|
}
|
||||||
|
private NetworkCallbacks 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(),
|
||||||
|
sNetworkCallbacks, sCallbackRefCount, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeCallbackListener() {
|
||||||
|
synchronized(sCallbackRefCount) {
|
||||||
|
if (sCallbackRefCount.decrementAndGet() == 0) {
|
||||||
|
sCallbackHandler.obtainMessage(CALLBACK_EXIT).sendToTarget();
|
||||||
|
sCallbackHandler = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static final HashMap<NetworkRequest, NetworkCallbacks> sNetworkCallbacks =
|
||||||
|
new HashMap<NetworkRequest, NetworkCallbacks>();
|
||||||
|
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 somethingForNetwork(NetworkCapabilities need,
|
||||||
|
NetworkCallbacks networkCallbacks, int timeoutSec, int action) {
|
||||||
|
NetworkRequest networkRequest = null;
|
||||||
|
if (networkCallbacks == null) throw new IllegalArgumentException("null NetworkCallbacks");
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
if (networkRequest != null) {
|
||||||
|
synchronized(sNetworkCallbacks) {
|
||||||
|
sNetworkCallbacks.put(networkRequest, networkCallbacks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} 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 follwed by listening to the various
|
||||||
|
* callbacks described in {@link NetworkCallbacks}. The {@link Network}
|
||||||
|
* can be used by using the {@link bindSocketToNetwork},
|
||||||
|
* {@link bindApplicationToNetwork} and {@link getAddrInfoOnNetwork} functions.
|
||||||
|
*
|
||||||
|
* @param need {@link NetworkCapabilities} required by this request.
|
||||||
|
* @param networkCallbacks 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.
|
||||||
|
* @return A {@link NetworkRequest} object identifying the request.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public NetworkRequest requestNetwork(NetworkCapabilities need,
|
||||||
|
NetworkCallbacks networkCallbacks) {
|
||||||
|
return somethingForNetwork(need, networkCallbacks, 0, REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request a network to satisfy a set of {@link NetworkCapabilities}, limited
|
||||||
|
* by a timeout.
|
||||||
|
*
|
||||||
|
* This function behaves identically, but if a suitable network is not found
|
||||||
|
* within the given time (in Seconds) the {@link NetworkCallbacks#unavailable}
|
||||||
|
* callback is called. The request must still be released normally by
|
||||||
|
* calling {@link releaseNetworkRequest}.
|
||||||
|
* @param need {@link NetworkCapabilities} required by this request.
|
||||||
|
* @param networkCallbacks 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 NetworkCallbacks#unavailable} is called.
|
||||||
|
* @return A {@link NetworkRequest} object identifying the request.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public NetworkRequest requestNetwork(NetworkCapabilities need,
|
||||||
|
NetworkCallbacks networkCallbacks, int timeoutSec) {
|
||||||
|
return somethingForNetwork(need, networkCallbacks, timeoutSec, REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request a network to satisfy a set of {@link NetworkCapabilities}.
|
||||||
|
*
|
||||||
|
* This function behavies identically, but instead of {@link NetworkCallbacks}
|
||||||
|
* 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_CAPABILTIES} containing
|
||||||
|
* the original requests parameters. It is important to create a new,
|
||||||
|
* {@link NetworkCallbacks} 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
|
||||||
|
* replace by this one, effectively releasing the previous {@link NetworkRequest}.
|
||||||
|
* <p>
|
||||||
|
* The request may be released normally by calling {@link releaseNetworkRequest}.
|
||||||
|
*
|
||||||
|
* @param need {@link NetworkCapabilties} required by this request.
|
||||||
|
* @param operation Action to perform when the network is available (corresponds
|
||||||
|
* to the {@link NetworkCallbacks#onAvailable} call. Typically
|
||||||
|
* comes from {@link PendingIntent#getBroadcast}.
|
||||||
|
* @return A {@link NetworkRequest} object identifying the request.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
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 networkCallbacks The {@link NetworkCallbacks} to be called as suitable
|
||||||
|
* networks change state.
|
||||||
|
* @return A {@link NetworkRequest} object identifying the request.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public NetworkRequest listenForNetwork(NetworkCapabilities need,
|
||||||
|
NetworkCallbacks networkCallbacks) {
|
||||||
|
return somethingForNetwork(need, networkCallbacks, 0, LISTEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Releases a {NetworkRequest} generated either through a {@link requestNetwork}
|
||||||
|
* or a {@link listenForNetwork} call. The {@link NetworkCallbacks} given in the
|
||||||
|
* earlier call may continue receiving calls until the {@link NetworkCallbacks#onReleased}
|
||||||
|
* function is called, signifiying the end of the request.
|
||||||
|
*
|
||||||
|
* @param networkRequest The {@link NetworkRequest} generated by an earlier call to
|
||||||
|
* {@link requestNetwork} or {@link listenForNetwork}.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public void releaseNetworkRequest(NetworkRequest networkRequest) {
|
||||||
|
if (networkRequest == null) throw new IllegalArgumentException("null NetworkRequest");
|
||||||
|
try {
|
||||||
|
mService.releaseNetworkRequest(networkRequest);
|
||||||
|
} catch (RemoteException e) {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,11 +16,14 @@
|
|||||||
|
|
||||||
package android.net;
|
package android.net;
|
||||||
|
|
||||||
|
import android.app.PendingIntent;
|
||||||
import android.net.LinkQualityInfo;
|
import android.net.LinkQualityInfo;
|
||||||
import android.net.LinkProperties;
|
import android.net.LinkProperties;
|
||||||
|
import android.net.Network;
|
||||||
import android.net.NetworkCapabilities;
|
import android.net.NetworkCapabilities;
|
||||||
import android.net.NetworkInfo;
|
import android.net.NetworkInfo;
|
||||||
import android.net.NetworkQuotaInfo;
|
import android.net.NetworkQuotaInfo;
|
||||||
|
import android.net.NetworkRequest;
|
||||||
import android.net.NetworkState;
|
import android.net.NetworkState;
|
||||||
import android.net.ProxyInfo;
|
import android.net.ProxyInfo;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
@@ -52,7 +55,10 @@ interface IConnectivityManager
|
|||||||
boolean isNetworkSupported(int networkType);
|
boolean isNetworkSupported(int networkType);
|
||||||
|
|
||||||
LinkProperties getActiveLinkProperties();
|
LinkProperties getActiveLinkProperties();
|
||||||
LinkProperties getLinkProperties(int networkType);
|
LinkProperties getLinkPropertiesForType(int networkType);
|
||||||
|
LinkProperties getLinkProperties(in Network network);
|
||||||
|
|
||||||
|
NetworkCapabilities getNetworkCapabilities(in Network network);
|
||||||
|
|
||||||
NetworkState[] getAllNetworkState();
|
NetworkState[] getAllNetworkState();
|
||||||
|
|
||||||
@@ -100,6 +106,8 @@ interface IConnectivityManager
|
|||||||
|
|
||||||
void reportInetCondition(int networkType, int percentage);
|
void reportInetCondition(int networkType, int percentage);
|
||||||
|
|
||||||
|
void reportBadNetwork(in Network network);
|
||||||
|
|
||||||
ProxyInfo getGlobalProxy();
|
ProxyInfo getGlobalProxy();
|
||||||
|
|
||||||
void setGlobalProxy(in ProxyInfo p);
|
void setGlobalProxy(in ProxyInfo p);
|
||||||
@@ -147,5 +155,20 @@ interface IConnectivityManager
|
|||||||
|
|
||||||
void registerNetworkFactory(in Messenger messenger);
|
void registerNetworkFactory(in Messenger messenger);
|
||||||
|
|
||||||
void registerNetworkAgent(in Messenger messenger, in NetworkInfo ni, in LinkProperties lp, in NetworkCapabilities nc, int score);
|
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);
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -384,7 +384,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
private static final int EVENT_ENABLE_FAIL_FAST_MOBILE_DATA = 14;
|
private static final int EVENT_ENABLE_FAIL_FAST_MOBILE_DATA = 14;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* user internally to indicate that data sampling interval is up
|
* used internally to indicate that data sampling interval is up
|
||||||
*/
|
*/
|
||||||
private static final int EVENT_SAMPLE_INTERVAL_ELAPSED = 15;
|
private static final int EVENT_SAMPLE_INTERVAL_ELAPSED = 15;
|
||||||
|
|
||||||
@@ -405,6 +405,32 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
*/
|
*/
|
||||||
private static final int EVENT_REGISTER_NETWORK_AGENT = 18;
|
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;
|
||||||
|
|
||||||
/** Handler used for internal events. */
|
/** Handler used for internal events. */
|
||||||
final private InternalHandler mHandler;
|
final private InternalHandler mHandler;
|
||||||
/** Handler used for incoming {@link NetworkStateTracker} events. */
|
/** Handler used for incoming {@link NetworkStateTracker} events. */
|
||||||
@@ -498,7 +524,9 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
netCap.addNetworkCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
|
netCap.addNetworkCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
|
||||||
netCap.addNetworkCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
|
netCap.addNetworkCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
|
||||||
mDefaultRequest = new NetworkRequest(netCap, true);
|
mDefaultRequest = new NetworkRequest(netCap, true);
|
||||||
mNetworkRequests.append(mDefaultRequest.requestId, mDefaultRequest);
|
NetworkRequestInfo nri = new NetworkRequestInfo(null, mDefaultRequest, new Binder(),
|
||||||
|
NetworkRequestInfo.REQUEST);
|
||||||
|
mNetworkRequests.put(mDefaultRequest, nri);
|
||||||
|
|
||||||
HandlerThread handlerThread = new HandlerThread("ConnectivityServiceThread");
|
HandlerThread handlerThread = new HandlerThread("ConnectivityServiceThread");
|
||||||
handlerThread.start();
|
handlerThread.start();
|
||||||
@@ -1058,19 +1086,35 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public LinkProperties getActiveLinkProperties() {
|
public LinkProperties getActiveLinkProperties() {
|
||||||
return getLinkProperties(mActiveDefaultNetwork);
|
return getLinkPropertiesForType(mActiveDefaultNetwork);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LinkProperties getLinkProperties(int networkType) {
|
public LinkProperties getLinkPropertiesForType(int networkType) {
|
||||||
enforceAccessPermission();
|
enforceAccessPermission();
|
||||||
if (isNetworkTypeValid(networkType)) {
|
if (isNetworkTypeValid(networkType)) {
|
||||||
return getLinkPropertiesForType(networkType);
|
return getLinkPropertiesForTypeInternal(networkType);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO - this should be ALL networks
|
// 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
|
@Override
|
||||||
public NetworkState[] getAllNetworkState() {
|
public NetworkState[] getAllNetworkState() {
|
||||||
enforceAccessPermission();
|
enforceAccessPermission();
|
||||||
@@ -1081,7 +1125,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
networkType++) {
|
networkType++) {
|
||||||
if (getNetworkInfoForType(networkType) != null) {
|
if (getNetworkInfoForType(networkType) != null) {
|
||||||
final NetworkInfo info = getFilteredNetworkInfo(networkType, uid);
|
final NetworkInfo info = getFilteredNetworkInfo(networkType, uid);
|
||||||
final LinkProperties lp = getLinkPropertiesForType(networkType);
|
final LinkProperties lp = getLinkPropertiesForTypeInternal(networkType);
|
||||||
final NetworkCapabilities netcap = getNetworkCapabilitiesForType(networkType);
|
final NetworkCapabilities netcap = getNetworkCapabilitiesForType(networkType);
|
||||||
result.add(new NetworkState(info, lp, netcap));
|
result.add(new NetworkState(info, lp, netcap));
|
||||||
}
|
}
|
||||||
@@ -1095,7 +1139,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
NetworkInfo info = getNetworkInfoForType(networkType);
|
NetworkInfo info = getNetworkInfoForType(networkType);
|
||||||
if (info != null) {
|
if (info != null) {
|
||||||
return new NetworkState(info,
|
return new NetworkState(info,
|
||||||
getLinkPropertiesForType(networkType),
|
getLinkPropertiesForTypeInternal(networkType),
|
||||||
getNetworkCapabilitiesForType(networkType));
|
getNetworkCapabilitiesForType(networkType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3002,7 +3046,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
* to the link that may have incorrectly setup by the lower
|
* to the link that may have incorrectly setup by the lower
|
||||||
* levels.
|
* levels.
|
||||||
*/
|
*/
|
||||||
LinkProperties lp = getLinkProperties(info.getType());
|
LinkProperties lp = getLinkPropertiesForTypeInternal(info.getType());
|
||||||
if (DBG) {
|
if (DBG) {
|
||||||
log("EVENT_STATE_CHANGED: connected to provisioning network, lp=" + lp);
|
log("EVENT_STATE_CHANGED: connected to provisioning network, lp=" + lp);
|
||||||
}
|
}
|
||||||
@@ -3050,11 +3094,10 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
|
if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
|
||||||
if (VDBG) log("NetworkFactory connected");
|
if (VDBG) log("NetworkFactory connected");
|
||||||
// A network factory has connected. Send it all current NetworkRequests.
|
// A network factory has connected. Send it all current NetworkRequests.
|
||||||
for (int i = 0; i < mNetworkRequests.size(); i++) {
|
for (NetworkRequestInfo nri : mNetworkRequests.values()) {
|
||||||
NetworkRequest request = mNetworkRequests.valueAt(i);
|
NetworkAgentInfo nai = mNetworkForRequestId.get(nri.request.requestId);
|
||||||
NetworkAgentInfo nai = mNetworkForRequestId.get(request.requestId);
|
|
||||||
ac.sendMessage(NetworkFactoryProtocol.CMD_REQUEST_NETWORK,
|
ac.sendMessage(NetworkFactoryProtocol.CMD_REQUEST_NETWORK,
|
||||||
(nai != null ? nai.currentScore : 0), 0, request);
|
(nai != null ? nai.currentScore : 0), 0, nri.request);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
loge("Error connecting NetworkFactory");
|
loge("Error connecting NetworkFactory");
|
||||||
@@ -3072,13 +3115,18 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
try {
|
try {
|
||||||
mNetworkAgentInfoForType[nai.networkInfo.getType()].remove(nai);
|
mNetworkAgentInfoForType[nai.networkInfo.getType()].remove(nai);
|
||||||
} catch (NullPointerException e) {}
|
} catch (NullPointerException e) {}
|
||||||
|
if (nai != null) {
|
||||||
|
mNetworkForNetId.remove(nai.network.netId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private void handleAsyncChannelDisconnected(Message msg) {
|
private void handleAsyncChannelDisconnected(Message msg) {
|
||||||
NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
|
NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
|
||||||
if (nai != null) {
|
if (nai != null) {
|
||||||
if (DBG) log(nai.name() + " got DISCONNECTED");
|
if (DBG) {
|
||||||
|
log(nai.name() + " got DISCONNECTED, was satisfying " + nai.networkRequests.size());
|
||||||
|
}
|
||||||
// A network agent has disconnected.
|
// A network agent has disconnected.
|
||||||
// Tell netd to clean up the configuration for this network
|
// Tell netd to clean up the configuration for this network
|
||||||
// (routing rules, DNS, etc).
|
// (routing rules, DNS, etc).
|
||||||
@@ -3087,7 +3135,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
loge("Exception removing network: " + e);
|
loge("Exception removing network: " + e);
|
||||||
}
|
}
|
||||||
notifyNetworkCallbacks(nai, NetworkCallbacks.LOST);
|
notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOST);
|
||||||
nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_DISCONNECTED);
|
nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_DISCONNECTED);
|
||||||
mNetworkAgentInfos.remove(msg.replyTo);
|
mNetworkAgentInfos.remove(msg.replyTo);
|
||||||
updateClat(null, nai.linkProperties, nai);
|
updateClat(null, nai.linkProperties, nai);
|
||||||
@@ -3095,12 +3143,17 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
mNetworkAgentInfoForType[nai.networkInfo.getType()].remove(nai);
|
mNetworkAgentInfoForType[nai.networkInfo.getType()].remove(nai);
|
||||||
} catch (NullPointerException e) {}
|
} catch (NullPointerException e) {}
|
||||||
|
|
||||||
|
mNetworkForNetId.remove(nai.network.netId);
|
||||||
// Since we've lost the network, go through all the requests that
|
// Since we've lost the network, go through all the requests that
|
||||||
// it was satisfying and see if any other factory can satisfy them.
|
// it was satisfying and see if any other factory can satisfy them.
|
||||||
final ArrayList<NetworkAgentInfo> toActivate = new ArrayList<NetworkAgentInfo>();
|
final ArrayList<NetworkAgentInfo> toActivate = new ArrayList<NetworkAgentInfo>();
|
||||||
for (int i = 0; i < nai.networkRequests.size(); i++) {
|
for (int i = 0; i < nai.networkRequests.size(); i++) {
|
||||||
NetworkRequest request = nai.networkRequests.valueAt(i);
|
NetworkRequest request = nai.networkRequests.valueAt(i);
|
||||||
NetworkAgentInfo currentNetwork = mNetworkForRequestId.get(request.requestId);
|
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) {
|
if (currentNetwork != null && currentNetwork.network.netId == nai.network.netId) {
|
||||||
mNetworkForRequestId.remove(request.requestId);
|
mNetworkForRequestId.remove(request.requestId);
|
||||||
sendUpdatedScoreToFactories(request, 0);
|
sendUpdatedScoreToFactories(request, 0);
|
||||||
@@ -3130,6 +3183,77 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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.networkRequests.put(nri.request.requestId, nri.request);
|
||||||
|
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 (AsyncChannel ac : mNetworkFactories) {
|
||||||
|
ac.sendMessage(NetworkFactoryProtocol.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) {
|
||||||
|
affectedNetwork.networkRequests.remove(nri.request.requestId);
|
||||||
|
if (VDBG) {
|
||||||
|
log(" Removing from current network " + affectedNetwork.name() + ", leaving " +
|
||||||
|
affectedNetwork.networkRequests.size() + " requests.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nri.isRequest) {
|
||||||
|
for (AsyncChannel factory : mNetworkFactories) {
|
||||||
|
factory.sendMessage(NetworkFactoryProtocol.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 {
|
private class InternalHandler extends Handler {
|
||||||
public InternalHandler(Looper looper) {
|
public InternalHandler(Looper looper) {
|
||||||
@@ -3232,6 +3356,15 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
handleRegisterNetworkAgent((NetworkAgentInfo)msg.obj);
|
handleRegisterNetworkAgent((NetworkAgentInfo)msg.obj);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case EVENT_REGISTER_NETWORK_REQUEST:
|
||||||
|
case EVENT_REGISTER_NETWORK_LISTENER: {
|
||||||
|
handleRegisterNetworkRequest(msg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EVENT_RELEASE_NETWORK_REQUEST: {
|
||||||
|
handleReleaseNetworkRequest((NetworkRequest) msg.obj);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3378,6 +3511,10 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
EVENT_INET_CONDITION_CHANGE, networkType, percentage));
|
EVENT_INET_CONDITION_CHANGE, networkType, percentage));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void reportBadNetwork(Network network) {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
private void handleInetConditionChange(int netType, int condition) {
|
private void handleInetConditionChange(int netType, int condition) {
|
||||||
if (mActiveDefaultNetwork == -1) {
|
if (mActiveDefaultNetwork == -1) {
|
||||||
if (DBG) log("handleInetConditionChange: no active default network - ignore");
|
if (DBG) log("handleInetConditionChange: no active default network - ignore");
|
||||||
@@ -4448,7 +4585,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
log("isMobileOk: addresses=" + inetAddressesToString(addresses));
|
log("isMobileOk: addresses=" + inetAddressesToString(addresses));
|
||||||
|
|
||||||
// Get the type of addresses supported by this link
|
// Get the type of addresses supported by this link
|
||||||
LinkProperties lp = mCs.getLinkProperties(
|
LinkProperties lp = mCs.getLinkPropertiesForTypeInternal(
|
||||||
ConnectivityManager.TYPE_MOBILE_HIPRI);
|
ConnectivityManager.TYPE_MOBILE_HIPRI);
|
||||||
boolean linkHasIpv4 = lp.hasIPv4Address();
|
boolean linkHasIpv4 = lp.hasIPv4Address();
|
||||||
boolean linkHasIpv6 = lp.hasIPv6Address();
|
boolean linkHasIpv6 = lp.hasIPv6Address();
|
||||||
@@ -5079,7 +5216,109 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final ArrayList<AsyncChannel> mNetworkFactories = new ArrayList<AsyncChannel>();
|
private final ArrayList<AsyncChannel> mNetworkFactories = new ArrayList<AsyncChannel>();
|
||||||
|
private final HashMap<NetworkRequest, NetworkRequestInfo> mNetworkRequests =
|
||||||
|
new HashMap<NetworkRequest, NetworkRequestInfo>();
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities,
|
||||||
|
Messenger messenger, int timeoutSec, IBinder binder) {
|
||||||
|
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));
|
||||||
|
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));
|
||||||
|
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) {
|
public void registerNetworkFactory(Messenger messenger) {
|
||||||
enforceConnectivityInternalPermission();
|
enforceConnectivityInternalPermission();
|
||||||
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_FACTORY, messenger));
|
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_FACTORY, messenger));
|
||||||
@@ -5090,11 +5329,16 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
AsyncChannel ac = new AsyncChannel();
|
AsyncChannel ac = new AsyncChannel();
|
||||||
mNetworkFactories.add(ac);
|
mNetworkFactories.add(ac);
|
||||||
ac.connect(mContext, mTrackerHandler, messenger);
|
ac.connect(mContext, mTrackerHandler, messenger);
|
||||||
|
for (NetworkRequestInfo nri : mNetworkRequests.values()) {
|
||||||
|
if (nri.isRequest) {
|
||||||
|
int score = 0;
|
||||||
|
NetworkAgentInfo currentNetwork = mNetworkForRequestId.get(nri.request.requestId);
|
||||||
|
if (currentNetwork != null) score = currentNetwork.currentScore;
|
||||||
|
ac.sendMessage(NetworkFactoryProtocol.CMD_REQUEST_NETWORK, score, 0, nri.request);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NetworkRequest by requestId
|
|
||||||
private final SparseArray<NetworkRequest> mNetworkRequests = new SparseArray<NetworkRequest>();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NetworkAgentInfo supporting a request by requestId.
|
* NetworkAgentInfo supporting a request by requestId.
|
||||||
* These have already been vetted (their Capabilities satisfy the request)
|
* These have already been vetted (their Capabilities satisfy the request)
|
||||||
@@ -5104,6 +5348,9 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
private final SparseArray<NetworkAgentInfo> mNetworkForRequestId =
|
private final SparseArray<NetworkAgentInfo> mNetworkForRequestId =
|
||||||
new SparseArray<NetworkAgentInfo>();
|
new SparseArray<NetworkAgentInfo>();
|
||||||
|
|
||||||
|
private final SparseArray<NetworkAgentInfo> mNetworkForNetId =
|
||||||
|
new SparseArray<NetworkAgentInfo>();
|
||||||
|
|
||||||
// NetworkAgentInfo keyed off its connecting messenger
|
// NetworkAgentInfo keyed off its connecting messenger
|
||||||
// TODO - eval if we can reduce the number of lists/hashmaps/sparsearrays
|
// TODO - eval if we can reduce the number of lists/hashmaps/sparsearrays
|
||||||
private final HashMap<Messenger, NetworkAgentInfo> mNetworkAgentInfos =
|
private final HashMap<Messenger, NetworkAgentInfo> mNetworkAgentInfos =
|
||||||
@@ -5131,6 +5378,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
loge("registered NetworkAgent for unsupported type: " + na);
|
loge("registered NetworkAgent for unsupported type: " + na);
|
||||||
}
|
}
|
||||||
|
mNetworkForNetId.put(na.network.netId, na);
|
||||||
na.asyncChannel.connect(mContext, mTrackerHandler, na.messenger);
|
na.asyncChannel.connect(mContext, mTrackerHandler, na.messenger);
|
||||||
NetworkInfo networkInfo = na.networkInfo;
|
NetworkInfo networkInfo = na.networkInfo;
|
||||||
na.networkInfo = null;
|
na.networkInfo = null;
|
||||||
@@ -5266,9 +5514,47 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void callCallbackForRequest(NetworkRequest networkRequest,
|
private void callCallbackForRequest(NetworkRequestInfo nri,
|
||||||
NetworkAgentInfo networkAgent, int notificationType) {
|
NetworkAgentInfo networkAgent, int notificationType) {
|
||||||
// TODO
|
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) {
|
private void handleLingerComplete(NetworkAgentInfo oldNetwork) {
|
||||||
@@ -5295,13 +5581,15 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
if (DBG) log("handleConnectionValidated for "+newNetwork.name());
|
if (DBG) log("handleConnectionValidated for "+newNetwork.name());
|
||||||
// check if any NetworkRequest wants this NetworkAgent
|
// check if any NetworkRequest wants this NetworkAgent
|
||||||
// first check if it satisfies the NetworkCapabilities
|
// first check if it satisfies the NetworkCapabilities
|
||||||
for (int i = 0; i < mNetworkRequests.size(); i++) {
|
ArrayList<NetworkAgentInfo> affectedNetworks = new ArrayList<NetworkAgentInfo>();
|
||||||
NetworkRequest nr = mNetworkRequests.valueAt(i);
|
if (VDBG) log(" new Network has: " + newNetwork.networkCapabilities);
|
||||||
if (nr.networkCapabilities.satisfiedByNetworkCapabilities(
|
for (NetworkRequestInfo nri : mNetworkRequests.values()) {
|
||||||
|
if (VDBG) log(" checking if request is satisfied: " + nri.request);
|
||||||
|
if (nri.request.networkCapabilities.satisfiedByNetworkCapabilities(
|
||||||
newNetwork.networkCapabilities)) {
|
newNetwork.networkCapabilities)) {
|
||||||
// next check if it's better than any current network we're using for
|
// next check if it's better than any current network we're using for
|
||||||
// this request
|
// this request
|
||||||
NetworkAgentInfo currentNetwork = mNetworkForRequestId.get(nr.requestId);
|
NetworkAgentInfo currentNetwork = mNetworkForRequestId.get(nri.request.requestId);
|
||||||
if (VDBG) {
|
if (VDBG) {
|
||||||
log("currentScore = " +
|
log("currentScore = " +
|
||||||
(currentNetwork != null ? currentNetwork.currentScore : 0) +
|
(currentNetwork != null ? currentNetwork.currentScore : 0) +
|
||||||
@@ -5310,28 +5598,52 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
if (currentNetwork == null ||
|
if (currentNetwork == null ||
|
||||||
currentNetwork.currentScore < newNetwork.currentScore) {
|
currentNetwork.currentScore < newNetwork.currentScore) {
|
||||||
if (currentNetwork != null) {
|
if (currentNetwork != null) {
|
||||||
currentNetwork.networkRequests.remove(nr.requestId);
|
if (VDBG) log(" accepting network in place of " + currentNetwork.name());
|
||||||
currentNetwork.networkListens.add(nr);
|
currentNetwork.networkRequests.remove(nri.request.requestId);
|
||||||
if (currentNetwork.networkRequests.size() == 0) {
|
currentNetwork.networkLingered.add(nri.request);
|
||||||
currentNetwork.networkMonitor.sendMessage(
|
affectedNetworks.add(currentNetwork);
|
||||||
NetworkMonitor.CMD_NETWORK_LINGER);
|
} else {
|
||||||
notifyNetworkCallbacks(currentNetwork, NetworkCallbacks.LOSING);
|
if (VDBG) log(" accepting network in place of null");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
mNetworkForRequestId.put(nr.requestId, newNetwork);
|
mNetworkForRequestId.put(nri.request.requestId, newNetwork);
|
||||||
newNetwork.networkRequests.put(nr.requestId, nr);
|
newNetwork.networkRequests.put(nri.request.requestId, nri.request);
|
||||||
keep = true;
|
keep = true;
|
||||||
// TODO - this could get expensive if we have alot of requests for this
|
// 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
|
// network. Think about if there is a way to reduce this. Push
|
||||||
// netid->request mapping to each factory?
|
// netid->request mapping to each factory?
|
||||||
sendUpdatedScoreToFactories(nr, newNetwork.currentScore);
|
sendUpdatedScoreToFactories(nri.request, newNetwork.currentScore);
|
||||||
if (mDefaultRequest.requestId == nr.requestId) {
|
if (mDefaultRequest.requestId == nri.request.requestId) {
|
||||||
isNewDefault = true;
|
isNewDefault = true;
|
||||||
updateActiveDefaultNetwork(newNetwork);
|
updateActiveDefaultNetwork(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 (keep) {
|
||||||
if (isNewDefault) {
|
if (isNewDefault) {
|
||||||
if (VDBG) log("Switching to new default network: " + newNetwork);
|
if (VDBG) log("Switching to new default network: " + newNetwork);
|
||||||
@@ -5370,8 +5682,14 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
// TODO
|
// TODO
|
||||||
//BatteryStatsService.getService().noteNetworkInterfaceType(iface, netType);
|
//BatteryStatsService.getService().noteNetworkInterfaceType(iface, netType);
|
||||||
// } catch (RemoteException e) { }
|
// } catch (RemoteException e) { }
|
||||||
notifyNetworkCallbacks(newNetwork, NetworkCallbacks.AVAILABLE);
|
notifyNetworkCallbacks(newNetwork, ConnectivityManager.CALLBACK_AVAILABLE);
|
||||||
} else if (newNetwork.networkRequests.size() == 0) {
|
} 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.");
|
if (VDBG) log("Validated network turns out to be unwanted. Tear it down.");
|
||||||
newNetwork.asyncChannel.disconnect();
|
newNetwork.asyncChannel.disconnect();
|
||||||
}
|
}
|
||||||
@@ -5401,7 +5719,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
loge("Error creating Network " + networkAgent.network.netId);
|
loge("Error creating Network " + networkAgent.network.netId);
|
||||||
}
|
}
|
||||||
updateLinkProperties(networkAgent, null);
|
updateLinkProperties(networkAgent, null);
|
||||||
notifyNetworkCallbacks(networkAgent, NetworkCallbacks.PRECHECK);
|
notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_PRECHECK);
|
||||||
networkAgent.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_CONNECTED);
|
networkAgent.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_CONNECTED);
|
||||||
} else if (state == NetworkInfo.State.DISCONNECTED ||
|
} else if (state == NetworkInfo.State.DISCONNECTED ||
|
||||||
state == NetworkInfo.State.SUSPENDED) {
|
state == NetworkInfo.State.SUSPENDED) {
|
||||||
@@ -5409,24 +5727,37 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
// }
|
||||||
|
if (nri.request.needsBroadcasts) {
|
||||||
|
// TODO
|
||||||
|
// sendNetworkBroadcast(nai, notifyType);
|
||||||
|
}
|
||||||
|
callCallbackForRequest(nri, nai, notifyType);
|
||||||
|
}
|
||||||
|
|
||||||
protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType) {
|
protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType) {
|
||||||
if (VDBG) log("notifyType " + notifyType + " for " + networkAgent.name());
|
if (VDBG) log("notifyType " + notifyType + " for " + networkAgent.name());
|
||||||
boolean needsBroadcasts = false;
|
boolean needsBroadcasts = false;
|
||||||
for (int i = 0; i < networkAgent.networkRequests.size(); i++) {
|
for (int i = 0; i < networkAgent.networkRequests.size(); i++) {
|
||||||
NetworkRequest request = networkAgent.networkRequests.valueAt(i);
|
NetworkRequest nr = networkAgent.networkRequests.valueAt(i);
|
||||||
if (request == null) continue;
|
NetworkRequestInfo nri = mNetworkRequests.get(nr);
|
||||||
if (request.needsBroadcasts) needsBroadcasts = true;
|
if (VDBG) log(" sending notification for " + nr);
|
||||||
callCallbackForRequest(request, networkAgent, notifyType);
|
if (nr.needsBroadcasts) needsBroadcasts = true;
|
||||||
}
|
callCallbackForRequest(nri, networkAgent, notifyType);
|
||||||
for (NetworkRequest request : networkAgent.networkListens) {
|
|
||||||
if (request.needsBroadcasts) needsBroadcasts = true;
|
|
||||||
callCallbackForRequest(request, networkAgent, notifyType);
|
|
||||||
}
|
}
|
||||||
if (needsBroadcasts) {
|
if (needsBroadcasts) {
|
||||||
if (notifyType == NetworkCallbacks.AVAILABLE) {
|
if (notifyType == ConnectivityManager.CALLBACK_AVAILABLE) {
|
||||||
sendConnectedBroadcastDelayed(networkAgent.networkInfo,
|
sendConnectedBroadcastDelayed(networkAgent.networkInfo,
|
||||||
getConnectivityChangeDelay());
|
getConnectivityChangeDelay());
|
||||||
} else if (notifyType == NetworkCallbacks.LOST) {
|
} else if (notifyType == ConnectivityManager.CALLBACK_LOST) {
|
||||||
NetworkInfo info = new NetworkInfo(networkAgent.networkInfo);
|
NetworkInfo info = new NetworkInfo(networkAgent.networkInfo);
|
||||||
Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION);
|
Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION);
|
||||||
intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info);
|
intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info);
|
||||||
@@ -5465,7 +5796,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private LinkProperties getLinkPropertiesForType(int networkType) {
|
private LinkProperties getLinkPropertiesForTypeInternal(int networkType) {
|
||||||
ArrayList<NetworkAgentInfo> list = mNetworkAgentInfoForType[networkType];
|
ArrayList<NetworkAgentInfo> list = mNetworkAgentInfoForType[networkType];
|
||||||
if (list == null) return null;
|
if (list == null) return null;
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -48,9 +48,8 @@ public class NetworkAgentInfo {
|
|||||||
|
|
||||||
// The list of NetworkRequests being satisfied by this Network.
|
// The list of NetworkRequests being satisfied by this Network.
|
||||||
public final SparseArray<NetworkRequest> networkRequests = new SparseArray<NetworkRequest>();
|
public final SparseArray<NetworkRequest> networkRequests = new SparseArray<NetworkRequest>();
|
||||||
|
public final ArrayList<NetworkRequest> networkLingered = new ArrayList<NetworkRequest>();
|
||||||
|
|
||||||
// The list of NetworkListens listening for changes on this Network.
|
|
||||||
public final ArrayList<NetworkRequest> networkListens = new ArrayList<NetworkRequest>();
|
|
||||||
public final Messenger messenger;
|
public final Messenger messenger;
|
||||||
public final AsyncChannel asyncChannel;
|
public final AsyncChannel asyncChannel;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user