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