1/* 2 * Copyright (C) 2012 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 17package android.support.v4.net; 18 19import android.support.annotation.RequiresApi; 20import android.net.TrafficStats; 21import android.os.Build; 22import android.os.ParcelFileDescriptor; 23 24import java.net.DatagramSocket; 25import java.net.Socket; 26import java.net.SocketException; 27 28/** 29 * Helper for accessing features in {@link TrafficStats} introduced after API level 14 30 * in a backwards compatible fashion. 31 */ 32public final class TrafficStatsCompat { 33 static class TrafficStatsCompatBaseImpl { 34 public void tagDatagramSocket(DatagramSocket socket) throws SocketException { 35 final ParcelFileDescriptor pfd = ParcelFileDescriptor.fromDatagramSocket(socket); 36 TrafficStats.tagSocket(new DatagramSocketWrapper(socket, pfd.getFileDescriptor())); 37 // The developer is still using the FD, so we need to detach it to 38 // prevent the PFD finalizer from closing it in their face. We had to 39 // wait until after the tagging call above, since detaching clears out 40 // the getFileDescriptor() result which tagging depends on. 41 pfd.detachFd(); 42 } 43 44 public void untagDatagramSocket(DatagramSocket socket) throws SocketException { 45 final ParcelFileDescriptor pfd = ParcelFileDescriptor.fromDatagramSocket(socket); 46 TrafficStats.untagSocket(new DatagramSocketWrapper(socket, pfd.getFileDescriptor())); 47 // The developer is still using the FD, so we need to detach it to 48 // prevent the PFD finalizer from closing it in their face. We had to 49 // wait until after the tagging call above, since detaching clears out 50 // the getFileDescriptor() result which tagging depends on. 51 pfd.detachFd(); 52 } 53 } 54 55 @RequiresApi(24) 56 static class TrafficStatsCompatApi24Impl extends TrafficStatsCompatBaseImpl { 57 @Override 58 public void tagDatagramSocket(DatagramSocket socket) throws SocketException { 59 TrafficStats.tagDatagramSocket(socket); 60 } 61 62 @Override 63 public void untagDatagramSocket(DatagramSocket socket) throws SocketException { 64 TrafficStats.untagDatagramSocket(socket); 65 } 66 } 67 68 private static final TrafficStatsCompatBaseImpl IMPL; 69 70 static { 71 if (Build.VERSION.SDK_INT >= 24) { 72 IMPL = new TrafficStatsCompatApi24Impl(); 73 } else { 74 IMPL = new TrafficStatsCompatBaseImpl(); 75 } 76 } 77 78 /** 79 * Clear active tag used when accounting {@link Socket} traffic originating 80 * from the current thread. 81 * 82 * @deprecated Use {@link TrafficStats#clearThreadStatsTag()} directly. 83 */ 84 @Deprecated 85 public static void clearThreadStatsTag() { 86 TrafficStats.clearThreadStatsTag(); 87 } 88 89 /** 90 * Get the active tag used when accounting {@link Socket} traffic originating 91 * from the current thread. Only one active tag per thread is supported. 92 * {@link #tagSocket(Socket)}. 93 * 94 * @deprecated Use {@link TrafficStats#getThreadStatsTag()} directly. 95 */ 96 @Deprecated 97 public static int getThreadStatsTag() { 98 return TrafficStats.getThreadStatsTag(); 99 } 100 101 /** 102 * Increment count of network operations performed under the accounting tag 103 * currently active on the calling thread. This can be used to derive 104 * bytes-per-operation. 105 * 106 * @param operationCount Number of operations to increment count by. 107 * 108 * @deprecated Use {@link TrafficStats#incrementOperationCount(int)} directly. 109 */ 110 @Deprecated 111 public static void incrementOperationCount(int operationCount) { 112 TrafficStats.incrementOperationCount(operationCount); 113 } 114 115 /** 116 * Increment count of network operations performed under the given 117 * accounting tag. This can be used to derive bytes-per-operation. 118 * 119 * @param tag Accounting tag used in {@link #setThreadStatsTag(int)}. 120 * @param operationCount Number of operations to increment count by. 121 * 122 * @deprecated Use {@link TrafficStats#incrementOperationCount(int, int)} directly. 123 */ 124 @Deprecated 125 public static void incrementOperationCount(int tag, int operationCount) { 126 TrafficStats.incrementOperationCount(tag, operationCount); 127 } 128 129 /** 130 * Set active tag to use when accounting {@link Socket} traffic originating 131 * from the current thread. Only one active tag per thread is supported. 132 * <p> 133 * Changes only take effect during subsequent calls to 134 * {@link #tagSocket(Socket)}. 135 * <p> 136 * Tags between {@code 0xFFFFFF00} and {@code 0xFFFFFFFF} are reserved and 137 * used internally by system services like DownloadManager when performing 138 * traffic on behalf of an application. 139 * 140 * @deprecated Use {@link TrafficStats#setThreadStatsTag(int)} directly. 141 */ 142 @Deprecated 143 public static void setThreadStatsTag(int tag) { 144 TrafficStats.setThreadStatsTag(tag); 145 } 146 147 /** 148 * Tag the given {@link Socket} with any statistics parameters active for 149 * the current thread. Subsequent calls always replace any existing 150 * parameters. When finished, call {@link #untagSocket(Socket)} to remove 151 * statistics parameters. 152 * 153 * @see #setThreadStatsTag(int) 154 * 155 * @deprecated Use {@link TrafficStats#tagSocket(Socket)} directly. 156 */ 157 @Deprecated 158 public static void tagSocket(Socket socket) throws SocketException { 159 TrafficStats.tagSocket(socket); 160 } 161 162 /** 163 * Remove any statistics parameters from the given {@link Socket}. 164 * 165 * @deprecated Use {@link TrafficStats#untagSocket(Socket)} directly. 166 */ 167 @Deprecated 168 public static void untagSocket(Socket socket) throws SocketException { 169 TrafficStats.untagSocket(socket); 170 } 171 172 /** 173 * Tag the given {@link DatagramSocket} with any statistics parameters 174 * active for the current thread. Subsequent calls always replace any 175 * existing parameters. When finished, call 176 * {@link #untagDatagramSocket(DatagramSocket)} to remove statistics 177 * parameters. 178 * 179 * @see #setThreadStatsTag(int) 180 */ 181 public static void tagDatagramSocket(DatagramSocket socket) throws SocketException { 182 IMPL.tagDatagramSocket(socket); 183 } 184 185 /** 186 * Remove any statistics parameters from the given {@link DatagramSocket}. 187 */ 188 public static void untagDatagramSocket(DatagramSocket socket) throws SocketException { 189 IMPL.untagDatagramSocket(socket); 190 } 191 192 private TrafficStatsCompat() {} 193} 194