auto import from //depot/cupcake/@135843
This commit is contained in:
@@ -1,294 +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.annotation.SdkConstant;
|
|
||||||
import android.annotation.SdkConstant.SdkConstantType;
|
|
||||||
import android.os.RemoteException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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>
|
|
||||||
* </ol>
|
|
||||||
*/
|
|
||||||
public class ConnectivityManager
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* A change in network connectivity has occurred. A 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
|
|
||||||
* reciever 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.
|
|
||||||
*/
|
|
||||||
public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
|
|
||||||
/**
|
|
||||||
* The lookup key for a {@link NetworkInfo} object. Retrieve with
|
|
||||||
* {@link android.content.Intent#getParcelableExtra(String)}.
|
|
||||||
*/
|
|
||||||
public static final String EXTRA_NETWORK_INFO = "networkInfo";
|
|
||||||
/**
|
|
||||||
* 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";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
* false.
|
|
||||||
*/
|
|
||||||
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
|
|
||||||
public static final String ACTION_BACKGROUND_DATA_SETTING_CHANGED =
|
|
||||||
"android.net.conn.BACKGROUND_DATA_SETTING_CHANGED";
|
|
||||||
|
|
||||||
public static final int TYPE_MOBILE = 0;
|
|
||||||
public static final int TYPE_WIFI = 1;
|
|
||||||
|
|
||||||
public static final int DEFAULT_NETWORK_PREFERENCE = TYPE_WIFI;
|
|
||||||
|
|
||||||
private IConnectivityManager mService;
|
|
||||||
|
|
||||||
static public boolean isNetworkTypeValid(int networkType) {
|
|
||||||
return networkType == TYPE_WIFI || networkType == TYPE_MOBILE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNetworkPreference(int preference) {
|
|
||||||
try {
|
|
||||||
mService.setNetworkPreference(preference);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getNetworkPreference() {
|
|
||||||
try {
|
|
||||||
return mService.getNetworkPreference();
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public NetworkInfo getActiveNetworkInfo() {
|
|
||||||
try {
|
|
||||||
return mService.getActiveNetworkInfo();
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public NetworkInfo getNetworkInfo(int networkType) {
|
|
||||||
try {
|
|
||||||
return mService.getNetworkInfo(networkType);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public NetworkInfo[] getAllNetworkInfo() {
|
|
||||||
try {
|
|
||||||
return mService.getAllNetworkInfo();
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** {@hide} */
|
|
||||||
public boolean setRadios(boolean turnOn) {
|
|
||||||
try {
|
|
||||||
return mService.setRadios(turnOn);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** {@hide} */
|
|
||||||
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.
|
|
||||||
* @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.
|
|
||||||
*/
|
|
||||||
public int startUsingNetworkFeature(int networkType, String feature) {
|
|
||||||
try {
|
|
||||||
return mService.startUsingNetworkFeature(networkType, feature);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
* @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.
|
|
||||||
*/
|
|
||||||
public int stopUsingNetworkFeature(int networkType, String feature) {
|
|
||||||
try {
|
|
||||||
return mService.stopUsingNetworkFeature(networkType, feature);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
* @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) {
|
|
||||||
try {
|
|
||||||
return mService.requestRouteToHost(networkType, hostAddress);
|
|
||||||
} 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}.
|
|
||||||
*
|
|
||||||
* @return Whether background data usage is allowed.
|
|
||||||
*/
|
|
||||||
public boolean getBackgroundDataSetting() {
|
|
||||||
try {
|
|
||||||
return mService.getBackgroundDataSetting();
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
// Err on the side of safety
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
public void setBackgroundDataSetting(boolean allowBackgroundData) {
|
|
||||||
try {
|
|
||||||
mService.setBackgroundDataSetting(allowBackgroundData);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Don't allow use of default constructor.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings({"UnusedDeclaration"})
|
|
||||||
private ConnectivityManager() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@hide}
|
|
||||||
*/
|
|
||||||
public ConnectivityManager(IConnectivityManager service) {
|
|
||||||
if (service == null) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"ConnectivityManager() cannot be constructed with null service");
|
|
||||||
}
|
|
||||||
mService = service;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,96 +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();
|
|
||||||
}
|
|
||||||
|
|
||||||
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(addr & 0xff).append('.').
|
|
||||||
append((addr >>>= 8) & 0xff).append('.').
|
|
||||||
append((addr >>>= 8) & 0xff).append('.').
|
|
||||||
append((addr >>>= 8) & 0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 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];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,51 +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.net.NetworkInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface that answers queries about, and allows changing, the
|
|
||||||
* state of network connectivity.
|
|
||||||
*/
|
|
||||||
/** {@hide} */
|
|
||||||
interface IConnectivityManager
|
|
||||||
{
|
|
||||||
void setNetworkPreference(int pref);
|
|
||||||
|
|
||||||
int getNetworkPreference();
|
|
||||||
|
|
||||||
NetworkInfo getActiveNetworkInfo();
|
|
||||||
|
|
||||||
NetworkInfo getNetworkInfo(int networkType);
|
|
||||||
|
|
||||||
NetworkInfo[] getAllNetworkInfo();
|
|
||||||
|
|
||||||
boolean setRadios(boolean onOff);
|
|
||||||
|
|
||||||
boolean setRadio(int networkType, boolean turnOn);
|
|
||||||
|
|
||||||
int startUsingNetworkFeature(int networkType, in String feature);
|
|
||||||
|
|
||||||
int stopUsingNetworkFeature(int networkType, in String feature);
|
|
||||||
|
|
||||||
boolean requestRouteToHost(int networkType, int hostAddress);
|
|
||||||
|
|
||||||
boolean getBackgroundDataSetting();
|
|
||||||
|
|
||||||
void setBackgroundDataSetting(boolean allowBackgroundData);
|
|
||||||
}
|
|
||||||
@@ -1,380 +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 java.util.EnumMap;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the status of a network interface of a given type
|
|
||||||
* (currently either Mobile or Wifi).
|
|
||||||
*/
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
/**
|
|
||||||
* Indicates whether network connectivity is possible:
|
|
||||||
*/
|
|
||||||
private boolean mIsAvailable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO This is going away as soon as API council review happens.
|
|
||||||
* @param type network type
|
|
||||||
*/
|
|
||||||
public NetworkInfo(int type) {}
|
|
||||||
|
|
||||||
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 = true;
|
|
||||||
mIsRoaming = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reports the type of network (currently mobile or Wi-Fi) to which the
|
|
||||||
* info in this object pertains.
|
|
||||||
* @return the network type
|
|
||||||
*/
|
|
||||||
public int getType() {
|
|
||||||
return mNetworkType;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a network-type-specific integer describing the subtype
|
|
||||||
* of the network.
|
|
||||||
* @return the network subtype
|
|
||||||
*
|
|
||||||
* @hide pending API council review
|
|
||||||
*/
|
|
||||||
public int getSubtype() {
|
|
||||||
return mSubtype;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setSubtype(int subtype, String subtypeName) {
|
|
||||||
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() {
|
|
||||||
return mTypeName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a human-readable name describing the subtype of the network.
|
|
||||||
* @return the name of the network subtype
|
|
||||||
*
|
|
||||||
* @hide pending API council review
|
|
||||||
*/
|
|
||||||
public String getSubtypeName() {
|
|
||||||
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() {
|
|
||||||
return mState == State.CONNECTED || mState == State.CONNECTING;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates whether network connectivity exists and it is possible to establish
|
|
||||||
* connections and pass data.
|
|
||||||
* @return {@code true} if network connectivity exists, {@code false} otherwise.
|
|
||||||
*/
|
|
||||||
public boolean isConnected() {
|
|
||||||
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() {
|
|
||||||
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) {
|
|
||||||
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() {
|
|
||||||
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) {
|
|
||||||
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.
|
|
||||||
*
|
|
||||||
* @hide pending API council
|
|
||||||
*/
|
|
||||||
public boolean isRoaming() {
|
|
||||||
return mIsRoaming;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setRoaming(boolean isRoaming) {
|
|
||||||
mIsRoaming = isRoaming;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reports the current coarse-grained state of the network.
|
|
||||||
* @return the coarse-grained state
|
|
||||||
*/
|
|
||||||
public State getState() {
|
|
||||||
return mState;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reports the current fine-grained state of the network.
|
|
||||||
* @return the fine-grained state
|
|
||||||
*/
|
|
||||||
public DetailedState getDetailedState() {
|
|
||||||
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.
|
|
||||||
*/
|
|
||||||
void setDetailedState(DetailedState detailedState, String reason, String extraInfo) {
|
|
||||||
this.mDetailedState = detailedState;
|
|
||||||
this.mState = stateMap.get(detailedState);
|
|
||||||
this.mReason = reason;
|
|
||||||
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() {
|
|
||||||
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() {
|
|
||||||
return mExtraInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
StringBuilder builder = new StringBuilder("NetworkInfo: ");
|
|
||||||
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);
|
|
||||||
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) {
|
|
||||||
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.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.mReason = in.readString();
|
|
||||||
netInfo.mExtraInfo = in.readString();
|
|
||||||
return netInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public NetworkInfo[] newArray(int size) {
|
|
||||||
return new NetworkInfo[size];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,128 +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.UnknownHostException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Native methods for managing network interfaces.
|
|
||||||
*
|
|
||||||
* {@hide}
|
|
||||||
*/
|
|
||||||
public class NetworkUtils {
|
|
||||||
/** Bring the named network interface down. */
|
|
||||||
public native static int disableInterface(String interfaceName);
|
|
||||||
|
|
||||||
/** Add a route to the specified host via the named interface. */
|
|
||||||
public native static int addHostRoute(String interfaceName, int hostaddr);
|
|
||||||
|
|
||||||
/** Add a default route for the named interface. */
|
|
||||||
public native static int setDefaultRoute(String interfaceName, int gwayAddr);
|
|
||||||
|
|
||||||
/** Return the gateway address for the default route for the named interface. */
|
|
||||||
public native static int getDefaultRoute(String interfaceName);
|
|
||||||
|
|
||||||
/** Remove host routes that uses the named interface. */
|
|
||||||
public native static int removeHostRoutes(String interfaceName);
|
|
||||||
|
|
||||||
/** Remove the default route for the named interface. */
|
|
||||||
public native static int removeDefaultRoute(String interfaceName);
|
|
||||||
|
|
||||||
/** Reset any sockets that are connected via the named interface. */
|
|
||||||
public native static int resetConnections(String interfaceName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 ipInfo 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, DhcpInfo ipInfo);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When static IP configuration has been specified, configure the network
|
|
||||||
* interface according to the values supplied.
|
|
||||||
* @param interfaceName the name of the interface to configure
|
|
||||||
* @param ipInfo the IP address, default gateway, and DNS server addresses
|
|
||||||
* with which to configure the interface.
|
|
||||||
* @return {@code true} for success, {@code false} for failure
|
|
||||||
*/
|
|
||||||
public static boolean configureInterface(String interfaceName, DhcpInfo ipInfo) {
|
|
||||||
return configureNative(interfaceName,
|
|
||||||
ipInfo.ipAddress,
|
|
||||||
ipInfo.netmask,
|
|
||||||
ipInfo.gateway,
|
|
||||||
ipInfo.dns1,
|
|
||||||
ipInfo.dns2);
|
|
||||||
}
|
|
||||||
|
|
||||||
private native static boolean configureNative(
|
|
||||||
String interfaceName, int ipAddress, int netmask, int gateway, int dns1, int dns2);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Look up a host name and return the result as an int. Works if the argument
|
|
||||||
* is an IP address in dot notation. Obviously, this can only be used for IPv4
|
|
||||||
* addresses.
|
|
||||||
* @param hostname the name of the host (or the IP address)
|
|
||||||
* @return the IP address as an {@code int} in network byte order
|
|
||||||
*/
|
|
||||||
public static int lookupHost(String hostname) {
|
|
||||||
InetAddress inetAddress;
|
|
||||||
try {
|
|
||||||
inetAddress = InetAddress.getByName(hostname);
|
|
||||||
} catch (UnknownHostException e) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
byte[] addrBytes;
|
|
||||||
int addr;
|
|
||||||
addrBytes = inetAddress.getAddress();
|
|
||||||
addr = ((addrBytes[3] & 0xff) << 24)
|
|
||||||
| ((addrBytes[2] & 0xff) << 16)
|
|
||||||
| ((addrBytes[1] & 0xff) << 8)
|
|
||||||
| (addrBytes[0] & 0xff);
|
|
||||||
return addr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,247 +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 <utils/misc.h>
|
|
||||||
#include <android_runtime/AndroidRuntime.h>
|
|
||||||
#include <utils/Log.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
int ifc_disable(const char *ifname);
|
|
||||||
int ifc_add_host_route(const char *ifname, uint32_t addr);
|
|
||||||
int ifc_remove_host_routes(const char *ifname);
|
|
||||||
int ifc_set_default_route(const char *ifname, uint32_t gateway);
|
|
||||||
int ifc_get_default_route(const char *ifname);
|
|
||||||
int ifc_remove_default_route(const char *ifname);
|
|
||||||
int ifc_reset_connections(const char *ifname);
|
|
||||||
int ifc_configure(const char *ifname, in_addr_t ipaddr, in_addr_t netmask, in_addr_t gateway, in_addr_t dns1, in_addr_t dns2);
|
|
||||||
|
|
||||||
int dhcp_do_request(const char *ifname,
|
|
||||||
in_addr_t *ipaddr,
|
|
||||||
in_addr_t *gateway,
|
|
||||||
in_addr_t *mask,
|
|
||||||
in_addr_t *dns1,
|
|
||||||
in_addr_t *dns2,
|
|
||||||
in_addr_t *server,
|
|
||||||
uint32_t *lease);
|
|
||||||
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 {
|
|
||||||
jclass dhcpInfoClass;
|
|
||||||
jmethodID constructorId;
|
|
||||||
jfieldID ipaddress;
|
|
||||||
jfieldID gateway;
|
|
||||||
jfieldID netmask;
|
|
||||||
jfieldID dns1;
|
|
||||||
jfieldID dns2;
|
|
||||||
jfieldID serverAddress;
|
|
||||||
jfieldID leaseDuration;
|
|
||||||
} dhcpInfoFieldIds;
|
|
||||||
|
|
||||||
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_addHostRoute(JNIEnv* env, jobject clazz, jstring ifname, jint addr)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
|
|
||||||
const char *nameStr = env->GetStringUTFChars(ifname, NULL);
|
|
||||||
result = ::ifc_add_host_route(nameStr, addr);
|
|
||||||
env->ReleaseStringUTFChars(ifname, nameStr);
|
|
||||||
return (jint)result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static jint android_net_utils_removeHostRoutes(JNIEnv* env, jobject clazz, jstring ifname)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
|
|
||||||
const char *nameStr = env->GetStringUTFChars(ifname, NULL);
|
|
||||||
result = ::ifc_remove_host_routes(nameStr);
|
|
||||||
env->ReleaseStringUTFChars(ifname, nameStr);
|
|
||||||
return (jint)result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static jint android_net_utils_setDefaultRoute(JNIEnv* env, jobject clazz, jstring ifname, jint gateway)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
|
|
||||||
const char *nameStr = env->GetStringUTFChars(ifname, NULL);
|
|
||||||
result = ::ifc_set_default_route(nameStr, gateway);
|
|
||||||
env->ReleaseStringUTFChars(ifname, nameStr);
|
|
||||||
return (jint)result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static jint android_net_utils_getDefaultRoute(JNIEnv* env, jobject clazz, jstring ifname)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
|
|
||||||
const char *nameStr = env->GetStringUTFChars(ifname, NULL);
|
|
||||||
result = ::ifc_get_default_route(nameStr);
|
|
||||||
env->ReleaseStringUTFChars(ifname, nameStr);
|
|
||||||
return (jint)result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static jint android_net_utils_removeDefaultRoute(JNIEnv* env, jobject clazz, jstring ifname)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
|
|
||||||
const char *nameStr = env->GetStringUTFChars(ifname, NULL);
|
|
||||||
result = ::ifc_remove_default_route(nameStr);
|
|
||||||
env->ReleaseStringUTFChars(ifname, nameStr);
|
|
||||||
return (jint)result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static jint android_net_utils_resetConnections(JNIEnv* env, jobject clazz, jstring ifname)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
|
|
||||||
const char *nameStr = env->GetStringUTFChars(ifname, NULL);
|
|
||||||
result = ::ifc_reset_connections(nameStr);
|
|
||||||
env->ReleaseStringUTFChars(ifname, nameStr);
|
|
||||||
return (jint)result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static jboolean android_net_utils_runDhcp(JNIEnv* env, jobject clazz, jstring ifname, jobject info)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
in_addr_t ipaddr, gateway, mask, dns1, dns2, server;
|
|
||||||
uint32_t lease;
|
|
||||||
|
|
||||||
const char *nameStr = env->GetStringUTFChars(ifname, NULL);
|
|
||||||
result = ::dhcp_do_request(nameStr, &ipaddr, &gateway, &mask,
|
|
||||||
&dns1, &dns2, &server, &lease);
|
|
||||||
env->ReleaseStringUTFChars(ifname, nameStr);
|
|
||||||
if (result == 0 && dhcpInfoFieldIds.dhcpInfoClass != NULL) {
|
|
||||||
env->SetIntField(info, dhcpInfoFieldIds.ipaddress, ipaddr);
|
|
||||||
env->SetIntField(info, dhcpInfoFieldIds.gateway, gateway);
|
|
||||||
env->SetIntField(info, dhcpInfoFieldIds.netmask, mask);
|
|
||||||
env->SetIntField(info, dhcpInfoFieldIds.dns1, dns1);
|
|
||||||
env->SetIntField(info, dhcpInfoFieldIds.dns2, dns2);
|
|
||||||
env->SetIntField(info, dhcpInfoFieldIds.serverAddress, server);
|
|
||||||
env->SetIntField(info, dhcpInfoFieldIds.leaseDuration, lease);
|
|
||||||
}
|
|
||||||
return (jboolean)(result == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
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 jboolean android_net_utils_configureInterface(JNIEnv* env,
|
|
||||||
jobject clazz,
|
|
||||||
jstring ifname,
|
|
||||||
jint ipaddr,
|
|
||||||
jint mask,
|
|
||||||
jint gateway,
|
|
||||||
jint dns1,
|
|
||||||
jint dns2)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
uint32_t lease;
|
|
||||||
|
|
||||||
const char *nameStr = env->GetStringUTFChars(ifname, NULL);
|
|
||||||
result = ::ifc_configure(nameStr, ipaddr, mask, gateway, dns1, dns2);
|
|
||||||
env->ReleaseStringUTFChars(ifname, nameStr);
|
|
||||||
return (jboolean)(result == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/*
|
|
||||||
* JNI registration.
|
|
||||||
*/
|
|
||||||
static JNINativeMethod gNetworkUtilMethods[] = {
|
|
||||||
/* name, signature, funcPtr */
|
|
||||||
|
|
||||||
{ "disableInterface", "(Ljava/lang/String;)I", (void *)android_net_utils_disableInterface },
|
|
||||||
{ "addHostRoute", "(Ljava/lang/String;I)I", (void *)android_net_utils_addHostRoute },
|
|
||||||
{ "removeHostRoutes", "(Ljava/lang/String;)I", (void *)android_net_utils_removeHostRoutes },
|
|
||||||
{ "setDefaultRoute", "(Ljava/lang/String;I)I", (void *)android_net_utils_setDefaultRoute },
|
|
||||||
{ "getDefaultRoute", "(Ljava/lang/String;)I", (void *)android_net_utils_getDefaultRoute },
|
|
||||||
{ "removeDefaultRoute", "(Ljava/lang/String;)I", (void *)android_net_utils_removeDefaultRoute },
|
|
||||||
{ "resetConnections", "(Ljava/lang/String;)I", (void *)android_net_utils_resetConnections },
|
|
||||||
{ "runDhcp", "(Ljava/lang/String;Landroid/net/DhcpInfo;)Z", (void *)android_net_utils_runDhcp },
|
|
||||||
{ "stopDhcp", "(Ljava/lang/String;)Z", (void *)android_net_utils_stopDhcp },
|
|
||||||
{ "releaseDhcpLease", "(Ljava/lang/String;)Z", (void *)android_net_utils_releaseDhcpLease },
|
|
||||||
{ "configureNative", "(Ljava/lang/String;IIIII)Z", (void *)android_net_utils_configureInterface },
|
|
||||||
{ "getDhcpError", "()Ljava/lang/String;", (void*) android_net_utils_getDhcpError },
|
|
||||||
};
|
|
||||||
|
|
||||||
int register_android_net_NetworkUtils(JNIEnv* env)
|
|
||||||
{
|
|
||||||
jclass netutils = env->FindClass(NETUTILS_PKG_NAME);
|
|
||||||
LOG_FATAL_IF(netutils == NULL, "Unable to find class " NETUTILS_PKG_NAME);
|
|
||||||
|
|
||||||
dhcpInfoFieldIds.dhcpInfoClass = env->FindClass("android/net/DhcpInfo");
|
|
||||||
if (dhcpInfoFieldIds.dhcpInfoClass != NULL) {
|
|
||||||
dhcpInfoFieldIds.constructorId = env->GetMethodID(dhcpInfoFieldIds.dhcpInfoClass, "<init>", "()V");
|
|
||||||
dhcpInfoFieldIds.ipaddress = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "ipAddress", "I");
|
|
||||||
dhcpInfoFieldIds.gateway = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "gateway", "I");
|
|
||||||
dhcpInfoFieldIds.netmask = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "netmask", "I");
|
|
||||||
dhcpInfoFieldIds.dns1 = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "dns1", "I");
|
|
||||||
dhcpInfoFieldIds.dns2 = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "dns2", "I");
|
|
||||||
dhcpInfoFieldIds.serverAddress = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "serverAddress", "I");
|
|
||||||
dhcpInfoFieldIds.leaseDuration = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "leaseDuration", "I");
|
|
||||||
}
|
|
||||||
|
|
||||||
return AndroidRuntime::registerNativeMethods(env,
|
|
||||||
NETUTILS_PKG_NAME, gNetworkUtilMethods, NELEM(gNetworkUtilMethods));
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // namespace android
|
|
||||||
@@ -1,741 +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 android.app.Notification;
|
|
||||||
import android.app.NotificationManager;
|
|
||||||
import android.content.ContentResolver;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.net.ConnectivityManager;
|
|
||||||
import android.net.IConnectivityManager;
|
|
||||||
import android.net.MobileDataStateTracker;
|
|
||||||
import android.net.NetworkInfo;
|
|
||||||
import android.net.NetworkStateTracker;
|
|
||||||
import android.net.wifi.WifiStateTracker;
|
|
||||||
import android.os.Binder;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Looper;
|
|
||||||
import android.os.Message;
|
|
||||||
import android.os.ServiceManager;
|
|
||||||
import android.os.SystemProperties;
|
|
||||||
import android.provider.Settings;
|
|
||||||
import android.provider.Sync;
|
|
||||||
import android.util.EventLog;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.io.FileDescriptor;
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public class ConnectivityService extends IConnectivityManager.Stub {
|
|
||||||
|
|
||||||
private static final boolean DBG = false;
|
|
||||||
private static final String TAG = "ConnectivityService";
|
|
||||||
|
|
||||||
// Event log tags (must be in sync with event-log-tags)
|
|
||||||
private static final int EVENTLOG_CONNECTIVITY_STATE_CHANGED = 50020;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sometimes we want to refer to the individual network state
|
|
||||||
* trackers separately, and sometimes we just want to treat them
|
|
||||||
* abstractly.
|
|
||||||
*/
|
|
||||||
private NetworkStateTracker mNetTrackers[];
|
|
||||||
private WifiStateTracker mWifiStateTracker;
|
|
||||||
private MobileDataStateTracker mMobileDataStateTracker;
|
|
||||||
private WifiWatchdogService mWifiWatchdogService;
|
|
||||||
|
|
||||||
private Context mContext;
|
|
||||||
private int mNetworkPreference;
|
|
||||||
private NetworkStateTracker mActiveNetwork;
|
|
||||||
|
|
||||||
private int mNumDnsEntries;
|
|
||||||
private static int sDnsChangeCounter;
|
|
||||||
|
|
||||||
private boolean mTestMode;
|
|
||||||
private static ConnectivityService sServiceInstance;
|
|
||||||
|
|
||||||
private static class ConnectivityThread extends Thread {
|
|
||||||
private Context mContext;
|
|
||||||
|
|
||||||
private ConnectivityThread(Context context) {
|
|
||||||
super("ConnectivityThread");
|
|
||||||
mContext = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
Looper.prepare();
|
|
||||||
synchronized (this) {
|
|
||||||
sServiceInstance = new ConnectivityService(mContext);
|
|
||||||
notifyAll();
|
|
||||||
}
|
|
||||||
Looper.loop();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ConnectivityService getServiceInstance(Context context) {
|
|
||||||
ConnectivityThread thread = new ConnectivityThread(context);
|
|
||||||
thread.start();
|
|
||||||
|
|
||||||
synchronized (thread) {
|
|
||||||
while (sServiceInstance == null) {
|
|
||||||
try {
|
|
||||||
// Wait until sServiceInstance has been initialized.
|
|
||||||
thread.wait();
|
|
||||||
} catch (InterruptedException ignore) {
|
|
||||||
Log.e(TAG,
|
|
||||||
"Unexpected InterruptedException while waiting for ConnectivityService thread");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sServiceInstance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ConnectivityService getInstance(Context context) {
|
|
||||||
return ConnectivityThread.getServiceInstance(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ConnectivityService(Context context) {
|
|
||||||
if (DBG) Log.v(TAG, "ConnectivityService starting up");
|
|
||||||
mContext = context;
|
|
||||||
mNetTrackers = new NetworkStateTracker[2];
|
|
||||||
Handler handler = new MyHandler();
|
|
||||||
|
|
||||||
mNetworkPreference = getPersistedNetworkPreference();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create the network state trackers for Wi-Fi and mobile
|
|
||||||
* data. Maybe this could be done with a factory class,
|
|
||||||
* but it's not clear that it's worth it, given that
|
|
||||||
* the number of different network types is not going
|
|
||||||
* to change very often.
|
|
||||||
*/
|
|
||||||
if (DBG) Log.v(TAG, "Starting Wifi Service.");
|
|
||||||
mWifiStateTracker = new WifiStateTracker(context, handler);
|
|
||||||
WifiService wifiService = new WifiService(context, mWifiStateTracker);
|
|
||||||
ServiceManager.addService(Context.WIFI_SERVICE, wifiService);
|
|
||||||
mNetTrackers[ConnectivityManager.TYPE_WIFI] = mWifiStateTracker;
|
|
||||||
|
|
||||||
mMobileDataStateTracker = new MobileDataStateTracker(context, handler);
|
|
||||||
mNetTrackers[ConnectivityManager.TYPE_MOBILE] = mMobileDataStateTracker;
|
|
||||||
|
|
||||||
mActiveNetwork = null;
|
|
||||||
mNumDnsEntries = 0;
|
|
||||||
|
|
||||||
mTestMode = SystemProperties.get("cm.test.mode").equals("true")
|
|
||||||
&& SystemProperties.get("ro.build.type").equals("eng");
|
|
||||||
|
|
||||||
for (NetworkStateTracker t : mNetTrackers)
|
|
||||||
t.startMonitoring();
|
|
||||||
|
|
||||||
// Constructing this starts it too
|
|
||||||
mWifiWatchdogService = new WifiWatchdogService(context, mWifiStateTracker);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the preferred network.
|
|
||||||
* @param preference the new preference
|
|
||||||
*/
|
|
||||||
public synchronized void setNetworkPreference(int preference) {
|
|
||||||
enforceChangePermission();
|
|
||||||
if (ConnectivityManager.isNetworkTypeValid(preference)) {
|
|
||||||
if (mNetworkPreference != preference) {
|
|
||||||
persistNetworkPreference(preference);
|
|
||||||
mNetworkPreference = preference;
|
|
||||||
enforcePreference();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getNetworkPreference() {
|
|
||||||
enforceAccessPermission();
|
|
||||||
return mNetworkPreference;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void persistNetworkPreference(int networkPreference) {
|
|
||||||
final ContentResolver cr = mContext.getContentResolver();
|
|
||||||
Settings.Secure.putInt(cr, Settings.Secure.NETWORK_PREFERENCE, networkPreference);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getPersistedNetworkPreference() {
|
|
||||||
final ContentResolver cr = mContext.getContentResolver();
|
|
||||||
|
|
||||||
final int networkPrefSetting = Settings.Secure
|
|
||||||
.getInt(cr, Settings.Secure.NETWORK_PREFERENCE, -1);
|
|
||||||
if (networkPrefSetting != -1) {
|
|
||||||
return networkPrefSetting;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ConnectivityManager.DEFAULT_NETWORK_PREFERENCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Make the state of network connectivity conform to the preference settings.
|
|
||||||
* In this method, we only tear down a non-preferred network. Establishing
|
|
||||||
* a connection to the preferred network is taken care of when we handle
|
|
||||||
* the disconnect event from the non-preferred network
|
|
||||||
* (see {@link #handleDisconnect(NetworkInfo)}).
|
|
||||||
*/
|
|
||||||
private void enforcePreference() {
|
|
||||||
if (mActiveNetwork == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (NetworkStateTracker t : mNetTrackers) {
|
|
||||||
if (t == mActiveNetwork) {
|
|
||||||
int netType = t.getNetworkInfo().getType();
|
|
||||||
int otherNetType = ((netType == ConnectivityManager.TYPE_WIFI) ?
|
|
||||||
ConnectivityManager.TYPE_MOBILE :
|
|
||||||
ConnectivityManager.TYPE_WIFI);
|
|
||||||
|
|
||||||
if (t.getNetworkInfo().getType() != mNetworkPreference) {
|
|
||||||
NetworkStateTracker otherTracker = mNetTrackers[otherNetType];
|
|
||||||
if (otherTracker.isAvailable()) {
|
|
||||||
teardown(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean teardown(NetworkStateTracker netTracker) {
|
|
||||||
if (netTracker.teardown()) {
|
|
||||||
netTracker.setTeardownRequested(true);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
public NetworkInfo getActiveNetworkInfo() {
|
|
||||||
enforceAccessPermission();
|
|
||||||
for (NetworkStateTracker t : mNetTrackers) {
|
|
||||||
NetworkInfo info = t.getNetworkInfo();
|
|
||||||
if (info.isConnected()) {
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public NetworkInfo getNetworkInfo(int networkType) {
|
|
||||||
enforceAccessPermission();
|
|
||||||
if (ConnectivityManager.isNetworkTypeValid(networkType)) {
|
|
||||||
NetworkStateTracker t = mNetTrackers[networkType];
|
|
||||||
if (t != null)
|
|
||||||
return t.getNetworkInfo();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public NetworkInfo[] getAllNetworkInfo() {
|
|
||||||
enforceAccessPermission();
|
|
||||||
NetworkInfo[] result = new NetworkInfo[mNetTrackers.length];
|
|
||||||
int i = 0;
|
|
||||||
for (NetworkStateTracker t : mNetTrackers) {
|
|
||||||
result[i++] = t.getNetworkInfo();
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean setRadios(boolean turnOn) {
|
|
||||||
boolean result = true;
|
|
||||||
enforceChangePermission();
|
|
||||||
for (NetworkStateTracker t : mNetTrackers) {
|
|
||||||
result = t.setRadio(turnOn) && result;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean setRadio(int netType, boolean turnOn) {
|
|
||||||
enforceChangePermission();
|
|
||||||
if (!ConnectivityManager.isNetworkTypeValid(netType)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
NetworkStateTracker tracker = mNetTrackers[netType];
|
|
||||||
return tracker != null && tracker.setRadio(turnOn);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int startUsingNetworkFeature(int networkType, String feature) {
|
|
||||||
enforceChangePermission();
|
|
||||||
if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
NetworkStateTracker tracker = mNetTrackers[networkType];
|
|
||||||
if (tracker != null) {
|
|
||||||
return tracker.startUsingNetworkFeature(feature, getCallingPid(), getCallingUid());
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int stopUsingNetworkFeature(int networkType, String feature) {
|
|
||||||
enforceChangePermission();
|
|
||||||
if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
NetworkStateTracker tracker = mNetTrackers[networkType];
|
|
||||||
if (tracker != null) {
|
|
||||||
return tracker.stopUsingNetworkFeature(feature, getCallingPid(), getCallingUid());
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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) {
|
|
||||||
enforceChangePermission();
|
|
||||||
if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
NetworkStateTracker tracker = mNetTrackers[networkType];
|
|
||||||
/*
|
|
||||||
* If there's only one connected network, and it's the one requested,
|
|
||||||
* then we don't have to do anything - the requested route already
|
|
||||||
* exists. If it's not the requested network, then it's not possible
|
|
||||||
* to establish the requested route. Finally, if there is more than
|
|
||||||
* one connected network, then we must insert an entry in the routing
|
|
||||||
* table.
|
|
||||||
*/
|
|
||||||
if (getNumConnectedNetworks() > 1) {
|
|
||||||
return tracker.requestRouteToHost(hostAddress);
|
|
||||||
} else {
|
|
||||||
return tracker.getNetworkInfo().getType() == networkType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ConnectivityManager#getBackgroundDataSetting()
|
|
||||||
*/
|
|
||||||
public boolean getBackgroundDataSetting() {
|
|
||||||
return Settings.Secure.getInt(mContext.getContentResolver(),
|
|
||||||
Settings.Secure.BACKGROUND_DATA, 1) == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ConnectivityManager#setBackgroundDataSetting(boolean)
|
|
||||||
*/
|
|
||||||
public void setBackgroundDataSetting(boolean allowBackgroundDataUsage) {
|
|
||||||
mContext.enforceCallingOrSelfPermission(
|
|
||||||
android.Manifest.permission.CHANGE_BACKGROUND_DATA_SETTING,
|
|
||||||
"ConnectivityService");
|
|
||||||
|
|
||||||
if (getBackgroundDataSetting() == allowBackgroundDataUsage) return;
|
|
||||||
|
|
||||||
Settings.Secure.putInt(mContext.getContentResolver(),
|
|
||||||
Settings.Secure.BACKGROUND_DATA, allowBackgroundDataUsage ? 1 : 0);
|
|
||||||
|
|
||||||
Intent broadcast = new Intent(
|
|
||||||
ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED);
|
|
||||||
mContext.sendBroadcast(broadcast);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getNumConnectedNetworks() {
|
|
||||||
int numConnectedNets = 0;
|
|
||||||
|
|
||||||
for (NetworkStateTracker nt : mNetTrackers) {
|
|
||||||
if (nt.getNetworkInfo().isConnected() && !nt.isTeardownRequested()) {
|
|
||||||
++numConnectedNets;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return numConnectedNets;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void enforceAccessPermission() {
|
|
||||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
|
|
||||||
"ConnectivityService");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void enforceChangePermission() {
|
|
||||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CHANGE_NETWORK_STATE,
|
|
||||||
"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) {
|
|
||||||
|
|
||||||
if (DBG) Log.v(TAG, "Handle DISCONNECT for " + info.getTypeName());
|
|
||||||
|
|
||||||
mNetTrackers[info.getType()].setTeardownRequested(false);
|
|
||||||
/*
|
|
||||||
* 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 (mActiveNetwork == null || info.getType() != mActiveNetwork.getNetworkInfo().getType())
|
|
||||||
return;
|
|
||||||
|
|
||||||
NetworkStateTracker newNet;
|
|
||||||
if (info.getType() == ConnectivityManager.TYPE_MOBILE) {
|
|
||||||
newNet = mWifiStateTracker;
|
|
||||||
} else /* info().getType() == TYPE_WIFI */ {
|
|
||||||
newNet = mMobileDataStateTracker;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* See if the other network is available to fail over to.
|
|
||||||
* If is not available, we enable it anyway, so that it
|
|
||||||
* will be able to connect when it does become available,
|
|
||||||
* but we report a total loss of connectivity rather than
|
|
||||||
* report that we are attempting to fail over.
|
|
||||||
*/
|
|
||||||
NetworkInfo switchTo = null;
|
|
||||||
if (newNet.isAvailable()) {
|
|
||||||
mActiveNetwork = newNet;
|
|
||||||
switchTo = newNet.getNetworkInfo();
|
|
||||||
switchTo.setFailover(true);
|
|
||||||
if (!switchTo.isConnectedOrConnecting()) {
|
|
||||||
newNet.reconnect();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
newNet.reconnect();
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean otherNetworkConnected = false;
|
|
||||||
Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION);
|
|
||||||
intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info);
|
|
||||||
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 (switchTo != null) {
|
|
||||||
otherNetworkConnected = switchTo.isConnected();
|
|
||||||
if (DBG) {
|
|
||||||
if (otherNetworkConnected) {
|
|
||||||
Log.v(TAG, "Switching to already connected " + switchTo.getTypeName());
|
|
||||||
} else {
|
|
||||||
Log.v(TAG, "Attempting to switch to " + switchTo.getTypeName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO, switchTo);
|
|
||||||
} else {
|
|
||||||
intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
|
|
||||||
}
|
|
||||||
if (DBG) Log.v(TAG, "Sending DISCONNECT bcast for " + info.getTypeName() +
|
|
||||||
(switchTo == null ? "" : " other=" + switchTo.getTypeName()));
|
|
||||||
|
|
||||||
mContext.sendStickyBroadcast(intent);
|
|
||||||
/*
|
|
||||||
* If the failover network is already connected, then immediately send out
|
|
||||||
* a followup broadcast indicating successful failover
|
|
||||||
*/
|
|
||||||
if (switchTo != null && otherNetworkConnected)
|
|
||||||
sendConnectedBroadcast(switchTo);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sendConnectedBroadcast(NetworkInfo info) {
|
|
||||||
Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION);
|
|
||||||
intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info);
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
mContext.sendStickyBroadcast(intent);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when an attempt to fail over to another network has failed.
|
|
||||||
* @param info the {@link NetworkInfo} for the failed network
|
|
||||||
*/
|
|
||||||
private void handleConnectionFailure(NetworkInfo info) {
|
|
||||||
mNetTrackers[info.getType()].setTeardownRequested(false);
|
|
||||||
if (getActiveNetworkInfo() == null) {
|
|
||||||
String reason = info.getReason();
|
|
||||||
String extraInfo = info.getExtraInfo();
|
|
||||||
|
|
||||||
if (DBG) {
|
|
||||||
String reasonText;
|
|
||||||
if (reason == null) {
|
|
||||||
reasonText = ".";
|
|
||||||
} else {
|
|
||||||
reasonText = " (" + reason + ").";
|
|
||||||
}
|
|
||||||
Log.v(TAG, "Attempt to connect to " + info.getTypeName() + " failed" + reasonText);
|
|
||||||
}
|
|
||||||
|
|
||||||
Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION);
|
|
||||||
intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info);
|
|
||||||
intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
|
|
||||||
if (reason != null) {
|
|
||||||
intent.putExtra(ConnectivityManager.EXTRA_REASON, reason);
|
|
||||||
}
|
|
||||||
if (extraInfo != null) {
|
|
||||||
intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, extraInfo);
|
|
||||||
}
|
|
||||||
if (info.isFailover()) {
|
|
||||||
intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
|
|
||||||
info.setFailover(false);
|
|
||||||
}
|
|
||||||
mContext.sendStickyBroadcast(intent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleConnect(NetworkInfo info) {
|
|
||||||
if (DBG) Log.v(TAG, "Handle CONNECT for " + info.getTypeName());
|
|
||||||
|
|
||||||
// snapshot isFailover, because sendConnectedBroadcast() resets it
|
|
||||||
boolean isFailover = info.isFailover();
|
|
||||||
NetworkStateTracker thisNet = mNetTrackers[info.getType()];
|
|
||||||
NetworkStateTracker deadnet = null;
|
|
||||||
NetworkStateTracker otherNet;
|
|
||||||
if (info.getType() == ConnectivityManager.TYPE_MOBILE) {
|
|
||||||
otherNet = mWifiStateTracker;
|
|
||||||
} else /* info().getType() == TYPE_WIFI */ {
|
|
||||||
otherNet = mMobileDataStateTracker;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Check policy to see whether we are connected to a non-preferred
|
|
||||||
* network that now needs to be torn down.
|
|
||||||
*/
|
|
||||||
NetworkInfo wifiInfo = mWifiStateTracker.getNetworkInfo();
|
|
||||||
NetworkInfo mobileInfo = mMobileDataStateTracker.getNetworkInfo();
|
|
||||||
if (wifiInfo.isConnected() && mobileInfo.isConnected()) {
|
|
||||||
if (mNetworkPreference == ConnectivityManager.TYPE_WIFI)
|
|
||||||
deadnet = mMobileDataStateTracker;
|
|
||||||
else
|
|
||||||
deadnet = mWifiStateTracker;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean toredown = false;
|
|
||||||
thisNet.setTeardownRequested(false);
|
|
||||||
if (!mTestMode && deadnet != null) {
|
|
||||||
if (DBG) Log.v(TAG, "Policy requires " +
|
|
||||||
deadnet.getNetworkInfo().getTypeName() + " teardown");
|
|
||||||
toredown = teardown(deadnet);
|
|
||||||
if (DBG && !toredown) {
|
|
||||||
Log.d(TAG, "Network declined teardown request");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Note that if toredown is true, deadnet cannot be null, so there is
|
|
||||||
* no danger of a null pointer exception here..
|
|
||||||
*/
|
|
||||||
if (!toredown || deadnet.getNetworkInfo().getType() != info.getType()) {
|
|
||||||
mActiveNetwork = thisNet;
|
|
||||||
if (DBG) Log.v(TAG, "Sending CONNECT bcast for " + info.getTypeName());
|
|
||||||
thisNet.updateNetworkSettings();
|
|
||||||
sendConnectedBroadcast(info);
|
|
||||||
if (isFailover) {
|
|
||||||
otherNet.releaseWakeLock();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (DBG) Log.v(TAG, "Not broadcasting CONNECT_ACTION to torn down network " +
|
|
||||||
info.getTypeName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleScanResultsAvailable(NetworkInfo info) {
|
|
||||||
int networkType = info.getType();
|
|
||||||
if (networkType != ConnectivityManager.TYPE_WIFI) {
|
|
||||||
if (DBG) Log.v(TAG, "Got ScanResultsAvailable for " + info.getTypeName() + " network."
|
|
||||||
+ " Don't know how to handle.");
|
|
||||||
}
|
|
||||||
|
|
||||||
mNetTrackers[networkType].interpretScanResultsAvailable();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleNotificationChange(boolean visible, int id, Notification notification) {
|
|
||||||
NotificationManager notificationManager = (NotificationManager) mContext
|
|
||||||
.getSystemService(Context.NOTIFICATION_SERVICE);
|
|
||||||
|
|
||||||
if (visible) {
|
|
||||||
notificationManager.notify(id, notification);
|
|
||||||
} else {
|
|
||||||
notificationManager.cancel(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* After any kind of change in the connectivity state of any network,
|
|
||||||
* make sure that anything that depends on the connectivity state of
|
|
||||||
* more than one network is set up correctly. 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.
|
|
||||||
*/
|
|
||||||
private void handleConnectivityChange() {
|
|
||||||
/*
|
|
||||||
* If both mobile and wifi are enabled, add the host routes that
|
|
||||||
* will allow MMS traffic to pass on the mobile network. But
|
|
||||||
* remove the default route for the mobile network, so that there
|
|
||||||
* will be only one default route, to ensure that all traffic
|
|
||||||
* except MMS will travel via Wi-Fi.
|
|
||||||
*/
|
|
||||||
int numConnectedNets = handleConfigurationChange();
|
|
||||||
if (numConnectedNets > 1) {
|
|
||||||
mMobileDataStateTracker.addPrivateRoutes();
|
|
||||||
mMobileDataStateTracker.removeDefaultRoute();
|
|
||||||
} else if (mMobileDataStateTracker.getNetworkInfo().isConnected()) {
|
|
||||||
mMobileDataStateTracker.removePrivateRoutes();
|
|
||||||
mMobileDataStateTracker.restoreDefaultRoute();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int handleConfigurationChange() {
|
|
||||||
/*
|
|
||||||
* Set DNS properties. Always put Wi-Fi entries at the front of
|
|
||||||
* the list if it is active.
|
|
||||||
*/
|
|
||||||
int index = 1;
|
|
||||||
String lastDns = "";
|
|
||||||
int numConnectedNets = 0;
|
|
||||||
int incrValue = ConnectivityManager.TYPE_MOBILE - ConnectivityManager.TYPE_WIFI;
|
|
||||||
int stopValue = ConnectivityManager.TYPE_MOBILE + incrValue;
|
|
||||||
|
|
||||||
for (int netType = ConnectivityManager.TYPE_WIFI; netType != stopValue; netType += incrValue) {
|
|
||||||
NetworkStateTracker nt = mNetTrackers[netType];
|
|
||||||
if (nt.getNetworkInfo().isConnected() && !nt.isTeardownRequested()) {
|
|
||||||
++numConnectedNets;
|
|
||||||
String[] dnsList = nt.getNameServers();
|
|
||||||
for (int i = 0; i < dnsList.length && dnsList[i] != null; i++) {
|
|
||||||
// skip duplicate entries
|
|
||||||
if (!dnsList[i].equals(lastDns)) {
|
|
||||||
SystemProperties.set("net.dns" + index++, dnsList[i]);
|
|
||||||
lastDns = dnsList[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Null out any DNS properties that are no longer used
|
|
||||||
for (int i = index; i <= mNumDnsEntries; i++) {
|
|
||||||
SystemProperties.set("net.dns" + i, "");
|
|
||||||
}
|
|
||||||
mNumDnsEntries = index - 1;
|
|
||||||
// Notify the name resolver library of the change
|
|
||||||
SystemProperties.set("net.dnschange", String.valueOf(sDnsChangeCounter++));
|
|
||||||
return numConnectedNets;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
if (mActiveNetwork == null) {
|
|
||||||
pw.println("No active network");
|
|
||||||
} else {
|
|
||||||
pw.println("Active network: " + mActiveNetwork.getNetworkInfo().getTypeName());
|
|
||||||
}
|
|
||||||
pw.println();
|
|
||||||
for (NetworkStateTracker nst : mNetTrackers) {
|
|
||||||
pw.println(nst.getNetworkInfo());
|
|
||||||
pw.println(nst);
|
|
||||||
pw.println();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class MyHandler extends Handler {
|
|
||||||
@Override
|
|
||||||
public void handleMessage(Message msg) {
|
|
||||||
NetworkInfo info;
|
|
||||||
switch (msg.what) {
|
|
||||||
case NetworkStateTracker.EVENT_STATE_CHANGED:
|
|
||||||
info = (NetworkInfo) msg.obj;
|
|
||||||
if (DBG) Log.v(TAG, "ConnectivityChange for " + info.getTypeName() + ": " +
|
|
||||||
info.getState() + "/" + info.getDetailedState());
|
|
||||||
|
|
||||||
// Connectivity state changed:
|
|
||||||
// [31-13] Reserved for future use
|
|
||||||
// [12-9] Network subtype (for mobile network, as defined by TelephonyManager)
|
|
||||||
// [8-3] Detailed state ordinal (as defined by NetworkInfo.DetailedState)
|
|
||||||
// [2-0] Network type (as defined by ConnectivityManager)
|
|
||||||
int eventLogParam = (info.getType() & 0x7) |
|
|
||||||
((info.getDetailedState().ordinal() & 0x3f) << 3) |
|
|
||||||
(info.getSubtype() << 9);
|
|
||||||
EventLog.writeEvent(EVENTLOG_CONNECTIVITY_STATE_CHANGED, eventLogParam);
|
|
||||||
|
|
||||||
if (info.getDetailedState() == NetworkInfo.DetailedState.FAILED) {
|
|
||||||
handleConnectionFailure(info);
|
|
||||||
} else if (info.getState() == NetworkInfo.State.DISCONNECTED) {
|
|
||||||
handleDisconnect(info);
|
|
||||||
} else if (info.getState() == NetworkInfo.State.SUSPENDED) {
|
|
||||||
// TODO: need to think this over.
|
|
||||||
// the logic here is, handle SUSPENDED the same as DISCONNECTED. The
|
|
||||||
// only difference being we are broadcasting an intent with NetworkInfo
|
|
||||||
// that's suspended. This allows the applications an opportunity to
|
|
||||||
// handle DISCONNECTED and SUSPENDED differently, or not.
|
|
||||||
handleDisconnect(info);
|
|
||||||
} else if (info.getState() == NetworkInfo.State.CONNECTED) {
|
|
||||||
handleConnect(info);
|
|
||||||
}
|
|
||||||
handleConnectivityChange();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NetworkStateTracker.EVENT_SCAN_RESULTS_AVAILABLE:
|
|
||||||
info = (NetworkInfo) msg.obj;
|
|
||||||
handleScanResultsAvailable(info);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NetworkStateTracker.EVENT_NOTIFICATION_CHANGED:
|
|
||||||
handleNotificationChange(msg.arg1 == 1, msg.arg2, (Notification) msg.obj);
|
|
||||||
|
|
||||||
case NetworkStateTracker.EVENT_CONFIGURATION_CHANGED:
|
|
||||||
handleConfigurationChange();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NetworkStateTracker.EVENT_ROAMING_CHANGED:
|
|
||||||
// fill me in
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NetworkStateTracker.EVENT_NETWORK_SUBTYPE_CHANGED:
|
|
||||||
// fill me in
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user