1 /* <lambda>null2 * 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 android.service.settings.preferences 18 19 import android.Manifest 20 import android.content.Context 21 import android.os.OutcomeReceiver 22 import android.platform.test.annotations.RequiresFlagsEnabled 23 import android.platform.test.flag.junit.CheckFlagsRule 24 import android.platform.test.flag.junit.DeviceFlagsValueProvider 25 import androidx.test.platform.app.InstrumentationRegistry 26 import com.android.bedstead.harrier.BedsteadJUnit4 27 import com.android.bedstead.nene.TestApis 28 import com.android.settingslib.flags.Flags.FLAG_SETTINGS_CATALYST 29 import com.android.settingslib.flags.Flags.FLAG_WRITE_SYSTEM_PREFERENCE_PERMISSION_ENABLED 30 import com.google.common.truth.Truth 31 import java.util.concurrent.CountDownLatch 32 import java.util.concurrent.TimeUnit 33 import org.junit.After 34 import org.junit.Before 35 import org.junit.Rule 36 import org.junit.Test 37 import org.junit.runner.RunWith 38 39 @RunWith(BedsteadJUnit4::class) 40 class SettingsPreferenceServiceClientTest { 41 42 @get:Rule 43 val checkFlagsRule: CheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule() 44 45 private lateinit var context: Context 46 private lateinit var client: SettingsPreferenceServiceClient 47 48 @Before 49 fun setup() { 50 val connectionLatch = CountDownLatch(1) 51 context = InstrumentationRegistry.getInstrumentation().context 52 TestApis.permissions().withPermission(Manifest.permission.READ_SYSTEM_PREFERENCES).use { 53 client = SettingsPreferenceServiceClient( 54 context, 55 "android.service.settings.preferences.cts", 56 false, 57 context.mainExecutor, 58 object : OutcomeReceiver<SettingsPreferenceServiceClient, Exception> { 59 override fun onResult(result: SettingsPreferenceServiceClient) { 60 connectionLatch.countDown() 61 } 62 63 override fun onError(error: Exception) { 64 throw AssertionError("Binding failed") 65 } 66 } 67 ) 68 if (!connectionLatch.await(1, TimeUnit.SECONDS)) { 69 throw AssertionError("Binding timeout") 70 } 71 } 72 } 73 74 @After 75 fun teardown() { 76 client.close() 77 } 78 79 @RequiresFlagsEnabled(FLAG_SETTINGS_CATALYST) 80 @Test 81 fun getAllPreferenceMetadata_retrievesResult() { 82 val statusLatch = CountDownLatch(1) 83 TestApis.permissions().withPermission(Manifest.permission.READ_SYSTEM_PREFERENCES).use { 84 client.getAllPreferenceMetadata( 85 MetadataRequest.Builder().build(), 86 context.mainExecutor 87 ) { result -> 88 Truth.assertThat(result.resultCode).isEqualTo(MetadataResult.RESULT_OK) 89 Truth.assertThat(result.metadataList).isNotEmpty() 90 statusLatch.countDown() 91 } 92 } 93 Truth.assertThat(statusLatch.await(1, TimeUnit.SECONDS)).isTrue() 94 } 95 96 @RequiresFlagsEnabled(FLAG_SETTINGS_CATALYST) 97 @Test 98 fun getPreferenceValue_retrievesResult() { 99 val statusLatch = CountDownLatch(1) 100 TestApis.permissions().withPermission(Manifest.permission.READ_SYSTEM_PREFERENCES).use { 101 client.getPreferenceValue( 102 GetValueRequest.Builder("s", "k").build(), 103 context.mainExecutor 104 ) { result -> 105 Truth.assertThat(result.resultCode).isEqualTo(MetadataResult.RESULT_OK) 106 Truth.assertThat(result.metadata).isNotNull() 107 Truth.assertThat(result.value).isNotNull() 108 statusLatch.countDown() 109 } 110 } 111 Truth.assertThat(statusLatch.await(1, TimeUnit.SECONDS)).isTrue() 112 } 113 114 @RequiresFlagsEnabled(FLAG_SETTINGS_CATALYST) 115 @Test 116 fun getPreferenceValue_unsupportedKey_retrievesNoResult() { 117 val statusLatch = CountDownLatch(1) 118 TestApis.permissions().withPermission(Manifest.permission.READ_SYSTEM_PREFERENCES).use { 119 client.getPreferenceValue( 120 GetValueRequest.Builder("invalid", "invalid").build(), 121 context.mainExecutor 122 ) { result -> 123 Truth.assertThat(result.resultCode).isEqualTo(MetadataResult.RESULT_UNSUPPORTED) 124 Truth.assertThat(result.metadata).isNull() 125 Truth.assertThat(result.value).isNull() 126 statusLatch.countDown() 127 } 128 } 129 Truth.assertThat(statusLatch.await(1, TimeUnit.SECONDS)).isTrue() 130 } 131 132 @RequiresFlagsEnabled(FLAG_SETTINGS_CATALYST, FLAG_WRITE_SYSTEM_PREFERENCE_PERMISSION_ENABLED) 133 @Test 134 fun setPreferenceValue_retrievesResult() { 135 val statusLatch = CountDownLatch(1) 136 TestApis.permissions().withPermission( 137 Manifest.permission.READ_SYSTEM_PREFERENCES, 138 Manifest.permission.WRITE_SYSTEM_PREFERENCES 139 ).withAppOp("android:write_system_preferences").use { 140 client.setPreferenceValue( 141 SetValueRequest.Builder( 142 "s", 143 "k", 144 SettingsPreferenceValue.Builder(SettingsPreferenceValue.TYPE_STRING) 145 .setStringValue("value") 146 .build() 147 ).build(), 148 context.mainExecutor 149 ) { result -> 150 Truth.assertThat(result.resultCode).isEqualTo(MetadataResult.RESULT_OK) 151 statusLatch.countDown() 152 } 153 } 154 Truth.assertThat(statusLatch.await(1, TimeUnit.SECONDS)).isTrue() 155 } 156 157 @RequiresFlagsEnabled(FLAG_SETTINGS_CATALYST, FLAG_WRITE_SYSTEM_PREFERENCE_PERMISSION_ENABLED) 158 @Test 159 fun setPreferenceValue_withoutPermission_throwsException() { 160 val statusLatch = CountDownLatch(1) 161 client.setPreferenceValue( 162 SetValueRequest.Builder( 163 "s", 164 "k", 165 SettingsPreferenceValue.Builder(SettingsPreferenceValue.TYPE_STRING) 166 .setStringValue("value") 167 .build() 168 ).build(), 169 context.mainExecutor, 170 object : OutcomeReceiver<SetValueResult, Exception> { 171 override fun onResult(result: SetValueResult?) { 172 throw AssertionError("onResult should not be invoked") 173 } 174 175 override fun onError(error: Exception) { 176 Truth.assertThat(error).isInstanceOf(SecurityException::class.java) 177 statusLatch.countDown() 178 } 179 } 180 ) 181 Truth.assertThat(statusLatch.await(1, TimeUnit.SECONDS)).isTrue() 182 } 183 } 184