1 /* 2 * Copyright (C) 2023 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.tests.sdksandbox; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.junit.Assert.assertThrows; 22 import static org.junit.Assume.assumeTrue; 23 24 import android.Manifest; 25 import android.app.sdksandbox.SandboxedSdk; 26 import android.app.sdksandbox.SdkSandboxManager; 27 import android.app.sdksandbox.testutils.EmptyActivity; 28 import android.app.sdksandbox.testutils.FakeLoadSdkCallback; 29 import android.content.Context; 30 import android.os.Bundle; 31 import android.os.IBinder; 32 import android.provider.DeviceConfig; 33 34 import androidx.test.core.app.ApplicationProvider; 35 import androidx.test.ext.junit.rules.ActivityScenarioRule; 36 import androidx.test.platform.app.InstrumentationRegistry; 37 38 import com.android.modules.utils.build.SdkLevel; 39 import com.android.tests.sdkprovider.restrictions.broadcasts.IBroadcastSdkApi; 40 41 import org.junit.After; 42 import org.junit.Before; 43 import org.junit.Rule; 44 import org.junit.Test; 45 import org.junit.runner.RunWith; 46 import org.junit.runners.JUnit4; 47 48 @RunWith(JUnit4.class) 49 public class BroadcastRestrictionsTestApp { 50 private SdkSandboxManager mSdkSandboxManager; 51 private static final String ENFORCE_BROADCAST_RECEIVER_RESTRICTIONS = 52 "enforce_broadcast_receiver_restrictions"; 53 54 private static final String SDK_PACKAGE = 55 "com.android.tests.sdkprovider.restrictions.broadcasts"; 56 57 private Boolean mEnforceBroadcastRestrictionsSandboxNamespace = null; 58 private Boolean mEnforceBroadcastRestrictionsAdServicesNamespace = null; 59 60 /** This rule is defined to start an activity in the foreground to call the sandbox APIs */ 61 @Rule public final ActivityScenarioRule mRule = new ActivityScenarioRule<>(EmptyActivity.class); 62 63 @Before setup()64 public void setup() { 65 Context context = ApplicationProvider.getApplicationContext(); 66 mSdkSandboxManager = context.getSystemService(SdkSandboxManager.class); 67 assertThat(mSdkSandboxManager).isNotNull(); 68 InstrumentationRegistry.getInstrumentation() 69 .getUiAutomation() 70 .adoptShellPermissionIdentity( 71 Manifest.permission.WRITE_DEVICE_CONFIG, 72 Manifest.permission.READ_DEVICE_CONFIG); 73 DeviceConfig.Properties propertiesSdkSandboxNamespace = 74 DeviceConfig.getProperties( 75 DeviceConfig.NAMESPACE_SDK_SANDBOX, 76 ENFORCE_BROADCAST_RECEIVER_RESTRICTIONS); 77 if (propertiesSdkSandboxNamespace 78 .getKeyset() 79 .contains(ENFORCE_BROADCAST_RECEIVER_RESTRICTIONS)) { 80 mEnforceBroadcastRestrictionsSandboxNamespace = 81 propertiesSdkSandboxNamespace.getBoolean( 82 ENFORCE_BROADCAST_RECEIVER_RESTRICTIONS, /*defaultValue=*/ false); 83 } 84 DeviceConfig.Properties propertiesAdServicesNamespace = 85 DeviceConfig.getProperties( 86 DeviceConfig.NAMESPACE_ADSERVICES, ENFORCE_BROADCAST_RECEIVER_RESTRICTIONS); 87 if (propertiesAdServicesNamespace 88 .getKeyset() 89 .contains(ENFORCE_BROADCAST_RECEIVER_RESTRICTIONS)) { 90 mEnforceBroadcastRestrictionsAdServicesNamespace = 91 propertiesSdkSandboxNamespace.getBoolean( 92 ENFORCE_BROADCAST_RECEIVER_RESTRICTIONS, /*defaultValue=*/ false); 93 } 94 mRule.getScenario(); 95 96 // Greedily unload SDK to reduce flakiness 97 mSdkSandboxManager.unloadSdk(SDK_PACKAGE); 98 } 99 100 @After tearDown()101 public void tearDown() { 102 /** 103 * We check if the properties contain enforce_broadcast_receiver_restrictions key, and 104 * update the property to the pre-test value 105 */ 106 if (mEnforceBroadcastRestrictionsSandboxNamespace != null) { 107 DeviceConfig.setProperty( 108 DeviceConfig.NAMESPACE_SDK_SANDBOX, 109 ENFORCE_BROADCAST_RECEIVER_RESTRICTIONS, 110 String.valueOf(mEnforceBroadcastRestrictionsSandboxNamespace), 111 /*makeDefault=*/ false); 112 } else { 113 DeviceConfig.deleteProperty( 114 DeviceConfig.NAMESPACE_SDK_SANDBOX, ENFORCE_BROADCAST_RECEIVER_RESTRICTIONS); 115 } 116 117 if (mEnforceBroadcastRestrictionsAdServicesNamespace != null) { 118 DeviceConfig.setProperty( 119 DeviceConfig.NAMESPACE_ADSERVICES, 120 ENFORCE_BROADCAST_RECEIVER_RESTRICTIONS, 121 String.valueOf(mEnforceBroadcastRestrictionsAdServicesNamespace), 122 /*makeDefault=*/ false); 123 } else { 124 DeviceConfig.deleteProperty( 125 DeviceConfig.NAMESPACE_ADSERVICES, ENFORCE_BROADCAST_RECEIVER_RESTRICTIONS); 126 } 127 128 InstrumentationRegistry.getInstrumentation() 129 .getUiAutomation() 130 .dropShellPermissionIdentity(); 131 132 // Greedily unload SDK to reduce flakiness 133 mSdkSandboxManager.unloadSdk(SDK_PACKAGE); 134 } 135 136 /** 137 * Tests that a SecurityException is not thrown when SDK sandbox process tries to register a 138 * broadcast receiver because the default value of false. 139 */ 140 @Test testRegisterBroadcastReceiver_defaultValueRestrictionsNotApplied()141 public void testRegisterBroadcastReceiver_defaultValueRestrictionsNotApplied() 142 throws Exception { 143 assumeTrue(SdkLevel.isAtLeastU()); 144 145 /** Ensuring that the property is not present in DeviceConfig */ 146 DeviceConfig.deleteProperty( 147 DeviceConfig.NAMESPACE_ADSERVICES, ENFORCE_BROADCAST_RECEIVER_RESTRICTIONS); 148 FakeLoadSdkCallback callback = new FakeLoadSdkCallback(); 149 mSdkSandboxManager.loadSdk(SDK_PACKAGE, new Bundle(), Runnable::run, callback); 150 callback.assertLoadSdkIsSuccessful(); 151 SandboxedSdk sandboxedSdk = callback.getSandboxedSdk(); 152 153 IBinder binder = sandboxedSdk.getInterface(); 154 IBroadcastSdkApi broadcastSdkApi = IBroadcastSdkApi.Stub.asInterface(binder); 155 156 broadcastSdkApi.registerBroadcastReceiver(); 157 } 158 159 /** 160 * Tests that a SecurityException is thrown when SDK sandbox process tries to register a 161 * broadcast receiver. This behavior depends on the value of a {@link DeviceConfig} property. 162 */ 163 @Test testRegisterBroadcastReceiver_restrictionsApplied()164 public void testRegisterBroadcastReceiver_restrictionsApplied() throws Exception { 165 assumeTrue(SdkLevel.isAtLeastU()); 166 167 DeviceConfig.setProperty( 168 DeviceConfig.NAMESPACE_ADSERVICES, 169 ENFORCE_BROADCAST_RECEIVER_RESTRICTIONS, 170 "true", 171 false); 172 173 FakeLoadSdkCallback callback = new FakeLoadSdkCallback(); 174 mSdkSandboxManager.loadSdk(SDK_PACKAGE, new Bundle(), Runnable::run, callback); 175 callback.assertLoadSdkIsSuccessful(); 176 SandboxedSdk sandboxedSdk = callback.getSandboxedSdk(); 177 178 IBinder binder = sandboxedSdk.getInterface(); 179 IBroadcastSdkApi broadcastSdkApi = IBroadcastSdkApi.Stub.asInterface(binder); 180 181 final SecurityException thrown = 182 assertThrows( 183 SecurityException.class, () -> broadcastSdkApi.registerBroadcastReceiver()); 184 185 assertThat(thrown).hasMessageThat().contains("android.intent.action.SEND"); 186 assertThat(thrown).hasMessageThat().contains("android.intent.action.VIEW"); 187 assertThat(thrown) 188 .hasMessageThat() 189 .contains( 190 "SDK sandbox not allowed to register receiver with the given IntentFilter"); 191 } 192 193 /** 194 * Tests that a SecurityException is not thrown when SDK sandbox process tries to register a 195 * broadcast receiver. This behavior depends on the value of a {@link DeviceConfig} property. 196 */ 197 @Test(expected = Test.None.class /* no exception expected */) testRegisterBroadcastReceiver_restrictionsNotApplied()198 public void testRegisterBroadcastReceiver_restrictionsNotApplied() throws Exception { 199 assumeTrue(SdkLevel.isAtLeastU()); 200 201 DeviceConfig.setProperty( 202 DeviceConfig.NAMESPACE_ADSERVICES, 203 ENFORCE_BROADCAST_RECEIVER_RESTRICTIONS, 204 "false", 205 false); 206 207 FakeLoadSdkCallback callback = new FakeLoadSdkCallback(); 208 mSdkSandboxManager.loadSdk(SDK_PACKAGE, new Bundle(), Runnable::run, callback); 209 callback.assertLoadSdkIsSuccessful(); 210 SandboxedSdk sandboxedSdk = callback.getSandboxedSdk(); 211 212 IBinder binder = sandboxedSdk.getInterface(); 213 IBroadcastSdkApi broadcastSdkApi = IBroadcastSdkApi.Stub.asInterface(binder); 214 215 broadcastSdkApi.registerBroadcastReceiver(); 216 } 217 218 @Test testRegisterBroadcastReceiver_defaultValueRestrictionsNotApplied_preU()219 public void testRegisterBroadcastReceiver_defaultValueRestrictionsNotApplied_preU() 220 throws Exception { 221 if (SdkLevel.isAtLeastU()) { 222 return; 223 } 224 225 /** Ensuring that the property is not present in DeviceConfig */ 226 DeviceConfig.deleteProperty( 227 DeviceConfig.NAMESPACE_SDK_SANDBOX, ENFORCE_BROADCAST_RECEIVER_RESTRICTIONS); 228 FakeLoadSdkCallback callback = new FakeLoadSdkCallback(); 229 mSdkSandboxManager.loadSdk(SDK_PACKAGE, new Bundle(), Runnable::run, callback); 230 callback.assertLoadSdkIsSuccessful(); 231 SandboxedSdk sandboxedSdk = callback.getSandboxedSdk(); 232 233 IBinder binder = sandboxedSdk.getInterface(); 234 IBroadcastSdkApi broadcastSdkApi = IBroadcastSdkApi.Stub.asInterface(binder); 235 236 broadcastSdkApi.registerBroadcastReceiver(); 237 } 238 239 @Test testRegisterBroadcastReceiver_restrictionsApplied_preU()240 public void testRegisterBroadcastReceiver_restrictionsApplied_preU() throws Exception { 241 if (SdkLevel.isAtLeastU()) { 242 return; 243 } 244 245 DeviceConfig.setProperty( 246 DeviceConfig.NAMESPACE_SDK_SANDBOX, 247 ENFORCE_BROADCAST_RECEIVER_RESTRICTIONS, 248 "true", 249 false); 250 251 FakeLoadSdkCallback callback = new FakeLoadSdkCallback(); 252 mSdkSandboxManager.loadSdk(SDK_PACKAGE, new Bundle(), Runnable::run, callback); 253 callback.assertLoadSdkIsSuccessful(); 254 SandboxedSdk sandboxedSdk = callback.getSandboxedSdk(); 255 256 IBinder binder = sandboxedSdk.getInterface(); 257 IBroadcastSdkApi broadcastSdkApi = IBroadcastSdkApi.Stub.asInterface(binder); 258 259 final SecurityException thrown = 260 assertThrows( 261 SecurityException.class, () -> broadcastSdkApi.registerBroadcastReceiver()); 262 263 assertThat(thrown) 264 .hasMessageThat() 265 .contains("SDK sandbox process not allowed to call registerReceiver"); 266 } 267 268 /** 269 * Tests that a SecurityException is not thrown when SDK sandbox process tries to register a 270 * broadcast receiver. This behavior depends on the value of a {@link DeviceConfig} property. 271 */ 272 @Test(expected = Test.None.class /* no exception expected */) testRegisterBroadcastReceiver_restrictionsNotApplied_preU()273 public void testRegisterBroadcastReceiver_restrictionsNotApplied_preU() throws Exception { 274 if (SdkLevel.isAtLeastU()) { 275 return; 276 } 277 278 DeviceConfig.setProperty( 279 DeviceConfig.NAMESPACE_SDK_SANDBOX, 280 ENFORCE_BROADCAST_RECEIVER_RESTRICTIONS, 281 "false", 282 false); 283 284 FakeLoadSdkCallback callback = new FakeLoadSdkCallback(); 285 mSdkSandboxManager.loadSdk(SDK_PACKAGE, new Bundle(), Runnable::run, callback); 286 callback.assertLoadSdkIsSuccessful(); 287 SandboxedSdk sandboxedSdk = callback.getSandboxedSdk(); 288 289 IBinder binder = sandboxedSdk.getInterface(); 290 IBroadcastSdkApi broadcastSdkApi = IBroadcastSdkApi.Stub.asInterface(binder); 291 292 broadcastSdkApi.registerBroadcastReceiver(); 293 } 294 295 /** 296 * Tests that a SecurityException is thrown when SDK sandbox process tries to register a 297 * broadcast receiver with no action mentioned in the {@link android.content.IntentFilter} 298 * object. 299 */ 300 @Test testRegisterBroadcastReceiver_intentFilterWithoutAction()301 public void testRegisterBroadcastReceiver_intentFilterWithoutAction() throws Exception { 302 assumeTrue(SdkLevel.isAtLeastU()); 303 304 FakeLoadSdkCallback callback = new FakeLoadSdkCallback(); 305 mSdkSandboxManager.loadSdk(SDK_PACKAGE, new Bundle(), Runnable::run, callback); 306 callback.assertLoadSdkIsSuccessful(); 307 SandboxedSdk sandboxedSdk = callback.getSandboxedSdk(); 308 309 IBinder binder = sandboxedSdk.getInterface(); 310 IBroadcastSdkApi broadcastSdkApi = IBroadcastSdkApi.Stub.asInterface(binder); 311 312 final SecurityException thrown = 313 assertThrows( 314 SecurityException.class, 315 () -> broadcastSdkApi.registerBroadcastReceiverWithoutAction()); 316 317 assertThat(thrown) 318 .hasMessageThat() 319 .contains( 320 "SDK sandbox not allowed to register receiver with the given IntentFilter"); 321 } 322 323 /** 324 * Tests that broadcast receiver is registered successfully from SDK sandbox process with no 325 * action mentioned in the {@link android.content.IntentFilter} object. 326 */ 327 @Test testRegisterBroadcastReceiver_intentFilterWithoutAction_preU()328 public void testRegisterBroadcastReceiver_intentFilterWithoutAction_preU() throws Exception { 329 if (SdkLevel.isAtLeastU()) { 330 return; 331 } 332 333 FakeLoadSdkCallback callback = new FakeLoadSdkCallback(); 334 mSdkSandboxManager.loadSdk(SDK_PACKAGE, new Bundle(), Runnable::run, callback); 335 callback.assertLoadSdkIsSuccessful(); 336 SandboxedSdk sandboxedSdk = callback.getSandboxedSdk(); 337 338 IBinder binder = sandboxedSdk.getInterface(); 339 IBroadcastSdkApi broadcastSdkApi = IBroadcastSdkApi.Stub.asInterface(binder); 340 341 broadcastSdkApi.registerBroadcastReceiverWithoutAction(); 342 } 343 } 344