1 /*
2  * Copyright (C) 2021 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.bedstead.remotedpc;
18 
19 import static android.os.Build.VERSION_CODES.Q;
20 import static android.os.UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES;
21 
22 import static com.google.common.truth.Truth.assertThat;
23 
24 import static org.testng.Assert.assertThrows;
25 
26 import android.content.ComponentName;
27 import android.os.UserHandle;
28 
29 import com.android.bedstead.harrier.BedsteadJUnit4;
30 import com.android.bedstead.harrier.DeviceState;
31 import com.android.bedstead.harrier.annotations.AfterClass;
32 import com.android.bedstead.harrier.annotations.BeforeClass;
33 import com.android.bedstead.harrier.annotations.EnsureHasNoSecondaryUser;
34 import com.android.bedstead.harrier.annotations.EnsureHasNoWorkProfile;
35 import com.android.bedstead.harrier.annotations.RequireRunOnSystemUser;
36 import com.android.bedstead.harrier.annotations.RequireSdkVersion;
37 import com.android.bedstead.harrier.annotations.enterprise.EnsureHasDeviceOwner;
38 import com.android.bedstead.harrier.annotations.enterprise.EnsureHasNoDeviceOwner;
39 import com.android.bedstead.harrier.annotations.enterprise.EnsureHasNoProfileOwner;
40 import com.android.bedstead.harrier.annotations.enterprise.EnsureHasProfileOwner;
41 import com.android.bedstead.nene.TestApis;
42 import com.android.bedstead.nene.devicepolicy.DeviceOwner;
43 import com.android.bedstead.nene.devicepolicy.ProfileOwner;
44 import com.android.bedstead.nene.exceptions.NeneException;
45 import com.android.bedstead.nene.users.UserReference;
46 import com.android.bedstead.nene.users.UserType;
47 import com.android.bedstead.testapp.TestApp;
48 import com.android.bedstead.testapp.TestAppProvider;
49 
50 import org.junit.ClassRule;
51 import org.junit.Rule;
52 import org.junit.Test;
53 import org.junit.runner.RunWith;
54 
55 @RunWith(BedsteadJUnit4.class)
56 public class RemoteDpcTest {
57     //  TODO(180478924): We shouldn't need to hardcode this
58     private static final String DEVICE_ADMIN_TESTAPP_PACKAGE_NAME =
59             "com.android.bedstead.testapp.DeviceAdminTestApp";
60     private static final ComponentName NON_REMOTE_DPC_COMPONENT =
61             new ComponentName(DEVICE_ADMIN_TESTAPP_PACKAGE_NAME,
62                     "com.android.bedstead.testapp.DeviceAdminTestApp.DeviceAdminReceiver");
63 
64     @ClassRule @Rule
65     public static DeviceState sDeviceState = new DeviceState();
66 
67     private static TestApp sNonRemoteDpcTestApp;
68     private static final UserReference sUser = TestApis.users().instrumented();
69     private static final UserReference NON_EXISTING_USER_REFERENCE =
70             TestApis.users().find(99999);
71     private static final UserHandle NON_EXISTING_USER_HANDLE =
72             NON_EXISTING_USER_REFERENCE.userHandle();
73 
74     @BeforeClass
setupClass()75     public static void setupClass() {
76         sNonRemoteDpcTestApp = new TestAppProvider().query()
77                 // TODO(180478924): Query by feature not package name
78                 .wherePackageName().isEqualTo(DEVICE_ADMIN_TESTAPP_PACKAGE_NAME)
79                 .get();
80 
81         sNonRemoteDpcTestApp.install();
82         sNonRemoteDpcTestApp.install(TestApis.users().system());
83     }
84 
85     @AfterClass
teardownClass()86     public static void teardownClass() {
87         sNonRemoteDpcTestApp.uninstallFromAllUsers();
88     }
89 
90     @Test
91     @EnsureHasNoDeviceOwner
deviceOwner_noDeviceOwner_returnsNull()92     public void deviceOwner_noDeviceOwner_returnsNull() {
93         assertThat(RemoteDpc.deviceOwner()).isNull();
94     }
95 
96     @Test
97     @RequireRunOnSystemUser
98     @EnsureHasNoDeviceOwner
99     @EnsureHasNoProfileOwner
100     @EnsureHasNoSecondaryUser // TODO(b/202832720): Replace with @EnsureHasOnlyInstrumentedUser
101     @EnsureHasNoWorkProfile // TODO(b/202832720): Replace with @EnsureHasOnlyInstrumentedUser
deviceOwner_nonRemoteDpcDeviceOwner_returnsNull()102     public void deviceOwner_nonRemoteDpcDeviceOwner_returnsNull() {
103         DeviceOwner deviceOwner =
104                 TestApis.devicePolicy().setDeviceOwner(NON_REMOTE_DPC_COMPONENT);
105         try {
106             assertThat(RemoteDpc.deviceOwner()).isNull();
107         } finally {
108             deviceOwner.remove();
109         }
110     }
111 
112     @Test
113     @EnsureHasDeviceOwner
deviceOwner_remoteDpcDeviceOwner_returnsInstance()114     public void deviceOwner_remoteDpcDeviceOwner_returnsInstance() {
115         assertThat(RemoteDpc.deviceOwner()).isNotNull();
116     }
117 
118     @Test
119     @EnsureHasNoProfileOwner
profileOwner_noProfileOwner_returnsNull()120     public void profileOwner_noProfileOwner_returnsNull() {
121         assertThat(RemoteDpc.profileOwner()).isNull();
122     }
123 
124     @Test
125     @EnsureHasNoDeviceOwner
126     @EnsureHasNoProfileOwner
profileOwner_nonRemoteDpcProfileOwner_returnsNull()127     public void profileOwner_nonRemoteDpcProfileOwner_returnsNull() {
128         ProfileOwner profileOwner =
129                 TestApis.devicePolicy().setProfileOwner(sUser, NON_REMOTE_DPC_COMPONENT);
130         try {
131             assertThat(RemoteDpc.profileOwner()).isNull();
132         } finally {
133             profileOwner.remove();
134         }
135     }
136 
137     @Test
138     @EnsureHasProfileOwner
profileOwner_remoteDpcProfileOwner_returnsInstance()139     public void profileOwner_remoteDpcProfileOwner_returnsInstance() {
140         assertThat(RemoteDpc.profileOwner()).isNotNull();
141     }
142 
143     @Test
profileOwner_userHandle_null_throwsException()144     public void profileOwner_userHandle_null_throwsException() {
145         assertThrows(NullPointerException.class, () -> RemoteDpc.profileOwner((UserHandle) null));
146     }
147 
148     @Test
149     @EnsureHasNoDeviceOwner
150     @EnsureHasNoWorkProfile
151     @RequireRunOnSystemUser
profileOwner_userHandle_noProfileOwner_returnsNull()152     public void profileOwner_userHandle_noProfileOwner_returnsNull() {
153         UserReference profile = TestApis.users().createUser()
154                 .parent(sUser)
155                 .type(TestApis.users().supportedType(UserType.MANAGED_PROFILE_TYPE_NAME))
156                 .createAndStart();
157         try {
158             assertThat(RemoteDpc.profileOwner(profile.userHandle())).isNull();
159         } finally {
160             profile.remove();
161         }
162     }
163 
164     @Test
165     @EnsureHasNoDeviceOwner
166     @EnsureHasNoWorkProfile
167     @RequireRunOnSystemUser
168     @RequireSdkVersion(min = Q, reason = "Cannot use RemoteDPC cross-user prior to Q")
profileOwner_userHandle_nonRemoteDpcProfileOwner_returnsNull()169     public void profileOwner_userHandle_nonRemoteDpcProfileOwner_returnsNull() {
170         UserReference profile = TestApis.users().createUser()
171                 .parent(sUser)
172                 .type(TestApis.users().supportedType(UserType.MANAGED_PROFILE_TYPE_NAME))
173                 .createAndStart();
174         sNonRemoteDpcTestApp.install(profile);
175         try {
176             TestApis.devicePolicy().setProfileOwner(profile, NON_REMOTE_DPC_COMPONENT);
177 
178             assertThat(RemoteDpc.profileOwner(profile.userHandle())).isNull();
179         } finally {
180             profile.remove();
181         }
182     }
183 
184     @Test
185     @EnsureHasNoDeviceOwner
186     @EnsureHasNoWorkProfile
187     @RequireRunOnSystemUser
188     @RequireSdkVersion(min = Q, reason = "Cannot use RemoteDPC cross-user prior to Q")
profileOwner_userHandle_remoteDpcProfileOwner_returnsInstance()189     public void profileOwner_userHandle_remoteDpcProfileOwner_returnsInstance() {
190         UserReference profile = TestApis.users().createUser()
191                 .parent(sUser)
192                 .type(TestApis.users().supportedType(UserType.MANAGED_PROFILE_TYPE_NAME))
193                 .createAndStart();
194         RemoteDpc.setAsProfileOwner(profile);
195         try {
196             assertThat(RemoteDpc.profileOwner(profile.userHandle())).isNotNull();
197         } finally {
198             profile.remove();
199         }
200     }
201 
202     @Test
profileOwner_userReference_null_throwsException()203     public void profileOwner_userReference_null_throwsException() {
204         assertThrows(NullPointerException.class,
205                 () -> RemoteDpc.profileOwner((UserReference) null));
206     }
207 
208     @Test
209     @EnsureHasNoDeviceOwner
210     @EnsureHasNoWorkProfile
211     @RequireRunOnSystemUser
profileOwner_userReference_noProfileOwner_returnsNull()212     public void profileOwner_userReference_noProfileOwner_returnsNull() {
213         UserReference profile = TestApis.users().createUser()
214                 .parent(sUser)
215                 .type(TestApis.users().supportedType(UserType.MANAGED_PROFILE_TYPE_NAME))
216                 .createAndStart();
217         try {
218             assertThat(RemoteDpc.profileOwner(profile)).isNull();
219         } finally {
220             profile.remove();
221         }
222     }
223 
224     @Test
225     @EnsureHasNoDeviceOwner
226     @RequireRunOnSystemUser
227     @EnsureHasNoWorkProfile
profileOwner_userReference_nonRemoteDpcProfileOwner_returnsNull()228     public void profileOwner_userReference_nonRemoteDpcProfileOwner_returnsNull() {
229         UserReference profile = TestApis.users().createUser()
230                 .parent(sUser)
231                 .type(TestApis.users().supportedType(UserType.MANAGED_PROFILE_TYPE_NAME))
232                 .createAndStart();
233         sNonRemoteDpcTestApp.install(profile);
234         try {
235             TestApis.devicePolicy().setProfileOwner(profile, NON_REMOTE_DPC_COMPONENT);
236 
237             assertThat(RemoteDpc.profileOwner(profile)).isNull();
238         } finally {
239             profile.remove();
240         }
241     }
242 
243     @Test
244     @EnsureHasNoDeviceOwner
245     @EnsureHasNoWorkProfile
246     @RequireRunOnSystemUser
247     @RequireSdkVersion(min = Q, reason = "Cannot use RemoteDPC cross-user prior to Q")
profileOwner_userReference_remoteDpcProfileOwner_returnsInstance()248     public void profileOwner_userReference_remoteDpcProfileOwner_returnsInstance() {
249         UserReference profile = TestApis.users().createUser()
250                 .parent(sUser)
251                 .type(TestApis.users().supportedType(UserType.MANAGED_PROFILE_TYPE_NAME))
252                 .createAndStart();
253         RemoteDpc.setAsProfileOwner(profile);
254         try {
255             assertThat(RemoteDpc.profileOwner(profile)).isNotNull();
256         } finally {
257             profile.remove();
258         }
259     }
260 
261     @Test
262     @EnsureHasNoDeviceOwner
263     @EnsureHasNoProfileOwner
any_noDeviceOwner_noProfileOwner_returnsNull()264     public void any_noDeviceOwner_noProfileOwner_returnsNull() {
265         assertThat(RemoteDpc.any()).isNull();
266     }
267 
268     @Test
269     @EnsureHasNoDeviceOwner
270     @EnsureHasNoProfileOwner
any_noDeviceOwner_nonRemoteDpcProfileOwner_returnsNull()271     public void any_noDeviceOwner_nonRemoteDpcProfileOwner_returnsNull() {
272         ProfileOwner profileOwner = TestApis.devicePolicy().setProfileOwner(sUser,
273                 NON_REMOTE_DPC_COMPONENT);
274 
275         try {
276             assertThat(RemoteDpc.any()).isNull();
277         } finally {
278             profileOwner.remove();
279         }
280     }
281 
282     @Test
283     @EnsureHasNoDeviceOwner
284     @EnsureHasNoProfileOwner
285     @RequireRunOnSystemUser
286     @EnsureHasNoSecondaryUser // TODO(b/202832720): Replace with @EnsureHasOnlyInstrumentedUser
287     @EnsureHasNoWorkProfile // TODO(b/202832720): Replace with @EnsureHasOnlyInstrumentedUser
any_nonRemoteDpcDeviceOwner_noProfileOwner_returnsNull()288     public void any_nonRemoteDpcDeviceOwner_noProfileOwner_returnsNull() {
289         DeviceOwner deviceOwner = TestApis.devicePolicy().setDeviceOwner(
290                 NON_REMOTE_DPC_COMPONENT);
291 
292         try {
293             assertThat(RemoteDpc.any()).isNull();
294         } finally {
295             deviceOwner.remove();
296         }
297     }
298 
299     @Test
300     @EnsureHasDeviceOwner
any_remoteDpcDeviceOwner_returnsDeviceOwner()301     public void any_remoteDpcDeviceOwner_returnsDeviceOwner() {
302         assertThat(RemoteDpc.any()).isNotNull();
303     }
304 
305     @Test
306     @EnsureHasProfileOwner
any_remoteDpcProfileOwner_returnsProfileOwner()307     public void any_remoteDpcProfileOwner_returnsProfileOwner() {
308         assertThat(RemoteDpc.any()).isNotNull();
309     }
310 
311     @Test
any_userHandle_null_throwsException()312     public void any_userHandle_null_throwsException() {
313         assertThrows(NullPointerException.class, () -> RemoteDpc.any((UserHandle) null));
314     }
315 
316     @Test
317     @EnsureHasNoDeviceOwner
318     @EnsureHasNoProfileOwner
any_userHandle_noDeviceOwner_noProfileOwner_returnsNull()319     public void any_userHandle_noDeviceOwner_noProfileOwner_returnsNull() {
320         assertThat(RemoteDpc.any(sUser.userHandle())).isNull();
321     }
322 
323     @Test
324     @EnsureHasNoDeviceOwner
325     @EnsureHasNoWorkProfile
326     @RequireRunOnSystemUser
any_userHandle_noDeviceOwner_nonRemoteDpcProfileOwner_returnsNull()327     public void any_userHandle_noDeviceOwner_nonRemoteDpcProfileOwner_returnsNull() {
328         UserReference profile = TestApis.users().createUser()
329                 .parent(sUser)
330                 .type(TestApis.users().supportedType(UserType.MANAGED_PROFILE_TYPE_NAME))
331                 .createAndStart();
332         sNonRemoteDpcTestApp.install(profile);
333         try {
334             TestApis.devicePolicy().setProfileOwner(profile, NON_REMOTE_DPC_COMPONENT);
335 
336             assertThat(RemoteDpc.any(profile.userHandle())).isNull();
337         } finally {
338             profile.remove();
339         }
340     }
341 
342     @Test
343     @EnsureHasNoDeviceOwner
344     @EnsureHasNoProfileOwner
345     @RequireRunOnSystemUser
346     @EnsureHasNoSecondaryUser // TODO(b/202832720): Replace with @EnsureHasOnlyInstrumentedUser
347     @EnsureHasNoWorkProfile // TODO(b/202832720): Replace with @EnsureHasOnlyInstrumentedUser
any_userHandle_nonRemoteDpcDeviceOwner_noProfileOwner_returnsNull()348     public void any_userHandle_nonRemoteDpcDeviceOwner_noProfileOwner_returnsNull() {
349         DeviceOwner deviceOwner = TestApis.devicePolicy().setDeviceOwner(
350                 NON_REMOTE_DPC_COMPONENT);
351 
352         try {
353             assertThat(RemoteDpc.any(sUser.userHandle())).isNull();
354         } finally {
355             deviceOwner.remove();
356         }
357     }
358 
359     @Test
360     @EnsureHasDeviceOwner
361     @EnsureHasNoProfileOwner
any_userHandle_remoteDpcDeviceOwner_returnsDeviceOwner()362     public void any_userHandle_remoteDpcDeviceOwner_returnsDeviceOwner() {
363         RemoteDpc deviceOwner = RemoteDpc.deviceOwner();
364 
365         assertThat(RemoteDpc.any(sUser.userHandle())).isEqualTo(deviceOwner);
366     }
367 
368     @Test
369     @EnsureHasNoDeviceOwner
370     @EnsureHasNoWorkProfile
371     @RequireRunOnSystemUser
372     @RequireSdkVersion(min = Q, reason = "Cannot use RemoteDPC cross-user prior to Q")
any_userHandle_remoteDpcProfileOwner_returnsProfileOwner()373     public void any_userHandle_remoteDpcProfileOwner_returnsProfileOwner() {
374         UserReference profile = TestApis.users().createUser()
375                 .parent(sUser)
376                 .type(TestApis.users().supportedType(UserType.MANAGED_PROFILE_TYPE_NAME))
377                 .createAndStart();
378         try {
379             RemoteDpc profileOwner = RemoteDpc.setAsProfileOwner(profile);
380 
381             assertThat(RemoteDpc.any(profile.userHandle())).isEqualTo(profileOwner);
382         } finally {
383             profile.remove();
384         }
385     }
386 
387     @Test
any_userReference_null_throwsException()388     public void any_userReference_null_throwsException() {
389         assertThrows(NullPointerException.class, () -> RemoteDpc.any((UserReference) null));
390     }
391 
392     @Test
any_userReference_noDeviceOwner_noProfileOwner_returnsNull()393     public void any_userReference_noDeviceOwner_noProfileOwner_returnsNull() {
394         assertThat(RemoteDpc.any(sUser)).isNull();
395     }
396 
397     @Test
398     @EnsureHasNoDeviceOwner
399     @EnsureHasNoWorkProfile
400     @RequireRunOnSystemUser
any_userReference_noDeviceOwner_nonRemoteDpcProfileOwner_returnsNull()401     public void any_userReference_noDeviceOwner_nonRemoteDpcProfileOwner_returnsNull() {
402         UserReference profile = TestApis.users().createUser()
403                 .parent(sUser)
404                 .type(TestApis.users().supportedType(UserType.MANAGED_PROFILE_TYPE_NAME))
405                 .createAndStart();
406         sNonRemoteDpcTestApp.install(profile);
407         try {
408             TestApis.devicePolicy().setProfileOwner(profile, NON_REMOTE_DPC_COMPONENT);
409 
410             assertThat(RemoteDpc.any(profile)).isNull();
411         } finally {
412             profile.remove();
413         }
414     }
415 
416     @Test
417     @EnsureHasNoDeviceOwner
418     @EnsureHasNoProfileOwner
419     @RequireRunOnSystemUser
420     @EnsureHasNoSecondaryUser // TODO(b/202832720): Replace with @EnsureHasOnlyInstrumentedUser
421     @EnsureHasNoWorkProfile // TODO(b/202832720): Replace with @EnsureHasOnlyInstrumentedUser
any_userReference_nonRemoteDpcDeviceOwner_noProfileOwner_returnsNull()422     public void any_userReference_nonRemoteDpcDeviceOwner_noProfileOwner_returnsNull() {
423         DeviceOwner deviceOwner = TestApis.devicePolicy().setDeviceOwner(
424                 NON_REMOTE_DPC_COMPONENT);
425 
426         try {
427             assertThat(RemoteDpc.any(sUser)).isNull();
428         } finally {
429             deviceOwner.remove();
430         }
431     }
432 
433     @Test
434     @EnsureHasDeviceOwner
435     @EnsureHasNoProfileOwner
any_userReference_remoteDpcDeviceOwner_returnsDeviceOwner()436     public void any_userReference_remoteDpcDeviceOwner_returnsDeviceOwner() {
437         RemoteDpc deviceOwner = RemoteDpc.deviceOwner();
438 
439         assertThat(RemoteDpc.any(sUser)).isEqualTo(deviceOwner);
440     }
441 
442     @Test
443     @EnsureHasNoDeviceOwner
444     @EnsureHasNoWorkProfile
445     @RequireRunOnSystemUser
446     @RequireSdkVersion(min = Q, reason = "Cannot use RemoteDPC cross-user prior to Q")
any_userReference_remoteDpcProfileOwner_returnsProfileOwner()447     public void any_userReference_remoteDpcProfileOwner_returnsProfileOwner() {
448         UserReference profile = TestApis.users().createUser()
449                 .parent(sUser)
450                 .type(TestApis.users().supportedType(UserType.MANAGED_PROFILE_TYPE_NAME))
451                 .createAndStart();
452         try {
453             RemoteDpc profileOwner = RemoteDpc.setAsProfileOwner(profile);
454 
455             assertThat(RemoteDpc.any(profile)).isEqualTo(profileOwner);
456         } finally {
457             profile.remove();
458         }
459     }
460 
461     @Test
462     @EnsureHasDeviceOwner
setAsDeviceOwner_alreadySet_doesNothing()463     public void setAsDeviceOwner_alreadySet_doesNothing() {
464         RemoteDpc.setAsDeviceOwner();
465 
466         DeviceOwner deviceOwner = TestApis.devicePolicy().getDeviceOwner();
467         assertThat(deviceOwner).isNotNull();
468     }
469 
470     @Test
471     @EnsureHasNoDeviceOwner
472     @EnsureHasNoProfileOwner
473     @RequireRunOnSystemUser
474     @EnsureHasNoSecondaryUser // TODO(b/202832720): Replace with @EnsureHasOnlyInstrumentedUser
475     @EnsureHasNoWorkProfile // TODO(b/202832720): Replace with @EnsureHasOnlyInstrumentedUser
setAsDeviceOwner_alreadyHasDeviceOwner_replacesDeviceOwner()476     public void setAsDeviceOwner_alreadyHasDeviceOwner_replacesDeviceOwner() {
477         TestApis.devicePolicy().setDeviceOwner(NON_REMOTE_DPC_COMPONENT);
478 
479         try {
480             RemoteDpc remoteDPC = RemoteDpc.setAsDeviceOwner();
481 
482             DeviceOwner deviceOwner = TestApis.devicePolicy().getDeviceOwner();
483             assertThat(deviceOwner).isEqualTo(remoteDPC.devicePolicyController());
484         } finally {
485             TestApis.devicePolicy().getDeviceOwner().remove();
486         }
487     }
488 
489     @Test
490     @EnsureHasNoDeviceOwner
491     @EnsureHasNoProfileOwner
setAsDeviceOwner_doesNotHaveDeviceOwner_setsDeviceOwner()492     public void setAsDeviceOwner_doesNotHaveDeviceOwner_setsDeviceOwner() {
493         RemoteDpc.setAsDeviceOwner();
494 
495         DeviceOwner deviceOwner = TestApis.devicePolicy().getDeviceOwner();
496         try {
497             assertThat(deviceOwner).isNotNull();
498         } finally {
499             if (deviceOwner != null) {
500                 deviceOwner.remove();
501             }
502         }
503     }
504 
505     @Test
setAsProfileOwner_userHandle_null_throwsException()506     public void setAsProfileOwner_userHandle_null_throwsException() {
507         assertThrows(NullPointerException.class,
508                 () -> RemoteDpc.setAsProfileOwner((UserHandle) null));
509     }
510 
511     @Test
setAsProfileOwner_userHandle_nonExistingUser_throwsException()512     public void setAsProfileOwner_userHandle_nonExistingUser_throwsException() {
513         assertThrows(NeneException.class,
514                 () -> RemoteDpc.setAsProfileOwner(NON_EXISTING_USER_HANDLE));
515     }
516 
517     @Test
518     @EnsureHasNoDeviceOwner
519     @EnsureHasNoWorkProfile
520     @RequireRunOnSystemUser
521     @RequireSdkVersion(min = Q, reason = "Cannot use RemoteDPC cross-user prior to Q")
setAsProfileOwner_userHandle_alreadySet_doesNothing()522     public void setAsProfileOwner_userHandle_alreadySet_doesNothing() {
523         UserReference profile = TestApis.users().createUser()
524                 .parent(sUser)
525                 .type(TestApis.users().supportedType(UserType.MANAGED_PROFILE_TYPE_NAME))
526                 .createAndStart();
527         try {
528             RemoteDpc.setAsProfileOwner(profile.userHandle());
529 
530             RemoteDpc.setAsProfileOwner(profile.userHandle());
531 
532             assertThat(TestApis.devicePolicy().getProfileOwner(profile)).isNotNull();
533         } finally {
534             profile.remove();
535         }
536     }
537 
538     @Test
539     @EnsureHasNoDeviceOwner
540     @EnsureHasNoWorkProfile
541     @RequireRunOnSystemUser
542     @RequireSdkVersion(min = Q, reason = "Cannot use RemoteDPC cross-user prior to Q")
setAsProfileOwner_userHandle_alreadyHasProfileOwner_replacesProfileOwner()543     public void setAsProfileOwner_userHandle_alreadyHasProfileOwner_replacesProfileOwner() {
544         UserReference profile = TestApis.users().createUser()
545                 .parent(sUser)
546                 .type(TestApis.users().supportedType(UserType.MANAGED_PROFILE_TYPE_NAME))
547                 .createAndStart();
548         sNonRemoteDpcTestApp.install(profile);
549         try {
550             TestApis.devicePolicy().setProfileOwner(profile, NON_REMOTE_DPC_COMPONENT);
551 
552             RemoteDpc remoteDPC = RemoteDpc.setAsProfileOwner(profile.userHandle());
553 
554             assertThat(TestApis.devicePolicy().getProfileOwner(profile))
555                     .isEqualTo(remoteDPC.devicePolicyController());
556         } finally {
557             profile.remove();
558         }
559     }
560 
561     @Test
562     @EnsureHasNoDeviceOwner
563     @EnsureHasNoWorkProfile
564     @RequireRunOnSystemUser
565     @RequireSdkVersion(min = Q, reason = "Cannot use RemoteDPC cross-user prior to Q")
setAsProfileOwner_userHandle_doesNotHaveProfileOwner_setsProfileOwner()566     public void setAsProfileOwner_userHandle_doesNotHaveProfileOwner_setsProfileOwner() {
567         UserReference profile = TestApis.users().createUser()
568                 .parent(sUser)
569                 .type(TestApis.users().supportedType(UserType.MANAGED_PROFILE_TYPE_NAME))
570                 .createAndStart();
571         try {
572             RemoteDpc.setAsProfileOwner(profile.userHandle());
573 
574             assertThat(TestApis.devicePolicy().getProfileOwner(profile)).isNotNull();
575         } finally {
576             profile.remove();
577         }
578     }
579 
580     @Test
581     @EnsureHasNoDeviceOwner
582     @EnsureHasNoWorkProfile
583     @RequireRunOnSystemUser
584     @RequireSdkVersion(min = Q, reason = "Cannot use RemoteDPC cross-user prior to Q")
setAsProfileOwner_disallowInstallUnknownSourcesIsDisabled()585     public void setAsProfileOwner_disallowInstallUnknownSourcesIsDisabled() {
586         // This is a temp fix for an issue where DISALLOW_INSTALL_UNKNOWN_SOURCES causes
587         // verification failures
588         UserReference profile = TestApis.users().createUser()
589                 .parent(sUser)
590                 .type(TestApis.users().supportedType(UserType.MANAGED_PROFILE_TYPE_NAME))
591                 .createAndStart();
592         try {
593             RemoteDpc profileOwner = RemoteDpc.setAsProfileOwner(profile.userHandle());
594 
595             assertThat(profileOwner.userManager()
596                     .hasUserRestriction(DISALLOW_INSTALL_UNKNOWN_SOURCES))
597                     .isFalse();
598         } finally {
599             profile.remove();
600         }
601     }
602 
603     @Test
setAsProfileOwner_userReference_null_throwsException()604     public void setAsProfileOwner_userReference_null_throwsException() {
605         assertThrows(NullPointerException.class,
606                 () -> RemoteDpc.setAsProfileOwner((UserReference) null));
607     }
608 
609     @Test
setAsProfileOwner_userReference_nonExistingUser_throwsException()610     public void setAsProfileOwner_userReference_nonExistingUser_throwsException() {
611         assertThrows(NeneException.class,
612                 () -> RemoteDpc.setAsProfileOwner(NON_EXISTING_USER_REFERENCE));
613     }
614 
615     @Test
616     @EnsureHasNoDeviceOwner
617     @EnsureHasNoWorkProfile
618     @RequireRunOnSystemUser
619     @RequireSdkVersion(min = Q, reason = "Cannot use RemoteDPC cross-user prior to Q")
setAsProfileOwner_userReference_alreadySet_doesNothing()620     public void setAsProfileOwner_userReference_alreadySet_doesNothing() {
621         UserReference profile = TestApis.users().createUser()
622                 .parent(sUser)
623                 .type(TestApis.users().supportedType(UserType.MANAGED_PROFILE_TYPE_NAME))
624                 .createAndStart();
625         try {
626             RemoteDpc.setAsProfileOwner(profile);
627 
628             RemoteDpc.setAsProfileOwner(profile);
629 
630             assertThat(TestApis.devicePolicy().getProfileOwner(profile)).isNotNull();
631         } finally {
632             profile.remove();
633         }
634     }
635 
636     @Test
637     @EnsureHasNoDeviceOwner
638     @EnsureHasNoWorkProfile
639     @RequireRunOnSystemUser
640     @RequireSdkVersion(min = Q, reason = "Cannot use RemoteDPC cross-user prior to Q")
setAsProfileOwner_userReference_alreadyHasProfileOwner_replacesProfileOwner()641     public void setAsProfileOwner_userReference_alreadyHasProfileOwner_replacesProfileOwner() {
642         UserReference profile = TestApis.users().createUser()
643                 .parent(sUser)
644                 .type(TestApis.users().supportedType(UserType.MANAGED_PROFILE_TYPE_NAME))
645                 .createAndStart();
646         sNonRemoteDpcTestApp.install(profile);
647         try {
648             TestApis.devicePolicy().setProfileOwner(profile, NON_REMOTE_DPC_COMPONENT);
649 
650             RemoteDpc remoteDPC = RemoteDpc.setAsProfileOwner(profile);
651 
652             assertThat(TestApis.devicePolicy().getProfileOwner(profile))
653                     .isEqualTo(remoteDPC.devicePolicyController());
654         } finally {
655             profile.remove();
656         }
657     }
658 
659     @Test
660     @EnsureHasNoDeviceOwner
661     @EnsureHasNoWorkProfile
662     @RequireRunOnSystemUser
663     @RequireSdkVersion(min = Q, reason = "Cannot use RemoteDPC cross-user prior to Q")
setAsProfileOwner_userReference_doesNotHaveProfileOwner_setsProfileOwner()664     public void setAsProfileOwner_userReference_doesNotHaveProfileOwner_setsProfileOwner() {
665         UserReference profile = TestApis.users().createUser()
666                 .parent(sUser)
667                 .type(TestApis.users().supportedType(UserType.MANAGED_PROFILE_TYPE_NAME))
668                 .createAndStart();
669         try {
670             RemoteDpc.setAsProfileOwner(profile);
671 
672             assertThat(TestApis.devicePolicy().getProfileOwner(profile)).isNotNull();
673         } finally {
674             profile.remove();
675         }
676     }
677 
678     @Test
679     @EnsureHasDeviceOwner
devicePolicyController_returnsDevicePolicyController()680     public void devicePolicyController_returnsDevicePolicyController() {
681         RemoteDpc remoteDPC = RemoteDpc.deviceOwner();
682 
683         try {
684             assertThat(remoteDPC.devicePolicyController())
685                     .isEqualTo(TestApis.devicePolicy().getDeviceOwner());
686         } finally {
687             remoteDPC.remove();
688         }
689     }
690 
691     @Test
692     @EnsureHasDeviceOwner
remove_deviceOwner_removes()693     public void remove_deviceOwner_removes() {
694         RemoteDpc remoteDPC = RemoteDpc.deviceOwner();
695 
696         remoteDPC.remove();
697 
698         assertThat(TestApis.devicePolicy().getDeviceOwner()).isNull();
699     }
700 
701     @Test
702     @EnsureHasNoDeviceOwner
703     @EnsureHasNoWorkProfile
704     @RequireRunOnSystemUser
705     @RequireSdkVersion(min = Q, reason = "Cannot use RemoteDPC cross-user prior to Q")
remove_profileOwner_removes()706     public void remove_profileOwner_removes() {
707         try (UserReference profile = TestApis.users().createUser()
708                 .parent(sUser)
709                 .type(TestApis.users().supportedType(UserType.MANAGED_PROFILE_TYPE_NAME))
710                 .createAndStart()) {
711             RemoteDpc remoteDPC = RemoteDpc.setAsProfileOwner(profile);
712 
713             remoteDPC.remove();
714 
715             assertThat(TestApis.devicePolicy().getProfileOwner(profile)).isNull();
716         }
717     }
718 
719     // TODO(scottjonathan): Do we need to support the case where there is both a DO and a PO on
720     //  older versions of Android?
721 
722     @Test
723     @EnsureHasDeviceOwner
frameworkCall_makesCall()724     public void frameworkCall_makesCall() {
725         sDeviceState.dpc().devicePolicyManager().getCurrentFailedPasswordAttempts();
726     }
727 
728     @Test
729     @EnsureHasNoDeviceOwner
730     @EnsureHasNoWorkProfile
731     @RequireRunOnSystemUser
732     @RequireSdkVersion(min = Q, reason = "Cannot use RemoteDPC cross-user prior to Q")
frameworkCall_onProfile_makesCall()733     public void frameworkCall_onProfile_makesCall() {
734         try (UserReference profile = TestApis.users().createUser()
735                 .parent(sUser)
736                 .type(TestApis.users().supportedType(UserType.MANAGED_PROFILE_TYPE_NAME))
737                 .createAndStart()) {
738             RemoteDpc remoteDPC = RemoteDpc.setAsProfileOwner(profile);
739 
740             // Checking that the call succeeds
741             remoteDPC.devicePolicyManager().isUsingUnifiedPassword(remoteDPC.componentName());
742         }
743     }
744 
745     @Test
746     @EnsureHasDeviceOwner
frameworkCallRequiresProfileOwner_notProfileOwner_throwsSecurityException()747     public void frameworkCallRequiresProfileOwner_notProfileOwner_throwsSecurityException() {
748         RemoteDpc remoteDPC = RemoteDpc.deviceOwner();
749 
750         assertThrows(SecurityException.class, () ->
751                 remoteDPC.devicePolicyManager().isUsingUnifiedPassword(remoteDPC.componentName()));
752     }
753 
754     @Test
forDevicePolicyController_nullDevicePolicyController_throwsException()755     public void forDevicePolicyController_nullDevicePolicyController_throwsException() {
756         assertThrows(NullPointerException.class, () -> RemoteDpc.forDevicePolicyController(null));
757     }
758 
759     @Test
760     @RequireRunOnSystemUser
761     @EnsureHasNoDeviceOwner
762     @EnsureHasNoProfileOwner
763     @EnsureHasNoSecondaryUser // TODO(b/202832720): Replace with @EnsureHasOnlyInstrumentedUser
764     @EnsureHasNoWorkProfile // TODO(b/202832720): Replace with @EnsureHasOnlyInstrumentedUser
forDevicePolicyController_nonRemoteDpcDevicePolicyController_throwsException()765     public void forDevicePolicyController_nonRemoteDpcDevicePolicyController_throwsException() {
766         DeviceOwner deviceOwner = TestApis.devicePolicy().setDeviceOwner(NON_REMOTE_DPC_COMPONENT);
767 
768         try {
769             assertThrows(IllegalStateException.class,
770                     () -> RemoteDpc.forDevicePolicyController(deviceOwner));
771         } finally {
772             deviceOwner.remove();
773         }
774     }
775 
776     @Test
777     @EnsureHasDeviceOwner
forDevicePolicyController_remoteDpcDevicePolicyController_returnsRemoteDpc()778     public void forDevicePolicyController_remoteDpcDevicePolicyController_returnsRemoteDpc() {
779         RemoteDpc remoteDPC = RemoteDpc.deviceOwner();
780 
781         assertThat(RemoteDpc.forDevicePolicyController(remoteDPC.devicePolicyController()))
782                 .isNotNull();
783     }
784 
785     @Test
786     @EnsureHasNoWorkProfile
787     @EnsureHasNoDeviceOwner
788     @RequireRunOnSystemUser
789     @RequireSdkVersion(min = Q, reason = "Cannot use RemoteDPC cross-user prior to Q")
getParentProfileInstance_returnsUsableInstance()790     public void getParentProfileInstance_returnsUsableInstance() {
791         try (UserReference profile = TestApis.users().createUser()
792                 .parent(sUser)
793                 .type(TestApis.users().supportedType(UserType.MANAGED_PROFILE_TYPE_NAME))
794                 .createAndStart()) {
795             RemoteDpc remoteDpc = RemoteDpc.setAsProfileOwner(profile);
796 
797             // Confirm that we can call methods on the RemoteDevicePolicyManager which comes from
798             // getParentProfileInstance
799             remoteDpc.devicePolicyManager()
800                     .getParentProfileInstance(remoteDpc.componentName())
801                     .getPasswordQuality(remoteDpc.componentName());
802 
803             // APIs which are not supported on parent instances should throw SecurityException
804             assertThrows(SecurityException.class, () ->
805                     remoteDpc.devicePolicyManager()
806                             .getParentProfileInstance(remoteDpc.componentName())
807                             .getParentProfileInstance(remoteDpc.componentName()));
808         }
809     }
810 }
811