Merge "Always set targetSdkLevel to DefaultAppTargetSdk"
diff --git a/Android.bp b/Android.bp
index 342ca4c..ec7d13a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -492,6 +492,7 @@
srcs: [
"apex/androidmk.go",
"apex/apex.go",
+ "apex/apex_singleton.go",
"apex/builder.go",
"apex/key.go",
"apex/prebuilt.go",
diff --git a/android/apex.go b/android/apex.go
index 75be150..30152db 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -425,7 +425,8 @@
fullListPath OutputPath
}
-type ApexDepsInfoIntf interface {
+type ApexBundleDepsInfoIntf interface {
+ Updatable() bool
FlatListPath() Path
FullListPath() Path
}
@@ -438,8 +439,6 @@
return d.fullListPath
}
-var _ ApexDepsInfoIntf = (*ApexBundleDepsInfo)(nil)
-
// Generate two module out files:
// 1. FullList with transitive deps and their parents in the dep graph
// 2. FlatList with a flat list of transitive deps
diff --git a/apex/apex.go b/apex/apex.go
index 9659c3f..4fee6e2 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -287,7 +287,10 @@
"android.hidl.token@1.0",
"android.hidl.token@1.0-utils",
"bionic_libc_platform_headers",
+ "exoplayer2-extractor",
+ "exoplayer2-extractor-annotation-stubs",
"gl_headers",
+ "jsr305",
"libEGL",
"libEGL_blobCache",
"libEGL_getProcAddress",
@@ -542,12 +545,6 @@
// Module separator
//
m["com.android.permission"] = []string{
- "androidx.annotation_annotation",
- "androidx.annotation_annotation-nodeps",
- "androidx.lifecycle_lifecycle-common",
- "androidx.lifecycle_lifecycle-common-java8",
- "androidx.lifecycle_lifecycle-common-java8-nodeps",
- "androidx.lifecycle_lifecycle-common-nodeps",
"kotlin-annotations",
"kotlin-stdlib",
"kotlin-stdlib-jdk7",
@@ -618,13 +615,21 @@
// Module separator
//
m["com.android.tethering"] = []string{
- "libnativehelper_compat_libc++",
- "android.hardware.tetheroffload.config@1.0",
+ "android.hardware.tetheroffload.config-V1.0-java",
+ "android.hardware.tetheroffload.control-V1.0-java",
+ "android.hidl.base-V1.0-java",
+ "ipmemorystore-aidl-interfaces-java",
"libcgrouprc",
"libcgrouprc_format",
+ "libnativehelper_compat_libc++",
"libtetherutilsjni",
"libvndksupport",
+ "net-utils-framework-common",
+ "netd_aidl_interface-V3-java",
+ "netlink-client",
+ "networkstack-aidl-interfaces-java",
"tethering-aidl-interfaces-java",
+ "TetheringApiCurrentLib",
}
//
// Module separator
@@ -648,8 +653,6 @@
"android.hidl.manager-V1.0-java",
"android.hidl.manager-V1.1-java",
"android.hidl.manager-V1.2-java",
- "androidx.annotation_annotation",
- "androidx.annotation_annotation-nodeps",
"bouncycastle-unbundled",
"dnsresolver_aidl_interface-V2-java",
"error_prone_annotations",
@@ -671,7 +674,6 @@
"wifi-nano-protos",
"wifi-service-pre-jarjar",
"wifi-service-resources",
- "prebuilt_androidx.annotation_annotation-nodeps",
}
//
// Module separator
@@ -691,6 +693,15 @@
// Module separator
//
m[android.AvailableToAnyApex] = []string{
+ // TODO(b/156996905) Set apex_available/min_sdk_version for androidx/extras support libraries
+ "androidx",
+ "androidx-constraintlayout_constraintlayout",
+ "androidx-constraintlayout_constraintlayout-nodeps",
+ "androidx-constraintlayout_constraintlayout-solver",
+ "androidx-constraintlayout_constraintlayout-solver-nodeps",
+ "com.google.android.material_material",
+ "com.google.android.material_material-nodeps",
+
"libatomic",
"libclang_rt",
"libgcc_stripped",
@@ -747,7 +758,7 @@
apexBundles = []android.ApexInfo{{
ApexName: mctx.ModuleName(),
MinSdkVersion: a.minSdkVersion(mctx),
- Updatable: proptools.Bool(a.properties.Updatable),
+ Updatable: a.Updatable(),
}}
directDep = true
} else if am, ok := mctx.Module().(android.ApexModule); ok {
@@ -1451,19 +1462,7 @@
target,
a.getImageVariation(config))
}
-
- if strings.HasPrefix(ctx.ModuleName(), "com.android.runtime") && target.Os.Class == android.Device {
- for _, sanitizer := range ctx.Config().SanitizeDevice() {
- if sanitizer == "hwaddress" {
- addDependenciesForNativeModules(ctx,
- ApexNativeDependencies{[]string{"libclang_rt.hwasan-aarch64-android"}, nil, nil, nil},
- target, a.getImageVariation(config))
- break
- }
- }
- }
}
-
}
// For prebuilt_etc, use the first variant (64 on 64/32bit device,
@@ -1595,6 +1594,21 @@
return android.InList(sanitizerName, globalSanitizerNames)
}
+func (a *apexBundle) AddSanitizerDependencies(ctx android.BottomUpMutatorContext, sanitizerName string) {
+ if ctx.Device() && sanitizerName == "hwaddress" && strings.HasPrefix(a.Name(), "com.android.runtime") {
+ for _, target := range ctx.MultiTargets() {
+ if target.Arch.ArchType.Multilib == "lib64" {
+ ctx.AddFarVariationDependencies(append(target.Variations(), []blueprint.Variation{
+ {Mutator: "image", Variation: a.getImageVariation(ctx.DeviceConfig())},
+ {Mutator: "link", Variation: "shared"},
+ {Mutator: "version", Variation: ""}, // "" is the non-stub variant
+ }...), sharedLibTag, "libclang_rt.hwasan-aarch64-android")
+ break
+ }
+ }
+ }
+}
+
var _ cc.Coverage = (*apexBundle)(nil)
func (a *apexBundle) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool {
@@ -1798,6 +1812,12 @@
return intVer
}
+func (a *apexBundle) Updatable() bool {
+ return proptools.Bool(a.properties.Updatable)
+}
+
+var _ android.ApexBundleDepsInfoIntf = (*apexBundle)(nil)
+
// Ensures that the dependencies are marked as available for this APEX
func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
// Let's be practical. Availability for test, host, and the VNDK apex isn't important
@@ -1839,7 +1859,7 @@
}
func (a *apexBundle) checkUpdatable(ctx android.ModuleContext) {
- if proptools.Bool(a.properties.Updatable) {
+ if a.Updatable() {
if String(a.properties.Min_sdk_version) == "" {
ctx.PropertyErrorf("updatable", "updatable APEXes should set min_sdk_version as well")
}
@@ -2225,7 +2245,7 @@
// We don't need the optimization for updatable APEXes, as it might give false signal
// to the system health when the APEXes are still bundled (b/149805758)
- if proptools.Bool(a.properties.Updatable) && a.properties.ApexType == imageApex {
+ if a.Updatable() && a.properties.ApexType == imageApex {
a.linkToSystemLib = false
}
@@ -2291,6 +2311,10 @@
// We don't want to list them all
moduleName = "libclang_rt"
}
+ if strings.HasPrefix(moduleName, "androidx.") {
+ // TODO(b/156996905) Set apex_available/min_sdk_version for androidx support libraries
+ moduleName = "androidx"
+ }
return moduleName
}
diff --git a/apex/apex_singleton.go b/apex/apex_singleton.go
new file mode 100644
index 0000000..83a56a2
--- /dev/null
+++ b/apex/apex_singleton.go
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package apex
+
+import (
+ "github.com/google/blueprint"
+
+ "android/soong/android"
+)
+
+func init() {
+ android.RegisterSingletonType("apex_depsinfo_singleton", apexDepsInfoSingletonFactory)
+}
+
+type apexDepsInfoSingleton struct {
+ // Output file with all flatlists from updatable modules' deps-info combined
+ updatableFlatListsPath android.OutputPath
+}
+
+func apexDepsInfoSingletonFactory() android.Singleton {
+ return &apexDepsInfoSingleton{}
+}
+
+var combineFilesRule = pctx.AndroidStaticRule("combineFilesRule",
+ blueprint.RuleParams{
+ Command: "cat $out.rsp | xargs cat > $out",
+ Rspfile: "$out.rsp",
+ RspfileContent: "$in",
+ },
+)
+
+func (s *apexDepsInfoSingleton) GenerateBuildActions(ctx android.SingletonContext) {
+ updatableFlatLists := android.Paths{}
+ ctx.VisitAllModules(func(module android.Module) {
+ if binaryInfo, ok := module.(android.ApexBundleDepsInfoIntf); ok {
+ if path := binaryInfo.FlatListPath(); path != nil {
+ if binaryInfo.Updatable() {
+ updatableFlatLists = append(updatableFlatLists, path)
+ }
+ }
+ }
+ })
+
+ s.updatableFlatListsPath = android.PathForOutput(ctx, "apex", "depsinfo", "updatable-flatlists.txt")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: combineFilesRule,
+ Description: "Generate " + s.updatableFlatListsPath.String(),
+ Inputs: updatableFlatLists,
+ Output: s.updatableFlatListsPath,
+ })
+}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 3c25b52..cbe5953 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -909,6 +909,130 @@
}
+func TestRuntimeApexShouldInstallHwasanIfLibcDependsOnIt(t *testing.T) {
+ ctx, _ := testApex(t, "", func(fs map[string][]byte, config android.Config) {
+ bp := `
+ apex {
+ name: "com.android.runtime",
+ key: "com.android.runtime.key",
+ native_shared_libs: ["libc"],
+ }
+
+ apex_key {
+ name: "com.android.runtime.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ cc_library {
+ name: "libc",
+ no_libcrt: true,
+ nocrt: true,
+ stl: "none",
+ system_shared_libs: [],
+ stubs: { versions: ["1"] },
+ apex_available: ["com.android.runtime"],
+
+ sanitize: {
+ hwaddress: true,
+ }
+ }
+
+ cc_prebuilt_library_shared {
+ name: "libclang_rt.hwasan-aarch64-android",
+ no_libcrt: true,
+ nocrt: true,
+ stl: "none",
+ system_shared_libs: [],
+ srcs: [""],
+ stubs: { versions: ["1"] },
+
+ sanitize: {
+ never: true,
+ },
+ }
+ `
+ // override bp to use hard-coded names: com.android.runtime and libc
+ fs["Android.bp"] = []byte(bp)
+ fs["system/sepolicy/apex/com.android.runtime-file_contexts"] = nil
+ })
+
+ ensureExactContents(t, ctx, "com.android.runtime", "android_common_hwasan_com.android.runtime_image", []string{
+ "lib64/bionic/libc.so",
+ "lib64/bionic/libclang_rt.hwasan-aarch64-android.so",
+ })
+
+ hwasan := ctx.ModuleForTests("libclang_rt.hwasan-aarch64-android", "android_arm64_armv8-a_shared")
+
+ installed := hwasan.Description("install libclang_rt.hwasan")
+ ensureContains(t, installed.Output.String(), "/system/lib64/bootstrap/libclang_rt.hwasan-aarch64-android.so")
+
+ symlink := hwasan.Description("install symlink libclang_rt.hwasan")
+ ensureEquals(t, symlink.Args["fromPath"], "/apex/com.android.runtime/lib64/bionic/libclang_rt.hwasan-aarch64-android.so")
+ ensureContains(t, symlink.Output.String(), "/system/lib64/libclang_rt.hwasan-aarch64-android.so")
+}
+
+func TestRuntimeApexShouldInstallHwasanIfHwaddressSanitized(t *testing.T) {
+ ctx, _ := testApex(t, "", func(fs map[string][]byte, config android.Config) {
+ bp := `
+ apex {
+ name: "com.android.runtime",
+ key: "com.android.runtime.key",
+ native_shared_libs: ["libc"],
+ }
+
+ apex_key {
+ name: "com.android.runtime.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ cc_library {
+ name: "libc",
+ no_libcrt: true,
+ nocrt: true,
+ stl: "none",
+ system_shared_libs: [],
+ stubs: { versions: ["1"] },
+ apex_available: ["com.android.runtime"],
+ }
+
+ cc_prebuilt_library_shared {
+ name: "libclang_rt.hwasan-aarch64-android",
+ no_libcrt: true,
+ nocrt: true,
+ stl: "none",
+ system_shared_libs: [],
+ srcs: [""],
+ stubs: { versions: ["1"] },
+
+ sanitize: {
+ never: true,
+ },
+ }
+ `
+ // override bp to use hard-coded names: com.android.runtime and libc
+ fs["Android.bp"] = []byte(bp)
+ fs["system/sepolicy/apex/com.android.runtime-file_contexts"] = nil
+
+ config.TestProductVariables.SanitizeDevice = []string{"hwaddress"}
+ })
+
+ ensureExactContents(t, ctx, "com.android.runtime", "android_common_hwasan_com.android.runtime_image", []string{
+ "lib64/bionic/libc.so",
+ "lib64/bionic/libclang_rt.hwasan-aarch64-android.so",
+ })
+
+ hwasan := ctx.ModuleForTests("libclang_rt.hwasan-aarch64-android", "android_arm64_armv8-a_shared")
+
+ installed := hwasan.Description("install libclang_rt.hwasan")
+ ensureContains(t, installed.Output.String(), "/system/lib64/bootstrap/libclang_rt.hwasan-aarch64-android.so")
+
+ symlink := hwasan.Description("install symlink libclang_rt.hwasan")
+ ensureEquals(t, symlink.Args["fromPath"], "/apex/com.android.runtime/lib64/bionic/libclang_rt.hwasan-aarch64-android.so")
+ ensureContains(t, symlink.Output.String(), "/system/lib64/libclang_rt.hwasan-aarch64-android.so")
+}
+
func TestApexDependsOnLLNDKTransitively(t *testing.T) {
testcases := []struct {
name string
diff --git a/cc/cc.go b/cc/cc.go
index b97dba9..94512d5 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -1074,7 +1074,7 @@
func InstallToBootstrap(name string, config android.Config) bool {
if name == "libclang_rt.hwasan-aarch64-android" {
- return inList("hwaddress", config.SanitizeDevice())
+ return true
}
return isBionic(name)
}
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 3412c9b..aaaf694 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -989,6 +989,7 @@
android.Module
IsSanitizerEnabled(ctx android.BaseModuleContext, sanitizerName string) bool
EnableSanitizer(sanitizerName string)
+ AddSanitizerDependencies(ctx android.BottomUpMutatorContext, sanitizerName string)
}
// Create sanitized variants for modules that need them
@@ -1075,6 +1076,7 @@
c.sanitize.Properties.SanitizeDep = false
} else if sanitizeable, ok := mctx.Module().(Sanitizeable); ok && sanitizeable.IsSanitizerEnabled(mctx, t.name()) {
// APEX modules fall here
+ sanitizeable.AddSanitizerDependencies(mctx, t.name())
mctx.CreateVariations(t.variationName())
}
}
diff --git a/cmd/extract_apks/main.go b/cmd/extract_apks/main.go
index a638db2..e9a850e 100644
--- a/cmd/extract_apks/main.go
+++ b/cmd/extract_apks/main.go
@@ -374,6 +374,10 @@
regexp.MustCompile(`^.*/` + selected.moduleName + `(-.*\.apk)$`),
config.stem + `$1`,
},
+ {
+ regexp.MustCompile(`^universal\.apk$`),
+ config.stem + ".apk",
+ },
}
renamer := func(path string) (string, bool) {
for _, rr := range renameRules {
diff --git a/cmd/extract_apks/main_test.go b/cmd/extract_apks/main_test.go
index bc4d377..bdd4bec 100644
--- a/cmd/extract_apks/main_test.go
+++ b/cmd/extract_apks/main_test.go
@@ -24,19 +24,19 @@
"android/soong/third_party/zip"
)
-type TestConfigDesc struct {
+type testConfigDesc struct {
name string
targetConfig TargetConfig
expected SelectionResult
}
-type TestDesc struct {
+type testDesc struct {
protoText string
- configs []TestConfigDesc
+ configs []testConfigDesc
}
func TestSelectApks_ApkSet(t *testing.T) {
- testCases := []TestDesc{
+ testCases := []testDesc{
{
protoText: `
variant {
@@ -117,7 +117,7 @@
version: "0.10.3" }
`,
- configs: []TestConfigDesc{
+ configs: []testConfigDesc{
{
name: "one",
targetConfig: TargetConfig{
@@ -209,7 +209,7 @@
value { min { value: 21 } } } }
path: "splits/base-master.apk"
split_apk_metadata { is_master_split: true } } } }`,
- configs: []TestConfigDesc{
+ configs: []testConfigDesc{
{
name: "Prerelease",
targetConfig: TargetConfig{
@@ -225,6 +225,30 @@
},
},
},
+ {
+ protoText: `
+variant {
+ targeting {
+ sdk_version_targeting {
+ value { min { value: 29 } } } }
+ apk_set {
+ module_metadata {
+ name: "base" targeting {} delivery_type: INSTALL_TIME }
+ apk_description {
+ targeting {}
+ path: "universal.apk"
+ standalone_apk_metadata { fused_module_name: "base" } } } }`,
+ configs: []testConfigDesc{
+ {
+ name: "Universal",
+ targetConfig: TargetConfig{sdkVersion: 30},
+ expected: SelectionResult{
+ "base",
+ []string{"universal.apk"},
+ },
+ },
+ },
+ },
}
for _, testCase := range testCases {
var toc bp.BuildApksResult
@@ -241,7 +265,7 @@
}
func TestSelectApks_ApexSet(t *testing.T) {
- testCases := []TestDesc{
+ testCases := []testDesc{
{
protoText: `
variant {
@@ -300,7 +324,7 @@
version: "0.10.3" }
`,
- configs: []TestConfigDesc{
+ configs: []testConfigDesc{
{
name: "order matches priorities",
targetConfig: TargetConfig{
@@ -406,24 +430,48 @@
return nil
}
-func TestWriteZip(t *testing.T) {
+type testCaseWriteZip struct {
+ name string
+ moduleName string
+ stem string
// what we write from what
- expected := map[string]string{
- "Foo.apk": "splits/mybase-master.apk",
- "Foo-xhdpi.apk": "splits/mybase-xhdpi.apk",
+ expected map[string]string
+}
+
+func TestWriteZip(t *testing.T) {
+ testCases := []testCaseWriteZip{
+ {
+ name: "splits",
+ moduleName: "mybase",
+ stem: "Foo",
+ expected: map[string]string{
+ "Foo.apk": "splits/mybase-master.apk",
+ "Foo-xhdpi.apk": "splits/mybase-xhdpi.apk",
+ },
+ },
+ {
+ name: "universal",
+ moduleName: "base",
+ stem: "Bar",
+ expected: map[string]string{
+ "Bar.apk": "universal.apk",
+ },
+ },
}
- apkSet := ApkSet{entries: make(map[string]*zip.File)}
- sel := SelectionResult{moduleName: "mybase"}
- for _, in := range expected {
- apkSet.entries[in] = &zip.File{FileHeader: zip.FileHeader{Name: in}}
- sel.entries = append(sel.entries, in)
- }
- writer := testZip2ZipWriter{make(map[string]string)}
- config := TargetConfig{stem: "Foo"}
- if err := apkSet.writeApks(sel, config, writer); err != nil {
- t.Error(err)
- }
- if !reflect.DeepEqual(expected, writer.entries) {
- t.Errorf("expected %v, got %v", expected, writer.entries)
+ for _, testCase := range testCases {
+ apkSet := ApkSet{entries: make(map[string]*zip.File)}
+ sel := SelectionResult{moduleName: testCase.moduleName}
+ for _, in := range testCase.expected {
+ apkSet.entries[in] = &zip.File{FileHeader: zip.FileHeader{Name: in}}
+ sel.entries = append(sel.entries, in)
+ }
+ writer := testZip2ZipWriter{make(map[string]string)}
+ config := TargetConfig{stem: testCase.stem}
+ if err := apkSet.writeApks(sel, config, writer); err != nil {
+ t.Error(err)
+ }
+ if !reflect.DeepEqual(testCase.expected, writer.entries) {
+ t.Errorf("expected %v, got %v", testCase.expected, writer.entries)
+ }
}
}
diff --git a/java/aar.go b/java/aar.go
index 6e3b9e6..c8daf83 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -379,8 +379,11 @@
sharedLibs = append(sharedLibs, exportPackage)
}
- if _, ok := module.(SdkLibraryDependency); ok {
- sdkLibraries = append(sdkLibraries, ctx.OtherModuleName(module))
+ // If the module is (or possibly could be) a component of a java_sdk_library
+ // (including the java_sdk_library) itself then append any implicit sdk library
+ // names to the list of sdk libraries to be added to the manifest.
+ if component, ok := module.(SdkLibraryComponentDependency); ok {
+ sdkLibraries = append(sdkLibraries, component.OptionalImplicitSdkLibrary()...)
}
case frameworkResTag:
@@ -513,6 +516,7 @@
module.androidLibraryProperties.BuildAAR = true
+ android.InitApexModule(module)
InitJavaModule(module, android.DeviceSupported)
return module
}
@@ -537,8 +541,12 @@
type AARImport struct {
android.ModuleBase
android.DefaultableModuleBase
+ android.ApexModuleBase
prebuilt android.Prebuilt
+ // Functionality common to Module and Import.
+ embeddableInModuleAndImport
+
properties AARImportProperties
classpathFile android.WritablePath
@@ -742,6 +750,10 @@
return nil, nil
}
+func (a *AARImport) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
+ return a.depIsInSameApex(ctx, dep)
+}
+
var _ android.PrebuiltInterface = (*Import)(nil)
// android_library_import imports an `.aar` file into the build graph as if it was built with android_library.
@@ -754,6 +766,7 @@
module.AddProperties(&module.properties)
android.InitPrebuiltModule(module, &module.properties.Aars)
+ android.InitApexModule(module)
InitJavaModule(module, android.DeviceSupported)
return module
}
diff --git a/java/androidmk.go b/java/androidmk.go
index ba1af0d..6747b30 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -211,6 +211,11 @@
}
func (prebuilt *AARImport) AndroidMkEntries() []android.AndroidMkEntries {
+ if !prebuilt.IsForPlatform() {
+ return []android.AndroidMkEntries{{
+ Disabled: true,
+ }}
+ }
return []android.AndroidMkEntries{android.AndroidMkEntries{
Class: "JAVA_LIBRARIES",
OutputFile: android.OptionalPathForPath(prebuilt.classpathFile),
@@ -416,6 +421,11 @@
}
func (a *AndroidLibrary) AndroidMkEntries() []android.AndroidMkEntries {
+ if !a.IsForPlatform() {
+ return []android.AndroidMkEntries{{
+ Disabled: true,
+ }}
+ }
entriesList := a.Library.AndroidMkEntries()
entries := &entriesList[0]
diff --git a/java/app.go b/java/app.go
index 215b07b..8241b68 100755
--- a/java/app.go
+++ b/java/app.go
@@ -414,7 +414,7 @@
}
func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) {
- if Bool(a.appProperties.Updatable) || a.ApexModuleBase.Updatable() {
+ if a.Updatable() {
if !a.sdkVersion().stable() {
ctx.PropertyErrorf("sdk_version", "Updatable apps must use stable SDKs, found %v", a.sdkVersion())
}
@@ -897,6 +897,10 @@
a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(), depsInfo)
}
+func (a *AndroidApp) Updatable() bool {
+ return Bool(a.appProperties.Updatable) || a.ApexModuleBase.Updatable()
+}
+
func (a *AndroidApp) getCertString(ctx android.BaseModuleContext) string {
certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(ctx.ModuleName())
if overridden {
@@ -1257,6 +1261,8 @@
usesLibrary usesLibrary
+ preprocessed bool
+
installPath android.InstallPath
}
@@ -1272,6 +1278,9 @@
// be set for presigned modules.
Presigned *bool
+ // Name of the signing certificate lineage file.
+ Lineage *string
+
// Sign with the default system dev certificate. Must be used judiciously. Most imported apps
// need to either specify a specific certificate or be presigned.
Default_dev_cert *bool
@@ -1346,7 +1355,7 @@
ctx android.ModuleContext, inputPath android.Path, outputPath android.OutputPath) {
// Test apps don't need their JNI libraries stored uncompressed. As a matter of fact, messing
// with them may invalidate pre-existing signature data.
- if ctx.InstallInTestcases() && Bool(a.properties.Presigned) {
+ if ctx.InstallInTestcases() && (Bool(a.properties.Presigned) || a.preprocessed) {
ctx.Build(pctx, android.BuildParams{
Rule: android.Cp,
Output: outputPath,
@@ -1367,7 +1376,7 @@
// Returns whether this module should have the dex file stored uncompressed in the APK.
func (a *AndroidAppImport) shouldUncompressDex(ctx android.ModuleContext) bool {
- if ctx.Config().UnbundledBuild() {
+ if ctx.Config().UnbundledBuild() || a.preprocessed {
return false
}
@@ -1459,9 +1468,13 @@
apkFilename := proptools.StringDefault(a.properties.Filename, a.BaseModuleName()+".apk")
- // Sign or align the package
// TODO: Handle EXTERNAL
- if !Bool(a.properties.Presigned) {
+
+ // Sign or align the package if package has not been preprocessed
+ if a.preprocessed {
+ a.outputFile = srcApk
+ a.certificate = presignedCertificate
+ } else if !Bool(a.properties.Presigned) {
// If the certificate property is empty at this point, default_dev_cert must be set to true.
// Which makes processMainCert's behavior for the empty cert string WAI.
certificates = processMainCert(a.ModuleBase, String(a.properties.Certificate), certificates, ctx)
@@ -1470,7 +1483,11 @@
}
a.certificate = certificates[0]
signed := android.PathForModuleOut(ctx, "signed", apkFilename)
- SignAppPackage(ctx, signed, dexOutput, certificates, nil)
+ var lineageFile android.Path
+ if lineage := String(a.properties.Lineage); lineage != "" {
+ lineageFile = android.PathForModuleSrc(ctx, lineage)
+ }
+ SignAppPackage(ctx, signed, dexOutput, certificates, lineageFile)
a.outputFile = signed
} else {
alignedApk := android.PathForModuleOut(ctx, "zip-aligned", apkFilename)
@@ -1602,15 +1619,24 @@
return module
}
+type androidTestImportProperties struct {
+ // Whether the prebuilt apk can be installed without additional processing. Default is false.
+ Preprocessed *bool
+}
+
type AndroidTestImport struct {
AndroidAppImport
testProperties testProperties
+ testImportProperties androidTestImportProperties
+
data android.Paths
}
func (a *AndroidTestImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ a.preprocessed = Bool(a.testImportProperties.Preprocessed)
+
a.generateAndroidBuildActions(ctx)
a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
@@ -1628,6 +1654,7 @@
module.AddProperties(&module.dexpreoptProperties)
module.AddProperties(&module.usesLibrary.usesLibraryProperties)
module.AddProperties(&module.testProperties)
+ module.AddProperties(&module.testImportProperties)
module.populateAllVariantStructs()
android.AddLoadHook(module, func(ctx android.LoadHookContext) {
module.processVariants(ctx)
diff --git a/java/app_test.go b/java/app_test.go
index 2195afd..1a718f4 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -2071,6 +2071,27 @@
}
}
+func TestAndroidAppImport_SigningLineage(t *testing.T) {
+ ctx, _ := testJava(t, `
+ android_app_import {
+ name: "foo",
+ apk: "prebuilts/apk/app.apk",
+ certificate: "platform",
+ lineage: "lineage.bin",
+ }
+ `)
+
+ variant := ctx.ModuleForTests("foo", "android_common")
+
+ // Check cert signing lineage flag.
+ signedApk := variant.Output("signed/foo.apk")
+ signingFlag := signedApk.Args["flags"]
+ expected := "--lineage lineage.bin"
+ if expected != signingFlag {
+ t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
+ }
+}
+
func TestAndroidAppImport_DefaultDevCert(t *testing.T) {
ctx, _ := testJava(t, `
android_app_import {
@@ -2348,6 +2369,45 @@
if jniRule != android.Cp.String() {
t.Errorf("Unexpected JNI uncompress rule: " + jniRule)
}
+ if variant.MaybeOutput("zip-aligned/foo_presigned.apk").Rule == nil {
+ t.Errorf("Presigned test apk should be aligned")
+ }
+}
+
+func TestAndroidTestImport_Preprocessed(t *testing.T) {
+ ctx, _ := testJava(t, `
+ android_test_import {
+ name: "foo",
+ apk: "prebuilts/apk/app.apk",
+ presigned: true,
+ preprocessed: true,
+ }
+
+ android_test_import {
+ name: "foo_cert",
+ apk: "prebuilts/apk/app.apk",
+ certificate: "cert/new_cert",
+ preprocessed: true,
+ }
+ `)
+
+ testModules := []string{"foo", "foo_cert"}
+ for _, m := range testModules {
+ apkName := m + ".apk"
+ variant := ctx.ModuleForTests(m, "android_common")
+ jniRule := variant.Output("jnis-uncompressed/" + apkName).BuildParams.Rule.String()
+ if jniRule != android.Cp.String() {
+ t.Errorf("Unexpected JNI uncompress rule: " + jniRule)
+ }
+
+ // Make sure signing and aligning were skipped.
+ if variant.MaybeOutput("signed/"+apkName).Rule != nil {
+ t.Errorf("signing rule shouldn't be included for preprocessed.")
+ }
+ if variant.MaybeOutput("zip-aligned/"+apkName).Rule != nil {
+ t.Errorf("aligning rule shouldn't be for preprocessed")
+ }
+ }
}
func TestStl(t *testing.T) {
@@ -2423,6 +2483,20 @@
}
java_sdk_library {
+ name: "qux",
+ srcs: ["a.java"],
+ api_packages: ["qux"],
+ sdk_version: "current",
+ }
+
+ java_sdk_library {
+ name: "quuz",
+ srcs: ["a.java"],
+ api_packages: ["quuz"],
+ sdk_version: "current",
+ }
+
+ java_sdk_library {
name: "bar",
srcs: ["a.java"],
api_packages: ["bar"],
@@ -2432,6 +2506,7 @@
android_app {
name: "app",
srcs: ["a.java"],
+ libs: ["qux", "quuz.stubs"],
uses_libs: ["foo"],
sdk_version: "current",
optional_uses_libs: [
@@ -2462,6 +2537,15 @@
app := ctx.ModuleForTests("app", "android_common")
prebuilt := ctx.ModuleForTests("prebuilt", "android_common")
+ // Test that implicit dependencies on java_sdk_library instances are passed to the manifest.
+ manifestFixerArgs := app.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
+ if w := "--uses-library qux"; !strings.Contains(manifestFixerArgs, w) {
+ t.Errorf("unexpected manifest_fixer args: wanted %q in %q", w, manifestFixerArgs)
+ }
+ if w := "--uses-library quuz"; !strings.Contains(manifestFixerArgs, w) {
+ t.Errorf("unexpected manifest_fixer args: wanted %q in %q", w, manifestFixerArgs)
+ }
+
// Test that all libraries are verified
cmd := app.Rule("verify_uses_libraries").RuleParams.Command
if w := "--uses-library foo"; !strings.Contains(cmd, w) {
diff --git a/java/dexpreopt_bootjars_test.go b/java/dexpreopt_bootjars_test.go
index feee91a..e9704dc 100644
--- a/java/dexpreopt_bootjars_test.go
+++ b/java/dexpreopt_bootjars_test.go
@@ -116,43 +116,15 @@
func TestDexpreoptBootZip(t *testing.T) {
ruleFile := "boot.zip"
- expectedInputs := []string{
- "dex_bootjars/android/system/framework/arm/boot-foo.art",
- "dex_bootjars/android/system/framework/arm/boot-bar.art",
- "dex_bootjars/android/system/framework/arm/boot-baz.art",
- "dex_bootjars/android/system/framework/arm/boot-foo.oat",
- "dex_bootjars/android/system/framework/arm/boot-bar.oat",
- "dex_bootjars/android/system/framework/arm/boot-baz.oat",
- "dex_bootjars/android/system/framework/arm/boot-foo.vdex",
- "dex_bootjars/android/system/framework/arm/boot-bar.vdex",
- "dex_bootjars/android/system/framework/arm/boot-baz.vdex",
- "dex_bootjars/android/system/framework/arm64/boot-foo.art",
- "dex_bootjars/android/system/framework/arm64/boot-bar.art",
- "dex_bootjars/android/system/framework/arm64/boot-baz.art",
- "dex_bootjars/android/system/framework/arm64/boot-foo.oat",
- "dex_bootjars/android/system/framework/arm64/boot-bar.oat",
- "dex_bootjars/android/system/framework/arm64/boot-baz.oat",
- "dex_bootjars/android/system/framework/arm64/boot-foo.vdex",
- "dex_bootjars/android/system/framework/arm64/boot-bar.vdex",
- "dex_bootjars/android/system/framework/arm64/boot-baz.vdex",
- "dex_bootjars/linux_glibc/system/framework/x86/boot-foo.art",
- "dex_bootjars/linux_glibc/system/framework/x86/boot-bar.art",
- "dex_bootjars/linux_glibc/system/framework/x86/boot-baz.art",
- "dex_bootjars/linux_glibc/system/framework/x86/boot-foo.oat",
- "dex_bootjars/linux_glibc/system/framework/x86/boot-bar.oat",
- "dex_bootjars/linux_glibc/system/framework/x86/boot-baz.oat",
- "dex_bootjars/linux_glibc/system/framework/x86/boot-foo.vdex",
- "dex_bootjars/linux_glibc/system/framework/x86/boot-bar.vdex",
- "dex_bootjars/linux_glibc/system/framework/x86/boot-baz.vdex",
- "dex_bootjars/linux_glibc/system/framework/x86_64/boot-foo.art",
- "dex_bootjars/linux_glibc/system/framework/x86_64/boot-bar.art",
- "dex_bootjars/linux_glibc/system/framework/x86_64/boot-baz.art",
- "dex_bootjars/linux_glibc/system/framework/x86_64/boot-foo.oat",
- "dex_bootjars/linux_glibc/system/framework/x86_64/boot-bar.oat",
- "dex_bootjars/linux_glibc/system/framework/x86_64/boot-baz.oat",
- "dex_bootjars/linux_glibc/system/framework/x86_64/boot-foo.vdex",
- "dex_bootjars/linux_glibc/system/framework/x86_64/boot-bar.vdex",
- "dex_bootjars/linux_glibc/system/framework/x86_64/boot-baz.vdex",
+ ctx := android.PathContextForTesting(testConfig(nil, "", nil))
+ expectedInputs := []string{}
+ for _, target := range dexpreoptTargets(ctx) {
+ for _, ext := range []string{".art", ".oat", ".vdex"} {
+ for _, jar := range []string{"foo", "bar", "baz"} {
+ expectedInputs = append(expectedInputs,
+ filepath.Join("dex_bootjars", target.Os.String(), "system/framework", target.Arch.ArchType.String(), "boot-"+jar+ext))
+ }
+ }
}
expectedOutputs := []string{
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 414882c..a5a6785 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -351,11 +351,16 @@
ApiFilePath() android.Path
}
+type ApiStubsSrcProvider interface {
+ StubsSrcJar() android.Path
+}
+
// Provider of information about API stubs, used by java_sdk_library.
type ApiStubsProvider interface {
ApiFilePath
RemovedApiFilePath() android.Path
- StubsSrcJar() android.Path
+
+ ApiStubsSrcProvider
}
//
@@ -1932,6 +1937,10 @@
}
}
+func (d *PrebuiltStubsSources) StubsSrcJar() android.Path {
+ return d.stubsSrcJar
+}
+
func (p *PrebuiltStubsSources) GenerateAndroidBuildActions(ctx android.ModuleContext) {
p.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
diff --git a/java/hiddenapi.go b/java/hiddenapi.go
index 884a757..ce624bf 100644
--- a/java/hiddenapi.go
+++ b/java/hiddenapi.go
@@ -180,7 +180,9 @@
// b/149353192: when a module is instrumented, jacoco adds synthetic members
// $jacocoData and $jacocoInit. Since they don't exist when building the hidden API flags,
// don't complain when we don't find hidden API flags for the synthetic members.
- if j, ok := ctx.Module().(*Library); ok && j.shouldInstrument(ctx) {
+ if j, ok := ctx.Module().(interface {
+ shouldInstrument(android.BaseModuleContext) bool
+ }); ok && j.shouldInstrument(ctx) {
enforceHiddenApiFlagsToAllMembers = false
}
diff --git a/java/java.go b/java/java.go
index 5b1dcd7..b97defa 100644
--- a/java/java.go
+++ b/java/java.go
@@ -351,7 +351,17 @@
}
// Functionality common to Module and Import
+//
+// It is embedded in Module so its functionality can be used by methods in Module
+// but it is currently only initialized by Import and Library.
type embeddableInModuleAndImport struct {
+
+ // Functionality related to this being used as a component of a java_sdk_library.
+ EmbeddableSdkLibraryComponent
+}
+
+func (e *embeddableInModuleAndImport) initModuleAndImport(moduleBase *android.ModuleBase) {
+ e.initSdkLibraryComponent(moduleBase)
}
// Module/Import's DepIsInSameApex(...) delegates to this method.
@@ -492,11 +502,6 @@
JacocoReportClassesFile() android.Path
}
-type SdkLibraryDependency interface {
- SdkHeaderJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths
- SdkImplementationJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths
-}
-
type xref interface {
XrefJavaFiles() android.Paths
}
@@ -926,6 +931,12 @@
}
}
+ // If this is a component library (stubs, etc.) for a java_sdk_library then
+ // add the name of that java_sdk_library to the exported sdk libs to make sure
+ // that, if necessary, a <uses-library> element for that java_sdk_library is
+ // added to the Android manifest.
+ j.exportedSdkLibs = append(j.exportedSdkLibs, j.OptionalImplicitSdkLibrary()...)
+
ctx.VisitDirectDeps(func(module android.Module) {
otherName := ctx.OtherModuleName(module)
tag := ctx.OtherModuleDependencyTag(module)
@@ -945,7 +956,7 @@
case libTag:
deps.classpath = append(deps.classpath, dep.SdkHeaderJars(ctx, j.sdkVersion())...)
// names of sdk libs that are directly depended are exported
- j.exportedSdkLibs = append(j.exportedSdkLibs, otherName)
+ j.exportedSdkLibs = append(j.exportedSdkLibs, dep.OptionalImplicitSdkLibrary()...)
case staticLibTag:
ctx.ModuleErrorf("dependency on java_sdk_library %q can only be in libs", otherName)
}
@@ -1986,6 +1997,8 @@
&module.Module.protoProperties,
&module.libraryProperties)
+ module.initModuleAndImport(&module.ModuleBase)
+
android.InitApexModule(module)
android.InitSdkAwareModule(module)
InitJavaModule(module, android.HostAndDeviceSupported)
@@ -2458,6 +2471,12 @@
}
j.combinedClasspathFile = outputFile
+ // If this is a component library (impl, stubs, etc.) for a java_sdk_library then
+ // add the name of that java_sdk_library to the exported sdk libs to make sure
+ // that, if necessary, a <uses-library> element for that java_sdk_library is
+ // added to the Android manifest.
+ j.exportedSdkLibs = append(j.exportedSdkLibs, j.OptionalImplicitSdkLibrary()...)
+
ctx.VisitDirectDeps(func(module android.Module) {
otherName := ctx.OtherModuleName(module)
tag := ctx.OtherModuleDependencyTag(module)
@@ -2576,6 +2595,8 @@
module.AddProperties(&module.properties)
+ module.initModuleAndImport(&module.ModuleBase)
+
android.InitPrebuiltModule(module, &module.properties.Jars)
android.InitApexModule(module)
android.InitSdkAwareModule(module)
diff --git a/java/java_test.go b/java/java_test.go
index f61f4bb..ab6d88e 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -19,6 +19,7 @@
"os"
"path/filepath"
"reflect"
+ "sort"
"strconv"
"strings"
"testing"
@@ -575,6 +576,7 @@
},
test: {
jars: ["c.jar"],
+ stub_srcs: ["c.java"],
},
}
`)
@@ -1152,13 +1154,42 @@
java_library {
name: "baz",
srcs: ["c.java"],
- libs: ["foo", "bar"],
+ libs: ["foo", "bar.stubs"],
sdk_version: "system_current",
}
+ java_sdk_library {
+ name: "barney",
+ srcs: ["c.java"],
+ api_only: true,
+ }
+ java_sdk_library {
+ name: "betty",
+ srcs: ["c.java"],
+ shared_library: false,
+ }
+ java_sdk_library_import {
+ name: "quuz",
+ public: {
+ jars: ["c.jar"],
+ },
+ }
+ java_sdk_library_import {
+ name: "fred",
+ public: {
+ jars: ["b.jar"],
+ },
+ }
+ java_sdk_library_import {
+ name: "wilma",
+ public: {
+ jars: ["b.jar"],
+ },
+ shared_library: false,
+ }
java_library {
name: "qux",
srcs: ["c.java"],
- libs: ["baz"],
+ libs: ["baz", "fred", "quuz.stubs", "wilma", "barney", "betty"],
sdk_version: "system_current",
}
java_library {
@@ -1223,12 +1254,120 @@
qux := ctx.ModuleForTests("qux", "android_common")
if quxLib, ok := qux.Module().(*Library); ok {
sdkLibs := quxLib.ExportedSdkLibs()
- if len(sdkLibs) != 2 || !android.InList("foo", sdkLibs) || !android.InList("bar", sdkLibs) {
- t.Errorf("qux should export \"foo\" and \"bar\" but exports %v", sdkLibs)
+ sort.Strings(sdkLibs)
+ if w := []string{"bar", "foo", "fred", "quuz"}; !reflect.DeepEqual(w, sdkLibs) {
+ t.Errorf("qux should export %q but exports %q", w, sdkLibs)
}
}
}
+func TestJavaSdkLibrary_UseSourcesFromAnotherSdkLibrary(t *testing.T) {
+ testJava(t, `
+ java_sdk_library {
+ name: "foo",
+ srcs: ["a.java"],
+ api_packages: ["foo"],
+ public: {
+ enabled: true,
+ },
+ }
+
+ java_library {
+ name: "bar",
+ srcs: ["b.java", ":foo{.public.stubs.source}"],
+ }
+ `)
+}
+
+func TestJavaSdkLibrary_AccessOutputFiles_MissingScope(t *testing.T) {
+ testJavaError(t, `"foo" does not provide api scope system`, `
+ java_sdk_library {
+ name: "foo",
+ srcs: ["a.java"],
+ api_packages: ["foo"],
+ public: {
+ enabled: true,
+ },
+ }
+
+ java_library {
+ name: "bar",
+ srcs: ["b.java", ":foo{.system.stubs.source}"],
+ }
+ `)
+}
+
+func TestJavaSdkLibraryImport_AccessOutputFiles(t *testing.T) {
+ testJava(t, `
+ java_sdk_library_import {
+ name: "foo",
+ public: {
+ jars: ["a.jar"],
+ stub_srcs: ["a.java"],
+ current_api: "api/current.txt",
+ removed_api: "api/removed.txt",
+ },
+ }
+
+ java_library {
+ name: "bar",
+ srcs: [":foo{.public.stubs.source}"],
+ java_resources: [
+ ":foo{.public.api.txt}",
+ ":foo{.public.removed-api.txt}",
+ ],
+ }
+ `)
+}
+
+func TestJavaSdkLibraryImport_AccessOutputFiles_Invalid(t *testing.T) {
+ bp := `
+ java_sdk_library_import {
+ name: "foo",
+ public: {
+ jars: ["a.jar"],
+ },
+ }
+ `
+
+ t.Run("stubs.source", func(t *testing.T) {
+ testJavaError(t, `stubs.source not available for api scope public`, bp+`
+ java_library {
+ name: "bar",
+ srcs: [":foo{.public.stubs.source}"],
+ java_resources: [
+ ":foo{.public.api.txt}",
+ ":foo{.public.removed-api.txt}",
+ ],
+ }
+ `)
+ })
+
+ t.Run("api.txt", func(t *testing.T) {
+ testJavaError(t, `api.txt not available for api scope public`, bp+`
+ java_library {
+ name: "bar",
+ srcs: ["a.java"],
+ java_resources: [
+ ":foo{.public.api.txt}",
+ ],
+ }
+ `)
+ })
+
+ t.Run("removed-api.txt", func(t *testing.T) {
+ testJavaError(t, `removed-api.txt not available for api scope public`, bp+`
+ java_library {
+ name: "bar",
+ srcs: ["a.java"],
+ java_resources: [
+ ":foo{.public.removed-api.txt}",
+ ],
+ }
+ `)
+ })
+}
+
func TestJavaSdkLibrary_InvalidScopes(t *testing.T) {
testJavaError(t, `module "foo": enabled api scope "system" depends on disabled scope "public"`, `
java_sdk_library {
@@ -1261,6 +1400,45 @@
`)
}
+func TestJavaSdkLibrary_MissingScope(t *testing.T) {
+ testJavaError(t, `requires api scope module-lib from foo but it only has \[\] available`, `
+ java_sdk_library {
+ name: "foo",
+ srcs: ["a.java"],
+ public: {
+ enabled: false,
+ },
+ }
+
+ java_library {
+ name: "baz",
+ srcs: ["a.java"],
+ libs: ["foo"],
+ sdk_version: "module_current",
+ }
+ `)
+}
+
+func TestJavaSdkLibrary_FallbackScope(t *testing.T) {
+ testJava(t, `
+ java_sdk_library {
+ name: "foo",
+ srcs: ["a.java"],
+ system: {
+ enabled: true,
+ },
+ }
+
+ java_library {
+ name: "baz",
+ srcs: ["a.java"],
+ libs: ["foo"],
+ // foo does not have module-lib scope so it should fallback to system
+ sdk_version: "module_current",
+ }
+ `)
+}
+
var compilerFlagsTestCases = []struct {
in string
out bool
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 61bb106..8231278 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -19,6 +19,7 @@
"path"
"path/filepath"
"reflect"
+ "regexp"
"sort"
"strings"
"sync"
@@ -145,6 +146,8 @@
// Initialize a scope, creating and adding appropriate dependency tags
func initApiScope(scope *apiScope) *apiScope {
name := scope.name
+ scopeByName[name] = scope
+ allScopeNames = append(allScopeNames, name)
scope.propertyName = strings.ReplaceAll(name, "-", "_")
scope.fieldName = proptools.FieldNameForProperty(scope.propertyName)
scope.stubsTag = scopeDependencyTag{
@@ -217,6 +220,8 @@
}
var (
+ scopeByName = make(map[string]*apiScope)
+ allScopeNames []string
apiScopePublic = initApiScope(&apiScope{
name: "public",
@@ -367,7 +372,10 @@
// Defaults to "api".
Api_dir *string
- // If set to true there is no runtime library.
+ // Determines whether a runtime implementation library is built; defaults to false.
+ //
+ // If true then it also prevents the module from being used as a shared module, i.e.
+ // it is as is shared_library: false, was set.
Api_only *bool
// local files that are used within user customized droiddoc options.
@@ -433,12 +441,30 @@
//Html_doc *bool
}
+// Paths to outputs from java_sdk_library and java_sdk_library_import.
+//
+// Fields that are android.Paths are always set (during GenerateAndroidBuildActions).
+// OptionalPaths are always set by java_sdk_library but may not be set by
+// java_sdk_library_import as not all instances provide that information.
type scopePaths struct {
- stubsHeaderPath android.Paths
- stubsImplPath android.Paths
- currentApiFilePath android.Path
- removedApiFilePath android.Path
- stubsSrcJar android.Path
+ // The path (represented as Paths for convenience when returning) to the stubs header jar.
+ //
+ // That is the jar that is created by turbine.
+ stubsHeaderPath android.Paths
+
+ // The path (represented as Paths for convenience when returning) to the stubs implementation jar.
+ //
+ // This is not the implementation jar, it still only contains stubs.
+ stubsImplPath android.Paths
+
+ // The API specification file, e.g. system_current.txt.
+ currentApiFilePath android.OptionalPath
+
+ // The specification of API elements removed since the last release.
+ removedApiFilePath android.OptionalPath
+
+ // The stubs source jar.
+ stubsSrcJar android.OptionalPath
}
func (paths *scopePaths) extractStubsLibraryInfoFromDependency(dep android.Module) error {
@@ -460,9 +486,18 @@
}
}
+func (paths *scopePaths) treatDepAsApiStubsSrcProvider(dep android.Module, action func(provider ApiStubsSrcProvider)) error {
+ if apiStubsProvider, ok := dep.(ApiStubsSrcProvider); ok {
+ action(apiStubsProvider)
+ return nil
+ } else {
+ return fmt.Errorf("expected module that implements ApiStubsSrcProvider, e.g. droidstubs")
+ }
+}
+
func (paths *scopePaths) extractApiInfoFromApiStubsProvider(provider ApiStubsProvider) {
- paths.currentApiFilePath = provider.ApiFilePath()
- paths.removedApiFilePath = provider.RemovedApiFilePath()
+ paths.currentApiFilePath = android.OptionalPathForPath(provider.ApiFilePath())
+ paths.removedApiFilePath = android.OptionalPathForPath(provider.RemovedApiFilePath())
}
func (paths *scopePaths) extractApiInfoFromDep(dep android.Module) error {
@@ -471,12 +506,12 @@
})
}
-func (paths *scopePaths) extractStubsSourceInfoFromApiStubsProviders(provider ApiStubsProvider) {
- paths.stubsSrcJar = provider.StubsSrcJar()
+func (paths *scopePaths) extractStubsSourceInfoFromApiStubsProviders(provider ApiStubsSrcProvider) {
+ paths.stubsSrcJar = android.OptionalPathForPath(provider.StubsSrcJar())
}
func (paths *scopePaths) extractStubsSourceInfoFromDep(dep android.Module) error {
- return paths.treatDepAsApiStubsProvider(dep, func(provider ApiStubsProvider) {
+ return paths.treatDepAsApiStubsSrcProvider(dep, func(provider ApiStubsSrcProvider) {
paths.extractStubsSourceInfoFromApiStubsProviders(provider)
})
}
@@ -500,6 +535,13 @@
//
// TODO(b/155480189) - Remove once naming inconsistencies have been resolved.
Naming_scheme *string
+
+ // Specifies whether this module can be used as an Android shared library; defaults
+ // to true.
+ //
+ // An Android shared library is one that can be referenced in a <uses-library> element
+ // in an AndroidManifest.xml.
+ Shared_library *bool
}
// Common code between sdk library and sdk library import
@@ -510,17 +552,23 @@
namingScheme sdkLibraryComponentNamingScheme
- commonProperties commonToSdkLibraryAndImportProperties
+ commonSdkLibraryProperties 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)
+ moduleBase.AddProperties(&c.commonSdkLibraryProperties)
+
+ // Initialize this as an sdk library component.
+ c.initSdkLibraryComponent(moduleBase)
}
func (c *commonToSdkLibraryAndImport) initCommonAfterDefaultsApplied(ctx android.DefaultableHookContext) bool {
- schemeProperty := proptools.StringDefault(c.commonProperties.Naming_scheme, "default")
+ schemeProperty := proptools.StringDefault(c.commonSdkLibraryProperties.Naming_scheme, "default")
switch schemeProperty {
case "default":
c.namingScheme = &defaultNamingScheme{}
@@ -531,6 +579,12 @@
return false
}
+ // Only track this sdk library if this can be used as a shared library.
+ if c.sharedLibrary() {
+ // Use the name specified in the module definition as the owner.
+ c.sdkLibraryComponentProperties.SdkLibraryToImplicitlyTrack = proptools.StringPtr(c.moduleBase.BaseModuleName())
+ }
+
return true
}
@@ -551,7 +605,83 @@
return c.namingScheme.apiModuleName(apiScope, c.moduleBase.BaseModuleName())
}
-func (c *commonToSdkLibraryAndImport) getScopePaths(scope *apiScope) *scopePaths {
+// The component names for different outputs of the java_sdk_library.
+//
+// They are similar to the names used for the child modules it creates
+const (
+ stubsSourceComponentName = "stubs.source"
+
+ apiTxtComponentName = "api.txt"
+
+ removedApiTxtComponentName = "removed-api.txt"
+)
+
+// A regular expression to match tags that reference a specific stubs component.
+//
+// It will only match if given a valid scope and a valid component. It is verfy strict
+// to ensure it does not accidentally match a similar looking tag that should be processed
+// by the embedded Library.
+var tagSplitter = func() *regexp.Regexp {
+ // Given a list of literal string items returns a regular expression that will
+ // match any one of the items.
+ choice := func(items ...string) string {
+ return `\Q` + strings.Join(items, `\E|\Q`) + `\E`
+ }
+
+ // Regular expression to match one of the scopes.
+ scopesRegexp := choice(allScopeNames...)
+
+ // Regular expression to match one of the components.
+ componentsRegexp := choice(stubsSourceComponentName, apiTxtComponentName, removedApiTxtComponentName)
+
+ // Regular expression to match any combination of one scope and one component.
+ return regexp.MustCompile(fmt.Sprintf(`^\.(%s)\.(%s)$`, scopesRegexp, componentsRegexp))
+}()
+
+// For OutputFileProducer interface
+//
+// .<scope>.stubs.source
+// .<scope>.api.txt
+// .<scope>.removed-api.txt
+func (c *commonToSdkLibraryAndImport) commonOutputFiles(tag string) (android.Paths, error) {
+ if groups := tagSplitter.FindStringSubmatch(tag); groups != nil {
+ scopeName := groups[1]
+ component := groups[2]
+
+ if scope, ok := scopeByName[scopeName]; ok {
+ paths := c.findScopePaths(scope)
+ if paths == nil {
+ return nil, fmt.Errorf("%q does not provide api scope %s", c.moduleBase.BaseModuleName(), scopeName)
+ }
+
+ switch component {
+ case stubsSourceComponentName:
+ if paths.stubsSrcJar.Valid() {
+ return android.Paths{paths.stubsSrcJar.Path()}, nil
+ }
+
+ case apiTxtComponentName:
+ if paths.currentApiFilePath.Valid() {
+ return android.Paths{paths.currentApiFilePath.Path()}, nil
+ }
+
+ case removedApiTxtComponentName:
+ if paths.removedApiFilePath.Valid() {
+ return android.Paths{paths.removedApiFilePath.Path()}, nil
+ }
+ }
+
+ return nil, fmt.Errorf("%s not available for api scope %s", component, scopeName)
+ } else {
+ return nil, fmt.Errorf("unknown scope %s in %s", scope, tag)
+ }
+
+ } else {
+ return nil, nil
+ }
+}
+
+func (c *commonToSdkLibraryAndImport) getScopePathsCreateIfNeeded(scope *apiScope) *scopePaths {
if c.scopePaths == nil {
c.scopePaths = make(map[*apiScope]*scopePaths)
}
@@ -564,6 +694,147 @@
return paths
}
+func (c *commonToSdkLibraryAndImport) findScopePaths(scope *apiScope) *scopePaths {
+ if c.scopePaths == nil {
+ return nil
+ }
+
+ return c.scopePaths[scope]
+}
+
+// If this does not support the requested api scope then find the closest available
+// scope it does support. Returns nil if no such scope is available.
+func (c *commonToSdkLibraryAndImport) findClosestScopePath(scope *apiScope) *scopePaths {
+ for s := scope; s != nil; s = s.extends {
+ if paths := c.findScopePaths(s); paths != nil {
+ return paths
+ }
+ }
+
+ // This should never happen outside tests as public should be the base scope for every
+ // scope and is enabled by default.
+ return nil
+}
+
+func (c *commonToSdkLibraryAndImport) selectHeaderJarsForSdkVersion(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths {
+
+ // If a specific numeric version has been requested then use prebuilt versions of the sdk.
+ if sdkVersion.version.isNumbered() {
+ return PrebuiltJars(ctx, c.moduleBase.BaseModuleName(), sdkVersion)
+ }
+
+ var apiScope *apiScope
+ switch sdkVersion.kind {
+ case sdkSystem:
+ apiScope = apiScopeSystem
+ case sdkModule:
+ apiScope = apiScopeModuleLib
+ case sdkTest:
+ apiScope = apiScopeTest
+ default:
+ apiScope = apiScopePublic
+ }
+
+ paths := c.findClosestScopePath(apiScope)
+ if paths == nil {
+ var scopes []string
+ for _, s := range allApiScopes {
+ if c.findScopePaths(s) != nil {
+ scopes = append(scopes, s.name)
+ }
+ }
+ ctx.ModuleErrorf("requires api scope %s from %s but it only has %q available", apiScope.name, c.moduleBase.BaseModuleName(), scopes)
+ return nil
+ }
+
+ return paths.stubsHeaderPath
+}
+
+func (c *commonToSdkLibraryAndImport) sdkComponentPropertiesForChildLibrary() interface{} {
+ componentProps := &struct {
+ SdkLibraryToImplicitlyTrack *string
+ }{}
+
+ if c.sharedLibrary() {
+ // 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.
+ componentProps.SdkLibraryToImplicitlyTrack = proptools.StringPtr(c.moduleBase.BaseModuleName())
+ }
+
+ return componentProps
+}
+
+// Check if this can be used as a shared library.
+func (c *commonToSdkLibraryAndImport) sharedLibrary() bool {
+ return proptools.BoolDefault(c.commonSdkLibraryProperties.Shared_library, true)
+}
+
+// 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
@@ -656,17 +927,29 @@
}
}
- if !proptools.Bool(module.sdkLibraryProperties.Api_only) {
- // Add dependency to the rule for generating the xml permissions file
- ctx.AddDependency(module, xmlPermissionsFileTag, module.xmlFileName())
- }
+ if module.requiresRuntimeImplementationLibrary() {
+ if module.sharedLibrary() {
+ // Add dependency to the rule for generating the xml permissions file
+ ctx.AddDependency(module, xmlPermissionsFileTag, module.xmlFileName())
+ }
- module.Library.deps(ctx)
+ // Only add the deps for the library if it is actually going to be built.
+ module.Library.deps(ctx)
+ }
+}
+
+func (module *SdkLibrary) OutputFiles(tag string) (android.Paths, error) {
+ paths, err := module.commonOutputFiles(tag)
+ if paths == nil && err == nil {
+ return module.Library.OutputFiles(tag)
+ } else {
+ return paths, err
+ }
}
func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- // Don't build an implementation library if this is api only.
- if !proptools.Bool(module.sdkLibraryProperties.Api_only) {
+ // Only build an implementation library if required.
+ if module.requiresRuntimeImplementationLibrary() {
module.Library.GenerateAndroidBuildActions(ctx)
}
@@ -679,7 +962,7 @@
// Extract information from any of the scope specific dependencies.
if scopeTag, ok := tag.(scopeDependencyTag); ok {
apiScope := scopeTag.apiScope
- scopePaths := module.getScopePaths(apiScope)
+ scopePaths := module.getScopePathsCreateIfNeeded(apiScope)
// Extract information from the dependency. The exact information extracted
// is determined by the nature of the dependency which is determined by the tag.
@@ -689,7 +972,7 @@
}
func (module *SdkLibrary) AndroidMkEntries() []android.AndroidMkEntries {
- if proptools.Bool(module.sdkLibraryProperties.Api_only) {
+ if !module.requiresRuntimeImplementationLibrary() {
return nil
}
entriesList := module.Library.AndroidMkEntries()
@@ -805,7 +1088,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
@@ -1010,41 +1293,21 @@
return android.Paths{jarPath.Path()}
}
-func (module *SdkLibrary) sdkJars(
- ctx android.BaseModuleContext,
- sdkVersion sdkSpec,
- headerJars bool) android.Paths {
+func (module *SdkLibrary) sdkJars(ctx android.BaseModuleContext, sdkVersion sdkSpec, headerJars bool) android.Paths {
- // If a specific numeric version has been requested then use prebuilt versions of the sdk.
- if sdkVersion.version.isNumbered() {
- return PrebuiltJars(ctx, module.BaseModuleName(), sdkVersion)
- } else {
- if !sdkVersion.specified() {
- if headerJars {
- return module.HeaderJars()
- } else {
- return module.ImplementationJars()
- }
- }
- var apiScope *apiScope
- switch sdkVersion.kind {
- case sdkSystem:
- apiScope = apiScopeSystem
- case sdkTest:
- apiScope = apiScopeTest
- case sdkPrivate:
- return module.HeaderJars()
- default:
- apiScope = apiScopePublic
- }
-
- paths := module.getScopePaths(apiScope)
+ // Check any special cases for java_sdk_library.
+ //
+ // Only allow access to the implementation library in the following condition:
+ // * No sdk_version specified on the referencing module.
+ if sdkVersion.kind == sdkPrivate {
if headerJars {
- return paths.stubsHeaderPath
+ return module.HeaderJars()
} else {
- return paths.stubsImplPath
+ return module.ImplementationJars()
}
}
+
+ return module.selectHeaderJarsForSdkVersion(ctx, sdkVersion)
}
// to satisfy SdkLibraryDependency interface
@@ -1148,9 +1411,12 @@
module.createStubsLibrary(mctx, scope)
}
- if !proptools.Bool(module.sdkLibraryProperties.Api_only) {
- // for runtime
- module.createXmlFile(mctx)
+ if module.requiresRuntimeImplementationLibrary() {
+ // Only create an XML permissions file that declares the library as being usable
+ // as a shared library if required.
+ if module.sharedLibrary() {
+ module.createXmlFile(mctx)
+ }
// record java_sdk_library modules so that they are exported to make
javaSdkLibraries := javaSdkLibraries(mctx.Config())
@@ -1169,10 +1435,16 @@
&module.protoProperties,
)
+ module.initSdkLibraryComponent(&module.ModuleBase)
+
module.properties.Installable = proptools.BoolPtr(true)
module.deviceProperties.IsSDKLibrary = true
}
+func (module *SdkLibrary) requiresRuntimeImplementationLibrary() bool {
+ return !proptools.Bool(module.sdkLibraryProperties.Api_only)
+}
+
// Defines how to name the individual component modules the sdk library creates.
type sdkLibraryComponentNamingScheme interface {
stubsLibraryModuleName(scope *apiScope, baseName string) string
@@ -1251,6 +1523,18 @@
android.AddVisibilityProperty(module, "stubs_source_visibility", &module.sdkLibraryProperties.Stubs_source_visibility)
module.SetDefaultableHook(func(ctx android.DefaultableHookContext) {
+ // If no implementation is required then it cannot be used as a shared library
+ // either.
+ if !module.requiresRuntimeImplementationLibrary() {
+ // If shared_library has been explicitly set to true then it is incompatible
+ // with api_only: true.
+ if proptools.Bool(module.commonSdkLibraryProperties.Shared_library) {
+ ctx.PropertyErrorf("api_only/shared_library", "inconsistent settings, shared_library and api_only cannot both be true")
+ }
+ // Set shared_library: false.
+ module.commonSdkLibraryProperties.Shared_library = proptools.BoolPtr(false)
+ }
+
if module.initCommonAfterDefaultsApplied(ctx) {
module.CreateInternalModules(ctx)
}
@@ -1275,10 +1559,10 @@
Stub_srcs []string `android:"path"`
// The current.txt
- Current_api string `android:"path"`
+ Current_api *string `android:"path"`
// The removed.txt
- Removed_api string `android:"path"`
+ Removed_api *string `android:"path"`
}
type sdkLibraryImportProperties struct {
@@ -1388,7 +1672,9 @@
module.createJavaImportForStubs(mctx, apiScope, scopeProperties)
- module.createPrebuiltStubsSources(mctx, apiScope, scopeProperties)
+ if len(scopeProperties.Stub_srcs) > 0 {
+ module.createPrebuiltStubsSources(mctx, apiScope, scopeProperties)
+ }
}
javaSdkLibraries := javaSdkLibraries(mctx.Config())
@@ -1415,7 +1701,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) {
@@ -1440,45 +1727,48 @@
// Add dependencies to the prebuilt stubs library
ctx.AddVariationDependencies(nil, apiScope.stubsTag, module.stubsLibraryModuleName(apiScope))
+
+ if len(scopeProperties.Stub_srcs) > 0 {
+ // Add dependencies to the prebuilt stubs source library
+ ctx.AddVariationDependencies(nil, apiScope.stubsSourceTag, module.stubsSourceModuleName(apiScope))
+ }
}
}
+func (module *sdkLibraryImport) OutputFiles(tag string) (android.Paths, error) {
+ return module.commonOutputFiles(tag)
+}
+
func (module *sdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- // Record the paths to the prebuilt stubs library.
+ // Record the paths to the prebuilt stubs library and stubs source.
ctx.VisitDirectDeps(func(to android.Module) {
tag := ctx.OtherModuleDependencyTag(to)
- if lib, ok := to.(Dependency); ok {
- if scopeTag, ok := tag.(scopeDependencyTag); ok {
- apiScope := scopeTag.apiScope
- scopePaths := module.getScopePaths(apiScope)
- scopePaths.stubsHeaderPath = lib.HeaderJars()
- }
+ // Extract information from any of the scope specific dependencies.
+ if scopeTag, ok := tag.(scopeDependencyTag); ok {
+ apiScope := scopeTag.apiScope
+ scopePaths := module.getScopePathsCreateIfNeeded(apiScope)
+
+ // Extract information from the dependency. The exact information extracted
+ // is determined by the nature of the dependency which is determined by the tag.
+ scopeTag.extractDepInfo(ctx, to, scopePaths)
}
})
+
+ // Populate the scope paths with information from the properties.
+ for apiScope, scopeProperties := range module.scopeProperties {
+ if len(scopeProperties.Jars) == 0 {
+ continue
+ }
+
+ paths := module.getScopePathsCreateIfNeeded(apiScope)
+ paths.currentApiFilePath = android.OptionalPathForModuleSrc(ctx, scopeProperties.Current_api)
+ paths.removedApiFilePath = android.OptionalPathForModuleSrc(ctx, scopeProperties.Removed_api)
+ }
}
-func (module *sdkLibraryImport) sdkJars(
- ctx android.BaseModuleContext,
- sdkVersion sdkSpec) android.Paths {
-
- // If a specific numeric version has been requested then use prebuilt versions of the sdk.
- if sdkVersion.version.isNumbered() {
- return PrebuiltJars(ctx, module.BaseModuleName(), sdkVersion)
- }
-
- var apiScope *apiScope
- switch sdkVersion.kind {
- case sdkSystem:
- apiScope = apiScopeSystem
- case sdkTest:
- apiScope = apiScopeTest
- default:
- apiScope = apiScopePublic
- }
-
- paths := module.getScopePaths(apiScope)
- return paths.stubsHeaderPath
+func (module *sdkLibraryImport) sdkJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths {
+ return module.selectHeaderJarsForSdkVersion(ctx, sdkVersion)
}
// to satisfy SdkLibraryDependency interface
@@ -1651,21 +1941,25 @@
s.Scopes = make(map[*apiScope]scopeProperties)
for _, apiScope := range allApiScopes {
- paths := sdk.getScopePaths(apiScope)
+ paths := sdk.findScopePaths(apiScope)
+ if paths == nil {
+ continue
+ }
+
jars := paths.stubsImplPath
if len(jars) > 0 {
properties := scopeProperties{}
properties.Jars = jars
properties.SdkVersion = sdk.sdkVersionForStubsLibrary(ctx.SdkModuleContext(), apiScope)
- properties.StubsSrcJar = paths.stubsSrcJar
- properties.CurrentApiFile = paths.currentApiFilePath
- properties.RemovedApiFile = paths.removedApiFilePath
+ properties.StubsSrcJar = paths.stubsSrcJar.Path()
+ properties.CurrentApiFile = paths.currentApiFilePath.Path()
+ properties.RemovedApiFile = paths.removedApiFilePath.Path()
s.Scopes[apiScope] = properties
}
}
s.Libs = sdk.properties.Libs
- s.Naming_scheme = sdk.commonProperties.Naming_scheme
+ s.Naming_scheme = sdk.commonSdkLibraryProperties.Naming_scheme
}
func (s *sdkLibrarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {