1 /*
2  * Copyright (C) 2020 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.tests.atomicinstall;
18 
19 import static org.junit.Assert.fail;
20 
21 import android.Manifest;
22 import android.content.pm.PackageManager;
23 import android.platform.test.annotations.RequiresFlagsDisabled;
24 import android.platform.test.flag.junit.CheckFlagsRule;
25 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
26 
27 import androidx.test.InstrumentationRegistry;
28 
29 import com.android.compatibility.common.util.SystemUtil;
30 import com.android.cts.install.lib.Install;
31 import com.android.cts.install.lib.TestApp;
32 import com.android.cts.install.lib.Uninstall;
33 
34 import org.junit.After;
35 import org.junit.Before;
36 import org.junit.BeforeClass;
37 import org.junit.Rule;
38 import org.junit.Test;
39 import org.junit.runner.RunWith;
40 import org.junit.runners.JUnit4;
41 
42 /**
43  * Tests for package installation while Secure FRP mode is enabled.
44  *
45  * The test won't work once FRP hardening is done. On user build, the ground truth of FRP state
46  * can't be simply changed from shell.
47  */
48 @RunWith(JUnit4.class)
49 @RequiresFlagsDisabled(android.security.Flags.FLAG_FRP_ENFORCEMENT)
50 public class SecureFrpInstallTest {
51 
52     @Rule
53     public final CheckFlagsRule mCheckFlagsRule =
54             DeviceFlagsValueProvider.createCheckFlagsRule();
55 
56     private static PackageManager sPackageManager;
57 
adoptShellPermissions()58     private static void adoptShellPermissions() {
59         InstrumentationRegistry
60                 .getInstrumentation()
61                 .getUiAutomation()
62                 .adoptShellPermissionIdentity(
63                         Manifest.permission.INSTALL_PACKAGES, Manifest.permission.DELETE_PACKAGES);
64     }
65 
dropShellPermissions()66     private static void dropShellPermissions() {
67         InstrumentationRegistry
68                 .getInstrumentation()
69                 .getUiAutomation()
70                 .dropShellPermissionIdentity();
71     }
72 
setSecureFrp(boolean secureFrp)73     private static void setSecureFrp(boolean secureFrp) throws Exception {
74         adoptShellPermissions();
75         SystemUtil.runShellCommand(InstrumentationRegistry.getInstrumentation(),
76                 "settings put global secure_frp_mode " + (secureFrp ? "1" : "0"));
77         dropShellPermissions();
78     }
79 
assertInstalled()80     private static void assertInstalled() throws Exception {
81         sPackageManager.getPackageInfo(TestApp.A, PackageManager.PackageInfoFlags.of(0));
82     }
83 
assertNotInstalled()84     private static void assertNotInstalled() {
85         try {
86             sPackageManager.getPackageInfo(TestApp.A, PackageManager.PackageInfoFlags.of(0));
87             fail("Package should not be installed");
88         } catch (PackageManager.NameNotFoundException expected) {
89         }
90     }
91 
92     @BeforeClass
initialize()93     public static void initialize() {
94         sPackageManager = InstrumentationRegistry
95                 .getInstrumentation()
96                 .getContext()
97                 .getPackageManager();
98     }
99 
100     @Before
setup()101     public void setup() throws Exception {
102         adoptShellPermissions();
103         Uninstall.packages(TestApp.A);
104         dropShellPermissions();
105     }
106 
107     @After
teardown()108     public void teardown() throws Exception {
109         dropShellPermissions();
110         setSecureFrp(false);
111     }
112 
113     /** Tests a SecurityException is thrown while in secure FRP mode. */
114     @Test
testPackageInstallApi()115     public void testPackageInstallApi() throws Exception {
116         setSecureFrp(true);
117         try {
118             Install.single(TestApp.A1).commit();
119             fail("Expected a SecurityException");
120         } catch (SecurityException expected) {
121         }
122         assertNotInstalled();
123     }
124 
125     /** Tests can install when granted INSTALL_PACKAGES permission; even in secure FRP mode. */
126     @Test
testPackageInstallApiAsShell()127     public void testPackageInstallApiAsShell() throws Exception {
128         setSecureFrp(true);
129         adoptShellPermissions();
130         Install.single(TestApp.A1).commit();
131         dropShellPermissions();
132         assertInstalled();
133     }
134 }
135