1 /* 2 * Copyright (C) 2024 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 com.android.systemui.qs.tiles.impl.sensorprivacy.ui 18 19 import android.graphics.drawable.TestStubDrawable 20 import android.hardware.SensorPrivacyManager.Sensors.CAMERA 21 import android.hardware.SensorPrivacyManager.Sensors.MICROPHONE 22 import android.widget.Switch 23 import androidx.test.ext.junit.runners.AndroidJUnit4 24 import androidx.test.filters.SmallTest 25 import com.android.systemui.SysuiTestCase 26 import com.android.systemui.common.shared.model.Icon 27 import com.android.systemui.kosmos.Kosmos 28 import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject 29 import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.model.SensorPrivacyToggleTileModel 30 import com.android.systemui.qs.tiles.impl.sensorprivacy.qsCameraSensorPrivacyToggleTileConfig 31 import com.android.systemui.qs.tiles.impl.sensorprivacy.qsMicrophoneSensorPrivacyToggleTileConfig 32 import com.android.systemui.qs.tiles.impl.sensorprivacy.ui.SensorPrivacyTileResources.CameraPrivacyTileResources 33 import com.android.systemui.qs.tiles.impl.sensorprivacy.ui.SensorPrivacyTileResources.MicrophonePrivacyTileResources 34 import com.android.systemui.qs.tiles.viewmodel.QSTileState 35 import com.android.systemui.res.R 36 import org.junit.Test 37 import org.junit.runner.RunWith 38 39 @SmallTest 40 @RunWith(AndroidJUnit4::class) 41 class SensorPrivacyToggleTileMapperTest : SysuiTestCase() { 42 private val kosmos = Kosmos() 43 private val cameraConfig = kosmos.qsCameraSensorPrivacyToggleTileConfig 44 private val micConfig = kosmos.qsMicrophoneSensorPrivacyToggleTileConfig 45 46 @Test mapCamera_notBlockednull47 fun mapCamera_notBlocked() { 48 val mapper = createMapper(CameraPrivacyTileResources) 49 val inputModel = SensorPrivacyToggleTileModel(false) 50 51 val outputState = mapper.map(cameraConfig, inputModel) 52 53 val expectedState = 54 createSensorPrivacyToggleTileState( 55 QSTileState.ActivationState.ACTIVE, 56 context.getString(R.string.quick_settings_camera_mic_available), 57 R.drawable.qs_camera_access_icon_on, 58 null, 59 CAMERA, 60 ) 61 QSTileStateSubject.assertThat(outputState).isEqualTo(expectedState) 62 } 63 64 @Test mapCamera_blockednull65 fun mapCamera_blocked() { 66 val mapper = createMapper(CameraPrivacyTileResources) 67 val inputModel = SensorPrivacyToggleTileModel(true) 68 69 val outputState = mapper.map(cameraConfig, inputModel) 70 71 val expectedState = 72 createSensorPrivacyToggleTileState( 73 QSTileState.ActivationState.INACTIVE, 74 context.getString(R.string.quick_settings_camera_mic_blocked), 75 R.drawable.qs_camera_access_icon_off, 76 null, 77 CAMERA, 78 ) 79 QSTileStateSubject.assertThat(outputState).isEqualTo(expectedState) 80 } 81 82 @Test mapMic_notBlockednull83 fun mapMic_notBlocked() { 84 val mapper = createMapper(MicrophonePrivacyTileResources) 85 val inputModel = SensorPrivacyToggleTileModel(false) 86 87 val outputState = mapper.map(micConfig, inputModel) 88 89 val expectedState = 90 createSensorPrivacyToggleTileState( 91 QSTileState.ActivationState.ACTIVE, 92 context.getString(R.string.quick_settings_camera_mic_available), 93 R.drawable.qs_mic_access_on, 94 null, 95 MICROPHONE, 96 ) 97 QSTileStateSubject.assertThat(outputState).isEqualTo(expectedState) 98 } 99 100 @Test mapMic_blockednull101 fun mapMic_blocked() { 102 val mapper = createMapper(MicrophonePrivacyTileResources) 103 val inputModel = SensorPrivacyToggleTileModel(true) 104 105 val outputState = mapper.map(micConfig, inputModel) 106 107 val expectedState = 108 createSensorPrivacyToggleTileState( 109 QSTileState.ActivationState.INACTIVE, 110 context.getString(R.string.quick_settings_camera_mic_blocked), 111 R.drawable.qs_mic_access_off, 112 null, 113 MICROPHONE, 114 ) 115 QSTileStateSubject.assertThat(outputState).isEqualTo(expectedState) 116 } 117 createMappernull118 private fun createMapper( 119 sensorResources: SensorPrivacyTileResources 120 ): SensorPrivacyToggleTileMapper { 121 val mapper = 122 SensorPrivacyToggleTileMapper( 123 context.orCreateTestableResources 124 .apply { 125 addOverride(R.drawable.qs_camera_access_icon_off, TestStubDrawable()) 126 addOverride(R.drawable.qs_camera_access_icon_on, TestStubDrawable()) 127 addOverride(R.drawable.qs_mic_access_off, TestStubDrawable()) 128 addOverride(R.drawable.qs_mic_access_on, TestStubDrawable()) 129 } 130 .resources, 131 context.theme, 132 sensorResources, 133 ) 134 return mapper 135 } 136 createSensorPrivacyToggleTileStatenull137 private fun createSensorPrivacyToggleTileState( 138 activationState: QSTileState.ActivationState, 139 secondaryLabel: String, 140 iconRes: Int, 141 stateDescription: CharSequence?, 142 sensorId: Int, 143 ): QSTileState { 144 val label = 145 if (sensorId == CAMERA) context.getString(R.string.quick_settings_camera_label) 146 else context.getString(R.string.quick_settings_mic_label) 147 148 return QSTileState( 149 Icon.Loaded(context.getDrawable(iconRes)!!, null), 150 iconRes, 151 label, 152 activationState, 153 secondaryLabel, 154 setOf(QSTileState.UserAction.CLICK, QSTileState.UserAction.LONG_CLICK), 155 label, 156 stateDescription, 157 QSTileState.SideViewIcon.None, 158 QSTileState.EnabledState.ENABLED, 159 Switch::class.qualifiedName, 160 ) 161 } 162 } 163