1// Copyright 2018 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 "errors" 19 "fmt" 20 "path" 21 "path/filepath" 22 "reflect" 23 "sort" 24 "strings" 25 "sync" 26 27 "github.com/google/blueprint" 28 "github.com/google/blueprint/proptools" 29 30 "android/soong/android" 31 "android/soong/dexpreopt" 32) 33 34// A tag to associated a dependency with a specific api scope. 35type scopeDependencyTag struct { 36 blueprint.BaseDependencyTag 37 name string 38 apiScope *apiScope 39 40 // Function for extracting appropriate path information from the dependency. 41 depInfoExtractor func(paths *scopePaths, ctx android.ModuleContext, dep android.Module) error 42} 43 44// Extract tag specific information from the dependency. 45func (tag scopeDependencyTag) extractDepInfo(ctx android.ModuleContext, dep android.Module, paths *scopePaths) { 46 err := tag.depInfoExtractor(paths, ctx, dep) 47 if err != nil { 48 ctx.ModuleErrorf("has an invalid {scopeDependencyTag: %s} dependency on module %s: %s", tag.name, ctx.OtherModuleName(dep), err.Error()) 49 } 50} 51 52var _ android.ReplaceSourceWithPrebuilt = (*scopeDependencyTag)(nil) 53 54func (tag scopeDependencyTag) ReplaceSourceWithPrebuilt() bool { 55 return false 56} 57 58// Provides information about an api scope, e.g. public, system, test. 59type apiScope struct { 60 // The name of the api scope, e.g. public, system, test 61 name string 62 63 // The api scope that this scope extends. 64 // 65 // This organizes the scopes into an extension hierarchy. 66 // 67 // If set this means that the API provided by this scope includes the API provided by the scope 68 // set in this field. 69 extends *apiScope 70 71 // The next api scope that a library that uses this scope can access. 72 // 73 // This organizes the scopes into an access hierarchy. 74 // 75 // If set this means that a library that can access this API can also access the API provided by 76 // the scope set in this field. 77 // 78 // A module that sets sdk_version: "<scope>_current" should have access to the <scope> API of 79 // every java_sdk_library that it depends on. If the library does not provide an API for <scope> 80 // then it will traverse up this access hierarchy to find an API that it does provide. 81 // 82 // If this is not set then it defaults to the scope set in extends. 83 canAccess *apiScope 84 85 // The legacy enabled status for a specific scope can be dependent on other 86 // properties that have been specified on the library so it is provided by 87 // a function that can determine the status by examining those properties. 88 legacyEnabledStatus func(module *SdkLibrary) bool 89 90 // The default enabled status for non-legacy behavior, which is triggered by 91 // explicitly enabling at least one api scope. 92 defaultEnabledStatus bool 93 94 // Gets a pointer to the scope specific properties. 95 scopeSpecificProperties func(module *SdkLibrary) *ApiScopeProperties 96 97 // The name of the field in the dynamically created structure. 98 fieldName string 99 100 // The name of the property in the java_sdk_library_import 101 propertyName string 102 103 // The tag to use to depend on the prebuilt stubs library module 104 prebuiltStubsTag scopeDependencyTag 105 106 // The tag to use to depend on the everything stubs library module. 107 everythingStubsTag scopeDependencyTag 108 109 // The tag to use to depend on the exportable stubs library module. 110 exportableStubsTag scopeDependencyTag 111 112 // The tag to use to depend on the stubs source module (if separate from the API module). 113 stubsSourceTag scopeDependencyTag 114 115 // The tag to use to depend on the stubs source and API module. 116 stubsSourceAndApiTag scopeDependencyTag 117 118 // The tag to use to depend on the module that provides the latest version of the API .txt file. 119 latestApiModuleTag scopeDependencyTag 120 121 // The tag to use to depend on the module that provides the latest version of the API removed.txt 122 // file. 123 latestRemovedApiModuleTag scopeDependencyTag 124 125 // The scope specific prefix to add to the api file base of "current.txt" or "removed.txt". 126 apiFilePrefix string 127 128 // The scope specific suffix to add to the sdk library module name to construct a scope specific 129 // module name. 130 moduleSuffix string 131 132 // SDK version that the stubs library is built against. Note that this is always 133 // *current. Older stubs library built with a numbered SDK version is created from 134 // the prebuilt jar. 135 sdkVersion string 136 137 // The annotation that identifies this API level, empty for the public API scope. 138 annotation string 139 140 // Extra arguments to pass to droidstubs for this scope. 141 // 142 // This is not used directly but is used to construct the droidstubsArgs. 143 extraArgs []string 144 145 // The args that must be passed to droidstubs to generate the API and stubs source 146 // for this scope, constructed dynamically by initApiScope(). 147 // 148 // The API only includes the additional members that this scope adds over the scope 149 // that it extends. 150 // 151 // The stubs source must include the definitions of everything that is in this 152 // api scope and all the scopes that this one extends. 153 droidstubsArgs []string 154 155 // Whether the api scope can be treated as unstable, and should skip compat checks. 156 unstable bool 157 158 // Represents the SDK kind of this scope. 159 kind android.SdkKind 160} 161 162// Initialize a scope, creating and adding appropriate dependency tags 163func initApiScope(scope *apiScope) *apiScope { 164 name := scope.name 165 scopeByName[name] = scope 166 allScopeNames = append(allScopeNames, name) 167 scope.propertyName = strings.ReplaceAll(name, "-", "_") 168 scope.fieldName = proptools.FieldNameForProperty(scope.propertyName) 169 scope.prebuiltStubsTag = scopeDependencyTag{ 170 name: name + "-stubs", 171 apiScope: scope, 172 depInfoExtractor: (*scopePaths).extractStubsLibraryInfoFromDependency, 173 } 174 scope.everythingStubsTag = scopeDependencyTag{ 175 name: name + "-stubs-everything", 176 apiScope: scope, 177 depInfoExtractor: (*scopePaths).extractEverythingStubsLibraryInfoFromDependency, 178 } 179 scope.exportableStubsTag = scopeDependencyTag{ 180 name: name + "-stubs-exportable", 181 apiScope: scope, 182 depInfoExtractor: (*scopePaths).extractExportableStubsLibraryInfoFromDependency, 183 } 184 scope.stubsSourceTag = scopeDependencyTag{ 185 name: name + "-stubs-source", 186 apiScope: scope, 187 depInfoExtractor: (*scopePaths).extractStubsSourceInfoFromDep, 188 } 189 scope.stubsSourceAndApiTag = scopeDependencyTag{ 190 name: name + "-stubs-source-and-api", 191 apiScope: scope, 192 depInfoExtractor: (*scopePaths).extractStubsSourceAndApiInfoFromApiStubsProvider, 193 } 194 scope.latestApiModuleTag = scopeDependencyTag{ 195 name: name + "-latest-api", 196 apiScope: scope, 197 depInfoExtractor: (*scopePaths).extractLatestApiPath, 198 } 199 scope.latestRemovedApiModuleTag = scopeDependencyTag{ 200 name: name + "-latest-removed-api", 201 apiScope: scope, 202 depInfoExtractor: (*scopePaths).extractLatestRemovedApiPath, 203 } 204 205 // To get the args needed to generate the stubs source append all the args from 206 // this scope and all the scopes it extends as each set of args adds additional 207 // members to the stubs. 208 var scopeSpecificArgs []string 209 if scope.annotation != "" { 210 scopeSpecificArgs = []string{"--show-annotation", scope.annotation} 211 } 212 for s := scope; s != nil; s = s.extends { 213 scopeSpecificArgs = append(scopeSpecificArgs, s.extraArgs...) 214 215 // Ensure that the generated stubs includes all the API elements from the API scope 216 // that this scope extends. 217 if s != scope && s.annotation != "" { 218 scopeSpecificArgs = append(scopeSpecificArgs, "--show-for-stub-purposes-annotation", s.annotation) 219 } 220 } 221 222 // By default, a library that can access a scope can also access the scope it extends. 223 if scope.canAccess == nil { 224 scope.canAccess = scope.extends 225 } 226 227 // Escape any special characters in the arguments. This is needed because droidstubs 228 // passes these directly to the shell command. 229 scope.droidstubsArgs = proptools.ShellEscapeList(scopeSpecificArgs) 230 231 return scope 232} 233 234func (scope *apiScope) stubsLibraryModuleNameSuffix() string { 235 return ".stubs" + scope.moduleSuffix 236} 237 238func (scope *apiScope) exportableStubsLibraryModuleNameSuffix() string { 239 return ".stubs.exportable" + scope.moduleSuffix 240} 241 242func (scope *apiScope) apiLibraryModuleName(baseName string) string { 243 return scope.stubsLibraryModuleName(baseName) + ".from-text" 244} 245 246func (scope *apiScope) sourceStubsLibraryModuleName(baseName string) string { 247 return scope.stubsLibraryModuleName(baseName) + ".from-source" 248} 249 250func (scope *apiScope) exportableSourceStubsLibraryModuleName(baseName string) string { 251 return scope.exportableStubsLibraryModuleName(baseName) + ".from-source" 252} 253 254func (scope *apiScope) stubsLibraryModuleName(baseName string) string { 255 return baseName + scope.stubsLibraryModuleNameSuffix() 256} 257 258func (scope *apiScope) exportableStubsLibraryModuleName(baseName string) string { 259 return baseName + scope.exportableStubsLibraryModuleNameSuffix() 260} 261 262func (scope *apiScope) stubsSourceModuleName(baseName string) string { 263 return baseName + ".stubs.source" + scope.moduleSuffix 264} 265 266func (scope *apiScope) String() string { 267 return scope.name 268} 269 270// snapshotRelativeDir returns the snapshot directory into which the files related to scopes will 271// be stored. 272func (scope *apiScope) snapshotRelativeDir() string { 273 return filepath.Join("sdk_library", scope.name) 274} 275 276// snapshotRelativeCurrentApiTxtPath returns the snapshot path to the API .txt file for the named 277// library. 278func (scope *apiScope) snapshotRelativeCurrentApiTxtPath(name string) string { 279 return filepath.Join(scope.snapshotRelativeDir(), name+".txt") 280} 281 282// snapshotRelativeRemovedApiTxtPath returns the snapshot path to the removed API .txt file for the 283// named library. 284func (scope *apiScope) snapshotRelativeRemovedApiTxtPath(name string) string { 285 return filepath.Join(scope.snapshotRelativeDir(), name+"-removed.txt") 286} 287 288type apiScopes []*apiScope 289 290func (scopes apiScopes) Strings(accessor func(*apiScope) string) []string { 291 var list []string 292 for _, scope := range scopes { 293 list = append(list, accessor(scope)) 294 } 295 return list 296} 297 298// Method that maps the apiScopes properties to the index of each apiScopes elements. 299// apiScopes property to be used as the key can be specified with the input accessor. 300// Only a string property of apiScope can be used as the key of the map. 301func (scopes apiScopes) MapToIndex(accessor func(*apiScope) string) map[string]int { 302 ret := make(map[string]int) 303 for i, scope := range scopes { 304 ret[accessor(scope)] = i 305 } 306 return ret 307} 308 309func (scopes apiScopes) ConvertStubsLibraryExportableToEverything(name string) string { 310 for _, scope := range scopes { 311 if strings.HasSuffix(name, scope.exportableStubsLibraryModuleNameSuffix()) { 312 return strings.TrimSuffix(name, scope.exportableStubsLibraryModuleNameSuffix()) + 313 scope.stubsLibraryModuleNameSuffix() 314 } 315 } 316 return name 317} 318 319var ( 320 scopeByName = make(map[string]*apiScope) 321 allScopeNames []string 322 apiScopePublic = initApiScope(&apiScope{ 323 name: "public", 324 325 // Public scope is enabled by default for both legacy and non-legacy modes. 326 legacyEnabledStatus: func(module *SdkLibrary) bool { 327 return true 328 }, 329 defaultEnabledStatus: true, 330 331 scopeSpecificProperties: func(module *SdkLibrary) *ApiScopeProperties { 332 return &module.sdkLibraryProperties.Public 333 }, 334 sdkVersion: "current", 335 kind: android.SdkPublic, 336 }) 337 apiScopeSystem = initApiScope(&apiScope{ 338 name: "system", 339 extends: apiScopePublic, 340 legacyEnabledStatus: (*SdkLibrary).generateTestAndSystemScopesByDefault, 341 scopeSpecificProperties: func(module *SdkLibrary) *ApiScopeProperties { 342 return &module.sdkLibraryProperties.System 343 }, 344 apiFilePrefix: "system-", 345 moduleSuffix: ".system", 346 sdkVersion: "system_current", 347 annotation: "android.annotation.SystemApi(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS)", 348 kind: android.SdkSystem, 349 }) 350 apiScopeTest = initApiScope(&apiScope{ 351 name: "test", 352 extends: apiScopeSystem, 353 legacyEnabledStatus: (*SdkLibrary).generateTestAndSystemScopesByDefault, 354 scopeSpecificProperties: func(module *SdkLibrary) *ApiScopeProperties { 355 return &module.sdkLibraryProperties.Test 356 }, 357 apiFilePrefix: "test-", 358 moduleSuffix: ".test", 359 sdkVersion: "test_current", 360 annotation: "android.annotation.TestApi", 361 unstable: true, 362 kind: android.SdkTest, 363 }) 364 apiScopeModuleLib = initApiScope(&apiScope{ 365 name: "module-lib", 366 extends: apiScopeSystem, 367 // The module-lib scope is disabled by default in legacy mode. 368 // 369 // Enabling this would break existing usages. 370 legacyEnabledStatus: func(module *SdkLibrary) bool { 371 return false 372 }, 373 scopeSpecificProperties: func(module *SdkLibrary) *ApiScopeProperties { 374 return &module.sdkLibraryProperties.Module_lib 375 }, 376 apiFilePrefix: "module-lib-", 377 moduleSuffix: ".module_lib", 378 sdkVersion: "module_current", 379 annotation: "android.annotation.SystemApi(client=android.annotation.SystemApi.Client.MODULE_LIBRARIES)", 380 kind: android.SdkModule, 381 }) 382 apiScopeSystemServer = initApiScope(&apiScope{ 383 name: "system-server", 384 extends: apiScopePublic, 385 386 // The system-server scope can access the module-lib scope. 387 // 388 // A module that provides a system-server API is appended to the standard bootclasspath that is 389 // used by the system server. So, it should be able to access module-lib APIs provided by 390 // libraries on the bootclasspath. 391 canAccess: apiScopeModuleLib, 392 393 // The system-server scope is disabled by default in legacy mode. 394 // 395 // Enabling this would break existing usages. 396 legacyEnabledStatus: func(module *SdkLibrary) bool { 397 return false 398 }, 399 scopeSpecificProperties: func(module *SdkLibrary) *ApiScopeProperties { 400 return &module.sdkLibraryProperties.System_server 401 }, 402 apiFilePrefix: "system-server-", 403 moduleSuffix: ".system_server", 404 sdkVersion: "system_server_current", 405 annotation: "android.annotation.SystemApi(client=android.annotation.SystemApi.Client.SYSTEM_SERVER)", 406 extraArgs: []string{ 407 "--hide-annotation", "android.annotation.Hide", 408 // com.android.* classes are okay in this interface" 409 "--hide", "InternalClasses", 410 }, 411 kind: android.SdkSystemServer, 412 }) 413 AllApiScopes = apiScopes{ 414 apiScopePublic, 415 apiScopeSystem, 416 apiScopeTest, 417 apiScopeModuleLib, 418 apiScopeSystemServer, 419 } 420 apiLibraryAdditionalProperties = map[string]string{ 421 "legacy.i18n.module.platform.api": "i18n.module.public.api.stubs.source.api.contribution", 422 "stable.i18n.module.platform.api": "i18n.module.public.api.stubs.source.api.contribution", 423 "conscrypt.module.platform.api": "conscrypt.module.public.api.stubs.source.api.contribution", 424 } 425) 426 427var ( 428 javaSdkLibrariesLock sync.Mutex 429) 430 431// TODO: these are big features that are currently missing 432// 1) disallowing linking to the runtime shared lib 433// 2) HTML generation 434 435func init() { 436 RegisterSdkLibraryBuildComponents(android.InitRegistrationContext) 437 438 android.RegisterMakeVarsProvider(pctx, func(ctx android.MakeVarsContext) { 439 javaSdkLibraries := javaSdkLibraries(ctx.Config()) 440 sort.Strings(*javaSdkLibraries) 441 ctx.Strict("JAVA_SDK_LIBRARIES", strings.Join(*javaSdkLibraries, " ")) 442 }) 443 444 // Register sdk member types. 445 android.RegisterSdkMemberType(javaSdkLibrarySdkMemberType) 446} 447 448func RegisterSdkLibraryBuildComponents(ctx android.RegistrationContext) { 449 ctx.RegisterModuleType("java_sdk_library", SdkLibraryFactory) 450 ctx.RegisterModuleType("java_sdk_library_import", sdkLibraryImportFactory) 451} 452 453// Properties associated with each api scope. 454type ApiScopeProperties struct { 455 // Indicates whether the api surface is generated. 456 // 457 // If this is set for any scope then all scopes must explicitly specify if they 458 // are enabled. This is to prevent new usages from depending on legacy behavior. 459 // 460 // Otherwise, if this is not set for any scope then the default behavior is 461 // scope specific so please refer to the scope specific property documentation. 462 Enabled *bool 463 464 // The sdk_version to use for building the stubs. 465 // 466 // If not specified then it will use an sdk_version determined as follows: 467 // 468 // 1) If the sdk_version specified on the java_sdk_library is none then this 469 // will be none. This is used for java_sdk_library instances that are used 470 // to create stubs that contribute to the core_current sdk version. 471 // 2) Otherwise, it is assumed that this library extends but does not 472 // contribute directly to a specific sdk_version and so this uses the 473 // sdk_version appropriate for the api scope. e.g. public will use 474 // sdk_version: current, system will use sdk_version: system_current, etc. 475 // 476 // This does not affect the sdk_version used for either generating the stubs source 477 // or the API file. They both have to use the same sdk_version as is used for 478 // compiling the implementation library. 479 Sdk_version *string 480 481 // Extra libs used when compiling stubs for this scope. 482 Libs []string 483} 484 485type sdkLibraryProperties struct { 486 // List of source files that are needed to compile the API, but are not part of runtime library. 487 Api_srcs []string `android:"arch_variant"` 488 489 // Visibility for impl library module. If not specified then defaults to the 490 // visibility property. 491 Impl_library_visibility []string 492 493 // Visibility for stubs library modules. If not specified then defaults to the 494 // visibility property. 495 Stubs_library_visibility []string 496 497 // Visibility for stubs source modules. If not specified then defaults to the 498 // visibility property. 499 Stubs_source_visibility []string 500 501 // List of Java libraries that will be in the classpath when building the implementation lib 502 Impl_only_libs []string `android:"arch_variant"` 503 504 // List of Java libraries that will included in the implementation lib. 505 Impl_only_static_libs []string `android:"arch_variant"` 506 507 // List of Java libraries that will be in the classpath when building stubs 508 Stub_only_libs []string `android:"arch_variant"` 509 510 // List of Java libraries that will included in stub libraries 511 Stub_only_static_libs []string `android:"arch_variant"` 512 513 // list of package names that will be documented and publicized as API. 514 // This allows the API to be restricted to a subset of the source files provided. 515 // If this is unspecified then all the source files will be treated as being part 516 // of the API. 517 Api_packages []string 518 519 // the relative path to the directory containing the api specification files. 520 // Defaults to "api". 521 Api_dir *string 522 523 // Determines whether a runtime implementation library is built; defaults to false. 524 // 525 // If true then it also prevents the module from being used as a shared module, i.e. 526 // it is as if shared_library: false, was set. 527 Api_only *bool 528 529 // local files that are used within user customized droiddoc options. 530 Droiddoc_option_files []string 531 532 // additional droiddoc options. 533 // Available variables for substitution: 534 // 535 // $(location <label>): the path to the droiddoc_option_files with name <label> 536 Droiddoc_options []string 537 538 // is set to true, Metalava will allow framework SDK to contain annotations. 539 Annotations_enabled *bool 540 541 // a list of top-level directories containing files to merge qualifier annotations 542 // (i.e. those intended to be included in the stubs written) from. 543 Merge_annotations_dirs []string 544 545 // a list of top-level directories containing Java stub files to merge show/hide annotations from. 546 Merge_inclusion_annotations_dirs []string 547 548 // If set to true then don't create dist rules. 549 No_dist *bool 550 551 // The stem for the artifacts that are copied to the dist, if not specified 552 // then defaults to the base module name. 553 // 554 // For each scope the following artifacts are copied to the apistubs/<scope> 555 // directory in the dist. 556 // * stubs impl jar -> <dist-stem>.jar 557 // * API specification file -> api/<dist-stem>.txt 558 // * Removed API specification file -> api/<dist-stem>-removed.txt 559 // 560 // Also used to construct the name of the filegroup (created by prebuilt_apis) 561 // that references the latest released API and remove API specification files. 562 // * API specification filegroup -> <dist-stem>.api.<scope>.latest 563 // * Removed API specification filegroup -> <dist-stem>-removed.api.<scope>.latest 564 // * API incompatibilities baseline filegroup -> <dist-stem>-incompatibilities.api.<scope>.latest 565 Dist_stem *string 566 567 // The subdirectory for the artifacts that are copied to the dist directory. If not specified 568 // then defaults to "unknown". Should be set to "android" for anything that should be published 569 // in the public Android SDK. 570 Dist_group *string 571 572 // A compatibility mode that allows historical API-tracking files to not exist. 573 // Do not use. 574 Unsafe_ignore_missing_latest_api bool 575 576 // indicates whether system and test apis should be generated. 577 Generate_system_and_test_apis bool `blueprint:"mutated"` 578 579 // The properties specific to the public api scope 580 // 581 // Unless explicitly specified by using public.enabled the public api scope is 582 // enabled by default in both legacy and non-legacy mode. 583 Public ApiScopeProperties 584 585 // The properties specific to the system api scope 586 // 587 // In legacy mode the system api scope is enabled by default when sdk_version 588 // is set to something other than "none". 589 // 590 // In non-legacy mode the system api scope is disabled by default. 591 System ApiScopeProperties 592 593 // The properties specific to the test api scope 594 // 595 // In legacy mode the test api scope is enabled by default when sdk_version 596 // is set to something other than "none". 597 // 598 // In non-legacy mode the test api scope is disabled by default. 599 Test ApiScopeProperties 600 601 // The properties specific to the module-lib api scope 602 // 603 // Unless explicitly specified by using module_lib.enabled the module_lib api 604 // scope is disabled by default. 605 Module_lib ApiScopeProperties 606 607 // The properties specific to the system-server api scope 608 // 609 // Unless explicitly specified by using system_server.enabled the 610 // system_server api scope is disabled by default. 611 System_server ApiScopeProperties 612 613 // Determines if the stubs are preferred over the implementation library 614 // for linking, even when the client doesn't specify sdk_version. When this 615 // is set to true, such clients are provided with the widest API surface that 616 // this lib provides. Note however that this option doesn't affect the clients 617 // that are in the same APEX as this library. In that case, the clients are 618 // always linked with the implementation library. Default is false. 619 Default_to_stubs *bool 620 621 // Properties related to api linting. 622 Api_lint struct { 623 // Enable api linting. 624 Enabled *bool 625 626 // If API lint is enabled, this flag controls whether a set of legitimate lint errors 627 // are turned off. The default is true. 628 Legacy_errors_allowed *bool 629 } 630 631 // a list of aconfig_declarations module names that the stubs generated in this module 632 // depend on. 633 Aconfig_declarations []string 634 635 // Determines if the module generates the stubs from the api signature files 636 // instead of the source Java files. Defaults to true. 637 Build_from_text_stub *bool 638 639 // TODO: determines whether to create HTML doc or not 640 // Html_doc *bool 641} 642 643// Paths to outputs from java_sdk_library and java_sdk_library_import. 644// 645// Fields that are android.Paths are always set (during GenerateAndroidBuildActions). 646// OptionalPaths are always set by java_sdk_library but may not be set by 647// java_sdk_library_import as not all instances provide that information. 648type scopePaths struct { 649 // The path (represented as Paths for convenience when returning) to the stubs header jar. 650 // 651 // That is the jar that is created by turbine. 652 stubsHeaderPath android.Paths 653 654 // The path (represented as Paths for convenience when returning) to the stubs implementation jar. 655 // 656 // This is not the implementation jar, it still only contains stubs. 657 stubsImplPath android.Paths 658 659 // The dex jar for the stubs. 660 // 661 // This is not the implementation jar, it still only contains stubs. 662 stubsDexJarPath OptionalDexJarPath 663 664 // The exportable dex jar for the stubs. 665 // This is not the implementation jar, it still only contains stubs. 666 // Includes unflagged apis and flagged apis enabled by release configurations. 667 exportableStubsDexJarPath OptionalDexJarPath 668 669 // The API specification file, e.g. system_current.txt. 670 currentApiFilePath android.OptionalPath 671 672 // The specification of API elements removed since the last release. 673 removedApiFilePath android.OptionalPath 674 675 // The stubs source jar. 676 stubsSrcJar android.OptionalPath 677 678 // Extracted annotations. 679 annotationsZip android.OptionalPath 680 681 // The path to the latest API file. 682 latestApiPaths android.Paths 683 684 // The path to the latest removed API file. 685 latestRemovedApiPaths android.Paths 686} 687 688func (paths *scopePaths) extractStubsLibraryInfoFromDependency(ctx android.ModuleContext, dep android.Module) error { 689 if lib, ok := android.OtherModuleProvider(ctx, dep, JavaInfoProvider); ok { 690 paths.stubsHeaderPath = lib.HeaderJars 691 paths.stubsImplPath = lib.ImplementationJars 692 693 libDep := dep.(UsesLibraryDependency) 694 paths.stubsDexJarPath = libDep.DexJarBuildPath(ctx) 695 paths.exportableStubsDexJarPath = libDep.DexJarBuildPath(ctx) 696 return nil 697 } else { 698 return fmt.Errorf("expected module that has JavaInfoProvider, e.g. java_library") 699 } 700} 701 702func (paths *scopePaths) extractEverythingStubsLibraryInfoFromDependency(ctx android.ModuleContext, dep android.Module) error { 703 if lib, ok := android.OtherModuleProvider(ctx, dep, JavaInfoProvider); ok { 704 paths.stubsHeaderPath = lib.HeaderJars 705 if !ctx.Config().ReleaseHiddenApiExportableStubs() { 706 paths.stubsImplPath = lib.ImplementationJars 707 } 708 709 libDep := dep.(UsesLibraryDependency) 710 paths.stubsDexJarPath = libDep.DexJarBuildPath(ctx) 711 return nil 712 } else { 713 return fmt.Errorf("expected module that has JavaInfoProvider, e.g. java_library") 714 } 715} 716 717func (paths *scopePaths) extractExportableStubsLibraryInfoFromDependency(ctx android.ModuleContext, dep android.Module) error { 718 if lib, ok := android.OtherModuleProvider(ctx, dep, JavaInfoProvider); ok { 719 if ctx.Config().ReleaseHiddenApiExportableStubs() { 720 paths.stubsImplPath = lib.ImplementationJars 721 } 722 723 libDep := dep.(UsesLibraryDependency) 724 paths.exportableStubsDexJarPath = libDep.DexJarBuildPath(ctx) 725 return nil 726 } else { 727 return fmt.Errorf("expected module that has JavaInfoProvider, e.g. java_library") 728 } 729} 730 731func (paths *scopePaths) treatDepAsApiStubsProvider(dep android.Module, action func(provider ApiStubsProvider) error) error { 732 if apiStubsProvider, ok := dep.(ApiStubsProvider); ok { 733 err := action(apiStubsProvider) 734 if err != nil { 735 return err 736 } 737 return nil 738 } else { 739 return fmt.Errorf("expected module that implements ExportableApiStubsSrcProvider, e.g. droidstubs") 740 } 741} 742 743func (paths *scopePaths) treatDepAsApiStubsSrcProvider(dep android.Module, action func(provider ApiStubsSrcProvider) error) error { 744 if apiStubsProvider, ok := dep.(ApiStubsSrcProvider); ok { 745 err := action(apiStubsProvider) 746 if err != nil { 747 return err 748 } 749 return nil 750 } else { 751 return fmt.Errorf("expected module that implements ApiStubsSrcProvider, e.g. droidstubs") 752 } 753} 754 755func (paths *scopePaths) extractApiInfoFromApiStubsProvider(provider ApiStubsProvider, stubsType StubsType) error { 756 var annotationsZip, currentApiFilePath, removedApiFilePath android.Path 757 annotationsZip, annotationsZipErr := provider.AnnotationsZip(stubsType) 758 currentApiFilePath, currentApiFilePathErr := provider.ApiFilePath(stubsType) 759 removedApiFilePath, removedApiFilePathErr := provider.RemovedApiFilePath(stubsType) 760 761 combinedError := errors.Join(annotationsZipErr, currentApiFilePathErr, removedApiFilePathErr) 762 763 if combinedError == nil { 764 paths.annotationsZip = android.OptionalPathForPath(annotationsZip) 765 paths.currentApiFilePath = android.OptionalPathForPath(currentApiFilePath) 766 paths.removedApiFilePath = android.OptionalPathForPath(removedApiFilePath) 767 } 768 return combinedError 769} 770 771func (paths *scopePaths) extractStubsSourceInfoFromApiStubsProviders(provider ApiStubsSrcProvider, stubsType StubsType) error { 772 stubsSrcJar, err := provider.StubsSrcJar(stubsType) 773 if err == nil { 774 paths.stubsSrcJar = android.OptionalPathForPath(stubsSrcJar) 775 } 776 return err 777} 778 779func (paths *scopePaths) extractStubsSourceInfoFromDep(ctx android.ModuleContext, dep android.Module) error { 780 stubsType := Everything 781 if ctx.Config().ReleaseHiddenApiExportableStubs() { 782 stubsType = Exportable 783 } 784 return paths.treatDepAsApiStubsSrcProvider(dep, func(provider ApiStubsSrcProvider) error { 785 return paths.extractStubsSourceInfoFromApiStubsProviders(provider, stubsType) 786 }) 787} 788 789func (paths *scopePaths) extractStubsSourceAndApiInfoFromApiStubsProvider(ctx android.ModuleContext, dep android.Module) error { 790 stubsType := Everything 791 if ctx.Config().ReleaseHiddenApiExportableStubs() { 792 stubsType = Exportable 793 } 794 return paths.treatDepAsApiStubsProvider(dep, func(provider ApiStubsProvider) error { 795 extractApiInfoErr := paths.extractApiInfoFromApiStubsProvider(provider, stubsType) 796 extractStubsSourceInfoErr := paths.extractStubsSourceInfoFromApiStubsProviders(provider, stubsType) 797 return errors.Join(extractApiInfoErr, extractStubsSourceInfoErr) 798 }) 799} 800 801func extractOutputPaths(dep android.Module) (android.Paths, error) { 802 var paths android.Paths 803 if sourceFileProducer, ok := dep.(android.SourceFileProducer); ok { 804 paths = sourceFileProducer.Srcs() 805 return paths, nil 806 } else { 807 return nil, fmt.Errorf("module %q does not produce source files", dep) 808 } 809} 810 811func (paths *scopePaths) extractLatestApiPath(ctx android.ModuleContext, dep android.Module) error { 812 outputPaths, err := extractOutputPaths(dep) 813 paths.latestApiPaths = outputPaths 814 return err 815} 816 817func (paths *scopePaths) extractLatestRemovedApiPath(ctx android.ModuleContext, dep android.Module) error { 818 outputPaths, err := extractOutputPaths(dep) 819 paths.latestRemovedApiPaths = outputPaths 820 return err 821} 822 823type commonToSdkLibraryAndImportProperties struct { 824 // Specifies whether this module can be used as an Android shared library; defaults 825 // to true. 826 // 827 // An Android shared library is one that can be referenced in a <uses-library> element 828 // in an AndroidManifest.xml. 829 Shared_library *bool 830 831 // Files containing information about supported java doc tags. 832 Doctag_files []string `android:"path"` 833 834 // Signals that this shared library is part of the bootclasspath starting 835 // on the version indicated in this attribute. 836 // 837 // This will make platforms at this level and above to ignore 838 // <uses-library> tags with this library name because the library is already 839 // available 840 On_bootclasspath_since *string 841 842 // Signals that this shared library was part of the bootclasspath before 843 // (but not including) the version indicated in this attribute. 844 // 845 // The system will automatically add a <uses-library> tag with this library to 846 // apps that target any SDK less than the version indicated in this attribute. 847 On_bootclasspath_before *string 848 849 // Indicates that PackageManager should ignore this shared library if the 850 // platform is below the version indicated in this attribute. 851 // 852 // This means that the device won't recognise this library as installed. 853 Min_device_sdk *string 854 855 // Indicates that PackageManager should ignore this shared library if the 856 // platform is above the version indicated in this attribute. 857 // 858 // This means that the device won't recognise this library as installed. 859 Max_device_sdk *string 860} 861 862// commonSdkLibraryAndImportModule defines the interface that must be provided by a module that 863// embeds the commonToSdkLibraryAndImport struct. 864type commonSdkLibraryAndImportModule interface { 865 android.Module 866 867 // Returns the name of the root java_sdk_library that creates the child stub libraries 868 // This is the `name` as it appears in Android.bp, and not the name in Soong's build graph 869 // (with the prebuilt_ prefix) 870 // 871 // e.g. in the following java_sdk_library_import 872 // java_sdk_library_import { 873 // name: "framework-foo.v1", 874 // source_module_name: "framework-foo", 875 // } 876 // the values returned by 877 // 1. Name(): prebuilt_framework-foo.v1 # unique 878 // 2. BaseModuleName(): framework-foo # the source 879 // 3. RootLibraryName: framework-foo.v1 # the undecordated `name` from Android.bp 880 RootLibraryName() string 881} 882 883func (m *SdkLibrary) RootLibraryName() string { 884 return m.BaseModuleName() 885} 886 887func (m *SdkLibraryImport) RootLibraryName() string { 888 // m.BaseModuleName refers to the source of the import 889 // use moduleBase.Name to get the name of the module as it appears in the .bp file 890 return m.ModuleBase.Name() 891} 892 893// Common code between sdk library and sdk library import 894type commonToSdkLibraryAndImport struct { 895 module commonSdkLibraryAndImportModule 896 897 scopePaths map[*apiScope]*scopePaths 898 899 commonSdkLibraryProperties commonToSdkLibraryAndImportProperties 900 901 // Paths to commonSdkLibraryProperties.Doctag_files 902 doctagPaths android.Paths 903 904 // Functionality related to this being used as a component of a java_sdk_library. 905 EmbeddableSdkLibraryComponent 906 907 // Path to the header jars of the implementation library 908 // This is non-empty only when api_only is false. 909 implLibraryHeaderJars android.Paths 910 911 // The reference to the implementation library created by the source module. 912 // Is nil if the source module does not exist. 913 implLibraryModule *Library 914} 915 916func (c *commonToSdkLibraryAndImport) initCommon(module commonSdkLibraryAndImportModule) { 917 c.module = module 918 919 module.AddProperties(&c.commonSdkLibraryProperties) 920 921 // Initialize this as an sdk library component. 922 c.initSdkLibraryComponent(module) 923} 924 925func (c *commonToSdkLibraryAndImport) initCommonAfterDefaultsApplied() bool { 926 namePtr := proptools.StringPtr(c.module.RootLibraryName()) 927 c.sdkLibraryComponentProperties.SdkLibraryName = namePtr 928 929 // Only track this sdk library if this can be used as a shared library. 930 if c.sharedLibrary() { 931 // Use the name specified in the module definition as the owner. 932 c.sdkLibraryComponentProperties.SdkLibraryToImplicitlyTrack = namePtr 933 } 934 935 return true 936} 937 938// uniqueApexVariations provides common implementation of the ApexModule.UniqueApexVariations 939// method. 940func (c *commonToSdkLibraryAndImport) uniqueApexVariations() bool { 941 // A java_sdk_library that is a shared library produces an XML file that makes the shared library 942 // usable from an AndroidManifest.xml's <uses-library> entry. That XML file contains the name of 943 // the APEX and so it needs a unique variation per APEX. 944 return c.sharedLibrary() 945} 946 947func (c *commonToSdkLibraryAndImport) generateCommonBuildActions(ctx android.ModuleContext) SdkLibraryInfo { 948 c.doctagPaths = android.PathsForModuleSrc(ctx, c.commonSdkLibraryProperties.Doctag_files) 949 950 everythingStubPaths := make(map[android.SdkKind]OptionalDexJarPath) 951 exportableStubPaths := make(map[android.SdkKind]OptionalDexJarPath) 952 removedApiFilePaths := make(map[android.SdkKind]android.OptionalPath) 953 for kind := android.SdkNone; kind <= android.SdkPrivate; kind += 1 { 954 everythingStubPath := makeUnsetDexJarPath() 955 exportableStubPath := makeUnsetDexJarPath() 956 removedApiFilePath := android.OptionalPath{} 957 if scopePath := c.findClosestScopePath(sdkKindToApiScope(kind)); scopePath != nil { 958 everythingStubPath = scopePath.stubsDexJarPath 959 exportableStubPath = scopePath.exportableStubsDexJarPath 960 removedApiFilePath = scopePath.removedApiFilePath 961 } 962 everythingStubPaths[kind] = everythingStubPath 963 exportableStubPaths[kind] = exportableStubPath 964 removedApiFilePaths[kind] = removedApiFilePath 965 } 966 967 return SdkLibraryInfo{ 968 EverythingStubDexJarPaths: everythingStubPaths, 969 ExportableStubDexJarPaths: exportableStubPaths, 970 RemovedTxtFiles: removedApiFilePaths, 971 SharedLibrary: c.sharedLibrary(), 972 } 973} 974 975// The component names for different outputs of the java_sdk_library. 976// 977// They are similar to the names used for the child modules it creates 978const ( 979 stubsSourceComponentName = "stubs.source" 980 981 apiTxtComponentName = "api.txt" 982 983 removedApiTxtComponentName = "removed-api.txt" 984 985 annotationsComponentName = "annotations.zip" 986) 987 988func (module *commonToSdkLibraryAndImport) setOutputFiles(ctx android.ModuleContext) { 989 if module.doctagPaths != nil { 990 ctx.SetOutputFiles(module.doctagPaths, ".doctags") 991 } 992 for _, scopeName := range android.SortedKeys(scopeByName) { 993 paths := module.findScopePaths(scopeByName[scopeName]) 994 if paths == nil { 995 continue 996 } 997 componentToOutput := map[string]android.OptionalPath{ 998 stubsSourceComponentName: paths.stubsSrcJar, 999 apiTxtComponentName: paths.currentApiFilePath, 1000 removedApiTxtComponentName: paths.removedApiFilePath, 1001 annotationsComponentName: paths.annotationsZip, 1002 } 1003 for _, component := range android.SortedKeys(componentToOutput) { 1004 if componentToOutput[component].Valid() { 1005 ctx.SetOutputFiles(android.Paths{componentToOutput[component].Path()}, "."+scopeName+"."+component) 1006 } 1007 } 1008 } 1009} 1010 1011func (c *commonToSdkLibraryAndImport) getScopePathsCreateIfNeeded(scope *apiScope) *scopePaths { 1012 if c.scopePaths == nil { 1013 c.scopePaths = make(map[*apiScope]*scopePaths) 1014 } 1015 paths := c.scopePaths[scope] 1016 if paths == nil { 1017 paths = &scopePaths{} 1018 c.scopePaths[scope] = paths 1019 } 1020 1021 return paths 1022} 1023 1024func (c *commonToSdkLibraryAndImport) findScopePaths(scope *apiScope) *scopePaths { 1025 if c.scopePaths == nil { 1026 return nil 1027 } 1028 1029 return c.scopePaths[scope] 1030} 1031 1032// If this does not support the requested api scope then find the closest available 1033// scope it does support. Returns nil if no such scope is available. 1034func (c *commonToSdkLibraryAndImport) findClosestScopePath(scope *apiScope) *scopePaths { 1035 for s := scope; s != nil; s = s.canAccess { 1036 if paths := c.findScopePaths(s); paths != nil { 1037 return paths 1038 } 1039 } 1040 1041 // This should never happen outside tests as public should be the base scope for every 1042 // scope and is enabled by default. 1043 return nil 1044} 1045 1046// sdkKindToApiScope maps from android.SdkKind to apiScope. 1047func sdkKindToApiScope(kind android.SdkKind) *apiScope { 1048 var apiScope *apiScope 1049 switch kind { 1050 case android.SdkSystem: 1051 apiScope = apiScopeSystem 1052 case android.SdkModule: 1053 apiScope = apiScopeModuleLib 1054 case android.SdkTest: 1055 apiScope = apiScopeTest 1056 case android.SdkSystemServer: 1057 apiScope = apiScopeSystemServer 1058 default: 1059 apiScope = apiScopePublic 1060 } 1061 return apiScope 1062} 1063 1064func (c *commonToSdkLibraryAndImport) sdkComponentPropertiesForChildLibrary() interface{} { 1065 componentProps := &struct { 1066 SdkLibraryName *string 1067 SdkLibraryToImplicitlyTrack *string 1068 }{} 1069 1070 namePtr := proptools.StringPtr(c.module.RootLibraryName()) 1071 componentProps.SdkLibraryName = namePtr 1072 1073 if c.sharedLibrary() { 1074 // Mark the stubs library as being components of this java_sdk_library so that 1075 // any app that includes code which depends (directly or indirectly) on the stubs 1076 // library will have the appropriate <uses-library> invocation inserted into its 1077 // manifest if necessary. 1078 componentProps.SdkLibraryToImplicitlyTrack = namePtr 1079 } 1080 1081 return componentProps 1082} 1083 1084func (c *commonToSdkLibraryAndImport) sharedLibrary() bool { 1085 return proptools.BoolDefault(c.commonSdkLibraryProperties.Shared_library, true) 1086} 1087 1088// Check if the stub libraries should be compiled for dex 1089func (c *commonToSdkLibraryAndImport) stubLibrariesCompiledForDex() bool { 1090 // Always compile the dex file files for the stub libraries if they will be used on the 1091 // bootclasspath. 1092 return !c.sharedLibrary() 1093} 1094 1095// Properties related to the use of a module as an component of a java_sdk_library. 1096type SdkLibraryComponentProperties struct { 1097 // The name of the java_sdk_library/_import module. 1098 SdkLibraryName *string `blueprint:"mutated"` 1099 1100 // The name of the java_sdk_library/_import to add to a <uses-library> entry 1101 // in the AndroidManifest.xml of any Android app that includes code that references 1102 // this module. If not set then no java_sdk_library/_import is tracked. 1103 SdkLibraryToImplicitlyTrack *string `blueprint:"mutated"` 1104} 1105 1106// Structure to be embedded in a module struct that needs to support the 1107// SdkLibraryComponentDependency interface. 1108type EmbeddableSdkLibraryComponent struct { 1109 sdkLibraryComponentProperties SdkLibraryComponentProperties 1110} 1111 1112func (e *EmbeddableSdkLibraryComponent) initSdkLibraryComponent(module android.Module) { 1113 module.AddProperties(&e.sdkLibraryComponentProperties) 1114} 1115 1116// to satisfy SdkLibraryComponentDependency 1117func (e *EmbeddableSdkLibraryComponent) SdkLibraryName() *string { 1118 return e.sdkLibraryComponentProperties.SdkLibraryName 1119} 1120 1121// to satisfy SdkLibraryComponentDependency 1122func (e *EmbeddableSdkLibraryComponent) OptionalSdkLibraryImplementation() *string { 1123 // For shared libraries, this is the same as the SDK library name. If a Java library or app 1124 // depends on a component library (e.g. a stub library) it still needs to know the name of the 1125 // run-time library and the corresponding module that provides the implementation. This name is 1126 // passed to manifest_fixer (to be added to AndroidManifest.xml) and added to CLC (to be used 1127 // in dexpreopt). 1128 // 1129 // For non-shared SDK (component or not) libraries this returns `nil`, as they are not 1130 // <uses-library> and should not be added to the manifest or to CLC. 1131 return e.sdkLibraryComponentProperties.SdkLibraryToImplicitlyTrack 1132} 1133 1134// Implemented by modules that are (or possibly could be) a component of a java_sdk_library 1135// (including the java_sdk_library) itself. 1136type SdkLibraryComponentDependency interface { 1137 UsesLibraryDependency 1138 1139 // SdkLibraryName returns the name of the java_sdk_library/_import module. 1140 SdkLibraryName() *string 1141 1142 // The name of the implementation library for the optional SDK library or nil, if there isn't one. 1143 OptionalSdkLibraryImplementation() *string 1144} 1145 1146// Make sure that all the module types that are components of java_sdk_library/_import 1147// and which can be referenced (directly or indirectly) from an android app implement 1148// the SdkLibraryComponentDependency interface. 1149var _ SdkLibraryComponentDependency = (*Library)(nil) 1150var _ SdkLibraryComponentDependency = (*Import)(nil) 1151var _ SdkLibraryComponentDependency = (*SdkLibrary)(nil) 1152var _ SdkLibraryComponentDependency = (*SdkLibraryImport)(nil) 1153 1154type SdkLibraryInfo struct { 1155 // GeneratingLibs is the names of the library modules that this sdk library 1156 // generates. Note that this only includes the name of the modules that other modules can 1157 // depend on, and is not a holistic list of generated modules. 1158 GeneratingLibs []string 1159 1160 // Map of sdk kind to the dex jar for the "everything" stubs. 1161 // It is needed by the hiddenapi processing tool which processes dex files. 1162 EverythingStubDexJarPaths map[android.SdkKind]OptionalDexJarPath 1163 1164 // Map of sdk kind to the dex jar for the "exportable" stubs. 1165 // It is needed by the hiddenapi processing tool which processes dex files. 1166 ExportableStubDexJarPaths map[android.SdkKind]OptionalDexJarPath 1167 1168 // Map of sdk kind to the optional path to the removed.txt file. 1169 RemovedTxtFiles map[android.SdkKind]android.OptionalPath 1170 1171 // Whether if this can be used as a shared library. 1172 SharedLibrary bool 1173} 1174 1175var SdkLibraryInfoProvider = blueprint.NewProvider[SdkLibraryInfo]() 1176 1177func getGeneratingLibs(ctx android.ModuleContext, sdkVersion android.SdkSpec, sdkLibraryModuleName string, sdkInfo SdkLibraryInfo) []string { 1178 apiLevel := sdkVersion.ApiLevel 1179 if apiLevel.IsPreview() { 1180 return sdkInfo.GeneratingLibs 1181 } 1182 1183 generatingPrebuilts := []string{} 1184 for _, apiScope := range AllApiScopes { 1185 scopePrebuiltModuleName := prebuiltApiModuleName("sdk", sdkLibraryModuleName, apiScope.name, apiLevel.String()) 1186 if ctx.OtherModuleExists(scopePrebuiltModuleName) { 1187 generatingPrebuilts = append(generatingPrebuilts, scopePrebuiltModuleName) 1188 } 1189 } 1190 return generatingPrebuilts 1191} 1192 1193type SdkLibrary struct { 1194 Library 1195 1196 sdkLibraryProperties sdkLibraryProperties 1197 1198 // Map from api scope to the scope specific property structure. 1199 scopeToProperties map[*apiScope]*ApiScopeProperties 1200 1201 commonToSdkLibraryAndImport 1202 1203 builtInstalledForApex []dexpreopterInstall 1204} 1205 1206func (module *SdkLibrary) generateTestAndSystemScopesByDefault() bool { 1207 return module.sdkLibraryProperties.Generate_system_and_test_apis 1208} 1209 1210var _ UsesLibraryDependency = (*SdkLibrary)(nil) 1211 1212// To satisfy the UsesLibraryDependency interface 1213func (module *SdkLibrary) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath { 1214 if module.implLibraryModule != nil { 1215 return module.implLibraryModule.DexJarBuildPath(ctx) 1216 } 1217 return makeUnsetDexJarPath() 1218} 1219 1220// To satisfy the UsesLibraryDependency interface 1221func (module *SdkLibrary) DexJarInstallPath() android.Path { 1222 if module.implLibraryModule != nil { 1223 return module.implLibraryModule.DexJarInstallPath() 1224 } 1225 return nil 1226} 1227 1228func (module *SdkLibrary) getGeneratedApiScopes(ctx android.EarlyModuleContext) apiScopes { 1229 // Check to see if any scopes have been explicitly enabled. If any have then all 1230 // must be. 1231 anyScopesExplicitlyEnabled := false 1232 for _, scope := range AllApiScopes { 1233 scopeProperties := module.scopeToProperties[scope] 1234 if scopeProperties.Enabled != nil { 1235 anyScopesExplicitlyEnabled = true 1236 break 1237 } 1238 } 1239 1240 var generatedScopes apiScopes 1241 enabledScopes := make(map[*apiScope]struct{}) 1242 for _, scope := range AllApiScopes { 1243 scopeProperties := module.scopeToProperties[scope] 1244 // If any scopes are explicitly enabled then ignore the legacy enabled status. 1245 // This is to ensure that any new usages of this module type do not rely on legacy 1246 // behaviour. 1247 defaultEnabledStatus := false 1248 if anyScopesExplicitlyEnabled { 1249 defaultEnabledStatus = scope.defaultEnabledStatus 1250 } else { 1251 defaultEnabledStatus = scope.legacyEnabledStatus(module) 1252 } 1253 enabled := proptools.BoolDefault(scopeProperties.Enabled, defaultEnabledStatus) 1254 if enabled { 1255 enabledScopes[scope] = struct{}{} 1256 generatedScopes = append(generatedScopes, scope) 1257 } 1258 } 1259 1260 // Now check to make sure that any scope that is extended by an enabled scope is also 1261 // enabled. 1262 for _, scope := range AllApiScopes { 1263 if _, ok := enabledScopes[scope]; ok { 1264 extends := scope.extends 1265 if extends != nil { 1266 if _, ok := enabledScopes[extends]; !ok { 1267 ctx.ModuleErrorf("enabled api scope %q depends on disabled scope %q", scope, extends) 1268 } 1269 } 1270 } 1271 } 1272 1273 return generatedScopes 1274} 1275 1276var _ android.ModuleWithMinSdkVersionCheck = (*SdkLibrary)(nil) 1277 1278func (module *SdkLibrary) CheckMinSdkVersion(ctx android.ModuleContext) { 1279 CheckMinSdkVersion(ctx, &module.Library) 1280} 1281 1282func CheckMinSdkVersion(ctx android.ModuleContext, module *Library) { 1283 android.CheckMinSdkVersion(ctx, module.MinSdkVersion(ctx), func(c android.BaseModuleContext, do android.PayloadDepsCallback) { 1284 ctx.WalkDeps(func(child android.Module, parent android.Module) bool { 1285 isExternal := !module.depIsInSameApex(ctx, child) 1286 if am, ok := child.(android.ApexModule); ok { 1287 if !do(ctx, parent, am, isExternal) { 1288 return false 1289 } 1290 } 1291 return !isExternal 1292 }) 1293 }) 1294} 1295 1296type sdkLibraryComponentTag struct { 1297 blueprint.BaseDependencyTag 1298 name string 1299} 1300 1301// Mark this tag so dependencies that use it are excluded from visibility enforcement. 1302func (t sdkLibraryComponentTag) ExcludeFromVisibilityEnforcement() {} 1303 1304var xmlPermissionsFileTag = sdkLibraryComponentTag{name: "xml-permissions-file"} 1305 1306func IsXmlPermissionsFileDepTag(depTag blueprint.DependencyTag) bool { 1307 if dt, ok := depTag.(sdkLibraryComponentTag); ok { 1308 return dt == xmlPermissionsFileTag 1309 } 1310 return false 1311} 1312 1313var implLibraryTag = sdkLibraryComponentTag{name: "impl-library"} 1314 1315var _ android.InstallNeededDependencyTag = sdkLibraryComponentTag{} 1316 1317func (t sdkLibraryComponentTag) InstallDepNeeded() bool { 1318 return t.name == "xml-permissions-file" || t.name == "impl-library" 1319} 1320 1321// Add the dependencies on the child modules in the component deps mutator. 1322func (module *SdkLibrary) ComponentDepsMutator(ctx android.BottomUpMutatorContext) { 1323 for _, apiScope := range module.getGeneratedApiScopes(ctx) { 1324 // Add dependencies to the stubs library 1325 stubModuleName := module.stubsLibraryModuleName(apiScope) 1326 ctx.AddVariationDependencies(nil, apiScope.everythingStubsTag, stubModuleName) 1327 1328 exportableStubModuleName := module.exportableStubsLibraryModuleName(apiScope) 1329 ctx.AddVariationDependencies(nil, apiScope.exportableStubsTag, exportableStubModuleName) 1330 1331 // Add a dependency on the stubs source in order to access both stubs source and api information. 1332 ctx.AddVariationDependencies(nil, apiScope.stubsSourceAndApiTag, module.droidstubsModuleName(apiScope)) 1333 1334 if module.compareAgainstLatestApi(apiScope) { 1335 // Add dependencies on the latest finalized version of the API .txt file. 1336 latestApiModuleName := module.latestApiModuleName(apiScope) 1337 ctx.AddDependency(module, apiScope.latestApiModuleTag, latestApiModuleName) 1338 1339 // Add dependencies on the latest finalized version of the remove API .txt file. 1340 latestRemovedApiModuleName := module.latestRemovedApiModuleName(apiScope) 1341 ctx.AddDependency(module, apiScope.latestRemovedApiModuleTag, latestRemovedApiModuleName) 1342 } 1343 } 1344 1345 if module.requiresRuntimeImplementationLibrary() { 1346 // Add dependency to the rule for generating the implementation library. 1347 ctx.AddDependency(module, implLibraryTag, module.implLibraryModuleName()) 1348 1349 if module.sharedLibrary() { 1350 // Add dependency to the rule for generating the xml permissions file 1351 ctx.AddDependency(module, xmlPermissionsFileTag, module.xmlPermissionsModuleName()) 1352 } 1353 } 1354} 1355 1356// Add other dependencies as normal. 1357func (module *SdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) { 1358 // If the module does not create an implementation library or defaults to stubs, 1359 // mark the top level sdk library as stubs module as the module will provide stubs via 1360 // "magic" when listed as a dependency in the Android.bp files. 1361 notCreateImplLib := proptools.Bool(module.sdkLibraryProperties.Api_only) 1362 preferStubs := proptools.Bool(module.sdkLibraryProperties.Default_to_stubs) 1363 module.properties.Is_stubs_module = proptools.BoolPtr(notCreateImplLib || preferStubs) 1364 1365 var missingApiModules []string 1366 for _, apiScope := range module.getGeneratedApiScopes(ctx) { 1367 if apiScope.unstable { 1368 continue 1369 } 1370 if m := module.latestApiModuleName(apiScope); !ctx.OtherModuleExists(m) { 1371 missingApiModules = append(missingApiModules, m) 1372 } 1373 if m := module.latestRemovedApiModuleName(apiScope); !ctx.OtherModuleExists(m) { 1374 missingApiModules = append(missingApiModules, m) 1375 } 1376 if m := module.latestIncompatibilitiesModuleName(apiScope); !ctx.OtherModuleExists(m) { 1377 missingApiModules = append(missingApiModules, m) 1378 } 1379 } 1380 if len(missingApiModules) != 0 && !module.sdkLibraryProperties.Unsafe_ignore_missing_latest_api { 1381 m := module.Name() + " is missing tracking files for previously released library versions.\n" 1382 m += "You need to do one of the following:\n" 1383 m += "- Add `unsafe_ignore_missing_latest_api: true` to your blueprint (to disable compat tracking)\n" 1384 m += "- Add a set of prebuilt txt files representing the last released version of this library for compat checking.\n" 1385 m += " (the current set of API files can be used as a seed for this compatibility tracking\n" 1386 m += "\n" 1387 m += "The following filegroup modules are missing:\n " 1388 m += strings.Join(missingApiModules, "\n ") + "\n" 1389 m += "Please see the documentation of the prebuilt_apis module type (and a usage example in prebuilts/sdk) for a convenient way to generate these." 1390 ctx.ModuleErrorf(m) 1391 } 1392} 1393 1394func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1395 if disableSourceApexVariant(ctx) { 1396 // Prebuilts are active, do not create the installation rules for the source javalib. 1397 // Even though the source javalib is not used, we need to hide it to prevent duplicate installation rules. 1398 // TODO (b/331665856): Implement a principled solution for this. 1399 module.HideFromMake() 1400 module.SkipInstall() 1401 } 1402 1403 module.stem = proptools.StringDefault(module.overridableProperties.Stem, ctx.ModuleName()) 1404 1405 module.provideHiddenAPIPropertyInfo(ctx) 1406 1407 // Collate the components exported by this module. All scope specific modules are exported but 1408 // the impl and xml component modules are not. 1409 exportedComponents := map[string]struct{}{} 1410 1411 // Record the paths to the header jars of the library (stubs and impl). 1412 // When this java_sdk_library is depended upon from others via "libs" property, 1413 // the recorded paths will be returned depending on the link type of the caller. 1414 ctx.VisitDirectDeps(func(to android.Module) { 1415 tag := ctx.OtherModuleDependencyTag(to) 1416 1417 // Extract information from any of the scope specific dependencies. 1418 if scopeTag, ok := tag.(scopeDependencyTag); ok { 1419 apiScope := scopeTag.apiScope 1420 scopePaths := module.getScopePathsCreateIfNeeded(apiScope) 1421 1422 // Extract information from the dependency. The exact information extracted 1423 // is determined by the nature of the dependency which is determined by the tag. 1424 scopeTag.extractDepInfo(ctx, to, scopePaths) 1425 1426 exportedComponents[ctx.OtherModuleName(to)] = struct{}{} 1427 1428 ctx.Phony(ctx.ModuleName(), scopePaths.stubsHeaderPath...) 1429 } 1430 1431 if tag == implLibraryTag { 1432 if dep, ok := android.OtherModuleProvider(ctx, to, JavaInfoProvider); ok { 1433 module.implLibraryHeaderJars = append(module.implLibraryHeaderJars, dep.HeaderJars...) 1434 module.implLibraryModule = to.(*Library) 1435 } 1436 } 1437 }) 1438 1439 sdkLibInfo := module.generateCommonBuildActions(ctx) 1440 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) 1441 if !apexInfo.IsForPlatform() { 1442 module.hideApexVariantFromMake = true 1443 } 1444 1445 if module.implLibraryModule != nil { 1446 if ctx.Device() { 1447 module.classesJarPaths = android.Paths{module.implLibraryModule.implementationJarFile} 1448 module.bootDexJarPath = module.implLibraryModule.bootDexJarPath 1449 module.uncompressDexState = module.implLibraryModule.uncompressDexState 1450 module.active = module.implLibraryModule.active 1451 } 1452 1453 module.outputFile = module.implLibraryModule.outputFile 1454 module.dexJarFile = makeDexJarPathFromPath(module.implLibraryModule.dexJarFile.Path()) 1455 module.headerJarFile = module.implLibraryModule.headerJarFile 1456 module.implementationAndResourcesJar = module.implLibraryModule.implementationAndResourcesJar 1457 module.builtInstalledForApex = module.implLibraryModule.builtInstalledForApex 1458 module.dexpreopter.configPath = module.implLibraryModule.dexpreopter.configPath 1459 module.dexpreopter.outputProfilePathOnHost = module.implLibraryModule.dexpreopter.outputProfilePathOnHost 1460 1461 // Properties required for Library.AndroidMkEntries 1462 module.logtagsSrcs = module.implLibraryModule.logtagsSrcs 1463 module.dexpreopter.builtInstalled = module.implLibraryModule.dexpreopter.builtInstalled 1464 module.jacocoReportClassesFile = module.implLibraryModule.jacocoReportClassesFile 1465 module.dexer.proguardDictionary = module.implLibraryModule.dexer.proguardDictionary 1466 module.dexer.proguardUsageZip = module.implLibraryModule.dexer.proguardUsageZip 1467 module.linter.reports = module.implLibraryModule.linter.reports 1468 1469 if lintInfo, ok := android.OtherModuleProvider(ctx, module.implLibraryModule, LintProvider); ok { 1470 android.SetProvider(ctx, LintProvider, lintInfo) 1471 } 1472 1473 if !module.Host() { 1474 module.hostdexInstallFile = module.implLibraryModule.hostdexInstallFile 1475 } 1476 1477 if installFilesInfo, ok := android.OtherModuleProvider(ctx, module.implLibraryModule, android.InstallFilesProvider); ok { 1478 if installFilesInfo.CheckbuildTarget != nil { 1479 ctx.CheckbuildFile(installFilesInfo.CheckbuildTarget) 1480 } 1481 } 1482 android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: module.implLibraryModule.uniqueSrcFiles.Strings()}) 1483 } 1484 1485 // Make the set of components exported by this module available for use elsewhere. 1486 exportedComponentInfo := android.ExportedComponentsInfo{Components: android.SortedKeys(exportedComponents)} 1487 android.SetProvider(ctx, android.ExportedComponentsInfoProvider, exportedComponentInfo) 1488 1489 // Provide additional information for inclusion in an sdk's generated .info file. 1490 additionalSdkInfo := map[string]interface{}{} 1491 additionalSdkInfo["dist_stem"] = module.distStem() 1492 baseModuleName := module.distStem() 1493 scopes := map[string]interface{}{} 1494 additionalSdkInfo["scopes"] = scopes 1495 for scope, scopePaths := range module.scopePaths { 1496 scopeInfo := map[string]interface{}{} 1497 scopes[scope.name] = scopeInfo 1498 scopeInfo["current_api"] = scope.snapshotRelativeCurrentApiTxtPath(baseModuleName) 1499 scopeInfo["removed_api"] = scope.snapshotRelativeRemovedApiTxtPath(baseModuleName) 1500 if p := scopePaths.latestApiPaths; len(p) > 0 { 1501 // The last path in the list is the one that applies to this scope, the 1502 // preceding ones, if any, are for the scope(s) that it extends. 1503 scopeInfo["latest_api"] = p[len(p)-1].String() 1504 } 1505 if p := scopePaths.latestRemovedApiPaths; len(p) > 0 { 1506 // The last path in the list is the one that applies to this scope, the 1507 // preceding ones, if any, are for the scope(s) that it extends. 1508 scopeInfo["latest_removed_api"] = p[len(p)-1].String() 1509 } 1510 } 1511 android.SetProvider(ctx, android.AdditionalSdkInfoProvider, android.AdditionalSdkInfo{additionalSdkInfo}) 1512 module.setOutputFiles(ctx) 1513 1514 var generatingLibs []string 1515 for _, apiScope := range AllApiScopes { 1516 if _, ok := module.scopePaths[apiScope]; ok { 1517 generatingLibs = append(generatingLibs, module.stubsLibraryModuleName(apiScope)) 1518 } 1519 } 1520 1521 if module.requiresRuntimeImplementationLibrary() && module.implLibraryModule != nil { 1522 generatingLibs = append(generatingLibs, module.implLibraryModuleName()) 1523 setOutputFiles(ctx, module.implLibraryModule.Module) 1524 } 1525 1526 sdkLibInfo.GeneratingLibs = generatingLibs 1527 android.SetProvider(ctx, SdkLibraryInfoProvider, sdkLibInfo) 1528} 1529 1530func (module *SdkLibrary) BuiltInstalledForApex() []dexpreopterInstall { 1531 return module.builtInstalledForApex 1532} 1533 1534func (module *SdkLibrary) AndroidMkEntries() []android.AndroidMkEntries { 1535 if !module.requiresRuntimeImplementationLibrary() { 1536 return nil 1537 } 1538 entriesList := module.Library.AndroidMkEntries() 1539 entries := &entriesList[0] 1540 entries.Required = append(entries.Required, module.implLibraryModuleName()) 1541 if module.sharedLibrary() { 1542 entries.Required = append(entries.Required, module.xmlPermissionsModuleName()) 1543 } 1544 return entriesList 1545} 1546 1547// The dist path of the stub artifacts 1548func (module *SdkLibrary) apiDistPath(apiScope *apiScope) string { 1549 return path.Join("apistubs", module.distGroup(), apiScope.name) 1550} 1551 1552// Get the sdk version for use when compiling the stubs library. 1553func (module *SdkLibrary) sdkVersionForStubsLibrary(mctx android.EarlyModuleContext, apiScope *apiScope) string { 1554 scopeProperties := module.scopeToProperties[apiScope] 1555 if scopeProperties.Sdk_version != nil { 1556 return proptools.String(scopeProperties.Sdk_version) 1557 } 1558 1559 sdkDep := decodeSdkDep(mctx, android.SdkContext(&module.Library)) 1560 if sdkDep.hasStandardLibs() { 1561 // If building against a standard sdk then use the sdk version appropriate for the scope. 1562 return apiScope.sdkVersion 1563 } else { 1564 // Otherwise, use no system module. 1565 return "none" 1566 } 1567} 1568 1569func (module *SdkLibrary) distStem() string { 1570 return proptools.StringDefault(module.sdkLibraryProperties.Dist_stem, module.BaseModuleName()) 1571} 1572 1573// distGroup returns the subdirectory of the dist path of the stub artifacts. 1574func (module *SdkLibrary) distGroup() string { 1575 return proptools.StringDefault(module.sdkLibraryProperties.Dist_group, "unknown") 1576} 1577 1578func latestPrebuiltApiModuleName(name string, apiScope *apiScope) string { 1579 return PrebuiltApiModuleName(name, apiScope.name, "latest") 1580} 1581 1582func latestPrebuiltApiCombinedModuleName(name string, apiScope *apiScope) string { 1583 return PrebuiltApiCombinedModuleName(name, apiScope.name, "latest") 1584} 1585 1586func (module *SdkLibrary) latestApiFilegroupName(apiScope *apiScope) string { 1587 return ":" + module.latestApiModuleName(apiScope) 1588} 1589 1590func (module *SdkLibrary) latestApiModuleName(apiScope *apiScope) string { 1591 return latestPrebuiltApiCombinedModuleName(module.distStem(), apiScope) 1592} 1593 1594func (module *SdkLibrary) latestRemovedApiFilegroupName(apiScope *apiScope) string { 1595 return ":" + module.latestRemovedApiModuleName(apiScope) 1596} 1597 1598func (module *SdkLibrary) latestRemovedApiModuleName(apiScope *apiScope) string { 1599 return latestPrebuiltApiCombinedModuleName(module.distStem()+"-removed", apiScope) 1600} 1601 1602func (module *SdkLibrary) latestIncompatibilitiesFilegroupName(apiScope *apiScope) string { 1603 return ":" + module.latestIncompatibilitiesModuleName(apiScope) 1604} 1605 1606func (module *SdkLibrary) latestIncompatibilitiesModuleName(apiScope *apiScope) string { 1607 return latestPrebuiltApiModuleName(module.distStem()+"-incompatibilities", apiScope) 1608} 1609 1610// The listed modules' stubs contents do not match the corresponding txt files, 1611// but require additional api contributions to generate the full stubs. 1612// This method returns the name of the additional api contribution module 1613// for corresponding sdk_library modules. 1614func (module *SdkLibrary) apiLibraryAdditionalApiContribution() string { 1615 if val, ok := apiLibraryAdditionalProperties[module.Name()]; ok { 1616 return val 1617 } 1618 return "" 1619} 1620 1621func childModuleVisibility(childVisibility []string) []string { 1622 if childVisibility == nil { 1623 // No child visibility set. The child will use the visibility of the sdk_library. 1624 return nil 1625 } 1626 1627 // Prepend an override to ignore the sdk_library's visibility, and rely on the child visibility. 1628 var visibility []string 1629 visibility = append(visibility, "//visibility:override") 1630 visibility = append(visibility, childVisibility...) 1631 return visibility 1632} 1633 1634func (module *SdkLibrary) compareAgainstLatestApi(apiScope *apiScope) bool { 1635 return !(apiScope.unstable || module.sdkLibraryProperties.Unsafe_ignore_missing_latest_api) 1636} 1637 1638// Implements android.ApexModule 1639func (module *SdkLibrary) DepIsInSameApex(mctx android.BaseModuleContext, dep android.Module) bool { 1640 depTag := mctx.OtherModuleDependencyTag(dep) 1641 if depTag == xmlPermissionsFileTag { 1642 return true 1643 } 1644 if dep.Name() == module.implLibraryModuleName() { 1645 return true 1646 } 1647 return module.Library.DepIsInSameApex(mctx, dep) 1648} 1649 1650// Implements android.ApexModule 1651func (module *SdkLibrary) UniqueApexVariations() bool { 1652 return module.uniqueApexVariations() 1653} 1654 1655func (module *SdkLibrary) ModuleBuildFromTextStubs() bool { 1656 return proptools.BoolDefault(module.sdkLibraryProperties.Build_from_text_stub, true) 1657} 1658 1659var javaSdkLibrariesKey = android.NewOnceKey("javaSdkLibraries") 1660 1661func javaSdkLibraries(config android.Config) *[]string { 1662 return config.Once(javaSdkLibrariesKey, func() interface{} { 1663 return &[]string{} 1664 }).(*[]string) 1665} 1666 1667func (module *SdkLibrary) getApiDir() string { 1668 return proptools.StringDefault(module.sdkLibraryProperties.Api_dir, "api") 1669} 1670 1671// For a java_sdk_library module, create internal modules for stubs, docs, 1672// runtime libs and xml file. If requested, the stubs and docs are created twice 1673// once for public API level and once for system API level 1674func (module *SdkLibrary) CreateInternalModules(mctx android.DefaultableHookContext) { 1675 if len(module.properties.Srcs) == 0 { 1676 mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs") 1677 return 1678 } 1679 1680 // If this builds against standard libraries (i.e. is not part of the core libraries) 1681 // then assume it provides both system and test apis. 1682 sdkDep := decodeSdkDep(mctx, android.SdkContext(&module.Library)) 1683 hasSystemAndTestApis := sdkDep.hasStandardLibs() 1684 module.sdkLibraryProperties.Generate_system_and_test_apis = hasSystemAndTestApis 1685 1686 missingCurrentApi := false 1687 1688 generatedScopes := module.getGeneratedApiScopes(mctx) 1689 1690 apiDir := module.getApiDir() 1691 for _, scope := range generatedScopes { 1692 for _, api := range []string{"current.txt", "removed.txt"} { 1693 path := path.Join(mctx.ModuleDir(), apiDir, scope.apiFilePrefix+api) 1694 p := android.ExistentPathForSource(mctx, path) 1695 if !p.Valid() { 1696 if mctx.Config().AllowMissingDependencies() { 1697 mctx.AddMissingDependencies([]string{path}) 1698 } else { 1699 mctx.ModuleErrorf("Current api file %#v doesn't exist", path) 1700 missingCurrentApi = true 1701 } 1702 } 1703 } 1704 } 1705 1706 if missingCurrentApi { 1707 script := "build/soong/scripts/gen-java-current-api-files.sh" 1708 p := android.ExistentPathForSource(mctx, script) 1709 1710 if !p.Valid() { 1711 panic(fmt.Sprintf("script file %s doesn't exist", script)) 1712 } 1713 1714 mctx.ModuleErrorf("One or more current api files are missing. "+ 1715 "You can update them by:\n"+ 1716 "%s %q %s && m update-api", 1717 script, filepath.Join(mctx.ModuleDir(), apiDir), 1718 strings.Join(generatedScopes.Strings(func(s *apiScope) string { return s.apiFilePrefix }), " ")) 1719 return 1720 } 1721 1722 for _, scope := range generatedScopes { 1723 // Use the stubs source name for legacy reasons. 1724 module.createDroidstubs(mctx, scope, module.droidstubsModuleName(scope), scope.droidstubsArgs) 1725 1726 module.createFromSourceStubsLibrary(mctx, scope) 1727 module.createExportableFromSourceStubsLibrary(mctx, scope) 1728 1729 if mctx.Config().BuildFromTextStub() && module.ModuleBuildFromTextStubs() { 1730 module.createApiLibrary(mctx, scope) 1731 } 1732 module.createTopLevelStubsLibrary(mctx, scope) 1733 module.createTopLevelExportableStubsLibrary(mctx, scope) 1734 } 1735 1736 if module.requiresRuntimeImplementationLibrary() { 1737 // Create child module to create an implementation library. 1738 // 1739 // This temporarily creates a second implementation library that can be explicitly 1740 // referenced. 1741 // 1742 // TODO(b/156618935) - update comment once only one implementation library is created. 1743 module.createImplLibrary(mctx) 1744 1745 // Only create an XML permissions file that declares the library as being usable 1746 // as a shared library if required. 1747 if module.sharedLibrary() { 1748 module.createXmlFile(mctx) 1749 } 1750 1751 // record java_sdk_library modules so that they are exported to make 1752 javaSdkLibraries := javaSdkLibraries(mctx.Config()) 1753 javaSdkLibrariesLock.Lock() 1754 defer javaSdkLibrariesLock.Unlock() 1755 *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName()) 1756 } 1757 1758 // Add the impl_only_libs and impl_only_static_libs *after* we're done using them in submodules. 1759 module.properties.Libs = append(module.properties.Libs, module.sdkLibraryProperties.Impl_only_libs...) 1760 module.properties.Static_libs.AppendSimpleValue(module.sdkLibraryProperties.Impl_only_static_libs) 1761} 1762 1763func (module *SdkLibrary) InitSdkLibraryProperties() { 1764 module.addHostAndDeviceProperties() 1765 module.AddProperties(&module.sdkLibraryProperties) 1766 1767 module.initSdkLibraryComponent(module) 1768 1769 module.properties.Installable = proptools.BoolPtr(true) 1770 module.deviceProperties.IsSDKLibrary = true 1771} 1772 1773func (module *SdkLibrary) requiresRuntimeImplementationLibrary() bool { 1774 return !proptools.Bool(module.sdkLibraryProperties.Api_only) 1775} 1776 1777func moduleStubLinkType(j *Module) (stub bool, ret sdkLinkType) { 1778 kind := android.ToSdkKind(proptools.String(j.properties.Stub_contributing_api)) 1779 switch kind { 1780 case android.SdkPublic: 1781 return true, javaSdk 1782 case android.SdkSystem: 1783 return true, javaSystem 1784 case android.SdkModule: 1785 return true, javaModule 1786 case android.SdkTest: 1787 return true, javaSystem 1788 case android.SdkSystemServer: 1789 return true, javaSystemServer 1790 // Default value for all modules other than java_sdk_library-generated stub submodules 1791 case android.SdkInvalid: 1792 return false, javaPlatform 1793 default: 1794 panic(fmt.Sprintf("stub_contributing_api set as an unsupported sdk kind %s", kind.String())) 1795 } 1796} 1797 1798// java_sdk_library is a special Java library that provides optional platform APIs to apps. 1799// In practice, it can be viewed as a combination of several modules: 1) stubs library that clients 1800// are linked against to, 2) droiddoc module that internally generates API stubs source files, 1801// 3) the real runtime shared library that implements the APIs, and 4) XML file for adding 1802// the runtime lib to the classpath at runtime if requested via <uses-library>. 1803func SdkLibraryFactory() android.Module { 1804 module := &SdkLibrary{} 1805 1806 // Initialize information common between source and prebuilt. 1807 module.initCommon(module) 1808 1809 module.InitSdkLibraryProperties() 1810 android.InitApexModule(module) 1811 InitJavaModule(module, android.HostAndDeviceSupported) 1812 1813 // Initialize the map from scope to scope specific properties. 1814 scopeToProperties := make(map[*apiScope]*ApiScopeProperties) 1815 for _, scope := range AllApiScopes { 1816 scopeToProperties[scope] = scope.scopeSpecificProperties(module) 1817 } 1818 module.scopeToProperties = scopeToProperties 1819 1820 // Add the properties containing visibility rules so that they are checked. 1821 android.AddVisibilityProperty(module, "impl_library_visibility", &module.sdkLibraryProperties.Impl_library_visibility) 1822 android.AddVisibilityProperty(module, "stubs_library_visibility", &module.sdkLibraryProperties.Stubs_library_visibility) 1823 android.AddVisibilityProperty(module, "stubs_source_visibility", &module.sdkLibraryProperties.Stubs_source_visibility) 1824 1825 module.SetDefaultableHook(func(ctx android.DefaultableHookContext) { 1826 // If no implementation is required then it cannot be used as a shared library 1827 // either. 1828 if !module.requiresRuntimeImplementationLibrary() { 1829 // If shared_library has been explicitly set to true then it is incompatible 1830 // with api_only: true. 1831 if proptools.Bool(module.commonSdkLibraryProperties.Shared_library) { 1832 ctx.PropertyErrorf("api_only/shared_library", "inconsistent settings, shared_library and api_only cannot both be true") 1833 } 1834 // Set shared_library: false. 1835 module.commonSdkLibraryProperties.Shared_library = proptools.BoolPtr(false) 1836 } 1837 1838 if module.initCommonAfterDefaultsApplied() { 1839 module.CreateInternalModules(ctx) 1840 } 1841 }) 1842 return module 1843} 1844 1845// 1846// SDK library prebuilts 1847// 1848 1849// Properties associated with each api scope. 1850type sdkLibraryScopeProperties struct { 1851 Jars []string `android:"path"` 1852 1853 Sdk_version *string 1854 1855 // List of shared java libs that this module has dependencies to 1856 Libs []string 1857 1858 // The stubs source. 1859 Stub_srcs []string `android:"path"` 1860 1861 // The current.txt 1862 Current_api *string `android:"path"` 1863 1864 // The removed.txt 1865 Removed_api *string `android:"path"` 1866 1867 // Annotation zip 1868 Annotations *string `android:"path"` 1869} 1870 1871type sdkLibraryImportProperties struct { 1872 // List of shared java libs, common to all scopes, that this module has 1873 // dependencies to 1874 Libs []string 1875 1876 // If set to true, compile dex files for the stubs. Defaults to false. 1877 Compile_dex *bool 1878 1879 // If not empty, classes are restricted to the specified packages and their sub-packages. 1880 Permitted_packages []string 1881 1882 // Name of the source soong module that gets shadowed by this prebuilt 1883 // If unspecified, follows the naming convention that the source module of 1884 // the prebuilt is Name() without "prebuilt_" prefix 1885 Source_module_name *string 1886} 1887 1888type SdkLibraryImport struct { 1889 android.ModuleBase 1890 android.DefaultableModuleBase 1891 prebuilt android.Prebuilt 1892 android.ApexModuleBase 1893 1894 hiddenAPI 1895 dexpreopter 1896 1897 properties sdkLibraryImportProperties 1898 1899 // Map from api scope to the scope specific property structure. 1900 scopeProperties map[*apiScope]*sdkLibraryScopeProperties 1901 1902 commonToSdkLibraryAndImport 1903 1904 // The reference to the xml permissions module created by the source module. 1905 // Is nil if the source module does not exist. 1906 xmlPermissionsFileModule *sdkLibraryXml 1907 1908 // Build path to the dex implementation jar obtained from the prebuilt_apex, if any. 1909 dexJarFile OptionalDexJarPath 1910 dexJarFileErr error 1911 1912 // Expected install file path of the source module(sdk_library) 1913 // or dex implementation jar obtained from the prebuilt_apex, if any. 1914 installFile android.Path 1915} 1916 1917// The type of a structure that contains a field of type sdkLibraryScopeProperties 1918// for each apiscope in allApiScopes, e.g. something like: 1919// 1920// struct { 1921// Public sdkLibraryScopeProperties 1922// System sdkLibraryScopeProperties 1923// ... 1924// } 1925var allScopeStructType = createAllScopePropertiesStructType() 1926 1927// Dynamically create a structure type for each apiscope in allApiScopes. 1928func createAllScopePropertiesStructType() reflect.Type { 1929 var fields []reflect.StructField 1930 for _, apiScope := range AllApiScopes { 1931 field := reflect.StructField{ 1932 Name: apiScope.fieldName, 1933 Type: reflect.TypeOf(sdkLibraryScopeProperties{}), 1934 } 1935 fields = append(fields, field) 1936 } 1937 1938 return reflect.StructOf(fields) 1939} 1940 1941// Create an instance of the scope specific structure type and return a map 1942// from apiscope to a pointer to each scope specific field. 1943func createPropertiesInstance() (interface{}, map[*apiScope]*sdkLibraryScopeProperties) { 1944 allScopePropertiesPtr := reflect.New(allScopeStructType) 1945 allScopePropertiesStruct := allScopePropertiesPtr.Elem() 1946 scopeProperties := make(map[*apiScope]*sdkLibraryScopeProperties) 1947 1948 for _, apiScope := range AllApiScopes { 1949 field := allScopePropertiesStruct.FieldByName(apiScope.fieldName) 1950 scopeProperties[apiScope] = field.Addr().Interface().(*sdkLibraryScopeProperties) 1951 } 1952 1953 return allScopePropertiesPtr.Interface(), scopeProperties 1954} 1955 1956// java_sdk_library_import imports a prebuilt java_sdk_library. 1957func sdkLibraryImportFactory() android.Module { 1958 module := &SdkLibraryImport{} 1959 1960 allScopeProperties, scopeToProperties := createPropertiesInstance() 1961 module.scopeProperties = scopeToProperties 1962 module.AddProperties(&module.properties, allScopeProperties, &module.importDexpreoptProperties) 1963 1964 // Initialize information common between source and prebuilt. 1965 module.initCommon(module) 1966 1967 android.InitPrebuiltModule(module, &[]string{""}) 1968 android.InitApexModule(module) 1969 InitJavaModule(module, android.HostAndDeviceSupported) 1970 1971 module.SetDefaultableHook(func(mctx android.DefaultableHookContext) { 1972 if module.initCommonAfterDefaultsApplied() { 1973 module.createInternalModules(mctx) 1974 } 1975 }) 1976 return module 1977} 1978 1979var _ PermittedPackagesForUpdatableBootJars = (*SdkLibraryImport)(nil) 1980 1981func (module *SdkLibraryImport) PermittedPackagesForUpdatableBootJars() []string { 1982 return module.properties.Permitted_packages 1983} 1984 1985func (module *SdkLibraryImport) Prebuilt() *android.Prebuilt { 1986 return &module.prebuilt 1987} 1988 1989func (module *SdkLibraryImport) Name() string { 1990 return module.prebuilt.Name(module.ModuleBase.Name()) 1991} 1992 1993func (module *SdkLibraryImport) BaseModuleName() string { 1994 return proptools.StringDefault(module.properties.Source_module_name, module.ModuleBase.Name()) 1995} 1996 1997func (module *SdkLibraryImport) createInternalModules(mctx android.DefaultableHookContext) { 1998 1999 // If the build is configured to use prebuilts then force this to be preferred. 2000 if mctx.Config().AlwaysUsePrebuiltSdks() { 2001 module.prebuilt.ForcePrefer() 2002 } 2003 2004 for apiScope, scopeProperties := range module.scopeProperties { 2005 if len(scopeProperties.Jars) == 0 { 2006 continue 2007 } 2008 2009 module.createJavaImportForStubs(mctx, apiScope, scopeProperties) 2010 2011 if len(scopeProperties.Stub_srcs) > 0 { 2012 module.createPrebuiltStubsSources(mctx, apiScope, scopeProperties) 2013 } 2014 2015 if scopeProperties.Current_api != nil { 2016 module.createPrebuiltApiContribution(mctx, apiScope, scopeProperties) 2017 } 2018 } 2019 2020 javaSdkLibraries := javaSdkLibraries(mctx.Config()) 2021 javaSdkLibrariesLock.Lock() 2022 defer javaSdkLibrariesLock.Unlock() 2023 *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName()) 2024} 2025 2026// Add the dependencies on the child module in the component deps mutator so that it 2027// creates references to the prebuilt and not the source modules. 2028func (module *SdkLibraryImport) ComponentDepsMutator(ctx android.BottomUpMutatorContext) { 2029 for apiScope, scopeProperties := range module.scopeProperties { 2030 if len(scopeProperties.Jars) == 0 { 2031 continue 2032 } 2033 2034 // Add dependencies to the prebuilt stubs library 2035 ctx.AddVariationDependencies(nil, apiScope.prebuiltStubsTag, android.PrebuiltNameFromSource(module.stubsLibraryModuleName(apiScope))) 2036 2037 if len(scopeProperties.Stub_srcs) > 0 { 2038 // Add dependencies to the prebuilt stubs source library 2039 ctx.AddVariationDependencies(nil, apiScope.stubsSourceTag, android.PrebuiltNameFromSource(module.droidstubsModuleName(apiScope))) 2040 } 2041 } 2042} 2043 2044// Add other dependencies as normal. 2045func (module *SdkLibraryImport) DepsMutator(ctx android.BottomUpMutatorContext) { 2046 2047 implName := module.implLibraryModuleName() 2048 if ctx.OtherModuleExists(implName) { 2049 ctx.AddVariationDependencies(nil, implLibraryTag, implName) 2050 2051 xmlPermissionsModuleName := module.xmlPermissionsModuleName() 2052 if module.sharedLibrary() && ctx.OtherModuleExists(xmlPermissionsModuleName) { 2053 // Add dependency to the rule for generating the xml permissions file 2054 ctx.AddDependency(module, xmlPermissionsFileTag, xmlPermissionsModuleName) 2055 } 2056 } 2057} 2058 2059var _ android.ApexModule = (*SdkLibraryImport)(nil) 2060 2061// Implements android.ApexModule 2062func (module *SdkLibraryImport) DepIsInSameApex(mctx android.BaseModuleContext, dep android.Module) bool { 2063 depTag := mctx.OtherModuleDependencyTag(dep) 2064 if depTag == xmlPermissionsFileTag { 2065 return true 2066 } 2067 2068 // None of the other dependencies of the java_sdk_library_import are in the same apex 2069 // as the one that references this module. 2070 return false 2071} 2072 2073// Implements android.ApexModule 2074func (module *SdkLibraryImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext, 2075 sdkVersion android.ApiLevel) error { 2076 // we don't check prebuilt modules for sdk_version 2077 return nil 2078} 2079 2080// Implements android.ApexModule 2081func (module *SdkLibraryImport) UniqueApexVariations() bool { 2082 return module.uniqueApexVariations() 2083} 2084 2085// MinSdkVersion - Implements hiddenAPIModule 2086func (module *SdkLibraryImport) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { 2087 return android.NoneApiLevel 2088} 2089 2090var _ hiddenAPIModule = (*SdkLibraryImport)(nil) 2091 2092func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { 2093 // Assume that source module(sdk_library) is installed in /<sdk_library partition>/framework 2094 module.installFile = android.PathForModuleInstall(ctx, "framework", module.Stem()+".jar") 2095 2096 // Record the paths to the prebuilt stubs library and stubs source. 2097 ctx.VisitDirectDeps(func(to android.Module) { 2098 tag := ctx.OtherModuleDependencyTag(to) 2099 2100 // Extract information from any of the scope specific dependencies. 2101 if scopeTag, ok := tag.(scopeDependencyTag); ok { 2102 apiScope := scopeTag.apiScope 2103 scopePaths := module.getScopePathsCreateIfNeeded(apiScope) 2104 2105 // Extract information from the dependency. The exact information extracted 2106 // is determined by the nature of the dependency which is determined by the tag. 2107 scopeTag.extractDepInfo(ctx, to, scopePaths) 2108 } else if tag == implLibraryTag { 2109 if implLibrary, ok := to.(*Library); ok { 2110 module.implLibraryModule = implLibrary 2111 } else { 2112 ctx.ModuleErrorf("implementation library must be of type *java.Library but was %T", to) 2113 } 2114 } else if tag == xmlPermissionsFileTag { 2115 if xmlPermissionsFileModule, ok := to.(*sdkLibraryXml); ok { 2116 module.xmlPermissionsFileModule = xmlPermissionsFileModule 2117 } else { 2118 ctx.ModuleErrorf("xml permissions file module must be of type *sdkLibraryXml but was %T", to) 2119 } 2120 } 2121 }) 2122 sdkLibInfo := module.generateCommonBuildActions(ctx) 2123 2124 // Populate the scope paths with information from the properties. 2125 for apiScope, scopeProperties := range module.scopeProperties { 2126 if len(scopeProperties.Jars) == 0 { 2127 continue 2128 } 2129 2130 paths := module.getScopePathsCreateIfNeeded(apiScope) 2131 paths.annotationsZip = android.OptionalPathForModuleSrc(ctx, scopeProperties.Annotations) 2132 paths.currentApiFilePath = android.OptionalPathForModuleSrc(ctx, scopeProperties.Current_api) 2133 paths.removedApiFilePath = android.OptionalPathForModuleSrc(ctx, scopeProperties.Removed_api) 2134 } 2135 2136 if ctx.Device() { 2137 // Shared libraries deapexed from prebuilt apexes are no longer supported. 2138 // Set the dexJarBuildPath to a fake path. 2139 // This allows soong analysis pass, but will be an error during ninja execution if there are 2140 // any rdeps. 2141 ai, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) 2142 if ai.ForPrebuiltApex { 2143 module.dexJarFile = makeDexJarPathFromPath(android.PathForModuleInstall(ctx, "intentionally_no_longer_supported")) 2144 module.initHiddenAPI(ctx, module.dexJarFile, module.findScopePaths(apiScopePublic).stubsImplPath[0], nil) 2145 } 2146 } 2147 2148 var generatingLibs []string 2149 for _, apiScope := range AllApiScopes { 2150 if scopeProperties, ok := module.scopeProperties[apiScope]; ok { 2151 if len(scopeProperties.Jars) == 0 { 2152 continue 2153 } 2154 generatingLibs = append(generatingLibs, module.stubsLibraryModuleName(apiScope)) 2155 } 2156 } 2157 2158 module.setOutputFiles(ctx) 2159 if module.implLibraryModule != nil { 2160 generatingLibs = append(generatingLibs, module.implLibraryModuleName()) 2161 setOutputFiles(ctx, module.implLibraryModule.Module) 2162 } 2163 2164 sdkLibInfo.GeneratingLibs = generatingLibs 2165 android.SetProvider(ctx, SdkLibraryInfoProvider, sdkLibInfo) 2166} 2167 2168var _ UsesLibraryDependency = (*SdkLibraryImport)(nil) 2169 2170// to satisfy UsesLibraryDependency interface 2171func (module *SdkLibraryImport) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath { 2172 // The dex implementation jar extracted from the .apex file should be used in preference to the 2173 // source. 2174 if module.dexJarFileErr != nil { 2175 ctx.ModuleErrorf(module.dexJarFileErr.Error()) 2176 } 2177 if module.dexJarFile.IsSet() { 2178 return module.dexJarFile 2179 } 2180 if module.implLibraryModule == nil { 2181 return makeUnsetDexJarPath() 2182 } else { 2183 return module.implLibraryModule.DexJarBuildPath(ctx) 2184 } 2185} 2186 2187// to satisfy UsesLibraryDependency interface 2188func (module *SdkLibraryImport) DexJarInstallPath() android.Path { 2189 return module.installFile 2190} 2191 2192// to satisfy UsesLibraryDependency interface 2193func (module *SdkLibraryImport) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap { 2194 return nil 2195} 2196 2197// to satisfy apex.javaDependency interface 2198func (module *SdkLibraryImport) JacocoReportClassesFile() android.Path { 2199 if module.implLibraryModule == nil { 2200 return nil 2201 } else { 2202 return module.implLibraryModule.JacocoReportClassesFile() 2203 } 2204} 2205 2206// to satisfy apex.javaDependency interface 2207func (module *SdkLibraryImport) Stem() string { 2208 return module.BaseModuleName() 2209} 2210 2211var _ ApexDependency = (*SdkLibraryImport)(nil) 2212 2213// to satisfy java.ApexDependency interface 2214func (module *SdkLibraryImport) HeaderJars() android.Paths { 2215 if module.implLibraryModule == nil { 2216 return nil 2217 } else { 2218 return module.implLibraryModule.HeaderJars() 2219 } 2220} 2221 2222// to satisfy java.ApexDependency interface 2223func (module *SdkLibraryImport) ImplementationAndResourcesJars() android.Paths { 2224 if module.implLibraryModule == nil { 2225 return nil 2226 } else { 2227 return module.implLibraryModule.ImplementationAndResourcesJars() 2228 } 2229} 2230 2231// to satisfy java.DexpreopterInterface interface 2232func (module *SdkLibraryImport) IsInstallable() bool { 2233 return true 2234} 2235 2236var _ android.RequiredFilesFromPrebuiltApex = (*SdkLibraryImport)(nil) 2237 2238func (module *SdkLibraryImport) RequiredFilesFromPrebuiltApex(ctx android.BaseModuleContext) []string { 2239 name := module.BaseModuleName() 2240 return requiredFilesFromPrebuiltApexForImport(name, &module.dexpreopter) 2241} 2242 2243func (j *SdkLibraryImport) UseProfileGuidedDexpreopt() bool { 2244 return proptools.Bool(j.importDexpreoptProperties.Dex_preopt.Profile_guided) 2245} 2246 2247type sdkLibrarySdkMemberType struct { 2248 android.SdkMemberTypeBase 2249} 2250 2251func (s *sdkLibrarySdkMemberType) AddDependencies(ctx android.SdkDependencyContext, dependencyTag blueprint.DependencyTag, names []string) { 2252 ctx.AddVariationDependencies(nil, dependencyTag, names...) 2253} 2254 2255func (s *sdkLibrarySdkMemberType) IsInstance(module android.Module) bool { 2256 _, ok := module.(*SdkLibrary) 2257 return ok 2258} 2259 2260func (s *sdkLibrarySdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule { 2261 return ctx.SnapshotBuilder().AddPrebuiltModule(member, "java_sdk_library_import") 2262} 2263 2264func (s *sdkLibrarySdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties { 2265 return &sdkLibrarySdkMemberProperties{} 2266} 2267 2268var javaSdkLibrarySdkMemberType = &sdkLibrarySdkMemberType{ 2269 android.SdkMemberTypeBase{ 2270 PropertyName: "java_sdk_libs", 2271 SupportsSdk: true, 2272 }, 2273} 2274 2275type sdkLibrarySdkMemberProperties struct { 2276 android.SdkMemberPropertiesBase 2277 2278 // Stem name for files in the sdk snapshot. 2279 // 2280 // This is used to construct the path names of various sdk library files in the sdk snapshot to 2281 // make sure that they match the finalized versions of those files in prebuilts/sdk. 2282 // 2283 // This property is marked as keep so that it will be kept in all instances of this struct, will 2284 // not be cleared but will be copied to common structs. That is needed because this field is used 2285 // to construct many file names for other parts of this struct and so it needs to be present in 2286 // all structs. If it was not marked as keep then it would be cleared in some structs and so would 2287 // be unavailable for generating file names if there were other properties that were still set. 2288 Stem string `sdk:"keep"` 2289 2290 // Scope to per scope properties. 2291 Scopes map[*apiScope]*scopeProperties 2292 2293 // The Java stubs source files. 2294 Stub_srcs []string 2295 2296 // The naming scheme. 2297 Naming_scheme *string 2298 2299 // True if the java_sdk_library_import is for a shared library, false 2300 // otherwise. 2301 Shared_library *bool 2302 2303 // True if the stub imports should produce dex jars. 2304 Compile_dex *bool 2305 2306 // The paths to the doctag files to add to the prebuilt. 2307 Doctag_paths android.Paths 2308 2309 Permitted_packages []string 2310 2311 // Signals that this shared library is part of the bootclasspath starting 2312 // on the version indicated in this attribute. 2313 // 2314 // This will make platforms at this level and above to ignore 2315 // <uses-library> tags with this library name because the library is already 2316 // available 2317 On_bootclasspath_since *string 2318 2319 // Signals that this shared library was part of the bootclasspath before 2320 // (but not including) the version indicated in this attribute. 2321 // 2322 // The system will automatically add a <uses-library> tag with this library to 2323 // apps that target any SDK less than the version indicated in this attribute. 2324 On_bootclasspath_before *string 2325 2326 // Indicates that PackageManager should ignore this shared library if the 2327 // platform is below the version indicated in this attribute. 2328 // 2329 // This means that the device won't recognise this library as installed. 2330 Min_device_sdk *string 2331 2332 // Indicates that PackageManager should ignore this shared library if the 2333 // platform is above the version indicated in this attribute. 2334 // 2335 // This means that the device won't recognise this library as installed. 2336 Max_device_sdk *string 2337 2338 DexPreoptProfileGuided *bool `supported_build_releases:"UpsideDownCake+"` 2339} 2340 2341type scopeProperties struct { 2342 Jars android.Paths 2343 StubsSrcJar android.Path 2344 CurrentApiFile android.Path 2345 RemovedApiFile android.Path 2346 AnnotationsZip android.Path `supported_build_releases:"Tiramisu+"` 2347 SdkVersion string 2348} 2349 2350func (s *sdkLibrarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { 2351 sdk := variant.(*SdkLibrary) 2352 2353 // Copy the stem name for files in the sdk snapshot. 2354 s.Stem = sdk.distStem() 2355 2356 s.Scopes = make(map[*apiScope]*scopeProperties) 2357 for _, apiScope := range AllApiScopes { 2358 paths := sdk.findScopePaths(apiScope) 2359 if paths == nil { 2360 continue 2361 } 2362 2363 jars := paths.stubsImplPath 2364 if len(jars) > 0 { 2365 properties := scopeProperties{} 2366 properties.Jars = jars 2367 properties.SdkVersion = sdk.sdkVersionForStubsLibrary(ctx.SdkModuleContext(), apiScope) 2368 properties.StubsSrcJar = paths.stubsSrcJar.Path() 2369 if paths.currentApiFilePath.Valid() { 2370 properties.CurrentApiFile = paths.currentApiFilePath.Path() 2371 } 2372 if paths.removedApiFilePath.Valid() { 2373 properties.RemovedApiFile = paths.removedApiFilePath.Path() 2374 } 2375 // The annotations zip is only available for modules that set annotations_enabled: true. 2376 if paths.annotationsZip.Valid() { 2377 properties.AnnotationsZip = paths.annotationsZip.Path() 2378 } 2379 s.Scopes[apiScope] = &properties 2380 } 2381 } 2382 2383 s.Shared_library = proptools.BoolPtr(sdk.sharedLibrary()) 2384 s.Compile_dex = sdk.dexProperties.Compile_dex 2385 s.Doctag_paths = sdk.doctagPaths 2386 s.Permitted_packages = sdk.PermittedPackagesForUpdatableBootJars() 2387 s.On_bootclasspath_since = sdk.commonSdkLibraryProperties.On_bootclasspath_since 2388 s.On_bootclasspath_before = sdk.commonSdkLibraryProperties.On_bootclasspath_before 2389 s.Min_device_sdk = sdk.commonSdkLibraryProperties.Min_device_sdk 2390 s.Max_device_sdk = sdk.commonSdkLibraryProperties.Max_device_sdk 2391 2392 implLibrary := sdk.implLibraryModule 2393 if implLibrary != nil && implLibrary.dexpreopter.dexpreoptProperties.Dex_preopt_result.Profile_guided { 2394 s.DexPreoptProfileGuided = proptools.BoolPtr(true) 2395 } 2396} 2397 2398func (s *sdkLibrarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) { 2399 if s.Naming_scheme != nil { 2400 propertySet.AddProperty("naming_scheme", proptools.String(s.Naming_scheme)) 2401 } 2402 if s.Shared_library != nil { 2403 propertySet.AddProperty("shared_library", *s.Shared_library) 2404 } 2405 if s.Compile_dex != nil { 2406 propertySet.AddProperty("compile_dex", *s.Compile_dex) 2407 } 2408 if len(s.Permitted_packages) > 0 { 2409 propertySet.AddProperty("permitted_packages", s.Permitted_packages) 2410 } 2411 dexPreoptSet := propertySet.AddPropertySet("dex_preopt") 2412 if s.DexPreoptProfileGuided != nil { 2413 dexPreoptSet.AddProperty("profile_guided", proptools.Bool(s.DexPreoptProfileGuided)) 2414 } 2415 2416 stem := s.Stem 2417 2418 for _, apiScope := range AllApiScopes { 2419 if properties, ok := s.Scopes[apiScope]; ok { 2420 scopeSet := propertySet.AddPropertySet(apiScope.propertyName) 2421 2422 scopeDir := apiScope.snapshotRelativeDir() 2423 2424 var jars []string 2425 for _, p := range properties.Jars { 2426 dest := filepath.Join(scopeDir, stem+"-stubs.jar") 2427 ctx.SnapshotBuilder().CopyToSnapshot(p, dest) 2428 jars = append(jars, dest) 2429 } 2430 scopeSet.AddProperty("jars", jars) 2431 2432 if ctx.SdkModuleContext().Config().IsEnvTrue("SOONG_SDK_SNAPSHOT_USE_SRCJAR") { 2433 // Copy the stubs source jar into the snapshot zip as is. 2434 srcJarSnapshotPath := filepath.Join(scopeDir, stem+".srcjar") 2435 ctx.SnapshotBuilder().CopyToSnapshot(properties.StubsSrcJar, srcJarSnapshotPath) 2436 scopeSet.AddProperty("stub_srcs", []string{srcJarSnapshotPath}) 2437 } else { 2438 // Merge the stubs source jar into the snapshot zip so that when it is unpacked 2439 // the source files are also unpacked. 2440 snapshotRelativeDir := filepath.Join(scopeDir, stem+"_stub_sources") 2441 ctx.SnapshotBuilder().UnzipToSnapshot(properties.StubsSrcJar, snapshotRelativeDir) 2442 scopeSet.AddProperty("stub_srcs", []string{snapshotRelativeDir}) 2443 } 2444 2445 if properties.CurrentApiFile != nil { 2446 currentApiSnapshotPath := apiScope.snapshotRelativeCurrentApiTxtPath(stem) 2447 ctx.SnapshotBuilder().CopyToSnapshot(properties.CurrentApiFile, currentApiSnapshotPath) 2448 scopeSet.AddProperty("current_api", currentApiSnapshotPath) 2449 } 2450 2451 if properties.RemovedApiFile != nil { 2452 removedApiSnapshotPath := apiScope.snapshotRelativeRemovedApiTxtPath(stem) 2453 ctx.SnapshotBuilder().CopyToSnapshot(properties.RemovedApiFile, removedApiSnapshotPath) 2454 scopeSet.AddProperty("removed_api", removedApiSnapshotPath) 2455 } 2456 2457 if properties.AnnotationsZip != nil { 2458 annotationsSnapshotPath := filepath.Join(scopeDir, stem+"_annotations.zip") 2459 ctx.SnapshotBuilder().CopyToSnapshot(properties.AnnotationsZip, annotationsSnapshotPath) 2460 scopeSet.AddProperty("annotations", annotationsSnapshotPath) 2461 } 2462 2463 if properties.SdkVersion != "" { 2464 scopeSet.AddProperty("sdk_version", properties.SdkVersion) 2465 } 2466 } 2467 } 2468 2469 if len(s.Doctag_paths) > 0 { 2470 dests := []string{} 2471 for _, p := range s.Doctag_paths { 2472 dest := filepath.Join("doctags", p.Rel()) 2473 ctx.SnapshotBuilder().CopyToSnapshot(p, dest) 2474 dests = append(dests, dest) 2475 } 2476 propertySet.AddProperty("doctag_files", dests) 2477 } 2478} 2479