1*333d2b36SAndroid Build Coastguard Worker// Copyright (C) 2021 The Android Open Source Project 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 "fmt" 19*333d2b36SAndroid Build Coastguard Worker "strings" 20*333d2b36SAndroid Build Coastguard Worker 21*333d2b36SAndroid Build Coastguard Worker "android/soong/android" 22*333d2b36SAndroid Build Coastguard Worker "android/soong/dexpreopt" 23*333d2b36SAndroid Build Coastguard Worker 24*333d2b36SAndroid Build Coastguard Worker "github.com/google/blueprint" 25*333d2b36SAndroid Build Coastguard Worker) 26*333d2b36SAndroid Build Coastguard Worker 27*333d2b36SAndroid Build Coastguard Worker// Contains support for processing hiddenAPI in a modular fashion. 28*333d2b36SAndroid Build Coastguard Worker 29*333d2b36SAndroid Build Coastguard Worker// HiddenAPIScope encapsulates all the information that the hidden API processing needs about API 30*333d2b36SAndroid Build Coastguard Worker// scopes, i.e. what is called android.SdkKind and apiScope. It does not just use those as they do 31*333d2b36SAndroid Build Coastguard Worker// not provide the information needed by hidden API processing. 32*333d2b36SAndroid Build Coastguard Workertype HiddenAPIScope struct { 33*333d2b36SAndroid Build Coastguard Worker // The name of the scope, used for debug purposes. 34*333d2b36SAndroid Build Coastguard Worker name string 35*333d2b36SAndroid Build Coastguard Worker 36*333d2b36SAndroid Build Coastguard Worker // The corresponding android.SdkKind, used for retrieving paths from java_sdk_library* modules. 37*333d2b36SAndroid Build Coastguard Worker sdkKind android.SdkKind 38*333d2b36SAndroid Build Coastguard Worker 39*333d2b36SAndroid Build Coastguard Worker // The option needed to passed to "hiddenapi list". 40*333d2b36SAndroid Build Coastguard Worker hiddenAPIListOption string 41*333d2b36SAndroid Build Coastguard Worker 42*333d2b36SAndroid Build Coastguard Worker // The names of the source stub library modules that contain the API provided by the platform, 43*333d2b36SAndroid Build Coastguard Worker // i.e. by modules that are not in an APEX. 44*333d2b36SAndroid Build Coastguard Worker nonUpdatableSourceModule string 45*333d2b36SAndroid Build Coastguard Worker 46*333d2b36SAndroid Build Coastguard Worker // The names of from-text stub library modules that contain the API provided by the platform, 47*333d2b36SAndroid Build Coastguard Worker // i.e. by modules that are not in an APEX. 48*333d2b36SAndroid Build Coastguard Worker nonUpdatableFromTextModule string 49*333d2b36SAndroid Build Coastguard Worker 50*333d2b36SAndroid Build Coastguard Worker // The names of the prebuilt stub library modules that contain the API provided by the platform, 51*333d2b36SAndroid Build Coastguard Worker // i.e. by modules that are not in an APEX. 52*333d2b36SAndroid Build Coastguard Worker nonUpdatablePrebuiltModule string 53*333d2b36SAndroid Build Coastguard Worker} 54*333d2b36SAndroid Build Coastguard Worker 55*333d2b36SAndroid Build Coastguard Worker// initHiddenAPIScope initializes the scope. 56*333d2b36SAndroid Build Coastguard Workerfunc initHiddenAPIScope(apiScope *HiddenAPIScope) *HiddenAPIScope { 57*333d2b36SAndroid Build Coastguard Worker sdkKind := apiScope.sdkKind 58*333d2b36SAndroid Build Coastguard Worker // The platform does not provide a core platform API. 59*333d2b36SAndroid Build Coastguard Worker if sdkKind != android.SdkCorePlatform { 60*333d2b36SAndroid Build Coastguard Worker kindAsString := sdkKind.String() 61*333d2b36SAndroid Build Coastguard Worker var insert string 62*333d2b36SAndroid Build Coastguard Worker if sdkKind == android.SdkPublic { 63*333d2b36SAndroid Build Coastguard Worker insert = "" 64*333d2b36SAndroid Build Coastguard Worker } else { 65*333d2b36SAndroid Build Coastguard Worker insert = "." + strings.ReplaceAll(kindAsString, "-", "_") 66*333d2b36SAndroid Build Coastguard Worker } 67*333d2b36SAndroid Build Coastguard Worker 68*333d2b36SAndroid Build Coastguard Worker nonUpdatableModule := "android-non-updatable" 69*333d2b36SAndroid Build Coastguard Worker 70*333d2b36SAndroid Build Coastguard Worker // Construct the name of the android-non-updatable source module for this scope. 71*333d2b36SAndroid Build Coastguard Worker apiScope.nonUpdatableSourceModule = fmt.Sprintf("%s.stubs%s", nonUpdatableModule, insert) 72*333d2b36SAndroid Build Coastguard Worker 73*333d2b36SAndroid Build Coastguard Worker prebuiltModuleName := func(name string, kind string) string { 74*333d2b36SAndroid Build Coastguard Worker return fmt.Sprintf("sdk_%s_current_%s", kind, name) 75*333d2b36SAndroid Build Coastguard Worker } 76*333d2b36SAndroid Build Coastguard Worker 77*333d2b36SAndroid Build Coastguard Worker // Construct the name of the android-non-updatable prebuilt module for this scope. 78*333d2b36SAndroid Build Coastguard Worker apiScope.nonUpdatablePrebuiltModule = prebuiltModuleName(nonUpdatableModule, kindAsString) 79*333d2b36SAndroid Build Coastguard Worker } 80*333d2b36SAndroid Build Coastguard Worker 81*333d2b36SAndroid Build Coastguard Worker return apiScope 82*333d2b36SAndroid Build Coastguard Worker} 83*333d2b36SAndroid Build Coastguard Worker 84*333d2b36SAndroid Build Coastguard Worker// android-non-updatable takes the name of a module and returns a possibly scope specific name of 85*333d2b36SAndroid Build Coastguard Worker// the module. 86*333d2b36SAndroid Build Coastguard Workerfunc (l *HiddenAPIScope) scopeSpecificStubModule(ctx android.BaseModuleContext, name string) string { 87*333d2b36SAndroid Build Coastguard Worker // The android-non-updatable is not a java_sdk_library but there are separate stub libraries for 88*333d2b36SAndroid Build Coastguard Worker // each scope. 89*333d2b36SAndroid Build Coastguard Worker // TODO(b/192067200): Remove special handling of android-non-updatable. 90*333d2b36SAndroid Build Coastguard Worker if name == "android-non-updatable" { 91*333d2b36SAndroid Build Coastguard Worker if ctx.Config().AlwaysUsePrebuiltSdks() { 92*333d2b36SAndroid Build Coastguard Worker return l.nonUpdatablePrebuiltModule 93*333d2b36SAndroid Build Coastguard Worker } else { 94*333d2b36SAndroid Build Coastguard Worker if l.nonUpdatableFromTextModule != "" && ctx.Config().BuildFromTextStub() { 95*333d2b36SAndroid Build Coastguard Worker return l.nonUpdatableFromTextModule 96*333d2b36SAndroid Build Coastguard Worker } 97*333d2b36SAndroid Build Coastguard Worker return l.nonUpdatableSourceModule 98*333d2b36SAndroid Build Coastguard Worker } 99*333d2b36SAndroid Build Coastguard Worker } else { 100*333d2b36SAndroid Build Coastguard Worker // Assume that the module is either a java_sdk_library (or equivalent) and so will provide 101*333d2b36SAndroid Build Coastguard Worker // separate stub jars for each scope or is a java_library (or equivalent) in which case it will 102*333d2b36SAndroid Build Coastguard Worker // have the same stub jar for each scope. 103*333d2b36SAndroid Build Coastguard Worker return name 104*333d2b36SAndroid Build Coastguard Worker } 105*333d2b36SAndroid Build Coastguard Worker} 106*333d2b36SAndroid Build Coastguard Worker 107*333d2b36SAndroid Build Coastguard Workerfunc (l *HiddenAPIScope) String() string { 108*333d2b36SAndroid Build Coastguard Worker return fmt.Sprintf("HiddenAPIScope{%s}", l.name) 109*333d2b36SAndroid Build Coastguard Worker} 110*333d2b36SAndroid Build Coastguard Worker 111*333d2b36SAndroid Build Coastguard Workervar ( 112*333d2b36SAndroid Build Coastguard Worker PublicHiddenAPIScope = initHiddenAPIScope(&HiddenAPIScope{ 113*333d2b36SAndroid Build Coastguard Worker name: "public", 114*333d2b36SAndroid Build Coastguard Worker sdkKind: android.SdkPublic, 115*333d2b36SAndroid Build Coastguard Worker hiddenAPIListOption: "--public-stub-classpath", 116*333d2b36SAndroid Build Coastguard Worker }) 117*333d2b36SAndroid Build Coastguard Worker SystemHiddenAPIScope = initHiddenAPIScope(&HiddenAPIScope{ 118*333d2b36SAndroid Build Coastguard Worker name: "system", 119*333d2b36SAndroid Build Coastguard Worker sdkKind: android.SdkSystem, 120*333d2b36SAndroid Build Coastguard Worker hiddenAPIListOption: "--system-stub-classpath", 121*333d2b36SAndroid Build Coastguard Worker }) 122*333d2b36SAndroid Build Coastguard Worker TestHiddenAPIScope = initHiddenAPIScope(&HiddenAPIScope{ 123*333d2b36SAndroid Build Coastguard Worker name: "test", 124*333d2b36SAndroid Build Coastguard Worker sdkKind: android.SdkTest, 125*333d2b36SAndroid Build Coastguard Worker hiddenAPIListOption: "--test-stub-classpath", 126*333d2b36SAndroid Build Coastguard Worker }) 127*333d2b36SAndroid Build Coastguard Worker ModuleLibHiddenAPIScope = initHiddenAPIScope(&HiddenAPIScope{ 128*333d2b36SAndroid Build Coastguard Worker name: "module-lib", 129*333d2b36SAndroid Build Coastguard Worker sdkKind: android.SdkModule, 130*333d2b36SAndroid Build Coastguard Worker nonUpdatableFromTextModule: "android-non-updatable.stubs.test_module_lib", 131*333d2b36SAndroid Build Coastguard Worker }) 132*333d2b36SAndroid Build Coastguard Worker CorePlatformHiddenAPIScope = initHiddenAPIScope(&HiddenAPIScope{ 133*333d2b36SAndroid Build Coastguard Worker name: "core-platform", 134*333d2b36SAndroid Build Coastguard Worker sdkKind: android.SdkCorePlatform, 135*333d2b36SAndroid Build Coastguard Worker hiddenAPIListOption: "--core-platform-stub-classpath", 136*333d2b36SAndroid Build Coastguard Worker }) 137*333d2b36SAndroid Build Coastguard Worker 138*333d2b36SAndroid Build Coastguard Worker // hiddenAPIRelevantSdkKinds lists all the android.SdkKind instances that are needed by the hidden 139*333d2b36SAndroid Build Coastguard Worker // API processing. 140*333d2b36SAndroid Build Coastguard Worker // 141*333d2b36SAndroid Build Coastguard Worker // These are roughly in order from narrowest API surface to widest. Widest means the API stubs 142*333d2b36SAndroid Build Coastguard Worker // with the biggest API surface, e.g. test is wider than system is wider than public. 143*333d2b36SAndroid Build Coastguard Worker // 144*333d2b36SAndroid Build Coastguard Worker // Core platform is considered wider than system/module-lib because those modules that provide 145*333d2b36SAndroid Build Coastguard Worker // core platform APIs either do not have any system/module-lib APIs at all, or if they do it is 146*333d2b36SAndroid Build Coastguard Worker // because the core platform API is being converted to system/module-lib APIs. In either case the 147*333d2b36SAndroid Build Coastguard Worker // system/module-lib APIs are subsets of the core platform API. 148*333d2b36SAndroid Build Coastguard Worker // 149*333d2b36SAndroid Build Coastguard Worker // This is not strictly in order from narrowest to widest as the Test API is wider than system but 150*333d2b36SAndroid Build Coastguard Worker // is neither wider or narrower than the module-lib or core platform APIs. However, this works 151*333d2b36SAndroid Build Coastguard Worker // well enough at the moment. 152*333d2b36SAndroid Build Coastguard Worker // TODO(b/191644675): Correctly reflect the sub/superset relationships between APIs. 153*333d2b36SAndroid Build Coastguard Worker hiddenAPIScopes = []*HiddenAPIScope{ 154*333d2b36SAndroid Build Coastguard Worker PublicHiddenAPIScope, 155*333d2b36SAndroid Build Coastguard Worker SystemHiddenAPIScope, 156*333d2b36SAndroid Build Coastguard Worker TestHiddenAPIScope, 157*333d2b36SAndroid Build Coastguard Worker ModuleLibHiddenAPIScope, 158*333d2b36SAndroid Build Coastguard Worker CorePlatformHiddenAPIScope, 159*333d2b36SAndroid Build Coastguard Worker } 160*333d2b36SAndroid Build Coastguard Worker 161*333d2b36SAndroid Build Coastguard Worker // The HiddenAPIScope instances that are supported by a java_sdk_library. 162*333d2b36SAndroid Build Coastguard Worker // 163*333d2b36SAndroid Build Coastguard Worker // CorePlatformHiddenAPIScope is not used as the java_sdk_library does not have special support 164*333d2b36SAndroid Build Coastguard Worker // for core_platform API, instead it is implemented as a customized form of PublicHiddenAPIScope. 165*333d2b36SAndroid Build Coastguard Worker hiddenAPISdkLibrarySupportedScopes = []*HiddenAPIScope{ 166*333d2b36SAndroid Build Coastguard Worker PublicHiddenAPIScope, 167*333d2b36SAndroid Build Coastguard Worker SystemHiddenAPIScope, 168*333d2b36SAndroid Build Coastguard Worker TestHiddenAPIScope, 169*333d2b36SAndroid Build Coastguard Worker ModuleLibHiddenAPIScope, 170*333d2b36SAndroid Build Coastguard Worker } 171*333d2b36SAndroid Build Coastguard Worker 172*333d2b36SAndroid Build Coastguard Worker // The HiddenAPIScope instances that are supported by the `hiddenapi list`. 173*333d2b36SAndroid Build Coastguard Worker hiddenAPIFlagScopes = []*HiddenAPIScope{ 174*333d2b36SAndroid Build Coastguard Worker PublicHiddenAPIScope, 175*333d2b36SAndroid Build Coastguard Worker SystemHiddenAPIScope, 176*333d2b36SAndroid Build Coastguard Worker TestHiddenAPIScope, 177*333d2b36SAndroid Build Coastguard Worker CorePlatformHiddenAPIScope, 178*333d2b36SAndroid Build Coastguard Worker } 179*333d2b36SAndroid Build Coastguard Worker) 180*333d2b36SAndroid Build Coastguard Worker 181*333d2b36SAndroid Build Coastguard Workertype hiddenAPIStubsDependencyTag struct { 182*333d2b36SAndroid Build Coastguard Worker blueprint.BaseDependencyTag 183*333d2b36SAndroid Build Coastguard Worker 184*333d2b36SAndroid Build Coastguard Worker // The api scope for which this dependency was added. 185*333d2b36SAndroid Build Coastguard Worker apiScope *HiddenAPIScope 186*333d2b36SAndroid Build Coastguard Worker 187*333d2b36SAndroid Build Coastguard Worker // Indicates that the dependency is not for an API provided by the current bootclasspath fragment 188*333d2b36SAndroid Build Coastguard Worker // but is an additional API provided by a module that is not part of the current bootclasspath 189*333d2b36SAndroid Build Coastguard Worker // fragment. 190*333d2b36SAndroid Build Coastguard Worker fromAdditionalDependency bool 191*333d2b36SAndroid Build Coastguard Worker} 192*333d2b36SAndroid Build Coastguard Worker 193*333d2b36SAndroid Build Coastguard Workerfunc (b hiddenAPIStubsDependencyTag) ExcludeFromApexContents() { 194*333d2b36SAndroid Build Coastguard Worker} 195*333d2b36SAndroid Build Coastguard Worker 196*333d2b36SAndroid Build Coastguard Workerfunc (b hiddenAPIStubsDependencyTag) ReplaceSourceWithPrebuilt() bool { 197*333d2b36SAndroid Build Coastguard Worker return false 198*333d2b36SAndroid Build Coastguard Worker} 199*333d2b36SAndroid Build Coastguard Worker 200*333d2b36SAndroid Build Coastguard Workerfunc (b hiddenAPIStubsDependencyTag) SdkMemberType(child android.Module) android.SdkMemberType { 201*333d2b36SAndroid Build Coastguard Worker // Do not add additional dependencies to the sdk. 202*333d2b36SAndroid Build Coastguard Worker if b.fromAdditionalDependency { 203*333d2b36SAndroid Build Coastguard Worker return nil 204*333d2b36SAndroid Build Coastguard Worker } 205*333d2b36SAndroid Build Coastguard Worker 206*333d2b36SAndroid Build Coastguard Worker // If the module is a java_sdk_library then treat it as if it was specific in the java_sdk_libs 207*333d2b36SAndroid Build Coastguard Worker // property, otherwise treat if it was specified in the java_header_libs property. 208*333d2b36SAndroid Build Coastguard Worker if javaSdkLibrarySdkMemberType.IsInstance(child) { 209*333d2b36SAndroid Build Coastguard Worker return javaSdkLibrarySdkMemberType 210*333d2b36SAndroid Build Coastguard Worker } 211*333d2b36SAndroid Build Coastguard Worker 212*333d2b36SAndroid Build Coastguard Worker return javaHeaderLibsSdkMemberType 213*333d2b36SAndroid Build Coastguard Worker} 214*333d2b36SAndroid Build Coastguard Worker 215*333d2b36SAndroid Build Coastguard Workerfunc (b hiddenAPIStubsDependencyTag) ExportMember() bool { 216*333d2b36SAndroid Build Coastguard Worker // Export the module added via this dependency tag from the sdk. 217*333d2b36SAndroid Build Coastguard Worker return true 218*333d2b36SAndroid Build Coastguard Worker} 219*333d2b36SAndroid Build Coastguard Worker 220*333d2b36SAndroid Build Coastguard Worker// Avoid having to make stubs content explicitly visible to dependent modules. 221*333d2b36SAndroid Build Coastguard Worker// 222*333d2b36SAndroid Build Coastguard Worker// This is a temporary workaround to make it easier to migrate to bootclasspath_fragment modules 223*333d2b36SAndroid Build Coastguard Worker// with proper dependencies. 224*333d2b36SAndroid Build Coastguard Worker// TODO(b/177892522): Remove this and add needed visibility. 225*333d2b36SAndroid Build Coastguard Workerfunc (b hiddenAPIStubsDependencyTag) ExcludeFromVisibilityEnforcement() { 226*333d2b36SAndroid Build Coastguard Worker} 227*333d2b36SAndroid Build Coastguard Worker 228*333d2b36SAndroid Build Coastguard Workervar _ android.ExcludeFromVisibilityEnforcementTag = hiddenAPIStubsDependencyTag{} 229*333d2b36SAndroid Build Coastguard Workervar _ android.ReplaceSourceWithPrebuilt = hiddenAPIStubsDependencyTag{} 230*333d2b36SAndroid Build Coastguard Workervar _ android.ExcludeFromApexContentsTag = hiddenAPIStubsDependencyTag{} 231*333d2b36SAndroid Build Coastguard Workervar _ android.SdkMemberDependencyTag = hiddenAPIStubsDependencyTag{} 232*333d2b36SAndroid Build Coastguard Worker 233*333d2b36SAndroid Build Coastguard Worker// hiddenAPIComputeMonolithicStubLibModules computes the set of module names that provide stubs 234*333d2b36SAndroid Build Coastguard Worker// needed to produce the hidden API monolithic stub flags file. 235*333d2b36SAndroid Build Coastguard Workerfunc hiddenAPIComputeMonolithicStubLibModules(config android.Config) map[*HiddenAPIScope][]string { 236*333d2b36SAndroid Build Coastguard Worker var publicStubModules []string 237*333d2b36SAndroid Build Coastguard Worker var systemStubModules []string 238*333d2b36SAndroid Build Coastguard Worker var testStubModules []string 239*333d2b36SAndroid Build Coastguard Worker var corePlatformStubModules []string 240*333d2b36SAndroid Build Coastguard Worker 241*333d2b36SAndroid Build Coastguard Worker if config.AlwaysUsePrebuiltSdks() { 242*333d2b36SAndroid Build Coastguard Worker // Build configuration mandates using prebuilt stub modules 243*333d2b36SAndroid Build Coastguard Worker publicStubModules = append(publicStubModules, "sdk_public_current_android") 244*333d2b36SAndroid Build Coastguard Worker systemStubModules = append(systemStubModules, "sdk_system_current_android") 245*333d2b36SAndroid Build Coastguard Worker testStubModules = append(testStubModules, "sdk_test_current_android") 246*333d2b36SAndroid Build Coastguard Worker } else { 247*333d2b36SAndroid Build Coastguard Worker // Use stub modules built from source 248*333d2b36SAndroid Build Coastguard Worker if config.ReleaseHiddenApiExportableStubs() { 249*333d2b36SAndroid Build Coastguard Worker publicStubModules = append(publicStubModules, android.SdkPublic.DefaultExportableJavaLibraryName()) 250*333d2b36SAndroid Build Coastguard Worker systemStubModules = append(systemStubModules, android.SdkSystem.DefaultExportableJavaLibraryName()) 251*333d2b36SAndroid Build Coastguard Worker testStubModules = append(testStubModules, android.SdkTest.DefaultExportableJavaLibraryName()) 252*333d2b36SAndroid Build Coastguard Worker } else { 253*333d2b36SAndroid Build Coastguard Worker publicStubModules = append(publicStubModules, android.SdkPublic.DefaultJavaLibraryName()) 254*333d2b36SAndroid Build Coastguard Worker systemStubModules = append(systemStubModules, android.SdkSystem.DefaultJavaLibraryName()) 255*333d2b36SAndroid Build Coastguard Worker testStubModules = append(testStubModules, android.SdkTest.DefaultJavaLibraryName()) 256*333d2b36SAndroid Build Coastguard Worker } 257*333d2b36SAndroid Build Coastguard Worker } 258*333d2b36SAndroid Build Coastguard Worker // We do not have prebuilts of the core platform api yet 259*333d2b36SAndroid Build Coastguard Worker if config.ReleaseHiddenApiExportableStubs() { 260*333d2b36SAndroid Build Coastguard Worker corePlatformStubModules = append(corePlatformStubModules, "legacy.core.platform.api.stubs.exportable") 261*333d2b36SAndroid Build Coastguard Worker } else { 262*333d2b36SAndroid Build Coastguard Worker corePlatformStubModules = append(corePlatformStubModules, "legacy.core.platform.api.stubs") 263*333d2b36SAndroid Build Coastguard Worker } 264*333d2b36SAndroid Build Coastguard Worker 265*333d2b36SAndroid Build Coastguard Worker // Allow products to define their own stubs for custom product jars that apps can use. 266*333d2b36SAndroid Build Coastguard Worker publicStubModules = append(publicStubModules, config.ProductHiddenAPIStubs()...) 267*333d2b36SAndroid Build Coastguard Worker systemStubModules = append(systemStubModules, config.ProductHiddenAPIStubsSystem()...) 268*333d2b36SAndroid Build Coastguard Worker testStubModules = append(testStubModules, config.ProductHiddenAPIStubsTest()...) 269*333d2b36SAndroid Build Coastguard Worker if config.IsEnvTrue("EMMA_INSTRUMENT") { 270*333d2b36SAndroid Build Coastguard Worker // Add jacoco-stubs to public, system and test. It doesn't make any real difference as public 271*333d2b36SAndroid Build Coastguard Worker // allows everyone access but it is needed to ensure consistent flags between the 272*333d2b36SAndroid Build Coastguard Worker // bootclasspath fragment generated flags and the platform_bootclasspath generated flags. 273*333d2b36SAndroid Build Coastguard Worker publicStubModules = append(publicStubModules, "jacoco-stubs") 274*333d2b36SAndroid Build Coastguard Worker systemStubModules = append(systemStubModules, "jacoco-stubs") 275*333d2b36SAndroid Build Coastguard Worker testStubModules = append(testStubModules, "jacoco-stubs") 276*333d2b36SAndroid Build Coastguard Worker } 277*333d2b36SAndroid Build Coastguard Worker 278*333d2b36SAndroid Build Coastguard Worker m := map[*HiddenAPIScope][]string{} 279*333d2b36SAndroid Build Coastguard Worker m[PublicHiddenAPIScope] = publicStubModules 280*333d2b36SAndroid Build Coastguard Worker m[SystemHiddenAPIScope] = systemStubModules 281*333d2b36SAndroid Build Coastguard Worker m[TestHiddenAPIScope] = testStubModules 282*333d2b36SAndroid Build Coastguard Worker m[CorePlatformHiddenAPIScope] = corePlatformStubModules 283*333d2b36SAndroid Build Coastguard Worker return m 284*333d2b36SAndroid Build Coastguard Worker} 285*333d2b36SAndroid Build Coastguard Worker 286*333d2b36SAndroid Build Coastguard Worker// hiddenAPIAddStubLibDependencies adds dependencies onto the modules specified in 287*333d2b36SAndroid Build Coastguard Worker// apiScopeToStubLibModules. It adds them in a well known order and uses a HiddenAPIScope specific 288*333d2b36SAndroid Build Coastguard Worker// tag to identify the source of the dependency. 289*333d2b36SAndroid Build Coastguard Workerfunc hiddenAPIAddStubLibDependencies(ctx android.BottomUpMutatorContext, apiScopeToStubLibModules map[*HiddenAPIScope][]string) { 290*333d2b36SAndroid Build Coastguard Worker module := ctx.Module() 291*333d2b36SAndroid Build Coastguard Worker for _, apiScope := range hiddenAPIScopes { 292*333d2b36SAndroid Build Coastguard Worker modules := apiScopeToStubLibModules[apiScope] 293*333d2b36SAndroid Build Coastguard Worker ctx.AddDependency(module, hiddenAPIStubsDependencyTag{apiScope: apiScope}, modules...) 294*333d2b36SAndroid Build Coastguard Worker } 295*333d2b36SAndroid Build Coastguard Worker} 296*333d2b36SAndroid Build Coastguard Worker 297*333d2b36SAndroid Build Coastguard Worker// hiddenAPIRetrieveDexJarBuildPath retrieves the DexJarBuildPath from the specified module, if 298*333d2b36SAndroid Build Coastguard Worker// available, or reports an error. 299*333d2b36SAndroid Build Coastguard Workerfunc hiddenAPIRetrieveDexJarBuildPath(ctx android.ModuleContext, module android.Module, kind android.SdkKind) android.Path { 300*333d2b36SAndroid Build Coastguard Worker var dexJar OptionalDexJarPath 301*333d2b36SAndroid Build Coastguard Worker if sdkLibrary, ok := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider); ok { 302*333d2b36SAndroid Build Coastguard Worker if ctx.Config().ReleaseHiddenApiExportableStubs() { 303*333d2b36SAndroid Build Coastguard Worker dexJar = sdkLibrary.ExportableStubDexJarPaths[kind] 304*333d2b36SAndroid Build Coastguard Worker } else { 305*333d2b36SAndroid Build Coastguard Worker dexJar = sdkLibrary.EverythingStubDexJarPaths[kind] 306*333d2b36SAndroid Build Coastguard Worker } 307*333d2b36SAndroid Build Coastguard Worker } else if j, ok := module.(UsesLibraryDependency); ok { 308*333d2b36SAndroid Build Coastguard Worker dexJar = j.DexJarBuildPath(ctx) 309*333d2b36SAndroid Build Coastguard Worker } else { 310*333d2b36SAndroid Build Coastguard Worker ctx.ModuleErrorf("dependency %s of module type %s does not support providing a dex jar", module, ctx.OtherModuleType(module)) 311*333d2b36SAndroid Build Coastguard Worker return nil 312*333d2b36SAndroid Build Coastguard Worker } 313*333d2b36SAndroid Build Coastguard Worker 314*333d2b36SAndroid Build Coastguard Worker if !dexJar.Valid() { 315*333d2b36SAndroid Build Coastguard Worker ctx.ModuleErrorf("dependency %s does not provide a dex jar: %s", module, dexJar.InvalidReason()) 316*333d2b36SAndroid Build Coastguard Worker return nil 317*333d2b36SAndroid Build Coastguard Worker } 318*333d2b36SAndroid Build Coastguard Worker return dexJar.Path() 319*333d2b36SAndroid Build Coastguard Worker} 320*333d2b36SAndroid Build Coastguard Worker 321*333d2b36SAndroid Build Coastguard Worker// HIDDENAPI_STUB_FLAGS_IMPL_FLAGS is the set of flags that identify implementation only signatures, 322*333d2b36SAndroid Build Coastguard Worker// i.e. those signatures that are not part of any API (including the hidden API). 323*333d2b36SAndroid Build Coastguard Workervar HIDDENAPI_STUB_FLAGS_IMPL_FLAGS = []string{} 324*333d2b36SAndroid Build Coastguard Worker 325*333d2b36SAndroid Build Coastguard Workervar HIDDENAPI_FLAGS_CSV_IMPL_FLAGS = []string{"blocked"} 326*333d2b36SAndroid Build Coastguard Worker 327*333d2b36SAndroid Build Coastguard Worker// buildRuleToGenerateHiddenAPIStubFlagsFile creates a rule to create a hidden API stub flags file. 328*333d2b36SAndroid Build Coastguard Worker// 329*333d2b36SAndroid Build Coastguard Worker// The rule is initialized but not built so that the caller can modify it and select an appropriate 330*333d2b36SAndroid Build Coastguard Worker// name. 331*333d2b36SAndroid Build Coastguard Workerfunc buildRuleToGenerateHiddenAPIStubFlagsFile(ctx android.BuilderContext, name, desc string, outputPath android.WritablePath, bootDexJars android.Paths, input HiddenAPIFlagInput, stubFlagSubsets SignatureCsvSubsets) { 332*333d2b36SAndroid Build Coastguard Worker // Singleton rule which applies hiddenapi on all boot class path dex files. 333*333d2b36SAndroid Build Coastguard Worker rule := android.NewRuleBuilder(pctx, ctx) 334*333d2b36SAndroid Build Coastguard Worker 335*333d2b36SAndroid Build Coastguard Worker tempPath := tempPathForRestat(ctx, outputPath) 336*333d2b36SAndroid Build Coastguard Worker 337*333d2b36SAndroid Build Coastguard Worker // Find the widest API stubs provided by the fragments on which this depends, if any. 338*333d2b36SAndroid Build Coastguard Worker dependencyStubDexJars := input.DependencyStubDexJarsByScope.StubDexJarsForWidestAPIScope() 339*333d2b36SAndroid Build Coastguard Worker 340*333d2b36SAndroid Build Coastguard Worker // Add widest API stubs from the additional dependencies of this, if any. 341*333d2b36SAndroid Build Coastguard Worker dependencyStubDexJars = append(dependencyStubDexJars, input.AdditionalStubDexJarsByScope.StubDexJarsForWidestAPIScope()...) 342*333d2b36SAndroid Build Coastguard Worker 343*333d2b36SAndroid Build Coastguard Worker command := rule.Command(). 344*333d2b36SAndroid Build Coastguard Worker Tool(ctx.Config().HostToolPath(ctx, "hiddenapi")). 345*333d2b36SAndroid Build Coastguard Worker Text("list"). 346*333d2b36SAndroid Build Coastguard Worker FlagForEachInput("--dependency-stub-dex=", dependencyStubDexJars). 347*333d2b36SAndroid Build Coastguard Worker FlagForEachInput("--boot-dex=", bootDexJars) 348*333d2b36SAndroid Build Coastguard Worker 349*333d2b36SAndroid Build Coastguard Worker // If no module stub flags paths are provided then this must be being called for a 350*333d2b36SAndroid Build Coastguard Worker // bootclasspath_fragment and not the whole platform_bootclasspath. 351*333d2b36SAndroid Build Coastguard Worker if stubFlagSubsets == nil { 352*333d2b36SAndroid Build Coastguard Worker // This is being run on a fragment of the bootclasspath. 353*333d2b36SAndroid Build Coastguard Worker command.Flag("--fragment") 354*333d2b36SAndroid Build Coastguard Worker } 355*333d2b36SAndroid Build Coastguard Worker 356*333d2b36SAndroid Build Coastguard Worker // Iterate over the api scopes in a fixed order. 357*333d2b36SAndroid Build Coastguard Worker for _, apiScope := range hiddenAPIFlagScopes { 358*333d2b36SAndroid Build Coastguard Worker // Merge in the stub dex jar paths for this api scope from the fragments on which it depends. 359*333d2b36SAndroid Build Coastguard Worker // They will be needed to resolve dependencies from this fragment's stubs to classes in the 360*333d2b36SAndroid Build Coastguard Worker // other fragment's APIs. 361*333d2b36SAndroid Build Coastguard Worker var paths android.Paths 362*333d2b36SAndroid Build Coastguard Worker paths = append(paths, input.DependencyStubDexJarsByScope.StubDexJarsForScope(apiScope)...) 363*333d2b36SAndroid Build Coastguard Worker paths = append(paths, input.AdditionalStubDexJarsByScope.StubDexJarsForScope(apiScope)...) 364*333d2b36SAndroid Build Coastguard Worker paths = append(paths, input.StubDexJarsByScope.StubDexJarsForScope(apiScope)...) 365*333d2b36SAndroid Build Coastguard Worker if len(paths) > 0 { 366*333d2b36SAndroid Build Coastguard Worker option := apiScope.hiddenAPIListOption 367*333d2b36SAndroid Build Coastguard Worker command.FlagWithInputList(option+"=", paths, ":") 368*333d2b36SAndroid Build Coastguard Worker } 369*333d2b36SAndroid Build Coastguard Worker } 370*333d2b36SAndroid Build Coastguard Worker 371*333d2b36SAndroid Build Coastguard Worker // Add the output path. 372*333d2b36SAndroid Build Coastguard Worker command.FlagWithOutput("--out-api-flags=", tempPath) 373*333d2b36SAndroid Build Coastguard Worker 374*333d2b36SAndroid Build Coastguard Worker // If there are stub flag files that have been generated by fragments on which this depends then 375*333d2b36SAndroid Build Coastguard Worker // use them to validate the stub flag file generated by the rules created by this method. 376*333d2b36SAndroid Build Coastguard Worker if !ctx.Config().DisableVerifyOverlaps() && len(stubFlagSubsets) > 0 { 377*333d2b36SAndroid Build Coastguard Worker validFile := buildRuleValidateOverlappingCsvFiles(ctx, name, desc, outputPath, stubFlagSubsets, 378*333d2b36SAndroid Build Coastguard Worker HIDDENAPI_STUB_FLAGS_IMPL_FLAGS) 379*333d2b36SAndroid Build Coastguard Worker 380*333d2b36SAndroid Build Coastguard Worker // Add the file that indicates that the file generated by this is valid. 381*333d2b36SAndroid Build Coastguard Worker // 382*333d2b36SAndroid Build Coastguard Worker // This will cause the validation rule above to be run any time that the output of this rule 383*333d2b36SAndroid Build Coastguard Worker // changes but the validation will run in parallel with other rules that depend on this file. 384*333d2b36SAndroid Build Coastguard Worker command.Validation(validFile) 385*333d2b36SAndroid Build Coastguard Worker } 386*333d2b36SAndroid Build Coastguard Worker 387*333d2b36SAndroid Build Coastguard Worker commitChangeForRestat(rule, tempPath, outputPath) 388*333d2b36SAndroid Build Coastguard Worker 389*333d2b36SAndroid Build Coastguard Worker rule.Build(name, desc) 390*333d2b36SAndroid Build Coastguard Worker} 391*333d2b36SAndroid Build Coastguard Worker 392*333d2b36SAndroid Build Coastguard Worker// HiddenAPIFlagFileProperties contains paths to the flag files that can be used to augment the 393*333d2b36SAndroid Build Coastguard Worker// information obtained from annotations within the source code in order to create the complete set 394*333d2b36SAndroid Build Coastguard Worker// of flags that should be applied to the dex implementation jars on the bootclasspath. 395*333d2b36SAndroid Build Coastguard Worker// 396*333d2b36SAndroid Build Coastguard Worker// Each property contains a list of paths. With the exception of the Unsupported_packages the paths 397*333d2b36SAndroid Build Coastguard Worker// of each property reference a plain text file that contains a java signature per line. The flags 398*333d2b36SAndroid Build Coastguard Worker// for each of those signatures will be updated in a property specific way. 399*333d2b36SAndroid Build Coastguard Worker// 400*333d2b36SAndroid Build Coastguard Worker// The Unsupported_packages property contains a list of paths, each of which is a plain text file 401*333d2b36SAndroid Build Coastguard Worker// with one Java package per line. All members of all classes within that package (but not nested 402*333d2b36SAndroid Build Coastguard Worker// packages) will be updated in a property specific way. 403*333d2b36SAndroid Build Coastguard Workertype HiddenAPIFlagFileProperties struct { 404*333d2b36SAndroid Build Coastguard Worker Hidden_api struct { 405*333d2b36SAndroid Build Coastguard Worker // Marks each signature in the referenced files as being unsupported. 406*333d2b36SAndroid Build Coastguard Worker Unsupported []string `android:"path"` 407*333d2b36SAndroid Build Coastguard Worker 408*333d2b36SAndroid Build Coastguard Worker // Marks each signature in the referenced files as being unsupported because it has been 409*333d2b36SAndroid Build Coastguard Worker // removed. Any conflicts with other flags are ignored. 410*333d2b36SAndroid Build Coastguard Worker Removed []string `android:"path"` 411*333d2b36SAndroid Build Coastguard Worker 412*333d2b36SAndroid Build Coastguard Worker // Marks each signature in the referenced files as being supported only for 413*333d2b36SAndroid Build Coastguard Worker // targetSdkVersion <= R and low priority. 414*333d2b36SAndroid Build Coastguard Worker Max_target_r_low_priority []string `android:"path"` 415*333d2b36SAndroid Build Coastguard Worker 416*333d2b36SAndroid Build Coastguard Worker // Marks each signature in the referenced files as being supported only for 417*333d2b36SAndroid Build Coastguard Worker // targetSdkVersion <= Q. 418*333d2b36SAndroid Build Coastguard Worker Max_target_q []string `android:"path"` 419*333d2b36SAndroid Build Coastguard Worker 420*333d2b36SAndroid Build Coastguard Worker // Marks each signature in the referenced files as being supported only for 421*333d2b36SAndroid Build Coastguard Worker // targetSdkVersion <= P. 422*333d2b36SAndroid Build Coastguard Worker Max_target_p []string `android:"path"` 423*333d2b36SAndroid Build Coastguard Worker 424*333d2b36SAndroid Build Coastguard Worker // Marks each signature in the referenced files as being supported only for 425*333d2b36SAndroid Build Coastguard Worker // targetSdkVersion <= O 426*333d2b36SAndroid Build Coastguard Worker // and low priority. Any conflicts with other flags are ignored. 427*333d2b36SAndroid Build Coastguard Worker Max_target_o_low_priority []string `android:"path"` 428*333d2b36SAndroid Build Coastguard Worker 429*333d2b36SAndroid Build Coastguard Worker // Marks each signature in the referenced files as being blocked. 430*333d2b36SAndroid Build Coastguard Worker Blocked []string `android:"path"` 431*333d2b36SAndroid Build Coastguard Worker 432*333d2b36SAndroid Build Coastguard Worker // Marks each signature in every package in the referenced files as being unsupported. 433*333d2b36SAndroid Build Coastguard Worker Unsupported_packages []string `android:"path"` 434*333d2b36SAndroid Build Coastguard Worker } 435*333d2b36SAndroid Build Coastguard Worker} 436*333d2b36SAndroid Build Coastguard Worker 437*333d2b36SAndroid Build Coastguard Workertype hiddenAPIFlagFileCategory int 438*333d2b36SAndroid Build Coastguard Worker 439*333d2b36SAndroid Build Coastguard Workerconst ( 440*333d2b36SAndroid Build Coastguard Worker // The flag file category for removed members of the API. 441*333d2b36SAndroid Build Coastguard Worker // 442*333d2b36SAndroid Build Coastguard Worker // This is extracted from HiddenAPIFlagFileCategories as it is needed to add the dex signatures 443*333d2b36SAndroid Build Coastguard Worker // list of removed API members that are generated automatically from the removed.txt files provided 444*333d2b36SAndroid Build Coastguard Worker // by API stubs. 445*333d2b36SAndroid Build Coastguard Worker hiddenAPIFlagFileCategoryRemoved hiddenAPIFlagFileCategory = iota 446*333d2b36SAndroid Build Coastguard Worker hiddenAPIFlagFileCategoryUnsupported 447*333d2b36SAndroid Build Coastguard Worker hiddenAPIFlagFileCategoryMaxTargetRLowPriority 448*333d2b36SAndroid Build Coastguard Worker hiddenAPIFlagFileCategoryMaxTargetQ 449*333d2b36SAndroid Build Coastguard Worker hiddenAPIFlagFileCategoryMaxTargetP 450*333d2b36SAndroid Build Coastguard Worker hiddenAPIFlagFileCategoryMaxTargetOLowPriority 451*333d2b36SAndroid Build Coastguard Worker hiddenAPIFlagFileCategoryBlocked 452*333d2b36SAndroid Build Coastguard Worker hiddenAPIFlagFileCategoryUnsupportedPackages 453*333d2b36SAndroid Build Coastguard Worker) 454*333d2b36SAndroid Build Coastguard Worker 455*333d2b36SAndroid Build Coastguard Workerfunc (c hiddenAPIFlagFileCategory) PropertyName() string { 456*333d2b36SAndroid Build Coastguard Worker switch c { 457*333d2b36SAndroid Build Coastguard Worker case hiddenAPIFlagFileCategoryRemoved: 458*333d2b36SAndroid Build Coastguard Worker return "removed" 459*333d2b36SAndroid Build Coastguard Worker case hiddenAPIFlagFileCategoryUnsupported: 460*333d2b36SAndroid Build Coastguard Worker return "unsupported" 461*333d2b36SAndroid Build Coastguard Worker case hiddenAPIFlagFileCategoryMaxTargetRLowPriority: 462*333d2b36SAndroid Build Coastguard Worker return "max_target_r_low_priority" 463*333d2b36SAndroid Build Coastguard Worker case hiddenAPIFlagFileCategoryMaxTargetQ: 464*333d2b36SAndroid Build Coastguard Worker return "max_target_q" 465*333d2b36SAndroid Build Coastguard Worker case hiddenAPIFlagFileCategoryMaxTargetP: 466*333d2b36SAndroid Build Coastguard Worker return "max_target_p" 467*333d2b36SAndroid Build Coastguard Worker case hiddenAPIFlagFileCategoryMaxTargetOLowPriority: 468*333d2b36SAndroid Build Coastguard Worker return "max_target_o_low_priority" 469*333d2b36SAndroid Build Coastguard Worker case hiddenAPIFlagFileCategoryBlocked: 470*333d2b36SAndroid Build Coastguard Worker return "blocked" 471*333d2b36SAndroid Build Coastguard Worker case hiddenAPIFlagFileCategoryUnsupportedPackages: 472*333d2b36SAndroid Build Coastguard Worker return "unsupported_packages" 473*333d2b36SAndroid Build Coastguard Worker default: 474*333d2b36SAndroid Build Coastguard Worker panic(fmt.Sprintf("Unknown hidden api flag file category type: %d", c)) 475*333d2b36SAndroid Build Coastguard Worker } 476*333d2b36SAndroid Build Coastguard Worker} 477*333d2b36SAndroid Build Coastguard Worker 478*333d2b36SAndroid Build Coastguard Worker// propertyValueReader retrieves the value of the property for this category from the set of properties. 479*333d2b36SAndroid Build Coastguard Workerfunc (c hiddenAPIFlagFileCategory) propertyValueReader(properties *HiddenAPIFlagFileProperties) []string { 480*333d2b36SAndroid Build Coastguard Worker switch c { 481*333d2b36SAndroid Build Coastguard Worker case hiddenAPIFlagFileCategoryRemoved: 482*333d2b36SAndroid Build Coastguard Worker return properties.Hidden_api.Removed 483*333d2b36SAndroid Build Coastguard Worker case hiddenAPIFlagFileCategoryUnsupported: 484*333d2b36SAndroid Build Coastguard Worker return properties.Hidden_api.Unsupported 485*333d2b36SAndroid Build Coastguard Worker case hiddenAPIFlagFileCategoryMaxTargetRLowPriority: 486*333d2b36SAndroid Build Coastguard Worker return properties.Hidden_api.Max_target_r_low_priority 487*333d2b36SAndroid Build Coastguard Worker case hiddenAPIFlagFileCategoryMaxTargetQ: 488*333d2b36SAndroid Build Coastguard Worker return properties.Hidden_api.Max_target_q 489*333d2b36SAndroid Build Coastguard Worker case hiddenAPIFlagFileCategoryMaxTargetP: 490*333d2b36SAndroid Build Coastguard Worker return properties.Hidden_api.Max_target_p 491*333d2b36SAndroid Build Coastguard Worker case hiddenAPIFlagFileCategoryMaxTargetOLowPriority: 492*333d2b36SAndroid Build Coastguard Worker return properties.Hidden_api.Max_target_o_low_priority 493*333d2b36SAndroid Build Coastguard Worker case hiddenAPIFlagFileCategoryBlocked: 494*333d2b36SAndroid Build Coastguard Worker return properties.Hidden_api.Blocked 495*333d2b36SAndroid Build Coastguard Worker case hiddenAPIFlagFileCategoryUnsupportedPackages: 496*333d2b36SAndroid Build Coastguard Worker return properties.Hidden_api.Unsupported_packages 497*333d2b36SAndroid Build Coastguard Worker default: 498*333d2b36SAndroid Build Coastguard Worker panic(fmt.Sprintf("Unknown hidden api flag file category type: %d", c)) 499*333d2b36SAndroid Build Coastguard Worker } 500*333d2b36SAndroid Build Coastguard Worker} 501*333d2b36SAndroid Build Coastguard Worker 502*333d2b36SAndroid Build Coastguard Worker// commandMutator adds the appropriate command line options for this category to the supplied command 503*333d2b36SAndroid Build Coastguard Workerfunc (c hiddenAPIFlagFileCategory) commandMutator(command *android.RuleBuilderCommand, path android.Path) { 504*333d2b36SAndroid Build Coastguard Worker switch c { 505*333d2b36SAndroid Build Coastguard Worker case hiddenAPIFlagFileCategoryRemoved: 506*333d2b36SAndroid Build Coastguard Worker command.FlagWithInput("--unsupported ", path).Flag("--ignore-conflicts ").FlagWithArg("--tag ", "removed") 507*333d2b36SAndroid Build Coastguard Worker case hiddenAPIFlagFileCategoryUnsupported: 508*333d2b36SAndroid Build Coastguard Worker command.FlagWithInput("--unsupported ", path) 509*333d2b36SAndroid Build Coastguard Worker case hiddenAPIFlagFileCategoryMaxTargetRLowPriority: 510*333d2b36SAndroid Build Coastguard Worker command.FlagWithInput("--max-target-r ", path).FlagWithArg("--tag ", "lo-prio") 511*333d2b36SAndroid Build Coastguard Worker case hiddenAPIFlagFileCategoryMaxTargetQ: 512*333d2b36SAndroid Build Coastguard Worker command.FlagWithInput("--max-target-q ", path) 513*333d2b36SAndroid Build Coastguard Worker case hiddenAPIFlagFileCategoryMaxTargetP: 514*333d2b36SAndroid Build Coastguard Worker command.FlagWithInput("--max-target-p ", path) 515*333d2b36SAndroid Build Coastguard Worker case hiddenAPIFlagFileCategoryMaxTargetOLowPriority: 516*333d2b36SAndroid Build Coastguard Worker command.FlagWithInput("--max-target-o ", path).Flag("--ignore-conflicts ").FlagWithArg("--tag ", "lo-prio") 517*333d2b36SAndroid Build Coastguard Worker case hiddenAPIFlagFileCategoryBlocked: 518*333d2b36SAndroid Build Coastguard Worker command.FlagWithInput("--blocked ", path) 519*333d2b36SAndroid Build Coastguard Worker case hiddenAPIFlagFileCategoryUnsupportedPackages: 520*333d2b36SAndroid Build Coastguard Worker command.FlagWithInput("--unsupported ", path).Flag("--packages ") 521*333d2b36SAndroid Build Coastguard Worker default: 522*333d2b36SAndroid Build Coastguard Worker panic(fmt.Sprintf("Unknown hidden api flag file category type: %d", c)) 523*333d2b36SAndroid Build Coastguard Worker } 524*333d2b36SAndroid Build Coastguard Worker} 525*333d2b36SAndroid Build Coastguard Worker 526*333d2b36SAndroid Build Coastguard Workertype hiddenAPIFlagFileCategories []hiddenAPIFlagFileCategory 527*333d2b36SAndroid Build Coastguard Worker 528*333d2b36SAndroid Build Coastguard Workervar HiddenAPIFlagFileCategories = hiddenAPIFlagFileCategories{ 529*333d2b36SAndroid Build Coastguard Worker // See HiddenAPIFlagFileProperties.Unsupported 530*333d2b36SAndroid Build Coastguard Worker hiddenAPIFlagFileCategoryUnsupported, 531*333d2b36SAndroid Build Coastguard Worker // See HiddenAPIFlagFileProperties.Removed 532*333d2b36SAndroid Build Coastguard Worker hiddenAPIFlagFileCategoryRemoved, 533*333d2b36SAndroid Build Coastguard Worker // See HiddenAPIFlagFileProperties.Max_target_r_low_priority 534*333d2b36SAndroid Build Coastguard Worker hiddenAPIFlagFileCategoryMaxTargetRLowPriority, 535*333d2b36SAndroid Build Coastguard Worker // See HiddenAPIFlagFileProperties.Max_target_q 536*333d2b36SAndroid Build Coastguard Worker hiddenAPIFlagFileCategoryMaxTargetQ, 537*333d2b36SAndroid Build Coastguard Worker // See HiddenAPIFlagFileProperties.Max_target_p 538*333d2b36SAndroid Build Coastguard Worker hiddenAPIFlagFileCategoryMaxTargetP, 539*333d2b36SAndroid Build Coastguard Worker // See HiddenAPIFlagFileProperties.Max_target_o_low_priority 540*333d2b36SAndroid Build Coastguard Worker hiddenAPIFlagFileCategoryMaxTargetOLowPriority, 541*333d2b36SAndroid Build Coastguard Worker // See HiddenAPIFlagFileProperties.Blocked 542*333d2b36SAndroid Build Coastguard Worker hiddenAPIFlagFileCategoryBlocked, 543*333d2b36SAndroid Build Coastguard Worker // See HiddenAPIFlagFileProperties.Unsupported_packages 544*333d2b36SAndroid Build Coastguard Worker hiddenAPIFlagFileCategoryUnsupportedPackages, 545*333d2b36SAndroid Build Coastguard Worker} 546*333d2b36SAndroid Build Coastguard Worker 547*333d2b36SAndroid Build Coastguard Worker// FlagFilesByCategory maps a hiddenAPIFlagFileCategory to the paths to the files in that category. 548*333d2b36SAndroid Build Coastguard Workertype FlagFilesByCategory map[hiddenAPIFlagFileCategory]android.Paths 549*333d2b36SAndroid Build Coastguard Worker 550*333d2b36SAndroid Build Coastguard Worker// append the supplied flags files to the corresponding category in this map. 551*333d2b36SAndroid Build Coastguard Workerfunc (s FlagFilesByCategory) append(other FlagFilesByCategory) { 552*333d2b36SAndroid Build Coastguard Worker for _, category := range HiddenAPIFlagFileCategories { 553*333d2b36SAndroid Build Coastguard Worker s[category] = append(s[category], other[category]...) 554*333d2b36SAndroid Build Coastguard Worker } 555*333d2b36SAndroid Build Coastguard Worker} 556*333d2b36SAndroid Build Coastguard Worker 557*333d2b36SAndroid Build Coastguard Worker// sort the paths for each category in this map. 558*333d2b36SAndroid Build Coastguard Workerfunc (s FlagFilesByCategory) sort() { 559*333d2b36SAndroid Build Coastguard Worker for category, value := range s { 560*333d2b36SAndroid Build Coastguard Worker s[category] = android.SortedUniquePaths(value) 561*333d2b36SAndroid Build Coastguard Worker } 562*333d2b36SAndroid Build Coastguard Worker} 563*333d2b36SAndroid Build Coastguard Worker 564*333d2b36SAndroid Build Coastguard Worker// HiddenAPIInfo contains information provided by the hidden API processing. 565*333d2b36SAndroid Build Coastguard Worker// 566*333d2b36SAndroid Build Coastguard Worker// That includes paths resolved from HiddenAPIFlagFileProperties and also generated by hidden API 567*333d2b36SAndroid Build Coastguard Worker// processing. 568*333d2b36SAndroid Build Coastguard Workertype HiddenAPIInfo struct { 569*333d2b36SAndroid Build Coastguard Worker // FlagFilesByCategory maps from the flag file category to the paths containing information for 570*333d2b36SAndroid Build Coastguard Worker // that category. 571*333d2b36SAndroid Build Coastguard Worker FlagFilesByCategory FlagFilesByCategory 572*333d2b36SAndroid Build Coastguard Worker 573*333d2b36SAndroid Build Coastguard Worker // The paths to the stub dex jars for each of the *HiddenAPIScope in hiddenAPIScopes provided by 574*333d2b36SAndroid Build Coastguard Worker // this fragment and the fragments on which this depends. 575*333d2b36SAndroid Build Coastguard Worker TransitiveStubDexJarsByScope StubDexJarsByModule 576*333d2b36SAndroid Build Coastguard Worker 577*333d2b36SAndroid Build Coastguard Worker // The output from the hidden API processing needs to be made available to other modules. 578*333d2b36SAndroid Build Coastguard Worker HiddenAPIFlagOutput 579*333d2b36SAndroid Build Coastguard Worker} 580*333d2b36SAndroid Build Coastguard Worker 581*333d2b36SAndroid Build Coastguard Workerfunc newHiddenAPIInfo() *HiddenAPIInfo { 582*333d2b36SAndroid Build Coastguard Worker info := HiddenAPIInfo{ 583*333d2b36SAndroid Build Coastguard Worker FlagFilesByCategory: FlagFilesByCategory{}, 584*333d2b36SAndroid Build Coastguard Worker TransitiveStubDexJarsByScope: StubDexJarsByModule{}, 585*333d2b36SAndroid Build Coastguard Worker } 586*333d2b36SAndroid Build Coastguard Worker return &info 587*333d2b36SAndroid Build Coastguard Worker} 588*333d2b36SAndroid Build Coastguard Worker 589*333d2b36SAndroid Build Coastguard Workerfunc (i *HiddenAPIInfo) mergeFromFragmentDeps(ctx android.ModuleContext, fragments []android.Module) { 590*333d2b36SAndroid Build Coastguard Worker // Merge all the information from the fragments. The fragments form a DAG so it is possible that 591*333d2b36SAndroid Build Coastguard Worker // this will introduce duplicates so they will be resolved after processing all the fragments. 592*333d2b36SAndroid Build Coastguard Worker for _, fragment := range fragments { 593*333d2b36SAndroid Build Coastguard Worker if info, ok := android.OtherModuleProvider(ctx, fragment, HiddenAPIInfoProvider); ok { 594*333d2b36SAndroid Build Coastguard Worker i.TransitiveStubDexJarsByScope.addStubDexJarsByModule(info.TransitiveStubDexJarsByScope) 595*333d2b36SAndroid Build Coastguard Worker } 596*333d2b36SAndroid Build Coastguard Worker } 597*333d2b36SAndroid Build Coastguard Worker} 598*333d2b36SAndroid Build Coastguard Worker 599*333d2b36SAndroid Build Coastguard Worker// StubFlagSubset returns a SignatureCsvSubset that contains a path to a filtered-stub-flags.csv 600*333d2b36SAndroid Build Coastguard Worker// file and a path to a signature-patterns.csv file that defines a subset of the monolithic stub 601*333d2b36SAndroid Build Coastguard Worker// flags file, i.e. out/soong/hiddenapi/hiddenapi-stub-flags.txt, against which it will be compared. 602*333d2b36SAndroid Build Coastguard Workerfunc (i *HiddenAPIInfo) StubFlagSubset() SignatureCsvSubset { 603*333d2b36SAndroid Build Coastguard Worker return SignatureCsvSubset{i.FilteredStubFlagsPath, i.SignaturePatternsPath} 604*333d2b36SAndroid Build Coastguard Worker} 605*333d2b36SAndroid Build Coastguard Worker 606*333d2b36SAndroid Build Coastguard Worker// FlagSubset returns a SignatureCsvSubset that contains a path to a filtered-flags.csv file and a 607*333d2b36SAndroid Build Coastguard Worker// path to a signature-patterns.csv file that defines a subset of the monolithic flags file, i.e. 608*333d2b36SAndroid Build Coastguard Worker// out/soong/hiddenapi/hiddenapi-flags.csv, against which it will be compared. 609*333d2b36SAndroid Build Coastguard Workerfunc (i *HiddenAPIInfo) FlagSubset() SignatureCsvSubset { 610*333d2b36SAndroid Build Coastguard Worker return SignatureCsvSubset{i.FilteredFlagsPath, i.SignaturePatternsPath} 611*333d2b36SAndroid Build Coastguard Worker} 612*333d2b36SAndroid Build Coastguard Worker 613*333d2b36SAndroid Build Coastguard Workervar HiddenAPIInfoProvider = blueprint.NewProvider[HiddenAPIInfo]() 614*333d2b36SAndroid Build Coastguard Worker 615*333d2b36SAndroid Build Coastguard Worker// HiddenAPIInfoForSdk contains information provided by the hidden API processing for use 616*333d2b36SAndroid Build Coastguard Worker// by the sdk snapshot. 617*333d2b36SAndroid Build Coastguard Worker// 618*333d2b36SAndroid Build Coastguard Worker// That includes paths resolved from HiddenAPIFlagFileProperties and also generated by hidden API 619*333d2b36SAndroid Build Coastguard Worker// processing. 620*333d2b36SAndroid Build Coastguard Workertype HiddenAPIInfoForSdk struct { 621*333d2b36SAndroid Build Coastguard Worker // FlagFilesByCategory maps from the flag file category to the paths containing information for 622*333d2b36SAndroid Build Coastguard Worker // that category. 623*333d2b36SAndroid Build Coastguard Worker FlagFilesByCategory FlagFilesByCategory 624*333d2b36SAndroid Build Coastguard Worker 625*333d2b36SAndroid Build Coastguard Worker // The output from the hidden API processing needs to be made available to other modules. 626*333d2b36SAndroid Build Coastguard Worker HiddenAPIFlagOutput 627*333d2b36SAndroid Build Coastguard Worker} 628*333d2b36SAndroid Build Coastguard Worker 629*333d2b36SAndroid Build Coastguard Worker// Provides hidden API info for the sdk snapshot. 630*333d2b36SAndroid Build Coastguard Workervar HiddenAPIInfoForSdkProvider = blueprint.NewProvider[HiddenAPIInfoForSdk]() 631*333d2b36SAndroid Build Coastguard Worker 632*333d2b36SAndroid Build Coastguard Worker// ModuleStubDexJars contains the stub dex jars provided by a single module. 633*333d2b36SAndroid Build Coastguard Worker// 634*333d2b36SAndroid Build Coastguard Worker// It maps a *HiddenAPIScope to the path to stub dex jars appropriate for that scope. See 635*333d2b36SAndroid Build Coastguard Worker// hiddenAPIScopes for a list of the acceptable *HiddenAPIScope values. 636*333d2b36SAndroid Build Coastguard Workertype ModuleStubDexJars map[*HiddenAPIScope]android.Path 637*333d2b36SAndroid Build Coastguard Worker 638*333d2b36SAndroid Build Coastguard Worker// stubDexJarForWidestAPIScope returns the stub dex jars for the widest API scope provided by this 639*333d2b36SAndroid Build Coastguard Worker// map. 640*333d2b36SAndroid Build Coastguard Worker// 641*333d2b36SAndroid Build Coastguard Worker// The relative width of APIs is determined by their order in hiddenAPIScopes. 642*333d2b36SAndroid Build Coastguard Workerfunc (s ModuleStubDexJars) stubDexJarForWidestAPIScope() android.Path { 643*333d2b36SAndroid Build Coastguard Worker for i := len(hiddenAPIScopes) - 1; i >= 0; i-- { 644*333d2b36SAndroid Build Coastguard Worker apiScope := hiddenAPIScopes[i] 645*333d2b36SAndroid Build Coastguard Worker if stubsForAPIScope, ok := s[apiScope]; ok { 646*333d2b36SAndroid Build Coastguard Worker return stubsForAPIScope 647*333d2b36SAndroid Build Coastguard Worker } 648*333d2b36SAndroid Build Coastguard Worker } 649*333d2b36SAndroid Build Coastguard Worker 650*333d2b36SAndroid Build Coastguard Worker return nil 651*333d2b36SAndroid Build Coastguard Worker} 652*333d2b36SAndroid Build Coastguard Worker 653*333d2b36SAndroid Build Coastguard Worker// StubDexJarsByModule contains the stub dex jars provided by a set of modules. 654*333d2b36SAndroid Build Coastguard Worker// 655*333d2b36SAndroid Build Coastguard Worker// It maps a module name to the path to the stub dex jars provided by that module. 656*333d2b36SAndroid Build Coastguard Workertype StubDexJarsByModule map[string]ModuleStubDexJars 657*333d2b36SAndroid Build Coastguard Worker 658*333d2b36SAndroid Build Coastguard Worker// addStubDexJar adds a stub dex jar path provided by the specified module for the specified scope. 659*333d2b36SAndroid Build Coastguard Workerfunc (s StubDexJarsByModule) addStubDexJar(ctx android.ModuleContext, module android.Module, scope *HiddenAPIScope, stubDexJar android.Path) { 660*333d2b36SAndroid Build Coastguard Worker name := android.RemoveOptionalPrebuiltPrefix(module.Name()) 661*333d2b36SAndroid Build Coastguard Worker 662*333d2b36SAndroid Build Coastguard Worker // Each named module provides one dex jar for each scope. However, in some cases different API 663*333d2b36SAndroid Build Coastguard Worker // versions of a single classes are provided by separate modules. e.g. the core platform 664*333d2b36SAndroid Build Coastguard Worker // version of java.lang.Object is provided by the legacy.art.module.platform.api module but the 665*333d2b36SAndroid Build Coastguard Worker // public version is provided by the art.module.public.api module. In those cases it is necessary 666*333d2b36SAndroid Build Coastguard Worker // to treat all those modules as they were the same name, otherwise it will result in multiple 667*333d2b36SAndroid Build Coastguard Worker // definitions of a single class being passed to hidden API processing which will cause an error. 668*333d2b36SAndroid Build Coastguard Worker if name == scope.nonUpdatablePrebuiltModule || name == scope.nonUpdatableSourceModule || name == scope.nonUpdatableFromTextModule { 669*333d2b36SAndroid Build Coastguard Worker // Treat all *android-non-updatable* modules as if they were part of an android-non-updatable 670*333d2b36SAndroid Build Coastguard Worker // java_sdk_library. 671*333d2b36SAndroid Build Coastguard Worker // TODO(b/192067200): Remove once android-non-updatable is a java_sdk_library or equivalent. 672*333d2b36SAndroid Build Coastguard Worker name = "android-non-updatable" 673*333d2b36SAndroid Build Coastguard Worker } else if name == "legacy.art.module.platform.api" { 674*333d2b36SAndroid Build Coastguard Worker // Treat legacy.art.module.platform.api as if it was an API scope provided by the 675*333d2b36SAndroid Build Coastguard Worker // art.module.public.api java_sdk_library which will be the case once the former has been 676*333d2b36SAndroid Build Coastguard Worker // migrated to a module_lib API. 677*333d2b36SAndroid Build Coastguard Worker name = "art.module.public.api" 678*333d2b36SAndroid Build Coastguard Worker } else if name == "legacy.i18n.module.platform.api" { 679*333d2b36SAndroid Build Coastguard Worker // Treat legacy.i18n.module.platform.api as if it was an API scope provided by the 680*333d2b36SAndroid Build Coastguard Worker // i18n.module.public.api java_sdk_library which will be the case once the former has been 681*333d2b36SAndroid Build Coastguard Worker // migrated to a module_lib API. 682*333d2b36SAndroid Build Coastguard Worker name = "i18n.module.public.api" 683*333d2b36SAndroid Build Coastguard Worker } else if name == "conscrypt.module.platform.api" { 684*333d2b36SAndroid Build Coastguard Worker // Treat conscrypt.module.platform.api as if it was an API scope provided by the 685*333d2b36SAndroid Build Coastguard Worker // conscrypt.module.public.api java_sdk_library which will be the case once the former has been 686*333d2b36SAndroid Build Coastguard Worker // migrated to a module_lib API. 687*333d2b36SAndroid Build Coastguard Worker name = "conscrypt.module.public.api" 688*333d2b36SAndroid Build Coastguard Worker } else if d, ok := module.(SdkLibraryComponentDependency); ok { 689*333d2b36SAndroid Build Coastguard Worker sdkLibraryName := d.SdkLibraryName() 690*333d2b36SAndroid Build Coastguard Worker if sdkLibraryName != nil { 691*333d2b36SAndroid Build Coastguard Worker // The module is a component of a java_sdk_library so use the name of the java_sdk_library. 692*333d2b36SAndroid Build Coastguard Worker // e.g. if this module is `foo.system.stubs` and is part of the `foo` java_sdk_library then 693*333d2b36SAndroid Build Coastguard Worker // use `foo` as the name. 694*333d2b36SAndroid Build Coastguard Worker name = *sdkLibraryName 695*333d2b36SAndroid Build Coastguard Worker } 696*333d2b36SAndroid Build Coastguard Worker } 697*333d2b36SAndroid Build Coastguard Worker stubDexJarsByScope := s[name] 698*333d2b36SAndroid Build Coastguard Worker if stubDexJarsByScope == nil { 699*333d2b36SAndroid Build Coastguard Worker stubDexJarsByScope = ModuleStubDexJars{} 700*333d2b36SAndroid Build Coastguard Worker s[name] = stubDexJarsByScope 701*333d2b36SAndroid Build Coastguard Worker } 702*333d2b36SAndroid Build Coastguard Worker stubDexJarsByScope[scope] = stubDexJar 703*333d2b36SAndroid Build Coastguard Worker} 704*333d2b36SAndroid Build Coastguard Worker 705*333d2b36SAndroid Build Coastguard Worker// addStubDexJarsByModule adds the stub dex jars in the supplied StubDexJarsByModule to this map. 706*333d2b36SAndroid Build Coastguard Workerfunc (s StubDexJarsByModule) addStubDexJarsByModule(other StubDexJarsByModule) { 707*333d2b36SAndroid Build Coastguard Worker for module, stubDexJarsByScope := range other { 708*333d2b36SAndroid Build Coastguard Worker s[module] = stubDexJarsByScope 709*333d2b36SAndroid Build Coastguard Worker } 710*333d2b36SAndroid Build Coastguard Worker} 711*333d2b36SAndroid Build Coastguard Worker 712*333d2b36SAndroid Build Coastguard Worker// StubDexJarsForWidestAPIScope returns a list of stub dex jars containing the widest API scope 713*333d2b36SAndroid Build Coastguard Worker// provided by each module. 714*333d2b36SAndroid Build Coastguard Worker// 715*333d2b36SAndroid Build Coastguard Worker// The relative width of APIs is determined by their order in hiddenAPIScopes. 716*333d2b36SAndroid Build Coastguard Workerfunc (s StubDexJarsByModule) StubDexJarsForWidestAPIScope() android.Paths { 717*333d2b36SAndroid Build Coastguard Worker stubDexJars := android.Paths{} 718*333d2b36SAndroid Build Coastguard Worker modules := android.SortedKeys(s) 719*333d2b36SAndroid Build Coastguard Worker for _, module := range modules { 720*333d2b36SAndroid Build Coastguard Worker stubDexJarsByScope := s[module] 721*333d2b36SAndroid Build Coastguard Worker 722*333d2b36SAndroid Build Coastguard Worker stubDexJars = append(stubDexJars, stubDexJarsByScope.stubDexJarForWidestAPIScope()) 723*333d2b36SAndroid Build Coastguard Worker } 724*333d2b36SAndroid Build Coastguard Worker 725*333d2b36SAndroid Build Coastguard Worker return stubDexJars 726*333d2b36SAndroid Build Coastguard Worker} 727*333d2b36SAndroid Build Coastguard Worker 728*333d2b36SAndroid Build Coastguard Worker// StubDexJarsForScope returns a list of stub dex jars containing the stub dex jars provided by each 729*333d2b36SAndroid Build Coastguard Worker// module for the specified scope. 730*333d2b36SAndroid Build Coastguard Worker// 731*333d2b36SAndroid Build Coastguard Worker// If a module does not provide a stub dex jar for the supplied scope then it does not contribute to 732*333d2b36SAndroid Build Coastguard Worker// the returned list. 733*333d2b36SAndroid Build Coastguard Workerfunc (s StubDexJarsByModule) StubDexJarsForScope(scope *HiddenAPIScope) android.Paths { 734*333d2b36SAndroid Build Coastguard Worker stubDexJars := android.Paths{} 735*333d2b36SAndroid Build Coastguard Worker modules := android.SortedKeys(s) 736*333d2b36SAndroid Build Coastguard Worker for _, module := range modules { 737*333d2b36SAndroid Build Coastguard Worker stubDexJarsByScope := s[module] 738*333d2b36SAndroid Build Coastguard Worker // Not every module will have the same set of 739*333d2b36SAndroid Build Coastguard Worker if jars, ok := stubDexJarsByScope[scope]; ok { 740*333d2b36SAndroid Build Coastguard Worker stubDexJars = append(stubDexJars, jars) 741*333d2b36SAndroid Build Coastguard Worker } 742*333d2b36SAndroid Build Coastguard Worker } 743*333d2b36SAndroid Build Coastguard Worker 744*333d2b36SAndroid Build Coastguard Worker return stubDexJars 745*333d2b36SAndroid Build Coastguard Worker} 746*333d2b36SAndroid Build Coastguard Worker 747*333d2b36SAndroid Build Coastguard Workertype HiddenAPIPropertyInfo struct { 748*333d2b36SAndroid Build Coastguard Worker // FlagFilesByCategory contains the flag files that override the initial flags that are derived 749*333d2b36SAndroid Build Coastguard Worker // from the stub dex files. 750*333d2b36SAndroid Build Coastguard Worker FlagFilesByCategory FlagFilesByCategory 751*333d2b36SAndroid Build Coastguard Worker 752*333d2b36SAndroid Build Coastguard Worker // See HiddenAPIFlagFileProperties.Package_prefixes 753*333d2b36SAndroid Build Coastguard Worker PackagePrefixes []string 754*333d2b36SAndroid Build Coastguard Worker 755*333d2b36SAndroid Build Coastguard Worker // See HiddenAPIFlagFileProperties.Single_packages 756*333d2b36SAndroid Build Coastguard Worker SinglePackages []string 757*333d2b36SAndroid Build Coastguard Worker 758*333d2b36SAndroid Build Coastguard Worker // See HiddenAPIFlagFileProperties.Split_packages 759*333d2b36SAndroid Build Coastguard Worker SplitPackages []string 760*333d2b36SAndroid Build Coastguard Worker} 761*333d2b36SAndroid Build Coastguard Worker 762*333d2b36SAndroid Build Coastguard Workervar hiddenAPIPropertyInfoProvider = blueprint.NewProvider[HiddenAPIPropertyInfo]() 763*333d2b36SAndroid Build Coastguard Worker 764*333d2b36SAndroid Build Coastguard Worker// newHiddenAPIPropertyInfo creates a new initialized HiddenAPIPropertyInfo struct. 765*333d2b36SAndroid Build Coastguard Workerfunc newHiddenAPIPropertyInfo() HiddenAPIPropertyInfo { 766*333d2b36SAndroid Build Coastguard Worker return HiddenAPIPropertyInfo{ 767*333d2b36SAndroid Build Coastguard Worker FlagFilesByCategory: FlagFilesByCategory{}, 768*333d2b36SAndroid Build Coastguard Worker } 769*333d2b36SAndroid Build Coastguard Worker} 770*333d2b36SAndroid Build Coastguard Worker 771*333d2b36SAndroid Build Coastguard Worker// extractFlagFilesFromProperties extracts the paths to flag files that are specified in the 772*333d2b36SAndroid Build Coastguard Worker// supplied properties and stores them in this struct. 773*333d2b36SAndroid Build Coastguard Workerfunc (i *HiddenAPIPropertyInfo) extractFlagFilesFromProperties(ctx android.ModuleContext, p *HiddenAPIFlagFileProperties) { 774*333d2b36SAndroid Build Coastguard Worker for _, category := range HiddenAPIFlagFileCategories { 775*333d2b36SAndroid Build Coastguard Worker paths := android.PathsForModuleSrc(ctx, category.propertyValueReader(p)) 776*333d2b36SAndroid Build Coastguard Worker i.FlagFilesByCategory[category] = paths 777*333d2b36SAndroid Build Coastguard Worker } 778*333d2b36SAndroid Build Coastguard Worker} 779*333d2b36SAndroid Build Coastguard Worker 780*333d2b36SAndroid Build Coastguard Worker// extractPackageRulesFromProperties extracts the package rules that are specified in the supplied 781*333d2b36SAndroid Build Coastguard Worker// properties and stores them in this struct. 782*333d2b36SAndroid Build Coastguard Workerfunc (i *HiddenAPIPropertyInfo) extractPackageRulesFromProperties(p *HiddenAPIPackageProperties) { 783*333d2b36SAndroid Build Coastguard Worker i.PackagePrefixes = p.Hidden_api.Package_prefixes 784*333d2b36SAndroid Build Coastguard Worker i.SinglePackages = p.Hidden_api.Single_packages 785*333d2b36SAndroid Build Coastguard Worker i.SplitPackages = p.Hidden_api.Split_packages 786*333d2b36SAndroid Build Coastguard Worker} 787*333d2b36SAndroid Build Coastguard Worker 788*333d2b36SAndroid Build Coastguard Workerfunc (i *HiddenAPIPropertyInfo) gatherPropertyInfo(ctx android.ModuleContext, contents []android.Module) { 789*333d2b36SAndroid Build Coastguard Worker for _, module := range contents { 790*333d2b36SAndroid Build Coastguard Worker if info, ok := android.OtherModuleProvider(ctx, module, hiddenAPIPropertyInfoProvider); ok { 791*333d2b36SAndroid Build Coastguard Worker i.FlagFilesByCategory.append(info.FlagFilesByCategory) 792*333d2b36SAndroid Build Coastguard Worker i.PackagePrefixes = append(i.PackagePrefixes, info.PackagePrefixes...) 793*333d2b36SAndroid Build Coastguard Worker i.SinglePackages = append(i.SinglePackages, info.SinglePackages...) 794*333d2b36SAndroid Build Coastguard Worker i.SplitPackages = append(i.SplitPackages, info.SplitPackages...) 795*333d2b36SAndroid Build Coastguard Worker } 796*333d2b36SAndroid Build Coastguard Worker } 797*333d2b36SAndroid Build Coastguard Worker 798*333d2b36SAndroid Build Coastguard Worker // Dedup and sort the information to ensure consistent builds. 799*333d2b36SAndroid Build Coastguard Worker i.FlagFilesByCategory.sort() 800*333d2b36SAndroid Build Coastguard Worker i.PackagePrefixes = android.SortedUniqueStrings(i.PackagePrefixes) 801*333d2b36SAndroid Build Coastguard Worker i.SinglePackages = android.SortedUniqueStrings(i.SinglePackages) 802*333d2b36SAndroid Build Coastguard Worker i.SplitPackages = android.SortedUniqueStrings(i.SplitPackages) 803*333d2b36SAndroid Build Coastguard Worker} 804*333d2b36SAndroid Build Coastguard Worker 805*333d2b36SAndroid Build Coastguard Worker// HiddenAPIFlagInput encapsulates information obtained from a module and its dependencies that are 806*333d2b36SAndroid Build Coastguard Worker// needed for hidden API flag generation. 807*333d2b36SAndroid Build Coastguard Workertype HiddenAPIFlagInput struct { 808*333d2b36SAndroid Build Coastguard Worker HiddenAPIPropertyInfo 809*333d2b36SAndroid Build Coastguard Worker 810*333d2b36SAndroid Build Coastguard Worker // StubDexJarsByScope contains the stub dex jars for different *HiddenAPIScope and which determine 811*333d2b36SAndroid Build Coastguard Worker // the initial flags for each dex member. 812*333d2b36SAndroid Build Coastguard Worker StubDexJarsByScope StubDexJarsByModule 813*333d2b36SAndroid Build Coastguard Worker 814*333d2b36SAndroid Build Coastguard Worker // DependencyStubDexJarsByScope contains the stub dex jars provided by the fragments on which this 815*333d2b36SAndroid Build Coastguard Worker // depends. It is the result of merging HiddenAPIInfo.TransitiveStubDexJarsByScope from each 816*333d2b36SAndroid Build Coastguard Worker // fragment on which this depends. 817*333d2b36SAndroid Build Coastguard Worker DependencyStubDexJarsByScope StubDexJarsByModule 818*333d2b36SAndroid Build Coastguard Worker 819*333d2b36SAndroid Build Coastguard Worker // AdditionalStubDexJarsByScope contains stub dex jars provided by other modules in addition to 820*333d2b36SAndroid Build Coastguard Worker // the ones that are obtained from fragments on which this depends. 821*333d2b36SAndroid Build Coastguard Worker // 822*333d2b36SAndroid Build Coastguard Worker // These are kept separate from stub dex jars in HiddenAPIFlagInput.DependencyStubDexJarsByScope 823*333d2b36SAndroid Build Coastguard Worker // as there are not propagated transitively to other fragments that depend on this. 824*333d2b36SAndroid Build Coastguard Worker AdditionalStubDexJarsByScope StubDexJarsByModule 825*333d2b36SAndroid Build Coastguard Worker 826*333d2b36SAndroid Build Coastguard Worker // RemovedTxtFiles is the list of removed.txt files provided by java_sdk_library modules that are 827*333d2b36SAndroid Build Coastguard Worker // specified in the bootclasspath_fragment's stub_libs and contents properties. 828*333d2b36SAndroid Build Coastguard Worker RemovedTxtFiles android.Paths 829*333d2b36SAndroid Build Coastguard Worker} 830*333d2b36SAndroid Build Coastguard Worker 831*333d2b36SAndroid Build Coastguard Worker// newHiddenAPIFlagInput creates a new initialized HiddenAPIFlagInput struct. 832*333d2b36SAndroid Build Coastguard Workerfunc newHiddenAPIFlagInput() HiddenAPIFlagInput { 833*333d2b36SAndroid Build Coastguard Worker input := HiddenAPIFlagInput{ 834*333d2b36SAndroid Build Coastguard Worker HiddenAPIPropertyInfo: newHiddenAPIPropertyInfo(), 835*333d2b36SAndroid Build Coastguard Worker StubDexJarsByScope: StubDexJarsByModule{}, 836*333d2b36SAndroid Build Coastguard Worker DependencyStubDexJarsByScope: StubDexJarsByModule{}, 837*333d2b36SAndroid Build Coastguard Worker AdditionalStubDexJarsByScope: StubDexJarsByModule{}, 838*333d2b36SAndroid Build Coastguard Worker } 839*333d2b36SAndroid Build Coastguard Worker 840*333d2b36SAndroid Build Coastguard Worker return input 841*333d2b36SAndroid Build Coastguard Worker} 842*333d2b36SAndroid Build Coastguard Worker 843*333d2b36SAndroid Build Coastguard Worker// gatherStubLibInfo gathers information from the stub libs needed by hidden API processing from the 844*333d2b36SAndroid Build Coastguard Worker// dependencies added in hiddenAPIAddStubLibDependencies. 845*333d2b36SAndroid Build Coastguard Worker// 846*333d2b36SAndroid Build Coastguard Worker// That includes paths to the stub dex jars as well as paths to the *removed.txt files. 847*333d2b36SAndroid Build Coastguard Workerfunc (i *HiddenAPIFlagInput) gatherStubLibInfo(ctx android.ModuleContext, contents []android.Module) { 848*333d2b36SAndroid Build Coastguard Worker addFromModule := func(ctx android.ModuleContext, module android.Module, apiScope *HiddenAPIScope) { 849*333d2b36SAndroid Build Coastguard Worker sdkKind := apiScope.sdkKind 850*333d2b36SAndroid Build Coastguard Worker dexJar := hiddenAPIRetrieveDexJarBuildPath(ctx, module, sdkKind) 851*333d2b36SAndroid Build Coastguard Worker if dexJar != nil { 852*333d2b36SAndroid Build Coastguard Worker i.StubDexJarsByScope.addStubDexJar(ctx, module, apiScope, dexJar) 853*333d2b36SAndroid Build Coastguard Worker } 854*333d2b36SAndroid Build Coastguard Worker 855*333d2b36SAndroid Build Coastguard Worker if sdkLibrary, ok := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider); ok { 856*333d2b36SAndroid Build Coastguard Worker removedTxtFile := sdkLibrary.RemovedTxtFiles[sdkKind] 857*333d2b36SAndroid Build Coastguard Worker i.RemovedTxtFiles = append(i.RemovedTxtFiles, removedTxtFile.AsPaths()...) 858*333d2b36SAndroid Build Coastguard Worker } 859*333d2b36SAndroid Build Coastguard Worker } 860*333d2b36SAndroid Build Coastguard Worker 861*333d2b36SAndroid Build Coastguard Worker // If the contents includes any java_sdk_library modules then add them to the stubs. 862*333d2b36SAndroid Build Coastguard Worker for _, module := range contents { 863*333d2b36SAndroid Build Coastguard Worker if _, ok := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider); ok { 864*333d2b36SAndroid Build Coastguard Worker // Add information for every possible API scope needed by hidden API. 865*333d2b36SAndroid Build Coastguard Worker for _, apiScope := range hiddenAPISdkLibrarySupportedScopes { 866*333d2b36SAndroid Build Coastguard Worker addFromModule(ctx, module, apiScope) 867*333d2b36SAndroid Build Coastguard Worker } 868*333d2b36SAndroid Build Coastguard Worker } 869*333d2b36SAndroid Build Coastguard Worker } 870*333d2b36SAndroid Build Coastguard Worker 871*333d2b36SAndroid Build Coastguard Worker ctx.VisitDirectDeps(func(module android.Module) { 872*333d2b36SAndroid Build Coastguard Worker tag := ctx.OtherModuleDependencyTag(module) 873*333d2b36SAndroid Build Coastguard Worker if hiddenAPIStubsTag, ok := tag.(hiddenAPIStubsDependencyTag); ok { 874*333d2b36SAndroid Build Coastguard Worker apiScope := hiddenAPIStubsTag.apiScope 875*333d2b36SAndroid Build Coastguard Worker if hiddenAPIStubsTag.fromAdditionalDependency { 876*333d2b36SAndroid Build Coastguard Worker dexJar := hiddenAPIRetrieveDexJarBuildPath(ctx, module, apiScope.sdkKind) 877*333d2b36SAndroid Build Coastguard Worker if dexJar != nil { 878*333d2b36SAndroid Build Coastguard Worker i.AdditionalStubDexJarsByScope.addStubDexJar(ctx, module, apiScope, dexJar) 879*333d2b36SAndroid Build Coastguard Worker } 880*333d2b36SAndroid Build Coastguard Worker } else { 881*333d2b36SAndroid Build Coastguard Worker addFromModule(ctx, module, apiScope) 882*333d2b36SAndroid Build Coastguard Worker } 883*333d2b36SAndroid Build Coastguard Worker } 884*333d2b36SAndroid Build Coastguard Worker }) 885*333d2b36SAndroid Build Coastguard Worker 886*333d2b36SAndroid Build Coastguard Worker // Normalize the paths, i.e. remove duplicates and sort. 887*333d2b36SAndroid Build Coastguard Worker i.RemovedTxtFiles = android.SortedUniquePaths(i.RemovedTxtFiles) 888*333d2b36SAndroid Build Coastguard Worker} 889*333d2b36SAndroid Build Coastguard Worker 890*333d2b36SAndroid Build Coastguard Workerfunc (i *HiddenAPIFlagInput) transitiveStubDexJarsByScope() StubDexJarsByModule { 891*333d2b36SAndroid Build Coastguard Worker transitive := i.DependencyStubDexJarsByScope 892*333d2b36SAndroid Build Coastguard Worker transitive.addStubDexJarsByModule(i.StubDexJarsByScope) 893*333d2b36SAndroid Build Coastguard Worker return transitive 894*333d2b36SAndroid Build Coastguard Worker} 895*333d2b36SAndroid Build Coastguard Worker 896*333d2b36SAndroid Build Coastguard Worker// HiddenAPIFlagOutput contains paths to output files from the hidden API flag generation for a 897*333d2b36SAndroid Build Coastguard Worker// bootclasspath_fragment module. 898*333d2b36SAndroid Build Coastguard Workertype HiddenAPIFlagOutput struct { 899*333d2b36SAndroid Build Coastguard Worker // The path to the generated annotation-flags.csv file. 900*333d2b36SAndroid Build Coastguard Worker AnnotationFlagsPath android.Path 901*333d2b36SAndroid Build Coastguard Worker 902*333d2b36SAndroid Build Coastguard Worker // The path to the generated metadata.csv file. 903*333d2b36SAndroid Build Coastguard Worker MetadataPath android.Path 904*333d2b36SAndroid Build Coastguard Worker 905*333d2b36SAndroid Build Coastguard Worker // The path to the generated index.csv file. 906*333d2b36SAndroid Build Coastguard Worker IndexPath android.Path 907*333d2b36SAndroid Build Coastguard Worker 908*333d2b36SAndroid Build Coastguard Worker // The path to the generated stub-flags.csv file. 909*333d2b36SAndroid Build Coastguard Worker StubFlagsPath android.Path 910*333d2b36SAndroid Build Coastguard Worker 911*333d2b36SAndroid Build Coastguard Worker // The path to the generated all-flags.csv file. 912*333d2b36SAndroid Build Coastguard Worker AllFlagsPath android.Path 913*333d2b36SAndroid Build Coastguard Worker 914*333d2b36SAndroid Build Coastguard Worker // The path to the generated signature-patterns.txt file which defines the subset of the 915*333d2b36SAndroid Build Coastguard Worker // monolithic hidden API files provided in this. 916*333d2b36SAndroid Build Coastguard Worker SignaturePatternsPath android.Path 917*333d2b36SAndroid Build Coastguard Worker 918*333d2b36SAndroid Build Coastguard Worker // The path to the generated filtered-stub-flags.csv file. 919*333d2b36SAndroid Build Coastguard Worker FilteredStubFlagsPath android.Path 920*333d2b36SAndroid Build Coastguard Worker 921*333d2b36SAndroid Build Coastguard Worker // The path to the generated filtered-flags.csv file. 922*333d2b36SAndroid Build Coastguard Worker FilteredFlagsPath android.Path 923*333d2b36SAndroid Build Coastguard Worker} 924*333d2b36SAndroid Build Coastguard Worker 925*333d2b36SAndroid Build Coastguard Worker// bootDexJarByModule is a map from base module name (without prebuilt_ prefix) to the boot dex 926*333d2b36SAndroid Build Coastguard Worker// path. 927*333d2b36SAndroid Build Coastguard Workertype bootDexJarByModule map[string]android.Path 928*333d2b36SAndroid Build Coastguard Worker 929*333d2b36SAndroid Build Coastguard Worker// addPath adds the path for a module to the map. 930*333d2b36SAndroid Build Coastguard Workerfunc (b bootDexJarByModule) addPath(module android.Module, path android.Path) { 931*333d2b36SAndroid Build Coastguard Worker b[android.RemoveOptionalPrebuiltPrefix(module.Name())] = path 932*333d2b36SAndroid Build Coastguard Worker} 933*333d2b36SAndroid Build Coastguard Worker 934*333d2b36SAndroid Build Coastguard Worker// bootDexJars returns the boot dex jar paths sorted by their keys. 935*333d2b36SAndroid Build Coastguard Workerfunc (b bootDexJarByModule) bootDexJars() android.Paths { 936*333d2b36SAndroid Build Coastguard Worker paths := android.Paths{} 937*333d2b36SAndroid Build Coastguard Worker for _, k := range android.SortedKeys(b) { 938*333d2b36SAndroid Build Coastguard Worker paths = append(paths, b[k]) 939*333d2b36SAndroid Build Coastguard Worker } 940*333d2b36SAndroid Build Coastguard Worker return paths 941*333d2b36SAndroid Build Coastguard Worker} 942*333d2b36SAndroid Build Coastguard Worker 943*333d2b36SAndroid Build Coastguard Worker// bootDexJarsWithoutCoverage returns the boot dex jar paths sorted by their keys without coverage 944*333d2b36SAndroid Build Coastguard Worker// libraries if present. 945*333d2b36SAndroid Build Coastguard Workerfunc (b bootDexJarByModule) bootDexJarsWithoutCoverage() android.Paths { 946*333d2b36SAndroid Build Coastguard Worker paths := android.Paths{} 947*333d2b36SAndroid Build Coastguard Worker for _, k := range android.SortedKeys(b) { 948*333d2b36SAndroid Build Coastguard Worker if k == "jacocoagent" { 949*333d2b36SAndroid Build Coastguard Worker continue 950*333d2b36SAndroid Build Coastguard Worker } 951*333d2b36SAndroid Build Coastguard Worker paths = append(paths, b[k]) 952*333d2b36SAndroid Build Coastguard Worker } 953*333d2b36SAndroid Build Coastguard Worker return paths 954*333d2b36SAndroid Build Coastguard Worker} 955*333d2b36SAndroid Build Coastguard Worker 956*333d2b36SAndroid Build Coastguard Worker// HiddenAPIOutput encapsulates the output from the hidden API processing. 957*333d2b36SAndroid Build Coastguard Workertype HiddenAPIOutput struct { 958*333d2b36SAndroid Build Coastguard Worker HiddenAPIFlagOutput 959*333d2b36SAndroid Build Coastguard Worker 960*333d2b36SAndroid Build Coastguard Worker // The map from base module name to the path to the encoded boot dex file. 961*333d2b36SAndroid Build Coastguard Worker // This field is not available in prebuilt apexes 962*333d2b36SAndroid Build Coastguard Worker EncodedBootDexFilesByModule bootDexJarByModule 963*333d2b36SAndroid Build Coastguard Worker} 964*333d2b36SAndroid Build Coastguard Worker 965*333d2b36SAndroid Build Coastguard Worker// pathForValidation creates a path of the same type as the supplied type but with a name of 966*333d2b36SAndroid Build Coastguard Worker// <path>.valid. 967*333d2b36SAndroid Build Coastguard Worker// 968*333d2b36SAndroid Build Coastguard Worker// e.g. If path is an OutputPath for out/soong/hiddenapi/hiddenapi-flags.csv then this will return 969*333d2b36SAndroid Build Coastguard Worker// an OutputPath for out/soong/hiddenapi/hiddenapi-flags.csv.valid 970*333d2b36SAndroid Build Coastguard Workerfunc pathForValidation(ctx android.PathContext, path android.WritablePath) android.WritablePath { 971*333d2b36SAndroid Build Coastguard Worker extWithoutLeadingDot := strings.TrimPrefix(path.Ext(), ".") 972*333d2b36SAndroid Build Coastguard Worker return path.ReplaceExtension(ctx, extWithoutLeadingDot+".valid") 973*333d2b36SAndroid Build Coastguard Worker} 974*333d2b36SAndroid Build Coastguard Worker 975*333d2b36SAndroid Build Coastguard Worker// buildRuleToGenerateHiddenApiFlags creates a rule to create the monolithic hidden API flags from 976*333d2b36SAndroid Build Coastguard Worker// the flags from all the modules, the stub flags, augmented with some additional configuration 977*333d2b36SAndroid Build Coastguard Worker// files. 978*333d2b36SAndroid Build Coastguard Worker// 979*333d2b36SAndroid Build Coastguard Worker// baseFlagsPath is the path to the flags file containing all the information from the stubs plus 980*333d2b36SAndroid Build Coastguard Worker// an entry for every single member in the dex implementation jars of the individual modules. Every 981*333d2b36SAndroid Build Coastguard Worker// signature in any of the other files MUST be included in this file. 982*333d2b36SAndroid Build Coastguard Worker// 983*333d2b36SAndroid Build Coastguard Worker// annotationFlags is the path to the annotation flags file generated from annotation information 984*333d2b36SAndroid Build Coastguard Worker// in each module. 985*333d2b36SAndroid Build Coastguard Worker// 986*333d2b36SAndroid Build Coastguard Worker// hiddenAPIInfo is a struct containing paths to files that augment the information provided by 987*333d2b36SAndroid Build Coastguard Worker// the annotationFlags. 988*333d2b36SAndroid Build Coastguard Workerfunc buildRuleToGenerateHiddenApiFlags(ctx android.BuilderContext, name, desc string, 989*333d2b36SAndroid Build Coastguard Worker outputPath android.WritablePath, baseFlagsPath android.Path, annotationFlagPaths android.Paths, 990*333d2b36SAndroid Build Coastguard Worker flagFilesByCategory FlagFilesByCategory, flagSubsets SignatureCsvSubsets, generatedRemovedDexSignatures android.OptionalPath) { 991*333d2b36SAndroid Build Coastguard Worker 992*333d2b36SAndroid Build Coastguard Worker // Create the rule that will generate the flag files. 993*333d2b36SAndroid Build Coastguard Worker tempPath := tempPathForRestat(ctx, outputPath) 994*333d2b36SAndroid Build Coastguard Worker rule := android.NewRuleBuilder(pctx, ctx) 995*333d2b36SAndroid Build Coastguard Worker command := rule.Command(). 996*333d2b36SAndroid Build Coastguard Worker BuiltTool("generate_hiddenapi_lists"). 997*333d2b36SAndroid Build Coastguard Worker FlagWithInput("--csv ", baseFlagsPath). 998*333d2b36SAndroid Build Coastguard Worker Inputs(annotationFlagPaths). 999*333d2b36SAndroid Build Coastguard Worker FlagWithOutput("--output ", tempPath) 1000*333d2b36SAndroid Build Coastguard Worker 1001*333d2b36SAndroid Build Coastguard Worker // Add the options for the different categories of flag files. 1002*333d2b36SAndroid Build Coastguard Worker for _, category := range HiddenAPIFlagFileCategories { 1003*333d2b36SAndroid Build Coastguard Worker paths := flagFilesByCategory[category] 1004*333d2b36SAndroid Build Coastguard Worker for _, path := range paths { 1005*333d2b36SAndroid Build Coastguard Worker category.commandMutator(command, path) 1006*333d2b36SAndroid Build Coastguard Worker } 1007*333d2b36SAndroid Build Coastguard Worker } 1008*333d2b36SAndroid Build Coastguard Worker 1009*333d2b36SAndroid Build Coastguard Worker // If available then pass the automatically generated file containing dex signatures of removed 1010*333d2b36SAndroid Build Coastguard Worker // API members to the rule so they can be marked as removed. 1011*333d2b36SAndroid Build Coastguard Worker if generatedRemovedDexSignatures.Valid() { 1012*333d2b36SAndroid Build Coastguard Worker hiddenAPIFlagFileCategoryRemoved.commandMutator(command, generatedRemovedDexSignatures.Path()) 1013*333d2b36SAndroid Build Coastguard Worker } 1014*333d2b36SAndroid Build Coastguard Worker 1015*333d2b36SAndroid Build Coastguard Worker commitChangeForRestat(rule, tempPath, outputPath) 1016*333d2b36SAndroid Build Coastguard Worker 1017*333d2b36SAndroid Build Coastguard Worker // If there are flag files that have been generated by fragments on which this depends then use 1018*333d2b36SAndroid Build Coastguard Worker // them to validate the flag file generated by the rules created by this method. 1019*333d2b36SAndroid Build Coastguard Worker if !ctx.Config().DisableVerifyOverlaps() && len(flagSubsets) > 0 { 1020*333d2b36SAndroid Build Coastguard Worker validFile := buildRuleValidateOverlappingCsvFiles(ctx, name, desc, outputPath, flagSubsets, 1021*333d2b36SAndroid Build Coastguard Worker HIDDENAPI_FLAGS_CSV_IMPL_FLAGS) 1022*333d2b36SAndroid Build Coastguard Worker 1023*333d2b36SAndroid Build Coastguard Worker // Add the file that indicates that the file generated by this is valid. 1024*333d2b36SAndroid Build Coastguard Worker // 1025*333d2b36SAndroid Build Coastguard Worker // This will cause the validation rule above to be run any time that the output of this rule 1026*333d2b36SAndroid Build Coastguard Worker // changes but the validation will run in parallel with other rules that depend on this file. 1027*333d2b36SAndroid Build Coastguard Worker command.Validation(validFile) 1028*333d2b36SAndroid Build Coastguard Worker } 1029*333d2b36SAndroid Build Coastguard Worker 1030*333d2b36SAndroid Build Coastguard Worker rule.Build(name, desc) 1031*333d2b36SAndroid Build Coastguard Worker} 1032*333d2b36SAndroid Build Coastguard Worker 1033*333d2b36SAndroid Build Coastguard Worker// SignatureCsvSubset describes a subset of a monolithic flags file, i.e. either 1034*333d2b36SAndroid Build Coastguard Worker// out/soong/hiddenapi/hiddenapi-stub-flags.txt or out/soong/hiddenapi/hiddenapi-flags.csv 1035*333d2b36SAndroid Build Coastguard Workertype SignatureCsvSubset struct { 1036*333d2b36SAndroid Build Coastguard Worker // The path to the CSV file containing hidden API flags. 1037*333d2b36SAndroid Build Coastguard Worker // 1038*333d2b36SAndroid Build Coastguard Worker // It has the dex member signature as the first column, with flags, one per column, in the 1039*333d2b36SAndroid Build Coastguard Worker // subsequent columns. 1040*333d2b36SAndroid Build Coastguard Worker CsvFile android.Path 1041*333d2b36SAndroid Build Coastguard Worker 1042*333d2b36SAndroid Build Coastguard Worker // The path to the CSV file containing the signature patterns. 1043*333d2b36SAndroid Build Coastguard Worker // 1044*333d2b36SAndroid Build Coastguard Worker // It is a single column CSV file with the column containing a signature pattern. 1045*333d2b36SAndroid Build Coastguard Worker SignaturePatternsFile android.Path 1046*333d2b36SAndroid Build Coastguard Worker} 1047*333d2b36SAndroid Build Coastguard Worker 1048*333d2b36SAndroid Build Coastguard Workertype SignatureCsvSubsets []SignatureCsvSubset 1049*333d2b36SAndroid Build Coastguard Worker 1050*333d2b36SAndroid Build Coastguard Workerfunc (s SignatureCsvSubsets) RelativeToTop() []string { 1051*333d2b36SAndroid Build Coastguard Worker result := []string{} 1052*333d2b36SAndroid Build Coastguard Worker for _, subset := range s { 1053*333d2b36SAndroid Build Coastguard Worker result = append(result, fmt.Sprintf("%s:%s", subset.CsvFile.RelativeToTop(), subset.SignaturePatternsFile.RelativeToTop())) 1054*333d2b36SAndroid Build Coastguard Worker } 1055*333d2b36SAndroid Build Coastguard Worker return result 1056*333d2b36SAndroid Build Coastguard Worker} 1057*333d2b36SAndroid Build Coastguard Worker 1058*333d2b36SAndroid Build Coastguard Worker// buildRuleSignaturePatternsFile creates a rule to generate a file containing the set of signature 1059*333d2b36SAndroid Build Coastguard Worker// patterns that will select a subset of the monolithic flags. 1060*333d2b36SAndroid Build Coastguard Workerfunc buildRuleSignaturePatternsFile( 1061*333d2b36SAndroid Build Coastguard Worker ctx android.ModuleContext, flagsPath android.Path, 1062*333d2b36SAndroid Build Coastguard Worker splitPackages []string, packagePrefixes []string, singlePackages []string, 1063*333d2b36SAndroid Build Coastguard Worker suffix string) android.Path { 1064*333d2b36SAndroid Build Coastguard Worker hiddenApiSubDir := "modular-hiddenapi" + suffix 1065*333d2b36SAndroid Build Coastguard Worker 1066*333d2b36SAndroid Build Coastguard Worker patternsFile := android.PathForModuleOut(ctx, hiddenApiSubDir, "signature-patterns.csv") 1067*333d2b36SAndroid Build Coastguard Worker // Create a rule to validate the output from the following rule. 1068*333d2b36SAndroid Build Coastguard Worker rule := android.NewRuleBuilder(pctx, ctx) 1069*333d2b36SAndroid Build Coastguard Worker 1070*333d2b36SAndroid Build Coastguard Worker // Quote any * in the packages to avoid them being expanded by the shell. 1071*333d2b36SAndroid Build Coastguard Worker quotedSplitPackages := []string{} 1072*333d2b36SAndroid Build Coastguard Worker for _, pkg := range splitPackages { 1073*333d2b36SAndroid Build Coastguard Worker quotedSplitPackages = append(quotedSplitPackages, strings.ReplaceAll(pkg, "*", "\\*")) 1074*333d2b36SAndroid Build Coastguard Worker } 1075*333d2b36SAndroid Build Coastguard Worker 1076*333d2b36SAndroid Build Coastguard Worker rule.Command(). 1077*333d2b36SAndroid Build Coastguard Worker BuiltTool("signature_patterns"). 1078*333d2b36SAndroid Build Coastguard Worker FlagWithInput("--flags ", flagsPath). 1079*333d2b36SAndroid Build Coastguard Worker FlagForEachArg("--split-package ", quotedSplitPackages). 1080*333d2b36SAndroid Build Coastguard Worker FlagForEachArg("--package-prefix ", packagePrefixes). 1081*333d2b36SAndroid Build Coastguard Worker FlagForEachArg("--single-package ", singlePackages). 1082*333d2b36SAndroid Build Coastguard Worker FlagWithOutput("--output ", patternsFile) 1083*333d2b36SAndroid Build Coastguard Worker rule.Build("hiddenAPISignaturePatterns"+suffix, "hidden API signature patterns"+suffix) 1084*333d2b36SAndroid Build Coastguard Worker 1085*333d2b36SAndroid Build Coastguard Worker return patternsFile 1086*333d2b36SAndroid Build Coastguard Worker} 1087*333d2b36SAndroid Build Coastguard Worker 1088*333d2b36SAndroid Build Coastguard Worker// buildRuleRemoveSignaturesWithImplementationFlags creates a rule that will remove signatures from 1089*333d2b36SAndroid Build Coastguard Worker// the input flags file which have only the implementation flags, i.e. are not part of an API. 1090*333d2b36SAndroid Build Coastguard Worker// 1091*333d2b36SAndroid Build Coastguard Worker// The implementationFlags specifies the set of default flags that identifies the signature of a 1092*333d2b36SAndroid Build Coastguard Worker// private, implementation only, member. Signatures that match those flags are removed from the 1093*333d2b36SAndroid Build Coastguard Worker// flags as they are implementation only. 1094*333d2b36SAndroid Build Coastguard Worker// 1095*333d2b36SAndroid Build Coastguard Worker// This is used to remove implementation only signatures from the signature files that are persisted 1096*333d2b36SAndroid Build Coastguard Worker// in the sdk snapshot as the sdk snapshots should not include implementation details. The 1097*333d2b36SAndroid Build Coastguard Worker// signatures generated by this method will be compared by the buildRuleValidateOverlappingCsvFiles 1098*333d2b36SAndroid Build Coastguard Worker// method which treats any missing signatures as if they were implementation only signatures. 1099*333d2b36SAndroid Build Coastguard Workerfunc buildRuleRemoveSignaturesWithImplementationFlags(ctx android.BuilderContext, 1100*333d2b36SAndroid Build Coastguard Worker name string, desc string, inputPath android.Path, filteredPath android.WritablePath, 1101*333d2b36SAndroid Build Coastguard Worker implementationFlags []string) { 1102*333d2b36SAndroid Build Coastguard Worker 1103*333d2b36SAndroid Build Coastguard Worker rule := android.NewRuleBuilder(pctx, ctx) 1104*333d2b36SAndroid Build Coastguard Worker implementationFlagPattern := "" 1105*333d2b36SAndroid Build Coastguard Worker for _, implementationFlag := range implementationFlags { 1106*333d2b36SAndroid Build Coastguard Worker implementationFlagPattern = implementationFlagPattern + "," + implementationFlag 1107*333d2b36SAndroid Build Coastguard Worker } 1108*333d2b36SAndroid Build Coastguard Worker rule.Command(). 1109*333d2b36SAndroid Build Coastguard Worker Text(`grep -vE "^[^,]+` + implementationFlagPattern + `$"`).Input(inputPath). 1110*333d2b36SAndroid Build Coastguard Worker Text(">").Output(filteredPath). 1111*333d2b36SAndroid Build Coastguard Worker // Grep's exit code depends on whether it finds anything. It is 0 (build success) when it finds 1112*333d2b36SAndroid Build Coastguard Worker // something and 1 (build failure) when it does not and 2 (when it encounters an error). 1113*333d2b36SAndroid Build Coastguard Worker // However, while it is unlikely it is not an error if this does not find any matches. The 1114*333d2b36SAndroid Build Coastguard Worker // following will only run if the grep does not find something and in that case it will treat 1115*333d2b36SAndroid Build Coastguard Worker // an exit code of 1 as success and anything else as failure. 1116*333d2b36SAndroid Build Coastguard Worker Text("|| test $? -eq 1") 1117*333d2b36SAndroid Build Coastguard Worker rule.Build(name, desc) 1118*333d2b36SAndroid Build Coastguard Worker} 1119*333d2b36SAndroid Build Coastguard Worker 1120*333d2b36SAndroid Build Coastguard Worker// buildRuleValidateOverlappingCsvFiles checks that the modular CSV files, i.e. the files generated 1121*333d2b36SAndroid Build Coastguard Worker// by the individual bootclasspath_fragment modules are subsets of the monolithic CSV file. 1122*333d2b36SAndroid Build Coastguard Worker// 1123*333d2b36SAndroid Build Coastguard Worker// The implementationFlags specifies the set of default flags that identifies the signature of a 1124*333d2b36SAndroid Build Coastguard Worker// private, implementation only, member. A signature which is present in a monolithic flags subset 1125*333d2b36SAndroid Build Coastguard Worker// defined by SignatureCsvSubset but which is not present in the flags file from the corresponding 1126*333d2b36SAndroid Build Coastguard Worker// module is assumed to be an implementation only member and so must have these flags. 1127*333d2b36SAndroid Build Coastguard Workerfunc buildRuleValidateOverlappingCsvFiles(ctx android.BuilderContext, name string, desc string, 1128*333d2b36SAndroid Build Coastguard Worker monolithicFilePath android.WritablePath, csvSubsets SignatureCsvSubsets, 1129*333d2b36SAndroid Build Coastguard Worker implementationFlags []string) android.WritablePath { 1130*333d2b36SAndroid Build Coastguard Worker // The file which is used to record that the flags file is valid. 1131*333d2b36SAndroid Build Coastguard Worker validFile := pathForValidation(ctx, monolithicFilePath) 1132*333d2b36SAndroid Build Coastguard Worker 1133*333d2b36SAndroid Build Coastguard Worker // Create a rule to validate the output from the following rule. 1134*333d2b36SAndroid Build Coastguard Worker rule := android.NewRuleBuilder(pctx, ctx) 1135*333d2b36SAndroid Build Coastguard Worker command := rule.Command(). 1136*333d2b36SAndroid Build Coastguard Worker BuiltTool("verify_overlaps"). 1137*333d2b36SAndroid Build Coastguard Worker FlagWithInput("--monolithic-flags ", monolithicFilePath) 1138*333d2b36SAndroid Build Coastguard Worker 1139*333d2b36SAndroid Build Coastguard Worker for _, subset := range csvSubsets { 1140*333d2b36SAndroid Build Coastguard Worker command. 1141*333d2b36SAndroid Build Coastguard Worker Flag("--module-flags "). 1142*333d2b36SAndroid Build Coastguard Worker Textf("%s:%s", subset.CsvFile, subset.SignaturePatternsFile). 1143*333d2b36SAndroid Build Coastguard Worker Implicit(subset.CsvFile).Implicit(subset.SignaturePatternsFile) 1144*333d2b36SAndroid Build Coastguard Worker } 1145*333d2b36SAndroid Build Coastguard Worker 1146*333d2b36SAndroid Build Coastguard Worker for _, implementationFlag := range implementationFlags { 1147*333d2b36SAndroid Build Coastguard Worker command.FlagWithArg("--implementation-flag ", implementationFlag) 1148*333d2b36SAndroid Build Coastguard Worker } 1149*333d2b36SAndroid Build Coastguard Worker 1150*333d2b36SAndroid Build Coastguard Worker // If validation passes then update the file that records that. 1151*333d2b36SAndroid Build Coastguard Worker command.Text("&& touch").Output(validFile) 1152*333d2b36SAndroid Build Coastguard Worker rule.Build(name+"Validation", desc+" validation") 1153*333d2b36SAndroid Build Coastguard Worker 1154*333d2b36SAndroid Build Coastguard Worker return validFile 1155*333d2b36SAndroid Build Coastguard Worker} 1156*333d2b36SAndroid Build Coastguard Worker 1157*333d2b36SAndroid Build Coastguard Worker// hiddenAPIFlagRulesForBootclasspathFragment will generate all the flags for a fragment of the 1158*333d2b36SAndroid Build Coastguard Worker// bootclasspath. 1159*333d2b36SAndroid Build Coastguard Worker// 1160*333d2b36SAndroid Build Coastguard Worker// It takes: 1161*333d2b36SAndroid Build Coastguard Worker// * Map from android.SdkKind to stub dex jar paths defining the API for that sdk kind. 1162*333d2b36SAndroid Build Coastguard Worker// * The list of modules that are the contents of the fragment. 1163*333d2b36SAndroid Build Coastguard Worker// * The additional manually curated flag files to use. 1164*333d2b36SAndroid Build Coastguard Worker// 1165*333d2b36SAndroid Build Coastguard Worker// It generates: 1166*333d2b36SAndroid Build Coastguard Worker// * stub-flags.csv 1167*333d2b36SAndroid Build Coastguard Worker// * annotation-flags.csv 1168*333d2b36SAndroid Build Coastguard Worker// * metadata.csv 1169*333d2b36SAndroid Build Coastguard Worker// * index.csv 1170*333d2b36SAndroid Build Coastguard Worker// * all-flags.csv 1171*333d2b36SAndroid Build Coastguard Workerfunc hiddenAPIFlagRulesForBootclasspathFragment(ctx android.ModuleContext, bootDexInfoByModule bootDexInfoByModule, contents []android.Module, input HiddenAPIFlagInput, suffix string) HiddenAPIFlagOutput { 1172*333d2b36SAndroid Build Coastguard Worker hiddenApiSubDir := "modular-hiddenapi" + suffix 1173*333d2b36SAndroid Build Coastguard Worker 1174*333d2b36SAndroid Build Coastguard Worker // Generate the stub-flags.csv. 1175*333d2b36SAndroid Build Coastguard Worker stubFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "stub-flags.csv") 1176*333d2b36SAndroid Build Coastguard Worker buildRuleToGenerateHiddenAPIStubFlagsFile(ctx, "modularHiddenAPIStubFlagsFile"+suffix, "modular hiddenapi stub flags", stubFlagsCSV, bootDexInfoByModule.bootDexJars(), input, nil) 1177*333d2b36SAndroid Build Coastguard Worker 1178*333d2b36SAndroid Build Coastguard Worker // Extract the classes jars from the contents. 1179*333d2b36SAndroid Build Coastguard Worker classesJars := extractClassesJarsFromModules(contents) 1180*333d2b36SAndroid Build Coastguard Worker 1181*333d2b36SAndroid Build Coastguard Worker // Generate the set of flags from the annotations in the source code. 1182*333d2b36SAndroid Build Coastguard Worker annotationFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "annotation-flags.csv") 1183*333d2b36SAndroid Build Coastguard Worker buildRuleToGenerateAnnotationFlags(ctx, "modular hiddenapi annotation flags"+suffix, classesJars, stubFlagsCSV, annotationFlagsCSV) 1184*333d2b36SAndroid Build Coastguard Worker 1185*333d2b36SAndroid Build Coastguard Worker // Generate the metadata from the annotations in the source code. 1186*333d2b36SAndroid Build Coastguard Worker metadataCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "metadata.csv") 1187*333d2b36SAndroid Build Coastguard Worker buildRuleToGenerateMetadata(ctx, "modular hiddenapi metadata"+suffix, classesJars, stubFlagsCSV, metadataCSV) 1188*333d2b36SAndroid Build Coastguard Worker 1189*333d2b36SAndroid Build Coastguard Worker // Generate the index file from the CSV files in the classes jars. 1190*333d2b36SAndroid Build Coastguard Worker indexCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "index.csv") 1191*333d2b36SAndroid Build Coastguard Worker buildRuleToGenerateIndex(ctx, "modular hiddenapi index"+suffix, classesJars, indexCSV) 1192*333d2b36SAndroid Build Coastguard Worker 1193*333d2b36SAndroid Build Coastguard Worker // Removed APIs need to be marked and in order to do that the hiddenAPIInfo needs to specify files 1194*333d2b36SAndroid Build Coastguard Worker // containing dex signatures of all the removed APIs. In the monolithic files that is done by 1195*333d2b36SAndroid Build Coastguard Worker // manually combining all the removed.txt files for each API and then converting them to dex 1196*333d2b36SAndroid Build Coastguard Worker // signatures, see the combined-removed-dex module. This does that automatically by using the 1197*333d2b36SAndroid Build Coastguard Worker // *removed.txt files retrieved from the java_sdk_library modules that are specified in the 1198*333d2b36SAndroid Build Coastguard Worker // stub_libs and contents properties of a bootclasspath_fragment. 1199*333d2b36SAndroid Build Coastguard Worker removedDexSignatures := buildRuleToGenerateRemovedDexSignatures(ctx, suffix, input.RemovedTxtFiles) 1200*333d2b36SAndroid Build Coastguard Worker 1201*333d2b36SAndroid Build Coastguard Worker // Generate the all-flags.csv which are the flags that will, in future, be encoded into the dex 1202*333d2b36SAndroid Build Coastguard Worker // files. 1203*333d2b36SAndroid Build Coastguard Worker allFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "all-flags.csv") 1204*333d2b36SAndroid Build Coastguard Worker buildRuleToGenerateHiddenApiFlags(ctx, "modularHiddenApiAllFlags"+suffix, "modular hiddenapi all flags"+suffix, allFlagsCSV, stubFlagsCSV, android.Paths{annotationFlagsCSV}, input.FlagFilesByCategory, nil, removedDexSignatures) 1205*333d2b36SAndroid Build Coastguard Worker 1206*333d2b36SAndroid Build Coastguard Worker // Generate the filtered-stub-flags.csv file which contains the filtered stub flags that will be 1207*333d2b36SAndroid Build Coastguard Worker // compared against the monolithic stub flags. 1208*333d2b36SAndroid Build Coastguard Worker filteredStubFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "filtered-stub-flags.csv") 1209*333d2b36SAndroid Build Coastguard Worker buildRuleRemoveSignaturesWithImplementationFlags(ctx, "modularHiddenApiFilteredStubFlags"+suffix, 1210*333d2b36SAndroid Build Coastguard Worker "modular hiddenapi filtered stub flags"+suffix, stubFlagsCSV, filteredStubFlagsCSV, 1211*333d2b36SAndroid Build Coastguard Worker HIDDENAPI_STUB_FLAGS_IMPL_FLAGS) 1212*333d2b36SAndroid Build Coastguard Worker 1213*333d2b36SAndroid Build Coastguard Worker // Generate the filtered-flags.csv file which contains the filtered flags that will be compared 1214*333d2b36SAndroid Build Coastguard Worker // against the monolithic flags. 1215*333d2b36SAndroid Build Coastguard Worker filteredFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "filtered-flags.csv") 1216*333d2b36SAndroid Build Coastguard Worker buildRuleRemoveSignaturesWithImplementationFlags(ctx, "modularHiddenApiFilteredFlags"+suffix, 1217*333d2b36SAndroid Build Coastguard Worker "modular hiddenapi filtered flags"+suffix, allFlagsCSV, filteredFlagsCSV, 1218*333d2b36SAndroid Build Coastguard Worker HIDDENAPI_FLAGS_CSV_IMPL_FLAGS) 1219*333d2b36SAndroid Build Coastguard Worker 1220*333d2b36SAndroid Build Coastguard Worker // Store the paths in the info for use by other modules and sdk snapshot generation. 1221*333d2b36SAndroid Build Coastguard Worker return HiddenAPIFlagOutput{ 1222*333d2b36SAndroid Build Coastguard Worker AnnotationFlagsPath: annotationFlagsCSV, 1223*333d2b36SAndroid Build Coastguard Worker MetadataPath: metadataCSV, 1224*333d2b36SAndroid Build Coastguard Worker IndexPath: indexCSV, 1225*333d2b36SAndroid Build Coastguard Worker StubFlagsPath: stubFlagsCSV, 1226*333d2b36SAndroid Build Coastguard Worker AllFlagsPath: allFlagsCSV, 1227*333d2b36SAndroid Build Coastguard Worker FilteredStubFlagsPath: filteredStubFlagsCSV, 1228*333d2b36SAndroid Build Coastguard Worker FilteredFlagsPath: filteredFlagsCSV, 1229*333d2b36SAndroid Build Coastguard Worker } 1230*333d2b36SAndroid Build Coastguard Worker} 1231*333d2b36SAndroid Build Coastguard Worker 1232*333d2b36SAndroid Build Coastguard Worker// hiddenAPIEncodeRulesForBootclasspathFragment generates rules to encode hidden API flags into the 1233*333d2b36SAndroid Build Coastguard Worker// dex jars in bootDexInfoByModule. 1234*333d2b36SAndroid Build Coastguard Workerfunc hiddenAPIEncodeRulesForBootclasspathFragment(ctx android.ModuleContext, bootDexInfoByModule bootDexInfoByModule, allFlagsCSV android.Path) bootDexJarByModule { 1235*333d2b36SAndroid Build Coastguard Worker // Encode the flags into the boot dex files. 1236*333d2b36SAndroid Build Coastguard Worker encodedBootDexJarsByModule := bootDexJarByModule{} 1237*333d2b36SAndroid Build Coastguard Worker outputDir := android.PathForModuleOut(ctx, "hiddenapi-modular/encoded").OutputPath 1238*333d2b36SAndroid Build Coastguard Worker for _, name := range android.SortedKeys(bootDexInfoByModule) { 1239*333d2b36SAndroid Build Coastguard Worker bootDexInfo := bootDexInfoByModule[name] 1240*333d2b36SAndroid Build Coastguard Worker unencodedDex := bootDexInfo.path 1241*333d2b36SAndroid Build Coastguard Worker encodedDex := hiddenAPIEncodeDex(ctx, unencodedDex, allFlagsCSV, bootDexInfo.uncompressDex, bootDexInfo.minSdkVersion, outputDir) 1242*333d2b36SAndroid Build Coastguard Worker encodedBootDexJarsByModule[name] = encodedDex 1243*333d2b36SAndroid Build Coastguard Worker } 1244*333d2b36SAndroid Build Coastguard Worker return encodedBootDexJarsByModule 1245*333d2b36SAndroid Build Coastguard Worker} 1246*333d2b36SAndroid Build Coastguard Worker 1247*333d2b36SAndroid Build Coastguard Workerfunc buildRuleToGenerateRemovedDexSignatures(ctx android.ModuleContext, suffix string, removedTxtFiles android.Paths) android.OptionalPath { 1248*333d2b36SAndroid Build Coastguard Worker if len(removedTxtFiles) == 0 { 1249*333d2b36SAndroid Build Coastguard Worker return android.OptionalPath{} 1250*333d2b36SAndroid Build Coastguard Worker } 1251*333d2b36SAndroid Build Coastguard Worker 1252*333d2b36SAndroid Build Coastguard Worker output := android.PathForModuleOut(ctx, "module-hiddenapi"+suffix, "removed-dex-signatures.txt") 1253*333d2b36SAndroid Build Coastguard Worker 1254*333d2b36SAndroid Build Coastguard Worker rule := android.NewRuleBuilder(pctx, ctx) 1255*333d2b36SAndroid Build Coastguard Worker rule.Command(). 1256*333d2b36SAndroid Build Coastguard Worker BuiltTool("metalava"). 1257*333d2b36SAndroid Build Coastguard Worker Text("signature-to-dex"). 1258*333d2b36SAndroid Build Coastguard Worker Inputs(removedTxtFiles). 1259*333d2b36SAndroid Build Coastguard Worker FlagWithOutput("--out ", output) 1260*333d2b36SAndroid Build Coastguard Worker rule.Build("modular-hiddenapi-removed-dex-signatures"+suffix, "modular hiddenapi removed dex signatures"+suffix) 1261*333d2b36SAndroid Build Coastguard Worker return android.OptionalPathForPath(output) 1262*333d2b36SAndroid Build Coastguard Worker} 1263*333d2b36SAndroid Build Coastguard Worker 1264*333d2b36SAndroid Build Coastguard Worker// extractBootDexJarsFromModules extracts the boot dex jars from the supplied modules. 1265*333d2b36SAndroid Build Coastguard Worker// This information can come from two mechanisms 1266*333d2b36SAndroid Build Coastguard Worker// 1. New: Direct deps to _selected_ apexes. The apexes contain a ApexExportsInfo 1267*333d2b36SAndroid Build Coastguard Worker// 2. Legacy: An edge to java_sdk_library(_import) module. For prebuilt apexes, this serves as a hook and is populated by deapexers of prebuilt apxes 1268*333d2b36SAndroid Build Coastguard Worker// TODO: b/308174306 - Once all mainline modules have been flagged, drop (2) 1269*333d2b36SAndroid Build Coastguard Workerfunc extractBootDexJarsFromModules(ctx android.ModuleContext, contents []android.Module) bootDexJarByModule { 1270*333d2b36SAndroid Build Coastguard Worker bootDexJars := bootDexJarByModule{} 1271*333d2b36SAndroid Build Coastguard Worker 1272*333d2b36SAndroid Build Coastguard Worker apexNameToApexExportsInfoMap := getApexNameToApexExportsInfoMap(ctx) 1273*333d2b36SAndroid Build Coastguard Worker // For ART and mainline module jars, query apexNameToApexExportsInfoMap to get the dex file 1274*333d2b36SAndroid Build Coastguard Worker apexJars := dexpreopt.GetGlobalConfig(ctx).ArtApexJars.AppendList(&dexpreopt.GetGlobalConfig(ctx).ApexBootJars) 1275*333d2b36SAndroid Build Coastguard Worker for i := 0; i < apexJars.Len(); i++ { 1276*333d2b36SAndroid Build Coastguard Worker if dex, found := apexNameToApexExportsInfoMap.javaLibraryDexPathOnHost(ctx, apexJars.Apex(i), apexJars.Jar(i)); found { 1277*333d2b36SAndroid Build Coastguard Worker bootDexJars[apexJars.Jar(i)] = dex 1278*333d2b36SAndroid Build Coastguard Worker } 1279*333d2b36SAndroid Build Coastguard Worker } 1280*333d2b36SAndroid Build Coastguard Worker 1281*333d2b36SAndroid Build Coastguard Worker // TODO - b/308174306: Drop the legacy mechanism 1282*333d2b36SAndroid Build Coastguard Worker for _, module := range contents { 1283*333d2b36SAndroid Build Coastguard Worker if _, exists := bootDexJars[android.RemoveOptionalPrebuiltPrefix(module.Name())]; exists { 1284*333d2b36SAndroid Build Coastguard Worker continue 1285*333d2b36SAndroid Build Coastguard Worker } 1286*333d2b36SAndroid Build Coastguard Worker hiddenAPIModule := hiddenAPIModuleFromModule(ctx, module) 1287*333d2b36SAndroid Build Coastguard Worker if hiddenAPIModule == nil { 1288*333d2b36SAndroid Build Coastguard Worker continue 1289*333d2b36SAndroid Build Coastguard Worker } 1290*333d2b36SAndroid Build Coastguard Worker bootDexJar := retrieveBootDexJarFromHiddenAPIModule(ctx, hiddenAPIModule) 1291*333d2b36SAndroid Build Coastguard Worker bootDexJars.addPath(module, bootDexJar) 1292*333d2b36SAndroid Build Coastguard Worker } 1293*333d2b36SAndroid Build Coastguard Worker return bootDexJars 1294*333d2b36SAndroid Build Coastguard Worker} 1295*333d2b36SAndroid Build Coastguard Worker 1296*333d2b36SAndroid Build Coastguard Workerfunc hiddenAPIModuleFromModule(ctx android.BaseModuleContext, module android.Module) hiddenAPIModule { 1297*333d2b36SAndroid Build Coastguard Worker if hiddenAPIModule, ok := module.(hiddenAPIModule); ok { 1298*333d2b36SAndroid Build Coastguard Worker return hiddenAPIModule 1299*333d2b36SAndroid Build Coastguard Worker } else if _, ok := module.(*DexImport); ok { 1300*333d2b36SAndroid Build Coastguard Worker // Ignore this for the purposes of hidden API processing 1301*333d2b36SAndroid Build Coastguard Worker } else { 1302*333d2b36SAndroid Build Coastguard Worker ctx.ModuleErrorf("module %s does not implement hiddenAPIModule", module) 1303*333d2b36SAndroid Build Coastguard Worker } 1304*333d2b36SAndroid Build Coastguard Worker 1305*333d2b36SAndroid Build Coastguard Worker return nil 1306*333d2b36SAndroid Build Coastguard Worker} 1307*333d2b36SAndroid Build Coastguard Worker 1308*333d2b36SAndroid Build Coastguard Worker// bootDexInfo encapsulates both the path and uncompressDex status retrieved from a hiddenAPIModule. 1309*333d2b36SAndroid Build Coastguard Workertype bootDexInfo struct { 1310*333d2b36SAndroid Build Coastguard Worker // The path to the dex jar that has not had hidden API flags encoded into it. 1311*333d2b36SAndroid Build Coastguard Worker path android.Path 1312*333d2b36SAndroid Build Coastguard Worker 1313*333d2b36SAndroid Build Coastguard Worker // Indicates whether the dex jar needs uncompressing before encoding. 1314*333d2b36SAndroid Build Coastguard Worker uncompressDex bool 1315*333d2b36SAndroid Build Coastguard Worker 1316*333d2b36SAndroid Build Coastguard Worker // The minimum sdk version that the dex jar will be used on. 1317*333d2b36SAndroid Build Coastguard Worker minSdkVersion android.ApiLevel 1318*333d2b36SAndroid Build Coastguard Worker} 1319*333d2b36SAndroid Build Coastguard Worker 1320*333d2b36SAndroid Build Coastguard Worker// bootDexInfoByModule is a map from module name (as returned by module.Name()) to the boot dex 1321*333d2b36SAndroid Build Coastguard Worker// path (as returned by hiddenAPIModule.bootDexJar()) and the uncompressDex flag. 1322*333d2b36SAndroid Build Coastguard Workertype bootDexInfoByModule map[string]bootDexInfo 1323*333d2b36SAndroid Build Coastguard Worker 1324*333d2b36SAndroid Build Coastguard Worker// bootDexJars returns the boot dex jar paths sorted by their keys. 1325*333d2b36SAndroid Build Coastguard Workerfunc (b bootDexInfoByModule) bootDexJars() android.Paths { 1326*333d2b36SAndroid Build Coastguard Worker paths := android.Paths{} 1327*333d2b36SAndroid Build Coastguard Worker for _, m := range android.SortedKeys(b) { 1328*333d2b36SAndroid Build Coastguard Worker paths = append(paths, b[m].path) 1329*333d2b36SAndroid Build Coastguard Worker } 1330*333d2b36SAndroid Build Coastguard Worker return paths 1331*333d2b36SAndroid Build Coastguard Worker} 1332*333d2b36SAndroid Build Coastguard Worker 1333*333d2b36SAndroid Build Coastguard Worker// extractBootDexInfoFromModules extracts the boot dex jar and uncompress dex state from 1334*333d2b36SAndroid Build Coastguard Worker// each of the supplied modules which must implement hiddenAPIModule. 1335*333d2b36SAndroid Build Coastguard Workerfunc extractBootDexInfoFromModules(ctx android.ModuleContext, contents []android.Module) bootDexInfoByModule { 1336*333d2b36SAndroid Build Coastguard Worker bootDexJarsByModule := bootDexInfoByModule{} 1337*333d2b36SAndroid Build Coastguard Worker for _, module := range contents { 1338*333d2b36SAndroid Build Coastguard Worker hiddenAPIModule := module.(hiddenAPIModule) 1339*333d2b36SAndroid Build Coastguard Worker bootDexJar := retrieveBootDexJarFromHiddenAPIModule(ctx, hiddenAPIModule) 1340*333d2b36SAndroid Build Coastguard Worker bootDexJarsByModule[module.Name()] = bootDexInfo{ 1341*333d2b36SAndroid Build Coastguard Worker path: bootDexJar, 1342*333d2b36SAndroid Build Coastguard Worker uncompressDex: *hiddenAPIModule.uncompressDex(), 1343*333d2b36SAndroid Build Coastguard Worker minSdkVersion: hiddenAPIModule.MinSdkVersion(ctx), 1344*333d2b36SAndroid Build Coastguard Worker } 1345*333d2b36SAndroid Build Coastguard Worker } 1346*333d2b36SAndroid Build Coastguard Worker 1347*333d2b36SAndroid Build Coastguard Worker return bootDexJarsByModule 1348*333d2b36SAndroid Build Coastguard Worker} 1349*333d2b36SAndroid Build Coastguard Worker 1350*333d2b36SAndroid Build Coastguard Worker// retrieveBootDexJarFromHiddenAPIModule retrieves the boot dex jar from the hiddenAPIModule. 1351*333d2b36SAndroid Build Coastguard Worker// 1352*333d2b36SAndroid Build Coastguard Worker// If the module does not provide a boot dex jar, i.e. the returned boot dex jar is unset or 1353*333d2b36SAndroid Build Coastguard Worker// invalid, then create a fake path and either report an error immediately or defer reporting of the 1354*333d2b36SAndroid Build Coastguard Worker// error until the path is actually used. 1355*333d2b36SAndroid Build Coastguard Workerfunc retrieveBootDexJarFromHiddenAPIModule(ctx android.ModuleContext, module hiddenAPIModule) android.Path { 1356*333d2b36SAndroid Build Coastguard Worker bootDexJar := module.bootDexJar(ctx) 1357*333d2b36SAndroid Build Coastguard Worker if !bootDexJar.Valid() { 1358*333d2b36SAndroid Build Coastguard Worker fake := android.PathForModuleOut(ctx, fmt.Sprintf("fake/boot-dex/%s.jar", module.Name())) 1359*333d2b36SAndroid Build Coastguard Worker handleMissingDexBootFile(ctx, module, fake, bootDexJar.InvalidReason()) 1360*333d2b36SAndroid Build Coastguard Worker return fake 1361*333d2b36SAndroid Build Coastguard Worker } 1362*333d2b36SAndroid Build Coastguard Worker return bootDexJar.Path() 1363*333d2b36SAndroid Build Coastguard Worker} 1364*333d2b36SAndroid Build Coastguard Worker 1365*333d2b36SAndroid Build Coastguard Worker// extractClassesJarsFromModules extracts the class jars from the supplied modules. 1366*333d2b36SAndroid Build Coastguard Workerfunc extractClassesJarsFromModules(contents []android.Module) android.Paths { 1367*333d2b36SAndroid Build Coastguard Worker classesJars := android.Paths{} 1368*333d2b36SAndroid Build Coastguard Worker for _, module := range contents { 1369*333d2b36SAndroid Build Coastguard Worker classesJars = append(classesJars, retrieveClassesJarsFromModule(module)...) 1370*333d2b36SAndroid Build Coastguard Worker } 1371*333d2b36SAndroid Build Coastguard Worker return classesJars 1372*333d2b36SAndroid Build Coastguard Worker} 1373*333d2b36SAndroid Build Coastguard Worker 1374*333d2b36SAndroid Build Coastguard Worker// retrieveClassesJarsFromModule retrieves the classes jars from the supplied module. 1375*333d2b36SAndroid Build Coastguard Workerfunc retrieveClassesJarsFromModule(module android.Module) android.Paths { 1376*333d2b36SAndroid Build Coastguard Worker if hiddenAPIModule, ok := module.(hiddenAPIModule); ok { 1377*333d2b36SAndroid Build Coastguard Worker return hiddenAPIModule.classesJars() 1378*333d2b36SAndroid Build Coastguard Worker } 1379*333d2b36SAndroid Build Coastguard Worker 1380*333d2b36SAndroid Build Coastguard Worker return nil 1381*333d2b36SAndroid Build Coastguard Worker} 1382*333d2b36SAndroid Build Coastguard Worker 1383*333d2b36SAndroid Build Coastguard Worker// deferReportingMissingBootDexJar returns true if a missing boot dex jar should not be reported by 1384*333d2b36SAndroid Build Coastguard Worker// Soong but should instead only be reported in ninja if the file is actually built. 1385*333d2b36SAndroid Build Coastguard Workerfunc deferReportingMissingBootDexJar(ctx android.ModuleContext, module android.Module) bool { 1386*333d2b36SAndroid Build Coastguard Worker // Any missing dependency should be allowed. 1387*333d2b36SAndroid Build Coastguard Worker if ctx.Config().AllowMissingDependencies() { 1388*333d2b36SAndroid Build Coastguard Worker return true 1389*333d2b36SAndroid Build Coastguard Worker } 1390*333d2b36SAndroid Build Coastguard Worker 1391*333d2b36SAndroid Build Coastguard Worker // This is called for both platform_bootclasspath and bootclasspath_fragment modules. 1392*333d2b36SAndroid Build Coastguard Worker // 1393*333d2b36SAndroid Build Coastguard Worker // A bootclasspath_fragment module should only use the APEX variant of source or prebuilt modules. 1394*333d2b36SAndroid Build Coastguard Worker // Ideally, a bootclasspath_fragment module should never have a platform variant created for it 1395*333d2b36SAndroid Build Coastguard Worker // but unfortunately, due to b/187910671 it does. 1396*333d2b36SAndroid Build Coastguard Worker // 1397*333d2b36SAndroid Build Coastguard Worker // That causes issues when obtaining a boot dex jar for a prebuilt module as a prebuilt module 1398*333d2b36SAndroid Build Coastguard Worker // used by a bootclasspath_fragment can only provide a boot dex jar when it is part of APEX, i.e. 1399*333d2b36SAndroid Build Coastguard Worker // has an APEX variant not a platform variant. 1400*333d2b36SAndroid Build Coastguard Worker // 1401*333d2b36SAndroid Build Coastguard Worker // There are some other situations when a prebuilt module used by a bootclasspath_fragment cannot 1402*333d2b36SAndroid Build Coastguard Worker // provide a boot dex jar: 1403*333d2b36SAndroid Build Coastguard Worker // 1. If the bootclasspath_fragment is not exported by the prebuilt_apex/apex_set module then it 1404*333d2b36SAndroid Build Coastguard Worker // does not have an APEX variant and only has a platform variant and neither do its content 1405*333d2b36SAndroid Build Coastguard Worker // modules. 1406*333d2b36SAndroid Build Coastguard Worker // 2. Some build configurations, e.g. setting TARGET_BUILD_USE_PREBUILT_SDKS causes all 1407*333d2b36SAndroid Build Coastguard Worker // java_sdk_library_import modules to be treated as preferred and as many of them are not part 1408*333d2b36SAndroid Build Coastguard Worker // of an apex they cannot provide a boot dex jar. 1409*333d2b36SAndroid Build Coastguard Worker // 1410*333d2b36SAndroid Build Coastguard Worker // The first case causes problems when the affected prebuilt modules are preferred but that is an 1411*333d2b36SAndroid Build Coastguard Worker // invalid configuration and it is ok for it to fail as the work to enable that is not yet 1412*333d2b36SAndroid Build Coastguard Worker // complete. The second case is used for building targets that do not use boot dex jars and so 1413*333d2b36SAndroid Build Coastguard Worker // deferring error reporting to ninja is fine as the affected ninja targets should never be built. 1414*333d2b36SAndroid Build Coastguard Worker // That is handled above. 1415*333d2b36SAndroid Build Coastguard Worker // 1416*333d2b36SAndroid Build Coastguard Worker // A platform_bootclasspath module can use libraries from both platform and APEX variants. Unlike 1417*333d2b36SAndroid Build Coastguard Worker // the bootclasspath_fragment it supports dex_import modules which provides the dex file. So, it 1418*333d2b36SAndroid Build Coastguard Worker // can obtain a boot dex jar from a prebuilt that is not part of an APEX. However, it is assumed 1419*333d2b36SAndroid Build Coastguard Worker // that if the library can be part of an APEX then it is the APEX variant that is used. 1420*333d2b36SAndroid Build Coastguard Worker // 1421*333d2b36SAndroid Build Coastguard Worker // This check handles the slightly different requirements of the bootclasspath_fragment and 1422*333d2b36SAndroid Build Coastguard Worker // platform_bootclasspath modules by only deferring error reporting for the platform variant of 1423*333d2b36SAndroid Build Coastguard Worker // a prebuilt modules that has other variants which are part of an APEX. 1424*333d2b36SAndroid Build Coastguard Worker // 1425*333d2b36SAndroid Build Coastguard Worker // TODO(b/187910671): Remove this once platform variants are no longer created unnecessarily. 1426*333d2b36SAndroid Build Coastguard Worker if android.IsModulePrebuilt(module) { 1427*333d2b36SAndroid Build Coastguard Worker // An inactive source module can still contribute to the APEX but an inactive prebuilt module 1428*333d2b36SAndroid Build Coastguard Worker // should not contribute to anything. So, rather than have a missing dex jar cause a Soong 1429*333d2b36SAndroid Build Coastguard Worker // failure defer the error reporting to Ninja. Unless the prebuilt build target is explicitly 1430*333d2b36SAndroid Build Coastguard Worker // built Ninja should never use the dex jar file. 1431*333d2b36SAndroid Build Coastguard Worker if !isActiveModule(ctx, module) { 1432*333d2b36SAndroid Build Coastguard Worker return true 1433*333d2b36SAndroid Build Coastguard Worker } 1434*333d2b36SAndroid Build Coastguard Worker 1435*333d2b36SAndroid Build Coastguard Worker if am, ok := module.(android.ApexModule); ok && am.InAnyApex() { 1436*333d2b36SAndroid Build Coastguard Worker apexInfo, _ := android.OtherModuleProvider(ctx, module, android.ApexInfoProvider) 1437*333d2b36SAndroid Build Coastguard Worker if apexInfo.IsForPlatform() { 1438*333d2b36SAndroid Build Coastguard Worker return true 1439*333d2b36SAndroid Build Coastguard Worker } 1440*333d2b36SAndroid Build Coastguard Worker } 1441*333d2b36SAndroid Build Coastguard Worker } 1442*333d2b36SAndroid Build Coastguard Worker 1443*333d2b36SAndroid Build Coastguard Worker return false 1444*333d2b36SAndroid Build Coastguard Worker} 1445*333d2b36SAndroid Build Coastguard Worker 1446*333d2b36SAndroid Build Coastguard Worker// handleMissingDexBootFile will either log a warning or create an error rule to create the fake 1447*333d2b36SAndroid Build Coastguard Worker// file depending on the value returned from deferReportingMissingBootDexJar. 1448*333d2b36SAndroid Build Coastguard Workerfunc handleMissingDexBootFile(ctx android.ModuleContext, module android.Module, fake android.WritablePath, reason string) { 1449*333d2b36SAndroid Build Coastguard Worker if deferReportingMissingBootDexJar(ctx, module) { 1450*333d2b36SAndroid Build Coastguard Worker // Create an error rule that pretends to create the output file but will actually fail if it 1451*333d2b36SAndroid Build Coastguard Worker // is run. 1452*333d2b36SAndroid Build Coastguard Worker ctx.Build(pctx, android.BuildParams{ 1453*333d2b36SAndroid Build Coastguard Worker Rule: android.ErrorRule, 1454*333d2b36SAndroid Build Coastguard Worker Output: fake, 1455*333d2b36SAndroid Build Coastguard Worker Args: map[string]string{ 1456*333d2b36SAndroid Build Coastguard Worker "error": fmt.Sprintf("missing boot dex jar dependency for %s: %s", module, reason), 1457*333d2b36SAndroid Build Coastguard Worker }, 1458*333d2b36SAndroid Build Coastguard Worker }) 1459*333d2b36SAndroid Build Coastguard Worker } else { 1460*333d2b36SAndroid Build Coastguard Worker ctx.ModuleErrorf("module %s does not provide a dex jar: %s", module, reason) 1461*333d2b36SAndroid Build Coastguard Worker } 1462*333d2b36SAndroid Build Coastguard Worker} 1463*333d2b36SAndroid Build Coastguard Worker 1464*333d2b36SAndroid Build Coastguard Worker// retrieveEncodedBootDexJarFromModule returns a path to the boot dex jar from the supplied module's 1465*333d2b36SAndroid Build Coastguard Worker// DexJarBuildPath() method. 1466*333d2b36SAndroid Build Coastguard Worker// 1467*333d2b36SAndroid Build Coastguard Worker// The returned path will usually be to a dex jar file that has been encoded with hidden API flags. 1468*333d2b36SAndroid Build Coastguard Worker// However, under certain conditions, e.g. errors, or special build configurations it will return 1469*333d2b36SAndroid Build Coastguard Worker// a path to a fake file. 1470*333d2b36SAndroid Build Coastguard Workerfunc retrieveEncodedBootDexJarFromModule(ctx android.ModuleContext, module android.Module) android.Path { 1471*333d2b36SAndroid Build Coastguard Worker bootDexJar := module.(interface { 1472*333d2b36SAndroid Build Coastguard Worker DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath 1473*333d2b36SAndroid Build Coastguard Worker }).DexJarBuildPath(ctx) 1474*333d2b36SAndroid Build Coastguard Worker if !bootDexJar.Valid() { 1475*333d2b36SAndroid Build Coastguard Worker fake := android.PathForModuleOut(ctx, fmt.Sprintf("fake/encoded-dex/%s.jar", module.Name())) 1476*333d2b36SAndroid Build Coastguard Worker handleMissingDexBootFile(ctx, module, fake, bootDexJar.InvalidReason()) 1477*333d2b36SAndroid Build Coastguard Worker return fake 1478*333d2b36SAndroid Build Coastguard Worker } 1479*333d2b36SAndroid Build Coastguard Worker return bootDexJar.Path() 1480*333d2b36SAndroid Build Coastguard Worker} 1481