1 /*
2  * Copyright (C) 2015 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.cts.devicepolicy;
18 
19 import static com.android.cts.devicepolicy.metrics.DevicePolicyEventLogVerifier.assertMetricsLogged;
20 
21 import static org.junit.Assert.fail;
22 
23 import android.app.admin.flags.Flags;
24 import android.platform.test.annotations.FlakyTest;
25 import android.platform.test.annotations.LargeTest;
26 import android.platform.test.annotations.RequiresFlagsEnabled;
27 import android.platform.test.flag.junit.CheckFlagsRule;
28 import android.platform.test.flag.junit.host.HostFlagsValueProvider;
29 import android.stats.devicepolicy.EventId;
30 
31 import com.android.cts.devicepolicy.DeviceAdminFeaturesCheckerRule.IgnoreOnHeadlessSystemUserMode;
32 import com.android.cts.devicepolicy.DeviceAdminFeaturesCheckerRule.TemporarilyIgnoreOnHeadlessSystemUserMode;
33 import com.android.cts.devicepolicy.metrics.DevicePolicyEventWrapper;
34 import com.android.tradefed.device.DeviceNotAvailableException;
35 import com.android.tradefed.log.LogUtil.CLog;
36 
37 import org.junit.Ignore;
38 import org.junit.Rule;
39 import org.junit.Test;
40 
41 import java.io.FileNotFoundException;
42 import java.util.Collections;
43 import java.util.HashMap;
44 import java.util.Map;
45 
46 /**
47  * Set of tests for device owner use cases that also apply to profile owners.
48  * Tests that should be run identically in both cases are added in DeviceAndProfileOwnerTest.
49  */
50 public final class MixedDeviceOwnerTest extends DeviceAndProfileOwnerTest {
51 
52     private static final String ARG_SECURITY_LOGGING_BATCH_NUMBER = "batchNumber";
53     private static final int SECURITY_EVENTS_BATCH_SIZE = 100;
54 
55     private boolean mDeviceOwnerSet;
56 
57     @Rule
58     public final CheckFlagsRule mCheckFlagsRule =
59             HostFlagsValueProvider.createCheckFlagsRule(this::getDevice);
60 
61     @Override
setUp()62     public void setUp() throws Exception {
63         super.setUp();
64 
65         mUserId = mPrimaryUserId;
66 
67         CLog.i("%s.setUp(): mUserId=%d, mPrimaryUserId=%d, mInitialUserId=%d, "
68                 + "mDeviceOwnerUserId=%d", getClass(), mUserId, mPrimaryUserId, mInitialUserId,
69                 mDeviceOwnerUserId);
70 
71         installDeviceOwnerApp(DEVICE_ADMIN_APK);
72         mDeviceOwnerSet = setDeviceOwner(DEVICE_ADMIN_COMPONENT_FLATTENED, mDeviceOwnerUserId,
73                 /*expectFailure= */ false);
74 
75         if (!mDeviceOwnerSet) {
76             removeDeviceOwnerAdmin(DEVICE_ADMIN_COMPONENT_FLATTENED);
77             getDevice().uninstallPackage(DEVICE_ADMIN_PKG);
78             fail("Failed to set device owner on user " + mDeviceOwnerUserId);
79         }
80     }
81 
82     @Override
tearDown()83     public void tearDown() throws Exception {
84         if (mDeviceOwnerSet) {
85             removeDeviceOwnerAdmin(DEVICE_ADMIN_COMPONENT_FLATTENED);
86         }
87 
88         super.tearDown();
89     }
90 
91     @Override
installAppPermissionAppAsUser()92     protected void installAppPermissionAppAsUser()
93             throws FileNotFoundException, DeviceNotAvailableException {
94         super.installAppPermissionAppAsUser();
95 
96         if (isHeadlessSystemUserMode()) {
97             installAppPermissionAppAsUser(mDeviceOwnerUserId);
98         }
99     }
100 
101     @Test
102     @IgnoreOnHeadlessSystemUserMode(reason = "CreateAndManageUsers is blocked on headless single "
103             + "user mode")
testLockTask_unaffiliatedUser()104     public void testLockTask_unaffiliatedUser() throws Exception {
105         assumeCanCreateAdditionalUsers(1);
106 
107         final int userId = createSecondaryUserAsProfileOwner();
108         runDeviceTestsAsUser(
109                 DEVICE_ADMIN_PKG,
110                 ".AffiliationTest",
111                 "testLockTaskMethodsThrowExceptionIfUnaffiliated",
112                 userId);
113 
114         setUserAsAffiliatedUserToPrimary(userId);
115         runDeviceTestsAsUser(
116                 DEVICE_ADMIN_PKG,
117                 ".AffiliationTest",
118                 "testSetLockTaskPackagesClearedIfUserBecomesUnaffiliated",
119                 userId);
120     }
121 
122     @Override
123     @Test
124     @TemporarilyIgnoreOnHeadlessSystemUserMode(bugId = "218408549",
125             reason = "Will be migrated to new test infra")
testDelegationCertSelection()126     public void testDelegationCertSelection() throws Exception {
127         super.testDelegationCertSelection();
128     }
129 
130     @TemporarilyIgnoreOnHeadlessSystemUserMode(bugId = "218408549",
131             reason = "Will be migrated to new test infra")
132     @Test
testDelegatedCertInstallerDeviceIdAttestation()133     public void testDelegatedCertInstallerDeviceIdAttestation() throws Exception {
134         setUpDelegatedCertInstallerAndRunTests(() ->
135                 runDeviceTestsAsUser("com.android.cts.certinstaller",
136                         ".DelegatedDeviceIdAttestationTest",
137                         "testGenerateKeyPairWithDeviceIdAttestationExpectingSuccess", mUserId));
138     }
139 
140     @TemporarilyIgnoreOnHeadlessSystemUserMode(bugId = "218408549",
141             reason = "Will be migrated to new test infra")
142     @Override
testDelegatedCertInstaller()143     public void testDelegatedCertInstaller() throws Exception {
144         super.testDelegatedCertInstaller();
145     }
146 
147     @Test
testLockScreenInfo()148     public void testLockScreenInfo() throws Exception {
149         executeDeviceTestClass(".LockScreenInfoTest");
150 
151         assertMetricsLogged(getDevice(), () -> {
152             executeDeviceTestMethod(".LockScreenInfoTest", "testSetAndGetLockInfo");
153         }, new DevicePolicyEventWrapper.Builder(EventId.SET_DEVICE_OWNER_LOCK_SCREEN_INFO_VALUE)
154                 .setAdminPackageName(DEVICE_ADMIN_PKG)
155                 .build());
156     }
157 
158     @Test
testCommonCriteriaMode()159     public void testCommonCriteriaMode() throws Exception {
160         executeDeviceTestClass(".CommonCriteriaModeTest");
161     }
162 
163     @LargeTest
164     @Test
165     @Ignore("b/145932189")
testSystemUpdatePolicy()166     public void testSystemUpdatePolicy() throws Exception {
167         executeDeviceTestClass(".systemupdate.SystemUpdatePolicyTest");
168     }
169 
170     @Test
testInstallUpdate()171     public void testInstallUpdate() throws Exception {
172         pushUpdateFileToDevice("notZip.zi");
173         pushUpdateFileToDevice("empty.zip");
174         pushUpdateFileToDevice("wrongPayload.zip");
175         pushUpdateFileToDevice("wrongHash.zip");
176         pushUpdateFileToDevice("wrongSize.zip");
177 
178         executeInstallUpdateTest(/* testName= */ null);
179     }
180 
181     @Test
testInstallUpdateLogged()182     public void testInstallUpdateLogged() throws Exception {
183         assumeIsDeviceAb();
184 
185         pushUpdateFileToDevice("wrongHash.zip");
186         assertMetricsLogged(getDevice(), () -> {
187             executeInstallUpdateTest("testInstallUpdate_failWrongHash");
188         }, new DevicePolicyEventWrapper.Builder(EventId.INSTALL_SYSTEM_UPDATE_VALUE)
189                     .setAdminPackageName(DEVICE_ADMIN_PKG)
190                     .setBoolean(/* isDeviceAb */ true)
191                     .build(),
192             new DevicePolicyEventWrapper.Builder(EventId.INSTALL_SYSTEM_UPDATE_ERROR_VALUE)
193                     .setInt(UPDATE_ERROR_UPDATE_FILE_INVALID)
194                     .build());
195     }
196 
executeInstallUpdateTest(String testName)197     private void executeInstallUpdateTest(String testName) throws Exception {
198         // This test must run on system user as it calls installSystemUpdate(), which takes a
199         // Runnable callback (InstallSystemUpdateCallback) and hence it cannot be easily passed
200         // around through IPC (on headless system user mode).
201         executeDeviceTestMethodOnDeviceOwnerUser(".systemupdate.InstallUpdateTest", testName);
202     }
203 
204     // This test sometimes fail on headless system user mode because the DO app doesn't have
205     // INTERACT_ACROSS_USERS to use DpmWrapper - given that it will be refactored to use the new
206     // test infra, it's not worth to figure out why...
207     @FlakyTest(bugId = 137088260)
208     @Test
testSecurityLoggingWithSingleUser()209     public void testSecurityLoggingWithSingleUser() throws Exception {
210         // Backup stay awake setting because testGenerateLogs() will turn it off.
211         final String stayAwake = getDevice().getSetting("global", "stay_on_while_plugged_in");
212         try {
213             // Turn logging on.
214             executeDeviceTestMethod(".SecurityLoggingTest", "testEnablingSecurityLogging");
215             // Reboot to ensure ro.device_owner is set to true in logd and logging is on.
216             rebootAndWaitUntilReady();
217             waitForUserUnlock(mUserId);
218 
219             // Generate various types of events on device side and check that they are logged.
220             executeDeviceTestMethod(".SecurityLoggingTest", "testGenerateLogs");
221             getDevice().executeShellCommand("whoami"); // Generate adb command securty event
222             executeDeviceTestMethod(".SecurityLoggingTest", "testVerifyGeneratedLogs");
223 
224             // Reboot the device, so the security event ids are reset.
225             rebootAndWaitUntilReady();
226 
227             // Verify event ids are consistent across a consecutive batch.
228             for (int batchNumber = 0; batchNumber < 3; batchNumber++) {
229                 generateTestSecurityLogs();
230                 executeDeviceTestMethod(".SecurityLoggingTest", "testVerifyLogIds",
231                         Collections.singletonMap(ARG_SECURITY_LOGGING_BATCH_NUMBER,
232                                 Integer.toString(batchNumber)));
233             }
234 
235             // Immediately attempting to fetch events again should fail.
236             executeDeviceTestMethod(".SecurityLoggingTest",
237                     "testSecurityLoggingRetrievalRateLimited");
238         } finally {
239             // Turn logging off.
240             executeDeviceTestMethod(".SecurityLoggingTest", "testDisablingSecurityLogging");
241             // Restore stay awake setting.
242             if (stayAwake != null) {
243                 getDevice().setSetting("global", "stay_on_while_plugged_in", stayAwake);
244             }
245         }
246     }
247 
248     @Test
testSecurityLoggingEnabledLogged()249     public void testSecurityLoggingEnabledLogged() throws Exception {
250         assertMetricsLogged(getDevice(), () -> {
251             executeDeviceTestMethod(".SecurityLoggingTest", "testEnablingSecurityLogging");
252             executeDeviceTestMethod(".SecurityLoggingTest", "testDisablingSecurityLogging");
253         }, new DevicePolicyEventWrapper.Builder(EventId.SET_SECURITY_LOGGING_ENABLED_VALUE)
254                 .setAdminPackageName(DEVICE_ADMIN_PKG)
255                 .setBoolean(true)
256                 .build(),
257             new DevicePolicyEventWrapper.Builder(EventId.SET_SECURITY_LOGGING_ENABLED_VALUE)
258                     .setAdminPackageName(DEVICE_ADMIN_PKG)
259                     .setBoolean(false)
260                     .build());
261     }
262 
263     @Test
testSecurityLoggingWithTwoUsers()264     public void testSecurityLoggingWithTwoUsers() throws Exception {
265         assumeCanCreateAdditionalUsers(1);
266 
267         final int userId = createUser();
268         try {
269             // The feature can be enabled, but in a "paused" state. Attempting to retrieve logs
270             // should throw security exception.
271             executeDeviceTestMethod(".SecurityLoggingTest", "testEnablingSecurityLogging");
272             executeDeviceTestMethod(".SecurityLoggingTest",
273                     "testRetrievingSecurityLogsThrowsSecurityException");
274             executeDeviceTestMethod(".SecurityLoggingTest",
275                     "testRetrievingPreviousSecurityLogsThrowsSecurityException");
276         } finally {
277             removeUser(userId);
278             executeDeviceTestMethod(".SecurityLoggingTest", "testDisablingSecurityLogging");
279         }
280     }
281 
282     @Test
283     @RequiresFlagsEnabled(Flags.FLAG_HEADLESS_DEVICE_OWNER_DELEGATE_SECURITY_LOGGING_BUG_FIX)
testSecurityLoggingDelegate()284     public void testSecurityLoggingDelegate() throws Exception {
285         installAppAsUser(DELEGATE_APP_APK, mDeviceOwnerUserId);
286         try {
287             // Test that the delegate cannot access the logs already
288             runDeviceTestsAsUser(DELEGATE_APP_PKG, ".SecurityLoggingDelegateTest",
289                     "testCannotAccessApis", mDeviceOwnerUserId);
290 
291             // Set security logging delegate
292             executeDeviceTestMethodOnDeviceOwnerUser(".SecurityLoggingTest",
293                     "testSetDelegateScope_delegationSecurityLogging");
294 
295             runSecurityLoggingTests(DELEGATE_APP_PKG, ".SecurityLoggingDelegateTest");
296         } finally {
297             // Remove security logging delegate
298             executeDeviceTestMethodOnDeviceOwnerUser(".SecurityLoggingTest",
299                     "testSetDelegateScope_noDelegation");
300         }
301     }
302 
runSecurityLoggingTests(String packageName, String testClassName)303     private void runSecurityLoggingTests(String packageName, String testClassName)
304             throws Exception {
305         int userId = mDeviceOwnerUserId;
306         try {
307             // Turn logging on.
308             runDeviceTestsAsUser(packageName, testClassName, "testEnablingSecurityLogging", userId);
309             // Reboot to ensure ro.organization_owned is set to true in logd and logging is on.
310             rebootAndWaitUntilReady();
311             waitForUserUnlock(userId);
312 
313             // Generate various types of events on device side and check that they are logged.
314             runDeviceTestsAsUser(packageName, testClassName, "testGenerateLogs", userId);
315             runDeviceTestsAsUser(packageName, testClassName, "testVerifyGeneratedLogs", userId);
316 
317             // Immediately attempting to fetch events again should fail.
318             runDeviceTestsAsUser(packageName, testClassName,
319                     "testSecurityLoggingRetrievalRateLimited", userId);
320         } finally {
321             // Turn logging off.
322             runDeviceTestsAsUser(packageName, testClassName,
323                     "testDisablingSecurityLogging", userId);
324         }
325     }
326 
327     @Override
328     @Test
testAdminControlOverSensorPermissionGrantsDefault()329     public void testAdminControlOverSensorPermissionGrantsDefault() throws Exception {
330         // In Device Owner mode, by default, admin should be able to grant sensors-related
331         // permissions.
332         executeDeviceTestMethod(".SensorPermissionGrantTest",
333                 "testAdminCanGrantSensorsPermissions");
334     }
335 
336     //TODO(b/180413140) Investigate why the test fails on DO mode.
337     @Override
338     @Test
testPermissionPrompts()339     public void testPermissionPrompts() throws Exception {
340     }
341 
342 
343     @Override
344     @LargeTest
345     @Test
346     @IgnoreOnHeadlessSystemUserMode(reason = "Headless system user doesn't have UI")
testPackageInstallUserRestrictions()347     public void testPackageInstallUserRestrictions() throws Exception {
348         super.testPackageInstallUserRestrictions();
349     }
350 
351     @Override
352     @Test
353     @IgnoreOnHeadlessSystemUserMode(reason = "Headless system user doesn't launch activities")
testSuspendPackage()354     public void testSuspendPackage() throws Exception {
355         super.testSuspendPackage();
356     }
357 
358     @Override
359     @Test
360     @IgnoreOnHeadlessSystemUserMode(reason = "Headless system user doesn't launch activities")
testSuspendPackageWithPackageManager()361     public void testSuspendPackageWithPackageManager() throws Exception {
362         super.testSuspendPackageWithPackageManager();
363     }
364 
365     @Override
366     @Test
367     @IgnoreOnHeadlessSystemUserMode(reason = "Headless system user doesn't have credentials")
testGetPasswordExpiration()368     public void testGetPasswordExpiration() throws Exception {
369         super.testGetPasswordExpiration();
370     }
371 
372     @Override
373     @Test
374     @IgnoreOnHeadlessSystemUserMode(reason = "Headless system user doesn't have credentials")
testPasswordExpiration()375     public void testPasswordExpiration() throws Exception {
376         super.testPasswordExpiration();
377     }
378 
379     @Override
380     @Test
381     @IgnoreOnHeadlessSystemUserMode(reason = "Headless system user doesn't launch activities")
testDisallowAutofill_allowed()382     public void testDisallowAutofill_allowed() throws Exception {
383         super.testDisallowAutofill_allowed();
384     }
385 
386     @Override
387     @Test
388     @IgnoreOnHeadlessSystemUserMode(reason = "Headless system user doesn't launch activities")
testPermissionAppUpdate()389     public void testPermissionAppUpdate() throws Exception {
390         super.testPermissionAppUpdate();
391     }
392 
393     @Override
394     @Test
395     @IgnoreOnHeadlessSystemUserMode(reason = "Headless system user doesn't launch activities")
testPermissionPolicy()396     public void testPermissionPolicy() throws Exception {
397         super.testPermissionPolicy();
398     }
399 
400     @Override
401     @Test
402     @IgnoreOnHeadlessSystemUserMode(reason = "Headless system user doesn't launch activities")
testPermissionGrantOfDisallowedPermissionWhileOtherPermIsGranted()403     public void testPermissionGrantOfDisallowedPermissionWhileOtherPermIsGranted()
404             throws Exception {
405         super.testPermissionGrantOfDisallowedPermissionWhileOtherPermIsGranted();
406     }
407 
408     @Ignore("b/330134976")
409     @LargeTest
410     @Test
testLockTaskCantBeInterrupted()411     public void testLockTaskCantBeInterrupted() throws Exception {
412         try {
413             // Just start kiosk mode
414             executeDeviceTestMethod(
415                     ".LockTaskHostDrivenTest", "testStartLockTask_noAsserts");
416 
417             // Check that kiosk mode is working and can't be interrupted
418             executeDeviceTestMethod(".LockTaskHostDrivenTest",
419                     "testLockTaskIsActiveAndCantBeInterrupted");
420         } finally {
421             executeDeviceTestMethod(".LockTaskHostDrivenTest", "testCleanupLockTask_noAsserts");
422         }
423     }
424 
425 
426     @Override
installDelegateApp()427     protected void installDelegateApp() throws Exception {
428         // TODO(b/176993670): must call installDeviceOwnerApp() - even though it's not one - so
429         // the permissions required to use DpmWrapper are set on headless system user mode
430         installDeviceOwnerApp(DELEGATE_APP_APK);
431     }
432 
433     @Override
runDeviceTestsAsUser(String pkgName, String testClassName, String testName, int userId, Map<String, String> params)434     protected void runDeviceTestsAsUser(String pkgName, String testClassName, String testName,
435             int userId, Map<String, String> params) throws DeviceNotAvailableException {
436         Map<String, String> newParams = new HashMap(params);
437         Map<String, String> doParams = getParamsForDeviceOwnerTest();
438         CLog.d("runDeviceTestsAsUser(): adding device owner params (%s)", doParams);
439         newParams.putAll(doParams);
440         super.runDeviceTestsAsUser(
441                 pkgName, testClassName, testName, userId, newParams);
442     }
443 
444     @Override
getAdditionalExtrasForSetPolicyActivity()445     protected String getAdditionalExtrasForSetPolicyActivity() {
446         return " --es extra-admin-type DeviceOwner";
447     }
448 
449     @Override
getUserIdForAlwaysOnVpnTests()450     protected int getUserIdForAlwaysOnVpnTests() {
451         // Running on current user on headless system user would require too many hacky changes on
452         // DpmWrapper / VpnTestHelper such as providing a ConnectivityManager and properly waiting
453         // for broadcasts
454         return mDeviceOwnerUserId;
455     }
456 
457     @Override
executeDeviceTestMethod(String className, String testName, Map<String, String> params)458     protected void executeDeviceTestMethod(String className, String testName,
459             Map<String, String> params) throws Exception {
460         runDeviceTestsAsUser(DEVICE_ADMIN_PKG, className, testName, mUserId, params);
461     }
462 
executeDeviceTestMethodOnDeviceOwnerUser(String className, String testName)463     private void executeDeviceTestMethodOnDeviceOwnerUser(String className, String testName)
464             throws Exception {
465         executeDeviceTestMethod(className, testName, mDeviceOwnerUserId,
466                 /* params= */ new HashMap<>());
467     }
468 
generateTestSecurityLogs()469     private void generateTestSecurityLogs() throws Exception {
470         // Trigger security events of type TAG_ADB_SHELL_CMD.
471         for (int i = 0; i < SECURITY_EVENTS_BATCH_SIZE; i++) {
472             getDevice().executeShellCommand("echo just_testing_" + i);
473         }
474     }
475 
createSecondaryUserAsProfileOwner()476     private int createSecondaryUserAsProfileOwner() throws Exception {
477         final int userId = createUserAndWaitStart();
478         installAppAsUser(INTENT_RECEIVER_APK, userId);
479         installAppAsUser(DEVICE_ADMIN_APK, userId);
480         setProfileOwnerOrFail(DEVICE_ADMIN_COMPONENT_FLATTENED, userId);
481         return userId;
482     }
483 
setUserAsAffiliatedUserToPrimary(int userId)484     private void setUserAsAffiliatedUserToPrimary(int userId) throws Exception {
485         // Setting the same affiliation ids on both users
486         runDeviceTestsAsUser(
487                 DEVICE_ADMIN_PKG, ".AffiliationTest", "testSetAffiliationId1", mPrimaryUserId);
488         runDeviceTestsAsUser(
489                 DEVICE_ADMIN_PKG, ".AffiliationTest", "testSetAffiliationId1", userId);
490     }
491 }
492