1 /*
2  * Copyright (C) 2018 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.server.om.hosttest;
17 
18 import static org.junit.Assert.assertEquals;
19 import static org.junit.Assert.assertFalse;
20 import static org.junit.Assert.assertTrue;
21 import static org.junit.Assert.fail;
22 
23 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
24 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
25 
26 import org.junit.After;
27 import org.junit.Before;
28 import org.junit.Test;
29 import org.junit.runner.RunWith;
30 
31 @RunWith(DeviceJUnit4ClassRunner.class)
32 public class InstallOverlayTests extends BaseHostJUnit4Test {
33     private static final String SIG_OVERLAY_PACKAGE_NAME =
34             "com.android.server.om.hosttest.signature_overlay";
35     private static final String APP_OVERLAY_PACKAGE_NAME =
36             "com.android.server.om.hosttest.app_overlay";
37     private static final String FRAMEWORK_OVERLAY_PACKAGE_NAME =
38             "com.android.server.om.hosttest.framework_overlay";
39     private static final String[] ALL_PACKAGES = new String[] {
40             SIG_OVERLAY_PACKAGE_NAME, APP_OVERLAY_PACKAGE_NAME, FRAMEWORK_OVERLAY_PACKAGE_NAME
41     };
42 
43     private static final String DEVICE_TEST_PKG =
44             "com.android.server.om.hosttest.update_overlay_test";
45     private static final String DEVICE_TEST_CLS = DEVICE_TEST_PKG + ".UpdateOverlayTest";
46 
47     @Before
ensureNoOverlays()48     public void ensureNoOverlays() throws Exception {
49         // Make sure we're starting with a clean slate.
50         for (String pkg : ALL_PACKAGES) {
51             assertFalse(pkg + " should not be installed", isPackageInstalled(pkg));
52             assertFalse(pkg + " should not be registered with overlay manager service",
53                     overlayManagerContainsPackage(pkg));
54         }
55     }
56 
57     /*
58     For some reason, SuiteApkInstaller is *not* uninstalling overlays, even though #installPackage()
59     claims it will auto-clean.
60     TODO(b/72877546): Remove when auto-clean is fixed.
61      */
62     @After
uninstallOverlays()63     public void uninstallOverlays() throws Exception {
64         for (String pkg : ALL_PACKAGES) {
65             uninstallPackage(pkg);
66         }
67     }
68 
69     @Test
failToInstallNonPlatformSignedOverlayTargetPreQ()70     public void failToInstallNonPlatformSignedOverlayTargetPreQ() throws Exception {
71         try {
72             installPackage("OverlayHostTests_NonPlatformSignatureOverlay.apk");
73             fail("installed a non-platform signed overlay with targetSdkVersion < Q");
74         } catch (Exception e) {
75             // Expected.
76         }
77         assertFalse(overlayManagerContainsPackage(SIG_OVERLAY_PACKAGE_NAME));
78     }
79 
80     @Test
installedIsStaticOverlayIsMutable()81     public void installedIsStaticOverlayIsMutable() throws Exception {
82         installPackage("OverlayHostTests_PlatformSignatureStaticOverlay.apk");
83         assertTrue(isOverlayMutable(SIG_OVERLAY_PACKAGE_NAME));
84     }
85 
86     @Test
installPlatformSignedOverlay()87     public void installPlatformSignedOverlay() throws Exception {
88         installPackage("OverlayHostTests_PlatformSignatureOverlay.apk");
89         assertTrue(overlayManagerContainsPackage(SIG_OVERLAY_PACKAGE_NAME));
90     }
91 
92     @Test
installPlatformSignedAppOverlayAndUpdate()93     public void installPlatformSignedAppOverlayAndUpdate() throws Exception {
94         assertTrue(runDeviceTests(DEVICE_TEST_PKG, DEVICE_TEST_CLS, "expectAppResource"));
95 
96         installPackage("OverlayHostTests_AppOverlayV1.apk");
97         setOverlayEnabled(APP_OVERLAY_PACKAGE_NAME, true);
98         assertTrue(overlayManagerContainsPackage(APP_OVERLAY_PACKAGE_NAME));
99         assertEquals("v1", getDevice()
100                 .getAppPackageInfo(APP_OVERLAY_PACKAGE_NAME)
101                 .getVersionName());
102         assertTrue(runDeviceTests(DEVICE_TEST_PKG, DEVICE_TEST_CLS,
103                 "expectAppOverlayV1Resource"));
104 
105         installPackage("OverlayHostTests_AppOverlayV2.apk");
106         assertTrue(overlayManagerContainsPackage(APP_OVERLAY_PACKAGE_NAME));
107         assertEquals("v2", getDevice()
108                 .getAppPackageInfo(APP_OVERLAY_PACKAGE_NAME)
109                 .getVersionName());
110         assertTrue(runDeviceTests(DEVICE_TEST_PKG, DEVICE_TEST_CLS,
111                 "expectAppOverlayV2Resource"));
112     }
113 
114     @Test
installPlatformSignedFrameworkOverlayAndUpdate()115     public void installPlatformSignedFrameworkOverlayAndUpdate() throws Exception {
116         assertTrue(runDeviceTests(DEVICE_TEST_PKG, DEVICE_TEST_CLS, "expectFrameworkResource"));
117 
118         installPackage("OverlayHostTests_FrameworkOverlayV1.apk");
119         setOverlayEnabled(FRAMEWORK_OVERLAY_PACKAGE_NAME, true);
120         assertTrue(overlayManagerContainsPackage(FRAMEWORK_OVERLAY_PACKAGE_NAME));
121         assertEquals("v1", getDevice()
122                 .getAppPackageInfo(FRAMEWORK_OVERLAY_PACKAGE_NAME)
123                 .getVersionName());
124         assertTrue(runDeviceTests(DEVICE_TEST_PKG, DEVICE_TEST_CLS,
125                 "expectFrameworkOverlayV1Resource"));
126 
127         installPackage("OverlayHostTests_FrameworkOverlayV2.apk");
128         assertTrue(overlayManagerContainsPackage(FRAMEWORK_OVERLAY_PACKAGE_NAME));
129         assertEquals("v2", getDevice()
130                 .getAppPackageInfo(FRAMEWORK_OVERLAY_PACKAGE_NAME)
131                 .getVersionName());
132         assertTrue(runDeviceTests(DEVICE_TEST_PKG, DEVICE_TEST_CLS,
133                 "expectFrameworkOverlayV2Resource"));
134     }
135 
136     @Test
enabledFrameworkOverlayMustAffectNewlyInstalledPackage()137     public void enabledFrameworkOverlayMustAffectNewlyInstalledPackage() throws Exception {
138         try {
139             setPackageEnabled(DEVICE_TEST_PKG, false);
140 
141             installPackage("OverlayHostTests_FrameworkOverlayV1.apk");
142             setOverlayEnabled(FRAMEWORK_OVERLAY_PACKAGE_NAME, true);
143             assertTrue(overlayManagerContainsPackage(FRAMEWORK_OVERLAY_PACKAGE_NAME));
144 
145             setPackageEnabled(DEVICE_TEST_PKG, true);
146             assertTrue(runDeviceTests(DEVICE_TEST_PKG, DEVICE_TEST_CLS,
147                     "expectFrameworkOverlayV1Resource"));
148         } finally {
149             setPackageEnabled(DEVICE_TEST_PKG, true);
150         }
151     }
152 
153     @Test
instantAppsNotVisibleToOMS()154     public void instantAppsNotVisibleToOMS() throws Exception {
155         installInstantPackage("OverlayHostTests_AppOverlayV1.apk");
156         assertFalse(overlayManagerContainsPackage(APP_OVERLAY_PACKAGE_NAME));
157         installConvertExistingInstantPackageToFull(APP_OVERLAY_PACKAGE_NAME);
158         assertTrue(overlayManagerContainsPackage(APP_OVERLAY_PACKAGE_NAME));
159     }
160 
161     @Test
changesPersistedWhenUninstallingDisabledOverlay()162     public void changesPersistedWhenUninstallingDisabledOverlay() throws Exception {
163         getDevice().enableAdbRoot();
164         assertFalse(getDevice().executeShellCommand("cat /data/system/overlays.xml")
165                 .contains(APP_OVERLAY_PACKAGE_NAME));
166         installPackage("OverlayHostTests_AppOverlayV1.apk");
167         assertTrue(getDevice().executeShellCommand("cat /data/system/overlays.xml")
168                 .contains(APP_OVERLAY_PACKAGE_NAME));
169         uninstallPackage(APP_OVERLAY_PACKAGE_NAME);
170         delay();
171         assertFalse(getDevice().executeShellCommand("cat /data/system/overlays.xml")
172                 .contains(APP_OVERLAY_PACKAGE_NAME));
173     }
174 
175     @Test
testAdbShellOMSInterface()176     public void testAdbShellOMSInterface() throws Exception {
177         installPackage("OverlayHostTests_AppOverlayV1.apk");
178         assertTrue(shell("cmd overlay list " + DEVICE_TEST_PKG).contains(DEVICE_TEST_PKG));
179         assertTrue(shell("cmd overlay list " + DEVICE_TEST_PKG).contains(APP_OVERLAY_PACKAGE_NAME));
180         assertEquals("[ ] " + APP_OVERLAY_PACKAGE_NAME,
181                 shell("cmd overlay list " + APP_OVERLAY_PACKAGE_NAME).trim());
182         assertEquals("STATE_DISABLED",
183                 shell("cmd overlay dump state " + APP_OVERLAY_PACKAGE_NAME).trim());
184 
185         setOverlayEnabled(APP_OVERLAY_PACKAGE_NAME, true);
186         assertEquals("[x] " + APP_OVERLAY_PACKAGE_NAME,
187                 shell("cmd overlay list " + APP_OVERLAY_PACKAGE_NAME).trim());
188         assertEquals("STATE_ENABLED",
189                 shell("cmd overlay dump state " + APP_OVERLAY_PACKAGE_NAME).trim());
190     }
191 
delay()192     private void delay() {
193         try {
194             Thread.sleep(1000);
195         } catch (InterruptedException e) {
196         }
197     }
198 
installPackage(String pkg)199     private void installPackage(String pkg) throws Exception {
200         super.installPackage(pkg);
201         delay();
202     }
203 
installInstantPackage(String pkg)204     private void installInstantPackage(String pkg) throws Exception {
205         super.installPackage(pkg, "--instant");
206         delay();
207     }
208 
installConvertExistingInstantPackageToFull(String pkg)209     private void installConvertExistingInstantPackageToFull(String pkg) throws Exception {
210         shell("cmd package install-existing --wait --full " + pkg);
211     }
212 
setPackageEnabled(String pkg, boolean enabled)213     private void setPackageEnabled(String pkg, boolean enabled) throws Exception {
214         shell("cmd package " + (enabled ? "enable " : "disable ") + pkg);
215         delay();
216     }
217 
setOverlayEnabled(String pkg, boolean enabled)218     private void setOverlayEnabled(String pkg, boolean enabled) throws Exception {
219         shell("cmd overlay " + (enabled ? "enable " : "disable ") + pkg);
220         delay();
221     }
222 
overlayManagerContainsPackage(String pkg)223     private boolean overlayManagerContainsPackage(String pkg) throws Exception {
224         return shell("cmd overlay list").contains(pkg);
225     }
226 
isOverlayMutable(String pkg)227     private boolean isOverlayMutable(String pkg) throws Exception {
228         return shell("cmd overlay dump ismutable " + pkg).contains("true");
229     }
230 
shell(final String cmd)231     private String shell(final String cmd) throws Exception {
232         return getDevice().executeShellCommand(cmd);
233     }
234 }
235