1 /* 2 * Copyright (C) 2019 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 package android.net.util; 17 18 import android.net.TetherStatsParcel; 19 import android.net.TetheringRequestParcel; 20 21 import androidx.annotation.NonNull; 22 23 import java.io.FileDescriptor; 24 import java.net.SocketException; 25 import java.util.Objects; 26 27 /** 28 * The classes and the methods for tethering utilization. 29 * 30 * {@hide} 31 */ 32 public class TetheringUtils { 33 /** 34 * The object which records offload Tx/Rx forwarded bytes/packets. 35 * TODO: Replace the inner class ForwardedStats of class OffloadHardwareInterface with 36 * this class as well. 37 */ 38 public static class ForwardedStats { 39 public final long rxBytes; 40 public final long rxPackets; 41 public final long txBytes; 42 public final long txPackets; 43 ForwardedStats()44 public ForwardedStats() { 45 rxBytes = 0; 46 rxPackets = 0; 47 txBytes = 0; 48 txPackets = 0; 49 } 50 ForwardedStats(long rxBytes, long txBytes)51 public ForwardedStats(long rxBytes, long txBytes) { 52 this.rxBytes = rxBytes; 53 this.rxPackets = 0; 54 this.txBytes = txBytes; 55 this.txPackets = 0; 56 } 57 ForwardedStats(long rxBytes, long rxPackets, long txBytes, long txPackets)58 public ForwardedStats(long rxBytes, long rxPackets, long txBytes, long txPackets) { 59 this.rxBytes = rxBytes; 60 this.rxPackets = rxPackets; 61 this.txBytes = txBytes; 62 this.txPackets = txPackets; 63 } 64 ForwardedStats(@onNull TetherStatsParcel tetherStats)65 public ForwardedStats(@NonNull TetherStatsParcel tetherStats) { 66 rxBytes = tetherStats.rxBytes; 67 rxPackets = tetherStats.rxPackets; 68 txBytes = tetherStats.txBytes; 69 txPackets = tetherStats.txPackets; 70 } 71 ForwardedStats(@onNull ForwardedStats other)72 public ForwardedStats(@NonNull ForwardedStats other) { 73 rxBytes = other.rxBytes; 74 rxPackets = other.rxPackets; 75 txBytes = other.txBytes; 76 txPackets = other.txPackets; 77 } 78 79 /** Add Tx/Rx bytes/packets and return the result as a new object. */ 80 @NonNull add(@onNull ForwardedStats other)81 public ForwardedStats add(@NonNull ForwardedStats other) { 82 return new ForwardedStats(rxBytes + other.rxBytes, rxPackets + other.rxPackets, 83 txBytes + other.txBytes, txPackets + other.txPackets); 84 } 85 86 /** Subtract Tx/Rx bytes/packets and return the result as a new object. */ 87 @NonNull subtract(@onNull ForwardedStats other)88 public ForwardedStats subtract(@NonNull ForwardedStats other) { 89 // TODO: Perhaps throw an exception if any negative difference value just in case. 90 final long rxBytesDiff = Math.max(rxBytes - other.rxBytes, 0); 91 final long rxPacketsDiff = Math.max(rxPackets - other.rxPackets, 0); 92 final long txBytesDiff = Math.max(txBytes - other.txBytes, 0); 93 final long txPacketsDiff = Math.max(txPackets - other.txPackets, 0); 94 return new ForwardedStats(rxBytesDiff, rxPacketsDiff, txBytesDiff, txPacketsDiff); 95 } 96 97 /** Returns the string representation of this object. */ 98 @NonNull toString()99 public String toString() { 100 return String.format("ForwardedStats(rxb: %d, rxp: %d, txb: %d, txp: %d)", rxBytes, 101 rxPackets, txBytes, txPackets); 102 } 103 } 104 105 /** 106 * Configures a socket for receiving ICMPv6 router solicitations and sending advertisements. 107 * @param fd the socket's {@link FileDescriptor}. 108 * @param ifIndex the interface index. 109 */ setupRaSocket(FileDescriptor fd, int ifIndex)110 public static native void setupRaSocket(FileDescriptor fd, int ifIndex) 111 throws SocketException; 112 113 /** 114 * Read s as an unsigned 16-bit integer. 115 */ uint16(short s)116 public static int uint16(short s) { 117 return s & 0xffff; 118 } 119 120 /** Check whether two TetheringRequestParcels are the same. */ isTetheringRequestEquals(final TetheringRequestParcel request, final TetheringRequestParcel otherRequest)121 public static boolean isTetheringRequestEquals(final TetheringRequestParcel request, 122 final TetheringRequestParcel otherRequest) { 123 if (request == otherRequest) return true; 124 125 return request != null && otherRequest != null 126 && request.tetheringType == otherRequest.tetheringType 127 && Objects.equals(request.localIPv4Address, otherRequest.localIPv4Address) 128 && Objects.equals(request.staticClientAddress, otherRequest.staticClientAddress) 129 && request.exemptFromEntitlementCheck == otherRequest.exemptFromEntitlementCheck 130 && request.showProvisioningUi == otherRequest.showProvisioningUi; 131 } 132 } 133