Merge CSV files generated by UnsupportedAppUsageProcessor.
Flow: 1. Annotation processor generates a CSV file per class as a CLASS_OUTPUT resource. 2. hiddenapi.go extracts individual .csv files and merges them into an index.csv file per module. 3. hiddenapi_singleton.go merges individual index.csv files into a combined .csv file. In a follow up hiddenapi-index.csv would replace unsupportedappusage_index.csv Bug: 145132366 Change-Id: I87d92f9c8d4b1cc1df526fc576ee3c2101116b58 Merged-In: I87d92f9c8d4b1cc1df526fc576ee3c2101116b58 Test: diff unsupportedappusage_index.csv hiddenapi-index.csv Exempt-From-Owner-Approval: cp from r.android.com/1239709
This commit is contained in:
parent
d775f6ae65
commit
8a950790ee
|
@ -28,9 +28,10 @@ var hiddenAPIGenerateCSVRule = pctx.AndroidStaticRule("hiddenAPIGenerateCSV", bl
|
||||||
}, "outFlag", "stubAPIFlags")
|
}, "outFlag", "stubAPIFlags")
|
||||||
|
|
||||||
type hiddenAPI struct {
|
type hiddenAPI struct {
|
||||||
flagsCSVPath android.Path
|
|
||||||
metadataCSVPath android.Path
|
|
||||||
bootDexJarPath android.Path
|
bootDexJarPath android.Path
|
||||||
|
flagsCSVPath android.Path
|
||||||
|
indexCSVPath android.Path
|
||||||
|
metadataCSVPath android.Path
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *hiddenAPI) flagsCSV() android.Path {
|
func (h *hiddenAPI) flagsCSV() android.Path {
|
||||||
|
@ -45,17 +46,21 @@ func (h *hiddenAPI) bootDexJar() android.Path {
|
||||||
return h.bootDexJarPath
|
return h.bootDexJarPath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *hiddenAPI) indexCSV() android.Path {
|
||||||
|
return h.indexCSVPath
|
||||||
|
}
|
||||||
|
|
||||||
type hiddenAPIIntf interface {
|
type hiddenAPIIntf interface {
|
||||||
flagsCSV() android.Path
|
|
||||||
metadataCSV() android.Path
|
|
||||||
bootDexJar() android.Path
|
bootDexJar() android.Path
|
||||||
|
flagsCSV() android.Path
|
||||||
|
indexCSV() android.Path
|
||||||
|
metadataCSV() android.Path
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ hiddenAPIIntf = (*hiddenAPI)(nil)
|
var _ hiddenAPIIntf = (*hiddenAPI)(nil)
|
||||||
|
|
||||||
func (h *hiddenAPI) hiddenAPI(ctx android.ModuleContext, dexJar android.ModuleOutPath, implementationJar android.Path,
|
func (h *hiddenAPI) hiddenAPI(ctx android.ModuleContext, dexJar android.ModuleOutPath,
|
||||||
uncompressDex bool) android.ModuleOutPath {
|
implementationJar android.Path, uncompressDex bool) android.ModuleOutPath {
|
||||||
|
|
||||||
if !ctx.Config().IsEnvTrue("UNSAFE_DISABLE_HIDDENAPI_FLAGS") {
|
if !ctx.Config().IsEnvTrue("UNSAFE_DISABLE_HIDDENAPI_FLAGS") {
|
||||||
name := ctx.ModuleName()
|
name := ctx.ModuleName()
|
||||||
|
|
||||||
|
@ -77,9 +82,8 @@ func (h *hiddenAPI) hiddenAPI(ctx android.ModuleContext, dexJar android.ModuleOu
|
||||||
// Derive the greylist from classes jar.
|
// Derive the greylist from classes jar.
|
||||||
flagsCSV := android.PathForModuleOut(ctx, "hiddenapi", "flags.csv")
|
flagsCSV := android.PathForModuleOut(ctx, "hiddenapi", "flags.csv")
|
||||||
metadataCSV := android.PathForModuleOut(ctx, "hiddenapi", "metadata.csv")
|
metadataCSV := android.PathForModuleOut(ctx, "hiddenapi", "metadata.csv")
|
||||||
hiddenAPIGenerateCSV(ctx, flagsCSV, metadataCSV, implementationJar)
|
indexCSV := android.PathForModuleOut(ctx, "hiddenapi", "index.csv")
|
||||||
h.flagsCSVPath = flagsCSV
|
h.hiddenAPIGenerateCSV(ctx, flagsCSV, metadataCSV, indexCSV, implementationJar)
|
||||||
h.metadataCSVPath = metadataCSV
|
|
||||||
|
|
||||||
// If this module is actually on the boot jars list and not providing
|
// If this module is actually on the boot jars list and not providing
|
||||||
// hiddenapi information for a module on the boot jars list then encode
|
// hiddenapi information for a module on the boot jars list then encode
|
||||||
|
@ -96,9 +100,7 @@ func (h *hiddenAPI) hiddenAPI(ctx android.ModuleContext, dexJar android.ModuleOu
|
||||||
return dexJar
|
return dexJar
|
||||||
}
|
}
|
||||||
|
|
||||||
func hiddenAPIGenerateCSV(ctx android.ModuleContext, flagsCSV, metadataCSV android.WritablePath,
|
func (h *hiddenAPI) hiddenAPIGenerateCSV(ctx android.ModuleContext, flagsCSV, metadataCSV, indexCSV android.WritablePath, classesJar android.Path) {
|
||||||
classesJar android.Path) {
|
|
||||||
|
|
||||||
stubFlagsCSV := hiddenAPISingletonPaths(ctx).stubFlags
|
stubFlagsCSV := hiddenAPISingletonPaths(ctx).stubFlags
|
||||||
|
|
||||||
ctx.Build(pctx, android.BuildParams{
|
ctx.Build(pctx, android.BuildParams{
|
||||||
|
@ -112,6 +114,7 @@ func hiddenAPIGenerateCSV(ctx android.ModuleContext, flagsCSV, metadataCSV andro
|
||||||
"stubAPIFlags": stubFlagsCSV.String(),
|
"stubAPIFlags": stubFlagsCSV.String(),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
h.flagsCSVPath = flagsCSV
|
||||||
|
|
||||||
ctx.Build(pctx, android.BuildParams{
|
ctx.Build(pctx, android.BuildParams{
|
||||||
Rule: hiddenAPIGenerateCSVRule,
|
Rule: hiddenAPIGenerateCSVRule,
|
||||||
|
@ -124,18 +127,26 @@ func hiddenAPIGenerateCSV(ctx android.ModuleContext, flagsCSV, metadataCSV andro
|
||||||
"stubAPIFlags": stubFlagsCSV.String(),
|
"stubAPIFlags": stubFlagsCSV.String(),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
h.metadataCSVPath = metadataCSV
|
||||||
|
|
||||||
|
rule := android.NewRuleBuilder()
|
||||||
|
rule.Command().
|
||||||
|
BuiltTool(ctx, "merge_csv").
|
||||||
|
FlagWithInput("--zip_input=", classesJar).
|
||||||
|
FlagWithOutput("--output=", indexCSV)
|
||||||
|
rule.Build(pctx, ctx, "merged-hiddenapi-index", "Merged Hidden API index")
|
||||||
|
h.indexCSVPath = indexCSV
|
||||||
}
|
}
|
||||||
|
|
||||||
var hiddenAPIEncodeDexRule = pctx.AndroidStaticRule("hiddenAPIEncodeDex", blueprint.RuleParams{
|
var hiddenAPIEncodeDexRule = pctx.AndroidStaticRule("hiddenAPIEncodeDex", blueprint.RuleParams{
|
||||||
Command: `rm -rf $tmpDir && mkdir -p $tmpDir && mkdir $tmpDir/dex-input && mkdir $tmpDir/dex-output && ` +
|
Command: `rm -rf $tmpDir && mkdir -p $tmpDir && mkdir $tmpDir/dex-input && mkdir $tmpDir/dex-output &&
|
||||||
`unzip -o -q $in 'classes*.dex' -d $tmpDir/dex-input && ` +
|
unzip -o -q $in 'classes*.dex' -d $tmpDir/dex-input &&
|
||||||
`for INPUT_DEX in $$(find $tmpDir/dex-input -maxdepth 1 -name 'classes*.dex' | sort); do ` +
|
for INPUT_DEX in $$(find $tmpDir/dex-input -maxdepth 1 -name 'classes*.dex' | sort); do
|
||||||
` echo "--input-dex=$${INPUT_DEX}"; ` +
|
echo "--input-dex=$${INPUT_DEX}";
|
||||||
` echo "--output-dex=$tmpDir/dex-output/$$(basename $${INPUT_DEX})"; ` +
|
echo "--output-dex=$tmpDir/dex-output/$$(basename $${INPUT_DEX})";
|
||||||
`done | xargs ${config.HiddenAPI} encode --api-flags=$flagsCsv $hiddenapiFlags && ` +
|
done | xargs ${config.HiddenAPI} encode --api-flags=$flagsCsv $hiddenapiFlags &&
|
||||||
`${config.SoongZipCmd} $soongZipFlags -o $tmpDir/dex.jar -C $tmpDir/dex-output -f "$tmpDir/dex-output/classes*.dex" && ` +
|
${config.SoongZipCmd} $soongZipFlags -o $tmpDir/dex.jar -C $tmpDir/dex-output -f "$tmpDir/dex-output/classes*.dex" &&
|
||||||
`${config.MergeZipsCmd} -D -zipToNotStrip $tmpDir/dex.jar -stripFile "classes*.dex" $out $tmpDir/dex.jar $in`,
|
${config.MergeZipsCmd} -D -zipToNotStrip $tmpDir/dex.jar -stripFile "classes*.dex" -stripFile "**/*.uau" $out $tmpDir/dex.jar $in`,
|
||||||
CommandDeps: []string{
|
CommandDeps: []string{
|
||||||
"${config.HiddenAPI}",
|
"${config.HiddenAPI}",
|
||||||
"${config.SoongZipCmd}",
|
"${config.SoongZipCmd}",
|
||||||
|
|
|
@ -22,13 +22,15 @@ import (
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
android.RegisterSingletonType("hiddenapi", hiddenAPISingletonFactory)
|
android.RegisterSingletonType("hiddenapi", hiddenAPISingletonFactory)
|
||||||
|
android.RegisterSingletonType("hiddenapi_index", hiddenAPIIndexSingletonFactory)
|
||||||
android.RegisterModuleType("hiddenapi_flags", hiddenAPIFlagsFactory)
|
android.RegisterModuleType("hiddenapi_flags", hiddenAPIFlagsFactory)
|
||||||
}
|
}
|
||||||
|
|
||||||
type hiddenAPISingletonPathsStruct struct {
|
type hiddenAPISingletonPathsStruct struct {
|
||||||
stubFlags android.OutputPath
|
|
||||||
flags android.OutputPath
|
flags android.OutputPath
|
||||||
|
index android.OutputPath
|
||||||
metadata android.OutputPath
|
metadata android.OutputPath
|
||||||
|
stubFlags android.OutputPath
|
||||||
}
|
}
|
||||||
|
|
||||||
var hiddenAPISingletonPathsKey = android.NewOnceKey("hiddenAPISingletonPathsKey")
|
var hiddenAPISingletonPathsKey = android.NewOnceKey("hiddenAPISingletonPathsKey")
|
||||||
|
@ -39,9 +41,10 @@ var hiddenAPISingletonPathsKey = android.NewOnceKey("hiddenAPISingletonPathsKey"
|
||||||
func hiddenAPISingletonPaths(ctx android.PathContext) hiddenAPISingletonPathsStruct {
|
func hiddenAPISingletonPaths(ctx android.PathContext) hiddenAPISingletonPathsStruct {
|
||||||
return ctx.Config().Once(hiddenAPISingletonPathsKey, func() interface{} {
|
return ctx.Config().Once(hiddenAPISingletonPathsKey, func() interface{} {
|
||||||
return hiddenAPISingletonPathsStruct{
|
return hiddenAPISingletonPathsStruct{
|
||||||
stubFlags: android.PathForOutput(ctx, "hiddenapi", "hiddenapi-stub-flags.txt"),
|
|
||||||
flags: android.PathForOutput(ctx, "hiddenapi", "hiddenapi-flags.csv"),
|
flags: android.PathForOutput(ctx, "hiddenapi", "hiddenapi-flags.csv"),
|
||||||
|
index: android.PathForOutput(ctx, "hiddenapi", "hiddenapi-index.csv"),
|
||||||
metadata: android.PathForOutput(ctx, "hiddenapi", "hiddenapi-greylist.csv"),
|
metadata: android.PathForOutput(ctx, "hiddenapi", "hiddenapi-greylist.csv"),
|
||||||
|
stubFlags: android.PathForOutput(ctx, "hiddenapi", "hiddenapi-stub-flags.txt"),
|
||||||
}
|
}
|
||||||
}).(hiddenAPISingletonPathsStruct)
|
}).(hiddenAPISingletonPathsStruct)
|
||||||
}
|
}
|
||||||
|
@ -364,3 +367,45 @@ func hiddenAPIFlagsFactory() android.Module {
|
||||||
android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
|
android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
|
||||||
return module
|
return module
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func hiddenAPIIndexSingletonFactory() android.Singleton {
|
||||||
|
return &hiddenAPIIndexSingleton{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type hiddenAPIIndexSingleton struct {
|
||||||
|
index android.Path
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *hiddenAPIIndexSingleton) GenerateBuildActions(ctx android.SingletonContext) {
|
||||||
|
// Don't run any hiddenapi rules if UNSAFE_DISABLE_HIDDENAPI_FLAGS=true
|
||||||
|
if ctx.Config().IsEnvTrue("UNSAFE_DISABLE_HIDDENAPI_FLAGS") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
indexes := android.Paths{}
|
||||||
|
ctx.VisitAllModules(func(module android.Module) {
|
||||||
|
if h, ok := module.(hiddenAPIIntf); ok {
|
||||||
|
if h.indexCSV() != nil {
|
||||||
|
indexes = append(indexes, h.indexCSV())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
rule := android.NewRuleBuilder()
|
||||||
|
rule.Command().
|
||||||
|
BuiltTool(ctx, "merge_csv").
|
||||||
|
FlagWithArg("--header=", "signature,file,startline,startcol,endline,endcol,properties").
|
||||||
|
FlagWithOutput("--output=", hiddenAPISingletonPaths(ctx).index).
|
||||||
|
Inputs(indexes)
|
||||||
|
rule.Build(pctx, ctx, "singleton-merged-hiddenapi-index", "Singleton merged Hidden API index")
|
||||||
|
|
||||||
|
h.index = hiddenAPISingletonPaths(ctx).index
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *hiddenAPIIndexSingleton) MakeVars(ctx android.MakeVarsContext) {
|
||||||
|
if ctx.Config().IsEnvTrue("UNSAFE_DISABLE_HIDDENAPI_FLAGS") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.Strict("INTERNAL_PLATFORM_HIDDENAPI_INDEX", h.index.String())
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue