blob: 653c22f53cd6c4764e12c205d5c08382df6c6afd [file] [log] [blame]
/*
* Copyright (C) 2020 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 android.sensorratepermission.cts.resampling;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.hardware.cts.SensorTestCase;
import android.hardware.cts.helpers.SensorRatePermissionEventConnectionTestHelper;
import android.hardware.cts.helpers.SensorStats;
import android.hardware.cts.helpers.TestSensorEnvironment;
import android.hardware.cts.helpers.TestSensorEvent;
import android.hardware.cts.helpers.sensoroperations.TestSensorOperation;
import android.hardware.cts.helpers.sensorverification.EventGapVerification;
import android.hardware.cts.helpers.sensorverification.EventOrderingVerification;
import android.hardware.cts.helpers.sensorverification.EventTimestampSynchronizationVerification;
import android.hardware.cts.helpers.sensorverification.InitialValueVerification;
import android.hardware.cts.helpers.sensorverification.JitterVerification;
import android.hardware.cts.helpers.sensorverification.MagnitudeVerification;
import android.hardware.cts.helpers.sensorverification.MeanVerification;
import android.hardware.cts.helpers.sensorverification.StandardDeviationVerification;
import androidx.test.platform.app.InstrumentationRegistry;
import org.junit.Assert;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* Test the resampler in SensorEventConnection class.
*
* The resampler is to prevent the attack where an app without permission might get a sampling
* rate higher than our capped rate, because at the time it registers a listener, there is another
* app with the permission and requests a higher sampling rate.
*
* Test cases: Two apps register sensor listeners at the same time.
* - An app targets API 31 w/o HIGH_SAMPLING_RATE_SENSORS, hence being capped.
* - The other app targets API 25, hence not being capped
*
* Expected behaviors:
* - The one that should be capped is capped
* - The default verifications of returned sensor events meet the expectations as in other sensor
* tests
*/
public class ResamplingTest extends SensorTestCase {
private static final int NUM_EVENTS_COUNT = 1024;
private static SensorRatePermissionEventConnectionTestHelper mEventConnectionTestHelper;
private static Context mContext;
private static TestSensorEnvironment mTestEnvironment;
@Override
protected void setUp() throws Exception {
mContext = InstrumentationRegistry.getInstrumentation().getContext();
SensorManager sensorManager = mContext.getSystemService(SensorManager.class);
Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
if (sensor == null) {
return;
}
mTestEnvironment = new TestSensorEnvironment(
mContext,
sensor,
SensorManager.SENSOR_DELAY_FASTEST,
(int) TimeUnit.SECONDS.toMicros(5));
mEventConnectionTestHelper = new SensorRatePermissionEventConnectionTestHelper(
mTestEnvironment);
}
public void testResamplingEventConnections() throws Exception {
if (mTestEnvironment == null || mEventConnectionTestHelper == null) {
return;
}
// Start an app that registers a listener with high sampling rate
Intent intent = new Intent();
intent.setComponent(new ComponentName(
"android.sensorratepermission.cts.mictoggleoffapi25",
"android.sensorratepermission.cts.mictoggleoffapi25.MainService"));
mContext.startService(intent);
// At the same time, register a listener and obtain its sampling rate.
List<TestSensorEvent> events = mEventConnectionTestHelper.getSensorEvents(
true,
NUM_EVENTS_COUNT);
double obtainedRate = SensorRatePermissionEventConnectionTestHelper.computeAvgRate(events,
Long.MIN_VALUE, Long.MAX_VALUE);
Assert.assertTrue(mEventConnectionTestHelper.errorWhenExceedCappedRate(),
obtainedRate
<= SensorRatePermissionEventConnectionTestHelper.CAPPED_SAMPLE_RATE_HZ);
}
public void testSensorDefaultVerifications() throws Exception {
if (mTestEnvironment == null) {
return;
}
TestSensorOperation op = TestSensorOperation.createOperation(
mTestEnvironment,
NUM_EVENTS_COUNT);
op.addVerification(StandardDeviationVerification.getDefault(mTestEnvironment));
op.addVerification(EventGapVerification.getDefault(mTestEnvironment));
op.addVerification(EventOrderingVerification.getDefault(mTestEnvironment));
op.addVerification(JitterVerification.getDefault(mTestEnvironment));
op.addVerification(MagnitudeVerification.getDefault(mTestEnvironment));
op.addVerification(MeanVerification.getDefault(mTestEnvironment));
op.addVerification(EventTimestampSynchronizationVerification.getDefault(mTestEnvironment));
op.addVerification(InitialValueVerification.getDefault(mTestEnvironment));
try {
// Start an app that registers a listener with high sampling rate
Intent intent = new Intent();
intent.setComponent(new ComponentName(
"android.sensorratepermission.cts.mictoggleoffapi25",
"android.sensorratepermission.cts.mictoggleoffapi25.MainService"));
mContext.startService(intent);
op.execute(getCurrentTestNode());
} finally {
SensorStats stats = op.getStats();
String fileName = String.format(
"single_%s_%s.txt",
SensorStats.getSanitizedSensorName(mTestEnvironment.getSensor()),
mTestEnvironment.getFrequencyString());
stats.logToFile(mTestEnvironment.getContext(), fileName);
}
}
}