Merge "[TeX] Introduced Telemetry Express Histogram Logging APIs"
This commit is contained in:
107
core/java/com/android/internal/expresslog/Histogram.java
Normal file
107
core/java/com/android/internal/expresslog/Histogram.java
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.expresslog;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
|
||||
import com.android.internal.util.FrameworkStatsLog;
|
||||
|
||||
/** CounterHistogram encapsulates StatsD write API calls */
|
||||
public final class Histogram {
|
||||
|
||||
private final long mMetricIdHash;
|
||||
private final BinOptions mBinOptions;
|
||||
|
||||
public Histogram(@NonNull String metricId, @NonNull BinOptions binOptions) {
|
||||
mMetricIdHash = Utils.hashString(metricId);
|
||||
mBinOptions = binOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs increment sample count for automatically calculated bin
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void logSample(float sample) {
|
||||
final int binIndex = mBinOptions.getBinForSample(sample);
|
||||
FrameworkStatsLog.write(FrameworkStatsLog.EXPRESS_HISTOGRAM_SAMPLE_REPORTED, mMetricIdHash,
|
||||
/*count*/ 1, binIndex);
|
||||
}
|
||||
|
||||
/** Used by CounterHistogram to map data sample to corresponding bin */
|
||||
public interface BinOptions {
|
||||
/**
|
||||
* Returns bins count to be used by counter histogram
|
||||
*
|
||||
* @return bins count used to initialize Options, including overflow & underflow bins
|
||||
* @hide
|
||||
*/
|
||||
int getBinsCount();
|
||||
|
||||
/**
|
||||
* @return zero based index
|
||||
* Calculates bin index for the input sample value
|
||||
* index == 0 stands for underflow
|
||||
* index == getBinsCount() - 1 stands for overflow
|
||||
* @hide
|
||||
*/
|
||||
int getBinForSample(float sample);
|
||||
}
|
||||
|
||||
/** Used by CounterHistogram to map data sample to corresponding bin for on uniform bins */
|
||||
public static final class UniformOptions implements BinOptions {
|
||||
|
||||
private final int mBinCount;
|
||||
private final float mMinValue;
|
||||
private final float mExclusiveMaxValue;
|
||||
private final float mBinSize;
|
||||
|
||||
public UniformOptions(int binCount, float minValue, float exclusiveMaxValue) {
|
||||
if (binCount < 1) {
|
||||
throw new IllegalArgumentException("Bin count should be positive number");
|
||||
}
|
||||
|
||||
if (exclusiveMaxValue <= minValue) {
|
||||
throw new IllegalArgumentException("Bins range invalid (maxValue < minValue)");
|
||||
}
|
||||
|
||||
mMinValue = minValue;
|
||||
mExclusiveMaxValue = exclusiveMaxValue;
|
||||
mBinSize = (mExclusiveMaxValue - minValue) / binCount;
|
||||
|
||||
// Implicitly add 2 for the extra undeflow & overflow bins
|
||||
mBinCount = binCount + 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBinsCount() {
|
||||
return mBinCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBinForSample(float sample) {
|
||||
if (sample < mMinValue) {
|
||||
// goes to underflow
|
||||
return 0;
|
||||
} else if (sample >= mExclusiveMaxValue) {
|
||||
// goes to overflow
|
||||
return mBinCount - 1;
|
||||
}
|
||||
return (int) ((sample - mMinValue) / mBinSize + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
12
core/java/com/android/internal/expresslog/TEST_MAPPING
Normal file
12
core/java/com/android/internal/expresslog/TEST_MAPPING
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"presubmit": [
|
||||
{
|
||||
"name": "ExpressLogTests",
|
||||
"options": [
|
||||
{
|
||||
"exclude-annotation": "org.junit.Ignore"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
47
core/tests/expresslog/Android.bp
Normal file
47
core/tests/expresslog/Android.bp
Normal file
@@ -0,0 +1,47 @@
|
||||
// Copyright (C) 2023 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package {
|
||||
// See: http://go/android-license-faq
|
||||
// A large-scale-change added 'default_applicable_licenses' to import
|
||||
// all of the 'license_kinds' from "frameworks_base_license"
|
||||
// to get the below license kinds:
|
||||
// SPDX-license-identifier-Apache-2.0
|
||||
default_applicable_licenses: ["frameworks_base_license"],
|
||||
}
|
||||
|
||||
android_test {
|
||||
name: "ExpressLogTests",
|
||||
|
||||
srcs: [
|
||||
"src/**/*.java",
|
||||
],
|
||||
|
||||
static_libs: [
|
||||
"androidx.test.rules",
|
||||
"modules-utils-build",
|
||||
],
|
||||
|
||||
libs: [
|
||||
"android.test.base",
|
||||
"android.test.runner",
|
||||
],
|
||||
|
||||
platform_apis: true,
|
||||
test_suites: [
|
||||
"general-tests",
|
||||
],
|
||||
|
||||
certificate: "platform",
|
||||
}
|
||||
29
core/tests/expresslog/AndroidManifest.xml
Normal file
29
core/tests/expresslog/AndroidManifest.xml
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2023 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:installLocation="internalOnly"
|
||||
package="com.android.internal.expresslog" >
|
||||
|
||||
<application >
|
||||
<uses-library android:name="android.test.runner" />
|
||||
</application>
|
||||
|
||||
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
|
||||
android:targetPackage="com.android.internal.expresslog"
|
||||
android:label="Telemetry Express Logging Helper Tests" />
|
||||
|
||||
</manifest>
|
||||
3
core/tests/expresslog/OWNERS
Normal file
3
core/tests/expresslog/OWNERS
Normal file
@@ -0,0 +1,3 @@
|
||||
# Bug component: 719316
|
||||
# Stats/expresslog
|
||||
file:/services/core/java/com/android/server/stats/OWNERS
|
||||
12
core/tests/expresslog/TEST_MAPPING
Normal file
12
core/tests/expresslog/TEST_MAPPING
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"presubmit": [
|
||||
{
|
||||
"name": "ExpressLogTests",
|
||||
"options": [
|
||||
{
|
||||
"exclude-annotation": "org.junit.Ignore"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.internal.expresslog;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
@RunWith(JUnit4.class)
|
||||
public class UniformOptionsTest {
|
||||
private static final String TAG = UniformOptionsTest.class.getSimpleName();
|
||||
|
||||
@Test
|
||||
@SmallTest
|
||||
public void testGetBinsCount() {
|
||||
Histogram.UniformOptions options1 = new Histogram.UniformOptions(1, 100, 1000);
|
||||
assertEquals(3, options1.getBinsCount());
|
||||
|
||||
Histogram.UniformOptions options10 = new Histogram.UniformOptions(10, 100, 1000);
|
||||
assertEquals(12, options10.getBinsCount());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
@SmallTest
|
||||
public void testConstructZeroBinsCount() {
|
||||
new Histogram.UniformOptions(0, 100, 1000);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
@SmallTest
|
||||
public void testConstructNegativeBinsCount() {
|
||||
new Histogram.UniformOptions(-1, 100, 1000);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
@SmallTest
|
||||
public void testConstructMaxValueLessThanMinValue() {
|
||||
new Histogram.UniformOptions(10, 1000, 100);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SmallTest
|
||||
public void testBinIndexForRangeEqual1() {
|
||||
Histogram.UniformOptions options = new Histogram.UniformOptions(10, 1, 11);
|
||||
for (int i = 0, bins = options.getBinsCount(); i < bins; i++) {
|
||||
assertEquals(i, options.getBinForSample(i));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@SmallTest
|
||||
public void testBinIndexForRangeEqual2() {
|
||||
Histogram.UniformOptions options = new Histogram.UniformOptions(10, 1, 21);
|
||||
for (int i = 0, bins = options.getBinsCount(); i < bins; i++) {
|
||||
assertEquals(i, options.getBinForSample(i * 2));
|
||||
assertEquals(i, options.getBinForSample(i * 2 - 1));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@SmallTest
|
||||
public void testBinIndexForRangeEqual5() {
|
||||
Histogram.UniformOptions options = new Histogram.UniformOptions(2, 0, 10);
|
||||
assertEquals(4, options.getBinsCount());
|
||||
for (int i = 0; i < 2; i++) {
|
||||
for (int sample = 0; sample < 5; sample++) {
|
||||
assertEquals(i + 1, options.getBinForSample(i * 5 + sample));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@SmallTest
|
||||
public void testBinIndexForRangeEqual10() {
|
||||
Histogram.UniformOptions options = new Histogram.UniformOptions(10, 1, 101);
|
||||
assertEquals(0, options.getBinForSample(0));
|
||||
assertEquals(options.getBinsCount() - 2, options.getBinForSample(100));
|
||||
assertEquals(options.getBinsCount() - 1, options.getBinForSample(101));
|
||||
|
||||
final float binSize = (101 - 1) / 10f;
|
||||
for (int i = 1, bins = options.getBinsCount() - 1; i < bins; i++) {
|
||||
assertEquals(i, options.getBinForSample(i * binSize));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@SmallTest
|
||||
public void testBinIndexForRangeEqual90() {
|
||||
final int binCount = 10;
|
||||
final int minValue = 100;
|
||||
final int maxValue = 100000;
|
||||
|
||||
Histogram.UniformOptions options = new Histogram.UniformOptions(binCount, minValue,
|
||||
maxValue);
|
||||
|
||||
// logging underflow sample
|
||||
assertEquals(0, options.getBinForSample(minValue - 1));
|
||||
|
||||
// logging overflow sample
|
||||
assertEquals(binCount + 1, options.getBinForSample(maxValue));
|
||||
assertEquals(binCount + 1, options.getBinForSample(maxValue + 1));
|
||||
|
||||
// logging min edge sample
|
||||
assertEquals(1, options.getBinForSample(minValue));
|
||||
|
||||
// logging max edge sample
|
||||
assertEquals(binCount, options.getBinForSample(maxValue - 1));
|
||||
|
||||
// logging single valid sample per bin
|
||||
final int binSize = (maxValue - minValue) / binCount;
|
||||
|
||||
for (int i = 0; i < binCount; i++) {
|
||||
assertEquals(i + 1, options.getBinForSample(minValue + binSize * i));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user