@@ -88,6 +88,16 @@ public class TrafficStats {
8888 */
8989 public static final int TAG_SYSTEM_BACKUP = 0xFFFFFF03 ;
9090
91+ private static INetworkStatsService sStatsService ;
92+
93+ private synchronized static INetworkStatsService getStatsService () {
94+ if (sStatsService == null ) {
95+ sStatsService = INetworkStatsService .Stub .asInterface (
96+ ServiceManager .getService (Context .NETWORK_STATS_SERVICE ));
97+ }
98+ return sStatsService ;
99+ }
100+
91101 /**
92102 * Snapshot of {@link NetworkStats} when the currently active profiling
93103 * session started, or {@code null} if no session active.
@@ -228,11 +238,9 @@ public static void incrementOperationCount(int operationCount) {
228238 * @param operationCount Number of operations to increment count by.
229239 */
230240 public static void incrementOperationCount (int tag , int operationCount ) {
231- final INetworkStatsService statsService = INetworkStatsService .Stub .asInterface (
232- ServiceManager .getService (Context .NETWORK_STATS_SERVICE ));
233241 final int uid = android .os .Process .myUid ();
234242 try {
235- statsService .incrementOperationCount (uid , tag , operationCount );
243+ getStatsService () .incrementOperationCount (uid , tag , operationCount );
236244 } catch (RemoteException e ) {
237245 throw new RuntimeException (e );
238246 }
@@ -257,31 +265,55 @@ public static void closeQuietly(INetworkStatsSession session) {
257265 * @return number of packets. If the statistics are not supported by this device,
258266 * {@link #UNSUPPORTED} will be returned.
259267 */
260- public static native long getMobileTxPackets ();
268+ public static long getMobileTxPackets () {
269+ long total = 0 ;
270+ for (String iface : getMobileIfaces ()) {
271+ total += getTxPackets (iface );
272+ }
273+ return total ;
274+ }
261275
262276 /**
263277 * Get the total number of packets received through the mobile interface.
264278 *
265279 * @return number of packets. If the statistics are not supported by this device,
266280 * {@link #UNSUPPORTED} will be returned.
267281 */
268- public static native long getMobileRxPackets ();
282+ public static long getMobileRxPackets () {
283+ long total = 0 ;
284+ for (String iface : getMobileIfaces ()) {
285+ total += getRxPackets (iface );
286+ }
287+ return total ;
288+ }
269289
270290 /**
271291 * Get the total number of bytes transmitted through the mobile interface.
272292 *
273293 * @return number of bytes. If the statistics are not supported by this device,
274294 * {@link #UNSUPPORTED} will be returned.
275295 */
276- public static native long getMobileTxBytes ();
296+ public static long getMobileTxBytes () {
297+ long total = 0 ;
298+ for (String iface : getMobileIfaces ()) {
299+ total += getTxBytes (iface );
300+ }
301+ return total ;
302+ }
277303
278304 /**
279305 * Get the total number of bytes received through the mobile interface.
280306 *
281307 * @return number of bytes. If the statistics are not supported by this device,
282308 * {@link #UNSUPPORTED} will be returned.
283309 */
284- public static native long getMobileRxBytes ();
310+ public static long getMobileRxBytes () {
311+ long total = 0 ;
312+ for (String iface : getMobileIfaces ()) {
313+ total += getRxBytes (iface );
314+ }
315+ return total ;
316+ }
285317
286318 /**
287319 * Get the total number of packets transmitted through the specified interface.
@@ -290,7 +322,9 @@ public static void closeQuietly(INetworkStatsSession session) {
290322 * {@link #UNSUPPORTED} will be returned.
291323 * @hide
292324 */
293- public static native long getTxPackets (String iface );
325+ public static long getTxPackets (String iface ) {
326+ return nativeGetIfaceStat (iface , TYPE_TX_PACKETS );
327+ }
294328
295329 /**
296330 * Get the total number of packets received through the specified interface.
@@ -299,7 +333,9 @@ public static void closeQuietly(INetworkStatsSession session) {
299333 * {@link #UNSUPPORTED} will be returned.
300334 * @hide
301335 */
302- public static native long getRxPackets (String iface );
336+ public static long getRxPackets (String iface ) {
337+ return nativeGetIfaceStat (iface , TYPE_RX_PACKETS );
338+ }
303339
304340 /**
305341 * Get the total number of bytes transmitted through the specified interface.
@@ -308,7 +344,9 @@ public static void closeQuietly(INetworkStatsSession session) {
308344 * {@link #UNSUPPORTED} will be returned.
309345 * @hide
310346 */
311- public static native long getTxBytes (String iface );
347+ public static long getTxBytes (String iface ) {
348+ return nativeGetIfaceStat (iface , TYPE_TX_BYTES );
349+ }
312350
313351 /**
314352 * Get the total number of bytes received through the specified interface.
@@ -317,40 +355,49 @@ public static void closeQuietly(INetworkStatsSession session) {
317355 * {@link #UNSUPPORTED} will be returned.
318356 * @hide
319357 */
320- public static native long getRxBytes (String iface );
321-
358+ public static long getRxBytes (String iface ) {
359+ return nativeGetIfaceStat (iface , TYPE_RX_BYTES );
360+ }
322361
323362 /**
324363 * Get the total number of packets sent through all network interfaces.
325364 *
326365 * @return the number of packets. If the statistics are not supported by this device,
327366 * {@link #UNSUPPORTED} will be returned.
328367 */
329- public static native long getTotalTxPackets ();
368+ public static long getTotalTxPackets () {
369+ return nativeGetTotalStat (TYPE_TX_PACKETS );
370+ }
330371
331372 /**
332373 * Get the total number of packets received through all network interfaces.
333374 *
334375 * @return number of packets. If the statistics are not supported by this device,
335376 * {@link #UNSUPPORTED} will be returned.
336377 */
337- public static native long getTotalRxPackets ();
378+ public static long getTotalRxPackets () {
379+ return nativeGetTotalStat (TYPE_RX_PACKETS );
380+ }
338381
339382 /**
340383 * Get the total number of bytes sent through all network interfaces.
341384 *
342385 * @return number of bytes. If the statistics are not supported by this device,
343386 * {@link #UNSUPPORTED} will be returned.
344387 */
345- public static native long getTotalTxBytes ();
388+ public static long getTotalTxBytes () {
389+ return nativeGetTotalStat (TYPE_TX_BYTES );
390+ }
346391
347392 /**
348393 * Get the total number of bytes received through all network interfaces.
349394 *
350395 * @return number of bytes. If the statistics are not supported by this device,
351396 * {@link #UNSUPPORTED} will be returned.
352397 */
353- public static native long getTotalRxBytes ();
398+ public static long getTotalRxBytes () {
399+ return nativeGetTotalStat (TYPE_RX_BYTES );
400+ }
354401
355402 /**
356403 * Get the number of bytes sent through the network for this UID.
@@ -483,7 +530,6 @@ public static void closeQuietly(INetworkStatsSession session) {
483530 */
484531 public static native long getUidTcpRxSegments (int uid );
485532
486-
487533 /**
488534 * Get the number of UDP packets sent for this UID.
489535 * Includes DNS requests.
@@ -515,13 +561,33 @@ public static void closeQuietly(INetworkStatsSession session) {
515561 * special permission.
516562 */
517563 private static NetworkStats getDataLayerSnapshotForUid (Context context ) {
518- final INetworkStatsService statsService = INetworkStatsService .Stub .asInterface (
519- ServiceManager .getService (Context .NETWORK_STATS_SERVICE ));
520564 final int uid = android .os .Process .myUid ();
521565 try {
522- return statsService .getDataLayerSnapshotForUid (uid );
566+ return getStatsService ().getDataLayerSnapshotForUid (uid );
567+ } catch (RemoteException e ) {
568+ throw new RuntimeException (e );
569+ }
570+ }
571+
572+ /**
573+ * Return set of any ifaces associated with mobile networks since boot.
574+ * Interfaces are never removed from this list, so counters should always be
575+ * monotonic.
576+ */
577+ private static String [] getMobileIfaces () {
578+ try {
579+ return getStatsService ().getMobileIfaces ();
523580 } catch (RemoteException e ) {
524581 throw new RuntimeException (e );
525582 }
526583 }
584+
585+ // NOTE: keep these in sync with android_net_TrafficStats.cpp
586+ private static final int TYPE_RX_BYTES = 0 ;
587+ private static final int TYPE_RX_PACKETS = 1 ;
588+ private static final int TYPE_TX_BYTES = 2 ;
589+ private static final int TYPE_TX_PACKETS = 3 ;
590+
591+ private static native long nativeGetTotalStat (int type );
592+ private static native long nativeGetIfaceStat (String iface , int type );
527593}
0 commit comments