diff --git a/core/java/android/net/IpSecManager.java b/core/java/android/net/IpSecManager.java index 09ec6c35fc..d83715c692 100644 --- a/core/java/android/net/IpSecManager.java +++ b/core/java/android/net/IpSecManager.java @@ -51,7 +51,7 @@ import java.net.Socket; * *

Note that not all aspects of IPsec are permitted by this API. Applications may create * transport mode security associations and apply them to individual sockets. Applications looking - * to create a VPN should use {@link VpnService}. + * to create an IPsec VPN should use {@link VpnManager} and {@link Ikev2VpnProfile}. * * @see RFC 4301, Security Architecture for the * Internet Protocol diff --git a/core/java/android/net/NetworkStatsHistory.java b/core/java/android/net/NetworkStatsHistory.java index 6d46c205b2..3c1b86b9f1 100644 --- a/core/java/android/net/NetworkStatsHistory.java +++ b/core/java/android/net/NetworkStatsHistory.java @@ -548,32 +548,32 @@ public class NetworkStatsHistory implements Parcelable { final int startIndex = getIndexAfter(end); for (int i = startIndex; i >= 0; i--) { final long curStart = bucketStart[i]; - final long curEnd = curStart + bucketDuration; + long curEnd = curStart + bucketDuration; // bucket is older than request; we're finished if (curEnd <= start) break; // bucket is newer than request; keep looking if (curStart >= end) continue; - // include full value for active buckets, otherwise only fractional - final boolean activeBucket = curStart < now && curEnd > now; - final long overlap; - if (activeBucket) { - overlap = bucketDuration; - } else { - final long overlapEnd = curEnd < end ? curEnd : end; - final long overlapStart = curStart > start ? curStart : start; - overlap = overlapEnd - overlapStart; - } + // the active bucket is shorter then a normal completed bucket + if (curEnd > now) curEnd = now; + // usually this is simply bucketDuration + final long bucketSpan = curEnd - curStart; + // prevent division by zero + if (bucketSpan <= 0) continue; + + final long overlapEnd = curEnd < end ? curEnd : end; + final long overlapStart = curStart > start ? curStart : start; + final long overlap = overlapEnd - overlapStart; if (overlap <= 0) continue; // integer math each time is faster than floating point - if (activeTime != null) entry.activeTime += activeTime[i] * overlap / bucketDuration; - if (rxBytes != null) entry.rxBytes += rxBytes[i] * overlap / bucketDuration; - if (rxPackets != null) entry.rxPackets += rxPackets[i] * overlap / bucketDuration; - if (txBytes != null) entry.txBytes += txBytes[i] * overlap / bucketDuration; - if (txPackets != null) entry.txPackets += txPackets[i] * overlap / bucketDuration; - if (operations != null) entry.operations += operations[i] * overlap / bucketDuration; + if (activeTime != null) entry.activeTime += activeTime[i] * overlap / bucketSpan; + if (rxBytes != null) entry.rxBytes += rxBytes[i] * overlap / bucketSpan; + if (rxPackets != null) entry.rxPackets += rxPackets[i] * overlap / bucketSpan; + if (txBytes != null) entry.txBytes += txBytes[i] * overlap / bucketSpan; + if (txPackets != null) entry.txPackets += txPackets[i] * overlap / bucketSpan; + if (operations != null) entry.operations += operations[i] * overlap / bucketSpan; } return entry; } diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java index c98762074b..9540f43364 100644 --- a/services/core/java/com/android/server/IpSecService.java +++ b/services/core/java/com/android/server/IpSecService.java @@ -1556,16 +1556,16 @@ public class IpSecService extends IIpSecService.Stub { } Objects.requireNonNull(callingPackage, "Null calling package cannot create IpSec tunnels"); - switch (getAppOpsManager().noteOp(TUNNEL_OP, Binder.getCallingUid(), callingPackage)) { - case AppOpsManager.MODE_DEFAULT: - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.MANAGE_IPSEC_TUNNELS, "IpSecService"); - break; - case AppOpsManager.MODE_ALLOWED: - return; - default: - throw new SecurityException("Request to ignore AppOps for non-legacy API"); + + // OP_MANAGE_IPSEC_TUNNELS will return MODE_ERRORED by default, including for the system + // server. If the appop is not granted, require that the caller has the MANAGE_IPSEC_TUNNELS + // permission or is the System Server. + if (AppOpsManager.MODE_ALLOWED == getAppOpsManager().noteOpNoThrow( + TUNNEL_OP, Binder.getCallingUid(), callingPackage)) { + return; } + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.MANAGE_IPSEC_TUNNELS, "IpSecService"); } private void createOrUpdateTransform(