Merge "Frameworks/base: Make debug helper lazy in ConnectivityManager" into nyc-dev
diff --git a/core/java/android/net/NetworkInfo.java b/core/java/android/net/NetworkInfo.java
index af7a465..b6c5c6f 100644
--- a/core/java/android/net/NetworkInfo.java
+++ b/core/java/android/net/NetworkInfo.java
@@ -119,12 +119,9 @@
private String mReason;
private String mExtraInfo;
private boolean mIsFailover;
- private boolean mIsRoaming;
-
- /**
- * Indicates whether network connectivity is possible:
- */
private boolean mIsAvailable;
+ private boolean mIsRoaming;
+ private boolean mIsMetered;
/**
* @hide
@@ -139,8 +136,6 @@
mSubtypeName = subtypeName;
setDetailedState(DetailedState.IDLE, null, null);
mState = State.UNKNOWN;
- mIsAvailable = false; // until we're told otherwise, assume unavailable
- mIsRoaming = false;
}
/** {@hide} */
@@ -156,8 +151,9 @@
mReason = source.mReason;
mExtraInfo = source.mExtraInfo;
mIsFailover = source.mIsFailover;
- mIsRoaming = source.mIsRoaming;
mIsAvailable = source.mIsAvailable;
+ mIsRoaming = source.mIsRoaming;
+ mIsMetered = source.mIsMetered;
}
}
}
@@ -330,6 +326,30 @@
}
/**
+ * Returns if this network is metered. A network is classified as metered
+ * when the user is sensitive to heavy data usage on that connection due to
+ * monetary costs, data limitations or battery/performance issues. You
+ * should check this before doing large data transfers, and warn the user or
+ * delay the operation until another network is available.
+ *
+ * @return {@code true} if large transfers should be avoided, otherwise
+ * {@code false}.
+ */
+ public boolean isMetered() {
+ synchronized (this) {
+ return mIsMetered;
+ }
+ }
+
+ /** {@hide} */
+ @VisibleForTesting
+ public void setMetered(boolean isMetered) {
+ synchronized (this) {
+ mIsMetered = isMetered;
+ }
+ }
+
+ /**
* Reports the current coarse-grained state of the network.
* @return the coarse-grained state
*/
@@ -409,26 +429,21 @@
append("], state: ").append(mState).append("/").append(mDetailedState).
append(", reason: ").append(mReason == null ? "(unspecified)" : mReason).
append(", extra: ").append(mExtraInfo == null ? "(none)" : mExtraInfo).
- append(", roaming: ").append(mIsRoaming).
append(", failover: ").append(mIsFailover).
- append(", isAvailable: ").append(mIsAvailable).
+ append(", available: ").append(mIsAvailable).
+ append(", roaming: ").append(mIsRoaming).
+ append(", metered: ").append(mIsMetered).
append("]");
return builder.toString();
}
}
- /**
- * Implement the Parcelable interface
- * @hide
- */
+ @Override
public int describeContents() {
return 0;
}
- /**
- * Implement the Parcelable interface.
- * @hide
- */
+ @Override
public void writeToParcel(Parcel dest, int flags) {
synchronized (this) {
dest.writeInt(mNetworkType);
@@ -440,35 +455,34 @@
dest.writeInt(mIsFailover ? 1 : 0);
dest.writeInt(mIsAvailable ? 1 : 0);
dest.writeInt(mIsRoaming ? 1 : 0);
+ dest.writeInt(mIsMetered ? 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 static final Creator<NetworkInfo> CREATOR = new Creator<NetworkInfo>() {
+ @Override
+ 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.mIsMetered = in.readInt() != 0;
+ netInfo.mReason = in.readString();
+ netInfo.mExtraInfo = in.readString();
+ return netInfo;
+ }
- public NetworkInfo[] newArray(int size) {
- return new NetworkInfo[size];
- }
- };
+ @Override
+ public NetworkInfo[] newArray(int size) {
+ return new NetworkInfo[size];
+ }
+ };
}
diff --git a/core/java/android/net/NetworkState.java b/core/java/android/net/NetworkState.java
index 933287f..95e3802 100644
--- a/core/java/android/net/NetworkState.java
+++ b/core/java/android/net/NetworkState.java
@@ -25,6 +25,7 @@
* @hide
*/
public class NetworkState implements Parcelable {
+ public static final NetworkState EMPTY = new NetworkState(null, null, null, null, null, null);
public final NetworkInfo networkInfo;
public final LinkProperties linkProperties;
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index b069361..f06583b 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -821,37 +821,25 @@
}
private NetworkState getFilteredNetworkState(int networkType, int uid) {
- NetworkInfo info = null;
- LinkProperties lp = null;
- NetworkCapabilities nc = null;
- Network network = null;
- String subscriberId = null;
-
if (mLegacyTypeTracker.isTypeSupported(networkType)) {
- NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
+ final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
+ final NetworkState state;
if (nai != null) {
- synchronized (nai) {
- info = new NetworkInfo(nai.networkInfo);
- lp = new LinkProperties(nai.linkProperties);
- nc = new NetworkCapabilities(nai.networkCapabilities);
- // Network objects are outwardly immutable so there is no point to duplicating.
- // Duplicating also precludes sharing socket factories and connection pools.
- network = nai.network;
- subscriberId = (nai.networkMisc != null) ? nai.networkMisc.subscriberId : null;
- }
- info.setType(networkType);
+ state = nai.getNetworkState();
+ state.networkInfo.setType(networkType);
} else {
- info = new NetworkInfo(networkType, 0, getNetworkTypeName(networkType), "");
+ final NetworkInfo info = new NetworkInfo(networkType, 0,
+ getNetworkTypeName(networkType), "");
info.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null, null);
info.setIsAvailable(true);
- lp = new LinkProperties();
- nc = new NetworkCapabilities();
- network = null;
+ state = new NetworkState(info, new LinkProperties(), new NetworkCapabilities(),
+ null, null, null);
}
- info = getFilteredNetworkInfo(info, lp, uid);
+ filterNetworkStateForUid(state, uid);
+ return state;
+ } else {
+ return NetworkState.EMPTY;
}
-
- return new NetworkState(info, lp, nc, network, subscriberId, null);
}
private NetworkAgentInfo getNetworkAgentInfoForNetwork(Network network) {
@@ -861,7 +849,7 @@
synchronized (mNetworkForNetId) {
return mNetworkForNetId.get(network.netId);
}
- };
+ }
private Network[] getVpnUnderlyingNetworks(int uid) {
if (!mLockdownEnabled) {
@@ -877,12 +865,6 @@
}
private NetworkState getUnfilteredActiveNetworkState(int uid) {
- NetworkInfo info = null;
- LinkProperties lp = null;
- NetworkCapabilities nc = null;
- Network network = null;
- String subscriberId = null;
-
NetworkAgentInfo nai = getDefaultNetwork();
final Network[] networks = getVpnUnderlyingNetworks(uid);
@@ -900,18 +882,10 @@
}
if (nai != null) {
- synchronized (nai) {
- info = new NetworkInfo(nai.networkInfo);
- lp = new LinkProperties(nai.linkProperties);
- nc = new NetworkCapabilities(nai.networkCapabilities);
- // Network objects are outwardly immutable so there is no point to duplicating.
- // Duplicating also precludes sharing socket factories and connection pools.
- network = nai.network;
- subscriberId = (nai.networkMisc != null) ? nai.networkMisc.subscriberId : null;
- }
+ return nai.getNetworkState();
+ } else {
+ return NetworkState.EMPTY;
}
-
- return new NetworkState(info, lp, nc, network, subscriberId, null);
}
/**
@@ -952,21 +926,29 @@
}
/**
- * Return a filtered {@link NetworkInfo}, potentially marked
- * {@link DetailedState#BLOCKED} based on
- * {@link #isNetworkWithLinkPropertiesBlocked}.
+ * Apply any relevant filters to {@link NetworkState} for the given UID. For
+ * example, this may mark the network as {@link DetailedState#BLOCKED} based
+ * on {@link #isNetworkWithLinkPropertiesBlocked}, or
+ * {@link NetworkInfo#isMetered()} based on network policies.
*/
- private NetworkInfo getFilteredNetworkInfo(NetworkInfo info, LinkProperties lp, int uid) {
- if (info != null && isNetworkWithLinkPropertiesBlocked(lp, uid)) {
- // network is blocked; clone and override state
- info = new NetworkInfo(info);
- info.setDetailedState(DetailedState.BLOCKED, null, null);
+ private void filterNetworkStateForUid(NetworkState state, int uid) {
+ if (state == null || state.networkInfo == null || state.linkProperties == null) return;
+
+ if (isNetworkWithLinkPropertiesBlocked(state.linkProperties, uid)) {
+ state.networkInfo.setDetailedState(DetailedState.BLOCKED, null, null);
}
- if (info != null && mLockdownTracker != null) {
- info = mLockdownTracker.augmentNetworkInfo(info);
- if (VDBG) log("returning Locked NetworkInfo");
+ if (mLockdownTracker != null) {
+ mLockdownTracker.augmentNetworkInfo(state.networkInfo);
}
- return info;
+
+ // TODO: apply metered state closer to NetworkAgentInfo
+ final long token = Binder.clearCallingIdentity();
+ try {
+ state.networkInfo.setMetered(mPolicyManager.isNetworkMetered(state));
+ } catch (RemoteException e) {
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
}
/**
@@ -980,10 +962,10 @@
public NetworkInfo getActiveNetworkInfo() {
enforceAccessPermission();
final int uid = Binder.getCallingUid();
- NetworkState state = getUnfilteredActiveNetworkState(uid);
- NetworkInfo ni = getFilteredNetworkInfo(state.networkInfo, state.linkProperties, uid);
- maybeLogBlockedNetworkInfo(ni, uid);
- return ni;
+ final NetworkState state = getUnfilteredActiveNetworkState(uid);
+ filterNetworkStateForUid(state, uid);
+ maybeLogBlockedNetworkInfo(state.networkInfo, uid);
+ return state.networkInfo;
}
@Override
@@ -1027,8 +1009,9 @@
@Override
public NetworkInfo getActiveNetworkInfoForUid(int uid) {
enforceConnectivityInternalPermission();
- NetworkState state = getUnfilteredActiveNetworkState(uid);
- return getFilteredNetworkInfo(state.networkInfo, state.linkProperties, uid);
+ final NetworkState state = getUnfilteredActiveNetworkState(uid);
+ filterNetworkStateForUid(state, uid);
+ return state.networkInfo;
}
@Override
@@ -1039,12 +1022,13 @@
// A VPN is active, so we may need to return one of its underlying networks. This
// information is not available in LegacyTypeTracker, so we have to get it from
// getUnfilteredActiveNetworkState.
- NetworkState state = getUnfilteredActiveNetworkState(uid);
+ final NetworkState state = getUnfilteredActiveNetworkState(uid);
if (state.networkInfo != null && state.networkInfo.getType() == networkType) {
- return getFilteredNetworkInfo(state.networkInfo, state.linkProperties, uid);
+ filterNetworkStateForUid(state, uid);
+ return state.networkInfo;
}
}
- NetworkState state = getFilteredNetworkState(networkType, uid);
+ final NetworkState state = getFilteredNetworkState(networkType, uid);
return state.networkInfo;
}
@@ -1052,15 +1036,14 @@
public NetworkInfo getNetworkInfoForNetwork(Network network) {
enforceAccessPermission();
final int uid = Binder.getCallingUid();
- NetworkInfo info = null;
- NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
+ final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
if (nai != null) {
- synchronized (nai) {
- info = new NetworkInfo(nai.networkInfo);
- info = getFilteredNetworkInfo(info, nai.linkProperties, uid);
- }
+ final NetworkState state = nai.getNetworkState();
+ filterNetworkStateForUid(state, uid);
+ return state.networkInfo;
+ } else {
+ return null;
}
- return info;
}
@Override
@@ -1222,12 +1205,7 @@
for (Network network : getAllNetworks()) {
final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
if (nai != null) {
- synchronized (nai) {
- final String subscriberId = (nai.networkMisc != null)
- ? nai.networkMisc.subscriberId : null;
- result.add(new NetworkState(nai.networkInfo, nai.linkProperties,
- nai.networkCapabilities, network, subscriberId, null));
- }
+ result.add(nai.getNetworkState());
}
}
return result.toArray(new NetworkState[result.size()]);
@@ -1255,24 +1233,9 @@
@Override
public boolean isActiveNetworkMetered() {
enforceAccessPermission();
- final int uid = Binder.getCallingUid();
- final long token = Binder.clearCallingIdentity();
- try {
- return isActiveNetworkMeteredUnchecked(uid);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
- private boolean isActiveNetworkMeteredUnchecked(int uid) {
- final NetworkState state = getUnfilteredActiveNetworkState(uid);
- if (state.networkInfo != null) {
- try {
- return mPolicyManager.isNetworkMetered(state);
- } catch (RemoteException e) {
- }
- }
- return false;
+ final NetworkInfo info = getActiveNetworkInfo();
+ return (info != null) ? info.isMetered() : false;
}
private INetworkManagementEventObserver mDataActivityObserver = new BaseNetworkObserver() {
@@ -1490,7 +1453,8 @@
private Intent makeGeneralIntent(NetworkInfo info, String bcastType) {
if (mLockdownTracker != null) {
- info = mLockdownTracker.augmentNetworkInfo(info);
+ info = new NetworkInfo(info);
+ mLockdownTracker.augmentNetworkInfo(info);
}
Intent intent = new Intent(bcastType);
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index c5d38cb..3201060 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -25,6 +25,7 @@
import android.net.NetworkInfo;
import android.net.NetworkMisc;
import android.net.NetworkRequest;
+import android.net.NetworkState;
import android.os.Handler;
import android.os.Messenger;
import android.util.SparseArray;
@@ -247,6 +248,17 @@
currentScore = newScore;
}
+ public NetworkState getNetworkState() {
+ synchronized (this) {
+ // Network objects are outwardly immutable so there is no point to duplicating.
+ // Duplicating also precludes sharing socket factories and connection pools.
+ final String subscriberId = (networkMisc != null) ? networkMisc.subscriberId : null;
+ return new NetworkState(new NetworkInfo(networkInfo),
+ new LinkProperties(linkProperties),
+ new NetworkCapabilities(networkCapabilities), network, subscriberId, null);
+ }
+ }
+
public String toString() {
return "NetworkAgentInfo{ ni{" + networkInfo + "} " +
"network{" + network + "} nethandle{" + network.getNetworkHandle() + "} " +