Improve tracking of exported sdk libraries
The build tracks the java_sdk_library/_import modules that are
referenced by libraries so that it can ensure that any Android app that
includes code that depends on one of those modules has the appropriate
<uses-library> entry in their manifest.
Unfortunately, there were a couple of issues with that:
1) It only tracks direct references to the java_sdk_library module
itself, e.g. android.test.mock. Direct references to the stubs
module, e.g. android.test.mock.stubs were not tracked. Making it
possible for Android apps to reference libraries which would not be
available at runtime.
2) The logic for determining whether something was a java_sdk_library
was repeated in a number of places making it difficult to allow
java_sdk_library/_import instances to determine whether they should
be treated as an Android shared library.
3) It tracks (and could use) even those java_sdk_library instances
which do not represent a shared library, e.g. the ones that set
api_only: true. While this change will simplifty fixing that the
actual issue will be fixed in a follow up change.
Changes:
* Added EmbeddableSdkLibraryComponent and embedded it into
java_sdk_library/_import, java_library and java_import. It provides
the common code to minimize duplication. It contains an
SdkLibraryToImplicitlyTrack field that if set will cause any
references to the containing module to add the SdkLibraryParent to
the list of implicit sdk libraries being tracked.
* Changed code that assumed that anything that implemented
SdkLibraryDependency required tracking to use the
OptionalImplicitSdkLibrary() method to get the optional name of the
sdk library to track. That will allow a follow up change to return
nil from that method to exclude an sdk library from being tracked.
* Moved SdkLibraryDependency from java.go to sdk_library.go as that is
a better place for it to be.
* Changed the stubs java_library/java_import creation code to initialize
the SdkLibraryToImplicitlyTrack field with the name of the creating
module.
* Initialized the SdkLibraryToImplicitlyTrack field in the
java_sdk_library/_import so that direct references to them will be
tracked too.
* Added tests to verify that direct access to the .stubs child of both
java_sdk_library and java_sdk_library_import are tracked properly.
Test: atest CtsProviderTestCases - which relies on android.test.mock
being implicitly tracked to verify that I had not broken
anything. Used aapt2 dump badging to read the manifest.
m nothing - to run the new tests which failed before fixing the
code.
Bug: 156723295
Change-Id: Ia99def91e9b74d2ed0a777de04b476c00ea0393d
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 5efb4d0..0334f80 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -543,12 +543,18 @@
namingScheme sdkLibraryComponentNamingScheme
commonProperties commonToSdkLibraryAndImportProperties
+
+ // Functionality related to this being used as a component of a java_sdk_library.
+ EmbeddableSdkLibraryComponent
}
func (c *commonToSdkLibraryAndImport) initCommon(moduleBase *android.ModuleBase) {
c.moduleBase = moduleBase
moduleBase.AddProperties(&c.commonProperties)
+
+ // Initialize this as an sdk library component.
+ c.initSdkLibraryComponent(moduleBase)
}
func (c *commonToSdkLibraryAndImport) initCommonAfterDefaultsApplied(ctx android.DefaultableHookContext) bool {
@@ -563,6 +569,9 @@
return false
}
+ // Use the name specified in the module definition as the owner.
+ c.sdkLibraryComponentProperties.SdkLibraryToImplicitlyTrack = proptools.StringPtr(c.moduleBase.BaseModuleName())
+
return true
}
@@ -728,6 +737,84 @@
return paths.stubsHeaderPath
}
+func (c *commonToSdkLibraryAndImport) sdkComponentPropertiesForChildLibrary() interface{} {
+ componentProps := &struct {
+ SdkLibraryToImplicitlyTrack *string
+ }{
+ // Mark the stubs library as being components of this java_sdk_library so that
+ // any app that includes code which depends (directly or indirectly) on the stubs
+ // library will have the appropriate <uses-library> invocation inserted into its
+ // manifest if necessary.
+ SdkLibraryToImplicitlyTrack: proptools.StringPtr(c.moduleBase.BaseModuleName()),
+ }
+
+ return componentProps
+}
+
+// Properties related to the use of a module as an component of a java_sdk_library.
+type SdkLibraryComponentProperties struct {
+
+ // The name of the java_sdk_library/_import to add to a <uses-library> entry
+ // in the AndroidManifest.xml of any Android app that includes code that references
+ // this module. If not set then no java_sdk_library/_import is tracked.
+ SdkLibraryToImplicitlyTrack *string `blueprint:"mutated"`
+}
+
+// Structure to be embedded in a module struct that needs to support the
+// SdkLibraryComponentDependency interface.
+type EmbeddableSdkLibraryComponent struct {
+ sdkLibraryComponentProperties SdkLibraryComponentProperties
+}
+
+func (e *EmbeddableSdkLibraryComponent) initSdkLibraryComponent(moduleBase *android.ModuleBase) {
+ moduleBase.AddProperties(&e.sdkLibraryComponentProperties)
+}
+
+// to satisfy SdkLibraryComponentDependency
+func (e *EmbeddableSdkLibraryComponent) OptionalImplicitSdkLibrary() []string {
+ if e.sdkLibraryComponentProperties.SdkLibraryToImplicitlyTrack != nil {
+ return []string{*e.sdkLibraryComponentProperties.SdkLibraryToImplicitlyTrack}
+ }
+ return nil
+}
+
+// Implemented by modules that are (or possibly could be) a component of a java_sdk_library
+// (including the java_sdk_library) itself.
+type SdkLibraryComponentDependency interface {
+ // The optional name of the sdk library that should be implicitly added to the
+ // AndroidManifest of an app that contains code which references the sdk library.
+ //
+ // Returns an array containing 0 or 1 items rather than a *string to make it easier
+ // to append this to the list of exported sdk libraries.
+ OptionalImplicitSdkLibrary() []string
+}
+
+// Make sure that all the module types that are components of java_sdk_library/_import
+// and which can be referenced (directly or indirectly) from an android app implement
+// the SdkLibraryComponentDependency interface.
+var _ SdkLibraryComponentDependency = (*Library)(nil)
+var _ SdkLibraryComponentDependency = (*Import)(nil)
+var _ SdkLibraryComponentDependency = (*SdkLibrary)(nil)
+var _ SdkLibraryComponentDependency = (*sdkLibraryImport)(nil)
+
+// Provides access to sdk_version related header and implentation jars.
+type SdkLibraryDependency interface {
+ SdkLibraryComponentDependency
+
+ // Get the header jars appropriate for the supplied sdk_version.
+ //
+ // These are turbine generated jars so they only change if the externals of the
+ // class changes but it does not contain and implementation or JavaDoc.
+ SdkHeaderJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths
+
+ // Get the implementation jars appropriate for the supplied sdk version.
+ //
+ // These are either the implementation jar for the whole sdk library or the implementation
+ // jars for the stubs. The latter should only be needed when generating JavaDoc as otherwise
+ // they are identical to the corresponding header jars.
+ SdkImplementationJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths
+}
+
type SdkLibrary struct {
Library
@@ -978,7 +1065,7 @@
props.Dist.Tag = proptools.StringPtr(".jar")
}
- mctx.CreateModule(LibraryFactory, &props)
+ mctx.CreateModule(LibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
}
// Creates a droidstubs module that creates stubs source files from the given full source
@@ -1321,6 +1408,8 @@
&module.protoProperties,
)
+ module.initSdkLibraryComponent(&module.ModuleBase)
+
module.properties.Installable = proptools.BoolPtr(true)
module.deviceProperties.IsSDKLibrary = true
}
@@ -1569,7 +1658,8 @@
// The imports are preferred if the java_sdk_library_import is preferred.
props.Prefer = proptools.BoolPtr(module.prebuilt.Prefer())
- mctx.CreateModule(ImportFactory, &props)
+
+ mctx.CreateModule(ImportFactory, &props, module.sdkComponentPropertiesForChildLibrary())
}
func (module *sdkLibraryImport) createPrebuiltStubsSources(mctx android.DefaultableHookContext, apiScope *apiScope, scopeProperties *sdkLibraryScopeProperties) {