• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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