16b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey/* 26b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * Copyright (C) 2012 The Android Open Source Project 36b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * 46b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 56b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * you may not use this file except in compliance with the License. 66b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * You may obtain a copy of the License at 76b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * 86b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 96b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * 106b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * Unless required by applicable law or agreed to in writing, software 116b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 126b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * See the License for the specific language governing permissions and 146b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * limitations under the License. 156b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey */ 166b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey 176b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkeypackage android.support.v4.net; 186b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey 196b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkeyimport android.os.Build; 206b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey 216b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkeyimport java.net.Socket; 226b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkeyimport java.net.SocketException; 236b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey 246b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey/** 256b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * Helper for accessing features in TrafficStats introduced after API level 14 266b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * in a backwards compatible fashion. 276b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey */ 286b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkeypublic class TrafficStatsCompat { 296b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey 306b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey interface TrafficStatsCompatImpl { 316b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey void clearThreadStatsTag(); 326b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey int getThreadStatsTag(); 336b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey void incrementOperationCount(int operationCount); 346b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey void incrementOperationCount(int tag, int operationCount); 356b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey void setThreadStatsTag(int tag); 366b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey void tagSocket(Socket socket) throws SocketException; 376b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey void untagSocket(Socket socket) throws SocketException; 386b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey } 396b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey 406b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey static class BaseTrafficStatsCompatImpl implements TrafficStatsCompatImpl { 416b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey private static class SocketTags { 426b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey public int statsTag = -1; 436b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey } 446b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey 456b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey private ThreadLocal<SocketTags> mThreadSocketTags = new ThreadLocal<SocketTags>() { 466b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey @Override 476b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey protected SocketTags initialValue() { 486b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey return new SocketTags(); 496b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey } 506b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey }; 516b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey 526b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey @Override 536b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey public void clearThreadStatsTag() { 546b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey mThreadSocketTags.get().statsTag = -1; 556b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey } 566b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey 576b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey @Override 586b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey public int getThreadStatsTag() { 596b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey return mThreadSocketTags.get().statsTag; 606b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey } 616b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey 626b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey @Override 636b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey public void incrementOperationCount(int operationCount) { 646b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey } 656b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey 666b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey @Override 676b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey public void incrementOperationCount(int tag, int operationCount) { 686b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey } 696b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey 706b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey @Override 716b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey public void setThreadStatsTag(int tag) { 726b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey mThreadSocketTags.get().statsTag = tag; 736b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey } 746b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey 756b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey @Override 766b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey public void tagSocket(Socket socket) { 776b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey } 786b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey 796b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey @Override 806b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey public void untagSocket(Socket socket) { 816b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey } 826b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey } 836b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey 846b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey static class IcsTrafficStatsCompatImpl implements TrafficStatsCompatImpl { 856b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey @Override 866b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey public void clearThreadStatsTag() { 876b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey TrafficStatsCompatIcs.clearThreadStatsTag(); 886b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey } 896b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey 906b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey @Override 916b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey public int getThreadStatsTag() { 926b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey return TrafficStatsCompatIcs.getThreadStatsTag(); 936b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey } 946b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey 956b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey @Override 966b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey public void incrementOperationCount(int operationCount) { 976b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey TrafficStatsCompatIcs.incrementOperationCount(operationCount); 986b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey } 996b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey 1006b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey @Override 1016b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey public void incrementOperationCount(int tag, int operationCount) { 1026b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey TrafficStatsCompatIcs.incrementOperationCount(tag, operationCount); 1036b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey } 1046b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey 1056b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey @Override 1066b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey public void setThreadStatsTag(int tag) { 1076b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey TrafficStatsCompatIcs.setThreadStatsTag(tag); 1086b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey } 1096b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey 1106b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey @Override 1116b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey public void tagSocket(Socket socket) throws SocketException { 1126b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey TrafficStatsCompatIcs.tagSocket(socket); 1136b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey } 1146b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey 1156b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey @Override 1166b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey public void untagSocket(Socket socket) throws SocketException { 1176b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey TrafficStatsCompatIcs.untagSocket(socket); 1186b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey } 1196b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey } 1206b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey 1216b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey private static final TrafficStatsCompatImpl IMPL; 1226b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey 1236b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey static { 1246b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey if (Build.VERSION.SDK_INT >= 14) { 1256b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey IMPL = new IcsTrafficStatsCompatImpl(); 1266b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey } else { 1276b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey IMPL = new BaseTrafficStatsCompatImpl(); 1286b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey } 1296b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey } 1306b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey 1316b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey /** 1326b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * Clear active tag used when accounting {@link Socket} traffic originating 1336b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * from the current thread. 1346b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey */ 1356b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey public static void clearThreadStatsTag() { 1366b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey IMPL.clearThreadStatsTag(); 1376b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey } 1386b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey 1396b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey /** 1406b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * Get the active tag used when accounting {@link Socket} traffic originating 1416b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * from the current thread. Only one active tag per thread is supported. 1426b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * {@link #tagSocket(Socket)}. 1436b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey */ 1446b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey public static int getThreadStatsTag() { 1456b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey return IMPL.getThreadStatsTag(); 1466b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey } 1476b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey 1486b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey /** 1496b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * Increment count of network operations performed under the accounting tag 1506b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * currently active on the calling thread. This can be used to derive 1516b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * bytes-per-operation. 1526b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * 1536b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * @param operationCount Number of operations to increment count by. 1546b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey */ 1556b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey public static void incrementOperationCount(int operationCount) { 1566b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey IMPL.incrementOperationCount(operationCount); 1576b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey } 1586b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey 1596b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey /** 1606b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * Increment count of network operations performed under the given 1616b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * accounting tag. This can be used to derive bytes-per-operation. 1626b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * 1636b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * @param tag Accounting tag used in {@link #setThreadStatsTag(int)}. 1646b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * @param operationCount Number of operations to increment count by. 1656b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey */ 1666b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey public static void incrementOperationCount(int tag, int operationCount) { 1676b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey IMPL.incrementOperationCount(tag, operationCount); 1686b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey } 1696b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey 1706b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey /** 1716b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * Set active tag to use when accounting {@link Socket} traffic originating 1726b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * from the current thread. Only one active tag per thread is supported. 1736b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * <p> 1746b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * Changes only take effect during subsequent calls to 1756b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * {@link #tagSocket(Socket)}. 1766b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * <p> 1776b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * Tags between {@code 0xFFFFFF00} and {@code 0xFFFFFFFF} are reserved and 1786b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * used internally by system services like DownloadManager when performing 1796b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * traffic on behalf of an application. 1806b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey */ 1816b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey public static void setThreadStatsTag(int tag) { 1826b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey IMPL.setThreadStatsTag(tag); 1836b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey } 1846b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey 1856b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey /** 1866b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * Tag the given {@link Socket} with any statistics parameters active for 1876b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * the current thread. Subsequent calls always replace any existing 1886b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * parameters. When finished, call {@link #untagSocket(Socket)} to remove 1896b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * statistics parameters. 1906b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * 1916b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * @see #setThreadStatsTag(int) 1926b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey */ 1936b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey public static void tagSocket(Socket socket) throws SocketException { 1946b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey IMPL.tagSocket(socket); 1956b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey } 1966b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey 1976b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey /** 1986b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey * Remove any statistics parameters from the given {@link Socket}. 1996b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey */ 2006b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey public static void untagSocket(Socket socket) throws SocketException { 2016b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey IMPL.untagSocket(socket); 2026b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey } 2036b96c2a5aecbb56116667959e43489966e02ff73Jeff Sharkey} 204