1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.net.module.util; 18 19 /** 20 * Various utilities used for NetworkStats related code. 21 * 22 * @hide 23 */ 24 public class NetworkStatsUtils { 25 /** 26 * Safely multiple a value by a rational. 27 * <p> 28 * Internally it uses integer-based math whenever possible, but switches 29 * over to double-based math if values would overflow. 30 * @hide 31 */ multiplySafeByRational(long value, long num, long den)32 public static long multiplySafeByRational(long value, long num, long den) { 33 if (den == 0) { 34 throw new ArithmeticException("Invalid Denominator"); 35 } 36 long x = value; 37 long y = num; 38 39 // Logic shamelessly borrowed from Math.multiplyExact() 40 long r = x * y; 41 long ax = Math.abs(x); 42 long ay = Math.abs(y); 43 if (((ax | ay) >>> 31 != 0)) { 44 // Some bits greater than 2^31 that might cause overflow 45 // Check the result using the divide operator 46 // and check for the special case of Long.MIN_VALUE * -1 47 if (((y != 0) && (r / y != x)) 48 || (x == Long.MIN_VALUE && y == -1)) { 49 // Use double math to avoid overflowing 50 return (long) (((double) num / den) * value); 51 } 52 } 53 return r / den; 54 } 55 56 /** 57 * Value of the match rule of the subscriberId to match networks with specific subscriberId. 58 * 59 * @hide 60 */ 61 public static final int SUBSCRIBER_ID_MATCH_RULE_EXACT = 0; 62 /** 63 * Value of the match rule of the subscriberId to match networks with any subscriberId which 64 * includes null and non-null. 65 * 66 * @hide 67 */ 68 public static final int SUBSCRIBER_ID_MATCH_RULE_ALL = 1; 69 70 /** 71 * Name representing {@link #bandwidthSetGlobalAlert(long)} limit when delivered to 72 * {@link AlertObserver#onQuotaLimitReached(String, String)}. 73 */ 74 public static final String LIMIT_GLOBAL_ALERT = "globalAlert"; 75 76 /** 77 * Return the constrained value by given the lower and upper bounds. 78 */ constrain(int amount, int low, int high)79 public static int constrain(int amount, int low, int high) { 80 if (low > high) throw new IllegalArgumentException("low(" + low + ") > high(" + high + ")"); 81 return amount < low ? low : (amount > high ? high : amount); 82 } 83 84 /** 85 * Return the constrained value by given the lower and upper bounds. 86 */ constrain(long amount, long low, long high)87 public static long constrain(long amount, long low, long high) { 88 if (low > high) throw new IllegalArgumentException("low(" + low + ") > high(" + high + ")"); 89 return amount < low ? low : (amount > high ? high : amount); 90 } 91 } 92