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 */
16package com.android.server.devicepolicy;
17
18import com.android.server.LocalServices;
19import com.android.server.SystemService;
20import com.android.server.devicepolicy.DevicePolicyManagerServiceTestable.OwnersTestable;
21
22import android.app.admin.DevicePolicyManager;
23import android.app.admin.DevicePolicyManagerInternal;
24import android.content.pm.PackageManager;
25import android.content.pm.UserInfo;
26import android.os.Bundle;
27import android.os.UserHandle;
28import android.os.UserManager;
29import android.util.Pair;
30
31import org.mockito.invocation.InvocationOnMock;
32import org.mockito.stubbing.Answer;
33
34import java.io.File;
35import java.util.HashMap;
36import java.util.Map;
37
38import static org.mockito.Matchers.any;
39import static org.mockito.Matchers.anyInt;
40import static org.mockito.Matchers.eq;
41import static org.mockito.Mockito.doAnswer;
42import static org.mockito.Mockito.when;
43
44public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase {
45    private DpmMockContext mContext;
46
47    @Override
48    protected void setUp() throws Exception {
49        super.setUp();
50
51        mContext = getContext();
52
53        when(mContext.packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN)))
54                .thenReturn(true);
55    }
56
57    public void testMigration() throws Exception {
58        final File user10dir = mMockContext.addUser(10, 0);
59        final File user11dir = mMockContext.addUser(11, UserInfo.FLAG_MANAGED_PROFILE);
60        final File user12dir = mMockContext.addUser(12, 0);
61
62        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
63        setUpPackageManagerForAdmin(admin2, UserHandle.getUid(10, 123));
64        setUpPackageManagerForAdmin(admin3, UserHandle.getUid(11, 456));
65
66        // Create the legacy owners & policies file.
67        DpmTestUtils.writeToFile(
68                (new File(mContext.dataDir, OwnersTestable.LEGACY_FILE)).getAbsoluteFile(),
69                DpmTestUtils.readAsset(mRealTestContext,
70                        "DevicePolicyManagerServiceMigrationTest/legacy_device_owner.xml"));
71
72        DpmTestUtils.writeToFile(
73                (new File(mContext.systemUserDataDir, "device_policies.xml")).getAbsoluteFile(),
74                DpmTestUtils.readAsset(mRealTestContext,
75                        "DevicePolicyManagerServiceMigrationTest/legacy_device_policies.xml"));
76
77        DpmTestUtils.writeToFile(
78                (new File(user10dir, "device_policies.xml")).getAbsoluteFile(),
79                DpmTestUtils.readAsset(mRealTestContext,
80                        "DevicePolicyManagerServiceMigrationTest/legacy_device_policies_10.xml"));
81        DpmTestUtils.writeToFile(
82                (new File(user11dir, "device_policies.xml")).getAbsoluteFile(),
83                DpmTestUtils.readAsset(mRealTestContext,
84                        "DevicePolicyManagerServiceMigrationTest/legacy_device_policies_11.xml"));
85
86        // Set up UserManager
87        when(mMockContext.userManagerInternal.getBaseUserRestrictions(
88                eq(UserHandle.USER_SYSTEM))).thenReturn(DpmTestUtils.newRestrictions(
89                UserManager.DISALLOW_ADD_USER,
90                UserManager.DISALLOW_RECORD_AUDIO));
91
92        when(mMockContext.userManagerInternal.getBaseUserRestrictions(
93                eq(10))).thenReturn(DpmTestUtils.newRestrictions(
94                UserManager.DISALLOW_REMOVE_USER,
95                UserManager.DISALLOW_ADD_USER,
96                UserManager.DISALLOW_SMS,
97                UserManager.DISALLOW_OUTGOING_CALLS,
98                UserManager.DISALLOW_WALLPAPER,
99                UserManager.DISALLOW_RECORD_AUDIO));
100
101        when(mMockContext.userManagerInternal.getBaseUserRestrictions(
102                eq(11))).thenReturn(DpmTestUtils.newRestrictions(
103                UserManager.DISALLOW_REMOVE_USER,
104                UserManager.DISALLOW_ADD_USER,
105                UserManager.DISALLOW_SMS,
106                UserManager.DISALLOW_OUTGOING_CALLS,
107                UserManager.DISALLOW_WALLPAPER,
108                UserManager.DISALLOW_RECORD_AUDIO));
109
110        final Map<Integer, Bundle> newBaseRestrictions = new HashMap<>();
111
112        doAnswer(new Answer<Void>() {
113            @Override
114            public Void answer(InvocationOnMock invocation) throws Throwable {
115                Integer userId = (Integer) invocation.getArguments()[0];
116                Bundle bundle = (Bundle) invocation.getArguments()[1];
117
118                newBaseRestrictions.put(userId, bundle);
119
120                return null;
121            }
122        }).when(mContext.userManagerInternal).setBaseUserRestrictionsByDpmsForMigration(
123                anyInt(), any(Bundle.class));
124
125        // Initialize DPM/DPMS and let it migrate the persisted information.
126        // (Need clearCallingIdentity() to pass permission checks.)
127
128        final DevicePolicyManagerServiceTestable dpms;
129
130        final long ident = mContext.binder.clearCallingIdentity();
131        try {
132            LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
133
134            dpms = new DevicePolicyManagerServiceTestable(mContext, dataDir);
135
136            dpms.systemReady(SystemService.PHASE_LOCK_SETTINGS_READY);
137            dpms.systemReady(SystemService.PHASE_BOOT_COMPLETED);
138        } finally {
139            mContext.binder.restoreCallingIdentity(ident);
140        }
141
142        assertTrue(dpms.mOwners.hasDeviceOwner());
143        assertFalse(dpms.mOwners.hasProfileOwner(UserHandle.USER_SYSTEM));
144        assertTrue(dpms.mOwners.hasProfileOwner(10));
145        assertTrue(dpms.mOwners.hasProfileOwner(11));
146        assertFalse(dpms.mOwners.hasProfileOwner(12));
147
148        // Now all information should be migrated.
149        assertFalse(dpms.mOwners.getDeviceOwnerUserRestrictionsNeedsMigration());
150        assertFalse(dpms.mOwners.getProfileOwnerUserRestrictionsNeedsMigration(
151                UserHandle.USER_SYSTEM));
152        assertFalse(dpms.mOwners.getProfileOwnerUserRestrictionsNeedsMigration(10));
153        assertFalse(dpms.mOwners.getProfileOwnerUserRestrictionsNeedsMigration(11));
154        assertFalse(dpms.mOwners.getProfileOwnerUserRestrictionsNeedsMigration(12));
155
156        // Check the new base restrictions.
157        DpmTestUtils.assertRestrictions(
158                DpmTestUtils.newRestrictions(
159                        UserManager.DISALLOW_RECORD_AUDIO
160                ),
161                newBaseRestrictions.get(UserHandle.USER_SYSTEM));
162
163        DpmTestUtils.assertRestrictions(
164                DpmTestUtils.newRestrictions(
165                        UserManager.DISALLOW_ADD_USER,
166                        UserManager.DISALLOW_SMS,
167                        UserManager.DISALLOW_OUTGOING_CALLS,
168                        UserManager.DISALLOW_RECORD_AUDIO,
169                        UserManager.DISALLOW_WALLPAPER
170                ),
171                newBaseRestrictions.get(10));
172
173        DpmTestUtils.assertRestrictions(
174                DpmTestUtils.newRestrictions(
175                        UserManager.DISALLOW_ADD_USER,
176                        UserManager.DISALLOW_SMS,
177                        UserManager.DISALLOW_OUTGOING_CALLS,
178                        UserManager.DISALLOW_WALLPAPER,
179                        UserManager.DISALLOW_RECORD_AUDIO
180                ),
181                newBaseRestrictions.get(11));
182
183        // Check the new owner restrictions.
184        DpmTestUtils.assertRestrictions(
185                DpmTestUtils.newRestrictions(
186                        UserManager.DISALLOW_ADD_USER
187                ),
188                dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions());
189
190        DpmTestUtils.assertRestrictions(
191                DpmTestUtils.newRestrictions(
192                        UserManager.DISALLOW_REMOVE_USER
193                ),
194                dpms.getProfileOwnerAdminLocked(10).ensureUserRestrictions());
195
196        DpmTestUtils.assertRestrictions(
197                DpmTestUtils.newRestrictions(
198                        UserManager.DISALLOW_REMOVE_USER
199                ),
200                dpms.getProfileOwnerAdminLocked(11).ensureUserRestrictions());
201    }
202
203    public void testMigration2_profileOwnerOnUser0() throws Exception {
204        setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_SYSTEM_USER_UID);
205
206        // Create the legacy owners & policies file.
207        DpmTestUtils.writeToFile(
208                (new File(mContext.dataDir, OwnersTestable.LEGACY_FILE)).getAbsoluteFile(),
209                DpmTestUtils.readAsset(mRealTestContext,
210                        "DevicePolicyManagerServiceMigrationTest2/legacy_device_owner.xml"));
211
212        DpmTestUtils.writeToFile(
213                (new File(mContext.systemUserDataDir, "device_policies.xml")).getAbsoluteFile(),
214                DpmTestUtils.readAsset(mRealTestContext,
215                        "DevicePolicyManagerServiceMigrationTest2/legacy_device_policies.xml"));
216
217        // Set up UserManager
218        when(mMockContext.userManagerInternal.getBaseUserRestrictions(
219                eq(UserHandle.USER_SYSTEM))).thenReturn(DpmTestUtils.newRestrictions(
220                UserManager.DISALLOW_ADD_USER,
221                UserManager.DISALLOW_RECORD_AUDIO,
222                UserManager.DISALLOW_SMS,
223                UserManager.DISALLOW_OUTGOING_CALLS));
224
225        final Map<Integer, Bundle> newBaseRestrictions = new HashMap<>();
226
227        doAnswer(new Answer<Void>() {
228            @Override
229            public Void answer(InvocationOnMock invocation) throws Throwable {
230                Integer userId = (Integer) invocation.getArguments()[0];
231                Bundle bundle = (Bundle) invocation.getArguments()[1];
232
233                newBaseRestrictions.put(userId, bundle);
234
235                return null;
236            }
237        }).when(mContext.userManagerInternal).setBaseUserRestrictionsByDpmsForMigration(
238                anyInt(), any(Bundle.class));
239
240        // Initialize DPM/DPMS and let it migrate the persisted information.
241        // (Need clearCallingIdentity() to pass permission checks.)
242
243        final DevicePolicyManagerServiceTestable dpms;
244
245        final long ident = mContext.binder.clearCallingIdentity();
246        try {
247            LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
248
249            dpms = new DevicePolicyManagerServiceTestable(mContext, dataDir);
250
251            dpms.systemReady(SystemService.PHASE_LOCK_SETTINGS_READY);
252            dpms.systemReady(SystemService.PHASE_BOOT_COMPLETED);
253        } finally {
254            mContext.binder.restoreCallingIdentity(ident);
255        }
256        assertFalse(dpms.mOwners.hasDeviceOwner());
257        assertTrue(dpms.mOwners.hasProfileOwner(UserHandle.USER_SYSTEM));
258
259        // Now all information should be migrated.
260        assertFalse(dpms.mOwners.getDeviceOwnerUserRestrictionsNeedsMigration());
261        assertFalse(dpms.mOwners.getProfileOwnerUserRestrictionsNeedsMigration(
262                UserHandle.USER_SYSTEM));
263
264        // Check the new base restrictions.
265        DpmTestUtils.assertRestrictions(
266                DpmTestUtils.newRestrictions(
267                        UserManager.DISALLOW_RECORD_AUDIO
268                ),
269                newBaseRestrictions.get(UserHandle.USER_SYSTEM));
270
271        // Check the new owner restrictions.
272        DpmTestUtils.assertRestrictions(
273                DpmTestUtils.newRestrictions(
274                        UserManager.DISALLOW_ADD_USER,
275                        UserManager.DISALLOW_SMS,
276                        UserManager.DISALLOW_OUTGOING_CALLS
277                ),
278                dpms.getProfileOwnerAdminLocked(UserHandle.USER_SYSTEM).ensureUserRestrictions());
279    }
280}
281