• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 package com.android.launcher3.ui;
17 
18 import static com.android.launcher3.LauncherPrefs.WORK_EDU_STEP;
19 import static com.android.launcher3.LauncherState.ALL_APPS;
20 import static com.android.launcher3.allapps.AllAppsStore.DEFER_UPDATES_TEST;
21 import static com.android.launcher3.util.TestUtil.installDummyAppForUser;
22 import static com.android.launcher3.util.rule.TestStabilityRule.LOCAL;
23 import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT;
24 
25 import static org.junit.Assert.assertEquals;
26 import static org.junit.Assert.assertTrue;
27 import static org.junit.Assume.assumeTrue;
28 
29 import android.os.Process;
30 import android.util.Log;
31 import android.view.View;
32 
33 import androidx.recyclerview.widget.RecyclerView.ViewHolder;
34 import androidx.test.ext.junit.runners.AndroidJUnit4;
35 import androidx.test.filters.LargeTest;
36 
37 import com.android.launcher3.Launcher;
38 import com.android.launcher3.LauncherPrefs;
39 import com.android.launcher3.R;
40 import com.android.launcher3.allapps.ActivityAllAppsContainerView;
41 import com.android.launcher3.allapps.AllAppsPagedView;
42 import com.android.launcher3.allapps.WorkEduCard;
43 import com.android.launcher3.allapps.WorkPausedCard;
44 import com.android.launcher3.allapps.WorkProfileManager;
45 import com.android.launcher3.util.BaseLauncherActivityTest;
46 import com.android.launcher3.util.TestUtil;
47 import com.android.launcher3.util.rule.ScreenRecordRule;
48 import com.android.launcher3.util.rule.TestStabilityRule;
49 import com.android.launcher3.util.rule.TestStabilityRule.Stability;
50 
51 import org.junit.After;
52 import org.junit.Before;
53 import org.junit.Rule;
54 import org.junit.Test;
55 import org.junit.runner.RunWith;
56 
57 import java.util.function.Predicate;
58 
59 @LargeTest
60 @RunWith(AndroidJUnit4.class)
61 public class WorkProfileTest extends BaseLauncherActivityTest<Launcher> {
62 
63     private static final int WORK_PAGE = ActivityAllAppsContainerView.AdapterHolder.WORK;
64     public static final int WAIT_TIME_MS = 30000;
65 
66     @Rule
67     public ScreenRecordRule mScreenRecordRule = new ScreenRecordRule();
68     @Rule
69     public TestStabilityRule mTestStabilityRule = new TestStabilityRule();
70 
71     private int mProfileUserId;
72     private boolean mWorkProfileSetupSuccessful;
73     private static final String TAG = "WorkProfileTest";
74 
75     @Before
setUp()76     public void setUp() throws Exception {
77         String output = executeShellCommand(String.format(
78                 "pm create-user --profileOf %d --managed TestProfile",
79                 Process.myUserHandle().getIdentifier()));
80         updateWorkProfileSetupSuccessful("pm create-user", output);
81 
82         String[] tokens = output.split("\\s+");
83         mProfileUserId = Integer.parseInt(tokens[tokens.length - 1]);
84         StringBuilder logStr = new StringBuilder().append("profileId: ").append(mProfileUserId);
85         for (String str : tokens) {
86             logStr.append(str).append("\n");
87         }
88         installDummyAppForUser(mProfileUserId);
89         updateWorkProfileSetupSuccessful("am start-user", output);
90 
91         if (!mWorkProfileSetupSuccessful) {
92             return; // no need to setup launcher since all tests will skip.
93         }
94 
95         loadLauncherSync();
96         goToState(ALL_APPS);
97         waitForState("Launcher internal state didn't switch to All Apps", () -> ALL_APPS);
98     }
99 
100     @After
removeWorkProfile()101     public void removeWorkProfile() throws Exception {
102         TestUtil.uninstallDummyApp();
103         executeShellCommand("pm remove-user --wait " + mProfileUserId);
104     }
105 
waitForWorkTabSetup()106     private void waitForWorkTabSetup() {
107         waitForLauncherCondition("Work tab not setup", launcher -> {
108             if (launcher.getAppsView().getContentView() instanceof AllAppsPagedView) {
109                 launcher.getAppsView().getAppsStore().enableDeferUpdates(DEFER_UPDATES_TEST);
110                 return true;
111             }
112             return false;
113         }, WAIT_TIME_MS);
114     }
115 
116     @Test
117     @com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord // b/325383911
workTabExists()118     public void workTabExists() {
119         assumeTrue(mWorkProfileSetupSuccessful);
120         waitForWorkTabSetup();
121         waitForLauncherCondition("Personal tab is missing",
122                 launcher -> launcher.getAppsView().isPersonalTabVisible(),
123                 WAIT_TIME_MS);
124         waitForLauncherCondition("Work tab is missing",
125                 launcher -> launcher.getAppsView().isWorkTabVisible(),
126                 WAIT_TIME_MS);
127     }
128 
129     // Staging; will be promoted to presubmit if stable
130     @Stability(flavors = LOCAL | PLATFORM_POSTSUBMIT)
131     @Test
toggleWorks()132     public void toggleWorks() {
133         assumeTrue(mWorkProfileSetupSuccessful);
134         waitForWorkTabSetup();
135         executeOnLauncher(launcher -> {
136             AllAppsPagedView pagedView = (AllAppsPagedView) launcher.getAppsView().getContentView();
137             pagedView.setCurrentPage(WORK_PAGE);
138         });
139 
140         WorkProfileManager manager = getFromLauncher(l -> l.getAppsView().getWorkManager());
141 
142         waitForLauncherCondition("work profile initial state check failed", launcher ->
143                         manager.getWorkUtilityView() != null
144                                 && manager.getCurrentState() == WorkProfileManager.STATE_ENABLED
145                                 && manager.getWorkUtilityView().isEnabled(),
146                 WAIT_TIME_MS);
147 
148         //start work profile toggle OFF test
149         executeOnLauncher(l -> {
150             // Ensure updates are not deferred so notification happens when apps pause.
151             l.getAppsView().getAppsStore().disableDeferUpdates(DEFER_UPDATES_TEST);
152             l.getAppsView().getWorkManager().getWorkUtilityView().getWorkFAB().performClick();
153         });
154 
155         waitForLauncherCondition("Work profile toggle OFF failed", launcher -> {
156             manager.reset(); // pulls current state from system
157             return manager.getCurrentState() == WorkProfileManager.STATE_DISABLED;
158         }, WAIT_TIME_MS);
159 
160         waitForWorkCard("Work paused card not shown", view -> view instanceof WorkPausedCard);
161 
162         // start work profile toggle ON test
163         executeOnLauncher(l -> {
164             ActivityAllAppsContainerView<?> allApps = l.getAppsView();
165             assertEquals("Work tab is not focused", allApps.getCurrentPage(), WORK_PAGE);
166             View workPausedCard = allApps.getActiveRecyclerView()
167                     .findViewHolderForAdapterPosition(0).itemView;
168             workPausedCard.findViewById(R.id.enable_work_apps).performClick();
169         });
170         waitForLauncherCondition("Work profile toggle ON failed", launcher -> {
171             manager.reset(); // pulls current state from system
172             return manager.getCurrentState() == WorkProfileManager.STATE_ENABLED;
173         }, WAIT_TIME_MS);
174 
175     }
176 
177     @Test
testEdu()178     public void testEdu() {
179         assumeTrue(mWorkProfileSetupSuccessful);
180         waitForWorkTabSetup();
181         executeOnLauncher(l -> {
182             LauncherPrefs.get(l).putSync(WORK_EDU_STEP.to(0));
183             ((AllAppsPagedView) l.getAppsView().getContentView()).setCurrentPage(WORK_PAGE);
184             l.getAppsView().getWorkManager().reset();
185         });
186 
187         waitForWorkCard("Work profile education not shown", view -> view instanceof WorkEduCard);
188     }
189 
waitForWorkCard(String message, Predicate<View> workCardCheck)190     private void waitForWorkCard(String message, Predicate<View> workCardCheck) {
191         waitForLauncherCondition(message, l -> {
192             l.getAppsView().getAppsStore().disableDeferUpdates(DEFER_UPDATES_TEST);
193             ViewHolder holder = l.getAppsView().getActiveRecyclerView()
194                     .findViewHolderForAdapterPosition(0);
195             try {
196                 return holder != null && workCardCheck.test(holder.itemView);
197             } finally {
198                 l.getAppsView().getAppsStore().enableDeferUpdates(DEFER_UPDATES_TEST);
199             }
200         }, WAIT_TIME_MS);
201     }
202 
updateWorkProfileSetupSuccessful(String cli, String output)203     private void updateWorkProfileSetupSuccessful(String cli, String output) {
204         Log.d(TAG, "updateWorkProfileSetupSuccessful, cli=" + cli + " " + "output=" + output);
205         if (output.startsWith("Success")) {
206             assertTrue(output, output.startsWith("Success"));
207             mWorkProfileSetupSuccessful = true;
208         } else {
209             mWorkProfileSetupSuccessful = false;
210         }
211     }
212 }
213