112d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach/* 212d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * Copyright (C) 2018 The Android Open Source Project 312d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * 412d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * Licensed under the Apache License, Version 2.0 (the "License"); 512d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * you may not use this file except in compliance with the License. 612d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * You may obtain a copy of the License at 712d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * 812d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * http://www.apache.org/licenses/LICENSE-2.0 912d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * 1012d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * Unless required by applicable law or agreed to in writing, software 1112d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * distributed under the License is distributed on an "AS IS" BASIS, 1212d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1312d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * See the License for the specific language governing permissions and 1412d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * limitations under the License. 1512d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach */ 1612d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbachpackage com.android.server.wifi; 1712d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 1812d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbachimport android.annotation.Nullable; 1912d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbachimport android.os.SystemClock; 2012d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 2112d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbachimport com.android.internal.annotations.GuardedBy; 2212d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbachimport com.android.internal.annotations.VisibleForTesting; 2312d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbachimport com.android.server.wifi.nano.WifiMetricsProto.WifiWakeStats; 2412d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 2512d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbachimport java.io.PrintWriter; 2612d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbachimport java.util.ArrayList; 2712d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbachimport java.util.List; 2812d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 2912d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach/** 3012d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * Holds WifiWake metrics and converts them to a protobuf included in WifiLog. 3112d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach */ 3212d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbachpublic class WifiWakeMetrics { 3312d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 3412d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach /** Maximum number of sessions to store in WifiWakeStats proto. */ 3512d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach @VisibleForTesting 3612d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach static final int MAX_RECORDED_SESSIONS = 10; 3712d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 3812d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach @GuardedBy("mLock") 3912d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach private final List<Session> mSessions = new ArrayList<>(); 4012d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach @GuardedBy("mLock") 4112d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach private Session mCurrentSession; 4212d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 4312d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach private boolean mIsInSession = false; 4412d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach private int mTotalSessions = 0; 45dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach private int mTotalWakeups = 0; 46dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach private int mIgnoredStarts = 0; 4712d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 4812d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach private final Object mLock = new Object(); 4912d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 5012d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach /** 5112d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * Records the beginning of a Wifi Wake session. 5212d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * 5312d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * <p>Starts the session. 5412d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * 55dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach * @param numNetworks The total number of networks stored in the WakeupLock at start. 5612d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach */ 5712d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach public void recordStartEvent(int numNetworks) { 5812d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach synchronized (mLock) { 5912d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach mCurrentSession = new Session(numNetworks, SystemClock.elapsedRealtime()); 6012d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach mIsInSession = true; 6112d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 6212d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 6312d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 6412d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach /** 65dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach * Records the initialize event of the current Wifi Wake session. 66dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach * 67dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach * <p>Note: The start event must be recorded before this event, otherwise this call will be 68dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach * ignored. 69dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach * 70dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach * @param numScans The total number of elapsed scans since start. 71dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach * @param numNetworks The total number of networks in the lock. 72dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach */ 73dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach public void recordInitializeEvent(int numScans, int numNetworks) { 74dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach synchronized (mLock) { 75dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach if (!mIsInSession) { 76dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach return; 77dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach } 78dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach mCurrentSession.recordInitializeEvent(numScans, numNetworks, 79dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach SystemClock.elapsedRealtime()); 80dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach } 81dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach } 82dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach 83dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach /** 8412d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * Records the unlock event of the current Wifi Wake session. 8512d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * 8612d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * <p>The unlock event occurs when the WakeupLock has all of its networks removed. This event 87dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach * will not be recorded if the initialize event recorded 0 locked networks. 8812d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * 8912d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * <p>Note: The start event must be recorded before this event, otherwise this call will be 9012d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * ignored. 9112d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * 9212d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * @param numScans The total number of elapsed scans since start. 9312d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach */ 9412d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach public void recordUnlockEvent(int numScans) { 9512d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach synchronized (mLock) { 9612d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach if (!mIsInSession) { 9712d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach return; 9812d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 9912d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach mCurrentSession.recordUnlockEvent(numScans, SystemClock.elapsedRealtime()); 10012d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 10112d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 10212d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 10312d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach /** 10412d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * Records the wakeup event of the current Wifi Wake session. 10512d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * 10612d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * <p>The wakeup event occurs when Wifi is re-enabled by the WakeupController. 10712d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * 10812d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * <p>Note: The start event must be recorded before this event, otherwise this call will be 10912d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * ignored. 11012d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * 11112d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * @param numScans The total number of elapsed scans since start. 11212d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach */ 11312d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach public void recordWakeupEvent(int numScans) { 11412d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach synchronized (mLock) { 11512d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach if (!mIsInSession) { 11612d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach return; 11712d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 11812d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach mCurrentSession.recordWakeupEvent(numScans, SystemClock.elapsedRealtime()); 11912d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 12012d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 12112d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 12212d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach /** 12312d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * Records the reset event of the current Wifi Wake session. 12412d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * 12512d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * <p>The reset event occurs when Wifi enters client mode. Stores the first 12612d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * {@link #MAX_RECORDED_SESSIONS} in the session list. 12712d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * 12812d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * <p>Note: The start event must be recorded before this event, otherwise this call will be 12912d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * ignored. This event ends the current session. 13012d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * 13112d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * @param numScans The total number of elapsed scans since start. 13212d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach */ 13312d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach public void recordResetEvent(int numScans) { 13412d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach synchronized (mLock) { 13512d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach if (!mIsInSession) { 13612d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach return; 13712d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 13812d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach mCurrentSession.recordResetEvent(numScans, SystemClock.elapsedRealtime()); 13912d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 140dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach // tally successful wakeups here since this is the actual point when wifi is turned on 141dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach if (mCurrentSession.hasWakeupTriggered()) { 142dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach mTotalWakeups++; 143dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach } 144dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach 14512d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach mTotalSessions++; 14612d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach if (mSessions.size() < MAX_RECORDED_SESSIONS) { 14712d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach mSessions.add(mCurrentSession); 14812d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 14912d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach mIsInSession = false; 15012d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 15112d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 15212d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 15312d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach /** 154dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach * Records instance of the start event being ignored due to the controller already being active. 155dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach */ 156dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach public void recordIgnoredStart() { 157dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach mIgnoredStarts++; 158dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach } 159dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach 160dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach /** 16112d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * Returns the consolidated WifiWakeStats proto for WifiMetrics. 16212d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach */ 16312d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach public WifiWakeStats buildProto() { 16412d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach WifiWakeStats proto = new WifiWakeStats(); 16512d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 16612d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach proto.numSessions = mTotalSessions; 167dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach proto.numWakeups = mTotalWakeups; 168dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach proto.numIgnoredStarts = mIgnoredStarts; 16912d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach proto.sessions = new WifiWakeStats.Session[mSessions.size()]; 17012d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 17112d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach for (int i = 0; i < mSessions.size(); i++) { 17212d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach proto.sessions[i] = mSessions.get(i).buildProto(); 17312d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 17412d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 17512d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach return proto; 17612d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 17712d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 17812d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach /** 17912d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * Dump all WifiWake stats to console (pw) 18012d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * @param pw 18112d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach */ 18212d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach public void dump(PrintWriter pw) { 18312d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach synchronized (mLock) { 18412d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach pw.println("-------WifiWake metrics-------"); 18512d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach pw.println("mTotalSessions: " + mTotalSessions); 186dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach pw.println("mTotalWakeups: " + mTotalWakeups); 187dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach pw.println("mIgnoredStarts: " + mIgnoredStarts); 18812d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach pw.println("mIsInSession: " + mIsInSession); 18912d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach pw.println("Stored Sessions: " + mSessions.size()); 19012d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach for (Session session : mSessions) { 19112d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach session.dump(pw); 19212d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 19312d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach if (mCurrentSession != null) { 19412d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach pw.println("Current Session: "); 19512d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach mCurrentSession.dump(pw); 19612d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 19712d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach pw.println("----end of WifiWake metrics----"); 19812d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 19912d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 20012d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 20112d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach /** 20212d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * Clears WifiWakeMetrics. 20312d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * 20412d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * <p>Keeps the current WifiWake session. 20512d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach */ 20612d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach public void clear() { 207dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach synchronized (mLock) { 208dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach mSessions.clear(); 209dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach mTotalSessions = 0; 210dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach mTotalWakeups = 0; 211dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach mIgnoredStarts = 0; 212dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach } 21312d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 21412d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 21512d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach /** A single WifiWake session. */ 21612d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach public static class Session { 21712d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 21812d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach private final long mStartTimestamp; 219dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach private final int mStartNetworks; 220dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach private int mInitializeNetworks = 0; 22112d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 22212d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach @VisibleForTesting 22312d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach @Nullable 22412d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach Event mUnlockEvent; 22512d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach @VisibleForTesting 22612d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach @Nullable 227dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach Event mInitEvent; 228dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach @VisibleForTesting 229dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach @Nullable 23012d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach Event mWakeupEvent; 23112d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach @VisibleForTesting 23212d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach @Nullable 23312d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach Event mResetEvent; 23412d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 23512d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach /** Creates a new WifiWake session. */ 23612d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach public Session(int numNetworks, long timestamp) { 237dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach mStartNetworks = numNetworks; 23812d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach mStartTimestamp = timestamp; 23912d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 24012d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 24112d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach /** 242dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach * Records an initialize event. 243dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach * 244dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach * <p>Ignores subsequent calls. 245dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach * 246dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach * @param numScans Total number of scans at the time of this event. 247dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach * @param numNetworks Total number of networks in the lock. 248dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach * @param timestamp The timestamp of the event. 249dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach */ 250dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach public void recordInitializeEvent(int numScans, int numNetworks, long timestamp) { 251dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach if (mInitEvent == null) { 252dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach mInitializeNetworks = numNetworks; 253dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach mInitEvent = new Event(numScans, timestamp - mStartTimestamp); 254dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach } 255dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach } 256dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach 257dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach /** 25812d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * Records an unlock event. 25912d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * 26012d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * <p>Ignores subsequent calls. 26112d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * 26212d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * @param numScans Total number of scans at the time of this event. 26312d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * @param timestamp The timestamp of the event. 26412d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach */ 26512d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach public void recordUnlockEvent(int numScans, long timestamp) { 26612d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach if (mUnlockEvent == null) { 26712d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach mUnlockEvent = new Event(numScans, timestamp - mStartTimestamp); 26812d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 26912d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 27012d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 27112d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach /** 27212d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * Records a wakeup event. 27312d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * 27412d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * <p>Ignores subsequent calls. 27512d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * 27612d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * @param numScans Total number of scans at the time of this event. 27712d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * @param timestamp The timestamp of the event. 27812d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach */ 27912d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach public void recordWakeupEvent(int numScans, long timestamp) { 28012d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach if (mWakeupEvent == null) { 28112d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach mWakeupEvent = new Event(numScans, timestamp - mStartTimestamp); 28212d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 28312d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 28412d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 28512d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach /** 286dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach * Returns whether the current session has had its wakeup event triggered. 287dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach */ 288dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach public boolean hasWakeupTriggered() { 289dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach return mWakeupEvent != null; 290dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach } 291dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach 292dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach /** 29312d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * Records a reset event. 29412d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * 29512d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * <p>Ignores subsequent calls. 29612d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * 29712d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * @param numScans Total number of scans at the time of this event. 29812d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach * @param timestamp The timestamp of the event. 29912d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach */ 30012d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach public void recordResetEvent(int numScans, long timestamp) { 30112d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach if (mResetEvent == null) { 30212d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach mResetEvent = new Event(numScans, timestamp - mStartTimestamp); 30312d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 30412d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 30512d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 30612d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach /** Returns the proto representation of this session. */ 30712d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach public WifiWakeStats.Session buildProto() { 30812d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach WifiWakeStats.Session sessionProto = new WifiWakeStats.Session(); 30912d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach sessionProto.startTimeMillis = mStartTimestamp; 310dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach sessionProto.lockedNetworksAtStart = mStartNetworks; 31112d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 312dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach if (mInitEvent != null) { 313dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach sessionProto.lockedNetworksAtInitialize = mInitializeNetworks; 314dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach sessionProto.initializeEvent = mInitEvent.buildProto(); 315dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach } 31612d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach if (mUnlockEvent != null) { 31712d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach sessionProto.unlockEvent = mUnlockEvent.buildProto(); 31812d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 31912d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach if (mWakeupEvent != null) { 32012d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach sessionProto.wakeupEvent = mWakeupEvent.buildProto(); 32112d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 32212d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach if (mResetEvent != null) { 32312d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach sessionProto.resetEvent = mResetEvent.buildProto(); 32412d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 32512d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 32612d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach return sessionProto; 32712d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 32812d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 32912d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach /** Dumps the current state of the session. */ 33012d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach public void dump(PrintWriter pw) { 33112d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach pw.println("WifiWakeMetrics.Session:"); 33212d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach pw.println("mStartTimestamp: " + mStartTimestamp); 333dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach pw.println("mStartNetworks: " + mStartNetworks); 334dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach pw.println("mInitializeNetworks: " + mInitializeNetworks); 335dca47232ea69a4501318b4dfb69db69e1216694fEric Schwarzenbach pw.println("mInitEvent: " + (mInitEvent == null ? "{}" : mInitEvent.toString())); 33612d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach pw.println("mUnlockEvent: " + (mUnlockEvent == null ? "{}" : mUnlockEvent.toString())); 33712d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach pw.println("mWakeupEvent: " + (mWakeupEvent == null ? "{}" : mWakeupEvent.toString())); 33812d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach pw.println("mResetEvent: " + (mResetEvent == null ? "{}" : mResetEvent.toString())); 33912d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 34012d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 34112d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 34212d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach /** An event in a WifiWake session. */ 34312d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach public static class Event { 34412d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 34512d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach /** Total number of scans that have elapsed prior to this event. */ 34612d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach public final int mNumScans; 34712d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach /** Total elapsed time in milliseconds at the instant of this event. */ 34812d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach public final long mElapsedTime; 34912d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 35012d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach public Event(int numScans, long elapsedTime) { 35112d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach mNumScans = numScans; 35212d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach mElapsedTime = elapsedTime; 35312d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 35412d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 35512d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach /** Returns the proto representation of this event. */ 35612d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach public WifiWakeStats.Session.Event buildProto() { 35712d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach WifiWakeStats.Session.Event eventProto = new WifiWakeStats.Session.Event(); 35812d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach eventProto.elapsedScans = mNumScans; 35912d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach eventProto.elapsedTimeMillis = mElapsedTime; 36012d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach return eventProto; 36112d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 36212d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach 36312d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach @Override 36412d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach public String toString() { 36512d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach return "{ mNumScans: " + mNumScans + ", elapsedTime: " + mElapsedTime + " }"; 36612d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 36712d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach } 36812d31e7fea8e5c17dddc0ab433c26c31a3bf2550Eric Schwarzenbach} 369