1 /* 2 * Copyright (C) 2025 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 package com.android.settings.supervision 17 18 import android.app.Activity 19 import android.app.supervision.SupervisionManager 20 import android.content.Context 21 import android.content.ContextWrapper 22 import android.content.Intent 23 import androidx.preference.Preference 24 import androidx.test.core.app.ApplicationProvider 25 import androidx.test.ext.junit.runners.AndroidJUnit4 26 import com.android.settings.supervision.SupervisionMainSwitchPreference.Companion.REQUEST_CODE_CONFIRM_SUPERVISION_CREDENTIALS 27 import com.android.settingslib.metadata.PreferenceLifecycleContext 28 import com.android.settingslib.preference.createAndBindWidget 29 import com.android.settingslib.widget.MainSwitchPreference 30 import com.google.common.truth.Truth.assertThat 31 import org.junit.Before 32 import org.junit.Test 33 import org.junit.runner.RunWith 34 import org.mockito.kotlin.argumentCaptor 35 import org.mockito.kotlin.doReturn 36 import org.mockito.kotlin.eq 37 import org.mockito.kotlin.mock 38 import org.mockito.kotlin.never 39 import org.mockito.kotlin.stub 40 import org.mockito.kotlin.verify 41 42 @RunWith(AndroidJUnit4::class) 43 class SupervisionMainSwitchPreferenceTest { 44 private val mockLifeCycleContext = mock<PreferenceLifecycleContext>() 45 private val mockSupervisionManager = mock<SupervisionManager>() 46 47 private val appContext: Context = ApplicationProvider.getApplicationContext() 48 private val context = 49 object : ContextWrapper(appContext) { getSystemServicenull50 override fun getSystemService(name: String): Any = 51 when (name) { 52 Context.SUPERVISION_SERVICE -> mockSupervisionManager 53 else -> super.getSystemService(name) 54 } 55 } 56 57 private val preference = SupervisionMainSwitchPreference(context) 58 59 @Before setUpnull60 fun setUp() { 61 preference.onCreate(mockLifeCycleContext) 62 } 63 64 @Test checked_supervisionEnabled_returnTruenull65 fun checked_supervisionEnabled_returnTrue() { 66 setSupervisionEnabled(true) 67 68 assertThat(getMainSwitchPreference().isChecked).isTrue() 69 } 70 71 @Test checked_supervisionDisabled_returnFalsenull72 fun checked_supervisionDisabled_returnFalse() { 73 setSupervisionEnabled(false) 74 75 assertThat(getMainSwitchPreference().isChecked).isFalse() 76 } 77 78 @Test toggleOn_triggersPinVerificationnull79 fun toggleOn_triggersPinVerification() { 80 setSupervisionEnabled(false) 81 val widget = getMainSwitchPreference() 82 83 assertThat(widget.isChecked).isFalse() 84 85 widget.performClick() 86 87 verifyConfirmSupervisionCredentialsActivityStarted() 88 assertThat(widget.isChecked).isFalse() 89 verify(mockSupervisionManager, never()).setSupervisionEnabled(false) 90 } 91 92 @Test toggleOn_pinVerificationSucceeded_supervisionEnablednull93 fun toggleOn_pinVerificationSucceeded_supervisionEnabled() { 94 setSupervisionEnabled(false) 95 val widget = getMainSwitchPreference() 96 97 assertThat(widget.isChecked).isFalse() 98 99 preference.onActivityResult( 100 mockLifeCycleContext, 101 REQUEST_CODE_CONFIRM_SUPERVISION_CREDENTIALS, 102 Activity.RESULT_OK, 103 null, 104 ) 105 106 assertThat(widget.isChecked).isTrue() 107 verify(mockSupervisionManager).setSupervisionEnabled(true) 108 } 109 110 @Test toggleOff_pinVerificationSucceeded_supervisionDisablednull111 fun toggleOff_pinVerificationSucceeded_supervisionDisabled() { 112 setSupervisionEnabled(true) 113 val widget = getMainSwitchPreference() 114 115 assertThat(widget.isChecked).isTrue() 116 117 preference.onActivityResult( 118 mockLifeCycleContext, 119 REQUEST_CODE_CONFIRM_SUPERVISION_CREDENTIALS, 120 Activity.RESULT_OK, 121 null, 122 ) 123 124 assertThat(widget.isChecked).isFalse() 125 verify(mockSupervisionManager).setSupervisionEnabled(false) 126 } 127 128 @Test toggleOff_pinVerificationFailed_supervisionNotEnablednull129 fun toggleOff_pinVerificationFailed_supervisionNotEnabled() { 130 setSupervisionEnabled(true) 131 val widget = getMainSwitchPreference() 132 133 assertThat(widget.isChecked).isTrue() 134 135 preference.onActivityResult( 136 mockLifeCycleContext, 137 REQUEST_CODE_CONFIRM_SUPERVISION_CREDENTIALS, 138 Activity.RESULT_CANCELED, 139 null, 140 ) 141 142 assertThat(widget.isChecked).isTrue() 143 verify(mockSupervisionManager, never()).setSupervisionEnabled(true) 144 } 145 setSupervisionEnablednull146 private fun setSupervisionEnabled(enabled: Boolean) = 147 mockSupervisionManager.stub { on { isSupervisionEnabled } doReturn enabled } 148 getMainSwitchPreferencenull149 private fun getMainSwitchPreference(): MainSwitchPreference { 150 val widget: MainSwitchPreference = preference.createAndBindWidget(context) 151 152 mockLifeCycleContext.stub { 153 on { findPreference<Preference>(SupervisionMainSwitchPreference.KEY) } doReturn widget 154 on { 155 requirePreference<MainSwitchPreference>(SupervisionMainSwitchPreference.KEY) 156 } doReturn widget 157 } 158 return widget 159 } 160 verifyConfirmSupervisionCredentialsActivityStartednull161 private fun verifyConfirmSupervisionCredentialsActivityStarted() { 162 val intentCaptor = argumentCaptor<Intent>() 163 verify(mockLifeCycleContext) 164 .startActivityForResult( 165 intentCaptor.capture(), 166 eq(REQUEST_CODE_CONFIRM_SUPERVISION_CREDENTIALS), 167 eq(null), 168 ) 169 assertThat(intentCaptor.allValues.size).isEqualTo(1) 170 assertThat(intentCaptor.firstValue.component?.className) 171 .isEqualTo(ConfirmSupervisionCredentialsActivity::class.java.name) 172 } 173 } 174