1// Copyright 2021 Google Inc. All rights reserved. 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 java 16 17import ( 18 "strings" 19 20 "github.com/google/blueprint" 21 22 "android/soong/android" 23 "android/soong/dexpreopt" 24 25 "github.com/google/blueprint/pathtools" 26) 27 28func init() { 29 RegisterDexpreoptCheckBuildComponents(android.InitRegistrationContext) 30} 31 32func RegisterDexpreoptCheckBuildComponents(ctx android.RegistrationContext) { 33 ctx.RegisterParallelSingletonModuleType("dexpreopt_systemserver_check", dexpreoptSystemserverCheckFactory) 34} 35 36// A build-time check to verify if all compilation artifacts of system server jars are installed 37// into the system image. When the check fails, it means that dexpreopting is not working for some 38// system server jars and needs to be fixed. 39// This singleton module generates a list of the paths to the artifacts based on 40// PRODUCT_SYSTEM_SERVER_JARS and PRODUCT_APEX_SYSTEM_SERVER_JARS, and passes it to Make via a 41// variable. Make will then do the actual check. 42// Currently, it only checks artifacts of modules defined in Soong. Artifacts of modules defined in 43// Makefile are generated by a script generated by dexpreopt_gen, and their existence is unknown to 44// Make and Ninja. 45type dexpreoptSystemserverCheck struct { 46 android.SingletonModuleBase 47 48 // The install paths to the compilation artifacts. 49 artifacts []string 50} 51 52func dexpreoptSystemserverCheckFactory() android.SingletonModule { 53 m := &dexpreoptSystemserverCheck{} 54 android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon) 55 return m 56} 57 58func getInstallPath(ctx android.ModuleContext, location string) android.InstallPath { 59 return android.PathForModuleInPartitionInstall( 60 ctx, "", strings.TrimPrefix(location, "/")) 61} 62 63type systemServerDependencyTag struct { 64 blueprint.BaseDependencyTag 65} 66 67// systemServerJarDepTag willl be used for validation. Skip visiblility. 68func (b systemServerDependencyTag) ExcludeFromVisibilityEnforcement() { 69} 70 71var ( 72 // dep tag for platform and apex system server jars 73 systemServerJarDepTag = systemServerDependencyTag{} 74) 75 76var _ android.ExcludeFromVisibilityEnforcementTag = systemServerJarDepTag 77 78// Add a depenendency on the system server jars. The dexpreopt files of those will be emitted to make. 79// The kati packaging system will verify that those files appear in installed files. 80// Adding the dependency allows the singleton module to determine whether an apex system server jar is system_ext specific. 81func (m *dexpreoptSystemserverCheck) DepsMutator(ctx android.BottomUpMutatorContext) { 82 global := dexpreopt.GetGlobalConfig(ctx) 83 targets := ctx.Config().Targets[android.Android] 84 85 // The check should be skipped on unbundled builds because system server jars are not preopted on 86 // unbundled builds since the artifacts are installed into the system image, not the APEXes. 87 if global.DisablePreopt || global.OnlyPreoptArtBootImage || len(targets) == 0 || ctx.Config().UnbundledBuild() { 88 return 89 } 90 91 ctx.AddDependency(ctx.Module(), systemServerJarDepTag, global.AllSystemServerJars(ctx).CopyOfJars()...) 92} 93 94func (m *dexpreoptSystemserverCheck) GenerateAndroidBuildActions(ctx android.ModuleContext) { 95 global := dexpreopt.GetGlobalConfig(ctx) 96 targets := ctx.Config().Targets[android.Android] 97 98 ctx.VisitDirectDepsWithTag(systemServerJarDepTag, func(systemServerJar android.Module) { 99 partition := "system" 100 if systemServerJar.InstallInSystemExt() && ctx.Config().InstallApexSystemServerDexpreoptSamePartition() { 101 partition = ctx.DeviceConfig().SystemExtPath() // system_ext 102 } 103 dexLocation := dexpreopt.GetSystemServerDexLocation(ctx, global, systemServerJar.Name()) 104 odexLocation := dexpreopt.ToOdexPath(dexLocation, targets[0].Arch.ArchType, partition) 105 odexPath := getInstallPath(ctx, odexLocation) 106 vdexPath := getInstallPath(ctx, pathtools.ReplaceExtension(odexLocation, "vdex")) 107 m.artifacts = append(m.artifacts, odexPath.String(), vdexPath.String()) 108 }) 109} 110 111func (m *dexpreoptSystemserverCheck) GenerateSingletonBuildActions(ctx android.SingletonContext) { 112} 113 114func (m *dexpreoptSystemserverCheck) MakeVars(ctx android.MakeVarsContext) { 115 ctx.Strict("DEXPREOPT_SYSTEMSERVER_ARTIFACTS", strings.Join(m.artifacts, " ")) 116} 117