102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen/*
202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen * Copyright (C) 2018 The Android Open Source Project
302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen *
402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen * Licensed under the Apache License, Version 2.0 (the "License");
502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen * you may not use this file except in compliance with the License.
602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen * You may obtain a copy of the License at
702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen *
802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen *      http://www.apache.org/licenses/LICENSE-2.0
902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen *
1002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen * Unless required by applicable law or agreed to in writing, software
1102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen * distributed under the License is distributed on an "AS IS" BASIS,
1202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen * See the License for the specific language governing permissions and
1402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen * limitations under the License.
1502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen */
1602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
1702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohenpackage com.android.server.wifi.rtt;
1802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
1902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohenimport static com.android.server.wifi.util.MetricsUtils.addValueToLinearHistogram;
2002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohenimport static com.android.server.wifi.util.MetricsUtils.addValueToLogHistogram;
2102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohenimport static com.android.server.wifi.util.MetricsUtils.linearHistogramToGenericBuckets;
2202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohenimport static com.android.server.wifi.util.MetricsUtils.logHistogramToGenericBuckets;
2302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
2402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohenimport android.hardware.wifi.V1_0.RttResult;
2502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohenimport android.hardware.wifi.V1_0.RttStatus;
2602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohenimport android.net.MacAddress;
2702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohenimport android.net.wifi.rtt.RangingRequest;
2802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohenimport android.net.wifi.rtt.ResponderConfig;
2902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohenimport android.os.WorkSource;
3002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohenimport android.util.Log;
3102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohenimport android.util.SparseArray;
3202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohenimport android.util.SparseIntArray;
3302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
3402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohenimport com.android.server.wifi.Clock;
3502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohenimport com.android.server.wifi.nano.WifiMetricsProto;
3602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohenimport com.android.server.wifi.util.MetricsUtils;
3702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
3802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohenimport java.io.FileDescriptor;
3902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohenimport java.io.PrintWriter;
4002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohenimport java.util.HashMap;
4102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohenimport java.util.List;
4202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohenimport java.util.Map;
4302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
4402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen/**
4502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen * Wi-Fi RTT metric container/processor.
4602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen */
4702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohenpublic class RttMetrics {
4802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    private static final String TAG = "RttMetrics";
4902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    private static final boolean VDBG = false;
5002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    /* package */ boolean mDbg = false;
5102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
5202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    private final Object mLock = new Object();
5302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    private final Clock mClock;
5402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
5502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    // accumulated metrics data
5602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
5702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    // Histogram: 7 buckets (i=0, ..., 6) of 1 slots in range 10^i -> 10^(i+1)
5802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    // Buckets:
5902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    //    1 -> 10
6002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    //    10 -> 100
6102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    //    100 -> 1000
6202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    //    10^3 -> 10^4
6302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    //    10^4 -> 10^5
6402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    //    10^5 -> 10^6
6502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    //    10^5 -> 10^7 (10^7 ms = 160 minutes)
6602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    private static final MetricsUtils.LogHistParms COUNT_LOG_HISTOGRAM =
6702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            new MetricsUtils.LogHistParms(0, 1, 10, 1, 7);
6802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
6902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    // Histogram for ranging limits in discovery. Indicates the following 7 buckets (in meters):
7002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    //   < 0
7102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    //   [0, 5)
7202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    //   [5, 15)
7302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    //   [15, 30)
7402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    //   [30, 60)
7502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    //   [60, 100)
7602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    //   >= 100
7702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    private static final int[] DISTANCE_MM_HISTOGRAM =
7802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            {0, 5 * 1000, 15 * 1000, 30 * 1000, 60 * 1000, 100 * 1000};
7902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
8002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    private static final int PEER_AP = 0;
8102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    private static final int PEER_AWARE = 1;
8202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
8302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    private int mNumStartRangingCalls = 0;
8402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    private SparseIntArray mOverallStatusHistogram = new SparseIntArray();
8502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    private PerPeerTypeInfo[] mPerPeerTypeInfo;
8602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
8702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    public RttMetrics(Clock clock) {
8802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        mClock = clock;
8902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
9002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        mPerPeerTypeInfo = new PerPeerTypeInfo[2];
9102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        mPerPeerTypeInfo[PEER_AP] = new PerPeerTypeInfo();
9202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        mPerPeerTypeInfo[PEER_AWARE] = new PerPeerTypeInfo();
9302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    }
9402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
9502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    private class PerUidInfo {
9602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        public int numRequests;
9702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        public long lastRequestMs;
9802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
9902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        @Override
10002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        public String toString() {
10102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            return "numRequests=" + numRequests + ", lastRequestMs=" + lastRequestMs;
10202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        }
10302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    }
10402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
10502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    private class PerPeerTypeInfo {
10602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        public int numCalls;
10702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        public int numIndividualCalls;
10802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        public SparseArray<PerUidInfo> perUidInfo = new SparseArray<>();
10902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        public SparseIntArray numRequestsHistogram = new SparseIntArray();
11002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        public SparseIntArray requestGapHistogram = new SparseIntArray();
11102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        public SparseIntArray statusHistogram = new SparseIntArray();
11202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        public SparseIntArray measuredDistanceHistogram = new SparseIntArray();
11302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
11402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        @Override
11502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        public String toString() {
11602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            return "numCalls=" + numCalls + ", numIndividualCalls=" + numIndividualCalls
11702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                    + ", perUidInfo=" + perUidInfo + ", numRequestsHistogram="
11802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                    + numRequestsHistogram + ", requestGapHistogram=" + requestGapHistogram
11902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                    + ", measuredDistanceHistogram=" + measuredDistanceHistogram;
12002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        }
12102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    }
12202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
12302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    // metric recording API
12402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
12502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    /**
12602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen     * Record metrics for the range request.
12702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen     */
12802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    public void recordRequest(WorkSource ws, RangingRequest requests) {
12902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        mNumStartRangingCalls++;
13002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
13102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        int numApRequests = 0;
13202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        int numAwareRequests = 0;
13302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        for (ResponderConfig request : requests.mRttPeers) {
13402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            if (request == null) {
13502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                continue;
13602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            }
13702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            if (request.responderType == ResponderConfig.RESPONDER_AWARE) {
13802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                numAwareRequests++;
13902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            } else if (request.responderType == ResponderConfig.RESPONDER_AP) {
14002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                numApRequests++;
14102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            } else {
14202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                if (mDbg) Log.d(TAG, "Unexpected Responder type: " + request.responderType);
14302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            }
14402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        }
14502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
14602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        updatePeerInfoWithRequestInfo(mPerPeerTypeInfo[PEER_AP], ws, numApRequests);
14702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        updatePeerInfoWithRequestInfo(mPerPeerTypeInfo[PEER_AWARE], ws, numAwareRequests);
14802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    }
14902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
15002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    /**
15102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen     * Record metrics for the range results.
15202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen     */
15302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    public void recordResult(RangingRequest requests, List<RttResult> results) {
15402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        Map<MacAddress, ResponderConfig> requestEntries = new HashMap<>();
15502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        for (ResponderConfig responder : requests.mRttPeers) {
15602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            requestEntries.put(responder.macAddress, responder);
15702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        }
15802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
15902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        if (results != null) {
16002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            for (RttResult result : results) {
16102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                if (result == null) {
16202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                    continue;
16302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                }
16402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                ResponderConfig responder = requestEntries.remove(
16502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                        MacAddress.fromBytes(result.addr));
16602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                if (responder == null) {
16702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                    Log.e(TAG,
16802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                            "recordResult: found a result which doesn't match any requests: "
16902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                                    + result);
17002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                    continue;
17102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                }
17202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
17302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                if (responder.responderType == ResponderConfig.RESPONDER_AP) {
17402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                    updatePeerInfoWithResultInfo(mPerPeerTypeInfo[PEER_AP], result);
17502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                } else if (responder.responderType == ResponderConfig.RESPONDER_AWARE) {
17602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                    updatePeerInfoWithResultInfo(mPerPeerTypeInfo[PEER_AWARE], result);
17702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                } else {
17802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                    Log.e(TAG, "recordResult: unexpected peer type in responder: " + responder);
17902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                }
18002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            }
18102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        }
18202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
18302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        for (ResponderConfig responder : requestEntries.values()) {
18402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            PerPeerTypeInfo peerInfo;
18502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            if (responder.responderType == ResponderConfig.RESPONDER_AP) {
18602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                peerInfo = mPerPeerTypeInfo[PEER_AP];
18702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            } else if (responder.responderType == ResponderConfig.RESPONDER_AWARE) {
18802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                peerInfo = mPerPeerTypeInfo[PEER_AWARE];
18902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            } else {
19002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                Log.e(TAG, "recordResult: unexpected peer type in responder: " + responder);
19102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                continue;
19202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            }
19302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            peerInfo.statusHistogram.put(WifiMetricsProto.WifiRttLog.MISSING_RESULT,
19402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                    peerInfo.statusHistogram.get(WifiMetricsProto.WifiRttLog.MISSING_RESULT) + 1);
19502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        }
19602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    }
19702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
19802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    /**
19902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen     * Record metrics for the overall ranging request status.
20002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen     */
20102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    public void recordOverallStatus(int status) {
20202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        mOverallStatusHistogram.put(status, mOverallStatusHistogram.get(status) + 1);
20302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    }
20402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
20502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    private void updatePeerInfoWithRequestInfo(PerPeerTypeInfo peerInfo, WorkSource ws,
20602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            int numIndividualCalls) {
20702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        if (numIndividualCalls == 0) {
20802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            return;
20902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        }
21002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
21102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        long nowMs = mClock.getElapsedSinceBootMillis();
21202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        peerInfo.numCalls++;
21302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        peerInfo.numIndividualCalls += numIndividualCalls;
21402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        peerInfo.numRequestsHistogram.put(numIndividualCalls,
21502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                peerInfo.numRequestsHistogram.get(numIndividualCalls) + 1);
21602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        boolean recordedIntervals = false;
21702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
21802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        for (int i = 0; i < ws.size(); ++i) {
21902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            int uid = ws.get(i);
22002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
22102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            PerUidInfo perUidInfo = peerInfo.perUidInfo.get(uid);
22202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            if (perUidInfo == null) {
22302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                perUidInfo = new PerUidInfo();
22402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            }
22502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
22602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            perUidInfo.numRequests++;
22702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
22802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            if (!recordedIntervals && perUidInfo.lastRequestMs != 0) {
22902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                recordedIntervals = true; // don't want to record twice
23002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                addValueToLogHistogram(nowMs - perUidInfo.lastRequestMs,
23102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                        peerInfo.requestGapHistogram, COUNT_LOG_HISTOGRAM);
23202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            }
23302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            perUidInfo.lastRequestMs = nowMs;
23402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
23502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            peerInfo.perUidInfo.put(uid, perUidInfo);
23602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        }
23702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    }
23802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
23902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    private void updatePeerInfoWithResultInfo(PerPeerTypeInfo peerInfo, RttResult result) {
24002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        int protoStatus = convertRttStatusTypeToProtoEnum(result.status);
24102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        peerInfo.statusHistogram.put(protoStatus, peerInfo.statusHistogram.get(protoStatus) + 1);
24202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        addValueToLinearHistogram(result.distanceInMm, peerInfo.measuredDistanceHistogram,
24302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                DISTANCE_MM_HISTOGRAM);
24402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    }
24502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
24602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    /**
24702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen     * Consolidate all metrics into the proto.
24802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen     */
24902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    public WifiMetricsProto.WifiRttLog consolidateProto() {
25002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        WifiMetricsProto.WifiRttLog log = new WifiMetricsProto.WifiRttLog();
25102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        log.rttToAp = new WifiMetricsProto.WifiRttLog.RttToPeerLog();
25202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        log.rttToAware = new WifiMetricsProto.WifiRttLog.RttToPeerLog();
25302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        synchronized (mLock) {
25402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            log.numRequests = mNumStartRangingCalls;
25502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            log.histogramOverallStatus = consolidateOverallStatus(mOverallStatusHistogram);
25602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
25702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            consolidatePeerType(log.rttToAp, mPerPeerTypeInfo[PEER_AP]);
25802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            consolidatePeerType(log.rttToAware, mPerPeerTypeInfo[PEER_AWARE]);
25902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        }
26002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        return log;
26102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    }
26202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
26302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    private WifiMetricsProto.WifiRttLog.RttOverallStatusHistogramBucket[] consolidateOverallStatus(
26402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            SparseIntArray histogram) {
26502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        WifiMetricsProto.WifiRttLog.RttOverallStatusHistogramBucket[] h =
26602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                new WifiMetricsProto.WifiRttLog.RttOverallStatusHistogramBucket[histogram.size()];
26702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        for (int i = 0; i < histogram.size(); i++) {
26802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            h[i] = new WifiMetricsProto.WifiRttLog.RttOverallStatusHistogramBucket();
26902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            h[i].statusType = histogram.keyAt(i);
27002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            h[i].count = histogram.valueAt(i);
27102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        }
27202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        return h;
27302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    }
27402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
27502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    private void consolidatePeerType(WifiMetricsProto.WifiRttLog.RttToPeerLog peerLog,
27602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            PerPeerTypeInfo peerInfo) {
27702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        peerLog.numRequests = peerInfo.numCalls;
27802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        peerLog.numIndividualRequests = peerInfo.numIndividualCalls;
27902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        peerLog.numApps = peerInfo.perUidInfo.size();
28002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        peerLog.histogramNumPeersPerRequest = consolidateNumPeersPerRequest(
28102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                peerInfo.numRequestsHistogram);
28202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        peerLog.histogramNumRequestsPerApp = consolidateNumRequestsPerApp(peerInfo.perUidInfo);
28302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        peerLog.histogramRequestIntervalMs = genericBucketsToRttBuckets(
28402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                logHistogramToGenericBuckets(peerInfo.requestGapHistogram, COUNT_LOG_HISTOGRAM));
28502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        peerLog.histogramIndividualStatus = consolidateIndividualStatus(peerInfo.statusHistogram);
28602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        peerLog.histogramDistance = genericBucketsToRttBuckets(
28702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                linearHistogramToGenericBuckets(peerInfo.measuredDistanceHistogram,
28802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                        DISTANCE_MM_HISTOGRAM));
28902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    }
29002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
29102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    private WifiMetricsProto.WifiRttLog.RttIndividualStatusHistogramBucket[]
29202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            consolidateIndividualStatus(SparseIntArray histogram) {
29302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        WifiMetricsProto.WifiRttLog.RttIndividualStatusHistogramBucket[] h =
29402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                new WifiMetricsProto.WifiRttLog.RttIndividualStatusHistogramBucket[histogram.size(
29502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                )];
29602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        for (int i = 0; i < histogram.size(); i++) {
29702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            h[i] = new WifiMetricsProto.WifiRttLog.RttIndividualStatusHistogramBucket();
29802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            h[i].statusType = histogram.keyAt(i);
29902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            h[i].count = histogram.valueAt(i);
30002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        }
30102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        return h;
30202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    }
30302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
30402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    private WifiMetricsProto.WifiRttLog.HistogramBucket[] consolidateNumPeersPerRequest(
30502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            SparseIntArray data) {
30602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        WifiMetricsProto.WifiRttLog.HistogramBucket[] protoArray =
30702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                new WifiMetricsProto.WifiRttLog.HistogramBucket[data.size()];
30802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
30902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        for (int i = 0; i < data.size(); i++) {
31002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            protoArray[i] = new WifiMetricsProto.WifiRttLog.HistogramBucket();
31102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            protoArray[i].start = data.keyAt(i);
31202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            protoArray[i].end = data.keyAt(i);
31302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            protoArray[i].count = data.valueAt(i);
31402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        }
31502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
31602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        return protoArray;
31702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    }
31802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
31902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    private WifiMetricsProto.WifiRttLog.HistogramBucket[] consolidateNumRequestsPerApp(
32002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            SparseArray<PerUidInfo> perUidInfos) {
32102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        SparseIntArray histogramNumRequestsPerUid = new SparseIntArray();
32202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        for (int i = 0; i < perUidInfos.size(); i++) {
32302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            addValueToLogHistogram(perUidInfos.valueAt(i).numRequests, histogramNumRequestsPerUid,
32402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                    COUNT_LOG_HISTOGRAM);
32502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        }
32602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
32702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        return genericBucketsToRttBuckets(logHistogramToGenericBuckets(
32802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                histogramNumRequestsPerUid, COUNT_LOG_HISTOGRAM));
32902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    }
33002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
33102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    private WifiMetricsProto.WifiRttLog.HistogramBucket[] genericBucketsToRttBuckets(
33202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            MetricsUtils.GenericBucket[] genericHistogram) {
33302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        WifiMetricsProto.WifiRttLog.HistogramBucket[] histogram =
33402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                new WifiMetricsProto.WifiRttLog.HistogramBucket[genericHistogram.length];
33502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        for (int i = 0; i < genericHistogram.length; i++) {
33602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            histogram[i] = new WifiMetricsProto.WifiRttLog.HistogramBucket();
33702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            histogram[i].start = genericHistogram[i].start;
33802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            histogram[i].end = genericHistogram[i].end;
33902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            histogram[i].count = genericHistogram[i].count;
34002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        }
34102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        return histogram;
34202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    }
34302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
34402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    /**
34502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen     * Dump all RttMetrics to console (pw) - this method is never called to dump the serialized
34602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen     * metrics (handled by parent WifiMetrics).
34702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen     *
34802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen     * @param fd   unused
34902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen     * @param pw   PrintWriter for writing dump to
35002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen     * @param args unused
35102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen     */
35202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
35302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        synchronized (mLock) {
35402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            pw.println("RTT Metrics:");
35502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            pw.println("mNumStartRangingCalls:" + mNumStartRangingCalls);
35602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            pw.println("mOverallStatusHistogram:" + mOverallStatusHistogram);
35702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            pw.println("AP:" + mPerPeerTypeInfo[PEER_AP]);
35802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            pw.println("AWARE:" + mPerPeerTypeInfo[PEER_AWARE]);
35902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        }
36002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    }
36102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
36202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    /**
36302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen     * clear Wi-Fi RTT metrics
36402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen     */
36502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    public void clear() {
36602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        synchronized (mLock) {
36702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            mNumStartRangingCalls = 0;
36802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            mOverallStatusHistogram.clear();
36902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            mPerPeerTypeInfo[PEER_AP] = new PerPeerTypeInfo();
37002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            mPerPeerTypeInfo[PEER_AWARE] = new PerPeerTypeInfo();
37102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        }
37202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    }
37302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen
37402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    /**
37502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen     * Convert a HAL RttStatus enum to a Metrics proto enum RttIndividualStatusTypeEnum.
37602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen     */
37702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    public static int convertRttStatusTypeToProtoEnum(int rttStatusType) {
37802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        switch (rttStatusType) {
37902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            case RttStatus.SUCCESS:
38002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                return WifiMetricsProto.WifiRttLog.SUCCESS;
38102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            case RttStatus.FAILURE:
38202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                return WifiMetricsProto.WifiRttLog.FAILURE;
38302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            case RttStatus.FAIL_NO_RSP:
38402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                return WifiMetricsProto.WifiRttLog.FAIL_NO_RSP;
38502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            case RttStatus.FAIL_REJECTED:
38602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                return WifiMetricsProto.WifiRttLog.FAIL_REJECTED;
38702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            case RttStatus.FAIL_NOT_SCHEDULED_YET:
38802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                return WifiMetricsProto.WifiRttLog.FAIL_NOT_SCHEDULED_YET;
38902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            case RttStatus.FAIL_TM_TIMEOUT:
39002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                return WifiMetricsProto.WifiRttLog.FAIL_TM_TIMEOUT;
39102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            case RttStatus.FAIL_AP_ON_DIFF_CHANNEL:
39202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                return WifiMetricsProto.WifiRttLog.FAIL_AP_ON_DIFF_CHANNEL;
39302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            case RttStatus.FAIL_NO_CAPABILITY:
39402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                return WifiMetricsProto.WifiRttLog.FAIL_NO_CAPABILITY;
39502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            case RttStatus.ABORTED:
39602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                return WifiMetricsProto.WifiRttLog.ABORTED;
39702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            case RttStatus.FAIL_INVALID_TS:
39802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                return WifiMetricsProto.WifiRttLog.FAIL_INVALID_TS;
39902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            case RttStatus.FAIL_PROTOCOL:
40002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                return WifiMetricsProto.WifiRttLog.FAIL_PROTOCOL;
40102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            case RttStatus.FAIL_SCHEDULE:
40202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                return WifiMetricsProto.WifiRttLog.FAIL_SCHEDULE;
40302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            case RttStatus.FAIL_BUSY_TRY_LATER:
40402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                return WifiMetricsProto.WifiRttLog.FAIL_BUSY_TRY_LATER;
40502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            case RttStatus.INVALID_REQ:
40602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                return WifiMetricsProto.WifiRttLog.INVALID_REQ;
40702e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            case RttStatus.NO_WIFI:
40802e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                return WifiMetricsProto.WifiRttLog.NO_WIFI;
40902e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            case RttStatus.FAIL_FTM_PARAM_OVERRIDE:
41002e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                return WifiMetricsProto.WifiRttLog.FAIL_FTM_PARAM_OVERRIDE;
41102e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen            default:
41202e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                Log.e(TAG, "Unrecognized RttStatus: " + rttStatusType);
41302e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen                return WifiMetricsProto.WifiRttLog.UNKNOWN;
41402e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen        }
41502e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen    }
41602e1422fc015b3dc38f8afdfb8e1aec95881fefcEtan Cohen}
417