1 /* 2 * Copyright (C) 2017 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 android.net.metrics; 18 19 import android.net.MacAddress; 20 import android.os.Process; 21 import android.os.SystemClock; 22 import android.util.SparseIntArray; 23 24 import java.util.StringJoiner; 25 26 /** 27 * An event logged per interface and that aggregates WakeupEvents for that interface. 28 * {@hide} 29 */ 30 public class WakeupStats { 31 32 private static final int NO_UID = -1; 33 34 public final long creationTimeMs = SystemClock.elapsedRealtime(); 35 public final String iface; 36 37 public long totalWakeups = 0; 38 public long rootWakeups = 0; 39 public long systemWakeups = 0; 40 public long nonApplicationWakeups = 0; 41 public long applicationWakeups = 0; 42 public long noUidWakeups = 0; 43 public long durationSec = 0; 44 45 public long l2UnicastCount = 0; 46 public long l2MulticastCount = 0; 47 public long l2BroadcastCount = 0; 48 49 public final SparseIntArray ethertypes = new SparseIntArray(); 50 public final SparseIntArray ipNextHeaders = new SparseIntArray(); 51 WakeupStats(String iface)52 public WakeupStats(String iface) { 53 this.iface = iface; 54 } 55 56 /** Update durationSec with current time. */ updateDuration()57 public void updateDuration() { 58 durationSec = (SystemClock.elapsedRealtime() - creationTimeMs) / 1000; 59 } 60 61 /** Update wakeup counters for the given WakeupEvent. */ countEvent(WakeupEvent ev)62 public void countEvent(WakeupEvent ev) { 63 totalWakeups++; 64 switch (ev.uid) { 65 case Process.ROOT_UID: 66 rootWakeups++; 67 break; 68 case Process.SYSTEM_UID: 69 systemWakeups++; 70 break; 71 case NO_UID: 72 noUidWakeups++; 73 break; 74 default: 75 if (ev.uid >= Process.FIRST_APPLICATION_UID) { 76 applicationWakeups++; 77 } else { 78 nonApplicationWakeups++; 79 } 80 break; 81 } 82 83 switch (ev.dstHwAddr.getAddressType()) { 84 case MacAddress.TYPE_UNICAST: 85 l2UnicastCount++; 86 break; 87 case MacAddress.TYPE_MULTICAST: 88 l2MulticastCount++; 89 break; 90 case MacAddress.TYPE_BROADCAST: 91 l2BroadcastCount++; 92 break; 93 default: 94 break; 95 } 96 97 increment(ethertypes, ev.ethertype); 98 if (ev.ipNextHeader >= 0) { 99 increment(ipNextHeaders, ev.ipNextHeader); 100 } 101 } 102 103 @Override toString()104 public String toString() { 105 updateDuration(); 106 StringJoiner j = new StringJoiner(", ", "WakeupStats(", ")"); 107 j.add(iface); 108 j.add("" + durationSec + "s"); 109 j.add("total: " + totalWakeups); 110 j.add("root: " + rootWakeups); 111 j.add("system: " + systemWakeups); 112 j.add("apps: " + applicationWakeups); 113 j.add("non-apps: " + nonApplicationWakeups); 114 j.add("no uid: " + noUidWakeups); 115 j.add(String.format("l2 unicast/multicast/broadcast: %d/%d/%d", 116 l2UnicastCount, l2MulticastCount, l2BroadcastCount)); 117 for (int i = 0; i < ethertypes.size(); i++) { 118 int eth = ethertypes.keyAt(i); 119 int count = ethertypes.valueAt(i); 120 j.add(String.format("ethertype 0x%x: %d", eth, count)); 121 } 122 for (int i = 0; i < ipNextHeaders.size(); i++) { 123 int proto = ipNextHeaders.keyAt(i); 124 int count = ipNextHeaders.valueAt(i); 125 j.add(String.format("ipNxtHdr %d: %d", proto, count)); 126 } 127 return j.toString(); 128 } 129 increment(SparseIntArray counters, int key)130 private static void increment(SparseIntArray counters, int key) { 131 int newcount = counters.get(key, 0) + 1; 132 counters.put(key, newcount); 133 } 134 } 135