xref: /aosp_15_r20/cts/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyResourcesTest.java (revision b7c941bb3fa97aba169d73cee0bed2de8ac964bf)
1 /*
2  * Copyright (C) 2022 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.devicepolicy.cts;
18 
19 import static android.Manifest.permission.UPDATE_DEVICE_MANAGEMENT_RESOURCES;
20 
21 import static com.google.common.truth.Truth.assertThat;
22 
23 import static org.junit.Assert.assertThrows;
24 
25 import android.app.admin.DevicePolicyDrawableResource;
26 import android.app.admin.DevicePolicyManager;
27 import android.app.admin.DevicePolicyResources;
28 import android.app.admin.DevicePolicyStringResource;
29 import android.content.Context;
30 import android.graphics.Bitmap;
31 import android.graphics.Canvas;
32 import android.graphics.drawable.Drawable;
33 import android.graphics.drawable.Icon;
34 
35 import com.android.bedstead.harrier.BedsteadJUnit4;
36 import com.android.bedstead.harrier.DeviceState;
37 import com.android.bedstead.permissions.annotations.EnsureDoesNotHavePermission;
38 import com.android.bedstead.permissions.annotations.EnsureHasPermission;
39 import com.android.bedstead.harrier.annotations.Postsubmit;
40 import com.android.bedstead.nene.TestApis;
41 import com.android.bedstead.nene.utils.BlockingBroadcastReceiver;
42 
43 import org.junit.After;
44 import org.junit.Before;
45 import org.junit.ClassRule;
46 import org.junit.Ignore;
47 import org.junit.Rule;
48 import org.junit.Test;
49 import org.junit.runner.RunWith;
50 
51 import java.util.Set;
52 import java.util.function.Supplier;
53 
54 // TODO(b/208084779): Add more tests to cover calling from other packages after adding support for
55 //  the new APIs in the test sdk.
56 @RunWith(BedsteadJUnit4.class)
57 public class DevicePolicyResourcesTest {
58     private static final String TAG = "DevicePolicyResourcesTests";
59 
60     private static final Context sContext = TestApis.context().instrumentedContext();
61     private static final DevicePolicyManager sDpm =
62             sContext.getSystemService(DevicePolicyManager.class);
63 
64     private static final String UPDATABLE_DRAWABLE_ID_1 = "UPDATABLE_DRAWABLE_ID_1";
65     private static final String UPDATABLE_DRAWABLE_ID_2 = "UPDATABLE_DRAWABLE_ID_2";
66     private static final String DRAWABLE_STYLE_1 = "DRAWABLE_STYLE_1";
67     private static final String DRAWABLE_STYLE_2 = "DRAWABLE_STYLE_2";
68     private static final String DRAWABLE_SOURCE_1 = "DRAWABLE_SOURCE_1";
69     private static final String DRAWABLE_SOURCE_2 = "DRAWABLE_SOURCE_2";
70 
71     private static final String UPDATABLE_STRING_ID_1 = "UPDATABLE_STRING_ID_1";
72     private static final String UPDATABLE_STRING_ID_2 = "UPDATABLE_STRING_ID_2";
73 
74     private static final int INVALID_RESOURCE_ID = -1;
75 
76     @ClassRule
77     @Rule
78     public static final DeviceState sDeviceState = new DeviceState();
79 
80     @After
tearDown()81     public void tearDown() {
82         resetAllResources();
83     }
84 
85     @Before
setup()86     public void setup() {
87         resetAllResources();
88     }
89 
resetAllResources()90     private void resetAllResources() {
91         TestApis.devicePolicy().resources().drawables().reset(
92                 UPDATABLE_DRAWABLE_ID_1, UPDATABLE_DRAWABLE_ID_2);
93         TestApis.devicePolicy().resources().strings().reset(
94                 UPDATABLE_STRING_ID_1, UPDATABLE_STRING_ID_2);
95     }
96 
97     @Test
98     @Postsubmit(reason = "New test")
99     @EnsureDoesNotHavePermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
setDrawables_withoutRequiredPermission_throwsSecurityException()100     public void setDrawables_withoutRequiredPermission_throwsSecurityException() {
101         assertThrows(SecurityException.class, () ->
102                 sDpm.getResources().setDrawables(createDrawable(
103                         UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1, R.drawable.test_drawable_1)));
104     }
105 
106     @Test
107     @Postsubmit(reason = "New test")
108     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
setDrawables_withRequiredPermission_doesNotThrowSecurityException()109     public void setDrawables_withRequiredPermission_doesNotThrowSecurityException() {
110         sDpm.getResources().setDrawables(createDrawable(
111                 UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1, R.drawable.test_drawable_1));
112     }
113 
114     @Test
115     @Postsubmit(reason = "New test")
116     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
setDrawables_updatesCorrectUpdatableDrawable()117     public void setDrawables_updatesCorrectUpdatableDrawable() {
118         sDpm.getResources().setDrawables(createDrawable(
119                 UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1, R.drawable.test_drawable_1));
120 
121         Drawable drawable = sDpm.getResources().getDrawable(
122                 UPDATABLE_DRAWABLE_ID_1,
123                 DRAWABLE_STYLE_1,
124                 /* default= */ () -> null);
125         assertThat(areSameDrawables(drawable, sContext.getDrawable(R.drawable.test_drawable_1)))
126                 .isTrue();
127     }
128 
129     @Test
130     @Postsubmit(reason = "New test")
131     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
setDrawables_updatesCurrentlyUpdatedDrawable()132     public void setDrawables_updatesCurrentlyUpdatedDrawable() {
133         sDpm.getResources().setDrawables(createDrawable(
134                 UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1, R.drawable.test_drawable_1));
135 
136         sDpm.getResources().setDrawables(createDrawable(
137                 UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1, R.drawable.test_drawable_2));
138 
139         Drawable drawable = sDpm.getResources().getDrawable(
140                 UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1, /* default= */ () -> null);
141         assertThat(areSameDrawables(drawable, sContext.getDrawable(R.drawable.test_drawable_2)))
142                 .isTrue();
143     }
144 
145     @Test
146     @Postsubmit(reason = "New test")
147     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
setDrawables_doesNotUpdateOtherUpdatableDrawables()148     public void setDrawables_doesNotUpdateOtherUpdatableDrawables() {
149         Drawable defaultDrawable = sContext.getDrawable(R.drawable.test_drawable_2);
150         sDpm.getResources().resetDrawables(Set.of(UPDATABLE_DRAWABLE_ID_2));
151 
152         sDpm.getResources().setDrawables(createDrawable(
153                 UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1, R.drawable.test_drawable_1));
154 
155         Drawable drawable = sDpm.getResources().getDrawable(
156                 UPDATABLE_DRAWABLE_ID_2, DRAWABLE_STYLE_1, /* default= */ () -> defaultDrawable);
157         assertThat(drawable).isEqualTo(defaultDrawable);
158     }
159 
160     @Test
161     @Postsubmit(reason = "New test")
162     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
setDrawables_updateForSource_updatesCorrectly()163     public void setDrawables_updateForSource_updatesCorrectly() {
164         sDpm.getResources().setDrawables(createDrawable(
165                 UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1, R.drawable.test_drawable_1));
166 
167         sDpm.getResources().setDrawables(createDrawableForSource(
168                 DRAWABLE_SOURCE_1, UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1,
169                 R.drawable.test_drawable_2));
170 
171         Drawable drawable = sDpm.getResources().getDrawable(
172                 UPDATABLE_DRAWABLE_ID_1,
173                 DRAWABLE_STYLE_1,
174                 DRAWABLE_SOURCE_1,
175                 /* default= */ () -> null);
176         assertThat(areSameDrawables(drawable, sContext.getDrawable(R.drawable.test_drawable_2)))
177                 .isTrue();
178     }
179 
180     @Test
181     @Postsubmit(reason = "New test")
182     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
setDrawables_updateForMultipleSources_updatesCorrectly()183     public void setDrawables_updateForMultipleSources_updatesCorrectly() {
184         sDpm.getResources().setDrawables(createDrawableForSource(
185                 DRAWABLE_SOURCE_1, UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1,
186                 R.drawable.test_drawable_1));
187         sDpm.getResources().setDrawables(createDrawableForSource(
188                 DRAWABLE_SOURCE_2, UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1,
189                 R.drawable.test_drawable_2));
190 
191         Drawable drawable1 = sDpm.getResources().getDrawable(
192                 UPDATABLE_DRAWABLE_ID_1,
193                 DRAWABLE_STYLE_1,
194                 DRAWABLE_SOURCE_1,
195                 /* default= */ () -> null);
196         assertThat(areSameDrawables(drawable1, sContext.getDrawable(R.drawable.test_drawable_1)))
197                 .isTrue();
198         Drawable drawable2 = sDpm.getResources().getDrawable(
199                 UPDATABLE_DRAWABLE_ID_1,
200                 DRAWABLE_STYLE_1,
201                 DRAWABLE_SOURCE_2,
202                 /* default= */ () -> null);
203         assertThat(areSameDrawables(drawable2, sContext.getDrawable(R.drawable.test_drawable_2)))
204                 .isTrue();
205     }
206 
207     @Test
208     @Postsubmit(reason = "New test")
209     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
setDrawables_updateForSource_returnsGenericForUndefinedSource()210     public void setDrawables_updateForSource_returnsGenericForUndefinedSource() {
211         sDpm.getResources().setDrawables(createDrawable(
212                 UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1, R.drawable.test_drawable_1));
213 
214         sDpm.getResources().setDrawables(createDrawableForSource(
215                 DRAWABLE_SOURCE_1, UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1,
216                 R.drawable.test_drawable_2));
217 
218         Drawable drawable = sDpm.getResources().getDrawable(
219                 UPDATABLE_DRAWABLE_ID_1,
220                 DRAWABLE_STYLE_1,
221                 /* default= */ () -> null);
222         assertThat(areSameDrawables(drawable, sContext.getDrawable(R.drawable.test_drawable_1)))
223                 .isTrue();
224     }
225 
226     @Test
227     @Postsubmit(reason = "New test")
228     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
setDrawables_updateForSource_returnsGenericForUndefinedStyle()229     public void setDrawables_updateForSource_returnsGenericForUndefinedStyle() {
230         sDpm.getResources().setDrawables(createDrawable(
231                 UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1, R.drawable.test_drawable_1));
232 
233         sDpm.getResources().setDrawables(createDrawableForSource(
234                 DRAWABLE_SOURCE_1, UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_2,
235                 R.drawable.test_drawable_2));
236 
237         Drawable drawable = sDpm.getResources().getDrawable(
238                 UPDATABLE_DRAWABLE_ID_1,
239                 DRAWABLE_STYLE_1,
240                 DRAWABLE_SOURCE_1,
241                 /* default= */ () -> null);
242         assertThat(areSameDrawables(drawable, sContext.getDrawable(R.drawable.test_drawable_1)))
243                 .isTrue();
244     }
245 
246     @Test
247     @Postsubmit(reason = "New test")
248     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
setDrawables_drawableChangedFromNull_sendsBroadcast()249     public void setDrawables_drawableChangedFromNull_sendsBroadcast() {
250         sDpm.getResources().resetDrawables(Set.of(UPDATABLE_DRAWABLE_ID_1));
251         BlockingBroadcastReceiver broadcastReceiver = sDeviceState.registerBroadcastReceiver(
252                 DevicePolicyManager.ACTION_DEVICE_POLICY_RESOURCE_UPDATED);
253 
254         sDpm.getResources().setDrawables(createDrawable(
255                 UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1, R.drawable.test_drawable_1));
256 
257         broadcastReceiver.awaitForBroadcastOrFail();
258     }
259 
260     @Test
261     @Postsubmit(reason = "New test")
262     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
setDrawables_drawableChangedFromOtherDrawable_sendsBroadcast()263     public void setDrawables_drawableChangedFromOtherDrawable_sendsBroadcast() {
264         sDpm.getResources().setDrawables(createDrawable(
265                 UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1, R.drawable.test_drawable_1));
266         BlockingBroadcastReceiver broadcastReceiver = sDeviceState.registerBroadcastReceiver(
267                 DevicePolicyManager.ACTION_DEVICE_POLICY_RESOURCE_UPDATED);
268 
269         sDpm.getResources().setDrawables(createDrawable(
270                 UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1, R.drawable.test_drawable_2));
271 
272         broadcastReceiver.awaitForBroadcastOrFail();
273     }
274 
275     @Test
276     @Postsubmit(reason = "New test")
277     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
278     @Ignore("b/208237942")
setDrawables_drawableNotChanged_doesNotSendBroadcast()279     public void setDrawables_drawableNotChanged_doesNotSendBroadcast() {
280         sDpm.getResources().setDrawables(createDrawable(
281                 UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1, R.drawable.test_drawable_1));
282         BlockingBroadcastReceiver broadcastReceiver = sDeviceState.registerBroadcastReceiver(
283                 DevicePolicyManager.ACTION_DEVICE_POLICY_RESOURCE_UPDATED);
284 
285         sDpm.getResources().setDrawables(createDrawable(
286                 UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1, R.drawable.test_drawable_1));
287 
288         assertThat(broadcastReceiver.awaitForBroadcast()).isNull();
289     }
290 
291     @Test
292     @Postsubmit(reason = "New test")
293     @EnsureDoesNotHavePermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
resetDrawables_withoutRequiredPermission_throwsSecurityException()294     public void resetDrawables_withoutRequiredPermission_throwsSecurityException() {
295         assertThrows(SecurityException.class, () -> sDpm.getResources().resetDrawables(
296                 Set.of(UPDATABLE_DRAWABLE_ID_1)));
297     }
298 
299     @Test
300     @Postsubmit(reason = "New test")
301     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
resetDrawables_withRequiredPermission_doesNotThrowSecurityException()302     public void resetDrawables_withRequiredPermission_doesNotThrowSecurityException() {
303         sDpm.getResources().resetDrawables(Set.of(UPDATABLE_DRAWABLE_ID_1));
304     }
305 
306     @Test
307     @Postsubmit(reason = "New test")
308     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
resetDrawables_removesPreviouslySetDrawables()309     public void resetDrawables_removesPreviouslySetDrawables() {
310         Drawable defaultDrawable = sContext.getDrawable(R.drawable.test_drawable_2);
311         sDpm.getResources().setDrawables(createDrawable(
312                 UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1, R.drawable.test_drawable_1));
313 
314         sDpm.getResources().resetDrawables(Set.of(UPDATABLE_DRAWABLE_ID_1));
315 
316         Drawable drawable = sDpm.getResources().getDrawable(
317                 UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1, /* default= */ () -> defaultDrawable);
318         assertThat(drawable).isEqualTo(defaultDrawable);
319     }
320 
321     @Test
322     @Postsubmit(reason = "New test")
323     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
resetDrawables_doesNotResetOtherSetDrawables()324     public void resetDrawables_doesNotResetOtherSetDrawables() {
325         sDpm.getResources().setDrawables(createDrawable(
326                 UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1, R.drawable.test_drawable_1));
327         sDpm.getResources().setDrawables(createDrawable(
328                 UPDATABLE_DRAWABLE_ID_2, DRAWABLE_STYLE_1, R.drawable.test_drawable_2));
329 
330         sDpm.getResources().resetDrawables(Set.of(UPDATABLE_DRAWABLE_ID_1));
331 
332         Drawable drawable = sDpm.getResources().getDrawable(
333                 UPDATABLE_DRAWABLE_ID_2, DRAWABLE_STYLE_1, /* default= */ () -> null);
334         assertThat(areSameDrawables(drawable, sContext.getDrawable(R.drawable.test_drawable_2)))
335                 .isTrue();
336     }
337 
338     @Test
339     @Postsubmit(reason = "New test")
340     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
resetDrawables_drawableChanged_sendsBroadcast()341     public void resetDrawables_drawableChanged_sendsBroadcast() {
342         sDpm.getResources().setDrawables(createDrawable(
343                 UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1, R.drawable.test_drawable_1));
344         BlockingBroadcastReceiver broadcastReceiver = sDeviceState.registerBroadcastReceiver(
345                 DevicePolicyManager.ACTION_DEVICE_POLICY_RESOURCE_UPDATED);
346 
347         sDpm.getResources().resetDrawables(Set.of(UPDATABLE_DRAWABLE_ID_1));
348 
349         broadcastReceiver.awaitForBroadcastOrFail();
350     }
351 
352     @Test
353     @Postsubmit(reason = "New test")
354     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
355     @Ignore("b/208237942")
resetDrawables_drawableNotChanged_doesNotSendBroadcast()356     public void resetDrawables_drawableNotChanged_doesNotSendBroadcast() {
357         sDpm.getResources().resetDrawables(Set.of(UPDATABLE_DRAWABLE_ID_1));
358         BlockingBroadcastReceiver broadcastReceiver = sDeviceState.registerBroadcastReceiver(
359                 DevicePolicyManager.ACTION_DEVICE_POLICY_RESOURCE_UPDATED);
360 
361         sDpm.getResources().resetDrawables(Set.of(UPDATABLE_DRAWABLE_ID_1));
362 
363         assertThat(broadcastReceiver.awaitForBroadcast()).isNull();
364     }
365 
366     @Test
367     @Postsubmit(reason = "New test")
368     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
getDrawable_drawableIsSet_returnsUpdatedDrawable()369     public void getDrawable_drawableIsSet_returnsUpdatedDrawable() {
370         sDpm.getResources().setDrawables(createDrawable(
371                 UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1, R.drawable.test_drawable_1));
372 
373         Drawable drawable = sDpm.getResources().getDrawable(
374                 UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1, /* default= */ () -> null);
375 
376         assertThat(areSameDrawables(drawable, sContext.getDrawable(R.drawable.test_drawable_1)))
377                 .isTrue();
378     }
379 
380     @Test
381     @Postsubmit(reason = "New test")
382     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
getDrawable_drawableIsNotSet_returnsDefaultDrawable()383     public void getDrawable_drawableIsNotSet_returnsDefaultDrawable() {
384         Drawable defaultDrawable = sContext.getDrawable(R.drawable.test_drawable_1);
385         sDpm.getResources().resetDrawables(Set.of(UPDATABLE_DRAWABLE_ID_1));
386 
387         Drawable drawable = sDpm.getResources().getDrawable(
388                 UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1, /* default= */ () -> defaultDrawable);
389 
390         assertThat(drawable).isEqualTo(defaultDrawable);
391     }
392 
393     @Test
394     @Postsubmit(reason = "New test")
395     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
getDrawable_defaultLoaderIsNull_throwsException()396     public void getDrawable_defaultLoaderIsNull_throwsException() {
397         sDpm.getResources().resetDrawables(Set.of(UPDATABLE_DRAWABLE_ID_1));
398 
399         assertThrows(NullPointerException.class, () -> sDpm.getResources().getDrawable(
400                 UPDATABLE_DRAWABLE_ID_1,
401                 DRAWABLE_STYLE_1,
402                 /* default= */ (Supplier<Drawable>) null));
403     }
404 
405     @Test
406     @Postsubmit(reason = "New test")
407     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
getDrawable_defaultLoaderReturnsNull_returnsNull()408     public void getDrawable_defaultLoaderReturnsNull_returnsNull() {
409         sDpm.getResources().resetDrawables(Set.of(UPDATABLE_DRAWABLE_ID_1));
410 
411         assertThat(sDpm.getResources().getDrawable(
412                 UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1, /* default= */ () -> null)).isNull();
413     }
414 
415     @Test
416     @Postsubmit(reason = "New test")
417     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
getDrawableForDensity_drawableIsSet_returnsUpdatedDrawable()418     public void getDrawableForDensity_drawableIsSet_returnsUpdatedDrawable() {
419         sDpm.getResources().setDrawables(createDrawable(
420                 UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1, R.drawable.test_drawable_1));
421 
422         Drawable drawable = sDpm.getResources().getDrawableForDensity(
423                 UPDATABLE_DRAWABLE_ID_1,
424                 DRAWABLE_STYLE_1,
425                 /* density= */ 0,
426                 /* default= */ () -> null);
427 
428         assertThat(areSameDrawables(drawable, sContext.getDrawable(R.drawable.test_drawable_1)))
429                 .isTrue();
430     }
431 
432     @Test
433     @Postsubmit(reason = "New test")
434     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
getDrawableForDensity_drawableIsNotSet_returnsDefaultDrawable()435     public void getDrawableForDensity_drawableIsNotSet_returnsDefaultDrawable() {
436         Drawable defaultDrawable = sContext.getDrawable(R.drawable.test_drawable_1);
437         sDpm.getResources().resetDrawables(Set.of(UPDATABLE_DRAWABLE_ID_1));
438 
439         Drawable drawable = sDpm.getResources().getDrawableForDensity(
440                 UPDATABLE_DRAWABLE_ID_1,
441                 DRAWABLE_STYLE_1,
442                 /* density= */ 0,
443                 /* default= */ () -> defaultDrawable);
444 
445         assertThat(drawable).isEqualTo(defaultDrawable);
446     }
447 
448     @Test
449     @Postsubmit(reason = "New test")
450     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
getDrawable_drawableIsSet_returnsUpdatedIcon()451     public void getDrawable_drawableIsSet_returnsUpdatedIcon() {
452         sDpm.getResources().setDrawables(createDrawable(
453                 UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1, R.drawable.test_drawable_1));
454 
455         Icon icon = sDpm.getResources().getDrawableAsIcon(
456                 UPDATABLE_DRAWABLE_ID_1,
457                 DRAWABLE_STYLE_1,
458                 /* default= */ Icon.createWithResource(sContext, R.drawable.test_drawable_2));
459 
460         assertThat(icon.getResId()).isEqualTo(R.drawable.test_drawable_1);
461     }
462 
463     @Test
464     @Postsubmit(reason = "New test")
465     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
getDrawable_drawableIsNotSet_returnsDefaultIcon()466     public void getDrawable_drawableIsNotSet_returnsDefaultIcon() {
467         Icon defaultIcon = Icon.createWithResource(sContext, R.drawable.test_drawable_2);
468         sDpm.getResources().resetDrawables(Set.of(UPDATABLE_DRAWABLE_ID_1));
469 
470         Icon icon = sDpm.getResources().getDrawableAsIcon(
471                 UPDATABLE_DRAWABLE_ID_1,
472                 DRAWABLE_STYLE_1,
473                 defaultIcon);
474 
475         assertThat(icon).isEqualTo(defaultIcon);
476     }
477 
478     @Test
479     @Postsubmit(reason = "New test")
480     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
constructDevicePolicyDrawableResource_withNonExistentDrawable_throwsIllegalStateException()481     public void constructDevicePolicyDrawableResource_withNonExistentDrawable_throwsIllegalStateException() {
482         assertThrows(IllegalStateException.class, () -> new DevicePolicyDrawableResource(
483                 sContext, UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1, INVALID_RESOURCE_ID));
484     }
485 
486     @Test
487     @Postsubmit(reason = "New test")
488     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
constructDevicePolicyDrawableResource_withNonDrawableResource_throwsIllegalStateException()489     public void constructDevicePolicyDrawableResource_withNonDrawableResource_throwsIllegalStateException() {
490         assertThrows(IllegalStateException.class, () -> new DevicePolicyDrawableResource(
491                 sContext, UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1, R.string.test_string_1));
492     }
493 
494     @Test
495     @Postsubmit(reason = "New test")
496     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
getDrawableId_returnsCorrectValue()497     public void getDrawableId_returnsCorrectValue() {
498         DevicePolicyDrawableResource resource = new DevicePolicyDrawableResource(
499                 sContext, UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1, R.drawable.test_drawable_1);
500 
501         assertThat(resource.getDrawableId()).isEqualTo(UPDATABLE_DRAWABLE_ID_1);
502     }
503 
504     @Test
505     @Postsubmit(reason = "New test")
506     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
getDrawableStyle_returnsCorrectValue()507     public void getDrawableStyle_returnsCorrectValue() {
508         DevicePolicyDrawableResource resource = new DevicePolicyDrawableResource(
509                 sContext, UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1, R.drawable.test_drawable_1);
510 
511         assertThat(resource.getDrawableStyle()).isEqualTo(DRAWABLE_STYLE_1);
512     }
513 
514     @Test
515     @Postsubmit(reason = "New test")
516     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
getDrawableStyle_sourceNotSpecified_returnsUndefined()517     public void getDrawableStyle_sourceNotSpecified_returnsUndefined() {
518         DevicePolicyDrawableResource resource = new DevicePolicyDrawableResource(
519                 sContext, UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1, R.drawable.test_drawable_1);
520 
521         assertThat(resource.getDrawableSource()).isEqualTo(
522                 DevicePolicyResources.UNDEFINED);
523     }
524 
525     @Test
526     @Postsubmit(reason = "New test")
527     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
getDrawableStyle_sourceSpecified_returnsCorrectValue()528     public void getDrawableStyle_sourceSpecified_returnsCorrectValue() {
529         DevicePolicyDrawableResource resource = new DevicePolicyDrawableResource(
530                 sContext, UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1, DRAWABLE_SOURCE_1,
531                 R.drawable.test_drawable_1);
532 
533         assertThat(resource.getDrawableSource()).isEqualTo(DRAWABLE_SOURCE_1);
534     }
535 
536     @Test
537     @Postsubmit(reason = "New test")
538     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
devicePolicyDrawableResource_getResourceIdInCallingPackage_returnsCorrectValue()539     public void devicePolicyDrawableResource_getResourceIdInCallingPackage_returnsCorrectValue() {
540         DevicePolicyDrawableResource resource = new DevicePolicyDrawableResource(
541                 sContext, UPDATABLE_DRAWABLE_ID_1, DRAWABLE_STYLE_1, R.drawable.test_drawable_1);
542 
543         assertThat(resource.getResourceIdInCallingPackage()).isEqualTo(R.drawable.test_drawable_1);
544     }
545 
546     // TODO(b/16348282): extract to a common place to make it reusable.
areSameDrawables(Drawable drawable1, Drawable drawable2)547     private static boolean areSameDrawables(Drawable drawable1, Drawable drawable2) {
548         return drawable1 == drawable2 || getBitmap(drawable1).sameAs(getBitmap(drawable2));
549     }
550 
getBitmap(Drawable drawable)551     private static Bitmap getBitmap(Drawable drawable) {
552         int width = drawable.getIntrinsicWidth();
553         int height = drawable.getIntrinsicHeight();
554         // Some drawables have no intrinsic width - e.g. solid colours.
555         if (width <= 0) {
556             width = 1;
557         }
558         if (height <= 0) {
559             height = 1;
560         }
561         Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
562         Canvas canvas = new Canvas(result);
563         drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
564         drawable.draw(canvas);
565         return result;
566     }
567 
createDrawable( String updatableDrawableId, String style, int resourceId)568     private Set<DevicePolicyDrawableResource> createDrawable(
569             String updatableDrawableId, String style, int resourceId) {
570         return Set.of(new DevicePolicyDrawableResource(
571                 sContext, updatableDrawableId, style, resourceId));
572     }
573 
createDrawableForSource( String source, String updatableDrawableId, String style, int resourceId)574     private Set<DevicePolicyDrawableResource> createDrawableForSource(
575             String source, String updatableDrawableId, String style, int resourceId) {
576         return Set.of(new DevicePolicyDrawableResource(
577                 sContext, updatableDrawableId, style, source, resourceId));
578     }
579 
580     @Test
581     @Postsubmit(reason = "New test")
582     @EnsureDoesNotHavePermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
setStrings_withoutRequiredPermission_throwsSecurityException()583     public void setStrings_withoutRequiredPermission_throwsSecurityException() {
584         assertThrows(SecurityException.class, () -> sDpm.getResources().setStrings(
585                 createString(UPDATABLE_STRING_ID_1, R.string.test_string_1)));
586     }
587 
588     @Test
589     @Postsubmit(reason = "New test")
590     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
setStrings_withRequiredPermission_doesNotThrowSecurityException()591     public void setStrings_withRequiredPermission_doesNotThrowSecurityException() {
592         sDpm.getResources().setStrings(createString(UPDATABLE_STRING_ID_1, R.string.test_string_1));
593     }
594 
595     @Test
596     @Postsubmit(reason = "New test")
597     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
setStrings_updatesCorrectUpdatableString()598     public void setStrings_updatesCorrectUpdatableString() {
599         sDpm.getResources().setStrings(createString(UPDATABLE_STRING_ID_1, R.string.test_string_1));
600 
601         String string = sDpm.getResources().getString(
602                 UPDATABLE_STRING_ID_1, /* default= */ () -> null);
603         assertThat(string).isEqualTo(sContext.getString(R.string.test_string_1));
604     }
605 
606     @Test
607     @Postsubmit(reason = "New test")
608     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
setStrings_updatesCurrentlyUpdatedString()609     public void setStrings_updatesCurrentlyUpdatedString() {
610         sDpm.getResources().setStrings(createString(UPDATABLE_STRING_ID_1, R.string.test_string_1));
611 
612         sDpm.getResources().setStrings(createString(UPDATABLE_STRING_ID_1, R.string.test_string_2));
613 
614         String string = sDpm.getResources().getString(
615                 UPDATABLE_STRING_ID_1, /* default= */ () -> null);
616         assertThat(string).isEqualTo(sContext.getString(R.string.test_string_2));
617     }
618 
619     @Test
620     @Postsubmit(reason = "New test")
621     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
setStrings_doesNotUpdateOtherUpdatableStrings()622     public void setStrings_doesNotUpdateOtherUpdatableStrings() {
623         sDpm.getResources().resetStrings(Set.of(UPDATABLE_STRING_ID_2));
624         String defaultString = sContext.getString(R.string.test_string_2);
625 
626         sDpm.getResources().setStrings(createString(UPDATABLE_STRING_ID_1, R.string.test_string_1));
627 
628         assertThat(sDpm.getResources().getString(
629                 UPDATABLE_STRING_ID_2, /* default= */ () -> defaultString))
630                 .isEqualTo(defaultString);
631     }
632 
633     @Test
634     @Postsubmit(reason = "New test")
635     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
setStrings_stringChangedFromNull_sendsBroadcast()636     public void setStrings_stringChangedFromNull_sendsBroadcast() {
637         sDpm.getResources().resetStrings(Set.of(UPDATABLE_STRING_ID_1));
638         BlockingBroadcastReceiver broadcastReceiver = sDeviceState.registerBroadcastReceiver(
639                 DevicePolicyManager.ACTION_DEVICE_POLICY_RESOURCE_UPDATED);
640 
641         sDpm.getResources().setStrings(createString(UPDATABLE_STRING_ID_1, R.string.test_string_1));
642 
643         broadcastReceiver.awaitForBroadcastOrFail();
644     }
645 
646     @Test
647     @Postsubmit(reason = "New test")
648     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
setStrings_stringChangedFromOtherString_sendsBroadcast()649     public void setStrings_stringChangedFromOtherString_sendsBroadcast() {
650         sDpm.getResources().setStrings(createString(UPDATABLE_STRING_ID_1, R.string.test_string_1));
651         BlockingBroadcastReceiver broadcastReceiver = sDeviceState.registerBroadcastReceiver(
652                 DevicePolicyManager.ACTION_DEVICE_POLICY_RESOURCE_UPDATED);
653 
654         sDpm.getResources().setStrings(createString(UPDATABLE_STRING_ID_1, R.string.test_string_2));
655 
656         broadcastReceiver.awaitForBroadcastOrFail();
657     }
658 
659     @Test
660     @Postsubmit(reason = "New test")
661     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
662     @Ignore("b/208237942")
setStrings_stringNotChanged_doesNotSendBroadcast()663     public void setStrings_stringNotChanged_doesNotSendBroadcast() {
664         sDpm.getResources().setStrings(createString(UPDATABLE_STRING_ID_1, R.string.test_string_1));
665         BlockingBroadcastReceiver broadcastReceiver = sDeviceState.registerBroadcastReceiver(
666                 DevicePolicyManager.ACTION_DEVICE_POLICY_RESOURCE_UPDATED);
667 
668         sDpm.getResources().setStrings(createString(UPDATABLE_STRING_ID_1, R.string.test_string_1));
669 
670         assertThat(broadcastReceiver.awaitForBroadcast()).isNull();
671     }
672 
673     @Test
674     @Postsubmit(reason = "New test")
675     @EnsureDoesNotHavePermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
resetStrings_withoutRequiredPermission_throwsSecurityException()676     public void resetStrings_withoutRequiredPermission_throwsSecurityException() {
677         assertThrows(SecurityException.class,
678                 () -> sDpm.getResources().resetStrings(Set.of(UPDATABLE_STRING_ID_1)));
679     }
680 
681     @Test
682     @Postsubmit(reason = "New test")
683     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
resetStrings_withRequiredPermission_doesNotThrowSecurityException()684     public void resetStrings_withRequiredPermission_doesNotThrowSecurityException() {
685         sDpm.getResources().resetStrings(Set.of(UPDATABLE_STRING_ID_1));
686     }
687 
688     @Test
689     @Postsubmit(reason = "New test")
690     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
resetStrings_removesPreviouslySetStrings()691     public void resetStrings_removesPreviouslySetStrings() {
692         String defaultString = sContext.getString(R.string.test_string_2);
693         sDpm.getResources().setStrings(createString(UPDATABLE_STRING_ID_1, R.string.test_string_1));
694 
695         sDpm.getResources().resetStrings(Set.of(UPDATABLE_STRING_ID_1));
696 
697         assertThat(sDpm.getResources().getString(
698                 UPDATABLE_STRING_ID_1, /* default= */ () -> defaultString))
699                 .isEqualTo(defaultString);
700     }
701 
702     @Test
703     @Postsubmit(reason = "New test")
704     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
resetStrings_doesNotResetOtherSetStrings()705     public void resetStrings_doesNotResetOtherSetStrings() {
706         sDpm.getResources().setStrings(createString(UPDATABLE_STRING_ID_1, R.string.test_string_1));
707         sDpm.getResources().setStrings(createString(UPDATABLE_STRING_ID_2, R.string.test_string_2));
708 
709         sDpm.getResources().resetStrings(Set.of(UPDATABLE_STRING_ID_1));
710 
711         String string = sDpm.getResources().getString(
712                 UPDATABLE_STRING_ID_2, /* default= */ () -> null);
713         assertThat(string).isEqualTo(sContext.getString(R.string.test_string_2));
714     }
715 
716     @Test
717     @Postsubmit(reason = "New test")
718     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
resetStrings_stringChanged_sendsBroadcast()719     public void resetStrings_stringChanged_sendsBroadcast() {
720         sDpm.getResources().setStrings(createString(UPDATABLE_STRING_ID_1, R.string.test_string_1));
721         BlockingBroadcastReceiver broadcastReceiver = sDeviceState.registerBroadcastReceiver(
722                 DevicePolicyManager.ACTION_DEVICE_POLICY_RESOURCE_UPDATED);
723 
724         sDpm.getResources().resetStrings(Set.of(UPDATABLE_STRING_ID_1));
725 
726         broadcastReceiver.awaitForBroadcastOrFail();
727     }
728 
729     @Test
730     @Postsubmit(reason = "New test")
731     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
732     @Ignore("b/208237942")
resetStrings_stringNotChanged_doesNotSendBroadcast()733     public void resetStrings_stringNotChanged_doesNotSendBroadcast() {
734         sDpm.getResources().resetStrings(Set.of(UPDATABLE_STRING_ID_1));
735         BlockingBroadcastReceiver broadcastReceiver = sDeviceState.registerBroadcastReceiver(
736                 DevicePolicyManager.ACTION_DEVICE_POLICY_RESOURCE_UPDATED);
737 
738         sDpm.getResources().resetStrings(Set.of(UPDATABLE_STRING_ID_1));
739 
740         assertThat(broadcastReceiver.awaitForBroadcast()).isNull();
741     }
742 
743     @Test
744     @Postsubmit(reason = "New test")
745     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
getString_stringIsSet_returnsUpdatedString()746     public void getString_stringIsSet_returnsUpdatedString() {
747         sDpm.getResources().setStrings(createString(UPDATABLE_STRING_ID_1, R.string.test_string_1));
748 
749         String string = sDpm.getResources().getString(
750                 UPDATABLE_STRING_ID_1, /* default= */ () -> null);
751 
752         assertThat(string).isEqualTo(sContext.getString(R.string.test_string_1));
753     }
754 
755     @Test
756     @Postsubmit(reason = "New test")
757     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
getString_stringIsNotSet_returnsDefaultString()758     public void getString_stringIsNotSet_returnsDefaultString() {
759         sDpm.getResources().resetStrings(Set.of(UPDATABLE_STRING_ID_1));
760         String defaultString = sContext.getString(R.string.test_string_1);
761 
762         String string = sDpm.getResources().getString(
763                 UPDATABLE_STRING_ID_1, /* default= */ () -> defaultString);
764 
765         assertThat(string).isEqualTo(defaultString);
766     }
767 
768     @Test
769     @Postsubmit(reason = "New test")
770     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
getString_defaultLoaderIsNull_throwsException()771     public void getString_defaultLoaderIsNull_throwsException() {
772         sDpm.getResources().resetStrings(Set.of(UPDATABLE_STRING_ID_1));
773 
774         assertThrows(NullPointerException.class,
775                 () -> sDpm.getResources().getString(
776                         UPDATABLE_STRING_ID_1, /* default= */ null));
777     }
778 
779     @Test
780     @Postsubmit(reason = "New test")
781     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
getString_defaultLoaderReturnsNull_returnsNull()782     public void getString_defaultLoaderReturnsNull_returnsNull() {
783         sDpm.getResources().resetStrings(Set.of(UPDATABLE_STRING_ID_1));
784 
785         assertThat(sDpm.getResources().getString(UPDATABLE_STRING_ID_1, /* default= */ () -> null))
786                 .isNull();
787     }
788 
789     @Test
790     @Postsubmit(reason = "New test")
791     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
getString_stringWithArgs_returnsFormattedString()792     public void getString_stringWithArgs_returnsFormattedString() {
793         sDpm.getResources().setStrings(
794                 createString(UPDATABLE_STRING_ID_1, R.string.test_string_with_arg));
795         String testArg = "test arg";
796 
797         String string = sDpm.getResources().getString(
798                 UPDATABLE_STRING_ID_1, /* default= */ () -> null, testArg);
799 
800         assertThat(string).isEqualTo(sContext.getString(R.string.test_string_with_arg, testArg));
801     }
802 
803     @Test
804     @Postsubmit(reason = "New test")
805     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
constructDevicePolicyStringResource_withNonExistentString_throwsIllegalStateException()806     public void constructDevicePolicyStringResource_withNonExistentString_throwsIllegalStateException() {
807         assertThrows(IllegalStateException.class, () -> new DevicePolicyStringResource(
808                 sContext, UPDATABLE_STRING_ID_1, INVALID_RESOURCE_ID));
809     }
810 
811     @Test
812     @Postsubmit(reason = "New test")
813     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
constructDevicePolicyStringResource_withNonStringResource_throwsIllegalStateException()814     public void constructDevicePolicyStringResource_withNonStringResource_throwsIllegalStateException() {
815         assertThrows(IllegalStateException.class, () -> new DevicePolicyStringResource(
816                 sContext, UPDATABLE_STRING_ID_1, R.drawable.test_drawable_2));
817     }
818 
819     @Test
820     @Postsubmit(reason = "New test")
821     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
getStringId_returnsCorrectValue()822     public void getStringId_returnsCorrectValue() {
823         DevicePolicyStringResource resource = new  DevicePolicyStringResource(
824                 sContext, UPDATABLE_STRING_ID_1, R.string.test_string_1);
825 
826         assertThat(resource.getStringId()).isEqualTo(UPDATABLE_STRING_ID_1);
827     }
828 
829     @Test
830     @Postsubmit(reason = "New test")
831     @EnsureHasPermission(UPDATE_DEVICE_MANAGEMENT_RESOURCES)
devicePolicyStringResource_getResourceIdInCallingPackage_returnsCorrectValue()832     public void devicePolicyStringResource_getResourceIdInCallingPackage_returnsCorrectValue() {
833         DevicePolicyStringResource resource = new  DevicePolicyStringResource(
834                 sContext, UPDATABLE_STRING_ID_1, R.string.test_string_1);
835 
836         assertThat(resource.getResourceIdInCallingPackage()).isEqualTo(R.string.test_string_1);
837     }
838 
createString( String updatableStringId, int resourceId)839     private Set<DevicePolicyStringResource> createString(
840             String updatableStringId, int resourceId) {
841         return Set.of(new DevicePolicyStringResource(
842                 sContext, updatableStringId, resourceId));
843     }
844 }
845