1 /*
2  * Copyright (C) 2014 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 package com.android.cts.devicepolicy;
17 
18 import static com.android.cts.devicepolicy.metrics.DevicePolicyEventLogVerifier.assertMetricsLogged;
19 
20 import static org.junit.Assert.assertFalse;
21 import static org.junit.Assert.assertTrue;
22 import static org.junit.Assert.fail;
23 
24 import android.platform.test.annotations.LargeTest;
25 import android.stats.devicepolicy.EventId;
26 
27 import com.android.cts.devicepolicy.metrics.DevicePolicyEventWrapper;
28 import com.android.ddmlib.Log.LogLevel;
29 import com.android.tradefed.device.DeviceNotAvailableException;
30 import com.android.tradefed.log.LogUtil.CLog;
31 import com.android.tradefed.util.RunInterruptedException;
32 import com.android.tradefed.util.RunUtil;
33 
34 import org.junit.Test;
35 
36 import java.util.HashMap;
37 import java.util.Map;
38 import java.util.concurrent.TimeUnit;
39 
40 /**
41  * Set of tests for Managed Profile use cases.
42  */
43 public final class ManagedProfileTest extends BaseManagedProfileTest {
44 
45     private static final String DEVICE_OWNER_PKG = "com.android.cts.deviceowner";
46     private static final String DEVICE_OWNER_APK = "CtsDeviceOwnerApp.apk";
47     private static final String DEVICE_OWNER_ADMIN =
48             DEVICE_OWNER_PKG + ".BaseDeviceOwnerTest$BasicAdminReceiver";
49 
50     @Test
testManagedProfileSetup()51     public void testManagedProfileSetup() throws Exception {
52         runDeviceTestsAsUser(
53                 MANAGED_PROFILE_PKG, MANAGED_PROFILE_PKG + ".ManagedProfileSetupTest",
54                 mProfileUserId);
55     }
56 
57     /**
58      * Verify that removing a managed profile will remove all networks owned by that profile.
59      */
60     @Test
testProfileWifiCleanup()61     public void testProfileWifiCleanup() throws Exception {
62         assumeHasWifiFeature();
63 
64         try (LocationModeSetter locationModeSetter = new LocationModeSetter(getDevice())) {
65             locationModeSetter.setLocationEnabled(true);
66             runDeviceTestsAsUser(
67                     MANAGED_PROFILE_PKG, ".WifiTest", "testRemoveWifiNetworkIfExists",
68                     mParentUserId);
69 
70             runDeviceTestsAsUser(
71                     MANAGED_PROFILE_PKG, ".WifiTest", "testAddWifiNetwork", mProfileUserId);
72 
73             // Now delete the user - should undo the effect of testAddWifiNetwork.
74             removeUser(mProfileUserId);
75             runDeviceTestsAsUser(
76                     MANAGED_PROFILE_PKG, ".WifiTest", "testWifiNetworkDoesNotExist",
77                     mParentUserId);
78         }
79     }
80 
81     @Test
testSettingsIntents()82     public void testSettingsIntents() throws Exception {
83         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".SettingsIntentsTest",
84                 mProfileUserId);
85     }
86 
87     /** Tests for the API helper class. */
88     @Test
testCurrentApiHelper()89     public void testCurrentApiHelper() throws Exception {
90         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CurrentApiHelperTest",
91                 mProfileUserId);
92     }
93 
94     /** Test: unsupported public APIs are disabled on a parent profile. */
95     @Test
testParentProfileApiDisabled()96     public void testParentProfileApiDisabled() throws Exception {
97         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ParentProfileTest",
98                 "testParentProfileApiDisabled", mProfileUserId);
99     }
100 
101     @Test
testCannotCallMethodsOnParentProfile()102     public void testCannotCallMethodsOnParentProfile() throws Exception {
103         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ParentProfileTest",
104                 "testCannotWipeParentProfile", mProfileUserId);
105 
106         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ParentProfileTest",
107                 "testCannotCallSetDefaultSmsApplicationOnParentProfile", mProfileUserId);
108     }
109 
110     // TODO: This test is not specific to managed profiles, but applies to multi-user in general.
111     // Move it to a MultiUserTest class when there is one. Should probably move
112     // SetPolicyActivity to a more generic apk too as it might be useful for different kinds
113     // of tests (same applies to ComponentDisablingActivity).
114     @Test
testNoDebuggingFeaturesRestriction()115     public void testNoDebuggingFeaturesRestriction() throws Exception {
116         // If adb is running as root, then the adb uid is 0 instead of SHELL_UID,
117         // so the DISALLOW_DEBUGGING_FEATURES restriction does not work and this test
118         // fails.
119         if (getDevice().isAdbRoot()) {
120             CLog.logAndDisplay(LogLevel.WARN,
121                     "Cannot test testNoDebuggingFeaturesRestriction() in eng/userdebug build");
122             return;
123         }
124         String restriction = "no_debugging_features";  // UserManager.DISALLOW_DEBUGGING_FEATURES
125 
126         changeUserRestrictionOrFail(restriction, true, mProfileUserId);
127 
128 
129         // This should now fail, as the shell is not available to start activities under a different
130         // user once the restriction is in place.
131         String addRestrictionCommandOutput =
132                 changeUserRestriction(restriction, true, mProfileUserId);
133         assertTrue(
134                 "Expected SecurityException when starting the activity "
135                         + addRestrictionCommandOutput,
136                 addRestrictionCommandOutput.contains("SecurityException"));
137     }
138 
139     @Test
testOrganizationInfo()140     public void testOrganizationInfo() throws Exception {
141         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".OrganizationInfoTest",
142                 "testDefaultOrganizationColor", mProfileUserId);
143         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".OrganizationInfoTest",
144                 "testDefaultOrganizationNameIsNull", mProfileUserId);
145         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".OrganizationInfoTest",
146                 mProfileUserId);
147         assertMetricsLogged(getDevice(), () -> {
148             runDeviceTestsAsUser(
149                     MANAGED_PROFILE_PKG, MANAGED_PROFILE_PKG + ".OrganizationInfoTest",
150                     "testSetOrganizationColor", mProfileUserId);
151         }, new DevicePolicyEventWrapper.Builder(EventId.SET_ORGANIZATION_COLOR_VALUE)
152                 .setAdminPackageName(MANAGED_PROFILE_PKG)
153                 .build());
154     }
155 
156     @Test
testDevicePolicyManagerParentSupport()157     public void testDevicePolicyManagerParentSupport() throws Exception {
158         runDeviceTestsAsUser(
159                 MANAGED_PROFILE_PKG, ".DevicePolicyManagerParentSupportTest", mProfileUserId);
160     }
161 
162     @Test
testCannotSetProfileOwnerAgain()163     public void testCannotSetProfileOwnerAgain() throws Exception {
164         // verify that we can't set the same admin receiver as profile owner again
165         assertFalse(setProfileOwner(
166                 MANAGED_PROFILE_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS, mProfileUserId,
167                 /*expectFailure*/ true));
168 
169         // verify that we can't set a different admin receiver as profile owner
170         installAppAsUser(DEVICE_OWNER_APK, mProfileUserId);
171         assertFalse(setProfileOwner(DEVICE_OWNER_PKG + "/" + DEVICE_OWNER_ADMIN, mProfileUserId,
172                 /*expectFailure*/ true));
173     }
174 
175     @LargeTest
176     @Test
testCannotSetDeviceOwnerWhenProfilePresent()177     public void testCannotSetDeviceOwnerWhenProfilePresent() throws Exception {
178         try {
179             installAppAsUser(DEVICE_OWNER_APK, mParentUserId);
180             assertFalse(setDeviceOwner(DEVICE_OWNER_PKG + "/" + DEVICE_OWNER_ADMIN, mParentUserId,
181                     /*expectFailure*/ true));
182         } finally {
183             // make sure we clean up in case we succeeded in setting the device owner
184             removeAdmin(DEVICE_OWNER_PKG + "/" + DEVICE_OWNER_ADMIN, mParentUserId);
185             getDevice().uninstallPackage(DEVICE_OWNER_PKG);
186         }
187     }
188 
189     @Test
testNfcRestriction()190     public void testNfcRestriction() throws Exception {
191         assumeHasNfcFeatures();
192 
193         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".NfcTest",
194                 "testNfcShareEnabled", mProfileUserId);
195         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".NfcTest",
196                 "testNfcShareEnabled", mParentUserId);
197 
198         changeUserRestrictionOrFail("no_outgoing_beam" /* UserManager.DISALLOW_OUTGOING_BEAM */,
199                 true, mProfileUserId);
200 
201         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".NfcTest",
202                 "testNfcShareDisabled", mProfileUserId);
203         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".NfcTest",
204                 "testNfcShareEnabled", mParentUserId);
205     }
206 
207     @Test
testPhoneAccountVisibility()208     public void testPhoneAccountVisibility() throws Exception {
209         assumeHasTelephonyAndConnectionServiceFeatures();
210 
211         try {
212             // Register phone account in parent user.
213             runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".PhoneAccountTest",
214                     "testRegisterPhoneAccount",
215                     mParentUserId);
216             // The phone account should not be visible in managed user.
217             runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".PhoneAccountTest",
218                     "testPhoneAccountNotRegistered",
219                     mProfileUserId);
220         } finally {
221             // Unregister the phone account.
222             runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".PhoneAccountTest",
223                     "testUnregisterPhoneAccount",
224                     mParentUserId);
225         }
226 
227         try {
228             // Register phone account in profile user.
229             runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".PhoneAccountTest",
230                     "testRegisterPhoneAccount",
231                     mProfileUserId);
232             // The phone account should not be visible in parent user.
233             runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".PhoneAccountTest",
234                     "testPhoneAccountNotRegistered",
235                     mParentUserId);
236         } finally {
237             // Unregister the phone account.
238             runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".PhoneAccountTest",
239                     "testUnregisterPhoneAccount",
240                     mProfileUserId);
241         }
242     }
243 
244     @LargeTest
245     @Test
testManagedCall()246     public void testManagedCall() throws Exception {
247         assumeHasTelephonyAndConnectionServiceFeatures();
248 
249         getDevice().executeShellCommand("telecom set-default-dialer " + MANAGED_PROFILE_PKG);
250 
251         // Place a outgoing call through work phone account using TelecomManager and verify the
252         // call is inserted properly.
253         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".PhoneAccountTest",
254                 "testOutgoingCallUsingTelecomManager",
255                 mProfileUserId);
256         // Make sure the call is not inserted into parent user.
257         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".PhoneAccountTest",
258                 "testEnsureCallNotInserted",
259                 mParentUserId);
260 
261         // Place a outgoing call through work phone account using ACTION_CALL and verify the call
262         // is inserted properly.
263         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".PhoneAccountTest",
264                 "testOutgoingCallUsingActionCall",
265                 mProfileUserId);
266         // Make sure the call is not inserted into parent user.
267         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".PhoneAccountTest",
268                 "testEnsureCallNotInserted",
269                 mParentUserId);
270 
271         // Add an incoming call with parent user's phone account and verify the call is inserted
272         // properly.
273         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".PhoneAccountTest",
274                 "testIncomingCall",
275                 mProfileUserId);
276         // Make sure the call is not inserted into parent user.
277         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".PhoneAccountTest",
278                 "testEnsureCallNotInserted",
279                 mParentUserId);
280 
281         // Add an incoming missed call with parent user's phone account and verify the call is
282         // inserted properly.
283         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".PhoneAccountTest",
284                 "testIncomingMissedCall",
285                 mProfileUserId);
286         // Make sure the call is not inserted into parent user.
287         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".PhoneAccountTest",
288                 "testEnsureCallNotInserted",
289                 mParentUserId);
290     }
291 
292     @Test
testTrustAgentInfo()293     public void testTrustAgentInfo() throws Exception {
294         assumeHasSecureLockScreenFeature();
295 
296         // Set and get trust agent config using child dpm instance.
297         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".TrustAgentInfoTest",
298                 "testSetAndGetTrustAgentConfiguration_child",
299                 mProfileUserId);
300         // Set and get trust agent config using parent dpm instance.
301         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".TrustAgentInfoTest",
302                 "testSetAndGetTrustAgentConfiguration_parent",
303                 mProfileUserId);
304         // Unified case
305         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".TrustAgentInfoTest",
306                 "testSetTrustAgentConfiguration_bothHaveTrustAgentConfigAndUnified",
307                 mProfileUserId);
308         // Non-unified case
309         try {
310             changeUserCredential(TEST_PASSWORD, null, mProfileUserId);
311             runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".TrustAgentInfoTest",
312                     "testSetTrustAgentConfiguration_bothHaveTrustAgentConfigAndNonUnified",
313                     mProfileUserId);
314         } finally {
315             changeUserCredential(null, TEST_PASSWORD, mProfileUserId);
316         }
317     }
318 
319     @Test
testProfileOwnerOnPersonalDeviceCannotGetDeviceIdentifiers()320     public void testProfileOwnerOnPersonalDeviceCannotGetDeviceIdentifiers() throws Exception {
321         // The Profile Owner should have access to all device identifiers.
322         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".DeviceIdentifiersTest",
323                 "testProfileOwnerOnPersonalDeviceCannotGetDeviceIdentifiers", mProfileUserId);
324     }
325 
326     @Test
testSetProfileNameLogged()327     public void testSetProfileNameLogged() throws Exception {
328         assertMetricsLogged(getDevice(), () -> {
329             runDeviceTestsAsUser(
330                     MANAGED_PROFILE_PKG, MANAGED_PROFILE_PKG + ".DevicePolicyLoggingTest",
331                     "testSetProfileNameLogged", mProfileUserId);
332         }, new DevicePolicyEventWrapper.Builder(EventId.SET_PROFILE_NAME_VALUE)
333                 .setAdminPackageName(MANAGED_PROFILE_PKG)
334                 .build());
335     }
336 
337     @Test
testCanGetWorkShortcutIconDrawableFromPersonalProfile()338     public void testCanGetWorkShortcutIconDrawableFromPersonalProfile()
339             throws DeviceNotAvailableException {
340         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".LauncherAppsTest",
341                 "addDynamicShortcuts", mProfileUserId);
342         try {
343             Map<String, String> params = new HashMap<>();
344             params.put("otherProfileUserId", String.valueOf(mProfileUserId));
345             runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".LauncherAppsTest",
346                     "shortcutIconDrawable_currentToOtherProfile_withUsersFullPermission_isNotNull",
347                     mPrimaryUserId, params);
348         } finally {
349             runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".LauncherAppsTest",
350                     "removeAllDynamicShortcuts", mProfileUserId);
351         }
352     }
353 
354     @Test
testCanGetPersonalShortcutIconDrawableFromWorkProfile()355     public void testCanGetPersonalShortcutIconDrawableFromWorkProfile()
356             throws DeviceNotAvailableException {
357         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".LauncherAppsTest",
358                 "addDynamicShortcuts", mPrimaryUserId);
359         try {
360             Map<String, String> params = new HashMap<>();
361             params.put("otherProfileUserId", String.valueOf(mPrimaryUserId));
362             runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".LauncherAppsTest",
363                     "shortcutIconDrawable_currentToOtherProfile_withUsersFullPermission_isNotNull",
364                     mProfileUserId, params);
365             runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".LauncherAppsTest",
366                     "shortcutIconDrawable_currentToOtherProfile_withoutUsersFullPermission_isNull",
367                     mProfileUserId, params);
368         } finally {
369             runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".LauncherAppsTest",
370                     "removeAllDynamicShortcuts", mPrimaryUserId);
371         }
372     }
373 
374     @Test
testCanGetProfiles()375     public void testCanGetProfiles() throws Exception {
376         // getAllProfiles should contain both the primary and profile
377         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".UserManagerTest",
378                 "testGetAllProfiles", mPrimaryUserId);
379 
380         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".UserManagerTest",
381                 "testGetAllProfiles", mProfileUserId);
382 
383         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".UserManagerTest",
384                 "testIsProfileReturnsFalse_runAsPrimary", mPrimaryUserId);
385 
386         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".UserManagerTest",
387                 "testIsProfileReturnsTrue_runAsProfile", mProfileUserId);
388     }
389 
390     @Test
testCanCreateProfile()391     public void testCanCreateProfile() throws Exception {
392         // remove pre-created profile
393         removeUser(mProfileUserId);
394 
395         // create profile from installed app
396         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".UserManagerTest",
397                 "testCreateProfile_managedProfile", mPrimaryUserId);
398     }
399 
400     @Test
testResolverActivityLaunchedFromPersonalProfileWithSelectedWorkTab()401     public void testResolverActivityLaunchedFromPersonalProfileWithSelectedWorkTab()
402             throws Exception {
403         installAppAsUser(SHARING_APP_1_APK, mPrimaryUserId);
404         installAppAsUser(SHARING_APP_2_APK, mPrimaryUserId);
405         installAppAsUser(SHARING_APP_1_APK, mProfileUserId);
406         installAppAsUser(SHARING_APP_2_APK, mProfileUserId);
407         try {
408             runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileSharingTest",
409                     "addCrossProfileIntents", mProfileUserId);
410             runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileSharingTest",
411                     "startSwitchToOtherProfileIntent", mPrimaryUserId);
412             assertResolverActivityInForeground(mPrimaryUserId);
413         } finally {
414             pressHome();
415             runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileSharingTest",
416                     "clearCrossProfileIntents", mProfileUserId);
417         }
418     }
419 
420     @Test
testResolverActivityLaunchedFromWorkProfileWithSelectedPersonalTab()421     public void testResolverActivityLaunchedFromWorkProfileWithSelectedPersonalTab()
422             throws Exception {
423         installAppAsUser(SHARING_APP_1_APK, mPrimaryUserId);
424         installAppAsUser(SHARING_APP_2_APK, mPrimaryUserId);
425         installAppAsUser(SHARING_APP_1_APK, mProfileUserId);
426         installAppAsUser(SHARING_APP_2_APK, mProfileUserId);
427         try {
428             runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileSharingTest",
429                     "addCrossProfileIntents", mProfileUserId);
430             runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileSharingTest",
431                     "startSwitchToOtherProfileIntent", mProfileUserId);
432 
433             // TODO(b/223178698): Investigate potential increase in latency
434             RunUtil.getDefault().sleep(30000);
435 
436             assertResolverActivityInForeground(mProfileUserId);
437         } finally {
438             pressHome();
439             runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileSharingTest",
440                     "clearCrossProfileIntents", mProfileUserId);
441         }
442     }
443 
444     @Test
testChooserActivityLaunchedFromPersonalProfileWithSelectedWorkTab()445     public void testChooserActivityLaunchedFromPersonalProfileWithSelectedWorkTab()
446             throws Exception {
447         installAppAsUser(SHARING_APP_1_APK, mPrimaryUserId);
448         installAppAsUser(SHARING_APP_2_APK, mPrimaryUserId);
449         installAppAsUser(SHARING_APP_1_APK, mProfileUserId);
450         installAppAsUser(SHARING_APP_2_APK, mProfileUserId);
451         try {
452             runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileSharingTest",
453                     "addCrossProfileIntents", mProfileUserId);
454             runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileSharingTest",
455                     "startSwitchToOtherProfileIntent_chooser", mPrimaryUserId);
456             assertChooserActivityInForeground(mPrimaryUserId);
457         } finally {
458             pressHome();
459             runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileSharingTest",
460                     "clearCrossProfileIntents", mProfileUserId);
461         }
462     }
463 
pressHome()464     private void pressHome() throws Exception {
465         executeShellCommand("input keyevent KEYCODE_HOME");
466     }
467 
assertChooserActivityInForeground(int userId)468     private void assertChooserActivityInForeground(int userId)
469             throws Exception {
470         try {
471             assertActivityInForeground("android/com.android.internal.app.ChooserActivity", userId);
472         } catch (AssertionError e) {
473             CLog.v("ChooserActivity is not the default: " + e);
474             assertActivityInForeground(resolveActivity("android.intent.action.CHOOSER"), userId);
475         }
476     }
477 
assertResolverActivityInForeground(int userId)478     private void assertResolverActivityInForeground(int userId)
479             throws Exception {
480         try {
481             assertActivityInForeground("android/com.android.internal.app.ResolverActivity", userId);
482         } catch (AssertionError e) {
483             CLog.v("ResolverActivity is not the default: " + e);
484             assertActivityInForeground(getCustomResolverActivity(), userId);
485         }
486     }
487 
assertActivityInForeground(String fullActivityName, int userId)488     private void assertActivityInForeground(String fullActivityName, int userId)
489             throws DeviceNotAvailableException {
490         final long deadline = System.nanoTime() + TimeUnit.SECONDS.toNanos(30);
491         while (System.nanoTime() <= deadline) {
492             String commandOutput = getDevice().executeShellCommand(
493                     "dumpsys activity activities | grep Resumed:");
494             if (commandOutput.contains("u" + userId + " " + fullActivityName)) {
495                 return;
496             }
497             try {
498                 RunUtil.getDefault().sleep(100);
499             } catch (RunInterruptedException e){
500                 e.printStackTrace();
501                 Thread.currentThread().interrupt();
502             }
503         }
504         fail("Activity " + fullActivityName + " didn't become foreground");
505     }
506 
changeUserRestrictionOrFail(String key, boolean value, int userId)507     private void changeUserRestrictionOrFail(String key, boolean value, int userId)
508             throws DeviceNotAvailableException {
509         changeUserRestrictionOrFail(key, value, userId, MANAGED_PROFILE_PKG);
510     }
511 
changeUserRestriction(String key, boolean value, int userId)512     private String changeUserRestriction(String key, boolean value, int userId)
513             throws DeviceNotAvailableException {
514         return changeUserRestriction(key, value, userId, MANAGED_PROFILE_PKG);
515     }
516 
resolveActivity(String action)517     private String resolveActivity(String action) throws Exception  {
518         // Template output of 'pm resolve-activity -a {action} --brief' :
519         // priority=0 preferredOrder=0 match=0x0 specificIndex=-1 isDefault=false
520         // com.bar/.foo or com.bar/com.bar.foo
521         final String[] outputs = getDevice().executeShellCommand(
522                     "pm resolve-activity -a " + action + " --brief").split("\n");
523 
524         assertTrue("Result of shell command: 'pm resolve-activity -a " + action
525                    + " --brief' is " + outputs[0], outputs.length >= 2);
526 
527         return outputs[1];
528     }
529 
getCustomResolverActivity()530     private String getCustomResolverActivity() throws Exception {
531         final String[] outputs = getDevice().executeShellCommand(
532                 "cmd overlay lookup android android:string/config_customResolverActivity")
533                 .split("\n");
534 
535         String customResolverActivity = resolveActivity("android.intent.action.SEND");
536         if (outputs != null && outputs.length >= 1 && outputs[0] != null && !outputs[0].isEmpty()) {
537             customResolverActivity = outputs[0];
538         }
539         return customResolverActivity;
540     }
541 }
542