Optionally embed NOTICE files in apks.
If embed_notices or ALWAYS_EMBED_NOTICES is set, collect NOTICE files from all dependencies of the android_app, merge them with the app's own one (if exists), transform it to HTML, gzip it, and put it as an asset in the final APK output. Bug: 135460391 Test: app_test.go Change-Id: I52d92e2fd19b3f5f396100424665c5cc344190d8
This commit is contained in:
75
java/app.go
75
java/app.go
@@ -19,6 +19,7 @@ package java
|
||||
import (
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/google/blueprint"
|
||||
@@ -103,6 +104,10 @@ type appProperties struct {
|
||||
// Use_embedded_native_libs still selects whether they are stored uncompressed and aligned or compressed.
|
||||
// True for android_test* modules.
|
||||
AlwaysPackageNativeLibs bool `blueprint:"mutated"`
|
||||
|
||||
// If set, find and merge all NOTICE files that this module and its dependencies have and store
|
||||
// it in the APK as an asset.
|
||||
Embed_notices *bool
|
||||
}
|
||||
|
||||
// android_app properties that can be overridden by override_android_app
|
||||
@@ -351,6 +356,54 @@ func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, ctx android.ModuleContext
|
||||
return jniJarFile
|
||||
}
|
||||
|
||||
func (a *AndroidApp) noticeBuildActions(ctx android.ModuleContext, installDir android.OutputPath) android.OptionalPath {
|
||||
if !Bool(a.appProperties.Embed_notices) && !ctx.Config().IsEnvTrue("ALWAYS_EMBED_NOTICES") {
|
||||
return android.OptionalPath{}
|
||||
}
|
||||
|
||||
// Collect NOTICE files from all dependencies.
|
||||
seenModules := make(map[android.Module]bool)
|
||||
noticePathSet := make(map[android.Path]bool)
|
||||
|
||||
ctx.WalkDeps(func(child android.Module, parent android.Module) bool {
|
||||
// Have we already seen this?
|
||||
if _, ok := seenModules[child]; ok {
|
||||
return false
|
||||
}
|
||||
seenModules[child] = true
|
||||
|
||||
// Skip host modules.
|
||||
if child.Target().Os.Class == android.Host || child.Target().Os.Class == android.HostCross {
|
||||
return false
|
||||
}
|
||||
|
||||
path := child.(android.Module).NoticeFile()
|
||||
if path.Valid() {
|
||||
noticePathSet[path.Path()] = true
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
// If the app has one, add it too.
|
||||
if a.NoticeFile().Valid() {
|
||||
noticePathSet[a.NoticeFile().Path()] = true
|
||||
}
|
||||
|
||||
if len(noticePathSet) == 0 {
|
||||
return android.OptionalPath{}
|
||||
}
|
||||
var noticePaths []android.Path
|
||||
for path := range noticePathSet {
|
||||
noticePaths = append(noticePaths, path)
|
||||
}
|
||||
sort.Slice(noticePaths, func(i, j int) bool {
|
||||
return noticePaths[i].String() < noticePaths[j].String()
|
||||
})
|
||||
noticeFile := android.BuildNoticeOutput(ctx, installDir, a.installApkName+".apk", noticePaths)
|
||||
|
||||
return android.OptionalPathForPath(noticeFile)
|
||||
}
|
||||
|
||||
// Reads and prepends a main cert from the default cert dir if it hasn't been set already, i.e. it
|
||||
// isn't a cert module reference. Also checks and enforces system cert restriction if applicable.
|
||||
func processMainCert(m android.ModuleBase, certPropValue string, certificates []Certificate, ctx android.ModuleContext) []Certificate {
|
||||
@@ -391,6 +444,18 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
|
||||
// Check if the install APK name needs to be overridden.
|
||||
a.installApkName = ctx.DeviceConfig().OverridePackageNameFor(a.Name())
|
||||
|
||||
var installDir android.OutputPath
|
||||
if ctx.ModuleName() == "framework-res" {
|
||||
// framework-res.apk is installed as system/framework/framework-res.apk
|
||||
installDir = android.PathForModuleInstall(ctx, "framework")
|
||||
} else if Bool(a.appProperties.Privileged) {
|
||||
installDir = android.PathForModuleInstall(ctx, "priv-app", a.installApkName)
|
||||
} else {
|
||||
installDir = android.PathForModuleInstall(ctx, "app", a.installApkName)
|
||||
}
|
||||
|
||||
a.aapt.noticeFile = a.noticeBuildActions(ctx, installDir)
|
||||
|
||||
// Process all building blocks, from AAPT to certificates.
|
||||
a.aaptBuildActions(ctx)
|
||||
|
||||
@@ -432,16 +497,6 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
|
||||
a.bundleFile = bundleFile
|
||||
|
||||
// Install the app package.
|
||||
var installDir android.OutputPath
|
||||
if ctx.ModuleName() == "framework-res" {
|
||||
// framework-res.apk is installed as system/framework/framework-res.apk
|
||||
installDir = android.PathForModuleInstall(ctx, "framework")
|
||||
} else if Bool(a.appProperties.Privileged) {
|
||||
installDir = android.PathForModuleInstall(ctx, "priv-app", a.installApkName)
|
||||
} else {
|
||||
installDir = android.PathForModuleInstall(ctx, "app", a.installApkName)
|
||||
}
|
||||
|
||||
ctx.InstallFile(installDir, a.installApkName+".apk", a.outputFile)
|
||||
for _, split := range a.aapt.splits {
|
||||
ctx.InstallFile(installDir, a.installApkName+"_"+split.suffix+".apk", split.path)
|
||||
|
Reference in New Issue
Block a user