1910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen/*
2910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen * Copyright (C) 2017 The Android Open Source Project
3910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen *
4910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen * Licensed under the Apache License, Version 2.0 (the "License");
5910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen * you may not use this file except in compliance with the License.
6910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen * You may obtain a copy of the License at
7910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen *
8910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen *      http://www.apache.org/licenses/LICENSE-2.0
9910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen *
10910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen * Unless required by applicable law or agreed to in writing, software
11910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen * distributed under the License is distributed on an "AS IS" BASIS,
12910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen * See the License for the specific language governing permissions and
14910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen * limitations under the License.
15910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen */
16910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen
17910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohenpackage com.android.server.wifi.aware;
18910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen
19910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohenimport static com.android.server.wifi.aware.WifiAwareMetrics.addNanHalStatusToHistogram;
20910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohenimport static com.android.server.wifi.aware.WifiAwareMetrics.histogramToProtoArray;
21910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen
22910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohenimport static org.hamcrest.core.IsEqual.equalTo;
23910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohenimport static org.mockito.Mockito.when;
24910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen
25a83967f56939392072253162731bfe090c2e7709Etan Cohenimport android.app.AppOpsManager;
26a83967f56939392072253162731bfe090c2e7709Etan Cohenimport android.content.Context;
27910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohenimport android.hardware.wifi.V1_0.NanStatusType;
28f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohenimport android.net.wifi.aware.WifiAwareNetworkSpecifier;
29a83967f56939392072253162731bfe090c2e7709Etan Cohenimport android.util.Log;
30a83967f56939392072253162731bfe090c2e7709Etan Cohenimport android.util.SparseArray;
31910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohenimport android.util.SparseIntArray;
32910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen
33910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohenimport com.android.server.wifi.Clock;
34910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohenimport com.android.server.wifi.nano.WifiMetricsProto;
355b09fc76e4a2e05c5e5a24e96ff29be2fd49ed9fEtan Cohenimport com.android.server.wifi.util.MetricsUtils;
36910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen
37910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohenimport org.junit.Before;
38910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohenimport org.junit.Rule;
39910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohenimport org.junit.Test;
40910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohenimport org.junit.rules.ErrorCollector;
41910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohenimport org.mockito.Mock;
42910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohenimport org.mockito.MockitoAnnotations;
43910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen
44a83967f56939392072253162731bfe090c2e7709Etan Cohenimport java.io.PrintWriter;
45a83967f56939392072253162731bfe090c2e7709Etan Cohenimport java.io.StringWriter;
46f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohenimport java.util.HashMap;
47f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohenimport java.util.Map;
48a83967f56939392072253162731bfe090c2e7709Etan Cohen
49910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen/**
50910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen * Unit test harness for WifiAwareMetrics
51910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen */
52910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohenpublic class WifiAwareMetricsTest {
53910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen    @Mock Clock mClock;
54a83967f56939392072253162731bfe090c2e7709Etan Cohen    @Mock private Context mMockContext;
55a83967f56939392072253162731bfe090c2e7709Etan Cohen    @Mock private AppOpsManager mMockAppOpsManager;
56910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen    @Rule public ErrorCollector collector = new ErrorCollector();
57910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen
58910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen    private WifiAwareMetrics mDut;
59910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen
60910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen    // Histogram definition: start[i] = b + p * m^i with s sub-buckets, i=0,...,n-1
61910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen
62910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen    /**
63910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen     * Histogram of following buckets, start[i] = 0 + 1 * 10^i with 9 sub-buckets, i=0,...,5
64910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen     * 1 - 10: 9 sub-buckets each of width 1
65910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen     * 10 - 100: 10
66910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen     * 100 - 10e3: 10^2
67910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen     * 10e3 - 10e4: 10^3
68910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen     * 10e4 - 10e5: 10^4
69910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen     * 10e5 - 10e6: 10^5
70910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen     */
715b09fc76e4a2e05c5e5a24e96ff29be2fd49ed9fEtan Cohen    private static final MetricsUtils.LogHistParms HIST1 = new MetricsUtils.LogHistParms(0, 1,
72910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen            10, 9, 6);
73910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen
74910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen    /**
75910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen     * Histogram of following buckets, start[i] = -20 + 2 * 5^i with 40 sub-buckets, i=0,...,2
76910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen     * -18 - -10: 40 sub-bucket each of width 0.2
77910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen     * -10 - 30: 1
78910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen     * 30 - 230: 5
79910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen     */
805b09fc76e4a2e05c5e5a24e96ff29be2fd49ed9fEtan Cohen    private static final MetricsUtils.LogHistParms HIST2 = new MetricsUtils.LogHistParms(-20, 2,
81910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen            5, 40, 3);
82910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen
8305dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen    // Linear histogram of following buckets:
8405dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen    //   <10
8505dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen    //   [10, 30)
8605dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen    //   [30, 60)
8705dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen    //   [60, 100)
8805dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen    //   >100
8905dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen    private static final int[] HIST_LINEAR = { 10, 30, 60, 100 };
9005dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen
91910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen    /**
92910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen     * Pre-test configuration. Initialize and install mocks.
93910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen     */
94910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen    @Before
95910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen    public void setUp() throws Exception {
96910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        MockitoAnnotations.initMocks(this);
97a83967f56939392072253162731bfe090c2e7709Etan Cohen        when(mMockContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mMockAppOpsManager);
98910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        setTime(0);
99910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen
100910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        mDut = new WifiAwareMetrics(mClock);
101910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen    }
102910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen
103910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen    /**
104910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen     * Validates that recordEnableUsage() and recordDisableUsage() record valid metrics.
105910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen     */
106910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen    @Test
107910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen    public void testEnableDisableUsageMetrics() {
108910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        WifiMetricsProto.WifiAwareLog log;
109910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen
110910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        // create 2 records
111910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        setTime(5);
112910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        mDut.recordEnableUsage();
113910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        setTime(10);
114910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        mDut.recordDisableUsage();
115910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        setTime(11);
116910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        mDut.recordEnableUsage();
117910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        setTime(12);
118910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        mDut.recordDisableUsage();
119910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen
120910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        setTime(14);
121910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        log = mDut.consolidateProto();
122910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        collector.checkThat(countAllHistogramSamples(log.histogramAwareAvailableDurationMs),
123910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen                equalTo(2));
124910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        validateProtoHistBucket("Duration[0] #1", log.histogramAwareAvailableDurationMs[0], 1, 2,
125910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen                1);
126910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        validateProtoHistBucket("Duration[1] #1", log.histogramAwareAvailableDurationMs[1], 5, 6,
127910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen                1);
128910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        collector.checkThat(log.availableTimeMs, equalTo(6L));
129910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen
130910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        // create another partial record
131910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        setTime(15);
132910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        mDut.recordEnableUsage();
133910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen
134910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        setTime(17);
135910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        log = mDut.consolidateProto();
136910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        collector.checkThat(countAllHistogramSamples(log.histogramAwareAvailableDurationMs),
137910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen                equalTo(2));
138910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        validateProtoHistBucket("Duration[0] #2", log.histogramAwareAvailableDurationMs[0], 1, 2,
139910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen                1);
140910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        validateProtoHistBucket("Duration[1] #2", log.histogramAwareAvailableDurationMs[1], 5, 6,
141910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen                1);
142910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        collector.checkThat(log.availableTimeMs, equalTo(8L)); // the partial record of 2ms
143910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen
144910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen
145910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        // clear and continue that partial record (verify completed)
146910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        mDut.clear();
147910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        setTime(23);
148910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        mDut.recordDisableUsage();
149910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen
150910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        log = mDut.consolidateProto();
151910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        collector.checkThat(countAllHistogramSamples(log.histogramAwareAvailableDurationMs),
152910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen                equalTo(1));
153910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        validateProtoHistBucket("Duration[0] #3", log.histogramAwareAvailableDurationMs[0], 8, 9,
154910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen                1);
155910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        collector.checkThat(log.availableTimeMs, equalTo(6L)); // the remnant record of 6ms
156910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen
157910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        // clear and verify empty records
158910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        mDut.clear();
159910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        log = mDut.consolidateProto();
160910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        collector.checkThat(countAllHistogramSamples(log.histogramAwareAvailableDurationMs),
161910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen                equalTo(0));
162910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen    }
163910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen
164da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen    /**
165da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen     * Validates that recordEnableAware() and recordDisableAware() record valid metrics.
166da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen     */
167da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen    @Test
168da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen    public void testEnableDisableAwareMetrics() {
169da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        WifiMetricsProto.WifiAwareLog log;
170da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen
171da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        // create 2 records
172da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        setTime(5);
173da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        mDut.recordEnableAware();
174da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        setTime(10);
175da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        mDut.recordDisableAware();
176da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        setTime(11);
177da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        mDut.recordEnableAware();
178da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        setTime(12);
179da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        mDut.recordDisableAware();
180da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen
181da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        setTime(14);
182da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        log = mDut.consolidateProto();
183da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        collector.checkThat(countAllHistogramSamples(log.histogramAwareEnabledDurationMs),
184da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen                equalTo(2));
185da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        validateProtoHistBucket("Duration[0] #1", log.histogramAwareEnabledDurationMs[0], 1, 2,
186da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen                1);
187da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        validateProtoHistBucket("Duration[1] #1", log.histogramAwareEnabledDurationMs[1], 5, 6,
188da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen                1);
189da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        collector.checkThat(log.enabledTimeMs, equalTo(6L));
190da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen
191da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        // create another partial record
192da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        setTime(15);
193da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        mDut.recordEnableAware();
194da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen
195da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        setTime(17);
196da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        log = mDut.consolidateProto();
197da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        collector.checkThat(countAllHistogramSamples(log.histogramAwareEnabledDurationMs),
198da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen                equalTo(2));
199da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        validateProtoHistBucket("Duration[0] #2", log.histogramAwareEnabledDurationMs[0], 1, 2,
200da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen                1);
201da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        validateProtoHistBucket("Duration[1] #2", log.histogramAwareEnabledDurationMs[1], 5, 6,
202da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen                1);
203da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        collector.checkThat(log.enabledTimeMs, equalTo(8L)); // the partial record of 2ms
204da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen
205da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen
206da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        // clear and continue that partial record (verify completed)
207da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        mDut.clear();
208da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        setTime(23);
209da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        mDut.recordDisableAware();
210da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen
211da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        log = mDut.consolidateProto();
212da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        collector.checkThat(countAllHistogramSamples(log.histogramAwareEnabledDurationMs),
213da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen                equalTo(1));
214da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        validateProtoHistBucket("Duration[0] #3", log.histogramAwareEnabledDurationMs[0], 8, 9,
215da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen                1);
216da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        collector.checkThat(log.enabledTimeMs, equalTo(6L)); // the remnant record of 6ms
217da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen
218da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        // clear and verify empty records
219da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        mDut.clear();
220da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        log = mDut.consolidateProto();
221da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen        collector.checkThat(countAllHistogramSamples(log.histogramAwareEnabledDurationMs),
222da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen                equalTo(0));
223da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen    }
224da389f4b673e0f3fe54dc5b1123221037eb96e42Etan Cohen
225a83967f56939392072253162731bfe090c2e7709Etan Cohen    @Test
226a83967f56939392072253162731bfe090c2e7709Etan Cohen    public void testAttachSessionMetrics() {
227a83967f56939392072253162731bfe090c2e7709Etan Cohen        final int uid1 = 1005;
228a83967f56939392072253162731bfe090c2e7709Etan Cohen        final int uid2 = 1006;
229a83967f56939392072253162731bfe090c2e7709Etan Cohen        final SparseArray<WifiAwareClientState> clients = new SparseArray<>();
230a83967f56939392072253162731bfe090c2e7709Etan Cohen        WifiMetricsProto.WifiAwareLog log;
231a83967f56939392072253162731bfe090c2e7709Etan Cohen
232a83967f56939392072253162731bfe090c2e7709Etan Cohen        setTime(5);
233a83967f56939392072253162731bfe090c2e7709Etan Cohen
234a83967f56939392072253162731bfe090c2e7709Etan Cohen        // uid1: session 1
235a83967f56939392072253162731bfe090c2e7709Etan Cohen        clients.put(10,
236a83967f56939392072253162731bfe090c2e7709Etan Cohen                new WifiAwareClientState(mMockContext, 10, uid1, 0, null, null, null, false,
237a83967f56939392072253162731bfe090c2e7709Etan Cohen                        mClock.getElapsedSinceBootMillis()));
238a83967f56939392072253162731bfe090c2e7709Etan Cohen        mDut.recordAttachSession(uid1, false, clients);
239a83967f56939392072253162731bfe090c2e7709Etan Cohen
240a83967f56939392072253162731bfe090c2e7709Etan Cohen        // uid1: session 2
241a83967f56939392072253162731bfe090c2e7709Etan Cohen        clients.put(11,
242a83967f56939392072253162731bfe090c2e7709Etan Cohen                new WifiAwareClientState(mMockContext, 11, uid1, 0, null, null, null, false,
243a83967f56939392072253162731bfe090c2e7709Etan Cohen                        mClock.getElapsedSinceBootMillis()));
244a83967f56939392072253162731bfe090c2e7709Etan Cohen        mDut.recordAttachSession(uid1, false, clients);
245a83967f56939392072253162731bfe090c2e7709Etan Cohen
246a83967f56939392072253162731bfe090c2e7709Etan Cohen        // uid2: session 1
247a83967f56939392072253162731bfe090c2e7709Etan Cohen        clients.put(12,
248a83967f56939392072253162731bfe090c2e7709Etan Cohen                new WifiAwareClientState(mMockContext, 12, uid2, 0, null, null, null, false,
249a83967f56939392072253162731bfe090c2e7709Etan Cohen                        mClock.getElapsedSinceBootMillis()));
250a83967f56939392072253162731bfe090c2e7709Etan Cohen        mDut.recordAttachSession(uid2, false, clients);
251a83967f56939392072253162731bfe090c2e7709Etan Cohen
252a83967f56939392072253162731bfe090c2e7709Etan Cohen        // uid2: session 2
253a83967f56939392072253162731bfe090c2e7709Etan Cohen        clients.put(13,
254a83967f56939392072253162731bfe090c2e7709Etan Cohen                new WifiAwareClientState(mMockContext, 13, uid2, 0, null, null, null, true,
255a83967f56939392072253162731bfe090c2e7709Etan Cohen                        mClock.getElapsedSinceBootMillis()));
256a83967f56939392072253162731bfe090c2e7709Etan Cohen        mDut.recordAttachSession(uid2, true, clients);
257a83967f56939392072253162731bfe090c2e7709Etan Cohen
258a83967f56939392072253162731bfe090c2e7709Etan Cohen        // uid2: delete session 1
259a83967f56939392072253162731bfe090c2e7709Etan Cohen        setTime(10);
260a83967f56939392072253162731bfe090c2e7709Etan Cohen        mDut.recordAttachSessionDuration(clients.get(12).getCreationTime());
261a83967f56939392072253162731bfe090c2e7709Etan Cohen        clients.delete(12);
262a83967f56939392072253162731bfe090c2e7709Etan Cohen
263a83967f56939392072253162731bfe090c2e7709Etan Cohen        // uid2: delete session 2
264a83967f56939392072253162731bfe090c2e7709Etan Cohen        setTime(15);
265a83967f56939392072253162731bfe090c2e7709Etan Cohen        mDut.recordAttachSessionDuration(clients.get(13).getCreationTime());
266a83967f56939392072253162731bfe090c2e7709Etan Cohen        clients.delete(13);
267a83967f56939392072253162731bfe090c2e7709Etan Cohen
268a83967f56939392072253162731bfe090c2e7709Etan Cohen        // uid2: session 3
269a83967f56939392072253162731bfe090c2e7709Etan Cohen        clients.put(14,
270a83967f56939392072253162731bfe090c2e7709Etan Cohen                new WifiAwareClientState(mMockContext, 14, uid2, 0, null, null, null, false,
271a83967f56939392072253162731bfe090c2e7709Etan Cohen                        mClock.getElapsedSinceBootMillis()));
272a83967f56939392072253162731bfe090c2e7709Etan Cohen        mDut.recordAttachSession(uid2, false, clients);
273a83967f56939392072253162731bfe090c2e7709Etan Cohen
274a83967f56939392072253162731bfe090c2e7709Etan Cohen        // a few failures
275a83967f56939392072253162731bfe090c2e7709Etan Cohen        mDut.recordAttachStatus(NanStatusType.INTERNAL_FAILURE);
276a83967f56939392072253162731bfe090c2e7709Etan Cohen        mDut.recordAttachStatus(NanStatusType.INTERNAL_FAILURE);
277a83967f56939392072253162731bfe090c2e7709Etan Cohen        mDut.recordAttachStatus(-5); // invalid
278a83967f56939392072253162731bfe090c2e7709Etan Cohen
279a83967f56939392072253162731bfe090c2e7709Etan Cohen        // verify
280a83967f56939392072253162731bfe090c2e7709Etan Cohen        log = mDut.consolidateProto();
281a83967f56939392072253162731bfe090c2e7709Etan Cohen
282a83967f56939392072253162731bfe090c2e7709Etan Cohen        collector.checkThat("numApps", log.numApps, equalTo(2));
283a83967f56939392072253162731bfe090c2e7709Etan Cohen        collector.checkThat("numAppsUsingIdentityCallback", log.numAppsUsingIdentityCallback,
284a83967f56939392072253162731bfe090c2e7709Etan Cohen                equalTo(1));
285a83967f56939392072253162731bfe090c2e7709Etan Cohen        collector.checkThat("maxConcurrentAttachSessionsInApp",
286a83967f56939392072253162731bfe090c2e7709Etan Cohen                log.maxConcurrentAttachSessionsInApp, equalTo(2));
287a83967f56939392072253162731bfe090c2e7709Etan Cohen        collector.checkThat("histogramAttachSessionStatus.length",
288a83967f56939392072253162731bfe090c2e7709Etan Cohen                log.histogramAttachSessionStatus.length, equalTo(3)); // 3 buckets
289a83967f56939392072253162731bfe090c2e7709Etan Cohen        collector.checkThat("histogramAttachDurationMs.length",
290a83967f56939392072253162731bfe090c2e7709Etan Cohen                log.histogramAttachDurationMs.length, equalTo(2));
291a83967f56939392072253162731bfe090c2e7709Etan Cohen        validateProtoHistBucket("Duration[0]", log.histogramAttachDurationMs[0], 5, 6, 1);
292a83967f56939392072253162731bfe090c2e7709Etan Cohen        validateProtoHistBucket("Duration[1]", log.histogramAttachDurationMs[1], 10, 20, 1);
293a83967f56939392072253162731bfe090c2e7709Etan Cohen    }
294a83967f56939392072253162731bfe090c2e7709Etan Cohen
295d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen    @Test
296d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen    public void testDiscoverySessionMetrics() {
297d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        final int uid1 = 1005;
298d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        final int uid2 = 1006;
29905dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        final int uid3 = 1007;
300d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        final SparseArray<WifiAwareClientState> clients = new SparseArray<>();
301d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        WifiMetricsProto.WifiAwareLog log;
302d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen
303d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        setTime(5);
304d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        WifiAwareClientState client1 = new WifiAwareClientState(mMockContext, 10, uid1, 0, null,
305d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen                null, null, false, 0);
306d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        WifiAwareClientState client2 = new WifiAwareClientState(mMockContext, 11, uid2, 0, null,
307d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen                null, null, false, 0);
30805dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        WifiAwareClientState client3 = new WifiAwareClientState(mMockContext, 12, uid3, 0, null,
30905dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen                null, null, false, 0);
310d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        clients.put(10, client1);
311d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        clients.put(11, client2);
31205dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        clients.put(12, client3);
313d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen
314d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        // uid1: publish session 1
315d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        client1.addSession(new WifiAwareDiscoverySessionState(null, 100, (byte) 0, null, true,
31605dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen                false, mClock.getElapsedSinceBootMillis()));
31705dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        mDut.recordDiscoverySession(uid1, clients);
318d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        mDut.recordDiscoveryStatus(uid1, NanStatusType.SUCCESS, true);
319d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen
320d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        // uid1: publish session 2
321d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        client1.addSession(new WifiAwareDiscoverySessionState(null, 101, (byte) 0, null, true,
32205dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen                false, mClock.getElapsedSinceBootMillis()));
32305dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        mDut.recordDiscoverySession(uid1, clients);
324d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        mDut.recordDiscoveryStatus(uid1, NanStatusType.SUCCESS, true);
325d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen
32605dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        // uid3: publish session 3 with ranging
32705dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        client3.addSession(new WifiAwareDiscoverySessionState(null, 111, (byte) 0, null, true,
32805dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen                true, mClock.getElapsedSinceBootMillis()));
32905dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        mDut.recordDiscoverySessionWithRanging(uid3, false, -1, -1, clients);
33005dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        mDut.recordDiscoveryStatus(uid3, NanStatusType.SUCCESS, true);
33105dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen
332d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        // uid2: subscribe session 1
333d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        client2.addSession(new WifiAwareDiscoverySessionState(null, 102, (byte) 0, null, false,
33405dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen                false, mClock.getElapsedSinceBootMillis()));
33505dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        mDut.recordDiscoverySession(uid2, clients);
336d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        mDut.recordDiscoveryStatus(uid2, NanStatusType.SUCCESS, false);
337d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen
338d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        // uid2: publish session 2
339d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        client2.addSession(new WifiAwareDiscoverySessionState(null, 103, (byte) 0, null, true,
34005dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen                false, mClock.getElapsedSinceBootMillis()));
34105dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        mDut.recordDiscoverySession(uid2, clients);
342d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        mDut.recordDiscoveryStatus(uid2, NanStatusType.SUCCESS, false);
343d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen
34405dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        // uid3: subscribe session 3 with ranging: min
34505dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        client3.addSession(new WifiAwareDiscoverySessionState(null, 112, (byte) 0, null, false,
34605dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen                true, mClock.getElapsedSinceBootMillis()));
34705dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        mDut.recordDiscoverySessionWithRanging(uid3, true, 10, -1, clients);
34805dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        mDut.recordDiscoveryStatus(uid3, NanStatusType.SUCCESS, false);
34905dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen
35005dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        // uid3: subscribe session 3 with ranging: max
35105dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        client3.addSession(new WifiAwareDiscoverySessionState(null, 113, (byte) 0, null, false,
35205dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen                true, mClock.getElapsedSinceBootMillis()));
35305dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        mDut.recordDiscoverySessionWithRanging(uid3, true, -1, 50, clients);
35405dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        mDut.recordDiscoveryStatus(uid3, NanStatusType.SUCCESS, false);
35505dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen
35605dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        // uid3: subscribe session 3 with ranging: minmax
35705dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        client3.addSession(new WifiAwareDiscoverySessionState(null, 114, (byte) 0, null, false,
35805dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen                true, mClock.getElapsedSinceBootMillis()));
35905dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        mDut.recordDiscoverySessionWithRanging(uid3, true, 0, 110, clients);
36005dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        mDut.recordDiscoveryStatus(uid3, NanStatusType.SUCCESS, false);
36105dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen
362d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        // uid1: delete session 1
363d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        setTime(10);
364d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        mDut.recordDiscoverySessionDuration(client1.getSession(100).getCreationTime(),
365d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen                client1.getSession(100).isPublishSession());
366d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        client1.removeSession(100);
367d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen
368d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        // uid2: delete session 1
369d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        setTime(15);
370d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        mDut.recordDiscoverySessionDuration(client2.getSession(102).getCreationTime(),
371d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen                client2.getSession(102).isPublishSession());
372d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        client2.removeSession(102);
373d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen
374d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        // uid2: subscribe session 3
37505dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        mDut.recordDiscoverySession(uid2, clients);
376d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        client2.addSession(new WifiAwareDiscoverySessionState(null, 104, (byte) 0, null, false,
37705dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen                false, mClock.getElapsedSinceBootMillis()));
378d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen
379d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        // a few failures
380d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        mDut.recordDiscoveryStatus(uid1, NanStatusType.INTERNAL_FAILURE, true);
381d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        mDut.recordDiscoveryStatus(uid2, NanStatusType.INTERNAL_FAILURE, false);
382d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        mDut.recordDiscoveryStatus(uid2, NanStatusType.NO_RESOURCES_AVAILABLE, false);
383d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        mDut.recordAttachStatus(-5); // invalid
384d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen
385d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        // verify
386d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        log = mDut.consolidateProto();
387d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen
388d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        collector.checkThat("maxConcurrentPublishInApp", log.maxConcurrentPublishInApp, equalTo(2));
389d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        collector.checkThat("maxConcurrentSubscribeInApp", log.maxConcurrentSubscribeInApp,
39005dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen                equalTo(3));
391d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        collector.checkThat("maxConcurrentDiscoverySessionsInApp",
39205dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen                log.maxConcurrentDiscoverySessionsInApp, equalTo(4));
393d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        collector.checkThat("maxConcurrentPublishInSystem", log.maxConcurrentPublishInSystem,
39405dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen                equalTo(4));
395d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        collector.checkThat("maxConcurrentSubscribeInSystem", log.maxConcurrentSubscribeInSystem,
39605dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen                equalTo(4));
397d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        collector.checkThat("maxConcurrentDiscoverySessionsInSystem",
39805dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen                log.maxConcurrentDiscoverySessionsInSystem, equalTo(8));
399d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        collector.checkThat("histogramPublishStatus.length",
400d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen                log.histogramPublishStatus.length, equalTo(2)); // 2 buckets
401d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        collector.checkThat("histogramSubscribeStatus.length",
402d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen                log.histogramSubscribeStatus.length, equalTo(3)); // 3 buckets
403d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        collector.checkThat("numAppsWithDiscoverySessionFailureOutOfResources",
404d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen                log.numAppsWithDiscoverySessionFailureOutOfResources, equalTo(1));
405d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        validateProtoHistBucket("Publish Duration[0]", log.histogramPublishSessionDurationMs[0], 5,
406d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen                6, 1);
407d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        validateProtoHistBucket("Subscribe Duration[0]", log.histogramSubscribeSessionDurationMs[0],
408d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen                10, 20, 1);
40905dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen
41005dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        collector.checkThat("maxConcurrentPublishWithRangingInApp",
41105dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen                log.maxConcurrentPublishWithRangingInApp, equalTo(1));
41205dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        collector.checkThat("maxConcurrentSubscribeWithRangingInApp",
41305dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen                log.maxConcurrentSubscribeWithRangingInApp, equalTo(3));
41405dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        collector.checkThat("maxConcurrentPublishWithRangingInSystem",
41505dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen                log.maxConcurrentPublishWithRangingInSystem, equalTo(1));
41605dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        collector.checkThat("maxConcurrentSubscribeWithRangingInSystem",
41705dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen                log.maxConcurrentSubscribeWithRangingInSystem, equalTo(3));
41805dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        collector.checkThat("numSubscribesWithRanging", log.numSubscribesWithRanging, equalTo(3));
41905dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        collector.checkThat("histogramSubscribeGeofenceMin.length",
42005dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen                log.histogramSubscribeGeofenceMin.length, equalTo(2));
42105dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        collector.checkThat("histogramSubscribeGeofenceMax.length",
42205dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen                log.histogramSubscribeGeofenceMax.length, equalTo(2));
42305dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        validateProtoHistBucket("histogramSubscribeGeofenceMin[0]",
42405dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen                log.histogramSubscribeGeofenceMin[0], Integer.MIN_VALUE, 10, 1);
42505dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        validateProtoHistBucket("histogramSubscribeGeofenceMin[1]",
42605dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen                log.histogramSubscribeGeofenceMin[1], 10, 30, 1);
42705dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        validateProtoHistBucket("histogramSubscribeGeofenceMax[0]",
42805dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen                log.histogramSubscribeGeofenceMax[0], 30, 60, 1);
42905dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        validateProtoHistBucket("histogramSubscribeGeofenceMax[1]",
43005dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen                log.histogramSubscribeGeofenceMax[1], 100, Integer.MAX_VALUE, 1);
431d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen    }
432d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen
433910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen    /**
434f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen     * Validate the data-path (NDP & NDI) metrics.
435f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen     */
436f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen    @Test
437f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen    public void testDataPathMetrics() {
438f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        final int uid1 = 1005;
439f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        final int uid2 = 1006;
440f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        final String ndi0 = "aware_data0";
441f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        final String ndi1 = "aware_data1";
442f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        Map<WifiAwareNetworkSpecifier, WifiAwareDataPathStateManager.AwareNetworkRequestInformation>
443f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen                networkRequestCache = new HashMap<>();
444f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        WifiMetricsProto.WifiAwareLog log;
445f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen
446dca9963c7292e17318f5ba0dee6c3683c7c9f941Etan Cohen        setTime(5);
447dca9963c7292e17318f5ba0dee6c3683c7c9f941Etan Cohen
448f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        // uid1: ndp (non-secure) on ndi0
449f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        addNetworkInfoToCache(networkRequestCache, 10, uid1, ndi0, null);
450f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        mDut.recordNdpCreation(uid1, networkRequestCache);
451dca9963c7292e17318f5ba0dee6c3683c7c9f941Etan Cohen        setTime(7); // 2ms creation time
452dca9963c7292e17318f5ba0dee6c3683c7c9f941Etan Cohen        mDut.recordNdpStatus(NanStatusType.SUCCESS, false, 5);
453f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen
454f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        // uid2: ndp (non-secure) on ndi0
455f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        WifiAwareNetworkSpecifier ns = addNetworkInfoToCache(networkRequestCache, 11, uid2, ndi0,
456f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen                null);
457f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        mDut.recordNdpCreation(uid2, networkRequestCache);
458dca9963c7292e17318f5ba0dee6c3683c7c9f941Etan Cohen        setTime(10); // 3 ms creation time
459dca9963c7292e17318f5ba0dee6c3683c7c9f941Etan Cohen        mDut.recordNdpStatus(NanStatusType.SUCCESS, false, 7);
460f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen
461f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        // uid2: ndp (secure) on ndi1 (OOB)
462f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        addNetworkInfoToCache(networkRequestCache, 12, uid2, ndi1, "passphrase of some kind");
463f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        mDut.recordNdpCreation(uid2, networkRequestCache);
464dca9963c7292e17318f5ba0dee6c3683c7c9f941Etan Cohen        setTime(25); // 15 ms creation time
465dca9963c7292e17318f5ba0dee6c3683c7c9f941Etan Cohen        mDut.recordNdpStatus(NanStatusType.SUCCESS, true, 10);
466f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen
467f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        // uid2: ndp (secure) on ndi0 (OOB)
468f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        addNetworkInfoToCache(networkRequestCache, 13, uid2, ndi0, "super secret password");
469f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        mDut.recordNdpCreation(uid2, networkRequestCache);
470dca9963c7292e17318f5ba0dee6c3683c7c9f941Etan Cohen        setTime(36); // 11 ms creation time
471dca9963c7292e17318f5ba0dee6c3683c7c9f941Etan Cohen        mDut.recordNdpStatus(NanStatusType.SUCCESS, true, 25);
472f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen
473f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        // uid2: delete the first NDP
474f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        networkRequestCache.remove(ns);
475f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen
476f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        // uid2: ndp (non-secure) on ndi0
477f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        addNetworkInfoToCache(networkRequestCache, 14, uid2, ndi0, null);
478f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        mDut.recordNdpCreation(uid2, networkRequestCache);
479dca9963c7292e17318f5ba0dee6c3683c7c9f941Etan Cohen        setTime(37); // 1 ms creation time!
480dca9963c7292e17318f5ba0dee6c3683c7c9f941Etan Cohen        mDut.recordNdpStatus(NanStatusType.SUCCESS, false, 36);
481f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen
482f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        // a few error codes
483dca9963c7292e17318f5ba0dee6c3683c7c9f941Etan Cohen        mDut.recordNdpStatus(NanStatusType.INTERNAL_FAILURE, false, 0);
484dca9963c7292e17318f5ba0dee6c3683c7c9f941Etan Cohen        mDut.recordNdpStatus(NanStatusType.INTERNAL_FAILURE, false, 0);
485dca9963c7292e17318f5ba0dee6c3683c7c9f941Etan Cohen        mDut.recordNdpStatus(NanStatusType.NO_RESOURCES_AVAILABLE, false, 0);
486f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen
4877a44d3fab050e1aca22317a604a68016c79f5925Etan Cohen        // and some durations
4887a44d3fab050e1aca22317a604a68016c79f5925Etan Cohen        setTime(150);
4897a44d3fab050e1aca22317a604a68016c79f5925Etan Cohen        mDut.recordNdpSessionDuration(7);   // 143ms
4907a44d3fab050e1aca22317a604a68016c79f5925Etan Cohen        mDut.recordNdpSessionDuration(10);  // 140ms
4917a44d3fab050e1aca22317a604a68016c79f5925Etan Cohen        mDut.recordNdpSessionDuration(25);  // 125ms
4927a44d3fab050e1aca22317a604a68016c79f5925Etan Cohen        mDut.recordNdpSessionDuration(140); // 10ms
4937a44d3fab050e1aca22317a604a68016c79f5925Etan Cohen
494f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        //verify
495f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        log = mDut.consolidateProto();
496f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen
497f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        collector.checkThat("maxConcurrentNdiInApp", log.maxConcurrentNdiInApp, equalTo(2));
498f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        collector.checkThat("maxConcurrentNdiInSystem", log.maxConcurrentNdiInSystem, equalTo(2));
499f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        collector.checkThat("maxConcurrentNdpInApp", log.maxConcurrentNdpInApp, equalTo(3));
500f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        collector.checkThat("maxConcurrentNdpInSystem", log.maxConcurrentNdpInSystem, equalTo(4));
501f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        collector.checkThat("maxConcurrentSecureNdpInApp", log.maxConcurrentSecureNdpInApp,
502f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen                equalTo(2));
503f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        collector.checkThat("maxConcurrentSecureNdpInSystem", log.maxConcurrentSecureNdpInSystem,
504f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen                equalTo(2));
505f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        collector.checkThat("maxConcurrentNdpPerNdi", log.maxConcurrentNdpPerNdi, equalTo(3));
506f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        collector.checkThat("histogramRequestNdpStatus.length",
507f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen                log.histogramRequestNdpStatus.length, equalTo(3));
508f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        collector.checkThat("histogramRequestNdpOobStatus.length",
509f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen                log.histogramRequestNdpOobStatus.length, equalTo(1));
510dca9963c7292e17318f5ba0dee6c3683c7c9f941Etan Cohen
511dca9963c7292e17318f5ba0dee6c3683c7c9f941Etan Cohen        collector.checkThat("ndpCreationTimeMsMin", log.ndpCreationTimeMsMin, equalTo(1L));
512dca9963c7292e17318f5ba0dee6c3683c7c9f941Etan Cohen        collector.checkThat("ndpCreationTimeMsMax", log.ndpCreationTimeMsMax, equalTo(15L));
513dca9963c7292e17318f5ba0dee6c3683c7c9f941Etan Cohen        collector.checkThat("ndpCreationTimeMsSum", log.ndpCreationTimeMsSum, equalTo(32L));
514dca9963c7292e17318f5ba0dee6c3683c7c9f941Etan Cohen        collector.checkThat("ndpCreationTimeMsSumOfSq", log.ndpCreationTimeMsSumOfSq,
515dca9963c7292e17318f5ba0dee6c3683c7c9f941Etan Cohen                equalTo(360L));
516dca9963c7292e17318f5ba0dee6c3683c7c9f941Etan Cohen        collector.checkThat("ndpCreationTimeMsNumSamples", log.ndpCreationTimeMsNumSamples,
517dca9963c7292e17318f5ba0dee6c3683c7c9f941Etan Cohen                equalTo(5L));
518dca9963c7292e17318f5ba0dee6c3683c7c9f941Etan Cohen        validateProtoHistBucket("Creation[0]", log.histogramNdpCreationTimeMs[0], 1, 2, 1);
519dca9963c7292e17318f5ba0dee6c3683c7c9f941Etan Cohen        validateProtoHistBucket("Creation[1]", log.histogramNdpCreationTimeMs[1], 2, 3, 1);
520dca9963c7292e17318f5ba0dee6c3683c7c9f941Etan Cohen        validateProtoHistBucket("Creation[2]", log.histogramNdpCreationTimeMs[2], 3, 4, 1);
521dca9963c7292e17318f5ba0dee6c3683c7c9f941Etan Cohen        validateProtoHistBucket("Creation[3]", log.histogramNdpCreationTimeMs[3], 10, 20, 2);
5227a44d3fab050e1aca22317a604a68016c79f5925Etan Cohen
5237a44d3fab050e1aca22317a604a68016c79f5925Etan Cohen        validateProtoHistBucket("Duration[0]", log.histogramNdpSessionDurationMs[0], 10, 20, 1);
5247a44d3fab050e1aca22317a604a68016c79f5925Etan Cohen        validateProtoHistBucket("Duration[1]", log.histogramNdpSessionDurationMs[1], 100, 200, 3);
525f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen    }
526f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen
527f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen    /**
528910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen     * Validate that the histogram configuration is initialized correctly: bucket starting points
529910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen     * and sub-bucket widths.
530910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen     */
531910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen    @Test
532910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen    public void testHistParamInit() {
533910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        collector.checkThat("HIST1.mLog", HIST1.mLog, equalTo(Math.log(10)));
534910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        collector.checkThat("HIST1.bb[0]", HIST1.bb[0], equalTo(1.0));
535910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        collector.checkThat("HIST1.bb[1]", HIST1.bb[1], equalTo(10.0));
536910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        collector.checkThat("HIST1.bb[2]", HIST1.bb[2], equalTo(100.0));
537910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        collector.checkThat("HIST1.bb[3]", HIST1.bb[3], equalTo(1000.0));
538910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        collector.checkThat("HIST1.bb[4]", HIST1.bb[4], equalTo(10000.0));
539910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        collector.checkThat("HIST1.bb[5]", HIST1.bb[5], equalTo(100000.0));
540910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        collector.checkThat("HIST1.sbw[0]", HIST1.sbw[0], equalTo(1.0));
541910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        collector.checkThat("HIST1.sbw[1]", HIST1.sbw[1], equalTo(10.0));
542910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        collector.checkThat("HIST1.sbw[2]", HIST1.sbw[2], equalTo(100.0));
543910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        collector.checkThat("HIST1.sbw[3]", HIST1.sbw[3], equalTo(1000.0));
544910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        collector.checkThat("HIST1.sbw[4]", HIST1.sbw[4], equalTo(10000.0));
545910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        collector.checkThat("HIST1.sbw[5]", HIST1.sbw[5], equalTo(100000.0));
546910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen
547910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        collector.checkThat("HIST2.mLog", HIST1.mLog, equalTo(Math.log(10)));
548910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        collector.checkThat("HIST2.bb[0]", HIST2.bb[0], equalTo(-18.0));
549910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        collector.checkThat("HIST2.bb[1]", HIST2.bb[1], equalTo(-10.0));
550910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        collector.checkThat("HIST2.bb[2]", HIST2.bb[2], equalTo(30.0));
551910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        collector.checkThat("HIST2.sbw[0]", HIST2.sbw[0], equalTo(0.2));
552910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        collector.checkThat("HIST2.sbw[1]", HIST2.sbw[1], equalTo(1.0));
553910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        collector.checkThat("HIST2.sbw[2]", HIST2.sbw[2], equalTo(5.0));
554910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen    }
555910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen
556910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen    /**
557910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen     * Validate the conversion to a NanStatusType proto raw histogram.
558910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen     */
559910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen    @Test
560910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen    public void testNanStatusTypeHistogram() {
561910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        SparseIntArray statusHistogram = new SparseIntArray();
562910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen
563910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        addNanHalStatusToHistogram(NanStatusType.SUCCESS, statusHistogram);
564910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        addNanHalStatusToHistogram(-1, statusHistogram);
565910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        addNanHalStatusToHistogram(NanStatusType.ALREADY_ENABLED, statusHistogram);
566910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        addNanHalStatusToHistogram(NanStatusType.SUCCESS, statusHistogram);
567910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        addNanHalStatusToHistogram(NanStatusType.INTERNAL_FAILURE, statusHistogram);
568910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        addNanHalStatusToHistogram(NanStatusType.SUCCESS, statusHistogram);
569910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        addNanHalStatusToHistogram(NanStatusType.INTERNAL_FAILURE, statusHistogram);
570910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        addNanHalStatusToHistogram(55, statusHistogram);
571910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        addNanHalStatusToHistogram(65, statusHistogram);
572910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen
573910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        WifiMetricsProto.WifiAwareLog.NanStatusHistogramBucket[] sh = histogramToProtoArray(
574910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen                statusHistogram);
575910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        collector.checkThat("Number of buckets", sh.length, equalTo(4));
576910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        validateNanStatusProtoHistBucket("Bucket[SUCCESS]", sh[0],
577910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen                WifiMetricsProto.WifiAwareLog.SUCCESS, 3);
578910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        validateNanStatusProtoHistBucket("Bucket[INTERNAL_FAILURE]", sh[1],
579910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen                WifiMetricsProto.WifiAwareLog.INTERNAL_FAILURE, 2);
580910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        validateNanStatusProtoHistBucket("Bucket[ALREADY_ENABLED]", sh[2],
581910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen                WifiMetricsProto.WifiAwareLog.ALREADY_ENABLED, 1);
582910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        validateNanStatusProtoHistBucket("Bucket[UNKNOWN_HAL_STATUS]", sh[3],
583910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen                WifiMetricsProto.WifiAwareLog.UNKNOWN_HAL_STATUS, 3);
584910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen    }
585910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen
586910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen    // utilities
587910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen
588910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen    /**
589910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen     * Mock the elapsed time since boot to the input argument.
590910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen     */
591910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen    private void setTime(long timeMs) {
592910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        when(mClock.getElapsedSinceBootMillis()).thenReturn(timeMs);
593910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen    }
594910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen
595910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen    /**
596910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen     * Sum all the 'count' entries in the histogram array.
597910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen     */
598910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen    private int countAllHistogramSamples(WifiMetricsProto.WifiAwareLog.HistogramBucket[] hba) {
599910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        int sum = 0;
600910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        for (WifiMetricsProto.WifiAwareLog.HistogramBucket hb: hba) {
601910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen            sum += hb.count;
602910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        }
603910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        return sum;
604910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen    }
605910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen
606a83967f56939392072253162731bfe090c2e7709Etan Cohen    private int countAllHistogramSamples(
607a83967f56939392072253162731bfe090c2e7709Etan Cohen            WifiMetricsProto.WifiAwareLog.NanStatusHistogramBucket[] nshba) {
608a83967f56939392072253162731bfe090c2e7709Etan Cohen        int sum = 0;
609a83967f56939392072253162731bfe090c2e7709Etan Cohen        for (WifiMetricsProto.WifiAwareLog.NanStatusHistogramBucket nshb: nshba) {
610a83967f56939392072253162731bfe090c2e7709Etan Cohen            sum += nshb.count;
611a83967f56939392072253162731bfe090c2e7709Etan Cohen        }
612a83967f56939392072253162731bfe090c2e7709Etan Cohen        return sum;
613a83967f56939392072253162731bfe090c2e7709Etan Cohen    }
614a83967f56939392072253162731bfe090c2e7709Etan Cohen
615910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen    private void validateProtoHistBucket(String logPrefix,
616910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen            WifiMetricsProto.WifiAwareLog.HistogramBucket bucket, long start, long end, int count) {
617910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        collector.checkThat(logPrefix + ": start", bucket.start, equalTo(start));
618910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        collector.checkThat(logPrefix + ": end", bucket.end, equalTo(end));
619910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        collector.checkThat(logPrefix + ": count", bucket.count, equalTo(count));
620910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen    }
621910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen
622910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen    private void validateNanStatusProtoHistBucket(String logPrefix,
623910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen            WifiMetricsProto.WifiAwareLog.NanStatusHistogramBucket bucket, int type, int count) {
624910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        collector.checkThat(logPrefix + ": type", bucket.nanStatusType, equalTo(type));
625910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen        collector.checkThat(logPrefix + ": count", bucket.count, equalTo(count));
626910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen    }
627a83967f56939392072253162731bfe090c2e7709Etan Cohen
628f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen    private WifiAwareNetworkSpecifier addNetworkInfoToCache(
629f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen            Map<WifiAwareNetworkSpecifier, WifiAwareDataPathStateManager
630f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen                    .AwareNetworkRequestInformation> networkRequestCache,
631f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen            int index, int uid, String interfaceName, String passphrase) {
632f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        WifiAwareNetworkSpecifier ns = new WifiAwareNetworkSpecifier(0, 0, 0, index, 0, null, null,
633f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen                passphrase, 0);
634f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        WifiAwareDataPathStateManager.AwareNetworkRequestInformation anri =
635f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen                new WifiAwareDataPathStateManager.AwareNetworkRequestInformation();
636f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        anri.networkSpecifier = ns;
637d2b34d876c5b21790a4b98a94ae69cc95d2f5521Etan Cohen        anri.state = WifiAwareDataPathStateManager.AwareNetworkRequestInformation.STATE_CONFIRMED;
638f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        anri.uid = uid;
639f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        anri.interfaceName = interfaceName;
640f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen
641f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        networkRequestCache.put(ns, anri);
642f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen        return ns;
643f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen    }
644f28f838f3fe502fff47bcb3098098556b167ed88Etan Cohen
645a83967f56939392072253162731bfe090c2e7709Etan Cohen    private void dumpDut(String prefix) {
646a83967f56939392072253162731bfe090c2e7709Etan Cohen        StringWriter sw = new StringWriter();
647a83967f56939392072253162731bfe090c2e7709Etan Cohen        mDut.dump(null, new PrintWriter(sw), null);
648a83967f56939392072253162731bfe090c2e7709Etan Cohen        Log.e("WifiAwareMetrics", prefix + sw.toString());
649a83967f56939392072253162731bfe090c2e7709Etan Cohen    }
650910fdc720f0bf62b5529cb37a5f001ae585a5c59Etan Cohen}
651