1 /* 2 * Copyright (C) 2024 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 android.test.lib; 18 19 import android.test.productsharedlib.ProductSharedLib; 20 import android.test.systemextsharedlib.SystemExtSharedLib; 21 import android.test.systemsharedlib.SystemSharedLib; 22 import android.test.vendorsharedlib.VendorSharedLib; 23 24 import androidx.test.runner.AndroidJUnit4; 25 26 import org.junit.Test; 27 import org.junit.runner.RunWith; 28 29 @RunWith(AndroidJUnit4.class) 30 public abstract class AppTestCommon { 31 public enum AppLocation { DATA, SYSTEM, PRODUCT, VENDOR } 32 getAppLocation()33 public abstract AppLocation getAppLocation(); 34 35 // Loading private libs using absolute paths through shared libs should 36 // normally only depend on the location of the shared lib, so these tests 37 // are shared for all apps, regardless of location. 38 39 // Returns true when system private native libs are accessible directly from 40 // the app classloader namespace. systemPrivateLibsAccessibleFromAppNamespace()41 private boolean systemPrivateLibsAccessibleFromAppNamespace() { 42 // Currently it only works from system apps. It also works from product 43 // apps on old versions where they were treated like system apps. 44 return getAppLocation() == AppLocation.SYSTEM 45 || (getAppLocation() == AppLocation.PRODUCT && TestUtils.productAppsAreShared()); 46 } 47 48 // Detect exception when product private libs are accessible directly from 49 // the app classloader namespace even when they shouldn't be. productPrivateLibsAccessibleFromAppNamespace()50 private boolean productPrivateLibsAccessibleFromAppNamespace() { 51 // In old versions where product apps were treated like system apps, the 52 // product private libs were included in the system namespace, so 53 // they're accessible both from system and product apps. 54 return (getAppLocation() == AppLocation.SYSTEM || getAppLocation() == AppLocation.PRODUCT) 55 && TestUtils.productAppsAreShared(); 56 } 57 58 // Detect exception where we don't switch from a shared system namespace to 59 // a product or vendor "unbundled" namespace when calling into 60 // ProductSharedLib and VendorSharedLib. That means they still can load 61 // private system libs but not private libs in their own partition (however 62 // the latter works anyway when canLoadPrivateLibsFromSamePartition() is 63 // true). 64 // TODO(mast): Stop propagating the shared property (isBundledApp in 65 // LoadedApk.java) down to public and vendor shared java libs? noSwitchToVendorOrProductNamespace()66 private boolean noSwitchToVendorOrProductNamespace() { 67 // System apps get shared namespaces, and also product apps on old 68 // versions where they were treated like system apps. 69 return getAppLocation() == AppLocation.SYSTEM 70 || (getAppLocation() == AppLocation.PRODUCT && TestUtils.productAppsAreShared()); 71 } 72 73 @Test testLoadPrivateLibrariesViaSystemSharedLibWithAbsolutePaths()74 public void testLoadPrivateLibrariesViaSystemSharedLibWithAbsolutePaths() { 75 if (TestUtils.canLoadPrivateLibsFromSamePartition() 76 || systemPrivateLibsAccessibleFromAppNamespace()) { 77 SystemSharedLib.load(TestUtils.libPath("/system", "system_private7")); 78 SystemSharedLib.load(TestUtils.libPath("/system_ext", "systemext_private7")); 79 } else { 80 TestUtils.assertLibraryInaccessible(() -> { 81 SystemSharedLib.load(TestUtils.libPath("/system", "system_private7")); 82 }); 83 TestUtils.assertLibraryInaccessible(() -> { 84 SystemSharedLib.load(TestUtils.libPath("/system_ext", "systemext_private7")); 85 }); 86 } 87 88 if (productPrivateLibsAccessibleFromAppNamespace()) { 89 SystemSharedLib.load(TestUtils.libPath("/product", "product_private7")); 90 } else { 91 TestUtils.assertLibraryInaccessible(() -> { 92 SystemSharedLib.load(TestUtils.libPath("/product", "product_private7")); 93 }); 94 } 95 96 TestUtils.assertLibraryInaccessible( 97 () -> { SystemSharedLib.load(TestUtils.libPath("/vendor", "vendor_private7")); }); 98 } 99 100 @Test testLoadPrivateLibrariesViaSystemExtSharedLibWithAbsolutePaths()101 public void testLoadPrivateLibrariesViaSystemExtSharedLibWithAbsolutePaths() { 102 if (TestUtils.canLoadPrivateLibsFromSamePartition() 103 || systemPrivateLibsAccessibleFromAppNamespace()) { 104 SystemExtSharedLib.load(TestUtils.libPath("/system", "system_private8")); 105 SystemExtSharedLib.load(TestUtils.libPath("/system_ext", "systemext_private8")); 106 } else { 107 TestUtils.assertLibraryInaccessible(() -> { 108 SystemExtSharedLib.load(TestUtils.libPath("/system", "system_private8")); 109 }); 110 TestUtils.assertLibraryInaccessible(() -> { 111 SystemExtSharedLib.load(TestUtils.libPath("/system_ext", "systemext_private8")); 112 }); 113 } 114 115 if (productPrivateLibsAccessibleFromAppNamespace()) { 116 SystemExtSharedLib.load(TestUtils.libPath("/product", "product_private8")); 117 } else { 118 TestUtils.assertLibraryInaccessible(() -> { 119 SystemExtSharedLib.load(TestUtils.libPath("/product", "product_private8")); 120 }); 121 } 122 123 TestUtils.assertLibraryInaccessible(() -> { 124 SystemExtSharedLib.load(TestUtils.libPath("/vendor", "vendor_private8")); 125 }); 126 } 127 128 @Test testLoadPrivateLibrariesViaProductSharedLibWithAbsolutePaths()129 public void testLoadPrivateLibrariesViaProductSharedLibWithAbsolutePaths() { 130 if (systemPrivateLibsAccessibleFromAppNamespace() || noSwitchToVendorOrProductNamespace()) { 131 ProductSharedLib.load(TestUtils.libPath("/system", "system_private9")); 132 ProductSharedLib.load(TestUtils.libPath("/system_ext", "systemext_private9")); 133 } else { 134 TestUtils.assertLibraryInaccessible(() -> { 135 ProductSharedLib.load(TestUtils.libPath("/system", "system_private9")); 136 }); 137 TestUtils.assertLibraryInaccessible(() -> { 138 ProductSharedLib.load(TestUtils.libPath("/system_ext", "systemext_private9")); 139 }); 140 } 141 142 boolean loadPrivateProductLib; 143 if (TestUtils.productAppsAreShared()) { 144 // The library is accessible if the app is in either system or 145 // product, because both are loaded as system apps and private product 146 // libs are available for both. 147 loadPrivateProductLib = getAppLocation() == AppLocation.SYSTEM 148 || getAppLocation() == AppLocation.PRODUCT; 149 } else { 150 loadPrivateProductLib = TestUtils.canLoadPrivateLibsFromSamePartition() 151 || !noSwitchToVendorOrProductNamespace(); 152 } 153 if (loadPrivateProductLib) { 154 ProductSharedLib.load(TestUtils.libPath("/product", "product_private9")); 155 } else { 156 TestUtils.assertLibraryInaccessible(() -> { 157 ProductSharedLib.load(TestUtils.libPath("/product", "product_private9")); 158 }); 159 } 160 161 TestUtils.assertLibraryInaccessible( 162 () -> { ProductSharedLib.load(TestUtils.libPath("/vendor", "vendor_private9")); }); 163 } 164 165 @Test testLoadPrivateLibrariesViaVendorSharedLibWithAbsolutePaths()166 public void testLoadPrivateLibrariesViaVendorSharedLibWithAbsolutePaths() { 167 if (systemPrivateLibsAccessibleFromAppNamespace() || noSwitchToVendorOrProductNamespace()) { 168 VendorSharedLib.load(TestUtils.libPath("/system", "system_private10")); 169 VendorSharedLib.load(TestUtils.libPath("/system_ext", "systemext_private10")); 170 } else { 171 TestUtils.assertLibraryInaccessible(() -> { 172 VendorSharedLib.load(TestUtils.libPath("/system", "system_private10")); 173 }); 174 TestUtils.assertLibraryInaccessible(() -> { 175 VendorSharedLib.load(TestUtils.libPath("/system_ext", "systemext_private10")); 176 }); 177 } 178 179 if (productPrivateLibsAccessibleFromAppNamespace()) { 180 VendorSharedLib.load(TestUtils.libPath("/product", "product_private10")); 181 } else { 182 TestUtils.assertLibraryInaccessible(() -> { 183 VendorSharedLib.load(TestUtils.libPath("/product", "product_private10")); 184 }); 185 } 186 187 if (TestUtils.canLoadPrivateLibsFromSamePartition() 188 || !noSwitchToVendorOrProductNamespace()) { 189 VendorSharedLib.load(TestUtils.libPath("/vendor", "vendor_private10")); 190 } else { 191 TestUtils.assertLibraryInaccessible(() -> { 192 VendorSharedLib.load(TestUtils.libPath("/vendor", "vendor_private10")); 193 }); 194 } 195 } 196 } 197