Home | History | Annotate | Download | only in metrics
      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 
     52     public WakeupStats(String iface) {
     53         this.iface = iface;
     54     }
     55 
     56     /** Update durationSec with current time. */
     57     public void updateDuration() {
     58         durationSec = (SystemClock.elapsedRealtime() - creationTimeMs) / 1000;
     59     }
     60 
     61     /** Update wakeup counters for the given WakeupEvent. */
     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
    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 
    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