1*333d2b36SAndroid Build Coastguard Worker// Copyright 2019 Google Inc. All rights reserved. 2*333d2b36SAndroid Build Coastguard Worker// 3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License"); 4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License. 5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at 6*333d2b36SAndroid Build Coastguard Worker// 7*333d2b36SAndroid Build Coastguard Worker// http://www.apache.org/licenses/LICENSE-2.0 8*333d2b36SAndroid Build Coastguard Worker// 9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software 10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS, 11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and 13*333d2b36SAndroid Build Coastguard Worker// limitations under the License. 14*333d2b36SAndroid Build Coastguard Worker 15*333d2b36SAndroid Build Coastguard Workerpackage java 16*333d2b36SAndroid Build Coastguard Worker 17*333d2b36SAndroid Build Coastguard Workerimport ( 18*333d2b36SAndroid Build Coastguard Worker "github.com/google/blueprint" 19*333d2b36SAndroid Build Coastguard Worker 20*333d2b36SAndroid Build Coastguard Worker "android/soong/android" 21*333d2b36SAndroid Build Coastguard Worker) 22*333d2b36SAndroid Build Coastguard Worker 23*333d2b36SAndroid Build Coastguard Workervar ( 24*333d2b36SAndroid Build Coastguard Worker hiddenAPIGenerateCSVRule = pctx.AndroidStaticRule("hiddenAPIGenerateCSV", blueprint.RuleParams{ 25*333d2b36SAndroid Build Coastguard Worker Command: "${config.Class2NonSdkList} --stub-api-flags ${stubAPIFlags} $in $outFlag $out", 26*333d2b36SAndroid Build Coastguard Worker CommandDeps: []string{"${config.Class2NonSdkList}"}, 27*333d2b36SAndroid Build Coastguard Worker }, "outFlag", "stubAPIFlags") 28*333d2b36SAndroid Build Coastguard Worker 29*333d2b36SAndroid Build Coastguard Worker hiddenAPIGenerateIndexRule = pctx.AndroidStaticRule("hiddenAPIGenerateIndex", blueprint.RuleParams{ 30*333d2b36SAndroid Build Coastguard Worker Command: "${config.MergeCsvCommand} --zip_input --key_field signature --output=$out $in", 31*333d2b36SAndroid Build Coastguard Worker CommandDeps: []string{"${config.MergeCsvCommand}"}, 32*333d2b36SAndroid Build Coastguard Worker }) 33*333d2b36SAndroid Build Coastguard Worker) 34*333d2b36SAndroid Build Coastguard Worker 35*333d2b36SAndroid Build Coastguard Workertype hiddenAPI struct { 36*333d2b36SAndroid Build Coastguard Worker // True if the module containing this structure contributes to the hiddenapi information or has 37*333d2b36SAndroid Build Coastguard Worker // that information encoded within it. 38*333d2b36SAndroid Build Coastguard Worker active bool 39*333d2b36SAndroid Build Coastguard Worker 40*333d2b36SAndroid Build Coastguard Worker // The path to the dex jar that is in the boot class path. If this is unset then the associated 41*333d2b36SAndroid Build Coastguard Worker // module is not a boot jar, but could be one of the <x>-hiddenapi modules that provide additional 42*333d2b36SAndroid Build Coastguard Worker // annotations for the <x> boot dex jar but which do not actually provide a boot dex jar 43*333d2b36SAndroid Build Coastguard Worker // themselves. 44*333d2b36SAndroid Build Coastguard Worker // 45*333d2b36SAndroid Build Coastguard Worker // This must be the path to the unencoded dex jar as the encoded dex jar indirectly depends on 46*333d2b36SAndroid Build Coastguard Worker // this file so using the encoded dex jar here would result in a cycle in the ninja rules. 47*333d2b36SAndroid Build Coastguard Worker bootDexJarPath OptionalDexJarPath 48*333d2b36SAndroid Build Coastguard Worker bootDexJarPathErr error 49*333d2b36SAndroid Build Coastguard Worker 50*333d2b36SAndroid Build Coastguard Worker // The paths to the classes jars that contain classes and class members annotated with 51*333d2b36SAndroid Build Coastguard Worker // the UnsupportedAppUsage annotation that need to be extracted as part of the hidden API 52*333d2b36SAndroid Build Coastguard Worker // processing. 53*333d2b36SAndroid Build Coastguard Worker classesJarPaths android.Paths 54*333d2b36SAndroid Build Coastguard Worker 55*333d2b36SAndroid Build Coastguard Worker // The compressed state of the dex file being encoded. This is used to ensure that the encoded 56*333d2b36SAndroid Build Coastguard Worker // dex file has the same state. 57*333d2b36SAndroid Build Coastguard Worker uncompressDexState *bool 58*333d2b36SAndroid Build Coastguard Worker} 59*333d2b36SAndroid Build Coastguard Worker 60*333d2b36SAndroid Build Coastguard Workerfunc (h *hiddenAPI) bootDexJar(ctx android.ModuleErrorfContext) OptionalDexJarPath { 61*333d2b36SAndroid Build Coastguard Worker if h.bootDexJarPathErr != nil { 62*333d2b36SAndroid Build Coastguard Worker ctx.ModuleErrorf(h.bootDexJarPathErr.Error()) 63*333d2b36SAndroid Build Coastguard Worker } 64*333d2b36SAndroid Build Coastguard Worker return h.bootDexJarPath 65*333d2b36SAndroid Build Coastguard Worker} 66*333d2b36SAndroid Build Coastguard Worker 67*333d2b36SAndroid Build Coastguard Workerfunc (h *hiddenAPI) classesJars() android.Paths { 68*333d2b36SAndroid Build Coastguard Worker return h.classesJarPaths 69*333d2b36SAndroid Build Coastguard Worker} 70*333d2b36SAndroid Build Coastguard Worker 71*333d2b36SAndroid Build Coastguard Workerfunc (h *hiddenAPI) uncompressDex() *bool { 72*333d2b36SAndroid Build Coastguard Worker return h.uncompressDexState 73*333d2b36SAndroid Build Coastguard Worker} 74*333d2b36SAndroid Build Coastguard Worker 75*333d2b36SAndroid Build Coastguard Worker// hiddenAPIModule is the interface a module that embeds the hiddenAPI structure must implement. 76*333d2b36SAndroid Build Coastguard Workertype hiddenAPIModule interface { 77*333d2b36SAndroid Build Coastguard Worker android.Module 78*333d2b36SAndroid Build Coastguard Worker hiddenAPIIntf 79*333d2b36SAndroid Build Coastguard Worker 80*333d2b36SAndroid Build Coastguard Worker MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel 81*333d2b36SAndroid Build Coastguard Worker} 82*333d2b36SAndroid Build Coastguard Worker 83*333d2b36SAndroid Build Coastguard Workertype hiddenAPIIntf interface { 84*333d2b36SAndroid Build Coastguard Worker bootDexJar(ctx android.ModuleErrorfContext) OptionalDexJarPath 85*333d2b36SAndroid Build Coastguard Worker classesJars() android.Paths 86*333d2b36SAndroid Build Coastguard Worker uncompressDex() *bool 87*333d2b36SAndroid Build Coastguard Worker} 88*333d2b36SAndroid Build Coastguard Worker 89*333d2b36SAndroid Build Coastguard Workervar _ hiddenAPIIntf = (*hiddenAPI)(nil) 90*333d2b36SAndroid Build Coastguard Worker 91*333d2b36SAndroid Build Coastguard Worker// Initialize the hiddenapi structure 92*333d2b36SAndroid Build Coastguard Worker// 93*333d2b36SAndroid Build Coastguard Worker// uncompressedDexState should be nil when the module is a prebuilt and so does not require hidden 94*333d2b36SAndroid Build Coastguard Worker// API encoding. 95*333d2b36SAndroid Build Coastguard Workerfunc (h *hiddenAPI) initHiddenAPI(ctx android.ModuleContext, dexJar OptionalDexJarPath, classesJar android.Path, uncompressedDexState *bool) { 96*333d2b36SAndroid Build Coastguard Worker 97*333d2b36SAndroid Build Coastguard Worker // Save the classes jars even if this is not active as they may be used by modular hidden API 98*333d2b36SAndroid Build Coastguard Worker // processing. 99*333d2b36SAndroid Build Coastguard Worker classesJars := android.Paths{classesJar} 100*333d2b36SAndroid Build Coastguard Worker ctx.VisitDirectDepsWithTag(hiddenApiAnnotationsTag, func(dep android.Module) { 101*333d2b36SAndroid Build Coastguard Worker if javaInfo, ok := android.OtherModuleProvider(ctx, dep, JavaInfoProvider); ok { 102*333d2b36SAndroid Build Coastguard Worker classesJars = append(classesJars, javaInfo.ImplementationJars...) 103*333d2b36SAndroid Build Coastguard Worker } 104*333d2b36SAndroid Build Coastguard Worker }) 105*333d2b36SAndroid Build Coastguard Worker h.classesJarPaths = classesJars 106*333d2b36SAndroid Build Coastguard Worker 107*333d2b36SAndroid Build Coastguard Worker // Save the unencoded dex jar so it can be used when generating the 108*333d2b36SAndroid Build Coastguard Worker // hiddenAPISingletonPathsStruct.stubFlags file. 109*333d2b36SAndroid Build Coastguard Worker h.bootDexJarPath = dexJar 110*333d2b36SAndroid Build Coastguard Worker 111*333d2b36SAndroid Build Coastguard Worker h.uncompressDexState = uncompressedDexState 112*333d2b36SAndroid Build Coastguard Worker 113*333d2b36SAndroid Build Coastguard Worker // If hiddenapi processing is disabled treat this as inactive. 114*333d2b36SAndroid Build Coastguard Worker if ctx.Config().DisableHiddenApiChecks() { 115*333d2b36SAndroid Build Coastguard Worker return 116*333d2b36SAndroid Build Coastguard Worker } 117*333d2b36SAndroid Build Coastguard Worker 118*333d2b36SAndroid Build Coastguard Worker // The context module must implement hiddenAPIModule. 119*333d2b36SAndroid Build Coastguard Worker module := ctx.Module().(hiddenAPIModule) 120*333d2b36SAndroid Build Coastguard Worker 121*333d2b36SAndroid Build Coastguard Worker // If the frameworks/base directories does not exist and no prebuilt hidden API flag files have 122*333d2b36SAndroid Build Coastguard Worker // been configured then it is not possible to do hidden API encoding. 123*333d2b36SAndroid Build Coastguard Worker if !ctx.Config().FrameworksBaseDirExists(ctx) && ctx.Config().PrebuiltHiddenApiDir(ctx) == "" { 124*333d2b36SAndroid Build Coastguard Worker return 125*333d2b36SAndroid Build Coastguard Worker } 126*333d2b36SAndroid Build Coastguard Worker 127*333d2b36SAndroid Build Coastguard Worker // It is important that hiddenapi information is only gathered for/from modules that are actually 128*333d2b36SAndroid Build Coastguard Worker // on the boot jars list because the runtime only enforces access to the hidden API for the 129*333d2b36SAndroid Build Coastguard Worker // bootclassloader. If information is gathered for modules not on the list then that will cause 130*333d2b36SAndroid Build Coastguard Worker // failures in the CtsHiddenApiBlocklist... tests. 131*333d2b36SAndroid Build Coastguard Worker h.active = isModuleInBootClassPath(ctx, module) 132*333d2b36SAndroid Build Coastguard Worker} 133*333d2b36SAndroid Build Coastguard Worker 134*333d2b36SAndroid Build Coastguard Worker// Store any error encountered during the initialization of hiddenapi structure (e.g. unflagged co-existing prebuilt apexes) 135*333d2b36SAndroid Build Coastguard Workerfunc (h *hiddenAPI) initHiddenAPIError(err error) { 136*333d2b36SAndroid Build Coastguard Worker h.bootDexJarPathErr = err 137*333d2b36SAndroid Build Coastguard Worker} 138*333d2b36SAndroid Build Coastguard Worker 139*333d2b36SAndroid Build Coastguard Workerfunc isModuleInBootClassPath(ctx android.BaseModuleContext, module android.Module) bool { 140*333d2b36SAndroid Build Coastguard Worker // Get the configured platform and apex boot jars. 141*333d2b36SAndroid Build Coastguard Worker nonApexBootJars := ctx.Config().NonApexBootJars() 142*333d2b36SAndroid Build Coastguard Worker apexBootJars := ctx.Config().ApexBootJars() 143*333d2b36SAndroid Build Coastguard Worker active := isModuleInConfiguredList(ctx, module, nonApexBootJars) || 144*333d2b36SAndroid Build Coastguard Worker isModuleInConfiguredList(ctx, module, apexBootJars) 145*333d2b36SAndroid Build Coastguard Worker return active 146*333d2b36SAndroid Build Coastguard Worker} 147*333d2b36SAndroid Build Coastguard Worker 148*333d2b36SAndroid Build Coastguard Worker// hiddenAPIEncodeDex is called by any module that needs to encode dex files. 149*333d2b36SAndroid Build Coastguard Worker// 150*333d2b36SAndroid Build Coastguard Worker// It ignores any module that has not had initHiddenApi() called on it and which is not in the boot 151*333d2b36SAndroid Build Coastguard Worker// jar list. In that case it simply returns the supplied dex jar path. 152*333d2b36SAndroid Build Coastguard Worker// 153*333d2b36SAndroid Build Coastguard Worker// Otherwise, it creates a copy of the supplied dex file into which it has encoded the hiddenapi 154*333d2b36SAndroid Build Coastguard Worker// flags and returns this instead of the supplied dex jar. 155*333d2b36SAndroid Build Coastguard Workerfunc (h *hiddenAPI) hiddenAPIEncodeDex(ctx android.ModuleContext, dexJar android.Path) android.Path { 156*333d2b36SAndroid Build Coastguard Worker 157*333d2b36SAndroid Build Coastguard Worker if !h.active { 158*333d2b36SAndroid Build Coastguard Worker return dexJar 159*333d2b36SAndroid Build Coastguard Worker } 160*333d2b36SAndroid Build Coastguard Worker 161*333d2b36SAndroid Build Coastguard Worker // A nil uncompressDexState prevents the dex file from being encoded. 162*333d2b36SAndroid Build Coastguard Worker if h.uncompressDexState == nil { 163*333d2b36SAndroid Build Coastguard Worker ctx.ModuleErrorf("cannot encode dex file %s when uncompressDexState is nil", dexJar) 164*333d2b36SAndroid Build Coastguard Worker } 165*333d2b36SAndroid Build Coastguard Worker uncompressDex := *h.uncompressDexState 166*333d2b36SAndroid Build Coastguard Worker 167*333d2b36SAndroid Build Coastguard Worker // Create a copy of the dex jar which has been encoded with hiddenapi flags. 168*333d2b36SAndroid Build Coastguard Worker flagsCSV := hiddenAPISingletonPaths(ctx).flags 169*333d2b36SAndroid Build Coastguard Worker outputDir := android.PathForModuleOut(ctx, "hiddenapi").OutputPath 170*333d2b36SAndroid Build Coastguard Worker encodedDex := hiddenAPIEncodeDex(ctx, dexJar, flagsCSV, uncompressDex, android.NoneApiLevel, outputDir) 171*333d2b36SAndroid Build Coastguard Worker 172*333d2b36SAndroid Build Coastguard Worker // Use the encoded dex jar from here onwards. 173*333d2b36SAndroid Build Coastguard Worker return encodedDex 174*333d2b36SAndroid Build Coastguard Worker} 175*333d2b36SAndroid Build Coastguard Worker 176*333d2b36SAndroid Build Coastguard Worker// buildRuleToGenerateAnnotationFlags builds a ninja rule to generate the annotation-flags.csv file 177*333d2b36SAndroid Build Coastguard Worker// from the classes jars and stub-flags.csv files. 178*333d2b36SAndroid Build Coastguard Worker// 179*333d2b36SAndroid Build Coastguard Worker// The annotation-flags.csv file contains mappings from Java signature to various flags derived from 180*333d2b36SAndroid Build Coastguard Worker// annotations in the source, e.g. whether it is public or the sdk version above which it can no 181*333d2b36SAndroid Build Coastguard Worker// longer be used. 182*333d2b36SAndroid Build Coastguard Worker// 183*333d2b36SAndroid Build Coastguard Worker// It is created by the Class2NonSdkList tool which processes the .class files in the class 184*333d2b36SAndroid Build Coastguard Worker// implementation jar looking for UnsupportedAppUsage and CovariantReturnType annotations. The 185*333d2b36SAndroid Build Coastguard Worker// tool also consumes the hiddenAPISingletonPathsStruct.stubFlags file in order to perform 186*333d2b36SAndroid Build Coastguard Worker// consistency checks on the information in the annotations and to filter out bridge methods 187*333d2b36SAndroid Build Coastguard Worker// that are already part of the public API. 188*333d2b36SAndroid Build Coastguard Workerfunc buildRuleToGenerateAnnotationFlags(ctx android.ModuleContext, desc string, classesJars android.Paths, stubFlagsCSV android.Path, outputPath android.WritablePath) { 189*333d2b36SAndroid Build Coastguard Worker ctx.Build(pctx, android.BuildParams{ 190*333d2b36SAndroid Build Coastguard Worker Rule: hiddenAPIGenerateCSVRule, 191*333d2b36SAndroid Build Coastguard Worker Description: desc, 192*333d2b36SAndroid Build Coastguard Worker Inputs: classesJars, 193*333d2b36SAndroid Build Coastguard Worker Output: outputPath, 194*333d2b36SAndroid Build Coastguard Worker Implicit: stubFlagsCSV, 195*333d2b36SAndroid Build Coastguard Worker Args: map[string]string{ 196*333d2b36SAndroid Build Coastguard Worker "outFlag": "--write-flags-csv", 197*333d2b36SAndroid Build Coastguard Worker "stubAPIFlags": stubFlagsCSV.String(), 198*333d2b36SAndroid Build Coastguard Worker }, 199*333d2b36SAndroid Build Coastguard Worker }) 200*333d2b36SAndroid Build Coastguard Worker} 201*333d2b36SAndroid Build Coastguard Worker 202*333d2b36SAndroid Build Coastguard Worker// buildRuleToGenerateMetadata builds a ninja rule to generate the metadata.csv file from 203*333d2b36SAndroid Build Coastguard Worker// the classes jars and stub-flags.csv files. 204*333d2b36SAndroid Build Coastguard Worker// 205*333d2b36SAndroid Build Coastguard Worker// The metadata.csv file contains mappings from Java signature to the value of properties specified 206*333d2b36SAndroid Build Coastguard Worker// on UnsupportedAppUsage annotations in the source. 207*333d2b36SAndroid Build Coastguard Worker// 208*333d2b36SAndroid Build Coastguard Worker// Like the annotation-flags.csv file this is also created by the Class2NonSdkList in the same way. 209*333d2b36SAndroid Build Coastguard Worker// Although the two files could potentially be created in a single invocation of the 210*333d2b36SAndroid Build Coastguard Worker// Class2NonSdkList at the moment they are created using their own invocation, with the behavior 211*333d2b36SAndroid Build Coastguard Worker// being determined by the property that is used. 212*333d2b36SAndroid Build Coastguard Workerfunc buildRuleToGenerateMetadata(ctx android.ModuleContext, desc string, classesJars android.Paths, stubFlagsCSV android.Path, metadataCSV android.WritablePath) { 213*333d2b36SAndroid Build Coastguard Worker ctx.Build(pctx, android.BuildParams{ 214*333d2b36SAndroid Build Coastguard Worker Rule: hiddenAPIGenerateCSVRule, 215*333d2b36SAndroid Build Coastguard Worker Description: desc, 216*333d2b36SAndroid Build Coastguard Worker Inputs: classesJars, 217*333d2b36SAndroid Build Coastguard Worker Output: metadataCSV, 218*333d2b36SAndroid Build Coastguard Worker Implicit: stubFlagsCSV, 219*333d2b36SAndroid Build Coastguard Worker Args: map[string]string{ 220*333d2b36SAndroid Build Coastguard Worker "outFlag": "--write-metadata-csv", 221*333d2b36SAndroid Build Coastguard Worker "stubAPIFlags": stubFlagsCSV.String(), 222*333d2b36SAndroid Build Coastguard Worker }, 223*333d2b36SAndroid Build Coastguard Worker }) 224*333d2b36SAndroid Build Coastguard Worker} 225*333d2b36SAndroid Build Coastguard Worker 226*333d2b36SAndroid Build Coastguard Worker// buildRuleToGenerateIndex builds a ninja rule to generate the index.csv file from the classes 227*333d2b36SAndroid Build Coastguard Worker// jars. 228*333d2b36SAndroid Build Coastguard Worker// 229*333d2b36SAndroid Build Coastguard Worker// The index.csv file contains mappings from Java signature to source location information. 230*333d2b36SAndroid Build Coastguard Worker// 231*333d2b36SAndroid Build Coastguard Worker// It is created by the merge_csv tool which processes the class implementation jar, extracting 232*333d2b36SAndroid Build Coastguard Worker// all the files ending in .uau (which are CSV files) and merges them together. The .uau files are 233*333d2b36SAndroid Build Coastguard Worker// created by the unsupported app usage annotation processor during compilation of the class 234*333d2b36SAndroid Build Coastguard Worker// implementation jar. 235*333d2b36SAndroid Build Coastguard Workerfunc buildRuleToGenerateIndex(ctx android.ModuleContext, desc string, classesJars android.Paths, indexCSV android.WritablePath) { 236*333d2b36SAndroid Build Coastguard Worker ctx.Build(pctx, android.BuildParams{ 237*333d2b36SAndroid Build Coastguard Worker Rule: hiddenAPIGenerateIndexRule, 238*333d2b36SAndroid Build Coastguard Worker Description: desc, 239*333d2b36SAndroid Build Coastguard Worker Inputs: classesJars, 240*333d2b36SAndroid Build Coastguard Worker Output: indexCSV, 241*333d2b36SAndroid Build Coastguard Worker }) 242*333d2b36SAndroid Build Coastguard Worker} 243*333d2b36SAndroid Build Coastguard Worker 244*333d2b36SAndroid Build Coastguard Workervar hiddenAPIEncodeDexRule = pctx.AndroidStaticRule("hiddenAPIEncodeDex", blueprint.RuleParams{ 245*333d2b36SAndroid Build Coastguard Worker Command: `rm -rf $tmpDir && mkdir -p $tmpDir && mkdir $tmpDir/dex-input && mkdir $tmpDir/dex-output && 246*333d2b36SAndroid Build Coastguard Worker unzip -qoDD $in 'classes*.dex' -d $tmpDir/dex-input && 247*333d2b36SAndroid Build Coastguard Worker for INPUT_DEX in $$(find $tmpDir/dex-input -maxdepth 1 -name 'classes*.dex' | sort); do 248*333d2b36SAndroid Build Coastguard Worker echo "--input-dex=$${INPUT_DEX}"; 249*333d2b36SAndroid Build Coastguard Worker echo "--output-dex=$tmpDir/dex-output/$$(basename $${INPUT_DEX})"; 250*333d2b36SAndroid Build Coastguard Worker done | xargs ${config.HiddenAPI} encode --api-flags=$flagsCsv $hiddenapiFlags && 251*333d2b36SAndroid Build Coastguard Worker ${config.SoongZipCmd} $soongZipFlags -o $tmpDir/dex.jar -C $tmpDir/dex-output -f "$tmpDir/dex-output/classes*.dex" && 252*333d2b36SAndroid Build Coastguard Worker ${config.MergeZipsCmd} -j -D -zipToNotStrip $tmpDir/dex.jar -stripFile "classes*.dex" -stripFile "**/*.uau" $out $tmpDir/dex.jar $in`, 253*333d2b36SAndroid Build Coastguard Worker CommandDeps: []string{ 254*333d2b36SAndroid Build Coastguard Worker "${config.HiddenAPI}", 255*333d2b36SAndroid Build Coastguard Worker "${config.SoongZipCmd}", 256*333d2b36SAndroid Build Coastguard Worker "${config.MergeZipsCmd}", 257*333d2b36SAndroid Build Coastguard Worker }, 258*333d2b36SAndroid Build Coastguard Worker}, "flagsCsv", "hiddenapiFlags", "tmpDir", "soongZipFlags") 259*333d2b36SAndroid Build Coastguard Worker 260*333d2b36SAndroid Build Coastguard Worker// hiddenAPIEncodeDex generates the build rule that will encode the supplied dex jar and place the 261*333d2b36SAndroid Build Coastguard Worker// encoded dex jar in a file of the same name in the output directory. 262*333d2b36SAndroid Build Coastguard Worker// 263*333d2b36SAndroid Build Coastguard Worker// The encode dex rule requires unzipping, encoding and rezipping the classes.dex files along with 264*333d2b36SAndroid Build Coastguard Worker// all the resources from the input jar. It also ensures that if it was uncompressed in the input 265*333d2b36SAndroid Build Coastguard Worker// it stays uncompressed in the output. 266*333d2b36SAndroid Build Coastguard Workerfunc hiddenAPIEncodeDex(ctx android.ModuleContext, dexInput, flagsCSV android.Path, uncompressDex bool, minSdkVersion android.ApiLevel, outputDir android.OutputPath) android.OutputPath { 267*333d2b36SAndroid Build Coastguard Worker 268*333d2b36SAndroid Build Coastguard Worker // The output file has the same name as the input file and is in the output directory. 269*333d2b36SAndroid Build Coastguard Worker output := outputDir.Join(ctx, dexInput.Base()) 270*333d2b36SAndroid Build Coastguard Worker 271*333d2b36SAndroid Build Coastguard Worker // Create a jar specific temporary directory in which to do the work just in case this is called 272*333d2b36SAndroid Build Coastguard Worker // with the same output directory for multiple modules. 273*333d2b36SAndroid Build Coastguard Worker tmpDir := outputDir.Join(ctx, dexInput.Base()+"-tmp") 274*333d2b36SAndroid Build Coastguard Worker 275*333d2b36SAndroid Build Coastguard Worker // If the input is uncompressed then generate the output of the encode rule to an intermediate 276*333d2b36SAndroid Build Coastguard Worker // file as the final output will need further processing after encoding. 277*333d2b36SAndroid Build Coastguard Worker soongZipFlags := "" 278*333d2b36SAndroid Build Coastguard Worker encodeRuleOutput := output 279*333d2b36SAndroid Build Coastguard Worker if uncompressDex { 280*333d2b36SAndroid Build Coastguard Worker soongZipFlags = "-L 0" 281*333d2b36SAndroid Build Coastguard Worker encodeRuleOutput = outputDir.Join(ctx, "unaligned", dexInput.Base()) 282*333d2b36SAndroid Build Coastguard Worker } 283*333d2b36SAndroid Build Coastguard Worker 284*333d2b36SAndroid Build Coastguard Worker // b/149353192: when a module is instrumented, jacoco adds synthetic members 285*333d2b36SAndroid Build Coastguard Worker // $jacocoData and $jacocoInit. Since they don't exist when building the hidden API flags, 286*333d2b36SAndroid Build Coastguard Worker // don't complain when we don't find hidden API flags for the synthetic members. 287*333d2b36SAndroid Build Coastguard Worker hiddenapiFlags := "" 288*333d2b36SAndroid Build Coastguard Worker if j, ok := ctx.Module().(interface { 289*333d2b36SAndroid Build Coastguard Worker shouldInstrument(android.BaseModuleContext) bool 290*333d2b36SAndroid Build Coastguard Worker }); ok && j.shouldInstrument(ctx) { 291*333d2b36SAndroid Build Coastguard Worker hiddenapiFlags = "--no-force-assign-all" 292*333d2b36SAndroid Build Coastguard Worker } 293*333d2b36SAndroid Build Coastguard Worker 294*333d2b36SAndroid Build Coastguard Worker // If the library is targeted for Q and/or R then make sure that they do not 295*333d2b36SAndroid Build Coastguard Worker // have any S+ flags encoded as that will break the runtime. 296*333d2b36SAndroid Build Coastguard Worker minApiLevel := minSdkVersion 297*333d2b36SAndroid Build Coastguard Worker if !minApiLevel.IsNone() { 298*333d2b36SAndroid Build Coastguard Worker if minApiLevel.LessThanOrEqualTo(android.ApiLevelOrPanic(ctx, "R")) { 299*333d2b36SAndroid Build Coastguard Worker hiddenapiFlags = hiddenapiFlags + " --max-hiddenapi-level=max-target-r" 300*333d2b36SAndroid Build Coastguard Worker } 301*333d2b36SAndroid Build Coastguard Worker } 302*333d2b36SAndroid Build Coastguard Worker 303*333d2b36SAndroid Build Coastguard Worker ctx.Build(pctx, android.BuildParams{ 304*333d2b36SAndroid Build Coastguard Worker Rule: hiddenAPIEncodeDexRule, 305*333d2b36SAndroid Build Coastguard Worker Description: "hiddenapi encode dex", 306*333d2b36SAndroid Build Coastguard Worker Input: dexInput, 307*333d2b36SAndroid Build Coastguard Worker Output: encodeRuleOutput, 308*333d2b36SAndroid Build Coastguard Worker Implicit: flagsCSV, 309*333d2b36SAndroid Build Coastguard Worker Args: map[string]string{ 310*333d2b36SAndroid Build Coastguard Worker "flagsCsv": flagsCSV.String(), 311*333d2b36SAndroid Build Coastguard Worker "tmpDir": tmpDir.String(), 312*333d2b36SAndroid Build Coastguard Worker "soongZipFlags": soongZipFlags, 313*333d2b36SAndroid Build Coastguard Worker "hiddenapiFlags": hiddenapiFlags, 314*333d2b36SAndroid Build Coastguard Worker }, 315*333d2b36SAndroid Build Coastguard Worker }) 316*333d2b36SAndroid Build Coastguard Worker 317*333d2b36SAndroid Build Coastguard Worker if uncompressDex { 318*333d2b36SAndroid Build Coastguard Worker TransformZipAlign(ctx, output, encodeRuleOutput, nil) 319*333d2b36SAndroid Build Coastguard Worker } 320*333d2b36SAndroid Build Coastguard Worker 321*333d2b36SAndroid Build Coastguard Worker return output 322*333d2b36SAndroid Build Coastguard Worker} 323*333d2b36SAndroid Build Coastguard Worker 324*333d2b36SAndroid Build Coastguard Workertype hiddenApiAnnotationsDependencyTag struct { 325*333d2b36SAndroid Build Coastguard Worker blueprint.BaseDependencyTag 326*333d2b36SAndroid Build Coastguard Worker android.LicenseAnnotationSharedDependencyTag 327*333d2b36SAndroid Build Coastguard Worker} 328*333d2b36SAndroid Build Coastguard Worker 329*333d2b36SAndroid Build Coastguard Worker// Tag used to mark dependencies on java_library instances that contains Java source files whose 330*333d2b36SAndroid Build Coastguard Worker// sole purpose is to provide additional hiddenapi annotations. 331*333d2b36SAndroid Build Coastguard Workervar hiddenApiAnnotationsTag hiddenApiAnnotationsDependencyTag 332*333d2b36SAndroid Build Coastguard Worker 333*333d2b36SAndroid Build Coastguard Worker// Mark this tag so dependencies that use it are excluded from APEX contents. 334*333d2b36SAndroid Build Coastguard Workerfunc (t hiddenApiAnnotationsDependencyTag) ExcludeFromApexContents() {} 335*333d2b36SAndroid Build Coastguard Worker 336*333d2b36SAndroid Build Coastguard Workervar _ android.ExcludeFromApexContentsTag = hiddenApiAnnotationsTag 337