Create SensorPrivacy test module
Test: atest CtsSensorPrivacyTestCases
Bug: 162549680
Change-Id: I3bd23491f910b3abd4f01fcb7e218459be011982
diff --git a/tests/tests/sensorprivacy/Android.bp b/tests/tests/sensorprivacy/Android.bp
new file mode 100644
index 0000000..89fd386
--- /dev/null
+++ b/tests/tests/sensorprivacy/Android.bp
@@ -0,0 +1,44 @@
+//
+// Copyright (C) 2021 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.
+//
+
+
+android_test {
+ name: "CtsSensorPrivacyTestCases",
+ defaults: ["cts_defaults"],
+ // Tag this module as a cts test artifact
+ test_suites: [
+ "cts",
+ "general-tests",
+ "sts",
+ ],
+ compile_multilib: "both",
+ static_libs: [
+ "ctstestrunner-axt",
+ "compatibility-device-util-axt",
+ "androidx.annotation_annotation",
+ "androidx.test.uiautomator",
+ ],
+ srcs: [
+ "src/**/*.java",
+ "src/**/*.aidl",
+ "src/**/*.kt",
+ ],
+ sdk_version: "test_current",
+ libs: [
+ "android.test.runner",
+ "android.test.base",
+ ],
+}
\ No newline at end of file
diff --git a/tests/tests/sensorprivacy/AndroidManifest.xml b/tests/tests/sensorprivacy/AndroidManifest.xml
new file mode 100644
index 0000000..1c378ec
--- /dev/null
+++ b/tests/tests/sensorprivacy/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2021 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"
+ package="android.sensorprivacy.cts"
+ android:targetSandboxVersion="2">
+
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.sensorprivacy.cts"
+ android:label="CTS tests of android.sensorprivacy">
+ <meta-data android:name="listener"
+ android:value="com.android.cts.runner.CtsTestRunListener"/>
+ </instrumentation>
+
+</manifest>
diff --git a/tests/tests/sensorprivacy/AndroidTest.xml b/tests/tests/sensorprivacy/AndroidTest.xml
new file mode 100644
index 0000000..412b1ee
--- /dev/null
+++ b/tests/tests/sensorprivacy/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 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.
+-->
+<configuration description="Config for CTS Sensor Privacy test cases">
+ <option name="test-suite-tag" value="cts" />
+ <option name="config-descriptor:metadata" key="component" value="framework" />
+ <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
+ <option name="config-descriptor:metadata" key="parameter" value="secondary_user"/>
+
+ <!-- Install main test suite apk -->
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true" />
+ <option name="test-file-name" value="CtsSensorPrivacyTestCases.apk" />
+ <option name="test-file-name" value="CtsUseMicOrCameraForSensorPrivacy.apk" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="package" value="android.sensorprivacy.cts" />
+ </test>
+</configuration>
diff --git a/tests/tests/sensorprivacy/OWNERS b/tests/tests/sensorprivacy/OWNERS
new file mode 100644
index 0000000..3fb5fe2
--- /dev/null
+++ b/tests/tests/sensorprivacy/OWNERS
@@ -0,0 +1 @@
+file:platform/frameworks/native:/libs/sensorprivacy/OWNERS
\ No newline at end of file
diff --git a/tests/tests/sensorprivacy/src/android/sensorprivacy/cts/SensorPrivacyBaseTest.kt b/tests/tests/sensorprivacy/src/android/sensorprivacy/cts/SensorPrivacyBaseTest.kt
new file mode 100644
index 0000000..162abbd
--- /dev/null
+++ b/tests/tests/sensorprivacy/src/android/sensorprivacy/cts/SensorPrivacyBaseTest.kt
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2021 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.sensorprivacy.cts
+
+import android.content.Intent
+import android.hardware.SensorPrivacyManager
+import android.hardware.SensorPrivacyManager.OnSensorPrivacyChangedListener
+import android.support.test.uiautomator.By
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.UiDevice
+import com.android.compatibility.common.util.SystemUtil
+import com.android.compatibility.common.util.SystemUtil.runShellCommandOrThrow
+import com.android.compatibility.common.util.UiAutomatorUtils
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Assume
+import org.junit.Before
+import org.junit.Test
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.Executors
+import java.util.concurrent.TimeUnit
+
+abstract class SensorPrivacyBaseTest(
+ val feature: String,
+ val sensor: Int,
+ vararg val extras: String
+) {
+
+ companion object {
+ const val MIC_CAM_ACTIVITY_ACTION =
+ "android.sensorprivacy.cts.usemiccamera.action.USE_MIC_CAM"
+ const val FINISH_MIC_CAM_ACTIVITY_ACTION =
+ "android.sensorprivacy.cts.usemiccamera.action.FINISH_USE_MIC_CAM"
+ const val USE_MIC_EXTRA =
+ "android.sensorprivacy.cts.usemiccamera.extra.USE_MICROPHONE"
+ const val USE_CAM_EXTRA =
+ "android.sensorprivacy.cts.usemiccamera.extra.USE_CAMERA"
+ }
+
+ protected val instrumentation = InstrumentationRegistry.getInstrumentation()!!
+ protected val uiAutomation = instrumentation.uiAutomation!!
+ protected val uiDevice = UiDevice.getInstance(instrumentation)!!
+ protected val context = instrumentation.targetContext!!
+ protected val spm = context.getSystemService(SensorPrivacyManager::class.java)!!
+ protected val packageManager = context.packageManager!!
+
+ @Before
+ fun init() {
+ Assume.assumeTrue(packageManager.hasSystemFeature(feature))
+ uiDevice.wakeUp()
+ runShellCommandOrThrow("wm dismiss-keyguard")
+ uiDevice.waitForIdle()
+ }
+
+ @Test
+ fun testSetSensor() {
+ setSensor(true)
+ assertTrue(spm.isSensorPrivacyEnabled(sensor))
+
+ setSensor(false)
+ assertFalse(spm.isSensorPrivacyEnabled(sensor))
+ }
+
+ @Test
+ fun testDialog() {
+ setSensor(true)
+ val intent = Intent(MIC_CAM_ACTIVITY_ACTION).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ for (extra in extras) {
+ intent.putExtra(extra, true)
+ }
+ context.startActivity(intent)
+ UiAutomatorUtils.waitFindObject(By.text("Turn on")).click()
+ SystemUtil.eventually {
+ assertFalse(spm.isSensorPrivacyEnabled(sensor))
+ }
+ context.sendBroadcast(Intent(FINISH_MIC_CAM_ACTIVITY_ACTION))
+ }
+
+ @Test
+ fun testListener() {
+ val executor = Executors.newSingleThreadExecutor()
+ setSensor(false)
+ val latchEnabled = CountDownLatch(1)
+ SystemUtil.runWithShellPermissionIdentity {
+ spm.addSensorPrivacyListener(sensor, executor, OnSensorPrivacyChangedListener {
+ if (it) {
+ latchEnabled.countDown()
+ }
+ })
+ }
+ setSensor(true)
+ latchEnabled.await(100, TimeUnit.MILLISECONDS)
+
+ val latchDisabled = CountDownLatch(1)
+ SystemUtil.runWithShellPermissionIdentity {
+ spm.addSensorPrivacyListener(sensor, executor, OnSensorPrivacyChangedListener {
+ if (!it) {
+ latchDisabled.countDown()
+ }
+ })
+ }
+ setSensor(false)
+ latchEnabled.await(100, TimeUnit.MILLISECONDS)
+ }
+
+ fun setSensor(enable: Boolean) {
+ SystemUtil.runWithShellPermissionIdentity {
+ spm.setSensorPrivacy(sensor, enable)
+ }
+ }
+}
diff --git a/tests/tests/sensorprivacy/src/android/sensorprivacy/cts/SensorPrivacyCameraTest.kt b/tests/tests/sensorprivacy/src/android/sensorprivacy/cts/SensorPrivacyCameraTest.kt
new file mode 100644
index 0000000..d4a0082
--- /dev/null
+++ b/tests/tests/sensorprivacy/src/android/sensorprivacy/cts/SensorPrivacyCameraTest.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2021 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.sensorprivacy.cts
+
+import android.content.pm.PackageManager.FEATURE_CAMERA_TOGGLE
+import android.hardware.SensorPrivacyManager.Sensors.CAMERA
+
+class SensorPrivacyCameraTest : SensorPrivacyBaseTest(FEATURE_CAMERA_TOGGLE, CAMERA, USE_CAM_EXTRA)
diff --git a/tests/tests/sensorprivacy/src/android/sensorprivacy/cts/SensorPrivacyMicrophoneTest.kt b/tests/tests/sensorprivacy/src/android/sensorprivacy/cts/SensorPrivacyMicrophoneTest.kt
new file mode 100644
index 0000000..a9bee33
--- /dev/null
+++ b/tests/tests/sensorprivacy/src/android/sensorprivacy/cts/SensorPrivacyMicrophoneTest.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2021 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.sensorprivacy.cts
+
+import android.content.pm.PackageManager.FEATURE_MICROPHONE_TOGGLE
+import android.hardware.SensorPrivacyManager.Sensors.MICROPHONE
+
+class SensorPrivacyMicrophoneTest : SensorPrivacyBaseTest(
+ FEATURE_MICROPHONE_TOGGLE,
+ MICROPHONE,
+ USE_MIC_EXTRA
+)
diff --git a/tests/tests/sensorprivacy/test-apps/CtsUseMicOrCameraForSensorPrivacy/Android.bp b/tests/tests/sensorprivacy/test-apps/CtsUseMicOrCameraForSensorPrivacy/Android.bp
new file mode 100644
index 0000000..2f0c844
--- /dev/null
+++ b/tests/tests/sensorprivacy/test-apps/CtsUseMicOrCameraForSensorPrivacy/Android.bp
@@ -0,0 +1,29 @@
+//
+// Copyright (C) 2021 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.
+//
+
+android_test_helper_app {
+ name: "CtsUseMicOrCameraForSensorPrivacy",
+ defaults: ["cts_defaults"],
+
+ sdk_version: "test_current",
+
+ // Tag this module as a cts test artifact
+ test_suites: [
+ "cts",
+ "general-tests",
+ ],
+ srcs: ["src/**/*.kt"],
+}
diff --git a/tests/tests/sensorprivacy/test-apps/CtsUseMicOrCameraForSensorPrivacy/AndroidManifest.xml b/tests/tests/sensorprivacy/test-apps/CtsUseMicOrCameraForSensorPrivacy/AndroidManifest.xml
new file mode 100644
index 0000000..490773b
--- /dev/null
+++ b/tests/tests/sensorprivacy/test-apps/CtsUseMicOrCameraForSensorPrivacy/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2021 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"
+ package="android.sensorprivacy.cts.usemiccamera"
+ android:versionCode="1">
+
+ <uses-permission android:name="android.permission.RECORD_AUDIO"/>
+ <uses-permission android:name="android.permission.CAMERA"/>
+
+ <application android:label="CtsUseMicOrCameraForSensorPrivacy">
+ <activity android:name=".UseMicCamera"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.sensorprivacy.cts.usemiccamera.action.USE_MIC_CAM" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/tests/tests/sensorprivacy/test-apps/CtsUseMicOrCameraForSensorPrivacy/src/android/sensorprivacy/cts/usemiccamera/UseMicCamera.kt b/tests/tests/sensorprivacy/test-apps/CtsUseMicOrCameraForSensorPrivacy/src/android/sensorprivacy/cts/usemiccamera/UseMicCamera.kt
new file mode 100644
index 0000000..d1c5c9f
--- /dev/null
+++ b/tests/tests/sensorprivacy/test-apps/CtsUseMicOrCameraForSensorPrivacy/src/android/sensorprivacy/cts/usemiccamera/UseMicCamera.kt
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2021 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.sensorprivacy.cts.usemiccamera
+
+import android.app.Activity
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.hardware.camera2.CameraDevice
+import android.hardware.camera2.CameraDevice.StateCallback
+import android.hardware.camera2.CameraManager
+import android.media.AudioFormat
+import android.media.AudioRecord
+import android.media.MediaRecorder
+import android.os.Bundle
+import android.os.Handler
+
+private const val MIC = 1 shl 0
+private const val CAM = 1 shl 1
+
+private const val SAMPLING_RATE = 8000
+
+private const val finishMicCamActivityAction =
+ "android.sensorprivacy.cts.usemiccamera.action.FINISH_USE_MIC_CAM"
+private const val useMicExtra =
+ "android.sensorprivacy.cts.usemiccamera.extra.USE_MICROPHONE"
+private const val useCamExtra =
+ "android.sensorprivacy.cts.usemiccamera.extra.USE_CAMERA"
+
+class UseMicCamera : Activity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ val handler = Handler(mainLooper)
+
+ registerReceiver(object : BroadcastReceiver() {
+ override fun onReceive(context: Context?, intent: Intent?) {
+ unregisterReceiver(this)
+ finish()
+ }
+ }, IntentFilter(finishMicCamActivityAction))
+
+ val useMic = intent.getBooleanExtra(useMicExtra, false)
+ val useCam = intent.getBooleanExtra(useCamExtra, false)
+ if (useMic) {
+ handler.postDelayed({ openMic() }, 1000)
+ }
+ if (useCam) {
+ handler.postDelayed({ openCam() }, 1000)
+ }
+ }
+
+ private fun openMic() {
+ val audioRecord = AudioRecord.Builder()
+ .setAudioFormat(AudioFormat.Builder()
+ .setSampleRate(SAMPLING_RATE)
+ .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
+ .setChannelMask(AudioFormat.CHANNEL_IN_MONO).build())
+ .setAudioSource(MediaRecorder.AudioSource.DEFAULT)
+ .setBufferSizeInBytes(
+ AudioRecord.getMinBufferSize(SAMPLING_RATE,
+ AudioFormat.CHANNEL_IN_MONO,
+ AudioFormat.ENCODING_PCM_16BIT) * 10)
+ .build()
+
+ audioRecord.startRecording()
+ }
+
+ private fun openCam() {
+ val cameraManager = getSystemService(CameraManager::class.java)!!
+ val cameraId = cameraManager.cameraIdList[0] ?: return
+ cameraManager.openCamera(cameraId, mainExecutor, object : StateCallback() {
+ override fun onOpened(camera: CameraDevice) {
+ }
+
+ override fun onDisconnected(camera: CameraDevice) {
+ }
+
+ override fun onError(camera: CameraDevice, error: Int) {
+ }
+ })
+ }
+}
\ No newline at end of file