Merge changes from topic "ms65-identity" am: 3e389629aa am: af3d521d82 am: 2e39612bb2
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1954383 Change-Id: I8a713c284969ac77d45d210746ae17475172e663
This commit is contained in:
@@ -19,8 +19,10 @@ package android.net;
|
|||||||
import static android.net.ConnectivityManager.TYPE_WIFI;
|
import static android.net.ConnectivityManager.TYPE_WIFI;
|
||||||
import static android.net.NetworkTemplate.NETWORK_TYPE_ALL;
|
import static android.net.NetworkTemplate.NETWORK_TYPE_ALL;
|
||||||
|
|
||||||
|
import android.annotation.IntDef;
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.wifi.WifiInfo;
|
import android.net.wifi.WifiInfo;
|
||||||
import android.service.NetworkIdentityProto;
|
import android.service.NetworkIdentityProto;
|
||||||
@@ -31,6 +33,8 @@ import android.util.proto.ProtoOutputStream;
|
|||||||
import com.android.net.module.util.NetworkCapabilitiesUtils;
|
import com.android.net.module.util.NetworkCapabilitiesUtils;
|
||||||
import com.android.net.module.util.NetworkIdentityUtils;
|
import com.android.net.module.util.NetworkIdentityUtils;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@@ -49,6 +53,15 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> {
|
|||||||
// {@link NetworkTemplate#NETWORK_TYPE_ALL} instead.
|
// {@link NetworkTemplate#NETWORK_TYPE_ALL} instead.
|
||||||
public static final int SUBTYPE_COMBINED = -1;
|
public static final int SUBTYPE_COMBINED = -1;
|
||||||
|
|
||||||
|
/** @hide */
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
@IntDef(prefix = { "OEM_MANAGED_" }, value = {
|
||||||
|
NetworkTemplate.OEM_MANAGED_NO,
|
||||||
|
NetworkTemplate.OEM_MANAGED_PAID,
|
||||||
|
NetworkTemplate.OEM_MANAGED_PRIVATE
|
||||||
|
})
|
||||||
|
public @interface OemManaged{}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Network has no {@code NetworkCapabilities#NET_CAPABILITY_OEM_*}.
|
* Network has no {@code NetworkCapabilities#NET_CAPABILITY_OEM_*}.
|
||||||
* @hide
|
* @hide
|
||||||
@@ -177,42 +190,62 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> {
|
|||||||
proto.end(start);
|
proto.end(start);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hide */
|
/** Get the network type of this instance. */
|
||||||
public int getType() {
|
public int getType() {
|
||||||
return mType;
|
return mType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hide */
|
/** Get the Radio Access Technology(RAT) type of this instance. */
|
||||||
public int getRatType() {
|
public int getRatType() {
|
||||||
return mRatType;
|
return mRatType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hide */
|
/** Get the Subscriber Id of this instance. */
|
||||||
|
@Nullable
|
||||||
public String getSubscriberId() {
|
public String getSubscriberId() {
|
||||||
return mSubscriberId;
|
return mSubscriberId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hide */
|
/** Get the Wifi Network Key of this instance. See {@link WifiInfo#getCurrentNetworkKey()}. */
|
||||||
|
@Nullable
|
||||||
public String getWifiNetworkKey() {
|
public String getWifiNetworkKey() {
|
||||||
return mWifiNetworkKey;
|
return mWifiNetworkKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
|
// TODO: Remove this function after all callers are removed.
|
||||||
public boolean getRoaming() {
|
public boolean getRoaming() {
|
||||||
return mRoaming;
|
return mRoaming;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Return the roaming status of this instance. */
|
||||||
|
public boolean isRoaming() {
|
||||||
|
return mRoaming;
|
||||||
|
}
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
|
// TODO: Remove this function after all callers are removed.
|
||||||
public boolean getMetered() {
|
public boolean getMetered() {
|
||||||
return mMetered;
|
return mMetered;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Return the meteredness of this instance. */
|
||||||
|
public boolean isMetered() {
|
||||||
|
return mMetered;
|
||||||
|
}
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
|
// TODO: Remove this function after all callers are removed.
|
||||||
public boolean getDefaultNetwork() {
|
public boolean getDefaultNetwork() {
|
||||||
return mDefaultNetwork;
|
return mDefaultNetwork;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hide */
|
/** Return the default network status of this instance. */
|
||||||
|
public boolean isDefaultNetwork() {
|
||||||
|
return mDefaultNetwork;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get the OEM managed type of this instance. */
|
||||||
public int getOemManaged() {
|
public int getOemManaged() {
|
||||||
return mOemManaged;
|
return mOemManaged;
|
||||||
}
|
}
|
||||||
@@ -229,36 +262,16 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> {
|
|||||||
* {@link TelephonyManager#NETWORK_TYPE_UNKNOWN} if not applicable.
|
* {@link TelephonyManager#NETWORK_TYPE_UNKNOWN} if not applicable.
|
||||||
* See {@code TelephonyManager.NETWORK_TYPE_*}.
|
* See {@code TelephonyManager.NETWORK_TYPE_*}.
|
||||||
* @hide
|
* @hide
|
||||||
|
* @deprecated See {@link NetworkIdentity#Builder}.
|
||||||
*/
|
*/
|
||||||
// TODO: Remove this after all callers are migrated to use new Api.
|
// TODO: Remove this after all callers are migrated to use new Api.
|
||||||
|
@Deprecated
|
||||||
@NonNull
|
@NonNull
|
||||||
public static NetworkIdentity buildNetworkIdentity(Context context,
|
public static NetworkIdentity buildNetworkIdentity(Context context,
|
||||||
@NonNull NetworkStateSnapshot snapshot,
|
@NonNull NetworkStateSnapshot snapshot,
|
||||||
boolean defaultNetwork, @Annotation.NetworkType int ratType) {
|
boolean defaultNetwork, @Annotation.NetworkType int ratType) {
|
||||||
final int legacyType = snapshot.getLegacyType();
|
return new NetworkIdentity.Builder().setNetworkStateSnapshot(snapshot)
|
||||||
|
.setDefaultNetwork(defaultNetwork).setRatType(ratType).build();
|
||||||
final String subscriberId = snapshot.getSubscriberId();
|
|
||||||
String wifiNetworkKey = null;
|
|
||||||
boolean roaming = !snapshot.getNetworkCapabilities().hasCapability(
|
|
||||||
NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
|
|
||||||
boolean metered = !(snapshot.getNetworkCapabilities().hasCapability(
|
|
||||||
NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
|
|
||||||
|| snapshot.getNetworkCapabilities().hasCapability(
|
|
||||||
NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED));
|
|
||||||
|
|
||||||
final int oemManaged = getOemBitfield(snapshot.getNetworkCapabilities());
|
|
||||||
|
|
||||||
if (legacyType == TYPE_WIFI) {
|
|
||||||
final TransportInfo transportInfo = snapshot.getNetworkCapabilities()
|
|
||||||
.getTransportInfo();
|
|
||||||
if (transportInfo instanceof WifiInfo) {
|
|
||||||
final WifiInfo info = (WifiInfo) transportInfo;
|
|
||||||
wifiNetworkKey = info != null ? info.getCurrentNetworkKey() : null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new NetworkIdentity(legacyType, ratType, subscriberId, wifiNetworkKey, roaming,
|
|
||||||
metered, defaultNetwork, oemManaged);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -305,4 +318,192 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> {
|
|||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builder class for {@link NetworkIdentity}.
|
||||||
|
*/
|
||||||
|
public static final class Builder {
|
||||||
|
private int mType;
|
||||||
|
private int mRatType;
|
||||||
|
private String mSubscriberId;
|
||||||
|
private String mWifiNetworkKey;
|
||||||
|
private boolean mRoaming;
|
||||||
|
private boolean mMetered;
|
||||||
|
private boolean mDefaultNetwork;
|
||||||
|
private int mOemManaged;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new Builder.
|
||||||
|
*/
|
||||||
|
public Builder() {
|
||||||
|
// Initialize with default values. Will be overwritten by setters.
|
||||||
|
mType = ConnectivityManager.TYPE_NONE;
|
||||||
|
mRatType = NetworkTemplate.NETWORK_TYPE_ALL;
|
||||||
|
mSubscriberId = null;
|
||||||
|
mWifiNetworkKey = null;
|
||||||
|
mRoaming = false;
|
||||||
|
mMetered = false;
|
||||||
|
mDefaultNetwork = false;
|
||||||
|
mOemManaged = NetworkTemplate.OEM_MANAGED_NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an {@link NetworkStateSnapshot} into the {@link NetworkIdentity} instance.
|
||||||
|
* This is to read roaming, metered, wifikey... from the snapshot for convenience.
|
||||||
|
*
|
||||||
|
* @param snapshot The target {@link NetworkStateSnapshot} object.
|
||||||
|
* @return The builder object.
|
||||||
|
*/
|
||||||
|
@SuppressLint("MissingGetterMatchingBuilder")
|
||||||
|
@NonNull
|
||||||
|
public Builder setNetworkStateSnapshot(@NonNull NetworkStateSnapshot snapshot) {
|
||||||
|
setType(snapshot.getLegacyType());
|
||||||
|
|
||||||
|
setSubscriberId(snapshot.getSubscriberId());
|
||||||
|
setRoaming(!snapshot.getNetworkCapabilities().hasCapability(
|
||||||
|
NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING));
|
||||||
|
setMetered(!(snapshot.getNetworkCapabilities().hasCapability(
|
||||||
|
NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
|
||||||
|
|| snapshot.getNetworkCapabilities().hasCapability(
|
||||||
|
NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED)));
|
||||||
|
|
||||||
|
setOemManaged(getOemBitfield(snapshot.getNetworkCapabilities()));
|
||||||
|
|
||||||
|
if (mType == TYPE_WIFI) {
|
||||||
|
final TransportInfo transportInfo = snapshot.getNetworkCapabilities()
|
||||||
|
.getTransportInfo();
|
||||||
|
if (transportInfo instanceof WifiInfo) {
|
||||||
|
final WifiInfo info = (WifiInfo) transportInfo;
|
||||||
|
if (info != null) {
|
||||||
|
setWifiNetworkKey(info.getCurrentNetworkKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the network type of the network.
|
||||||
|
*
|
||||||
|
* @param type the network type. See {@link ConnectivityManager#TYPE_*}.
|
||||||
|
*
|
||||||
|
* @return this builder.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public Builder setType(int type) {
|
||||||
|
mType = type;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the Radio Access Technology(RAT) type of the network.
|
||||||
|
*
|
||||||
|
* @param ratType the Radio Access Technology(RAT) type if applicable. See
|
||||||
|
* {@code TelephonyManager.NETWORK_TYPE_*}.
|
||||||
|
*
|
||||||
|
* @return this builder.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public Builder setRatType(@Annotation.NetworkType int ratType) {
|
||||||
|
mRatType = ratType;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the Radio Access Technology(RAT) type of the network.
|
||||||
|
*
|
||||||
|
* @return this builder.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public Builder clearRatType() {
|
||||||
|
mRatType = NetworkTemplate.NETWORK_TYPE_ALL;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the Subscriber Id.
|
||||||
|
*
|
||||||
|
* @param subscriberId the Subscriber Id of the network. Or null if not applicable.
|
||||||
|
* @return this builder.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public Builder setSubscriberId(@Nullable String subscriberId) {
|
||||||
|
mSubscriberId = subscriberId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the Wifi Network Key.
|
||||||
|
*
|
||||||
|
* @param wifiNetworkKey Wifi Network Key of the network,
|
||||||
|
* see {@link WifiInfo#getCurrentNetworkKey()}.
|
||||||
|
* Or null if not applicable.
|
||||||
|
* @return this builder.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public Builder setWifiNetworkKey(@Nullable String wifiNetworkKey) {
|
||||||
|
mWifiNetworkKey = wifiNetworkKey;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the roaming.
|
||||||
|
*
|
||||||
|
* @param roaming the roaming status of the network.
|
||||||
|
* @return this builder.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public Builder setRoaming(boolean roaming) {
|
||||||
|
mRoaming = roaming;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the meteredness.
|
||||||
|
*
|
||||||
|
* @param metered the meteredness of the network.
|
||||||
|
* @return this builder.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public Builder setMetered(boolean metered) {
|
||||||
|
mMetered = metered;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the default network status.
|
||||||
|
*
|
||||||
|
* @param defaultNetwork the default network status of the network.
|
||||||
|
* @return this builder.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public Builder setDefaultNetwork(boolean defaultNetwork) {
|
||||||
|
mDefaultNetwork = defaultNetwork;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the OEM managed type.
|
||||||
|
*
|
||||||
|
* @param oemManaged Type of OEM managed network or unmanaged networks.
|
||||||
|
* See {@code NetworkTemplate#OEM_MANAGED_*}.
|
||||||
|
* @return this builder.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public Builder setOemManaged(@OemManaged int oemManaged) {
|
||||||
|
mOemManaged = oemManaged;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the instance of the {@link NetworkIdentity}.
|
||||||
|
*
|
||||||
|
* @return the built instance of {@link NetworkIdentity}.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public NetworkIdentity build() {
|
||||||
|
return new NetworkIdentity(mType, mRatType, mSubscriberId, mWifiNetworkKey,
|
||||||
|
mRoaming, mMetered, mDefaultNetwork, mOemManaged);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,9 +116,9 @@ public class NetworkIdentitySet extends HashSet<NetworkIdentity> implements
|
|||||||
out.writeInt(ident.getRatType());
|
out.writeInt(ident.getRatType());
|
||||||
writeOptionalString(out, ident.getSubscriberId());
|
writeOptionalString(out, ident.getSubscriberId());
|
||||||
writeOptionalString(out, ident.getWifiNetworkKey());
|
writeOptionalString(out, ident.getWifiNetworkKey());
|
||||||
out.writeBoolean(ident.getRoaming());
|
out.writeBoolean(ident.isRoaming());
|
||||||
out.writeBoolean(ident.getMetered());
|
out.writeBoolean(ident.isMetered());
|
||||||
out.writeBoolean(ident.getDefaultNetwork());
|
out.writeBoolean(ident.isDefaultNetwork());
|
||||||
out.writeInt(ident.getOemManaged());
|
out.writeInt(ident.getOemManaged());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -132,7 +132,7 @@ public class NetworkIdentitySet extends HashSet<NetworkIdentity> implements
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (NetworkIdentity ident : this) {
|
for (NetworkIdentity ident : this) {
|
||||||
if (ident.getMetered()) {
|
if (ident.isMetered()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -148,7 +148,7 @@ public class NetworkIdentitySet extends HashSet<NetworkIdentity> implements
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (NetworkIdentity ident : this) {
|
for (NetworkIdentity ident : this) {
|
||||||
if (ident.getRoaming()) {
|
if (ident.isRoaming()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -165,7 +165,7 @@ public class NetworkIdentitySet extends HashSet<NetworkIdentity> implements
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
for (NetworkIdentity ident : this) {
|
for (NetworkIdentity ident : this) {
|
||||||
if (!ident.getDefaultNetwork()) {
|
if (!ident.isDefaultNetwork()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1402,12 +1402,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
// VT is considered always metered in framework's layer. If VT is not metered
|
// VT is considered always metered in framework's layer. If VT is not metered
|
||||||
// per carrier's policy, modem will report 0 usage for VT calls.
|
// per carrier's policy, modem will report 0 usage for VT calls.
|
||||||
if (snapshot.getNetworkCapabilities().hasCapability(
|
if (snapshot.getNetworkCapabilities().hasCapability(
|
||||||
NetworkCapabilities.NET_CAPABILITY_IMS) && !ident.getMetered()) {
|
NetworkCapabilities.NET_CAPABILITY_IMS) && !ident.isMetered()) {
|
||||||
|
|
||||||
// Copy the identify from IMS one but mark it as metered.
|
// Copy the identify from IMS one but mark it as metered.
|
||||||
NetworkIdentity vtIdent = new NetworkIdentity(ident.getType(),
|
NetworkIdentity vtIdent = new NetworkIdentity(ident.getType(),
|
||||||
ident.getRatType(), ident.getSubscriberId(), ident.getWifiNetworkKey(),
|
ident.getRatType(), ident.getSubscriberId(), ident.getWifiNetworkKey(),
|
||||||
ident.getRoaming(), true /* metered */,
|
ident.isRoaming(), true /* metered */,
|
||||||
true /* onDefaultNetwork */, ident.getOemManaged());
|
true /* onDefaultNetwork */, ident.getOemManaged());
|
||||||
final String ifaceVt = IFACE_VT + getSubIdForMobile(snapshot);
|
final String ifaceVt = IFACE_VT + getSubIdForMobile(snapshot);
|
||||||
findOrCreateNetworkIdentitySet(mActiveIfaces, ifaceVt).add(vtIdent);
|
findOrCreateNetworkIdentitySet(mActiveIfaces, ifaceVt).add(vtIdent);
|
||||||
|
|||||||
@@ -16,23 +16,16 @@
|
|||||||
|
|
||||||
package com.android.settingslib.net;
|
package com.android.settingslib.net;
|
||||||
|
|
||||||
import static android.net.NetworkStatsHistory.FIELD_RX_BYTES;
|
import android.annotation.NonNull;
|
||||||
import static android.net.NetworkStatsHistory.FIELD_TX_BYTES;
|
|
||||||
|
|
||||||
import android.app.usage.NetworkStats;
|
import android.app.usage.NetworkStats;
|
||||||
import android.app.usage.NetworkStatsManager;
|
import android.app.usage.NetworkStatsManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.INetworkStatsService;
|
|
||||||
import android.net.INetworkStatsSession;
|
|
||||||
import android.net.NetworkPolicy;
|
import android.net.NetworkPolicy;
|
||||||
import android.net.NetworkPolicyManager;
|
import android.net.NetworkPolicyManager;
|
||||||
import android.net.NetworkStatsHistory;
|
|
||||||
import android.net.NetworkTemplate;
|
import android.net.NetworkTemplate;
|
||||||
import android.net.TrafficStats;
|
|
||||||
import android.os.RemoteException;
|
|
||||||
import android.os.ServiceManager;
|
|
||||||
import android.text.format.DateUtils;
|
import android.text.format.DateUtils;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
|
import android.util.Range;
|
||||||
|
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
import androidx.loader.content.AsyncTaskLoader;
|
import androidx.loader.content.AsyncTaskLoader;
|
||||||
@@ -52,8 +45,6 @@ public abstract class NetworkCycleDataLoader<D> extends AsyncTaskLoader<D> {
|
|||||||
protected final NetworkTemplate mNetworkTemplate;
|
protected final NetworkTemplate mNetworkTemplate;
|
||||||
private final NetworkPolicy mPolicy;
|
private final NetworkPolicy mPolicy;
|
||||||
private final ArrayList<Long> mCycles;
|
private final ArrayList<Long> mCycles;
|
||||||
@VisibleForTesting
|
|
||||||
final INetworkStatsService mNetworkStatsService;
|
|
||||||
|
|
||||||
protected NetworkCycleDataLoader(Builder<?> builder) {
|
protected NetworkCycleDataLoader(Builder<?> builder) {
|
||||||
super(builder.mContext);
|
super(builder.mContext);
|
||||||
@@ -61,8 +52,6 @@ public abstract class NetworkCycleDataLoader<D> extends AsyncTaskLoader<D> {
|
|||||||
mCycles = builder.mCycles;
|
mCycles = builder.mCycles;
|
||||||
mNetworkStatsManager = (NetworkStatsManager)
|
mNetworkStatsManager = (NetworkStatsManager)
|
||||||
builder.mContext.getSystemService(Context.NETWORK_STATS_SERVICE);
|
builder.mContext.getSystemService(Context.NETWORK_STATS_SERVICE);
|
||||||
mNetworkStatsService = INetworkStatsService.Stub.asInterface(
|
|
||||||
ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
|
|
||||||
final NetworkPolicyEditor policyEditor =
|
final NetworkPolicyEditor policyEditor =
|
||||||
new NetworkPolicyEditor(NetworkPolicyManager.from(builder.mContext));
|
new NetworkPolicyEditor(NetworkPolicyManager.from(builder.mContext));
|
||||||
policyEditor.read();
|
policyEditor.read();
|
||||||
@@ -112,23 +101,20 @@ public abstract class NetworkCycleDataLoader<D> extends AsyncTaskLoader<D> {
|
|||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void loadFourWeeksData() {
|
void loadFourWeeksData() {
|
||||||
|
if (mNetworkTemplate == null) return;
|
||||||
|
final NetworkStats stats = mNetworkStatsManager.queryDetailsForDevice(
|
||||||
|
mNetworkTemplate, Long.MIN_VALUE, Long.MAX_VALUE);
|
||||||
try {
|
try {
|
||||||
final INetworkStatsSession networkSession = mNetworkStatsService.openSession();
|
final Range<Long> historyTimeRange = getTimeRangeOf(stats);
|
||||||
final NetworkStatsHistory networkHistory = networkSession.getHistoryForNetwork(
|
|
||||||
mNetworkTemplate, FIELD_RX_BYTES | FIELD_TX_BYTES);
|
|
||||||
final long historyStart = networkHistory.getStart();
|
|
||||||
final long historyEnd = networkHistory.getEnd();
|
|
||||||
|
|
||||||
long cycleEnd = historyEnd;
|
long cycleEnd = historyTimeRange.getUpper();
|
||||||
while (cycleEnd > historyStart) {
|
while (cycleEnd > historyTimeRange.getLower()) {
|
||||||
final long cycleStart = cycleEnd - (DateUtils.WEEK_IN_MILLIS * 4);
|
final long cycleStart = cycleEnd - (DateUtils.WEEK_IN_MILLIS * 4);
|
||||||
recordUsage(cycleStart, cycleEnd);
|
recordUsage(cycleStart, cycleEnd);
|
||||||
cycleEnd = cycleStart;
|
cycleEnd = cycleStart;
|
||||||
}
|
}
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
TrafficStats.closeQuietly(networkSession);
|
// Empty history, ignore.
|
||||||
} catch (RemoteException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,6 +155,32 @@ public abstract class NetworkCycleDataLoader<D> extends AsyncTaskLoader<D> {
|
|||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@VisibleForTesting
|
||||||
|
Range getTimeRangeOf(@NonNull NetworkStats stats) {
|
||||||
|
long start = Long.MAX_VALUE;
|
||||||
|
long end = Long.MIN_VALUE;
|
||||||
|
while (hasNextBucket(stats)) {
|
||||||
|
final NetworkStats.Bucket bucket = getNextBucket(stats);
|
||||||
|
start = Math.min(start, bucket.getStartTimeStamp());
|
||||||
|
end = Math.max(end, bucket.getEndTimeStamp());
|
||||||
|
}
|
||||||
|
return new Range(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
boolean hasNextBucket(@NonNull NetworkStats stats) {
|
||||||
|
return stats.hasNextBucket();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@VisibleForTesting
|
||||||
|
NetworkStats.Bucket getNextBucket(@NonNull NetworkStats stats) {
|
||||||
|
NetworkStats.Bucket bucket = new NetworkStats.Bucket();
|
||||||
|
stats.getNextBucket(bucket);
|
||||||
|
return bucket;
|
||||||
|
}
|
||||||
|
|
||||||
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
|
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
|
||||||
public ArrayList<Long> getCycles() {
|
public ArrayList<Long> getCycles() {
|
||||||
return mCycles;
|
return mCycles;
|
||||||
|
|||||||
@@ -16,24 +16,24 @@
|
|||||||
|
|
||||||
package com.android.settingslib.net;
|
package com.android.settingslib.net;
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static android.app.usage.NetworkStats.Bucket.UID_ALL;
|
||||||
import static org.mockito.ArgumentMatchers.nullable;
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertThrows;
|
||||||
import static org.mockito.Mockito.doNothing;
|
import static org.mockito.Mockito.doNothing;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import android.annotation.NonNull;
|
||||||
|
import android.app.usage.NetworkStats;
|
||||||
import android.app.usage.NetworkStatsManager;
|
import android.app.usage.NetworkStatsManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.INetworkStatsService;
|
|
||||||
import android.net.INetworkStatsSession;
|
|
||||||
import android.net.NetworkPolicy;
|
import android.net.NetworkPolicy;
|
||||||
import android.net.NetworkPolicyManager;
|
import android.net.NetworkPolicyManager;
|
||||||
import android.net.NetworkStatsHistory;
|
|
||||||
import android.net.NetworkTemplate;
|
import android.net.NetworkTemplate;
|
||||||
import android.os.RemoteException;
|
|
||||||
import android.text.format.DateUtils;
|
import android.text.format.DateUtils;
|
||||||
import android.util.Range;
|
import android.util.Range;
|
||||||
|
|
||||||
@@ -49,6 +49,8 @@ import java.time.ZonedDateTime;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Queue;
|
||||||
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
public class NetworkCycleDataLoaderTest {
|
public class NetworkCycleDataLoaderTest {
|
||||||
@@ -63,8 +65,6 @@ public class NetworkCycleDataLoaderTest {
|
|||||||
private NetworkPolicy mPolicy;
|
private NetworkPolicy mPolicy;
|
||||||
@Mock
|
@Mock
|
||||||
private Iterator<Range<ZonedDateTime>> mIterator;
|
private Iterator<Range<ZonedDateTime>> mIterator;
|
||||||
@Mock
|
|
||||||
private INetworkStatsService mNetworkStatsService;
|
|
||||||
|
|
||||||
private NetworkCycleDataTestLoader mLoader;
|
private NetworkCycleDataTestLoader mLoader;
|
||||||
|
|
||||||
@@ -132,20 +132,24 @@ public class NetworkCycleDataLoaderTest {
|
|||||||
verify(mLoader).recordUsage(nowInMs, nowInMs);
|
verify(mLoader).recordUsage(nowInMs, nowInMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private NetworkStats.Bucket makeMockBucket(int uid, long rxBytes, long txBytes,
|
||||||
|
long start, long end) {
|
||||||
|
NetworkStats.Bucket ret = mock(NetworkStats.Bucket.class);
|
||||||
|
when(ret.getUid()).thenReturn(uid);
|
||||||
|
when(ret.getRxBytes()).thenReturn(rxBytes);
|
||||||
|
when(ret.getTxBytes()).thenReturn(txBytes);
|
||||||
|
when(ret.getStartTimeStamp()).thenReturn(start);
|
||||||
|
when(ret.getEndTimeStamp()).thenReturn(end);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void loadFourWeeksData_shouldRecordUsageForLast4Weeks() throws RemoteException {
|
public void loadFourWeeksData_shouldRecordUsageForLast4Weeks() {
|
||||||
mLoader = spy(new NetworkCycleDataTestLoader(mContext));
|
mLoader = spy(new NetworkCycleDataTestLoader(mContext));
|
||||||
ReflectionHelpers.setField(mLoader, "mNetworkStatsService", mNetworkStatsService);
|
|
||||||
final INetworkStatsSession networkSession = mock(INetworkStatsSession.class);
|
|
||||||
when(mNetworkStatsService.openSession()).thenReturn(networkSession);
|
|
||||||
final NetworkStatsHistory networkHistory = mock(NetworkStatsHistory.class);
|
|
||||||
when(networkSession.getHistoryForNetwork(nullable(NetworkTemplate.class), anyInt()))
|
|
||||||
.thenReturn(networkHistory);
|
|
||||||
final long now = System.currentTimeMillis();
|
final long now = System.currentTimeMillis();
|
||||||
final long fourWeeksAgo = now - (DateUtils.WEEK_IN_MILLIS * 4);
|
final long fourWeeksAgo = now - (DateUtils.WEEK_IN_MILLIS * 4);
|
||||||
final long twoDaysAgo = now - (DateUtils.DAY_IN_MILLIS * 2);
|
final long twoDaysAgo = now - (DateUtils.DAY_IN_MILLIS * 2);
|
||||||
when(networkHistory.getStart()).thenReturn(twoDaysAgo);
|
mLoader.addBucket(makeMockBucket(UID_ALL, 123, 456, twoDaysAgo, now));
|
||||||
when(networkHistory.getEnd()).thenReturn(now);
|
|
||||||
|
|
||||||
mLoader.loadFourWeeksData();
|
mLoader.loadFourWeeksData();
|
||||||
|
|
||||||
@@ -173,10 +177,31 @@ public class NetworkCycleDataLoaderTest {
|
|||||||
verify(mLoader).recordUsage(thirtyDaysAgo, twentyDaysAgo);
|
verify(mLoader).recordUsage(thirtyDaysAgo, twentyDaysAgo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getTimeRangeOf() {
|
||||||
|
mLoader = spy(new NetworkCycleDataTestLoader(mContext));
|
||||||
|
// If empty, new Range(MAX_VALUE, MIN_VALUE) will be constructed. Hence, the function
|
||||||
|
// should throw.
|
||||||
|
assertThrows(IllegalArgumentException.class,
|
||||||
|
() -> mLoader.getTimeRangeOf(mock(NetworkStats.class)));
|
||||||
|
|
||||||
|
mLoader.addBucket(makeMockBucket(UID_ALL, 123, 456, 0, 10));
|
||||||
|
// Feed the function with unused NetworkStats. The actual data injection is
|
||||||
|
// done by addBucket.
|
||||||
|
assertEquals(new Range(0L, 10L), mLoader.getTimeRangeOf(mock(NetworkStats.class)));
|
||||||
|
|
||||||
|
mLoader.addBucket(makeMockBucket(UID_ALL, 123, 456, 0, 10));
|
||||||
|
mLoader.addBucket(makeMockBucket(UID_ALL, 123, 456, 30, 40));
|
||||||
|
mLoader.addBucket(makeMockBucket(UID_ALL, 123, 456, 10, 25));
|
||||||
|
assertEquals(new Range(0L, 40L), mLoader.getTimeRangeOf(mock(NetworkStats.class)));
|
||||||
|
}
|
||||||
|
|
||||||
public class NetworkCycleDataTestLoader extends NetworkCycleDataLoader<List<NetworkCycleData>> {
|
public class NetworkCycleDataTestLoader extends NetworkCycleDataLoader<List<NetworkCycleData>> {
|
||||||
|
private final Queue<NetworkStats.Bucket> mMockedBuckets = new LinkedBlockingQueue<>();
|
||||||
|
|
||||||
private NetworkCycleDataTestLoader(Context context) {
|
private NetworkCycleDataTestLoader(Context context) {
|
||||||
super(NetworkCycleDataLoader.builder(mContext));
|
super(NetworkCycleDataLoader.builder(mContext)
|
||||||
|
.setNetworkTemplate(mock(NetworkTemplate.class)));
|
||||||
mContext = context;
|
mContext = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,5 +213,19 @@ public class NetworkCycleDataLoaderTest {
|
|||||||
List<NetworkCycleData> getCycleUsage() {
|
List<NetworkCycleData> getCycleUsage() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addBucket(NetworkStats.Bucket bucket) {
|
||||||
|
mMockedBuckets.add(bucket);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNextBucket(@NonNull NetworkStats unused) {
|
||||||
|
return !mMockedBuckets.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NetworkStats.Bucket getNextBucket(@NonNull NetworkStats unused) {
|
||||||
|
return mMockedBuckets.remove();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user