1 /*
2  * Copyright (C) 2019 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.server.om;
18 
19 import static android.content.om.OverlayInfo.STATE_DISABLED;
20 import static android.content.om.OverlayInfo.STATE_ENABLED;
21 import static android.content.om.OverlayInfo.STATE_MISSING_TARGET;
22 import static android.os.OverlayablePolicy.CONFIG_SIGNATURE;
23 
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.Assert.assertNotNull;
26 import static org.junit.Assert.assertNull;
27 import static org.junit.Assert.assertTrue;
28 import static org.testng.Assert.assertThrows;
29 
30 import android.content.om.OverlayIdentifier;
31 import android.content.om.OverlayInfo;
32 import android.content.pm.UserPackage;
33 
34 import androidx.test.runner.AndroidJUnit4;
35 
36 import org.junit.Test;
37 import org.junit.runner.RunWith;
38 
39 import java.util.List;
40 import java.util.Map;
41 import java.util.Optional;
42 import java.util.Set;
43 
44 @RunWith(AndroidJUnit4.class)
45 public class OverlayManagerServiceImplTests extends OverlayManagerServiceImplTestsBase {
46 
47     private static final String OVERLAY = "com.test.overlay";
48     private static final OverlayIdentifier IDENTIFIER = new OverlayIdentifier(OVERLAY);
49     private static final String TARGET = "com.test.target";
50     private static final int USER = 0;
51 
52     private static final String OVERLAY2 = OVERLAY + "2";
53     private static final String TARGET2 = TARGET + "2";
54     private static final OverlayIdentifier IDENTIFIER2 = new OverlayIdentifier(OVERLAY2);
55     private static final int USER2 = USER + 1;
56 
57     private static final String OVERLAY3 = OVERLAY + "3";
58     private static final OverlayIdentifier IDENTIFIER3 = new OverlayIdentifier(OVERLAY3);
59     private static final int USER3 = USER2 + 1;
60 
61     private static final String CONFIG_SIGNATURE_REFERENCE_PKG = "com.test.ref";
62     private static final String CERT_CONFIG_OK = "config_certificate_ok";
63     private static final String CERT_CONFIG_NOK = "config_certificate_nok";
64 
65     @Test
testGetOverlayInfo()66     public void testGetOverlayInfo() throws Exception {
67         installAndAssert(overlay(OVERLAY, TARGET), USER,
68                 Set.of(UserPackage.of(USER, OVERLAY), UserPackage.of(USER, TARGET)));
69 
70         final OverlayManagerServiceImpl impl = getImpl();
71         final OverlayInfo oi = impl.getOverlayInfo(IDENTIFIER, USER);
72         assertNotNull(oi);
73         assertEquals(oi.packageName, OVERLAY);
74         assertEquals(oi.targetPackageName, TARGET);
75         assertEquals(oi.userId, USER);
76     }
77 
78     @Test
testGetOverlayInfosForTarget()79     public void testGetOverlayInfosForTarget() throws Exception {
80         installAndAssert(overlay(OVERLAY, TARGET), USER,
81                 Set.of(UserPackage.of(USER, OVERLAY), UserPackage.of(USER, TARGET)));
82         installAndAssert(overlay(OVERLAY2, TARGET), USER,
83                 Set.of(UserPackage.of(USER, OVERLAY2), UserPackage.of(USER, TARGET)));
84         installAndAssert(overlay(OVERLAY3, TARGET), USER2,
85                 Set.of(UserPackage.of(USER2, OVERLAY3), UserPackage.of(USER2, TARGET)));
86 
87         final OverlayManagerServiceImpl impl = getImpl();
88         final List<OverlayInfo> ois = impl.getOverlayInfosForTarget(TARGET, USER);
89         assertEquals(ois.size(), 2);
90         assertTrue(ois.contains(impl.getOverlayInfo(IDENTIFIER, USER)));
91         assertTrue(ois.contains(impl.getOverlayInfo(IDENTIFIER2, USER)));
92 
93         final List<OverlayInfo> ois2 = impl.getOverlayInfosForTarget(TARGET, USER2);
94         assertEquals(ois2.size(), 1);
95         assertTrue(ois2.contains(impl.getOverlayInfo(IDENTIFIER3, USER2)));
96 
97         final List<OverlayInfo> ois3 = impl.getOverlayInfosForTarget(TARGET, USER3);
98         assertNotNull(ois3);
99         assertEquals(ois3.size(), 0);
100 
101         final List<OverlayInfo> ois4 = impl.getOverlayInfosForTarget("no.such.overlay", USER);
102         assertNotNull(ois4);
103         assertEquals(ois4.size(), 0);
104     }
105 
106     @Test
testGetOverlayInfosForUser()107     public void testGetOverlayInfosForUser() throws Exception {
108         installAndAssert(target(TARGET), USER,
109                 Set.of(UserPackage.of(USER, TARGET)));
110         installAndAssert(overlay(OVERLAY, TARGET), USER,
111                 Set.of(UserPackage.of(USER, OVERLAY), UserPackage.of(USER, TARGET)));
112         installAndAssert(overlay(OVERLAY2, TARGET), USER,
113                 Set.of(UserPackage.of(USER, OVERLAY2), UserPackage.of(USER, TARGET)));
114         installAndAssert(overlay(OVERLAY3, TARGET2), USER,
115                 Set.of(UserPackage.of(USER, OVERLAY3), UserPackage.of(USER, TARGET2)));
116 
117         final OverlayManagerServiceImpl impl = getImpl();
118         final Map<String, List<OverlayInfo>> everything = impl.getOverlaysForUser(USER);
119         assertEquals(everything.size(), 2);
120 
121         final List<OverlayInfo> ois = everything.get(TARGET);
122         assertNotNull(ois);
123         assertEquals(ois.size(), 2);
124         assertTrue(ois.contains(impl.getOverlayInfo(IDENTIFIER, USER)));
125         assertTrue(ois.contains(impl.getOverlayInfo(IDENTIFIER2, USER)));
126 
127         final List<OverlayInfo> ois2 = everything.get(TARGET2);
128         assertNotNull(ois2);
129         assertEquals(ois2.size(), 1);
130         assertTrue(ois2.contains(impl.getOverlayInfo(IDENTIFIER3, USER)));
131 
132         final Map<String, List<OverlayInfo>> everything2 = impl.getOverlaysForUser(USER2);
133         assertNotNull(everything2);
134         assertEquals(everything2.size(), 0);
135     }
136 
137     @Test
testPriority()138     public void testPriority() throws Exception {
139         installAndAssert(overlay(OVERLAY, TARGET), USER,
140                 Set.of(UserPackage.of(USER, OVERLAY), UserPackage.of(USER, TARGET)));
141         installAndAssert(overlay(OVERLAY2, TARGET), USER,
142                 Set.of(UserPackage.of(USER, OVERLAY2), UserPackage.of(USER, TARGET)));
143         installAndAssert(overlay(OVERLAY3, TARGET), USER,
144                 Set.of(UserPackage.of(USER, OVERLAY3), UserPackage.of(USER, TARGET)));
145 
146         final OverlayManagerServiceImpl impl = getImpl();
147         final OverlayInfo o1 = impl.getOverlayInfo(IDENTIFIER, USER);
148         final OverlayInfo o2 = impl.getOverlayInfo(IDENTIFIER2, USER);
149         final OverlayInfo o3 = impl.getOverlayInfo(IDENTIFIER3, USER);
150 
151         assertOverlayInfoForTarget(TARGET, USER, o1, o2, o3);
152 
153         assertEquals(impl.setLowestPriority(IDENTIFIER3, USER),
154                 Optional.of(UserPackage.of(USER, TARGET)));
155         assertOverlayInfoForTarget(TARGET, USER, o3, o1, o2);
156 
157         assertEquals(impl.setHighestPriority(IDENTIFIER3, USER),
158                 Set.of(UserPackage.of(USER, TARGET)));
159         assertOverlayInfoForTarget(TARGET, USER, o1, o2, o3);
160 
161         assertEquals(impl.setPriority(IDENTIFIER, IDENTIFIER2, USER),
162                 Optional.of(UserPackage.of(USER, TARGET)));
163         assertOverlayInfoForTarget(TARGET, USER, o2, o1, o3);
164     }
165 
166     @Test
testOverlayInfoStateTransitions()167     public void testOverlayInfoStateTransitions() throws Exception {
168         final OverlayManagerServiceImpl impl = getImpl();
169         assertNull(impl.getOverlayInfo(IDENTIFIER, USER));
170 
171         installAndAssert(overlay(OVERLAY, TARGET), USER,
172                 Set.of(UserPackage.of(USER, OVERLAY), UserPackage.of(USER, TARGET)));
173         assertState(STATE_MISSING_TARGET, IDENTIFIER, USER);
174 
175         installAndAssert(target(TARGET), USER,
176                 Set.of(UserPackage.of(USER, TARGET)));
177         assertState(STATE_DISABLED, IDENTIFIER, USER);
178 
179         assertEquals(impl.setEnabled(IDENTIFIER, true, USER),
180                 Set.of(UserPackage.of(USER, TARGET)));
181         assertState(STATE_ENABLED, IDENTIFIER, USER);
182 
183         // target upgrades do not change the state of the overlay
184         upgradeAndAssert(target(TARGET), USER,
185                 Set.of(UserPackage.of(USER, TARGET)),
186                 Set.of(UserPackage.of(USER, TARGET)));
187         assertState(STATE_ENABLED, IDENTIFIER, USER);
188 
189         uninstallAndAssert(TARGET, USER,
190                 Set.of(UserPackage.of(USER, TARGET)));
191         assertState(STATE_MISSING_TARGET, IDENTIFIER, USER);
192 
193         installAndAssert(target(TARGET), USER,
194                 Set.of(UserPackage.of(USER, TARGET)));
195         assertState(STATE_ENABLED, IDENTIFIER, USER);
196     }
197 
198     @Test
testOnOverlayPackageUpgraded()199     public void testOnOverlayPackageUpgraded() throws Exception {
200         installAndAssert(target(TARGET), USER,
201                 Set.of(UserPackage.of(USER, TARGET)));
202         installAndAssert(overlay(OVERLAY, TARGET), USER,
203                 Set.of(UserPackage.of(USER, OVERLAY), UserPackage.of(USER, TARGET)));
204         upgradeAndAssert(overlay(OVERLAY, TARGET), USER,
205                 Set.of(UserPackage.of(USER, TARGET)),
206                 Set.of(UserPackage.of(USER, TARGET)));
207 
208         // upgrade to a version where the overlay has changed its target
209         upgradeAndAssert(overlay(OVERLAY, TARGET2), USER,
210                 Set.of(UserPackage.of(USER, TARGET)),
211                 Set.of(UserPackage.of(USER, TARGET),
212                         UserPackage.of(USER, TARGET2)));
213     }
214 
215     @Test
testSetEnabledAtVariousConditions()216     public void testSetEnabledAtVariousConditions() throws Exception {
217         final OverlayManagerServiceImpl impl = getImpl();
218         assertThrows(OverlayManagerServiceImpl.OperationFailedException.class,
219                 () -> impl.setEnabled(IDENTIFIER, true, USER));
220 
221         // request succeeded, and there was a change that needs to be
222         // propagated to the rest of the system
223         installAndAssert(target(TARGET), USER,
224                 Set.of(UserPackage.of(USER, TARGET)));
225         installAndAssert(overlay(OVERLAY, TARGET), USER,
226                 Set.of(UserPackage.of(USER, OVERLAY), UserPackage.of(USER, TARGET)));
227         assertEquals(Set.of(UserPackage.of(USER, TARGET)),
228                 impl.setEnabled(IDENTIFIER, true, USER));
229 
230         // request succeeded, but nothing changed
231         assertEquals(Set.of(), impl.setEnabled(IDENTIFIER, true, USER));
232     }
233 
234     @Test
testConfigSignaturePolicyOk()235     public void testConfigSignaturePolicyOk() throws Exception {
236         setConfigSignaturePackageName(CONFIG_SIGNATURE_REFERENCE_PKG);
237         reinitializeImpl();
238 
239         addPackage(target(CONFIG_SIGNATURE_REFERENCE_PKG).setCertificate(CERT_CONFIG_OK), USER);
240         installAndAssert(target(TARGET), USER,
241                 Set.of(UserPackage.of(USER, TARGET)));
242         installAndAssert(overlay(OVERLAY, TARGET).setCertificate(CERT_CONFIG_OK), USER,
243                 Set.of(UserPackage.of(USER, OVERLAY), UserPackage.of(USER, TARGET)));
244 
245         final FakeIdmapDaemon idmapd = getIdmapd();
246         final FakeDeviceState state = getState();
247         final String overlayPath = state.select(OVERLAY, USER).apkPath;
248         assertTrue(idmapd.idmapExists(overlayPath, USER));
249 
250         final FakeIdmapDaemon.IdmapHeader idmap = idmapd.getIdmap(overlayPath);
251         assertEquals(CONFIG_SIGNATURE, CONFIG_SIGNATURE & idmap.policies);
252     }
253 
254     @Test
testConfigSignaturePolicyCertNok()255     public void testConfigSignaturePolicyCertNok() throws Exception {
256         setConfigSignaturePackageName(CONFIG_SIGNATURE_REFERENCE_PKG);
257         reinitializeImpl();
258 
259         addPackage(target(CONFIG_SIGNATURE_REFERENCE_PKG).setCertificate(CERT_CONFIG_OK), USER);
260         installAndAssert(target(TARGET), USER,
261                 Set.of(UserPackage.of(USER, TARGET)));
262         installAndAssert(overlay(OVERLAY, TARGET).setCertificate(CERT_CONFIG_NOK), USER,
263                 Set.of(UserPackage.of(USER, OVERLAY), UserPackage.of(USER, TARGET)));
264 
265         final FakeIdmapDaemon idmapd = getIdmapd();
266         final FakeDeviceState state = getState();
267         final String overlayPath = state.select(OVERLAY, USER).apkPath;
268         assertTrue(idmapd.idmapExists(overlayPath, USER));
269 
270         final FakeIdmapDaemon.IdmapHeader idmap = idmapd.getIdmap(overlayPath);
271         assertEquals(0, CONFIG_SIGNATURE & idmap.policies);
272     }
273 
274     @Test
testConfigSignaturePolicyNoConfig()275     public void testConfigSignaturePolicyNoConfig() throws Exception {
276         addPackage(target(CONFIG_SIGNATURE_REFERENCE_PKG).setCertificate(CERT_CONFIG_OK), USER);
277         installAndAssert(target(TARGET), USER,
278                 Set.of(UserPackage.of(USER, TARGET)));
279         installAndAssert(overlay(OVERLAY, TARGET).setCertificate(CERT_CONFIG_NOK), USER,
280                 Set.of(UserPackage.of(USER, OVERLAY), UserPackage.of(USER, TARGET)));
281 
282         final FakeIdmapDaemon idmapd = getIdmapd();
283         final FakeDeviceState state = getState();
284         final String overlayPath = state.select(OVERLAY, USER).apkPath;
285         assertTrue(idmapd.idmapExists(overlayPath, USER));
286 
287         final FakeIdmapDaemon.IdmapHeader idmap = idmapd.getIdmap(overlayPath);
288         assertEquals(0, CONFIG_SIGNATURE & idmap.policies);
289     }
290 
291     @Test
testConfigSignaturePolicyNoRefPkg()292     public void testConfigSignaturePolicyNoRefPkg() throws Exception {
293         installAndAssert(target(TARGET), USER,
294                 Set.of(UserPackage.of(USER, TARGET)));
295         installAndAssert(overlay(OVERLAY, TARGET).setCertificate(CERT_CONFIG_NOK), USER,
296                 Set.of(UserPackage.of(USER, OVERLAY), UserPackage.of(USER, TARGET)));
297 
298         final FakeIdmapDaemon idmapd = getIdmapd();
299         final FakeDeviceState state = getState();
300         final String overlayPath = state.select(OVERLAY, USER).apkPath;
301         assertTrue(idmapd.idmapExists(overlayPath, USER));
302 
303         final FakeIdmapDaemon.IdmapHeader idmap = idmapd.getIdmap(overlayPath);
304         assertEquals(0, CONFIG_SIGNATURE & idmap.policies);
305     }
306 
307     @Test
testConfigSignaturePolicyRefPkgNotSystem()308     public void testConfigSignaturePolicyRefPkgNotSystem() throws Exception {
309         setConfigSignaturePackageName(CONFIG_SIGNATURE_REFERENCE_PKG);
310         reinitializeImpl();
311 
312         addPackage(app(CONFIG_SIGNATURE_REFERENCE_PKG).setCertificate(CERT_CONFIG_OK), USER);
313         installAndAssert(target(TARGET), USER,
314                 Set.of(UserPackage.of(USER, TARGET)));
315         installAndAssert(overlay(OVERLAY, TARGET).setCertificate(CERT_CONFIG_NOK), USER,
316                 Set.of(UserPackage.of(USER, OVERLAY), UserPackage.of(USER, TARGET)));
317 
318         final FakeIdmapDaemon idmapd = getIdmapd();
319         final FakeDeviceState state = getState();
320         String overlayPath = state.select(OVERLAY, USER).apkPath;
321         assertTrue(idmapd.idmapExists(overlayPath, USER));
322 
323         FakeIdmapDaemon.IdmapHeader idmap = idmapd.getIdmap(overlayPath);
324         assertEquals(0, CONFIG_SIGNATURE & idmap.policies);
325     }
326 
327     @Test
testOnTargetSystemPackageUninstall()328     public void testOnTargetSystemPackageUninstall() throws Exception {
329         installAndAssert(target(TARGET), USER,
330                 Set.of(UserPackage.of(USER, TARGET)));
331         installAndAssert(overlay(OVERLAY, TARGET), USER,
332                 Set.of(UserPackage.of(USER, OVERLAY), UserPackage.of(USER, TARGET)));
333         upgradeAndAssert(target(TARGET), USER,
334                 Set.of(UserPackage.of(USER, TARGET)),
335                 Set.of(UserPackage.of(USER, TARGET)));
336 
337         downgradeAndAssert(target(TARGET), USER,
338                 Set.of(UserPackage.of(USER, TARGET)),
339                 Set.of(UserPackage.of(USER, TARGET)));
340     }
341 }
342