1// Copyright (C) 2019 The Android Open Source Project 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package sysprop 16 17import ( 18 "os" 19 "strings" 20 "testing" 21 22 "android/soong/android" 23 "android/soong/cc" 24 "android/soong/java" 25 "android/soong/rust" 26 27 "github.com/google/blueprint/proptools" 28) 29 30func TestMain(m *testing.M) { 31 os.Exit(m.Run()) 32} 33 34func test(t *testing.T, bp string) *android.TestResult { 35 t.Helper() 36 37 bp += ` 38 cc_library { 39 name: "libbase", 40 host_supported: true, 41 } 42 43 cc_library_headers { 44 name: "libbase_headers", 45 vendor_available: true, 46 product_available: true, 47 recovery_available: true, 48 } 49 50 java_library { 51 name: "sysprop-library-stub-platform", 52 sdk_version: "core_current", 53 } 54 55 java_library { 56 name: "sysprop-library-stub-vendor", 57 soc_specific: true, 58 sdk_version: "core_current", 59 } 60 61 java_library { 62 name: "sysprop-library-stub-product", 63 product_specific: true, 64 sdk_version: "core_current", 65 } 66 67 rust_library { 68 name: "librustutils", 69 crate_name: "rustutils", 70 srcs: ["librustutils/lib.rs"], 71 product_available: true, 72 vendor_available: true, 73 min_sdk_version: "29", 74 } 75 76 rust_library { 77 name: "liblog_rust", 78 crate_name: "log", 79 srcs: ["log/src/lib.rs"], 80 product_available: true, 81 vendor_available: true, 82 min_sdk_version: "29", 83 } 84 ` 85 86 mockFS := android.MockFS{ 87 "a.java": nil, 88 "b.java": nil, 89 "c.java": nil, 90 "d.cpp": nil, 91 "api/sysprop-platform-current.txt": nil, 92 "api/sysprop-platform-latest.txt": nil, 93 "api/sysprop-platform-on-product-current.txt": nil, 94 "api/sysprop-platform-on-product-latest.txt": nil, 95 "api/sysprop-vendor-current.txt": nil, 96 "api/sysprop-vendor-latest.txt": nil, 97 "api/sysprop-vendor-on-product-current.txt": nil, 98 "api/sysprop-vendor-on-product-latest.txt": nil, 99 "api/sysprop-odm-current.txt": nil, 100 "api/sysprop-odm-latest.txt": nil, 101 "framework/aidl/a.aidl": nil, 102 103 // For framework-res, which is an implicit dependency for framework 104 "AndroidManifest.xml": nil, 105 "build/make/target/product/security/testkey": nil, 106 107 "build/soong/scripts/jar-wrapper.sh": nil, 108 109 "jdk8/jre/lib/jce.jar": nil, 110 "jdk8/jre/lib/rt.jar": nil, 111 "jdk8/lib/tools.jar": nil, 112 113 "bar-doc/a.java": nil, 114 "bar-doc/b.java": nil, 115 "bar-doc/IFoo.aidl": nil, 116 "bar-doc/known_oj_tags.txt": nil, 117 "external/doclava/templates-sdk": nil, 118 119 "cert/new_cert.x509.pem": nil, 120 "cert/new_cert.pk8": nil, 121 122 "android/sysprop/PlatformProperties.sysprop": nil, 123 "com/android/VendorProperties.sysprop": nil, 124 "com/android2/OdmProperties.sysprop": nil, 125 126 "librustutils/lib.rs": nil, 127 "log/src/lib.rs": nil, 128 } 129 130 result := android.GroupFixturePreparers( 131 cc.PrepareForTestWithCcDefaultModules, 132 java.PrepareForTestWithJavaDefaultModules, 133 rust.PrepareForTestWithRustDefaultModules, 134 PrepareForTestWithSyspropBuildComponents, 135 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 136 variables.DeviceSystemSdkVersions = []string{"28"} 137 variables.DeviceCurrentApiLevelForVendorModules = proptools.StringPtr("28") 138 }), 139 java.FixtureWithPrebuiltApis(map[string][]string{ 140 "28": {}, 141 "29": {}, 142 "30": {}, 143 }), 144 mockFS.AddToFixture(), 145 android.FixtureWithRootAndroidBp(bp), 146 ).RunTest(t) 147 148 return result 149} 150 151func TestSyspropLibrary(t *testing.T) { 152 result := test(t, ` 153 sysprop_library { 154 name: "sysprop-platform", 155 apex_available: ["//apex_available:platform"], 156 srcs: ["android/sysprop/PlatformProperties.sysprop"], 157 api_packages: ["android.sysprop"], 158 property_owner: "Platform", 159 vendor_available: true, 160 host_supported: true, 161 } 162 163 sysprop_library { 164 name: "sysprop-platform-on-product", 165 srcs: ["android/sysprop/PlatformProperties.sysprop"], 166 api_packages: ["android.sysprop"], 167 property_owner: "Platform", 168 product_specific: true, 169 } 170 171 sysprop_library { 172 name: "sysprop-vendor", 173 srcs: ["com/android/VendorProperties.sysprop"], 174 api_packages: ["com.android"], 175 property_owner: "Vendor", 176 vendor: true, 177 } 178 179 sysprop_library { 180 name: "sysprop-vendor-on-product", 181 srcs: ["com/android/VendorProperties.sysprop"], 182 api_packages: ["com.android"], 183 property_owner: "Vendor", 184 product_specific: true, 185 } 186 187 sysprop_library { 188 name: "sysprop-odm", 189 srcs: ["com/android2/OdmProperties.sysprop"], 190 api_packages: ["com.android2"], 191 property_owner: "Odm", 192 device_specific: true, 193 } 194 195 java_library { 196 name: "java-platform", 197 srcs: ["c.java"], 198 sdk_version: "system_current", 199 libs: ["sysprop-platform"], 200 } 201 202 java_library { 203 name: "java-platform-private", 204 srcs: ["c.java"], 205 platform_apis: true, 206 libs: ["sysprop-platform"], 207 } 208 209 java_library { 210 name: "java-product", 211 srcs: ["c.java"], 212 sdk_version: "system_current", 213 product_specific: true, 214 libs: ["sysprop-platform", "sysprop-vendor-on-product"], 215 } 216 217 java_library { 218 name: "java-vendor", 219 srcs: ["c.java"], 220 sdk_version: "system_current", 221 soc_specific: true, 222 libs: ["sysprop-platform", "sysprop-vendor"], 223 } 224 225 cc_library { 226 name: "cc-client-platform", 227 srcs: ["d.cpp"], 228 static_libs: ["libsysprop-platform"], 229 } 230 231 cc_library_static { 232 name: "cc-client-platform-static", 233 srcs: ["d.cpp"], 234 whole_static_libs: ["libsysprop-platform"], 235 } 236 237 cc_library { 238 name: "cc-client-product", 239 srcs: ["d.cpp"], 240 product_specific: true, 241 static_libs: ["libsysprop-platform-on-product", "libsysprop-vendor-on-product"], 242 } 243 244 cc_library { 245 name: "cc-client-vendor", 246 srcs: ["d.cpp"], 247 soc_specific: true, 248 static_libs: ["libsysprop-platform", "libsysprop-vendor"], 249 } 250 251 cc_binary_host { 252 name: "hostbin", 253 static_libs: ["libsysprop-platform"], 254 } 255 `) 256 257 // Check for generated cc_library 258 for _, variant := range []string{ 259 "android_vendor_arm_armv7-a-neon_shared", 260 "android_vendor_arm_armv7-a-neon_static", 261 "android_vendor_arm64_armv8-a_shared", 262 "android_vendor_arm64_armv8-a_static", 263 } { 264 result.ModuleForTests("libsysprop-platform", variant) 265 result.ModuleForTests("libsysprop-vendor", variant) 266 result.ModuleForTests("libsysprop-odm", variant) 267 } 268 269 // product variant of vendor-owned sysprop_library 270 for _, variant := range []string{ 271 "android_product_arm_armv7-a-neon_shared", 272 "android_product_arm_armv7-a-neon_static", 273 "android_product_arm64_armv8-a_shared", 274 "android_product_arm64_armv8-a_static", 275 } { 276 result.ModuleForTests("libsysprop-vendor-on-product", variant) 277 } 278 279 for _, variant := range []string{ 280 "android_arm_armv7-a-neon_shared", 281 "android_arm_armv7-a-neon_static", 282 "android_arm64_armv8-a_shared", 283 "android_arm64_armv8-a_static", 284 } { 285 library := result.ModuleForTests("libsysprop-platform", variant).Module().(*cc.Module) 286 expectedApexAvailableOnLibrary := []string{"//apex_available:platform"} 287 android.AssertDeepEquals(t, "apex available property on libsysprop-platform", expectedApexAvailableOnLibrary, library.ApexProperties.Apex_available) 288 } 289 290 result.ModuleForTests("sysprop-platform", "android_common") 291 result.ModuleForTests("sysprop-platform_public", "android_common") 292 result.ModuleForTests("sysprop-vendor", "android_common") 293 result.ModuleForTests("sysprop-vendor-on-product", "android_common") 294 295 // Check for exported includes 296 coreVariant := "android_arm64_armv8-a_static" 297 vendorVariant := "android_vendor_arm64_armv8-a_static" 298 productVariant := "android_product_arm64_armv8-a_static" 299 300 platformInternalPath := "libsysprop-platform/android_arm64_armv8-a_static/gen/sysprop/include" 301 platformPublicVendorPath := "libsysprop-platform/android_vendor_arm64_armv8-a_static/gen/sysprop/public/include" 302 303 platformOnProductPath := "libsysprop-platform-on-product/android_product_arm64_armv8-a_static/gen/sysprop/public/include" 304 305 vendorInternalPath := "libsysprop-vendor/android_vendor_arm64_armv8-a_static/gen/sysprop/include" 306 vendorOnProductPath := "libsysprop-vendor-on-product/android_product_arm64_armv8-a_static/gen/sysprop/public/include" 307 308 platformClient := result.ModuleForTests("cc-client-platform", coreVariant) 309 platformFlags := platformClient.Rule("cc").Args["cFlags"] 310 311 // platform should use platform's internal header 312 android.AssertStringDoesContain(t, "flags for platform", platformFlags, platformInternalPath) 313 314 platformStaticClient := result.ModuleForTests("cc-client-platform-static", coreVariant) 315 platformStaticFlags := platformStaticClient.Rule("cc").Args["cFlags"] 316 317 // platform-static should use platform's internal header 318 android.AssertStringDoesContain(t, "flags for platform-static", platformStaticFlags, platformInternalPath) 319 320 productClient := result.ModuleForTests("cc-client-product", productVariant) 321 productFlags := productClient.Rule("cc").Args["cFlags"] 322 323 // Product should use platform's and vendor's public headers 324 if !strings.Contains(productFlags, platformOnProductPath) || 325 !strings.Contains(productFlags, vendorOnProductPath) { 326 t.Errorf("flags for product must contain %#v and %#v, but was %#v.", 327 platformOnProductPath, vendorOnProductPath, productFlags) 328 } 329 330 vendorClient := result.ModuleForTests("cc-client-vendor", vendorVariant) 331 vendorFlags := vendorClient.Rule("cc").Args["cFlags"] 332 333 // Vendor should use platform's public header and vendor's internal header 334 if !strings.Contains(vendorFlags, platformPublicVendorPath) || 335 !strings.Contains(vendorFlags, vendorInternalPath) { 336 t.Errorf("flags for vendor must contain %#v and %#v, but was %#v.", 337 platformPublicVendorPath, vendorInternalPath, vendorFlags) 338 } 339 340 // Java modules linking against system API should use public stub 341 javaSystemApiClient := result.ModuleForTests("java-platform", "android_common").Rule("javac") 342 syspropPlatformPublic := result.ModuleForTests("sysprop-platform_public", "android_common").Description("for turbine") 343 if g, w := javaSystemApiClient.Implicits.Strings(), syspropPlatformPublic.Output.String(); !android.InList(w, g) { 344 t.Errorf("system api client should use public stub %q, got %q", w, g) 345 } 346} 347 348func TestApexAvailabilityIsForwarded(t *testing.T) { 349 result := test(t, ` 350 sysprop_library { 351 name: "sysprop-platform", 352 apex_available: ["//apex_available:platform"], 353 srcs: ["android/sysprop/PlatformProperties.sysprop"], 354 api_packages: ["android.sysprop"], 355 property_owner: "Platform", 356 } 357 `) 358 359 expected := []string{"//apex_available:platform"} 360 361 ccModule := result.ModuleForTests("libsysprop-platform", "android_arm64_armv8-a_shared").Module().(*cc.Module) 362 propFromCc := ccModule.ApexProperties.Apex_available 363 android.AssertDeepEquals(t, "apex_available forwarding to cc module", expected, propFromCc) 364 365 javaModule := result.ModuleForTests("sysprop-platform", "android_common").Module().(*java.Library) 366 propFromJava := javaModule.ApexProperties.Apex_available 367 android.AssertDeepEquals(t, "apex_available forwarding to java module", expected, propFromJava) 368 369 rustModule := result.ModuleForTests("libsysprop_platform_rust", "android_arm64_armv8-a_rlib_rlib-std").Module().(*rust.Module) 370 propFromRust := rustModule.ApexProperties.Apex_available 371 android.AssertDeepEquals(t, "apex_available forwarding to rust module", expected, propFromRust) 372} 373 374func TestMinSdkVersionIsForwarded(t *testing.T) { 375 result := test(t, ` 376 sysprop_library { 377 name: "sysprop-platform", 378 srcs: ["android/sysprop/PlatformProperties.sysprop"], 379 api_packages: ["android.sysprop"], 380 property_owner: "Platform", 381 cpp: { 382 min_sdk_version: "29", 383 }, 384 java: { 385 min_sdk_version: "30", 386 }, 387 rust: { 388 min_sdk_version: "29", 389 } 390 } 391 `) 392 393 ccModule := result.ModuleForTests("libsysprop-platform", "android_arm64_armv8-a_shared").Module().(*cc.Module) 394 propFromCc := proptools.String(ccModule.Properties.Min_sdk_version) 395 android.AssertStringEquals(t, "min_sdk_version forwarding to cc module", "29", propFromCc) 396 397 javaModule := result.ModuleForTests("sysprop-platform", "android_common").Module().(*java.Library) 398 propFromJava := javaModule.MinSdkVersionString() 399 android.AssertStringEquals(t, "min_sdk_version forwarding to java module", "30", propFromJava) 400 401 rustModule := result.ModuleForTests("libsysprop_platform_rust", "android_arm64_armv8-a_rlib_rlib-std").Module().(*rust.Module) 402 propFromRust := proptools.String(rustModule.Properties.Min_sdk_version) 403 android.AssertStringEquals(t, "min_sdk_version forwarding to rust module", "29", propFromRust) 404} 405