1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.sensorratepermission.cts.directreportapi30; 18 19 import android.content.Context; 20 import android.hardware.HardwareBuffer; 21 import android.hardware.Sensor; 22 import android.hardware.SensorDirectChannel; 23 import android.hardware.SensorManager; 24 import android.hardware.SensorPrivacyManager; 25 import android.hardware.cts.SensorDirectReportTest; 26 import android.hardware.cts.helpers.SensorCtsHelper; 27 import android.hardware.cts.helpers.SensorRatePermissionDirectReportTestHelper; 28 import android.os.SystemClock; 29 import android.os.UserHandle; 30 31 import androidx.test.platform.app.InstrumentationRegistry; 32 33 import org.junit.After; 34 import org.junit.Assert; 35 import org.junit.Assume; 36 import org.junit.Before; 37 import org.junit.Test; 38 import org.junit.runner.RunWith; 39 import org.junit.runners.Parameterized; 40 41 import java.util.Collection; 42 import java.util.List; 43 import java.util.concurrent.TimeUnit; 44 45 /** 46 * Test sampling rate obtained by direct connections when: 47 * - The mic toggle is on and off 48 * - App targets API 30 49 * 50 * Expected behaviors: 51 * - Sampling rate is capped when the toggle is on 52 * - Sampling rate is not capped when the toggle is off 53 */ 54 @RunWith(Parameterized.class) 55 public class DirectReportAPI30Test { 56 private static SensorRatePermissionDirectReportTestHelper mDirectReportTestHelper; 57 private static SensorPrivacyManager mSensorPrivacyManager; 58 private static SensorManager mSensorManager; 59 private static int mUserID; 60 private final int sensorType; 61 DirectReportAPI30Test(int sensorType)62 public DirectReportAPI30Test(int sensorType) { 63 this.sensorType = sensorType; 64 } 65 66 @Parameterized.Parameters cappedSensorTypeSet()67 public static Collection cappedSensorTypeSet() { 68 return SensorRatePermissionDirectReportTestHelper.CAPPED_SENSOR_TYPE_SET; 69 } 70 71 @Before setUp()72 public void setUp() { 73 Context context = InstrumentationRegistry.getInstrumentation().getContext(); 74 mDirectReportTestHelper = new SensorRatePermissionDirectReportTestHelper(context, 75 sensorType); 76 Assume.assumeTrue("Failed to create mDirectReportTestHelper!", 77 mDirectReportTestHelper != null); 78 79 mSensorManager = context.getSystemService(SensorManager.class); 80 mSensorPrivacyManager = context.getSystemService(SensorPrivacyManager.class); 81 Assume.assumeTrue(mSensorPrivacyManager 82 .supportsSensorToggle(SensorPrivacyManager.Sensors.MICROPHONE)); 83 mUserID = UserHandle.myUserId(); 84 } 85 86 @After tearDown()87 public void tearDown() throws InterruptedException { 88 if (mDirectReportTestHelper != null) { 89 mDirectReportTestHelper.flipAndAssertMicToggleOff(mUserID, mSensorPrivacyManager); 90 } 91 } 92 93 @Test testSamplingRateMicToggleOff()94 public void testSamplingRateMicToggleOff() throws InterruptedException { 95 // Only run this test if we know for sure that the highest direct report rate level of 96 // corresponds to a sampling rate of > 200 Hz 97 if (mDirectReportTestHelper.getSensor().getHighestDirectReportRateLevel() 98 <= SensorDirectChannel.RATE_FAST) { 99 return; 100 } 101 102 mDirectReportTestHelper.flipAndAssertMicToggleOff(mUserID, mSensorPrivacyManager); 103 List<SensorDirectReportTest.DirectReportSensorEvent> events = 104 mDirectReportTestHelper.getSensorEvents(SensorDirectChannel.RATE_VERY_FAST); 105 106 double obtainedRate = SensorRatePermissionDirectReportTestHelper.computeAvgRate(events, 107 Long.MIN_VALUE, Long.MAX_VALUE); 108 109 Assert.assertTrue(mDirectReportTestHelper.errorWhenBelowExpectedRate(), 110 obtainedRate > SensorRatePermissionDirectReportTestHelper.CAPPED_SAMPLE_RATE_HZ); 111 } 112 113 @Test testSamplingRateMicToggleOn()114 public void testSamplingRateMicToggleOn() throws InterruptedException { 115 mDirectReportTestHelper.flipAndAssertMicToggleOn(mUserID, mSensorPrivacyManager); 116 List<SensorDirectReportTest.DirectReportSensorEvent> events = 117 mDirectReportTestHelper.getSensorEvents(SensorDirectChannel.RATE_VERY_FAST); 118 119 double obtainedRate = SensorRatePermissionDirectReportTestHelper.computeAvgRate(events, 120 Long.MIN_VALUE, Long.MAX_VALUE); 121 122 Assert.assertTrue(mDirectReportTestHelper.errorWhenExceedCappedRate(), 123 obtainedRate <= SensorRatePermissionDirectReportTestHelper.CAPPED_SAMPLE_RATE_HZ); 124 } 125 126 /** 127 * Test the case where a connection is ongoing while the mic toggle changes its state: 128 * off -> on -> off. This test is to show that the sensor service is able to cap/uncap the 129 * rate of ongoing direct sensor connections when the state of the mic toggle changes. 130 */ 131 @Test testSamplingRateMicToggleOffOnOff()132 public void testSamplingRateMicToggleOffOnOff() throws InterruptedException { 133 // Only run this test if we know for sure that the highest direct report rate level of 134 // the sensor corresponds to a sampling rate of > 200 Hz and that the sensor supports 135 // direct channel. 136 Sensor s = mDirectReportTestHelper.getSensor(); 137 if (s.getHighestDirectReportRateLevel() <= SensorDirectChannel.RATE_FAST 138 || !s.isDirectChannelTypeSupported(SensorDirectChannel.TYPE_HARDWARE_BUFFER)) { 139 return; 140 } 141 // Start with the mic toggle off 142 mDirectReportTestHelper.flipAndAssertMicToggleOff(mUserID, mSensorPrivacyManager); 143 144 // Configure a direct channel. 145 int sensorEventCount = 5500; // 800 Hz * 2.5s + 200 Hz * 2.5s + extra 146 int sharedMemorySize = sensorEventCount * 147 SensorRatePermissionDirectReportTestHelper.SENSORS_EVENT_SIZE; 148 HardwareBuffer hardwareBuffer = HardwareBuffer.create( 149 sharedMemorySize, 1, HardwareBuffer.BLOB, 1, 150 HardwareBuffer.USAGE_CPU_READ_OFTEN | HardwareBuffer.USAGE_GPU_DATA_BUFFER 151 | HardwareBuffer.USAGE_SENSOR_DIRECT_DATA); 152 SensorDirectChannel channel = mSensorManager.createDirectChannel(hardwareBuffer); 153 int token = channel.configure(s, SensorDirectChannel.RATE_VERY_FAST); 154 155 // Flip the mic toggle on 156 mDirectReportTestHelper.flipAndAssertMicToggleOn(mUserID, mSensorPrivacyManager); 157 long startMicToggleOn = SystemClock.elapsedRealtimeNanos(); 158 SensorCtsHelper.sleep( 159 SensorRatePermissionDirectReportTestHelper.TEST_RUN_TIME_PERIOD_MILLISEC / 2, 160 TimeUnit.MILLISECONDS); 161 long endMicToggleOn = SystemClock.elapsedRealtimeNanos(); 162 163 // Flip the mic toggle off 164 mDirectReportTestHelper.flipAndAssertMicToggleOff(mUserID, mSensorPrivacyManager); 165 long startMicToggleOff = SystemClock.elapsedRealtimeNanos(); 166 SensorCtsHelper.sleep( 167 SensorRatePermissionDirectReportTestHelper.TEST_RUN_TIME_PERIOD_MILLISEC / 2, 168 TimeUnit.MILLISECONDS); 169 170 // Read the sensor events out 171 channel.configure(s, SensorDirectChannel.RATE_STOP); 172 List<SensorDirectReportTest.DirectReportSensorEvent> events = 173 mDirectReportTestHelper.readEventsFromHardwareBuffer(token, 174 hardwareBuffer, sensorEventCount); 175 channel.close(); 176 hardwareBuffer.close(); 177 178 // Check the sampling rates when the mic toggle were on and off 179 double rateWhenMicToggleOn = 180 SensorRatePermissionDirectReportTestHelper.computeAvgRate(events, 181 startMicToggleOn, endMicToggleOn); 182 Assert.assertTrue(mDirectReportTestHelper.errorWhenExceedCappedRate(), 183 rateWhenMicToggleOn 184 <= SensorRatePermissionDirectReportTestHelper.CAPPED_SAMPLE_RATE_HZ); 185 186 double rateWhenMicToggleOff = SensorRatePermissionDirectReportTestHelper.computeAvgRate( 187 events, startMicToggleOff, Long.MAX_VALUE); 188 Assert.assertTrue(mDirectReportTestHelper.errorWhenBelowExpectedRate(), 189 rateWhenMicToggleOff 190 > SensorRatePermissionDirectReportTestHelper.CAPPED_SAMPLE_RATE_HZ); 191 } 192 } 193