1/*
2 * Copyright 2016, 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
17package com.android.managedprovisioning.ota;
18
19import static org.junit.Assert.assertEquals;
20import static org.junit.Assert.fail;
21import static org.mockito.Mockito.never;
22import static org.mockito.Mockito.verify;
23import static org.mockito.Mockito.when;
24
25import android.app.admin.DevicePolicyManager;
26import android.content.ComponentName;
27import android.content.Context;
28import android.content.pm.PackageManager;
29import android.content.pm.UserInfo;
30import android.os.UserHandle;
31import android.os.UserManager;
32import android.support.test.InstrumentationRegistry;
33import android.support.test.filters.SmallTest;
34import android.util.Pair;
35
36import com.android.managedprovisioning.task.AbstractProvisioningTask;
37import com.android.managedprovisioning.task.CrossProfileIntentFiltersSetter;
38import com.android.managedprovisioning.task.DeleteNonRequiredAppsTask;
39import com.android.managedprovisioning.task.DisableInstallShortcutListenersTask;
40import com.android.managedprovisioning.task.DisallowAddUserTask;
41import com.android.managedprovisioning.task.InstallExistingPackageTask;
42import com.android.managedprovisioning.task.MigrateSystemAppsSnapshotTask;
43
44import org.junit.Before;
45import org.junit.Test;
46import org.mockito.Mock;
47import org.mockito.MockitoAnnotations;
48
49import java.util.ArrayList;
50import java.util.Collections;
51import java.util.List;
52
53/**
54 * Unit tests for {@link OtaController}.
55 */
56@SmallTest
57public class OtaControllerTest {
58    private static final int DEVICE_OWNER_USER_ID = 12;
59    private static final int MANAGED_PROFILE_USER_ID = 15;
60    private static final int MANAGED_USER_USER_ID = 18;
61
62    private static final ComponentName ADMIN_COMPONENT = new ComponentName("com.test.admin",
63            ".AdminReceiver");
64
65    @Mock private Context mContext;
66    @Mock private DevicePolicyManager mDevicePolicyManager;
67    @Mock private PackageManager mPackageManager;
68    @Mock private UserManager mUserManager;
69    @Mock private CrossProfileIntentFiltersSetter mCrossProfileIntentFiltersSetter;
70
71    private TaskExecutor mTaskExecutor;
72    private OtaController mController;
73
74    private List<Pair<Integer, AbstractProvisioningTask>> mTasks = new ArrayList<>();
75    private List<UserInfo> mUsers = new ArrayList<>();
76    private List<UserInfo> mProfiles = new ArrayList<>();
77
78    @Before
79    public void setUp() {
80        MockitoAnnotations.initMocks(this);
81
82        when(mContext.getSystemService(Context.DEVICE_POLICY_SERVICE))
83                .thenReturn(mDevicePolicyManager);
84        when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
85        when(mContext.getPackageManager()).thenReturn(mPackageManager);
86        when(mContext.getResources())
87                .thenReturn(InstrumentationRegistry.getTargetContext().getResources());
88
89        when(mUserManager.getUsers()).thenReturn(mUsers);
90        when(mUserManager.getProfiles(UserHandle.USER_SYSTEM)).thenReturn(mProfiles);
91
92        mTaskExecutor = new FakeTaskExecutor();
93        mController = new OtaController(mContext, mTaskExecutor, mCrossProfileIntentFiltersSetter);
94
95        addSystemUser();
96    }
97
98    @Test
99    public void testDeviceOwnerSystemUser() {
100        // GIVEN that there is a device owner on the system user
101        setDeviceOwner(UserHandle.USER_SYSTEM, ADMIN_COMPONENT);
102
103        // WHEN running the OtaController
104        mController.run();
105
106        // THEN the task list should contain these tasks.
107        assertTaskList(
108                Pair.create(UserHandle.USER_SYSTEM, MigrateSystemAppsSnapshotTask.class),
109                Pair.create(UserHandle.USER_SYSTEM, DeleteNonRequiredAppsTask.class),
110                Pair.create(UserHandle.USER_SYSTEM, DisallowAddUserTask.class));
111
112        // THEN cross profile intent filters setter should be invoked for system user
113        verify(mCrossProfileIntentFiltersSetter).resetFilters(UserHandle.USER_SYSTEM);
114    }
115
116    @Test
117    public void testDeviceOwnerSeparate() {
118        // GIVEN that there is a device owner on a non-system meat user
119        addMeatUser(DEVICE_OWNER_USER_ID);
120        setDeviceOwner(DEVICE_OWNER_USER_ID, ADMIN_COMPONENT);
121
122        // WHEN running the OtaController
123        mController.run();
124
125        // THEN the task list should contain DeleteNonRequiredAppsTask and DisallowAddUserTask
126        assertTaskList(
127                Pair.create(UserHandle.USER_SYSTEM, MigrateSystemAppsSnapshotTask.class),
128                Pair.create(DEVICE_OWNER_USER_ID, DeleteNonRequiredAppsTask.class),
129                Pair.create(DEVICE_OWNER_USER_ID, DisallowAddUserTask.class));
130
131        // THEN cross profile intent filters setter should be invoked for both users
132        verify(mCrossProfileIntentFiltersSetter).resetFilters(UserHandle.USER_SYSTEM);
133        verify(mCrossProfileIntentFiltersSetter).resetFilters(DEVICE_OWNER_USER_ID);
134    }
135
136    @Test
137    public void testManagedProfile() {
138        // GIVEN that there is a managed profile
139        addManagedProfile(MANAGED_PROFILE_USER_ID, ADMIN_COMPONENT);
140
141        // WHEN running the OtaController
142        mController.run();
143
144        // THEN the task list should contain these tasks.
145        assertTaskList(
146                Pair.create(UserHandle.USER_SYSTEM, MigrateSystemAppsSnapshotTask.class),
147                Pair.create(MANAGED_PROFILE_USER_ID, InstallExistingPackageTask.class),
148                Pair.create(MANAGED_PROFILE_USER_ID, DisableInstallShortcutListenersTask.class),
149                Pair.create(MANAGED_PROFILE_USER_ID, DeleteNonRequiredAppsTask.class));
150
151        // THEN the cross profile intent filters should be reset
152        verify(mCrossProfileIntentFiltersSetter).resetFilters(UserHandle.USER_SYSTEM);
153        verify(mCrossProfileIntentFiltersSetter, never()).resetFilters(MANAGED_PROFILE_USER_ID);
154
155        // THEN the DISALLOW_WALLPAPER restriction should be set
156        verify(mUserManager).setUserRestriction(UserManager.DISALLOW_WALLPAPER, true,
157                UserHandle.of(MANAGED_PROFILE_USER_ID));
158    }
159
160    @Test
161    public void testManagedUser() {
162        // GIVEN that there is a managed profile
163        addManagedUser(MANAGED_USER_USER_ID, ADMIN_COMPONENT);
164
165        // WHEN running the OtaController
166        mController.run();
167
168        // THEN the task list should contain these tasks.
169        assertTaskList(
170                Pair.create(UserHandle.USER_SYSTEM, MigrateSystemAppsSnapshotTask.class),
171                Pair.create(MANAGED_USER_USER_ID, DeleteNonRequiredAppsTask.class));
172    }
173
174    private class FakeTaskExecutor extends TaskExecutor {
175
176        public FakeTaskExecutor() {
177            super();
178        }
179
180        @Override
181        public synchronized void execute(int userId, AbstractProvisioningTask task) {
182            mTasks.add(Pair.create(userId, task));
183        }
184    }
185
186    private void addMeatUser(int userId) {
187        UserInfo ui = new UserInfo(userId, null, 0);
188        mUsers.add(ui);
189        when(mUserManager.getProfiles(userId)).thenReturn(Collections.singletonList(ui));
190    }
191
192    private void setDeviceOwner(int userId, ComponentName admin) {
193        when(mDevicePolicyManager.getDeviceOwnerUserId()).thenReturn(userId);
194        when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn(admin);
195    }
196
197    private void addManagedProfile(int userId, ComponentName admin) {
198        UserInfo ui = new UserInfo(userId, null, UserInfo.FLAG_MANAGED_PROFILE);
199        mUsers.add(ui);
200        when(mDevicePolicyManager.getProfileOwnerAsUser(userId)).thenReturn(admin);
201        when(mUserManager.getProfiles(userId)).thenReturn(Collections.singletonList(ui));
202        mProfiles.add(ui);
203    }
204
205    private void addManagedUser(int userId, ComponentName admin) {
206        UserInfo ui = new UserInfo(userId, null, 0);
207        mUsers.add(ui);
208        when(mDevicePolicyManager.getProfileOwnerAsUser(userId)).thenReturn(admin);
209    }
210
211    private void addSystemUser() {
212        UserInfo ui = new UserInfo(UserHandle.USER_SYSTEM, null, UserInfo.FLAG_PRIMARY);
213        mUsers.add(ui);
214        mProfiles.add(ui);
215    }
216
217    private void assertTaskList(Pair<Integer, Class>... tasks) {
218        assertEquals(tasks.length, mTasks.size());
219
220        for (Pair<Integer, Class> task : tasks) {
221            assertTaskListContains(task.first, task.second);
222        }
223    }
224
225    private void assertTaskListContains(Integer userId, Class taskClass) {
226        for (Pair<Integer, AbstractProvisioningTask> task : mTasks) {
227            if (userId == task.first && taskClass.isInstance(task.second)) {
228                return;
229            }
230        }
231        fail("Task for class " + taskClass + " and userId " + userId + " not executed");
232    }
233}
234