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 "android/soong/android" 19 "android/soong/dexpreopt" 20 21 "github.com/google/blueprint" 22 "github.com/google/blueprint/proptools" 23) 24 25func init() { 26 registerSystemserverClasspathBuildComponents(android.InitRegistrationContext) 27 28 android.RegisterSdkMemberType(SystemServerClasspathFragmentSdkMemberType) 29} 30 31func registerSystemserverClasspathBuildComponents(ctx android.RegistrationContext) { 32 ctx.RegisterModuleType("platform_systemserverclasspath", platformSystemServerClasspathFactory) 33 ctx.RegisterModuleType("systemserverclasspath_fragment", systemServerClasspathFactory) 34 ctx.RegisterModuleType("prebuilt_systemserverclasspath_fragment", prebuiltSystemServerClasspathModuleFactory) 35} 36 37var SystemServerClasspathFragmentSdkMemberType = &systemServerClasspathFragmentMemberType{ 38 SdkMemberTypeBase: android.SdkMemberTypeBase{ 39 PropertyName: "systemserverclasspath_fragments", 40 SupportsSdk: true, 41 42 // Support for adding systemserverclasspath_fragments to the sdk snapshot was only added in 43 // Tiramisu. 44 SupportedBuildReleaseSpecification: "Tiramisu+", 45 }, 46} 47 48type platformSystemServerClasspathModule struct { 49 android.ModuleBase 50 51 ClasspathFragmentBase 52} 53 54func platformSystemServerClasspathFactory() android.Module { 55 m := &platformSystemServerClasspathModule{} 56 initClasspathFragment(m, SYSTEMSERVERCLASSPATH) 57 android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon) 58 return m 59} 60 61func (m *platformSystemServerClasspathModule) UniqueApexVariations() bool { 62 return true 63} 64 65func (p *platformSystemServerClasspathModule) AndroidMkEntries() (entries []android.AndroidMkEntries) { 66 return p.classpathFragmentBase().androidMkEntries() 67} 68 69func (p *platformSystemServerClasspathModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { 70 configuredJars := p.configuredJars(ctx) 71 classpathJars := configuredJarListToClasspathJars(ctx, configuredJars, p.classpathType) 72 standaloneConfiguredJars := p.standaloneConfiguredJars(ctx) 73 standaloneClasspathJars := configuredJarListToClasspathJars(ctx, standaloneConfiguredJars, STANDALONE_SYSTEMSERVER_JARS) 74 configuredJars = configuredJars.AppendList(&standaloneConfiguredJars) 75 classpathJars = append(classpathJars, standaloneClasspathJars...) 76 p.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, configuredJars, classpathJars) 77 p.classpathFragmentBase().installClasspathProto(ctx) 78} 79 80func (p *platformSystemServerClasspathModule) configuredJars(ctx android.ModuleContext) android.ConfiguredJarList { 81 // TODO(satayev): include any apex jars that don't populate their classpath proto config. 82 return dexpreopt.GetGlobalConfig(ctx).SystemServerJars 83} 84 85func (p *platformSystemServerClasspathModule) standaloneConfiguredJars(ctx android.ModuleContext) android.ConfiguredJarList { 86 return dexpreopt.GetGlobalConfig(ctx).StandaloneSystemServerJars 87} 88 89type SystemServerClasspathModule struct { 90 android.ModuleBase 91 android.ApexModuleBase 92 93 ClasspathFragmentBase 94 95 properties systemServerClasspathFragmentProperties 96} 97 98var _ android.ApexModule = (*SystemServerClasspathModule)(nil) 99 100func (m *SystemServerClasspathModule) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel { 101 return android.MinApiLevel 102} 103 104type systemServerClasspathFragmentProperties struct { 105 // List of system_server classpath jars, could be either java_library, or java_sdk_library. 106 // 107 // The order of this list matters as it is the order that is used in the SYSTEMSERVERCLASSPATH. 108 Contents proptools.Configurable[[]string] `android:"arch_variant"` 109 110 // List of jars that system_server loads dynamically using separate classloaders. 111 // 112 // The order does not matter. 113 Standalone_contents proptools.Configurable[[]string] `android:"arch_variant"` 114} 115 116func systemServerClasspathFactory() android.Module { 117 m := &SystemServerClasspathModule{} 118 m.AddProperties(&m.properties) 119 android.InitApexModule(m) 120 initClasspathFragment(m, SYSTEMSERVERCLASSPATH) 121 android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon) 122 return m 123} 124 125func (m *SystemServerClasspathModule) UniqueApexVariations() bool { 126 return true 127} 128 129func (s *SystemServerClasspathModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { 130 if len(s.properties.Contents.GetOrDefault(ctx, nil)) == 0 && len(s.properties.Standalone_contents.GetOrDefault(ctx, nil)) == 0 { 131 ctx.PropertyErrorf("contents", "Either contents or standalone_contents needs to be non-empty") 132 } 133 134 configuredJars := s.configuredJars(ctx) 135 classpathJars := configuredJarListToClasspathJars(ctx, configuredJars, s.classpathType) 136 standaloneConfiguredJars := s.standaloneConfiguredJars(ctx) 137 standaloneClasspathJars := configuredJarListToClasspathJars(ctx, standaloneConfiguredJars, STANDALONE_SYSTEMSERVER_JARS) 138 configuredJars = configuredJars.AppendList(&standaloneConfiguredJars) 139 classpathJars = append(classpathJars, standaloneClasspathJars...) 140 s.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, configuredJars, classpathJars) 141 s.setPartitionInfoOfLibraries(ctx) 142} 143 144// Map of java library name to their install partition. 145type LibraryNameToPartitionInfo struct { 146 LibraryNameToPartition map[string]string 147} 148 149// LibraryNameToPartitionInfoProvider will be used by the top-level apex to enforce that dexpreopt files 150// of apex system server jars are installed in the same partition as the top-level apex. 151var LibraryNameToPartitionInfoProvider = blueprint.NewProvider[LibraryNameToPartitionInfo]() 152 153func (s *SystemServerClasspathModule) setPartitionInfoOfLibraries(ctx android.ModuleContext) { 154 libraryNameToPartition := map[string]string{} 155 ctx.VisitDirectDepsWithTag(systemServerClasspathFragmentContentDepTag, func(m android.Module) { 156 libraryNameToPartition[m.Name()] = m.PartitionTag(ctx.DeviceConfig()) 157 }) 158 android.SetProvider(ctx, LibraryNameToPartitionInfoProvider, LibraryNameToPartitionInfo{ 159 LibraryNameToPartition: libraryNameToPartition, 160 }) 161} 162 163func (s *SystemServerClasspathModule) configuredJars(ctx android.ModuleContext) android.ConfiguredJarList { 164 global := dexpreopt.GetGlobalConfig(ctx) 165 166 possibleUpdatableModules := gatherPossibleApexModuleNamesAndStems(ctx, s.properties.Contents.GetOrDefault(ctx, nil), systemServerClasspathFragmentContentDepTag) 167 jars, unknown := global.ApexSystemServerJars.Filter(possibleUpdatableModules) 168 // TODO(satayev): remove geotz ssc_fragment, since geotz is not part of SSCP anymore. 169 _, unknown = android.RemoveFromList("geotz", unknown) 170 // This module only exists in car products. 171 // So ignore it even if it is not in PRODUCT_APEX_SYSTEM_SERVER_JARS. 172 // TODO(b/203233647): Add better mechanism to make it optional. 173 _, unknown = android.RemoveFromList("car-frameworks-service-module", unknown) 174 175 // This module is optional, so it is not present in all products. 176 // (See PRODUCT_ISOLATED_COMPILATION_ENABLED.) 177 // So ignore it even if it is not in PRODUCT_APEX_SYSTEM_SERVER_JARS. 178 // TODO(b/203233647): Add better mechanism to make it optional. 179 _, unknown = android.RemoveFromList("service-compos", unknown) 180 181 // TODO(satayev): for apex_test we want to include all contents unconditionally to classpaths 182 // config. However, any test specific jars would not be present in ApexSystemServerJars. Instead, 183 // we should check if we are creating a config for apex_test via ApexInfo and amend the values. 184 // This is an exception to support end-to-end test for ApexdUnitTests, until such support exists. 185 if android.InList("test_service-apexd", possibleUpdatableModules) { 186 jars = jars.Append("com.android.apex.test_package", "test_service-apexd") 187 } else if global.ApexSystemServerJars.Len() > 0 && len(unknown) > 0 { 188 // For non test apexes, make sure that all contents are actually declared in make. 189 ctx.ModuleErrorf("%s in contents must also be declared in PRODUCT_APEX_SYSTEM_SERVER_JARS", unknown) 190 } 191 192 return jars 193} 194 195func (s *SystemServerClasspathModule) standaloneConfiguredJars(ctx android.ModuleContext) android.ConfiguredJarList { 196 global := dexpreopt.GetGlobalConfig(ctx) 197 198 possibleUpdatableModules := gatherPossibleApexModuleNamesAndStems(ctx, s.properties.Standalone_contents.GetOrDefault(ctx, nil), systemServerClasspathFragmentContentDepTag) 199 jars, _ := global.ApexStandaloneSystemServerJars.Filter(possibleUpdatableModules) 200 201 // TODO(jiakaiz): add a check to ensure that the contents are declared in make. 202 203 return jars 204} 205 206type systemServerClasspathFragmentContentDependencyTag struct { 207 blueprint.BaseDependencyTag 208} 209 210// The systemserverclasspath_fragment contents must never depend on prebuilts. 211func (systemServerClasspathFragmentContentDependencyTag) ReplaceSourceWithPrebuilt() bool { 212 return false 213} 214 215// SdkMemberType causes dependencies added with this tag to be automatically added to the sdk as if 216// they were specified using java_systemserver_libs or java_sdk_libs. 217func (b systemServerClasspathFragmentContentDependencyTag) SdkMemberType(child android.Module) android.SdkMemberType { 218 // If the module is a java_sdk_library then treat it as if it was specified in the java_sdk_libs 219 // property, otherwise treat if it was specified in the java_systemserver_libs property. 220 if javaSdkLibrarySdkMemberType.IsInstance(child) { 221 return javaSdkLibrarySdkMemberType 222 } 223 224 return JavaSystemserverLibsSdkMemberType 225} 226 227func (b systemServerClasspathFragmentContentDependencyTag) ExportMember() bool { 228 return true 229} 230 231// Contents of system server fragments require files from prebuilt apex files. 232func (systemServerClasspathFragmentContentDependencyTag) RequiresFilesFromPrebuiltApex() {} 233 234var _ android.ReplaceSourceWithPrebuilt = systemServerClasspathFragmentContentDepTag 235var _ android.SdkMemberDependencyTag = systemServerClasspathFragmentContentDepTag 236var _ android.RequiresFilesFromPrebuiltApexTag = systemServerClasspathFragmentContentDepTag 237 238// The tag used for the dependency between the systemserverclasspath_fragment module and its contents. 239var systemServerClasspathFragmentContentDepTag = systemServerClasspathFragmentContentDependencyTag{} 240 241func IsSystemServerClasspathFragmentContentDepTag(tag blueprint.DependencyTag) bool { 242 return tag == systemServerClasspathFragmentContentDepTag 243} 244 245// The dexpreopt artifacts of apex system server jars are installed onto system image. 246func (s systemServerClasspathFragmentContentDependencyTag) InstallDepNeeded() bool { 247 return true 248} 249 250func (s *SystemServerClasspathModule) ComponentDepsMutator(ctx android.BottomUpMutatorContext) { 251 module := ctx.Module() 252 _, isSourceModule := module.(*SystemServerClasspathModule) 253 var deps []string 254 deps = append(deps, s.properties.Contents.GetOrDefault(ctx, nil)...) 255 deps = append(deps, s.properties.Standalone_contents.GetOrDefault(ctx, nil)...) 256 257 for _, name := range deps { 258 // A systemserverclasspath_fragment must depend only on other source modules, while the 259 // prebuilt_systemserverclasspath_fragment_fragment must only depend on other prebuilt modules. 260 if !isSourceModule { 261 name = android.PrebuiltNameFromSource(name) 262 } 263 ctx.AddDependency(module, systemServerClasspathFragmentContentDepTag, name) 264 } 265} 266 267// Collect information for opening IDE project files in java/jdeps.go. 268func (s *SystemServerClasspathModule) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) { 269 dpInfo.Deps = append(dpInfo.Deps, s.properties.Contents.GetOrDefault(ctx, nil)...) 270 dpInfo.Deps = append(dpInfo.Deps, s.properties.Standalone_contents.GetOrDefault(ctx, nil)...) 271} 272 273type systemServerClasspathFragmentMemberType struct { 274 android.SdkMemberTypeBase 275} 276 277func (s *systemServerClasspathFragmentMemberType) AddDependencies(ctx android.SdkDependencyContext, dependencyTag blueprint.DependencyTag, names []string) { 278 ctx.AddVariationDependencies(nil, dependencyTag, names...) 279} 280 281func (s *systemServerClasspathFragmentMemberType) IsInstance(module android.Module) bool { 282 _, ok := module.(*SystemServerClasspathModule) 283 return ok 284} 285 286func (s *systemServerClasspathFragmentMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule { 287 return ctx.SnapshotBuilder().AddPrebuiltModule(member, "prebuilt_systemserverclasspath_fragment") 288} 289 290func (s *systemServerClasspathFragmentMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties { 291 return &systemServerClasspathFragmentSdkMemberProperties{} 292} 293 294type systemServerClasspathFragmentSdkMemberProperties struct { 295 android.SdkMemberPropertiesBase 296 297 // List of system_server classpath jars, could be either java_library, or java_sdk_library. 298 // 299 // The order of this list matters as it is the order that is used in the SYSTEMSERVERCLASSPATH. 300 Contents []string 301 302 // List of jars that system_server loads dynamically using separate classloaders. 303 // 304 // The order does not matter. 305 Standalone_contents []string 306} 307 308func (s *systemServerClasspathFragmentSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { 309 module := variant.(*SystemServerClasspathModule) 310 311 s.Contents = module.properties.Contents.GetOrDefault(ctx.SdkModuleContext(), nil) 312 s.Standalone_contents = module.properties.Standalone_contents.GetOrDefault(ctx.SdkModuleContext(), nil) 313} 314 315func (s *systemServerClasspathFragmentSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) { 316 builder := ctx.SnapshotBuilder() 317 requiredMemberDependency := builder.SdkMemberReferencePropertyTag(true) 318 319 if len(s.Contents) > 0 { 320 propertySet.AddPropertyWithTag("contents", s.Contents, requiredMemberDependency) 321 } 322 323 if len(s.Standalone_contents) > 0 { 324 propertySet.AddPropertyWithTag("standalone_contents", s.Standalone_contents, requiredMemberDependency) 325 } 326} 327 328var _ android.SdkMemberType = (*systemServerClasspathFragmentMemberType)(nil) 329 330// A prebuilt version of the systemserverclasspath_fragment module. 331type prebuiltSystemServerClasspathModule struct { 332 SystemServerClasspathModule 333 prebuilt android.Prebuilt 334} 335 336func (module *prebuiltSystemServerClasspathModule) Prebuilt() *android.Prebuilt { 337 return &module.prebuilt 338} 339 340func (module *prebuiltSystemServerClasspathModule) Name() string { 341 return module.prebuilt.Name(module.ModuleBase.Name()) 342} 343 344func (module *prebuiltSystemServerClasspathModule) RequiredFilesFromPrebuiltApex(ctx android.BaseModuleContext) []string { 345 return nil 346} 347 348func (module *prebuiltSystemServerClasspathModule) UseProfileGuidedDexpreopt() bool { 349 return false 350} 351 352var _ android.RequiredFilesFromPrebuiltApex = (*prebuiltSystemServerClasspathModule)(nil) 353 354func prebuiltSystemServerClasspathModuleFactory() android.Module { 355 m := &prebuiltSystemServerClasspathModule{} 356 m.AddProperties(&m.properties) 357 // This doesn't actually have any prebuilt files of its own so pass a placeholder for the srcs 358 // array. 359 android.InitPrebuiltModule(m, &[]string{"placeholder"}) 360 android.InitApexModule(m) 361 android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon) 362 return m 363} 364